xref: /aosp_15_r20/external/angle/src/tests/gl_tests/SRGBTextureTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
8*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker namespace angle
11*8975f5c5SAndroid Build Coastguard Worker {
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker // These two colors are equivelent in different colorspaces
14*8975f5c5SAndroid Build Coastguard Worker constexpr GLColor kLinearColor(64, 127, 191, 255);
15*8975f5c5SAndroid Build Coastguard Worker constexpr GLColor kNonlinearColor(13, 54, 133, 255);
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker class SRGBTextureTest : public ANGLETest<>
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker   protected:
SRGBTextureTest()20*8975f5c5SAndroid Build Coastguard Worker     SRGBTextureTest()
21*8975f5c5SAndroid Build Coastguard Worker     {
22*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(128);
23*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(128);
24*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
25*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
26*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
27*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
28*8975f5c5SAndroid Build Coastguard Worker     }
29*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()30*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
31*8975f5c5SAndroid Build Coastguard Worker     {
32*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] =
33*8975f5c5SAndroid Build Coastguard Worker             "precision highp float;\n"
34*8975f5c5SAndroid Build Coastguard Worker             "attribute vec4 position;\n"
35*8975f5c5SAndroid Build Coastguard Worker             "varying vec2 texcoord;\n"
36*8975f5c5SAndroid Build Coastguard Worker             "\n"
37*8975f5c5SAndroid Build Coastguard Worker             "void main()\n"
38*8975f5c5SAndroid Build Coastguard Worker             "{\n"
39*8975f5c5SAndroid Build Coastguard Worker             "   gl_Position = vec4(position.xy, 0.0, 1.0);\n"
40*8975f5c5SAndroid Build Coastguard Worker             "   texcoord = (position.xy * 0.5) + 0.5;\n"
41*8975f5c5SAndroid Build Coastguard Worker             "}\n";
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] =
44*8975f5c5SAndroid Build Coastguard Worker             "precision highp float;\n"
45*8975f5c5SAndroid Build Coastguard Worker             "uniform sampler2D tex;\n"
46*8975f5c5SAndroid Build Coastguard Worker             "varying vec2 texcoord;\n"
47*8975f5c5SAndroid Build Coastguard Worker             "\n"
48*8975f5c5SAndroid Build Coastguard Worker             "void main()\n"
49*8975f5c5SAndroid Build Coastguard Worker             "{\n"
50*8975f5c5SAndroid Build Coastguard Worker             "   gl_FragColor = texture2D(tex, texcoord);\n"
51*8975f5c5SAndroid Build Coastguard Worker             "}\n";
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(kVS, kFS);
54*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, mProgram);
55*8975f5c5SAndroid Build Coastguard Worker 
56*8975f5c5SAndroid Build Coastguard Worker         mTextureLocation = glGetUniformLocation(mProgram, "tex");
57*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, mTextureLocation);
58*8975f5c5SAndroid Build Coastguard Worker     }
59*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()60*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override { glDeleteProgram(mProgram); }
61*8975f5c5SAndroid Build Coastguard Worker 
getSRGBA8TextureInternalFormat() const62*8975f5c5SAndroid Build Coastguard Worker     GLenum getSRGBA8TextureInternalFormat() const
63*8975f5c5SAndroid Build Coastguard Worker     {
64*8975f5c5SAndroid Build Coastguard Worker         return getClientMajorVersion() >= 3 ? GL_SRGB8_ALPHA8 : GL_SRGB_ALPHA_EXT;
65*8975f5c5SAndroid Build Coastguard Worker     }
66*8975f5c5SAndroid Build Coastguard Worker 
getSRGBA8TextureFormat() const67*8975f5c5SAndroid Build Coastguard Worker     GLenum getSRGBA8TextureFormat() const
68*8975f5c5SAndroid Build Coastguard Worker     {
69*8975f5c5SAndroid Build Coastguard Worker         return getClientMajorVersion() >= 3 ? GL_RGBA : GL_SRGB_ALPHA_EXT;
70*8975f5c5SAndroid Build Coastguard Worker     }
71*8975f5c5SAndroid Build Coastguard Worker 
getSRGB8TextureInternalFormat() const72*8975f5c5SAndroid Build Coastguard Worker     GLenum getSRGB8TextureInternalFormat() const
73*8975f5c5SAndroid Build Coastguard Worker     {
74*8975f5c5SAndroid Build Coastguard Worker         return getClientMajorVersion() >= 3 ? GL_SRGB8 : GL_SRGB_EXT;
75*8975f5c5SAndroid Build Coastguard Worker     }
76*8975f5c5SAndroid Build Coastguard Worker 
getSRGB8TextureFormat() const77*8975f5c5SAndroid Build Coastguard Worker     GLenum getSRGB8TextureFormat() const
78*8975f5c5SAndroid Build Coastguard Worker     {
79*8975f5c5SAndroid Build Coastguard Worker         return getClientMajorVersion() >= 3 ? GL_RGB : GL_SRGB_EXT;
80*8975f5c5SAndroid Build Coastguard Worker     }
81*8975f5c5SAndroid Build Coastguard Worker 
82*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram        = 0;
83*8975f5c5SAndroid Build Coastguard Worker     GLint mTextureLocation = -1;
84*8975f5c5SAndroid Build Coastguard Worker };
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker class SRGBTextureTestES3 : public SRGBTextureTest
87*8975f5c5SAndroid Build Coastguard Worker {};
88*8975f5c5SAndroid Build Coastguard Worker 
89*8975f5c5SAndroid Build Coastguard Worker // GenerateMipmaps should generate INVALID_OPERATION in ES 2.0 / WebGL 1.0 with EXT_sRGB.
90*8975f5c5SAndroid Build Coastguard Worker // https://bugs.chromium.org/p/chromium/issues/detail?id=769989
TEST_P(SRGBTextureTest,SRGBValidation)91*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTest, SRGBValidation)
92*8975f5c5SAndroid Build Coastguard Worker {
93*8975f5c5SAndroid Build Coastguard Worker     // TODO(fjhenigman): Figure out why this fails on Ozone Intel.
94*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone() && IsIntel() && IsOpenGLES());
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker     bool supported = IsGLExtensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3;
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker     GLuint tex = 0;
99*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &tex);
100*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     GLubyte pixel[3] = {0};
103*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGB8TextureInternalFormat(), 1, 1, 0,
104*8975f5c5SAndroid Build Coastguard Worker                  getSRGB8TextureFormat(), GL_UNSIGNED_BYTE, pixel);
105*8975f5c5SAndroid Build Coastguard Worker     if (supported)
106*8975f5c5SAndroid Build Coastguard Worker     {
107*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSRGB8TextureFormat(), GL_UNSIGNED_BYTE,
110*8975f5c5SAndroid Build Coastguard Worker                         pixel);
111*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker         // Mipmap generation always generates errors for SRGB unsized in ES2 or SRGB8 sized in ES3.
114*8975f5c5SAndroid Build Coastguard Worker         glGenerateMipmap(GL_TEXTURE_2D);
115*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
116*8975f5c5SAndroid Build Coastguard Worker     }
117*8975f5c5SAndroid Build Coastguard Worker     else
118*8975f5c5SAndroid Build Coastguard Worker     {
119*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_ENUM);
120*8975f5c5SAndroid Build Coastguard Worker     }
121*8975f5c5SAndroid Build Coastguard Worker 
122*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &tex);
123*8975f5c5SAndroid Build Coastguard Worker }
124*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SRGBTextureTest,SRGBAValidation)125*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTest, SRGBAValidation)
126*8975f5c5SAndroid Build Coastguard Worker {
127*8975f5c5SAndroid Build Coastguard Worker     // TODO(fjhenigman): Figure out why this fails on Ozone Intel.
128*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone() && IsIntel() && IsOpenGLES());
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker     bool supported = IsGLExtensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3;
131*8975f5c5SAndroid Build Coastguard Worker 
132*8975f5c5SAndroid Build Coastguard Worker     GLuint tex = 0;
133*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &tex);
134*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker     GLubyte pixel[4] = {0};
137*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
138*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, pixel);
139*8975f5c5SAndroid Build Coastguard Worker     if (supported)
140*8975f5c5SAndroid Build Coastguard Worker     {
141*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE,
144*8975f5c5SAndroid Build Coastguard Worker                         pixel);
145*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker         glGenerateMipmap(GL_TEXTURE_2D);
148*8975f5c5SAndroid Build Coastguard Worker         if (getClientMajorVersion() < 3)
149*8975f5c5SAndroid Build Coastguard Worker         {
150*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
151*8975f5c5SAndroid Build Coastguard Worker         }
152*8975f5c5SAndroid Build Coastguard Worker         else
153*8975f5c5SAndroid Build Coastguard Worker         {
154*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_NO_ERROR();
155*8975f5c5SAndroid Build Coastguard Worker         }
156*8975f5c5SAndroid Build Coastguard Worker     }
157*8975f5c5SAndroid Build Coastguard Worker     else
158*8975f5c5SAndroid Build Coastguard Worker     {
159*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_ENUM);
160*8975f5c5SAndroid Build Coastguard Worker     }
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &tex);
163*8975f5c5SAndroid Build Coastguard Worker }
164*8975f5c5SAndroid Build Coastguard Worker 
165*8975f5c5SAndroid Build Coastguard Worker // Test that sized SRGBA formats allow generating mipmaps
TEST_P(SRGBTextureTestES3,SRGBASizedValidation)166*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBASizedValidation)
167*8975f5c5SAndroid Build Coastguard Worker {
168*8975f5c5SAndroid Build Coastguard Worker     // TODO(fjhenigman): Figure out why this fails on Ozone Intel.
169*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone() && IsIntel() && IsOpenGLES());
170*8975f5c5SAndroid Build Coastguard Worker 
171*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
172*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
173*8975f5c5SAndroid Build Coastguard Worker 
174*8975f5c5SAndroid Build Coastguard Worker     GLubyte pixel[4] = {0};
175*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
176*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, pixel);
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
181*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
182*8975f5c5SAndroid Build Coastguard Worker 
183*8975f5c5SAndroid Build Coastguard Worker     glGenerateMipmap(GL_TEXTURE_2D);
184*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
185*8975f5c5SAndroid Build Coastguard Worker }
186*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SRGBTextureTest,SRGBARenderbuffer)187*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTest, SRGBARenderbuffer)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker     bool supported = IsGLExtensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3;
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker     GLuint rbo = 0;
192*8975f5c5SAndroid Build Coastguard Worker     glGenRenderbuffers(1, &rbo);
193*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
194*8975f5c5SAndroid Build Coastguard Worker 
195*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8_EXT, 1, 1);
196*8975f5c5SAndroid Build Coastguard Worker     if (supported)
197*8975f5c5SAndroid Build Coastguard Worker     {
198*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
199*8975f5c5SAndroid Build Coastguard Worker     }
200*8975f5c5SAndroid Build Coastguard Worker     else
201*8975f5c5SAndroid Build Coastguard Worker     {
202*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_ENUM);
203*8975f5c5SAndroid Build Coastguard Worker 
204*8975f5c5SAndroid Build Coastguard Worker         // Make sure the rbo has a size for future tests
205*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1);
206*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
207*8975f5c5SAndroid Build Coastguard Worker     }
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker     GLuint fbo = 0;
210*8975f5c5SAndroid Build Coastguard Worker     glGenFramebuffers(1, &fbo);
211*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
212*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
213*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker     GLint colorEncoding = 0;
216*8975f5c5SAndroid Build Coastguard Worker     glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
217*8975f5c5SAndroid Build Coastguard Worker                                           GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,
218*8975f5c5SAndroid Build Coastguard Worker                                           &colorEncoding);
219*8975f5c5SAndroid Build Coastguard Worker     if (supported)
220*8975f5c5SAndroid Build Coastguard Worker     {
221*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
222*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GL_SRGB_EXT, colorEncoding);
223*8975f5c5SAndroid Build Coastguard Worker     }
224*8975f5c5SAndroid Build Coastguard Worker     else
225*8975f5c5SAndroid Build Coastguard Worker     {
226*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_ENUM);
227*8975f5c5SAndroid Build Coastguard Worker     }
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker     glDeleteFramebuffers(1, &fbo);
230*8975f5c5SAndroid Build Coastguard Worker     glDeleteRenderbuffers(1, &rbo);
231*8975f5c5SAndroid Build Coastguard Worker }
232*8975f5c5SAndroid Build Coastguard Worker 
233*8975f5c5SAndroid Build Coastguard Worker // Verify that if the srgb decode extension is available, srgb textures are too
TEST_P(SRGBTextureTest,SRGBDecodeExtensionAvailability)234*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTest, SRGBDecodeExtensionAvailability)
235*8975f5c5SAndroid Build Coastguard Worker {
236*8975f5c5SAndroid Build Coastguard Worker     bool hasSRGBDecode = IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode");
237*8975f5c5SAndroid Build Coastguard Worker     if (hasSRGBDecode)
238*8975f5c5SAndroid Build Coastguard Worker     {
239*8975f5c5SAndroid Build Coastguard Worker         bool hasSRGBTextures = IsGLExtensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() >= 3;
240*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(hasSRGBTextures);
241*8975f5c5SAndroid Build Coastguard Worker     }
242*8975f5c5SAndroid Build Coastguard Worker }
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker // Test basic functionality of SRGB decode using the texture parameter
TEST_P(SRGBTextureTest,SRGBDecodeTextureParameter)245*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTest, SRGBDecodeTextureParameter)
246*8975f5c5SAndroid Build Coastguard Worker {
247*8975f5c5SAndroid Build Coastguard Worker     // TODO(fjhenigman): Figure out why this fails on Ozone Intel.
248*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone() && IsIntel() && IsOpenGLES());
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     constexpr angle::GLColor srgbColor(64, 127, 191, 255);
253*8975f5c5SAndroid Build Coastguard Worker     constexpr angle::GLColor decodedToLinearColor(13, 54, 133, 255);
254*8975f5c5SAndroid Build Coastguard Worker 
255*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
256*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
257*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
258*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, srgbColor.data());
259*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
260*8975f5c5SAndroid Build Coastguard Worker 
261*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
262*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
263*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
264*8975f5c5SAndroid Build Coastguard Worker 
265*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
266*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
267*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, decodedToLinearColor, 1.0);
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
270*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
271*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0);
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
274*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
275*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, decodedToLinearColor, 1.0);
276*8975f5c5SAndroid Build Coastguard Worker }
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker // Test interaction between SRGB decode and texelFetch
TEST_P(SRGBTextureTestES3,SRGBDecodeTexelFetch)279*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBDecodeTexelFetch)
280*8975f5c5SAndroid Build Coastguard Worker {
281*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker     constexpr angle::GLColor srgbColor(64, 127, 191, 255);
284*8975f5c5SAndroid Build Coastguard Worker     constexpr angle::GLColor decodedToLinearColor(13, 54, 133, 255);
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker     constexpr char kTexelFetchFS[] = R"(#version 300 es
287*8975f5c5SAndroid Build Coastguard Worker precision highp float;
288*8975f5c5SAndroid Build Coastguard Worker precision highp int;
289*8975f5c5SAndroid Build Coastguard Worker 
290*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler2D tex;
291*8975f5c5SAndroid Build Coastguard Worker 
292*8975f5c5SAndroid Build Coastguard Worker in vec4 v_position;
293*8975f5c5SAndroid Build Coastguard Worker out vec4 my_FragColor;
294*8975f5c5SAndroid Build Coastguard Worker 
295*8975f5c5SAndroid Build Coastguard Worker void main() {
296*8975f5c5SAndroid Build Coastguard Worker     ivec2 sampleCoords = ivec2(v_position.xy * 0.5 + 0.5);
297*8975f5c5SAndroid Build Coastguard Worker     my_FragColor = texelFetch(tex, sampleCoords, 0);
298*8975f5c5SAndroid Build Coastguard Worker }
299*8975f5c5SAndroid Build Coastguard Worker )";
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
302*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
303*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
304*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, srgbColor.data());
305*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
306*8975f5c5SAndroid Build Coastguard Worker 
307*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
308*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
311*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
312*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, decodedToLinearColor, 1.0);
313*8975f5c5SAndroid Build Coastguard Worker 
314*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
315*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
316*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0);
317*8975f5c5SAndroid Build Coastguard Worker 
318*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(texelFetchProgram, essl3_shaders::vs::Passthrough(), kTexelFetchFS);
319*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(texelFetchProgram);
320*8975f5c5SAndroid Build Coastguard Worker     GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
321*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GE(texLocation, 0);
322*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(texLocation, 0);
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker     drawQuad(texelFetchProgram, "a_position", 0.5f);
325*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, decodedToLinearColor, 1.0);
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker // Test basic functionality of SRGB override using the texture parameter
TEST_P(SRGBTextureTest,SRGBOverrideTextureParameter)329*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTest, SRGBOverrideTextureParameter)
330*8975f5c5SAndroid Build Coastguard Worker {
331*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));
332*8975f5c5SAndroid Build Coastguard Worker 
333*8975f5c5SAndroid Build Coastguard Worker     GLenum internalFormat = getClientMajorVersion() >= 3 ? GL_RGBA8 : GL_RGBA;
334*8975f5c5SAndroid Build Coastguard Worker 
335*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
336*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
337*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
338*8975f5c5SAndroid Build Coastguard Worker                  kLinearColor.data());
339*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
342*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
343*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
344*8975f5c5SAndroid Build Coastguard Worker 
345*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
346*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
347*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, kLinearColor, 1.0);
348*8975f5c5SAndroid Build Coastguard Worker 
349*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_SRGB);
350*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
351*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, kNonlinearColor, 1.0);
352*8975f5c5SAndroid Build Coastguard Worker 
353*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
354*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
355*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, kLinearColor, 1.0);
356*8975f5c5SAndroid Build Coastguard Worker }
357*8975f5c5SAndroid Build Coastguard Worker 
358*8975f5c5SAndroid Build Coastguard Worker // Test that all supported formats can be overridden
TEST_P(SRGBTextureTestES3,SRGBOverrideFormats)359*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBOverrideFormats)
360*8975f5c5SAndroid Build Coastguard Worker {
361*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));
362*8975f5c5SAndroid Build Coastguard Worker 
363*8975f5c5SAndroid Build Coastguard Worker     constexpr GLenum possibleFormats[] = {GL_RGB8,
364*8975f5c5SAndroid Build Coastguard Worker                                           GL_RGBA8,
365*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGB8_ETC2,
366*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA8_ETC2_EAC,
367*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
368*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_4x4,
369*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_5x4,
370*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_5x5,
371*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_6x5,
372*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_6x6,
373*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_8x5,
374*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_8x6,
375*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_8x8,
376*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_10x5,
377*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_10x6,
378*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_10x8,
379*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_10x10,
380*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_12x10,
381*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_ASTC_12x12,
382*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
383*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
384*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
385*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
386*8975f5c5SAndroid Build Coastguard Worker                                           GL_R8,
387*8975f5c5SAndroid Build Coastguard Worker                                           GL_RG8,
388*8975f5c5SAndroid Build Coastguard Worker                                           GL_COMPRESSED_RGBA_BPTC_UNORM_EXT};
389*8975f5c5SAndroid Build Coastguard Worker 
390*8975f5c5SAndroid Build Coastguard Worker     for (GLenum format : possibleFormats)
391*8975f5c5SAndroid Build Coastguard Worker     {
392*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex;
393*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, tex);
394*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2D(GL_TEXTURE_2D, 1, format, 4, 4);
395*8975f5c5SAndroid Build Coastguard Worker         GLenum error = glGetError();
396*8975f5c5SAndroid Build Coastguard Worker         if (error == GL_INVALID_ENUM)
397*8975f5c5SAndroid Build Coastguard Worker         {
398*8975f5c5SAndroid Build Coastguard Worker             // Format is not supported, we don't require the sRGB counterpart to be supported either
399*8975f5c5SAndroid Build Coastguard Worker             continue;
400*8975f5c5SAndroid Build Coastguard Worker         }
401*8975f5c5SAndroid Build Coastguard Worker         else
402*8975f5c5SAndroid Build Coastguard Worker         {
403*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EQ(static_cast<GLenum>(GL_NO_ERROR), error);
404*8975f5c5SAndroid Build Coastguard Worker         }
405*8975f5c5SAndroid Build Coastguard Worker 
406*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
407*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
410*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(mTextureLocation, 0);
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker         glDisable(GL_DEPTH_TEST);
413*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, "position", 0.5f);
414*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
415*8975f5c5SAndroid Build Coastguard Worker         // Discard result, we are only checking that we don't try to reinterpret to an unsupported
416*8975f5c5SAndroid Build Coastguard Worker         // format
417*8975f5c5SAndroid Build Coastguard Worker     }
418*8975f5c5SAndroid Build Coastguard Worker }
419*8975f5c5SAndroid Build Coastguard Worker 
420*8975f5c5SAndroid Build Coastguard Worker // Test interaction between sRGB_override and sampler objects
TEST_P(SRGBTextureTestES3,SRGBOverrideTextureParameterWithSampler)421*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBOverrideTextureParameterWithSampler)
422*8975f5c5SAndroid Build Coastguard Worker {
423*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));
424*8975f5c5SAndroid Build Coastguard Worker 
425*8975f5c5SAndroid Build Coastguard Worker     GLColor linearColor = kLinearColor;
426*8975f5c5SAndroid Build Coastguard Worker     GLColor srgbColor   = kNonlinearColor;
427*8975f5c5SAndroid Build Coastguard Worker 
428*8975f5c5SAndroid Build Coastguard Worker     GLenum internalFormat = getClientMajorVersion() >= 3 ? GL_RGBA8 : GL_RGBA;
429*8975f5c5SAndroid Build Coastguard Worker 
430*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
431*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
432*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
433*8975f5c5SAndroid Build Coastguard Worker                  &linearColor);
434*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
435*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
436*8975f5c5SAndroid Build Coastguard Worker 
437*8975f5c5SAndroid Build Coastguard Worker     GLSampler sampler;
438*8975f5c5SAndroid Build Coastguard Worker     glBindSampler(0, sampler);
439*8975f5c5SAndroid Build Coastguard Worker 
440*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
441*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
442*8975f5c5SAndroid Build Coastguard Worker 
443*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
444*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
445*8975f5c5SAndroid Build Coastguard Worker 
446*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0);
447*8975f5c5SAndroid Build Coastguard Worker 
448*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_SRGB);
449*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
450*8975f5c5SAndroid Build Coastguard Worker 
451*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0);
452*8975f5c5SAndroid Build Coastguard Worker 
453*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
454*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
455*8975f5c5SAndroid Build Coastguard Worker 
456*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0);
457*8975f5c5SAndroid Build Coastguard Worker }
458*8975f5c5SAndroid Build Coastguard Worker 
459*8975f5c5SAndroid Build Coastguard Worker // Test that SRGB override is a noop when used on a nonlinear texture format
460*8975f5c5SAndroid Build Coastguard Worker // EXT_texture_format_sRGB_override spec says:
461*8975f5c5SAndroid Build Coastguard Worker // "If the internal format is not one of the above formats, then
462*8975f5c5SAndroid Build Coastguard Worker // the value of TEXTURE_FORMAT_SRGB_OVERRIDE_EXT is ignored."
TEST_P(SRGBTextureTestES3,SRGBOverrideTextureParameterNoop)463*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBOverrideTextureParameterNoop)
464*8975f5c5SAndroid Build Coastguard Worker {
465*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));
466*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB"));
467*8975f5c5SAndroid Build Coastguard Worker 
468*8975f5c5SAndroid Build Coastguard Worker     GLColor linearColor = kLinearColor;
469*8975f5c5SAndroid Build Coastguard Worker     GLColor srgbColor   = kNonlinearColor;
470*8975f5c5SAndroid Build Coastguard Worker 
471*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
472*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
473*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
474*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, &linearColor);
475*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
476*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
477*8975f5c5SAndroid Build Coastguard Worker 
478*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
479*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
482*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
483*8975f5c5SAndroid Build Coastguard Worker 
484*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0);
485*8975f5c5SAndroid Build Coastguard Worker 
486*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_SRGB);
487*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
488*8975f5c5SAndroid Build Coastguard Worker 
489*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0);
490*8975f5c5SAndroid Build Coastguard Worker }
491*8975f5c5SAndroid Build Coastguard Worker 
492*8975f5c5SAndroid Build Coastguard Worker // Test basic functionality of SRGB decode using the sampler parameter
TEST_P(SRGBTextureTestES3,SRGBDecodeSamplerParameter)493*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBDecodeSamplerParameter)
494*8975f5c5SAndroid Build Coastguard Worker {
495*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
496*8975f5c5SAndroid Build Coastguard Worker 
497*8975f5c5SAndroid Build Coastguard Worker     GLColor linearColor = kLinearColor;
498*8975f5c5SAndroid Build Coastguard Worker     GLColor srgbColor   = kNonlinearColor;
499*8975f5c5SAndroid Build Coastguard Worker 
500*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
501*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
502*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
503*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, &linearColor);
504*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
505*8975f5c5SAndroid Build Coastguard Worker 
506*8975f5c5SAndroid Build Coastguard Worker     GLSampler sampler;
507*8975f5c5SAndroid Build Coastguard Worker     glBindSampler(0, sampler);
508*8975f5c5SAndroid Build Coastguard Worker     glSamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
509*8975f5c5SAndroid Build Coastguard Worker 
510*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
511*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
512*8975f5c5SAndroid Build Coastguard Worker 
513*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
514*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
515*8975f5c5SAndroid Build Coastguard Worker 
516*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0);
517*8975f5c5SAndroid Build Coastguard Worker 
518*8975f5c5SAndroid Build Coastguard Worker     glSamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
519*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
520*8975f5c5SAndroid Build Coastguard Worker 
521*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0);
522*8975f5c5SAndroid Build Coastguard Worker }
523*8975f5c5SAndroid Build Coastguard Worker 
524*8975f5c5SAndroid Build Coastguard Worker // Toggle between GL_DECODE_EXT and GL_SKIP_DECODE_EXT of sampler parameter
525*8975f5c5SAndroid Build Coastguard Worker // GL_TEXTURE_SRGB_DECODE_EXT
TEST_P(SRGBTextureTestES3,SRGBDecodeSamplerParameterToggle)526*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBDecodeSamplerParameterToggle)
527*8975f5c5SAndroid Build Coastguard Worker {
528*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
529*8975f5c5SAndroid Build Coastguard Worker 
530*8975f5c5SAndroid Build Coastguard Worker     GLColor linearColor = kLinearColor;
531*8975f5c5SAndroid Build Coastguard Worker     GLColor srgbColor   = kNonlinearColor;
532*8975f5c5SAndroid Build Coastguard Worker 
533*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
534*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
535*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
536*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, &linearColor);
537*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
538*8975f5c5SAndroid Build Coastguard Worker 
539*8975f5c5SAndroid Build Coastguard Worker     GLSampler sampler;
540*8975f5c5SAndroid Build Coastguard Worker     glBindSampler(0, sampler);
541*8975f5c5SAndroid Build Coastguard Worker 
542*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
543*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
544*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
545*8975f5c5SAndroid Build Coastguard Worker 
546*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++)
547*8975f5c5SAndroid Build Coastguard Worker     {
548*8975f5c5SAndroid Build Coastguard Worker         // Toggle betwee decode and skip decode and verify pixel value
549*8975f5c5SAndroid Build Coastguard Worker         GLint decode                  = ((i & 1) == 0) ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT;
550*8975f5c5SAndroid Build Coastguard Worker         angle::GLColor &expectedColor = ((i & 1) == 0) ? srgbColor : linearColor;
551*8975f5c5SAndroid Build Coastguard Worker 
552*8975f5c5SAndroid Build Coastguard Worker         glSamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, decode);
553*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, "position", 0.5f);
554*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
555*8975f5c5SAndroid Build Coastguard Worker     }
556*8975f5c5SAndroid Build Coastguard Worker }
557*8975f5c5SAndroid Build Coastguard Worker 
558*8975f5c5SAndroid Build Coastguard Worker // Test that sampler state overrides texture state for srgb decode
TEST_P(SRGBTextureTestES3,SRGBDecodeTextureAndSamplerParameter)559*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBDecodeTextureAndSamplerParameter)
560*8975f5c5SAndroid Build Coastguard Worker {
561*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
562*8975f5c5SAndroid Build Coastguard Worker 
563*8975f5c5SAndroid Build Coastguard Worker     GLColor linearColor = kLinearColor;
564*8975f5c5SAndroid Build Coastguard Worker     GLColor srgbColor   = kNonlinearColor;
565*8975f5c5SAndroid Build Coastguard Worker 
566*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
567*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
568*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
569*8975f5c5SAndroid Build Coastguard Worker                  getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, &linearColor);
570*8975f5c5SAndroid Build Coastguard Worker 
571*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
572*8975f5c5SAndroid Build Coastguard Worker 
573*8975f5c5SAndroid Build Coastguard Worker     GLSampler sampler;
574*8975f5c5SAndroid Build Coastguard Worker     glBindSampler(0, sampler);
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
577*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
578*8975f5c5SAndroid Build Coastguard Worker 
579*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
580*8975f5c5SAndroid Build Coastguard Worker 
581*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
582*8975f5c5SAndroid Build Coastguard Worker     glSamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
583*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
584*8975f5c5SAndroid Build Coastguard Worker 
585*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0);
586*8975f5c5SAndroid Build Coastguard Worker 
587*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
588*8975f5c5SAndroid Build Coastguard Worker     glSamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
589*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
590*8975f5c5SAndroid Build Coastguard Worker 
591*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0);
592*8975f5c5SAndroid Build Coastguard Worker }
593*8975f5c5SAndroid Build Coastguard Worker 
594*8975f5c5SAndroid Build Coastguard Worker // Test that srgb decode state takes priority over srgb override state
TEST_P(SRGBTextureTestES3,SRGBDecodeOverridePriority)595*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, SRGBDecodeOverridePriority)
596*8975f5c5SAndroid Build Coastguard Worker {
597*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
598*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));
599*8975f5c5SAndroid Build Coastguard Worker 
600*8975f5c5SAndroid Build Coastguard Worker     GLColor linearColor = kLinearColor;
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker     GLenum internalFormat = getClientMajorVersion() >= 3 ? GL_RGBA8 : GL_RGBA;
603*8975f5c5SAndroid Build Coastguard Worker 
604*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
605*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
606*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
607*8975f5c5SAndroid Build Coastguard Worker                  &linearColor);
608*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
609*8975f5c5SAndroid Build Coastguard Worker 
610*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
611*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureLocation, 0);
612*8975f5c5SAndroid Build Coastguard Worker 
613*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
614*8975f5c5SAndroid Build Coastguard Worker 
615*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_SRGB);
616*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
617*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
618*8975f5c5SAndroid Build Coastguard Worker 
619*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0);
620*8975f5c5SAndroid Build Coastguard Worker }
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker // Test that mipmaps are generated correctly for sRGB textures
TEST_P(SRGBTextureTestES3,GenerateMipmaps)623*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, GenerateMipmaps)
624*8975f5c5SAndroid Build Coastguard Worker {
625*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOpenGL() && ((IsIntel() && IsMac()) || IsAMD()));
626*8975f5c5SAndroid Build Coastguard Worker 
627*8975f5c5SAndroid Build Coastguard Worker     auto createAndReadBackTexture = [this](GLenum internalFormat, const GLColor &color) {
628*8975f5c5SAndroid Build Coastguard Worker         constexpr GLsizei width  = 128;
629*8975f5c5SAndroid Build Coastguard Worker         constexpr GLsizei height = 128;
630*8975f5c5SAndroid Build Coastguard Worker 
631*8975f5c5SAndroid Build Coastguard Worker         std::array<GLColor, width * height> buf;
632*8975f5c5SAndroid Build Coastguard Worker         std::fill(buf.begin(), buf.end(), color);
633*8975f5c5SAndroid Build Coastguard Worker 
634*8975f5c5SAndroid Build Coastguard Worker         // Set up-left region of the texture as red color.
635*8975f5c5SAndroid Build Coastguard Worker         // In order to make sure bi-linear interpolation operates on different colors, red region
636*8975f5c5SAndroid Build Coastguard Worker         // is 1 pixel smaller than a quarter of the full texture on each side.
637*8975f5c5SAndroid Build Coastguard Worker         constexpr GLsizei redWidth  = width / 2 - 1;
638*8975f5c5SAndroid Build Coastguard Worker         constexpr GLsizei redHeight = height / 2 - 1;
639*8975f5c5SAndroid Build Coastguard Worker         std::array<GLColor, redWidth * redHeight> redBuf;
640*8975f5c5SAndroid Build Coastguard Worker         std::fill(redBuf.begin(), redBuf.end(), GLColor::red);
641*8975f5c5SAndroid Build Coastguard Worker 
642*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex;
643*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, tex);
644*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
645*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
646*8975f5c5SAndroid Build Coastguard Worker                      buf.data());
647*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, redWidth, redHeight, GL_RGBA, GL_UNSIGNED_BYTE,
648*8975f5c5SAndroid Build Coastguard Worker                         redBuf.data());
649*8975f5c5SAndroid Build Coastguard Worker         glGenerateMipmap(GL_TEXTURE_2D);
650*8975f5c5SAndroid Build Coastguard Worker 
651*8975f5c5SAndroid Build Coastguard Worker         constexpr GLsizei drawWidth  = 32;
652*8975f5c5SAndroid Build Coastguard Worker         constexpr GLsizei drawHeight = 32;
653*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, drawWidth, drawHeight);
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, "position", 0.5f);
656*8975f5c5SAndroid Build Coastguard Worker 
657*8975f5c5SAndroid Build Coastguard Worker         std::array<GLColor, drawWidth * drawHeight> result;
658*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, drawWidth, drawHeight, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
659*8975f5c5SAndroid Build Coastguard Worker 
660*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
661*8975f5c5SAndroid Build Coastguard Worker 
662*8975f5c5SAndroid Build Coastguard Worker         return result;
663*8975f5c5SAndroid Build Coastguard Worker     };
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker     GLColor srgbaColor(0, 63, 127, 255);
666*8975f5c5SAndroid Build Coastguard Worker     auto srgbaReadback = createAndReadBackTexture(GL_SRGB8_ALPHA8, srgbaColor);
667*8975f5c5SAndroid Build Coastguard Worker 
668*8975f5c5SAndroid Build Coastguard Worker     GLColor linearColor(0, 13, 54, 255);
669*8975f5c5SAndroid Build Coastguard Worker     auto rgbaReadback = createAndReadBackTexture(GL_RGBA8, linearColor);
670*8975f5c5SAndroid Build Coastguard Worker 
671*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(srgbaReadback.size(), rgbaReadback.size());
672*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < srgbaReadback.size(); i++)
673*8975f5c5SAndroid Build Coastguard Worker     {
674*8975f5c5SAndroid Build Coastguard Worker         constexpr double tolerence = 7.0;
675*8975f5c5SAndroid Build Coastguard Worker         EXPECT_COLOR_NEAR(srgbaReadback[i], rgbaReadback[i], tolerence);
676*8975f5c5SAndroid Build Coastguard Worker     }
677*8975f5c5SAndroid Build Coastguard Worker }
678*8975f5c5SAndroid Build Coastguard Worker 
679*8975f5c5SAndroid Build Coastguard Worker // Test that generated mip levels are correct for solid color textures
TEST_P(SRGBTextureTestES3,GenerateMipmapsSolid)680*8975f5c5SAndroid Build Coastguard Worker TEST_P(SRGBTextureTestES3, GenerateMipmapsSolid)
681*8975f5c5SAndroid Build Coastguard Worker {
682*8975f5c5SAndroid Build Coastguard Worker     GLColor color(7, 7, 7, 7);
683*8975f5c5SAndroid Build Coastguard Worker 
684*8975f5c5SAndroid Build Coastguard Worker     std::array<GLColor, 4 * 4> buf;
685*8975f5c5SAndroid Build Coastguard Worker     std::fill(buf.begin(), buf.end(), color);
686*8975f5c5SAndroid Build Coastguard Worker 
687*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
688*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
689*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
690*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf.data());
691*8975f5c5SAndroid Build Coastguard Worker     glGenerateMipmap(GL_TEXTURE_2D);
692*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
693*8975f5c5SAndroid Build Coastguard Worker 
694*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fb;
695*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
696*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 1);
697*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
698*8975f5c5SAndroid Build Coastguard Worker 
699*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, color, 1);
700*8975f5c5SAndroid Build Coastguard Worker }
701*8975f5c5SAndroid Build Coastguard Worker 
702*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(SRGBTextureTest);
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SRGBTextureTestES3);
705*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(SRGBTextureTestES3);
706*8975f5c5SAndroid Build Coastguard Worker 
707*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
708