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:
@@ -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;
|
||||||
|
Reference in New Issue
Block a user