readpix: add error checking for GLES3
authorJordan Justen <jordan.l.justen@intel.com>
Fri, 28 Dec 2012 19:24:37 +0000 (11:24 -0800)
committerMatt Turner <mattst88@gmail.com>
Mon, 21 Jan 2013 03:54:38 +0000 (19:54 -0800)
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
src/mesa/main/readpix.c

index 5b80e9a8ba14741e5366394140bbbdd5670fde64..d9c840e619727c52453b43cbb7000e64ef4a0f77 100644 (file)
@@ -674,12 +674,59 @@ _mesa_readpixels(struct gl_context *ctx,
 }
 
 
+static GLenum
+read_pixels_es3_error_check(GLenum format, GLenum type,
+                            const struct gl_renderbuffer *rb)
+{
+   const GLenum internalFormat = rb->InternalFormat;
+   const GLenum data_type = _mesa_get_format_datatype(rb->Format);
+   GLboolean is_unsigned_int = GL_FALSE;
+   GLboolean is_signed_int = GL_FALSE;
+
+   if (!_mesa_is_color_format(internalFormat)) {
+      return GL_INVALID_OPERATION;
+   }
+
+   is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
+   if (!is_unsigned_int) {
+      is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
+   }
+
+   switch (format) {
+   case GL_RGBA:
+      if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
+         return GL_NO_ERROR;
+      if (internalFormat == GL_RGB10_A2 &&
+          type == GL_UNSIGNED_INT_2_10_10_10_REV)
+         return GL_NO_ERROR;
+      if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
+         return GL_NO_ERROR;
+      break;
+   case GL_BGRA:
+      /* GL_EXT_read_format_bgra */
+      if (type == GL_UNSIGNED_BYTE ||
+          type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+          type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
+         return GL_NO_ERROR;
+      break;
+   case GL_RGBA_INTEGER:
+      if ((is_signed_int && type == GL_INT) ||
+          (is_unsigned_int && type == GL_UNSIGNED_INT))
+         return GL_NO_ERROR;
+      break;
+   }
+
+   return GL_INVALID_OPERATION;
+}
+
+
 void GLAPIENTRY
 _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
                      GLenum format, GLenum type, GLsizei bufSize,
                       GLvoid *pixels )
 {
    GLenum err = GL_NO_ERROR;
+   struct gl_renderbuffer *rb;
 
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -699,6 +746,13 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
       return;
    }
 
+   rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
+   if (rb == NULL) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glReadPixels(read buffer)");
+      return;
+   }
+
    /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
     * combinations of format and type that can be used.
     *
@@ -715,6 +769,8 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
                err = GL_INVALID_OPERATION;
             }
          }
+      } else {
+         err = read_pixels_es3_error_check(format, type, rb);
       }
 
       if (err == GL_NO_ERROR && (format == GL_DEPTH_COMPONENT