Commit 5555af49 by Nicolas Capens Committed by Nicolas Capens

Implement sRGB texture sampling.

Previously sRGB data was converted to linear space on upload. This caused a loss of precision. This change performs the conversion after texel lookup. Note that we had a code path for performing the conversion after filtering, but that leads to failures in dEQP and unacceptable darkening between texels. Also, glTexSubImage calls can update sRGB textures using a format/type combination with no indication of the color space, which caused an unintentional conversion on upload. Likewise we were missing support for an A2B10G10R10UI implementation format. Change-Id: Ib10845f628fb2d1849e88d7a9350868cdec32fa2 Reviewed-on: https://swiftshader-review.googlesource.com/15068Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent e13238e0
......@@ -52,8 +52,6 @@ namespace
RGB10A2UI,
R11G11B10F,
RGB9E5,
SRGB,
SRGBA,
D16,
D24,
D32,
......@@ -298,36 +296,6 @@ namespace
}
template<>
void LoadImageRow<SRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{
dest += xoffset * 4;
for(int x = 0; x < width; x++)
{
for(int rgb = 0; rgb < 3; ++rgb)
{
*dest++ = sw::sRGB8toLinear8(*source++);
}
*dest++ = 255;
}
}
template<>
void LoadImageRow<SRGBA>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{
dest += xoffset * 4;
for(int x = 0; x < width; x++)
{
for(int rgb = 0; rgb < 3; ++rgb)
{
*dest++ = sw::sRGB8toLinear8(*source++);
}
*dest++ = *source++;
}
}
template<>
void LoadImageRow<D16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{
const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
......@@ -559,6 +527,7 @@ namespace egl
{
case GL_INT: return sw::FORMAT_A32B32G32R32I;
case GL_UNSIGNED_INT: return sw::FORMAT_A32B32G32R32UI;
case GL_UNSIGNED_INT_2_10_10_10_REV: return sw::FORMAT_A2B10G10R10UI;
default: UNREACHABLE(type);
}
break;
......@@ -805,16 +774,18 @@ namespace egl
case GL_RGB8_SNORM:
case GL_RGB8:
case GL_RGB:
case GL_SRGB8:
return sw::FORMAT_X8B8G8R8;
case GL_SRGB8:
return sw::FORMAT_SRGB8_X8;
case GL_RGB8UI:
case GL_RGB_INTEGER:
return sw::FORMAT_X8B8G8R8UI;
case GL_RGBA8_SNORM:
case GL_RGBA8:
case GL_RGBA:
case GL_SRGB8_ALPHA8:
return sw::FORMAT_A8B8G8R8;
case GL_SRGB8_ALPHA8:
return sw::FORMAT_SRGB8_A8;
case GL_RGBA8UI:
case GL_RGBA_INTEGER:
return sw::FORMAT_A8B8G8R8UI;
......@@ -934,7 +905,7 @@ namespace egl
case GL_UNSIGNED_INT_2_10_10_10_REV:
if(format == GL_RGB10_A2UI)
{
return sw::FORMAT_A16B16G16R16UI;
return sw::FORMAT_A2B10G10R10UI;
}
else
{
......@@ -1338,8 +1309,8 @@ namespace egl
void Image::loadImageData(Context *context, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input)
{
sw::Format selectedInternalFormat = SelectInternalFormat(format, type);
if(selectedInternalFormat == sw::FORMAT_NULL)
sw::Format uploadFormat = SelectInternalFormat(format, type);
if(uploadFormat == sw::FORMAT_NULL)
{
return;
}
......@@ -1349,7 +1320,10 @@ namespace egl
GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight;
input = ((char*)input) + ComputePackingOffset(format, type, inputWidth, inputHeight, unpackInfo.alignment, unpackInfo.skipImages, unpackInfo.skipRows, unpackInfo.skipPixels);
if(selectedInternalFormat == internalFormat)
if(uploadFormat == internalFormat ||
(uploadFormat == sw::FORMAT_A8B8G8R8 && internalFormat == sw::FORMAT_SRGB8_A8) ||
(uploadFormat == sw::FORMAT_X8B8G8R8 && internalFormat == sw::FORMAT_SRGB8_X8) ||
(uploadFormat == sw::FORMAT_A2B10G10R10 && internalFormat == sw::FORMAT_A2B10G10R10UI))
{
void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
......@@ -1427,6 +1401,7 @@ namespace egl
case GL_RGB8_SNORM:
case GL_RGB:
case GL_RGB_INTEGER:
case GL_SRGB8:
LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getSlice(), input, buffer);
break;
case GL_RGBA8:
......@@ -1436,13 +1411,8 @@ namespace egl
case GL_RGBA_INTEGER:
case GL_BGRA_EXT:
case GL_BGRA8_EXT:
LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getSlice(), input, buffer);
break;
case GL_SRGB8:
LoadImageData<SRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getSlice(), input, buffer);
break;
case GL_SRGB8_ALPHA8:
LoadImageData<SRGBA>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getSlice(), input, buffer);
LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getSlice(), input, buffer);
break;
default: UNREACHABLE(format);
}
......@@ -1501,8 +1471,6 @@ namespace egl
switch(format)
{
case GL_RGB10_A2UI:
LoadImageData<RGB10A2UI>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getSlice(), input, buffer);
break;
case GL_RGB10_A2:
case GL_RGBA:
case GL_RGBA_INTEGER:
......
......@@ -5062,7 +5062,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
if(validationError != GL_NONE)
{
return error(validationError);
......@@ -5423,8 +5423,6 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
if(context)
{
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
if(target == GL_TEXTURE_2D)
{
es2::Texture2D *texture = context->getTexture2D();
......@@ -5435,13 +5433,13 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
return error(validationError);
}
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
if(validationError != GL_NONE)
{
return error(validationError);
}
texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
texture->subImage(context, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), data);
}
else if(es2::IsCubemapTextureTarget(target))
{
......@@ -5453,13 +5451,13 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
return error(validationError);
}
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
if(validationError != GL_NONE)
{
return error(validationError);
}
texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
texture->subImage(context, target, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), data);
}
else UNREACHABLE(target);
}
......@@ -6342,21 +6340,19 @@ void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset,
{
es2::Texture3D *texture = context->getTexture3D();
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
if(validationError != GL_NONE)
{
return error(validationError);
}
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
if(validationError != GL_NONE)
{
return error(validationError);
}
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), data);
}
}
......
......@@ -2193,7 +2193,6 @@ namespace es2sw
case GL_R16UI: return sw::FORMAT_R16UI;
case GL_RG16UI: return sw::FORMAT_G16R16UI;
case GL_RGB16UI: return sw::FORMAT_X16B16G16R16UI;
case GL_RGB10_A2UI:
case GL_RGBA16UI: return sw::FORMAT_A16B16G16R16UI;
case GL_R32I: return sw::FORMAT_R32I;
case GL_RG32I: return sw::FORMAT_G32R32I;
......@@ -2213,6 +2212,7 @@ namespace es2sw
case GL_RGB32F: return sw::FORMAT_B32G32R32F;
case GL_RGBA32F: return sw::FORMAT_A32B32G32R32F;
case GL_RGB10_A2: return sw::FORMAT_A2B10G10R10;
case GL_RGB10_A2UI: return sw::FORMAT_A2B10G10R10UI;
case GL_SRGB8: return sw::FORMAT_SRGB8_X8;
case GL_SRGB8_ALPHA8: return sw::FORMAT_SRGB8_A8;
default: UNREACHABLE(format); return sw::FORMAT_NULL;
......
......@@ -393,6 +393,7 @@ namespace sw
c.z = Float(Int(*Pointer<UShort>(element) & UShort(0x001F)));
break;
case FORMAT_A2B10G10R10:
case FORMAT_A2B10G10R10UI:
c.x = Float(Int((*Pointer<UInt>(element) & UInt(0x000003FF))));
c.y = Float(Int((*Pointer<UInt>(element) & UInt(0x000FFC00)) >> 10));
c.z = Float(Int((*Pointer<UInt>(element) & UInt(0x3FF00000)) >> 20));
......@@ -741,6 +742,7 @@ namespace sw
}
break;
case FORMAT_A2B10G10R10:
case FORMAT_A2B10G10R10UI:
if(writeRGBA)
{
*Pointer<UInt>(element) = UInt(RoundInt(Float(c.x)) |
......@@ -1047,6 +1049,7 @@ namespace sw
case FORMAT_B32G32R32F:
case FORMAT_G32R32F:
case FORMAT_R32F:
case FORMAT_A2B10G10R10UI:
scale = vector(1.0f, 1.0f, 1.0f, 1.0f);
break;
case FORMAT_R5G6B5:
......
......@@ -96,7 +96,7 @@ namespace sw
state.addressingModeV = getAddressingModeV();
state.addressingModeW = getAddressingModeW();
state.mipmapFilter = mipmapFilter();
state.sRGB = sRGB && Surface::isSRGBreadable(externalTextureFormat);
state.sRGB = (sRGB && Surface::isSRGBreadable(externalTextureFormat)) || Surface::isSRGBformat(internalTextureFormat);
state.swizzleR = swizzleR;
state.swizzleG = swizzleG;
state.swizzleB = swizzleB;
......
......@@ -169,6 +169,7 @@ namespace sw
*(unsigned int*)element = (unorm<2>(color.a) << 30) | (unorm<10>(color.r) << 20) | (unorm<10>(color.g) << 10) | (unorm<10>(color.b) << 0);
break;
case FORMAT_A2B10G10R10:
case FORMAT_A2B10G10R10UI:
*(unsigned int*)element = (unorm<2>(color.a) << 30) | (unorm<10>(color.b) << 20) | (unorm<10>(color.g) << 10) | (unorm<10>(color.r) << 0);
break;
case FORMAT_G8R8I_SNORM:
......@@ -701,6 +702,16 @@ namespace sw
r = (abgr & 0x000003FF) * (1.0f / 0x000003FF);
}
break;
case FORMAT_A2B10G10R10UI:
{
unsigned int abgr = *(unsigned int*)element;
a = static_cast<float>((abgr & 0xC0000000) >> 30);
b = static_cast<float>((abgr & 0x3FF00000) >> 20);
g = static_cast<float>((abgr & 0x000FFC00) >> 10);
r = static_cast<float>(abgr & 0x000003FF);
}
break;
case FORMAT_A16B16G16R16I:
{
short* abgr = (short*)element;
......@@ -1544,6 +1555,7 @@ namespace sw
case FORMAT_A8B8G8R8I_SNORM: return 4;
case FORMAT_A2R10G10B10: return 4;
case FORMAT_A2B10G10R10: return 4;
case FORMAT_A2B10G10R10UI: return 4;
case FORMAT_G8R8I: return 2;
case FORMAT_G8R8: return 2;
case FORMAT_G16R16I: return 4;
......@@ -2824,6 +2836,7 @@ namespace sw
case FORMAT_G8R8I:
case FORMAT_G8R8:
case FORMAT_A2B10G10R10:
case FORMAT_A2B10G10R10UI:
case FORMAT_R8I_SNORM:
case FORMAT_G8R8I_SNORM:
case FORMAT_X8B8G8R8I_SNORM:
......@@ -2908,6 +2921,7 @@ namespace sw
case FORMAT_SRGB8_A8:
case FORMAT_G8R8:
case FORMAT_A2B10G10R10:
case FORMAT_A2B10G10R10UI:
case FORMAT_R16UI:
case FORMAT_G16R16:
case FORMAT_G16R16UI:
......@@ -3027,6 +3041,18 @@ namespace sw
}
}
bool Surface::isSRGBformat(Format format)
{
switch(format)
{
case FORMAT_SRGB8_X8:
case FORMAT_SRGB8_A8:
return true;
default:
return false;
}
}
bool Surface::isCompressed(Format format)
{
switch(format)
......@@ -3166,6 +3192,7 @@ namespace sw
case FORMAT_X8B8G8R8UI: return 3;
case FORMAT_A8B8G8R8UI: return 4;
case FORMAT_A2B10G10R10: return 4;
case FORMAT_A2B10G10R10UI: return 4;
case FORMAT_G16R16I: return 2;
case FORMAT_G16R16UI: return 2;
case FORMAT_G16R16: return 2;
......@@ -3765,6 +3792,8 @@ namespace sw
case FORMAT_A2B10G10R10:
case FORMAT_A16B16G16R16:
return FORMAT_A16B16G16R16;
case FORMAT_A2B10G10R10UI:
return FORMAT_A16B16G16R16UI;
case FORMAT_X32B32G32R32I:
return FORMAT_X32B32G32R32I;
case FORMAT_A32B32G32R32I:
......
......@@ -107,6 +107,7 @@ namespace sw
FORMAT_G32R32UI,
FORMAT_A2R10G10B10,
FORMAT_A2B10G10R10,
FORMAT_A2B10G10R10UI,
FORMAT_A16B16G16R16, // D3D format
FORMAT_X16B16G16R16I,
FORMAT_X16B16G16R16UI,
......@@ -368,6 +369,7 @@ namespace sw
static bool isUnsignedComponent(Format format, int component);
static bool isSRGBreadable(Format format);
static bool isSRGBwritable(Format format);
static bool isSRGBformat(Format format);
static bool isCompressed(Format format);
static bool isSignedNonNormalizedInteger(Format format);
static bool isUnsignedNonNormalizedInteger(Format format);
......
......@@ -264,17 +264,17 @@ namespace sw
for(int i = 0; i < 256; i++)
{
sRGBtoLinear8_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0xFF) * 0x1000 + 0.5f);
sRGBtoLinear8_16[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0xFF) * 0xFFFF + 0.5f);
}
for(int i = 0; i < 64; i++)
{
sRGBtoLinear6_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x3F) * 0x1000 + 0.5f);
sRGBtoLinear6_16[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x3F) * 0xFFFF + 0.5f);
}
for(int i = 0; i < 32; i++)
{
sRGBtoLinear5_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x1F) * 0x1000 + 0.5f);
sRGBtoLinear5_16[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x1F) * 0xFFFF + 0.5f);
}
for(int i = 0; i < 0x1000; i++)
......
......@@ -22,7 +22,7 @@ namespace sw
struct Constants
{
Constants();
unsigned int transposeBit0[16];
unsigned int transposeBit1[16];
unsigned int transposeBit2[16];
......@@ -67,9 +67,9 @@ namespace sw
dword4 maskD01X[4];
word4 mask565Q[8];
unsigned short sRGBtoLinear8_12[256];
unsigned short sRGBtoLinear6_12[64];
unsigned short sRGBtoLinear5_12[32];
unsigned short sRGBtoLinear8_16[256];
unsigned short sRGBtoLinear6_16[64];
unsigned short sRGBtoLinear5_16[32];
unsigned short linearToSRGB12_16[4096];
unsigned short sRGBtoLinear12_16[4096];
......
......@@ -133,46 +133,23 @@ namespace sw
if(fixed12 && !hasFloatTexture())
{
if(has16bitTextureFormat())
if(state.textureFormat == FORMAT_R5G6B5)
{
switch(state.textureFormat)
{
case FORMAT_R5G6B5:
if(state.sRGB)
{
sRGBtoLinear16_5_12(c.x);
sRGBtoLinear16_6_12(c.y);
sRGBtoLinear16_5_12(c.z);
}
else
{
c.x = MulHigh(As<UShort4>(c.x), UShort4(0x10000000 / 0xF800));
c.y = MulHigh(As<UShort4>(c.y), UShort4(0x10000000 / 0xFC00));
c.z = MulHigh(As<UShort4>(c.z), UShort4(0x10000000 / 0xF800));
}
break;
default:
ASSERT(false);
}
c.x = MulHigh(As<UShort4>(c.x), UShort4(0x10000000 / 0xF800));
c.y = MulHigh(As<UShort4>(c.y), UShort4(0x10000000 / 0xFC00));
c.z = MulHigh(As<UShort4>(c.z), UShort4(0x10000000 / 0xF800));
}
else
{
for(int component = 0; component < textureComponentCount(); component++)
{
if(state.sRGB && isRGBComponent(component))
if(hasUnsignedTextureComponent(component))
{
sRGBtoLinear16_8_12(c[component]); // FIXME: Perform linearization at surface level for read-only textures
c[component] = As<UShort4>(c[component]) >> 4;
}
else
{
if(hasUnsignedTextureComponent(component))
{
c[component] = As<UShort4>(c[component]) >> 4;
}
else
{
c[component] = c[component] >> 3;
}
c[component] = c[component] >> 3;
}
}
}
......@@ -316,8 +293,8 @@ namespace sw
}
else
{
// FIXME: YUV and sRGB are not supported by the floating point path
bool forceFloatFiltering = state.highPrecisionFiltering && !state.sRGB && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
// FIXME: YUV is not supported by the floating point path
bool forceFloatFiltering = state.highPrecisionFiltering && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS);
if(hasFloatTexture() || hasUnnormalizedIntegerTexture() || forceFloatFiltering || seamlessCube) // FIXME: Mostly identical to integer sampling
{
......@@ -380,52 +357,23 @@ namespace sw
{
Vector4s cs = sampleTexture(texture, u, v, w, q, bias, dsx, dsy, offset, function, false);
if(has16bitTextureFormat())
if(state.textureFormat == FORMAT_R5G6B5)
{
switch(state.textureFormat)
{
case FORMAT_R5G6B5:
if(state.sRGB)
{
sRGBtoLinear16_5_12(cs.x);
sRGBtoLinear16_6_12(cs.y);
sRGBtoLinear16_5_12(cs.z);
convertSigned12(c.x, cs.x);
convertSigned12(c.y, cs.y);
convertSigned12(c.z, cs.z);
}
else
{
c.x = Float4(As<UShort4>(cs.x)) * Float4(1.0f / 0xF800);
c.y = Float4(As<UShort4>(cs.y)) * Float4(1.0f / 0xFC00);
c.z = Float4(As<UShort4>(cs.z)) * Float4(1.0f / 0xF800);
}
break;
default:
ASSERT(false);
}
c.x = Float4(As<UShort4>(cs.x)) * Float4(1.0f / 0xF800);
c.y = Float4(As<UShort4>(cs.y)) * Float4(1.0f / 0xFC00);
c.z = Float4(As<UShort4>(cs.z)) * Float4(1.0f / 0xF800);
}
else
{
for(int component = 0; component < textureComponentCount(); component++)
{
// Normalized integer formats
if(state.sRGB && isRGBComponent(component))
if(hasUnsignedTextureComponent(component))
{
sRGBtoLinear16_8_12(cs[component]); // FIXME: Perform linearization at surface level for read-only textures
convertSigned12(c[component], cs[component]);
convertUnsigned16(c[component], cs[component]);
}
else
{
if(hasUnsignedTextureComponent(component))
{
convertUnsigned16(c[component], cs[component]);
}
else
{
convertSigned15(c[component], cs[component]);
}
convertSigned15(c[component], cs[component]);
}
}
}
......@@ -2036,6 +1984,26 @@ namespace sw
}
else ASSERT(false);
if(state.sRGB)
{
if(state.textureFormat == FORMAT_R5G6B5)
{
sRGBtoLinear16_5_16(c.x);
sRGBtoLinear16_6_16(c.y);
sRGBtoLinear16_5_16(c.z);
}
else
{
for(int i = 0; i < textureComponentCount(); i++)
{
if(isRGBComponent(i))
{
sRGBtoLinear16_8_16(c[i]);
}
}
}
}
return c;
}
......@@ -2238,7 +2206,7 @@ namespace sw
bool isInteger = Surface::isNonNormalizedInteger(state.textureFormat);
int componentCount = textureComponentCount();
for(int n = 0; n < componentCount; ++n)
for(int n = 0; n < componentCount; n++)
{
if(hasUnsignedTextureComponent(n))
{
......@@ -2555,11 +2523,11 @@ namespace sw
cf = Float4(As<UShort4>(cs)) * Float4(1.0f / 0xFFFF);
}
void SamplerCore::sRGBtoLinear16_8_12(Short4 &c)
void SamplerCore::sRGBtoLinear16_8_16(Short4 &c)
{
c = As<UShort4>(c) >> 8;
Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear8_12));
Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear8_16));
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
......@@ -2567,11 +2535,11 @@ namespace sw
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 3))), 3);
}
void SamplerCore::sRGBtoLinear16_6_12(Short4 &c)
void SamplerCore::sRGBtoLinear16_6_16(Short4 &c)
{
c = As<UShort4>(c) >> 10;
Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear6_12));
Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear6_16));
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
......@@ -2579,11 +2547,11 @@ namespace sw
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 3))), 3);
}
void SamplerCore::sRGBtoLinear16_5_12(Short4 &c)
void SamplerCore::sRGBtoLinear16_5_16(Short4 &c)
{
c = As<UShort4>(c) >> 11;
Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear5_12));
Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear5_16));
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
......
......@@ -92,9 +92,9 @@ namespace sw
void convertSigned12(Float4 &cf, Short4 &ci);
void convertSigned15(Float4 &cf, Short4 &ci);
void convertUnsigned16(Float4 &cf, Short4 &ci);
void sRGBtoLinear16_8_12(Short4 &c);
void sRGBtoLinear16_6_12(Short4 &c);
void sRGBtoLinear16_5_12(Short4 &c);
void sRGBtoLinear16_8_16(Short4 &c);
void sRGBtoLinear16_6_16(Short4 &c);
void sRGBtoLinear16_5_16(Short4 &c);
bool hasFloatTexture() const;
bool hasUnnormalizedIntegerTexture() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment