mesa: fix proxy texture error handling in glTexStorage()
authorBrian Paul <brianp@vmware.com>
Sat, 8 Sep 2012 15:33:13 +0000 (09:33 -0600)
committerBrian Paul <brianp@vmware.com>
Tue, 11 Sep 2012 23:38:21 +0000 (17:38 -0600)
This is basically a follow-on to 1f5b1f98468d5e80be39e619ed15c422fbede8d3.
Basically, generate GL errors for ordinary invalid parameters for proxy
targets the same as for non-proxy targets.  Only texture size and OOM
errors should be handled specially for proxies.

Note: This is a candidate for the stable branches.

src/mesa/main/texstorage.c

index 8e03e5eb7381155278aa6c601d051083beb02a11..f8a9397949aca5b246ed7d3ca74aebf863238aca 100644 (file)
@@ -192,9 +192,10 @@ setup_texstorage(struct gl_context *ctx,
 
          return;
       }
-   }
 
-   texObj->Immutable = GL_TRUE;
+      /* Only set this field for non-proxy texture objects */
+      texObj->Immutable = GL_TRUE;
+   }
 }
 
 
@@ -242,7 +243,6 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,
                         GLsizei levels, GLenum internalformat,
                         GLsizei width, GLsizei height, GLsizei depth)
 {
-   const GLboolean isProxy = _mesa_is_proxy_texture(target);
    struct gl_texture_object *texObj;
    GLuint maxDim;
    GLboolean legalFormat;
@@ -296,19 +296,15 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,
 
    /* size check */
    if (width < 1 || height < 1 || depth < 1) {
-      if (!isProxy) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glTexStorage%uD(width, height or depth < 1)", dims);
-      }
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glTexStorage%uD(width, height or depth < 1)", dims);
       return GL_TRUE;
    }  
 
    /* levels check */
    if (levels < 1 || height < 1 || depth < 1) {
-      if (!isProxy) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)",
-                     dims);
-      }
+      _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)",
+                  dims);
       return GL_TRUE;
    }  
 
@@ -322,40 +318,32 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,
 
    /* check levels against maximum */
    if (levels > _mesa_max_texture_levels(ctx, target)) {
-      if (!isProxy) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glTexStorage%uD(levels too large)", dims);
-      }
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTexStorage%uD(levels too large)", dims);
       return GL_TRUE;
    }
 
    /* check levels against width/height/depth */
    maxDim = MAX3(width, height, depth);
    if (levels > _mesa_logbase2(maxDim) + 1) {
-      if (!isProxy) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glTexStorage%uD(too many levels for max texture dimension)",
-                     dims);
-      }
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTexStorage%uD(too many levels for max texture dimension)",
+                  dims);
       return GL_TRUE;
    }
 
    /* non-default texture object check */
    texObj = _mesa_get_current_tex_object(ctx, target);
-   if (!texObj || (texObj->Name == 0 && !isProxy)) {
-      if (!isProxy) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glTexStorage%uD(texture object 0)", dims);
-      }
+   if (!texObj || (texObj->Name == 0)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTexStorage%uD(texture object 0)", dims);
       return GL_TRUE;
    }
 
    /* Check if texObj->Immutable is set */
    if (texObj->Immutable) {
-      if (!isProxy) {
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)",
-                     dims);
-      }
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)",
+                  dims);
       return GL_TRUE;
    }
 
@@ -371,22 +359,38 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
            GLsizei width, GLsizei height, GLsizei depth)
 {
    struct gl_texture_object *texObj;
-   GLboolean error;
+   GLboolean sizeOK;
+   GLenum proxyTarget = _mesa_get_proxy_target(target);
 
    GET_CURRENT_CONTEXT(ctx);
 
    texObj = _mesa_get_current_tex_object(ctx, target);
 
-   error = tex_storage_error_check(ctx, dims, target, levels,
-                                   internalformat, width, height, depth);
-   if (!error) {
+   if (tex_storage_error_check(ctx, dims, target, levels,
+                               internalformat, width, height, depth)) {
+      return; /* error was recorded */
+   }
+
+   sizeOK = ctx->Driver.TestProxyTexImage(ctx, proxyTarget, 0,
+                                          internalformat, GL_NONE, GL_NONE,
+                                          width, height, depth, 0);
+
+   if (!sizeOK) {
+      if (_mesa_is_proxy_texture(texObj->Target)) {
+         /* clear all image fields for [levels] */
+         clear_image_fields(ctx, dims, texObj);
+      }
+      else {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glTexStorage%uD(invalid width, height or depth)",
+                     dims);
+         return;
+      }
+   }
+   else {
       setup_texstorage(ctx, texObj, dims, levels, internalformat,
                        width, height, depth);
    }
-   else if (_mesa_is_proxy_texture(target)) {
-      /* clear all image fields for [levels] */
-      clear_image_fields(ctx, dims, texObj);
-   }
 }