OSDN Git Service

Fix internal format handling for OpenGL ES 1.1.
authorNicolas Capens <capn@google.com>
Mon, 26 Feb 2018 22:47:06 +0000 (17:47 -0500)
committerNicolas Capens <nicolascapens@google.com>
Tue, 27 Feb 2018 19:32:48 +0000 (19:32 +0000)
With the egl::Image class now only storing the sized internal format,
some OpenGL ES 1.1 functionality broke because it was still expecting a
base format.

Change-Id: Ib41e91f371a06b2a09471ea45dd1f8f56b94091f
Reviewed-on: https://swiftshader-review.googlesource.com/17468
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
src/OpenGL/libGLES_CM/Context.cpp
src/OpenGL/libGLES_CM/Renderbuffer.cpp
src/OpenGL/libGLES_CM/Renderbuffer.h
src/OpenGL/libGLES_CM/Texture.cpp
src/OpenGL/libGLES_CM/Texture.h
src/OpenGL/libGLES_CM/libGLES_CM.cpp
src/OpenGL/libGLES_CM/utilities.cpp
src/OpenGL/libGLES_CM/utilities.h
src/OpenGL/libGLESv2/Texture.cpp
src/OpenGL/libGLESv2/Texture.h

index 91f865c..99abd4e 100644 (file)
@@ -2444,12 +2444,12 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                unsigned short *dest16 = (unsigned short*)dest;
                unsigned int *dest32 = (unsigned int*)dest;
 
-               if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&
+               if(renderTarget->getExternalFormat() == sw::FORMAT_A8B8G8R8 &&
                   format == GL_RGBA && type == GL_UNSIGNED_BYTE)
                {
                        memcpy(dest, source, (rect.x1 - rect.x0) * 4);
                }
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+               else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
                                format == GL_RGBA && type == GL_UNSIGNED_BYTE)
                {
                        for(int i = 0; i < rect.x1 - rect.x0; i++)
@@ -2459,7 +2459,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                                dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
                        }
                }
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+               else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
                                format == GL_RGBA && type == GL_UNSIGNED_BYTE)
                {
                        for(int i = 0; i < rect.x1 - rect.x0; i++)
@@ -2469,7 +2469,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                                dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
                        }
                }
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+               else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
                                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
                {
                        for(int i = 0; i < rect.x1 - rect.x0; i++)
@@ -2479,17 +2479,17 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                                dest32[i] = xrgb | 0xFF000000;
                        }
                }
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+               else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
                                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
                {
                        memcpy(dest, source, (rect.x1 - rect.x0) * 4);
                }
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
+               else if(renderTarget->getExternalFormat() == sw::FORMAT_A1R5G5B5 &&
                                format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
                {
                        memcpy(dest, source, (rect.x1 - rect.x0) * 2);
                }
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
+               else if(renderTarget->getExternalFormat() == sw::FORMAT_R5G6B5 &&
                                format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
                {
                        memcpy(dest, source, (rect.x1 - rect.x0) * 2);
@@ -2503,7 +2503,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                                float b;
                                float a;
 
-                               switch(renderTarget->getInternalFormat())
+                               switch(renderTarget->getExternalFormat())
                                {
                                case sw::FORMAT_R5G6B5:
                                        {
@@ -2577,7 +2577,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                                        break;
                                default:
                                        UNIMPLEMENTED();   // FIXME
-                                       UNREACHABLE(renderTarget->getInternalFormat());
+                                       UNREACHABLE(renderTarget->getExternalFormat());
                                }
 
                                switch(format)
index a0d64cc..c832443 100644 (file)
@@ -122,7 +122,7 @@ GLsizei RenderbufferTexture2D::getHeight() const
        return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
 }
 
-GLenum RenderbufferTexture2D::getFormat() const
+GLint RenderbufferTexture2D::getFormat() const
 {
        return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
 }
@@ -260,7 +260,7 @@ GLsizei RenderbufferStorage::getHeight() const
        return mHeight;
 }
 
-GLenum RenderbufferStorage::getFormat() const
+GLint RenderbufferStorage::getFormat() const
 {
        return format;
 }
index f5275f9..4405b93 100644 (file)
@@ -48,7 +48,7 @@ public:
 
        virtual GLsizei getWidth() const = 0;
        virtual GLsizei getHeight() const = 0;
-       virtual GLenum getFormat() const = 0;
+       virtual GLint getFormat() const = 0;
        virtual GLsizei getSamples() const = 0;
 
        GLuint getRedSize() const;
@@ -75,7 +75,7 @@ public:
 
        virtual GLsizei getWidth() const;
        virtual GLsizei getHeight() const;
-       virtual GLenum getFormat() const;
+       virtual GLint getFormat() const;
        virtual GLsizei getSamples() const;
 
 private:
@@ -98,7 +98,7 @@ public:
 
        virtual GLsizei getWidth() const;
        virtual GLsizei getHeight() const;
-       virtual GLenum getFormat() const;
+       virtual GLint getFormat() const;
        virtual GLsizei getSamples() const;
 
 protected:
index d66c723..05f1ebd 100644 (file)
@@ -252,21 +252,6 @@ void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
                return error(GL_INVALID_OPERATION);
        }
 
-       if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
-       {
-               return error(GL_INVALID_VALUE);
-       }
-
-       if(IsCompressed(image->getFormat()))
-       {
-               return error(GL_INVALID_OPERATION);
-       }
-
-       if(format != image->getFormat())
-       {
-               return error(GL_INVALID_OPERATION);
-       }
-
        if(pixels)
        {
                gl::PixelStorageModes unpackParameters;
@@ -282,16 +267,6 @@ void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
                return error(GL_INVALID_OPERATION);
        }
 
-       if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
-       {
-               return error(GL_INVALID_VALUE);
-       }
-
-       if(format != image->getFormat())
-       {
-               return error(GL_INVALID_OPERATION);
-       }
-
        if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
        {
                image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);
@@ -432,12 +407,6 @@ GLint Texture2D::getFormat(GLenum target, GLint level) const
        return image[level] ? image[level]->getFormat() : GL_NONE;
 }
 
-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
-{
-       ASSERT(target == GL_TEXTURE_2D);
-       return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
-}
-
 int Texture2D::getTopLevel() const
 {
        ASSERT(isSamplerComplete());
@@ -782,7 +751,9 @@ egl::Image *createBackBuffer(int width, int height, sw::Format format, int multi
                return nullptr;
        }
 
-       return egl::Image::create(width, height, format, multiSampleDepth, false);
+       GLenum internalformat = sw2es::ConvertBackBufferFormat(format);
+
+       return egl::Image::create(width, height, internalformat, multiSampleDepth, false);
 }
 
 egl::Image *createDepthStencil(int width, int height, sw::Format format, int multiSampleDepth)
@@ -818,7 +789,9 @@ egl::Image *createDepthStencil(int width, int height, sw::Format format, int mul
                UNREACHABLE(format);
        }
 
-       egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
+       GLenum internalformat = sw2es::ConvertDepthStencilFormat(format);
+
+       egl::Image *surface = egl::Image::create(width, height, internalformat, multiSampleDepth, lockable);
 
        if(!surface)
        {
index d823c61..0439039 100644 (file)
@@ -77,7 +77,6 @@ public:
        virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
        virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
        virtual GLint getFormat(GLenum target, GLint level) const = 0;
-       virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
        virtual int getTopLevel() const = 0;
 
        virtual bool isSamplerComplete() const = 0;
@@ -134,7 +133,6 @@ public:
        GLsizei getWidth(GLenum target, GLint level) const override;
        GLsizei getHeight(GLenum target, GLint level) const override;
        GLint getFormat(GLenum target, GLint level) const override;
-       sw::Format getInternalFormat(GLenum target, GLint level) const override;
        int getTopLevel() const override;
 
        void setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
index 440f6cf..f27271c 100644 (file)
@@ -48,41 +48,6 @@ static bool validImageSize(GLint level, GLsizei width, GLsizei height)
        return true;
 }
 
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture)
-{
-       if(!texture)
-       {
-               return error(GL_INVALID_OPERATION, false);
-       }
-
-       if(compressed != texture->isCompressed(target, level))
-       {
-               return error(GL_INVALID_OPERATION, false);
-       }
-
-       if(format != GL_NONE_OES && format != texture->getFormat(target, level))
-       {
-               return error(GL_INVALID_OPERATION, false);
-       }
-
-       if(compressed)
-       {
-               if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
-                  (height % 4 != 0 && height != texture->getHeight(target, 0)))
-               {
-                       return error(GL_INVALID_OPERATION, false);
-               }
-       }
-
-       if(xoffset + width > texture->getWidth(target, level) ||
-          yoffset + height > texture->getHeight(target, level))
-       {
-               return error(GL_INVALID_VALUE, false);
-       }
-
-       return true;
-}
-
 void ActiveTexture(GLenum texture)
 {
        TRACE("(GLenum texture = 0x%X)", texture);
@@ -725,7 +690,6 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs
        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
                break;
        case GL_DEPTH_COMPONENT16_OES:
-       case GL_DEPTH_COMPONENT32_OES:
        case GL_DEPTH_STENCIL_OES:
        case GL_DEPTH24_STENCIL8_OES:
                return error(GL_INVALID_OPERATION);
@@ -832,10 +796,13 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo
                {
                        es1::Texture2D *texture = context->getTexture2D();
 
-                       if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
+                       GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE_OES, texture);
+                       if(validationError != GL_NO_ERROR)
                        {
-                               texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+                               return error(validationError);
                        }
+
+                       texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
                }
                else UNREACHABLE(target);
        }
@@ -1025,9 +992,10 @@ void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                }
                else UNREACHABLE(target);
 
-               if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture))
+               GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE_OES, GL_NONE_OES, texture);
+               if(validationError != GL_NO_ERROR)
                {
-                       return;
+                       return error(validationError);
                }
 
                texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
@@ -2292,7 +2260,6 @@ const GLubyte* GetString(GLenum name)
                        "GL_OES_blend_func_separate "
                        "GL_OES_blend_subtract "
                        "GL_OES_compressed_ETC1_RGB8_texture "
-                       "GL_OES_depth_texture "
                        "GL_OES_EGL_image "
                        "GL_OES_EGL_image_external "
                        "GL_OES_EGL_sync "
@@ -4231,7 +4198,6 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
                switch(type)
                {
                case GL_UNSIGNED_BYTE:
-               case GL_FLOAT:
                        break;
                default:
                        return error(GL_INVALID_ENUM);
@@ -4242,7 +4208,6 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
                {
                case GL_UNSIGNED_BYTE:
                case GL_UNSIGNED_SHORT_5_6_5:
-               case GL_FLOAT:
                        break;
                default:
                        return error(GL_INVALID_ENUM);
@@ -4254,7 +4219,6 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
                case GL_UNSIGNED_BYTE:
                case GL_UNSIGNED_SHORT_4_4_4_4:
                case GL_UNSIGNED_SHORT_5_5_5_1:
-               case GL_FLOAT:
                        break;
                default:
                        return error(GL_INVALID_ENUM);
@@ -4536,11 +4500,6 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
                return error(GL_INVALID_VALUE);
        }
 
-       if(!es1::CheckTextureFormatType(format, type))
-       {
-               return error(GL_INVALID_ENUM);
-       }
-
        if(width == 0 || height == 0 || !pixels)
        {
                return;
@@ -4554,10 +4513,13 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
                {
                        es1::Texture2D *texture = context->getTexture2D();
 
-                       if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
+                       GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture);
+                       if(validationError != GL_NO_ERROR)
                        {
-                               texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
+                               return error(validationError);
                        }
+
+                       texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
                }
                else UNREACHABLE(target);
        }
index b2ba5eb..0df34c7 100644 (file)
@@ -32,6 +32,72 @@ namespace es1
                format == GL_ETC1_RGB8_OES;
        }
 
+       bool IsSizedInternalFormat(GLint internalformat)
+       {
+               switch(internalformat)
+               {
+               case GL_ALPHA8_EXT:
+               case GL_LUMINANCE8_ALPHA8_EXT:
+               case GL_LUMINANCE8_EXT:
+               case GL_RGBA4_OES:
+               case GL_RGB5_A1_OES:
+               case GL_RGB565_OES:
+               case GL_RGB8_OES:
+               case GL_RGBA8_OES:
+               case GL_BGRA8_EXT:   // GL_APPLE_texture_format_BGRA8888
+               case GL_DEPTH_COMPONENT16_OES:
+               case GL_STENCIL_INDEX8_OES:
+               case GL_DEPTH24_STENCIL8_OES:
+                       return true;
+               default:
+                       return false;
+               }
+       }
+
+       GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                                     GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture)
+       {
+               if(!texture)
+               {
+                       return GL_INVALID_OPERATION;
+               }
+
+               GLenum sizedInternalFormat = texture->getFormat(target, level);
+
+               if(compressed)
+               {
+                       if(format != sizedInternalFormat)
+                       {
+                               return GL_INVALID_OPERATION;
+                       }
+               }
+               else if(!copy)   // CopyTexSubImage doesn't have format/type parameters.
+               {
+                       GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target);
+                       if(validationError != GL_NO_ERROR)
+                       {
+                               return validationError;
+                       }
+               }
+
+               if(compressed)
+               {
+                       if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
+                          (height % 4 != 0 && height != texture->getHeight(target, 0)))
+                       {
+                               return GL_INVALID_OPERATION;
+                       }
+               }
+
+               if(xoffset + width > texture->getWidth(target, level) ||
+                  yoffset + height > texture->getHeight(target, level))
+               {
+                       return GL_INVALID_VALUE;
+               }
+
+               return GL_NO_ERROR;
+       }
+
        bool IsDepthTexture(GLenum format)
        {
                return format == GL_DEPTH_STENCIL_OES;
@@ -68,42 +134,195 @@ namespace es1
        }
 
        // Verify that format/type are one of the combinations from table 3.4.
-       bool CheckTextureFormatType(GLenum format, GLenum type)
+       GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target)
        {
                switch(type)
                {
                case GL_UNSIGNED_BYTE:
+               case GL_UNSIGNED_SHORT_4_4_4_4:
+               case GL_UNSIGNED_SHORT_5_5_5_1:
+               case GL_UNSIGNED_SHORT_5_6_5:
+               case GL_UNSIGNED_INT_24_8_OES:   // GL_OES_packed_depth_stencil
+                       break;
+               default:
+                       return GL_INVALID_ENUM;
+               }
+
+               switch(format)
+               {
+               case GL_ALPHA:
+               case GL_RGB:
+               case GL_RGBA:
+               case GL_LUMINANCE:
+               case GL_LUMINANCE_ALPHA:
+               case GL_BGRA_EXT:            // GL_EXT_texture_format_BGRA8888
+                       break;
+               case GL_DEPTH_STENCIL_OES:   // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
+                       switch(target)
+                       {
+                       case GL_TEXTURE_2D:
+                               break;
+                       default:
+                               return GL_INVALID_OPERATION;
+                       }
+                       break;
+               default:
+                       return GL_INVALID_ENUM;
+               }
+
+               if((GLenum)internalformat != format)
+               {
+                       if(gl::IsUnsizedInternalFormat(internalformat))
+                       {
+                               return GL_INVALID_OPERATION;
+                       }
+
+                       if(!IsSizedInternalFormat(internalformat))
+                       {
+                               return GL_INVALID_VALUE;
+                       }
+               }
+
+               if((GLenum)internalformat == format)
+               {
+                       // Validate format, type, and unsized internalformat combinations [OpenGL ES 1.1 Table 3.3]
                        switch(format)
                        {
                        case GL_RGBA:
-                       case GL_BGRA_EXT:
+                               switch(type)
+                               {
+                               case GL_UNSIGNED_BYTE:
+                               case GL_UNSIGNED_SHORT_4_4_4_4:
+                               case GL_UNSIGNED_SHORT_5_5_5_1:
+                                       break;
+                               default:
+                                       return GL_INVALID_OPERATION;
+                               }
+                               break;
                        case GL_RGB:
-                       case GL_ALPHA:
-                       case GL_LUMINANCE:
+                               switch(type)
+                               {
+                               case GL_UNSIGNED_BYTE:
+                               case GL_UNSIGNED_SHORT_5_6_5:
+                                       break;
+                               default:
+                                       return GL_INVALID_OPERATION;
+                               }
+                               break;
                        case GL_LUMINANCE_ALPHA:
-                               return true;
+                       case GL_LUMINANCE:
+                       case GL_ALPHA:
+                               switch(type)
+                               {
+                               case GL_UNSIGNED_BYTE:
+                                       break;
+                               default:
+                                       return GL_INVALID_OPERATION;
+                               }
+                               break;
+                       case GL_DEPTH_STENCIL_OES:
+                               switch(type)
+                               {
+                               case GL_UNSIGNED_INT_24_8_OES:   // GL_OES_packed_depth_stencil
+                                       break;
+                               default:
+                                       return GL_INVALID_OPERATION;
+                               }
+                               break;
+                       case GL_BGRA_EXT:
+                               if(type != GL_UNSIGNED_BYTE)   // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888
+                               {
+                                       return GL_INVALID_OPERATION;
+                               }
+                               break;
                        default:
-                               return false;
+                               UNREACHABLE(format);
+                               return GL_INVALID_ENUM;
                        }
-               case GL_FLOAT:
-               case GL_UNSIGNED_SHORT_4_4_4_4:
-               case GL_UNSIGNED_SHORT_5_5_5_1:
-                       return (format == GL_RGBA);
-               case GL_UNSIGNED_SHORT_5_6_5:
-                       return (format == GL_RGB);
-               case GL_UNSIGNED_INT_24_8_OES:
-                       return (format == GL_DEPTH_STENCIL_OES);
+
+                       return GL_NO_ERROR;
+               }
+
+               // Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
+               bool validSizedInternalformat = false;
+               #define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
+
+               switch(format)
+               {
+               case GL_RGBA:
+                       switch(type)
+                       {
+                       case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8_OES, GL_RGB5_A1_OES, GL_RGBA4_OES)
+                       case GL_UNSIGNED_SHORT_4_4_4_4:      VALIDATE_INTERNALFORMAT(GL_RGBA4_OES)
+                       case GL_UNSIGNED_SHORT_5_5_5_1:      VALIDATE_INTERNALFORMAT(GL_RGB5_A1_OES)
+                       default:                             return GL_INVALID_OPERATION;
+                       }
+                       break;
+               case GL_RGB:
+                       switch(type)
+                       {
+                       case GL_UNSIGNED_BYTE:                VALIDATE_INTERNALFORMAT(GL_RGB8_OES, GL_RGB565_OES)
+                       case GL_UNSIGNED_SHORT_5_6_5:         VALIDATE_INTERNALFORMAT(GL_RGB565_OES)
+                       default:                              return GL_INVALID_OPERATION;
+                       }
+                       break;
+               case GL_DEPTH_STENCIL_OES:
+                       switch(type)
+                       {
+                       case GL_UNSIGNED_INT_24_8_OES: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8_OES)
+                       default:                       return GL_INVALID_OPERATION;
+                       }
+                       break;
+               case GL_LUMINANCE_ALPHA:
+                       switch(type)
+                       {
+                       case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT)
+                       default:
+                               return GL_INVALID_OPERATION;
+                       }
+                       break;
+               case GL_LUMINANCE:
+                       switch(type)
+                       {
+                       case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT)
+                       default:
+                               return GL_INVALID_OPERATION;
+                       }
+                       break;
+               case GL_ALPHA:
+                       switch(type)
+                       {
+                       case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT)
+                       default:
+                               return GL_INVALID_OPERATION;
+                       }
+                       break;
+               case GL_BGRA_EXT:   // GL_APPLE_texture_format_BGRA8888
+                       switch(type)
+                       {
+                       case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT)
+                       default:               return GL_INVALID_OPERATION;
+                       }
+                       break;
                default:
-                       return false;
+                       UNREACHABLE(format);
+                       return GL_INVALID_ENUM;
+               }
+
+               #undef VALIDATE_INTERNALFORMAT
+
+               if(!validSizedInternalformat)
+               {
+                       return GL_INVALID_OPERATION;
                }
+
+               return GL_NO_ERROR;
        }
 
-       bool IsColorRenderable(GLenum internalformat)
+       bool IsColorRenderable(GLint internalformat)
        {
                switch(internalformat)
                {
-               case GL_RGB:
-               case GL_RGBA:
                case GL_RGBA4_OES:
                case GL_RGB5_A1_OES:
                case GL_RGB565_OES:
@@ -121,7 +340,7 @@ namespace es1
                return false;
        }
 
-       bool IsDepthRenderable(GLenum internalformat)
+       bool IsDepthRenderable(GLint internalformat)
        {
                switch(internalformat)
                {
@@ -142,7 +361,7 @@ namespace es1
                return false;
        }
 
-       bool IsStencilRenderable(GLenum internalformat)
+       bool IsStencilRenderable(GLint internalformat)
        {
                switch(internalformat)
                {
@@ -167,45 +386,13 @@ namespace es1
        {
                switch(internalformat)
                {
-               case GL_NONE:           return 0;
-               case GL_RGBA4:          return 4;
-               case GL_RGB5_A1:        return 1;
-               case GL_RGB565:         return 0;
-               case GL_R8:             return 0;
-               case GL_RG8:            return 0;
-               case GL_RGB8:           return 0;
-               case GL_RGBA8:          return 8;
-               case GL_R16F:           return 0;
-               case GL_RG16F:          return 0;
-               case GL_RGB16F:         return 0;
-               case GL_RGBA16F:        return 16;
-               case GL_R32F:           return 0;
-               case GL_RG32F:          return 0;
-               case GL_RGB32F:         return 0;
-               case GL_RGBA32F:        return 32;
-               case GL_BGRA8_EXT:      return 8;
-               case GL_R8UI:           return 0;
-               case GL_R8I:            return 0;
-               case GL_R16UI:          return 0;
-               case GL_R16I:           return 0;
-               case GL_R32UI:          return 0;
-               case GL_R32I:           return 0;
-               case GL_RG8UI:          return 0;
-               case GL_RG8I:           return 0;
-               case GL_RG16UI:         return 0;
-               case GL_RG16I:          return 0;
-               case GL_RG32UI:         return 0;
-               case GL_RG32I:          return 0;
-               case GL_SRGB8_ALPHA8:   return 8;
-               case GL_RGB10_A2:       return 2;
-               case GL_RGBA8UI:        return 8;
-               case GL_RGBA8I:         return 8;
-               case GL_RGB10_A2UI:     return 2;
-               case GL_RGBA16UI:       return 16;
-               case GL_RGBA16I:        return 16;
-               case GL_RGBA32I:        return 32;
-               case GL_RGBA32UI:       return 32;
-               case GL_R11F_G11F_B10F: return 0;
+               case GL_NONE_OES:    return 0;
+               case GL_RGBA4_OES:   return 4;
+               case GL_RGB5_A1_OES: return 1;
+               case GL_RGB565_OES:  return 0;
+               case GL_RGB8_OES:    return 0;
+               case GL_RGBA8_OES:   return 8;
+               case GL_BGRA8_EXT:   return 8;
                default:
                //      UNREACHABLE(internalformat);
                        return 0;
@@ -216,45 +403,13 @@ namespace es1
        {
                switch(internalformat)
                {
-               case GL_NONE:           return 0;
-               case GL_RGBA4:          return 4;
-               case GL_RGB5_A1:        return 5;
-               case GL_RGB565:         return 5;
-               case GL_R8:             return 8;
-               case GL_RG8:            return 8;
-               case GL_RGB8:           return 8;
-               case GL_RGBA8:          return 8;
-               case GL_R16F:           return 16;
-               case GL_RG16F:          return 16;
-               case GL_RGB16F:         return 16;
-               case GL_RGBA16F:        return 16;
-               case GL_R32F:           return 32;
-               case GL_RG32F:          return 32;
-               case GL_RGB32F:         return 32;
-               case GL_RGBA32F:        return 32;
-               case GL_BGRA8_EXT:      return 8;
-               case GL_R8UI:           return 8;
-               case GL_R8I:            return 8;
-               case GL_R16UI:          return 16;
-               case GL_R16I:           return 16;
-               case GL_R32UI:          return 32;
-               case GL_R32I:           return 32;
-               case GL_RG8UI:          return 8;
-               case GL_RG8I:           return 8;
-               case GL_RG16UI:         return 16;
-               case GL_RG16I:          return 16;
-               case GL_RG32UI:         return 32;
-               case GL_RG32I:          return 32;
-               case GL_SRGB8_ALPHA8:   return 8;
-               case GL_RGB10_A2:       return 10;
-               case GL_RGBA8UI:        return 8;
-               case GL_RGBA8I:         return 8;
-               case GL_RGB10_A2UI:     return 10;
-               case GL_RGBA16UI:       return 16;
-               case GL_RGBA16I:        return 16;
-               case GL_RGBA32I:        return 32;
-               case GL_RGBA32UI:       return 32;
-               case GL_R11F_G11F_B10F: return 11;
+               case GL_NONE_OES:    return 0;
+               case GL_RGBA4_OES:   return 4;
+               case GL_RGB5_A1_OES: return 5;
+               case GL_RGB565_OES:  return 5;
+               case GL_RGB8_OES:    return 8;
+               case GL_RGBA8_OES:   return 8;
+               case GL_BGRA8_EXT:   return 8;
                default:
                //      UNREACHABLE(internalformat);
                        return 0;
@@ -265,45 +420,13 @@ namespace es1
        {
                switch(internalformat)
                {
-               case GL_NONE:           return 0;
-               case GL_RGBA4:          return 4;
-               case GL_RGB5_A1:        return 5;
-               case GL_RGB565:         return 6;
-               case GL_R8:             return 0;
-               case GL_RG8:            return 8;
-               case GL_RGB8:           return 8;
-               case GL_RGBA8:          return 8;
-               case GL_R16F:           return 0;
-               case GL_RG16F:          return 16;
-               case GL_RGB16F:         return 16;
-               case GL_RGBA16F:        return 16;
-               case GL_R32F:           return 0;
-               case GL_RG32F:          return 32;
-               case GL_RGB32F:         return 32;
-               case GL_RGBA32F:        return 32;
-               case GL_BGRA8_EXT:      return 8;
-               case GL_R8UI:           return 0;
-               case GL_R8I:            return 0;
-               case GL_R16UI:          return 0;
-               case GL_R16I:           return 0;
-               case GL_R32UI:          return 0;
-               case GL_R32I:           return 0;
-               case GL_RG8UI:          return 8;
-               case GL_RG8I:           return 8;
-               case GL_RG16UI:         return 16;
-               case GL_RG16I:          return 16;
-               case GL_RG32UI:         return 32;
-               case GL_RG32I:          return 32;
-               case GL_SRGB8_ALPHA8:   return 8;
-               case GL_RGB10_A2:       return 10;
-               case GL_RGBA8UI:        return 8;
-               case GL_RGBA8I:         return 8;
-               case GL_RGB10_A2UI:     return 10;
-               case GL_RGBA16UI:       return 16;
-               case GL_RGBA16I:        return 16;
-               case GL_RGBA32I:        return 32;
-               case GL_RGBA32UI:       return 32;
-               case GL_R11F_G11F_B10F: return 11;
+               case GL_NONE_OES:    return 0;
+               case GL_RGBA4_OES:   return 4;
+               case GL_RGB5_A1_OES: return 5;
+               case GL_RGB565_OES:  return 6;
+               case GL_RGB8_OES:    return 8;
+               case GL_RGBA8_OES:   return 8;
+               case GL_BGRA8_EXT:   return 8;
                default:
                //      UNREACHABLE(internalformat);
                        return 0;
@@ -314,45 +437,13 @@ namespace es1
        {
                switch(internalformat)
                {
-               case GL_NONE:           return 0;
-               case GL_RGBA4:          return 4;
-               case GL_RGB5_A1:        return 5;
-               case GL_RGB565:         return 5;
-               case GL_R8:             return 0;
-               case GL_RG8:            return 0;
-               case GL_RGB8:           return 8;
-               case GL_RGBA8:          return 8;
-               case GL_R16F:           return 0;
-               case GL_RG16F:          return 0;
-               case GL_RGB16F:         return 16;
-               case GL_RGBA16F:        return 16;
-               case GL_R32F:           return 0;
-               case GL_RG32F:          return 0;
-               case GL_RGB32F:         return 32;
-               case GL_RGBA32F:        return 32;
-               case GL_BGRA8_EXT:      return 8;
-               case GL_R8UI:           return 0;
-               case GL_R8I:            return 0;
-               case GL_R16UI:          return 0;
-               case GL_R16I:           return 0;
-               case GL_R32UI:          return 0;
-               case GL_R32I:           return 0;
-               case GL_RG8UI:          return 0;
-               case GL_RG8I:           return 0;
-               case GL_RG16UI:         return 0;
-               case GL_RG16I:          return 0;
-               case GL_RG32UI:         return 0;
-               case GL_RG32I:          return 0;
-               case GL_SRGB8_ALPHA8:   return 8;
-               case GL_RGB10_A2:       return 10;
-               case GL_RGBA8UI:        return 8;
-               case GL_RGBA8I:         return 8;
-               case GL_RGB10_A2UI:     return 10;
-               case GL_RGBA16UI:       return 16;
-               case GL_RGBA16I:        return 16;
-               case GL_RGBA32I:        return 32;
-               case GL_RGBA32UI:       return 32;
-               case GL_R11F_G11F_B10F: return 10;
+               case GL_NONE_OES:    return 0;
+               case GL_RGBA4_OES:   return 4;
+               case GL_RGB5_A1_OES: return 5;
+               case GL_RGB565_OES:  return 5;
+               case GL_RGB8_OES:    return 8;
+               case GL_RGBA8_OES:   return 8;
+               case GL_BGRA8_EXT:   return 8;
                default:
                //      UNREACHABLE(internalformat);
                        return 0;
@@ -363,13 +454,9 @@ namespace es1
        {
                switch(internalformat)
                {
-               case GL_STENCIL_INDEX8:        return 0;
-               case GL_DEPTH_COMPONENT16:     return 16;
-               case GL_DEPTH_COMPONENT24:     return 24;
-               case GL_DEPTH_COMPONENT32_OES: return 32;
-               case GL_DEPTH_COMPONENT32F:    return 32;
-               case GL_DEPTH24_STENCIL8:      return 24;
-               case GL_DEPTH32F_STENCIL8:     return 32;
+               case GL_STENCIL_INDEX8_OES:    return 0;
+               case GL_DEPTH_COMPONENT16_OES: return 16;
+               case GL_DEPTH24_STENCIL8_OES:  return 24;
                default:
                //      UNREACHABLE(internalformat);
                        return 0;
@@ -380,38 +467,33 @@ namespace es1
        {
                switch(internalformat)
                {
-               case GL_STENCIL_INDEX8:        return 8;
-               case GL_DEPTH_COMPONENT16:     return 0;
-               case GL_DEPTH_COMPONENT24:     return 0;
-               case GL_DEPTH_COMPONENT32_OES: return 0;
-               case GL_DEPTH_COMPONENT32F:    return 0;
-               case GL_DEPTH24_STENCIL8:      return 8;
-               case GL_DEPTH32F_STENCIL8:     return 8;
+               case GL_STENCIL_INDEX8_OES:    return 8;
+               case GL_DEPTH_COMPONENT16_OES: return 0;
+               case GL_DEPTH24_STENCIL8_OES:  return 8;
                default:
                //      UNREACHABLE(internalformat);
                        return 0;
                }
        }
 
-       bool IsAlpha(GLenum texFormat)
+       bool IsAlpha(GLint internalformat)
        {
-               switch(texFormat)
+               switch(internalformat)
                {
-               case GL_ALPHA:
+               case GL_ALPHA8_EXT:
                        return true;
                default:
                        return false;
                }
        }
 
-       bool IsRGB(GLenum texFormat)
+       bool IsRGB(GLint internalformat)
        {
-               switch(texFormat)
+               switch(internalformat)
                {
-               case GL_LUMINANCE:
-               case GL_RGB:
-               case GL_RGB565_OES:   // GL_OES_framebuffer_object
-               case GL_RGB8_OES:     // GL_OES_rgb8_rgba8
+               case GL_LUMINANCE8_EXT:
+               case GL_RGB565_OES:
+               case GL_RGB8_OES:
                case SW_YV12_BT601:
                case SW_YV12_BT709:
                case SW_YV12_JFIF:
@@ -421,16 +503,16 @@ namespace es1
                }
        }
 
-       bool IsRGBA(GLenum texFormat)
+       bool IsRGBA(GLint internalformat)
        {
-               switch(texFormat)
+               switch(internalformat)
                {
-               case GL_LUMINANCE_ALPHA:
+               case GL_LUMINANCE8_ALPHA8_EXT:
                case GL_RGBA:
-               case GL_BGRA_EXT:      // GL_EXT_texture_format_BGRA8888
-               case GL_RGBA4_OES:     // GL_OES_framebuffer_object
-               case GL_RGB5_A1_OES:   // GL_OES_framebuffer_object
-               case GL_RGBA8_OES:     // GL_OES_rgb8_rgba8
+               case GL_BGRA8_EXT:     // GL_EXT_texture_format_BGRA8888
+               case GL_RGBA4_OES:
+               case GL_RGB5_A1_OES:
+               case GL_RGBA8_OES:
                        return true;
                default:
                        return false;
@@ -708,7 +790,7 @@ namespace es2sw
                sw::DrawType elementSize;
                switch(elementType)
                {
-               case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;
+               case GL_NONE_OES:       elementSize = sw::DRAW_NONINDEXED; break;
                case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;
                case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;
                case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;
@@ -720,22 +802,6 @@ namespace es2sw
                return true;
        }
 
-       sw::Format ConvertRenderbufferFormat(GLenum format)
-       {
-               switch(format)
-               {
-               case GL_RGBA4_OES:
-               case GL_RGB5_A1_OES:
-               case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;
-               case GL_RGB565_OES:           return sw::FORMAT_R5G6B5;
-               case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;
-               case GL_DEPTH_COMPONENT16_OES:
-               case GL_STENCIL_INDEX8_OES:
-               case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
-               default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;
-               }
-       }
-
        sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation)
        {
                switch(operation)
index 4f55c86..402a341 100644 (file)
@@ -31,16 +31,18 @@ namespace es1
        struct Color;
 
        bool IsCompressed(GLenum format);
+       GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                                     GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture);
        bool IsDepthTexture(GLenum format);
        bool IsStencilTexture(GLenum format);
        bool IsCubemapTextureTarget(GLenum target);
        int CubeFaceIndex(GLenum cubeTarget);
        bool IsTextureTarget(GLenum target);
-       bool CheckTextureFormatType(GLenum format, GLenum type);
+       GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target);
 
-       bool IsColorRenderable(GLenum internalformat);
-       bool IsDepthRenderable(GLenum internalformat);
-       bool IsStencilRenderable(GLenum internalformat);
+       bool IsColorRenderable(GLint internalformat);
+       bool IsDepthRenderable(GLint internalformat);
+       bool IsStencilRenderable(GLint internalformat);
 
        GLuint GetAlphaSize(GLint internalformat);
        GLuint GetRedSize(GLint internalformat);
@@ -49,9 +51,9 @@ namespace es1
        GLuint GetDepthSize(GLint internalformat);
        GLuint GetStencilSize(GLint internalformat);
 
-       bool IsAlpha(GLenum texFormat);
-       bool IsRGB(GLenum texFormat);
-       bool IsRGBA(GLenum texFormat);
+       bool IsAlpha(GLint texFormat);
+       bool IsRGB(GLint texFormat);
+       bool IsRGBA(GLint texFormat);
 }
 
 namespace es2sw
index 3d01ee5..1e3e51f 100644 (file)
@@ -509,7 +509,7 @@ GLsizei Texture2D::getHeight(GLenum target, GLint level) const
        return image[level] ? image[level]->getHeight() : 0;
 }
 
-GLenum Texture2D::getFormat(GLenum target, GLint level) const
+GLint Texture2D::getFormat(GLenum target, GLint level) const
 {
        ASSERT(target == getTarget());
        return image[level] ? image[level]->getFormat() : GL_NONE;
@@ -966,7 +966,7 @@ GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
        return image[face][level] ? image[face][level]->getHeight() : 0;
 }
 
-GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const
+GLint TextureCubeMap::getFormat(GLenum target, GLint level) const
 {
        int face = CubeFaceIndex(target);
        return image[face][level] ? image[face][level]->getFormat() : 0;
@@ -1475,7 +1475,7 @@ GLsizei Texture3D::getDepth(GLenum target, GLint level) const
        return image[level] ? image[level]->getDepth() : 0;
 }
 
-GLenum Texture3D::getFormat(GLenum target, GLint level) const
+GLint Texture3D::getFormat(GLenum target, GLint level) const
 {
        ASSERT(target == getTarget());
        return image[level] ? image[level]->getFormat() : GL_NONE;
index b33c1bc..13b3a56 100644 (file)
@@ -93,7 +93,7 @@ public:
        virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
        virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
        virtual GLsizei getDepth(GLenum target, GLint level) const;
-       virtual GLenum getFormat(GLenum target, GLint level) const = 0;
+       virtual GLint getFormat(GLenum target, GLint level) const = 0;
        virtual int getTopLevel() const = 0;
 
        virtual bool isSamplerComplete() const = 0;
@@ -155,7 +155,7 @@ public:
 
        GLsizei getWidth(GLenum target, GLint level) const override;
        GLsizei getHeight(GLenum target, GLint level) const override;
-       GLenum getFormat(GLenum target, GLint level) const override;
+       GLint getFormat(GLenum target, GLint level) const override;
        int getTopLevel() const override;
 
        void setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
@@ -220,7 +220,7 @@ public:
 
        GLsizei getWidth(GLenum target, GLint level) const override;
        GLsizei getHeight(GLenum target, GLint level) const override;
-       GLenum getFormat(GLenum target, GLint level) const override;
+       GLint getFormat(GLenum target, GLint level) const override;
        int getTopLevel() const override;
 
        void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
@@ -281,7 +281,7 @@ public:
        GLsizei getWidth(GLenum target, GLint level) const override;
        GLsizei getHeight(GLenum target, GLint level) const override;
        GLsizei getDepth(GLenum target, GLint level) const override;
-       GLenum getFormat(GLenum target, GLint level) const override;
+       GLint getFormat(GLenum target, GLint level) const override;
        int getTopLevel() const override;
 
        void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);