struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); FIXUP(dfn->code, 5, 0x12345678, (int)vb.colorptr); return dfn; } else { DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); FIXUP(dfn->code, 27, 0xdeadbeaf, (int)vb.floatcolorptr); FIXUP(dfn->code, 33, 0xdeadbeaf, (int)vb.floatcolorptr+4); FIXUP(dfn->code, 55, 0xdeadbeaf, (int)vb.floatcolorptr+8); FIXUP(dfn->code, 61, 0xdeadbeaf, (int)vb.floatcolorptr+12); return dfn; } }
struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) { if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) return 0; else { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f ); FIXUP(dfn->code, 1, 0x12345678, (int)vb.floatcolorptr); return dfn; } }
struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key ) { if (R200_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); FIXUP(dfn->code, 18, 0x0, (int)vb.colorptr); FIXUP(dfn->code, 24, 0x0, (int)vb.colorptr+1); FIXUP(dfn->code, 30, 0x0, (int)vb.colorptr+2); FIXUP(dfn->code, 36, 0x0, (int)vb.colorptr+3); return dfn; } else return 0; }
/** * 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; }
void VFMT_FALLBACK( const char *caller ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; GLuint i, prim; GLuint ind0 = rmesa->vb.vtxfmt_0; GLuint ind1 = rmesa->vb.vtxfmt_1; GLuint nrverts; GLfloat alpha = 1.0; GLuint count; GLuint unit; if (R200_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); if (rmesa->vb.prim[0] == GL_POLYGON+1) { VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); return; } /* Copy vertices out of dma: */ nrverts = copy_dma_verts( rmesa, tmp ); /* Finish the prim at this point: */ note_last_prim( rmesa, 0 ); flush_prims( rmesa ); /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. */ prim = rmesa->vb.prim[0]; ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; _tnl_wakeup_exec( ctx ); ctx->Driver.FlushVertices = r200FlushVertices; assert(rmesa->dma.flush == 0); rmesa->vb.fell_back = GL_TRUE; rmesa->vb.installed = GL_FALSE; CALL_Begin(GET_DISPATCH(), (prim)); if (rmesa->vb.installed_color_3f_sz == 4) alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; /* Replay saved vertices */ for (i = 0 ; i < nrverts; i++) { GLuint offset = 3; if (ind0 & R200_VTX_N0) { CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); offset += 3; } if (ind0 & R200_VTX_DISCRETE_FOG) { CALL_FogCoordfvEXT(GET_DISPATCH(), (&tmp[i][offset])); offset++; } if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { CALL_Color4ubv(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); offset++; } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); offset+=4; } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); offset+=3; } if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { CALL_SecondaryColor3ubvEXT(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); offset++; } for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { count = VTX_TEXn_COUNT( ind1, unit ); dispatch_multitexcoord( count, unit, &tmp[i][offset] ); offset += count; } CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); } /* Replay current vertex */ if (ind0 & R200_VTX_N0) CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); if (ind0 & R200_VTX_DISCRETE_FOG) { CALL_FogCoordfvEXT(GET_DISPATCH(), (rmesa->vb.fogptr)); } if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, rmesa->vb.colorptr->green, rmesa->vb.colorptr->blue, rmesa->vb.colorptr->alpha)); } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) { CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0], rmesa->vb.floatcolorptr[1], rmesa->vb.floatcolorptr[2], alpha)); } else { CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); } } if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, rmesa->vb.specptr->green, rmesa->vb.specptr->blue)); for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { count = VTX_TEXn_COUNT( ind1, unit ); dispatch_multitexcoord( count, unit, rmesa->vb.texcoordptr[unit] ); } }
void r200_copy_to_current( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); unsigned i; if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s\n", __FUNCTION__); assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); if (rmesa->vb.vtxfmt_0 & R200_VTX_N0) { ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0]; ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1]; ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2]; } if (rmesa->vb.vtxfmt_0 & R200_VTX_DISCRETE_FOG) { ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = rmesa->vb.fogptr[0]; } switch( VTX_COLOR(rmesa->vb.vtxfmt_0, 0) ) { case R200_VTX_PK_RGBA: ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red ); ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green ); ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue ); ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha ); break; case R200_VTX_FP_RGB: ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; break; case R200_VTX_FP_RGBA: ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3]; break; default: break; } if (VTX_COLOR(rmesa->vb.vtxfmt_0, 1) == R200_VTX_PK_RGBA) { ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red ); ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green ); ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue ); } for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { const unsigned count = VTX_TEXn_COUNT( rmesa->vb.vtxfmt_1, i ); GLfloat * const src = rmesa->vb.texcoordptr[i]; if ( count != 0 ) { switch( count ) { case 3: ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = src[2]; break; case 2: ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; break; case 1: ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = 0.0F; ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; break; } ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][0] = src[0]; ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][3] = 1.0F; } } ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; }