📄 r200_vtxfmt.c
字号:
*/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; }}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] ); }}static void wrap_buffer( void ){ GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; GLuint i, nrverts; if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); /* Don't deal with parity. */ if ((((rmesa->vb.initial_counter - rmesa->vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { rmesa->vb.counter++; rmesa->vb.initial_counter++; return; } /* Copy vertices out of dma: */ if (rmesa->vb.prim[0] == GL_POLYGON+1) nrverts = 0; else { nrverts = copy_dma_verts( rmesa, tmp ); if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%d vertices to copy\n", nrverts); /* Finish the prim at this point: */ note_last_prim( rmesa, 0 ); } /* Fire any buffered primitives */ flush_prims( rmesa ); /* Get new buffer */ r200RefillCurrentDmaRegion( rmesa ); /* Reset counter, dmaptr */ rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); 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; /* Restart wrapped primitive: */ if (rmesa->vb.prim[0] != GL_POLYGON+1) start_prim( rmesa, rmesa->vb.prim[0] ); /* Reemit saved vertices */ for (i = 0 ; i < nrverts; i++) { if (R200_DEBUG & DEBUG_VERTS) { int j; fprintf(stderr, "re-emit vertex %d to %p\n", i, (void *)rmesa->vb.dmaptr); if (R200_DEBUG & DEBUG_VERBOSE) for (j = 0 ; j < rmesa->vb.vertex_size; j++) fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); } memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 ); rmesa->vb.dmaptr += rmesa->vb.vertex_size; rmesa->vb.counter--; }}/** * 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 || (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))) 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__);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -