diff options
author | Ian Romanick <[email protected]> | 2012-01-20 17:23:02 -0800 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2012-01-24 12:31:04 -0800 |
commit | 34c353ce463960afdf64fa2be1f155b8b7f6c70c (patch) | |
tree | 9e326284a369485f6b08c0ca1b005035e5966633 /src/mesa/main/attrib.c | |
parent | 09639901530da7df7347428512c2bee86af1ef8e (diff) |
mesa: Don't resurrect deleted ARB VAOs in glPopClientAttrib
When ARB VAOs are used, glPopClientAttrib does not resurrect a deleted
VAO or VBO. This difference between the two spec is, unfortunately,
not very well spelled out in the specs.
Fixes oglc vao(advanced.pushPop.deleteVAO) and
vao(advanced.pushPop.deleteVBO) tests.
NOTE: This is a candidate for release branches.
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa/main/attrib.c')
-rw-r--r-- | src/mesa/main/attrib.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 1cd1fc46791..01e79455c2a 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -58,6 +58,8 @@ #include "viewport.h" #include "mtypes.h" #include "main/dispatch.h" +#include "hash.h" +#include <stdbool.h> /** @@ -1337,7 +1339,8 @@ copy_array_object(struct gl_context *ctx, static void copy_array_attrib(struct gl_context *ctx, struct gl_array_attrib *dest, - struct gl_array_attrib *src) + struct gl_array_attrib *src, + bool vbo_deleted) { /* skip ArrayObj */ /* skip DefaultArrayObj, Objects */ @@ -1349,7 +1352,8 @@ copy_array_attrib(struct gl_context *ctx, /* skip NewState */ /* skip RebindArrays */ - copy_array_object(ctx, dest->ArrayObj, src->ArrayObj); + if (!vbo_deleted) + copy_array_object(ctx, dest->ArrayObj, src->ArrayObj); /* skip ArrayBufferObj */ /* skip ElementArrayBufferObj */ @@ -1367,7 +1371,7 @@ save_array_attrib(struct gl_context *ctx, * Needs to match value in the object hash. */ dest->ArrayObj->Name = src->ArrayObj->Name; /* And copy all of the rest. */ - copy_array_attrib(ctx, dest, src); + copy_array_attrib(ctx, dest, src, false); /* Just reference them here */ _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj, @@ -1384,17 +1388,44 @@ restore_array_attrib(struct gl_context *ctx, struct gl_array_attrib *dest, struct gl_array_attrib *src) { - /* Restore or recreate the array object by its name ... */ - _mesa_BindVertexArrayAPPLE(src->ArrayObj->Name); + /* The ARB_vertex_array_object spec says: + * + * "BindVertexArray fails and an INVALID_OPERATION error is generated + * if array is not a name returned from a previous call to + * GenVertexArrays, or if such a name has since been deleted with + * DeleteVertexArrays." + * + * Therefore popping a deleted VAO cannot magically recreate it. + * + * The semantics of objects created using APPLE_vertex_array_objects behave + * differently. These objects expect to be recreated by pop. Alas. + */ + const bool arb_vao = (src->ArrayObj->Name != 0 + && src->ArrayObj->ARBsemantics); + + if (arb_vao && !_mesa_IsVertexArrayAPPLE(src->ArrayObj->Name)) + return; - /* ... and restore its content */ - copy_array_attrib(ctx, dest, src); + _mesa_BindVertexArrayAPPLE(src->ArrayObj->Name); /* Restore or recreate the buffer objects by the names ... */ - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - src->ArrayBufferObj->Name); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, - src->ArrayObj->ElementArrayBufferObj->Name); + if (!arb_vao + || src->ArrayBufferObj->Name == 0 + || _mesa_IsBufferARB(src->ArrayBufferObj->Name)) { + /* ... and restore its content */ + copy_array_attrib(ctx, dest, src, false); + + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + src->ArrayBufferObj->Name); + } else { + copy_array_attrib(ctx, dest, src, true); + } + + if (!arb_vao + || src->ArrayObj->ElementArrayBufferObj->Name == 0 + || _mesa_IsBufferARB(src->ArrayObj->ElementArrayBufferObj->Name)) + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, + src->ArrayObj->ElementArrayBufferObj->Name); /* Better safe than sorry?! */ dest->RebindArrays = GL_TRUE; |