OSDN Git Service

SRGB implementation
authorAlexis Hetu <sugoi@google.com>
Mon, 25 Apr 2016 20:59:58 +0000 (16:59 -0400)
committerAlexis Hétu <sugoi@google.com>
Thu, 28 Apr 2016 15:41:15 +0000 (15:41 +0000)
The SRGB conversion code was already available, but wasn't used
specifically for the SRGB type framebuffers. Also, the SRGB
conversion should always be applied after blending.

According to the GLES 3.0 spec, section 4.1.8 - sRGB Conversion:
"the R, G, and B values after blending are converted
 into the non-linear sRGB color space by computing."

All related dEQP tests pass.

Change-Id: I9342d2f74aa650f28835a951bdfa8bd371bc6924
Reviewed-on: https://swiftshader-review.googlesource.com/5189
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
src/Main/FrameBuffer.cpp
src/OpenGL/libGLESv2/Framebuffer.cpp
src/OpenGL/libGLESv2/Texture.cpp
src/OpenGL/libGLESv2/utilities.cpp
src/Renderer/Blitter.cpp
src/Renderer/Surface.cpp
src/Renderer/Surface.hpp
src/Shader/PixelProgram.cpp
src/Shader/PixelRoutine.cpp
src/Shader/PixelRoutine.hpp
src/Shader/SamplerCore.cpp

index aa3e55f..97d9afe 100644 (file)
@@ -369,6 +369,8 @@ namespace sw
                                        break;
                                case FORMAT_X8B8G8R8:
                                case FORMAT_A8B8G8R8:
+                               case FORMAT_SRGB8_X8:
+                               case FORMAT_SRGB8_A8:
                                        {
                                                Int x = x0;
 
@@ -689,6 +691,8 @@ namespace sw
                        break;
                case FORMAT_X8B8G8R8:
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                        {
                                c1 = Swizzle(c1, 0xC6);
 
index 6363f0c..5ab7b7e 100644 (file)
@@ -499,6 +499,7 @@ GLenum Framebuffer::getImplementationColorReadFormat()
                case sw::FORMAT_A32B32G32R32F:
                case sw::FORMAT_A8R8G8B8:
                case sw::FORMAT_A8B8G8R8:
+               case sw::FORMAT_SRGB8_A8:
                case sw::FORMAT_A1R5G5B5:      return GL_BGRA_EXT;
                case sw::FORMAT_X8B8G8R8I:
                case sw::FORMAT_X8B8G8R8UI:
@@ -509,6 +510,7 @@ GLenum Framebuffer::getImplementationColorReadFormat()
                case sw::FORMAT_X32B32G32R32F:
                case sw::FORMAT_B16G16R16F:
                case sw::FORMAT_X8B8G8R8I_SNORM:
+               case sw::FORMAT_SRGB8_X8:
                case sw::FORMAT_X8B8G8R8:      return GL_RGB;
                case sw::FORMAT_X8R8G8B8:      return 0x80E0;   // GL_BGR_EXT
                case sw::FORMAT_R5G6B5:        return GL_RGB;
@@ -563,6 +565,8 @@ GLenum Framebuffer::getImplementationColorReadType()
                case sw::FORMAT_A8B8G8R8I_SNORM:return GL_BYTE;
                case sw::FORMAT_R8:
                case sw::FORMAT_G8R8:
+               case sw::FORMAT_SRGB8_X8:
+               case sw::FORMAT_SRGB8_A8:
                case sw::FORMAT_A8R8G8B8:
                case sw::FORMAT_A8B8G8R8:
                case sw::FORMAT_X8R8G8B8:
index fe1824c..c27c113 100644 (file)
@@ -658,6 +658,7 @@ void Texture2D::bindTexImage(egl::Surface *surface)
     switch(surface->getInternalFormat())\r
     {\r
     case sw::FORMAT_A8R8G8B8:\r
+       case sw::FORMAT_SRGB8_A8:\r
                format = GL_BGRA_EXT;\r
         break;\r
        case sw::FORMAT_A8B8G8R8:\r
@@ -665,7 +666,8 @@ void Texture2D::bindTexImage(egl::Surface *surface)
         break;\r
     case sw::FORMAT_X8B8G8R8:\r
        case sw::FORMAT_X8R8G8B8:\r
-        format = GL_RGB;\r
+       case sw::FORMAT_SRGB8_X8:\r
+               format = GL_RGB;\r
         break;\r
     default:\r
         UNIMPLEMENTED();\r
index 04c288a..ffcad31 100644 (file)
@@ -1520,7 +1520,8 @@ namespace es2sw
                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
+               case GL_SRGB8:                return sw::FORMAT_SRGB8_X8;\r
+               case GL_SRGB8_ALPHA8:         return sw::FORMAT_SRGB8_A8;\r
                default: UNREACHABLE(format); return sw::FORMAT_NULL;\r
                }\r
        }\r
@@ -1571,6 +1572,7 @@ namespace sw2es
                        return 2;\r
                case sw::FORMAT_A8R8G8B8:\r
                case sw::FORMAT_A8B8G8R8:\r
+               case sw::FORMAT_SRGB8_A8:\r
                case sw::FORMAT_A8B8G8R8I:\r
                case sw::FORMAT_A8B8G8R8UI:\r
                case sw::FORMAT_A8B8G8R8I_SNORM:\r
@@ -1581,6 +1583,7 @@ namespace sw2es
                        return 1;\r
                case sw::FORMAT_X8R8G8B8:\r
                case sw::FORMAT_X8B8G8R8:\r
+               case sw::FORMAT_SRGB8_X8:\r
                case sw::FORMAT_R5G6B5:\r
                        return 0;\r
                default:\r
@@ -1626,6 +1629,8 @@ namespace sw2es
                case sw::FORMAT_A8B8G8R8:\r
                case sw::FORMAT_X8R8G8B8:\r
                case sw::FORMAT_X8B8G8R8:\r
+               case sw::FORMAT_SRGB8_A8:\r
+               case sw::FORMAT_SRGB8_X8:\r
                case sw::FORMAT_R8:\r
                case sw::FORMAT_G8R8:\r
                case sw::FORMAT_R8I:\r
@@ -1681,6 +1686,8 @@ namespace sw2es
                case sw::FORMAT_A8B8G8R8:\r
                case sw::FORMAT_X8R8G8B8:\r
                case sw::FORMAT_X8B8G8R8:\r
+               case sw::FORMAT_SRGB8_A8:\r
+               case sw::FORMAT_SRGB8_X8:\r
                case sw::FORMAT_G8R8:\r
                case sw::FORMAT_G8R8I:\r
                case sw::FORMAT_X8B8G8R8I:\r
@@ -1727,6 +1734,8 @@ namespace sw2es
                case sw::FORMAT_A8B8G8R8:\r
                case sw::FORMAT_X8R8G8B8:\r
                case sw::FORMAT_X8B8G8R8:\r
+               case sw::FORMAT_SRGB8_A8:\r
+               case sw::FORMAT_SRGB8_X8:\r
                case sw::FORMAT_X8B8G8R8I:\r
                case sw::FORMAT_A8B8G8R8I:\r
                case sw::FORMAT_X8B8G8R8UI:\r
@@ -1850,6 +1859,8 @@ namespace sw2es
                        case sw::FORMAT_A8B8G8R8:\r
                        case sw::FORMAT_X8R8G8B8:\r
                        case sw::FORMAT_X8B8G8R8:\r
+                       case sw::FORMAT_SRGB8_A8:\r
+                       case sw::FORMAT_SRGB8_X8:\r
                        case sw::FORMAT_A1R5G5B5:\r
                        case sw::FORMAT_R5G6B5:\r
                                return GL_UNSIGNED_NORMALIZED;\r
@@ -1883,6 +1894,8 @@ namespace sw2es
                case sw::FORMAT_R5G6B5:   return GL_RGB565;\r
                case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;\r
                case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;\r
+               case sw::FORMAT_SRGB8_A8: return GL_RGBA8_OES;\r
+               case sw::FORMAT_SRGB8_X8: return GL_RGB8_OES;\r
                default:\r
                        UNREACHABLE(format);\r
                }\r
index 88dd2e6..64ad6d0 100644 (file)
@@ -178,6 +178,7 @@ namespace sw
                        break;
                case FORMAT_A8B8G8R8:
                case FORMAT_A8B8G8R8UI:
+               case FORMAT_SRGB8_A8:
                        c = Float4(*Pointer<Byte4>(element));
                        break;
                case FORMAT_X8R8G8B8:
@@ -203,6 +204,7 @@ namespace sw
                        break;
                case FORMAT_X8B8G8R8:
                case FORMAT_X8B8G8R8UI:
+               case FORMAT_SRGB8_X8:
                        c = Float4(*Pointer<Byte4>(element));
                        c.w = float(0xFF);
                        break;
@@ -355,6 +357,7 @@ namespace sw
                        }
                        break;
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_A8:
                        if(writeRGBA)
                        {
                                UShort4 c0 = As<UShort4>(RoundShort4(c));
@@ -385,6 +388,7 @@ namespace sw
                        }
                        break;
                case FORMAT_X8B8G8R8:
+               case FORMAT_SRGB8_X8:
                        if(writeRGBA)
                        {
                                UShort4 c0 = As<UShort4>(RoundShort4(c));
@@ -924,6 +928,8 @@ namespace sw
                case FORMAT_B8G8R8:
                case FORMAT_X8B8G8R8:
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                        scale = vector(0xFF, 0xFF, 0xFF, 0xFF);
                        break;
                case FORMAT_R8I_SNORM:
index 8e5f4fb..d64e041 100644 (file)
@@ -130,6 +130,7 @@ namespace sw
                                                  (static_cast<unsigned int>(snorm<8>(color.r)) << 0);
                        break;
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_A8:
                        *(unsigned int*)element = (unorm<8>(color.a) << 24) | (unorm<8>(color.b) << 16) | (unorm<8>(color.g) << 8) | (unorm<8>(color.r) << 0);
                        break;
                case FORMAT_A8B8G8R8I:
@@ -148,6 +149,7 @@ namespace sw
                                                  (static_cast<unsigned int>(snorm<8>(color.r)) << 0);
                        break;
                case FORMAT_X8B8G8R8:
+               case FORMAT_SRGB8_X8:
                        *(unsigned int*)element = 0xFF000000 | (unorm<8>(color.b) << 16) | (unorm<8>(color.g) << 8) | (unorm<8>(color.r) << 0);
                        break;
                case FORMAT_X8B8G8R8I:
@@ -542,6 +544,7 @@ namespace sw
                        }
                        break;
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_A8:
                        {
                                unsigned int abgr = *(unsigned int*)element;
 
@@ -581,6 +584,7 @@ namespace sw
                        }
                        break;
                case FORMAT_X8B8G8R8:
+               case FORMAT_SRGB8_X8:
                        {
                                unsigned int xbgr = *(unsigned int*)element;
 
@@ -1469,6 +1473,8 @@ namespace sw
        //      case FORMAT_A8G8R8B8Q:                  return 4;
                case FORMAT_X8B8G8R8I:                  return 4;
                case FORMAT_X8B8G8R8:                   return 4;
+               case FORMAT_SRGB8_X8:                   return 4;
+               case FORMAT_SRGB8_A8:                   return 4;
                case FORMAT_A8B8G8R8I:                  return 4;
                case FORMAT_R8UI:                               return 1;
                case FORMAT_G8R8UI:                             return 2;
@@ -2645,6 +2651,8 @@ namespace sw
                case FORMAT_X8B8G8R8I:
                case FORMAT_X8B8G8R8:
                case FORMAT_A8R8G8B8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_A8B8G8R8I:
                case FORMAT_R8UI:
                case FORMAT_G8R8UI:
@@ -2725,6 +2733,8 @@ namespace sw
                case FORMAT_X8B8G8R8:
                case FORMAT_A8R8G8B8:
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_G8R8:
                case FORMAT_A2B10G10R10:
                case FORMAT_R16UI:
@@ -2804,6 +2814,8 @@ namespace sw
                case FORMAT_X8R8G8B8:
                case FORMAT_A8B8G8R8:
                case FORMAT_X8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_R5G6B5:
                case FORMAT_X1R5G5B5:
                case FORMAT_A1R5G5B5:
@@ -2833,6 +2845,8 @@ namespace sw
                case FORMAT_X8R8G8B8:
                case FORMAT_A8B8G8R8:
                case FORMAT_X8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_R5G6B5:
                        return true;
                default:
@@ -2939,6 +2953,8 @@ namespace sw
                case FORMAT_X8B8G8R8I:      return 3;
                case FORMAT_X8B8G8R8:       return 3;
                case FORMAT_A8R8G8B8:       return 4;
+               case FORMAT_SRGB8_X8:       return 3;
+               case FORMAT_SRGB8_A8:       return 4;
                case FORMAT_A8B8G8R8I:      return 4;
                case FORMAT_A8B8G8R8:       return 4;
                case FORMAT_G8R8I:          return 2;
@@ -3531,6 +3547,10 @@ namespace sw
                case FORMAT_B8G8R8:
                case FORMAT_X8B8G8R8:
                        return FORMAT_X8B8G8R8;
+               case FORMAT_SRGB8_X8:
+                       return FORMAT_SRGB8_X8;
+               case FORMAT_SRGB8_A8:
+                       return FORMAT_SRGB8_A8;
                // Compressed formats
                #if S3TC_SUPPORT
                case FORMAT_DXT1:
@@ -3687,7 +3707,9 @@ namespace sw
                unsigned char *sourceE = sourceD + slice;
                unsigned char *sourceF = sourceE + slice;
 
-               if(internal.format == FORMAT_X8R8G8B8 || internal.format == FORMAT_A8R8G8B8 || internal.format == FORMAT_X8B8G8R8 || internal.format == FORMAT_A8B8G8R8)
+               if(internal.format == FORMAT_X8R8G8B8 || internal.format == FORMAT_A8R8G8B8 ||
+                  internal.format == FORMAT_X8B8G8R8 || internal.format == FORMAT_A8B8G8R8 ||
+                  internal.format == FORMAT_SRGB8_X8 || internal.format == FORMAT_SRGB8_A8)
                {
                        if(CPUID::supportsSSE2() && (width % 4) == 0)
                        {
index 9e09753..e7764e8 100644 (file)
@@ -76,6 +76,8 @@ namespace sw
                FORMAT_A8B8G8R8UI,\r
                FORMAT_A8B8G8R8I_SNORM,\r
                FORMAT_A8B8G8R8, // UI_SNORM\r
+               FORMAT_SRGB8_X8,\r
+               FORMAT_SRGB8_A8,\r
                FORMAT_X1R5G5B5,\r
                FORMAT_A1R5G5B5,\r
                FORMAT_R5G5B5A1,\r
index c12097e..6f04f45 100644 (file)
@@ -578,7 +578,7 @@ namespace sw
                                continue;
                        }
 
-                       if(!postBlendSRGB && state.writeSRGB)
+                       if(!postBlendSRGB && state.writeSRGB && !isSRGB(index))
                        {
                                c[index].x = linearToSRGB(c[index].x);
                                c[index].y = linearToSRGB(c[index].y);
@@ -597,6 +597,8 @@ namespace sw
                        case FORMAT_X8B8G8R8:
                        case FORMAT_A8R8G8B8:
                        case FORMAT_A8B8G8R8:
+                       case FORMAT_SRGB8_X8:
+                       case FORMAT_SRGB8_A8:
                        case FORMAT_A8:
                        case FORMAT_G16R16:
                        case FORMAT_A16B16G16R16:
@@ -733,6 +735,8 @@ namespace sw
                        case FORMAT_A8B8G8R8:
                        case FORMAT_X8R8G8B8:
                        case FORMAT_X8B8G8R8:
+                       case FORMAT_SRGB8_X8:
+                       case FORMAT_SRGB8_A8:
                        case FORMAT_A8:
                        case FORMAT_G16R16:
                        case FORMAT_A16B16G16R16:
index ca38074..a1a752c 100644 (file)
@@ -996,6 +996,11 @@ namespace sw
                }
        }
 
+       bool PixelRoutine::isSRGB(int index) const
+       {
+               return state.targetFormat[index] == FORMAT_SRGB8_A8 || state.targetFormat[index] == FORMAT_SRGB8_X8;
+       }
+
        void PixelRoutine::readPixel(int index, Pointer<Byte> &cBuffer, Int &x, Vector4s &pixel)
        {
                Short4 c01;
@@ -1035,6 +1040,7 @@ namespace sw
                        pixel.w = UnpackHigh(As<Byte8>(pixel.w), As<Byte8>(pixel.w));
                        break;
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_A8:
                        buffer = cBuffer + 4 * x;
                        c01 = *Pointer<Short4>(buffer);
                        buffer += *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
@@ -1082,6 +1088,7 @@ namespace sw
                        pixel.w = Short4(0xFFFFu);
                        break;
                case FORMAT_X8B8G8R8:
+               case FORMAT_SRGB8_X8:
                        buffer = cBuffer + 4 * x;
                        c01 = *Pointer<Short4>(buffer);
                        buffer += *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
@@ -1141,7 +1148,7 @@ namespace sw
                        ASSERT(false);
                }
 
-               if(postBlendSRGB && state.writeSRGB)
+               if((postBlendSRGB && state.writeSRGB) || isSRGB(index))
                {
                        sRGBtoLinear16_12_16(pixel);
                }
@@ -1363,7 +1370,7 @@ namespace sw
 
        void PixelRoutine::writeColor(int index, Pointer<Byte> &cBuffer, Int &x, Vector4s &current, Int &sMask, Int &zMask, Int &cMask)
        {
-               if(postBlendSRGB && state.writeSRGB)
+               if((postBlendSRGB && state.writeSRGB) || isSRGB(index))
                {
                        linearToSRGB16_12_16(current);
                }
@@ -1383,6 +1390,8 @@ namespace sw
                        case FORMAT_X8B8G8R8:
                        case FORMAT_A8R8G8B8:
                        case FORMAT_A8B8G8R8:
+                       case FORMAT_SRGB8_X8:
+                       case FORMAT_SRGB8_A8:
                                current.x = current.x - As<Short4>(As<UShort4>(current.x) >> 8) + Short4(0x0080, 0x0080, 0x0080, 0x0080);
                                current.y = current.y - As<Short4>(As<UShort4>(current.y) >> 8) + Short4(0x0080, 0x0080, 0x0080, 0x0080);
                                current.z = current.z - As<Short4>(As<UShort4>(current.z) >> 8) + Short4(0x0080, 0x0080, 0x0080, 0x0080);
@@ -1465,7 +1474,9 @@ namespace sw
                        break;
                case FORMAT_X8B8G8R8:
                case FORMAT_A8B8G8R8:
-                       if(state.targetFormat[index] == FORMAT_X8B8G8R8 || rgbaWriteMask == 0x7)
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
+                       if(state.targetFormat[index] == FORMAT_X8B8G8R8 || state.targetFormat[index] == FORMAT_SRGB8_X8 || rgbaWriteMask == 0x7)
                        {
                                current.x = As<Short4>(As<UShort4>(current.x) >> 8);
                                current.y = As<Short4>(As<UShort4>(current.y) >> 8);
@@ -1655,13 +1666,17 @@ namespace sw
                        break;
                case FORMAT_A8B8G8R8:
                case FORMAT_X8B8G8R8:   // FIXME: Don't touch alpha?
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                        {
                                Pointer<Byte> buffer = cBuffer + x * 4;
                                Short4 value = *Pointer<Short4>(buffer);
 
-                               if((state.targetFormat[index] == FORMAT_A8B8G8R8 && rgbaWriteMask != 0x0000000F) ||
-                                  ((state.targetFormat[index] == FORMAT_X8B8G8R8 && rgbaWriteMask != 0x00000007) &&
-                                       (state.targetFormat[index] == FORMAT_X8B8G8R8 && rgbaWriteMask != 0x0000000F)))   // FIXME: Need for masking when XBGR && Fh?
+                               bool masked = (((state.targetFormat[index] == FORMAT_A8B8G8R8 || state.targetFormat[index] == FORMAT_SRGB8_A8) && rgbaWriteMask != 0x0000000F) ||
+                                             (((state.targetFormat[index] == FORMAT_X8B8G8R8 || state.targetFormat[index] == FORMAT_SRGB8_X8) && rgbaWriteMask != 0x00000007) &&
+                                              ((state.targetFormat[index] == FORMAT_X8B8G8R8 || state.targetFormat[index] == FORMAT_SRGB8_X8) && rgbaWriteMask != 0x0000000F))); // FIXME: Need for masking when XBGR && Fh?
+
+                               if(masked)
                                {
                                        Short4 masked = value;
                                        c01 &= *Pointer<Short4>(constants + OFFSET(Constants,maskB4Q[rgbaWriteMask][0]));
@@ -1677,9 +1692,7 @@ namespace sw
                                buffer += *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index]));
                                value = *Pointer<Short4>(buffer);
 
-                               if((state.targetFormat[index] == FORMAT_A8B8G8R8 && rgbaWriteMask != 0x0000000F) ||
-                                  ((state.targetFormat[index] == FORMAT_X8B8G8R8 && rgbaWriteMask != 0x00000007) &&
-                                       (state.targetFormat[index] == FORMAT_X8B8G8R8 && rgbaWriteMask != 0x0000000F)))   // FIXME: Need for masking when XBGR && Fh?
+                               if(masked)
                                {
                                        Short4 masked = value;
                                        c23 &= *Pointer<Short4>(constants + OFFSET(Constants,maskB4Q[rgbaWriteMask][0]));
@@ -2026,7 +2039,7 @@ namespace sw
                        ASSERT(false);
                }
 
-               if(postBlendSRGB && state.writeSRGB)
+               if((postBlendSRGB && state.writeSRGB) || isSRGB(index))
                {
                        sRGBtoLinear(pixel.x);
                        sRGBtoLinear(pixel.y);
index e631b62..2cce393 100644 (file)
@@ -58,6 +58,7 @@ namespace sw
                void alphaBlend(int index, Pointer<Byte> &cBuffer, Vector4f &oC, Int &x);
                void writeColor(int index, Pointer<Byte> &cBuffer, Int &i, Vector4f &oC, Int &sMask, Int &zMask, Int &cMask);
 
+               bool isSRGB(int index) const;
                UShort4 convertFixed16(Float4 &cf, bool saturate = true);
                void linearToSRGB12_16(Vector4s &c);
 
index 1dc78bf..956f526 100644 (file)
@@ -222,6 +222,8 @@ namespace sw
                                case FORMAT_X8B8G8R8:
                                case FORMAT_A8R8G8B8:
                                case FORMAT_A8B8G8R8:
+                               case FORMAT_SRGB8_X8:
+                               case FORMAT_SRGB8_A8:
                                case FORMAT_V8U8:
                                case FORMAT_Q8W8V8U8:
                                case FORMAT_X8L8V8U8:
@@ -480,6 +482,8 @@ namespace sw
                                case FORMAT_X8B8G8R8:
                                case FORMAT_A8R8G8B8:
                                case FORMAT_A8B8G8R8:
+                               case FORMAT_SRGB8_X8:
+                               case FORMAT_SRGB8_A8:
                                case FORMAT_V8U8:
                                case FORMAT_Q8W8V8U8:
                                case FORMAT_X8L8V8U8:
@@ -1738,6 +1742,7 @@ namespace sw
                                        case FORMAT_A8B8G8R8UI:
                                        case FORMAT_A8B8G8R8I_SNORM:
                                        case FORMAT_Q8W8V8U8:
+                                       case FORMAT_SRGB8_A8:
                                                c.z = c.x;
                                                c.x = As<Short4>(UnpackLow(c.x, c.y));
                                                c.z = As<Short4>(UnpackHigh(c.z, c.y));
@@ -1778,6 +1783,7 @@ namespace sw
                                        case FORMAT_X8B8G8R8I:
                                        case FORMAT_X8B8G8R8:
                                        case FORMAT_X8L8V8U8:
+                                       case FORMAT_SRGB8_X8:
                                                c.z = c.x;
                                                c.x = As<Short4>(UnpackLow(c.x, c.y));
                                                c.z = As<Short4>(UnpackHigh(c.z, c.y));
@@ -2213,6 +2219,8 @@ namespace sw
                case FORMAT_X8B8G8R8:
                case FORMAT_A8R8G8B8:
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_V8U8:
                case FORMAT_Q8W8V8U8:
                case FORMAT_X8L8V8U8:
@@ -2262,6 +2270,8 @@ namespace sw
                case FORMAT_X8B8G8R8:
                case FORMAT_A8R8G8B8:
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_V8U8:
                case FORMAT_Q8W8V8U8:
                case FORMAT_X8L8V8U8:
@@ -2354,6 +2364,8 @@ namespace sw
                case FORMAT_X8B8G8R8:
                case FORMAT_A8R8G8B8:
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_V8U8:
                case FORMAT_Q8W8V8U8:
                case FORMAT_X8L8V8U8:
@@ -2429,6 +2441,8 @@ namespace sw
                case FORMAT_X8B8G8R8:
                case FORMAT_A8R8G8B8:
                case FORMAT_A8B8G8R8:
+               case FORMAT_SRGB8_X8:
+               case FORMAT_SRGB8_A8:
                case FORMAT_V8U8:
                case FORMAT_Q8W8V8U8:
                case FORMAT_X8L8V8U8:
@@ -2496,6 +2510,8 @@ namespace sw
                case FORMAT_X8B8G8R8:       return component < 3;
                case FORMAT_A8R8G8B8:       return component < 3;
                case FORMAT_A8B8G8R8:       return component < 3;
+               case FORMAT_SRGB8_X8:       return component < 3;
+               case FORMAT_SRGB8_A8:       return component < 3;
                case FORMAT_V8U8:           return false;
                case FORMAT_Q8W8V8U8:       return false;
                case FORMAT_X8L8V8U8:       return false;