OSDN Git Service

Fixed format validations
authorAlexis Hetu <sugoi@google.com>
Thu, 15 Oct 2015 21:22:57 +0000 (17:22 -0400)
committerAlexis Hétu <sugoi@google.com>
Fri, 18 Dec 2015 19:50:34 +0000 (19:50 +0000)
Format validations were failing if the exact same format
wasn't used between different texture related calls to the
same texture, even when the formats were equivalent, so I
added a GetSizedInternalFormat function based on a format
map (courtesy of Angle). The validation checks were also
unified in utilities.cpp and used wherever texture formats
were used, to make sure Image objects used in Texture
objects always use the sized format, so that format
comparisons work properly.

Change-Id: I72fc8fb1b0f135ac679c274866e5b8e223541e7f
Reviewed-on: https://swiftshader-review.googlesource.com/4082
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/common/Image.cpp
src/OpenGL/libGL/Texture.cpp
src/OpenGL/libGLES_CM/Texture.cpp
src/OpenGL/libGLESv2/Texture.cpp
src/OpenGL/libGLESv2/libGLESv2.cpp
src/OpenGL/libGLESv2/libGLESv3.cpp
src/OpenGL/libGLESv2/utilities.cpp
src/OpenGL/libGLESv2/utilities.h

index 32c3744..9799f98 100644 (file)
@@ -468,6 +468,7 @@ namespace egl
                        }
                        break;
                case GL_BGRA_EXT:
+               case GL_BGRA8_EXT:
                        switch(type)
                        {
                        case GL_UNSIGNED_BYTE:          return sw::FORMAT_A8R8G8B8;
@@ -735,6 +736,7 @@ namespace egl
                        case GL_RGBA_INTEGER:
                                return sw::FORMAT_A8B8G8R8UI;
                        case GL_BGRA_EXT:
+                       case GL_BGRA8_EXT:
                                return sw::FORMAT_A8R8G8B8;
                        case GL_ALPHA:
                        case GL_ALPHA8_EXT:
@@ -923,7 +925,8 @@ namespace egl
                        case GL_SRGB8_ALPHA8:
                        case GL_RGBA:            return sizeof(unsigned char) * 4;
                        case GL_RGBA_INTEGER:    return sizeof(unsigned char) * 4;
-                       case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
+                       case GL_BGRA_EXT:
+                       case GL_BGRA8_EXT:       return sizeof(unsigned char)* 4;
                        default: UNREACHABLE(format);
                        }
                        break;
@@ -1226,6 +1229,7 @@ namespace egl
                                        case GL_RGBA:
                                        case GL_RGBA_INTEGER:
                                        case GL_BGRA_EXT:
+                                       case GL_BGRA8_EXT:
                                                LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
                                                break;
                                        default: UNREACHABLE(format);
@@ -1267,6 +1271,7 @@ namespace egl
                                        case GL_RGBA:
                                        case GL_RGBA_INTEGER:
                                        case GL_BGRA_EXT:
+                                       case GL_BGRA8_EXT:
                                                LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
                                                break;
                                        case GL_SRGB8:
@@ -1441,6 +1446,7 @@ namespace egl
                                        case GL_RGBA:
                                        case GL_RGBA_INTEGER:
                                        case GL_BGRA_EXT:
+                                       case GL_BGRA8_EXT:
                                                LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
                                                break;
                                        default: UNREACHABLE(format);
@@ -1471,6 +1477,7 @@ namespace egl
                                        case GL_RGBA:
                                        case GL_RGBA_INTEGER:
                                        case GL_BGRA_EXT:
+                                       case GL_BGRA8_EXT:
                                                LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
                                                break;
                                        case GL_DEPTH_COMPONENT:
@@ -1505,6 +1512,7 @@ namespace egl
                                        case GL_RGBA:
                                        case GL_RGBA_INTEGER:
                                        case GL_BGRA_EXT:
+                                       case GL_BGRA8_EXT:
                                                LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
                                                break;
                                        default: UNREACHABLE(format);
@@ -1535,6 +1543,7 @@ namespace egl
                                        case GL_RGBA:
                                        case GL_RGBA_INTEGER:
                                        case GL_BGRA_EXT:
+                                       case GL_BGRA8_EXT:
                                                LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
                                                break;
                                        case GL_DEPTH_COMPONENT16:
index e6b761d..162599c 100644 (file)
@@ -339,13 +339,13 @@ GLsizei Texture2D::getHeight(GLenum target, GLint level) const
 GLenum Texture2D::getFormat(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);\r
-    return image[level] ? image[level]->getFormat() : 0;\r
+       return image[level] ? image[level]->getFormat() : GL_NONE;\r
 }\r
 \r
 GLenum Texture2D::getType(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);\r
-    return image[level] ? image[level]->getType() : 0;\r
+       return image[level] ? image[level]->getType() : GL_NONE;\r
 }\r
 \r
 sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const\r
@@ -716,13 +716,13 @@ GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
 GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const\r
 {\r
        int face = CubeFaceIndex(target);\r
-    return image[face][level] ? image[face][level]->getFormat() : 0;\r
+       return image[face][level] ? image[face][level]->getFormat() : GL_NONE;\r
 }\r
 \r
 GLenum TextureCubeMap::getType(GLenum target, GLint level) const\r
 {\r
        int face = CubeFaceIndex(target);\r
-    return image[face][level] ? image[face][level]->getType() : 0;\r
+       return image[face][level] ? image[face][level]->getType() : GL_NONE;\r
 }\r
 \r
 sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const\r
index 13b52c0..0741b03 100644 (file)
@@ -407,13 +407,13 @@ GLsizei Texture2D::getHeight(GLenum target, GLint level) const
 GLenum Texture2D::getFormat(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == GL_TEXTURE_2D);\r
-    return image[level] ? image[level]->getFormat() : 0;\r
+       return image[level] ? image[level]->getFormat() : GL_NONE;\r
 }\r
 \r
 GLenum Texture2D::getType(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == GL_TEXTURE_2D);\r
-    return image[level] ? image[level]->getType() : 0;\r
+       return image[level] ? image[level]->getType() : GL_NONE;\r
 }\r
 \r
 sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const\r
index 79bc28e..7c216b9 100644 (file)
@@ -578,13 +578,13 @@ GLsizei Texture2D::getHeight(GLenum target, GLint level) const
 GLenum Texture2D::getFormat(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == GL_TEXTURE_2D);\r
-    return image[level] ? image[level]->getFormat() : 0;\r
+       return image[level] ? image[level]->getFormat() : GL_NONE;\r
 }\r
 \r
 GLenum Texture2D::getType(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == GL_TEXTURE_2D);\r
-    return image[level] ? image[level]->getType() : 0;\r
+       return image[level] ? image[level]->getType() : GL_NONE;\r
 }\r
 \r
 sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const\r
@@ -678,7 +678,8 @@ void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
                image[level]->unbind(this);\r
        }\r
 \r
-       image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+       GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+       image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
 \r
        if(!image[level])\r
        {\r
@@ -713,7 +714,8 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
                image[level]->unbind(this);\r
        }\r
 \r
-       image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+       GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+       image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
 \r
        if(!image[level])\r
        {\r
@@ -733,7 +735,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
                sw::SliceRect sourceRect(x, y, x + width, y + height, 0);\r
                sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());\r
 \r
-        copy(renderTarget, sourceRect, format, 0, 0, 0, image[level]);\r
+               copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[level]);\r
     }\r
 \r
        renderTarget->release();\r
@@ -1079,7 +1081,8 @@ void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum forma
                image[face][level]->unbind(this);\r
        }\r
 \r
-       image[face][level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+       GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+       image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
 \r
        if(!image[face][level])\r
        {\r
@@ -1247,7 +1250,8 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
                image[face][level]->unbind(this);\r
        }\r
 \r
-       image[face][level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+       GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+       image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
 \r
        if(!image[face][level])\r
        {\r
@@ -1267,7 +1271,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
                sw::SliceRect sourceRect(x, y, x + width, y + height, 0);\r
                sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());\r
         \r
-        copy(renderTarget, sourceRect, format, 0, 0, 0, image[face][level]);\r
+               copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[face][level]);\r
     }\r
 \r
        renderTarget->release();\r
@@ -1484,13 +1488,13 @@ GLsizei Texture3D::getDepth(GLenum target, GLint level) const
 GLenum Texture3D::getFormat(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == getTarget());\r
-       return image[level] ? image[level]->getFormat() : 0;\r
+       return image[level] ? image[level]->getFormat() : GL_NONE;\r
 }\r
 \r
 GLenum Texture3D::getType(GLenum target, GLint level) const\r
 {\r
        ASSERT(target == getTarget());\r
-       return image[level] ? image[level]->getType() : 0;\r
+       return image[level] ? image[level]->getType() : GL_NONE;\r
 }\r
 \r
 sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const\r
@@ -1580,7 +1584,8 @@ void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
                image[level]->unbind(this);\r
        }\r
 \r
-       image[level] = new egl::Image(this, width, height, depth, format, GL_UNSIGNED_BYTE);\r
+       GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+       image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
 \r
        if(!image[level])\r
        {\r
@@ -1592,7 +1597,7 @@ void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
 \r
 void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)\r
 {\r
-       Texture::subImage(xoffset, yoffset, zoffset, width, height, format, depth, type, unpackInfo, pixels, image[level]);\r
+       Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels, image[level]);\r
 }\r
 \r
 void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)\r
@@ -1615,7 +1620,8 @@ void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z,
                image[level]->unbind(this);\r
        }\r
 \r
-       image[level] = new egl::Image(this, width, height, depth, format, GL_UNSIGNED_BYTE);\r
+       GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+       image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
 \r
        if(!image[level])\r
        {\r
@@ -1636,7 +1642,7 @@ void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z,
                sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());\r
                for(GLint sliceZ = 0; sliceZ < depth; ++sliceZ, ++sourceRect.slice)\r
                {\r
-                       copy(renderTarget, sourceRect, format, 0, 0, sliceZ, image[level]);\r
+                       copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, sliceZ, image[level]);\r
                }\r
        }\r
 \r
index 44bf326..b5364b9 100644 (file)
@@ -57,84 +57,12 @@ static bool validImageSize(GLint level, GLsizei width, GLsizei height)
        return true;\r
 }\r
 \r
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)\r
-{\r
-       if(!texture)\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(compressed != texture->isCompressed(target, level))\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(format != GL_NONE && format != texture->getFormat(target, level))\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(compressed)\r
-       {\r
-               if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
-                  (height % 4 != 0 && height != texture->getHeight(target, 0)))\r
-               {\r
-                       return error(GL_INVALID_OPERATION, false);\r
-               }\r
-       }\r
-\r
-       if(xoffset + width > texture->getWidth(target, level) ||\r
-          yoffset + height > texture->getHeight(target, level))\r
-       {\r
-               return error(GL_INVALID_VALUE, false);\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)\r
-{\r
-       if(!texture)\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(compressed != texture->isCompressed(target, level))\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(format != GL_NONE && format != texture->getFormat(target, level))\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(compressed)\r
-       {\r
-               if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
-                  (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
-                  (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
-               {\r
-                       return error(GL_INVALID_OPERATION, false);\r
-               }\r
-       }\r
-\r
-       if(xoffset + width > texture->getWidth(target, level) ||\r
-          yoffset + height > texture->getHeight(target, level) ||\r
-          zoffset + depth > texture->getDepth(target, level))\r
-       {\r
-               return error(GL_INVALID_VALUE, false);\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)\r
 {\r
-       GLenum formatError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
-       if(formatError != GL_NONE)\r
+       GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
+       if(validationError != GL_NONE)\r
        {\r
-               return error(formatError, false);\r
+               return error(validationError, false);\r
        }\r
 \r
        // [OpenGL ES 2.0.24] table 3.9\r
@@ -970,10 +898,10 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs
                return error(GL_INVALID_OPERATION);\r
        default:\r
                {\r
-                       GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
-                       if(formatError != GL_NONE)\r
+                       GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
+                       if(validationError != GL_NONE)\r
                        {\r
-                               return error(formatError);\r
+                               return error(validationError);\r
                        }\r
                }\r
                break;\r
@@ -1082,10 +1010,10 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo
                return error(GL_INVALID_VALUE);\r
        }\r
 \r
-       GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
-       if(formatError != GL_NONE)\r
+       GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
+       if(validationError != GL_NONE)\r
        {\r
-               return error(formatError);\r
+               return error(validationError);\r
        }\r
 \r
        if(width == 0 || height == 0 || data == NULL)\r
@@ -1113,22 +1041,36 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo
                        return error(GL_INVALID_OPERATION);\r
                }\r
 \r
+               GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);\r
+\r
                if(target == GL_TEXTURE_2D)\r
                {\r
                        es2::Texture2D *texture = context->getTexture2D();\r
 \r
-                       if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))\r
+                       GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+                       if(validationError == GL_NONE)\r
                        {\r
-                               texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);\r
+                               texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);\r
+                       }\r
+                       else\r
+                       {\r
+                               return error(validationError);\r
                        }\r
                }\r
                else if(es2::IsCubemapTextureTarget(target))\r
                {\r
                        es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
 \r
-                       if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))\r
+                       GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+                       if(validationError == GL_NONE)\r
+                       {\r
+                               texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);\r
+                       }\r
+                       else\r
                        {\r
-                               texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);\r
+                               return error(validationError);\r
                        }\r
                }\r
                else UNREACHABLE(target);\r
@@ -1293,9 +1235,10 @@ void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                }\r
                else UNREACHABLE(target);\r
 \r
-               if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))\r
+               GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);\r
+               if(validationError != GL_NONE)\r
                {\r
-                       return;\r
+                       return error(validationError);\r
                }\r
 \r
                texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);\r
@@ -5184,10 +5127,10 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
                        }\r
                }\r
 \r
-               GLenum formatError = ValidateCompressedFormat(format, clientVersion, false);\r
-               if(formatError != GL_NONE)\r
+               GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);\r
+               if(validationError != GL_NONE)\r
                {\r
-                       return error(formatError);\r
+                       return error(validationError);\r
                }\r
 \r
                switch(format)\r
@@ -5904,6 +5847,8 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
                        return error(GL_INVALID_ENUM);\r
                }\r
 \r
+               GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
                if(target == GL_TEXTURE_2D)\r
                {\r
                        es2::Texture2D *texture = context->getTexture2D();\r
@@ -5913,7 +5858,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
                                return error(GL_INVALID_OPERATION);\r
                        }\r
 \r
-                       texture->setImage(level, width, height, format, type, context->getUnpackInfo(), pixels);\r
+                       texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
                }\r
                else\r
                {\r
@@ -5924,7 +5869,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
                                return error(GL_INVALID_OPERATION);\r
                        }\r
 \r
-                       texture->setImage(target, level, width, height, format, type, context->getUnpackInfo(), pixels);\r
+                       texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
                }\r
        }\r
 }\r
@@ -6281,22 +6226,36 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
                        return error(GL_INVALID_VALUE);\r
                }\r
 \r
+               GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
                if(target == GL_TEXTURE_2D)\r
                {\r
                        es2::Texture2D *texture = context->getTexture2D();\r
 \r
-                       if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))\r
+                       GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+                       if(validationError == GL_NONE)\r
                        {\r
-                               texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), pixels);\r
+                               texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+                       }\r
+                       else\r
+                       {\r
+                               return error(validationError);\r
                        }\r
                }\r
                else if(es2::IsCubemapTextureTarget(target))\r
                {\r
                        es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
 \r
-                       if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))\r
+                       GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+                       if(validationError == GL_NONE)\r
                        {\r
-                               texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), pixels);\r
+                               texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+                       }\r
+                       else\r
+                       {\r
+                               return error(validationError);\r
                        }\r
                }\r
                else UNREACHABLE(target);\r
@@ -7112,7 +7071,7 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi
                        return error(GL_INVALID_OPERATION);\r
                }\r
 \r
-               texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), pixels);\r
+               texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);\r
        }\r
 }\r
 \r
@@ -7152,9 +7111,16 @@ void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset,
        {\r
                es2::Texture3D *texture = context->getTexture3D();\r
 \r
-               if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))\r
+               GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
+               GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);\r
+               if(validationError == GL_NONE)\r
                {\r
-                       texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), pixels);\r
+                       texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+               }\r
+               else\r
+               {\r
+                       return error(validationError);\r
                }\r
        }\r
 }\r
@@ -7198,9 +7164,11 @@ void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffs
 \r
                es2::Texture3D *texture = context->getTexture3D();\r
 \r
-               if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))\r
+               GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);\r
+\r
+               if(validationError != GL_NONE)\r
                {\r
-                       return;\r
+                       return error(validationError);\r
                }\r
 \r
                texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);\r
@@ -7242,10 +7210,10 @@ void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat,
                return error(GL_INVALID_OPERATION);\r
        default:\r
                {\r
-                       GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
-                       if(formatError != GL_NONE)\r
+                       GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
+                       if(validationError != GL_NONE)\r
                        {\r
-                               return error(formatError);\r
+                               return error(validationError);\r
                        }\r
                }\r
        }\r
@@ -7290,10 +7258,10 @@ void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint
                return error(GL_INVALID_VALUE);\r
        }\r
 \r
-       GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
-       if(formatError != GL_NONE)\r
+       GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
+       if(validationError != GL_NONE)\r
        {\r
-               return error(formatError);\r
+               return error(validationError);\r
        }\r
 \r
        if(width == 0 || height == 0 || depth == 0 || data == NULL)\r
index 488f529..b2743df 100644 (file)
@@ -46,49 +46,13 @@ static bool validImageSize(GLint level, GLsizei width, GLsizei height)
        return true;\r
 }\r
 \r
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)\r
-{\r
-       if(!texture)\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(compressed != texture->isCompressed(target, level))\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(format != GL_NONE && format != texture->getFormat(target, level))\r
-       {\r
-               return error(GL_INVALID_OPERATION, false);\r
-       }\r
-\r
-       if(compressed)\r
-       {\r
-               if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
-                  (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
-                  (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
-               {\r
-                       return error(GL_INVALID_OPERATION, false);\r
-               }\r
-       }\r
-\r
-       if(xoffset + width > texture->getWidth(target, level) ||\r
-               yoffset + height > texture->getHeight(target, level) ||\r
-               zoffset + depth > texture->getDepth(target, level))\r
-       {\r
-               return error(GL_INVALID_VALUE, false);\r
-       }\r
-\r
-       return true;\r
-}\r
 \r
 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)\r
 {\r
-       GLenum formatError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
-       if(formatError != GL_NONE)\r
+       GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
+       if(validationError != GL_NONE)\r
        {\r
-               return error(formatError, false);\r
+               return error(validationError, false);\r
        }\r
 \r
        switch(textureFormat)\r
@@ -706,7 +670,7 @@ GL_APICALL void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint inter
                        return error(GL_INVALID_OPERATION);\r
                }\r
 \r
-               texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), pixels);\r
+               texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);\r
        }\r
 }\r
 \r
@@ -747,9 +711,16 @@ GL_APICALL void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xo
        {\r
                es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();\r
 \r
-               if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))\r
+               GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
+               GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);\r
+               if(validationError == GL_NONE)\r
                {\r
-                       texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), pixels);\r
+                       texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+               }\r
+               else\r
+               {\r
+                       return error(validationError);\r
                }\r
        }\r
 }\r
@@ -800,9 +771,10 @@ GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLin
                GLenum colorbufferFormat = source->getFormat();\r
                es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();\r
 \r
-               if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))\r
+               GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);\r
+               if(validationError != GL_NONE)\r
                {\r
-                       return;\r
+                       return error(validationError);\r
                }\r
 \r
                GLenum textureFormat = texture->getFormat(target, level);\r
@@ -852,10 +824,10 @@ GL_APICALL void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, G
                return error(GL_INVALID_OPERATION);\r
        default:\r
                {\r
-                       GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
-                       if(formatError != GL_NONE)\r
+                       GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
+                       if(validationError != GL_NONE)\r
                        {\r
-                               return error(formatError);\r
+                               return error(validationError);\r
                        }\r
                }\r
        }\r
@@ -901,10 +873,10 @@ GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level
                return error(GL_INVALID_VALUE);\r
        }\r
 \r
-       GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
-       if(formatError != GL_NONE)\r
+       GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
+       if(validationError != GL_NONE)\r
        {\r
-               return error(formatError);\r
+               return error(validationError);\r
        }\r
 \r
        if(width == 0 || height == 0 || depth == 0 || data == NULL)\r
@@ -3875,7 +3847,7 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
 \r
                        for(int level = 0; level < levels; ++level)\r
                        {\r
-                               texture->setImage(level, width, height, internalformat, type, context->getUnpackInfo(), NULL);\r
+                               texture->setImage(level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
                                width = std::max(1, (width / 2));\r
                                height = std::max(1, (height / 2));\r
                        }\r
@@ -3894,7 +3866,7 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
                        {\r
                                for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)\r
                                {\r
-                                       texture->setImage(face, level, width, height, internalformat, type, context->getUnpackInfo(), NULL);\r
+                                       texture->setImage(face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
                                }\r
                                width = std::max(1, (width / 2));\r
                                height = std::max(1, (height / 2));\r
@@ -3945,7 +3917,7 @@ GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum
 \r
                        for(int level = 0; level < levels; ++level)\r
                        {\r
-                               texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), NULL);\r
+                               texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
                                width = std::max(1, (width / 2));\r
                                height = std::max(1, (height / 2));\r
                                depth = std::max(1, (depth / 2));\r
@@ -3970,7 +3942,7 @@ GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum
                        {\r
                                for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)\r
                                {\r
-                                       texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), NULL);\r
+                                       texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
                                }\r
                                width = std::max(1, (width / 2));\r
                                height = std::max(1, (height / 2));\r
index 4896b27..0b83802 100644 (file)
 \r
 namespace es2\r
 {\r
+       // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation\r
+       // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid\r
+       // format and type combinations.\r
+\r
+       typedef std::pair<GLenum, GLenum> FormatTypePair;\r
+       typedef std::pair<FormatTypePair, GLenum> FormatPair;\r
+       typedef std::map<FormatTypePair, GLenum> FormatMap;\r
+\r
+       // A helper function to insert data into the format map with fewer characters.\r
+       static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)\r
+       {\r
+               map->insert(FormatPair(FormatTypePair(format, type), internalFormat));\r
+       }\r
+\r
+       FormatMap BuildFormatMap()\r
+       {\r
+               static const GLenum GL_BGRA4_ANGLEX = 0x6ABC;\r
+               static const GLenum GL_BGR5_A1_ANGLEX = 0x6ABD;\r
+\r
+               FormatMap map;\r
+\r
+               //                       | Format | Type | Internal format |\r
+               InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);\r
+               InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);\r
+               InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);\r
+               InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);\r
+               InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);\r
+               InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);\r
+               InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);\r
+               InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);\r
+\r
+               InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);\r
+               InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);\r
+               InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);\r
+               InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);\r
+               InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);\r
+               InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);\r
+               InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);\r
+\r
+               InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);\r
+               InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);\r
+               InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);\r
+               InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);\r
+               InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);\r
+               InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);\r
+               InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);\r
+               InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);\r
+\r
+               InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);\r
+               InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);\r
+               InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);\r
+               InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);\r
+               InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);\r
+               InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);\r
+\r
+               InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);\r
+               InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);\r
+               InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);\r
+               InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);\r
+               InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);\r
+\r
+               InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);\r
+               InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);\r
+               InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);\r
+               InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);\r
+               InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);\r
+               InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);\r
+\r
+               InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);\r
+               InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);\r
+               InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);\r
+               InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);\r
+               InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);\r
+\r
+               InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);\r
+               InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);\r
+               InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);\r
+               InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);\r
+               InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);\r
+               InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);\r
+\r
+               InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);\r
+               InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);\r
+               InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);\r
+               InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);\r
+               InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);\r
+               InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);\r
+               InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);\r
+               InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);\r
+               InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);\r
+               InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);\r
+               InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);\r
+               InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);\r
+\r
+               InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);\r
+               InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);\r
+               InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);\r
+\r
+               InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);\r
+               InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);\r
+\r
+               InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);\r
+               InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);\r
+               InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);\r
+               InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);\r
+\r
+               InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);\r
+               InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);\r
+               InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);\r
+\r
+               InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);\r
+\r
+               InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);\r
+               InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);\r
+\r
+               return map;\r
+       }\r
+\r
+       GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)\r
+       {\r
+               switch(internalFormat)\r
+               {\r
+               case GL_ALPHA:\r
+               case GL_LUMINANCE:\r
+               case GL_LUMINANCE_ALPHA:\r
+               case GL_RED:\r
+               case GL_RG:\r
+               case GL_RGB:\r
+               case GL_RGBA:\r
+               case GL_RED_INTEGER:\r
+               case GL_RG_INTEGER:\r
+               case GL_RGB_INTEGER:\r
+               case GL_RGBA_INTEGER:\r
+               case GL_BGRA_EXT:\r
+               case GL_DEPTH_COMPONENT:\r
+               case GL_DEPTH_STENCIL:\r
+               case GL_SRGB_EXT:\r
+               case GL_SRGB_ALPHA_EXT:\r
+                       {\r
+                               static const FormatMap formatMap = BuildFormatMap();\r
+                               FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));\r
+                               return (iter != formatMap.end()) ? iter->second : GL_NONE;\r
+                       }\r
+               default:\r
+                       return internalFormat;\r
+               }\r
+       }\r
+\r
        unsigned int UniformComponentCount(GLenum type)\r
        {\r
                switch(type)\r
@@ -377,6 +525,78 @@ namespace es2
                }\r
        }\r
 \r
+       GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)\r
+       {\r
+               if(!texture)\r
+               {\r
+                       return GL_INVALID_OPERATION;\r
+               }\r
+\r
+               if(compressed != texture->isCompressed(target, level))\r
+               {\r
+                       return GL_INVALID_OPERATION;\r
+               }\r
+\r
+               if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))\r
+               {\r
+                       return GL_INVALID_OPERATION;\r
+               }\r
+\r
+               if(compressed)\r
+               {\r
+                       if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
+                          (height % 4 != 0 && height != texture->getHeight(target, 0)))\r
+                       {\r
+                               return GL_INVALID_OPERATION;\r
+                       }\r
+               }\r
+\r
+               if(xoffset + width > texture->getWidth(target, level) ||\r
+                  yoffset + height > texture->getHeight(target, level))\r
+               {\r
+                       return GL_INVALID_VALUE;\r
+               }\r
+\r
+               return GL_NONE;\r
+       }\r
+\r
+       GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)\r
+       {\r
+               if(!texture)\r
+               {\r
+                       return GL_INVALID_OPERATION;\r
+               }\r
+\r
+               if(compressed != texture->isCompressed(target, level))\r
+               {\r
+                       return GL_INVALID_OPERATION;\r
+               }\r
+\r
+               if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))\r
+               {\r
+                       return GL_INVALID_OPERATION;\r
+               }\r
+\r
+               if(compressed)\r
+               {\r
+                       if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
+                          (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
+                          (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
+                       {\r
+                               return GL_INVALID_OPERATION;\r
+                       }\r
+               }\r
+\r
+               if(xoffset + width > texture->getWidth(target, level) ||\r
+                  yoffset + height > texture->getHeight(target, level) ||\r
+                  zoffset + depth > texture->getDepth(target, level))\r
+               {\r
+                       return GL_INVALID_VALUE;\r
+               }\r
+\r
+               return GL_NONE;\r
+       }\r
+\r
        bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion)\r
        {\r
                switch(format)\r
@@ -452,7 +672,9 @@ namespace es2
        bool IsStencilTexture(GLenum format)\r
        {\r
                return format == GL_STENCIL_INDEX_OES ||\r
-                      format == GL_DEPTH_STENCIL_OES;\r
+                      format == GL_DEPTH_STENCIL_OES ||\r
+                      format == GL_DEPTH24_STENCIL8 ||\r
+                      format == GL_DEPTH32F_STENCIL8;\r
        }\r
 \r
        bool IsCubemapTextureTarget(GLenum target)\r
index 7354f95..db4930d 100644 (file)
@@ -41,7 +41,10 @@ namespace es2
        GLint floatToInt(GLfloat value);\r
 \r
        bool IsCompressed(GLenum format, egl::GLint clientVersion);\r
+       GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);\r
        GLenum ValidateCompressedFormat(GLenum format, egl::GLint clientVersion, bool expectCompressedFormats);\r
+       GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);\r
+       GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);\r
        bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion);\r
        bool IsDepthTexture(GLenum format);\r
        bool IsStencilTexture(GLenum format);\r