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 <ian.d.romanick@intel.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Ian Romanick
2012-01-20 17:23:02 -08:00
parent 0963990153
commit 34c353ce46

View File

@@ -58,6 +58,8 @@
#include "viewport.h" #include "viewport.h"
#include "mtypes.h" #include "mtypes.h"
#include "main/dispatch.h" #include "main/dispatch.h"
#include "hash.h"
#include <stdbool.h>
/** /**
@@ -1337,7 +1339,8 @@ copy_array_object(struct gl_context *ctx,
static void static void
copy_array_attrib(struct gl_context *ctx, copy_array_attrib(struct gl_context *ctx,
struct gl_array_attrib *dest, struct gl_array_attrib *dest,
struct gl_array_attrib *src) struct gl_array_attrib *src,
bool vbo_deleted)
{ {
/* skip ArrayObj */ /* skip ArrayObj */
/* skip DefaultArrayObj, Objects */ /* skip DefaultArrayObj, Objects */
@@ -1349,7 +1352,8 @@ copy_array_attrib(struct gl_context *ctx,
/* skip NewState */ /* skip NewState */
/* skip RebindArrays */ /* skip RebindArrays */
copy_array_object(ctx, dest->ArrayObj, src->ArrayObj); if (!vbo_deleted)
copy_array_object(ctx, dest->ArrayObj, src->ArrayObj);
/* skip ArrayBufferObj */ /* skip ArrayBufferObj */
/* skip ElementArrayBufferObj */ /* skip ElementArrayBufferObj */
@@ -1367,7 +1371,7 @@ save_array_attrib(struct gl_context *ctx,
* Needs to match value in the object hash. */ * Needs to match value in the object hash. */
dest->ArrayObj->Name = src->ArrayObj->Name; dest->ArrayObj->Name = src->ArrayObj->Name;
/* And copy all of the rest. */ /* And copy all of the rest. */
copy_array_attrib(ctx, dest, src); copy_array_attrib(ctx, dest, src, false);
/* Just reference them here */ /* Just reference them here */
_mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj, _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 *dest,
struct gl_array_attrib *src) struct gl_array_attrib *src)
{ {
/* Restore or recreate the array object by its 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;
_mesa_BindVertexArrayAPPLE(src->ArrayObj->Name); _mesa_BindVertexArrayAPPLE(src->ArrayObj->Name);
/* ... and restore its content */
copy_array_attrib(ctx, dest, src);
/* Restore or recreate the buffer objects by the names ... */ /* Restore or recreate the buffer objects by the names ... */
_mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, if (!arb_vao
src->ArrayBufferObj->Name); || src->ArrayBufferObj->Name == 0
_mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, || _mesa_IsBufferARB(src->ArrayBufferObj->Name)) {
src->ArrayObj->ElementArrayBufferObj->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?! */ /* Better safe than sorry?! */
dest->RebindArrays = GL_TRUE; dest->RebindArrays = GL_TRUE;