/** * \todo * An interesting optimization of this function would be to have 3 element * table with the dispatch offsets of the TexCoord?fv functions, use count * to look-up the table, and a specialized version of GL_CALL that used the * offset number instead of the name. */ static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f ) { switch( count ) { case 3: CALL_MultiTexCoord3fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); break; case 2: CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); break; case 1: CALL_MultiTexCoord1fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); break; default: assert( count == 0 ); break; } }
static void VFMT_FALLBACK( const char *caller ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE]; GLuint i, prim; GLuint ind = rmesa->vb.vertex_format; GLuint nrverts; GLfloat alpha = 1.0; GLuint unit; if (RADEON_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 = radeonFlushVertices; 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 (ind & RADEON_CP_VC_FRMT_N0) { CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); offset += 3; } if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { radeon_color_t *col = (radeon_color_t *)&tmp[i][offset]; CALL_Color4ub(GET_DISPATCH(), (col->red, col->green, col->blue, col->alpha)); offset++; } else if (ind & RADEON_CP_VC_FRMT_FPALPHA) { CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); offset+=4; } else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); offset+=3; } if (ind & RADEON_CP_VC_FRMT_PKSPEC) { radeon_color_t *spec = (radeon_color_t *)&tmp[i][offset]; CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (spec->red, spec->green, spec->blue)); offset++; } for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { if (ind & RADEON_ST_BIT(unit)) { CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), &tmp[i][offset])); offset += 2; } } CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); } /* Replay current vertex */ if (ind & RADEON_CP_VC_FRMT_N0) CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); if (ind & RADEON_CP_VC_FRMT_PKCOLOR) CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, rmesa->vb.colorptr->green, rmesa->vb.colorptr->blue, rmesa->vb.colorptr->alpha)); else if (ind & RADEON_CP_VC_FRMT_FPALPHA) CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { 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 (ind & RADEON_CP_VC_FRMT_PKSPEC) CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, rmesa->vb.specptr->green, rmesa->vb.specptr->blue)); for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { if (ind & RADEON_ST_BIT(unit)) { CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), rmesa->vb.texcoordptr[unit])); } } }