summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2003-11-11 11:42:50 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2003-11-11 11:42:50 +0000
commit701208d25937ac629dd146560fc0861eaac755cb (patch)
treec358c4cf165da70592859cd7c8403cce81112799
parentdfd3c9c40fa78b47e1d4a32426d033aff66d07d3 (diff)
Add CallLists() to vtxfmt.
Restore old NormalLength optimization for display lists. Add some heuristics to t_vtx_api.c to prevent bloated vertices and excessive flushing (hopefully).
-rw-r--r--src/mesa/tnl/t_context.h11
-rw-r--r--src/mesa/tnl/t_save_api.c58
-rw-r--r--src/mesa/tnl/t_save_playback.c7
-rw-r--r--src/mesa/tnl/t_vb_lighttmp.h4
-rw-r--r--src/mesa/tnl/t_vtx_api.c104
-rw-r--r--src/mesa/tnl/t_vtx_exec.c9
6 files changed, 149 insertions, 44 deletions
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index 112d8edb72..9d806da81f 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -231,7 +231,7 @@ struct tnl_copied_vtx {
GLuint nr;
};
-#define VERT_BUFFER_SIZE 2048
+#define VERT_BUFFER_SIZE 2048 /* 8kbytes */
typedef void (*attrfv_func)( const GLfloat * );
@@ -285,6 +285,7 @@ struct tnl_vertex_list {
GLuint dangling_attr_ref; /* current attr implicitly referenced
outside the list */
+ GLfloat *normal_lengths;
struct tnl_prim *prim;
GLuint prim_count;
@@ -292,7 +293,9 @@ struct tnl_vertex_list {
struct tnl_primitive_store *prim_store;
};
-/* These buffers should be a reasonable size:
+/* These buffers should be a reasonable size to support upload to
+ * hardware? Maybe drivers should stitch them back together, or
+ * specify a desired size?
*/
#define SAVE_BUFFER_SIZE (16*1024)
#define SAVE_PRIM_SIZE 128
@@ -377,11 +380,11 @@ struct vertex_buffer
{
/* Constant over life of the vertex_buffer.
*/
- GLuint Size;
+ GLuint Size;
/* Constant over the pipeline.
*/
- GLuint Count; /* for everything except Elts */
+ GLuint Count; /* for everything except Elts */
/* Pointers to current data.
*/
diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c
index d17b41d009..63a59e77d1 100644
--- a/src/mesa/tnl/t_save_api.c
+++ b/src/mesa/tnl/t_save_api.c
@@ -151,9 +151,33 @@ static GLuint _save_copy_vertices( GLcontext *ctx,
}
+static void
+build_normal_lengths( struct tnl_vertex_list *node )
+{
+ GLuint i;
+ GLfloat *len;
+ GLfloat *n = node->buffer;
+ GLuint stride = node->vertex_size;
+ GLuint count = node->count;
+
+ len = node->normal_lengths = MALLOC( count * sizeof(GLfloat) );
+ if (!len)
+ return;
+
+ /* Find the normal of the first vertex:
+ */
+ for (i = 0 ; i < _TNL_ATTRIB_NORMAL ; i++)
+ n += node->attrsz[i];
+
+ for (i = 0 ; i < count ; i++, n += stride) {
+ len[i] = LEN_3FV( n );
+ if (len[i] > 0.0F) len[i] = 1.0F / len[i];
+ }
+}
+
static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx )
{
- struct tnl_vertex_store *store = ALIGN_MALLOC( sizeof(*store), 32 );
+ struct tnl_vertex_store *store = MALLOC( sizeof(*store) );
store->used = 0;
store->refcount = 1;
return store;
@@ -161,7 +185,7 @@ static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx )
static struct tnl_primitive_store *alloc_prim_store( GLcontext *ctx )
{
- struct tnl_primitive_store *store = ALIGN_MALLOC( sizeof(*store), 32 );
+ struct tnl_primitive_store *store = MALLOC( sizeof(*store) );
store->used = 0;
store->refcount = 1;
return store;
@@ -222,13 +246,20 @@ static void _save_compile_vertex_list( GLcontext *ctx )
node->vertex_store = tnl->save.vertex_store;
node->prim_store = tnl->save.prim_store;
node->dangling_attr_ref = tnl->save.dangling_attr_ref;
+ node->normal_lengths = 0;
node->vertex_store->refcount++;
node->prim_store->refcount++;
-
assert(node->attrsz[_TNL_ATTRIB_POS] != 0);
+ /* Maybe calculate normal lengths:
+ */
+ if (tnl->CalcDListNormalLengths &&
+ node->attrsz[_TNL_ATTRIB_NORMAL] == 3 &&
+ !node->dangling_attr_ref)
+ build_normal_lengths( node );
+
tnl->save.vertex_store->used += tnl->save.vertex_size * node->count;
tnl->save.prim_store->used += node->prim_count;
@@ -279,6 +310,8 @@ static void _save_wrap_buffers( GLcontext *ctx )
assert(i < tnl->save.prim_max);
assert(i >= 0);
+ /* Close off in-progress primitive.
+ */
tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) -
tnl->save.prim[i].start);
mode = tnl->save.prim[i].mode & ~(PRIM_BEGIN|PRIM_END);
@@ -1118,10 +1151,20 @@ static void _save_EvalPoint2( GLint i, GLint j )
static void _save_CallList( GLuint l )
{
GET_CURRENT_CONTEXT(ctx);
+ fprintf(stderr, "%s\n", __FUNCTION__);
FALLBACK(ctx);
ctx->Save->CallList( l );
}
+static void _save_CallLists( GLsizei n, GLenum type, const GLvoid *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ FALLBACK(ctx);
+ ctx->Save->CallLists( n, type, v );
+}
+
+
/* This begin is hooked into ... Updating of
@@ -1311,7 +1354,6 @@ static void _save_vtxfmt_init( GLcontext *ctx )
vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
vfmt->Begin = _save_Begin;
- vfmt->CallList = _mesa_CallList;
vfmt->Color3f = _save_Color3f;
vfmt->Color3fv = _save_Color3fv;
vfmt->Color4f = _save_Color4f;
@@ -1362,6 +1404,7 @@ static void _save_vtxfmt_init( GLcontext *ctx )
/* This will all require us to fallback to saving the list as opcodes:
*/
vfmt->CallList = _save_CallList; /* inside begin/end */
+ vfmt->CallLists = _save_CallLists; /* inside begin/end */
vfmt->EvalCoord1f = _save_EvalCoord1f;
vfmt->EvalCoord1fv = _save_EvalCoord1fv;
vfmt->EvalCoord2f = _save_EvalCoord2f;
@@ -1438,10 +1481,13 @@ static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data )
struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
if ( --node->vertex_store->refcount == 0 )
- ALIGN_FREE( node->vertex_store );
+ FREE( node->vertex_store );
if ( --node->prim_store->refcount == 0 )
- ALIGN_FREE( node->prim_store );
+ FREE( node->prim_store );
+
+ if ( node->normal_lengths )
+ FREE( node->normal_lengths );
}
diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c
index 78e6c66159..52011996b0 100644
--- a/src/mesa/tnl/t_save_playback.c
+++ b/src/mesa/tnl/t_save_playback.c
@@ -64,7 +64,7 @@ static void _tnl_bind_vertex_list( GLcontext *ctx,
VB->Primitive = node->prim;
VB->PrimitiveCount = node->prim_count;
VB->Elts = NULL;
- VB->NormalLengthPtr = NULL;
+ VB->NormalLengthPtr = node->normal_lengths;
for (attr = 0; attr <= _TNL_ATTRIB_INDEX; attr++) {
if (node->attrsz[attr]) {
@@ -173,7 +173,7 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
if (node->prim_count) {
if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
- (node->prim[0].mode & PRIM_BEGIN)) {
+ (node->prim[0].mode & PRIM_BEGIN)) {
/* Degenerate case: list is called inside begin/end pair and
* includes operations such as glBegin or glDrawArrays.
@@ -182,7 +182,8 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
_tnl_loopback_vertex_list( ctx, data );
return;
}
- else if (node->dangling_attr_ref) {
+ else if (tnl->LoopbackDListCassettes ||
+ node->dangling_attr_ref) {
/* Degenerate case: list references current data and would
* require fixup. Take the easier option & loop it back.
*/
diff --git a/src/mesa/tnl/t_vb_lighttmp.h b/src/mesa/tnl/t_vb_lighttmp.h
index eaca5552d7..167325eae8 100644
--- a/src/mesa/tnl/t_vb_lighttmp.h
+++ b/src/mesa/tnl/t_vb_lighttmp.h
@@ -37,7 +37,7 @@
/* define TRACE to trace lighting code */
-/* #define TRACE 1 */
+/* #define TRACE 1 */
/*
* ctx is the current context
@@ -532,7 +532,7 @@ static void TAG(light_fast_rgba)( GLcontext *ctx,
const struct gl_light *light;
#ifdef TRACE
- fprintf(stderr, "%s\n", __FUNCTION__ );
+ fprintf(stderr, "%s %d\n", __FUNCTION__, nr );
#endif
(void) input;
diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c
index 894744f349..21ec1c9a7b 100644
--- a/src/mesa/tnl/t_vtx_api.c
+++ b/src/mesa/tnl/t_vtx_api.c
@@ -42,6 +42,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "t_vtx_api.h"
+static void init_attrfv( TNLcontext *tnl );
+
+
/* Close off the last primitive, execute the buffer, restart the
* primitive.
*/
@@ -166,6 +169,7 @@ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx,
GLuint oldsz;
GLint i;
GLfloat *tmp;
+ GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter;
/* Run pipeline on current vertices, copy wrapped vertices
@@ -179,6 +183,20 @@ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx,
*/
_tnl_copy_to_current( ctx );
+
+ /* Heuristic: Attempt to isolate attributes received outside
+ * begin/end so that they don't bloat the vertices.
+ */
+#if 1
+ if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
+ tnl->vtx.attrsz[attr] == 0
+ && lastcount > 8
+ ) {
+ init_attrfv( tnl );
+ }
+#endif
+
+
/* Fix up sizes:
*/
oldsz = tnl->vtx.attrsz[attr];
@@ -407,29 +425,33 @@ ATTRS( 15 )
static void init_attrfv( TNLcontext *tnl )
{
- GLuint i;
-
- init_0( tnl );
- init_1( tnl );
- init_2( tnl );
- init_3( tnl );
- init_4( tnl );
- init_5( tnl );
- init_6( tnl );
- init_7( tnl );
- init_8( tnl );
- init_9( tnl );
- init_10( tnl );
- init_11( tnl );
- init_12( tnl );
- init_13( tnl );
- init_14( tnl );
- init_15( tnl );
-
- for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
- tnl->vtx.attrsz[i] = 0;
-
- tnl->vtx.vertex_size = 0;
+ if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, tnl->vtx.vertex_size);
+
+ if (tnl->vtx.vertex_size) {
+ GLuint i;
+
+ init_0( tnl );
+ init_1( tnl );
+ init_2( tnl );
+ init_3( tnl );
+ init_4( tnl );
+ init_5( tnl );
+ init_6( tnl );
+ init_7( tnl );
+ init_8( tnl );
+ init_9( tnl );
+ init_10( tnl );
+ init_11( tnl );
+ init_12( tnl );
+ init_13( tnl );
+ init_14( tnl );
+ init_15( tnl );
+
+ for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
+ tnl->vtx.attrsz[i] = 0;
+
+ tnl->vtx.vertex_size = 0;
+ }
}
/* These can be made efficient with codegen. Further, by adding more
@@ -952,6 +974,14 @@ static void _tnl_Begin( GLenum mode )
return;
}
+#if 1
+ /* Heuristic: attempt to isolate attributes occuring outside
+ * begin/end pairs.
+ */
+ if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0])
+ _tnl_FlushVertices( ctx, ~0 );
+#endif
+
i = tnl->vtx.prim_count++;
tnl->vtx.prim[i].mode = mode | PRIM_BEGIN;
tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter;
@@ -978,8 +1008,19 @@ static void _tnl_End( void )
ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
- if (tnl->vtx.prim_count == TNL_MAX_PRIM)
+#if 0
+ if (tnl->vtx.counter * 2 > tnl->vtx.initial_counter)
+ _tnl_FlushVertices( ctx, ~0 );
+#endif
+
+ if (tnl->vtx.prim_count == TNL_MAX_PRIM) {
+#if 0
+ _tnl_FlushVertices( ctx, ~0 );
+#else
_tnl_flush_vtx( ctx );
+#endif
+ }
+
}
else
_mesa_error( ctx, GL_INVALID_OPERATION, __FUNCTION__ );
@@ -992,6 +1033,7 @@ static void _tnl_exec_vtxfmt_init( GLcontext *ctx )
vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
vfmt->Begin = _tnl_Begin;
vfmt->CallList = _mesa_CallList;
+ vfmt->CallLists = _mesa_CallLists;
vfmt->Color3f = _tnl_Color3f;
vfmt->Color3fv = _tnl_Color3fv;
vfmt->Color4f = _tnl_Color4f;
@@ -1061,18 +1103,24 @@ void _tnl_FlushVertices( GLcontext *ctx, GLuint flags )
if (tnl->vtx.counter != tnl->vtx.initial_counter) {
_tnl_flush_vtx( ctx );
- init_0( tnl );
+#if 0
+ init_0(tnl);
+#endif
}
- if (flags & FLUSH_UPDATE_CURRENT) {
+#if 0
+ if (flags & FLUSH_UPDATE_CURRENT)
+#endif
+ {
_tnl_copy_to_current( ctx );
/* reset attrfv table
*/
init_attrfv( tnl );
+ flags |= FLUSH_UPDATE_CURRENT;
}
- ctx->Driver.NeedFlush &= ~flags;
+ ctx->Driver.NeedFlush = 0;
}
static void _tnl_current_init( GLcontext *ctx )
@@ -1106,7 +1154,7 @@ void _tnl_vtx_init( GLcontext *ctx )
_tnl_exec_vtxfmt_init( ctx );
_mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
- init_attrfv( tnl );
+ tnl->vtx.vertex_size = 1; init_attrfv( tnl );
}
diff --git a/src/mesa/tnl/t_vtx_exec.c b/src/mesa/tnl/t_vtx_exec.c
index 376e580e3e..b72f10c36a 100644
--- a/src/mesa/tnl/t_vtx_exec.c
+++ b/src/mesa/tnl/t_vtx_exec.c
@@ -77,7 +77,7 @@ static GLint get_size( const GLfloat *f )
/* Some nasty stuff still hanging on here.
*
- * TODO - remove VB->ColorPtr, etc and just use the AttrPtr's.
+ * TODO - remove VB->NormalPtr, etc and just use the AttrPtr's.
*/
static void _tnl_vb_bind_vtx( GLcontext *ctx )
{
@@ -88,6 +88,10 @@ static void _tnl_vb_bind_vtx( GLcontext *ctx )
GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;
GLuint attr, i;
+ fprintf(stderr, "%s: %d verts %d vertsize\n",
+ __FUNCTION__, count, tnl->vtx.vertex_size);
+
+
/* Setup constant data in the VB.
*/
VB->Count = count;
@@ -137,8 +141,11 @@ static void _tnl_vb_bind_vtx( GLcontext *ctx )
VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
+ VB->ColorPtr[1] = 0;
VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX];
+ VB->IndexPtr[1] = 0;
VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
+ VB->SecondaryColorPtr[1] = 0;
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];