summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2009-06-30 19:52:44 +0100
committerKeith Whitwell <keithw@vmware.com>2009-06-30 19:52:44 +0100
commit1fa4cde757cc94c0afa40d855309911247974e98 (patch)
tree0ad8a007b86bea133c49ab6d2e25432f699df79d /src
parent70ae7ba818e9d8a5485653b258e76f06c988654c (diff)
mesa/vbo: fix compile and replay of nodes ending in a FALLBACK
Where vbo save nodes are terminated with a call to DO_FALLBACK(), as in the case of a recursive CallList which is itself within a Begin/End pair, there two problems: 1) The display list node's primitive information was incorrect, stating the cut-off prim had zero vertices 2) On replay, we would get confused by a primitive that started in a node, but was terminated by individual opcodes. This change fixes the first problem by correctly terminating the last primitive on fallback, and the second by forcing the display list to use the Loopback path, converting all nodes into immediate-mode rendering. The loopback fix is a performance hit, but avoiding this would require a fairly large rework of this code.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/vbo/vbo_save_api.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index 971a338af4..85cb79c71c 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -667,19 +667,33 @@ do { \
* -- Flush current buffer
* -- Fallback to opcodes for the rest of the begin/end object.
*/
-#define DO_FALLBACK(ctx) \
-do { \
- struct vbo_save_context *save = &vbo_context(ctx)->save; \
- \
- if (save->vert_count || save->prim_count) \
- _save_compile_vertex_list( ctx ); \
- \
- _save_copy_to_current( ctx ); \
- _save_reset_vertex( ctx ); \
- _save_reset_counters( ctx ); \
- _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \
- ctx->Driver.SaveNeedFlush = 0; \
-} while (0)
+static void DO_FALLBACK( GLcontext *ctx )
+{
+ struct vbo_save_context *save = &vbo_context(ctx)->save;
+
+ if (save->vert_count || save->prim_count) {
+ GLint i = save->prim_count - 1;
+
+ /* Close off in-progress primitive.
+ */
+ save->prim[i].count = (save->vert_count -
+ save->prim[i].start);
+
+ /* Need to replay this display list with loopback,
+ * unfortunately, otherwise this primitive won't be handled
+ * properly:
+ */
+ save->dangling_attr_ref = 1;
+
+ _save_compile_vertex_list( ctx );
+ }
+
+ _save_copy_to_current( ctx );
+ _save_reset_vertex( ctx );
+ _save_reset_counters( ctx );
+ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
+ ctx->Driver.SaveNeedFlush = 0;
+}
static void GLAPIENTRY _save_EvalCoord1f( GLfloat u )
{