/* KW: If are compiling, we don't know whether eval will produce a * vertex when it is run in the future. If this is pure immediate * mode, eval is a noop if neither vertex map is enabled. * * Thus we need to have a check in the display list code or * elsewhere for eval(1,2) vertices in the case where * map(1,2)_vertex is disabled, and to purge those vertices from * the vb. */ void GLAPIENTRY _mesa_noop_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) { GET_CURRENT_CONTEXT(ctx); GLint i; GLfloat u, du; GLenum prim; switch (mode) { case GL_POINT: prim = GL_POINTS; break; case GL_LINE: prim = GL_LINE_STRIP; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); return; } /* No effect if vertex maps disabled. */ if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3 && !(ctx->VertexProgram._Enabled && ctx->Eval.Map1Attrib[VERT_ATTRIB_POS])) return; du = ctx->Eval.MapGrid1du; u = ctx->Eval.MapGrid1u1 + i1 * du; CALL_Begin(GET_DISPATCH(), (prim)); for (i=i1;i<=i2;i++,u+=du) { CALL_EvalCoord1f(GET_DISPATCH(), (u)); } CALL_End(GET_DISPATCH(), ()); }
/** * Called via glBegin. */ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) { GET_CURRENT_CONTEXT( ctx ); struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int i; if (_mesa_inside_begin_end(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin"); return; } if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) { return; } vbo_draw_method(vbo_context(ctx), DRAW_BEGIN_END); if (ctx->NewState) { _mesa_update_state( ctx ); CALL_Begin(ctx->Exec, (mode)); return; } if (!_mesa_valid_to_render(ctx, "glBegin")) { return; } /* Heuristic: attempt to isolate attributes occurring outside * begin/end pairs. */ if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) vbo_exec_FlushVertices_internal(exec, GL_FALSE); i = exec->vtx.prim_count++; exec->vtx.prim[i].mode = mode; exec->vtx.prim[i].begin = 1; exec->vtx.prim[i].end = 0; exec->vtx.prim[i].indexed = 0; exec->vtx.prim[i].weak = 0; exec->vtx.prim[i].pad = 0; exec->vtx.prim[i].start = exec->vtx.vert_count; exec->vtx.prim[i].count = 0; exec->vtx.prim[i].num_instances = 1; exec->vtx.prim[i].base_instance = 0; exec->vtx.prim[i].is_indirect = 0; ctx->Driver.CurrentExecPrimitive = mode; ctx->Exec = ctx->BeginEnd; /* We may have been called from a display list, in which case we should * leave dlist.c's dispatch table in place. */ if (ctx->CurrentDispatch == ctx->OutsideBeginEnd) { ctx->CurrentDispatch = ctx->BeginEnd; _glapi_set_dispatch(ctx->CurrentDispatch); } else { assert(ctx->CurrentDispatch == ctx->Save); } }
void GLAPIENTRY _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { GET_CURRENT_CONTEXT(ctx); GLint i; if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) return; CALL_Begin(GET_DISPATCH(), (mode)); switch (type) { case GL_UNSIGNED_BYTE: for (i = 0 ; i < count ; i++) CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); break; case GL_UNSIGNED_SHORT: for (i = 0 ; i < count ; i++) CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); break; case GL_UNSIGNED_INT: for (i = 0 ; i < count ; i++) CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); break; } CALL_End(GET_DISPATCH(), ()); }
/** * Called from glBegin. * ctx->Driver.CurrentExecPrimitive will be set to <mode>. */ static void GLAPIENTRY _tnl_Begin( GLenum mode ) { GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { /* we're not inside a glBegin/End pair */ TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; if (ctx->NewState) { _mesa_update_state( ctx ); if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin (invalid vertex/fragment program)"); tnl->DiscardPrimitive = GL_TRUE; return; } if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "glBegin(incomplete framebuffer)"); tnl->DiscardPrimitive = GL_TRUE; return; } tnl->DiscardPrimitive = GL_FALSE; if (!(tnl->Driver.NotifyBegin && tnl->Driver.NotifyBegin( ctx, mode ))) CALL_Begin(ctx->Exec, (mode)); return; } /* Heuristic: attempt to isolate attributes occuring outside * begin/end pairs. */ if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0]) _tnl_FlushVertices( ctx, ~0 ); i = tnl->vtx.prim_count++; tnl->vtx.prim[i].mode = mode | PRIM_BEGIN; tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter; tnl->vtx.prim[i].count = 0; ctx->Driver.CurrentExecPrimitive = mode; } else { /* already inside glBegin/End */ _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); } }
/** * Called via glBegin. */ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) { GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int i; if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) { return; } vbo_draw_method(vbo_context(ctx), DRAW_BEGIN_END); if (ctx->Driver.PrepareExecBegin) ctx->Driver.PrepareExecBegin(ctx); if (ctx->NewState) { _mesa_update_state( ctx ); CALL_Begin(ctx->Exec, (mode)); return; } if (!_mesa_valid_to_render(ctx, "glBegin")) { return; } /* Heuristic: attempt to isolate attributes occuring outside * begin/end pairs. */ if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) vbo_exec_FlushVertices_internal(exec, GL_FALSE); i = exec->vtx.prim_count++; exec->vtx.prim[i].mode = mode; exec->vtx.prim[i].begin = 1; exec->vtx.prim[i].end = 0; exec->vtx.prim[i].indexed = 0; exec->vtx.prim[i].weak = 0; exec->vtx.prim[i].pad = 0; exec->vtx.prim[i].start = exec->vtx.vert_count; exec->vtx.prim[i].count = 0; exec->vtx.prim[i].num_instances = 1; exec->vtx.prim[i].base_instance = 0; ctx->Driver.CurrentExecPrimitive = mode; } else _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); }
/* Some very basic support for arrays. Drivers without explicit array * support can hook these in, but still need to supply an array-elt * implementation. */ void GLAPIENTRY _mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count) { GET_CURRENT_CONTEXT(ctx); GLint i; if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) return; CALL_Begin(GET_DISPATCH(), (mode)); for (i = 0; i < count; i++) CALL_ArrayElement(GET_DISPATCH(), (start + i)); CALL_End(GET_DISPATCH(), ()); }
/** * Execute a glRectf() function. */ static void GLAPIENTRY vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); CALL_Begin(GET_DISPATCH(), (GL_QUADS)); CALL_Vertex2f(GET_DISPATCH(), (x1, y1)); CALL_Vertex2f(GET_DISPATCH(), (x2, y1)); CALL_Vertex2f(GET_DISPATCH(), (x2, y2)); CALL_Vertex2f(GET_DISPATCH(), (x1, y2)); CALL_End(GET_DISPATCH(), ()); }
/* Build a list of primitives on the fly. Keep * ctx->Driver.CurrentExecPrimitive uptodate as well. */ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) { GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int i; if (ctx->NewState) { _mesa_update_state( ctx ); CALL_Begin(ctx->Exec, (mode)); return; } if (!vbo_validate_shaders(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin (invalid vertex/fragment program)"); return; } /* Heuristic: attempt to isolate attributes occuring outside * begin/end pairs. */ if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) vbo_exec_FlushVertices_internal( ctx, GL_FALSE ); i = exec->vtx.prim_count++; exec->vtx.prim[i].mode = mode; exec->vtx.prim[i].begin = 1; exec->vtx.prim[i].end = 0; exec->vtx.prim[i].indexed = 0; exec->vtx.prim[i].weak = 0; exec->vtx.prim[i].pad = 0; exec->vtx.prim[i].start = exec->vtx.vert_count; exec->vtx.prim[i].count = 0; ctx->Driver.CurrentExecPrimitive = mode; } else _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); }
static void GLAPIENTRY vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2) { GET_CURRENT_CONTEXT(ctx); GLint i; GLfloat u, du; GLenum prim; ASSERT_OUTSIDE_BEGIN_END(ctx); switch (mode) { case GL_POINT: prim = GL_POINTS; break; case GL_LINE: prim = GL_LINE_STRIP; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); return; } /* No effect if vertex maps disabled. */ if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) return; du = ctx->Eval.MapGrid1du; u = ctx->Eval.MapGrid1u1 + i1 * du; CALL_Begin(GET_DISPATCH(), (prim)); for (i=i1;i<=i2;i++,u+=du) { CALL_EvalCoord1f(GET_DISPATCH(), (u)); } CALL_End(GET_DISPATCH(), ()); }
void GLAPIENTRY _mesa_noop_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) { GET_CURRENT_CONTEXT(ctx); GLfloat u, du, v, dv, v1, u1; GLint i, j; switch (mode) { case GL_POINT: case GL_LINE: case GL_FILL: break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" ); return; } /* No effect if vertex maps disabled. */ if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3 && !(ctx->VertexProgram._Enabled && ctx->Eval.Map2Attrib[VERT_ATTRIB_POS])) return; du = ctx->Eval.MapGrid2du; dv = ctx->Eval.MapGrid2dv; v1 = ctx->Eval.MapGrid2v1 + j1 * dv; u1 = ctx->Eval.MapGrid2u1 + i1 * du; switch (mode) { case GL_POINT: CALL_Begin(GET_DISPATCH(), (GL_POINTS)); for (v=v1,j=j1;j<=j2;j++,v+=dv) { for (u=u1,i=i1;i<=i2;i++,u+=du) { CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); } } CALL_End(GET_DISPATCH(), ()); break; case GL_LINE: for (v=v1,j=j1;j<=j2;j++,v+=dv) { CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); for (u=u1,i=i1;i<=i2;i++,u+=du) { CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); } CALL_End(GET_DISPATCH(), ()); } for (u=u1,i=i1;i<=i2;i++,u+=du) { CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); for (v=v1,j=j1;j<=j2;j++,v+=dv) { CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); } CALL_End(GET_DISPATCH(), ()); } break; case GL_FILL: for (v=v1,j=j1;j<j2;j++,v+=dv) { CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP)); for (u=u1,i=i1;i<=i2;i++,u+=du) { CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); CALL_EvalCoord2f(GET_DISPATCH(), (u, v+dv)); } CALL_End(GET_DISPATCH(), ()); } break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" ); return; } }
/* Begin/End */ static void radeon_Begin( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if (RADEON_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) radeonValidateState( ctx ); if (rmesa->vb.recheck) radeonVtxfmtValidate( ctx ); if (!rmesa->vb.installed) { CALL_Begin(GET_DISPATCH(), (mode)); return; } if (rmesa->dma.flush && rmesa->vb.counter < 12) { if (RADEON_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) { /* FIXME: what are these constants? */ if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > rmesa->dma.current.end) { RADEON_NEWPRIM( rmesa ); radeonRefillCurrentDmaRegion( 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 ); }
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])); } } }
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] ); } }