mesa: Fix error generation for glClearBuffer{i ui}v with GL_DEPTH or GL_STENCIL
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 1 Nov 2011 22:11:12 +0000 (15:11 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 7 Nov 2011 21:32:22 +0000 (13:32 -0800)
The spec says "Only ClearBufferiv should be used to clear
stencil buffers." and "Only ClearBufferfv should be used to clear
depth buffers."  However, on the following page it also says:

    "The result of ClearBuffer is undefined if no conversion between
    the type of the specified value and the type of the buffer being
    cleared is defined (for example, if ClearBufferiv is called for a
    fixed- or floating-point buffer, or if ClearBufferfv is called
    for a signed or unsigned integer buffer). *This is not an error.*"

Emphasis mine.

Fixes problems with piglit's clearbuffer-invalid-drawbuffer test.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/main/clear.c

index c35675fb4d1650d7ff22e7afef80946a42b24774..2e27c951bbbfb2d315e787ae117dc97f5ce0329b 100644 (file)
@@ -326,6 +326,13 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
 
    switch (buffer) {
    case GL_STENCIL:
+      /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
+       *
+       *     "ClearBuffer generates an INVALID VALUE error if buffer is
+       *     COLOR and drawbuffer is less than zero, or greater than the
+       *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
+       *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
+       */
       if (drawbuffer != 0) {
          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
                      drawbuffer);
@@ -373,6 +380,25 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
          }
       }
       break;
+   case GL_DEPTH:
+      /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
+       *
+       *     "The result of ClearBuffer is undefined if no conversion between
+       *     the type of the specified value and the type of the buffer being
+       *     cleared is defined (for example, if ClearBufferiv is called for a
+       *     fixed- or floating-point buffer, or if ClearBufferfv is called
+       *     for a signed or unsigned integer buffer). This is not an error."
+       *
+       * In this case we take "undefined" and "not an error" to mean "ignore."
+       * Note that we still need to generate an error for the invalid
+       * drawbuffer case (see the GL_STENCIL case above).
+       */
+      if (drawbuffer != 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
+                     drawbuffer);
+         return;
+      }
+      return;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
                   _mesa_lookup_enum_by_nr(buffer));
@@ -424,6 +450,31 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
          }
       }
       break;
+   case GL_DEPTH:
+   case GL_STENCIL:
+      /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
+       *
+       *     "The result of ClearBuffer is undefined if no conversion between
+       *     the type of the specified value and the type of the buffer being
+       *     cleared is defined (for example, if ClearBufferiv is called for a
+       *     fixed- or floating-point buffer, or if ClearBufferfv is called
+       *     for a signed or unsigned integer buffer). This is not an error."
+       *
+       * In this case we take "undefined" and "not an error" to mean "ignore."
+       * Even though we could do something sensible for GL_STENCIL, page 263
+       * (page 279 of the PDF) says:
+       *
+       *     "Only ClearBufferiv should be used to clear stencil buffers."
+       *
+       * Note that we still need to generate an error for the invalid
+       * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
+       */
+      if (drawbuffer != 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
+                     drawbuffer);
+         return;
+      }
+      return;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
                   _mesa_lookup_enum_by_nr(buffer));
@@ -450,6 +501,13 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
 
    switch (buffer) {
    case GL_DEPTH:
+      /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
+       *
+       *     "ClearBuffer generates an INVALID VALUE error if buffer is
+       *     COLOR and drawbuffer is less than zero, or greater than the
+       *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
+       *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
+       */
       if (drawbuffer != 0) {
          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
                      drawbuffer);
@@ -498,6 +556,25 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
          }
       }
       break;
+   case GL_STENCIL:
+      /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
+       *
+       *     "The result of ClearBuffer is undefined if no conversion between
+       *     the type of the specified value and the type of the buffer being
+       *     cleared is defined (for example, if ClearBufferiv is called for a
+       *     fixed- or floating-point buffer, or if ClearBufferfv is called
+       *     for a signed or unsigned integer buffer). This is not an error."
+       *
+       * In this case we take "undefined" and "not an error" to mean "ignore."
+       * Note that we still need to generate an error for the invalid
+       * drawbuffer case (see the GL_DEPTH case above).
+       */
+      if (drawbuffer != 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
+                     drawbuffer);
+         return;
+      }
+      return;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
                   _mesa_lookup_enum_by_nr(buffer));
@@ -525,6 +602,13 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
       return;
    }
 
+   /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
+    *
+    *     "ClearBuffer generates an INVALID VALUE error if buffer is
+    *     COLOR and drawbuffer is less than zero, or greater than the
+    *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
+    *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
+    */
    if (drawbuffer != 0) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
                   drawbuffer);