Add support for EXT_sRGB.
BUG=angle:672
Change-Id: I001ff3dde7a39e545a535a399c02f3a6d91634c8
Reviewed-on: https://chromium-review.googlesource.com/203460
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Caps.cpp b/src/libGLESv2/Caps.cpp
index 42aa70a..088e502 100644
--- a/src/libGLESv2/Caps.cpp
+++ b/src/libGLESv2/Caps.cpp
@@ -125,6 +125,7 @@
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 @@
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 @@
textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps);
textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps);
textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps);
+ sRGB = DetermineSRGBTextureSupport(textureCaps);
depthTextures = DetermineDepthTextureSupport(textureCaps);
colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps);
}
diff --git a/src/libGLESv2/Caps.h b/src/libGLESv2/Caps.h
index 4ad7b9d..7fd5443 100644
--- a/src/libGLESv2/Caps.h
+++ b/src/libGLESv2/Caps.h
@@ -119,6 +119,11 @@
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;
diff --git a/src/libGLESv2/formatutils.cpp b/src/libGLESv2/formatutils.cpp
index 8f249b5..ed6e05f 100644
--- a/src/libGLESv2/formatutils.cpp
+++ b/src/libGLESv2/formatutils.cpp
@@ -80,6 +80,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 |
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 791332b..0c08ac8 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -2016,6 +2016,13 @@
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 @@
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 @@
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);
}
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index cb20bac..b50513c 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -169,6 +169,7 @@
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;
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index a58822f..11033cb 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -2037,6 +2037,11 @@
return std::numeric_limits<GLint>::max();
}
+bool Renderer11::getSRGBTextureSupport() const
+{
+ return true;
+}
+
int Renderer11::getMajorShaderModel() const
{
switch (mFeatureLevel)
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d11/Renderer11.h
index e940599..490e190 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.h
@@ -123,6 +123,7 @@
virtual bool getPostSubBufferSupport() const;
virtual int getMaxRecommendedElementsIndices() const;
virtual int getMaxRecommendedElementsVertices() const;
+ virtual bool getSRGBTextureSupport() const;
virtual int getMajorShaderModel() const;
virtual float getMaxPointSize() const;
diff --git a/src/libGLESv2/renderer/d3d11/formatutils11.cpp b/src/libGLESv2/renderer/d3d11/formatutils11.cpp
index 6252cce..0ad37a8 100644
--- a/src/libGLESv2/renderer/d3d11/formatutils11.cpp
+++ b/src/libGLESv2/renderer/d3d11/formatutils11.cpp
@@ -406,6 +406,10 @@
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> )));
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
index 05916d8..46b7a72 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
@@ -2362,6 +2362,11 @@
return 0;
}
+bool Renderer9::getSRGBTextureSupport() const
+{
+ return false;
+}
+
int Renderer9::getMajorShaderModel() const
{
return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d9/Renderer9.h
index 71fc69f..d7c32f2 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.h
@@ -124,6 +124,7 @@
virtual bool getPostSubBufferSupport() const;
virtual int getMaxRecommendedElementsIndices() const;
virtual int getMaxRecommendedElementsVertices() const;
+ virtual bool getSRGBTextureSupport() const;
virtual int getMajorShaderModel() const;
virtual float getMaxPointSize() const;
diff --git a/src/libGLESv2/renderer/d3d9/formatutils9.cpp b/src/libGLESv2/renderer/d3d9/formatutils9.cpp
index 7eb25d8..752f196 100644
--- a/src/libGLESv2/renderer/d3d9/formatutils9.cpp
+++ b/src/libGLESv2/renderer/d3d9/formatutils9.cpp
@@ -740,7 +740,6 @@
}
else
{
- UNREACHABLE();
return D3DFMT_UNKNOWN;
}
}
@@ -754,7 +753,6 @@
}
else
{
- UNREACHABLE();
return D3DFMT_UNKNOWN;
}
}
diff --git a/src/libGLESv2/validationES2.cpp b/src/libGLESv2/validationES2.cpp
index 9c54ee9..f2ba5da 100644
--- a/src/libGLESv2/validationES2.cpp
+++ b/src/libGLESv2/validationES2.cpp
@@ -341,6 +341,20 @@
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:
diff --git a/tests/angle_tests/SRGBTextureTest.cpp b/tests/angle_tests/SRGBTextureTest.cpp
new file mode 100644
index 0000000..090b2c2
--- /dev/null
+++ b/tests/angle_tests/SRGBTextureTest.cpp
@@ -0,0 +1,133 @@
+#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);
+}