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