OSDN Git Service

Floating point renderbuffer support
authorAlexis Hetu <sugoi@google.com>
Thu, 12 Nov 2015 21:36:34 +0000 (16:36 -0500)
committerAlexis Hétu <sugoi@google.com>
Thu, 26 Nov 2015 20:52:23 +0000 (20:52 +0000)
It is now possible to use floating point renderbuffers and read
the data back from them. The changes include:
- Modified glReadPixels so that it always uses the blitter to
  copy the data to the external buffer.
- Added new types to both Framebuffer and some utility functions.
- Added the new ValidReadPixelsFormatType function to validate the
  glReadPixels format/type combo, which had a bit more
  possibilities than the RGBA/UNSIGNED BYTE combo previously used.

Change-Id: I1726ea57c4f7aa85bf0ffa7f323dc6a16abc34ff
Reviewed-on: https://swiftshader-review.googlesource.com/4260
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/libGLESv2/Context.cpp
src/OpenGL/libGLESv2/Context.h
src/OpenGL/libGLESv2/Framebuffer.cpp
src/OpenGL/libGLESv2/libGLESv2.cpp
src/OpenGL/libGLESv2/libGLESv3.cpp
src/OpenGL/libGLESv2/utilities.cpp
src/OpenGL/libGLESv2/utilities.h

index e90ddc9..5826ec9 100644 (file)
@@ -165,8 +165,10 @@ Context::Context(const egl::Config *config, const Context *shareContext, EGLint
     mState.packAlignment = 4;\r
        mState.unpackInfo.alignment = 4;\r
        mState.packRowLength = 0;\r
+       mState.packImageHeight = 0;\r
        mState.packSkipPixels = 0;\r
        mState.packSkipRows = 0;\r
+       mState.packSkipImages = 0;\r
        mState.unpackInfo.rowLength = 0;\r
        mState.unpackInfo.imageHeight = 0;\r
        mState.unpackInfo.skipPixels = 0;\r
@@ -848,6 +850,11 @@ void Context::setPackRowLength(GLint rowLength)
        mState.packRowLength = rowLength;\r
 }\r
 \r
+void Context::setPackImageHeight(GLint imageHeight)\r
+{\r
+       mState.packImageHeight = imageHeight;\r
+}\r
+\r
 void Context::setPackSkipPixels(GLint skipPixels)\r
 {\r
        mState.packSkipPixels = skipPixels;\r
@@ -858,6 +865,11 @@ void Context::setPackSkipRows(GLint skipRows)
        mState.packSkipRows = skipRows;\r
 }\r
 \r
+void Context::setPackSkipImages(GLint skipImages)\r
+{\r
+       mState.packSkipImages = skipImages;\r
+}\r
+\r
 void Context::setUnpackRowLength(GLint rowLength)\r
 {\r
        mState.unpackInfo.rowLength = rowLength;\r
@@ -3262,15 +3274,18 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
         return error(GL_INVALID_OPERATION);\r
     }\r
 \r
-       if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)\r
+       GLenum readFormat = framebuffer->getImplementationColorReadFormat();\r
+       GLenum readType = framebuffer->getImplementationColorReadType();\r
+\r
+       if(!(readFormat == format && readType == type) && !ValidReadPixelsFormatType(readFormat, readType, format, type, clientVersion))\r
        {\r
-               if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())\r
-               {\r
-                       return error(GL_INVALID_OPERATION);\r
-               }\r
+               return error(GL_INVALID_OPERATION);\r
        }\r
 \r
-       GLsizei outputPitch = (mState.packRowLength > 0) ? mState.packRowLength : egl::ComputePitch(width, format, type, mState.packAlignment);\r
+       GLsizei outputPitch = egl::ComputePitch((mState.packRowLength > 0) ? mState.packRowLength : width, format, type, mState.packAlignment);\r
+       GLsizei outputHeight = (mState.packImageHeight == 0) ? height : mState.packImageHeight;\r
+       pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;\r
+       pixels = ((char*)pixels) + (mState.packSkipImages * outputHeight + mState.packSkipRows) * outputPitch + mState.packSkipPixels;\r
     \r
        // Sized query sanity check\r
     if(bufSize)\r
@@ -3292,256 +3307,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
        x += mState.packSkipPixels;\r
        y += mState.packSkipRows;\r
        sw::Rect rect = {x, y, x + width, y + height};\r
+       sw::Rect dstRect = { 0, 0, width, height };\r
        rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());\r
 \r
-    unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);\r
-    unsigned char *dest = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;\r
-    int inputPitch = (int)renderTarget->getPitch();\r
-\r
-    for(int j = 0; j < rect.y1 - rect.y0; j++)\r
-    {\r
-               unsigned short *dest16 = (unsigned short*)dest;\r
-               unsigned int *dest32 = (unsigned int*)dest;\r
-\r
-               if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&\r
-           format == GL_RGBA && type == GL_UNSIGNED_BYTE)\r
-        {\r
-            memcpy(dest, source, (rect.x1 - rect.x0) * 4);\r
-        }\r
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&\r
-                format == GL_RGBA && type == GL_UNSIGNED_BYTE)\r
-        {\r
-            for(int i = 0; i < rect.x1 - rect.x0; i++)\r
-                       {\r
-                               unsigned int argb = *(unsigned int*)(source + 4 * i);\r
-\r
-                               dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);\r
-                       }\r
-        }\r
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&\r
-                format == GL_RGBA && type == GL_UNSIGNED_BYTE)\r
-        {\r
-            for(int i = 0; i < rect.x1 - rect.x0; i++)\r
-                       {\r
-                               unsigned int xrgb = *(unsigned int*)(source + 4 * i);\r
-\r
-                               dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;\r
-                       }\r
-        }\r
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&\r
-                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)\r
-        {\r
-            for(int i = 0; i < rect.x1 - rect.x0; i++)\r
-                       {\r
-                               unsigned int xrgb = *(unsigned int*)(source + 4 * i);\r
-\r
-                               dest32[i] = xrgb | 0xFF000000;\r
-                       }\r
-        }\r
-        else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&\r
-                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)\r
-        {\r
-            memcpy(dest, source, (rect.x1 - rect.x0) * 4);\r
-        }\r
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F &&\r
-                format == GL_RGBA && (type == GL_HALF_FLOAT || type == GL_HALF_FLOAT_OES))\r
-        {\r
-            memcpy(dest, source, (rect.x1 - rect.x0) * 8);\r
-        }\r
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F &&\r
-                format == GL_RGBA && type == GL_FLOAT)\r
-        {\r
-            memcpy(dest, source, (rect.x1 - rect.x0) * 16);\r
-        }\r
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&\r
-                format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)\r
-        {\r
-            memcpy(dest, source, (rect.x1 - rect.x0) * 2);\r
-        }\r
-               else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&\r
-                format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT\r
-        {\r
-            memcpy(dest, source, (rect.x1 - rect.x0) * 2);\r
-        }\r
-               else\r
-               {\r
-                       for(int i = 0; i < rect.x1 - rect.x0; i++)\r
-                       {\r
-                               float r;\r
-                               float g;\r
-                               float b;\r
-                               float a;\r
-\r
-                               switch(renderTarget->getInternalFormat())\r
-                               {\r
-                               case sw::FORMAT_R5G6B5:\r
-                                       {\r
-                                               unsigned short rgb = *(unsigned short*)(source + 2 * i);\r
-\r
-                                               a = 1.0f;\r
-                                               b = (rgb & 0x001F) * (1.0f / 0x001F);\r
-                                               g = (rgb & 0x07E0) * (1.0f / 0x07E0);\r
-                                               r = (rgb & 0xF800) * (1.0f / 0xF800);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_A1R5G5B5:\r
-                                       {\r
-                                               unsigned short argb = *(unsigned short*)(source + 2 * i);\r
-\r
-                                               a = (argb & 0x8000) ? 1.0f : 0.0f;\r
-                                               b = (argb & 0x001F) * (1.0f / 0x001F);\r
-                                               g = (argb & 0x03E0) * (1.0f / 0x03E0);\r
-                                               r = (argb & 0x7C00) * (1.0f / 0x7C00);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_A8R8G8B8:\r
-                                       {\r
-                                               unsigned int argb = *(unsigned int*)(source + 4 * i);\r
-\r
-                                               a = (argb & 0xFF000000) * (1.0f / 0xFF000000);\r
-                                               b = (argb & 0x000000FF) * (1.0f / 0x000000FF);\r
-                                               g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);\r
-                                               r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_A8B8G8R8:\r
-                                       {\r
-                                               unsigned int abgr = *(unsigned int*)(source + 4 * i);\r
-\r
-                                               a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);\r
-                                               b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);\r
-                                               g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);\r
-                                               r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_X8R8G8B8:\r
-                                       {\r
-                                               unsigned int xrgb = *(unsigned int*)(source + 4 * i);\r
-\r
-                                               a = 1.0f;\r
-                                               b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);\r
-                                               g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);\r
-                                               r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_X8B8G8R8:\r
-                                       {\r
-                                               unsigned int xbgr = *(unsigned int*)(source + 4 * i);\r
-\r
-                                               a = 1.0f;\r
-                                               b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);\r
-                                               g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);\r
-                                               r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_A2R10G10B10:\r
-                                       {\r
-                                               unsigned int argb = *(unsigned int*)(source + 4 * i);\r
-\r
-                                               a = (argb & 0xC0000000) * (1.0f / 0xC0000000);\r
-                                               b = (argb & 0x000003FF) * (1.0f / 0x000003FF);\r
-                                               g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);\r
-                                               r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_A32B32G32R32F:\r
-                                       {\r
-                                               r = *((float*)(source + 16 * i) + 0);\r
-                                               g = *((float*)(source + 16 * i) + 1);\r
-                                               b = *((float*)(source + 16 * i) + 2);\r
-                                               a = *((float*)(source + 16 * i) + 3);\r
-                                       }\r
-                                       break;\r
-                               case sw::FORMAT_A16B16G16R16F:\r
-                                       {\r
-                                               r = (float)*((sw::half*)(source + 8 * i) + 0);\r
-                                               g = (float)*((sw::half*)(source + 8 * i) + 1);\r
-                                               b = (float)*((sw::half*)(source + 8 * i) + 2);\r
-                                               a = (float)*((sw::half*)(source + 8 * i) + 3);\r
-                                       }\r
-                                       break;\r
-                               default:\r
-                                       UNIMPLEMENTED();   // FIXME\r
-                                       UNREACHABLE(renderTarget->getInternalFormat());\r
-                               }\r
-\r
-                               switch(format)\r
-                               {\r
-                               case GL_RGBA:\r
-                                       switch(type)\r
-                                       {\r
-                                       case GL_UNSIGNED_BYTE:\r
-                                               dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);\r
-                                               dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);\r
-                                               dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);\r
-                                               dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);\r
-                                               break;\r
-                                       default: UNREACHABLE(type);\r
-                                       }\r
-                                       break;\r
-                               case GL_BGRA_EXT:\r
-                                       switch(type)\r
-                                       {\r
-                                       case GL_UNSIGNED_BYTE:\r
-                                               dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);\r
-                                               dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);\r
-                                               dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);\r
-                                               dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);\r
-                                               break;\r
-                                       case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:\r
-                                               // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section\r
-                                               // this type is packed as follows:\r
-                                               //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0\r
-                                               //  --------------------------------------------------------------------------------\r
-                                               // |       4th         |        3rd         |        2nd        |   1st component   |\r
-                                               //  --------------------------------------------------------------------------------\r
-                                               // in the case of BGRA_EXT, B is the first component, G the second, and so forth.\r
-                                               dest16[i] =\r
-                                                       ((unsigned short)(15 * a + 0.5f) << 12)|\r
-                                                       ((unsigned short)(15 * r + 0.5f) << 8) |\r
-                                                       ((unsigned short)(15 * g + 0.5f) << 4) |\r
-                                                       ((unsigned short)(15 * b + 0.5f) << 0);\r
-                                               break;\r
-                                       case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:\r
-                                               // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section\r
-                                               // this type is packed as follows:\r
-                                               //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0\r
-                                               //  --------------------------------------------------------------------------------\r
-                                               // | 4th |          3rd           |           2nd          |      1st component     |\r
-                                               //  --------------------------------------------------------------------------------\r
-                                               // in the case of BGRA_EXT, B is the first component, G the second, and so forth.\r
-                                               dest16[i] =\r
-                                                       ((unsigned short)(     a + 0.5f) << 15) |\r
-                                                       ((unsigned short)(31 * r + 0.5f) << 10) |\r
-                                                       ((unsigned short)(31 * g + 0.5f) << 5) |\r
-                                                       ((unsigned short)(31 * b + 0.5f) << 0);\r
-                                               break;\r
-                                       default: UNREACHABLE(type);\r
-                                       }\r
-                                       break;\r
-                               case GL_RGB:\r
-                                       switch(type)\r
-                                       {\r
-                                       case GL_UNSIGNED_SHORT_5_6_5:\r
-                                               dest16[i] =\r
-                                                       ((unsigned short)(31 * b + 0.5f) << 0) |\r
-                                                       ((unsigned short)(63 * g + 0.5f) << 5) |\r
-                                                       ((unsigned short)(31 * r + 0.5f) << 11);\r
-                                               break;\r
-                                       default: UNREACHABLE(type);\r
-                                       }\r
-                                       break;\r
-                               default: UNREACHABLE(format);\r
-                               }\r
-                       }\r
-        }\r
-\r
-               source += inputPitch;\r
-               dest += outputPitch;\r
-    }\r
-\r
-       renderTarget->unlock();\r
-       renderTarget->release();\r
+       sw::Surface externalSurface(width, height, 1, egl::SelectInternalFormat(format, type), pixels, outputPitch, outputPitch * outputHeight);\r
+       sw::SliceRect sliceRect(rect);\r
+       sw::SliceRect dstSliceRect(dstRect);\r
+       device->blit(renderTarget, sliceRect, &externalSurface, dstSliceRect, false);\r
 }\r
 \r
 void Context::clear(GLbitfield mask)\r
index 545d442..4d7e7fa 100644 (file)
@@ -397,8 +397,10 @@ struct State
        egl::Image::UnpackInfo unpackInfo;\r
     GLint packAlignment;\r
        GLint packRowLength;\r
+       GLint packImageHeight;\r
        GLint packSkipPixels;\r
        GLint packSkipRows;\r
+       GLint packSkipImages;\r
 };\r
 \r
 class Context : public egl::Context\r
@@ -511,8 +513,10 @@ public:
 \r
     void setPackAlignment(GLint alignment);\r
        void setPackRowLength(GLint rowLength);\r
+       void setPackImageHeight(GLint imageHeight);\r
        void setPackSkipPixels(GLint skipPixels);\r
        void setPackSkipRows(GLint skipRows);\r
+       void setPackSkipImages(GLint skipImages);\r
 \r
     // These create  and destroy methods are merely pass-throughs to \r
     // ResourceManager, which owns these object types\r
index 3dc9f2f..6473473 100644 (file)
@@ -284,7 +284,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
 
                        if(mColorbufferType[i] == GL_RENDERBUFFER)
                        {
-                               if(!es2::IsColorRenderable(colorbuffer->getFormat()))
+                               if(!es2::IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion()))
                                {
                                        return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
                                }
@@ -448,14 +448,49 @@ GLenum Framebuffer::getImplementationColorReadFormat()
                // Don't return GL_RGBA since that's always supported. Provide a second option here.
                switch(colorbuffer->getInternalFormat())
                {
-               case sw::FORMAT_A16B16G16R16F: return GL_BGRA_EXT;
-               case sw::FORMAT_A32B32G32R32F: return GL_BGRA_EXT;
-               case sw::FORMAT_A8R8G8B8:      return GL_BGRA_EXT;
-               case sw::FORMAT_A8B8G8R8:      return GL_BGRA_EXT;
-               case sw::FORMAT_X8R8G8B8:      return 0x80E0;   // GL_BGR_EXT
-               case sw::FORMAT_X8B8G8R8:      return 0x80E0;   // GL_BGR_EXT
+               case sw::FORMAT_A8B8G8R8I:
+               case sw::FORMAT_A8B8G8R8UI:
+               case sw::FORMAT_A16B16G16R16I:
+               case sw::FORMAT_A16B16G16R16UI:
+               case sw::FORMAT_A32B32G32R32I:
+               case sw::FORMAT_A32B32G32R32UI:return GL_RGBA_INTEGER;
+               case sw::FORMAT_A2B10G10R10:   return GL_RGB10_A2;
+               case sw::FORMAT_A8B8G8R8I_SNORM:
+               case sw::FORMAT_A16B16G16R16F:
+               case sw::FORMAT_A32B32G32R32F:
+               case sw::FORMAT_A8R8G8B8:
+               case sw::FORMAT_A8B8G8R8:
                case sw::FORMAT_A1R5G5B5:      return GL_BGRA_EXT;
+               case sw::FORMAT_X8B8G8R8I:
+               case sw::FORMAT_X8B8G8R8UI:
+               case sw::FORMAT_X16B16G16R16I:
+               case sw::FORMAT_X16B16G16R16UI:
+               case sw::FORMAT_X32B32G32R32I:
+               case sw::FORMAT_X32B32G32R32UI:return GL_RGB_INTEGER;
+               case sw::FORMAT_X8B8G8R8I_SNORM:
+               case sw::FORMAT_X8B8G8R8:
+               case sw::FORMAT_X8R8G8B8:
                case sw::FORMAT_R5G6B5:        return 0x80E0;   // GL_BGR_EXT
+               case sw::FORMAT_G8R8I:
+               case sw::FORMAT_G8R8UI:
+               case sw::FORMAT_G16R16I:
+               case sw::FORMAT_G16R16UI:
+               case sw::FORMAT_G32R32I:
+               case sw::FORMAT_G32R32UI:      return GL_RG_INTEGER;
+               case sw::FORMAT_G8R8:
+               case sw::FORMAT_G8R8I_SNORM:
+               case sw::FORMAT_G16R16F:
+               case sw::FORMAT_G32R32F:       return GL_RG;
+               case sw::FORMAT_R8I:
+               case sw::FORMAT_R8UI:
+               case sw::FORMAT_R16I:
+               case sw::FORMAT_R16UI:
+               case sw::FORMAT_R32I:
+               case sw::FORMAT_R32UI:         return GL_RED_INTEGER;
+               case sw::FORMAT_R8:
+               case sw::FORMAT_R8I_SNORM:
+               case sw::FORMAT_R16F:
+               case sw::FORMAT_R32F:          return GL_RED;
                default:
                        UNREACHABLE(colorbuffer->getInternalFormat());
                }
@@ -472,12 +507,49 @@ GLenum Framebuffer::getImplementationColorReadType()
        {
                switch(colorbuffer->getInternalFormat())
                {
-               case sw::FORMAT_A16B16G16R16F: return (egl::getClientVersion() < 3) ? GL_HALF_FLOAT_OES : GL_HALF_FLOAT;
+               case sw::FORMAT_R16F:
+               case sw::FORMAT_G16R16F:
+               case sw::FORMAT_B16G16R16F:
+               case sw::FORMAT_A16B16G16R16F:
+               case sw::FORMAT_R32F:
+               case sw::FORMAT_G32R32F:
+               case sw::FORMAT_B32G32R32F:
                case sw::FORMAT_A32B32G32R32F: return GL_FLOAT;
-               case sw::FORMAT_A8R8G8B8:      return GL_UNSIGNED_BYTE;
-               case sw::FORMAT_A8B8G8R8:      return GL_UNSIGNED_BYTE;
-               case sw::FORMAT_X8R8G8B8:      return GL_UNSIGNED_BYTE;
+               case sw::FORMAT_R8I_SNORM:
+               case sw::FORMAT_G8R8I_SNORM:
+               case sw::FORMAT_X8B8G8R8I_SNORM:
+               case sw::FORMAT_A8B8G8R8I_SNORM:return GL_BYTE;
+               case sw::FORMAT_R8:
+               case sw::FORMAT_G8R8:
+               case sw::FORMAT_A8R8G8B8:
+               case sw::FORMAT_A8B8G8R8:
+               case sw::FORMAT_X8R8G8B8:
                case sw::FORMAT_X8B8G8R8:      return GL_UNSIGNED_BYTE;
+               case sw::FORMAT_R8I:
+               case sw::FORMAT_G8R8I:
+               case sw::FORMAT_X8B8G8R8I:
+               case sw::FORMAT_A8B8G8R8I:
+               case sw::FORMAT_R16I:
+               case sw::FORMAT_G16R16I:
+               case sw::FORMAT_X16B16G16R16I:
+               case sw::FORMAT_A16B16G16R16I:
+               case sw::FORMAT_R32I:
+               case sw::FORMAT_G32R32I:
+               case sw::FORMAT_X32B32G32R32I:
+               case sw::FORMAT_A32B32G32R32I: return GL_INT;
+               case sw::FORMAT_R8UI:
+               case sw::FORMAT_G8R8UI:
+               case sw::FORMAT_X8B8G8R8UI:
+               case sw::FORMAT_A8B8G8R8UI:
+               case sw::FORMAT_R16UI:
+               case sw::FORMAT_G16R16UI:
+               case sw::FORMAT_X16B16G16R16UI:
+               case sw::FORMAT_A16B16G16R16UI:
+               case sw::FORMAT_R32UI:
+               case sw::FORMAT_G32R32UI:
+               case sw::FORMAT_X32B32G32R32UI:
+               case sw::FORMAT_A32B32G32R32UI:return GL_UNSIGNED_INT;
+               case sw::FORMAT_A2B10G10R10:   return GL_UNSIGNED_INT_10_10_10_2_OES;
                case sw::FORMAT_A1R5G5B5:      return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
                case sw::FORMAT_R5G6B5:        return GL_UNSIGNED_SHORT_5_6_5;
                default:
index 8836945..e230759 100644 (file)
@@ -4744,6 +4744,14 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum
                case GL_RGBA16I:\r
                case GL_RGBA32I:\r
                case GL_RGBA32UI:\r
+               case GL_R16F:\r
+               case GL_RG16F:\r
+               case GL_R11F_G11F_B10F:\r
+               case GL_RGBA16F:\r
+               case GL_R32F:\r
+               case GL_RG32F:\r
+               case GL_RGB32F:\r
+               case GL_RGBA32F:\r
                        if(clientVersion < 3)\r
                        {\r
                                return error(GL_INVALID_ENUM);\r
@@ -4760,6 +4768,7 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum
                        context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));\r
                        break;\r
                case GL_DEPTH32F_STENCIL8:\r
+               case GL_DEPTH_COMPONENT32_OES:\r
                        if(clientVersion < 3)\r
                        {\r
                                return error(GL_INVALID_ENUM);\r
index f756918..2c99a87 100644 (file)
@@ -3951,7 +3951,7 @@ GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internal
                return error(GL_INVALID_VALUE);\r
        }\r
 \r
-       if(!IsColorRenderable(internalformat) && !IsDepthRenderable(internalformat) && !IsStencilRenderable(internalformat))\r
+       if(!IsColorRenderable(internalformat, egl::getClientVersion()) && !IsDepthRenderable(internalformat) && !IsStencilRenderable(internalformat))\r
        {\r
                return error(GL_INVALID_ENUM);\r
        }\r
index 6442993..d7ec68b 100644 (file)
@@ -377,6 +377,66 @@ namespace es2
                }\r
        }\r
 \r
+       bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion)\r
+       {\r
+               switch(format)\r
+               {\r
+               case GL_RGBA:\r
+                       switch(type)\r
+                       {\r
+                       case GL_UNSIGNED_BYTE:\r
+                               break;\r
+                       case GL_UNSIGNED_INT_2_10_10_10_REV:\r
+                               return (clientVersion >= 3) && (internalFormat == GL_RGB10_A2);\r
+                       case GL_FLOAT:\r
+                               return (clientVersion >= 3) && (internalType == GL_FLOAT);\r
+                       default:\r
+                               return false;\r
+                       }\r
+                       break;\r
+               case GL_RGBA_INTEGER:\r
+                       if(clientVersion < 3)\r
+                       {\r
+                               return false;\r
+                       }\r
+                       switch(type)\r
+                       {\r
+                       case GL_INT:\r
+                               if(internalType != GL_INT)\r
+                               {\r
+                                       return false;\r
+                               }\r
+                               break;\r
+                       case GL_UNSIGNED_INT:\r
+                               if(internalType != GL_UNSIGNED_INT)\r
+                               {\r
+                                       return false;\r
+                               }\r
+                               break;\r
+                       default:\r
+                               return false;\r
+                       }\r
+                       break;\r
+               case GL_BGRA_EXT:\r
+                       switch(type)\r
+                       {\r
+                       case GL_UNSIGNED_BYTE:\r
+                       case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:\r
+                       case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:\r
+                               break;\r
+                       default:\r
+                               return false;\r
+                       }\r
+                       break;\r
+               case GL_RG_EXT:\r
+               case GL_RED_EXT:\r
+                       return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE);\r
+               default:\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+\r
        bool IsDepthTexture(GLenum format)\r
        {\r
                return format == GL_DEPTH_COMPONENT ||\r
@@ -535,7 +595,7 @@ namespace es2
                }\r
        }\r
 \r
-       bool IsColorRenderable(GLenum internalformat)\r
+       bool IsColorRenderable(GLenum internalformat, egl::GLint clientVersion)\r
        {\r
                switch(internalformat)\r
                {\r
@@ -568,7 +628,18 @@ namespace es2
                case GL_RGB8_OES:\r
                case GL_RGBA8_OES:\r
                        return true;\r
+               case GL_R16F:\r
+               case GL_RG16F:\r
+               case GL_R11F_G11F_B10F:\r
+               case GL_RGB16F:\r
+               case GL_RGBA16F:\r
+               case GL_R32F:\r
+               case GL_RG32F:\r
+               case GL_RGB32F:\r
+               case GL_RGBA32F:\r
+                       return clientVersion >= 3;\r
                case GL_DEPTH_COMPONENT24:\r
+               case GL_DEPTH_COMPONENT32_OES:\r
                case GL_DEPTH_COMPONENT32F:\r
                case GL_DEPTH32F_STENCIL8:\r
                case GL_DEPTH_COMPONENT16:\r
@@ -587,6 +658,7 @@ namespace es2
                switch(internalformat)\r
                {\r
                case GL_DEPTH_COMPONENT24:\r
+               case GL_DEPTH_COMPONENT32_OES:\r
                case GL_DEPTH_COMPONENT32F:\r
                case GL_DEPTH32F_STENCIL8:\r
                case GL_DEPTH_COMPONENT16:\r
@@ -621,6 +693,15 @@ namespace es2
                case GL_RGB565:\r
                case GL_RGB8_OES:\r
                case GL_RGBA8_OES:\r
+               case GL_R16F:\r
+               case GL_RG16F:\r
+               case GL_R11F_G11F_B10F:\r
+               case GL_RGB16F:\r
+               case GL_RGBA16F:\r
+               case GL_R32F:\r
+               case GL_RG32F:\r
+               case GL_RGB32F:\r
+               case GL_RGBA32F:\r
                        return false;\r
                default:\r
                        UNIMPLEMENTED();\r
@@ -665,8 +746,18 @@ namespace es2
                case GL_RGB565:\r
                case GL_RGB8_OES:\r
                case GL_RGBA8_OES:\r
+               case GL_R16F:\r
+               case GL_RG16F:\r
+               case GL_R11F_G11F_B10F:\r
+               case GL_RGB16F:\r
+               case GL_RGBA16F:\r
+               case GL_R32F:\r
+               case GL_RG32F:\r
+               case GL_RGB32F:\r
+               case GL_RGBA32F:\r
                case GL_DEPTH_COMPONENT16:\r
                case GL_DEPTH_COMPONENT24:\r
+               case GL_DEPTH_COMPONENT32_OES:\r
                case GL_DEPTH_COMPONENT32F:\r
                        return false;\r
                default:\r
@@ -965,7 +1056,46 @@ namespace es2sw
                case GL_DEPTH_COMPONENT16:\r
                case GL_STENCIL_INDEX8:       \r
                case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;\r
-               default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;\r
+               case GL_DEPTH_COMPONENT32_OES:return sw::FORMAT_D32;\r
+               case GL_R8:                   return sw::FORMAT_R8;\r
+               case GL_RG8:                  return sw::FORMAT_G8R8;\r
+               case GL_R8I:                  return sw::FORMAT_R8I;\r
+               case GL_RG8I:                 return sw::FORMAT_G8R8I;\r
+               case GL_RGB8I:                return sw::FORMAT_X8B8G8R8I;\r
+               case GL_RGBA8I:               return sw::FORMAT_A8B8G8R8I;\r
+               case GL_R8UI:                 return sw::FORMAT_R8UI;\r
+               case GL_RG8UI:                return sw::FORMAT_G8R8UI;\r
+               case GL_RGB8UI:               return sw::FORMAT_X8B8G8R8UI;\r
+               case GL_RGBA8UI:              return sw::FORMAT_A8B8G8R8UI;\r
+               case GL_R16I:                 return sw::FORMAT_R16I;\r
+               case GL_RG16I:                return sw::FORMAT_G16R16I;\r
+               case GL_RGB16I:               return sw::FORMAT_X16B16G16R16I;\r
+               case GL_RGBA16I:              return sw::FORMAT_A16B16G16R16I;\r
+               case GL_R16UI:                return sw::FORMAT_R16UI;\r
+               case GL_RG16UI:               return sw::FORMAT_G16R16UI;\r
+               case GL_RGB16UI:              return sw::FORMAT_X16B16G16R16UI;\r
+               case GL_RGB10_A2UI:\r
+               case GL_RGBA16UI:             return sw::FORMAT_A16B16G16R16UI;\r
+               case GL_R32I:                 return sw::FORMAT_R32I;\r
+               case GL_RG32I:                return sw::FORMAT_G32R32I;\r
+               case GL_RGB32I:               return sw::FORMAT_X32B32G32R32I;\r
+               case GL_RGBA32I:              return sw::FORMAT_A32B32G32R32I;\r
+               case GL_R32UI:                return sw::FORMAT_R32UI;\r
+               case GL_RG32UI:               return sw::FORMAT_G32R32UI;\r
+               case GL_RGB32UI:              return sw::FORMAT_X32B32G32R32UI;\r
+               case GL_RGBA32UI:             return sw::FORMAT_A32B32G32R32UI;\r
+               case GL_R16F:                 return sw::FORMAT_R16F;\r
+               case GL_RG16F:                return sw::FORMAT_G16R16F;\r
+               case GL_R11F_G11F_B10F:\r
+               case GL_RGB16F:               return sw::FORMAT_B16G16R16F;\r
+               case GL_RGBA16F:              return sw::FORMAT_A16B16G16R16F;\r
+               case GL_R32F:                 return sw::FORMAT_R32F;\r
+               case GL_RG32F:                return sw::FORMAT_G32R32F;\r
+               case GL_RGB32F:               return sw::FORMAT_B32G32R32F;\r
+               case GL_RGBA32F:              return sw::FORMAT_A32B32G32R32F;\r
+               case GL_RGB10_A2:             return sw::FORMAT_A2B10G10R10;\r
+               case GL_SRGB8_ALPHA8:         // FIXME: Implement SRGB\r
+               default: UNREACHABLE(format); return sw::FORMAT_NULL;\r
                }\r
        }\r
 }\r
@@ -1002,14 +1132,23 @@ namespace sw2es
                switch(colorFormat)\r
                {\r
                case sw::FORMAT_A16B16G16R16F:\r
+               case sw::FORMAT_A16B16G16R16I:\r
+               case sw::FORMAT_A16B16G16R16UI:\r
                        return 16;\r
                case sw::FORMAT_A32B32G32R32F:\r
+               case sw::FORMAT_A32B32G32R32I:\r
+               case sw::FORMAT_A32B32G32R32UI:\r
                        return 32;\r
                case sw::FORMAT_A2R10G10B10:\r
                        return 2;\r
                case sw::FORMAT_A8R8G8B8:\r
                case sw::FORMAT_A8B8G8R8:\r
+               case sw::FORMAT_A8B8G8R8I:\r
+               case sw::FORMAT_A8B8G8R8UI:\r
+               case sw::FORMAT_A8B8G8R8I_SNORM:\r
                        return 8;\r
+               case sw::FORMAT_A2B10G10R10:\r
+                       return 2;\r
                case sw::FORMAT_A1R5G5B5:\r
                        return 1;\r
                case sw::FORMAT_X8R8G8B8:\r
@@ -1025,16 +1164,53 @@ namespace sw2es
        {\r
                switch(colorFormat)\r
                {\r
+               case sw::FORMAT_R16F:\r
+               case sw::FORMAT_G16R16F:\r
+               case sw::FORMAT_B16G16R16F:\r
                case sw::FORMAT_A16B16G16R16F:\r
+               case sw::FORMAT_R16I:\r
+               case sw::FORMAT_G16R16I:\r
+               case sw::FORMAT_X16B16G16R16I:\r
+               case sw::FORMAT_A16B16G16R16I:\r
+               case sw::FORMAT_R16UI:\r
+               case sw::FORMAT_G16R16UI:\r
+               case sw::FORMAT_X16B16G16R16UI:\r
+               case sw::FORMAT_A16B16G16R16UI:\r
                        return 16;\r
+               case sw::FORMAT_R32F:\r
+               case sw::FORMAT_G32R32F:\r
+               case sw::FORMAT_B32G32R32F:\r
                case sw::FORMAT_A32B32G32R32F:\r
+               case sw::FORMAT_R32I:\r
+               case sw::FORMAT_G32R32I:\r
+               case sw::FORMAT_X32B32G32R32I:\r
+               case sw::FORMAT_A32B32G32R32I:\r
+               case sw::FORMAT_R32UI:\r
+               case sw::FORMAT_G32R32UI:\r
+               case sw::FORMAT_X32B32G32R32UI:\r
+               case sw::FORMAT_A32B32G32R32UI:\r
                        return 32;\r
+               case sw::FORMAT_A2B10G10R10:\r
                case sw::FORMAT_A2R10G10B10:\r
                        return 10;\r
                case sw::FORMAT_A8R8G8B8:\r
                case sw::FORMAT_A8B8G8R8:\r
                case sw::FORMAT_X8R8G8B8:\r
                case sw::FORMAT_X8B8G8R8:\r
+               case sw::FORMAT_R8:\r
+               case sw::FORMAT_G8R8:\r
+               case sw::FORMAT_R8I:\r
+               case sw::FORMAT_G8R8I:\r
+               case sw::FORMAT_X8B8G8R8I:\r
+               case sw::FORMAT_A8B8G8R8I:\r
+               case sw::FORMAT_R8UI:\r
+               case sw::FORMAT_G8R8UI:\r
+               case sw::FORMAT_X8B8G8R8UI:\r
+               case sw::FORMAT_A8B8G8R8UI:\r
+               case sw::FORMAT_R8I_SNORM:\r
+               case sw::FORMAT_G8R8I_SNORM:\r
+               case sw::FORMAT_X8B8G8R8I_SNORM:\r
+               case sw::FORMAT_A8B8G8R8I_SNORM:\r
                        return 8;\r
                case sw::FORMAT_A1R5G5B5:\r
                case sw::FORMAT_R5G6B5:\r
@@ -1048,16 +1224,43 @@ namespace sw2es
        {\r
                switch(colorFormat)\r
                {\r
+               case sw::FORMAT_G16R16F:\r
+               case sw::FORMAT_B16G16R16F:\r
                case sw::FORMAT_A16B16G16R16F:\r
+               case sw::FORMAT_G16R16I:\r
+               case sw::FORMAT_X16B16G16R16I:\r
+               case sw::FORMAT_A16B16G16R16I:\r
+               case sw::FORMAT_G16R16UI:\r
+               case sw::FORMAT_X16B16G16R16UI:\r
+               case sw::FORMAT_A16B16G16R16UI:\r
                        return 16;\r
+               case sw::FORMAT_G32R32F:\r
+               case sw::FORMAT_B32G32R32F:\r
                case sw::FORMAT_A32B32G32R32F:\r
+               case sw::FORMAT_G32R32I:\r
+               case sw::FORMAT_X32B32G32R32I:\r
+               case sw::FORMAT_A32B32G32R32I:\r
+               case sw::FORMAT_G32R32UI:\r
+               case sw::FORMAT_X32B32G32R32UI:\r
+               case sw::FORMAT_A32B32G32R32UI:\r
                        return 32;\r
+               case sw::FORMAT_A2B10G10R10:\r
                case sw::FORMAT_A2R10G10B10:\r
                        return 10;\r
                case sw::FORMAT_A8R8G8B8:\r
                case sw::FORMAT_A8B8G8R8:\r
                case sw::FORMAT_X8R8G8B8:\r
                case sw::FORMAT_X8B8G8R8:\r
+               case sw::FORMAT_G8R8:\r
+               case sw::FORMAT_G8R8I:\r
+               case sw::FORMAT_X8B8G8R8I:\r
+               case sw::FORMAT_A8B8G8R8I:\r
+               case sw::FORMAT_G8R8UI:\r
+               case sw::FORMAT_X8B8G8R8UI:\r
+               case sw::FORMAT_A8B8G8R8UI:\r
+               case sw::FORMAT_G8R8I_SNORM:\r
+               case sw::FORMAT_X8B8G8R8I_SNORM:\r
+               case sw::FORMAT_A8B8G8R8I_SNORM:\r
                        return 8;\r
                case sw::FORMAT_A1R5G5B5:\r
                        return 5;\r
@@ -1072,16 +1275,33 @@ namespace sw2es
        {\r
                switch(colorFormat)\r
                {\r
+               case sw::FORMAT_B16G16R16F:\r
                case sw::FORMAT_A16B16G16R16F:\r
+               case sw::FORMAT_X16B16G16R16I:\r
+               case sw::FORMAT_A16B16G16R16I:\r
+               case sw::FORMAT_X16B16G16R16UI:\r
+               case sw::FORMAT_A16B16G16R16UI:\r
                        return 16;\r
+               case sw::FORMAT_B32G32R32F:\r
                case sw::FORMAT_A32B32G32R32F:\r
+               case sw::FORMAT_X32B32G32R32I:\r
+               case sw::FORMAT_A32B32G32R32I:\r
+               case sw::FORMAT_X32B32G32R32UI:\r
+               case sw::FORMAT_A32B32G32R32UI:\r
                        return 32;\r
+               case sw::FORMAT_A2B10G10R10:\r
                case sw::FORMAT_A2R10G10B10:\r
                        return 10;\r
                case sw::FORMAT_A8R8G8B8:\r
                case sw::FORMAT_A8B8G8R8:\r
                case sw::FORMAT_X8R8G8B8:\r
                case sw::FORMAT_X8B8G8R8:\r
+               case sw::FORMAT_X8B8G8R8I:\r
+               case sw::FORMAT_A8B8G8R8I:\r
+               case sw::FORMAT_X8B8G8R8UI:\r
+               case sw::FORMAT_A8B8G8R8UI:\r
+               case sw::FORMAT_X8B8G8R8I_SNORM:\r
+               case sw::FORMAT_A8B8G8R8I_SNORM:\r
                        return 8;\r
                case sw::FORMAT_A1R5G5B5:\r
                case sw::FORMAT_R5G6B5:\r
@@ -1134,9 +1354,44 @@ namespace sw2es
                case GL_COLOR_ATTACHMENT15:\r
                        switch(format)\r
                        {\r
+                       case sw::FORMAT_R8I:\r
+                       case sw::FORMAT_G8R8I:\r
+                       case sw::FORMAT_X8B8G8R8I:\r
+                       case sw::FORMAT_A8B8G8R8I:\r
+                       case sw::FORMAT_R16I:\r
+                       case sw::FORMAT_G16R16I:\r
+                       case sw::FORMAT_X16B16G16R16I:\r
+                       case sw::FORMAT_A16B16G16R16I:\r
+                       case sw::FORMAT_R32I:\r
+                       case sw::FORMAT_G32R32I:\r
+                       case sw::FORMAT_X32B32G32R32I:\r
+                       case sw::FORMAT_A32B32G32R32I:\r
+                               return GL_INT;\r
+                       case sw::FORMAT_R8UI:\r
+                       case sw::FORMAT_G8R8UI:\r
+                       case sw::FORMAT_X8B8G8R8UI:\r
+                       case sw::FORMAT_A8B8G8R8UI:\r
+                       case sw::FORMAT_R16UI:\r
+                       case sw::FORMAT_G16R16UI:\r
+                       case sw::FORMAT_X16B16G16R16UI:\r
+                       case sw::FORMAT_A16B16G16R16UI:\r
+                       case sw::FORMAT_R32UI:\r
+                       case sw::FORMAT_G32R32UI:\r
+                       case sw::FORMAT_X32B32G32R32UI:\r
+                       case sw::FORMAT_A32B32G32R32UI:\r
+                               return GL_UNSIGNED_INT;\r
+                       case sw::FORMAT_R16F:\r
+                       case sw::FORMAT_G16R16F:\r
+                       case sw::FORMAT_B16G16R16F:\r
                        case sw::FORMAT_A16B16G16R16F:\r
+                       case sw::FORMAT_R32F:\r
+                       case sw::FORMAT_G32R32F:\r
+                       case sw::FORMAT_B32G32R32F:\r
                        case sw::FORMAT_A32B32G32R32F:\r
                                return GL_FLOAT;\r
+                       case sw::FORMAT_R8:\r
+                       case sw::FORMAT_G8R8:\r
+                       case sw::FORMAT_A2B10G10R10:\r
                        case sw::FORMAT_A2R10G10B10:\r
                        case sw::FORMAT_A8R8G8B8:\r
                        case sw::FORMAT_A8B8G8R8:\r
@@ -1145,6 +1400,11 @@ namespace sw2es
                        case sw::FORMAT_A1R5G5B5:\r
                        case sw::FORMAT_R5G6B5:\r
                                return GL_UNSIGNED_NORMALIZED;\r
+                       case sw::FORMAT_R8I_SNORM:\r
+                       case sw::FORMAT_X8B8G8R8I_SNORM:\r
+                       case sw::FORMAT_A8B8G8R8I_SNORM:\r
+                       case sw::FORMAT_G8R8I_SNORM:\r
+                               return GL_SIGNED_NORMALIZED;\r
                        default:\r
                                UNREACHABLE(format);\r
                                return 0;\r
index cc1a1d1..7354f95 100644 (file)
@@ -42,6 +42,7 @@ namespace es2
 \r
        bool IsCompressed(GLenum format, egl::GLint clientVersion);\r
        GLenum ValidateCompressedFormat(GLenum format, egl::GLint clientVersion, bool expectCompressedFormats);\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
        bool IsCubemapTextureTarget(GLenum target);\r
@@ -49,7 +50,7 @@ namespace es2
        bool IsTextureTarget(GLenum target);\r
        bool CheckTextureFormatType(GLenum format, GLenum type, egl::GLint clientVersion);\r
 \r
-       bool IsColorRenderable(GLenum internalformat);\r
+       bool IsColorRenderable(GLenum internalformat, egl::GLint clientVersion);\r
        bool IsDepthRenderable(GLenum internalformat);\r
        bool IsStencilRenderable(GLenum internalformat);\r
 \r