Commit 05b05028 by Geoff Lang

Add support for EXT_sRGB.

BUG=angle:672 Change-Id: I001ff3dde7a39e545a535a399c02f3a6d91634c8 Reviewed-on: https://chromium-review.googlesource.com/203460Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 66aaf723
......@@ -125,6 +125,7 @@ std::vector<std::string> Extensions::getStrings(GLuint clientVersion) const
InsertExtensionString("GL_EXT_texture_compression_dxt1", 2, 0, textureCompressionDXT1, clientVersion, &extensionStrings);
InsertExtensionString("GL_ANGLE_texture_compression_dxt3", 2, 0, textureCompressionDXT3, clientVersion, &extensionStrings);
InsertExtensionString("GL_ANGLE_texture_compression_dxt5", 2, 0, textureCompressionDXT5, clientVersion, &extensionStrings);
InsertExtensionString("GL_EXT_sRGB", 2, 0, sRGB, clientVersion, &extensionStrings); // FIXME: Don't advertise in ES3
InsertExtensionString("GL_ANGLE_depth_texture", 2, 0, depthTextures, clientVersion, &extensionStrings);
InsertExtensionString("GL_EXT_texture_storage", 2, 0, textureStorage, clientVersion, &extensionStrings);
InsertExtensionString("GL_OES_texture_npot", 2, 0, textureNPOT, clientVersion, &extensionStrings);
......@@ -282,6 +283,20 @@ static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
return GetFormatSupport(textureCaps, requiredFormats, true, false, false);
}
// Check for GL_ANGLE_texture_compression_dxt5
static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
{
std::vector<GLenum> requiredFilterFormats;
requiredFilterFormats.push_back(GL_SRGB8);
requiredFilterFormats.push_back(GL_SRGB8_ALPHA8);
std::vector<GLenum> requiredRenderFormats;
requiredRenderFormats.push_back(GL_SRGB8_ALPHA8);
return GetFormatSupport(textureCaps, requiredFilterFormats, true, false, false) &&
GetFormatSupport(textureCaps, requiredRenderFormats, false, true, false);
}
// Check for GL_ANGLE_depth_texture
static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps)
{
......@@ -320,6 +335,7 @@ void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps);
textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps);
textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps);
sRGB = DetermineSRGBTextureSupport(textureCaps);
depthTextures = DetermineDepthTextureSupport(textureCaps);
colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps);
}
......
......@@ -119,6 +119,11 @@ struct Extensions
bool textureCompressionDXT3;
bool textureCompressionDXT5;
// GL_EXT_sRGB
// Implies that TextureCaps for GL_SRGB8_ALPHA8 and GL_SRGB8 exist
// TODO: Don't advertise this extension in ES3
bool sRGB;
// GL_ANGLE_depth_texture
bool depthTextures;
......
......@@ -80,6 +80,9 @@ FormatMap BuildES2FormatMap()
InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F_EXT, WriteColor<R32G32B32A32F, GLfloat>);
InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F_EXT, WriteColor<R16G16B16A16F, GLfloat>);
InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8, WriteColor<R8G8B8, GLfloat> );
InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8, WriteColor<R8G8B8A8, GLfloat> );
InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT, WriteColor<B8G8R8A8, GLfloat> );
InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX, WriteColor<B4G4R4A4, GLfloat> );
InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX, WriteColor<B5G5R5A1, GLfloat> );
......@@ -175,6 +178,9 @@ FormatMap BuildES3FormatMap()
InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX, WriteColor<B4G4R4A4, GLfloat> );
InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX, WriteColor<B5G5R5A1, GLfloat> );
InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8, WriteColor<R8G8B8, GLfloat> );
InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8, WriteColor<R8G8B8A8, GLfloat> );
InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, NULL );
InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL );
InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL );
......@@ -307,6 +313,8 @@ ES3FormatSet BuildES3FormatSet()
set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_SRGB_EXT, GL_SRGB_EXT, GL_UNSIGNED_BYTE ));
// Depth stencil formats
set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT ));
......@@ -316,6 +324,10 @@ ES3FormatSet BuildES3FormatSet()
set.insert(FormatInfo(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 ));
set.insert(FormatInfo(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
// From GL_EXT_sRGB
set.insert(FormatInfo(GL_SRGB8_ALPHA8_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_SRGB8, GL_SRGB_EXT, GL_UNSIGNED_BYTE ));
// From GL_OES_texture_float
set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT ));
set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT ));
......@@ -712,6 +724,8 @@ static InternalFormatInfoMap BuildES3InternalFormatInfoMap()
map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_SRGB_EXT, InternalFormatInfo::UnsizedFormat(GL_RGB, CheckSupport<&Extensions::sRGB>)));
map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, InternalFormatInfo::UnsizedFormat(GL_RGBA, CheckSupport<&Extensions::sRGB>)));
// Compressed formats, From ES 3.0.1 spec, table 3.16
// | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported |
......@@ -761,6 +775,10 @@ static InternalFormatInfoMap BuildES2InternalFormatInfoMap()
map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Extensions::textureFormatBGRA8888>)));
map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Extensions::textureFormatBGRA8888>)));
// From GL_EXT_sRGB
map.insert(InternalFormatInfoPair(GL_SRGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, CheckSupport<&Extensions::sRGB>)));
map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, CheckSupport<&Extensions::sRGB>)));
// Floating point formats have to query the renderer for support
// | Internal format | | R | G | B | A |S | Format | Type | Comp | SRGB | Supported |
// | | | | | | | | | | type | | |
......@@ -793,6 +811,8 @@ static InternalFormatInfoMap BuildES2InternalFormatInfoMap()
map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, CheckSupport<&Extensions::textureFormatBGRA8888>)));
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL_OES, InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL_OES, CheckSupport<&Extensions::packedDepthStencil> )));
map.insert(InternalFormatInfoPair(GL_SRGB_EXT, InternalFormatInfo::UnsizedFormat(GL_RGB, CheckSupport<&Extensions::sRGB> )));
map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, InternalFormatInfo::UnsizedFormat(GL_RGBA, CheckSupport<&Extensions::sRGB> )));
// Luminance alpha formats from GL_EXT_texture_storage
// | Internal format | | L | A | Format | Type | Component type | Supported |
......
......@@ -2016,6 +2016,13 @@ void __stdcall glGenerateMipmap(GLenum target)
return gl::error(GL_INVALID_OPERATION);
}
// GL_EXT_sRGB does not support mipmap generation on sRGB textures
if (context->getClientVersion() == 2 &&
gl::GetColorEncoding(internalFormat, context->getClientVersion()) == GL_SRGB)
{
return gl::error(GL_INVALID_OPERATION);
}
// Non-power of 2 ES2 check
if (!context->getCaps().extensions.textureNPOT && (!gl::isPow2(texture->getBaseLevelWidth()) || !gl::isPow2(texture->getBaseLevelHeight())))
{
......@@ -2552,6 +2559,12 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
break;
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
if (clientVersion < 3 && !context->getCaps().extensions.sRGB)
{
return gl::error(GL_INVALID_ENUM);
}
break;
case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
......@@ -2559,12 +2572,12 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
if (clientVersion >= 3)
if (clientVersion < 3)
{
break;
return gl::error(GL_INVALID_ENUM);
}
break;
default:
return gl::error(GL_INVALID_ENUM);
}
......
......@@ -169,6 +169,7 @@ class Renderer
virtual bool getPostSubBufferSupport() const = 0;
virtual int getMaxRecommendedElementsIndices() const = 0;
virtual int getMaxRecommendedElementsVertices() const = 0;
virtual bool getSRGBTextureSupport() const = 0;
virtual int getMajorShaderModel() const = 0;
virtual float getMaxPointSize() const = 0;
......
......@@ -2037,6 +2037,11 @@ int Renderer11::getMaxRecommendedElementsVertices() const
return std::numeric_limits<GLint>::max();
}
bool Renderer11::getSRGBTextureSupport() const
{
return true;
}
int Renderer11::getMajorShaderModel() const
{
switch (mFeatureLevel)
......
......@@ -123,6 +123,7 @@ class Renderer11 : public Renderer
virtual bool getPostSubBufferSupport() const;
virtual int getMaxRecommendedElementsIndices() const;
virtual int getMaxRecommendedElementsVertices() const;
virtual bool getSRGBTextureSupport() const;
virtual int getMajorShaderModel() const;
virtual float getMaxPointSize() const;
......
......@@ -406,6 +406,10 @@ static D3D11ES2FormatMap BuildD3D11ES2FormatMap()
map.insert(D3D11ES2FormatPair(GL_BGRA4_ANGLEX, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA4444DataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_BGR5_A1_ANGLEX, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA5551DataToRGBA )));
// From GL_EXT_sRGB
map.insert(D3D11ES2FormatPair(GL_SRGB8, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadToNative3To4<GLubyte, 0xFF> )));
map.insert(D3D11ES2FormatPair(GL_SRGB8_ALPHA8, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, loadToNative<GLubyte, 4> )));
// From GL_EXT_texture_rg
map.insert(D3D11ES2FormatPair(GL_R8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN, loadToNative<GLubyte, 1> )));
map.insert(D3D11ES2FormatPair(GL_R32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, loadToNative<GLfloat, 1> )));
......
......@@ -2362,6 +2362,11 @@ int Renderer9::getMaxRecommendedElementsVertices() const
return 0;
}
bool Renderer9::getSRGBTextureSupport() const
{
return false;
}
int Renderer9::getMajorShaderModel() const
{
return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
......
......@@ -124,6 +124,7 @@ class Renderer9 : public Renderer
virtual bool getPostSubBufferSupport() const;
virtual int getMaxRecommendedElementsIndices() const;
virtual int getMaxRecommendedElementsVertices() const;
virtual bool getSRGBTextureSupport() const;
virtual int getMajorShaderModel() const;
virtual float getMaxPointSize() const;
......
......@@ -740,7 +740,6 @@ D3DFORMAT GetTextureFormat(GLenum internalFormat)
}
else
{
UNREACHABLE();
return D3DFMT_UNKNOWN;
}
}
......@@ -754,7 +753,6 @@ D3DFORMAT GetRenderFormat(GLenum internalFormat)
}
else
{
UNREACHABLE();
return D3DFMT_UNKNOWN;
}
}
......
......@@ -341,6 +341,20 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
return gl::error(GL_INVALID_OPERATION, false);
}
break;
case GL_SRGB_EXT:
case GL_SRGB_ALPHA_EXT:
if (!context->getCaps().extensions.sRGB)
{
return gl::error(GL_INVALID_ENUM, false);
}
switch (type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return gl::error(GL_INVALID_OPERATION, false);
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
......
#include "ANGLETest.h"
class SRGBTextureTest : public ANGLETest
{
protected:
SRGBTextureTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
virtual void SetUp()
{
ANGLETest::SetUp();
}
virtual void TearDown()
{
ANGLETest::TearDown();
}
};
TEST_F(SRGBTextureTest, srgb_validation)
{
bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3;
GLuint tex = 0;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
GLubyte pixel[3] = { 0 };
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, 1, 1, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel);
if (supported)
{
EXPECT_GL_NO_ERROR();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel);
EXPECT_GL_NO_ERROR();
glGenerateMipmap(GL_TEXTURE_2D);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
else
{
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
glDeleteTextures(1, &tex);
}
TEST_F(SRGBTextureTest, srgba_validation)
{
bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3;
GLuint tex = 0;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
GLubyte pixel[4] = { 0 };
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel);
if (supported)
{
EXPECT_GL_NO_ERROR();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel);
EXPECT_GL_NO_ERROR();
glGenerateMipmap(GL_TEXTURE_2D);
if (getClientVersion() == 2)
{
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
else
{
EXPECT_GL_NO_ERROR();
}
}
else
{
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
glDeleteTextures(1, &tex);
}
TEST_F(SRGBTextureTest, srgba_renderbuffer)
{
bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3;
GLuint rbo = 0;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8_EXT, 1, 1);
if (supported)
{
EXPECT_GL_NO_ERROR();
}
else
{
EXPECT_GL_ERROR(GL_INVALID_ENUM);
// Make sure the rbo has a size for future tests
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1);
EXPECT_GL_NO_ERROR();
}
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
EXPECT_GL_NO_ERROR();
GLint colorEncoding = 0;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT, &colorEncoding);
if (supported)
{
EXPECT_GL_NO_ERROR();
EXPECT_EQ(GL_SRGB_EXT, colorEncoding);
}
else
{
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
glDeleteFramebuffers(1, &fbo);
glDeleteRenderbuffers(1, &rbo);
}
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