summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2003-10-13 18:01:05 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2003-10-13 18:01:05 +0000
commit79a49e30a19af701b75e3d1ec0e64628f4607eed (patch)
tree2fa451b644d95a73290df33140776982679abe1c
parentf1582dbe52460b03320862aa6d71ba3c6a89da5b (diff)
Fix several more display list glitches.
Get 'loopback' replay of display lists working.
-rw-r--r--src/mesa/tnl/t_save_api.c130
-rw-r--r--src/mesa/tnl/t_save_loopback.c45
-rw-r--r--src/mesa/tnl/t_save_playback.c83
-rw-r--r--src/mesa/tnl/t_vb_light.c2
4 files changed, 163 insertions, 97 deletions
diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c
index 56b26ac3aa..643645f211 100644
--- a/src/mesa/tnl/t_save_api.c
+++ b/src/mesa/tnl/t_save_api.c
@@ -68,8 +68,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "dlist.h"
#include "context.h"
+#include "dlist.h"
+#include "enums.h"
#include "macros.h"
#include "api_validate.h"
#include "api_arrayelt.h"
@@ -89,10 +90,12 @@ static GLuint _save_copy_vertices( GLcontext *ctx,
GLuint sz = tnl->save.vertex_size;
GLfloat *src = node->buffer + prim->start * sz;
GLfloat *dst = tnl->save.copied.buffer;
- GLenum mode = prim->mode & PRIM_MODE_MASK;
GLuint ovf, i;
- switch( mode )
+ if (prim->mode & PRIM_END)
+ return 0;
+
+ switch( prim->mode & PRIM_MODE_MASK )
{
case GL_POINTS:
return 0;
@@ -197,11 +200,6 @@ static void _save_compile_vertex_list( GLcontext *ctx )
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct tnl_vertex_list *node;
- if (tnl->save.initial_counter == tnl->save.counter) {
- _save_reset_counters( ctx );
- return;
- }
-
/* Allocate space for this structure in the display list currently
* being compiled.
*/
@@ -226,6 +224,9 @@ static void _save_compile_vertex_list( GLcontext *ctx )
node->vertex_store->refcount++;
node->prim_store->refcount++;
+
+ assert(node->attrsz[_TNL_ATTRIB_POS] != 0);
+
tnl->save.vertex_store->used += tnl->save.vertex_size * node->count;
tnl->save.prim_store->used += node->prim_count;
@@ -298,13 +299,6 @@ static void _save_wrap_buffers( GLcontext *ctx )
/* Called only when buffers are wrapped as the result of filling the
* vertex_store struct.
- *
- * -- what about when be wraps?
- * -- Don't need to copy vertices or emit fake begin/ends
- * -- Just call _save_compile_vertex_list()
- * -- what about vertex upgrades?
- * -- Same logic, but want to do more before emitting vertices in new
- * format.
*/
static void _save_wrap_filled_vertex( GLcontext *ctx )
{
@@ -392,8 +386,8 @@ static void _save_upgrade_vertex( GLcontext *ctx,
/* Store the current run of vertices, and emit a GL_END. Emit a
* BEGIN in the new buffer.
*/
- _save_wrap_buffers( ctx );
-
+ if (tnl->save.initial_counter != tnl->save.counter)
+ _save_wrap_buffers( ctx );
/* Do a COPY_TO_CURRENT to ensure back-copying works for the case
* when the attribute already exists in the vertex and is having
@@ -401,7 +395,6 @@ static void _save_upgrade_vertex( GLcontext *ctx,
*/
_save_copy_to_current( ctx );
-
/* Fix up sizes:
*/
oldsz = tnl->save.attrsz[attr];
@@ -1103,17 +1096,21 @@ static void _save_CallList( GLuint l )
static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- int i = tnl->save.prim_count++;
- assert(i < tnl->save.prim_max);
- tnl->save.prim[i].mode = mode | PRIM_BEGIN;
- tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter;
- tnl->save.prim[i].count = 0;
+ if (1) {
+ int i = tnl->save.prim_count++;
- _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
+ assert(i < tnl->save.prim_max);
+ tnl->save.prim[i].mode = mode | PRIM_BEGIN;
+ tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter;
+ tnl->save.prim[i].count = 0;
- ctx->Driver.SaveNeedFlush = 1;
- return GL_TRUE;
+ _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
+ ctx->Driver.SaveNeedFlush = 1;
+ return GL_TRUE;
+ }
+ else
+ return GL_FALSE;
}
@@ -1277,11 +1274,34 @@ static void _save_vtxfmt_init( GLcontext *ctx )
}
+void _tnl_SaveFlushVertices( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLint i;
+
+ /* Noop when we are actually active:
+ */
+ if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
+ ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
+ return;
+
+ if (tnl->save.initial_counter != tnl->save.counter ||
+ tnl->save.prim_count)
+ _save_compile_vertex_list( ctx );
+
+ save_init_attrfv( tnl );
+
+ for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
+ tnl->save.attrsz[i] = 0;
+
+ tnl->save.vertex_size = 0;
+ ctx->Driver.SaveNeedFlush = 0;
+}
void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- assert(tnl->save.vertex_size == 0);
+ GLuint i;
if (!tnl->save.prim_store)
tnl->save.prim_store = alloc_prim_store( ctx );
@@ -1291,6 +1311,14 @@ void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
tnl->save.vbptr = tnl->save.vertex_store->buffer;
}
+ save_init_attrfv( tnl );
+
+ for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
+ tnl->save.attrsz[i] = 0;
+
+ tnl->save.vertex_size = 0;
+ ctx->Driver.SaveNeedFlush = 0;
+
_save_reset_counters( ctx );
}
@@ -1308,28 +1336,6 @@ void _tnl_EndCallList( GLcontext *ctx )
{
}
-/* Called when
- */
-void _tnl_SaveFlushVertices( GLcontext *ctx )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLint i;
-
- if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
- ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
- return;
-
- _save_compile_vertex_list( ctx );
-
- save_init_attrfv( tnl );
-
- for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
- tnl->save.attrsz[i] = 0;
-
- tnl->save.vertex_size = 0;
-
- ctx->Driver.SaveNeedFlush = 0;
-}
static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data )
{
@@ -1346,10 +1352,23 @@ static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data )
static void _tnl_print_vertex_list( GLcontext *ctx, void *data )
{
struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
+ GLuint i;
- _mesa_debug(ctx, "TNL-VERTEX-LIST, %u vertices %d primitives\n",
+ _mesa_debug(0, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
node->count,
- node->prim_count);
+ node->prim_count,
+ node->vertex_size);
+
+ for (i = 0 ; i < node->prim_count ; i++) {
+ struct tnl_prim *prim = &node->prim[i];
+ _mesa_debug(0, " prim %d: %s %d..%d %s %s\n",
+ i,
+ _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK),
+ prim->start,
+ prim->start + prim->count,
+ (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)",
+ (prim->mode & PRIM_END) ? "END" : "(wrap)");
+ }
}
@@ -1383,14 +1402,6 @@ void _tnl_save_init( GLcontext *ctx )
struct tnl_vertex_arrays *tmp = &tnl->save_inputs;
GLuint i;
- save_init_attrfv( tnl );
-
- for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
- tnl->save.attrsz[i] = 0;
-
- tnl->save.vertex_size = 0;
-
- _save_vtxfmt_init( ctx );
for (i = 0; i < _TNL_ATTRIB_MAX; i++)
_mesa_vector4f_init( &tmp->Attribs[i], 0, 0);
@@ -1404,6 +1415,7 @@ void _tnl_save_init( GLcontext *ctx )
ctx->Driver.NotifySaveBegin = _save_NotifyBegin;
+ _save_vtxfmt_init( ctx );
_save_current_init( ctx );
}
diff --git a/src/mesa/tnl/t_save_loopback.c b/src/mesa/tnl/t_save_loopback.c
index 26fa9ccdfd..351a60bb70 100644
--- a/src/mesa/tnl/t_save_loopback.c
+++ b/src/mesa/tnl/t_save_loopback.c
@@ -28,6 +28,7 @@
*/
#include "context.h"
+#include "enums.h"
#include "glapi.h"
#include "imports.h"
#include "macros.h"
@@ -175,10 +176,10 @@ struct loopback_attr {
void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
{
- struct loopback_attr la[32];
+ struct loopback_attr la[_TNL_ATTRIB_MAX];
GLuint i, nr = 0;
- for (i = 1 ; i <= _TNL_ATTRIB_TEX7 ; i++) {
+ for (i = 0 ; i <= _TNL_ATTRIB_TEX7 ; i++) {
if (list->attrsz[i]) {
la[nr].target = i;
la[nr].sz = list->attrsz[i];
@@ -212,32 +213,20 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
nr++;
}
- /* Must be last
- */
- if (list->attrsz[_TNL_ATTRIB_POS]) {
- la[nr].target = _TNL_ATTRIB_POS;
- la[nr].sz = list->attrsz[_TNL_ATTRIB_POS];
- la[nr].func = vert_attrfunc[list->attrsz[0]-1];
- nr++;
- }
- else {
- fprintf(stderr, "No pos attrib???\n");
- return;
- }
-
/* Don't emit ends and begins on wrapped primitives. Don't replay
* wrapped vertices. If we get here, it's probably because the the
* precalculated wrapping is wrong.
*/
for (i = 0 ; i < list->prim_count ; i++) {
- GLint begin = list->prim[i].start;
- GLint end = begin + list->prim[i].count;
+ struct tnl_prim *prim = &list->prim[i];
+ GLint begin = prim->start;
+ GLint end = begin + prim->count;
GLfloat *data;
GLint j, k;
- if (list->prim[i].mode & PRIM_BEGIN)
- glBegin( list->prim[i].mode & PRIM_MODE_MASK );
- else {
+ if (prim->mode & PRIM_BEGIN) {
+ glBegin( prim->mode & PRIM_MODE_MASK );
+ } else {
assert(i == 0);
assert(begin == 0);
begin += list->wrap_count;
@@ -246,14 +235,22 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
data = list->buffer + begin * list->vertex_size;
for (j = begin ; j < end ; j++) {
- for (k = 0 ; k < nr ; k++) {
- la[k].func( la[k].target, data );
- data += la[k].sz;
+ GLfloat *tmp = data + la[0].sz;
+
+ for (k = 1 ; k < nr ; k++) {
+ la[k].func( la[k].target, tmp );
+ tmp += la[k].sz;
}
+
+ /* Fire the vertex
+ */
+ la[0].func( VERT_ATTRIB_POS, data );
+ data = tmp;
}
- if (list->prim[i].mode & PRIM_END)
+ if (prim->mode & PRIM_END) {
glEnd();
+ }
else {
assert (i == list->prim_count-1);
}
diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c
index f62057249c..4928e33dde 100644
--- a/src/mesa/tnl/t_save_playback.c
+++ b/src/mesa/tnl/t_save_playback.c
@@ -30,6 +30,8 @@
#include "context.h"
#include "imports.h"
#include "mtypes.h"
+#include "macros.h"
+#include "light.h"
#include "state.h"
#include "t_pipeline.h"
#include "t_save_api.h"
@@ -114,6 +116,49 @@ static void _tnl_bind_vertex_list( GLcontext *ctx,
}
}
+static void _playback_copy_to_current( GLcontext *ctx,
+ struct tnl_vertex_list *node )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLfloat *data;
+ GLuint i;
+
+ if (node->count)
+ data = node->buffer + (node->count-1) * node->vertex_size;
+ else
+ data = node->buffer;
+
+ for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) {
+ if (node->attrsz[i]) {
+ ASSIGN_4V(tnl->vtx.current[i], 0, 0, 0, 1);
+ COPY_SZ_4V(tnl->vtx.current[i], node->attrsz[i], data);
+ data += node->attrsz[i];
+ }
+ }
+
+ /* Edgeflag requires special treatment:
+ */
+ if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
+ ctx->Current.EdgeFlag = (data[0] == 1.0);
+ }
+
+ /* Colormaterial -- this kindof sucks.
+ */
+ if (ctx->Light.ColorMaterialEnabled) {
+ _mesa_update_color_material( ctx,
+ ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
+ }
+
+ /* CurrentExecPrimitive
+ */
+ if (node->prim_count) {
+ GLenum mode = node->prim[node->prim_count - 1].mode;
+ if (mode & PRIM_END)
+ ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
+ else
+ ctx->Driver.CurrentExecPrimitive = (mode & PRIM_MODE_MASK);
+ }
+}
/**
@@ -126,25 +171,39 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
FLUSH_CURRENT(ctx, 0);
- if (!node->prim_count || !node->count)
- return;
+ if (node->prim_count) {
- if (ctx->NewState)
- _mesa_update_state( ctx );
+ /* Degenerate case: list is called inside begin/end pair.
+ */
+ if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
+ (node->prim[0].mode & PRIM_BEGIN)) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin");
+ _tnl_loopback_vertex_list( ctx, data );
+ return;
+ }
+ else if (1) {
+ _tnl_loopback_vertex_list( ctx, data );
+ return;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
- if (tnl->pipeline.build_state_changes)
- _tnl_validate_pipeline( ctx );
+ if (tnl->pipeline.build_state_changes)
+ _tnl_validate_pipeline( ctx );
- _tnl_bind_vertex_list( ctx, node );
+ _tnl_bind_vertex_list( ctx, node );
- /* Invalidate all stored data before and after run:
- */
- tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
- tnl->Driver.RunPipeline( ctx );
- tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
+ /* Invalidate all stored data before and after run:
+ */
+ tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
+ tnl->Driver.RunPipeline( ctx );
+ tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
+ }
/* Copy to current?
*/
+ _playback_copy_to_current( ctx, node );
}
diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c
index a42147c803..ae1cc6231c 100644
--- a/src/mesa/tnl/t_vb_light.c
+++ b/src/mesa/tnl/t_vb_light.c
@@ -173,8 +173,6 @@ static GLboolean run_lighting( GLcontext *ctx, struct tnl_pipeline_stage *stage
GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
GLuint idx;
-/* _tnl_print_vert_flags( __FUNCTION__, stage->changed_inputs ); */
-
/* Make sure we can talk about position x,y and z:
*
* FIXME!