[Piglit] New test regarding GL_CLIENT_VERTEX_ARRAY_BIT on push/pop

Brian Paul brianp at vmware.com
Mon Oct 31 08:55:56 PDT 2011


On 10/27/2011 09:43 AM, Mathias Fröhlich wrote:
>
> Hi,
>
> Attached is a new test that checks vertex array state.
> Checks are done for the initial state, push and pop of
> GL_CLIENT_VERTEX_ARRAY_BIT and buffer objects assigned
> to the array state.
> The test is not complete in that it does not check every state
> that needs to be pushed, but it includes the most important
> ones and might be a good starting point to be extended.
>
> There is one thing that is unclear to me in the standard and
> consequently is not checked to the end. That is the question
> what happens to a buffer object that is pushed with the array
> state and deleted while being pushed.

Buffer objects are reference counted.  A BO isn't truly deleted until 
its refcount hits zero.  If a BO is referenced by some pushed/saved 
state, the BO won't be deleted until after that saved state is popped. 
  The alternative would be to dig through (multiple layers of) the 
saved state and remove references to the buffer.  I don't think that 
makes sense.


> Nicely also the closed source drivers as of today from nvidia
> and ati also disagree with their behaviour.

Can you elaborate?


>
> Please review and apply if the test is ok so far.

I think a better name for the test would be "varray-push-pop-state" or 
something like that.

Other minor comments below.

Thanks for writing this test!

-Brian


> From f9afe8a93a2a8c92aa3d8541799853e0e6766276 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Mathias=20Fr=C3=B6hlich?= <Mathias.Froehlich at web.de>
> Date: Thu, 27 Oct 2011 17:10:27 +0200
> Subject: [PATCH 1/2] Add a partial test on push/pop array client attribs.
>
> ---
>  tests/general/CMakeLists.gl.txt |    1 +
>  tests/general/varray-bit.c      |  568 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 569 insertions(+), 0 deletions(-)
>  create mode 100644 tests/general/varray-bit.c
>
> diff --git a/tests/general/CMakeLists.gl.txt b/tests/general/CMakeLists.gl.txt
> index 8ff3771..7eb496e 100644
> --- a/tests/general/CMakeLists.gl.txt
> +++ b/tests/general/CMakeLists.gl.txt
> @@ -106,6 +106,7 @@ add_executable (timer_query timer_query.c)
>  add_executable (two-sided-lighting two-sided-lighting.c)
>  add_executable (two-sided-lighting-separate-specular two-sided-lighting-separate-specular.c)
>  add_executable (user-clip user-clip.c)
> +add_executable (varray-bit varray-bit.c)
>  add_executable (varray-disabled varray-disabled.c)
>  add_executable (vao-01 vao-01.c)
>  add_executable (vao-02 vao-02.c)
> diff --git a/tests/general/varray-bit.c b/tests/general/varray-bit.c
> new file mode 100644
> index 0000000..74e65eb
> --- /dev/null
> +++ b/tests/general/varray-bit.c
> @@ -0,0 +1,568 @@
> +/*
> + * (C) Copyright IBM Corporation 2006

Is this test derrived from an IBM test?


> + * (C) Copyright Mathias Froehlich 2011
> + * All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * on the rights to use, copy, modify, merge, publish, distribute, sub
> + * license, and/or sell copies of the Software, and to permit persons to whom
> + * the Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
> + * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +/**
> + * \file varray-bit.c
> + *
> + * Incomplete test of glPushClientAttrib/glPopClientAttrib functionality.
> + *
> + * \author Mathias Fröhlich <Mathias.Froehlich at web.de>
> + */
> +
> +#include "piglit-util.h"
> +
> +#define Elements(array) (sizeof(array) / sizeof(array[0]))

I think there's already a piglit macro for getting the size of an array.


> +
> +struct array_state {
> +   GLenum _which;
> +   GLuint _index; /* For texture coords and generic attributes */
> +   GLboolean _enabled;
> +   GLuint _buffer;
> +   GLint _size;
> +   GLenum _type;
> +   GLsizei _stride;
> +   GLvoid* _pointer;
> +};

I don't see any reason to prefix all these fields with an underscore.


> +
> +static const struct array_state initial_state[] = {
> +   { GL_VERTEX_ARRAY, 0,          GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_WEIGHT_ARRAY_ARB, 0,      GL_FALSE, 0, 1, GL_FLOAT, 0, 0 },
> +   { GL_NORMAL_ARRAY, 0,          GL_FALSE, 0, 3, GL_FLOAT, 0, 0 },
> +   { GL_COLOR_ARRAY, 0,           GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_SECONDARY_COLOR_ARRAY, 0, GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_FOG_COORD_ARRAY, 0,       GL_FALSE, 0, 1, GL_FLOAT, 0, 0 },
> +   { GL_INDEX_ARRAY, 0,           GL_FALSE, 0, 1, GL_FLOAT, 0, 0 },
> +   { GL_EDGE_FLAG_ARRAY, 0,       GL_FALSE, 0, 1, GL_BOOL, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 0,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 1,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 2,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 3,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 4,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 5,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 6,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 },
> +   { GL_TEXTURE_COORD_ARRAY, 7,   GL_FALSE, 0, 4, GL_FLOAT, 0, 0 }
> +   /* generic0-15 ?? */
> +};
> +
> +static struct array_state changed_state[] = {
> +   { GL_VERTEX_ARRAY, 0,          GL_TRUE, 0, 2, GL_DOUBLE, 64, (GLvoid*)0x100 },
> +   { GL_WEIGHT_ARRAY_ARB, 0,      GL_TRUE, 0, 1, GL_FLOAT, 2*64, (GLvoid*)0x200 },
> +   { GL_NORMAL_ARRAY, 0,          GL_TRUE, 0, 3, GL_DOUBLE, 3*64, (GLvoid*)0x300 },
> +   { GL_COLOR_ARRAY, 0,           GL_TRUE, 0, 3, GL_DOUBLE, 4*64, (GLvoid*)0x400 },
> +   { GL_SECONDARY_COLOR_ARRAY, 0, GL_TRUE, 0, 3, GL_DOUBLE, 5*64, (GLvoid*)0x500 },
> +   { GL_FOG_COORD_ARRAY, 0,       GL_TRUE, 0, 1, GL_DOUBLE, 6*64, (GLvoid*)0x600 },
> +   { GL_INDEX_ARRAY, 0,           GL_TRUE, 0, 1, GL_DOUBLE, 7*64, (GLvoid*)0x700 },
> +   { GL_EDGE_FLAG_ARRAY, 0,       GL_TRUE, 0, 1, GL_BOOL, 8*64, (GLvoid*)0x800 },
> +   { GL_TEXTURE_COORD_ARRAY, 0,   GL_TRUE, 0, 3, GL_DOUBLE, 9*64, (GLvoid*)0x900 },
> +   { GL_TEXTURE_COORD_ARRAY, 1,   GL_TRUE, 0, 2, GL_DOUBLE, 1*64, (GLvoid*)0x100 },
> +   { GL_TEXTURE_COORD_ARRAY, 2,   GL_TRUE, 0, 1, GL_DOUBLE, 2*64, (GLvoid*)0x200 },
> +   { GL_TEXTURE_COORD_ARRAY, 3,   GL_TRUE, 0, 2, GL_DOUBLE, 3*64, (GLvoid*)0x300 },
> +   { GL_TEXTURE_COORD_ARRAY, 4,   GL_TRUE, 0, 3, GL_DOUBLE, 4*64, (GLvoid*)0x400 },
> +   { GL_TEXTURE_COORD_ARRAY, 5,   GL_TRUE, 0, 2, GL_DOUBLE, 5*64, (GLvoid*)0x500 },
> +   { GL_TEXTURE_COORD_ARRAY, 6,   GL_TRUE, 0, 3, GL_DOUBLE, 6*64, (GLvoid*)0x600 },
> +   { GL_TEXTURE_COORD_ARRAY, 7,   GL_TRUE, 0, 2, GL_DOUBLE, 7*64, (GLvoid*)0x700 }
> +};
> +
> +static struct array_state changed_state2[] = {
> +   { GL_VERTEX_ARRAY, 0,          GL_FALSE, 0, 2, GL_FLOAT, 128, (GLvoid*)0x100100 },
> +   { GL_WEIGHT_ARRAY_ARB, 0,      GL_FALSE, 0, 1, GL_FLOAT, 2*128, (GLvoid*)0x100200 },
> +   { GL_NORMAL_ARRAY, 0,          GL_FALSE, 0, 3, GL_FLOAT, 3*128, (GLvoid*)0x100300 },
> +   { GL_COLOR_ARRAY, 0,           GL_FALSE, 0, 3, GL_FLOAT, 4*128, (GLvoid*)0x100400 },
> +   { GL_SECONDARY_COLOR_ARRAY, 0, GL_FALSE, 0, 3, GL_FLOAT, 5*128, (GLvoid*)0x100500 },
> +   { GL_FOG_COORD_ARRAY, 0,       GL_FALSE, 0, 1, GL_FLOAT, 6*128, (GLvoid*)0x100600 },
> +   { GL_INDEX_ARRAY, 0,           GL_FALSE, 0, 1, GL_FLOAT, 7*128, (GLvoid*)0x100700 },
> +   { GL_EDGE_FLAG_ARRAY, 0,       GL_FALSE, 0, 1, GL_BOOL, 8*128, (GLvoid*)0x100800 },
> +   { GL_TEXTURE_COORD_ARRAY, 0,   GL_FALSE, 0, 3, GL_FLOAT, 9*128, (GLvoid*)0x100900 },
> +   { GL_TEXTURE_COORD_ARRAY, 1,   GL_FALSE, 0, 2, GL_FLOAT, 1*128, (GLvoid*)0x100100 },
> +   { GL_TEXTURE_COORD_ARRAY, 2,   GL_FALSE, 0, 1, GL_FLOAT, 2*128, (GLvoid*)0x100200 },
> +   { GL_TEXTURE_COORD_ARRAY, 3,   GL_FALSE, 0, 2, GL_FLOAT, 3*128, (GLvoid*)0x100300 },
> +   { GL_TEXTURE_COORD_ARRAY, 4,   GL_FALSE, 0, 3, GL_FLOAT, 4*128, (GLvoid*)0x100400 },
> +   { GL_TEXTURE_COORD_ARRAY, 5,   GL_FALSE, 0, 2, GL_FLOAT, 5*128, (GLvoid*)0x100500 },
> +   { GL_TEXTURE_COORD_ARRAY, 6,   GL_FALSE, 0, 3, GL_FLOAT, 6*128, (GLvoid*)0x100600 },
> +   { GL_TEXTURE_COORD_ARRAY, 7,   GL_FALSE, 0, 2, GL_FLOAT, 7*128, (GLvoid*)0x100700 }
> +};
> +
> +static void
> +set_array_state(const struct array_state* as, GLuint count)
> +{
> +   while (count-- != 0) {
> +      GLenum err;
> +
> +      if (as->_which == GL_WEIGHT_ARRAY_ARB &&
> +          !piglit_is_extension_supported("GL_ARB_vertex_blend"))
> +         continue;
> +
> +      switch (as->_which) {
> +      case GL_TEXTURE_COORD_ARRAY:
> +         glClientActiveTexture(as->_index);
> +         break;
> +      default:
> +         break;
> +      }

This would be simpler:

if (as->_which == GL_TEXTURE_COORD_ARRAY) {
    glClientActiveTexture(as->_index);
}


> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }

I think there's a piglit helper function for testing GL error state 
and exiting.


> +
> +      if (piglit_is_extension_supported("GL_ARB_vertex_buffer_object")) {
> +         glBindBuffer(GL_ARRAY_BUFFER_ARB, as->_buffer);
> +         err = glGetError();
> +         if (err) {
> +            printf("glGetError incorrectly returned 0x%04x.\n", err);
> +            piglit_report_result(PIGLIT_FAIL);
> +         }
> +      }
> +
> +      switch (as->_which) {
> +      case GL_VERTEX_ARRAY:
> +         glVertexPointer(as->_size, as->_type, as->_stride, as->_pointer);
> +         break;
> +      case GL_WEIGHT_ARRAY_ARB:
> +         glWeightPointerARB(as->_size, as->_type, as->_stride, as->_pointer);
> +         break;
> +      case GL_NORMAL_ARRAY:
> +         glNormalPointer(as->_type, as->_stride, as->_pointer);
> +         break;
> +      case GL_COLOR_ARRAY:
> +         glColorPointer(as->_size, as->_type, as->_stride, as->_pointer);
> +         break;
> +      case GL_SECONDARY_COLOR_ARRAY:
> +         glSecondaryColorPointer(as->_size, as->_type, as->_stride, as->_pointer);
> +         break;
> +      case GL_FOG_COORD_ARRAY:
> +         glFogCoordPointer(as->_type, as->_stride, as->_pointer);
> +         break;
> +      case GL_INDEX_ARRAY:
> +         glIndexPointer(as->_type, as->_stride, as->_pointer);
> +         break;
> +      case GL_EDGE_FLAG_ARRAY:
> +         glEdgeFlagPointer(as->_stride, as->_pointer);
> +         break;
> +      case GL_TEXTURE_COORD_ARRAY:
> +         glTexCoordPointer(as->_size, as->_type, as->_stride, as->_pointer);
> +         break;
> +      default:
> +         printf("Test internal implementation error.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +         break;
> +      }
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      if (as->_enabled)
> +         glEnableClientState(as->_which);
> +      else
> +         glDisableClientState(as->_which);
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      ++as;
> +   }
> +}
> +
> +static void
> +check_array_state(const struct array_state* as, GLuint count, GLboolean check_buffer_binding)
> +{
> +   while (count-- != 0) {
> +      GLenum err;
> +      GLint ivalue;
> +      GLvoid* pointer;
> +
> +      if (as->_which == GL_WEIGHT_ARRAY_ARB &&
> +          !piglit_is_extension_supported("GL_ARB_vertex_blend"))
> +         continue;
> +
> +      switch (as->_which) {
> +      case GL_TEXTURE_COORD_ARRAY:
> +         glClientActiveTexture(as->_index);
> +         break;
> +      default:
> +         break;
> +      }
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      if (as->_enabled != glIsEnabled(as->_which)) {
> +         printf("Array state is incorrectly enabled/disabled.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      switch (as->_which) {
> +      case GL_VERTEX_ARRAY:
> +         glGetIntegerv(GL_VERTEX_ARRAY_SIZE, &ivalue);
> +         break;
> +      case GL_WEIGHT_ARRAY_ARB:
> +         ivalue = 1; /* No size here, is always 1 */
> +         break;
> +      case GL_NORMAL_ARRAY:
> +         ivalue = 3; /* No size here, is always 3 */
> +         break;
> +      case GL_COLOR_ARRAY:
> +         glGetIntegerv(GL_COLOR_ARRAY_SIZE, &ivalue);
> +         break;
> +      case GL_SECONDARY_COLOR_ARRAY:
> +         glGetIntegerv(GL_SECONDARY_COLOR_ARRAY_SIZE, &ivalue);
> +         break;
> +      case GL_FOG_COORD_ARRAY:
> +         ivalue = 1; /* No size here, is always 1 */
> +         break;
> +      case GL_INDEX_ARRAY:
> +         ivalue = 1; /* No size here, is always 1 */
> +         break;
> +      case GL_EDGE_FLAG_ARRAY:
> +         ivalue = 1; /* No size here, is always 1 */
> +         break;
> +      case GL_TEXTURE_COORD_ARRAY:
> +         glGetIntegerv(GL_TEXTURE_COORD_ARRAY_SIZE, &ivalue);
> +         break;
> +      default:
> +         printf("Test internal implementation error.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +         break;
> +      }
> +      if (ivalue != as->_size) {
> +         printf("Array state has incorrect size.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      switch (as->_which) {
> +      case GL_VERTEX_ARRAY:
> +         glGetIntegerv(GL_VERTEX_ARRAY_TYPE, &ivalue);
> +         break;
> +      case GL_WEIGHT_ARRAY_ARB:
> +         glGetIntegerv(GL_WEIGHT_ARRAY_TYPE_ARB, &ivalue);
> +         break;
> +      case GL_NORMAL_ARRAY:
> +         glGetIntegerv(GL_NORMAL_ARRAY_TYPE, &ivalue);
> +         break;
> +      case GL_COLOR_ARRAY:
> +         glGetIntegerv(GL_COLOR_ARRAY_TYPE, &ivalue);
> +         break;
> +      case GL_SECONDARY_COLOR_ARRAY:
> +         glGetIntegerv(GL_SECONDARY_COLOR_ARRAY_TYPE, &ivalue);
> +         break;
> +      case GL_FOG_COORD_ARRAY:
> +         glGetIntegerv(GL_FOG_COORD_ARRAY_TYPE, &ivalue);
> +         break;
> +      case GL_INDEX_ARRAY:
> +         glGetIntegerv(GL_INDEX_ARRAY_TYPE, &ivalue);
> +         break;
> +      case GL_EDGE_FLAG_ARRAY:
> +         ivalue = GL_BOOL;
> +         break;
> +      case GL_TEXTURE_COORD_ARRAY:
> +         glGetIntegerv(GL_TEXTURE_COORD_ARRAY_TYPE, &ivalue);
> +         break;
> +      default:
> +         printf("Test internal implementation error.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +         break;
> +      }
> +      if (ivalue != as->_type) {
> +         printf("Array state has incorrect type.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      switch (as->_which) {
> +      case GL_VERTEX_ARRAY:
> +         glGetIntegerv(GL_VERTEX_ARRAY_STRIDE, &ivalue);
> +         break;
> +      case GL_WEIGHT_ARRAY_ARB:
> +         glGetIntegerv(GL_WEIGHT_ARRAY_STRIDE_ARB, &ivalue);
> +         break;
> +      case GL_NORMAL_ARRAY:
> +         glGetIntegerv(GL_NORMAL_ARRAY_STRIDE, &ivalue);
> +         break;
> +      case GL_COLOR_ARRAY:
> +         glGetIntegerv(GL_COLOR_ARRAY_STRIDE, &ivalue);
> +         break;
> +      case GL_SECONDARY_COLOR_ARRAY:
> +         glGetIntegerv(GL_SECONDARY_COLOR_ARRAY_STRIDE, &ivalue);
> +         break;
> +      case GL_FOG_COORD_ARRAY:
> +         glGetIntegerv(GL_FOG_COORD_ARRAY_STRIDE, &ivalue);
> +         break;
> +      case GL_INDEX_ARRAY:
> +         glGetIntegerv(GL_INDEX_ARRAY_STRIDE, &ivalue);
> +         break;
> +      case GL_EDGE_FLAG_ARRAY:
> +         glGetIntegerv(GL_EDGE_FLAG_ARRAY_STRIDE, &ivalue);
> +         break;
> +      case GL_TEXTURE_COORD_ARRAY:
> +         glGetIntegerv(GL_TEXTURE_COORD_ARRAY_STRIDE, &ivalue);
> +         break;
> +      default:
> +         printf("Test internal implementation error.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +         break;
> +      }
> +      if (ivalue != as->_stride) {
> +         printf("Array state has incorrect stride.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      switch (as->_which) {
> +      case GL_VERTEX_ARRAY:
> +         glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer);
> +         break;
> +      case GL_WEIGHT_ARRAY_ARB:
> +         glGetPointerv(GL_WEIGHT_ARRAY_POINTER_ARB, &pointer);
> +         break;
> +      case GL_NORMAL_ARRAY:
> +         glGetPointerv(GL_NORMAL_ARRAY_POINTER, &pointer);
> +         break;
> +      case GL_COLOR_ARRAY:
> +         glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer);
> +         break;
> +      case GL_SECONDARY_COLOR_ARRAY:
> +         glGetPointerv(GL_SECONDARY_COLOR_ARRAY_POINTER, &pointer);
> +         break;
> +      case GL_FOG_COORD_ARRAY:
> +         glGetPointerv(GL_FOG_COORD_ARRAY_POINTER, &pointer);
> +         break;
> +      case GL_INDEX_ARRAY:
> +         glGetPointerv(GL_INDEX_ARRAY_POINTER, &pointer);
> +         break;
> +      case GL_EDGE_FLAG_ARRAY:
> +         glGetPointerv(GL_EDGE_FLAG_ARRAY_POINTER, &pointer);
> +         break;
> +      case GL_TEXTURE_COORD_ARRAY:
> +         glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer);
> +         break;
> +      default:
> +         printf("Test internal implementation error.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +         break;
> +      }
> +      if (pointer != as->_pointer) {
> +         printf("Array state has incorrect pointer.\n");
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +      err = glGetError();
> +      if (err) {
> +         printf("glGetError incorrectly returned 0x%04x.\n", err);
> +         piglit_report_result(PIGLIT_FAIL);
> +      }
> +
> +      if (check_buffer_binding &&
> +          piglit_is_extension_supported("GL_ARB_vertex_buffer_object")) {
> +         switch (as->_which) {
> +         case GL_VERTEX_ARRAY:
> +            glGetIntegerv(GL_VERTEX_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         case GL_WEIGHT_ARRAY_ARB:
> +            glGetIntegerv(GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB, &ivalue);
> +            break;
> +         case GL_NORMAL_ARRAY:
> +            glGetIntegerv(GL_NORMAL_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         case GL_COLOR_ARRAY:
> +            glGetIntegerv(GL_COLOR_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         case GL_SECONDARY_COLOR_ARRAY:
> +            glGetIntegerv(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         case GL_FOG_COORD_ARRAY:
> +            glGetIntegerv(GL_FOG_COORD_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         case GL_INDEX_ARRAY:
> +            glGetIntegerv(GL_INDEX_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         case GL_EDGE_FLAG_ARRAY:
> +            glGetIntegerv(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         case GL_TEXTURE_COORD_ARRAY:
> +            glGetIntegerv(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &ivalue);
> +            break;
> +         default:
> +            printf("Test internal implementation error.\n");
> +            piglit_report_result(PIGLIT_FAIL);
> +            break;
> +         }
> +         if (ivalue != as->_buffer) {
> +            printf("Array state is bound to wrong buffer.\n");
> +            piglit_report_result(PIGLIT_FAIL);
> +         }
> +         err = glGetError();
> +         if (err) {
> +            printf("glGetError incorrectly returned 0x%04x.\n", err);
> +            piglit_report_result(PIGLIT_FAIL);
> +         }
> +
> +         if ((as->_buffer != 0) != glIsBuffer(ivalue)) {
> +            printf("Array bound buffer is not a buffer object as expected.\n");
> +            piglit_report_result(PIGLIT_FAIL);
> +         }
> +         err = glGetError();
> +         if (err) {
> +            printf("glGetError incorrectly returned 0x%04x.\n", err);
> +            piglit_report_result(PIGLIT_FAIL);
> +         }
> +      }
> +
> +      ++as;
> +   }
> +}
> +
> +
> +int piglit_width = 400;
> +int piglit_height = 200;
> +int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +   return PIGLIT_PASS;
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +   GLuint obj, i;
> +
> +   /* Check the initial specified state */
> +   check_array_state(initial_state, Elements(initial_state), GL_TRUE);
> +
> +   /* Set something and test */
> +   set_array_state(changed_state, Elements(changed_state));
> +   check_array_state(changed_state, Elements(changed_state), GL_TRUE);
> +
> +   glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
> +
> +   set_array_state(changed_state2, Elements(changed_state2));
> +   check_array_state(changed_state2, Elements(changed_state2), GL_TRUE);
> +
> +   glPopClientAttrib();
> +
> +   /* Past pop, the state must be restored */
> +   check_array_state(changed_state, Elements(changed_state), GL_TRUE);
> +
> +   /* Try in the oposite order */

"opposite"


> +   set_array_state(changed_state2, Elements(changed_state2));
> +   check_array_state(changed_state2, Elements(changed_state2), GL_TRUE);
> +
> +   glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
> +
> +   set_array_state(changed_state, Elements(changed_state));
> +   check_array_state(changed_state, Elements(changed_state), GL_TRUE);
> +
> +   glPopClientAttrib();
> +
> +   /* Past pop, the state must be restored */
> +   check_array_state(changed_state2, Elements(changed_state2), GL_TRUE);
> +
> +
> +   /* Do a few tests with vbos */
> +   glGenBuffers(1, &obj);
> +   glBindBuffer(GL_ARRAY_BUFFER_ARB, obj);
> +   for (i = 0; i < Elements(changed_state2); ++i)
> +      changed_state2[i]._buffer = obj;
> +
> +   /* Set the state with the vbo's */
> +   set_array_state(changed_state2, Elements(changed_state2));
> +   check_array_state(changed_state2, Elements(changed_state2), GL_TRUE);
> +
> +   glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
> +
> +   set_array_state(changed_state, Elements(changed_state));
> +   check_array_state(changed_state, Elements(changed_state), GL_TRUE);
> +
> +   glPopClientAttrib();
> +
> +   /* Past pop, the state must be restored */
> +   check_array_state(changed_state2, Elements(changed_state2), GL_TRUE);
> +
> +
> +   /* Try in the oposite order */
> +   set_array_state(changed_state, Elements(changed_state));
> +   check_array_state(changed_state, Elements(changed_state), GL_TRUE);
> +
> +   glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
> +
> +   set_array_state(changed_state2, Elements(changed_state2));
> +   check_array_state(changed_state2, Elements(changed_state2), GL_TRUE);
> +
> +   glPopClientAttrib();
> +
> +   /* Past pop, the state must be restored */
> +   check_array_state(changed_state, Elements(changed_state), GL_TRUE);
> +
> +
> +   /* Set the state with vbos */
> +   set_array_state(changed_state2, Elements(changed_state2));
> +   check_array_state(changed_state2, Elements(changed_state2), GL_TRUE);
> +
> +   glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
> +
> +   set_array_state(changed_state, Elements(changed_state));
> +   check_array_state(changed_state, Elements(changed_state), GL_TRUE);
> +
> +   glDeleteBuffers(1, &obj);
> +
> +   /* It is unclear what needs to happen restoring the deleted object?
> +      Also the closed source drivers as of today disagree on that.
> +      So starting from this point do no longer check the bound array object. */
> +   /* for (i = 0; i < Elements(changed_state2); ++i) */
> +   /*   changed_state2[i]._buffer = 0; */
> +
> +   check_array_state(changed_state, Elements(changed_state), GL_FALSE);
> +
> +   glPopClientAttrib();
> +
> +   check_array_state(changed_state2, Elements(changed_state2), GL_FALSE);
> +
> +   /* If we get to this point we must have survived */
> +   piglit_report_result(PIGLIT_PASS);
> +}


More information about the Piglit mailing list