X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Ftnl%2Ft_vtx_api.c;h=fa9e04ad336f52c38e994abff940248f477b87ee;hb=dfb6c56ed85d7b11b6e7e9b0a5ec7eddb1162510;hp=f47114cf6239149d80252a8367a5236330b722db;hpb=77865f81c9ce422b6f23bb105c632c2c6fb9bd67;p=mesa.git diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c index f47114cf623..fa9e04ad336 100644 --- a/src/mesa/tnl/t_vtx_api.c +++ b/src/mesa/tnl/t_vtx_api.c @@ -43,10 +43,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "t_vtx_api.h" #include "simple_list.h" +#include "dispatch.h" + static void reset_attrfv( TNLcontext *tnl ); -static attrfv_func choose[_TNL_MAX_ATTR_CODEGEN+1][4]; /* +1 for ERROR_ATTRIB */ -static attrfv_func generic_attr_func[_TNL_MAX_ATTR_CODEGEN][4]; +static tnl_attrfv_func choose[_TNL_MAX_ATTR_CODEGEN+1][4]; /* +1 for ERROR_ATTRIB */ +static tnl_attrfv_func generic_attr_func[_TNL_MAX_ATTR_CODEGEN][4]; /* Close off the last primitive, execute the buffer, restart the @@ -64,7 +66,7 @@ static void _tnl_wrap_buffers( GLcontext *ctx ) } else { GLuint last_prim = tnl->vtx.prim[tnl->vtx.prim_count-1].mode; - GLuint last_count = tnl->vtx.prim[tnl->vtx.prim_count-1].count; + GLuint last_count; if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { GLint i = tnl->vtx.prim_count - 1; @@ -74,6 +76,8 @@ static void _tnl_wrap_buffers( GLcontext *ctx ) tnl->vtx.prim[i].start); } + last_count = tnl->vtx.prim[tnl->vtx.prim_count-1].count; + /* Execute the buffer and save copied vertices. */ if (tnl->vtx.counter != tnl->vtx.initial_counter) @@ -102,8 +106,10 @@ static void _tnl_wrap_buffers( GLcontext *ctx ) /* Deal with buffer wrapping where provoked by the vertex buffer * filling up, as opposed to upgrade_vertex(). + * + * Make it GLAPIENTRY, so we can tail from the codegen'ed Vertex*fv */ -void _tnl_wrap_filled_vertex( GLcontext *ctx ) +void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLfloat *data = tnl->vtx.copied.buffer; @@ -138,23 +144,30 @@ static void _tnl_copy_to_current( GLcontext *ctx ) TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) + for (i = _TNL_ATTRIB_POS+1 ; i < _TNL_ATTRIB_INDEX ; i++) { if (tnl->vtx.attrsz[i]) { /* Note: the tnl->vtx.current[i] pointers points to * the ctx->Current fields. The first 16 or so, anyway. */ - ASSIGN_4V( tnl->vtx.current[i], 0, 0, 0, 1 ); - COPY_SZ_4V(tnl->vtx.current[i], + COPY_CLEAN_4V(tnl->vtx.current[i], tnl->vtx.attrsz[i], tnl->vtx.attrptr[i]); } + } - /* Edgeflag requires special treatment: + /* color index is special (it's not a float[4] so COPY_CLEAN_4V above + * will trash adjacent memory!) */ - if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) - ctx->Current.EdgeFlag = - (tnl->vtx.attrptr[_TNL_ATTRIB_EDGEFLAG][0] == 1.0); + if (tnl->vtx.attrsz[_TNL_ATTRIB_INDEX]) { + ctx->Current.Index = tnl->vtx.attrptr[_TNL_ATTRIB_INDEX][0]; + } + /* Edgeflag requires additional treatment: + */ + if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) { + ctx->Current.EdgeFlag = + (tnl->vtx.CurrentFloatEdgeFlag == 1.0); + } /* Colormaterial -- this kindof sucks. */ @@ -176,7 +189,12 @@ static void _tnl_copy_from_current( GLcontext *ctx ) TNLcontext *tnl = TNL_CONTEXT(ctx); GLint i; - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) + /* Edgeflag requires additional treatment: + */ + tnl->vtx.CurrentFloatEdgeFlag = + (GLfloat)ctx->Current.EdgeFlag; + + for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_MAX ; i++) switch (tnl->vtx.attrsz[i]) { case 4: tnl->vtx.attrptr[i][3] = tnl->vtx.current[i][3]; case 3: tnl->vtx.attrptr[i][2] = tnl->vtx.current[i][2]; @@ -185,13 +203,6 @@ static void _tnl_copy_from_current( GLcontext *ctx ) break; } - /* Edgeflag requires special treatment: - */ - if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) - tnl->vtx.attrptr[_TNL_ATTRIB_EDGEFLAG][0] = - (GLfloat)ctx->Current.EdgeFlag; - - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; } @@ -251,7 +262,7 @@ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, tmp += tnl->vtx.attrsz[i]; } else - tnl->vtx.attrptr[i] = 0; /* will not be dereferenced */ + tnl->vtx.attrptr[i] = NULL; /* will not be dereferenced */ } /* Copy from current to repopulate the vertex with correct values. @@ -273,10 +284,14 @@ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { if (tnl->vtx.attrsz[j]) { if (j == attr) { - COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] ); - COPY_SZ_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; + if (oldsz) { + COPY_CLEAN_4V( dest, oldsz, data ); + data += oldsz; + dest += newsz; + } else { + COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] ); + dest += newsz; + } } else { GLuint sz = tnl->vtx.attrsz[j]; @@ -327,8 +342,18 @@ static void _tnl_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) for (i = sz ; i <= tnl->vtx.attrsz[attr] ; i++) tnl->vtx.attrptr[attr][i-1] = id[i-1]; } + + /* Does setting NeedFlush belong here? Necessitates resetting + * vtxfmt on each flush (otherwise flags won't get reset + * afterwards). + */ + if (attr == 0) + ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + else + ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; } +#ifdef USE_X86_ASM static struct _tnl_dynfn *lookup( struct _tnl_dynfn *l, GLuint key ) { @@ -339,14 +364,14 @@ static struct _tnl_dynfn *lookup( struct _tnl_dynfn *l, GLuint key ) return f; } - return 0; + return NULL; } -static attrfv_func do_codegen( GLcontext *ctx, GLuint attr, GLuint sz ) +static tnl_attrfv_func do_codegen( GLcontext *ctx, GLuint attr, GLuint sz ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct _tnl_dynfn *dfn = 0; + struct _tnl_dynfn *dfn = NULL; if (attr == 0) { GLuint key = tnl->vtx.vertex_size; @@ -366,16 +391,18 @@ static attrfv_func do_codegen( GLcontext *ctx, GLuint attr, GLuint sz ) } if (dfn) - return (attrfv_func) dfn->code; + return *(tnl_attrfv_func *) &dfn->code; else - return 0; + return NULL; } +#endif /* USE_X86_ASM */ + /* Helper function for 'CHOOSE' macro. Do what's necessary when an * entrypoint is called for the first time. */ -static attrfv_func do_choose( GLuint attr, GLuint sz ) +static tnl_attrfv_func do_choose( GLuint attr, GLuint sz ) { GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); @@ -391,23 +418,17 @@ static attrfv_func do_choose( GLuint attr, GLuint sz ) _tnl_fixup_vertex( ctx, attr, sz ); - /* Does setting NeedFlush belong here? Necessitates resetting - * vtxfmt on each flush (otherwise flags won't get reset - * afterwards). - */ - if (attr == 0) - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - else - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; } /* Try to use codegen: - */ + */ +#ifdef USE_X86_ASM if (tnl->AllowCodegen) tnl->vtx.tabfv[attr][sz-1] = do_codegen( ctx, attr, sz ); else - tnl->vtx.tabfv[attr][sz-1] = 0; +#endif + tnl->vtx.tabfv[attr][sz-1] = NULL; /* Else use generic version: */ @@ -422,7 +443,7 @@ static attrfv_func do_choose( GLuint attr, GLuint sz ) #define CHOOSE( ATTR, N ) \ static void choose_##ATTR##_##N( const GLfloat *v ) \ { \ - attrfv_func f = do_choose(ATTR, N); \ + tnl_attrfv_func f = do_choose(ATTR, N); \ f( v ); \ } @@ -471,11 +492,15 @@ static void reset_attrfv( TNLcontext *tnl ) for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) if (tnl->vtx.attrsz[i]) { - GLuint j = tnl->vtx.attrsz[i] - 1; + GLint j = tnl->vtx.attrsz[i] - 1; tnl->vtx.attrsz[i] = 0; - if (i < _TNL_MAX_ATTR_CODEGEN) - tnl->vtx.tabfv[i][j] = choose[i][j]; + if (i < _TNL_MAX_ATTR_CODEGEN) { + while (j >= 0) { + tnl->vtx.tabfv[i][j] = choose[i][j]; + j--; + } + } } tnl->vtx.vertex_size = 0; @@ -509,7 +534,6 @@ do { \ if (N>1) dest[1] = (params)[1]; \ if (N>2) dest[2] = (params)[2]; \ if (N>3) dest[3] = (params)[3]; \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ } \ } while (0) @@ -623,7 +647,7 @@ static void GLAPIENTRY _tnl_EvalCoord1f( GLfloat u ) for (i = 0 ; i <= _TNL_ATTRIB_INDEX ; i++) { if (tnl->vtx.eval.map1[i].map) - if (tnl->vtx.attrsz[i] < tnl->vtx.eval.map1[i].sz) + if (tnl->vtx.attrsz[i] != tnl->vtx.eval.map1[i].sz) _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map1[i].sz ); } } @@ -651,12 +675,12 @@ static void GLAPIENTRY _tnl_EvalCoord2f( GLfloat u, GLfloat v ) for (i = 0 ; i <= _TNL_ATTRIB_INDEX ; i++) { if (tnl->vtx.eval.map2[i].map) - if (tnl->vtx.attrsz[i] < tnl->vtx.eval.map2[i].sz) + if (tnl->vtx.attrsz[i] != tnl->vtx.eval.map2[i].sz) _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map2[i].sz ); } if (ctx->Eval.AutoNormal) - if (tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL] < 3) + if (tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL] != 3) _tnl_fixup_vertex( ctx, _TNL_ATTRIB_NORMAL, 3 ); } @@ -711,24 +735,23 @@ static void GLAPIENTRY _tnl_Begin( GLenum mode ) { GET_CURRENT_CONTEXT( ctx ); - if ((ctx->VertexProgram.Enabled - && !ctx->VertexProgram.Current->Instructions) || - (ctx->FragmentProgram.Enabled - && !ctx->FragmentProgram.Current->Instructions)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - return; - } - if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { TNLcontext *tnl = TNL_CONTEXT(ctx); int 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)"); + return; + } + if (!(tnl->Driver.NotifyBegin && tnl->Driver.NotifyBegin( ctx, mode ))) - ctx->Exec->Begin(mode); + CALL_Begin(ctx->Exec, (mode)); return; } @@ -812,6 +835,7 @@ static void _tnl_exec_vtxfmt_init( GLcontext *ctx ) void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ) { TNLcontext *tnl = TNL_CONTEXT(ctx); + (void) flags; if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) return; @@ -844,11 +868,13 @@ static void _tnl_current_init( GLcontext *ctx ) ctx->Light.Material.Attrib[i]; tnl->vtx.current[_TNL_ATTRIB_INDEX] = &ctx->Current.Index; + tnl->vtx.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->vtx.CurrentFloatEdgeFlag; } static struct _tnl_dynfn *no_codegen( GLcontext *ctx, int key ) { - return 0; + (void) ctx; (void) key; + return NULL; } void _tnl_vtx_init( GLcontext *ctx ) @@ -883,13 +909,17 @@ void _tnl_vtx_init( GLcontext *ctx ) choose[ERROR_ATTRIB][2] = error_attrib; choose[ERROR_ATTRIB][3] = error_attrib; - _tnl_x86choosers(choose, do_choose); /* x86 INIT_CHOOSERS */ +#ifdef USE_X86_ASM + if (tnl->AllowCodegen) { + _tnl_x86choosers(choose, do_choose); /* x86 INIT_CHOOSERS */ + } +#endif _tnl_generic_attr_table_init( generic_attr_func ); } for (i = 0; i < _TNL_ATTRIB_INDEX; i++) - _mesa_vector4f_init( &tmp->Attribs[i], 0, 0); + _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); for (i = 0; i < 4; i++) { make_empty_list( &tnl->vtx.cache.Vertex[i] ); @@ -898,12 +928,18 @@ void _tnl_vtx_init( GLcontext *ctx ) tnl->vtx.gen.Attribute[i] = no_codegen; } +#ifdef USE_X86_ASM _tnl_InitX86Codegen( &tnl->vtx.gen ); +#endif _tnl_current_init( ctx ); _tnl_exec_vtxfmt_init( ctx ); _tnl_generic_exec_vtxfmt_init( ctx ); - _tnl_x86_exec_vtxfmt_init( ctx ); /* x86 DISPATCH_ATTRFV */ +#ifdef USE_X86_ASM + if (tnl->AllowCodegen) { + _tnl_x86_exec_vtxfmt_init( ctx ); /* x86 DISPATCH_ATTRFV */ + } +#endif _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );