summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2003-10-14 10:19:05 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2003-10-14 10:19:05 +0000
commitdf3b1eb5bcef8b4ad8ecfa3540e763ebb6aaf11b (patch)
treefb6f55e24b77c7d318b8e440de6734c8cdf98764
parent34a9e4adafe3bc9d41c154ea4161e6efcfa1485d (diff)
Cope with dangling attribute references from display lists
Handle colormaterial updates correctly
-rw-r--r--src/mesa/tnl/t_context.h5
-rw-r--r--src/mesa/tnl/t_save_api.c73
-rw-r--r--src/mesa/tnl/t_save_playback.c14
-rw-r--r--src/mesa/tnl/t_vtx_api.c17
4 files changed, 65 insertions, 44 deletions
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index 7182508426..112d8edb72 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -282,6 +282,8 @@ struct tnl_vertex_list {
GLfloat *buffer;
GLuint count;
GLuint wrap_count; /* number of copied vertices at start */
+ GLuint dangling_attr_ref; /* current attr implicitly referenced
+ outside the list */
struct tnl_prim *prim;
GLuint prim_count;
@@ -328,7 +330,8 @@ struct tnl_save {
GLfloat vertex[_TNL_ATTRIB_MAX*4]; /* current values */
GLfloat *attrptr[_TNL_ATTRIB_MAX];
GLuint counter, initial_counter;
-
+ GLuint dangling_attr_ref;
+
GLuint opcode_vertex_list;
struct tnl_copied_vtx copied;
diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c
index cd2f3a1bb1..3c3ac97ac7 100644
--- a/src/mesa/tnl/t_save_api.c
+++ b/src/mesa/tnl/t_save_api.c
@@ -189,6 +189,7 @@ static void _save_reset_counters( GLcontext *ctx )
tnl->save.prim_count = 0;
tnl->save.prim_max = SAVE_PRIM_SIZE - tnl->save.prim_store->used;
tnl->save.copied.nr = 0;
+ tnl->save.dangling_attr_ref = 0;
}
@@ -220,6 +221,7 @@ static void _save_compile_vertex_list( GLcontext *ctx )
node->prim_count = tnl->save.prim_count;
node->vertex_store = tnl->save.vertex_store;
node->prim_store = tnl->save.prim_store;
+ node->dangling_attr_ref = tnl->save.dangling_attr_ref;
node->vertex_store->refcount++;
node->prim_store->refcount++;
@@ -436,8 +438,21 @@ static void _save_upgrade_vertex( GLcontext *ctx,
*/
if (tnl->save.currentsz[attr] == 0) {
assert(oldsz == 0);
+ tnl->save.dangling_attr_ref = attr;
_mesa_debug(0, "%s: dangling reference attr %d\n",
__FUNCTION__, attr);
+
+#if 0
+ /* The current strategy is to punt these degenerate cases
+ * through _tnl_loopback_vertex_list(), a lower-performance
+ * option. To minimize the impact of this, artificially
+ * reduce the size of this vertex_list.
+ */
+ if (t->save.counter > 10) {
+ t->save.initial_counter = 10;
+ t->save.counter = 10;
+ }
+#endif
}
for (i = 0 ; i < tnl->save.copied.nr ; i++) {
@@ -519,37 +534,37 @@ static void do_choose( GLuint attr, GLuint sz,
* 3f version won't otherwise set color[3] to 1.0 -- this is the job
* of the chooser function when switching between Color4f and Color3f.
*/
-#define ATTRFV( ATTR, N ) \
+#define ATTRFV( ATTR, N ) \
static void save_choose_##ATTR##_##N( const GLfloat *v ); \
- \
+ \
static void save_attrib_##ATTR##_##N( const GLfloat *v ) \
-{ \
- GET_CURRENT_CONTEXT( ctx ); \
- TNLcontext *tnl = TNL_CONTEXT(ctx); \
- \
- if ((ATTR) == 0) { \
- int i; \
- \
- if (N>0) tnl->save.vbptr[0] = v[0]; \
- if (N>1) tnl->save.vbptr[1] = v[1]; \
- if (N>2) tnl->save.vbptr[2] = v[2]; \
- if (N>3) tnl->save.vbptr[3] = v[3]; \
- \
- for (i = N; i < tnl->save.vertex_size; i++) \
- tnl->save.vbptr[i] = tnl->save.vertex[i]; \
- \
- tnl->save.vbptr += tnl->save.vertex_size; \
- \
- if (--tnl->save.counter == 0) \
+{ \
+ GET_CURRENT_CONTEXT( ctx ); \
+ TNLcontext *tnl = TNL_CONTEXT(ctx); \
+ \
+ if ((ATTR) == 0) { \
+ int i; \
+ \
+ if (N>0) tnl->save.vbptr[0] = v[0]; \
+ if (N>1) tnl->save.vbptr[1] = v[1]; \
+ if (N>2) tnl->save.vbptr[2] = v[2]; \
+ if (N>3) tnl->save.vbptr[3] = v[3]; \
+ \
+ for (i = N; i < tnl->save.vertex_size; i++) \
+ tnl->save.vbptr[i] = tnl->save.vertex[i]; \
+ \
+ tnl->save.vbptr += tnl->save.vertex_size; \
+ \
+ if (--tnl->save.counter == 0) \
_save_wrap_filled_vertex( ctx ); \
- } \
- else { \
- GLfloat *dest = tnl->save.attrptr[ATTR]; \
- if (N>0) dest[0] = v[0]; \
- if (N>1) dest[1] = v[1]; \
- if (N>2) dest[2] = v[2]; \
- if (N>3) dest[3] = v[3]; \
- } \
+ } \
+ else { \
+ GLfloat *dest = tnl->save.attrptr[ATTR]; \
+ if (N>0) dest[0] = v[0]; \
+ if (N>1) dest[1] = v[1]; \
+ if (N>2) dest[2] = v[2]; \
+ if (N>3) dest[3] = v[3]; \
+ } \
}
#define CHOOSE( ATTR, N ) \
@@ -573,8 +588,6 @@ static void save_init_##ATTR( TNLcontext *tnl ) \
tnl->save.tabfv[ATTR][3] = save_choose_##ATTR##_4; \
}
-
-
#define ATTRS( ATTRIB ) \
ATTRFV( ATTRIB, 1 ) \
ATTRFV( ATTRIB, 2 ) \
diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c
index 4928e33dde..0d1d97c388 100644
--- a/src/mesa/tnl/t_save_playback.c
+++ b/src/mesa/tnl/t_save_playback.c
@@ -145,8 +145,7 @@ static void _playback_copy_to_current( GLcontext *ctx,
/* Colormaterial -- this kindof sucks.
*/
if (ctx->Light.ColorMaterialEnabled) {
- _mesa_update_color_material( ctx,
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
+ _mesa_update_color_material(ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
}
/* CurrentExecPrimitive
@@ -173,15 +172,20 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
if (node->prim_count) {
- /* Degenerate case: list is called inside begin/end pair.
- */
if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
(node->prim[0].mode & PRIM_BEGIN)) {
+
+ /* Degenerate case: list is called inside begin/end pair.
+ */
_mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin");
_tnl_loopback_vertex_list( ctx, data );
return;
}
- else if (1) {
+ else if (node->dangling_attr_ref) {
+ /* Degenerate case: list references current data and would
+ * require fixup. Take the easier option & loop it back.
+ */
+ _mesa_debug( 0, "%s: loopback dangling attr ref\n", __FUNCTION__);
_tnl_loopback_vertex_list( ctx, data );
return;
}
diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c
index d8bfe2ee7d..894744f349 100644
--- a/src/mesa/tnl/t_vtx_api.c
+++ b/src/mesa/tnl/t_vtx_api.c
@@ -36,6 +36,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "vtxfmt.h"
#include "dlist.h"
#include "state.h"
+#include "light.h"
#include "api_arrayelt.h"
#include "api_noop.h"
#include "t_vtx_api.h"
@@ -115,6 +116,13 @@ static void _tnl_copy_to_current( GLcontext *ctx )
if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG])
ctx->Current.EdgeFlag =
(tnl->vtx.attrptr[_TNL_ATTRIB_EDGEFLAG][0] == 1.0);
+
+
+ /* Colormaterial -- this kindof sucks.
+ */
+ if (ctx->Light.ColorMaterialEnabled) {
+ _mesa_update_color_material(ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
+ }
ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
}
@@ -725,7 +733,7 @@ do { \
} \
\
{ \
- GLfloat *dest = tnl->vtx.attrptr[A]; \
+ GLfloat *dest = tnl->vtx.attrptr[A]; \
if (N>0) dest[0] = params[0]; \
if (N>1) dest[1] = params[1]; \
if (N>2) dest[2] = params[2]; \
@@ -1080,13 +1088,6 @@ static void _tnl_current_init( GLcontext *ctx )
ctx->Light.Material.Attrib[i];
tnl->vtx.current[_TNL_ATTRIB_INDEX] = &ctx->Current.Index;
-
- /* Current edgeflag?
- */
-
- /* Initialize the vertex4f pointers pointing to Current also?
- */
-
}