aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRadosław Kujawa <radoslaw.kujawa@c0ff33.net>2026-08-02 22:04:06 +0200
committerRadosław Kujawa <radoslaw.kujawa@c0ff33.net>2026-08-02 22:04:32 +0200
commit56e89c9e4fb00b5c2af4536d4c50294608d0c46c (patch)
treeb247c62b317ce11e8c26e5b311a16cfae2f7d9c9 /src
parentafc74a01283fad7dfbbd670a535e68d90de7ed9a (diff)
Performance improvements, support userspace simulatorsHEADmaster
Diffstat (limited to 'src')
-rw-r--r--src/mesa/Makefile56
-rw-r--r--src/mesa/drivers/verite/libv3d.c7
-rw-r--r--src/mesa/drivers/verite/libv3d.h1
-rw-r--r--src/mesa/drivers/verite/rlgl.c3
-rw-r--r--src/mesa/drivers/verite/vrspan.c4
-rw-r--r--src/mesa/main/imports.h2
-rw-r--r--src/mesa/ppc/ppc_xform.c11
-rw-r--r--src/mesa/sources7
-rw-r--r--src/mesa/swrast/swrast.h9
-rw-r--r--src/mesa/tnl/t_context.c9
-rw-r--r--src/mesa/tnl/t_context.h3
-rw-r--r--src/mesa/tnl/t_vb_light.c9
-rw-r--r--src/mesa/tnl/t_vb_program.c5
-rw-r--r--src/mesa/tnl/t_vertex.c109
-rw-r--r--src/mesa/tnl/t_vtx_api.c33
-rw-r--r--src/mesa/tnl/t_vtx_api.h2
-rw-r--r--src/mesa/tnl/t_vtx_generic.c133
17 files changed, 313 insertions, 90 deletions
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
@@ -171,6 +175,50 @@ verite-alone: depend $(VERITE_ALONE_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
ALL_SOURCES = \
@@ -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
@@ -284,6 +284,13 @@ v3d_alloc(struct v3d *v, uint32_t size, uint32_t align, uint32_t *addr)
}
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)
{
struct v3d_mode vm;
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 <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
@@ -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<<attr);
}
}
-
- /* FIXME: Is this already done?
- */
- _mesa_update_material( ctx, ~0 );
- _mesa_validate_all_lighting_tables( ctx );
+ if (store->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 );
}