xref: /aosp_15_r20/external/angle/src/tests/gl_tests/CubeMapTextureTest.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 using namespace angle;
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker class CubeMapTextureTest : public ANGLETest<>
13*8975f5c5SAndroid Build Coastguard Worker {
14*8975f5c5SAndroid Build Coastguard Worker   protected:
CubeMapTextureTest()15*8975f5c5SAndroid Build Coastguard Worker     CubeMapTextureTest()
16*8975f5c5SAndroid Build Coastguard Worker     {
17*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(256);
18*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(256);
19*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
20*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
21*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
22*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
23*8975f5c5SAndroid Build Coastguard Worker     }
24*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()25*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
26*8975f5c5SAndroid Build Coastguard Worker     {
27*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
28*8975f5c5SAndroid Build Coastguard Worker         if (mProgram == 0)
29*8975f5c5SAndroid Build Coastguard Worker         {
30*8975f5c5SAndroid Build Coastguard Worker             FAIL() << "shader compilation failed.";
31*8975f5c5SAndroid Build Coastguard Worker         }
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker         mColorLocation = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0, 0, 0, 0);
38*8975f5c5SAndroid Build Coastguard Worker         glClearDepthf(0.0);
39*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
40*8975f5c5SAndroid Build Coastguard Worker 
41*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_BLEND);
42*8975f5c5SAndroid Build Coastguard Worker         glDisable(GL_DEPTH_TEST);
43*8975f5c5SAndroid Build Coastguard Worker 
44*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
45*8975f5c5SAndroid Build Coastguard Worker     }
46*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()47*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override { glDeleteProgram(mProgram); }
48*8975f5c5SAndroid Build Coastguard Worker 
49*8975f5c5SAndroid Build Coastguard Worker     void runSampleCoordinateTransformTest(const char *shader, const bool useES3);
50*8975f5c5SAndroid Build Coastguard Worker 
51*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
52*8975f5c5SAndroid Build Coastguard Worker     GLint mColorLocation;
53*8975f5c5SAndroid Build Coastguard Worker };
54*8975f5c5SAndroid Build Coastguard Worker 
55*8975f5c5SAndroid Build Coastguard Worker // Verify that rendering to the faces of a cube map consecutively will correctly render to each
56*8975f5c5SAndroid Build Coastguard Worker // face.
TEST_P(CubeMapTextureTest,RenderToFacesConsecutively)57*8975f5c5SAndroid Build Coastguard Worker TEST_P(CubeMapTextureTest, RenderToFacesConsecutively)
58*8975f5c5SAndroid Build Coastguard Worker {
59*8975f5c5SAndroid Build Coastguard Worker     // TODO: Diagnose and fix. http://anglebug.com/42261648
60*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
61*8975f5c5SAndroid Build Coastguard Worker 
62*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42261821
63*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsFuchsia());
64*8975f5c5SAndroid Build Coastguard Worker 
65*8975f5c5SAndroid Build Coastguard Worker     const GLfloat faceColors[] = {
66*8975f5c5SAndroid Build Coastguard Worker         1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
67*8975f5c5SAndroid Build Coastguard Worker         1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
68*8975f5c5SAndroid Build Coastguard Worker     };
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker     GLuint tex = 0;
71*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &tex);
72*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
73*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < 6; face++)
74*8975f5c5SAndroid Build Coastguard Worker     {
75*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
76*8975f5c5SAndroid Build Coastguard Worker                      GL_UNSIGNED_BYTE, nullptr);
77*8975f5c5SAndroid Build Coastguard Worker     }
78*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
79*8975f5c5SAndroid Build Coastguard Worker 
80*8975f5c5SAndroid Build Coastguard Worker     GLuint fbo = 0;
81*8975f5c5SAndroid Build Coastguard Worker     glGenFramebuffers(1, &fbo);
82*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
83*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < 6; face++)
86*8975f5c5SAndroid Build Coastguard Worker     {
87*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
88*8975f5c5SAndroid Build Coastguard Worker                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
89*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker         const GLfloat *faceColor = faceColors + (face * 4);
94*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(mColorLocation, faceColor[0], faceColor[1], faceColor[2], faceColor[3]);
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
97*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
98*8975f5c5SAndroid Build Coastguard Worker     }
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < 6; face++)
101*8975f5c5SAndroid Build Coastguard Worker     {
102*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
103*8975f5c5SAndroid Build Coastguard Worker                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
104*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker         const GLfloat *faceColor = faceColors + (face * 4);
107*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_EQ(0, 0, faceColor[0] * 255, faceColor[1] * 255, faceColor[2] * 255,
108*8975f5c5SAndroid Build Coastguard Worker                         faceColor[3] * 255);
109*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
110*8975f5c5SAndroid Build Coastguard Worker     }
111*8975f5c5SAndroid Build Coastguard Worker 
112*8975f5c5SAndroid Build Coastguard Worker     glDeleteFramebuffers(1, &fbo);
113*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &tex);
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
116*8975f5c5SAndroid Build Coastguard Worker }
117*8975f5c5SAndroid Build Coastguard Worker 
runSampleCoordinateTransformTest(const char * shader,const bool useES3)118*8975f5c5SAndroid Build Coastguard Worker void CubeMapTextureTest::runSampleCoordinateTransformTest(const char *shader, const bool useES3)
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker     // Fails to compile the shader.  anglebug.com/42262420
121*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kCubeFaceCount            = 6;
124*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kCubeFaceSectionCount     = 4;
125*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kCubeFaceSectionCountSqrt = 2;
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     constexpr GLColor faceColors[kCubeFaceCount][kCubeFaceSectionCount] = {
128*8975f5c5SAndroid Build Coastguard Worker         {GLColor(255, 0, 0, 255), GLColor(191, 0, 0, 255), GLColor(127, 0, 0, 255),
129*8975f5c5SAndroid Build Coastguard Worker          GLColor(63, 0, 0, 255)},
130*8975f5c5SAndroid Build Coastguard Worker         {GLColor(0, 255, 0, 255), GLColor(0, 191, 0, 255), GLColor(0, 127, 0, 255),
131*8975f5c5SAndroid Build Coastguard Worker          GLColor(0, 63, 0, 255)},
132*8975f5c5SAndroid Build Coastguard Worker         {GLColor(0, 0, 255, 255), GLColor(0, 0, 191, 255), GLColor(0, 0, 127, 255),
133*8975f5c5SAndroid Build Coastguard Worker          GLColor(0, 0, 63, 255)},
134*8975f5c5SAndroid Build Coastguard Worker         {GLColor(255, 63, 0, 255), GLColor(191, 127, 0, 255), GLColor(127, 191, 0, 255),
135*8975f5c5SAndroid Build Coastguard Worker          GLColor(63, 255, 0, 255)},
136*8975f5c5SAndroid Build Coastguard Worker         {GLColor(0, 255, 63, 255), GLColor(0, 191, 127, 255), GLColor(0, 127, 191, 255),
137*8975f5c5SAndroid Build Coastguard Worker          GLColor(0, 63, 255, 255)},
138*8975f5c5SAndroid Build Coastguard Worker         {GLColor(63, 0, 255, 255), GLColor(127, 0, 191, 255), GLColor(191, 0, 127, 255),
139*8975f5c5SAndroid Build Coastguard Worker          GLColor(255, 0, 63, 255)},
140*8975f5c5SAndroid Build Coastguard Worker     };
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kTextureSize = 32;
143*8975f5c5SAndroid Build Coastguard Worker 
144*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
145*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
146*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < kCubeFaceCount; face++)
147*8975f5c5SAndroid Build Coastguard Worker     {
148*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLColor> faceData(kTextureSize * kTextureSize);
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker         // Create the face with four sections, each with a solid color from |faceColors|.
151*8975f5c5SAndroid Build Coastguard Worker         for (size_t row = 0; row < kTextureSize / kCubeFaceSectionCountSqrt; ++row)
152*8975f5c5SAndroid Build Coastguard Worker         {
153*8975f5c5SAndroid Build Coastguard Worker             for (size_t col = 0; col < kTextureSize / kCubeFaceSectionCountSqrt; ++col)
154*8975f5c5SAndroid Build Coastguard Worker             {
155*8975f5c5SAndroid Build Coastguard Worker                 for (size_t srow = 0; srow < kCubeFaceSectionCountSqrt; ++srow)
156*8975f5c5SAndroid Build Coastguard Worker                 {
157*8975f5c5SAndroid Build Coastguard Worker                     for (size_t scol = 0; scol < kCubeFaceSectionCountSqrt; ++scol)
158*8975f5c5SAndroid Build Coastguard Worker                     {
159*8975f5c5SAndroid Build Coastguard Worker                         size_t r = row + srow * kTextureSize / kCubeFaceSectionCountSqrt;
160*8975f5c5SAndroid Build Coastguard Worker                         size_t c = col + scol * kTextureSize / kCubeFaceSectionCountSqrt;
161*8975f5c5SAndroid Build Coastguard Worker                         size_t s = srow * kCubeFaceSectionCountSqrt + scol;
162*8975f5c5SAndroid Build Coastguard Worker                         faceData[r * kTextureSize + c] = faceColors[face][s];
163*8975f5c5SAndroid Build Coastguard Worker                     }
164*8975f5c5SAndroid Build Coastguard Worker                 }
165*8975f5c5SAndroid Build Coastguard Worker             }
166*8975f5c5SAndroid Build Coastguard Worker         }
167*8975f5c5SAndroid Build Coastguard Worker 
168*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kTextureSize, kTextureSize,
169*8975f5c5SAndroid Build Coastguard Worker                      0, GL_RGBA, GL_UNSIGNED_BYTE, faceData.data());
170*8975f5c5SAndroid Build Coastguard Worker     }
171*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
172*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
173*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
174*8975f5c5SAndroid Build Coastguard Worker 
175*8975f5c5SAndroid Build Coastguard Worker     GLTexture fboTex;
176*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, fboTex);
177*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeFaceCount, kCubeFaceSectionCount, 0, GL_RGBA,
178*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
181*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
182*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
183*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, useES3 ? essl3_shaders::vs::Simple() : essl1_shaders::vs::Simple(),
186*8975f5c5SAndroid Build Coastguard Worker                      shader);
187*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
188*8975f5c5SAndroid Build Coastguard Worker 
189*8975f5c5SAndroid Build Coastguard Worker     GLint texCubeLocation = glGetUniformLocation(program, "texCube");
190*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, texCubeLocation);
191*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(texCubeLocation, 0);
192*8975f5c5SAndroid Build Coastguard Worker 
193*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, useES3 ? essl3_shaders::PositionAttrib() : essl1_shaders::PositionAttrib(),
194*8975f5c5SAndroid Build Coastguard Worker              0.5f);
195*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
196*8975f5c5SAndroid Build Coastguard Worker 
197*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < kCubeFaceCount; face++)
198*8975f5c5SAndroid Build Coastguard Worker     {
199*8975f5c5SAndroid Build Coastguard Worker         // The following table defines the translation from textureCube coordinates to coordinates
200*8975f5c5SAndroid Build Coastguard Worker         // in each face.  The framebuffer has width 6 and height 4.  Every column corresponding to
201*8975f5c5SAndroid Build Coastguard Worker         // an x value represents one cube face.  The values in rows are samples from the four
202*8975f5c5SAndroid Build Coastguard Worker         // sections of the face.
203*8975f5c5SAndroid Build Coastguard Worker         //
204*8975f5c5SAndroid Build Coastguard Worker         // Major    Axis Direction Target    sc  tc  ma
205*8975f5c5SAndroid Build Coastguard Worker         //  +rx  TEXTURE_CUBE_MAP_POSITIVE_X −rz −ry rx
206*8975f5c5SAndroid Build Coastguard Worker         //  −rx  TEXTURE_CUBE_MAP_NEGATIVE_X  rz −ry rx
207*8975f5c5SAndroid Build Coastguard Worker         //  +ry  TEXTURE_CUBE_MAP_POSITIVE_Y  rx  rz ry
208*8975f5c5SAndroid Build Coastguard Worker         //  −ry  TEXTURE_CUBE_MAP_NEGATIVE_Y  rx −rz ry
209*8975f5c5SAndroid Build Coastguard Worker         //  +rz  TEXTURE_CUBE_MAP_POSITIVE_Z  rx −ry rz
210*8975f5c5SAndroid Build Coastguard Worker         //  −rz  TEXTURE_CUBE_MAP_NEGATIVE_Z −rx −ry rz
211*8975f5c5SAndroid Build Coastguard Worker         //
212*8975f5c5SAndroid Build Coastguard Worker         // This table is used only to determine the direction of growth for s and t.  The shader
213*8975f5c5SAndroid Build Coastguard Worker         // always generates (row,col) coordinates (0, 0), (0, 1), (1, 0), (1, 1) which is the order
214*8975f5c5SAndroid Build Coastguard Worker         // the data is uploaded to the faces, but based on the table above, the sample order would
215*8975f5c5SAndroid Build Coastguard Worker         // be different.
216*8975f5c5SAndroid Build Coastguard Worker         constexpr size_t faceSampledSections[kCubeFaceCount][kCubeFaceSectionCount] = {
217*8975f5c5SAndroid Build Coastguard Worker             {3, 2, 1, 0}, {2, 3, 0, 1}, {0, 1, 2, 3}, {2, 3, 0, 1}, {2, 3, 0, 1}, {3, 2, 1, 0},
218*8975f5c5SAndroid Build Coastguard Worker         };
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker         for (size_t section = 0; section < kCubeFaceSectionCount; ++section)
221*8975f5c5SAndroid Build Coastguard Worker         {
222*8975f5c5SAndroid Build Coastguard Worker             const GLColor sectionColor = faceColors[face][faceSampledSections[face][section]];
223*8975f5c5SAndroid Build Coastguard Worker 
224*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_EQ(face, section, sectionColor)
225*8975f5c5SAndroid Build Coastguard Worker                 << "face " << face << ", section " << section;
226*8975f5c5SAndroid Build Coastguard Worker         }
227*8975f5c5SAndroid Build Coastguard Worker     }
228*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
229*8975f5c5SAndroid Build Coastguard Worker }
230*8975f5c5SAndroid Build Coastguard Worker 
231*8975f5c5SAndroid Build Coastguard Worker // Verify that cube map sampling follows the rules that map cubemap coordinates to coordinates
232*8975f5c5SAndroid Build Coastguard Worker // within each face.  See section 3.7.5 of GLES2.0 (Cube Map Texture Selection).
TEST_P(CubeMapTextureTest,SampleCoordinateTransform)233*8975f5c5SAndroid Build Coastguard Worker TEST_P(CubeMapTextureTest, SampleCoordinateTransform)
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096654
236*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D9());
237*8975f5c5SAndroid Build Coastguard Worker     // Create a program that samples from 6x4 directions of the cubemap, draw and verify that the
238*8975f5c5SAndroid Build Coastguard Worker     // colors match the right color from |faceColors|.
239*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(precision mediump float;
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker uniform samplerCube texCube;
242*8975f5c5SAndroid Build Coastguard Worker 
243*8975f5c5SAndroid Build Coastguard Worker const mat4 coordInSection = mat4(
244*8975f5c5SAndroid Build Coastguard Worker     vec4(-0.5, -0.5, 0, 0),
245*8975f5c5SAndroid Build Coastguard Worker     vec4( 0.5, -0.5, 0, 0),
246*8975f5c5SAndroid Build Coastguard Worker     vec4(-0.5,  0.5, 0, 0),
247*8975f5c5SAndroid Build Coastguard Worker     vec4( 0.5,  0.5, 0, 0)
248*8975f5c5SAndroid Build Coastguard Worker );
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker void main()
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker     vec3 coord;
253*8975f5c5SAndroid Build Coastguard Worker     if (gl_FragCoord.x < 2.0)
254*8975f5c5SAndroid Build Coastguard Worker     {
255*8975f5c5SAndroid Build Coastguard Worker         coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
256*8975f5c5SAndroid Build Coastguard Worker         coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
257*8975f5c5SAndroid Build Coastguard Worker     }
258*8975f5c5SAndroid Build Coastguard Worker     else if (gl_FragCoord.x < 4.0)
259*8975f5c5SAndroid Build Coastguard Worker     {
260*8975f5c5SAndroid Build Coastguard Worker         coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
261*8975f5c5SAndroid Build Coastguard Worker         coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
262*8975f5c5SAndroid Build Coastguard Worker     }
263*8975f5c5SAndroid Build Coastguard Worker     else
264*8975f5c5SAndroid Build Coastguard Worker     {
265*8975f5c5SAndroid Build Coastguard Worker         coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
266*8975f5c5SAndroid Build Coastguard Worker         coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
267*8975f5c5SAndroid Build Coastguard Worker     }
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = textureCube(texCube, coord);
270*8975f5c5SAndroid Build Coastguard Worker })";
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     runSampleCoordinateTransformTest(kFS, false);
273*8975f5c5SAndroid Build Coastguard Worker }
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker // On Android Vulkan, unequal x and y derivatives cause this test to fail.
TEST_P(CubeMapTextureTest,SampleCoordinateTransformGrad)276*8975f5c5SAndroid Build Coastguard Worker TEST_P(CubeMapTextureTest, SampleCoordinateTransformGrad)
277*8975f5c5SAndroid Build Coastguard Worker {
278*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_texture_lod"));
279*8975f5c5SAndroid Build Coastguard Worker 
280*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#extension GL_EXT_shader_texture_lod : require
281*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker uniform samplerCube texCube;
284*8975f5c5SAndroid Build Coastguard Worker 
285*8975f5c5SAndroid Build Coastguard Worker const mat4 coordInSection = mat4(
286*8975f5c5SAndroid Build Coastguard Worker     vec4(-0.5, -0.5, 0, 0),
287*8975f5c5SAndroid Build Coastguard Worker     vec4( 0.5, -0.5, 0, 0),
288*8975f5c5SAndroid Build Coastguard Worker     vec4(-0.5,  0.5, 0, 0),
289*8975f5c5SAndroid Build Coastguard Worker     vec4( 0.5,  0.5, 0, 0)
290*8975f5c5SAndroid Build Coastguard Worker );
291*8975f5c5SAndroid Build Coastguard Worker 
292*8975f5c5SAndroid Build Coastguard Worker void main()
293*8975f5c5SAndroid Build Coastguard Worker {
294*8975f5c5SAndroid Build Coastguard Worker     vec3 coord;
295*8975f5c5SAndroid Build Coastguard Worker     if (gl_FragCoord.x < 2.0)
296*8975f5c5SAndroid Build Coastguard Worker     {
297*8975f5c5SAndroid Build Coastguard Worker         coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
298*8975f5c5SAndroid Build Coastguard Worker         coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
299*8975f5c5SAndroid Build Coastguard Worker     }
300*8975f5c5SAndroid Build Coastguard Worker     else if (gl_FragCoord.x < 4.0)
301*8975f5c5SAndroid Build Coastguard Worker     {
302*8975f5c5SAndroid Build Coastguard Worker         coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
303*8975f5c5SAndroid Build Coastguard Worker         coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
304*8975f5c5SAndroid Build Coastguard Worker     }
305*8975f5c5SAndroid Build Coastguard Worker     else
306*8975f5c5SAndroid Build Coastguard Worker     {
307*8975f5c5SAndroid Build Coastguard Worker         coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
308*8975f5c5SAndroid Build Coastguard Worker         coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
309*8975f5c5SAndroid Build Coastguard Worker     }
310*8975f5c5SAndroid Build Coastguard Worker 
311*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = textureCubeGradEXT(texCube, coord,
312*8975f5c5SAndroid Build Coastguard Worker                                       vec3(10.0, 10.0, 0.0), vec3(0.0, 10.0, 10.0));
313*8975f5c5SAndroid Build Coastguard Worker })";
314*8975f5c5SAndroid Build Coastguard Worker 
315*8975f5c5SAndroid Build Coastguard Worker     runSampleCoordinateTransformTest(kFS, false);
316*8975f5c5SAndroid Build Coastguard Worker }
317*8975f5c5SAndroid Build Coastguard Worker 
318*8975f5c5SAndroid Build Coastguard Worker // Same as the previous but uses the ES 3.0 explicit gradient function.
TEST_P(CubeMapTextureTest,SampleCoordinateTransformGrad_ES3)319*8975f5c5SAndroid Build Coastguard Worker TEST_P(CubeMapTextureTest, SampleCoordinateTransformGrad_ES3)
320*8975f5c5SAndroid Build Coastguard Worker {
321*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
322*8975f5c5SAndroid Build Coastguard Worker 
323*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
324*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker uniform samplerCube texCube;
327*8975f5c5SAndroid Build Coastguard Worker out vec4 my_FragColor;
328*8975f5c5SAndroid Build Coastguard Worker 
329*8975f5c5SAndroid Build Coastguard Worker const mat4 coordInSection = mat4(
330*8975f5c5SAndroid Build Coastguard Worker     vec4(-0.5, -0.5, 0, 0),
331*8975f5c5SAndroid Build Coastguard Worker     vec4( 0.5, -0.5, 0, 0),
332*8975f5c5SAndroid Build Coastguard Worker     vec4(-0.5,  0.5, 0, 0),
333*8975f5c5SAndroid Build Coastguard Worker     vec4( 0.5,  0.5, 0, 0)
334*8975f5c5SAndroid Build Coastguard Worker );
335*8975f5c5SAndroid Build Coastguard Worker 
336*8975f5c5SAndroid Build Coastguard Worker void main()
337*8975f5c5SAndroid Build Coastguard Worker {
338*8975f5c5SAndroid Build Coastguard Worker     vec3 coord;
339*8975f5c5SAndroid Build Coastguard Worker     if (gl_FragCoord.x < 2.0)
340*8975f5c5SAndroid Build Coastguard Worker     {
341*8975f5c5SAndroid Build Coastguard Worker         coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
342*8975f5c5SAndroid Build Coastguard Worker         coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
343*8975f5c5SAndroid Build Coastguard Worker     }
344*8975f5c5SAndroid Build Coastguard Worker     else if (gl_FragCoord.x < 4.0)
345*8975f5c5SAndroid Build Coastguard Worker     {
346*8975f5c5SAndroid Build Coastguard Worker         coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
347*8975f5c5SAndroid Build Coastguard Worker         coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
348*8975f5c5SAndroid Build Coastguard Worker     }
349*8975f5c5SAndroid Build Coastguard Worker     else
350*8975f5c5SAndroid Build Coastguard Worker     {
351*8975f5c5SAndroid Build Coastguard Worker         coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
352*8975f5c5SAndroid Build Coastguard Worker         coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
353*8975f5c5SAndroid Build Coastguard Worker     }
354*8975f5c5SAndroid Build Coastguard Worker 
355*8975f5c5SAndroid Build Coastguard Worker     my_FragColor = textureGrad(texCube, coord,
356*8975f5c5SAndroid Build Coastguard Worker                                vec3(10.0, 10.0, 0.0), vec3(0.0, 10.0, 10.0));
357*8975f5c5SAndroid Build Coastguard Worker })";
358*8975f5c5SAndroid Build Coastguard Worker 
359*8975f5c5SAndroid Build Coastguard Worker     runSampleCoordinateTransformTest(kFS, true);
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker // Use this to select which configurations (e.g. which renderer, which GLES major version) these
363*8975f5c5SAndroid Build Coastguard Worker // tests should be run against.
364*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(CubeMapTextureTest);
365