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/Makefile | 56 ++++++++++++++++- src/mesa/drivers/verite/libv3d.c | 7 +++ src/mesa/drivers/verite/libv3d.h | 1 + src/mesa/drivers/verite/rlgl.c | 3 +- src/mesa/drivers/verite/vrspan.c | 4 ++ src/mesa/main/imports.h | 2 +- src/mesa/ppc/ppc_xform.c | 11 ---- src/mesa/sources | 7 ++- src/mesa/swrast/swrast.h | 9 ++- src/mesa/tnl/t_context.c | 9 ++- src/mesa/tnl/t_context.h | 3 + src/mesa/tnl/t_vb_light.c | 9 ++- src/mesa/tnl/t_vb_program.c | 5 +- src/mesa/tnl/t_vertex.c | 109 +++++++++++++++++++++++++++++--- src/mesa/tnl/t_vtx_api.c | 33 ++++++++-- src/mesa/tnl/t_vtx_api.h | 2 + src/mesa/tnl/t_vtx_generic.c | 133 ++++++++++++++++++++++++--------------- 17 files changed, 313 insertions(+), 90 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 1315e35..d612675 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -28,6 +28,10 @@ default: $(MAKE) beos ; \ elif [ "${DRIVER_DIRS}" = "verite" ] ; then \ $(MAKE) verite-alone ; \ + elif [ "${DRIVER_DIRS}" = "verite-sim" ] ; then \ + $(MAKE) verite-sim ; \ + elif [ "${DRIVER_DIRS}" = "glide-sim" ] ; then \ + $(MAKE) glide-sim ; \ else \ $(MAKE) stand-alone ; \ fi @@ -170,6 +174,50 @@ verite-alone: depend $(VERITE_ALONE_OBJECTS) $(OSMESA_DRIVER_OBJECTS) $(OSMESA_DRIVER_OBJECTS) +###################################################################### +# Verite driver over the userspace simulator + +VERITE_SIM_SOURCES = \ + $(CORE_SOURCES) \ + $(COMMON_DRIVER_SOURCES) \ + $(VERITE_COMMON_DRIVER_SOURCES) \ + $(PPC_SOURCES) + +VERITE_SIM_OBJECTS = $(VERITE_SIM_SOURCES:.c=.o) + +-include $(VERITE_SIM_OBJECTS:.o=.d) + +# rm -f first: mklib's Darwin static case updates with "ar -ruv", which +# would keep stale members (e.g. libv3d.o) from a previous config. +verite-sim: depend $(VERITE_SIM_OBJECTS) + rm -f $(LIB_DIR)/$(GL_LIB_NAME) + CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(GL_LIB) \ + -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ + -install $(LIB_DIR) $(MKLIB_OPTIONS) $(GL_LIB_DEPS) \ + $(VERITE_SIM_OBJECTS) + + +###################################################################### +# fxMesa (3dfx Glide driver) over the userspace Voodoo simulator + +GLIDE_SIM_SOURCES = \ + $(CORE_SOURCES) \ + $(COMMON_DRIVER_SOURCES) \ + $(GLIDE_DRIVER_SOURCES) \ + $(PPC_SOURCES) + +GLIDE_SIM_OBJECTS = $(GLIDE_SIM_SOURCES:.c=.o) + +-include $(GLIDE_SIM_OBJECTS:.o=.d) + +glide-sim: depend $(GLIDE_SIM_OBJECTS) + rm -f $(LIB_DIR)/$(GL_LIB_NAME) + CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(GL_LIB) \ + -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ + -install $(LIB_DIR) $(MKLIB_OPTIONS) $(GL_LIB_DEPS) \ + $(GLIDE_SIM_OBJECTS) + + ###################################################################### # Generic stuff @@ -205,8 +253,10 @@ tags: clean: -rm -f */*.o -rm -f depend.bak mesa.a - -rm -f */*.d drivers/*/*.d - -rm -f drivers/*/*.o - (cd drivers/dri ; $(MAKE) clean) + -rm -f */*.d drivers/*/*.d drivers/*/*/*.d + -rm -f drivers/*/*.o drivers/*/*/*.o + @if [ -f drivers/dri/Makefile ] ; then \ + (cd drivers/dri ; $(MAKE) clean) ; \ + fi include depend diff --git a/src/mesa/drivers/verite/libv3d.c b/src/mesa/drivers/verite/libv3d.c index b09f960..8d8050b 100644 --- a/src/mesa/drivers/verite/libv3d.c +++ b/src/mesa/drivers/verite/libv3d.c @@ -283,6 +283,13 @@ v3d_alloc(struct v3d *v, uint32_t size, uint32_t align, uint32_t *addr) return 0; } +int +v3d_free(struct v3d *v, uint32_t addr) +{ + + return ioctl(v->fd, V3D_FREE, &addr); +} + int v3d_mode(struct v3d *v, uint32_t depth, uint32_t frame_base) { diff --git a/src/mesa/drivers/verite/libv3d.h b/src/mesa/drivers/verite/libv3d.h index 4ee44b1..e27175a 100644 --- a/src/mesa/drivers/verite/libv3d.h +++ b/src/mesa/drivers/verite/libv3d.h @@ -122,6 +122,7 @@ void v3d_commit(struct v3d *, uint32_t nwords); int v3d_flush(struct v3d *); int v3d_sync(struct v3d *); int v3d_alloc(struct v3d *, uint32_t, uint32_t, uint32_t *); +int v3d_free(struct v3d *, uint32_t addr); int v3d_mode(struct v3d *, uint32_t depth, uint32_t frame_base); int v3d_flip(struct v3d *, uint32_t frame_base); diff --git a/src/mesa/drivers/verite/rlgl.c b/src/mesa/drivers/verite/rlgl.c index 1da14f2..4e25d93 100644 --- a/src/mesa/drivers/verite/rlgl.c +++ b/src/mesa/drivers/verite/rlgl.c @@ -27,7 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include @@ -289,7 +288,7 @@ rlgl_tex_free(struct rlgl *rl, struct rlgl_tex *t) return; if (rl->cur_tex == addr) rl->cur_tex = (uint32_t)-1; - (void)ioctl(rl->v.fd, V3D_FREE, &addr); + (void)v3d_free(&rl->v, addr); t->addr = 0; } diff --git a/src/mesa/drivers/verite/vrspan.c b/src/mesa/drivers/verite/vrspan.c index 82a9f73..b666f6b 100644 --- a/src/mesa/drivers/verite/vrspan.c +++ b/src/mesa/drivers/verite/vrspan.c @@ -89,7 +89,11 @@ vr_set_buffer(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit) } } +#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define VR_SWAP16(x) ((GLushort)((((x) & 0xff) << 8) | ((x) >> 8))) +#else +#define VR_SWAP16(x) ((GLushort)(x)) +#endif #define NAME(PREFIX) PREFIX##_565 #define SPAN_VARS \ diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 86480c8..98e5960 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -228,7 +228,7 @@ extern void _ext_mesa_free_pixelbuffer( void *pb ); defined(ia64) || defined(__ia64__) || \ defined(__hppa__) || defined(hpux) || \ defined(__mips) || defined(_MIPS_ARCH) || \ - defined(__arm__) || \ + defined(__arm__) || defined(__aarch64__) || \ (defined(__alpha__) && (defined(__IEEE_FLOAT) || !defined(VMS))) #define USE_IEEE #define IEEE_ONE 0x3f800000 diff --git a/src/mesa/ppc/ppc_xform.c b/src/mesa/ppc/ppc_xform.c index 966798c..cbc122a 100644 --- a/src/mesa/ppc/ppc_xform.c +++ b/src/mesa/ppc/ppc_xform.c @@ -26,21 +26,10 @@ _mesa_init_all_ppc_transform_asm(void) rlvec_init(); - /* - * points3 = the glVertex3f-class path. - */ _mesa_transform_tab[3][MATRIX_GENERAL] = ppc_transform_points3_general; _mesa_transform_tab[3][MATRIX_PERSPECTIVE] = ppc_transform_points3_general; - _mesa_transform_tab[3][MATRIX_3D] = - ppc_transform_points3_general; - _mesa_transform_tab[3][MATRIX_3D_NO_ROT] = - ppc_transform_points3_general; - _mesa_transform_tab[3][MATRIX_2D] = - ppc_transform_points3_general; - _mesa_transform_tab[3][MATRIX_2D_NO_ROT] = - ppc_transform_points3_general; } #endif /* USE_PPC_ASM */ diff --git a/src/mesa/sources b/src/mesa/sources index 8490906..4b88f6b 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -219,13 +219,16 @@ GLIDE_DRIVER_SOURCES = \ drivers/glide/fxglidew.c \ drivers/glide/fxg.c -VERITE_DRIVER_SOURCES = \ +VERITE_COMMON_DRIVER_SOURCES = \ drivers/verite/vrapi.c \ drivers/verite/vrdd.c \ drivers/verite/vrspan.c \ drivers/verite/vrtex.c \ drivers/verite/vrtris.c \ - drivers/verite/rlgl.c \ + drivers/verite/rlgl.c + +VERITE_DRIVER_SOURCES = \ + $(VERITE_COMMON_DRIVER_SOURCES) \ drivers/verite/libv3d.c SVGA_DRIVER_SOURCES = \ diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 7fb0d2a..a3cd9e0 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -62,14 +62,19 @@ */ typedef struct { /** win[0], win[1] are the screen-coords of SWvertex. win[2] is the - * z-coord. what is win[3]? */ + * z-coord. what is win[3]? + * + * The texcoord array (most of the struct) trails so a + * fixed-function vertex's hot fields share fewer cache lines. All + * access is by field name, no code depends on member order. + */ GLfloat win[4]; - GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4]; GLchan color[4]; GLchan specular[4]; GLfloat fog; GLfloat index; GLfloat pointSize; + GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4]; } SWvertex; diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index e4d0d04..8db1c78 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -54,6 +54,13 @@ _tnl_MakeCurrent( GLcontext *ctx, (void) ctx; (void) drawBuffer; (void) readBuffer; } +static void +_tnl_validate_material( GLcontext *ctx ) +{ + _mesa_update_material( ctx, ~0 ); + _mesa_validate_all_lighting_tables( ctx ); +} + static void install_driver_callbacks( GLcontext *ctx ) @@ -123,7 +130,7 @@ _tnl_CreateContext( GLcontext *ctx ) tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; - tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables; + tnl->Driver.NotifyMaterialChange = _tnl_validate_material; return GL_TRUE; } diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index 55b405e..ae565fb 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -278,6 +278,9 @@ struct _tnl_dynfn_generators { struct tnl_vtx { GLfloat buffer[VERT_BUFFER_SIZE]; GLubyte attrsz[_TNL_ATTRIB_MAX]; + GLubyte active_sz[_TNL_ATTRIB_MAX]; /* size the generic entrypoints + * currently store per attribute; + * 0 forces _tnl_choose_attr() */ GLuint vertex_size; struct tnl_prim prim[TNL_MAX_PRIM]; GLuint prim_count; diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c index 1a89bf3..7d19c15 100644 --- a/src/mesa/tnl/t_vb_light.c +++ b/src/mesa/tnl/t_vb_light.c @@ -118,12 +118,11 @@ static GLuint prepare_materials( GLcontext *ctx, store->mat_bitmask |= (1<mat_count) { + _mesa_update_material( ctx, ~0 ); + _mesa_validate_all_lighting_tables( ctx ); + } return store->mat_count; } diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index 38b04b4..aedfb4e 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -355,7 +355,10 @@ static void dtr( struct tnl_pipeline_stage *stage ) const struct tnl_pipeline_stage _tnl_vertex_program_stage = { "vertex-program", - _NEW_ALL, /*XXX FIX */ /* recheck */ + _NEW_PROGRAM, /* recheck: check_vp() only reads + * VertexProgram._Enabled and + * Current->InputsRead, both always + * flushed with _NEW_PROGRAM */ _NEW_ALL, /*XXX FIX */ /* recalc */ GL_FALSE, /* active */ 0, /* inputs - calculated on the fly */ diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c index 900648a..6245f70 100644 --- a/src/mesa/tnl/t_vertex.c +++ b/src/mesa/tnl/t_vertex.c @@ -871,6 +871,107 @@ static void generic_emit( GLcontext *ctx, } +#define FUSED_EMIT( NAME, COLSZ, HAVE_TEX ) \ +static void NAME( GLcontext *ctx, GLuint start, GLuint end, \ + void *dest ) \ +{ \ + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \ + const struct tnl_clipspace_attr *a = vtx->attr; \ + const GLfloat * const vp = a[0].vp; \ + const GLubyte *pos_ptr = a[0].inputptr; \ + const GLubyte *col_ptr = a[1].inputptr; \ + const GLubyte *tex_ptr = HAVE_TEX ? a[2].inputptr : NULL; \ + const GLuint pos_stride = a[0].inputstride; \ + const GLuint col_stride = a[1].inputstride; \ + const GLuint tex_stride = HAVE_TEX ? a[2].inputstride : 0; \ + const GLuint pos_off = a[0].vertoffset; \ + const GLuint col_off = a[1].vertoffset; \ + const GLuint tex_off = HAVE_TEX ? a[2].vertoffset : 0; \ + const GLuint stride = vtx->vertex_size; \ + GLubyte *v = (GLubyte *)dest; \ + GLuint i; \ + \ + end -= start; \ + \ + for (i = 0; i < end; i++, v += stride) { \ + { \ + const GLfloat *in = (const GLfloat *)pos_ptr; \ + GLfloat *out = (GLfloat *)(v + pos_off); \ + \ + out[0] = vp[0] * in[0] + vp[12]; \ + out[1] = vp[5] * in[1] + vp[13]; \ + out[2] = vp[10] * in[2] + vp[14]; \ + out[3] = in[3]; \ + pos_ptr += pos_stride; \ + } \ + { \ + const GLfloat *in = (const GLfloat *)col_ptr; \ + GLchan *c = (GLchan *)(v + col_off); \ + \ + UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); \ + UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); \ + UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); \ + if (COLSZ == 4) { \ + UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]); \ + } \ + else \ + c[3] = CHAN_MAX; \ + col_ptr += col_stride; \ + } \ + if (HAVE_TEX) { \ + const GLfloat *in = (const GLfloat *)tex_ptr; \ + GLfloat *out = (GLfloat *)(v + tex_off); \ + \ + out[0] = in[0]; \ + out[1] = in[1]; \ + out[2] = 0; \ + out[3] = 1; \ + tex_ptr += tex_stride; \ + } \ + } \ +} + +FUSED_EMIT( emit_viewport4_rgba3, 3, 0 ) +FUSED_EMIT( emit_viewport4_rgba4, 4, 0 ) +FUSED_EMIT( emit_viewport4_rgba3_st, 3, 1 ) +FUSED_EMIT( emit_viewport4_rgba4_st, 4, 1 ) + +#undef FUSED_EMIT + +/* Match the installed attribute map plus this flush's input vector + * sizes against the fused layouts above; anything else takes + * generic_emit. + */ +static tnl_emit_func choose_emit_func( struct tnl_clipspace *vtx, + struct vertex_buffer *VB ) +{ + const struct tnl_clipspace_attr *a = vtx->attr; + const GLuint count = vtx->attr_count; + GLuint colsz; + + if (count < 2 || count > 3 || + a[0].format != EMIT_4F_VIEWPORT || + VB->AttribPtr[a[0].attrib]->size != 4 || + a[1].attrib != VERT_ATTRIB_COLOR0 || + a[1].format != EMIT_4CHAN_4F_RGBA) + return generic_emit; + + colsz = VB->AttribPtr[a[1].attrib]->size; + if (colsz != 3 && colsz != 4) + return generic_emit; + + if (count == 3) { + if (a[2].format != EMIT_4F || + VB->AttribPtr[a[2].attrib]->size != 2) + return generic_emit; + return (colsz == 4) ? emit_viewport4_rgba4_st + : emit_viewport4_rgba3_st; + } + + return (colsz == 4) ? emit_viewport4_rgba4 : emit_viewport4_rgba3; +} + + static void generic_interp( GLcontext *ctx, GLfloat t, GLuint edst, GLuint eout, GLuint ein, @@ -1030,13 +1131,7 @@ static void do_emit( GLcontext *ctx, GLuint start, GLuint end, a[j].emit = a[j].insert[vptr->size - 1]; } - vtx->emit = 0; - - if (0) - vtx->emit = _tnl_codegen_emit(ctx); - - if (!vtx->emit) - vtx->emit = generic_emit; + vtx->emit = choose_emit_func( vtx, VB ); vtx->emit( ctx, start, end, dest ); } diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c index 56b1e9f..f2e7857 100644 --- a/src/mesa/tnl/t_vtx_api.c +++ b/src/mesa/tnl/t_vtx_api.c @@ -312,14 +312,20 @@ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, * codegen. Might be a reasonable place to try & detect attributes * in the vertex which aren't being submitted any more. */ - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) + for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) { + /* Force the generic entrypoints through _tnl_choose_attr() again + * so shrunken attributes get their identity components refilled + * (mirrors the tabfv reset below). + */ + tnl->vtx.active_sz[i] = 0; + if (tnl->vtx.attrsz[i]) { GLuint j = tnl->vtx.attrsz[i] - 1; if (i < _TNL_MAX_ATTR_CODEGEN) tnl->vtx.tabfv[i][j] = choose[i][j]; } - + } } @@ -440,6 +446,22 @@ static tnl_attrfv_func do_choose( GLuint attr, GLuint sz ) +/* Helper for the single-dispatch generic entrypoints + */ +void _tnl_choose_attr( GLcontext *ctx, GLuint attr, GLuint sz ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + assert(attr < _TNL_ATTRIB_MAX); + assert(sz >= 1 && sz <= 4); + + if (tnl->vtx.attrsz[attr] != sz) + _tnl_fixup_vertex( ctx, attr, sz ); + + tnl->vtx.active_sz[attr] = (GLubyte) sz; +} + + #define CHOOSE( ATTR, N ) \ static void choose_##ATTR##_##N( const GLfloat *v ) \ { \ @@ -487,10 +509,12 @@ static void error_attrib( const GLfloat *unused ) static void reset_attrfv( TNLcontext *tnl ) -{ +{ GLuint i; - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) + for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) { + tnl->vtx.active_sz[i] = 0; + if (tnl->vtx.attrsz[i]) { GLint j = tnl->vtx.attrsz[i] - 1; tnl->vtx.attrsz[i] = 0; @@ -502,6 +526,7 @@ static void reset_attrfv( TNLcontext *tnl ) } } } + } tnl->vtx.vertex_size = 0; tnl->vtx.have_materials = 0; diff --git a/src/mesa/tnl/t_vtx_api.h b/src/mesa/tnl/t_vtx_api.h index 9818c08..0480bad 100644 --- a/src/mesa/tnl/t_vtx_api.h +++ b/src/mesa/tnl/t_vtx_api.h @@ -51,6 +51,8 @@ extern void _tnl_flush_vtx( GLcontext *ctx ); extern void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx ); +extern void _tnl_choose_attr( GLcontext *ctx, GLuint attr, GLuint sz ); + /* t_vtx_exec.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