From 56e89c9e4fb00b5c2af4536d4c50294608d0c46c Mon Sep 17 00:00:00 2001 From: Radosław Kujawa Date: Sun, 2 Aug 2026 22:04:06 +0200 Subject: Performance improvements, support userspace simulators --- src/mesa/tnl/t_vtx_generic.c | 133 ++++++++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 51 deletions(-) (limited to 'src/mesa/tnl/t_vtx_generic.c') diff --git a/src/mesa/tnl/t_vtx_generic.c b/src/mesa/tnl/t_vtx_generic.c index daa7dea..faf7e19 100644 --- a/src/mesa/tnl/t_vtx_generic.c +++ b/src/mesa/tnl/t_vtx_generic.c @@ -133,52 +133,51 @@ void _tnl_generic_attr_table_init( tnl_attrfv_func (*tab)[4] ) INIT( tab, 15 ); } -/* These can be made efficient with codegen. Further, by adding more - * logic to do_choose(), the double-dispatch for legacy entrypoints - * like glVertex3f() can be removed. - */ -#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - tnl->vtx.tabfv[ATTR][COUNT-1]( P ); \ +/* Single-dispatch entrypoints */ +#define ATTRF( A, N, X, Y, Z, W ) \ +do { \ + GET_CURRENT_CONTEXT( ctx ); \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + \ + if (tnl->vtx.active_sz[A] != (N)) \ + _tnl_choose_attr( ctx, (A), (N) ); \ + \ + if ((A) == 0) { \ + GLfloat *dest = tnl->vtx.vbptr; \ + GLuint i; \ + \ + if ((N)>0) dest[0] = (X); \ + if ((N)>1) dest[1] = (Y); \ + if ((N)>2) dest[2] = (Z); \ + if ((N)>3) dest[3] = (W); \ + \ + for (i = (N); i < tnl->vtx.vertex_size; i++) \ + dest[i] = tnl->vtx.vertex[i]; \ + \ + tnl->vtx.vbptr = dest + tnl->vtx.vertex_size; \ + \ + if (--tnl->vtx.counter == 0) \ + _tnl_wrap_filled_vertex( ctx ); \ + } \ + else { \ + GLfloat *dest = tnl->vtx.attrptr[A]; \ + \ + if ((N)>0) dest[0] = (X); \ + if ((N)>1) dest[1] = (Y); \ + if ((N)>2) dest[2] = (Z); \ + if ((N)>3) dest[3] = (W); \ + } \ } while (0) -#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V ) -#define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V ) -#define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V ) -#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V ) - -#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) ) +#define DISPATCH_ATTR1FV( ATTR, V ) ATTRF( ATTR, 1, (V)[0], 0, 0, 1 ) +#define DISPATCH_ATTR2FV( ATTR, V ) ATTRF( ATTR, 2, (V)[0], (V)[1], 0, 1 ) +#define DISPATCH_ATTR3FV( ATTR, V ) ATTRF( ATTR, 3, (V)[0], (V)[1], (V)[2], 1 ) +#define DISPATCH_ATTR4FV( ATTR, V ) ATTRF( ATTR, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) -#if defined(USE_X86_ASM) && 0 /* will break register calling convention */ -/* Naughty cheat: - */ -#define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) ) -#define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) ) -#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) ) -#else -/* Safe: - */ -#define DISPATCH_ATTR2F( ATTR, S,T ) \ -do { \ - GLfloat v[2]; \ - v[0] = S; v[1] = T; \ - DISPATCH_ATTR2FV( ATTR, v ); \ -} while (0) -#define DISPATCH_ATTR3F( ATTR, S,T,R ) \ -do { \ - GLfloat v[3]; \ - v[0] = S; v[1] = T; v[2] = R; \ - DISPATCH_ATTR3FV( ATTR, v ); \ -} while (0) -#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \ -do { \ - GLfloat v[4]; \ - v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \ - DISPATCH_ATTR4FV( ATTR, v ); \ -} while (0) -#endif +#define DISPATCH_ATTR1F( ATTR, S ) ATTRF( ATTR, 1, S, 0, 0, 1 ) +#define DISPATCH_ATTR2F( ATTR, S,T ) ATTRF( ATTR, 2, S, T, 0, 1 ) +#define DISPATCH_ATTR3F( ATTR, S,T,R ) ATTRF( ATTR, 3, S, T, R, 1 ) +#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) ATTRF( ATTR, 4, S, T, R, Q ) static void GLAPIENTRY _tnl_Vertex2f( GLfloat x, GLfloat y ) @@ -363,42 +362,66 @@ static void GLAPIENTRY _tnl_MultiTexCoord4fv( GLenum target, static void GLAPIENTRY _tnl_VertexAttrib1fNV( GLuint index, GLfloat x ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR1F( index, x ); } static void GLAPIENTRY _tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR1FV( index, v ); } static void GLAPIENTRY _tnl_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR2F( index, x, y ); } static void GLAPIENTRY _tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR2FV( index, v ); } static void GLAPIENTRY _tnl_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR3F( index, x, y, z ); } static void GLAPIENTRY _tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR3FV( index, v ); } @@ -406,14 +429,22 @@ static void GLAPIENTRY _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR4F( index, x, y, z, w ); } static void GLAPIENTRY _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) { - if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB; + if (index >= VERT_ATTRIB_MAX) { + GET_CURRENT_CONTEXT( ctx ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); + return; + } DISPATCH_ATTR4FV( index, v ); } -- cgit