xref: /aosp_15_r20/external/angle/src/tests/gl_tests/ComputeShaderTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 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 // ComputeShaderTest:
7*8975f5c5SAndroid Build Coastguard Worker //   Compute shader specific tests.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include <vector>
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker namespace
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker class ComputeShaderTest : public ANGLETest<>
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker   protected:
ComputeShaderTest()21*8975f5c5SAndroid Build Coastguard Worker     ComputeShaderTest() {}
22*8975f5c5SAndroid Build Coastguard Worker 
createMockOutputImage(GLuint texture,GLenum internalFormat,GLint width,GLint height)23*8975f5c5SAndroid Build Coastguard Worker     void createMockOutputImage(GLuint texture, GLenum internalFormat, GLint width, GLint height)
24*8975f5c5SAndroid Build Coastguard Worker     {
25*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
26*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, width, height);
27*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
28*8975f5c5SAndroid Build Coastguard Worker 
29*8975f5c5SAndroid Build Coastguard Worker         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, internalFormat);
30*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
31*8975f5c5SAndroid Build Coastguard Worker     }
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker     template <class T, GLint kWidth, GLint kHeight>
runSharedMemoryTest(const char * kCS,GLenum internalFormat,GLenum format,const std::array<T,kWidth * kHeight> & inputData,const std::array<T,kWidth * kHeight> & expectedValues)34*8975f5c5SAndroid Build Coastguard Worker     void runSharedMemoryTest(const char *kCS,
35*8975f5c5SAndroid Build Coastguard Worker                              GLenum internalFormat,
36*8975f5c5SAndroid Build Coastguard Worker                              GLenum format,
37*8975f5c5SAndroid Build Coastguard Worker                              const std::array<T, kWidth * kHeight> &inputData,
38*8975f5c5SAndroid Build Coastguard Worker                              const std::array<T, kWidth * kHeight> &expectedValues)
39*8975f5c5SAndroid Build Coastguard Worker     {
40*8975f5c5SAndroid Build Coastguard Worker         GLTexture texture[2];
41*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer framebuffer;
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture[0]);
44*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, kWidth, kHeight);
45*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, format,
46*8975f5c5SAndroid Build Coastguard Worker                         inputData.data());
47*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
48*8975f5c5SAndroid Build Coastguard Worker 
49*8975f5c5SAndroid Build Coastguard Worker         constexpr T initData[kWidth * kHeight] = {};
50*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture[1]);
51*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, kWidth, kHeight);
52*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, format, initData);
53*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
54*8975f5c5SAndroid Build Coastguard Worker 
55*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
56*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker         glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, internalFormat);
59*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker         glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalFormat);
62*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker         glDispatchCompute(1, 1, 1);
65*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
66*8975f5c5SAndroid Build Coastguard Worker 
67*8975f5c5SAndroid Build Coastguard Worker         glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
68*8975f5c5SAndroid Build Coastguard Worker 
69*8975f5c5SAndroid Build Coastguard Worker         T outputValues[kWidth * kHeight] = {};
70*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(0);
71*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
72*8975f5c5SAndroid Build Coastguard Worker 
73*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1],
74*8975f5c5SAndroid Build Coastguard Worker                                0);
75*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
76*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, format, outputValues);
77*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kWidth * kHeight; i++)
80*8975f5c5SAndroid Build Coastguard Worker         {
81*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(expectedValues[i], outputValues[i]);
82*8975f5c5SAndroid Build Coastguard Worker         }
83*8975f5c5SAndroid Build Coastguard Worker     }
84*8975f5c5SAndroid Build Coastguard Worker };
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker class ComputeShaderTestES3 : public ANGLETest<>
87*8975f5c5SAndroid Build Coastguard Worker {
88*8975f5c5SAndroid Build Coastguard Worker   protected:
ComputeShaderTestES3()89*8975f5c5SAndroid Build Coastguard Worker     ComputeShaderTestES3() {}
90*8975f5c5SAndroid Build Coastguard Worker };
91*8975f5c5SAndroid Build Coastguard Worker 
92*8975f5c5SAndroid Build Coastguard Worker class WebGL2ComputeTest : public ComputeShaderTest
93*8975f5c5SAndroid Build Coastguard Worker {
94*8975f5c5SAndroid Build Coastguard Worker   protected:
WebGL2ComputeTest()95*8975f5c5SAndroid Build Coastguard Worker     WebGL2ComputeTest() { setWebGLCompatibilityEnabled(true); }
96*8975f5c5SAndroid Build Coastguard Worker };
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker // link a simple compute program. It should be successful.
TEST_P(ComputeShaderTest,LinkComputeProgram)99*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, LinkComputeProgram)
100*8975f5c5SAndroid Build Coastguard Worker {
101*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
102*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
103*8975f5c5SAndroid Build Coastguard Worker void main()
104*8975f5c5SAndroid Build Coastguard Worker {
105*8975f5c5SAndroid Build Coastguard Worker })";
106*8975f5c5SAndroid Build Coastguard Worker 
107*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
110*8975f5c5SAndroid Build Coastguard Worker }
111*8975f5c5SAndroid Build Coastguard Worker 
112*8975f5c5SAndroid Build Coastguard Worker // Link a simple compute program. Then detach the shader and dispatch compute.
113*8975f5c5SAndroid Build Coastguard Worker // It should be successful.
TEST_P(ComputeShaderTest,DetachShaderAfterLinkSuccess)114*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DetachShaderAfterLinkSuccess)
115*8975f5c5SAndroid Build Coastguard Worker {
116*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
117*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
118*8975f5c5SAndroid Build Coastguard Worker void main()
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker })";
121*8975f5c5SAndroid Build Coastguard Worker 
122*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker     GLuint cs = CompileShader(GL_COMPUTE_SHADER, kCS);
125*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, cs);
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, cs);
128*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(cs);
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
131*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
132*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
133*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(linkStatus);
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     glDetachShader(program, cs);
136*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
139*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(8, 4, 2);
140*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
141*8975f5c5SAndroid Build Coastguard Worker }
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker // link a simple compute program. There is no local size and linking should fail.
TEST_P(ComputeShaderTest,LinkComputeProgramNoLocalSizeLinkError)144*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, LinkComputeProgramNoLocalSizeLinkError)
145*8975f5c5SAndroid Build Coastguard Worker {
146*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
147*8975f5c5SAndroid Build Coastguard Worker void main()
148*8975f5c5SAndroid Build Coastguard Worker {
149*8975f5c5SAndroid Build Coastguard Worker })";
150*8975f5c5SAndroid Build Coastguard Worker 
151*8975f5c5SAndroid Build Coastguard Worker     GLuint program = CompileComputeProgram(kCS, false);
152*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0u, program);
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker 
159*8975f5c5SAndroid Build Coastguard Worker // link a simple compute program.
160*8975f5c5SAndroid Build Coastguard Worker // make sure that uniforms and uniform samplers get recorded
TEST_P(ComputeShaderTest,LinkComputeProgramWithUniforms)161*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, LinkComputeProgramWithUniforms)
162*8975f5c5SAndroid Build Coastguard Worker {
163*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
164*8975f5c5SAndroid Build Coastguard Worker precision mediump sampler2D;
165*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
166*8975f5c5SAndroid Build Coastguard Worker uniform int myUniformInt;
167*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D myUniformSampler;
168*8975f5c5SAndroid Build Coastguard Worker layout(rgba32i) uniform highp writeonly iimage2D imageOut;
169*8975f5c5SAndroid Build Coastguard Worker void main()
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker     int q = myUniformInt;
172*8975f5c5SAndroid Build Coastguard Worker     vec4 v = textureLod(myUniformSampler, vec2(0.0), 0.0);
173*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(0), ivec4(v) * q);
174*8975f5c5SAndroid Build Coastguard Worker })";
175*8975f5c5SAndroid Build Coastguard Worker 
176*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker     GLint uniformLoc = glGetUniformLocation(program, "myUniformInt");
179*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(-1, uniformLoc);
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker     uniformLoc = glGetUniformLocation(program, "myUniformSampler");
182*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(-1, uniformLoc);
183*8975f5c5SAndroid Build Coastguard Worker 
184*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
185*8975f5c5SAndroid Build Coastguard Worker }
186*8975f5c5SAndroid Build Coastguard Worker 
187*8975f5c5SAndroid Build Coastguard Worker // Attach both compute and non-compute shaders. A link time error should occur.
188*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.10, 7.3 Program Objects
TEST_P(ComputeShaderTest,AttachMultipleShaders)189*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AttachMultipleShaders)
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
192*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
193*8975f5c5SAndroid Build Coastguard Worker void main()
194*8975f5c5SAndroid Build Coastguard Worker {
195*8975f5c5SAndroid Build Coastguard Worker })";
196*8975f5c5SAndroid Build Coastguard Worker 
197*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 310 es
198*8975f5c5SAndroid Build Coastguard Worker void main()
199*8975f5c5SAndroid Build Coastguard Worker {
200*8975f5c5SAndroid Build Coastguard Worker })";
201*8975f5c5SAndroid Build Coastguard Worker 
202*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 310 es
203*8975f5c5SAndroid Build Coastguard Worker void main()
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker })";
206*8975f5c5SAndroid Build Coastguard Worker 
207*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS);
210*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
211*8975f5c5SAndroid Build Coastguard Worker     GLuint cs = CompileShader(GL_COMPUTE_SHADER, kCS);
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, vs);
214*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, fs);
215*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, cs);
216*8975f5c5SAndroid Build Coastguard Worker 
217*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
218*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
221*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, cs);
224*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(cs);
225*8975f5c5SAndroid Build Coastguard Worker 
226*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
227*8975f5c5SAndroid Build Coastguard Worker 
228*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
229*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
230*8975f5c5SAndroid Build Coastguard Worker 
231*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(linkStatus);
232*8975f5c5SAndroid Build Coastguard Worker 
233*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker 
236*8975f5c5SAndroid Build Coastguard Worker // Attach a vertex, fragment and compute shader.
237*8975f5c5SAndroid Build Coastguard Worker // Query for the number of attached shaders and check the count.
TEST_P(ComputeShaderTest,AttachmentCount)238*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AttachmentCount)
239*8975f5c5SAndroid Build Coastguard Worker {
240*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
241*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
242*8975f5c5SAndroid Build Coastguard Worker void main()
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker })";
245*8975f5c5SAndroid Build Coastguard Worker 
246*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 310 es
247*8975f5c5SAndroid Build Coastguard Worker void main()
248*8975f5c5SAndroid Build Coastguard Worker {
249*8975f5c5SAndroid Build Coastguard Worker })";
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 310 es
252*8975f5c5SAndroid Build Coastguard Worker void main()
253*8975f5c5SAndroid Build Coastguard Worker {
254*8975f5c5SAndroid Build Coastguard Worker })";
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
257*8975f5c5SAndroid Build Coastguard Worker 
258*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS);
259*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
260*8975f5c5SAndroid Build Coastguard Worker     GLuint cs = CompileShader(GL_COMPUTE_SHADER, kCS);
261*8975f5c5SAndroid Build Coastguard Worker 
262*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, vs);
263*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, fs);
264*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, cs);
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
267*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
270*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, cs);
273*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(cs);
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     GLint numAttachedShaders;
276*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_ATTACHED_SHADERS, &numAttachedShaders);
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(3, numAttachedShaders);
279*8975f5c5SAndroid Build Coastguard Worker 
280*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
281*8975f5c5SAndroid Build Coastguard Worker 
282*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
283*8975f5c5SAndroid Build Coastguard Worker }
284*8975f5c5SAndroid Build Coastguard Worker 
285*8975f5c5SAndroid Build Coastguard Worker // Attach a compute shader and link, but start rendering.
TEST_P(ComputeShaderTest,StartRenderingWithComputeProgram)286*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, StartRenderingWithComputeProgram)
287*8975f5c5SAndroid Build Coastguard Worker {
288*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
289*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
290*8975f5c5SAndroid Build Coastguard Worker void main()
291*8975f5c5SAndroid Build Coastguard Worker {
292*8975f5c5SAndroid Build Coastguard Worker })";
293*8975f5c5SAndroid Build Coastguard Worker 
294*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
295*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
296*8975f5c5SAndroid Build Coastguard Worker 
297*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
298*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_POINTS, 0, 2);
299*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker 
302*8975f5c5SAndroid Build Coastguard Worker // Attach a vertex and fragment shader and link, but dispatch compute.
TEST_P(ComputeShaderTest,DispatchComputeWithRenderingProgram)303*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchComputeWithRenderingProgram)
304*8975f5c5SAndroid Build Coastguard Worker {
305*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 310 es
306*8975f5c5SAndroid Build Coastguard Worker void main() {})";
307*8975f5c5SAndroid Build Coastguard Worker 
308*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 310 es
309*8975f5c5SAndroid Build Coastguard Worker void main() {})";
310*8975f5c5SAndroid Build Coastguard Worker 
311*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS);
314*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
315*8975f5c5SAndroid Build Coastguard Worker 
316*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, vs);
317*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, fs);
318*8975f5c5SAndroid Build Coastguard Worker 
319*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
320*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
323*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
324*8975f5c5SAndroid Build Coastguard Worker 
325*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
326*8975f5c5SAndroid Build Coastguard Worker 
327*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
328*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
329*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(linkStatus);
330*8975f5c5SAndroid Build Coastguard Worker 
331*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
332*8975f5c5SAndroid Build Coastguard Worker 
333*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
334*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(8, 4, 2);
335*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
336*8975f5c5SAndroid Build Coastguard Worker }
337*8975f5c5SAndroid Build Coastguard Worker 
338*8975f5c5SAndroid Build Coastguard Worker // Access all compute shader special variables.
TEST_P(ComputeShaderTest,AccessAllSpecialVariables)339*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AccessAllSpecialVariables)
340*8975f5c5SAndroid Build Coastguard Worker {
341*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
342*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
343*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
344*8975f5c5SAndroid Build Coastguard Worker void main()
345*8975f5c5SAndroid Build Coastguard Worker {
346*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp1 = gl_NumWorkGroups;
347*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp2 = gl_WorkGroupSize;
348*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp3 = gl_WorkGroupID;
349*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp4 = gl_LocalInvocationID;
350*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp5 = gl_GlobalInvocationID;
351*8975f5c5SAndroid Build Coastguard Worker     uint  temp6 = gl_LocalInvocationIndex;
352*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), uvec4(temp1 + temp2 + temp3 + temp4 + temp5, temp6));
353*8975f5c5SAndroid Build Coastguard Worker })";
354*8975f5c5SAndroid Build Coastguard Worker 
355*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
356*8975f5c5SAndroid Build Coastguard Worker }
357*8975f5c5SAndroid Build Coastguard Worker 
358*8975f5c5SAndroid Build Coastguard Worker // Access part compute shader special variables.
TEST_P(ComputeShaderTest,AccessPartSpecialVariables)359*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AccessPartSpecialVariables)
360*8975f5c5SAndroid Build Coastguard Worker {
361*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
362*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
363*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
364*8975f5c5SAndroid Build Coastguard Worker void main()
365*8975f5c5SAndroid Build Coastguard Worker {
366*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp1 = gl_WorkGroupSize;
367*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp2 = gl_WorkGroupID;
368*8975f5c5SAndroid Build Coastguard Worker     uint  temp3 = gl_LocalInvocationIndex;
369*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), uvec4(temp1 + temp2, temp3));
370*8975f5c5SAndroid Build Coastguard Worker })";
371*8975f5c5SAndroid Build Coastguard Worker 
372*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
373*8975f5c5SAndroid Build Coastguard Worker }
374*8975f5c5SAndroid Build Coastguard Worker 
375*8975f5c5SAndroid Build Coastguard Worker // Use glDispatchCompute to define work group count.
TEST_P(ComputeShaderTest,DispatchCompute)376*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchCompute)
377*8975f5c5SAndroid Build Coastguard Worker {
378*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
379*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
380*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
381*8975f5c5SAndroid Build Coastguard Worker void main()
382*8975f5c5SAndroid Build Coastguard Worker {
383*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp = gl_NumWorkGroups;
384*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_GlobalInvocationID.xy), uvec4(temp, 0u));
385*8975f5c5SAndroid Build Coastguard Worker })";
386*8975f5c5SAndroid Build Coastguard Worker 
387*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
388*8975f5c5SAndroid Build Coastguard Worker 
389*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
390*8975f5c5SAndroid Build Coastguard Worker     createMockOutputImage(texture, GL_RGBA32UI, 4, 3);
391*8975f5c5SAndroid Build Coastguard Worker 
392*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
393*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(8, 4, 2);
394*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
395*8975f5c5SAndroid Build Coastguard Worker }
396*8975f5c5SAndroid Build Coastguard Worker 
397*8975f5c5SAndroid Build Coastguard Worker // Binds a storage buffer to slot 0, then binds a storage image to slot 0, then buffer again.
TEST_P(ComputeShaderTest,BufferImageBuffer)398*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BufferImageBuffer)
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS0[] = R"(#version 310 es
401*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
402*8975f5c5SAndroid Build Coastguard Worker layout(binding = 0, offset = 4) uniform atomic_uint ac[2];
403*8975f5c5SAndroid Build Coastguard Worker void main()
404*8975f5c5SAndroid Build Coastguard Worker {
405*8975f5c5SAndroid Build Coastguard Worker     atomicCounterIncrement(ac[0]);
406*8975f5c5SAndroid Build Coastguard Worker     atomicCounterDecrement(ac[1]);
407*8975f5c5SAndroid Build Coastguard Worker })";
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program0, kCS0);
410*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program0);
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker     unsigned int bufferData[3] = {11u, 4u, 4u};
413*8975f5c5SAndroid Build Coastguard Worker     GLBuffer atomicCounterBuffer;
414*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
415*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
416*8975f5c5SAndroid Build Coastguard Worker 
417*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
418*8975f5c5SAndroid Build Coastguard Worker 
419*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
420*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
421*8975f5c5SAndroid Build Coastguard Worker 
422*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
423*8975f5c5SAndroid Build Coastguard Worker     void *mappedBuffer =
424*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_READ_BIT);
425*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferData, mappedBuffer, sizeof(bufferData));
426*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
427*8975f5c5SAndroid Build Coastguard Worker 
428*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(11u, bufferData[0]);
429*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(5u, bufferData[1]);
430*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(3u, bufferData[2]);
431*8975f5c5SAndroid Build Coastguard Worker 
432*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS1[] = R"(#version 310 es
433*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
434*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
435*8975f5c5SAndroid Build Coastguard Worker void main()
436*8975f5c5SAndroid Build Coastguard Worker {
437*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp = gl_NumWorkGroups;
438*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_GlobalInvocationID.xy), uvec4(temp, 0u));
439*8975f5c5SAndroid Build Coastguard Worker })";
440*8975f5c5SAndroid Build Coastguard Worker 
441*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program1, kCS1);
442*8975f5c5SAndroid Build Coastguard Worker 
443*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
444*8975f5c5SAndroid Build Coastguard Worker     createMockOutputImage(texture, GL_RGBA32UI, 4, 3);
445*8975f5c5SAndroid Build Coastguard Worker 
446*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program1);
447*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(8, 4, 2);
448*8975f5c5SAndroid Build Coastguard Worker 
449*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
450*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program0);
451*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
452*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
453*8975f5c5SAndroid Build Coastguard Worker     mappedBuffer =
454*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_READ_BIT);
455*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferData, mappedBuffer, sizeof(bufferData));
456*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
457*8975f5c5SAndroid Build Coastguard Worker 
458*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(11u, bufferData[0]);
459*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(6u, bufferData[1]);
460*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(2u, bufferData[2]);
461*8975f5c5SAndroid Build Coastguard Worker 
462*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
463*8975f5c5SAndroid Build Coastguard Worker }
464*8975f5c5SAndroid Build Coastguard Worker 
465*8975f5c5SAndroid Build Coastguard Worker // Test that the buffer written to by imageStore() in the CS does not race with writing to the
466*8975f5c5SAndroid Build Coastguard Worker // buffer when it's mapped.
TEST_P(ComputeShaderTest,BufferImageBufferMapWrite)467*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BufferImageBufferMapWrite)
468*8975f5c5SAndroid Build Coastguard Worker {
469*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS0[] = R"(#version 310 es
470*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
471*8975f5c5SAndroid Build Coastguard Worker layout(binding = 0, offset = 4) uniform atomic_uint ac[2];
472*8975f5c5SAndroid Build Coastguard Worker void main()
473*8975f5c5SAndroid Build Coastguard Worker {
474*8975f5c5SAndroid Build Coastguard Worker     atomicCounterIncrement(ac[0]);
475*8975f5c5SAndroid Build Coastguard Worker     atomicCounterDecrement(ac[1]);
476*8975f5c5SAndroid Build Coastguard Worker })";
477*8975f5c5SAndroid Build Coastguard Worker 
478*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program0, kCS0);
479*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program0);
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker     unsigned int expectedBufferData[3] = {11u, 4u, 4u};
482*8975f5c5SAndroid Build Coastguard Worker     unsigned int bufferData[3]         = {0};
483*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferData, expectedBufferData, sizeof(bufferData));
484*8975f5c5SAndroid Build Coastguard Worker 
485*8975f5c5SAndroid Build Coastguard Worker     GLBuffer atomicCounterBuffer;
486*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
487*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
488*8975f5c5SAndroid Build Coastguard Worker 
489*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
490*8975f5c5SAndroid Build Coastguard Worker 
491*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
492*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
493*8975f5c5SAndroid Build Coastguard Worker 
494*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
495*8975f5c5SAndroid Build Coastguard Worker     void *mappedBuffer =
496*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_READ_BIT);
497*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferData, mappedBuffer, sizeof(bufferData));
498*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
499*8975f5c5SAndroid Build Coastguard Worker 
500*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(11u, bufferData[0]);
501*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(5u, bufferData[1]);
502*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(3u, bufferData[2]);
503*8975f5c5SAndroid Build Coastguard Worker 
504*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS1[] = R"(#version 310 es
505*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=4, local_size_y=3, local_size_z=2) in;
506*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui) uniform highp writeonly uimage2D imageOut;
507*8975f5c5SAndroid Build Coastguard Worker void main()
508*8975f5c5SAndroid Build Coastguard Worker {
509*8975f5c5SAndroid Build Coastguard Worker     uvec3 temp = gl_NumWorkGroups;
510*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_GlobalInvocationID.xy), uvec4(temp, 0u));
511*8975f5c5SAndroid Build Coastguard Worker })";
512*8975f5c5SAndroid Build Coastguard Worker 
513*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program1, kCS1);
514*8975f5c5SAndroid Build Coastguard Worker 
515*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
516*8975f5c5SAndroid Build Coastguard Worker     createMockOutputImage(texture, GL_RGBA32UI, 4, 3);
517*8975f5c5SAndroid Build Coastguard Worker 
518*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program1);
519*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(8, 4, 2);
520*8975f5c5SAndroid Build Coastguard Worker 
521*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
522*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program0);
523*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
524*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
525*8975f5c5SAndroid Build Coastguard Worker     mappedBuffer =
526*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_WRITE_BIT);
527*8975f5c5SAndroid Build Coastguard Worker 
528*8975f5c5SAndroid Build Coastguard Worker     memcpy(mappedBuffer, expectedBufferData, sizeof(expectedBufferData));
529*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
530*8975f5c5SAndroid Build Coastguard Worker 
531*8975f5c5SAndroid Build Coastguard Worker     // Force the CS imageStore() writes to the buffer to complete.
532*8975f5c5SAndroid Build Coastguard Worker     glFinish();
533*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
534*8975f5c5SAndroid Build Coastguard Worker 
535*8975f5c5SAndroid Build Coastguard Worker     mappedBuffer =
536*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_READ_BIT);
537*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferData, mappedBuffer, sizeof(bufferData));
538*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
539*8975f5c5SAndroid Build Coastguard Worker 
540*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(expectedBufferData[0], bufferData[0]);
541*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(expectedBufferData[1], bufferData[1]);
542*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(expectedBufferData[2], bufferData[2]);
543*8975f5c5SAndroid Build Coastguard Worker 
544*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
545*8975f5c5SAndroid Build Coastguard Worker }
546*8975f5c5SAndroid Build Coastguard Worker 
547*8975f5c5SAndroid Build Coastguard Worker // Test that binds UAV with type image to slot 0, then binds UAV with type buffer to slot 0.
TEST_P(ComputeShaderTest,ImageAtomicCounterBuffer)548*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageAtomicCounterBuffer)
549*8975f5c5SAndroid Build Coastguard Worker {
550*8975f5c5SAndroid Build Coastguard Worker     // Flaky hang. http://anglebug.com/40644695
551*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsDesktopOpenGL());
552*8975f5c5SAndroid Build Coastguard Worker 
553*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS0[] = R"(#version 310 es
554*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
555*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) writeonly uniform highp uimage2D uImage[2];
556*8975f5c5SAndroid Build Coastguard Worker void main()
557*8975f5c5SAndroid Build Coastguard Worker {
558*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
559*8975f5c5SAndroid Build Coastguard Worker 0, 0));
560*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
561*8975f5c5SAndroid Build Coastguard Worker 0, 0));
562*8975f5c5SAndroid Build Coastguard Worker })";
563*8975f5c5SAndroid Build Coastguard Worker 
564*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program0, kCS0);
565*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program0);
566*8975f5c5SAndroid Build Coastguard Worker     int width = 1, height = 1;
567*8975f5c5SAndroid Build Coastguard Worker     GLuint inputValues[] = {200};
568*8975f5c5SAndroid Build Coastguard Worker     GLTexture mTexture[2];
569*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture[0]);
570*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height);
571*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT,
572*8975f5c5SAndroid Build Coastguard Worker                     inputValues);
573*8975f5c5SAndroid Build Coastguard Worker 
574*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture[1]);
575*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height);
576*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT,
577*8975f5c5SAndroid Build Coastguard Worker                     inputValues);
578*8975f5c5SAndroid Build Coastguard Worker 
579*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, mTexture[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
580*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, mTexture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
581*8975f5c5SAndroid Build Coastguard Worker 
582*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
583*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
584*8975f5c5SAndroid Build Coastguard Worker 
585*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS1[] = R"(#version 310 es
586*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
587*8975f5c5SAndroid Build Coastguard Worker layout(binding = 0, offset = 4) uniform atomic_uint ac[2];
588*8975f5c5SAndroid Build Coastguard Worker void main()
589*8975f5c5SAndroid Build Coastguard Worker {
590*8975f5c5SAndroid Build Coastguard Worker     atomicCounterIncrement(ac[0]);
591*8975f5c5SAndroid Build Coastguard Worker     atomicCounterDecrement(ac[1]);
592*8975f5c5SAndroid Build Coastguard Worker })";
593*8975f5c5SAndroid Build Coastguard Worker 
594*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program1, kCS1);
595*8975f5c5SAndroid Build Coastguard Worker 
596*8975f5c5SAndroid Build Coastguard Worker     unsigned int bufferData[3] = {11u, 4u, 4u};
597*8975f5c5SAndroid Build Coastguard Worker     GLBuffer atomicCounterBuffer;
598*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
599*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
600*8975f5c5SAndroid Build Coastguard Worker 
601*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
602*8975f5c5SAndroid Build Coastguard Worker 
603*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program1);
604*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
605*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
606*8975f5c5SAndroid Build Coastguard Worker 
607*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
608*8975f5c5SAndroid Build Coastguard Worker     void *mappedBuffer =
609*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_READ_BIT);
610*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferData, mappedBuffer, sizeof(bufferData));
611*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
612*8975f5c5SAndroid Build Coastguard Worker 
613*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(11u, bufferData[0]);
614*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(5u, bufferData[1]);
615*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(3u, bufferData[2]);
616*8975f5c5SAndroid Build Coastguard Worker 
617*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
618*8975f5c5SAndroid Build Coastguard Worker }
619*8975f5c5SAndroid Build Coastguard Worker 
620*8975f5c5SAndroid Build Coastguard Worker // Test that binds UAV with type image to slot 0, then binds UAV with type buffer to slot 0.
TEST_P(ComputeShaderTest,ImageShaderStorageBuffer)621*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageShaderStorageBuffer)
622*8975f5c5SAndroid Build Coastguard Worker {
623*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS0[] = R"(#version 310 es
624*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
625*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) writeonly uniform highp uimage2D uImage[2];
626*8975f5c5SAndroid Build Coastguard Worker void main()
627*8975f5c5SAndroid Build Coastguard Worker {
628*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
629*8975f5c5SAndroid Build Coastguard Worker 0, 0));
630*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
631*8975f5c5SAndroid Build Coastguard Worker 0, 0));
632*8975f5c5SAndroid Build Coastguard Worker })";
633*8975f5c5SAndroid Build Coastguard Worker 
634*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program0, kCS0);
635*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program0);
636*8975f5c5SAndroid Build Coastguard Worker     int width = 1, height = 1;
637*8975f5c5SAndroid Build Coastguard Worker     GLuint inputValues[] = {200};
638*8975f5c5SAndroid Build Coastguard Worker     GLTexture mTexture[2];
639*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture[0]);
640*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height);
641*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT,
642*8975f5c5SAndroid Build Coastguard Worker                     inputValues);
643*8975f5c5SAndroid Build Coastguard Worker 
644*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture[1]);
645*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height);
646*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT,
647*8975f5c5SAndroid Build Coastguard Worker                     inputValues);
648*8975f5c5SAndroid Build Coastguard Worker 
649*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, mTexture[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
650*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, mTexture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
651*8975f5c5SAndroid Build Coastguard Worker 
652*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
653*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS1[] =
656*8975f5c5SAndroid Build Coastguard Worker         R"(#version 310 es
657*8975f5c5SAndroid Build Coastguard Worker  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
658*8975f5c5SAndroid Build Coastguard Worker  layout(std140, binding = 0) buffer blockOut {
659*8975f5c5SAndroid Build Coastguard Worker      uvec2 data;
660*8975f5c5SAndroid Build Coastguard Worker  } instanceOut;
661*8975f5c5SAndroid Build Coastguard Worker  layout(std140, binding = 1) buffer blockIn {
662*8975f5c5SAndroid Build Coastguard Worker      uvec2 data;
663*8975f5c5SAndroid Build Coastguard Worker  } instanceIn;
664*8975f5c5SAndroid Build Coastguard Worker  void main()
665*8975f5c5SAndroid Build Coastguard Worker  {
666*8975f5c5SAndroid Build Coastguard Worker      instanceOut.data = instanceIn.data;
667*8975f5c5SAndroid Build Coastguard Worker  }
668*8975f5c5SAndroid Build Coastguard Worker  )";
669*8975f5c5SAndroid Build Coastguard Worker 
670*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program1, kCS1);
671*8975f5c5SAndroid Build Coastguard Worker 
672*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kBufferSize              = 2;
673*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kBufferData[kBufferSize] = {10, 20};
674*8975f5c5SAndroid Build Coastguard Worker 
675*8975f5c5SAndroid Build Coastguard Worker     GLBuffer blockIn;
676*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, blockIn);
677*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferData), kBufferData, GL_STATIC_DRAW);
678*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, blockIn);
679*8975f5c5SAndroid Build Coastguard Worker 
680*8975f5c5SAndroid Build Coastguard Worker     GLBuffer blockOut;
681*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, blockOut);
682*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferData), nullptr, GL_STATIC_DRAW);
683*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, blockOut);
684*8975f5c5SAndroid Build Coastguard Worker 
685*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program1);
686*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
687*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
688*8975f5c5SAndroid Build Coastguard Worker 
689*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
690*8975f5c5SAndroid Build Coastguard Worker 
691*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, blockOut);
692*8975f5c5SAndroid Build Coastguard Worker     unsigned int bufferDataOut[kBufferSize] = {};
693*8975f5c5SAndroid Build Coastguard Worker     const GLColor *ptr                      = reinterpret_cast<GLColor *>(
694*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferData), GL_MAP_READ_BIT));
695*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferDataOut, ptr, sizeof(kBufferData));
696*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
697*8975f5c5SAndroid Build Coastguard Worker 
698*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int index = 0; index < kBufferSize; ++index)
699*8975f5c5SAndroid Build Coastguard Worker     {
700*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(bufferDataOut[index], kBufferData[index]) << " index " << index;
701*8975f5c5SAndroid Build Coastguard Worker     }
702*8975f5c5SAndroid Build Coastguard Worker }
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker // Basic test for DispatchComputeIndirect.
TEST_P(ComputeShaderTest,DispatchComputeIndirect)705*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchComputeIndirect)
706*8975f5c5SAndroid Build Coastguard Worker {
707*8975f5c5SAndroid Build Coastguard Worker     // Flaky crash on teardown, see http://anglebug.com/40096579
708*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11() && IsIntel() && IsWindows());
709*8975f5c5SAndroid Build Coastguard Worker 
710*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
711*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
712*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) uniform highp uimage2D uImage;
713*8975f5c5SAndroid Build Coastguard Worker void main()
714*8975f5c5SAndroid Build Coastguard Worker {
715*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y), uvec4(100, 0, 0, 0));
716*8975f5c5SAndroid Build Coastguard Worker })";
717*8975f5c5SAndroid Build Coastguard Worker 
718*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
719*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
720*8975f5c5SAndroid Build Coastguard Worker     const int kWidth = 4, kHeight = 6;
721*8975f5c5SAndroid Build Coastguard Worker     GLuint inputValues[kWidth][kHeight] = {};
722*8975f5c5SAndroid Build Coastguard Worker 
723*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buffer;
724*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer);
725*8975f5c5SAndroid Build Coastguard Worker     GLuint params[] = {kWidth, kHeight, 1};
726*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(params), params, GL_STATIC_DRAW);
727*8975f5c5SAndroid Build Coastguard Worker 
728*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
729*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
730*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
731*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
732*8975f5c5SAndroid Build Coastguard Worker                     inputValues);
733*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
734*8975f5c5SAndroid Build Coastguard Worker 
735*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
736*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
737*8975f5c5SAndroid Build Coastguard Worker 
738*8975f5c5SAndroid Build Coastguard Worker     glDispatchComputeIndirect(0);
739*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
740*8975f5c5SAndroid Build Coastguard Worker 
741*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
742*8975f5c5SAndroid Build Coastguard Worker 
743*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth][kHeight];
744*8975f5c5SAndroid Build Coastguard Worker 
745*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
746*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
747*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
748*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
749*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
750*8975f5c5SAndroid Build Coastguard Worker 
751*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
752*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
753*8975f5c5SAndroid Build Coastguard Worker 
754*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kExpectedValue = 100u;
755*8975f5c5SAndroid Build Coastguard Worker     for (int x = 0; x < kWidth; x++)
756*8975f5c5SAndroid Build Coastguard Worker     {
757*8975f5c5SAndroid Build Coastguard Worker         for (int y = 0; y < kHeight; y++)
758*8975f5c5SAndroid Build Coastguard Worker         {
759*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(kExpectedValue, outputValues[x][y]);
760*8975f5c5SAndroid Build Coastguard Worker         }
761*8975f5c5SAndroid Build Coastguard Worker     }
762*8975f5c5SAndroid Build Coastguard Worker }
763*8975f5c5SAndroid Build Coastguard Worker 
764*8975f5c5SAndroid Build Coastguard Worker // Test that uploading data to buffer that's in use then using it as indirect buffer works.
TEST_P(ComputeShaderTest,UseAsUBOThenUpdateThenDispatchComputeIndirect)765*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, UseAsUBOThenUpdateThenDispatchComputeIndirect)
766*8975f5c5SAndroid Build Coastguard Worker {
767*8975f5c5SAndroid Build Coastguard Worker     // Flaky crash on teardown, see http://anglebug.com/40096579
768*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11() && IsIntel() && IsWindows());
769*8975f5c5SAndroid Build Coastguard Worker 
770*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kWidth = 4, kHeight = 6;
771*8975f5c5SAndroid Build Coastguard Worker 
772*8975f5c5SAndroid Build Coastguard Worker     const std::array<uint32_t, 4> kInitialData = {1, 2, 3, 4};
773*8975f5c5SAndroid Build Coastguard Worker     const std::array<uint32_t, 4> kUpdateData  = {kWidth, kHeight, 1, 0};
774*8975f5c5SAndroid Build Coastguard Worker 
775*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buffer;
776*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_UNIFORM_BUFFER, buffer);
777*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
778*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
779*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
780*8975f5c5SAndroid Build Coastguard Worker 
781*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVerifyUBO[] = R"(#version 310 es
782*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
783*8975f5c5SAndroid Build Coastguard Worker layout(binding = 0) uniform block {
784*8975f5c5SAndroid Build Coastguard Worker     uvec4 data;
785*8975f5c5SAndroid Build Coastguard Worker } ubo;
786*8975f5c5SAndroid Build Coastguard Worker out vec4 colorOut;
787*8975f5c5SAndroid Build Coastguard Worker void main()
788*8975f5c5SAndroid Build Coastguard Worker {
789*8975f5c5SAndroid Build Coastguard Worker     if (all(equal(ubo.data, uvec4(1, 2, 3, 4))))
790*8975f5c5SAndroid Build Coastguard Worker         colorOut = vec4(0, 1.0, 0, 1.0);
791*8975f5c5SAndroid Build Coastguard Worker     else
792*8975f5c5SAndroid Build Coastguard Worker         colorOut = vec4(1.0, 0, 0, 1.0);
793*8975f5c5SAndroid Build Coastguard Worker })";
794*8975f5c5SAndroid Build Coastguard Worker 
795*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(verifyUbo, essl31_shaders::vs::Simple(), kVerifyUBO);
796*8975f5c5SAndroid Build Coastguard Worker     drawQuad(verifyUbo, essl31_shaders::PositionAttrib(), 0.5);
797*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
798*8975f5c5SAndroid Build Coastguard Worker 
799*8975f5c5SAndroid Build Coastguard Worker     // Update buffer data
800*8975f5c5SAndroid Build Coastguard Worker     glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
801*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
802*8975f5c5SAndroid Build Coastguard Worker 
803*8975f5c5SAndroid Build Coastguard Worker     const char kCS[] = R"(#version 310 es
804*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
805*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) uniform highp uimage2D uImage;
806*8975f5c5SAndroid Build Coastguard Worker void main()
807*8975f5c5SAndroid Build Coastguard Worker {
808*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y), uvec4(100, 0, 0, 0));
809*8975f5c5SAndroid Build Coastguard Worker })";
810*8975f5c5SAndroid Build Coastguard Worker 
811*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
812*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
813*8975f5c5SAndroid Build Coastguard Worker 
814*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer);
815*8975f5c5SAndroid Build Coastguard Worker 
816*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLuint> inputValues(kWidth * kHeight, 0);
817*8975f5c5SAndroid Build Coastguard Worker 
818*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
819*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
820*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
821*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
822*8975f5c5SAndroid Build Coastguard Worker                     inputValues.data());
823*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
824*8975f5c5SAndroid Build Coastguard Worker 
825*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
826*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
827*8975f5c5SAndroid Build Coastguard Worker 
828*8975f5c5SAndroid Build Coastguard Worker     glDispatchComputeIndirect(0);
829*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
830*8975f5c5SAndroid Build Coastguard Worker 
831*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
832*8975f5c5SAndroid Build Coastguard Worker 
833*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
834*8975f5c5SAndroid Build Coastguard Worker 
835*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth][kHeight];
836*8975f5c5SAndroid Build Coastguard Worker 
837*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
838*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
839*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
840*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
841*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
842*8975f5c5SAndroid Build Coastguard Worker 
843*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
844*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
845*8975f5c5SAndroid Build Coastguard Worker 
846*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kExpectedValue = 100u;
847*8975f5c5SAndroid Build Coastguard Worker     for (int x = 0; x < kWidth; x++)
848*8975f5c5SAndroid Build Coastguard Worker     {
849*8975f5c5SAndroid Build Coastguard Worker         for (int y = 0; y < kHeight; y++)
850*8975f5c5SAndroid Build Coastguard Worker         {
851*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(kExpectedValue, outputValues[x][y]);
852*8975f5c5SAndroid Build Coastguard Worker         }
853*8975f5c5SAndroid Build Coastguard Worker     }
854*8975f5c5SAndroid Build Coastguard Worker }
855*8975f5c5SAndroid Build Coastguard Worker 
856*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to write texture in compute shader, and verify the content is expected.
TEST_P(ComputeShaderTest,BindImageTexture)857*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTexture)
858*8975f5c5SAndroid Build Coastguard Worker {
859*8975f5c5SAndroid Build Coastguard Worker     GLTexture mTexture[2];
860*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer mFramebuffer;
861*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
862*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
863*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) writeonly uniform highp uimage2D uImage[2];
864*8975f5c5SAndroid Build Coastguard Worker void main()
865*8975f5c5SAndroid Build Coastguard Worker {
866*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
867*8975f5c5SAndroid Build Coastguard Worker 0, 0));
868*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
869*8975f5c5SAndroid Build Coastguard Worker 0, 0));
870*8975f5c5SAndroid Build Coastguard Worker })";
871*8975f5c5SAndroid Build Coastguard Worker 
872*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
873*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
874*8975f5c5SAndroid Build Coastguard Worker     int width = 1, height = 1;
875*8975f5c5SAndroid Build Coastguard Worker     GLuint inputValues[] = {200};
876*8975f5c5SAndroid Build Coastguard Worker 
877*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture[0]);
878*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height);
879*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT,
880*8975f5c5SAndroid Build Coastguard Worker                     inputValues);
881*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
882*8975f5c5SAndroid Build Coastguard Worker 
883*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, mTexture[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
884*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
885*8975f5c5SAndroid Build Coastguard Worker 
886*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture[1]);
887*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height);
888*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT,
889*8975f5c5SAndroid Build Coastguard Worker                     inputValues);
890*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
891*8975f5c5SAndroid Build Coastguard Worker 
892*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, mTexture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
893*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
894*8975f5c5SAndroid Build Coastguard Worker 
895*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
896*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
897*8975f5c5SAndroid Build Coastguard Worker 
898*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
899*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
900*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[2][1];
901*8975f5c5SAndroid Build Coastguard Worker     GLuint expectedValue = 100;
902*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
903*8975f5c5SAndroid Build Coastguard Worker 
904*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture[0],
905*8975f5c5SAndroid Build Coastguard Worker                            0);
906*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
907*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues[0]);
908*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
909*8975f5c5SAndroid Build Coastguard Worker 
910*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture[1],
911*8975f5c5SAndroid Build Coastguard Worker                            0);
912*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
913*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues[1]);
914*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
915*8975f5c5SAndroid Build Coastguard Worker 
916*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < width * height; i++)
917*8975f5c5SAndroid Build Coastguard Worker     {
918*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[0][i]);
919*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[1][i]);
920*8975f5c5SAndroid Build Coastguard Worker     }
921*8975f5c5SAndroid Build Coastguard Worker }
922*8975f5c5SAndroid Build Coastguard Worker 
923*8975f5c5SAndroid Build Coastguard Worker // Test that binding a 2D slice of a 3D texture works with compute shader
TEST_P(ComputeShaderTest,BindImageTexture3D)924*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTexture3D)
925*8975f5c5SAndroid Build Coastguard Worker {
926*8975f5c5SAndroid Build Coastguard Worker     GLTexture mTexture[2];
927*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer mFramebuffer;
928*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
929*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
930*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) writeonly uniform highp uimage2D uImage[2];
931*8975f5c5SAndroid Build Coastguard Worker void main()
932*8975f5c5SAndroid Build Coastguard Worker {
933*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
934*8975f5c5SAndroid Build Coastguard Worker 0, 0));
935*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, gl_WorkGroupID.x), uvec4(100, 0,
936*8975f5c5SAndroid Build Coastguard Worker 0, 0));
937*8975f5c5SAndroid Build Coastguard Worker })";
938*8975f5c5SAndroid Build Coastguard Worker 
939*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
940*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
941*8975f5c5SAndroid Build Coastguard Worker     int width = 1, height = 1, depth = 1;
942*8975f5c5SAndroid Build Coastguard Worker     GLuint inputValues[] = {200};
943*8975f5c5SAndroid Build Coastguard Worker 
944*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, mTexture[0]);
945*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, width, height, depth);
946*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, width, height, depth, GL_RED_INTEGER,
947*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, inputValues);
948*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
949*8975f5c5SAndroid Build Coastguard Worker 
950*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, mTexture[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
951*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
952*8975f5c5SAndroid Build Coastguard Worker 
953*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, mTexture[1]);
954*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, width, height, depth);
955*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, width, height, depth, GL_RED_INTEGER,
956*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, inputValues);
957*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
958*8975f5c5SAndroid Build Coastguard Worker 
959*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, mTexture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
960*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
961*8975f5c5SAndroid Build Coastguard Worker 
962*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
963*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
964*8975f5c5SAndroid Build Coastguard Worker 
965*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
966*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
967*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[2][1];
968*8975f5c5SAndroid Build Coastguard Worker     GLuint expectedValue = 100;
969*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
970*8975f5c5SAndroid Build Coastguard Worker 
971*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture[0], 0, 0);
972*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
973*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues[0]);
974*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
975*8975f5c5SAndroid Build Coastguard Worker 
976*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture[1], 0, 0);
977*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
978*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, width, height, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues[1]);
979*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
980*8975f5c5SAndroid Build Coastguard Worker 
981*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < width * height; i++)
982*8975f5c5SAndroid Build Coastguard Worker     {
983*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[0][i]);
984*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[1][i]);
985*8975f5c5SAndroid Build Coastguard Worker     }
986*8975f5c5SAndroid Build Coastguard Worker }
987*8975f5c5SAndroid Build Coastguard Worker 
988*8975f5c5SAndroid Build Coastguard Worker // When declare a image array without a binding qualifier, all elements are bound to unit zero.
TEST_P(ComputeShaderTest,ImageArrayWithoutBindingQualifier)989*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageArrayWithoutBindingQualifier)
990*8975f5c5SAndroid Build Coastguard Worker {
991*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
992*8975f5c5SAndroid Build Coastguard Worker 
993*8975f5c5SAndroid Build Coastguard Worker     // TODO([email protected]): On AMD desktop OpenGL, bind two image variables to unit 0,
994*8975f5c5SAndroid Build Coastguard Worker     // only one variable is valid.
995*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
996*8975f5c5SAndroid Build Coastguard Worker 
997*8975f5c5SAndroid Build Coastguard Worker     GLTexture mTexture;
998*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer mFramebuffer;
999*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1000*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1001*8975f5c5SAndroid Build Coastguard Worker layout(r32ui) writeonly uniform highp uimage2D uImage[2];
1002*8975f5c5SAndroid Build Coastguard Worker void main()
1003*8975f5c5SAndroid Build Coastguard Worker {
1004*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, 0), uvec4(100, 0, 0, 0));
1005*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, 1), uvec4(100, 0, 0, 0));
1006*8975f5c5SAndroid Build Coastguard Worker })";
1007*8975f5c5SAndroid Build Coastguard Worker 
1008*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1009*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1010*8975f5c5SAndroid Build Coastguard Worker     constexpr int kTextureWidth = 1, kTextureHeight = 2;
1011*8975f5c5SAndroid Build Coastguard Worker     GLuint inputValues[] = {200, 200};
1012*8975f5c5SAndroid Build Coastguard Worker 
1013*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture);
1014*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kTextureWidth, kTextureHeight);
1015*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RED_INTEGER,
1016*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, inputValues);
1017*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1018*8975f5c5SAndroid Build Coastguard Worker 
1019*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, mTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
1020*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1021*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1022*8975f5c5SAndroid Build Coastguard Worker 
1023*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1024*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1025*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
1026*8975f5c5SAndroid Build Coastguard Worker 
1027*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1028*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kTextureWidth * kTextureHeight];
1029*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kTextureWidth, kTextureHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1030*8975f5c5SAndroid Build Coastguard Worker                  outputValues);
1031*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1032*8975f5c5SAndroid Build Coastguard Worker 
1033*8975f5c5SAndroid Build Coastguard Worker     GLuint expectedValue = 100;
1034*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTextureWidth * kTextureHeight; i++)
1035*8975f5c5SAndroid Build Coastguard Worker     {
1036*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1037*8975f5c5SAndroid Build Coastguard Worker     }
1038*8975f5c5SAndroid Build Coastguard Worker }
1039*8975f5c5SAndroid Build Coastguard Worker 
1040*8975f5c5SAndroid Build Coastguard Worker // When an image array is declared without a binding qualifier, all elements are bound to unit zero.
1041*8975f5c5SAndroid Build Coastguard Worker // Check that the unused uniform image array element does not cause any corruption. Checks for a bug
1042*8975f5c5SAndroid Build Coastguard Worker // where unused element could make the whole array seem as unused.
TEST_P(ComputeShaderTest,ImageArrayUnusedElement)1043*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageArrayUnusedElement)
1044*8975f5c5SAndroid Build Coastguard Worker {
1045*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
1046*8975f5c5SAndroid Build Coastguard Worker 
1047*8975f5c5SAndroid Build Coastguard Worker     // TODO([email protected]): On AMD desktop OpenGL, bind two image variables to unit 0,
1048*8975f5c5SAndroid Build Coastguard Worker     // only one variable is valid.
1049*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
1050*8975f5c5SAndroid Build Coastguard Worker 
1051*8975f5c5SAndroid Build Coastguard Worker     // Vulkan is currently unable to handle unbound image units in compute shaders.
1052*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263596
1053*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan());
1054*8975f5c5SAndroid Build Coastguard Worker 
1055*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1056*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1057*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1058*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding=0) writeonly uniform highp uimage2D uOut;
1059*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding=1) readonly uniform highp uimage2D uIn[2];
1060*8975f5c5SAndroid Build Coastguard Worker 
1061*8975f5c5SAndroid Build Coastguard Worker void main()
1062*8975f5c5SAndroid Build Coastguard Worker {
1063*8975f5c5SAndroid Build Coastguard Worker     uvec4 inValue = imageLoad(uIn[0], ivec2(gl_LocalInvocationID.xy));
1064*8975f5c5SAndroid Build Coastguard Worker     imageStore(uOut, ivec2(gl_LocalInvocationIndex, 0), inValue);
1065*8975f5c5SAndroid Build Coastguard Worker     imageStore(uOut, ivec2(gl_LocalInvocationIndex, 1), inValue);
1066*8975f5c5SAndroid Build Coastguard Worker })";
1067*8975f5c5SAndroid Build Coastguard Worker 
1068*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1069*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1070*8975f5c5SAndroid Build Coastguard Worker     constexpr int kTextureWidth = 1, kTextureHeight = 2;
1071*8975f5c5SAndroid Build Coastguard Worker     GLuint inputValues[] = {100, 100};
1072*8975f5c5SAndroid Build Coastguard Worker     GLTexture in;
1073*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, in);
1074*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kTextureWidth, kTextureHeight);
1075*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RED_INTEGER,
1076*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, inputValues);
1077*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1078*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, in, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
1079*8975f5c5SAndroid Build Coastguard Worker 
1080*8975f5c5SAndroid Build Coastguard Worker     GLuint initValues[] = {111, 111};
1081*8975f5c5SAndroid Build Coastguard Worker     GLTexture out;
1082*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, out);
1083*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kTextureWidth, kTextureHeight);
1084*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RED_INTEGER,
1085*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, initValues);
1086*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1087*8975f5c5SAndroid Build Coastguard Worker 
1088*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, out, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
1089*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1090*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1091*8975f5c5SAndroid Build Coastguard Worker 
1092*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1093*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1094*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1095*8975f5c5SAndroid Build Coastguard Worker 
1096*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, out, 0);
1097*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kTextureWidth * kTextureHeight];
1098*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kTextureWidth, kTextureHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1099*8975f5c5SAndroid Build Coastguard Worker                  outputValues);
1100*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1101*8975f5c5SAndroid Build Coastguard Worker 
1102*8975f5c5SAndroid Build Coastguard Worker     GLuint expectedValue = 100;
1103*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTextureWidth * kTextureHeight; i++)
1104*8975f5c5SAndroid Build Coastguard Worker     {
1105*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1106*8975f5c5SAndroid Build Coastguard Worker     }
1107*8975f5c5SAndroid Build Coastguard Worker }
1108*8975f5c5SAndroid Build Coastguard Worker // imageLoad functions
TEST_P(ComputeShaderTest,ImageLoad)1109*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageLoad)
1110*8975f5c5SAndroid Build Coastguard Worker {
1111*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1112*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
1113*8975f5c5SAndroid Build Coastguard Worker layout(rgba8) uniform highp readonly image2D mImage2DInput;
1114*8975f5c5SAndroid Build Coastguard Worker layout(rgba16i) uniform highp readonly iimageCube mImageCubeInput;
1115*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui) uniform highp readonly uimage3D mImage3DInput;
1116*8975f5c5SAndroid Build Coastguard Worker layout(r32i) uniform highp writeonly iimage2D imageOut;
1117*8975f5c5SAndroid Build Coastguard Worker void main()
1118*8975f5c5SAndroid Build Coastguard Worker {
1119*8975f5c5SAndroid Build Coastguard Worker     vec4 result2d = imageLoad(mImage2DInput, ivec2(gl_LocalInvocationID.xy));
1120*8975f5c5SAndroid Build Coastguard Worker     ivec4 resultCube = imageLoad(mImageCubeInput, ivec3(gl_LocalInvocationID.xyz));
1121*8975f5c5SAndroid Build Coastguard Worker     uvec4 result3d = imageLoad(mImage3DInput, ivec3(gl_LocalInvocationID.xyz));
1122*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), ivec4(result2d) + resultCube + ivec4(result3d));
1123*8975f5c5SAndroid Build Coastguard Worker })";
1124*8975f5c5SAndroid Build Coastguard Worker 
1125*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1126*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1127*8975f5c5SAndroid Build Coastguard Worker }
1128*8975f5c5SAndroid Build Coastguard Worker 
1129*8975f5c5SAndroid Build Coastguard Worker // imageStore functions
TEST_P(ComputeShaderTest,ImageStore)1130*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageStore)
1131*8975f5c5SAndroid Build Coastguard Worker {
1132*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1133*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
1134*8975f5c5SAndroid Build Coastguard Worker layout(rgba16f) uniform highp writeonly imageCube mImageCubeOutput;
1135*8975f5c5SAndroid Build Coastguard Worker layout(r32f) uniform highp writeonly image3D mImage3DOutput;
1136*8975f5c5SAndroid Build Coastguard Worker layout(rgba8ui) uniform highp writeonly uimage2DArray mImage2DArrayOutput;
1137*8975f5c5SAndroid Build Coastguard Worker void main()
1138*8975f5c5SAndroid Build Coastguard Worker {
1139*8975f5c5SAndroid Build Coastguard Worker     imageStore(mImageCubeOutput, ivec3(gl_LocalInvocationID.xyz), vec4(0.0));
1140*8975f5c5SAndroid Build Coastguard Worker     imageStore(mImage3DOutput, ivec3(gl_LocalInvocationID.xyz), vec4(0.0));
1141*8975f5c5SAndroid Build Coastguard Worker     imageStore(mImage2DArrayOutput, ivec3(gl_LocalInvocationID.xyz), uvec4(0));
1142*8975f5c5SAndroid Build Coastguard Worker })";
1143*8975f5c5SAndroid Build Coastguard Worker 
1144*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1145*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1146*8975f5c5SAndroid Build Coastguard Worker }
1147*8975f5c5SAndroid Build Coastguard Worker 
1148*8975f5c5SAndroid Build Coastguard Worker // imageSize functions
TEST_P(ComputeShaderTest,ImageSize)1149*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageSize)
1150*8975f5c5SAndroid Build Coastguard Worker {
1151*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1152*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
1153*8975f5c5SAndroid Build Coastguard Worker layout(rgba8) uniform highp readonly imageCube mImageCubeInput;
1154*8975f5c5SAndroid Build Coastguard Worker layout(r32i) uniform highp readonly iimage2D mImage2DInput;
1155*8975f5c5SAndroid Build Coastguard Worker layout(rgba16ui) uniform highp readonly uimage2DArray mImage2DArrayInput;
1156*8975f5c5SAndroid Build Coastguard Worker layout(r32i) uniform highp writeonly iimage2D imageOut;
1157*8975f5c5SAndroid Build Coastguard Worker void main()
1158*8975f5c5SAndroid Build Coastguard Worker {
1159*8975f5c5SAndroid Build Coastguard Worker     ivec2 sizeCube = imageSize(mImageCubeInput);
1160*8975f5c5SAndroid Build Coastguard Worker     ivec2 size2D = imageSize(mImage2DInput);
1161*8975f5c5SAndroid Build Coastguard Worker     ivec3 size2DArray = imageSize(mImage2DArrayInput);
1162*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_LocalInvocationIndex, 0), ivec4(sizeCube, size2D.x, size2DArray.x));
1163*8975f5c5SAndroid Build Coastguard Worker })";
1164*8975f5c5SAndroid Build Coastguard Worker 
1165*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1166*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1167*8975f5c5SAndroid Build Coastguard Worker }
1168*8975f5c5SAndroid Build Coastguard Worker 
1169*8975f5c5SAndroid Build Coastguard Worker // Test that texelFetch works well in compute shader.
TEST_P(ComputeShaderTest,TexelFetchFunction)1170*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, TexelFetchFunction)
1171*8975f5c5SAndroid Build Coastguard Worker {
1172*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1173*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=16, local_size_y=12) in;
1174*8975f5c5SAndroid Build Coastguard Worker precision highp usampler2D;
1175*8975f5c5SAndroid Build Coastguard Worker uniform usampler2D tex;
1176*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer buf {
1177*8975f5c5SAndroid Build Coastguard Worker     uint outData[12][16];
1178*8975f5c5SAndroid Build Coastguard Worker };
1179*8975f5c5SAndroid Build Coastguard Worker 
1180*8975f5c5SAndroid Build Coastguard Worker void main()
1181*8975f5c5SAndroid Build Coastguard Worker {
1182*8975f5c5SAndroid Build Coastguard Worker     uint x = gl_LocalInvocationID.x;
1183*8975f5c5SAndroid Build Coastguard Worker     uint y = gl_LocalInvocationID.y;
1184*8975f5c5SAndroid Build Coastguard Worker     outData[y][x] = texelFetch(tex, ivec2(x, y), 0).x;
1185*8975f5c5SAndroid Build Coastguard Worker })";
1186*8975f5c5SAndroid Build Coastguard Worker 
1187*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kWidth  = 16;
1188*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kHeight = 12;
1189*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
1190*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
1191*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1192*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1193*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
1194*8975f5c5SAndroid Build Coastguard Worker     GLuint texels[kHeight][kWidth] = {{0}};
1195*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int y = 0; y < kHeight; ++y)
1196*8975f5c5SAndroid Build Coastguard Worker     {
1197*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int x = 0; x < kWidth; ++x)
1198*8975f5c5SAndroid Build Coastguard Worker         {
1199*8975f5c5SAndroid Build Coastguard Worker             texels[y][x] = x + y * kWidth;
1200*8975f5c5SAndroid Build Coastguard Worker         }
1201*8975f5c5SAndroid Build Coastguard Worker     }
1202*8975f5c5SAndroid Build Coastguard Worker     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1203*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1204*8975f5c5SAndroid Build Coastguard Worker                     texels);
1205*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
1206*8975f5c5SAndroid Build Coastguard Worker 
1207*8975f5c5SAndroid Build Coastguard Worker     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
1208*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kArrayStride = 16;
1209*8975f5c5SAndroid Build Coastguard Worker     GLBuffer ssbo;
1210*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1211*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, kWidth * kHeight * kArrayStride, nullptr,
1212*8975f5c5SAndroid Build Coastguard Worker                  GL_STREAM_DRAW);
1213*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1214*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1215*8975f5c5SAndroid Build Coastguard Worker 
1216*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1217*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1218*8975f5c5SAndroid Build Coastguard Worker 
1219*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
1220*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
1221*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(program, "tex"), 0);
1222*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1223*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
1224*8975f5c5SAndroid Build Coastguard Worker 
1225*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1226*8975f5c5SAndroid Build Coastguard Worker 
1227*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1228*8975f5c5SAndroid Build Coastguard Worker 
1229*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1230*8975f5c5SAndroid Build Coastguard Worker     const GLuint *ptr = reinterpret_cast<const GLuint *>(glMapBufferRange(
1231*8975f5c5SAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BUFFER, 0, kWidth * kHeight * kArrayStride, GL_MAP_READ_BIT));
1232*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1233*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < kWidth * kHeight; idx++)
1234*8975f5c5SAndroid Build Coastguard Worker     {
1235*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(idx, *(ptr + idx * kArrayStride / 4));
1236*8975f5c5SAndroid Build Coastguard Worker     }
1237*8975f5c5SAndroid Build Coastguard Worker }
1238*8975f5c5SAndroid Build Coastguard Worker 
1239*8975f5c5SAndroid Build Coastguard Worker // Test that texture function works well in compute shader.
TEST_P(ComputeShaderTest,TextureFunction)1240*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, TextureFunction)
1241*8975f5c5SAndroid Build Coastguard Worker {
1242*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1243*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=16, local_size_y=16) in;
1244*8975f5c5SAndroid Build Coastguard Worker precision highp usampler2D;
1245*8975f5c5SAndroid Build Coastguard Worker uniform usampler2D tex;
1246*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer buf {
1247*8975f5c5SAndroid Build Coastguard Worker     uint outData[16][16];
1248*8975f5c5SAndroid Build Coastguard Worker };
1249*8975f5c5SAndroid Build Coastguard Worker 
1250*8975f5c5SAndroid Build Coastguard Worker void main()
1251*8975f5c5SAndroid Build Coastguard Worker {
1252*8975f5c5SAndroid Build Coastguard Worker     uint x = gl_LocalInvocationID.x;
1253*8975f5c5SAndroid Build Coastguard Worker     uint y = gl_LocalInvocationID.y;
1254*8975f5c5SAndroid Build Coastguard Worker     float xCoord = float(x) / float(16);
1255*8975f5c5SAndroid Build Coastguard Worker     float yCoord = float(y) / float(16);
1256*8975f5c5SAndroid Build Coastguard Worker     outData[y][x] = texture(tex, vec2(xCoord, yCoord)).x;
1257*8975f5c5SAndroid Build Coastguard Worker })";
1258*8975f5c5SAndroid Build Coastguard Worker 
1259*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kWidth  = 16;
1260*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kHeight = 16;
1261*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
1262*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
1263*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1264*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1265*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
1266*8975f5c5SAndroid Build Coastguard Worker     GLuint texels[kHeight][kWidth] = {{0}};
1267*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int y = 0; y < kHeight; ++y)
1268*8975f5c5SAndroid Build Coastguard Worker     {
1269*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int x = 0; x < kWidth; ++x)
1270*8975f5c5SAndroid Build Coastguard Worker         {
1271*8975f5c5SAndroid Build Coastguard Worker             texels[y][x] = x + y * kWidth;
1272*8975f5c5SAndroid Build Coastguard Worker         }
1273*8975f5c5SAndroid Build Coastguard Worker     }
1274*8975f5c5SAndroid Build Coastguard Worker     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1275*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1276*8975f5c5SAndroid Build Coastguard Worker                     texels);
1277*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
1278*8975f5c5SAndroid Build Coastguard Worker 
1279*8975f5c5SAndroid Build Coastguard Worker     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
1280*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kArrayStride = 16;
1281*8975f5c5SAndroid Build Coastguard Worker     GLBuffer ssbo;
1282*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1283*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, kWidth * kHeight * kArrayStride, nullptr,
1284*8975f5c5SAndroid Build Coastguard Worker                  GL_STREAM_DRAW);
1285*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1286*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1287*8975f5c5SAndroid Build Coastguard Worker 
1288*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1289*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1290*8975f5c5SAndroid Build Coastguard Worker 
1291*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
1292*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
1293*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(program, "tex"), 0);
1294*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1295*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
1296*8975f5c5SAndroid Build Coastguard Worker 
1297*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1298*8975f5c5SAndroid Build Coastguard Worker 
1299*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1300*8975f5c5SAndroid Build Coastguard Worker 
1301*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1302*8975f5c5SAndroid Build Coastguard Worker     const GLuint *ptr = reinterpret_cast<const GLuint *>(glMapBufferRange(
1303*8975f5c5SAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BUFFER, 0, kWidth * kHeight * kArrayStride, GL_MAP_READ_BIT));
1304*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1305*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < kWidth * kHeight; idx++)
1306*8975f5c5SAndroid Build Coastguard Worker     {
1307*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(idx, *(ptr + idx * kArrayStride / 4));
1308*8975f5c5SAndroid Build Coastguard Worker     }
1309*8975f5c5SAndroid Build Coastguard Worker }
1310*8975f5c5SAndroid Build Coastguard Worker 
1311*8975f5c5SAndroid Build Coastguard Worker // Test mixed use of sampler and image.
TEST_P(ComputeShaderTest,SamplingAndImageReadWrite)1312*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, SamplingAndImageReadWrite)
1313*8975f5c5SAndroid Build Coastguard Worker {
1314*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[3];
1315*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1316*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1317*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1318*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
1319*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
1320*8975f5c5SAndroid Build Coastguard Worker precision highp usampler2D;
1321*8975f5c5SAndroid Build Coastguard Worker uniform usampler2D tex;
1322*8975f5c5SAndroid Build Coastguard Worker void main()
1323*8975f5c5SAndroid Build Coastguard Worker {
1324*8975f5c5SAndroid Build Coastguard Worker     uvec4 value_1 = texelFetch(tex, ivec2(gl_LocalInvocationID.xy), 0);
1325*8975f5c5SAndroid Build Coastguard Worker     uvec4 value_2 = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
1326*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value_1 + value_2);
1327*8975f5c5SAndroid Build Coastguard Worker })";
1328*8975f5c5SAndroid Build Coastguard Worker 
1329*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1;
1330*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[3][1] = {{50}, {100}, {20}};
1331*8975f5c5SAndroid Build Coastguard Worker 
1332*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
1333*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
1334*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1335*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[0]);
1336*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[2]);
1337*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
1338*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1339*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[2]);
1340*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1341*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
1342*8975f5c5SAndroid Build Coastguard Worker 
1343*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
1344*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1345*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1346*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
1347*8975f5c5SAndroid Build Coastguard Worker     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1348*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1349*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[1]);
1350*8975f5c5SAndroid Build Coastguard Worker 
1351*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1352*8975f5c5SAndroid Build Coastguard Worker 
1353*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1354*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1355*8975f5c5SAndroid Build Coastguard Worker 
1356*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
1357*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[2], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
1358*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1359*8975f5c5SAndroid Build Coastguard Worker 
1360*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1361*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1362*8975f5c5SAndroid Build Coastguard Worker 
1363*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1364*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
1365*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 150;
1366*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1367*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1368*8975f5c5SAndroid Build Coastguard Worker 
1369*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[2], 0);
1370*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1371*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1372*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1373*8975f5c5SAndroid Build Coastguard Worker 
1374*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1375*8975f5c5SAndroid Build Coastguard Worker     {
1376*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1377*8975f5c5SAndroid Build Coastguard Worker     }
1378*8975f5c5SAndroid Build Coastguard Worker }
1379*8975f5c5SAndroid Build Coastguard Worker 
1380*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write Texture2D in compute shader, and verify the contents.
TEST_P(ComputeShaderTest,BindImageTextureWithTexture2D)1381*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithTexture2D)
1382*8975f5c5SAndroid Build Coastguard Worker {
1383*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1384*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1385*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1386*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1387*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
1388*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
1389*8975f5c5SAndroid Build Coastguard Worker void main()
1390*8975f5c5SAndroid Build Coastguard Worker {
1391*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
1392*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
1393*8975f5c5SAndroid Build Coastguard Worker })";
1394*8975f5c5SAndroid Build Coastguard Worker 
1395*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1;
1396*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][1] = {{200}, {100}};
1397*8975f5c5SAndroid Build Coastguard Worker 
1398*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
1399*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
1400*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1401*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[0]);
1402*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1403*8975f5c5SAndroid Build Coastguard Worker 
1404*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
1405*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
1406*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1407*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[1]);
1408*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1409*8975f5c5SAndroid Build Coastguard Worker 
1410*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1411*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1412*8975f5c5SAndroid Build Coastguard Worker 
1413*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
1414*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1415*8975f5c5SAndroid Build Coastguard Worker 
1416*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
1417*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1418*8975f5c5SAndroid Build Coastguard Worker 
1419*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1420*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1421*8975f5c5SAndroid Build Coastguard Worker 
1422*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1423*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
1424*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 200;
1425*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1426*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1427*8975f5c5SAndroid Build Coastguard Worker 
1428*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
1429*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1430*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1431*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1432*8975f5c5SAndroid Build Coastguard Worker 
1433*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1434*8975f5c5SAndroid Build Coastguard Worker     {
1435*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1436*8975f5c5SAndroid Build Coastguard Worker     }
1437*8975f5c5SAndroid Build Coastguard Worker }
1438*8975f5c5SAndroid Build Coastguard Worker 
1439*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write Texture2D with non-zero base in compute shader, and verify
1440*8975f5c5SAndroid Build Coastguard Worker // the contents.
TEST_P(ComputeShaderTest,BindImageTextureWithNonZeroBaseTexture2D)1441*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithNonZeroBaseTexture2D)
1442*8975f5c5SAndroid Build Coastguard Worker {
1443*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1444*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1445*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1446*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1447*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
1448*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
1449*8975f5c5SAndroid Build Coastguard Worker void main()
1450*8975f5c5SAndroid Build Coastguard Worker {
1451*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
1452*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
1453*8975f5c5SAndroid Build Coastguard Worker })";
1454*8975f5c5SAndroid Build Coastguard Worker 
1455*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1;
1456*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][1] = {{200}, {100}};
1457*8975f5c5SAndroid Build Coastguard Worker 
1458*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
1459*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 2, GL_R32UI, kWidth * 2, kHeight * 2);
1460*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1461*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[0]);
1462*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1463*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1464*8975f5c5SAndroid Build Coastguard Worker 
1465*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
1466*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 2, GL_R32UI, kWidth * 2, kHeight * 2);
1467*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1468*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[1]);
1469*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1470*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1471*8975f5c5SAndroid Build Coastguard Worker 
1472*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1473*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1474*8975f5c5SAndroid Build Coastguard Worker 
1475*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 1, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
1476*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1477*8975f5c5SAndroid Build Coastguard Worker 
1478*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 1, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
1479*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1480*8975f5c5SAndroid Build Coastguard Worker 
1481*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1482*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1483*8975f5c5SAndroid Build Coastguard Worker 
1484*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1485*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
1486*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 200;
1487*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1488*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1489*8975f5c5SAndroid Build Coastguard Worker 
1490*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 1);
1491*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1492*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1493*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1494*8975f5c5SAndroid Build Coastguard Worker 
1495*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1496*8975f5c5SAndroid Build Coastguard Worker     {
1497*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]) << "  at index: " << i;
1498*8975f5c5SAndroid Build Coastguard Worker     }
1499*8975f5c5SAndroid Build Coastguard Worker }
1500*8975f5c5SAndroid Build Coastguard Worker 
1501*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write Texture2DArray in compute shader, and verify the contents.
TEST_P(ComputeShaderTest,BindImageTextureWithTexture2DArray)1502*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithTexture2DArray)
1503*8975f5c5SAndroid Build Coastguard Worker {
1504*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1505*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1506*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1507*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=2, local_size_y=2, local_size_z=2) in;
1508*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2DArray uImage_1;
1509*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2DArray uImage_2;
1510*8975f5c5SAndroid Build Coastguard Worker void main()
1511*8975f5c5SAndroid Build Coastguard Worker {
1512*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec3(gl_LocalInvocationID.xyz));
1513*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec3(gl_LocalInvocationID.xyz), value);
1514*8975f5c5SAndroid Build Coastguard Worker })";
1515*8975f5c5SAndroid Build Coastguard Worker 
1516*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
1517*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][2] = {{200, 200}, {100, 100}};
1518*8975f5c5SAndroid Build Coastguard Worker 
1519*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture[0]);
1520*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32UI, kWidth, kHeight, kDepth);
1521*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1522*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[0]);
1523*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1524*8975f5c5SAndroid Build Coastguard Worker 
1525*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture[1]);
1526*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32UI, kWidth, kHeight, kDepth);
1527*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1528*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[1]);
1529*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1530*8975f5c5SAndroid Build Coastguard Worker 
1531*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1532*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1533*8975f5c5SAndroid Build Coastguard Worker 
1534*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
1535*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1536*8975f5c5SAndroid Build Coastguard Worker 
1537*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
1538*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1539*8975f5c5SAndroid Build Coastguard Worker 
1540*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1541*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1542*8975f5c5SAndroid Build Coastguard Worker 
1543*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1544*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
1545*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 200;
1546*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1547*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1548*8975f5c5SAndroid Build Coastguard Worker 
1549*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
1550*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
1551*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1552*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1553*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1554*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1555*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1556*8975f5c5SAndroid Build Coastguard Worker     {
1557*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1558*8975f5c5SAndroid Build Coastguard Worker     }
1559*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1560*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1561*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1562*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1563*8975f5c5SAndroid Build Coastguard Worker     {
1564*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1565*8975f5c5SAndroid Build Coastguard Worker     }
1566*8975f5c5SAndroid Build Coastguard Worker }
1567*8975f5c5SAndroid Build Coastguard Worker 
1568*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write Texture2DArray with non-zero base in compute shader, and
1569*8975f5c5SAndroid Build Coastguard Worker // verify the contents.
TEST_P(ComputeShaderTest,BindImageTextureWithNonZeroBaseTexture2DArray)1570*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithNonZeroBaseTexture2DArray)
1571*8975f5c5SAndroid Build Coastguard Worker {
1572*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1573*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1574*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1575*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=2, local_size_y=2, local_size_z=2) in;
1576*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2DArray uImage_1;
1577*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2DArray uImage_2;
1578*8975f5c5SAndroid Build Coastguard Worker void main()
1579*8975f5c5SAndroid Build Coastguard Worker {
1580*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec3(gl_LocalInvocationID.xyz));
1581*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec3(gl_LocalInvocationID.xyz), value);
1582*8975f5c5SAndroid Build Coastguard Worker })";
1583*8975f5c5SAndroid Build Coastguard Worker 
1584*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
1585*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][2] = {{200, 200}, {100, 100}};
1586*8975f5c5SAndroid Build Coastguard Worker 
1587*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture[0]);
1588*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 2, GL_R32UI, kWidth * 2, kHeight * 2, kDepth);
1589*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1590*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[0]);
1591*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1592*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1593*8975f5c5SAndroid Build Coastguard Worker 
1594*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture[1]);
1595*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 2, GL_R32UI, kWidth * 2, kHeight * 2, kDepth);
1596*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1597*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[1]);
1598*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1599*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1600*8975f5c5SAndroid Build Coastguard Worker 
1601*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1602*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1603*8975f5c5SAndroid Build Coastguard Worker 
1604*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 1, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
1605*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1606*8975f5c5SAndroid Build Coastguard Worker 
1607*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 1, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
1608*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1609*8975f5c5SAndroid Build Coastguard Worker 
1610*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1611*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1612*8975f5c5SAndroid Build Coastguard Worker 
1613*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1614*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
1615*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 200;
1616*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1617*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1618*8975f5c5SAndroid Build Coastguard Worker 
1619*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 1, 0);
1620*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 1, 1);
1621*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1622*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1623*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1624*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1625*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1626*8975f5c5SAndroid Build Coastguard Worker     {
1627*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1628*8975f5c5SAndroid Build Coastguard Worker     }
1629*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1630*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1631*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1632*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1633*8975f5c5SAndroid Build Coastguard Worker     {
1634*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1635*8975f5c5SAndroid Build Coastguard Worker     }
1636*8975f5c5SAndroid Build Coastguard Worker }
1637*8975f5c5SAndroid Build Coastguard Worker 
1638*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write Texture3D in compute shader, and verify the contents.
TEST_P(ComputeShaderTest,BindImageTextureWithTexture3D)1639*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithTexture3D)
1640*8975f5c5SAndroid Build Coastguard Worker {
1641*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1642*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1643*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1644*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=2) in;
1645*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage3D uImage_1;
1646*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage3D uImage_2;
1647*8975f5c5SAndroid Build Coastguard Worker void main()
1648*8975f5c5SAndroid Build Coastguard Worker {
1649*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec3(gl_LocalInvocationID.xyz));
1650*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec3(gl_LocalInvocationID.xyz), value);
1651*8975f5c5SAndroid Build Coastguard Worker })";
1652*8975f5c5SAndroid Build Coastguard Worker 
1653*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
1654*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][2] = {{200, 200}, {100, 100}};
1655*8975f5c5SAndroid Build Coastguard Worker 
1656*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, texture[0]);
1657*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, kWidth, kHeight, kDepth);
1658*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1659*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[0]);
1660*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1661*8975f5c5SAndroid Build Coastguard Worker 
1662*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, texture[1]);
1663*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, kWidth, kHeight, kDepth);
1664*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1665*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[1]);
1666*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1667*8975f5c5SAndroid Build Coastguard Worker 
1668*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1669*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1670*8975f5c5SAndroid Build Coastguard Worker 
1671*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
1672*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1673*8975f5c5SAndroid Build Coastguard Worker 
1674*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
1675*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1676*8975f5c5SAndroid Build Coastguard Worker 
1677*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1678*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1679*8975f5c5SAndroid Build Coastguard Worker 
1680*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1681*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
1682*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 200;
1683*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1684*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1685*8975f5c5SAndroid Build Coastguard Worker 
1686*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
1687*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
1688*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1689*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1690*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1691*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1692*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1693*8975f5c5SAndroid Build Coastguard Worker     {
1694*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1695*8975f5c5SAndroid Build Coastguard Worker     }
1696*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1697*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1698*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1699*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
1700*8975f5c5SAndroid Build Coastguard Worker     {
1701*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]);
1702*8975f5c5SAndroid Build Coastguard Worker     }
1703*8975f5c5SAndroid Build Coastguard Worker }
1704*8975f5c5SAndroid Build Coastguard Worker 
1705*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write TextureCube in compute shader, and verify the contents.
TEST_P(ComputeShaderTest,BindImageTextureWithTextureCube)1706*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithTextureCube)
1707*8975f5c5SAndroid Build Coastguard Worker {
1708*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1709*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1710*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1711*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1712*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimageCube uImage_1;
1713*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimageCube uImage_2;
1714*8975f5c5SAndroid Build Coastguard Worker void main()
1715*8975f5c5SAndroid Build Coastguard Worker {
1716*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 6; i++)
1717*8975f5c5SAndroid Build Coastguard Worker     {
1718*8975f5c5SAndroid Build Coastguard Worker         uvec4 value = imageLoad(uImage_1, ivec3(gl_LocalInvocationID.xy, i));
1719*8975f5c5SAndroid Build Coastguard Worker         imageStore(uImage_2, ivec3(gl_LocalInvocationID.xy, i), value);
1720*8975f5c5SAndroid Build Coastguard Worker     }
1721*8975f5c5SAndroid Build Coastguard Worker })";
1722*8975f5c5SAndroid Build Coastguard Worker 
1723*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1;
1724*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][1] = {{200}, {100}};
1725*8975f5c5SAndroid Build Coastguard Worker 
1726*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, texture[0]);
1727*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_R32UI, kWidth, kHeight);
1728*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1729*8975f5c5SAndroid Build Coastguard Worker          face++)
1730*8975f5c5SAndroid Build Coastguard Worker     {
1731*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(face, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1732*8975f5c5SAndroid Build Coastguard Worker                         kInputValues[0]);
1733*8975f5c5SAndroid Build Coastguard Worker     }
1734*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1735*8975f5c5SAndroid Build Coastguard Worker 
1736*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, texture[1]);
1737*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_R32UI, kWidth, kHeight);
1738*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1739*8975f5c5SAndroid Build Coastguard Worker          face++)
1740*8975f5c5SAndroid Build Coastguard Worker     {
1741*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(face, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1742*8975f5c5SAndroid Build Coastguard Worker                         kInputValues[1]);
1743*8975f5c5SAndroid Build Coastguard Worker     }
1744*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1745*8975f5c5SAndroid Build Coastguard Worker 
1746*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1747*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1748*8975f5c5SAndroid Build Coastguard Worker 
1749*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
1750*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1751*8975f5c5SAndroid Build Coastguard Worker 
1752*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
1753*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1754*8975f5c5SAndroid Build Coastguard Worker 
1755*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1756*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1757*8975f5c5SAndroid Build Coastguard Worker 
1758*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1759*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
1760*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 200;
1761*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1762*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1763*8975f5c5SAndroid Build Coastguard Worker 
1764*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < 6; face++)
1765*8975f5c5SAndroid Build Coastguard Worker     {
1766*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1767*8975f5c5SAndroid Build Coastguard Worker                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[1], 0);
1768*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
1769*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1770*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
1771*8975f5c5SAndroid Build Coastguard Worker 
1772*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kWidth * kHeight; i++)
1773*8975f5c5SAndroid Build Coastguard Worker         {
1774*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(expectedValue, outputValues[i]);
1775*8975f5c5SAndroid Build Coastguard Worker         }
1776*8975f5c5SAndroid Build Coastguard Worker     }
1777*8975f5c5SAndroid Build Coastguard Worker }
1778*8975f5c5SAndroid Build Coastguard Worker 
1779*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write one layer of Texture2DArray in compute shader, and verify the
1780*8975f5c5SAndroid Build Coastguard Worker // contents.
TEST_P(ComputeShaderTest,BindImageTextureWithOneLayerTexture2DArray)1781*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithOneLayerTexture2DArray)
1782*8975f5c5SAndroid Build Coastguard Worker {
1783*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1784*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1785*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1786*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1787*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
1788*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
1789*8975f5c5SAndroid Build Coastguard Worker void main()
1790*8975f5c5SAndroid Build Coastguard Worker {
1791*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
1792*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
1793*8975f5c5SAndroid Build Coastguard Worker })";
1794*8975f5c5SAndroid Build Coastguard Worker 
1795*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
1796*8975f5c5SAndroid Build Coastguard Worker     constexpr int kResultSize           = kWidth * kHeight;
1797*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][2] = {{200, 150}, {100, 50}};
1798*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_1    = 200;
1799*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_2    = 100;
1800*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kResultSize];
1801*8975f5c5SAndroid Build Coastguard Worker 
1802*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture[0]);
1803*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32UI, kWidth, kHeight, kDepth);
1804*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1805*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[0]);
1806*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1807*8975f5c5SAndroid Build Coastguard Worker 
1808*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture[1]);
1809*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32UI, kWidth, kHeight, kDepth);
1810*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1811*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[1]);
1812*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1813*8975f5c5SAndroid Build Coastguard Worker 
1814*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1815*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1816*8975f5c5SAndroid Build Coastguard Worker 
1817*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
1818*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1819*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 1, GL_WRITE_ONLY, GL_R32UI);
1820*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1821*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1822*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1823*8975f5c5SAndroid Build Coastguard Worker 
1824*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1825*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1826*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1827*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
1828*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
1829*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1830*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1831*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1832*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1833*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kResultSize; i++)
1834*8975f5c5SAndroid Build Coastguard Worker     {
1835*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue_2, outputValues[i]);
1836*8975f5c5SAndroid Build Coastguard Worker     }
1837*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1838*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1839*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1840*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kResultSize; i++)
1841*8975f5c5SAndroid Build Coastguard Worker     {
1842*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue_1, outputValues[i]);
1843*8975f5c5SAndroid Build Coastguard Worker     }
1844*8975f5c5SAndroid Build Coastguard Worker }
1845*8975f5c5SAndroid Build Coastguard Worker 
1846*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write one layer of Texture3D in compute shader, and verify the
1847*8975f5c5SAndroid Build Coastguard Worker // contents.
TEST_P(ComputeShaderTest,BindImageTextureWithOneLayerTexture3D)1848*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithOneLayerTexture3D)
1849*8975f5c5SAndroid Build Coastguard Worker {
1850*8975f5c5SAndroid Build Coastguard Worker     // Vulkan validation error creating a 2D image view of a 3D image layer.
1851*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42262531
1852*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan());
1853*8975f5c5SAndroid Build Coastguard Worker 
1854*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1855*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1856*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1857*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1858*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
1859*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
1860*8975f5c5SAndroid Build Coastguard Worker void main()
1861*8975f5c5SAndroid Build Coastguard Worker {
1862*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
1863*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
1864*8975f5c5SAndroid Build Coastguard Worker })";
1865*8975f5c5SAndroid Build Coastguard Worker 
1866*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
1867*8975f5c5SAndroid Build Coastguard Worker     constexpr int kResultSize           = kWidth * kHeight;
1868*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][2] = {{200, 150}, {100, 50}};
1869*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_1    = 150;
1870*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_2    = 50;
1871*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kResultSize];
1872*8975f5c5SAndroid Build Coastguard Worker 
1873*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, texture[0]);
1874*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, kWidth, kHeight, kDepth);
1875*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1876*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[0]);
1877*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1878*8975f5c5SAndroid Build Coastguard Worker 
1879*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, texture[1]);
1880*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, kWidth, kHeight, kDepth);
1881*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
1882*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, kInputValues[1]);
1883*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1884*8975f5c5SAndroid Build Coastguard Worker 
1885*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1886*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1887*8975f5c5SAndroid Build Coastguard Worker 
1888*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 1, GL_READ_ONLY, GL_R32UI);
1889*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1890*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
1891*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1892*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1893*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1894*8975f5c5SAndroid Build Coastguard Worker 
1895*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1896*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1897*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1898*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0, 0);
1899*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture[1], 0, 1);
1900*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1901*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1902*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1903*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1904*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kResultSize; i++)
1905*8975f5c5SAndroid Build Coastguard Worker     {
1906*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue_1, outputValues[i]);
1907*8975f5c5SAndroid Build Coastguard Worker     }
1908*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1909*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1910*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1911*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kResultSize; i++)
1912*8975f5c5SAndroid Build Coastguard Worker     {
1913*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue_2, outputValues[i]);
1914*8975f5c5SAndroid Build Coastguard Worker     }
1915*8975f5c5SAndroid Build Coastguard Worker }
1916*8975f5c5SAndroid Build Coastguard Worker 
1917*8975f5c5SAndroid Build Coastguard Worker // Use image uniform to read and write one layer of TextureCube in compute shader, and verify the
1918*8975f5c5SAndroid Build Coastguard Worker // contents.
TEST_P(ComputeShaderTest,BindImageTextureWithOneLayerTextureCube)1919*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithOneLayerTextureCube)
1920*8975f5c5SAndroid Build Coastguard Worker {
1921*8975f5c5SAndroid Build Coastguard Worker     // GL_FRAMEBUFFER_BARRIER_BIT is invalid on Nvidia Linux platform.
1922*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42262394
1923*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL() && IsLinux());
1924*8975f5c5SAndroid Build Coastguard Worker 
1925*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
1926*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
1927*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
1928*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1929*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
1930*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
1931*8975f5c5SAndroid Build Coastguard Worker void main()
1932*8975f5c5SAndroid Build Coastguard Worker {
1933*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
1934*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
1935*8975f5c5SAndroid Build Coastguard Worker })";
1936*8975f5c5SAndroid Build Coastguard Worker 
1937*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1;
1938*8975f5c5SAndroid Build Coastguard Worker     constexpr int kResultSize           = kWidth * kHeight;
1939*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][1] = {{200}, {100}};
1940*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_1    = 200;
1941*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_2    = 100;
1942*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kResultSize];
1943*8975f5c5SAndroid Build Coastguard Worker 
1944*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, texture[0]);
1945*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_R32UI, kWidth, kHeight);
1946*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1947*8975f5c5SAndroid Build Coastguard Worker          face++)
1948*8975f5c5SAndroid Build Coastguard Worker     {
1949*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(face, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1950*8975f5c5SAndroid Build Coastguard Worker                         kInputValues[0]);
1951*8975f5c5SAndroid Build Coastguard Worker     }
1952*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1953*8975f5c5SAndroid Build Coastguard Worker 
1954*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, texture[1]);
1955*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_R32UI, kWidth, kHeight);
1956*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1957*8975f5c5SAndroid Build Coastguard Worker          face++)
1958*8975f5c5SAndroid Build Coastguard Worker     {
1959*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(face, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
1960*8975f5c5SAndroid Build Coastguard Worker                         kInputValues[1]);
1961*8975f5c5SAndroid Build Coastguard Worker     }
1962*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1963*8975f5c5SAndroid Build Coastguard Worker 
1964*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1965*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1966*8975f5c5SAndroid Build Coastguard Worker 
1967*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 3, GL_READ_ONLY, GL_R32UI);
1968*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1969*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 4, GL_WRITE_ONLY, GL_R32UI);
1970*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1971*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
1972*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1973*8975f5c5SAndroid Build Coastguard Worker 
1974*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1975*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1976*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1977*8975f5c5SAndroid Build Coastguard Worker 
1978*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < 6; face++)
1979*8975f5c5SAndroid Build Coastguard Worker     {
1980*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1981*8975f5c5SAndroid Build Coastguard Worker                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[1], 0);
1982*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
1983*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
1984*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
1985*8975f5c5SAndroid Build Coastguard Worker 
1986*8975f5c5SAndroid Build Coastguard Worker         if (face == 4)
1987*8975f5c5SAndroid Build Coastguard Worker         {
1988*8975f5c5SAndroid Build Coastguard Worker             for (int i = 0; i < kResultSize; i++)
1989*8975f5c5SAndroid Build Coastguard Worker             {
1990*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(expectedValue_1, outputValues[i]);
1991*8975f5c5SAndroid Build Coastguard Worker             }
1992*8975f5c5SAndroid Build Coastguard Worker         }
1993*8975f5c5SAndroid Build Coastguard Worker         else
1994*8975f5c5SAndroid Build Coastguard Worker         {
1995*8975f5c5SAndroid Build Coastguard Worker             for (int i = 0; i < kResultSize; i++)
1996*8975f5c5SAndroid Build Coastguard Worker             {
1997*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(expectedValue_2, outputValues[i]);
1998*8975f5c5SAndroid Build Coastguard Worker             }
1999*8975f5c5SAndroid Build Coastguard Worker         }
2000*8975f5c5SAndroid Build Coastguard Worker     }
2001*8975f5c5SAndroid Build Coastguard Worker }
2002*8975f5c5SAndroid Build Coastguard Worker 
2003*8975f5c5SAndroid Build Coastguard Worker // Test to bind kinds of texture types, bind either the entire texture
2004*8975f5c5SAndroid Build Coastguard Worker // level or a single layer or face of the face level.
TEST_P(ComputeShaderTest,BindImageTextureWithMixTextureTypes)2005*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, BindImageTextureWithMixTextureTypes)
2006*8975f5c5SAndroid Build Coastguard Worker {
2007*8975f5c5SAndroid Build Coastguard Worker     // GL_FRAMEBUFFER_BARRIER_BIT is invalid on Nvidia Linux platform.
2008*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42262394
2009*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL() && IsLinux());
2010*8975f5c5SAndroid Build Coastguard Worker 
2011*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2012*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2013*8975f5c5SAndroid Build Coastguard Worker 
2014*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[4];
2015*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
2016*8975f5c5SAndroid Build Coastguard Worker     const char csSource[] =
2017*8975f5c5SAndroid Build Coastguard Worker         R"(#version 310 es
2018*8975f5c5SAndroid Build Coastguard Worker         layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2019*8975f5c5SAndroid Build Coastguard Worker         layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
2020*8975f5c5SAndroid Build Coastguard Worker         layout(r32ui, binding = 1) readonly uniform highp uimage2D uImage_2;
2021*8975f5c5SAndroid Build Coastguard Worker         layout(r32ui, binding = 2) readonly uniform highp uimage3D uImage_3;
2022*8975f5c5SAndroid Build Coastguard Worker         layout(r32ui, binding = 3) writeonly uniform highp uimage2D uImage_4;
2023*8975f5c5SAndroid Build Coastguard Worker         void main()
2024*8975f5c5SAndroid Build Coastguard Worker         {
2025*8975f5c5SAndroid Build Coastguard Worker             uvec4 value_1 = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
2026*8975f5c5SAndroid Build Coastguard Worker             uvec4 value_2 = imageLoad(uImage_2, ivec2(gl_LocalInvocationID.xy));
2027*8975f5c5SAndroid Build Coastguard Worker             uvec4 value_3 = imageLoad(uImage_3, ivec3(gl_LocalInvocationID.xyz));
2028*8975f5c5SAndroid Build Coastguard Worker             imageStore(uImage_4, ivec2(gl_LocalInvocationID.xy), value_1 + value_2 + value_3);
2029*8975f5c5SAndroid Build Coastguard Worker         })";
2030*8975f5c5SAndroid Build Coastguard Worker 
2031*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
2032*8975f5c5SAndroid Build Coastguard Worker     constexpr int kResultSize               = kWidth * kHeight;
2033*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues2D[1]      = {11};
2034*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint KInputValues2DArray[2] = {23, 35};
2035*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint KInputValues3D[2]      = {102, 67};
2036*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint KInputValuesCube[1]    = {232};
2037*8975f5c5SAndroid Build Coastguard Worker 
2038*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_1 = 148;
2039*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue_2 = 232;
2040*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kResultSize];
2041*8975f5c5SAndroid Build Coastguard Worker 
2042*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
2043*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
2044*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
2045*8975f5c5SAndroid Build Coastguard Worker                     kInputValues2D);
2046*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2047*8975f5c5SAndroid Build Coastguard Worker 
2048*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture[1]);
2049*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32UI, kWidth, kHeight, kDepth);
2050*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
2051*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, KInputValues2DArray);
2052*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2053*8975f5c5SAndroid Build Coastguard Worker 
2054*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_3D, texture[2]);
2055*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32UI, kWidth, kHeight, kDepth);
2056*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RED_INTEGER,
2057*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_INT, KInputValues3D);
2058*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2059*8975f5c5SAndroid Build Coastguard Worker 
2060*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, texture[3]);
2061*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_R32UI, kWidth, kHeight);
2062*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
2063*8975f5c5SAndroid Build Coastguard Worker          face++)
2064*8975f5c5SAndroid Build Coastguard Worker     {
2065*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(face, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
2066*8975f5c5SAndroid Build Coastguard Worker                         KInputValuesCube);
2067*8975f5c5SAndroid Build Coastguard Worker     }
2068*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2069*8975f5c5SAndroid Build Coastguard Worker 
2070*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
2071*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
2072*8975f5c5SAndroid Build Coastguard Worker 
2073*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
2074*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2075*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 1, GL_READ_ONLY, GL_R32UI);
2076*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2077*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(2, texture[2], 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32UI);
2078*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2079*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(3, texture[3], 0, GL_FALSE, 4, GL_WRITE_ONLY, GL_R32UI);
2080*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2081*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
2082*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2083*8975f5c5SAndroid Build Coastguard Worker 
2084*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2085*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
2086*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2087*8975f5c5SAndroid Build Coastguard Worker 
2088*8975f5c5SAndroid Build Coastguard Worker     for (GLenum face = 0; face < 6; face++)
2089*8975f5c5SAndroid Build Coastguard Worker     {
2090*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2091*8975f5c5SAndroid Build Coastguard Worker                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[3], 0);
2092*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
2093*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
2094*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
2095*8975f5c5SAndroid Build Coastguard Worker 
2096*8975f5c5SAndroid Build Coastguard Worker         if (face == 4)
2097*8975f5c5SAndroid Build Coastguard Worker         {
2098*8975f5c5SAndroid Build Coastguard Worker             for (int i = 0; i < kResultSize; i++)
2099*8975f5c5SAndroid Build Coastguard Worker             {
2100*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(expectedValue_1, outputValues[i]);
2101*8975f5c5SAndroid Build Coastguard Worker             }
2102*8975f5c5SAndroid Build Coastguard Worker         }
2103*8975f5c5SAndroid Build Coastguard Worker         else
2104*8975f5c5SAndroid Build Coastguard Worker         {
2105*8975f5c5SAndroid Build Coastguard Worker             for (int i = 0; i < kResultSize; i++)
2106*8975f5c5SAndroid Build Coastguard Worker             {
2107*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(expectedValue_2, outputValues[i]);
2108*8975f5c5SAndroid Build Coastguard Worker             }
2109*8975f5c5SAndroid Build Coastguard Worker         }
2110*8975f5c5SAndroid Build Coastguard Worker     }
2111*8975f5c5SAndroid Build Coastguard Worker }
2112*8975f5c5SAndroid Build Coastguard Worker 
2113*8975f5c5SAndroid Build Coastguard Worker // Verify an INVALID_OPERATION error is reported when querying GL_COMPUTE_WORK_GROUP_SIZE for a
2114*8975f5c5SAndroid Build Coastguard Worker // program which has not been linked successfully or which does not contain objects to form a
2115*8975f5c5SAndroid Build Coastguard Worker // compute shader.
TEST_P(ComputeShaderTest,QueryComputeWorkGroupSize)2116*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, QueryComputeWorkGroupSize)
2117*8975f5c5SAndroid Build Coastguard Worker {
2118*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 310 es
2119*8975f5c5SAndroid Build Coastguard Worker void main()
2120*8975f5c5SAndroid Build Coastguard Worker {
2121*8975f5c5SAndroid Build Coastguard Worker })";
2122*8975f5c5SAndroid Build Coastguard Worker 
2123*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 310 es
2124*8975f5c5SAndroid Build Coastguard Worker void main()
2125*8975f5c5SAndroid Build Coastguard Worker {
2126*8975f5c5SAndroid Build Coastguard Worker })";
2127*8975f5c5SAndroid Build Coastguard Worker 
2128*8975f5c5SAndroid Build Coastguard Worker     GLint workGroupSize[3];
2129*8975f5c5SAndroid Build Coastguard Worker 
2130*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(graphicsProgram, kVS, kFS);
2131*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(graphicsProgram, GL_COMPUTE_WORK_GROUP_SIZE, workGroupSize);
2132*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2133*8975f5c5SAndroid Build Coastguard Worker 
2134*8975f5c5SAndroid Build Coastguard Worker     GLuint computeProgram = glCreateProgram();
2135*8975f5c5SAndroid Build Coastguard Worker     GLShader computeShader(GL_COMPUTE_SHADER);
2136*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(computeProgram, computeShader);
2137*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(computeProgram);
2138*8975f5c5SAndroid Build Coastguard Worker     glDetachShader(computeProgram, computeShader);
2139*8975f5c5SAndroid Build Coastguard Worker 
2140*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
2141*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(computeProgram, GL_LINK_STATUS, &linkStatus);
2142*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FALSE(linkStatus);
2143*8975f5c5SAndroid Build Coastguard Worker 
2144*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(computeProgram, GL_COMPUTE_WORK_GROUP_SIZE, workGroupSize);
2145*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2146*8975f5c5SAndroid Build Coastguard Worker 
2147*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(computeProgram);
2148*8975f5c5SAndroid Build Coastguard Worker 
2149*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2150*8975f5c5SAndroid Build Coastguard Worker }
2151*8975f5c5SAndroid Build Coastguard Worker 
2152*8975f5c5SAndroid Build Coastguard Worker // Use groupMemoryBarrier and barrier to sync reads/writes order and the execution
2153*8975f5c5SAndroid Build Coastguard Worker // order of multiple shader invocations in compute shader.
TEST_P(ComputeShaderTest,GroupMemoryBarrierAndBarrierTest)2154*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, GroupMemoryBarrierAndBarrierTest)
2155*8975f5c5SAndroid Build Coastguard Worker {
2156*8975f5c5SAndroid Build Coastguard Worker     // TODO([email protected]): Figure out why we get this error message
2157*8975f5c5SAndroid Build Coastguard Worker     // that shader uses features not recognized by this D3D version.
2158*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF((IsAMD() || IsNVIDIA()) && IsD3D11());
2159*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
2160*8975f5c5SAndroid Build Coastguard Worker 
2161*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2162*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2163*8975f5c5SAndroid Build Coastguard Worker 
2164*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
2165*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
2166*8975f5c5SAndroid Build Coastguard Worker 
2167*8975f5c5SAndroid Build Coastguard Worker     // Each invocation first stores a single value in an image, then each invocation sums up
2168*8975f5c5SAndroid Build Coastguard Worker     // all the values in the image and stores the sum in the image. groupMemoryBarrier is
2169*8975f5c5SAndroid Build Coastguard Worker     // used to order reads/writes to variables stored in memory accessible to other shader
2170*8975f5c5SAndroid Build Coastguard Worker     // invocations, and barrier is used to control the relative execution order of multiple
2171*8975f5c5SAndroid Build Coastguard Worker     // shader invocations used to process a local work group.
2172*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
2173*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=2, local_size_y=2, local_size_z=1) in;
2174*8975f5c5SAndroid Build Coastguard Worker layout(r32i, binding = 0) uniform highp iimage2D image;
2175*8975f5c5SAndroid Build Coastguard Worker void main()
2176*8975f5c5SAndroid Build Coastguard Worker {
2177*8975f5c5SAndroid Build Coastguard Worker     uint x = gl_LocalInvocationID.x;
2178*8975f5c5SAndroid Build Coastguard Worker     uint y = gl_LocalInvocationID.y;
2179*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), ivec4(x + y));
2180*8975f5c5SAndroid Build Coastguard Worker     groupMemoryBarrier();
2181*8975f5c5SAndroid Build Coastguard Worker     barrier();
2182*8975f5c5SAndroid Build Coastguard Worker     int sum = 0;
2183*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 2; i++)
2184*8975f5c5SAndroid Build Coastguard Worker     {
2185*8975f5c5SAndroid Build Coastguard Worker         for(int j = 0; j < 2; j++)
2186*8975f5c5SAndroid Build Coastguard Worker         {
2187*8975f5c5SAndroid Build Coastguard Worker             sum += imageLoad(image, ivec2(i, j)).x;
2188*8975f5c5SAndroid Build Coastguard Worker         }
2189*8975f5c5SAndroid Build Coastguard Worker     }
2190*8975f5c5SAndroid Build Coastguard Worker     groupMemoryBarrier();
2191*8975f5c5SAndroid Build Coastguard Worker     barrier();
2192*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), ivec4(sum));
2193*8975f5c5SAndroid Build Coastguard Worker })";
2194*8975f5c5SAndroid Build Coastguard Worker 
2195*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 2, kHeight = 2;
2196*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
2197*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32I, kWidth, kHeight);
2198*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2199*8975f5c5SAndroid Build Coastguard Worker 
2200*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
2201*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
2202*8975f5c5SAndroid Build Coastguard Worker 
2203*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
2204*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2205*8975f5c5SAndroid Build Coastguard Worker 
2206*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
2207*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2208*8975f5c5SAndroid Build Coastguard Worker 
2209*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2210*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
2211*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kExpectedValue = 4;
2212*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
2213*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2214*8975f5c5SAndroid Build Coastguard Worker 
2215*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2216*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2217*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_INT, outputValues);
2218*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2219*8975f5c5SAndroid Build Coastguard Worker 
2220*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
2221*8975f5c5SAndroid Build Coastguard Worker     {
2222*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(kExpectedValue, outputValues[i]);
2223*8975f5c5SAndroid Build Coastguard Worker     }
2224*8975f5c5SAndroid Build Coastguard Worker }
2225*8975f5c5SAndroid Build Coastguard Worker 
2226*8975f5c5SAndroid Build Coastguard Worker // Verify that a link error is generated when the sum of the number of active image uniforms and
2227*8975f5c5SAndroid Build Coastguard Worker // active shader storage blocks in a compute shader exceeds GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES.
TEST_P(ComputeShaderTest,ExceedCombinedShaderOutputResourcesInCS)2228*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ExceedCombinedShaderOutputResourcesInCS)
2229*8975f5c5SAndroid Build Coastguard Worker {
2230*8975f5c5SAndroid Build Coastguard Worker     GLint maxCombinedShaderOutputResources;
2231*8975f5c5SAndroid Build Coastguard Worker     GLint maxComputeShaderStorageBlocks;
2232*8975f5c5SAndroid Build Coastguard Worker     GLint maxComputeImageUniforms;
2233*8975f5c5SAndroid Build Coastguard Worker 
2234*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &maxCombinedShaderOutputResources);
2235*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &maxComputeShaderStorageBlocks);
2236*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &maxComputeImageUniforms);
2237*8975f5c5SAndroid Build Coastguard Worker 
2238*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(maxCombinedShaderOutputResources >=
2239*8975f5c5SAndroid Build Coastguard Worker                        maxComputeShaderStorageBlocks + maxComputeImageUniforms);
2240*8975f5c5SAndroid Build Coastguard Worker 
2241*8975f5c5SAndroid Build Coastguard Worker     std::ostringstream computeShaderStream;
2242*8975f5c5SAndroid Build Coastguard Worker     computeShaderStream << "#version 310 es\n"
2243*8975f5c5SAndroid Build Coastguard Worker                            "layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in;\n"
2244*8975f5c5SAndroid Build Coastguard Worker                            "layout(shared, binding = 0) buffer blockName"
2245*8975f5c5SAndroid Build Coastguard Worker                            "{\n"
2246*8975f5c5SAndroid Build Coastguard Worker                            "    uint data;\n"
2247*8975f5c5SAndroid Build Coastguard Worker                            "} instance["
2248*8975f5c5SAndroid Build Coastguard Worker                         << maxComputeShaderStorageBlocks << "];\n";
2249*8975f5c5SAndroid Build Coastguard Worker 
2250*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GE(maxComputeImageUniforms, 4);
2251*8975f5c5SAndroid Build Coastguard Worker     int numImagesInArray  = maxComputeImageUniforms / 2;
2252*8975f5c5SAndroid Build Coastguard Worker     int numImagesNonArray = maxComputeImageUniforms - numImagesInArray;
2253*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < numImagesNonArray; ++i)
2254*8975f5c5SAndroid Build Coastguard Worker     {
2255*8975f5c5SAndroid Build Coastguard Worker         computeShaderStream << "layout(r32f, binding = " << i << ") uniform highp image2D image"
2256*8975f5c5SAndroid Build Coastguard Worker                             << i << ";\n";
2257*8975f5c5SAndroid Build Coastguard Worker     }
2258*8975f5c5SAndroid Build Coastguard Worker 
2259*8975f5c5SAndroid Build Coastguard Worker     computeShaderStream << "layout(r32f, binding = " << numImagesNonArray
2260*8975f5c5SAndroid Build Coastguard Worker                         << ") uniform highp image2D imageArray[" << numImagesInArray << "];\n";
2261*8975f5c5SAndroid Build Coastguard Worker 
2262*8975f5c5SAndroid Build Coastguard Worker     computeShaderStream << "void main()\n"
2263*8975f5c5SAndroid Build Coastguard Worker                            "{\n"
2264*8975f5c5SAndroid Build Coastguard Worker                            "    uint val = 0u;\n"
2265*8975f5c5SAndroid Build Coastguard Worker                            "    vec4 val2 = vec4(0.0);\n";
2266*8975f5c5SAndroid Build Coastguard Worker 
2267*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < maxComputeShaderStorageBlocks; ++i)
2268*8975f5c5SAndroid Build Coastguard Worker     {
2269*8975f5c5SAndroid Build Coastguard Worker         computeShaderStream << "    val += instance[" << i << "].data; \n";
2270*8975f5c5SAndroid Build Coastguard Worker     }
2271*8975f5c5SAndroid Build Coastguard Worker 
2272*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < numImagesNonArray; ++i)
2273*8975f5c5SAndroid Build Coastguard Worker     {
2274*8975f5c5SAndroid Build Coastguard Worker         computeShaderStream << "    val2 += imageLoad(image" << i
2275*8975f5c5SAndroid Build Coastguard Worker                             << ", ivec2(gl_LocalInvocationID.xy)); \n";
2276*8975f5c5SAndroid Build Coastguard Worker     }
2277*8975f5c5SAndroid Build Coastguard Worker 
2278*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < numImagesInArray; ++i)
2279*8975f5c5SAndroid Build Coastguard Worker     {
2280*8975f5c5SAndroid Build Coastguard Worker         computeShaderStream << "    val2 += imageLoad(imageArray[" << i << "]"
2281*8975f5c5SAndroid Build Coastguard Worker                             << ", ivec2(gl_LocalInvocationID.xy)); \n";
2282*8975f5c5SAndroid Build Coastguard Worker     }
2283*8975f5c5SAndroid Build Coastguard Worker 
2284*8975f5c5SAndroid Build Coastguard Worker     computeShaderStream << "    instance[0].data = val + uint(val2.x);\n"
2285*8975f5c5SAndroid Build Coastguard Worker                            "}\n";
2286*8975f5c5SAndroid Build Coastguard Worker 
2287*8975f5c5SAndroid Build Coastguard Worker     GLuint computeProgram = CompileComputeProgram(computeShaderStream.str().c_str());
2288*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0u, computeProgram);
2289*8975f5c5SAndroid Build Coastguard Worker }
2290*8975f5c5SAndroid Build Coastguard Worker 
2291*8975f5c5SAndroid Build Coastguard Worker // Test that uniform block with struct member in compute shader is supported.
TEST_P(ComputeShaderTest,UniformBlockWithStructMember)2292*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, UniformBlockWithStructMember)
2293*8975f5c5SAndroid Build Coastguard Worker {
2294*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
2295*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
2296*8975f5c5SAndroid Build Coastguard Worker layout(rgba8) uniform highp readonly image2D mImage2DInput;
2297*8975f5c5SAndroid Build Coastguard Worker layout(rgba8) uniform highp writeonly image2D mImage2DOutput;
2298*8975f5c5SAndroid Build Coastguard Worker struct S {
2299*8975f5c5SAndroid Build Coastguard Worker     ivec3 a;
2300*8975f5c5SAndroid Build Coastguard Worker     ivec2 b;
2301*8975f5c5SAndroid Build Coastguard Worker };
2302*8975f5c5SAndroid Build Coastguard Worker 
2303*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding=0) uniform blockName {
2304*8975f5c5SAndroid Build Coastguard Worker     S bd;
2305*8975f5c5SAndroid Build Coastguard Worker } instanceName;
2306*8975f5c5SAndroid Build Coastguard Worker void main()
2307*8975f5c5SAndroid Build Coastguard Worker {
2308*8975f5c5SAndroid Build Coastguard Worker     ivec2 t1 = instanceName.bd.b;
2309*8975f5c5SAndroid Build Coastguard Worker     vec4 result2d = imageLoad(mImage2DInput, t1);
2310*8975f5c5SAndroid Build Coastguard Worker     imageStore(mImage2DOutput, ivec2(gl_LocalInvocationID.xy), result2d);
2311*8975f5c5SAndroid Build Coastguard Worker })";
2312*8975f5c5SAndroid Build Coastguard Worker 
2313*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
2314*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2315*8975f5c5SAndroid Build Coastguard Worker }
2316*8975f5c5SAndroid Build Coastguard Worker 
2317*8975f5c5SAndroid Build Coastguard Worker // Verify shared non-array variables can work correctly.
TEST_P(ComputeShaderTest,NonArraySharedVariable)2318*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, NonArraySharedVariable)
2319*8975f5c5SAndroid Build Coastguard Worker {
2320*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2321*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2322*8975f5c5SAndroid Build Coastguard Worker 
2323*8975f5c5SAndroid Build Coastguard Worker     const char kCSShader[] = R"(#version 310 es
2324*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 2, local_size_y = 2, local_size_z = 1) in;
2325*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
2326*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
2327*8975f5c5SAndroid Build Coastguard Worker shared uint temp;
2328*8975f5c5SAndroid Build Coastguard Worker void main()
2329*8975f5c5SAndroid Build Coastguard Worker {
2330*8975f5c5SAndroid Build Coastguard Worker     if (gl_LocalInvocationID == uvec3(0, 0, 0))
2331*8975f5c5SAndroid Build Coastguard Worker     {
2332*8975f5c5SAndroid Build Coastguard Worker         temp = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2333*8975f5c5SAndroid Build Coastguard Worker     }
2334*8975f5c5SAndroid Build Coastguard Worker     groupMemoryBarrier();
2335*8975f5c5SAndroid Build Coastguard Worker     barrier();
2336*8975f5c5SAndroid Build Coastguard Worker     if (gl_LocalInvocationID == uvec3(1, 1, 0))
2337*8975f5c5SAndroid Build Coastguard Worker     {
2338*8975f5c5SAndroid Build Coastguard Worker         imageStore(dstImage, ivec2(gl_LocalInvocationID.xy), uvec4(temp));
2339*8975f5c5SAndroid Build Coastguard Worker     }
2340*8975f5c5SAndroid Build Coastguard Worker     else
2341*8975f5c5SAndroid Build Coastguard Worker     {
2342*8975f5c5SAndroid Build Coastguard Worker         uint inputValue = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2343*8975f5c5SAndroid Build Coastguard Worker         imageStore(dstImage, ivec2(gl_LocalInvocationID.xy), uvec4(inputValue));
2344*8975f5c5SAndroid Build Coastguard Worker     }
2345*8975f5c5SAndroid Build Coastguard Worker })";
2346*8975f5c5SAndroid Build Coastguard Worker 
2347*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 4> inputData      = {{250, 200, 150, 100}};
2348*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 4> expectedValues = {{250, 200, 150, 250}};
2349*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 2, 2>(kCSShader, GL_R32UI, GL_UNSIGNED_INT, inputData,
2350*8975f5c5SAndroid Build Coastguard Worker                                       expectedValues);
2351*8975f5c5SAndroid Build Coastguard Worker }
2352*8975f5c5SAndroid Build Coastguard Worker 
2353*8975f5c5SAndroid Build Coastguard Worker // Verify shared non-struct array variables can work correctly.
TEST_P(ComputeShaderTest,NonStructArrayAsSharedVariable)2354*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, NonStructArrayAsSharedVariable)
2355*8975f5c5SAndroid Build Coastguard Worker {
2356*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2357*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2358*8975f5c5SAndroid Build Coastguard Worker 
2359*8975f5c5SAndroid Build Coastguard Worker     const char kCSShader[] = R"(#version 310 es
2360*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 2, local_size_y = 2, local_size_z = 1) in;
2361*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
2362*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
2363*8975f5c5SAndroid Build Coastguard Worker shared uint sharedData[2][2];
2364*8975f5c5SAndroid Build Coastguard Worker void main()
2365*8975f5c5SAndroid Build Coastguard Worker {
2366*8975f5c5SAndroid Build Coastguard Worker     uint inputData = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2367*8975f5c5SAndroid Build Coastguard Worker     sharedData[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = inputData;
2368*8975f5c5SAndroid Build Coastguard Worker     groupMemoryBarrier();
2369*8975f5c5SAndroid Build Coastguard Worker     barrier();
2370*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
2371*8975f5c5SAndroid Build Coastguard Worker                 uvec4(sharedData[gl_LocalInvocationID.y][gl_LocalInvocationID.x]));
2372*8975f5c5SAndroid Build Coastguard Worker })";
2373*8975f5c5SAndroid Build Coastguard Worker 
2374*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 4> inputData      = {{250, 200, 150, 100}};
2375*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 4> expectedValues = {{250, 150, 200, 100}};
2376*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 2, 2>(kCSShader, GL_R32UI, GL_UNSIGNED_INT, inputData,
2377*8975f5c5SAndroid Build Coastguard Worker                                       expectedValues);
2378*8975f5c5SAndroid Build Coastguard Worker }
2379*8975f5c5SAndroid Build Coastguard Worker 
2380*8975f5c5SAndroid Build Coastguard Worker // Verify shared struct array variables work correctly.
TEST_P(ComputeShaderTest,StructArrayAsSharedVariable)2381*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, StructArrayAsSharedVariable)
2382*8975f5c5SAndroid Build Coastguard Worker {
2383*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2384*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2385*8975f5c5SAndroid Build Coastguard Worker 
2386*8975f5c5SAndroid Build Coastguard Worker     const char kCSShader[] = R"(#version 310 es
2387*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 2, local_size_y = 2, local_size_z = 1) in;
2388*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
2389*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
2390*8975f5c5SAndroid Build Coastguard Worker struct SharedStruct
2391*8975f5c5SAndroid Build Coastguard Worker {
2392*8975f5c5SAndroid Build Coastguard Worker     uint data;
2393*8975f5c5SAndroid Build Coastguard Worker };
2394*8975f5c5SAndroid Build Coastguard Worker shared SharedStruct sharedData[2][2];
2395*8975f5c5SAndroid Build Coastguard Worker void main()
2396*8975f5c5SAndroid Build Coastguard Worker {
2397*8975f5c5SAndroid Build Coastguard Worker     uint inputData = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2398*8975f5c5SAndroid Build Coastguard Worker     sharedData[gl_LocalInvocationID.x][gl_LocalInvocationID.y].data = inputData;
2399*8975f5c5SAndroid Build Coastguard Worker     groupMemoryBarrier();
2400*8975f5c5SAndroid Build Coastguard Worker     barrier();
2401*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
2402*8975f5c5SAndroid Build Coastguard Worker                 uvec4(sharedData[gl_LocalInvocationID.y][gl_LocalInvocationID.x].data));
2403*8975f5c5SAndroid Build Coastguard Worker })";
2404*8975f5c5SAndroid Build Coastguard Worker 
2405*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 4> inputData      = {{250, 200, 150, 100}};
2406*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 4> expectedValues = {{250, 150, 200, 100}};
2407*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 2, 2>(kCSShader, GL_R32UI, GL_UNSIGNED_INT, inputData,
2408*8975f5c5SAndroid Build Coastguard Worker                                       expectedValues);
2409*8975f5c5SAndroid Build Coastguard Worker }
2410*8975f5c5SAndroid Build Coastguard Worker 
2411*8975f5c5SAndroid Build Coastguard Worker // Verify using atomic functions without return value can work correctly.
TEST_P(ComputeShaderTest,AtomicFunctionsNoReturnValue)2412*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AtomicFunctionsNoReturnValue)
2413*8975f5c5SAndroid Build Coastguard Worker {
2414*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2415*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2416*8975f5c5SAndroid Build Coastguard Worker 
2417*8975f5c5SAndroid Build Coastguard Worker     // Fails to link on Android.  http://anglebug.com/42262519
2418*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAndroid());
2419*8975f5c5SAndroid Build Coastguard Worker 
2420*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
2421*8975f5c5SAndroid Build Coastguard Worker 
2422*8975f5c5SAndroid Build Coastguard Worker     const char kCSShader[] = R"(#version 310 es
2423*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 8, local_size_y = 1, local_size_z = 1) in;
2424*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
2425*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
2426*8975f5c5SAndroid Build Coastguard Worker 
2427*8975f5c5SAndroid Build Coastguard Worker const uint kSumIndex = 0u;
2428*8975f5c5SAndroid Build Coastguard Worker const uint kMinIndex = 1u;
2429*8975f5c5SAndroid Build Coastguard Worker const uint kMaxIndex = 2u;
2430*8975f5c5SAndroid Build Coastguard Worker const uint kOrIndex = 3u;
2431*8975f5c5SAndroid Build Coastguard Worker const uint kAndIndex = 4u;
2432*8975f5c5SAndroid Build Coastguard Worker const uint kXorIndex = 5u;
2433*8975f5c5SAndroid Build Coastguard Worker const uint kExchangeIndex = 6u;
2434*8975f5c5SAndroid Build Coastguard Worker const uint kCompSwapIndex = 7u;
2435*8975f5c5SAndroid Build Coastguard Worker 
2436*8975f5c5SAndroid Build Coastguard Worker shared highp uint results[8];
2437*8975f5c5SAndroid Build Coastguard Worker 
2438*8975f5c5SAndroid Build Coastguard Worker void main()
2439*8975f5c5SAndroid Build Coastguard Worker {
2440*8975f5c5SAndroid Build Coastguard Worker     if (gl_LocalInvocationID.x == kMinIndex || gl_LocalInvocationID.x == kAndIndex)
2441*8975f5c5SAndroid Build Coastguard Worker     {
2442*8975f5c5SAndroid Build Coastguard Worker         results[gl_LocalInvocationID.x] = 0xFFFFu;
2443*8975f5c5SAndroid Build Coastguard Worker     }
2444*8975f5c5SAndroid Build Coastguard Worker     else if (gl_LocalInvocationID.x == kCompSwapIndex)
2445*8975f5c5SAndroid Build Coastguard Worker     {
2446*8975f5c5SAndroid Build Coastguard Worker         results[gl_LocalInvocationID.x] = 1u;
2447*8975f5c5SAndroid Build Coastguard Worker     }
2448*8975f5c5SAndroid Build Coastguard Worker     else
2449*8975f5c5SAndroid Build Coastguard Worker     {
2450*8975f5c5SAndroid Build Coastguard Worker         results[gl_LocalInvocationID.x] = 0u;
2451*8975f5c5SAndroid Build Coastguard Worker     }
2452*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2453*8975f5c5SAndroid Build Coastguard Worker     barrier();
2454*8975f5c5SAndroid Build Coastguard Worker 
2455*8975f5c5SAndroid Build Coastguard Worker     uint value = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2456*8975f5c5SAndroid Build Coastguard Worker     atomicAdd(results[kSumIndex], value);
2457*8975f5c5SAndroid Build Coastguard Worker     atomicMin(results[kMinIndex], value);
2458*8975f5c5SAndroid Build Coastguard Worker     atomicMax(results[kMaxIndex], value);
2459*8975f5c5SAndroid Build Coastguard Worker     atomicOr(results[kOrIndex], value);
2460*8975f5c5SAndroid Build Coastguard Worker     atomicAnd(results[kAndIndex], value);
2461*8975f5c5SAndroid Build Coastguard Worker     atomicXor(results[kXorIndex], value);
2462*8975f5c5SAndroid Build Coastguard Worker     atomicExchange(results[kExchangeIndex], value);
2463*8975f5c5SAndroid Build Coastguard Worker     atomicCompSwap(results[kCompSwapIndex], value, 256u);
2464*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2465*8975f5c5SAndroid Build Coastguard Worker     barrier();
2466*8975f5c5SAndroid Build Coastguard Worker 
2467*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
2468*8975f5c5SAndroid Build Coastguard Worker                 uvec4(results[gl_LocalInvocationID.x]));
2469*8975f5c5SAndroid Build Coastguard Worker })";
2470*8975f5c5SAndroid Build Coastguard Worker 
2471*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 8> inputData      = {{1, 2, 4, 8, 16, 32, 64, 128}};
2472*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 8> expectedValues = {{255, 1, 128, 255, 0, 255, 128, 256}};
2473*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 8, 1>(kCSShader, GL_R32UI, GL_UNSIGNED_INT, inputData,
2474*8975f5c5SAndroid Build Coastguard Worker                                       expectedValues);
2475*8975f5c5SAndroid Build Coastguard Worker }
2476*8975f5c5SAndroid Build Coastguard Worker 
2477*8975f5c5SAndroid Build Coastguard Worker // Verify using atomic functions in a non-initializer single assignment can work correctly.
TEST_P(ComputeShaderTest,AtomicFunctionsInNonInitializerSingleAssignment)2478*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AtomicFunctionsInNonInitializerSingleAssignment)
2479*8975f5c5SAndroid Build Coastguard Worker {
2480*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2481*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2482*8975f5c5SAndroid Build Coastguard Worker 
2483*8975f5c5SAndroid Build Coastguard Worker     const char kCSShader[] = R"(#version 310 es
2484*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 9, local_size_y = 1, local_size_z = 1) in;
2485*8975f5c5SAndroid Build Coastguard Worker layout (r32i, binding = 0) readonly uniform highp iimage2D srcImage;
2486*8975f5c5SAndroid Build Coastguard Worker layout (r32i, binding = 1) writeonly uniform highp iimage2D dstImage;
2487*8975f5c5SAndroid Build Coastguard Worker 
2488*8975f5c5SAndroid Build Coastguard Worker shared highp int sharedVariable;
2489*8975f5c5SAndroid Build Coastguard Worker 
2490*8975f5c5SAndroid Build Coastguard Worker shared highp int inputData[9];
2491*8975f5c5SAndroid Build Coastguard Worker shared highp int outputData[9];
2492*8975f5c5SAndroid Build Coastguard Worker 
2493*8975f5c5SAndroid Build Coastguard Worker void main()
2494*8975f5c5SAndroid Build Coastguard Worker {
2495*8975f5c5SAndroid Build Coastguard Worker     int inputValue = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2496*8975f5c5SAndroid Build Coastguard Worker     inputData[gl_LocalInvocationID.x] = inputValue;
2497*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2498*8975f5c5SAndroid Build Coastguard Worker     barrier();
2499*8975f5c5SAndroid Build Coastguard Worker 
2500*8975f5c5SAndroid Build Coastguard Worker     if (gl_LocalInvocationID.x == 0u)
2501*8975f5c5SAndroid Build Coastguard Worker     {
2502*8975f5c5SAndroid Build Coastguard Worker         sharedVariable = 0;
2503*8975f5c5SAndroid Build Coastguard Worker 
2504*8975f5c5SAndroid Build Coastguard Worker         outputData[0] = atomicAdd(sharedVariable, inputData[0]);
2505*8975f5c5SAndroid Build Coastguard Worker         outputData[1] = atomicMin(sharedVariable, inputData[1]);
2506*8975f5c5SAndroid Build Coastguard Worker         outputData[2] = atomicMax(sharedVariable, inputData[2]);
2507*8975f5c5SAndroid Build Coastguard Worker         outputData[3] = atomicAnd(sharedVariable, inputData[3]);
2508*8975f5c5SAndroid Build Coastguard Worker         outputData[4] = atomicOr(sharedVariable, inputData[4]);
2509*8975f5c5SAndroid Build Coastguard Worker         outputData[5] = atomicXor(sharedVariable, inputData[5]);
2510*8975f5c5SAndroid Build Coastguard Worker         outputData[6] = atomicExchange(sharedVariable, inputData[6]);
2511*8975f5c5SAndroid Build Coastguard Worker         outputData[7] = atomicCompSwap(sharedVariable, 64, inputData[7]);
2512*8975f5c5SAndroid Build Coastguard Worker         outputData[8] = atomicAdd(sharedVariable, inputData[8]);
2513*8975f5c5SAndroid Build Coastguard Worker     }
2514*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2515*8975f5c5SAndroid Build Coastguard Worker     barrier();
2516*8975f5c5SAndroid Build Coastguard Worker 
2517*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
2518*8975f5c5SAndroid Build Coastguard Worker                 ivec4(outputData[gl_LocalInvocationID.x]));
2519*8975f5c5SAndroid Build Coastguard Worker })";
2520*8975f5c5SAndroid Build Coastguard Worker 
2521*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLint, 9> inputData      = {{1, 2, 4, 8, 16, 32, 64, 128, 1}};
2522*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLint, 9> expectedValues = {{0, 1, 1, 4, 0, 16, 48, 64, 128}};
2523*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLint, 9, 1>(kCSShader, GL_R32I, GL_INT, inputData, expectedValues);
2524*8975f5c5SAndroid Build Coastguard Worker }
2525*8975f5c5SAndroid Build Coastguard Worker 
2526*8975f5c5SAndroid Build Coastguard Worker // Verify using atomic functions in an initializers and using unsigned int works correctly.
TEST_P(ComputeShaderTest,AtomicFunctionsInitializerWithUnsigned)2527*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AtomicFunctionsInitializerWithUnsigned)
2528*8975f5c5SAndroid Build Coastguard Worker {
2529*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2530*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2531*8975f5c5SAndroid Build Coastguard Worker 
2532*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCShader[] = R"(#version 310 es
2533*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 9, local_size_y = 1, local_size_z = 1) in;
2534*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
2535*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
2536*8975f5c5SAndroid Build Coastguard Worker 
2537*8975f5c5SAndroid Build Coastguard Worker shared highp uint sharedVariable;
2538*8975f5c5SAndroid Build Coastguard Worker 
2539*8975f5c5SAndroid Build Coastguard Worker shared highp uint inputData[9];
2540*8975f5c5SAndroid Build Coastguard Worker shared highp uint outputData[9];
2541*8975f5c5SAndroid Build Coastguard Worker 
2542*8975f5c5SAndroid Build Coastguard Worker void main()
2543*8975f5c5SAndroid Build Coastguard Worker {
2544*8975f5c5SAndroid Build Coastguard Worker     uint inputValue = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2545*8975f5c5SAndroid Build Coastguard Worker     inputData[gl_LocalInvocationID.x] = inputValue;
2546*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2547*8975f5c5SAndroid Build Coastguard Worker     barrier();
2548*8975f5c5SAndroid Build Coastguard Worker 
2549*8975f5c5SAndroid Build Coastguard Worker     if (gl_LocalInvocationID.x == 0u)
2550*8975f5c5SAndroid Build Coastguard Worker     {
2551*8975f5c5SAndroid Build Coastguard Worker         sharedVariable = 0u;
2552*8975f5c5SAndroid Build Coastguard Worker 
2553*8975f5c5SAndroid Build Coastguard Worker         uint addValue = atomicAdd(sharedVariable, inputData[0]);
2554*8975f5c5SAndroid Build Coastguard Worker         outputData[0] = addValue;
2555*8975f5c5SAndroid Build Coastguard Worker         uint minValue = atomicMin(sharedVariable, inputData[1]);
2556*8975f5c5SAndroid Build Coastguard Worker         outputData[1] = minValue;
2557*8975f5c5SAndroid Build Coastguard Worker         uint maxValue = atomicMax(sharedVariable, inputData[2]);
2558*8975f5c5SAndroid Build Coastguard Worker         outputData[2] = maxValue;
2559*8975f5c5SAndroid Build Coastguard Worker         uint andValue = atomicAnd(sharedVariable, inputData[3]);
2560*8975f5c5SAndroid Build Coastguard Worker         outputData[3] = andValue;
2561*8975f5c5SAndroid Build Coastguard Worker         uint orValue = atomicOr(sharedVariable, inputData[4]);
2562*8975f5c5SAndroid Build Coastguard Worker         outputData[4] = orValue;
2563*8975f5c5SAndroid Build Coastguard Worker         uint xorValue = atomicXor(sharedVariable, inputData[5]);
2564*8975f5c5SAndroid Build Coastguard Worker         outputData[5] = xorValue;
2565*8975f5c5SAndroid Build Coastguard Worker         uint exchangeValue = atomicExchange(sharedVariable, inputData[6]);
2566*8975f5c5SAndroid Build Coastguard Worker         outputData[6] = exchangeValue;
2567*8975f5c5SAndroid Build Coastguard Worker         uint compSwapValue = atomicCompSwap(sharedVariable, 64u, inputData[7]);
2568*8975f5c5SAndroid Build Coastguard Worker         outputData[7] = compSwapValue;
2569*8975f5c5SAndroid Build Coastguard Worker         uint sharedVariable = atomicAdd(sharedVariable, inputData[8]);
2570*8975f5c5SAndroid Build Coastguard Worker         outputData[8] = sharedVariable;
2571*8975f5c5SAndroid Build Coastguard Worker 
2572*8975f5c5SAndroid Build Coastguard Worker     }
2573*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2574*8975f5c5SAndroid Build Coastguard Worker     barrier();
2575*8975f5c5SAndroid Build Coastguard Worker 
2576*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
2577*8975f5c5SAndroid Build Coastguard Worker                 uvec4(outputData[gl_LocalInvocationID.x]));
2578*8975f5c5SAndroid Build Coastguard Worker })";
2579*8975f5c5SAndroid Build Coastguard Worker 
2580*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLuint, 9> kInputData      = {{1, 2, 4, 8, 16, 32, 64, 128, 1}};
2581*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLuint, 9> kExpectedValues = {{0, 1, 1, 4, 0, 16, 48, 64, 128}};
2582*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 9, 1>(kCShader, GL_R32UI, GL_UNSIGNED_INT, kInputData,
2583*8975f5c5SAndroid Build Coastguard Worker                                       kExpectedValues);
2584*8975f5c5SAndroid Build Coastguard Worker }
2585*8975f5c5SAndroid Build Coastguard Worker 
2586*8975f5c5SAndroid Build Coastguard Worker // Verify using atomic functions inside expressions as unsigned int.
TEST_P(ComputeShaderTest,AtomicFunctionsReturnWithUnsigned)2587*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AtomicFunctionsReturnWithUnsigned)
2588*8975f5c5SAndroid Build Coastguard Worker {
2589*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2590*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2591*8975f5c5SAndroid Build Coastguard Worker 
2592*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCShader[] = R"(#version 310 es
2593*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 9, local_size_y = 1, local_size_z = 1) in;
2594*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
2595*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
2596*8975f5c5SAndroid Build Coastguard Worker 
2597*8975f5c5SAndroid Build Coastguard Worker shared highp uint sharedVariable;
2598*8975f5c5SAndroid Build Coastguard Worker 
2599*8975f5c5SAndroid Build Coastguard Worker shared highp uint inputData[9];
2600*8975f5c5SAndroid Build Coastguard Worker shared highp uint outputData[9];
2601*8975f5c5SAndroid Build Coastguard Worker 
2602*8975f5c5SAndroid Build Coastguard Worker void main()
2603*8975f5c5SAndroid Build Coastguard Worker {
2604*8975f5c5SAndroid Build Coastguard Worker     uint inputValue = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2605*8975f5c5SAndroid Build Coastguard Worker     inputData[gl_LocalInvocationID.x] = inputValue;
2606*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2607*8975f5c5SAndroid Build Coastguard Worker     barrier();
2608*8975f5c5SAndroid Build Coastguard Worker 
2609*8975f5c5SAndroid Build Coastguard Worker     if (gl_LocalInvocationID.x == 0u)
2610*8975f5c5SAndroid Build Coastguard Worker     {
2611*8975f5c5SAndroid Build Coastguard Worker         sharedVariable = 0u;
2612*8975f5c5SAndroid Build Coastguard Worker 
2613*8975f5c5SAndroid Build Coastguard Worker         outputData[0] = 1u + atomicAdd(sharedVariable, inputData[0]);
2614*8975f5c5SAndroid Build Coastguard Worker         outputData[1] = 1u + atomicMin(sharedVariable, inputData[1]);
2615*8975f5c5SAndroid Build Coastguard Worker         outputData[2] = 1u + atomicMax(sharedVariable, inputData[2]);
2616*8975f5c5SAndroid Build Coastguard Worker         outputData[3] = 1u + atomicAnd(sharedVariable, inputData[3]);
2617*8975f5c5SAndroid Build Coastguard Worker         outputData[4] = 1u + atomicOr(sharedVariable, inputData[4]);
2618*8975f5c5SAndroid Build Coastguard Worker         outputData[5] = 1u + atomicXor(sharedVariable, inputData[5]);
2619*8975f5c5SAndroid Build Coastguard Worker         outputData[6] = 1u + atomicExchange(sharedVariable, inputData[6]);
2620*8975f5c5SAndroid Build Coastguard Worker         outputData[7] = 1u + atomicCompSwap(sharedVariable, 64u, inputData[7]);
2621*8975f5c5SAndroid Build Coastguard Worker         outputData[8] = 1u + atomicAdd(sharedVariable, inputData[8]);
2622*8975f5c5SAndroid Build Coastguard Worker     }
2623*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2624*8975f5c5SAndroid Build Coastguard Worker     barrier();
2625*8975f5c5SAndroid Build Coastguard Worker 
2626*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
2627*8975f5c5SAndroid Build Coastguard Worker                 uvec4(outputData[gl_LocalInvocationID.x]));
2628*8975f5c5SAndroid Build Coastguard Worker })";
2629*8975f5c5SAndroid Build Coastguard Worker 
2630*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLuint, 9> kInputData      = {{1, 2, 4, 8, 16, 32, 64, 128, 1}};
2631*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLuint, 9> kExpectedValues = {{1, 2, 2, 5, 1, 17, 49, 65, 129}};
2632*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 9, 1>(kCShader, GL_R32UI, GL_UNSIGNED_INT, kInputData,
2633*8975f5c5SAndroid Build Coastguard Worker                                       kExpectedValues);
2634*8975f5c5SAndroid Build Coastguard Worker }
2635*8975f5c5SAndroid Build Coastguard Worker 
2636*8975f5c5SAndroid Build Coastguard Worker // Verify using nested atomic functions in expressions.
TEST_P(ComputeShaderTest,AtomicFunctionsReturnWithMultipleTypes)2637*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AtomicFunctionsReturnWithMultipleTypes)
2638*8975f5c5SAndroid Build Coastguard Worker {
2639*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2640*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2641*8975f5c5SAndroid Build Coastguard Worker 
2642*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCShader[] = R"(#version 310 es
2643*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
2644*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
2645*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
2646*8975f5c5SAndroid Build Coastguard Worker 
2647*8975f5c5SAndroid Build Coastguard Worker shared highp uint sharedVariable;
2648*8975f5c5SAndroid Build Coastguard Worker shared highp int  indexVariable;
2649*8975f5c5SAndroid Build Coastguard Worker 
2650*8975f5c5SAndroid Build Coastguard Worker shared highp uint inputData[4];
2651*8975f5c5SAndroid Build Coastguard Worker shared highp uint outputData[4];
2652*8975f5c5SAndroid Build Coastguard Worker 
2653*8975f5c5SAndroid Build Coastguard Worker void main()
2654*8975f5c5SAndroid Build Coastguard Worker {
2655*8975f5c5SAndroid Build Coastguard Worker     uint inputValue = imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)).x;
2656*8975f5c5SAndroid Build Coastguard Worker     inputData[gl_LocalInvocationID.x] = inputValue;
2657*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2658*8975f5c5SAndroid Build Coastguard Worker     barrier();
2659*8975f5c5SAndroid Build Coastguard Worker 
2660*8975f5c5SAndroid Build Coastguard Worker     if (gl_LocalInvocationID.x == 0u)
2661*8975f5c5SAndroid Build Coastguard Worker     {
2662*8975f5c5SAndroid Build Coastguard Worker         sharedVariable = 0u;
2663*8975f5c5SAndroid Build Coastguard Worker         indexVariable = 2;
2664*8975f5c5SAndroid Build Coastguard Worker 
2665*8975f5c5SAndroid Build Coastguard Worker         outputData[0] = 1u + atomicAdd(sharedVariable, inputData[atomicAdd(indexVariable, -1)]);
2666*8975f5c5SAndroid Build Coastguard Worker         outputData[1] = 1u + atomicAdd(sharedVariable, inputData[atomicAdd(indexVariable, -1)]);
2667*8975f5c5SAndroid Build Coastguard Worker         outputData[2] = 1u + atomicAdd(sharedVariable, inputData[atomicAdd(indexVariable, -1)]);
2668*8975f5c5SAndroid Build Coastguard Worker         outputData[3] = atomicAdd(sharedVariable, 0u);
2669*8975f5c5SAndroid Build Coastguard Worker 
2670*8975f5c5SAndroid Build Coastguard Worker     }
2671*8975f5c5SAndroid Build Coastguard Worker     memoryBarrierShared();
2672*8975f5c5SAndroid Build Coastguard Worker     barrier();
2673*8975f5c5SAndroid Build Coastguard Worker 
2674*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
2675*8975f5c5SAndroid Build Coastguard Worker                 uvec4(outputData[gl_LocalInvocationID.x]));
2676*8975f5c5SAndroid Build Coastguard Worker })";
2677*8975f5c5SAndroid Build Coastguard Worker 
2678*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLuint, 4> kInputData      = {{1, 2, 3, 0}};
2679*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<GLuint, 4> kExpectedValues = {{1, 4, 6, 6}};
2680*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 4, 1>(kCShader, GL_R32UI, GL_UNSIGNED_INT, kInputData,
2681*8975f5c5SAndroid Build Coastguard Worker                                       kExpectedValues);
2682*8975f5c5SAndroid Build Coastguard Worker }
2683*8975f5c5SAndroid Build Coastguard Worker 
2684*8975f5c5SAndroid Build Coastguard Worker // Basic uniform buffer functionality.
TEST_P(ComputeShaderTest,UniformBuffer)2685*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, UniformBuffer)
2686*8975f5c5SAndroid Build Coastguard Worker {
2687*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2688*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2689*8975f5c5SAndroid Build Coastguard Worker 
2690*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
2691*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buffer;
2692*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
2693*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
2694*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2695*8975f5c5SAndroid Build Coastguard Worker uniform uni
2696*8975f5c5SAndroid Build Coastguard Worker {
2697*8975f5c5SAndroid Build Coastguard Worker     uvec4 value;
2698*8975f5c5SAndroid Build Coastguard Worker };
2699*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui, binding = 0) writeonly uniform highp uimage2D uImage;
2700*8975f5c5SAndroid Build Coastguard Worker void main()
2701*8975f5c5SAndroid Build Coastguard Worker {
2702*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage, ivec2(gl_LocalInvocationID.xy), value);
2703*8975f5c5SAndroid Build Coastguard Worker })";
2704*8975f5c5SAndroid Build Coastguard Worker 
2705*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1;
2706*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[4] = {56, 57, 58, 59};
2707*8975f5c5SAndroid Build Coastguard Worker 
2708*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
2709*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, kWidth, kHeight);
2710*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
2711*8975f5c5SAndroid Build Coastguard Worker                     kInputValues);
2712*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2713*8975f5c5SAndroid Build Coastguard Worker 
2714*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
2715*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
2716*8975f5c5SAndroid Build Coastguard Worker 
2717*8975f5c5SAndroid Build Coastguard Worker     GLint uniformBufferIndex = glGetUniformBlockIndex(program, "uni");
2718*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(uniformBufferIndex, -1);
2719*8975f5c5SAndroid Build Coastguard Worker     GLuint data[4] = {201, 202, 203, 204};
2720*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_UNIFORM_BUFFER, buffer);
2721*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_UNIFORM_BUFFER, sizeof(GLuint) * 4, data, GL_STATIC_DRAW);
2722*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
2723*8975f5c5SAndroid Build Coastguard Worker     glUniformBlockBinding(program, uniformBufferIndex, 0);
2724*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2725*8975f5c5SAndroid Build Coastguard Worker 
2726*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
2727*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2728*8975f5c5SAndroid Build Coastguard Worker 
2729*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
2730*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2731*8975f5c5SAndroid Build Coastguard Worker 
2732*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2733*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight * 4];
2734*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
2735*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2736*8975f5c5SAndroid Build Coastguard Worker 
2737*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2738*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2739*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RGBA_INTEGER, GL_UNSIGNED_INT, outputValues);
2740*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2741*8975f5c5SAndroid Build Coastguard Worker 
2742*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight * 4; i++)
2743*8975f5c5SAndroid Build Coastguard Worker     {
2744*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(data[i], outputValues[i]);
2745*8975f5c5SAndroid Build Coastguard Worker     }
2746*8975f5c5SAndroid Build Coastguard Worker }
2747*8975f5c5SAndroid Build Coastguard Worker 
2748*8975f5c5SAndroid Build Coastguard Worker // Test that storing data to image and then loading the same image data works correctly.
TEST_P(ComputeShaderTest,StoreImageThenLoad)2749*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, StoreImageThenLoad)
2750*8975f5c5SAndroid Build Coastguard Worker {
2751*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2752*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2753*8975f5c5SAndroid Build Coastguard Worker 
2754*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2755*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2756*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
2757*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
2758*8975f5c5SAndroid Build Coastguard Worker void main()
2759*8975f5c5SAndroid Build Coastguard Worker {
2760*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
2761*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
2762*8975f5c5SAndroid Build Coastguard Worker })";
2763*8975f5c5SAndroid Build Coastguard Worker 
2764*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[3][1] = {{300}, {200}, {100}};
2765*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[3];
2766*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
2767*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 1, 1);
2768*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, kInputValues[0]);
2769*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2770*8975f5c5SAndroid Build Coastguard Worker 
2771*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
2772*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 1, 1);
2773*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, kInputValues[1]);
2774*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2775*8975f5c5SAndroid Build Coastguard Worker 
2776*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[2]);
2777*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 1, 1);
2778*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, kInputValues[2]);
2779*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2780*8975f5c5SAndroid Build Coastguard Worker 
2781*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2782*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
2783*8975f5c5SAndroid Build Coastguard Worker 
2784*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
2785*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
2786*8975f5c5SAndroid Build Coastguard Worker 
2787*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
2788*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2789*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2790*8975f5c5SAndroid Build Coastguard Worker 
2791*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[1], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
2792*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[2], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
2793*8975f5c5SAndroid Build Coastguard Worker 
2794*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
2795*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2796*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2797*8975f5c5SAndroid Build Coastguard Worker 
2798*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValue;
2799*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
2800*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2801*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[2], 0);
2802*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &outputValue);
2803*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2804*8975f5c5SAndroid Build Coastguard Worker 
2805*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(300u, outputValue);
2806*8975f5c5SAndroid Build Coastguard Worker }
2807*8975f5c5SAndroid Build Coastguard Worker 
2808*8975f5c5SAndroid Build Coastguard Worker // Test that loading image data and then storing data to the same image works correctly.
TEST_P(ComputeShaderTest,LoadImageThenStore)2809*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, LoadImageThenStore)
2810*8975f5c5SAndroid Build Coastguard Worker {
2811*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
2812*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2813*8975f5c5SAndroid Build Coastguard Worker 
2814*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2815*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2816*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
2817*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
2818*8975f5c5SAndroid Build Coastguard Worker void main()
2819*8975f5c5SAndroid Build Coastguard Worker {
2820*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
2821*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
2822*8975f5c5SAndroid Build Coastguard Worker })";
2823*8975f5c5SAndroid Build Coastguard Worker 
2824*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[3][1] = {{300}, {200}, {100}};
2825*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[3];
2826*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
2827*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 1, 1);
2828*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, kInputValues[0]);
2829*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2830*8975f5c5SAndroid Build Coastguard Worker 
2831*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
2832*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 1, 1);
2833*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, kInputValues[1]);
2834*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2835*8975f5c5SAndroid Build Coastguard Worker 
2836*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[2]);
2837*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 1, 1);
2838*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, kInputValues[2]);
2839*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2840*8975f5c5SAndroid Build Coastguard Worker 
2841*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2842*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
2843*8975f5c5SAndroid Build Coastguard Worker 
2844*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
2845*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
2846*8975f5c5SAndroid Build Coastguard Worker 
2847*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
2848*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2849*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2850*8975f5c5SAndroid Build Coastguard Worker 
2851*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[2], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
2852*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
2853*8975f5c5SAndroid Build Coastguard Worker 
2854*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
2855*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2856*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2857*8975f5c5SAndroid Build Coastguard Worker 
2858*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValue;
2859*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
2860*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2861*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[0], 0);
2862*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &outputValue);
2863*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2864*8975f5c5SAndroid Build Coastguard Worker 
2865*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(100u, outputValue);
2866*8975f5c5SAndroid Build Coastguard Worker }
2867*8975f5c5SAndroid Build Coastguard Worker 
2868*8975f5c5SAndroid Build Coastguard Worker // Test that the length of a struct buffer variable is supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksStructLength)2869*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksStructLength)
2870*8975f5c5SAndroid Build Coastguard Worker {
2871*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2872*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
2873*8975f5c5SAndroid Build Coastguard Worker 
2874*8975f5c5SAndroid Build Coastguard Worker struct Particle
2875*8975f5c5SAndroid Build Coastguard Worker {
2876*8975f5c5SAndroid Build Coastguard Worker     int len;
2877*8975f5c5SAndroid Build Coastguard Worker };
2878*8975f5c5SAndroid Build Coastguard Worker 
2879*8975f5c5SAndroid Build Coastguard Worker layout(binding = 0, std430) readonly buffer Buf1
2880*8975f5c5SAndroid Build Coastguard Worker {
2881*8975f5c5SAndroid Build Coastguard Worker     Particle particlesRead[];
2882*8975f5c5SAndroid Build Coastguard Worker };
2883*8975f5c5SAndroid Build Coastguard Worker 
2884*8975f5c5SAndroid Build Coastguard Worker layout(binding = 1, std430) buffer Buf2
2885*8975f5c5SAndroid Build Coastguard Worker {
2886*8975f5c5SAndroid Build Coastguard Worker     Particle particlesWrite[];
2887*8975f5c5SAndroid Build Coastguard Worker };
2888*8975f5c5SAndroid Build Coastguard Worker 
2889*8975f5c5SAndroid Build Coastguard Worker void main()
2890*8975f5c5SAndroid Build Coastguard Worker {
2891*8975f5c5SAndroid Build Coastguard Worker     int index = int(gl_GlobalInvocationID.x);
2892*8975f5c5SAndroid Build Coastguard Worker     particlesWrite[index].len = particlesRead.length();
2893*8975f5c5SAndroid Build Coastguard Worker })";
2894*8975f5c5SAndroid Build Coastguard Worker 
2895*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2896*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2897*8975f5c5SAndroid Build Coastguard Worker }
2898*8975f5c5SAndroid Build Coastguard Worker 
2899*8975f5c5SAndroid Build Coastguard Worker // Test that scalar buffer variables are supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksScalar)2900*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksScalar)
2901*8975f5c5SAndroid Build Coastguard Worker {
2902*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2903*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
2904*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
2905*8975f5c5SAndroid Build Coastguard Worker     uvec3 uv;
2906*8975f5c5SAndroid Build Coastguard Worker     float f;
2907*8975f5c5SAndroid Build Coastguard Worker } instanceA;
2908*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
2909*8975f5c5SAndroid Build Coastguard Worker     vec2 v;
2910*8975f5c5SAndroid Build Coastguard Worker     uint u[3];
2911*8975f5c5SAndroid Build Coastguard Worker     float f;
2912*8975f5c5SAndroid Build Coastguard Worker };
2913*8975f5c5SAndroid Build Coastguard Worker void main()
2914*8975f5c5SAndroid Build Coastguard Worker {
2915*8975f5c5SAndroid Build Coastguard Worker     f = instanceA.f;
2916*8975f5c5SAndroid Build Coastguard Worker })";
2917*8975f5c5SAndroid Build Coastguard Worker 
2918*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2919*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2920*8975f5c5SAndroid Build Coastguard Worker }
2921*8975f5c5SAndroid Build Coastguard Worker 
2922*8975f5c5SAndroid Build Coastguard Worker // Test that vector buffer variables are supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksVector)2923*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksVector)
2924*8975f5c5SAndroid Build Coastguard Worker {
2925*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2926*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
2927*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
2928*8975f5c5SAndroid Build Coastguard Worker     vec2 f;
2929*8975f5c5SAndroid Build Coastguard Worker } instanceA;
2930*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
2931*8975f5c5SAndroid Build Coastguard Worker     vec3 f;
2932*8975f5c5SAndroid Build Coastguard Worker };
2933*8975f5c5SAndroid Build Coastguard Worker void main()
2934*8975f5c5SAndroid Build Coastguard Worker {
2935*8975f5c5SAndroid Build Coastguard Worker     f[1] = instanceA.f[0];
2936*8975f5c5SAndroid Build Coastguard Worker })";
2937*8975f5c5SAndroid Build Coastguard Worker 
2938*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2939*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2940*8975f5c5SAndroid Build Coastguard Worker }
2941*8975f5c5SAndroid Build Coastguard Worker 
2942*8975f5c5SAndroid Build Coastguard Worker // Test that matrix buffer variables are supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksMatrix)2943*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksMatrix)
2944*8975f5c5SAndroid Build Coastguard Worker {
2945*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2946*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
2947*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
2948*8975f5c5SAndroid Build Coastguard Worker     mat3x4 m;
2949*8975f5c5SAndroid Build Coastguard Worker } instanceA;
2950*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
2951*8975f5c5SAndroid Build Coastguard Worker     mat3x4 m;
2952*8975f5c5SAndroid Build Coastguard Worker };
2953*8975f5c5SAndroid Build Coastguard Worker void main()
2954*8975f5c5SAndroid Build Coastguard Worker {
2955*8975f5c5SAndroid Build Coastguard Worker     m[0][1] = instanceA.m[0][1];
2956*8975f5c5SAndroid Build Coastguard Worker })";
2957*8975f5c5SAndroid Build Coastguard Worker 
2958*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2959*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2960*8975f5c5SAndroid Build Coastguard Worker }
2961*8975f5c5SAndroid Build Coastguard Worker 
2962*8975f5c5SAndroid Build Coastguard Worker // Test that scalar array buffer variables are supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksScalarArray)2963*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksScalarArray)
2964*8975f5c5SAndroid Build Coastguard Worker {
2965*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2966*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
2967*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
2968*8975f5c5SAndroid Build Coastguard Worker     float f[8];
2969*8975f5c5SAndroid Build Coastguard Worker } instanceA;
2970*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
2971*8975f5c5SAndroid Build Coastguard Worker     float f[8];
2972*8975f5c5SAndroid Build Coastguard Worker };
2973*8975f5c5SAndroid Build Coastguard Worker void main()
2974*8975f5c5SAndroid Build Coastguard Worker {
2975*8975f5c5SAndroid Build Coastguard Worker     f[gl_LocalInvocationIndex] = instanceA.f[gl_LocalInvocationIndex];
2976*8975f5c5SAndroid Build Coastguard Worker })";
2977*8975f5c5SAndroid Build Coastguard Worker 
2978*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2979*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
2980*8975f5c5SAndroid Build Coastguard Worker }
2981*8975f5c5SAndroid Build Coastguard Worker 
2982*8975f5c5SAndroid Build Coastguard Worker // Test that vector array buffer variables are supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksVectorArray)2983*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksVectorArray)
2984*8975f5c5SAndroid Build Coastguard Worker {
2985*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
2986*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=4) in;
2987*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
2988*8975f5c5SAndroid Build Coastguard Worker     vec2 v[4];
2989*8975f5c5SAndroid Build Coastguard Worker } instanceA;
2990*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
2991*8975f5c5SAndroid Build Coastguard Worker     vec4 v[4];
2992*8975f5c5SAndroid Build Coastguard Worker };
2993*8975f5c5SAndroid Build Coastguard Worker void main()
2994*8975f5c5SAndroid Build Coastguard Worker {
2995*8975f5c5SAndroid Build Coastguard Worker     v[0][gl_LocalInvocationIndex] = instanceA.v[gl_LocalInvocationIndex][1];
2996*8975f5c5SAndroid Build Coastguard Worker })";
2997*8975f5c5SAndroid Build Coastguard Worker 
2998*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
2999*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3000*8975f5c5SAndroid Build Coastguard Worker }
3001*8975f5c5SAndroid Build Coastguard Worker 
3002*8975f5c5SAndroid Build Coastguard Worker // Test that matrix array buffer variables are supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksMatrixArray)3003*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksMatrixArray)
3004*8975f5c5SAndroid Build Coastguard Worker {
3005*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
3006*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
3007*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
3008*8975f5c5SAndroid Build Coastguard Worker     float v1[5];
3009*8975f5c5SAndroid Build Coastguard Worker     mat4 m[8];
3010*8975f5c5SAndroid Build Coastguard Worker } instanceA;
3011*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
3012*8975f5c5SAndroid Build Coastguard Worker     vec2 v1[3];
3013*8975f5c5SAndroid Build Coastguard Worker     mat4 m[8];
3014*8975f5c5SAndroid Build Coastguard Worker };
3015*8975f5c5SAndroid Build Coastguard Worker void main()
3016*8975f5c5SAndroid Build Coastguard Worker {
3017*8975f5c5SAndroid Build Coastguard Worker     float data = instanceA.m[gl_LocalInvocationIndex][0][0];
3018*8975f5c5SAndroid Build Coastguard Worker     m[gl_LocalInvocationIndex][gl_LocalInvocationIndex][gl_LocalInvocationIndex] = data;
3019*8975f5c5SAndroid Build Coastguard Worker })";
3020*8975f5c5SAndroid Build Coastguard Worker 
3021*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
3022*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3023*8975f5c5SAndroid Build Coastguard Worker }
3024*8975f5c5SAndroid Build Coastguard Worker 
3025*8975f5c5SAndroid Build Coastguard Worker // Test that shader storage blocks only in assignment right is supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksInAssignmentRight)3026*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksInAssignmentRight)
3027*8975f5c5SAndroid Build Coastguard Worker {
3028*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
3029*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
3030*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
3031*8975f5c5SAndroid Build Coastguard Worker     float data[8];
3032*8975f5c5SAndroid Build Coastguard Worker } instanceA;
3033*8975f5c5SAndroid Build Coastguard Worker layout(r32f, binding = 0) writeonly uniform highp image2D imageOut;
3034*8975f5c5SAndroid Build Coastguard Worker 
3035*8975f5c5SAndroid Build Coastguard Worker void main()
3036*8975f5c5SAndroid Build Coastguard Worker {
3037*8975f5c5SAndroid Build Coastguard Worker     float data = 1.0;
3038*8975f5c5SAndroid Build Coastguard Worker     data = instanceA.data[gl_LocalInvocationIndex];
3039*8975f5c5SAndroid Build Coastguard Worker     imageStore(imageOut, ivec2(gl_LocalInvocationID.xy), vec4(data));
3040*8975f5c5SAndroid Build Coastguard Worker })";
3041*8975f5c5SAndroid Build Coastguard Worker 
3042*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
3043*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3044*8975f5c5SAndroid Build Coastguard Worker }
3045*8975f5c5SAndroid Build Coastguard Worker 
3046*8975f5c5SAndroid Build Coastguard Worker // Test that shader storage blocks with unsized array are supported.
TEST_P(ComputeShaderTest,ShaderStorageBlocksWithUnsizedArray)3047*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksWithUnsizedArray)
3048*8975f5c5SAndroid Build Coastguard Worker {
3049*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
3050*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
3051*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
3052*8975f5c5SAndroid Build Coastguard Worker     float v[];
3053*8975f5c5SAndroid Build Coastguard Worker } instanceA;
3054*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockB {
3055*8975f5c5SAndroid Build Coastguard Worker     float v[];
3056*8975f5c5SAndroid Build Coastguard Worker } instanceB[1];
3057*8975f5c5SAndroid Build Coastguard Worker 
3058*8975f5c5SAndroid Build Coastguard Worker void main()
3059*8975f5c5SAndroid Build Coastguard Worker {
3060*8975f5c5SAndroid Build Coastguard Worker     float data = instanceA.v[gl_LocalInvocationIndex];
3061*8975f5c5SAndroid Build Coastguard Worker     instanceB[0].v[gl_LocalInvocationIndex * 2u + 1u] = data;
3062*8975f5c5SAndroid Build Coastguard Worker }
3063*8975f5c5SAndroid Build Coastguard Worker )";
3064*8975f5c5SAndroid Build Coastguard Worker 
3065*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
3066*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3067*8975f5c5SAndroid Build Coastguard Worker }
3068*8975f5c5SAndroid Build Coastguard Worker 
3069*8975f5c5SAndroid Build Coastguard Worker // Test that EOpIndexDirect/EOpIndexIndirect/EOpIndexDirectStruct nodes in ssbo EOpIndexInDirect
3070*8975f5c5SAndroid Build Coastguard Worker // don't need to calculate the offset and should be translated by OutputHLSL directly.
TEST_P(ComputeShaderTest,IndexAndDotOperatorsInSSBOIndexIndirectOperator)3071*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, IndexAndDotOperatorsInSSBOIndexIndirectOperator)
3072*8975f5c5SAndroid Build Coastguard Worker {
3073*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeShaderSource[] = R"(#version 310 es
3074*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
3075*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
3076*8975f5c5SAndroid Build Coastguard Worker     float v[4];
3077*8975f5c5SAndroid Build Coastguard Worker };
3078*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
3079*8975f5c5SAndroid Build Coastguard Worker     float v[4];
3080*8975f5c5SAndroid Build Coastguard Worker } instanceB[1];
3081*8975f5c5SAndroid Build Coastguard Worker struct S
3082*8975f5c5SAndroid Build Coastguard Worker {
3083*8975f5c5SAndroid Build Coastguard Worker     uvec4 index[2];
3084*8975f5c5SAndroid Build Coastguard Worker } s;
3085*8975f5c5SAndroid Build Coastguard Worker void main()
3086*8975f5c5SAndroid Build Coastguard Worker {
3087*8975f5c5SAndroid Build Coastguard Worker         s.index[0] = uvec4(0u, 1u, 2u, 3u);
3088*8975f5c5SAndroid Build Coastguard Worker     float data = v[s.index[0].y];
3089*8975f5c5SAndroid Build Coastguard Worker     instanceB[0].v[s.index[0].x] = data;
3090*8975f5c5SAndroid Build Coastguard Worker })";
3091*8975f5c5SAndroid Build Coastguard Worker 
3092*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
3093*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3094*8975f5c5SAndroid Build Coastguard Worker }
3095*8975f5c5SAndroid Build Coastguard Worker 
3096*8975f5c5SAndroid Build Coastguard Worker // Test that swizzle node in non-SSBO symbol works well.
TEST_P(ComputeShaderTest,ShaderStorageBlocksWithNonSSBOSwizzle)3097*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksWithNonSSBOSwizzle)
3098*8975f5c5SAndroid Build Coastguard Worker {
3099*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeShaderSource[] = R"(#version 310 es
3100*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
3101*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
3102*8975f5c5SAndroid Build Coastguard Worker     float v[8];
3103*8975f5c5SAndroid Build Coastguard Worker };
3104*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
3105*8975f5c5SAndroid Build Coastguard Worker     float v[8];
3106*8975f5c5SAndroid Build Coastguard Worker } instanceB[1];
3107*8975f5c5SAndroid Build Coastguard Worker 
3108*8975f5c5SAndroid Build Coastguard Worker void main()
3109*8975f5c5SAndroid Build Coastguard Worker {
3110*8975f5c5SAndroid Build Coastguard Worker     float data = v[gl_GlobalInvocationID.x];
3111*8975f5c5SAndroid Build Coastguard Worker     instanceB[0].v[gl_GlobalInvocationID.x] = data;
3112*8975f5c5SAndroid Build Coastguard Worker })";
3113*8975f5c5SAndroid Build Coastguard Worker 
3114*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
3115*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3116*8975f5c5SAndroid Build Coastguard Worker }
3117*8975f5c5SAndroid Build Coastguard Worker 
3118*8975f5c5SAndroid Build Coastguard Worker // Test that swizzle node in SSBO symbol works well.
TEST_P(ComputeShaderTest,ShaderStorageBlocksWithSSBOSwizzle)3119*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ShaderStorageBlocksWithSSBOSwizzle)
3120*8975f5c5SAndroid Build Coastguard Worker {
3121*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeShaderSource[] = R"(#version 310 es
3122*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
3123*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer blockA {
3124*8975f5c5SAndroid Build Coastguard Worker     vec2 v;
3125*8975f5c5SAndroid Build Coastguard Worker };
3126*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
3127*8975f5c5SAndroid Build Coastguard Worker     float v;
3128*8975f5c5SAndroid Build Coastguard Worker } instanceB[1];
3129*8975f5c5SAndroid Build Coastguard Worker 
3130*8975f5c5SAndroid Build Coastguard Worker void main()
3131*8975f5c5SAndroid Build Coastguard Worker {
3132*8975f5c5SAndroid Build Coastguard Worker     instanceB[0].v = v.x;
3133*8975f5c5SAndroid Build Coastguard Worker })";
3134*8975f5c5SAndroid Build Coastguard Worker 
3135*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
3136*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3137*8975f5c5SAndroid Build Coastguard Worker }
3138*8975f5c5SAndroid Build Coastguard Worker 
3139*8975f5c5SAndroid Build Coastguard Worker // Test that a large struct array in std140 uniform block won't consume too much time.
TEST_P(ComputeShaderTest,LargeStructArraySize)3140*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, LargeStructArraySize)
3141*8975f5c5SAndroid Build Coastguard Worker {
3142*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeShaderSource[] = R"(#version 310 es
3143*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=8) in;
3144*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
3145*8975f5c5SAndroid Build Coastguard Worker 
3146*8975f5c5SAndroid Build Coastguard Worker struct InstancingData
3147*8975f5c5SAndroid Build Coastguard Worker {
3148*8975f5c5SAndroid Build Coastguard Worker     mat4 transformation;
3149*8975f5c5SAndroid Build Coastguard Worker };
3150*8975f5c5SAndroid Build Coastguard Worker 
3151*8975f5c5SAndroid Build Coastguard Worker #define MAX_INSTANCE_COUNT 800
3152*8975f5c5SAndroid Build Coastguard Worker 
3153*8975f5c5SAndroid Build Coastguard Worker layout(std140) uniform InstanceBlock
3154*8975f5c5SAndroid Build Coastguard Worker {
3155*8975f5c5SAndroid Build Coastguard Worker     InstancingData instances[MAX_INSTANCE_COUNT];
3156*8975f5c5SAndroid Build Coastguard Worker };
3157*8975f5c5SAndroid Build Coastguard Worker 
3158*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 1) buffer blockB {
3159*8975f5c5SAndroid Build Coastguard Worker     mat4 v[];
3160*8975f5c5SAndroid Build Coastguard Worker } instanceB;
3161*8975f5c5SAndroid Build Coastguard Worker 
3162*8975f5c5SAndroid Build Coastguard Worker void main()
3163*8975f5c5SAndroid Build Coastguard Worker {
3164*8975f5c5SAndroid Build Coastguard Worker     instanceB.v[gl_GlobalInvocationID.x] = instances[gl_GlobalInvocationID.x].transformation;
3165*8975f5c5SAndroid Build Coastguard Worker })";
3166*8975f5c5SAndroid Build Coastguard Worker 
3167*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
3168*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3169*8975f5c5SAndroid Build Coastguard Worker }
3170*8975f5c5SAndroid Build Coastguard Worker 
3171*8975f5c5SAndroid Build Coastguard Worker // Check that it is not possible to create a compute shader when the context does not support ES
3172*8975f5c5SAndroid Build Coastguard Worker // 3.10
TEST_P(ComputeShaderTestES3,NotSupported)3173*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTestES3, NotSupported)
3174*8975f5c5SAndroid Build Coastguard Worker {
3175*8975f5c5SAndroid Build Coastguard Worker     GLuint computeShaderHandle = glCreateShader(GL_COMPUTE_SHADER);
3176*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0u, computeShaderHandle);
3177*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3178*8975f5c5SAndroid Build Coastguard Worker }
3179*8975f5c5SAndroid Build Coastguard Worker 
3180*8975f5c5SAndroid Build Coastguard Worker // The contents of shared variables should be cleared to zero at the beginning of shader execution.
TEST_P(WebGL2ComputeTest,sharedVariablesShouldBeZero)3181*8975f5c5SAndroid Build Coastguard Worker TEST_P(WebGL2ComputeTest, sharedVariablesShouldBeZero)
3182*8975f5c5SAndroid Build Coastguard Worker {
3183*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40644676
3184*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
3185*8975f5c5SAndroid Build Coastguard Worker 
3186*8975f5c5SAndroid Build Coastguard Worker     // Fails on Android, AMD/windows and Intel/windows.  Probably works by chance on other
3187*8975f5c5SAndroid Build Coastguard Worker     // platforms, so suppressing on all platforms to avoid possible flakiness.
3188*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42262513
3189*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan());
3190*8975f5c5SAndroid Build Coastguard Worker 
3191*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096654
3192*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
3193*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOpenGL() &&
3194*8975f5c5SAndroid Build Coastguard Worker                        ((getClientMajorVersion() == 3) && (getClientMinorVersion() >= 1)));
3195*8975f5c5SAndroid Build Coastguard Worker 
3196*8975f5c5SAndroid Build Coastguard Worker     const char kCSShader[] = R"(#version 310 es
3197*8975f5c5SAndroid Build Coastguard Worker layout (local_size_x = 4, local_size_y = 4, local_size_z = 1) in;
3198*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 0) readonly uniform highp uimage2D srcImage;
3199*8975f5c5SAndroid Build Coastguard Worker layout (r32ui, binding = 1) writeonly uniform highp uimage2D dstImage;
3200*8975f5c5SAndroid Build Coastguard Worker struct S {
3201*8975f5c5SAndroid Build Coastguard Worker     float f;
3202*8975f5c5SAndroid Build Coastguard Worker     int i;
3203*8975f5c5SAndroid Build Coastguard Worker     uint u;
3204*8975f5c5SAndroid Build Coastguard Worker     bool b;
3205*8975f5c5SAndroid Build Coastguard Worker     vec4 v[64];
3206*8975f5c5SAndroid Build Coastguard Worker };
3207*8975f5c5SAndroid Build Coastguard Worker 
3208*8975f5c5SAndroid Build Coastguard Worker shared S vars[16];
3209*8975f5c5SAndroid Build Coastguard Worker void main()
3210*8975f5c5SAndroid Build Coastguard Worker {
3211*8975f5c5SAndroid Build Coastguard Worker     S zeroS;
3212*8975f5c5SAndroid Build Coastguard Worker     zeroS.f = 0.0f;
3213*8975f5c5SAndroid Build Coastguard Worker     zeroS.i = 0;
3214*8975f5c5SAndroid Build Coastguard Worker     zeroS.u = 0u;
3215*8975f5c5SAndroid Build Coastguard Worker     zeroS.b = false;
3216*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 64; i++)
3217*8975f5c5SAndroid Build Coastguard Worker     {
3218*8975f5c5SAndroid Build Coastguard Worker         zeroS.v[i] = vec4(0.0f);
3219*8975f5c5SAndroid Build Coastguard Worker     }
3220*8975f5c5SAndroid Build Coastguard Worker 
3221*8975f5c5SAndroid Build Coastguard Worker     uint tid = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 4u;
3222*8975f5c5SAndroid Build Coastguard Worker     uint value = (zeroS == vars[tid] ? 127u : 0u);
3223*8975f5c5SAndroid Build Coastguard Worker     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy), uvec4(value));
3224*8975f5c5SAndroid Build Coastguard Worker })";
3225*8975f5c5SAndroid Build Coastguard Worker 
3226*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 16> inputData = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
3227*8975f5c5SAndroid Build Coastguard Worker     const std::array<GLuint, 16> expectedValues = {
3228*8975f5c5SAndroid Build Coastguard Worker         {127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127}};
3229*8975f5c5SAndroid Build Coastguard Worker     runSharedMemoryTest<GLuint, 4, 4>(kCSShader, GL_R32UI, GL_UNSIGNED_INT, inputData,
3230*8975f5c5SAndroid Build Coastguard Worker                                       expectedValues);
3231*8975f5c5SAndroid Build Coastguard Worker }
3232*8975f5c5SAndroid Build Coastguard Worker 
3233*8975f5c5SAndroid Build Coastguard Worker // Test uniform dirty in compute shader, and verify the contents.
TEST_P(ComputeShaderTest,UniformDirty)3234*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, UniformDirty)
3235*8975f5c5SAndroid Build Coastguard Worker {
3236*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
3237*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
3238*8975f5c5SAndroid Build Coastguard Worker 
3239*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
3240*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
3241*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
3242*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3243*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
3244*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
3245*8975f5c5SAndroid Build Coastguard Worker uniform uint factor;
3246*8975f5c5SAndroid Build Coastguard Worker void main()
3247*8975f5c5SAndroid Build Coastguard Worker {
3248*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
3249*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value * factor);
3250*8975f5c5SAndroid Build Coastguard Worker })";
3251*8975f5c5SAndroid Build Coastguard Worker 
3252*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1;
3253*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[2][1] = {{200}, {100}};
3254*8975f5c5SAndroid Build Coastguard Worker 
3255*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
3256*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
3257*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
3258*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[0]);
3259*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3260*8975f5c5SAndroid Build Coastguard Worker 
3261*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
3262*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
3263*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
3264*8975f5c5SAndroid Build Coastguard Worker                     kInputValues[1]);
3265*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3266*8975f5c5SAndroid Build Coastguard Worker 
3267*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3268*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3269*8975f5c5SAndroid Build Coastguard Worker 
3270*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
3271*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3272*8975f5c5SAndroid Build Coastguard Worker 
3273*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
3274*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3275*8975f5c5SAndroid Build Coastguard Worker 
3276*8975f5c5SAndroid Build Coastguard Worker     glUniform1ui(glGetUniformLocation(program, "factor"), 2);
3277*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3278*8975f5c5SAndroid Build Coastguard Worker 
3279*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3280*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3281*8975f5c5SAndroid Build Coastguard Worker 
3282*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3283*8975f5c5SAndroid Build Coastguard Worker 
3284*8975f5c5SAndroid Build Coastguard Worker     glUniform1ui(glGetUniformLocation(program, "factor"), 3);
3285*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3286*8975f5c5SAndroid Build Coastguard Worker 
3287*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3288*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3289*8975f5c5SAndroid Build Coastguard Worker 
3290*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3291*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth * kHeight];
3292*8975f5c5SAndroid Build Coastguard Worker     GLuint expectedValue = 600;
3293*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
3294*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
3295*8975f5c5SAndroid Build Coastguard Worker 
3296*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
3297*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3298*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
3299*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3300*8975f5c5SAndroid Build Coastguard Worker 
3301*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth * kHeight; i++)
3302*8975f5c5SAndroid Build Coastguard Worker     {
3303*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue, outputValues[i]) << " index " << i;
3304*8975f5c5SAndroid Build Coastguard Worker     }
3305*8975f5c5SAndroid Build Coastguard Worker }
3306*8975f5c5SAndroid Build Coastguard Worker 
3307*8975f5c5SAndroid Build Coastguard Worker // Test storage buffer bound is unchanged, shader writes it, buffer content should be updated.
TEST_P(ComputeShaderTest,StorageBufferBoundUnchanged)3308*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, StorageBufferBoundUnchanged)
3309*8975f5c5SAndroid Build Coastguard Worker {
3310*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096654
3311*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(isSwiftshader());
3312*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
3313*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=16, local_size_y=16) in;
3314*8975f5c5SAndroid Build Coastguard Worker precision highp usampler2D;
3315*8975f5c5SAndroid Build Coastguard Worker uniform usampler2D tex;
3316*8975f5c5SAndroid Build Coastguard Worker uniform uint factor;
3317*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer buf {
3318*8975f5c5SAndroid Build Coastguard Worker     uint outData[16][16];
3319*8975f5c5SAndroid Build Coastguard Worker };
3320*8975f5c5SAndroid Build Coastguard Worker 
3321*8975f5c5SAndroid Build Coastguard Worker void main()
3322*8975f5c5SAndroid Build Coastguard Worker {
3323*8975f5c5SAndroid Build Coastguard Worker     uint x = gl_LocalInvocationID.x;
3324*8975f5c5SAndroid Build Coastguard Worker     uint y = gl_LocalInvocationID.y;
3325*8975f5c5SAndroid Build Coastguard Worker     float xCoord = float(x) / float(16);
3326*8975f5c5SAndroid Build Coastguard Worker     float yCoord = float(y) / float(16);
3327*8975f5c5SAndroid Build Coastguard Worker     outData[y][x] = texture(tex, vec2(xCoord, yCoord)).x + factor;
3328*8975f5c5SAndroid Build Coastguard Worker })";
3329*8975f5c5SAndroid Build Coastguard Worker 
3330*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kWidth  = 16;
3331*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kHeight = 16;
3332*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
3333*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
3334*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3335*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3336*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
3337*8975f5c5SAndroid Build Coastguard Worker     GLuint texels[kHeight][kWidth] = {{0}};
3338*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int y = 0; y < kHeight; ++y)
3339*8975f5c5SAndroid Build Coastguard Worker     {
3340*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int x = 0; x < kWidth; ++x)
3341*8975f5c5SAndroid Build Coastguard Worker         {
3342*8975f5c5SAndroid Build Coastguard Worker             texels[y][x] = x + y * kWidth;
3343*8975f5c5SAndroid Build Coastguard Worker         }
3344*8975f5c5SAndroid Build Coastguard Worker     }
3345*8975f5c5SAndroid Build Coastguard Worker     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3346*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
3347*8975f5c5SAndroid Build Coastguard Worker                     texels);
3348*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
3349*8975f5c5SAndroid Build Coastguard Worker 
3350*8975f5c5SAndroid Build Coastguard Worker     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
3351*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kArrayStride = 16;
3352*8975f5c5SAndroid Build Coastguard Worker     GLBuffer ssbo;
3353*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
3354*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, kWidth * kHeight * kArrayStride, nullptr,
3355*8975f5c5SAndroid Build Coastguard Worker                  GL_STREAM_DRAW);
3356*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
3357*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3358*8975f5c5SAndroid Build Coastguard Worker 
3359*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3360*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3361*8975f5c5SAndroid Build Coastguard Worker 
3362*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
3363*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
3364*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(program, "tex"), 0);
3365*8975f5c5SAndroid Build Coastguard Worker     glUniform1ui(glGetUniformLocation(program, "factor"), 2);
3366*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
3367*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
3368*8975f5c5SAndroid Build Coastguard Worker 
3369*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3370*8975f5c5SAndroid Build Coastguard Worker 
3371*8975f5c5SAndroid Build Coastguard Worker     const GLuint *ptr1 = reinterpret_cast<const GLuint *>(glMapBufferRange(
3372*8975f5c5SAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BUFFER, 0, kWidth * kHeight * kArrayStride, GL_MAP_READ_BIT));
3373*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3374*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < kWidth * kHeight; idx++)
3375*8975f5c5SAndroid Build Coastguard Worker     {
3376*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(idx + 2, *(ptr1 + idx * kArrayStride / 4));
3377*8975f5c5SAndroid Build Coastguard Worker     }
3378*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3379*8975f5c5SAndroid Build Coastguard Worker     glUniform1ui(glGetUniformLocation(program, "factor"), 3);
3380*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3381*8975f5c5SAndroid Build Coastguard Worker 
3382*8975f5c5SAndroid Build Coastguard Worker     const GLuint *ptr2 = reinterpret_cast<const GLuint *>(glMapBufferRange(
3383*8975f5c5SAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BUFFER, 0, kWidth * kHeight * kArrayStride, GL_MAP_READ_BIT));
3384*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3385*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < kWidth * kHeight; idx++)
3386*8975f5c5SAndroid Build Coastguard Worker     {
3387*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(idx + 3, *(ptr2 + idx * kArrayStride / 4));
3388*8975f5c5SAndroid Build Coastguard Worker     }
3389*8975f5c5SAndroid Build Coastguard Worker }
3390*8975f5c5SAndroid Build Coastguard Worker 
3391*8975f5c5SAndroid Build Coastguard Worker // Test imageSize to access mipmap slice.
TEST_P(ComputeShaderTest,ImageSizeMipmapSlice)3392*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageSizeMipmapSlice)
3393*8975f5c5SAndroid Build Coastguard Worker {
3394*8975f5c5SAndroid Build Coastguard Worker     // TODO([email protected]): http://anglebug.com/42261780
3395*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
3396*8975f5c5SAndroid Build Coastguard Worker 
3397*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263018
3398*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsD3D11());
3399*8975f5c5SAndroid Build Coastguard Worker 
3400*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
3401*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
3402*8975f5c5SAndroid Build Coastguard Worker     const char kCS[] = R"(#version 310 es
3403*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3404*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
3405*8975f5c5SAndroid Build Coastguard Worker layout(rgba32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
3406*8975f5c5SAndroid Build Coastguard Worker void main()
3407*8975f5c5SAndroid Build Coastguard Worker {
3408*8975f5c5SAndroid Build Coastguard Worker     ivec2 size = imageSize(uImage_1);
3409*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), uvec4(size, 0, 0));
3410*8975f5c5SAndroid Build Coastguard Worker })";
3411*8975f5c5SAndroid Build Coastguard Worker 
3412*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth1 = 8, kHeight1 = 4, kWidth2 = 1, kHeight2 = 1;
3413*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues[] = {0, 0, 0, 0};
3414*8975f5c5SAndroid Build Coastguard Worker 
3415*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
3416*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 2, GL_R32UI, kWidth1, kHeight1);
3417*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3418*8975f5c5SAndroid Build Coastguard Worker 
3419*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
3420*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, kWidth2, kHeight2);
3421*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth2, kHeight2, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
3422*8975f5c5SAndroid Build Coastguard Worker                     kInputValues);
3423*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3424*8975f5c5SAndroid Build Coastguard Worker 
3425*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3426*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3427*8975f5c5SAndroid Build Coastguard Worker 
3428*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 1, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
3429*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
3430*8975f5c5SAndroid Build Coastguard Worker 
3431*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3432*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3433*8975f5c5SAndroid Build Coastguard Worker 
3434*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3435*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues[kWidth2 * kHeight2 * 4];
3436*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue[] = {4, 2};
3437*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
3438*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
3439*8975f5c5SAndroid Build Coastguard Worker 
3440*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
3441*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3442*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth2, kHeight2, GL_RGBA_INTEGER, GL_UNSIGNED_INT, outputValues);
3443*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3444*8975f5c5SAndroid Build Coastguard Worker 
3445*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kWidth2 * kHeight2; i++)
3446*8975f5c5SAndroid Build Coastguard Worker     {
3447*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue[i], outputValues[i]);
3448*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedValue[i + 1], outputValues[i + 1]);
3449*8975f5c5SAndroid Build Coastguard Worker     }
3450*8975f5c5SAndroid Build Coastguard Worker }
3451*8975f5c5SAndroid Build Coastguard Worker 
3452*8975f5c5SAndroid Build Coastguard Worker // Test imageLoad to access mipmap slice.
TEST_P(ComputeShaderTest,ImageLoadMipmapSlice)3453*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageLoadMipmapSlice)
3454*8975f5c5SAndroid Build Coastguard Worker {
3455*8975f5c5SAndroid Build Coastguard Worker     // TODO([email protected]): http://anglebug.com/42261780
3456*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
3457*8975f5c5SAndroid Build Coastguard Worker 
3458*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
3459*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
3460*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
3461*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3462*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
3463*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
3464*8975f5c5SAndroid Build Coastguard Worker void main()
3465*8975f5c5SAndroid Build Coastguard Worker {
3466*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
3467*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
3468*8975f5c5SAndroid Build Coastguard Worker })";
3469*8975f5c5SAndroid Build Coastguard Worker 
3470*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth1 = 2, kHeight1 = 2, kWidth2 = 1, kHeight2 = 1;
3471*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues11[] = {3, 3, 3, 3};
3472*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues12[] = {2};
3473*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues2[]  = {1};
3474*8975f5c5SAndroid Build Coastguard Worker 
3475*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
3476*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 2, GL_R32UI, kWidth1, kHeight1);
3477*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth1, kHeight1, GL_RED_INTEGER, GL_UNSIGNED_INT,
3478*8975f5c5SAndroid Build Coastguard Worker                     kInputValues11);
3479*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kWidth2, kHeight2, GL_RED_INTEGER, GL_UNSIGNED_INT,
3480*8975f5c5SAndroid Build Coastguard Worker                     kInputValues12);
3481*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3482*8975f5c5SAndroid Build Coastguard Worker 
3483*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
3484*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth2, kHeight2);
3485*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth2, kHeight2, GL_RED_INTEGER, GL_UNSIGNED_INT,
3486*8975f5c5SAndroid Build Coastguard Worker                     kInputValues2);
3487*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3488*8975f5c5SAndroid Build Coastguard Worker 
3489*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3490*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3491*8975f5c5SAndroid Build Coastguard Worker 
3492*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 1, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
3493*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
3494*8975f5c5SAndroid Build Coastguard Worker 
3495*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3496*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3497*8975f5c5SAndroid Build Coastguard Worker 
3498*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3499*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues;
3500*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 2;
3501*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
3502*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
3503*8975f5c5SAndroid Build Coastguard Worker 
3504*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
3505*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3506*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth2, kHeight2, GL_RED_INTEGER, GL_UNSIGNED_INT, &outputValues);
3507*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3508*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(expectedValue, outputValues);
3509*8975f5c5SAndroid Build Coastguard Worker }
3510*8975f5c5SAndroid Build Coastguard Worker 
3511*8975f5c5SAndroid Build Coastguard Worker // Test imageStore to access mipmap slice.
TEST_P(ComputeShaderTest,ImageStoreMipmapSlice)3512*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageStoreMipmapSlice)
3513*8975f5c5SAndroid Build Coastguard Worker {
3514*8975f5c5SAndroid Build Coastguard Worker     // TODO([email protected]): http://anglebug.com/42261780
3515*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
3516*8975f5c5SAndroid Build Coastguard Worker 
3517*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[2];
3518*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
3519*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
3520*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3521*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
3522*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
3523*8975f5c5SAndroid Build Coastguard Worker void main()
3524*8975f5c5SAndroid Build Coastguard Worker {
3525*8975f5c5SAndroid Build Coastguard Worker     uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
3526*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
3527*8975f5c5SAndroid Build Coastguard Worker })";
3528*8975f5c5SAndroid Build Coastguard Worker 
3529*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth1 = 1, kHeight1 = 1, kWidth2 = 2, kHeight2 = 2;
3530*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues1[]  = {3};
3531*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues21[] = {2, 2, 2, 2};
3532*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInputValues22[] = {1};
3533*8975f5c5SAndroid Build Coastguard Worker 
3534*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
3535*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth1, kHeight1);
3536*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth1, kHeight1, GL_RED_INTEGER, GL_UNSIGNED_INT,
3537*8975f5c5SAndroid Build Coastguard Worker                     kInputValues1);
3538*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3539*8975f5c5SAndroid Build Coastguard Worker 
3540*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
3541*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 2, GL_R32UI, kWidth2, kHeight2);
3542*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth2, kHeight2, GL_RED_INTEGER, GL_UNSIGNED_INT,
3543*8975f5c5SAndroid Build Coastguard Worker                     kInputValues21);
3544*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kWidth1, kHeight1, GL_RED_INTEGER, GL_UNSIGNED_INT,
3545*8975f5c5SAndroid Build Coastguard Worker                     kInputValues22);
3546*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3547*8975f5c5SAndroid Build Coastguard Worker 
3548*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3549*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3550*8975f5c5SAndroid Build Coastguard Worker 
3551*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
3552*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(1, texture[1], 1, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
3553*8975f5c5SAndroid Build Coastguard Worker 
3554*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3555*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3556*8975f5c5SAndroid Build Coastguard Worker 
3557*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3558*8975f5c5SAndroid Build Coastguard Worker     GLuint outputValues;
3559*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint expectedValue = 3;
3560*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
3561*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
3562*8975f5c5SAndroid Build Coastguard Worker 
3563*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 1);
3564*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3565*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, kWidth1, kHeight1, GL_RED_INTEGER, GL_UNSIGNED_INT, &outputValues);
3566*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3567*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(expectedValue, outputValues);
3568*8975f5c5SAndroid Build Coastguard Worker }
3569*8975f5c5SAndroid Build Coastguard Worker 
3570*8975f5c5SAndroid Build Coastguard Worker // Test that a resource is bound on render pipeline output, and then it's bound as the compute
3571*8975f5c5SAndroid Build Coastguard Worker // pipeline input. It works well. See http://anglebug.com/42262319
TEST_P(ComputeShaderTest,DrawTexture1DispatchTexture2)3572*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DrawTexture1DispatchTexture2)
3573*8975f5c5SAndroid Build Coastguard Worker {
3574*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
3575*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
3576*8975f5c5SAndroid Build Coastguard Worker 
3577*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_color_buffer_float"));
3578*8975f5c5SAndroid Build Coastguard Worker 
3579*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
3580*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3581*8975f5c5SAndroid Build Coastguard Worker precision highp sampler2D;
3582*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
3583*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) writeonly uniform highp image2D image;
3584*8975f5c5SAndroid Build Coastguard Worker void main()
3585*8975f5c5SAndroid Build Coastguard Worker {
3586*8975f5c5SAndroid Build Coastguard Worker     vec4 value = texelFetch(tex, ivec2(gl_LocalInvocationID.xy), 0);
3587*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), vec4(value.x - 1.0, 1.0, 0.0, value.w - 1.0));
3588*8975f5c5SAndroid Build Coastguard Worker })";
3589*8975f5c5SAndroid Build Coastguard Worker 
3590*8975f5c5SAndroid Build Coastguard Worker     const char kVSSource[] = R"(#version 310 es
3591*8975f5c5SAndroid Build Coastguard Worker layout (location = 0) in vec2 pos;
3592*8975f5c5SAndroid Build Coastguard Worker out vec2 texCoord;
3593*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3594*8975f5c5SAndroid Build Coastguard Worker     texCoord = 0.5*pos + 0.5;
3595*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 0.0, 1.0);
3596*8975f5c5SAndroid Build Coastguard Worker })";
3597*8975f5c5SAndroid Build Coastguard Worker 
3598*8975f5c5SAndroid Build Coastguard Worker     const char kFSSource[] = R"(#version 310 es
3599*8975f5c5SAndroid Build Coastguard Worker precision highp float;
3600*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
3601*8975f5c5SAndroid Build Coastguard Worker in vec2 texCoord;
3602*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
3603*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3604*8975f5c5SAndroid Build Coastguard Worker     fragColor = texture(tex, texCoord);
3605*8975f5c5SAndroid Build Coastguard Worker })";
3606*8975f5c5SAndroid Build Coastguard Worker 
3607*8975f5c5SAndroid Build Coastguard Worker     GLuint aPosLoc = 0;
3608*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
3609*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
3610*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, aPosLoc, "pos");
3611*8975f5c5SAndroid Build Coastguard Worker     GLuint buffer;
3612*8975f5c5SAndroid Build Coastguard Worker     glGenBuffers(1, &buffer);
3613*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, buffer);
3614*8975f5c5SAndroid Build Coastguard Worker     GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
3615*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, vertices, GL_STATIC_DRAW);
3616*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(aPosLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
3617*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(aPosLoc);
3618*8975f5c5SAndroid Build Coastguard Worker 
3619*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat kInputValues[4] = {1.0, 0.0, 0.0, 1.0};
3620*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat kZero[4]        = {0.0, 0.0, 0.0, 0.0};
3621*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
3622*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture[3];
3623*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
3624*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
3625*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kInputValues);
3626*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3627*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3628*8975f5c5SAndroid Build Coastguard Worker 
3629*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
3630*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
3631*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kZero);
3632*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3633*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3634*8975f5c5SAndroid Build Coastguard Worker 
3635*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[2]);
3636*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
3637*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kZero);
3638*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3639*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3640*8975f5c5SAndroid Build Coastguard Worker 
3641*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3642*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
3643*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[0]);
3644*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(program, "tex"), 0);
3645*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3646*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
3647*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3648*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3649*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
3650*8975f5c5SAndroid Build Coastguard Worker     GLfloat actual[4];
3651*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, actual);
3652*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3653*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(1.0, actual[0]);
3654*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0.0, actual[1]);
3655*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0.0, actual[2]);
3656*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(1.0, actual[3]);
3657*8975f5c5SAndroid Build Coastguard Worker 
3658*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
3659*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
3660*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture[1]);
3661*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(program, "tex"), 0);
3662*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture[2], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
3663*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3664*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3665*8975f5c5SAndroid Build Coastguard Worker 
3666*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
3667*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[2], 0);
3668*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, actual);
3669*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3670*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0.0, actual[0]);
3671*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(1.0, actual[1]);
3672*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0.0, actual[2]);
3673*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0.0, actual[3]);
3674*8975f5c5SAndroid Build Coastguard Worker }
3675*8975f5c5SAndroid Build Coastguard Worker 
3676*8975f5c5SAndroid Build Coastguard Worker // Test that render pipeline and compute pipeline access to the same texture.
3677*8975f5c5SAndroid Build Coastguard Worker // Steps:
3678*8975f5c5SAndroid Build Coastguard Worker //   1. DispatchCompute.
3679*8975f5c5SAndroid Build Coastguard Worker //   2. DrawArrays.
TEST_P(ComputeShaderTest,DispatchDraw)3680*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchDraw)
3681*8975f5c5SAndroid Build Coastguard Worker {
3682*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
3683*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
3684*8975f5c5SAndroid Build Coastguard Worker 
3685*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
3686*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3687*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) writeonly uniform highp image2D image;
3688*8975f5c5SAndroid Build Coastguard Worker void main()
3689*8975f5c5SAndroid Build Coastguard Worker {
3690*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), vec4(0.0, 0.0, 1.0, 1.0));
3691*8975f5c5SAndroid Build Coastguard Worker })";
3692*8975f5c5SAndroid Build Coastguard Worker 
3693*8975f5c5SAndroid Build Coastguard Worker     const char kVSSource[] = R"(#version 310 es
3694*8975f5c5SAndroid Build Coastguard Worker layout (location = 0) in vec2 pos;
3695*8975f5c5SAndroid Build Coastguard Worker out vec2 texCoord;
3696*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3697*8975f5c5SAndroid Build Coastguard Worker     texCoord = 0.5*pos + 0.5;
3698*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 0.0, 1.0);
3699*8975f5c5SAndroid Build Coastguard Worker })";
3700*8975f5c5SAndroid Build Coastguard Worker 
3701*8975f5c5SAndroid Build Coastguard Worker     const char kFSSource[] = R"(#version 310 es
3702*8975f5c5SAndroid Build Coastguard Worker precision highp float;
3703*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
3704*8975f5c5SAndroid Build Coastguard Worker in vec2 texCoord;
3705*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
3706*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3707*8975f5c5SAndroid Build Coastguard Worker     fragColor = texture(tex, texCoord);
3708*8975f5c5SAndroid Build Coastguard Worker })";
3709*8975f5c5SAndroid Build Coastguard Worker 
3710*8975f5c5SAndroid Build Coastguard Worker     GLuint aPosLoc = 0;
3711*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
3712*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, aPosLoc, "pos");
3713*8975f5c5SAndroid Build Coastguard Worker     GLuint buffer;
3714*8975f5c5SAndroid Build Coastguard Worker     glGenBuffers(1, &buffer);
3715*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, buffer);
3716*8975f5c5SAndroid Build Coastguard Worker     GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
3717*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, vertices, GL_STATIC_DRAW);
3718*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(aPosLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
3719*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(aPosLoc);
3720*8975f5c5SAndroid Build Coastguard Worker 
3721*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat kInputValues[4] = {1.0, 0.0, 0.0, 1.0};
3722*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
3723*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
3724*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
3725*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kInputValues);
3726*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3727*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3728*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3729*8975f5c5SAndroid Build Coastguard Worker 
3730*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
3731*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
3732*8975f5c5SAndroid Build Coastguard Worker 
3733*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
3734*8975f5c5SAndroid Build Coastguard Worker 
3735*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3736*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3737*8975f5c5SAndroid Build Coastguard Worker 
3738*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
3739*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3740*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3741*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::blue);
3742*8975f5c5SAndroid Build Coastguard Worker }
3743*8975f5c5SAndroid Build Coastguard Worker 
3744*8975f5c5SAndroid Build Coastguard Worker // Test that render pipeline and compute pipeline access to the same texture.
3745*8975f5c5SAndroid Build Coastguard Worker // Steps:
3746*8975f5c5SAndroid Build Coastguard Worker //   1. DrawArrays.
3747*8975f5c5SAndroid Build Coastguard Worker //   2. DispatchCompute.
3748*8975f5c5SAndroid Build Coastguard Worker //   3. DispatchCompute.
3749*8975f5c5SAndroid Build Coastguard Worker //   4. DrawArrays.
TEST_P(ComputeShaderTest,DrawDispatchDispatchDraw)3750*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DrawDispatchDispatchDraw)
3751*8975f5c5SAndroid Build Coastguard Worker {
3752*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
3753*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
3754*8975f5c5SAndroid Build Coastguard Worker 
3755*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
3756*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3757*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) writeonly uniform highp image2D image;
3758*8975f5c5SAndroid Build Coastguard Worker uniform float factor;
3759*8975f5c5SAndroid Build Coastguard Worker void main()
3760*8975f5c5SAndroid Build Coastguard Worker {
3761*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), vec4(factor, 0.0, 1.0, 1.0));
3762*8975f5c5SAndroid Build Coastguard Worker })";
3763*8975f5c5SAndroid Build Coastguard Worker 
3764*8975f5c5SAndroid Build Coastguard Worker     const char kVSSource[] = R"(#version 310 es
3765*8975f5c5SAndroid Build Coastguard Worker layout (location = 0) in vec2 pos;
3766*8975f5c5SAndroid Build Coastguard Worker out vec2 texCoord;
3767*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3768*8975f5c5SAndroid Build Coastguard Worker     texCoord = 0.5*pos + 0.5;
3769*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 0.0, 1.0);
3770*8975f5c5SAndroid Build Coastguard Worker })";
3771*8975f5c5SAndroid Build Coastguard Worker 
3772*8975f5c5SAndroid Build Coastguard Worker     const char kFSSource[] = R"(#version 310 es
3773*8975f5c5SAndroid Build Coastguard Worker precision highp float;
3774*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
3775*8975f5c5SAndroid Build Coastguard Worker in vec2 texCoord;
3776*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
3777*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3778*8975f5c5SAndroid Build Coastguard Worker     fragColor = texture(tex, texCoord);
3779*8975f5c5SAndroid Build Coastguard Worker })";
3780*8975f5c5SAndroid Build Coastguard Worker 
3781*8975f5c5SAndroid Build Coastguard Worker     GLuint aPosLoc = 0;
3782*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
3783*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, aPosLoc, "pos");
3784*8975f5c5SAndroid Build Coastguard Worker     GLuint buffer;
3785*8975f5c5SAndroid Build Coastguard Worker     glGenBuffers(1, &buffer);
3786*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, buffer);
3787*8975f5c5SAndroid Build Coastguard Worker     GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
3788*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, vertices, GL_STATIC_DRAW);
3789*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(aPosLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
3790*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(aPosLoc);
3791*8975f5c5SAndroid Build Coastguard Worker 
3792*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat kInputValues[4] = {1.0, 0.0, 0.0, 1.0};
3793*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
3794*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
3795*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
3796*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kInputValues);
3797*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3798*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3799*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3800*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3801*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3802*8975f5c5SAndroid Build Coastguard Worker 
3803*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
3804*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
3805*8975f5c5SAndroid Build Coastguard Worker     glUniform1f(glGetUniformLocation(csProgram, "factor"), 0.0);
3806*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
3807*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3808*8975f5c5SAndroid Build Coastguard Worker 
3809*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3810*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3811*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3812*8975f5c5SAndroid Build Coastguard Worker 
3813*8975f5c5SAndroid Build Coastguard Worker     glUniform1f(glGetUniformLocation(csProgram, "factor"), 1.0);
3814*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3815*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
3816*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3817*8975f5c5SAndroid Build Coastguard Worker 
3818*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3819*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3820*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::magenta);
3821*8975f5c5SAndroid Build Coastguard Worker }
3822*8975f5c5SAndroid Build Coastguard Worker 
3823*8975f5c5SAndroid Build Coastguard Worker // Test that render pipeline and compute pipeline access to the same texture.
3824*8975f5c5SAndroid Build Coastguard Worker // Steps:
3825*8975f5c5SAndroid Build Coastguard Worker //   1. DispatchCompute.
3826*8975f5c5SAndroid Build Coastguard Worker //   2. DrawArrays.
3827*8975f5c5SAndroid Build Coastguard Worker //   3. DrawArrays.
3828*8975f5c5SAndroid Build Coastguard Worker //   4. DispatchCompute.
TEST_P(ComputeShaderTest,DispatchDrawDrawDispatch)3829*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchDrawDrawDispatch)
3830*8975f5c5SAndroid Build Coastguard Worker {
3831*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
3832*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
3833*8975f5c5SAndroid Build Coastguard Worker 
3834*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
3835*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3836*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) writeonly uniform highp image2D image;
3837*8975f5c5SAndroid Build Coastguard Worker 
3838*8975f5c5SAndroid Build Coastguard Worker void main()
3839*8975f5c5SAndroid Build Coastguard Worker {
3840*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), vec4(0.0, 0.0, 1.0, 1.0));
3841*8975f5c5SAndroid Build Coastguard Worker })";
3842*8975f5c5SAndroid Build Coastguard Worker 
3843*8975f5c5SAndroid Build Coastguard Worker     const char kVSSource[] = R"(#version 310 es
3844*8975f5c5SAndroid Build Coastguard Worker layout (location = 0) in vec2 pos;
3845*8975f5c5SAndroid Build Coastguard Worker out vec2 texCoord;
3846*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3847*8975f5c5SAndroid Build Coastguard Worker     texCoord = 0.5*pos + 0.5;
3848*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 0.0, 1.0);
3849*8975f5c5SAndroid Build Coastguard Worker })";
3850*8975f5c5SAndroid Build Coastguard Worker 
3851*8975f5c5SAndroid Build Coastguard Worker     const char kFSSource[] = R"(#version 310 es
3852*8975f5c5SAndroid Build Coastguard Worker precision highp float;
3853*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
3854*8975f5c5SAndroid Build Coastguard Worker in vec2 texCoord;
3855*8975f5c5SAndroid Build Coastguard Worker uniform float factor;
3856*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
3857*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3858*8975f5c5SAndroid Build Coastguard Worker     fragColor = texture(tex, texCoord) + vec4(factor, 0.0, 0.0, 0.0);
3859*8975f5c5SAndroid Build Coastguard Worker })";
3860*8975f5c5SAndroid Build Coastguard Worker 
3861*8975f5c5SAndroid Build Coastguard Worker     GLuint aPosLoc = 0;
3862*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
3863*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, aPosLoc, "pos");
3864*8975f5c5SAndroid Build Coastguard Worker     GLuint buffer;
3865*8975f5c5SAndroid Build Coastguard Worker     glGenBuffers(1, &buffer);
3866*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, buffer);
3867*8975f5c5SAndroid Build Coastguard Worker     GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
3868*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, vertices, GL_STATIC_DRAW);
3869*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(aPosLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
3870*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(aPosLoc);
3871*8975f5c5SAndroid Build Coastguard Worker 
3872*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat kInputValues[4] = {1.0, 0.0, 0.0, 1.0};
3873*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
3874*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
3875*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
3876*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kInputValues);
3877*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3878*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3879*8975f5c5SAndroid Build Coastguard Worker 
3880*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
3881*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
3882*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
3883*8975f5c5SAndroid Build Coastguard Worker 
3884*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3885*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
3886*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3887*8975f5c5SAndroid Build Coastguard Worker 
3888*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3889*8975f5c5SAndroid Build Coastguard Worker     glUniform1f(glGetUniformLocation(program, "factor"), 0.0);
3890*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3891*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3892*8975f5c5SAndroid Build Coastguard Worker 
3893*8975f5c5SAndroid Build Coastguard Worker     glUniform1f(glGetUniformLocation(program, "factor"), 1.0);
3894*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3895*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3896*8975f5c5SAndroid Build Coastguard Worker 
3897*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3898*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
3899*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3900*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
3901*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3902*8975f5c5SAndroid Build Coastguard Worker 
3903*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
3904*8975f5c5SAndroid Build Coastguard Worker     glUniform1f(glGetUniformLocation(program, "factor"), 0.0);
3905*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3906*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::blue);
3907*8975f5c5SAndroid Build Coastguard Worker }
3908*8975f5c5SAndroid Build Coastguard Worker 
3909*8975f5c5SAndroid Build Coastguard Worker // Test color texture sample from fragment shader and then read access from compute
TEST_P(ComputeShaderTest,DrawReadDrawDispatch)3910*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DrawReadDrawDispatch)
3911*8975f5c5SAndroid Build Coastguard Worker {
3912*8975f5c5SAndroid Build Coastguard Worker     const char kVS[] = R"(#version 310 es
3913*8975f5c5SAndroid Build Coastguard Worker layout (location = 0) in vec3 pos;
3914*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3915*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 1.0);
3916*8975f5c5SAndroid Build Coastguard Worker })";
3917*8975f5c5SAndroid Build Coastguard Worker 
3918*8975f5c5SAndroid Build Coastguard Worker     const char kFS[] = R"(#version 310 es
3919*8975f5c5SAndroid Build Coastguard Worker precision highp float;
3920*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
3921*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
3922*8975f5c5SAndroid Build Coastguard Worker void main(void) {
3923*8975f5c5SAndroid Build Coastguard Worker         fragColor = texture(tex,vec2(0,0));
3924*8975f5c5SAndroid Build Coastguard Worker })";
3925*8975f5c5SAndroid Build Coastguard Worker 
3926*8975f5c5SAndroid Build Coastguard Worker     // Create color texture
3927*8975f5c5SAndroid Build Coastguard Worker     GLTexture colorTexture;
3928*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
3929*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, colorTexture);
3930*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3931*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3932*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
3933*8975f5c5SAndroid Build Coastguard Worker     const GLColor textureData = GLColor::green;
3934*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, textureData.data());
3935*8975f5c5SAndroid Build Coastguard Worker 
3936*8975f5c5SAndroid Build Coastguard Worker     // Render to surface with texture sample
3937*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(graphicsProgram, kVS, kFS);
3938*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(graphicsProgram);
3939*8975f5c5SAndroid Build Coastguard Worker     const auto &quadVertices = GetQuadVertices();
3940*8975f5c5SAndroid Build Coastguard Worker     GLBuffer arrayBuffer;
3941*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
3942*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
3943*8975f5c5SAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
3944*8975f5c5SAndroid Build Coastguard Worker     GLint positionAttributeLocation = 0;
3945*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(graphicsProgram, positionAttributeLocation, "pos");
3946*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
3947*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(positionAttributeLocation);
3948*8975f5c5SAndroid Build Coastguard Worker 
3949*8975f5c5SAndroid Build Coastguard Worker     GLint uTextureLocation = glGetUniformLocation(graphicsProgram, "tex");
3950*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, uTextureLocation);
3951*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
3952*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, colorTexture);
3953*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(uTextureLocation, 0);
3954*8975f5c5SAndroid Build Coastguard Worker     // Sample the color texture from fragment shader and verify. This flushes out commands which
3955*8975f5c5SAndroid Build Coastguard Worker     // ensures there will be no layout transition in next renderPass.
3956*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_DEPTH_TEST);
3957*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 6);
3958*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, textureData);
3959*8975f5c5SAndroid Build Coastguard Worker 
3960*8975f5c5SAndroid Build Coastguard Worker     // Sample the texture from fragment shader. No image layout transition expected here.
3961*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 6);
3962*8975f5c5SAndroid Build Coastguard Worker 
3963*8975f5c5SAndroid Build Coastguard Worker     // Sample it from compute shader while the renderPass also sample from the same texture
3964*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
3965*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3966*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding=0) buffer buf {
3967*8975f5c5SAndroid Build Coastguard Worker     vec4 outData;
3968*8975f5c5SAndroid Build Coastguard Worker };
3969*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D u_tex2D;
3970*8975f5c5SAndroid Build Coastguard Worker void main()
3971*8975f5c5SAndroid Build Coastguard Worker {
3972*8975f5c5SAndroid Build Coastguard Worker     outData = texture(u_tex2D, vec2(gl_LocalInvocationID.xy));
3973*8975f5c5SAndroid Build Coastguard Worker })";
3974*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(computeProgram, kCS);
3975*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(computeProgram);
3976*8975f5c5SAndroid Build Coastguard Worker     uTextureLocation = glGetUniformLocation(computeProgram, "u_tex2D");
3977*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, uTextureLocation);
3978*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(uTextureLocation, 0);
3979*8975f5c5SAndroid Build Coastguard Worker     GLBuffer ssbo;
3980*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLfloat> initialData(4, 0.0f);
3981*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
3982*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, initialData.size() * sizeof(GLfloat), initialData.data(),
3983*8975f5c5SAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
3984*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
3985*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
3986*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3987*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
3988*8975f5c5SAndroid Build Coastguard Worker     const GLfloat *ptr      = reinterpret_cast<const GLfloat *>(glMapBufferRange(
3989*8975f5c5SAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BUFFER, 0, initialData.size() * sizeof(GLfloat), GL_MAP_READ_BIT));
3990*8975f5c5SAndroid Build Coastguard Worker     angle::Vector4 expected = textureData.toNormalizedVector();
3991*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NEAR(expected[0], ptr[0], 0.001);
3992*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NEAR(expected[1], ptr[1], 0.001);
3993*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NEAR(expected[2], ptr[2], 0.001);
3994*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NEAR(expected[3], ptr[3], 0.001);
3995*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
3996*8975f5c5SAndroid Build Coastguard Worker }
3997*8975f5c5SAndroid Build Coastguard Worker 
3998*8975f5c5SAndroid Build Coastguard Worker // Test that invalid memory barrier will produce an error.
TEST_P(ComputeShaderTest,InvalidMemoryBarrier)3999*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, InvalidMemoryBarrier)
4000*8975f5c5SAndroid Build Coastguard Worker {
4001*8975f5c5SAndroid Build Coastguard Worker     GLbitfield barriers = 0;
4002*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(barriers);
4003*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_VALUE);
4004*8975f5c5SAndroid Build Coastguard Worker }
4005*8975f5c5SAndroid Build Coastguard Worker 
4006*8975f5c5SAndroid Build Coastguard Worker // test atomic counter increment
4007*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42261924
TEST_P(ComputeShaderTest,AtomicCounterIncrement)4008*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AtomicCounterIncrement)
4009*8975f5c5SAndroid Build Coastguard Worker {
4010*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeShader[] = R"(#version 310 es
4011*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
4012*8975f5c5SAndroid Build Coastguard Worker layout(binding = 1, std430) buffer Output {
4013*8975f5c5SAndroid Build Coastguard Worker   uint preGet[1];
4014*8975f5c5SAndroid Build Coastguard Worker   uint increment[1];
4015*8975f5c5SAndroid Build Coastguard Worker   uint postGet[1];
4016*8975f5c5SAndroid Build Coastguard Worker } sb_in;
4017*8975f5c5SAndroid Build Coastguard Worker layout(binding=0) uniform atomic_uint counter0;
4018*8975f5c5SAndroid Build Coastguard Worker 
4019*8975f5c5SAndroid Build Coastguard Worker void main(void)
4020*8975f5c5SAndroid Build Coastguard Worker {
4021*8975f5c5SAndroid Build Coastguard Worker   uint id = (gl_GlobalInvocationID.x);
4022*8975f5c5SAndroid Build Coastguard Worker   sb_in.preGet[0u]    = atomicCounter(counter0);
4023*8975f5c5SAndroid Build Coastguard Worker   sb_in.increment[0u] = atomicCounterIncrement(counter0);
4024*8975f5c5SAndroid Build Coastguard Worker   sb_in.postGet[0u]   = atomicCounter(counter0);
4025*8975f5c5SAndroid Build Coastguard Worker }
4026*8975f5c5SAndroid Build Coastguard Worker )";
4027*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShader);
4028*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4029*8975f5c5SAndroid Build Coastguard Worker 
4030*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4031*8975f5c5SAndroid Build Coastguard Worker 
4032*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
4033*8975f5c5SAndroid Build Coastguard Worker 
4034*8975f5c5SAndroid Build Coastguard Worker     GLBuffer shaderStorageBuffer;
4035*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
4036*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, nullptr, GL_STATIC_DRAW);
4037*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
4038*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4039*8975f5c5SAndroid Build Coastguard Worker 
4040*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint atomicBufferInitialData[] = {2u};
4041*8975f5c5SAndroid Build Coastguard Worker     GLuint atomicBuffer;
4042*8975f5c5SAndroid Build Coastguard Worker     glGenBuffers(1, &atomicBuffer);
4043*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
4044*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(atomicBufferInitialData), atomicBufferInitialData,
4045*8975f5c5SAndroid Build Coastguard Worker                  GL_DYNAMIC_DRAW);
4046*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicBuffer);
4047*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4048*8975f5c5SAndroid Build Coastguard Worker 
4049*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4050*8975f5c5SAndroid Build Coastguard Worker     glFinish();
4051*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4052*8975f5c5SAndroid Build Coastguard Worker 
4053*8975f5c5SAndroid Build Coastguard Worker     // read back
4054*8975f5c5SAndroid Build Coastguard Worker     const GLuint *ptr = reinterpret_cast<const GLuint *>(
4055*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * kBytesPerComponent, GL_MAP_READ_BIT));
4056*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(2u, ptr[0]);
4057*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(2u, ptr[1]);
4058*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(3u, ptr[2]);
4059*8975f5c5SAndroid Build Coastguard Worker 
4060*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4061*8975f5c5SAndroid Build Coastguard Worker }
4062*8975f5c5SAndroid Build Coastguard Worker 
4063*8975f5c5SAndroid Build Coastguard Worker // Create a 'very large' array inside of a function in a compute shader.
TEST_P(ComputeShaderTest,VeryLargeArrayInsideFunction)4064*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, VeryLargeArrayInsideFunction)
4065*8975f5c5SAndroid Build Coastguard Worker {
4066*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeShader[] = R"(#version 310 es
4067*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
4068*8975f5c5SAndroid Build Coastguard Worker layout(binding = 0, std430) buffer Output {
4069*8975f5c5SAndroid Build Coastguard Worker   int value[1];
4070*8975f5c5SAndroid Build Coastguard Worker } output_data;
4071*8975f5c5SAndroid Build Coastguard Worker 
4072*8975f5c5SAndroid Build Coastguard Worker void main()
4073*8975f5c5SAndroid Build Coastguard Worker {
4074*8975f5c5SAndroid Build Coastguard Worker     int values[1000];
4075*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < values.length(); i++)
4076*8975f5c5SAndroid Build Coastguard Worker     {
4077*8975f5c5SAndroid Build Coastguard Worker         values[i] = 0;
4078*8975f5c5SAndroid Build Coastguard Worker     }
4079*8975f5c5SAndroid Build Coastguard Worker 
4080*8975f5c5SAndroid Build Coastguard Worker     int total = 0;
4081*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < values.length(); i++)
4082*8975f5c5SAndroid Build Coastguard Worker     {
4083*8975f5c5SAndroid Build Coastguard Worker         total += i;
4084*8975f5c5SAndroid Build Coastguard Worker         values[i] = total;
4085*8975f5c5SAndroid Build Coastguard Worker     }
4086*8975f5c5SAndroid Build Coastguard Worker     output_data.value[0u] = values[1000-1];
4087*8975f5c5SAndroid Build Coastguard Worker })";
4088*8975f5c5SAndroid Build Coastguard Worker 
4089*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShader);
4090*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4091*8975f5c5SAndroid Build Coastguard Worker 
4092*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4093*8975f5c5SAndroid Build Coastguard Worker 
4094*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned int kBytesPerComponent = sizeof(GLint);
4095*8975f5c5SAndroid Build Coastguard Worker 
4096*8975f5c5SAndroid Build Coastguard Worker     GLBuffer shaderStorageBuffer;
4097*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
4098*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, 1 * kBytesPerComponent, nullptr, GL_STATIC_DRAW);
4099*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
4100*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4101*8975f5c5SAndroid Build Coastguard Worker 
4102*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4103*8975f5c5SAndroid Build Coastguard Worker     glFinish();
4104*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4105*8975f5c5SAndroid Build Coastguard Worker 
4106*8975f5c5SAndroid Build Coastguard Worker     // read back
4107*8975f5c5SAndroid Build Coastguard Worker     const GLint *ptr = reinterpret_cast<const GLint *>(
4108*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 1 * kBytesPerComponent, GL_MAP_READ_BIT));
4109*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(499500, ptr[0]);
4110*8975f5c5SAndroid Build Coastguard Worker 
4111*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4112*8975f5c5SAndroid Build Coastguard Worker }
4113*8975f5c5SAndroid Build Coastguard Worker 
4114*8975f5c5SAndroid Build Coastguard Worker // Test that render pipeline and compute pipeline access to the same texture.
4115*8975f5c5SAndroid Build Coastguard Worker // Steps:
4116*8975f5c5SAndroid Build Coastguard Worker //   1. Clear the texture and DrawArrays.
4117*8975f5c5SAndroid Build Coastguard Worker //   2. DispatchCompute to set the image's first pixel to a specific color.
4118*8975f5c5SAndroid Build Coastguard Worker //   3. DrawArrays and check data.
TEST_P(ComputeShaderTest,DrawDispatchDrawPreserve)4119*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DrawDispatchDrawPreserve)
4120*8975f5c5SAndroid Build Coastguard Worker {
4121*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
4122*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
4123*8975f5c5SAndroid Build Coastguard Worker 
4124*8975f5c5SAndroid Build Coastguard Worker     const char kCSSource[] = R"(#version 310 es
4125*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1) in;
4126*8975f5c5SAndroid Build Coastguard Worker layout(rgba8, binding = 0) writeonly uniform highp image2D image;
4127*8975f5c5SAndroid Build Coastguard Worker void main()
4128*8975f5c5SAndroid Build Coastguard Worker {
4129*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(0, 0), vec4(0.0, 0.0, 1.0, 1.0));
4130*8975f5c5SAndroid Build Coastguard Worker })";
4131*8975f5c5SAndroid Build Coastguard Worker 
4132*8975f5c5SAndroid Build Coastguard Worker     const char kVSSource[] = R"(#version 310 es
4133*8975f5c5SAndroid Build Coastguard Worker layout (location = 0) in vec2 pos;
4134*8975f5c5SAndroid Build Coastguard Worker in vec4 inTex;
4135*8975f5c5SAndroid Build Coastguard Worker out vec4 texCoord;
4136*8975f5c5SAndroid Build Coastguard Worker void main(void) {
4137*8975f5c5SAndroid Build Coastguard Worker     texCoord = inTex;
4138*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 0.0, 1.0);
4139*8975f5c5SAndroid Build Coastguard Worker })";
4140*8975f5c5SAndroid Build Coastguard Worker 
4141*8975f5c5SAndroid Build Coastguard Worker     const char kFSSource[] = R"(#version 310 es
4142*8975f5c5SAndroid Build Coastguard Worker precision highp float;
4143*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
4144*8975f5c5SAndroid Build Coastguard Worker in vec4 texCoord;
4145*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
4146*8975f5c5SAndroid Build Coastguard Worker void main(void) {
4147*8975f5c5SAndroid Build Coastguard Worker     fragColor = texture(tex, texCoord.xy);
4148*8975f5c5SAndroid Build Coastguard Worker })";
4149*8975f5c5SAndroid Build Coastguard Worker     GLuint aPosLoc         = 0;
4150*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
4151*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, aPosLoc, "pos");
4152*8975f5c5SAndroid Build Coastguard Worker 
4153*8975f5c5SAndroid Build Coastguard Worker     unsigned char *data = new unsigned char[4 * getWindowWidth() * getWindowHeight()];
4154*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < getWindowWidth() * getWindowHeight(); i++)
4155*8975f5c5SAndroid Build Coastguard Worker     {
4156*8975f5c5SAndroid Build Coastguard Worker         data[i * 4]     = 0xff;
4157*8975f5c5SAndroid Build Coastguard Worker         data[i * 4 + 1] = 0;
4158*8975f5c5SAndroid Build Coastguard Worker         data[i * 4 + 2] = 0;
4159*8975f5c5SAndroid Build Coastguard Worker         data[i * 4 + 3] = 0xff;
4160*8975f5c5SAndroid Build Coastguard Worker     }
4161*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
4162*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
4163*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, getWindowWidth(), getWindowHeight());
4164*8975f5c5SAndroid Build Coastguard Worker     // Clear the texture level 0 to Red.
4165*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA,
4166*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, data);
4167*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < getWindowWidth() * getWindowHeight(); i++)
4168*8975f5c5SAndroid Build Coastguard Worker     {
4169*8975f5c5SAndroid Build Coastguard Worker         data[i * 4]     = 0;
4170*8975f5c5SAndroid Build Coastguard Worker         data[i * 4 + 1] = 0xff;
4171*8975f5c5SAndroid Build Coastguard Worker         data[i * 4 + 2] = 0;
4172*8975f5c5SAndroid Build Coastguard Worker         data[i * 4 + 3] = 0xff;
4173*8975f5c5SAndroid Build Coastguard Worker     }
4174*8975f5c5SAndroid Build Coastguard Worker     // Clear the texture level 1 to Green.
4175*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
4176*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, data);
4177*8975f5c5SAndroid Build Coastguard Worker     delete[] data;
4178*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4179*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4180*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4181*8975f5c5SAndroid Build Coastguard Worker     GLfloat vertices[]  = {-1, -1, 1, -1, -1, 1, 1, 1};
4182*8975f5c5SAndroid Build Coastguard Worker     GLfloat texCoords[] = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
4183*8975f5c5SAndroid Build Coastguard Worker     GLint pos           = glGetAttribLocation(program, "pos");
4184*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(pos);
4185*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(pos, 2, GL_FLOAT, GL_FALSE, 0, vertices);
4186*8975f5c5SAndroid Build Coastguard Worker     GLint posTex = glGetAttribLocation(program, "inTex");
4187*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(posTex);
4188*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(posTex, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
4189*8975f5c5SAndroid Build Coastguard Worker 
4190*8975f5c5SAndroid Build Coastguard Worker     // Draw with level 0, the whole framebuffer should be Red.
4191*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth(), getWindowHeight());
4192*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4193*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4194*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4195*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
4196*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
4197*8975f5c5SAndroid Build Coastguard Worker     // Draw with level 1, a quarter of the framebuffer should be Green.
4198*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight() / 2);
4199*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4200*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4201*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
4202*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2 - 1, getWindowHeight() / 2 - 1, GLColor::green);
4203*8975f5c5SAndroid Build Coastguard Worker 
4204*8975f5c5SAndroid Build Coastguard Worker     // Clear the texture level 0's (0, 0) position to Blue.
4205*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
4206*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
4207*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
4208*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4209*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
4210*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4211*8975f5c5SAndroid Build Coastguard Worker     glFinish();
4212*8975f5c5SAndroid Build Coastguard Worker 
4213*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4214*8975f5c5SAndroid Build Coastguard Worker     // Draw with level 0, the first position should be Blue.
4215*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth(), getWindowHeight());
4216*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4217*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
4218*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
4219*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
4220*8975f5c5SAndroid Build Coastguard Worker     // Draw with level 1, a quarter of the framebuffer should be Green.
4221*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight() / 2);
4222*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4223*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4224*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
4225*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2 - 1, getWindowHeight() / 2 - 1, GLColor::green);
4226*8975f5c5SAndroid Build Coastguard Worker }
4227*8975f5c5SAndroid Build Coastguard Worker 
4228*8975f5c5SAndroid Build Coastguard Worker // Test that maxComputeWorkGroupCount is valid number.
TEST_P(ComputeShaderTest,ValidateMaxComputeWorkGroupCount)4229*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ValidateMaxComputeWorkGroupCount)
4230*8975f5c5SAndroid Build Coastguard Worker {
4231*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
4232*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1) in;
4233*8975f5c5SAndroid Build Coastguard Worker void main()
4234*8975f5c5SAndroid Build Coastguard Worker {
4235*8975f5c5SAndroid Build Coastguard Worker })";
4236*8975f5c5SAndroid Build Coastguard Worker 
4237*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
4238*8975f5c5SAndroid Build Coastguard Worker     GLuint cs      = CompileShader(GL_COMPUTE_SHADER, kCS);
4239*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0u, cs);
4240*8975f5c5SAndroid Build Coastguard Worker 
4241*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, cs);
4242*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(cs);
4243*8975f5c5SAndroid Build Coastguard Worker 
4244*8975f5c5SAndroid Build Coastguard Worker     GLint x, y, z;
4245*8975f5c5SAndroid Build Coastguard Worker     glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &x);
4246*8975f5c5SAndroid Build Coastguard Worker     EXPECT_LE(65535, x);
4247*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GE(std::numeric_limits<GLint>::max(), x);
4248*8975f5c5SAndroid Build Coastguard Worker 
4249*8975f5c5SAndroid Build Coastguard Worker     glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &y);
4250*8975f5c5SAndroid Build Coastguard Worker     EXPECT_LE(65535, y);
4251*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GE(std::numeric_limits<GLint>::max(), y);
4252*8975f5c5SAndroid Build Coastguard Worker 
4253*8975f5c5SAndroid Build Coastguard Worker     glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &z);
4254*8975f5c5SAndroid Build Coastguard Worker     EXPECT_LE(65535, z);
4255*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GE(std::numeric_limits<GLint>::max(), z);
4256*8975f5c5SAndroid Build Coastguard Worker 
4257*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
4258*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4259*8975f5c5SAndroid Build Coastguard Worker }
4260*8975f5c5SAndroid Build Coastguard Worker 
4261*8975f5c5SAndroid Build Coastguard Worker // Validate that on Vulkan, compute pipeline driver uniforms descriptor set is updated after an
4262*8975f5c5SAndroid Build Coastguard Worker // internal compute-based UtilsVk function is used.  The latter is achieved through a draw with a
4263*8975f5c5SAndroid Build Coastguard Worker // vertex buffer whose format is not natively supported.  Atomic counters are used to make sure the
4264*8975f5c5SAndroid Build Coastguard Worker // compute pipeline uses the driver uniforms descriptor set.
TEST_P(ComputeShaderTest,DispatchConvertVertexDispatch)4265*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchConvertVertexDispatch)
4266*8975f5c5SAndroid Build Coastguard Worker {
4267*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_vertex_type_10_10_10_2"));
4268*8975f5c5SAndroid Build Coastguard Worker 
4269*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t kVertexCount = 6;
4270*8975f5c5SAndroid Build Coastguard Worker 
4271*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
4272*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=6, local_size_y=1, local_size_z=1) in;
4273*8975f5c5SAndroid Build Coastguard Worker 
4274*8975f5c5SAndroid Build Coastguard Worker layout(binding = 0) uniform atomic_uint ac;
4275*8975f5c5SAndroid Build Coastguard Worker 
4276*8975f5c5SAndroid Build Coastguard Worker layout(binding=0, std140) buffer VertexData
4277*8975f5c5SAndroid Build Coastguard Worker {
4278*8975f5c5SAndroid Build Coastguard Worker     uint data[];
4279*8975f5c5SAndroid Build Coastguard Worker };
4280*8975f5c5SAndroid Build Coastguard Worker 
4281*8975f5c5SAndroid Build Coastguard Worker void main()
4282*8975f5c5SAndroid Build Coastguard Worker {
4283*8975f5c5SAndroid Build Coastguard Worker     atomicCounterIncrement(ac);
4284*8975f5c5SAndroid Build Coastguard Worker     data[gl_GlobalInvocationID.x] = gl_GlobalInvocationID.x;
4285*8975f5c5SAndroid Build Coastguard Worker })";
4286*8975f5c5SAndroid Build Coastguard Worker 
4287*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 310 es
4288*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
4289*8975f5c5SAndroid Build Coastguard Worker 
4290*8975f5c5SAndroid Build Coastguard Worker layout(location = 0) in vec4 position;
4291*8975f5c5SAndroid Build Coastguard Worker layout(location = 1) in uvec4 data;
4292*8975f5c5SAndroid Build Coastguard Worker 
4293*8975f5c5SAndroid Build Coastguard Worker out vec4 color;
4294*8975f5c5SAndroid Build Coastguard Worker 
4295*8975f5c5SAndroid Build Coastguard Worker void main() {
4296*8975f5c5SAndroid Build Coastguard Worker     color = data.x < 6u && data.y == 0u && data.z == 0u && data.w == 0u
4297*8975f5c5SAndroid Build Coastguard Worker         ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
4298*8975f5c5SAndroid Build Coastguard Worker     gl_Position = position;
4299*8975f5c5SAndroid Build Coastguard Worker })";
4300*8975f5c5SAndroid Build Coastguard Worker 
4301*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 310 es
4302*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
4303*8975f5c5SAndroid Build Coastguard Worker in vec4 color;
4304*8975f5c5SAndroid Build Coastguard Worker out vec4 colorOut;
4305*8975f5c5SAndroid Build Coastguard Worker void main() {
4306*8975f5c5SAndroid Build Coastguard Worker     colorOut = color;
4307*8975f5c5SAndroid Build Coastguard Worker })";
4308*8975f5c5SAndroid Build Coastguard Worker 
4309*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(programCS, kCS);
4310*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(programVSFS, kVS, kFS);
4311*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4312*8975f5c5SAndroid Build Coastguard Worker 
4313*8975f5c5SAndroid Build Coastguard Worker     // Create atomic counter buffer
4314*8975f5c5SAndroid Build Coastguard Worker     GLBuffer atomicCounterBuffer;
4315*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kInitialAcbData = 0;
4316*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
4317*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(kInitialAcbData), &kInitialAcbData,
4318*8975f5c5SAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
4319*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
4320*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4321*8975f5c5SAndroid Build Coastguard Worker 
4322*8975f5c5SAndroid Build Coastguard Worker     // Create vertex buffer
4323*8975f5c5SAndroid Build Coastguard Worker     constexpr unsigned kVertexBufferInitData[kVertexCount] = {};
4324*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
4325*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, vertexBuffer);
4326*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kVertexBufferInitData), kVertexBufferInitData,
4327*8975f5c5SAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
4328*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vertexBuffer);
4329*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4330*8975f5c5SAndroid Build Coastguard Worker 
4331*8975f5c5SAndroid Build Coastguard Worker     // Create position buffer
4332*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat positions[kVertexCount * 2] = {1.0, 1.0, -1.0, 1.0,  -1.0, -1.0,
4333*8975f5c5SAndroid Build Coastguard Worker                                                      1.0, 1.0, -1.0, -1.0, 1.0,  -1.0};
4334*8975f5c5SAndroid Build Coastguard Worker     GLBuffer positionBuffer;
4335*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
4336*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
4337*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4338*8975f5c5SAndroid Build Coastguard Worker 
4339*8975f5c5SAndroid Build Coastguard Worker     // Create vertex array
4340*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao;
4341*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(vao);
4342*8975f5c5SAndroid Build Coastguard Worker 
4343*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
4344*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(0);
4345*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
4346*8975f5c5SAndroid Build Coastguard Worker 
4347*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
4348*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(1);
4349*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(1, 4, GL_UNSIGNED_INT_10_10_10_2_OES, false, 0, 0);
4350*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4351*8975f5c5SAndroid Build Coastguard Worker 
4352*8975f5c5SAndroid Build Coastguard Worker     // Fill the vertex buffer with a dispatch call
4353*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(programCS);
4354*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4355*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4356*8975f5c5SAndroid Build Coastguard Worker 
4357*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
4358*8975f5c5SAndroid Build Coastguard Worker 
4359*8975f5c5SAndroid Build Coastguard Worker     // Draw using the vertex buffer, causing vertex format conversion in compute (in the Vulkan
4360*8975f5c5SAndroid Build Coastguard Worker     // backend)
4361*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(programVSFS);
4362*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(vao);
4363*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, kVertexCount);
4364*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4365*8975f5c5SAndroid Build Coastguard Worker 
4366*8975f5c5SAndroid Build Coastguard Worker     // Issue another dispatch call. The driver uniforms descriptor set must be rebound.
4367*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(programCS);
4368*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4369*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4370*8975f5c5SAndroid Build Coastguard Worker 
4371*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4372*8975f5c5SAndroid Build Coastguard Worker 
4373*8975f5c5SAndroid Build Coastguard Worker     // Verify that the atomic counter has the expected value.
4374*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
4375*8975f5c5SAndroid Build Coastguard Worker     GLuint *mappedBuffer = static_cast<GLuint *>(
4376*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT));
4377*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(kVertexCount * 2, mappedBuffer[0]);
4378*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
4379*8975f5c5SAndroid Build Coastguard Worker }
4380*8975f5c5SAndroid Build Coastguard Worker 
4381*8975f5c5SAndroid Build Coastguard Worker // Validate that on Vulkan, compute pipeline is correctly bound after an internal dispatch call is
4382*8975f5c5SAndroid Build Coastguard Worker // made.  Blit stencil may issue a dispatch call.
TEST_P(ComputeShaderTest,DispatchBlitStencilDispatch)4383*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchBlitStencilDispatch)
4384*8975f5c5SAndroid Build Coastguard Worker {
4385*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264069
4386*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
4387*8975f5c5SAndroid Build Coastguard Worker 
4388*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263641
4389*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
4390*8975f5c5SAndroid Build Coastguard Worker 
4391*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kSize = 1;
4392*8975f5c5SAndroid Build Coastguard Worker 
4393*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
4394*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=6, local_size_y=1, local_size_z=1) in;
4395*8975f5c5SAndroid Build Coastguard Worker 
4396*8975f5c5SAndroid Build Coastguard Worker uniform vec4 data;
4397*8975f5c5SAndroid Build Coastguard Worker 
4398*8975f5c5SAndroid Build Coastguard Worker layout(rgba8, binding = 0) writeonly uniform highp image2D image;
4399*8975f5c5SAndroid Build Coastguard Worker 
4400*8975f5c5SAndroid Build Coastguard Worker void main()
4401*8975f5c5SAndroid Build Coastguard Worker {
4402*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), data);
4403*8975f5c5SAndroid Build Coastguard Worker })";
4404*8975f5c5SAndroid Build Coastguard Worker 
4405*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(programCS, kCS);
4406*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4407*8975f5c5SAndroid Build Coastguard Worker 
4408*8975f5c5SAndroid Build Coastguard Worker     // Create a framebuffer with stencil buffer.  Use multisampled textures so the future blit
4409*8975f5c5SAndroid Build Coastguard Worker     // cannot use vkCmdBlitImage.
4410*8975f5c5SAndroid Build Coastguard Worker     GLTexture color;
4411*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, color);
4412*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, true);
4413*8975f5c5SAndroid Build Coastguard Worker 
4414*8975f5c5SAndroid Build Coastguard Worker     GLTexture depthStencil;
4415*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, depthStencil);
4416*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_DEPTH24_STENCIL8, kSize, kSize,
4417*8975f5c5SAndroid Build Coastguard Worker                               true);
4418*8975f5c5SAndroid Build Coastguard Worker 
4419*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
4420*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4421*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, color,
4422*8975f5c5SAndroid Build Coastguard Worker                            0);
4423*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
4424*8975f5c5SAndroid Build Coastguard Worker                            depthStencil, 0);
4425*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4426*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4427*8975f5c5SAndroid Build Coastguard Worker 
4428*8975f5c5SAndroid Build Coastguard Worker     // Clear the stencil and make sure it's done.
4429*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4430*8975f5c5SAndroid Build Coastguard Worker     glClearStencil(0x55);
4431*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4432*8975f5c5SAndroid Build Coastguard Worker 
4433*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_STENCIL_TEST);
4434*8975f5c5SAndroid Build Coastguard Worker     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
4435*8975f5c5SAndroid Build Coastguard Worker     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
4436*8975f5c5SAndroid Build Coastguard Worker     glStencilMask(0xFF);
4437*8975f5c5SAndroid Build Coastguard Worker 
4438*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
4439*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
4440*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4441*8975f5c5SAndroid Build Coastguard Worker 
4442*8975f5c5SAndroid Build Coastguard Worker     GLTexture colorCopy;
4443*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, colorCopy);
4444*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4445*8975f5c5SAndroid Build Coastguard Worker 
4446*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer copyFbo;
4447*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, copyFbo);
4448*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorCopy, 0);
4449*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
4450*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
4451*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4452*8975f5c5SAndroid Build Coastguard Worker 
4453*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, copyFbo);
4454*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4455*8975f5c5SAndroid Build Coastguard Worker 
4456*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4457*8975f5c5SAndroid Build Coastguard Worker 
4458*8975f5c5SAndroid Build Coastguard Worker     // Setup image for compute call
4459*8975f5c5SAndroid Build Coastguard Worker     GLTexture computeOut;
4460*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, computeOut);
4461*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4462*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, computeOut, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
4463*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4464*8975f5c5SAndroid Build Coastguard Worker 
4465*8975f5c5SAndroid Build Coastguard Worker     // Issue a dispatch call.
4466*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(programCS);
4467*8975f5c5SAndroid Build Coastguard Worker     GLint uniformLoc = glGetUniformLocation(programCS, "data");
4468*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(uniformLoc, -1);
4469*8975f5c5SAndroid Build Coastguard Worker 
4470*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(uniformLoc, 0.0f, 0.0f, 1.0f, 1.0f);
4471*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4472*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
4473*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4474*8975f5c5SAndroid Build Coastguard Worker 
4475*8975f5c5SAndroid Build Coastguard Worker     // Blit the stencil texture.  This may use a compute shader internally.
4476*8975f5c5SAndroid Build Coastguard Worker     GLTexture depthStencilCopy;
4477*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, depthStencilCopy);
4478*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
4479*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4480*8975f5c5SAndroid Build Coastguard Worker 
4481*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, copyFbo);
4482*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
4483*8975f5c5SAndroid Build Coastguard Worker                            depthStencilCopy, 0);
4484*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
4485*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4486*8975f5c5SAndroid Build Coastguard Worker 
4487*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
4488*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4489*8975f5c5SAndroid Build Coastguard Worker 
4490*8975f5c5SAndroid Build Coastguard Worker     // Issue another dispatch call.
4491*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(uniformLoc, 0.0f, 1.0f, 0.0f, 1.0f);
4492*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4493*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4494*8975f5c5SAndroid Build Coastguard Worker 
4495*8975f5c5SAndroid Build Coastguard Worker     // Verify the results.
4496*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
4497*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, copyFbo);
4498*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, computeOut);
4499*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, computeOut, 0);
4500*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4501*8975f5c5SAndroid Build Coastguard Worker 
4502*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4503*8975f5c5SAndroid Build Coastguard Worker 
4504*8975f5c5SAndroid Build Coastguard Worker     // Verify the blit copy results.
4505*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
4506*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4507*8975f5c5SAndroid Build Coastguard Worker 
4508*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4509*8975f5c5SAndroid Build Coastguard Worker }
4510*8975f5c5SAndroid Build Coastguard Worker 
4511*8975f5c5SAndroid Build Coastguard Worker // Validate that on Vulkan, compute pipeline is correctly bound after an internal dispatch call is
4512*8975f5c5SAndroid Build Coastguard Worker // made.  Generate mipmap may issue a dispatch call.
TEST_P(ComputeShaderTest,DispatchGenerateMipmapDispatch)4513*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DispatchGenerateMipmapDispatch)
4514*8975f5c5SAndroid Build Coastguard Worker {
4515*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kSize = 8;
4516*8975f5c5SAndroid Build Coastguard Worker 
4517*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
4518*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=6, local_size_y=1, local_size_z=1) in;
4519*8975f5c5SAndroid Build Coastguard Worker 
4520*8975f5c5SAndroid Build Coastguard Worker uniform vec4 data;
4521*8975f5c5SAndroid Build Coastguard Worker 
4522*8975f5c5SAndroid Build Coastguard Worker layout(rgba8, binding = 0) writeonly uniform highp image2D image;
4523*8975f5c5SAndroid Build Coastguard Worker 
4524*8975f5c5SAndroid Build Coastguard Worker void main()
4525*8975f5c5SAndroid Build Coastguard Worker {
4526*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), data);
4527*8975f5c5SAndroid Build Coastguard Worker })";
4528*8975f5c5SAndroid Build Coastguard Worker 
4529*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(programCS, kCS);
4530*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4531*8975f5c5SAndroid Build Coastguard Worker 
4532*8975f5c5SAndroid Build Coastguard Worker     GLTexture color;
4533*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, color);
4534*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 4, GL_RGBA8, kSize, kSize);
4535*8975f5c5SAndroid Build Coastguard Worker 
4536*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLColor> kInitialColor(kSize * kSize, GLColor::green);
4537*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE,
4538*8975f5c5SAndroid Build Coastguard Worker                     kInitialColor.data());
4539*8975f5c5SAndroid Build Coastguard Worker 
4540*8975f5c5SAndroid Build Coastguard Worker     // Setup image for compute call
4541*8975f5c5SAndroid Build Coastguard Worker     GLTexture computeOut;
4542*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, computeOut);
4543*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4544*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, computeOut, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
4545*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4546*8975f5c5SAndroid Build Coastguard Worker 
4547*8975f5c5SAndroid Build Coastguard Worker     // Issue a dispatch call.
4548*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(programCS);
4549*8975f5c5SAndroid Build Coastguard Worker     GLint uniformLoc = glGetUniformLocation(programCS, "data");
4550*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(uniformLoc, -1);
4551*8975f5c5SAndroid Build Coastguard Worker 
4552*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(uniformLoc, 0.0f, 0.0f, 1.0f, 1.0f);
4553*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4554*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
4555*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4556*8975f5c5SAndroid Build Coastguard Worker 
4557*8975f5c5SAndroid Build Coastguard Worker     // Generate mipmap on the texture.  This may use a compute shader internally.
4558*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, color);
4559*8975f5c5SAndroid Build Coastguard Worker     glGenerateMipmap(GL_TEXTURE_2D);
4560*8975f5c5SAndroid Build Coastguard Worker 
4561*8975f5c5SAndroid Build Coastguard Worker     // Issue another dispatch call.
4562*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(uniformLoc, 0.0f, 1.0f, 0.0f, 1.0f);
4563*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4564*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4565*8975f5c5SAndroid Build Coastguard Worker 
4566*8975f5c5SAndroid Build Coastguard Worker     // Verify the results.
4567*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
4568*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4569*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, computeOut);
4570*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, computeOut, 0);
4571*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4572*8975f5c5SAndroid Build Coastguard Worker 
4573*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
4574*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4575*8975f5c5SAndroid Build Coastguard Worker }
4576*8975f5c5SAndroid Build Coastguard Worker 
4577*8975f5c5SAndroid Build Coastguard Worker // Write to image array with an aliasing format.
TEST_P(ComputeShaderTest,AliasingFormatForImageArray)4578*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AliasingFormatForImageArray)
4579*8975f5c5SAndroid Build Coastguard Worker {
4580*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263894
4581*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
4582*8975f5c5SAndroid Build Coastguard Worker 
4583*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
4584*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=2) in;
4585*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) writeonly uniform highp uimage2DArray image;
4586*8975f5c5SAndroid Build Coastguard Worker void main()
4587*8975f5c5SAndroid Build Coastguard Worker {
4588*8975f5c5SAndroid Build Coastguard Worker     uint yellow = 0xFF00FFFFu;
4589*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec3(gl_LocalInvocationID.xyz), uvec4(yellow, 0, 0, 0));
4590*8975f5c5SAndroid Build Coastguard Worker })";
4591*8975f5c5SAndroid Build Coastguard Worker 
4592*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
4593*8975f5c5SAndroid Build Coastguard Worker 
4594*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLColor> kInitData(kWidth * kHeight * kDepth, GLColor::black);
4595*8975f5c5SAndroid Build Coastguard Worker 
4596*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
4597*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
4598*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4599*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RGBA,
4600*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, kInitData.data());
4601*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4602*8975f5c5SAndroid Build Coastguard Worker 
4603*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
4604*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4605*8975f5c5SAndroid Build Coastguard Worker 
4606*8975f5c5SAndroid Build Coastguard Worker     // Output yellow to both layers.
4607*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
4608*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4609*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4610*8975f5c5SAndroid Build Coastguard Worker 
4611*8975f5c5SAndroid Build Coastguard Worker     // Verify results.
4612*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
4613*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4614*8975f5c5SAndroid Build Coastguard Worker 
4615*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
4616*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
4617*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, 0);
4618*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture, 0, 1);
4619*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4620*8975f5c5SAndroid Build Coastguard Worker 
4621*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
4622*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
4623*8975f5c5SAndroid Build Coastguard Worker 
4624*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
4625*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
4626*8975f5c5SAndroid Build Coastguard Worker }
4627*8975f5c5SAndroid Build Coastguard Worker 
4628*8975f5c5SAndroid Build Coastguard Worker // Write to one layer of image array with an aliasing format.
TEST_P(ComputeShaderTest,AliasingFormatForOneLayerOfImageArray)4629*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AliasingFormatForOneLayerOfImageArray)
4630*8975f5c5SAndroid Build Coastguard Worker {
4631*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263894
4632*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
4633*8975f5c5SAndroid Build Coastguard Worker 
4634*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
4635*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
4636*8975f5c5SAndroid Build Coastguard Worker layout(r32ui, binding = 0) writeonly uniform highp uimage2D image;
4637*8975f5c5SAndroid Build Coastguard Worker void main()
4638*8975f5c5SAndroid Build Coastguard Worker {
4639*8975f5c5SAndroid Build Coastguard Worker     uint yellow = 0xFF00FFFFu;
4640*8975f5c5SAndroid Build Coastguard Worker     imageStore(image, ivec2(gl_LocalInvocationID.xy), uvec4(yellow, 0, 0, 0));
4641*8975f5c5SAndroid Build Coastguard Worker })";
4642*8975f5c5SAndroid Build Coastguard Worker 
4643*8975f5c5SAndroid Build Coastguard Worker     constexpr int kWidth = 1, kHeight = 1, kDepth = 2;
4644*8975f5c5SAndroid Build Coastguard Worker 
4645*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLColor> kInitData(kWidth * kHeight * kDepth, GLColor::black);
4646*8975f5c5SAndroid Build Coastguard Worker 
4647*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
4648*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
4649*8975f5c5SAndroid Build Coastguard Worker     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4650*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RGBA,
4651*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, kInitData.data());
4652*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4653*8975f5c5SAndroid Build Coastguard Worker 
4654*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
4655*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
4656*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, 0);
4657*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture, 0, 1);
4658*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4659*8975f5c5SAndroid Build Coastguard Worker 
4660*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
4661*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4662*8975f5c5SAndroid Build Coastguard Worker 
4663*8975f5c5SAndroid Build Coastguard Worker     // Output yellow to layer 0.
4664*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
4665*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4666*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4667*8975f5c5SAndroid Build Coastguard Worker 
4668*8975f5c5SAndroid Build Coastguard Worker     // Verify that only layer 0 was changed.
4669*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
4670*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4671*8975f5c5SAndroid Build Coastguard Worker 
4672*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
4673*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
4674*8975f5c5SAndroid Build Coastguard Worker 
4675*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
4676*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4677*8975f5c5SAndroid Build Coastguard Worker 
4678*8975f5c5SAndroid Build Coastguard Worker     // Reset texture back to black.
4679*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RGBA,
4680*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, kInitData.data());
4681*8975f5c5SAndroid Build Coastguard Worker 
4682*8975f5c5SAndroid Build Coastguard Worker     // Output yellow to layer 1.
4683*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 1, GL_WRITE_ONLY, GL_R32UI);
4684*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4685*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4686*8975f5c5SAndroid Build Coastguard Worker 
4687*8975f5c5SAndroid Build Coastguard Worker     // Verify that only layer 1 was changed.
4688*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
4689*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4690*8975f5c5SAndroid Build Coastguard Worker 
4691*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
4692*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4693*8975f5c5SAndroid Build Coastguard Worker 
4694*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
4695*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
4696*8975f5c5SAndroid Build Coastguard Worker }
4697*8975f5c5SAndroid Build Coastguard Worker 
4698*8975f5c5SAndroid Build Coastguard Worker // Test glMemoryBarrier(CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT) by writing to persistenly mapped
4699*8975f5c5SAndroid Build Coastguard Worker // buffer from a compute shader.
TEST_P(ComputeShaderTest,WriteToPersistentBuffer)4700*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, WriteToPersistentBuffer)
4701*8975f5c5SAndroid Build Coastguard Worker {
4702*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_buffer_storage"));
4703*8975f5c5SAndroid Build Coastguard Worker 
4704*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCS[] = R"(#version 310 es
4705*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
4706*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding = 0) buffer block {
4707*8975f5c5SAndroid Build Coastguard Worker     uvec4 data;
4708*8975f5c5SAndroid Build Coastguard Worker } outBlock;
4709*8975f5c5SAndroid Build Coastguard Worker void main()
4710*8975f5c5SAndroid Build Coastguard Worker {
4711*8975f5c5SAndroid Build Coastguard Worker     outBlock.data += uvec4(1);
4712*8975f5c5SAndroid Build Coastguard Worker })";
4713*8975f5c5SAndroid Build Coastguard Worker 
4714*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
4715*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4716*8975f5c5SAndroid Build Coastguard Worker 
4717*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<uint32_t, 4> kInitData = {};
4718*8975f5c5SAndroid Build Coastguard Worker 
4719*8975f5c5SAndroid Build Coastguard Worker     GLBuffer coherentBuffer;
4720*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, coherentBuffer);
4721*8975f5c5SAndroid Build Coastguard Worker     glBufferStorageEXT(
4722*8975f5c5SAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BUFFER, sizeof(kInitData), kInitData.data(),
4723*8975f5c5SAndroid Build Coastguard Worker         GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT);
4724*8975f5c5SAndroid Build Coastguard Worker 
4725*8975f5c5SAndroid Build Coastguard Worker     GLBuffer nonCoherentBuffer;
4726*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, nonCoherentBuffer);
4727*8975f5c5SAndroid Build Coastguard Worker     glBufferStorageEXT(GL_SHADER_STORAGE_BUFFER, sizeof(kInitData), kInitData.data(),
4728*8975f5c5SAndroid Build Coastguard Worker                        GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT_EXT);
4729*8975f5c5SAndroid Build Coastguard Worker 
4730*8975f5c5SAndroid Build Coastguard Worker     // Map the buffers for read and write.
4731*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, coherentBuffer);
4732*8975f5c5SAndroid Build Coastguard Worker     uint32_t *coherentMapped = reinterpret_cast<uint32_t *>(glMapBufferRange(
4733*8975f5c5SAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BUFFER, 0, sizeof(kInitData),
4734*8975f5c5SAndroid Build Coastguard Worker         GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT));
4735*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4736*8975f5c5SAndroid Build Coastguard Worker 
4737*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, nonCoherentBuffer);
4738*8975f5c5SAndroid Build Coastguard Worker     uint32_t *nonCoherentMapped = reinterpret_cast<uint32_t *>(
4739*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kInitData),
4740*8975f5c5SAndroid Build Coastguard Worker                          GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT_EXT));
4741*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
4742*8975f5c5SAndroid Build Coastguard Worker 
4743*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<uint32_t, 4> kCoherentExpectedData = {
4744*8975f5c5SAndroid Build Coastguard Worker         0x12354678u,
4745*8975f5c5SAndroid Build Coastguard Worker         0x2468ACE0u,
4746*8975f5c5SAndroid Build Coastguard Worker         0x13579BDFu,
4747*8975f5c5SAndroid Build Coastguard Worker         0x76543210u,
4748*8975f5c5SAndroid Build Coastguard Worker     };
4749*8975f5c5SAndroid Build Coastguard Worker 
4750*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<uint32_t, 4> kNonCoherentExpectedData = {
4751*8975f5c5SAndroid Build Coastguard Worker         0x9ABCDEF0u,
4752*8975f5c5SAndroid Build Coastguard Worker         0xFDB97531u,
4753*8975f5c5SAndroid Build Coastguard Worker         0x1F2E3D4Bu,
4754*8975f5c5SAndroid Build Coastguard Worker         0x5A697887u,
4755*8975f5c5SAndroid Build Coastguard Worker     };
4756*8975f5c5SAndroid Build Coastguard Worker 
4757*8975f5c5SAndroid Build Coastguard Worker     coherentMapped[0] = kCoherentExpectedData[0] - 1;
4758*8975f5c5SAndroid Build Coastguard Worker     coherentMapped[1] = kCoherentExpectedData[1] - 1;
4759*8975f5c5SAndroid Build Coastguard Worker     coherentMapped[2] = kCoherentExpectedData[2] - 1;
4760*8975f5c5SAndroid Build Coastguard Worker     coherentMapped[3] = kCoherentExpectedData[3] - 1;
4761*8975f5c5SAndroid Build Coastguard Worker 
4762*8975f5c5SAndroid Build Coastguard Worker     nonCoherentMapped[0] = kNonCoherentExpectedData[0] - 1;
4763*8975f5c5SAndroid Build Coastguard Worker     nonCoherentMapped[1] = kNonCoherentExpectedData[1] - 1;
4764*8975f5c5SAndroid Build Coastguard Worker     nonCoherentMapped[2] = kNonCoherentExpectedData[2] - 1;
4765*8975f5c5SAndroid Build Coastguard Worker     nonCoherentMapped[3] = kNonCoherentExpectedData[3] - 1;
4766*8975f5c5SAndroid Build Coastguard Worker 
4767*8975f5c5SAndroid Build Coastguard Worker     // Test coherent write
4768*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, coherentBuffer);
4769*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4770*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4771*8975f5c5SAndroid Build Coastguard Worker 
4772*8975f5c5SAndroid Build Coastguard Worker     glFinish();
4773*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(coherentMapped[0], kCoherentExpectedData[0]);
4774*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(coherentMapped[1], kCoherentExpectedData[1]);
4775*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(coherentMapped[2], kCoherentExpectedData[2]);
4776*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(coherentMapped[3], kCoherentExpectedData[3]);
4777*8975f5c5SAndroid Build Coastguard Worker 
4778*8975f5c5SAndroid Build Coastguard Worker     // Test non-coherent write
4779*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, nonCoherentBuffer);
4780*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4781*8975f5c5SAndroid Build Coastguard Worker 
4782*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT);
4783*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4784*8975f5c5SAndroid Build Coastguard Worker 
4785*8975f5c5SAndroid Build Coastguard Worker     glFinish();
4786*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(nonCoherentMapped[0], kNonCoherentExpectedData[0]);
4787*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(nonCoherentMapped[1], kNonCoherentExpectedData[1]);
4788*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(nonCoherentMapped[2], kNonCoherentExpectedData[2]);
4789*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(nonCoherentMapped[3], kNonCoherentExpectedData[3]);
4790*8975f5c5SAndroid Build Coastguard Worker 
4791*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, coherentBuffer);
4792*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4793*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, nonCoherentBuffer);
4794*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4795*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4796*8975f5c5SAndroid Build Coastguard Worker }
4797*8975f5c5SAndroid Build Coastguard Worker 
4798*8975f5c5SAndroid Build Coastguard Worker // Verify the CS doesn't overwrite the mapped buffer data.
TEST_P(ComputeShaderTest,ImageBufferMapWrite)4799*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageBufferMapWrite)
4800*8975f5c5SAndroid Build Coastguard Worker {
4801*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
4802*8975f5c5SAndroid Build Coastguard Worker 
4803*8975f5c5SAndroid Build Coastguard Worker     // Claims to support GL_OES_texture_buffer, but fails compilation of shader because "extension
4804*8975f5c5SAndroid Build Coastguard Worker     // 'GL_OES_texture_buffer' is not supported".  http://anglebug.com/42264369
4805*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
4806*8975f5c5SAndroid Build Coastguard Worker 
4807*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeImageBuffer[] = R"(#version 310 es
4808*8975f5c5SAndroid Build Coastguard Worker #extension GL_OES_texture_buffer : require
4809*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
4810*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
4811*8975f5c5SAndroid Build Coastguard Worker uniform vec4 uniformData;
4812*8975f5c5SAndroid Build Coastguard Worker void main()
4813*8975f5c5SAndroid Build Coastguard Worker {
4814*8975f5c5SAndroid Build Coastguard Worker     imageStore(dst, int(gl_GlobalInvocationID.x), uniformData);
4815*8975f5c5SAndroid Build Coastguard Worker })";
4816*8975f5c5SAndroid Build Coastguard Worker 
4817*8975f5c5SAndroid Build Coastguard Worker     GLProgram program;
4818*8975f5c5SAndroid Build Coastguard Worker     program.makeCompute(kComputeImageBuffer);
4819*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4820*8975f5c5SAndroid Build Coastguard Worker 
4821*8975f5c5SAndroid Build Coastguard Worker     GLBuffer textureBufferStorage;
4822*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
4823*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<float, 4> kInitData = {1.0, 0.0, 0.0, 1.0};
4824*8975f5c5SAndroid Build Coastguard Worker 
4825*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_TEXTURE_BUFFER, textureBufferStorage);
4826*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_TEXTURE_BUFFER, sizeof(kInitData), kInitData.data(), GL_STATIC_DRAW);
4827*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4828*8975f5c5SAndroid Build Coastguard Worker 
4829*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_BUFFER, texture);
4830*8975f5c5SAndroid Build Coastguard Worker     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, textureBufferStorage);
4831*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
4832*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4833*8975f5c5SAndroid Build Coastguard Worker 
4834*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<float, 4> kComputeShaderData = {0.0, 1.0, 0.0, 1.0};
4835*8975f5c5SAndroid Build Coastguard Worker     GLint uniformLocation = glGetUniformLocation(program, "uniformData");
4836*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(uniformLocation, -1);
4837*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(uniformLocation, kComputeShaderData[0], kComputeShaderData[1],
4838*8975f5c5SAndroid Build Coastguard Worker                 kComputeShaderData[2], kComputeShaderData[3]);
4839*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
4840*8975f5c5SAndroid Build Coastguard Worker 
4841*8975f5c5SAndroid Build Coastguard Worker     // Write to the buffer with the CS.
4842*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
4843*8975f5c5SAndroid Build Coastguard Worker 
4844*8975f5c5SAndroid Build Coastguard Worker     // Issue the appropriate memory barrier before mapping the buffer.
4845*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4846*8975f5c5SAndroid Build Coastguard Worker 
4847*8975f5c5SAndroid Build Coastguard Worker     // Map the buffer and write to it.
4848*8975f5c5SAndroid Build Coastguard Worker     constexpr std::array<float, 4> kMapData = {0.0, 0.0, 1.0, 1.0};
4849*8975f5c5SAndroid Build Coastguard Worker     void *mappedBuffer =
4850*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_WRITE_BIT);
4851*8975f5c5SAndroid Build Coastguard Worker     memcpy(mappedBuffer, kMapData.data(), sizeof(kMapData));
4852*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_TEXTURE_BUFFER);
4853*8975f5c5SAndroid Build Coastguard Worker 
4854*8975f5c5SAndroid Build Coastguard Worker     glFinish();
4855*8975f5c5SAndroid Build Coastguard Worker 
4856*8975f5c5SAndroid Build Coastguard Worker     // Read back and verify buffer data.
4857*8975f5c5SAndroid Build Coastguard Worker     std::array<float, 4> bufferData = {0};
4858*8975f5c5SAndroid Build Coastguard Worker     mappedBuffer = glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(GLuint) * 3, GL_MAP_READ_BIT);
4859*8975f5c5SAndroid Build Coastguard Worker     memcpy(bufferData.data(), mappedBuffer, sizeof(bufferData));
4860*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_TEXTURE_BUFFER);
4861*8975f5c5SAndroid Build Coastguard Worker 
4862*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(bufferData[0], kMapData[0]);
4863*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(bufferData[1], kMapData[1]);
4864*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(bufferData[2], kMapData[2]);
4865*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(bufferData[3], kMapData[3]);
4866*8975f5c5SAndroid Build Coastguard Worker }
4867*8975f5c5SAndroid Build Coastguard Worker 
4868*8975f5c5SAndroid Build Coastguard Worker // Test compute shader write to texture buffer followed by texSubData and followed by compute shader
4869*8975f5c5SAndroid Build Coastguard Worker // write to texture buffer again.
TEST_P(ComputeShaderTest,ImageBufferMapWriteAndBufferSubData)4870*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, ImageBufferMapWriteAndBufferSubData)
4871*8975f5c5SAndroid Build Coastguard Worker {
4872*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
4873*8975f5c5SAndroid Build Coastguard Worker 
4874*8975f5c5SAndroid Build Coastguard Worker     // Claims to support GL_OES_texture_buffer, but fails compilation of shader because "extension
4875*8975f5c5SAndroid Build Coastguard Worker     // 'GL_OES_texture_buffer' is not supported".  http://anglebug.com/42264369
4876*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
4877*8975f5c5SAndroid Build Coastguard Worker 
4878*8975f5c5SAndroid Build Coastguard Worker     // angleporject:6545. Known bug.
4879*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan());
4880*8975f5c5SAndroid Build Coastguard Worker 
4881*8975f5c5SAndroid Build Coastguard Worker     constexpr char kComputeImageBuffer[] = R"(#version 310 es
4882*8975f5c5SAndroid Build Coastguard Worker #extension GL_OES_texture_buffer : require
4883*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
4884*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
4885*8975f5c5SAndroid Build Coastguard Worker uniform vec4 uniformData;
4886*8975f5c5SAndroid Build Coastguard Worker uniform int uniformOffset;
4887*8975f5c5SAndroid Build Coastguard Worker void main()
4888*8975f5c5SAndroid Build Coastguard Worker {
4889*8975f5c5SAndroid Build Coastguard Worker     imageStore(dst, uniformOffset, uniformData);
4890*8975f5c5SAndroid Build Coastguard Worker })";
4891*8975f5c5SAndroid Build Coastguard Worker 
4892*8975f5c5SAndroid Build Coastguard Worker     GLProgram program;
4893*8975f5c5SAndroid Build Coastguard Worker     program.makeCompute(kComputeImageBuffer);
4894*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
4895*8975f5c5SAndroid Build Coastguard Worker 
4896*8975f5c5SAndroid Build Coastguard Worker     for (int loop = 0; loop < 2; loop++)
4897*8975f5c5SAndroid Build Coastguard Worker     {
4898*8975f5c5SAndroid Build Coastguard Worker         GLBuffer textureBufferStorage;
4899*8975f5c5SAndroid Build Coastguard Worker         GLTexture texture;
4900*8975f5c5SAndroid Build Coastguard Worker         constexpr unsigned int kShaderUsedSize    = sizeof(float) * 4;
4901*8975f5c5SAndroid Build Coastguard Worker         constexpr unsigned int kMiddlePaddingSize = 1024;
4902*8975f5c5SAndroid Build Coastguard Worker         constexpr unsigned int kBufferSize = kShaderUsedSize + kMiddlePaddingSize + kShaderUsedSize;
4903*8975f5c5SAndroid Build Coastguard Worker         constexpr unsigned int kOffset0    = 0;
4904*8975f5c5SAndroid Build Coastguard Worker         constexpr unsigned int kOffset1    = kShaderUsedSize;
4905*8975f5c5SAndroid Build Coastguard Worker         constexpr unsigned int kOffset2    = kShaderUsedSize + kMiddlePaddingSize;
4906*8975f5c5SAndroid Build Coastguard Worker 
4907*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_TEXTURE_BUFFER, textureBufferStorage);
4908*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_TEXTURE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
4909*8975f5c5SAndroid Build Coastguard Worker 
4910*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_BUFFER, texture);
4911*8975f5c5SAndroid Build Coastguard Worker         glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, textureBufferStorage);
4912*8975f5c5SAndroid Build Coastguard Worker         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
4913*8975f5c5SAndroid Build Coastguard Worker 
4914*8975f5c5SAndroid Build Coastguard Worker         // Write to the buffer with the CS.
4915*8975f5c5SAndroid Build Coastguard Worker         constexpr std::array<float, 4> kComputeShaderData1 = {0.0, 1.0, 0.0, 1.0};
4916*8975f5c5SAndroid Build Coastguard Worker         GLint uniformDataLocation = glGetUniformLocation(program, "uniformData");
4917*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(uniformDataLocation, -1);
4918*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(uniformDataLocation, kComputeShaderData1[0], kComputeShaderData1[1],
4919*8975f5c5SAndroid Build Coastguard Worker                     kComputeShaderData1[2], kComputeShaderData1[3]);
4920*8975f5c5SAndroid Build Coastguard Worker         GLint uniformOffsetLocation = glGetUniformLocation(program, "uniformOffset");
4921*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(uniformOffsetLocation, -1);
4922*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(uniformOffsetLocation, kOffset0 / (sizeof(float) * 4));
4923*8975f5c5SAndroid Build Coastguard Worker         glDispatchCompute(1, 1, 1);
4924*8975f5c5SAndroid Build Coastguard Worker         // Issue the appropriate memory barrier before mapping the buffer.
4925*8975f5c5SAndroid Build Coastguard Worker         glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
4926*8975f5c5SAndroid Build Coastguard Worker 
4927*8975f5c5SAndroid Build Coastguard Worker         // Write to the buffer with the CS.
4928*8975f5c5SAndroid Build Coastguard Worker         constexpr std::array<float, 4> kComputeShaderData2 = {1.0, 0.0, 1.0, 1.0};
4929*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(uniformDataLocation, kComputeShaderData2[0], kComputeShaderData2[1],
4930*8975f5c5SAndroid Build Coastguard Worker                     kComputeShaderData2[2], kComputeShaderData2[3]);
4931*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(uniformOffsetLocation, kOffset2 / (sizeof(float) * 4));
4932*8975f5c5SAndroid Build Coastguard Worker         glDispatchCompute(1, 1, 1);
4933*8975f5c5SAndroid Build Coastguard Worker 
4934*8975f5c5SAndroid Build Coastguard Worker         if (loop == 1)
4935*8975f5c5SAndroid Build Coastguard Worker         {
4936*8975f5c5SAndroid Build Coastguard Worker             // Make write operation finished but read operation pending. We don't care actual
4937*8975f5c5SAndroid Build Coastguard Worker             // rendering result but just to have a unflushed rendering using the buffer so that it
4938*8975f5c5SAndroid Build Coastguard Worker             // will appears as pending.
4939*8975f5c5SAndroid Build Coastguard Worker             glFinish();
4940*8975f5c5SAndroid Build Coastguard Worker             constexpr char kVS[] = R"(attribute vec4 in_attrib;
4941*8975f5c5SAndroid Build Coastguard Worker                                     varying vec4 v_attrib;
4942*8975f5c5SAndroid Build Coastguard Worker                                     void main()
4943*8975f5c5SAndroid Build Coastguard Worker                                     {
4944*8975f5c5SAndroid Build Coastguard Worker                                         v_attrib = in_attrib;
4945*8975f5c5SAndroid Build Coastguard Worker                                         gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
4946*8975f5c5SAndroid Build Coastguard Worker                                         gl_PointSize = 100.0;
4947*8975f5c5SAndroid Build Coastguard Worker                                     })";
4948*8975f5c5SAndroid Build Coastguard Worker             constexpr char kFS[] = R"(precision mediump float;
4949*8975f5c5SAndroid Build Coastguard Worker                                     varying vec4 v_attrib;
4950*8975f5c5SAndroid Build Coastguard Worker                                     void main()
4951*8975f5c5SAndroid Build Coastguard Worker                                     {
4952*8975f5c5SAndroid Build Coastguard Worker                                         gl_FragColor = v_attrib;
4953*8975f5c5SAndroid Build Coastguard Worker                                     })";
4954*8975f5c5SAndroid Build Coastguard Worker             GLuint readProgram   = CompileProgram(kVS, kFS);
4955*8975f5c5SAndroid Build Coastguard Worker             ASSERT_NE(readProgram, 0U);
4956*8975f5c5SAndroid Build Coastguard Worker             GLint attribLocation = glGetAttribLocation(readProgram, "in_attrib");
4957*8975f5c5SAndroid Build Coastguard Worker             ASSERT_NE(attribLocation, -1);
4958*8975f5c5SAndroid Build Coastguard Worker             glUseProgram(readProgram);
4959*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
4960*8975f5c5SAndroid Build Coastguard Worker             glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT);
4961*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, textureBufferStorage);
4962*8975f5c5SAndroid Build Coastguard Worker             glVertexAttribPointer(attribLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4, nullptr);
4963*8975f5c5SAndroid Build Coastguard Worker             glEnableVertexAttribArray(attribLocation);
4964*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, textureBufferStorage);
4965*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4966*8975f5c5SAndroid Build Coastguard Worker             glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, nullptr);
4967*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
4968*8975f5c5SAndroid Build Coastguard Worker         }
4969*8975f5c5SAndroid Build Coastguard Worker 
4970*8975f5c5SAndroid Build Coastguard Worker         // Use subData to update middle portion of data to trigger acquireAndUpdate code path in
4971*8975f5c5SAndroid Build Coastguard Worker         // ANGLE
4972*8975f5c5SAndroid Build Coastguard Worker         glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4973*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_TEXTURE_BUFFER, textureBufferStorage);
4974*8975f5c5SAndroid Build Coastguard Worker         constexpr unsigned int kMiddlePaddingValue = 0x55555555u;
4975*8975f5c5SAndroid Build Coastguard Worker         std::vector<unsigned int> kPaddingValues(kMiddlePaddingSize / sizeof(unsigned int),
4976*8975f5c5SAndroid Build Coastguard Worker                                                  kMiddlePaddingValue);
4977*8975f5c5SAndroid Build Coastguard Worker         glBufferSubData(GL_TEXTURE_BUFFER, kOffset1, kMiddlePaddingSize, kPaddingValues.data());
4978*8975f5c5SAndroid Build Coastguard Worker 
4979*8975f5c5SAndroid Build Coastguard Worker         // Read back and verify buffer data.
4980*8975f5c5SAndroid Build Coastguard Worker         const GLbyte *mappedBuffer = reinterpret_cast<const GLbyte *>(
4981*8975f5c5SAndroid Build Coastguard Worker             glMapBufferRange(GL_TEXTURE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
4982*8975f5c5SAndroid Build Coastguard Worker 
4983*8975f5c5SAndroid Build Coastguard Worker         const GLfloat *ptr0 = reinterpret_cast<const GLfloat *>(mappedBuffer);
4984*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr0[0], kComputeShaderData1[0]);
4985*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr0[1], kComputeShaderData1[1]);
4986*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr0[2], kComputeShaderData1[2]);
4987*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr0[3], kComputeShaderData1[3]);
4988*8975f5c5SAndroid Build Coastguard Worker 
4989*8975f5c5SAndroid Build Coastguard Worker         const GLuint *ptr1 = reinterpret_cast<const GLuint *>(mappedBuffer + kOffset1);
4990*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int idx = 0; idx < kMiddlePaddingSize / sizeof(unsigned int); idx++)
4991*8975f5c5SAndroid Build Coastguard Worker         {
4992*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(ptr1[idx], kMiddlePaddingValue);
4993*8975f5c5SAndroid Build Coastguard Worker         }
4994*8975f5c5SAndroid Build Coastguard Worker 
4995*8975f5c5SAndroid Build Coastguard Worker         const GLfloat *ptr2 = reinterpret_cast<const GLfloat *>(mappedBuffer + kOffset2);
4996*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr2[0], kComputeShaderData2[0]);
4997*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr2[1], kComputeShaderData2[1]);
4998*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr2[2], kComputeShaderData2[2]);
4999*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(ptr2[3], kComputeShaderData2[3]);
5000*8975f5c5SAndroid Build Coastguard Worker 
5001*8975f5c5SAndroid Build Coastguard Worker         glUnmapBuffer(GL_TEXTURE_BUFFER);
5002*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
5003*8975f5c5SAndroid Build Coastguard Worker     }
5004*8975f5c5SAndroid Build Coastguard Worker }
5005*8975f5c5SAndroid Build Coastguard Worker 
5006*8975f5c5SAndroid Build Coastguard Worker // Test one texture sampled by fragment shader, then bind it to image, followed by compute
5007*8975f5c5SAndroid Build Coastguard Worker // shader load this image, and fragment shader read it again.
TEST_P(ComputeShaderTest,DrawDispatchImageReadDraw)5008*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, DrawDispatchImageReadDraw)
5009*8975f5c5SAndroid Build Coastguard Worker {
5010*8975f5c5SAndroid Build Coastguard Worker 
5011*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVSSource[] = R"(#version 310 es
5012*8975f5c5SAndroid Build Coastguard Worker in vec4 a_position;
5013*8975f5c5SAndroid Build Coastguard Worker out vec2 v_texCoord;
5014*8975f5c5SAndroid Build Coastguard Worker 
5015*8975f5c5SAndroid Build Coastguard Worker void main()
5016*8975f5c5SAndroid Build Coastguard Worker {
5017*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(a_position.xy, 0.0, 1.0);
5018*8975f5c5SAndroid Build Coastguard Worker     v_texCoord = a_position.xy * 0.5 + vec2(0.5);
5019*8975f5c5SAndroid Build Coastguard Worker })";
5020*8975f5c5SAndroid Build Coastguard Worker 
5021*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFSSource[] = R"(#version 310 es
5022*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
5023*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D u_tex2D;
5024*8975f5c5SAndroid Build Coastguard Worker in vec2 v_texCoord;
5025*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
5026*8975f5c5SAndroid Build Coastguard Worker void main()
5027*8975f5c5SAndroid Build Coastguard Worker {
5028*8975f5c5SAndroid Build Coastguard Worker     out_FragColor = texture(u_tex2D, v_texCoord);
5029*8975f5c5SAndroid Build Coastguard Worker })";
5030*8975f5c5SAndroid Build Coastguard Worker 
5031*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCSSource[] = R"(#version 310 es
5032*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
5033*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding=0) readonly  uniform highp image2D uIn;
5034*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding=0) buffer buf {
5035*8975f5c5SAndroid Build Coastguard Worker     vec4 outData;
5036*8975f5c5SAndroid Build Coastguard Worker };
5037*8975f5c5SAndroid Build Coastguard Worker 
5038*8975f5c5SAndroid Build Coastguard Worker void main()
5039*8975f5c5SAndroid Build Coastguard Worker {
5040*8975f5c5SAndroid Build Coastguard Worker     outData = imageLoad(uIn, ivec2(gl_LocalInvocationID.xy));
5041*8975f5c5SAndroid Build Coastguard Worker })";
5042*8975f5c5SAndroid Build Coastguard Worker 
5043*8975f5c5SAndroid Build Coastguard Worker     GLfloat initValue[4] = {1.0, 1.0, 1.0, 1.0};
5044*8975f5c5SAndroid Build Coastguard Worker 
5045*8975f5c5SAndroid Build Coastguard Worker     // Step 1: Set up a simple 2D Texture rendering loop.
5046*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
5047*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
5048*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
5049*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, initValue);
5050*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5051*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5052*8975f5c5SAndroid Build Coastguard Worker 
5053*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
5054*8975f5c5SAndroid Build Coastguard Worker     GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
5055*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
5056*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
5057*8975f5c5SAndroid Build Coastguard Worker 
5058*8975f5c5SAndroid Build Coastguard Worker     GLBuffer ssbo;
5059*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
5060*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, 16, nullptr, GL_STREAM_DRAW);
5061*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
5062*8975f5c5SAndroid Build Coastguard Worker 
5063*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
5064*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
5065*8975f5c5SAndroid Build Coastguard Worker 
5066*8975f5c5SAndroid Build Coastguard Worker     GLint posLoc = glGetAttribLocation(program, "a_position");
5067*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, posLoc);
5068*8975f5c5SAndroid Build Coastguard Worker 
5069*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
5070*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(posLoc);
5071*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5072*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
5073*8975f5c5SAndroid Build Coastguard Worker 
5074*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 6);
5075*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5076*8975f5c5SAndroid Build Coastguard Worker 
5077*8975f5c5SAndroid Build Coastguard Worker     // Step 2: load this image through compute
5078*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
5079*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
5080*8975f5c5SAndroid Build Coastguard Worker 
5081*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
5082*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
5083*8975f5c5SAndroid Build Coastguard Worker 
5084*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
5085*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
5086*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5087*8975f5c5SAndroid Build Coastguard Worker 
5088*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
5089*8975f5c5SAndroid Build Coastguard Worker     const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
5090*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT));
5091*8975f5c5SAndroid Build Coastguard Worker 
5092*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
5093*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < 4; idx++)
5094*8975f5c5SAndroid Build Coastguard Worker     {
5095*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(1.0, *(ptr + idx));
5096*8975f5c5SAndroid Build Coastguard Worker     }
5097*8975f5c5SAndroid Build Coastguard Worker 
5098*8975f5c5SAndroid Build Coastguard Worker     // Step3: use the first program sample texture again
5099*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
5100*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 6);
5101*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5102*8975f5c5SAndroid Build Coastguard Worker 
5103*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::white);
5104*8975f5c5SAndroid Build Coastguard Worker }
5105*8975f5c5SAndroid Build Coastguard Worker 
5106*8975f5c5SAndroid Build Coastguard Worker // Test fragment shader read a image, followed by compute shader sample it.
TEST_P(ComputeShaderTest,FSReadImageThenCSSample)5107*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, FSReadImageThenCSSample)
5108*8975f5c5SAndroid Build Coastguard Worker {
5109*8975f5c5SAndroid Build Coastguard Worker     GLint maxFragmentImageUniforms = 0;
5110*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &maxFragmentImageUniforms);
5111*8975f5c5SAndroid Build Coastguard Worker 
5112*8975f5c5SAndroid Build Coastguard Worker     // MAX_FRAGMENT_IMAGE_UNIFORMS can be 0 according to OpenGL ES 3.1 SPEC.
5113*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(maxFragmentImageUniforms == 0);
5114*8975f5c5SAndroid Build Coastguard Worker 
5115*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVSSource[] = R"(#version 310 es
5116*8975f5c5SAndroid Build Coastguard Worker in vec4 a_position;
5117*8975f5c5SAndroid Build Coastguard Worker out vec2 v_texCoord;
5118*8975f5c5SAndroid Build Coastguard Worker void main()
5119*8975f5c5SAndroid Build Coastguard Worker {
5120*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(a_position.xy, 0.0, 1.0);
5121*8975f5c5SAndroid Build Coastguard Worker     v_texCoord = a_position.xy * 0.5 + vec2(0.5);;
5122*8975f5c5SAndroid Build Coastguard Worker })";
5123*8975f5c5SAndroid Build Coastguard Worker 
5124*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFSSource[] = R"(#version 310 es
5125*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
5126*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding=0) readonly  uniform highp image2D uIn;
5127*8975f5c5SAndroid Build Coastguard Worker in vec2 v_texCoord;
5128*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
5129*8975f5c5SAndroid Build Coastguard Worker 
5130*8975f5c5SAndroid Build Coastguard Worker void main()
5131*8975f5c5SAndroid Build Coastguard Worker {
5132*8975f5c5SAndroid Build Coastguard Worker     out_FragColor = imageLoad(uIn, ivec2(v_texCoord));
5133*8975f5c5SAndroid Build Coastguard Worker })";
5134*8975f5c5SAndroid Build Coastguard Worker 
5135*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCSSource[] = R"(#version 310 es
5136*8975f5c5SAndroid Build Coastguard Worker layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
5137*8975f5c5SAndroid Build Coastguard Worker layout(std140, binding=0) buffer buf {
5138*8975f5c5SAndroid Build Coastguard Worker     vec4 outData;
5139*8975f5c5SAndroid Build Coastguard Worker };
5140*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D u_tex2D;
5141*8975f5c5SAndroid Build Coastguard Worker void main()
5142*8975f5c5SAndroid Build Coastguard Worker {
5143*8975f5c5SAndroid Build Coastguard Worker     outData = texture(u_tex2D, vec2(gl_LocalInvocationID.xy));
5144*8975f5c5SAndroid Build Coastguard Worker })";
5145*8975f5c5SAndroid Build Coastguard Worker 
5146*8975f5c5SAndroid Build Coastguard Worker     GLfloat initValue[4] = {1.0, 1.0, 1.0, 1.0};
5147*8975f5c5SAndroid Build Coastguard Worker 
5148*8975f5c5SAndroid Build Coastguard Worker     // Step 1: Set up a simple 2D Texture rendering loop.
5149*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
5150*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
5151*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
5152*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, initValue);
5153*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5154*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5155*8975f5c5SAndroid Build Coastguard Worker 
5156*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
5157*8975f5c5SAndroid Build Coastguard Worker     GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
5158*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
5159*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
5160*8975f5c5SAndroid Build Coastguard Worker 
5161*8975f5c5SAndroid Build Coastguard Worker     GLBuffer ssbo;
5162*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
5163*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, 16, nullptr, GL_STREAM_DRAW);
5164*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
5165*8975f5c5SAndroid Build Coastguard Worker 
5166*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
5167*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
5168*8975f5c5SAndroid Build Coastguard Worker 
5169*8975f5c5SAndroid Build Coastguard Worker     GLint posLoc = glGetAttribLocation(program, "a_position");
5170*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(-1, posLoc);
5171*8975f5c5SAndroid Build Coastguard Worker 
5172*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
5173*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(posLoc);
5174*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5175*8975f5c5SAndroid Build Coastguard Worker     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
5176*8975f5c5SAndroid Build Coastguard Worker 
5177*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5178*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5179*8975f5c5SAndroid Build Coastguard Worker 
5180*8975f5c5SAndroid Build Coastguard Worker     // Step 2: load this image through compute
5181*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
5182*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
5183*8975f5c5SAndroid Build Coastguard Worker 
5184*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
5185*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
5186*8975f5c5SAndroid Build Coastguard Worker 
5187*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(1, 1, 1);
5188*8975f5c5SAndroid Build Coastguard Worker 
5189*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
5190*8975f5c5SAndroid Build Coastguard Worker     const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
5191*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT));
5192*8975f5c5SAndroid Build Coastguard Worker 
5193*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
5194*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < 4; idx++)
5195*8975f5c5SAndroid Build Coastguard Worker     {
5196*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(1.0, *(ptr + idx));
5197*8975f5c5SAndroid Build Coastguard Worker     }
5198*8975f5c5SAndroid Build Coastguard Worker }
5199*8975f5c5SAndroid Build Coastguard Worker 
5200*8975f5c5SAndroid Build Coastguard Worker // Replicate the dEQP test dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite
TEST_P(ComputeShaderTest,SSBOAliasOverWrite)5201*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, SSBOAliasOverWrite)
5202*8975f5c5SAndroid Build Coastguard Worker {
5203*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCSSource[] = R"(#version 310 es
5204*8975f5c5SAndroid Build Coastguard Worker     layout (local_size_x=16, local_size_y=8) in;
5205*8975f5c5SAndroid Build Coastguard Worker     layout(binding=0, std430) buffer Output {
5206*8975f5c5SAndroid Build Coastguard Worker         highp int values[];
5207*8975f5c5SAndroid Build Coastguard Worker     } sb_result;
5208*8975f5c5SAndroid Build Coastguard Worker     layout(binding=1, std430) coherent buffer Storage0
5209*8975f5c5SAndroid Build Coastguard Worker     {
5210*8975f5c5SAndroid Build Coastguard Worker         highp int values[];
5211*8975f5c5SAndroid Build Coastguard Worker     } sb_store0;
5212*8975f5c5SAndroid Build Coastguard Worker     layout(binding=2, std430) coherent buffer Storage1
5213*8975f5c5SAndroid Build Coastguard Worker     {
5214*8975f5c5SAndroid Build Coastguard Worker         highp int values[];
5215*8975f5c5SAndroid Build Coastguard Worker     } sb_store1;
5216*8975f5c5SAndroid Build Coastguard Worker 
5217*8975f5c5SAndroid Build Coastguard Worker     highp int getIndex(in highp uvec2 localID, in highp int element)
5218*8975f5c5SAndroid Build Coastguard Worker     {
5219*8975f5c5SAndroid Build Coastguard Worker         highp uint groupNdx = gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x;
5220*8975f5c5SAndroid Build Coastguard Worker         return int((localID.y * gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupSize.x) + (groupNdx * gl_WorkGroupSize.x) + localID.x) * 8 + element;
5221*8975f5c5SAndroid Build Coastguard Worker     }
5222*8975f5c5SAndroid Build Coastguard Worker 
5223*8975f5c5SAndroid Build Coastguard Worker     void main (void)
5224*8975f5c5SAndroid Build Coastguard Worker     {
5225*8975f5c5SAndroid Build Coastguard Worker         int resultNdx = int(gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x + gl_GlobalInvocationID.x);
5226*8975f5c5SAndroid Build Coastguard Worker         int groupNdx = int(gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x);
5227*8975f5c5SAndroid Build Coastguard Worker         bool allOk = true;
5228*8975f5c5SAndroid Build Coastguard Worker 
5229*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 0)] = 456;
5230*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 1)] = 456;
5231*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 2)] = 456;
5232*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 3)] = 456;
5233*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 4)] = 456;
5234*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 5)] = 456;
5235*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 6)] = 456;
5236*8975f5c5SAndroid Build Coastguard Worker         sb_store0.values[getIndex(gl_LocalInvocationID.xy, 7)] = 456;
5237*8975f5c5SAndroid Build Coastguard Worker 
5238*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 0)] = groupNdx;
5239*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 1)] = groupNdx;
5240*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 2)] = groupNdx;
5241*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 3)] = groupNdx;
5242*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 4)] = groupNdx;
5243*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 5)] = groupNdx;
5244*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 6)] = groupNdx;
5245*8975f5c5SAndroid Build Coastguard Worker         sb_store1.values[getIndex(gl_LocalInvocationID.xy, 7)] = groupNdx;
5246*8975f5c5SAndroid Build Coastguard Worker 
5247*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 0)] == groupNdx);
5248*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 1)] == groupNdx);
5249*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 2)] == groupNdx);
5250*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 3)] == groupNdx);
5251*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 4)] == groupNdx);
5252*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 5)] == groupNdx);
5253*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 6)] == groupNdx);
5254*8975f5c5SAndroid Build Coastguard Worker         allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 7)] == groupNdx);
5255*8975f5c5SAndroid Build Coastguard Worker 
5256*8975f5c5SAndroid Build Coastguard Worker         sb_result.values[resultNdx] = allOk ? (1) : (2);
5257*8975f5c5SAndroid Build Coastguard Worker 
5258*8975f5c5SAndroid Build Coastguard Worker     })";
5259*8975f5c5SAndroid Build Coastguard Worker 
5260*8975f5c5SAndroid Build Coastguard Worker     const int totalWorkWidth        = 256;
5261*8975f5c5SAndroid Build Coastguard Worker     const int totalWorkHeight       = 256;
5262*8975f5c5SAndroid Build Coastguard Worker     const int elementsPerInvocation = 8;
5263*8975f5c5SAndroid Build Coastguard Worker 
5264*8975f5c5SAndroid Build Coastguard Worker     // define compute shader input storage buffer
5265*8975f5c5SAndroid Build Coastguard Worker     const int inputSSBOBufferSizeInBytes =
5266*8975f5c5SAndroid Build Coastguard Worker         totalWorkWidth * totalWorkHeight * elementsPerInvocation * sizeof(uint32_t);
5267*8975f5c5SAndroid Build Coastguard Worker     const int inputSSBOBufferElementsCount =
5268*8975f5c5SAndroid Build Coastguard Worker         totalWorkWidth * totalWorkHeight * elementsPerInvocation;
5269*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint32_t> zeros(inputSSBOBufferElementsCount, 0);
5270*8975f5c5SAndroid Build Coastguard Worker     GLBuffer ssbo;
5271*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
5272*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, inputSSBOBufferSizeInBytes, zeros.data(),
5273*8975f5c5SAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
5274*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5275*8975f5c5SAndroid Build Coastguard Worker 
5276*8975f5c5SAndroid Build Coastguard Worker     // define compute shader output buffer
5277*8975f5c5SAndroid Build Coastguard Worker     const int outputBufferSizeInBytes   = totalWorkWidth * totalWorkHeight * sizeof(int32_t);
5278*8975f5c5SAndroid Build Coastguard Worker     const int outputBufferElementsCount = totalWorkWidth * totalWorkHeight;
5279*8975f5c5SAndroid Build Coastguard Worker     std::vector<int32_t> minusOnes(outputBufferElementsCount, -1);
5280*8975f5c5SAndroid Build Coastguard Worker     GLBuffer resultBuffer;
5281*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultBuffer);
5282*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, outputBufferSizeInBytes, &minusOnes[0], GL_STATIC_DRAW);
5283*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5284*8975f5c5SAndroid Build Coastguard Worker 
5285*8975f5c5SAndroid Build Coastguard Worker     // dispatch compute shader
5286*8975f5c5SAndroid Build Coastguard Worker     const int localWidth  = 16;
5287*8975f5c5SAndroid Build Coastguard Worker     const int localHeight = 8;
5288*8975f5c5SAndroid Build Coastguard Worker     ASSERT(totalWorkWidth % localWidth == 0);
5289*8975f5c5SAndroid Build Coastguard Worker     ASSERT(totalWorkHeight % localHeight == 0);
5290*8975f5c5SAndroid Build Coastguard Worker     const int numGroupDimX = totalWorkWidth / localWidth;
5291*8975f5c5SAndroid Build Coastguard Worker     const int numGroupDimY = totalWorkHeight / localHeight;
5292*8975f5c5SAndroid Build Coastguard Worker 
5293*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
5294*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
5295*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5296*8975f5c5SAndroid Build Coastguard Worker 
5297*8975f5c5SAndroid Build Coastguard Worker     // Bind storage buffer to compute shader binding locations
5298*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
5299*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
5300*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, resultBuffer);
5301*8975f5c5SAndroid Build Coastguard Worker 
5302*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(numGroupDimX, numGroupDimY, 1);
5303*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5304*8975f5c5SAndroid Build Coastguard Worker 
5305*8975f5c5SAndroid Build Coastguard Worker     // verify the result
5306*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultBuffer);
5307*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5308*8975f5c5SAndroid Build Coastguard Worker     void *mappedResults =
5309*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, outputBufferSizeInBytes, GL_MAP_READ_BIT);
5310*8975f5c5SAndroid Build Coastguard Worker     std::vector<int32_t> results(outputBufferElementsCount);
5311*8975f5c5SAndroid Build Coastguard Worker     memcpy(results.data(), mappedResults, outputBufferSizeInBytes);
5312*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5313*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5314*8975f5c5SAndroid Build Coastguard Worker 
5315*8975f5c5SAndroid Build Coastguard Worker     bool error = false;
5316*8975f5c5SAndroid Build Coastguard Worker     for (int index = 0; index < static_cast<int>(results.size()); ++index)
5317*8975f5c5SAndroid Build Coastguard Worker     {
5318*8975f5c5SAndroid Build Coastguard Worker         if (results[index] != 1)
5319*8975f5c5SAndroid Build Coastguard Worker         {
5320*8975f5c5SAndroid Build Coastguard Worker             error = true;
5321*8975f5c5SAndroid Build Coastguard Worker         }
5322*8975f5c5SAndroid Build Coastguard Worker     }
5323*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(false, error);
5324*8975f5c5SAndroid Build Coastguard Worker }
5325*8975f5c5SAndroid Build Coastguard Worker 
5326*8975f5c5SAndroid Build Coastguard Worker // Performs an atomic operation and assigns the previous value to an SSBO.
TEST_P(ComputeShaderTest,AtomicOpPreviousValueAssignedToSSBO)5327*8975f5c5SAndroid Build Coastguard Worker TEST_P(ComputeShaderTest, AtomicOpPreviousValueAssignedToSSBO)
5328*8975f5c5SAndroid Build Coastguard Worker {
5329*8975f5c5SAndroid Build Coastguard Worker 
5330*8975f5c5SAndroid Build Coastguard Worker     constexpr char kCSSource[] = R"(#version 310 es
5331*8975f5c5SAndroid Build Coastguard Worker     shared int wg;
5332*8975f5c5SAndroid Build Coastguard Worker     layout(binding = 0, std430) buffer Storage0 {
5333*8975f5c5SAndroid Build Coastguard Worker       int inner[16];
5334*8975f5c5SAndroid Build Coastguard Worker     } buf;
5335*8975f5c5SAndroid Build Coastguard Worker 
5336*8975f5c5SAndroid Build Coastguard Worker     layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
5337*8975f5c5SAndroid Build Coastguard Worker     void main() {
5338*8975f5c5SAndroid Build Coastguard Worker       wg = 0;
5339*8975f5c5SAndroid Build Coastguard Worker       atomicExchange(wg, 0);
5340*8975f5c5SAndroid Build Coastguard Worker       barrier();
5341*8975f5c5SAndroid Build Coastguard Worker       buf.inner[gl_WorkGroupID.x] = atomicOr(wg, 1);
5342*8975f5c5SAndroid Build Coastguard Worker     })";
5343*8975f5c5SAndroid Build Coastguard Worker 
5344*8975f5c5SAndroid Build Coastguard Worker     const int dispatchSize = 16;
5345*8975f5c5SAndroid Build Coastguard Worker 
5346*8975f5c5SAndroid Build Coastguard Worker     // define compute shader output buffer
5347*8975f5c5SAndroid Build Coastguard Worker     const int outputBufferSizeInBytes   = dispatchSize * sizeof(int32_t);
5348*8975f5c5SAndroid Build Coastguard Worker     const int outputBufferElementsCount = dispatchSize;
5349*8975f5c5SAndroid Build Coastguard Worker     std::vector<int32_t> minusOnes(outputBufferElementsCount, -1);
5350*8975f5c5SAndroid Build Coastguard Worker     GLBuffer resultBuffer;
5351*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultBuffer);
5352*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_SHADER_STORAGE_BUFFER, outputBufferSizeInBytes, &minusOnes[0], GL_STATIC_DRAW);
5353*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5354*8975f5c5SAndroid Build Coastguard Worker 
5355*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
5356*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(csProgram);
5357*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5358*8975f5c5SAndroid Build Coastguard Worker 
5359*8975f5c5SAndroid Build Coastguard Worker     // Bind storage buffer to compute shader binding locations
5360*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, resultBuffer);
5361*8975f5c5SAndroid Build Coastguard Worker 
5362*8975f5c5SAndroid Build Coastguard Worker     glDispatchCompute(dispatchSize, 1, 1);
5363*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5364*8975f5c5SAndroid Build Coastguard Worker 
5365*8975f5c5SAndroid Build Coastguard Worker     // verify the result
5366*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultBuffer);
5367*8975f5c5SAndroid Build Coastguard Worker     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5368*8975f5c5SAndroid Build Coastguard Worker     void *mappedResults =
5369*8975f5c5SAndroid Build Coastguard Worker         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, outputBufferSizeInBytes, GL_MAP_READ_BIT);
5370*8975f5c5SAndroid Build Coastguard Worker     std::vector<int32_t> results(outputBufferElementsCount);
5371*8975f5c5SAndroid Build Coastguard Worker     memcpy(results.data(), mappedResults, outputBufferSizeInBytes);
5372*8975f5c5SAndroid Build Coastguard Worker     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5373*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
5374*8975f5c5SAndroid Build Coastguard Worker 
5375*8975f5c5SAndroid Build Coastguard Worker     for (int index = 0; index < static_cast<int>(results.size()); ++index)
5376*8975f5c5SAndroid Build Coastguard Worker     {
5377*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(results[index], 0);
5378*8975f5c5SAndroid Build Coastguard Worker     }
5379*8975f5c5SAndroid Build Coastguard Worker }
5380*8975f5c5SAndroid Build Coastguard Worker 
5381*8975f5c5SAndroid Build Coastguard Worker class StorageImageRenderProgramTest : public ANGLETest<>
5382*8975f5c5SAndroid Build Coastguard Worker {};
5383*8975f5c5SAndroid Build Coastguard Worker 
5384*8975f5c5SAndroid Build Coastguard Worker // Test creating a program with a vertex shader using storage image.
TEST_P(StorageImageRenderProgramTest,StorageImageInVertexShader)5385*8975f5c5SAndroid Build Coastguard Worker TEST_P(StorageImageRenderProgramTest, StorageImageInVertexShader)
5386*8975f5c5SAndroid Build Coastguard Worker {
5387*8975f5c5SAndroid Build Coastguard Worker     GLint maxVertexShaderImage = 0;
5388*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &maxVertexShaderImage);
5389*8975f5c5SAndroid Build Coastguard Worker 
5390*8975f5c5SAndroid Build Coastguard Worker     // MAX_VERTEX_IMAGE_UNIFORMS can be 0 according to OpenGL ES 3.1 SPEC.
5391*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(maxVertexShaderImage == 0);
5392*8975f5c5SAndroid Build Coastguard Worker 
5393*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVSSource_readonly[] = R"(#version 310 es
5394*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) readonly uniform highp image2D uIn;
5395*8975f5c5SAndroid Build Coastguard Worker void main()
5396*8975f5c5SAndroid Build Coastguard Worker {
5397*8975f5c5SAndroid Build Coastguard Worker     gl_Position = imageLoad(uIn, ivec2(0, 0));
5398*8975f5c5SAndroid Build Coastguard Worker })";
5399*8975f5c5SAndroid Build Coastguard Worker 
5400*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVSSource_writeonly[] = R"(#version 310 es
5401*8975f5c5SAndroid Build Coastguard Worker layout(rgba32f, binding = 0) writeonly uniform highp image2D uOut;
5402*8975f5c5SAndroid Build Coastguard Worker void main()
5403*8975f5c5SAndroid Build Coastguard Worker {
5404*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(0, 0, 0, 1);
5405*8975f5c5SAndroid Build Coastguard Worker     imageStore(uOut, ivec2(0, 0), vec4(0, 0, 0, 1));
5406*8975f5c5SAndroid Build Coastguard Worker })";
5407*8975f5c5SAndroid Build Coastguard Worker 
5408*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVSSource_readwrite[] = R"(#version 310 es
5409*8975f5c5SAndroid Build Coastguard Worker layout(r32f, binding = 0) uniform highp image2D uImage;
5410*8975f5c5SAndroid Build Coastguard Worker void main()
5411*8975f5c5SAndroid Build Coastguard Worker {
5412*8975f5c5SAndroid Build Coastguard Worker     gl_Position = imageLoad(uImage, ivec2(0, 0));
5413*8975f5c5SAndroid Build Coastguard Worker     imageStore(uImage, ivec2(0, 0), vec4(0, 0, 0, 1));
5414*8975f5c5SAndroid Build Coastguard Worker })";
5415*8975f5c5SAndroid Build Coastguard Worker 
5416*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFSSource[] = R"(#version 310 es
5417*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
5418*8975f5c5SAndroid Build Coastguard Worker out vec4 out_FragColor;
5419*8975f5c5SAndroid Build Coastguard Worker void main()
5420*8975f5c5SAndroid Build Coastguard Worker {
5421*8975f5c5SAndroid Build Coastguard Worker     out_FragColor = vec4(0, 1, 0, 1);
5422*8975f5c5SAndroid Build Coastguard Worker })";
5423*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program1, kVSSource_readonly, kFSSource);
5424*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
5425*8975f5c5SAndroid Build Coastguard Worker 
5426*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program2, kVSSource_writeonly, kFSSource);
5427*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
5428*8975f5c5SAndroid Build Coastguard Worker 
5429*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program3, kVSSource_readwrite, kFSSource);
5430*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
5431*8975f5c5SAndroid Build Coastguard Worker }
5432*8975f5c5SAndroid Build Coastguard Worker 
5433*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ComputeShaderTest);
5434*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES31(ComputeShaderTest);
5435*8975f5c5SAndroid Build Coastguard Worker 
5436*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ComputeShaderTestES3);
5437*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(ComputeShaderTestES3);
5438*8975f5c5SAndroid Build Coastguard Worker 
5439*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WebGL2ComputeTest);
5440*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES31(WebGL2ComputeTest);
5441*8975f5c5SAndroid Build Coastguard Worker 
5442*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StorageImageRenderProgramTest);
5443*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES31(StorageImageRenderProgramTest);
5444*8975f5c5SAndroid Build Coastguard Worker }  // namespace
5445