void r200TclPrimitive( struct gl_context *ctx, GLenum prim, int hw_prim ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint newprim = hw_prim | R200_VF_TCL_OUTPUT_VTX_ENABLE; radeon_prepare_render(&rmesa->radeon); if (rmesa->radeon.NewGLState) r200ValidateState( ctx ); if (newprim != rmesa->tcl.hw_primitive || !discrete_prim[hw_prim&0xf]) { /* need to disable perspective-correct texturing for point sprites */ if ((prim & PRIM_MODE_MASK) == GL_POINTS && ctx->Point.PointSprite) { if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) { R200_STATECHANGE( rmesa, set ); rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE; } } else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) { R200_STATECHANGE( rmesa, set ); rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE; } R200_NEWPRIM( rmesa ); rmesa->tcl.hw_primitive = newprim; } }
static void transition_to_swtnl( struct gl_context *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); R200_NEWPRIM( rmesa ); r200ChooseVertexState( ctx ); r200ChooseRenderState( ctx ); _tnl_validate_shine_tables( ctx ); tnl->Driver.NotifyMaterialChange = _tnl_validate_shine_tables; radeonReleaseArrays( ctx, ~0 ); /* Still using the D3D based hardware-rasterizer from the radeon; * need to put the card into D3D mode to make it work: */ R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_TCL_ENABLE|R200_VAP_PROG_VTX_SHADER_ENABLE); }
/* Begin/End */ static void r200_Begin( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s( %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr( mode )); if (mode > GL_POLYGON) { _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); return; } if (rmesa->vb.prim[0] != GL_POLYGON+1) { _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); return; } if (ctx->NewState) _mesa_update_state( ctx ); if (rmesa->NewGLState) r200ValidateState( ctx ); if (rmesa->vb.recheck) r200VtxfmtValidate( ctx ); if (!rmesa->vb.installed) { CALL_Begin(GET_DISPATCH(), (mode)); return; } if (rmesa->dma.flush && rmesa->vb.counter < 12) { if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); flush_prims( rmesa ); } /* Need to arrange to save vertices here? Or always copy from dma (yuk)? */ if (!rmesa->dma.flush) { if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > rmesa->dma.current.end) { R200_NEWPRIM( rmesa ); r200RefillCurrentDmaRegion( rmesa ); } rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / (rmesa->vb.vertex_size * 4); rmesa->vb.counter--; rmesa->vb.initial_counter = rmesa->vb.counter; rmesa->vb.notify = wrap_buffer; rmesa->dma.flush = flush_prims; ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; } rmesa->vb.prim[0] = mode; start_prim( rmesa, mode | PRIM_BEGIN ); }
/** * Determines the hardware vertex format based on the current state vector. * * \returns * If the hardware TCL unit is capable of handling the current state vector, * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned. * * \todo * Make this color format selection data driven. If we receive only ubytes, * send color as ubytes. Also check if converting (with free checking for * overflow) is cheaper than sending floats directly. * * \todo * When intializing texture coordinates, it might be faster to just copy the * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that * some of the data (i.e., the last texture coordinate components) get copied * over, but that still may be faster than the conditional branching. If * nothing else, the code will be smaller and easier to follow. */ static GLboolean check_vtx_fmt( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint ind0 = R200_VTX_Z0; GLuint ind1 = 0; GLuint i; GLuint count[R200_MAX_TEXTURE_UNITS]; if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag) return GL_FALSE; if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); /* Make all this event-driven: */ if (ctx->Light.Enabled) { ind0 |= R200_VTX_N0; if (ctx->Light.ColorMaterialEnabled) ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; else ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; } else { /* TODO: make this data driven? */ ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; } } if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { ind0 |= R200_VTX_DISCRETE_FOG; } for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { count[i] = 0; if (ctx->Texture.Unit[i]._ReallyEnabled) { if (rmesa->TexGenNeedNormals[i]) { ind0 |= R200_VTX_N0; } else { switch( ctx->Texture.Unit[i]._ReallyEnabled ) { case TEXTURE_CUBE_BIT: case TEXTURE_3D_BIT: count[i] = 3; break; case TEXTURE_2D_BIT: case TEXTURE_RECT_BIT: count[i] = 2; break; case TEXTURE_1D_BIT: count[i] = 1; break; } ind1 |= count[i] << (3 * i); } } } if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 ); R200_NEWPRIM(rmesa); rmesa->vb.vtxfmt_0 = ind0; rmesa->vb.vtxfmt_1 = ind1; rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; rmesa->vb.vertex_size = 3; rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; rmesa->vb.colorptr = NULL; rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; rmesa->vb.fogptr = ctx->Current.Attrib[VERT_ATTRIB_FOG]; rmesa->vb.specptr = NULL; rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX3]; rmesa->vb.texcoordptr[4] = ctx->Current.Attrib[VERT_ATTRIB_TEX4]; rmesa->vb.texcoordptr[5] = ctx->Current.Attrib[VERT_ATTRIB_TEX5]; rmesa->vb.texcoordptr[6] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ rmesa->vb.texcoordptr[7] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ /* Run through and initialize the vertex components in the order * the hardware understands: */ if (ind0 & R200_VTX_N0) { rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 3; rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; } if (ind0 & R200_VTX_DISCRETE_FOG) { rmesa->vb.fogptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 1; rmesa->vb.fogptr[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; } if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; rmesa->vb.vertex_size += 1; UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 4; rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 3; rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; } if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; rmesa->vb.vertex_size += 1; UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); } for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { if ( count[i] != 0 ) { float * const attr = ctx->Current.Attrib[VERT_ATTRIB_TEX0+i]; unsigned j; rmesa->vb.texcoordptr[i] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; for ( j = 0 ; j < count[i] ; j++ ) { rmesa->vb.texcoordptr[i][j] = attr[j]; } rmesa->vb.vertex_size += count[i]; } } if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) { if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "reinstall on vertex_format change\n"); _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); rmesa->vb.installed_vertex_format = rmesa->vb.vtxfmt_0; } if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s -- success\n", __FUNCTION__); return GL_TRUE; }