diff options
-rw-r--r-- | src/mesa/tnl/t_vtx_api.c | 425 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_exec.c | 4 | ||||
-rw-r--r-- | src/mesa/tnl/t_vtx_x86.c | 312 |
3 files changed, 425 insertions, 316 deletions
diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c index 8ae0569584a..b957f336691 100644 --- a/src/mesa/tnl/t_vtx_api.c +++ b/src/mesa/tnl/t_vtx_api.c @@ -44,36 +44,39 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* MultiTexcoord ends up with both of these branches, unfortunately - * (it may its own version of the macro after size-tracking is working). + * (it may get its own version of the macro after size-tracking is + * working). + * + * Errors (VertexAttribNV when ATTR>15) are handled at a higher level. */ -#define ATTRF( ATTR, N, A, B, C, D ) \ -{ \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if (((ATTR) & 0xf) == 0) { \ - int i; \ - \ - if (N>0) tnl->dmaptr[0].f = A; \ - if (N>1) tnl->dmaptr[1].f = B; \ - if (N>2) tnl->dmaptr[2].f = C; \ - if (N>3) tnl->dmaptr[3].f = D; \ - \ - for (i = N; i < tnl->vertex_size; i++) \ - *tnl->dmaptr[i].i = tnl->vertex[i].i; \ - \ - tnl->dmaptr += tnl->vertex_size; \ - \ - if (--tnl->counter == 0) \ - tnl->notify(); \ - } \ - else { \ - GLfloat *dest = tnl->attrptr[(ATTR) & 0xf]; \ - if (N>0) dest[0] = A; \ - if (N>1) dest[1] = B; \ - if (N>2) dest[2] = C; \ - if (N>3) dest[3] = D; \ - } \ +#define ATTRF( ATTR, N, A, B, C, D ) \ +{ \ + GET_CURRENT_CONTEXT( ctx ); \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + \ + if ((ATTR) == 0) { \ + int i; \ + \ + if (N>0) tnl->vbptr[0].f = A; \ + if (N>1) tnl->vbptr[1].f = B; \ + if (N>2) tnl->vbptr[2].f = C; \ + if (N>3) tnl->vbptr[3].f = D; \ + \ + for (i = N; i < tnl->vertex_size; i++) \ + *tnl->vbptr[i].i = tnl->vertex[i].i; \ + \ + tnl->vbptr += tnl->vertex_size; \ + \ + if (--tnl->counter == 0) \ + tnl->notify(); \ + } \ + else { \ + GLfloat *dest = tnl->attrptr[ATTR]; \ + if (N>0) dest[0] = A; \ + if (N>1) dest[1] = B; \ + if (N>2) dest[2] = C; \ + if (N>3) dest[3] = D; \ + } \ } #define ATTR4F( ATTR, A, B, C, D ) ATTRF( ATTR, 4, A, B, C, D ) @@ -266,176 +269,319 @@ static void tnl_TexCoord4fv( const GLfloat *v ) } -/* MultiTexcoord +/* Miscellaneous: + * + * These don't alias NV attributes, but still need similar treatment. + * Basically these are attributes with numbers greater than 16. */ -static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s ) +static void tnl_EdgeFlag( GLboolean flag ) +{ + GLfloat f = flag ? 1 : 0; + ATTR1F( VERT_ATTRIB_EDGEFLAG, f); +} + +static void tnl_EdgeFlagv( const GLboolean *flag ) +{ + GLfloat f = flag[0] ? 1 : 0; + ATTR1F( VERT_ATTRIB_EDGEFLAG, f); +} + +static void tnl_Indexi( GLint idx ) +{ + ATTR1F( VERT_ATTRIB_INDEX, idx ); +} + +static void tnl_Indexiv( const GLint *idx ) +{ + ATTR1F( VERT_ATTRIB_INDEX, idx ); +} + +/* Use dispatch switching to build 'ranges' of eval vertices for each + * type, avoiding need for flags. (Make + * evalcoords/evalpoints/vertices/attr0 mutually exclusive) + */ +static void _tnl_EvalCoord1f( GLfloat u ) +{ + ATTR1F( VERT_ATTRIB_POS, u ); +} + +static void _tnl_EvalCoord1fv( const GLfloat *v ) +{ + ATTR1F( VERT_ATTRIB_POS, v[0] ); +} + +static void _tnl_EvalCoord2f( GLfloat u, GLfloat v ) +{ + ATTR2F( VERT_ATTRIB_POS, u, v ); +} + +static void _tnl_EvalCoord2fv( const GLfloat *v ) +{ + ATTR2F( VERT_ATTRIB_POS, v[0], v[1] ); +} + + + +/* Second level dispatch table for MultiTexCoord, Material and + * VertexAttribNV. + * + * Need this because we want to track things like vertex attribute + * sizes, presence/otherwise of attribs in recorded vertices, etc, by + * manipulating the state of dispatch tables. Need therefore a + * dispatch slot for each value of 'index' or 'unit' in VertexAttribNV + * and MultiTexCoordARB. Also need a mechnism for keeping this data + * consistent with what's coming in via the Vertex/Normal/etc api + * above (where aliasing exists with the traditional entrypoints). + * Note that MultiTexCoordARB aliases with TexCoord when unit==0. + * + * Need presence tracking for material components, too, but not size + * tracking or help with aliasing. Could move material to seperate + * dispatch without the "*4" below, or even do the checks every time. + */ +struct attr_dispatch_tab { + void (*tab[32*4])( void ); + void (*swapped[32*4])( void ); + int swapcount; + int installed_sizes[32]; +}; + +#define DISPATCH_ATTR1F( ATTR, N, ) + tnl->vb.attr_dispatch + +/* Result at the back end after second dispatch -- could further + * specialize for attr zero -- maybe just in the codegen version. + */ +static void tnl_Attr1f( GLint attr, GLfloat s ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR1F( attr, s ); } -static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) +static void tnl_Attr1fv( GLint attr, const GLfloat *v ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR1F( attr, v[0] ); } -static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) +static void tnl_Attr2f( GLint attr, GLfloat s, GLfloat t ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR2F( attr, s, t ); } -static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) +static void tnl_Attr2fv( GLint attr, const GLfloat *v ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR2F( attr, v[0], v[1] ); } -static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t, - GLfloat r) +static void tnl_Attr3f( GLint attr, GLfloat s, GLfloat t, GLfloat r ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR3F( attr, s, t, r ); } -static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v ) +static void tnl_Attr3fv( GLint attr, const GLfloat *v ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR3F( attr, v[0], v[1], v[2] ); } -static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t, - GLfloat r, GLfloat q ) +static void tnl_Attr4f( GLint attr, GLfloat s, GLfloat t, GLfloat r, GLfloat q ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR4F( attr, s, t, r, q ); } -static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v ) +static void tnl_Attr4fv( GLint attr, const GLfloat *v ) { - GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; ATTR4F( attr, v[0], v[1], v[2], v[3] ); } -/* NV_vertex_program: - * - * *** Need second dispatch layer above this for size tracking. One - * *** dispatch layer handles both VertexAttribute and MultiTexCoord +/* MultiTexcoord: Send through second level dispatch. */ -static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s ) +static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s ) { - ATTR1F( index, s ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR1F( attr, s ); } -static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) +static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) { - ATTR1F( index, v[0] ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR1F( attr, v[0] ); } -static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t ) +static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) { - ATTR2F( index, s, t ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR2F( attr, s, t ); } -static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) +static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) { - ATTR2F( index, v[0], v[1] ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR2F( attr, v[0], v[1] ); } -static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t, - GLfloat r ) +static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t, + GLfloat r) { - ATTR3F( index, s, t, r ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR3F( attr, s, t, r ); } -static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) +static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v ) { - ATTR3F( index, v[0], v[1], v[2] ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR3F( attr, v[0], v[1], v[2] ); } -static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t, - GLfloat r, GLfloat q ) +static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t, + GLfloat r, GLfloat q ) { - ATTR4F( index, s, t, r, q ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR4F( attr, s, t, r, q ); } -static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) +static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v ) { - ATTR4F( index, v[0], v[1], v[2], v[3] ); + GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0; + if (attr < MAX_VERT_ATTRS) + DISPATCH_ATTR4F( attr, v[0], v[1], v[2], v[3] ); } -/* Miscellaneous: (These don't alias NV attributes, right?) +/* NV_vertex_program: + * + * Check for errors & reroute through second dispatch layer to get + * size tracking per-attribute. */ -static void tnl_EdgeFlag( GLboolean flag ) +static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s ) { - GET_TNL; - tnl->edgeflagptr[0] = flag; + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR1F( index, s ); + else + DISPATCH_ERROR; } -static void tnl_EdgeFlagv( const GLboolean *flag ) +static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) { - GET_TNL; - tnl->edgeflagptr[0] = *flag; + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR1F( index, v[0] ); + else + DISPATCH_ERROR; } -static void tnl_Indexi( GLint idx ) +static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t ) { - GET_TNL; - tnl->indexptr[0] = idx; + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR2F( index, s, t ); + else + DISPATCH_ERROR; } -static void tnl_Indexiv( const GLint *idx ) +static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) { - GET_TNL; - tnl->indexptr[0] = *idx; + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR2F( index, v[0], v[1] ); + else + DISPATCH_ERROR; } - - -/* Could use dispatch switching to build 'ranges' of eval vertices for - * each type, avoiding need for flags. (Make - * evalcoords/evalpoints/vertices/attr0 mutually exclusive) - * --> In which case, may as well use Vertex{12}f{v} here. - */ -static void _tnl_EvalCoord1f( GLfloat u ) +static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t, + GLfloat r ) { - ATTR1F( VERT_ATTRIB_POS, u ); + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR3F( index, s, t, r ); + else + DISPATCH_ERROR; } -static void _tnl_EvalCoord1fv( const GLfloat *v ) +static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) { - ATTR1F( VERT_ATTRIB_POS, v[0] ); + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR3F( index, v[0], v[1], v[2] ); + else + DISPATCH_ERROR; } -static void _tnl_EvalCoord2f( GLfloat u, GLfloat v ) +static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t, + GLfloat r, GLfloat q ) { - ATTR2F( VERT_ATTRIB_POS, u, v ); + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR4F( index, s, t, r, q ); + else + DISPATCH_ERROR; } -static void _tnl_EvalCoord2fv( const GLfloat *v ) +static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) { - ATTR2F( VERT_ATTRIB_POS, v[0], v[1] ); + if (index < MAX_VERT_ATTRS) + DISPATCH_ATTR4F( index, v[0], v[1], v[2], v[3] ); + else + DISPATCH_ERROR; } + + + + + /* Materials: - * *** Treat as more vertex attributes + * + * These are treated as per-vertex attributes, at indices above where + * the NV_vertex_program leaves off. There are a lot of good things + * about treating materials this way. + * + * *** Need a dispatch step (like VertexAttribute GLint attr, and MultiTexCoord) + * *** to expand vertex size, etc. Use the same second level dispatch + * *** (keyed by attr number) as above. + */ +#define MAT( ATTR, face, params ) \ +do { \ + if (face != GL_BACK) \ + DISPATCH_ATTRF( ATTR, N, params ); \ + if (face != GL_FRONT) \ + DISPATCH_ATTRF( ATTR+7, N, params ); \ +} while (0) + + +/* NOTE: Have to remove/dealwith colormaterial crossovers, probably + * later on - in the meantime just store everything. */ static void _tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) { - if (MESA_VERBOSE & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (tnl->prim[0] != GL_POLYGON+1) { - VFMT_FALLBACK( __FUNCTION__ ); - glMaterialfv( face, pname, params ); + switch (pname) { + case GL_EMISSION: + MAT( VERT_ATTRIB_FRONT_EMMISSION, 4, face, params ); + break; + case GL_AMBIENT: + MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params ); + break; + case GL_DIFFUSE: + MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params ); + break; + case GL_SPECULAR: + MAT( VERT_ATTRIB_FRONT_SPECULAR, 4, face, params ); + break; + case GL_SHININESS: + MAT( VERT_ATTRIB_FRONT_SHININESS, 1, face, params ); + break; + case GL_COLOR_INDEXES: + MAT( VERT_ATTRIB_FRONT_EMMISSION, 3, face, params ); + break; + case GL_AMBIENT_AND_DIFFUSE: + MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params ); + MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params ); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, where ); return; } - _mesa_noop_Materialfv( face, pname, params ); } @@ -455,6 +601,13 @@ static struct dynfn *lookup( struct dynfn *l, int key ) return 0; } +/* Vertex descriptor + */ +struct _tnl_vertex_descriptor { + GLuint attr_bits[4]; +}; + + /* Can't use the loopback template for this: */ #define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ @@ -560,28 +713,28 @@ void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt ) vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; - vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; + vfmt->MultiTexCoord1fARB = dd_MultiTexCoord1fARB; + vfmt->MultiTexCoord1fvARB = dd_MultiTexCoord1fvARB; + vfmt->MultiTexCoord2fARB = dd_MultiTexCoord2fARB; + vfmt->MultiTexCoord2fvARB = dd_MultiTexCoord2fvARB; + vfmt->MultiTexCoord3fARB = dd_MultiTexCoord3fARB; + vfmt->MultiTexCoord3fvARB = dd_MultiTexCoord3fvARB; + vfmt->MultiTexCoord4fARB = dd_MultiTexCoord4fARB; + vfmt->MultiTexCoord4fvARB = dd_MultiTexCoord4fvARB; vfmt->Normal3f = choose_Normal3f; vfmt->Normal3fv = choose_Normal3fv; vfmt->TexCoord1f = choose_TexCoord1f; vfmt->TexCoord1fv = choose_TexCoord1fv; vfmt->TexCoord2f = choose_TexCoord2f; vfmt->TexCoord2fv = choose_TexCoord2fv; - vfmt->Vertex2f = choose_Vertex2f; - vfmt->Vertex2fv = choose_Vertex2fv; - vfmt->Vertex3f = choose_Vertex3f; - vfmt->Vertex3fv = choose_Vertex3fv; vfmt->TexCoord3f = choose_TexCoord3f; vfmt->TexCoord3fv = choose_TexCoord3fv; vfmt->TexCoord4f = choose_TexCoord4f; vfmt->TexCoord4fv = choose_TexCoord4fv; - vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB; - vfmt->MultiTexCoord4fARB = choose_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = choose_MultiTexCoord4fvARB; + vfmt->Vertex2f = choose_Vertex2f; + vfmt->Vertex2fv = choose_Vertex2fv; + vfmt->Vertex3f = choose_Vertex3f; + vfmt->Vertex3fv = choose_Vertex3fv; vfmt->Vertex4f = choose_Vertex4f; vfmt->Vertex4fv = choose_Vertex4fv; vfmt->FogCoordfvEXT = choose_FogCoordfvEXT; @@ -594,12 +747,7 @@ void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt ) vfmt->EvalCoord1fv = choose_EvalCoord1fv; vfmt->EvalCoord2f = choose_EvalCoord2f; vfmt->EvalCoord2fv = choose_EvalCoord2fv; - vfmt->EvalMesh1 = choose_EvalMesh1; - vfmt->EvalMesh2 = choose_EvalMesh2; - vfmt->EvalPoint1 = choose_EvalPoint1; - vfmt->EvalPoint2 = choose_EvalPoint2; - - vfmt->Materialfv = _tnl_Materialfv; + vfmt->Materialfv = dd_Materialfv; } @@ -611,13 +759,8 @@ static struct dynfn *codegen_noop( struct _vb *vb, int key ) void _tnl_InitCodegen( struct dfn_generators *gen ) { - gen->Vertex2f = codegen_noop; - gen->Vertex2fv = codegen_noop; - gen->Vertex3f = codegen_noop; - gen->Vertex3fv = codegen_noop; - gen->Vertex4f = codegen_noop; - gen->Vertex4fv = codegen_noop; - + /* Generate an attribute or vertex command. + */ gen->Attr1f = codegen_noop; gen->Attr1fv = codegen_noop; gen->Attr2f = codegen_noop; @@ -626,18 +769,16 @@ void _tnl_InitCodegen( struct dfn_generators *gen ) gen->Attr3fv = codegen_noop; gen->Attr4f = codegen_noop; gen->Attr4fv = codegen_noop; + + /* Index is never zero for these... + */ gen->Attr3ub = codegen_noop; gen->Attr3ubv = codegen_noop; gen->Attr4ub = codegen_noop; gen->Attr4ubv = codegen_noop; - /* Probably need two versions of this, one for the front end - * (double dispatch), one for the back end (do the work) -- but - * will also need a second level of CHOOSE functions? - * -- Generate the dispatch layer using the existing templates somehow. - * -- Generate the backend and 2nd level choosers here. - * -- No need for a chooser on the top level. - * -- Can aliasing help -- ie can NVAttr1f == Attr1f/Vertex2f at this level (index is known) + /* As above, but deal with the extra (redundant by now) index + * argument to the generated function. */ gen->NVAttr1f = codegen_noop; gen->NVAttr1fv = codegen_noop; @@ -648,14 +789,6 @@ void _tnl_InitCodegen( struct dfn_generators *gen ) gen->NVAttr4f = codegen_noop; gen->NVAttr4fv = codegen_noop; - gen->MTAttr1f = codegen_noop; - gen->MTAttr1fv = codegen_noop; - gen->MTAttr2f = codegen_noop; - gen->MTAttr2fv = codegen_noop; - gen->MTAttr3f = codegen_noop; - gen->MTAttr3fv = codegen_noop; - gen->MTAttr4f = codegen_noop; - gen->MTAttr4fv = codegen_noop; if (!getenv("MESA_NO_CODEGEN")) { #if defined(USE_X86_ASM) diff --git a/src/mesa/tnl/t_vtx_exec.c b/src/mesa/tnl/t_vtx_exec.c index 8470d6ab35a..b9eb5bde8db 100644 --- a/src/mesa/tnl/t_vtx_exec.c +++ b/src/mesa/tnl/t_vtx_exec.c @@ -184,10 +184,6 @@ static void copy_vertex( TNLcontext *tnl, GLuint n, GLfloat *dst ) } } -/* NOTE: This actually reads the copied vertices back from uncached - * memory. Could also use the counter/notify mechanism to populate - * tmp on the fly as vertices are generated. - */ static GLuint copy_wrapped_verts( TNLcontext *tnl, GLfloat (*tmp)[15] ) { GLuint ovf, i; diff --git a/src/mesa/tnl/t_vtx_x86.c b/src/mesa/tnl/t_vtx_x86.c index 4713a325bf2..05cad629023 100644 --- a/src/mesa/tnl/t_vtx_x86.c +++ b/src/mesa/tnl/t_vtx_x86.c @@ -40,6 +40,61 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(USE_X86_ASM) + +struct dynfn *tnl_makeX86Vertex2f( TNLcontext *tnl, int key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + switch (tnl->vertex_size) { + default: { + /* Repz convenient as it's possible to emit code for any size + * vertex with little tweaking. Might as well read vertsize + * though, and have only one of these. + */ + static char temp[] = { + 0x57, /* push %edi */ + 0x56, /* push %esi */ + 0xbe, 0, 0, 0, 0, /* mov $VERTEX+2,%esi */ + 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */ + 0x8b, 0x44, 0x24, 0x0c, /* mov 0x0c(%esp,1),%eax */ + 0x8b, 0x54, 0x24, 0x10, /* mov 0x10(%esp,1),%edx */ + 0x89, 0x07, /* mov %eax,(%edi) */ + 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */ + 0x83, 0xc7, 0x08, /* add $0x8,%edi */ + 0xb9, 0, 0, 0, 0, /* mov $VERTSIZE-2,%ecx */ + 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/ + 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */ + 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */ + 0x48, /* dec %eax */ + 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */ + 0x5e, /* pop %esi */ + 0x5f, /* pop %edi */ + 0x74, 0x01, /* je +1 */ + 0xc3, /* ret */ + 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */ + }; + + dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[2]); + FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr); + FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-2); + FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter); + FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr); + FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter); + FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify); + break; + } + } + + insert_at_head( &tnl->dfn_cache.Vertex3f, dfn ); + dfn->key = key; + return dfn; +} + /* Build specialized versions of the immediate calls on the fly for * the current state. Generic x86 versions. */ @@ -317,7 +372,7 @@ struct dynfn *tnl_makeX86Vertex3fv( TNLcontext *tnl, int key ) } -struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key ) +struct dynfn *tnl_makeX86Attr4fv( TNLcontext *tnl, int key ) { static char temp[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ @@ -328,6 +383,8 @@ struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key ) 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */ 0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */ 0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */ + 0x8b, 0x48, 0x0a, /* mov 0xa(%eax),%ecx */ + 0x89, 0x4a, 0x0a, /* mov %ecx,0xa(%edx) */ 0xc3, /* ret */ }; @@ -344,7 +401,7 @@ struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key ) return dfn; } -struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key ) +struct dynfn *tnl_makeX86Attr4f( TNLcontext *tnl, int key ) { static char temp[] = { 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ @@ -354,6 +411,8 @@ struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key ) 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */ 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */ + 0x8b, 0x44, 0x24, 0x10, /* mov 0x10(%esp,1),%eax */ + 0x89, 0x42, 0x0a, /* mov %eax,0xa(%edx) */ 0xc3, /* ret */ }; @@ -370,7 +429,61 @@ struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key ) return dfn; } -struct dynfn *tnl_makeX86Color4ubv( TNLcontext *tnl, int key ) + +struct dynfn *tnl_makeX86Attr3fv( TNLcontext *tnl, int key ) +{ + static char temp[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0xba, 0, 0, 0, 0, /* mov $DEST,%edx */ + 0x8b, 0x08, /* mov (%eax),%ecx */ + 0x89, 0x0a, /* mov %ecx,(%edx) */ + 0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */ + 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */ + 0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */ + 0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */ + 0xc3, /* ret */ + }; + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (TNL_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + insert_at_head( &tnl->dfn_cache.Normal3fv, dfn ); + dfn->key = key; + dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr); + return dfn; +} + +struct dynfn *tnl_makeX86Attr3f( TNLcontext *tnl, int key ) +{ + static char temp[] = { + 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x89, 0x02, /* mov %eax,(%edx) */ + 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */ + 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ + 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */ + 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */ + 0xc3, /* ret */ + }; + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (TNL_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + insert_at_head( &tnl->dfn_cache.Normal3f, dfn ); + dfn->key = key; + dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr); + return dfn; +} + +struct dynfn *tnl_makeX86Attr4ubv( TNLcontext *tnl, int key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); insert_at_head( &tnl->dfn_cache.Color4ubv, dfn ); @@ -431,7 +544,7 @@ struct dynfn *tnl_makeX86Color4ubv( TNLcontext *tnl, int key ) } } -struct dynfn *tnl_makeX86Color4ub( TNLcontext *tnl, int key ) +struct dynfn *tnl_makeX86Attr4ub( TNLcontext *tnl, int key ) { if (TNL_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); @@ -469,72 +582,8 @@ struct dynfn *tnl_makeX86Color4ub( TNLcontext *tnl, int key ) } -struct dynfn *tnl_makeX86Color3fv( TNLcontext *tnl, int key ) -{ - if (key & (TNL_CP_VC_FRMT_PKCOLOR|TNL_CP_VC_FRMT_FPALPHA)) - return 0; - else - { - static char temp[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0xba, 0, 0, 0, 0, /* mov $DEST,%edx */ - 0x8b, 0x08, /* mov (%eax),%ecx */ - 0x89, 0x0a, /* mov %ecx,(%edx) */ - 0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */ - 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */ - 0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */ - 0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */ - 0xc3, /* ret */ - }; - - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - if (TNL_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - insert_at_head( &tnl->dfn_cache.Color3fv, dfn ); - dfn->key = key; - dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); - memcpy (dfn->code, temp, sizeof(temp)); - FIXUP(dfn->code, 5, 0x0, (int)tnl->floatcolorptr); - return dfn; - } -} - -struct dynfn *tnl_makeX86Color3f( TNLcontext *tnl, int key ) -{ - if (key & (TNL_CP_VC_FRMT_PKCOLOR|TNL_CP_VC_FRMT_FPALPHA)) - return 0; - else - { - static char temp[] = { - 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x89, 0x02, /* mov %eax,(%edx) */ - 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */ - 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ - 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */ - 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */ - 0xc3, /* ret */ - }; - - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (TNL_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - insert_at_head( &tnl->dfn_cache.Color3f, dfn ); - dfn->key = key; - dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); - memcpy (dfn->code, temp, sizeof(temp)); - FIXUP(dfn->code, 1, 0x12345678, (int)tnl->floatcolorptr); - return dfn; - } -} - - - -struct dynfn *tnl_makeX86TexCoord2fv( TNLcontext *tnl, int key ) +struct dynfn *tnl_makeX86Attr2fv( TNLcontext *tnl, int key ) { static char temp[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ @@ -559,7 +608,7 @@ struct dynfn *tnl_makeX86TexCoord2fv( TNLcontext *tnl, int key ) return dfn; } -struct dynfn *tnl_makeX86TexCoord2f( TNLcontext *tnl, int key ) +struct dynfn *tnl_makeX86Attr2f( TNLcontext *tnl, int key ) { static char temp[] = { 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ @@ -583,31 +632,14 @@ struct dynfn *tnl_makeX86TexCoord2f( TNLcontext *tnl, int key ) return dfn; } -struct dynfn *tnl_makeX86MultiTexCoord2fvARB( TNLcontext *tnl, int key ) + +struct dynfn *tnl_makeX86Attr1fv( TNLcontext *tnl, int key ) { static char temp[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x11, /* mov (%ecx),%edx */ - 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ - 0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */ - 0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */ - 0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */ - 0xc3, /* ret */ - }; - - static char temp2[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */ - 0x8b, 0x01, /* mov (%ecx),%eax */ - 0x89, 0x02, /* mov %eax,(%edx) */ - 0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */ - 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ + 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ + 0x8b, 0x08, /* mov (%eax),%ecx */ + 0x89, 0x0a, /* mov %ecx,(%edx) */ 0xc3, /* ret */ }; @@ -616,104 +648,52 @@ struct dynfn *tnl_makeX86MultiTexCoord2fvARB( TNLcontext *tnl, int key ) if (TNL_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - insert_at_head( &tnl->dfn_cache.MultiTexCoord2fvARB, dfn ); + insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn ); dfn->key = key; - - if ((key & (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) == - (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) { - dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); - memcpy (dfn->code, temp, sizeof(temp)); - FIXUP(dfn->code, 26, 0x0, (int)tnl->texcoordptr[0]); - FIXUP(dfn->code, 32, 0x0, (int)tnl->texcoordptr[0]+4); - } else { - dfn->code = ALIGN_MALLOC( sizeof(temp2), 16 ); - memcpy (dfn->code, temp2, sizeof(temp2)); - FIXUP(dfn->code, 19, 0x0, (int)tnl->texcoordptr); - } + dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]); return dfn; } -struct dynfn *tnl_makeX86MultiTexCoord2fARB( TNLcontext *tnl, - int key ) +struct dynfn *tnl_makeX86Attr1f( TNLcontext *tnl, int key ) { static char temp[] = { + 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ - 0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */ - 0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */ + 0x89, 0x02, /* mov %eax,(%edx) */ 0xc3, /* ret */ }; - static char temp2[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */ - 0x89, 0x10, /* mov %edx,(%eax) */ - 0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */ - 0xc3, /* ret */ - }; - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); if (TNL_DEBUG & DEBUG_CODEGEN) fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - insert_at_head( &tnl->dfn_cache.MultiTexCoord2fARB, dfn ); + insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn ); dfn->key = key; - - if ((key & (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) == - (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) { - dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); - memcpy (dfn->code, temp, sizeof(temp)); - FIXUP(dfn->code, 25, 0x0, (int)tnl->texcoordptr[0]); - FIXUP(dfn->code, 31, 0x0, (int)tnl->texcoordptr[0]+4); - } - else { - /* Note: this might get generated multiple times, even though the - * actual emitted code is the same. - */ - dfn->code = ALIGN_MALLOC( sizeof(temp2), 16 ); - memcpy (dfn->code, temp2, sizeof(temp2)); - FIXUP(dfn->code, 23, 0x0, (int)tnl->texcoordptr); - } + dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]); return dfn; } + void _tnl_InitX86Codegen( struct dfn_generators *gen ) { + gen->Attr1f = tnl_makeX86Attr1f; + gen->Attr1fv = tnl_makeX86Attr1fv; + gen->Attr2f = tnl_makeX86Attr2f; + gen->Attr2fv = tnl_makeX86Attr2fv; + gen->Attr3f = tnl_makeX86Attr3f; + gen->Attr3fv = tnl_makeX86Attr3fv; + gen->Attr4f = tnl_makeX86Attr4f; + gen->Attr4fv = tnl_makeX86Attr4fv; + gen->Attr4ub = tnl_makeX86Attr4ub; + gen->Attr4ubv = tnl_makeX86Attr4ubv; gen->Vertex3f = tnl_makeX86Vertex3f; gen->Vertex3fv = tnl_makeX86Vertex3fv; - gen->Color4ub = tnl_makeX86Color4ub; /* PKCOLOR only */ - gen->Color4ubv = tnl_makeX86Color4ubv; /* PKCOLOR only */ - gen->Normal3f = tnl_makeX86Normal3f; - gen->Normal3fv = tnl_makeX86Normal3fv; - gen->TexCoord2f = tnl_makeX86TexCoord2f; - gen->TexCoord2fv = tnl_makeX86TexCoord2fv; - gen->MultiTexCoord2fARB = tnl_makeX86MultiTexCoord2fARB; - gen->MultiTexCoord2fvARB = tnl_makeX86MultiTexCoord2fvARB; - gen->Color3f = tnl_makeX86Color3f; - gen->Color3fv = tnl_makeX86Color3fv; - - /* Not done: - */ -/* gen->Vertex2f = tnl_makeX86Vertex2f; */ -/* gen->Vertex2fv = tnl_makeX86Vertex2fv; */ -/* gen->Color3ub = tnl_makeX86Color3ub; */ -/* gen->Color3ubv = tnl_makeX86Color3ubv; */ -/* gen->Color4f = tnl_makeX86Color4f; */ -/* gen->Color4fv = tnl_makeX86Color4fv; */ -/* gen->TexCoord1f = tnl_makeX86TexCoord1f; */ -/* gen->TexCoord1fv = tnl_makeX86TexCoord1fv; */ -/* gen->MultiTexCoord1fARB = tnl_makeX86MultiTexCoord1fARB; */ -/* gen->MultiTexCoord1fvARB = tnl_makeX86MultiTexCoord1fvARB; */ } |