mesa: fix invalid target error handling for teximage
[mesa.git] / src / mesa / main / teximage.c
index 875d2226ad99cfadd677b9ed3de8a9cc24d9836c..b80d5a9b675f98375113653daf3d192b0f3b9830 100644 (file)
@@ -2205,6 +2205,15 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
+   if (!texture_formats_agree(texImage->InternalFormat, format)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(incompatible internalFormat = %s, format = %s)",
+                  callerName,
+                  _mesa_enum_to_string(texImage->InternalFormat),
+                  _mesa_enum_to_string(format));
+      return GL_TRUE;
+   }
+
    GLenum internalFormat = _mesa_is_gles(ctx) ?
       oes_float_internal_format(ctx, texImage->InternalFormat, type) :
       texImage->InternalFormat;
@@ -2979,17 +2988,18 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
 
    internalFormat = override_internal_format(internalFormat, width, height);
 
+   if (!no_error &&
+       /* target error checking */
+       !legal_teximage_target(ctx, dims, target)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
+                  func, dims, _mesa_enum_to_string(target));
+      return;
+   }
+
    if (!texObj)
       texObj = _mesa_get_current_tex_object(ctx, target);
 
    if (!no_error) {
-      /* target error checking */
-      if (!legal_teximage_target(ctx, dims, target)) {
-         _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
-                     func, dims, _mesa_enum_to_string(target));
-         return;
-      }
-
       /* general error checking */
       if (compressed) {
          if (compressed_texture_error_check(ctx, dims, target, texObj,
@@ -5376,6 +5386,26 @@ _mesa_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level,
 }
 
 
+void GLAPIENTRY
+_mesa_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level,
+                                   GLenum internalFormat, GLsizei width,
+                                   GLint border, GLsizei imageSize,
+                                   const GLvoid *pixels)
+{
+   struct gl_texture_object*  texObj;
+   GET_CURRENT_CONTEXT(ctx);
+
+   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
+                                                   texunit - GL_TEXTURE0,
+                                                   true,
+                                                   "glCompressedMultiTexImage1DEXT");
+   if (!texObj)
+      return;
+   teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat,
+            width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
+}
+
+
 void GLAPIENTRY
 _mesa_CompressedTexImage2D(GLenum target, GLint level,
                               GLenum internalFormat, GLsizei width,
@@ -5406,6 +5436,26 @@ _mesa_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level,
 }
 
 
+void GLAPIENTRY
+_mesa_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level,
+                                   GLenum internalFormat, GLsizei width,
+                                   GLsizei height, GLint border, GLsizei imageSize,
+                                   const GLvoid *pixels)
+{
+   struct gl_texture_object*  texObj;
+   GET_CURRENT_CONTEXT(ctx);
+
+   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
+                                                   texunit - GL_TEXTURE0,
+                                                   true,
+                                                   "glCompressedMultiTexImage2DEXT");
+   if (!texObj)
+      return;
+   teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat,
+            width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
+}
+
+
 void GLAPIENTRY
 _mesa_CompressedTexImage3D(GLenum target, GLint level,
                               GLenum internalFormat, GLsizei width,
@@ -5436,6 +5486,25 @@ _mesa_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level,
 }
 
 
+void GLAPIENTRY
+_mesa_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level,
+                                   GLenum internalFormat, GLsizei width,
+                                   GLsizei height, GLsizei depth, GLint border,
+                                   GLsizei imageSize, const GLvoid *pixels)
+{
+   struct gl_texture_object*  texObj;
+   GET_CURRENT_CONTEXT(ctx);
+
+   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
+                                                   texunit - GL_TEXTURE0,
+                                                   true,
+                                                   "glCompressedMultiTexImage3DEXT");
+   if (!texObj)
+      return;
+   teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat,
+            width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false);
+}
+
 
 void GLAPIENTRY
 _mesa_CompressedTexImage1D_no_error(GLenum target, GLint level,
@@ -5516,18 +5585,20 @@ enum tex_mode {
    TEX_MODE_DSA_ERROR,
    /* Use the specified texture name + target */
    TEX_MODE_EXT_DSA_TEXTURE,
+   /* Use the specified texture unit + target */
+   TEX_MODE_EXT_DSA_TEXUNIT,
 };
 
 
 static void
-compressed_tex_sub_image(unsigned dim, GLenum target, GLuint texture,
+compressed_tex_sub_image(unsigned dim, GLenum target, GLuint textureOrIndex,
                          GLint level, GLint xoffset, GLint yoffset,
                          GLint zoffset, GLsizei width, GLsizei height,
                          GLsizei depth, GLenum format, GLsizei imageSize,
                          const GLvoid *data, enum tex_mode mode,
                          const char *caller)
 {
-   struct gl_texture_object *texObj;
+   struct gl_texture_object *texObj = NULL;
    struct gl_texture_image *texImage;
    bool no_error = false;
    GET_CURRENT_CONTEXT(ctx);
@@ -5535,34 +5606,35 @@ compressed_tex_sub_image(unsigned dim, GLenum target, GLuint texture,
    switch (mode) {
       case TEX_MODE_DSA_ERROR:
          assert(target == 0);
-         texObj = _mesa_lookup_texture_err(ctx, texture, caller);
+         texObj = _mesa_lookup_texture_err(ctx, textureOrIndex, caller);
          if (texObj)
             target = texObj->Target;
          break;
       case TEX_MODE_DSA_NO_ERROR:
          assert(target == 0);
-         texObj = _mesa_lookup_texture(ctx, texture);
+         texObj = _mesa_lookup_texture(ctx, textureOrIndex);
          if (texObj)
             target = texObj->Target;
          no_error = true;
          break;
       case TEX_MODE_EXT_DSA_TEXTURE:
-         texObj = _mesa_lookup_or_create_texture(ctx, target, texture,
+         texObj = _mesa_lookup_or_create_texture(ctx, target, textureOrIndex,
                                                  false, true, caller);
          break;
-      case TEX_MODE_CURRENT_ERROR:
-         no_error = true;
+      case TEX_MODE_EXT_DSA_TEXUNIT:
+         texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
+                                                         textureOrIndex,
+                                                         false,
+                                                         caller);
+         break;
       case TEX_MODE_CURRENT_NO_ERROR:
+         no_error = true;
+      case TEX_MODE_CURRENT_ERROR:
       default:
-         assert(texture == 0);
-         texObj = _mesa_get_current_tex_object(ctx, target);
+         assert(textureOrIndex == 0);
          break;
    }
 
-   if (!texObj)
-      return;
-
-
    if (!no_error &&
        compressed_subtexture_target_check(ctx, target, dim, format,
                                           mode == TEX_MODE_DSA_ERROR,
@@ -5570,7 +5642,12 @@ compressed_tex_sub_image(unsigned dim, GLenum target, GLuint texture,
       return;
    }
 
-   if (!no_error && !texObj)
+   if (mode == TEX_MODE_CURRENT_NO_ERROR ||
+       mode == TEX_MODE_CURRENT_ERROR) {
+      texObj = _mesa_get_current_tex_object(ctx, target);
+   }
+
+   if (!texObj)
       return;
 
    if (!no_error &&
@@ -5695,6 +5772,20 @@ _mesa_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target,
 }
 
 
+void GLAPIENTRY
+_mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target,
+                                      GLint level, GLint xoffset,
+                                      GLsizei width, GLenum format,
+                                      GLsizei imageSize, const GLvoid *data)
+{
+   compressed_tex_sub_image(1, target, texunit - GL_TEXTURE0, level,
+                            xoffset, 0, 0, width, 1, 1, format, imageSize,
+                            data,
+                            TEX_MODE_EXT_DSA_TEXUNIT,
+                            "glCompressedMultiTexSubImage1DEXT");
+}
+
+
 void GLAPIENTRY
 _mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level,
                                        GLint xoffset, GLint yoffset,
@@ -5739,6 +5830,20 @@ _mesa_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target,
 }
 
 
+void GLAPIENTRY
+_mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target,
+                                      GLint level, GLint xoffset, GLint yoffset,
+                                      GLsizei width, GLsizei height, GLenum format,
+                                      GLsizei imageSize, const GLvoid *data)
+{
+   compressed_tex_sub_image(2, target, texunit - GL_TEXTURE0, level,
+                            xoffset, yoffset, 0, width, height, 1, format,
+                            imageSize, data,
+                            TEX_MODE_EXT_DSA_TEXUNIT,
+                            "glCompressedMultiTexSubImage2DEXT");
+}
+
+
 void GLAPIENTRY
 _mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level,
                                            GLint xoffset, GLint yoffset,
@@ -5840,6 +5945,21 @@ _mesa_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target,
 }
 
 
+void GLAPIENTRY
+_mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target,
+                                      GLint level, GLint xoffset, GLint yoffset,
+                                      GLint zoffset, GLsizei width, GLsizei height,
+                                      GLsizei depth, GLenum format,
+                                      GLsizei imageSize, const GLvoid *data)
+{
+   compressed_tex_sub_image(3, target, texunit - GL_TEXTURE0, level,
+                            xoffset, yoffset, zoffset, width, height, depth,
+                            format, imageSize, data,
+                            TEX_MODE_EXT_DSA_TEXUNIT,
+                            "glCompressedMultiTexSubImage3DEXT");
+}
+
+
 mesa_format
 _mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
 {