break;
case FORMAT_X8B8G8R8:
case FORMAT_A8B8G8R8:
+ case FORMAT_SRGB8_X8:
+ case FORMAT_SRGB8_A8:
{
Int x = x0;
break;
case FORMAT_X8B8G8R8:
case FORMAT_A8B8G8R8:
+ case FORMAT_SRGB8_X8:
+ case FORMAT_SRGB8_A8:
{
c1 = Swizzle(c1, 0xC6);
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:
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;
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:
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
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
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
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
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
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
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
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
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
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
break;
case FORMAT_A8B8G8R8:
case FORMAT_A8B8G8R8UI:
+ case FORMAT_SRGB8_A8:
c = Float4(*Pointer<Byte4>(element));
break;
case FORMAT_X8R8G8B8:
break;
case FORMAT_X8B8G8R8:
case FORMAT_X8B8G8R8UI:
+ case FORMAT_SRGB8_X8:
c = Float4(*Pointer<Byte4>(element));
c.w = float(0xFF);
break;
}
break;
case FORMAT_A8B8G8R8:
+ case FORMAT_SRGB8_A8:
if(writeRGBA)
{
UShort4 c0 = As<UShort4>(RoundShort4(c));
}
break;
case FORMAT_X8B8G8R8:
+ case FORMAT_SRGB8_X8:
if(writeRGBA)
{
UShort4 c0 = As<UShort4>(RoundShort4(c));
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:
(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:
(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:
}
break;
case FORMAT_A8B8G8R8:
+ case FORMAT_SRGB8_A8:
{
unsigned int abgr = *(unsigned int*)element;
}
break;
case FORMAT_X8B8G8R8:
+ case FORMAT_SRGB8_X8:
{
unsigned int xbgr = *(unsigned int*)element;
// 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;
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:
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:
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:
case FORMAT_X8R8G8B8:
case FORMAT_A8B8G8R8:
case FORMAT_X8B8G8R8:
+ case FORMAT_SRGB8_X8:
+ case FORMAT_SRGB8_A8:
case FORMAT_R5G6B5:
return true;
default:
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;
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:
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)
{
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
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);
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:
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:
}
}
+ 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;
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]));
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]));
ASSERT(false);
}
- if(postBlendSRGB && state.writeSRGB)
+ if((postBlendSRGB && state.writeSRGB) || isSRGB(index))
{
sRGBtoLinear16_12_16(pixel);
}
void PixelRoutine::writeColor(int index, Pointer<Byte> &cBuffer, Int &x, Vector4s ¤t, Int &sMask, Int &zMask, Int &cMask)
{
- if(postBlendSRGB && state.writeSRGB)
+ if((postBlendSRGB && state.writeSRGB) || isSRGB(index))
{
linearToSRGB16_12_16(current);
}
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);
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);
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]));
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]));
ASSERT(false);
}
- if(postBlendSRGB && state.writeSRGB)
+ if((postBlendSRGB && state.writeSRGB) || isSRGB(index))
{
sRGBtoLinear(pixel.x);
sRGBtoLinear(pixel.y);
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);
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:
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:
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));
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));
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:
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:
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:
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:
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;