xref: /aosp_15_r20/external/angle/src/tests/gl_tests/ShaderStorageBufferTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // ShaderStorageBufferTest:
7 //   Various tests related for shader storage buffers.
8 //
9 
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12 
13 using namespace angle;
14 
15 namespace
16 {
17 
18 struct MatrixCase
19 {
MatrixCase__anon3b3142410111::MatrixCase20     MatrixCase(unsigned cols,
21                unsigned rows,
22                unsigned matrixStride,
23                const char *computeShaderSource,
24                const float *inputData)
25         : mColumns(cols),
26           mRows(rows),
27           mMatrixStride(matrixStride),
28           mComputeShaderSource(computeShaderSource),
29           mInputdata(inputData)
30     {}
31     unsigned int mColumns;
32     unsigned int mRows;
33     unsigned int mMatrixStride;
34     const char *mComputeShaderSource;
35     const float *mInputdata;
36     const unsigned int kBytesPerComponent = sizeof(float);
37 };
38 
39 struct VectorCase
40 {
VectorCase__anon3b3142410111::VectorCase41     VectorCase(unsigned components,
42                const char *computeShaderSource,
43                const GLuint *inputData,
44                const GLuint *expectedData)
45         : mComponents(components),
46           mComputeShaderSource(computeShaderSource),
47           mInputdata(inputData),
48           mExpectedData(expectedData)
49     {}
50     unsigned int mComponents;
51     const char *mComputeShaderSource;
52     const GLuint *mInputdata;
53     const GLuint *mExpectedData;
54     const unsigned int kBytesPerComponent = sizeof(GLuint);
55 };
56 
57 class ShaderStorageBufferTest31 : public ANGLETest<>
58 {
59   protected:
ShaderStorageBufferTest31()60     ShaderStorageBufferTest31()
61     {
62         setWindowWidth(128);
63         setWindowHeight(128);
64         setConfigRedBits(8);
65         setConfigGreenBits(8);
66         setConfigBlueBits(8);
67         setConfigAlphaBits(8);
68 
69         // Test flakiness was noticed when reusing displays.
70         forceNewDisplay();
71     }
72 
runMatrixTest(const MatrixCase & matrixCase)73     void runMatrixTest(const MatrixCase &matrixCase)
74     {
75         ANGLE_GL_COMPUTE_PROGRAM(program, matrixCase.mComputeShaderSource);
76         glUseProgram(program);
77 
78         // Create shader storage buffer
79         GLBuffer shaderStorageBuffer[2];
80         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
81         glBufferData(GL_SHADER_STORAGE_BUFFER, matrixCase.mRows * matrixCase.mMatrixStride,
82                      matrixCase.mInputdata, GL_STATIC_DRAW);
83         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
84         glBufferData(GL_SHADER_STORAGE_BUFFER, matrixCase.mRows * matrixCase.mMatrixStride, nullptr,
85                      GL_STATIC_DRAW);
86 
87         // Bind shader storage buffer
88         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
89         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
90 
91         glDispatchCompute(1, 1, 1);
92         glFinish();
93 
94         // Read back shader storage buffer
95         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
96         const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
97             glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
98                              matrixCase.mRows * matrixCase.mMatrixStride, GL_MAP_READ_BIT));
99 
100         for (unsigned int row = 0; row < matrixCase.mRows; row++)
101         {
102             for (unsigned int col = 0; col < matrixCase.mColumns; col++)
103             {
104                 GLfloat expected = matrixCase.mInputdata[row * (matrixCase.mMatrixStride /
105                                                                 matrixCase.kBytesPerComponent) +
106                                                          col];
107                 GLfloat actual =
108                     *(ptr + row * (matrixCase.mMatrixStride / matrixCase.kBytesPerComponent) + col);
109 
110                 EXPECT_EQ(expected, actual) << " at row " << row << " and column " << col;
111             }
112         }
113 
114         EXPECT_GL_NO_ERROR();
115     }
116 
runVectorTest(const VectorCase & vectorCase)117     void runVectorTest(const VectorCase &vectorCase)
118     {
119         ANGLE_GL_COMPUTE_PROGRAM(program, vectorCase.mComputeShaderSource);
120         glUseProgram(program);
121 
122         // Create shader storage buffer
123         GLBuffer shaderStorageBuffer[2];
124         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
125         glBufferData(GL_SHADER_STORAGE_BUFFER,
126                      vectorCase.mComponents * vectorCase.kBytesPerComponent, vectorCase.mInputdata,
127                      GL_STATIC_DRAW);
128         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
129         glBufferData(GL_SHADER_STORAGE_BUFFER,
130                      vectorCase.mComponents * vectorCase.kBytesPerComponent, nullptr,
131                      GL_STATIC_DRAW);
132 
133         // Bind shader storage buffer
134         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
135         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
136 
137         glDispatchCompute(1, 1, 1);
138         glFinish();
139 
140         // Read back shader storage buffer
141         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
142         const GLuint *ptr = reinterpret_cast<const GLuint *>(glMapBufferRange(
143             GL_SHADER_STORAGE_BUFFER, 0, vectorCase.mComponents * vectorCase.kBytesPerComponent,
144             GL_MAP_READ_BIT));
145         for (unsigned int idx = 0; idx < vectorCase.mComponents; idx++)
146         {
147             EXPECT_EQ(vectorCase.mExpectedData[idx], *(ptr + idx));
148         }
149 
150         EXPECT_GL_NO_ERROR();
151     }
152 };
153 
154 // Matched block names within a shader interface must match in terms of having the same number of
155 // declarations with the same sequence of types.
TEST_P(ShaderStorageBufferTest31,MatchedBlockNameWithDifferentMemberType)156 TEST_P(ShaderStorageBufferTest31, MatchedBlockNameWithDifferentMemberType)
157 {
158     constexpr char kVS[] =
159         "#version 310 es\n"
160         "buffer blockName {\n"
161         "    float data;\n"
162         "};\n"
163         "void main()\n"
164         "{\n"
165         "}\n";
166     constexpr char kFS[] =
167         "#version 310 es\n"
168         "buffer blockName {\n"
169         "    uint data;\n"
170         "};\n"
171         "void main()\n"
172         "{\n"
173         "}\n";
174 
175     GLuint program = CompileProgram(kVS, kFS);
176     EXPECT_EQ(0u, program);
177 }
178 
179 // Linking should fail if blocks in vertex shader exceed GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS.
TEST_P(ShaderStorageBufferTest31,ExceedMaxVertexShaderStorageBlocks)180 TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks)
181 {
182     std::ostringstream instanceCount;
183     GLint maxVertexShaderStorageBlocks = 0;
184     glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks);
185     EXPECT_GL_NO_ERROR();
186     instanceCount << maxVertexShaderStorageBlocks;
187 
188     const std::string &vertexShaderSource =
189         "#version 310 es\n"
190         "layout(shared) buffer blockName {\n"
191         "    uint data;\n"
192         "} instance[" +
193         instanceCount.str() +
194         " + 1];\n"
195         "void main()\n"
196         "{\n"
197         "}\n";
198     constexpr char kFS[] =
199         "#version 310 es\n"
200         "void main()\n"
201         "{\n"
202         "}\n";
203 
204     GLuint program = CompileProgram(vertexShaderSource.c_str(), kFS);
205     EXPECT_EQ(0u, program);
206 }
207 
208 // Linking should fail if the sum of the number of active shader storage blocks exceeds
209 // MAX_COMBINED_SHADER_STORAGE_BLOCKS.
TEST_P(ShaderStorageBufferTest31,ExceedMaxCombinedShaderStorageBlocks)210 TEST_P(ShaderStorageBufferTest31, ExceedMaxCombinedShaderStorageBlocks)
211 {
212     std::ostringstream vertexInstanceCount;
213     GLint maxVertexShaderStorageBlocks = 0;
214     glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks);
215     vertexInstanceCount << maxVertexShaderStorageBlocks;
216 
217     GLint maxFragmentShaderStorageBlocks = 0;
218     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
219 
220     GLint maxCombinedShaderStorageBlocks = 0;
221     glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedShaderStorageBlocks);
222     EXPECT_GL_NO_ERROR();
223 
224     ASSERT_GE(maxCombinedShaderStorageBlocks, maxVertexShaderStorageBlocks);
225     ASSERT_GE(maxCombinedShaderStorageBlocks, maxFragmentShaderStorageBlocks);
226 
227     // As SPEC allows MAX_VERTEX_SHADER_STORAGE_BLOCKS and MAX_FRAGMENT_SHADER_STORAGE_BLOCKS to be
228     // 0, in this situation we should skip this test to prevent these unexpected compile errors.
229     ANGLE_SKIP_TEST_IF(maxVertexShaderStorageBlocks == 0 || maxFragmentShaderStorageBlocks == 0);
230 
231     GLint fragmentShaderStorageBlocks =
232         maxCombinedShaderStorageBlocks - maxVertexShaderStorageBlocks + 1;
233     ANGLE_SKIP_TEST_IF(fragmentShaderStorageBlocks > maxFragmentShaderStorageBlocks);
234 
235     std::ostringstream fragmentInstanceCount;
236     fragmentInstanceCount << fragmentShaderStorageBlocks;
237 
238     const std::string &vertexShaderSource =
239         "#version 310 es\n"
240         "layout(shared) buffer blockName0 {\n"
241         "    uint data;\n"
242         "} instance0[" +
243         vertexInstanceCount.str() +
244         "];\n"
245         "void main()\n"
246         "{\n"
247         "}\n";
248     const std::string &fragmentShaderSource =
249         "#version 310 es\n"
250         "layout(shared) buffer blockName1 {\n"
251         "    uint data;\n"
252         "} instance1[" +
253         fragmentInstanceCount.str() +
254         "];\n"
255         "void main()\n"
256         "{\n"
257         "}\n";
258 
259     GLuint program = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
260     EXPECT_EQ(0u, program);
261 }
262 
263 // Linking should not fail if block size in shader equals to GL_MAX_SHADER_STORAGE_BLOCK_SIZE.
264 // Linking should fail if block size in shader exceeds GL_MAX_SHADER_STORAGE_BLOCK_SIZE.
TEST_P(ShaderStorageBufferTest31,ExceedMaxShaderStorageBlockSize)265 TEST_P(ShaderStorageBufferTest31, ExceedMaxShaderStorageBlockSize)
266 {
267     GLint maxShaderStorageBlockSize = 0;
268     glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxShaderStorageBlockSize);
269     EXPECT_GL_NO_ERROR();
270 
271     // Linking should not fail if block size in shader equals to GL_MAX_SHADER_STORAGE_BLOCK_SIZE.
272     std::ostringstream blockArraySize;
273     blockArraySize << (maxShaderStorageBlockSize / 4);
274     const std::string &computeShaderSource =
275         "#version 310 es\n"
276         "layout (local_size_x = 1) in;\n"
277         "layout(std430) buffer FullSizeBlock\n"
278         "{\n"
279         "uint data[" +
280         blockArraySize.str() +
281         "];\n"
282         "};\n"
283         "void main()\n"
284         "{\n"
285         "for (int i=0; i<" +
286         blockArraySize.str() +
287         "; i++)\n"
288         "{\n"
289         "data[i] = uint(0);\n"
290         "};\n"
291         "}\n";
292 
293     GLuint ComputeProgram = CompileComputeProgram(computeShaderSource.c_str(), true);
294     EXPECT_NE(0u, ComputeProgram);
295     glDeleteProgram(ComputeProgram);
296 
297     // Linking should fail if block size in shader exceeds GL_MAX_SHADER_STORAGE_BLOCK_SIZE.
298     std::ostringstream exceedBlockArraySize;
299     exceedBlockArraySize << (maxShaderStorageBlockSize / 4 + 1);
300     const std::string &exceedComputeShaderSource =
301         "#version 310 es\n"
302         "layout (local_size_x = 1) in;\n"
303         "layout(std430) buffer FullSizeBlock\n"
304         "{\n"
305         "uint data[" +
306         exceedBlockArraySize.str() +
307         "];\n"
308         "};\n"
309         "void main()\n"
310         "{\n"
311         "for (int i=0; i<" +
312         exceedBlockArraySize.str() +
313         "; i++)\n"
314         "{\n"
315         "data[i] = uint(0);\n"
316         "};\n"
317         "}\n";
318 
319     GLuint exceedComputeProgram = CompileComputeProgram(exceedComputeShaderSource.c_str(), true);
320     EXPECT_EQ(0u, exceedComputeProgram);
321     glDeleteProgram(exceedComputeProgram);
322 }
323 
324 // Test shader storage buffer read write.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWrite)325 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite)
326 {
327     constexpr char kCS[] =
328         "#version 310 es\n"
329         "layout(local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
330         "layout(std140, binding = 1) buffer blockName {\n"
331         "    uint data[2];\n"
332         "} instanceName;\n"
333         "void main()\n"
334         "{\n"
335         "    instanceName.data[0] = 3u;\n"
336         "    instanceName.data[1] = 4u;\n"
337         "}\n";
338 
339     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
340 
341     glUseProgram(program);
342 
343     constexpr unsigned int kElementCount = 2;
344     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
345     constexpr unsigned int kArrayStride = 16;
346     // Create shader storage buffer
347     GLBuffer shaderStorageBuffer;
348     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
349     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, nullptr, GL_STATIC_DRAW);
350 
351     // Bind shader storage buffer
352     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
353 
354     // Dispath compute
355     glDispatchCompute(1, 1, 1);
356 
357     glFinish();
358 
359     // Read back shader storage buffer
360     constexpr unsigned int kExpectedValues[2] = {3u, 4u};
361     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
362     void *ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kElementCount * kArrayStride,
363                                  GL_MAP_READ_BIT);
364     for (unsigned int idx = 0; idx < kElementCount; idx++)
365     {
366         EXPECT_EQ(kExpectedValues[idx],
367                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
368                                                      idx * kArrayStride)));
369     }
370     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
371     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
372 
373     EXPECT_GL_NO_ERROR();
374 }
375 
376 // Test shader storage buffer write followed by glTexSUbData and followed by shader storage write
377 // again.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWriteAndBufferSubData)378 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteAndBufferSubData)
379 {
380     constexpr char kCS[] =
381         "#version 310 es\n"
382         "layout(local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
383         "layout(std140, binding = 1) buffer blockName {\n"
384         "    uint data[2];\n"
385         "} instanceName;\n"
386         "void main()\n"
387         "{\n"
388         "    instanceName.data[0] = 3u;\n"
389         "    instanceName.data[1] = 4u;\n"
390         "}\n";
391 
392     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
393 
394     glUseProgram(program);
395 
396     int bufferAlignOffset;
397     glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &bufferAlignOffset);
398 
399     constexpr unsigned int kElementCount = 2;
400     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
401     constexpr unsigned int kArrayStride       = 16;
402     constexpr unsigned int kMiddlePaddingSize = 1024;
403     unsigned int kShaderUsedSize              = kElementCount * kArrayStride;
404     unsigned int kOffset1    = (kShaderUsedSize + bufferAlignOffset - 1) & ~(bufferAlignOffset - 1);
405     unsigned int kOffset2    = kOffset1 + kMiddlePaddingSize;
406     unsigned int kBufferSize = kOffset2 + kShaderUsedSize;
407 
408     for (int loop = 0; loop < 2; loop++)
409     {
410         // Create shader storage buffer
411         GLBuffer shaderStorageBuffer;
412         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
413         glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_DYNAMIC_DRAW);
414 
415         // Bind shader storage buffer and dispath compute
416         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
417         glDispatchCompute(1, 1, 1);
418         glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
419         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer, kOffset2,
420                           kShaderUsedSize);
421         glDispatchCompute(1, 1, 1);
422         EXPECT_GL_NO_ERROR();
423 
424         if (loop == 1)
425         {
426             // Make write operation finished but read operation pending. We don't care actual
427             // rendering result but just to have a unflushed rendering using the buffer so that it
428             // will appears as pending.
429             glFinish();
430             constexpr char kVS[] = R"(attribute vec4 in_attrib;
431                                     varying vec4 v_attrib;
432                                     void main()
433                                     {
434                                         v_attrib = in_attrib;
435                                         gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
436                                         gl_PointSize = 100.0;
437                                     })";
438             constexpr char kFS[] = R"(precision mediump float;
439                                     varying vec4 v_attrib;
440                                     void main()
441                                     {
442                                         gl_FragColor = v_attrib;
443                                     })";
444             GLuint readProgram   = CompileProgram(kVS, kFS);
445             ASSERT_NE(readProgram, 0U);
446             GLint attribLocation = glGetAttribLocation(readProgram, "in_attrib");
447             ASSERT_NE(attribLocation, -1);
448             glUseProgram(readProgram);
449             ASSERT_GL_NO_ERROR();
450             glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT);
451             glBindBuffer(GL_ARRAY_BUFFER, shaderStorageBuffer);
452             glVertexAttribPointer(attribLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4, nullptr);
453             glEnableVertexAttribArray(attribLocation);
454             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shaderStorageBuffer);
455             glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
456             glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, nullptr);
457             ASSERT_GL_NO_ERROR();
458         }
459 
460         // Use subData to update middle portion of data to trigger acquireAndUpdate code path in
461         // ANGLE
462         glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
463         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
464         constexpr unsigned int kMiddlePaddingValue = 0x55555555u;
465         std::vector<unsigned int> kMiddlePaddingValues(kMiddlePaddingSize / sizeof(unsigned int),
466                                                        kMiddlePaddingValue);
467         glBufferSubData(GL_SHADER_STORAGE_BUFFER, kOffset1, kMiddlePaddingSize,
468                         kMiddlePaddingValues.data());
469 
470         // Read back shader storage buffer
471         constexpr unsigned int kExpectedValues[2] = {3u, 4u};
472         const GLbyte *ptr0                        = reinterpret_cast<const GLbyte *>(
473             glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
474         for (unsigned int idx = 0; idx < kElementCount; idx++)
475         {
476             EXPECT_EQ(kExpectedValues[idx],
477                       *(reinterpret_cast<const GLuint *>(ptr0 + idx * kArrayStride)));
478         }
479 
480         const GLbyte *ptr1 = reinterpret_cast<const GLbyte *>(ptr0 + kOffset1);
481         for (unsigned int idx = 0; idx < kMiddlePaddingSize / sizeof(unsigned int); idx++)
482         {
483             EXPECT_EQ(kMiddlePaddingValue, reinterpret_cast<const GLuint *>(ptr1)[idx]);
484         }
485 
486         const GLbyte *ptr2 = ptr1 + kMiddlePaddingSize;
487         for (unsigned int idx = 0; idx < kElementCount; idx++)
488         {
489             EXPECT_EQ(kExpectedValues[idx],
490                       *(reinterpret_cast<const GLuint *>(ptr2 + idx * kArrayStride)));
491         }
492 
493         glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
494         glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
495 
496         EXPECT_GL_NO_ERROR();
497     }
498 }
499 
500 // Tests modifying an existing shader storage buffer
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWriteSame)501 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteSame)
502 {
503     constexpr char kComputeShaderSource[] =
504         R"(#version 310 es
505 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
506 layout(std140, binding = 0) buffer block {
507     uint data;
508 } instance;
509 void main()
510 {
511     uint temp = instance.data;
512     instance.data = temp + 1u;
513 }
514 )";
515 
516     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
517 
518     glUseProgram(program);
519 
520     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
521     constexpr unsigned int kInitialData       = 123u;
522 
523     // Create shader storage buffer
524     GLBuffer shaderStorageBuffer;
525 
526     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
527     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInitialData, GL_STATIC_DRAW);
528 
529     // Bind shader storage buffer
530     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
531 
532     glDispatchCompute(1, 1, 1);
533 
534     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
535 
536     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
537     const void *bufferData =
538         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT);
539 
540     constexpr unsigned int kExpectedData = 124u;
541     EXPECT_EQ(kExpectedData, *static_cast<const GLuint *>(bufferData));
542     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
543 
544     // Running shader twice to make sure that the buffer gets updated correctly 123->124->125
545     glDispatchCompute(1, 1, 1);
546 
547     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT);
548 
549     bufferData = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT);
550 
551     constexpr unsigned int kExpectedData2 = 125u;
552     EXPECT_EQ(kExpectedData2, *static_cast<const GLuint *>(bufferData));
553 
554     // Verify re-using the SSBO buffer with a PBO contains expected data.
555     // This will read-back from FBO using a PBO into the same SSBO buffer.
556 
557     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
558 
559     GLTexture texture;
560     glBindTexture(GL_TEXTURE_2D, texture);
561     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
562 
563     GLFramebuffer framebuffer;
564     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
565     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
566 
567     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
568     glClear(GL_COLOR_BUFFER_BIT);
569 
570     glBindBuffer(GL_PIXEL_PACK_BUFFER, shaderStorageBuffer);
571     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
572     EXPECT_GL_NO_ERROR();
573 
574     void *mappedPtr =
575         glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT);
576     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
577     EXPECT_GL_NO_ERROR();
578 
579     EXPECT_EQ(GLColor::red, dataColor[0]);
580     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
581     EXPECT_GL_NO_ERROR();
582 
583     // Verify that binding the buffer back to the SSBO keeps the expected data.
584 
585     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
586 
587     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
588     const GLColor *ptr = reinterpret_cast<GLColor *>(
589         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT));
590     EXPECT_EQ(GLColor::red, *ptr);
591 
592     EXPECT_GL_NO_ERROR();
593 }
594 
595 // Tests reading and writing to a shader storage buffer bound at an offset.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWriteOffset)596 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteOffset)
597 {
598     constexpr char kCS[] = R"(#version 310 es
599 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
600 
601 layout(std140, binding = 0) buffer block0 {
602     uint data[2];
603 } instance0;
604 
605 void main()
606 {
607     instance0.data[0] = 3u;
608     instance0.data[1] = 4u;
609 }
610 )";
611 
612     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
613 
614     glUseProgram(program);
615 
616     constexpr unsigned int kElementCount = 2;
617     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
618     constexpr unsigned int kArrayStride = 16;
619     // Create shader storage buffer
620     GLBuffer shaderStorageBuffer;
621     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
622 
623     int bufferAlignOffset;
624     glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &bufferAlignOffset);
625 
626     constexpr int kBufferSize = kElementCount * kArrayStride;
627     const int unalignedBytes  = kBufferSize % bufferAlignOffset;
628     const int alignCorrection = unalignedBytes == 0 ? 0 : bufferAlignOffset - unalignedBytes;
629     const int kBufferOffset   = kBufferSize + alignCorrection;
630 
631     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferOffset + kBufferSize, nullptr, GL_STATIC_DRAW);
632 
633     // Bind shader storage buffer at an offset
634     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer, kBufferOffset, kBufferSize);
635     EXPECT_GL_NO_ERROR();
636 
637     glDispatchCompute(1, 1, 1);
638     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
639 
640     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
641 
642     // Bind the buffer at a separate location
643     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer, 0, kBufferSize);
644     EXPECT_GL_NO_ERROR();
645 
646     glDispatchCompute(1, 1, 1);
647     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
648 
649     // Read back shader storage buffer
650     constexpr unsigned int kExpectedValues[2] = {3u, 4u};
651     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
652     void *ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT);
653     for (unsigned int idx = 0; idx < kElementCount; idx++)
654     {
655         EXPECT_EQ(kExpectedValues[idx],
656                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
657                                                      idx * kArrayStride)));
658     }
659     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
660 
661     ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, kBufferOffset, kBufferSize, GL_MAP_READ_BIT);
662     for (unsigned int idx = 0; idx < kElementCount; idx++)
663     {
664         EXPECT_EQ(kExpectedValues[idx],
665                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
666                                                      idx * kArrayStride)));
667     }
668     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
669 
670     EXPECT_GL_NO_ERROR();
671 }
672 
673 // Test that access/write to vector data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferVector)674 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferVector)
675 {
676     constexpr char kComputeShaderSource[] =
677         R"(#version 310 es
678  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
679  layout(std140, binding = 0) buffer blockIn {
680      uvec2 data;
681  } instanceIn;
682  layout(std140, binding = 1) buffer blockOut {
683      uvec2 data;
684  } instanceOut;
685  void main()
686  {
687      instanceOut.data[0] = instanceIn.data[0];
688      instanceOut.data[1] = instanceIn.data[1];
689  }
690  )";
691 
692     constexpr unsigned int kComponentCount         = 2;
693     constexpr GLuint kInputValues[kComponentCount] = {3u, 4u};
694 
695     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kInputValues);
696     runVectorTest(vectorCase);
697 }
698 
699 // Test that the shader works well with an active SSBO but not statically used.
TEST_P(ShaderStorageBufferTest31,ActiveSSBOButNotStaticallyUsed)700 TEST_P(ShaderStorageBufferTest31, ActiveSSBOButNotStaticallyUsed)
701 {
702     // http://anglebug.com/42262382
703     ANGLE_SKIP_TEST_IF(IsAndroid() && IsPixel2() && IsVulkan());
704 
705     constexpr char kComputeShaderSource[] =
706         R"(#version 310 es
707  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
708  layout(std140, binding = 0) buffer blockIn {
709      uvec2 data;
710  } instanceIn;
711  layout(std140, binding = 1) buffer blockOut {
712      uvec2 data;
713  } instanceOut;
714  layout(std140, binding = 2) buffer blockC {
715      uvec2 data;
716  } instanceC;
717  void main()
718  {
719      instanceOut.data[0] = instanceIn.data[0];
720      instanceOut.data[1] = instanceIn.data[1];
721  }
722  )";
723 
724     GLBuffer shaderStorageBufferC;
725     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBufferC);
726     glBufferData(GL_SHADER_STORAGE_BUFFER, 32, nullptr, GL_STATIC_DRAW);
727     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBufferC);
728 
729     constexpr unsigned int kComponentCount         = 2;
730     constexpr GLuint kInputValues[kComponentCount] = {3u, 4u};
731 
732     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kInputValues);
733     runVectorTest(vectorCase);
734 }
735 
736 // Test that access/write to swizzle scalar data in shader storage block.
TEST_P(ShaderStorageBufferTest31,ScalarSwizzleTest)737 TEST_P(ShaderStorageBufferTest31, ScalarSwizzleTest)
738 {
739     constexpr char kComputeShaderSource[] =
740         R"(#version 310 es
741  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
742  layout(std140, binding = 0) buffer blockIn {
743      uvec2 data;
744  } instanceIn;
745  layout(std140, binding = 1) buffer blockOut {
746      uvec2 data;
747  } instanceOut;
748  void main()
749  {
750      instanceOut.data.x = instanceIn.data.y;
751      instanceOut.data.y = instanceIn.data.x;
752  }
753  )";
754 
755     constexpr unsigned int kComponentCount            = 2;
756     constexpr GLuint kInputValues[kComponentCount]    = {3u, 4u};
757     constexpr GLuint kExpectedValues[kComponentCount] = {4u, 3u};
758 
759     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kExpectedValues);
760     runVectorTest(vectorCase);
761 }
762 
763 // Test that access/write to swizzle vector data in shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorSwizzleTest)764 TEST_P(ShaderStorageBufferTest31, VectorSwizzleTest)
765 {
766     constexpr char kComputeShaderSource[] =
767         R"(#version 310 es
768  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
769  layout(std140, binding = 0) buffer blockIn {
770      uvec2 data;
771  } instanceIn;
772  layout(std140, binding = 1) buffer blockOut {
773      uvec2 data;
774  } instanceOut;
775  void main()
776  {
777      instanceOut.data.yx = instanceIn.data.xy;
778  }
779  )";
780 
781     constexpr unsigned int kComponentCount            = 2;
782     constexpr GLuint kInputValues[kComponentCount]    = {3u, 4u};
783     constexpr GLuint kExpectedValues[kComponentCount] = {4u, 3u};
784 
785     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kExpectedValues);
786     runVectorTest(vectorCase);
787 }
788 
789 // Test that access/write to swizzle vector data in column_major matrix in shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorSwizzleInColumnMajorMatrixTest)790 TEST_P(ShaderStorageBufferTest31, VectorSwizzleInColumnMajorMatrixTest)
791 {
792     constexpr char kComputeShaderSource[] =
793         R"(#version 310 es
794  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
795  layout(std140, binding = 0) buffer blockIn {
796      layout(column_major) mat2x3 data;
797  } instanceIn;
798  layout(std140, binding = 1) buffer blockOut {
799      layout(column_major) mat2x3 data;
800  } instanceOut;
801  void main()
802  {
803      instanceOut.data[0].xyz = instanceIn.data[0].xyz;
804      instanceOut.data[1].xyz = instanceIn.data[1].xyz;
805  }
806  )";
807 
808     constexpr unsigned int kColumns                                             = 2;
809     constexpr unsigned int kRows                                                = 3;
810     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
811     constexpr unsigned int kMatrixStride                                        = 16;
812     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
813         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
814     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
815     runMatrixTest(matrixCase);
816 }
817 
818 // Test that access/write to swizzle vector data in row_major matrix in shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorSwizzleInRowMajorMatrixTest)819 TEST_P(ShaderStorageBufferTest31, VectorSwizzleInRowMajorMatrixTest)
820 {
821     ANGLE_SKIP_TEST_IF(IsAndroid());
822 
823     constexpr char kComputeShaderSource[] =
824         R"(#version 310 es
825  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
826  layout(std140, binding = 0) buffer blockIn {
827      layout(row_major) mat2x3 data;
828  } instanceIn;
829  layout(std140, binding = 1) buffer blockOut {
830      layout(row_major) mat2x3 data;
831  } instanceOut;
832  void main()
833  {
834      instanceOut.data[0].xyz = instanceIn.data[0].xyz;
835      instanceOut.data[1].xyz = instanceIn.data[1].xyz;
836  }
837  )";
838 
839     constexpr unsigned int kColumns           = 2;
840     constexpr unsigned int kRows              = 3;
841     constexpr unsigned int kBytesPerComponent = sizeof(float);
842     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
843     // rounded up a multiple of the base alignment of a vec4.
844     constexpr unsigned int kMatrixStride                                     = 16;
845     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
846         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
847     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
848     runMatrixTest(matrixCase);
849 }
850 
851 // Test that access/write to scalar data in matrix in shader storage block with row major.
TEST_P(ShaderStorageBufferTest31,ScalarDataInMatrixInSSBOWithRowMajorQualifier)852 TEST_P(ShaderStorageBufferTest31, ScalarDataInMatrixInSSBOWithRowMajorQualifier)
853 {
854     // TODO([email protected]): Figure out why it fails on Intel Linux platform.
855     // http://anglebug.com/40644618
856     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
857     ANGLE_SKIP_TEST_IF(IsAndroid());
858 
859     constexpr char kComputeShaderSource[] =
860         R"(#version 310 es
861 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
862 layout(std140, binding = 0) buffer blockIn {
863     layout(row_major) mat2x3 data;
864 } instanceIn;
865 layout(std140, binding = 1) buffer blockOut {
866     layout(row_major) mat2x3 data;
867 } instanceOut;
868 void main()
869 {
870     instanceOut.data[0][0] = instanceIn.data[0][0];
871     instanceOut.data[0][1] = instanceIn.data[0][1];
872     instanceOut.data[0][2] = instanceIn.data[0][2];
873     instanceOut.data[1][0] = instanceIn.data[1][0];
874     instanceOut.data[1][1] = instanceIn.data[1][1];
875     instanceOut.data[1][2] = instanceIn.data[1][2];
876 }
877 )";
878 
879     constexpr unsigned int kColumns           = 2;
880     constexpr unsigned int kRows              = 3;
881     constexpr unsigned int kBytesPerComponent = sizeof(float);
882     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
883     // rounded up a multiple of the base alignment of a vec4.
884     constexpr unsigned int kMatrixStride                                     = 16;
885     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
886         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
887     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
888     runMatrixTest(matrixCase);
889 }
890 
TEST_P(ShaderStorageBufferTest31,VectorDataInMatrixInSSBOWithRowMajorQualifier)891 TEST_P(ShaderStorageBufferTest31, VectorDataInMatrixInSSBOWithRowMajorQualifier)
892 {
893     ANGLE_SKIP_TEST_IF(IsAndroid());
894 
895     constexpr char kComputeShaderSource[] =
896         R"(#version 310 es
897 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
898 layout(std140, binding = 0) buffer blockIn {
899     layout(row_major) mat2x3 data;
900 } instanceIn;
901 layout(std140, binding = 1) buffer blockOut {
902     layout(row_major) mat2x3 data;
903 } instanceOut;
904 void main()
905 {
906     instanceOut.data[0] = instanceIn.data[0];
907     instanceOut.data[1] = instanceIn.data[1];
908 }
909 )";
910 
911     constexpr unsigned int kColumns           = 2;
912     constexpr unsigned int kRows              = 3;
913     constexpr unsigned int kBytesPerComponent = sizeof(float);
914     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
915     // rounded up a multiple of the base alignment of a vec4.
916     constexpr unsigned int kMatrixStride                                     = 16;
917     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
918         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
919     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
920     runMatrixTest(matrixCase);
921 }
922 
TEST_P(ShaderStorageBufferTest31,MatrixDataInSSBOWithRowMajorQualifier)923 TEST_P(ShaderStorageBufferTest31, MatrixDataInSSBOWithRowMajorQualifier)
924 {
925     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
926 
927     constexpr char kComputeShaderSource[] =
928         R"(#version 310 es
929 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
930 layout(std140, binding = 0) buffer blockIn {
931     layout(row_major) mat2x3 data;
932 } instanceIn;
933 layout(std140, binding = 1) buffer blockOut {
934     layout(row_major) mat2x3 data;
935 } instanceOut;
936 void main()
937 {
938     instanceOut.data = instanceIn.data;
939 }
940 )";
941 
942     constexpr unsigned int kColumns           = 2;
943     constexpr unsigned int kRows              = 3;
944     constexpr unsigned int kBytesPerComponent = sizeof(float);
945     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
946     // rounded up a multiple of the base alignment of a vec4.
947     constexpr unsigned int kMatrixStride                                     = 16;
948     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
949         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
950     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
951     runMatrixTest(matrixCase);
952 }
953 
954 // Test that access/write to scalar data in structure matrix in shader storage block with row major.
TEST_P(ShaderStorageBufferTest31,ScalarDataInMatrixInStructureInSSBOWithRowMajorQualifier)955 TEST_P(ShaderStorageBufferTest31, ScalarDataInMatrixInStructureInSSBOWithRowMajorQualifier)
956 {
957     // TODO([email protected]): Figure out why it fails on Intel Linux platform.
958     // http://anglebug.com/40644618
959     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
960     ANGLE_SKIP_TEST_IF(IsAndroid());
961 
962     constexpr char kComputeShaderSource[] =
963         R"(#version 310 es
964 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
965 struct S
966 {
967     mat2x3 data;
968 };
969 layout(std140, binding = 0) buffer blockIn {
970     layout(row_major) S s;
971 } instanceIn;
972 layout(std140, binding = 1) buffer blockOut {
973     layout(row_major) S s;
974 } instanceOut;
975 void main()
976 {
977     instanceOut.s.data[0][0] = instanceIn.s.data[0][0];
978     instanceOut.s.data[0][1] = instanceIn.s.data[0][1];
979     instanceOut.s.data[0][2] = instanceIn.s.data[0][2];
980     instanceOut.s.data[1][0] = instanceIn.s.data[1][0];
981     instanceOut.s.data[1][1] = instanceIn.s.data[1][1];
982     instanceOut.s.data[1][2] = instanceIn.s.data[1][2];
983 }
984 )";
985 
986     constexpr unsigned int kColumns           = 2;
987     constexpr unsigned int kRows              = 3;
988     constexpr unsigned int kBytesPerComponent = sizeof(float);
989     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
990     // rounded up a multiple of the base alignment of a vec4.
991     constexpr unsigned int kMatrixStride                                     = 16;
992     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
993         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
994     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
995     runMatrixTest(matrixCase);
996 }
997 
998 // Test that access/write to column major matrix data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ScalarDataInMatrixInSSBO)999 TEST_P(ShaderStorageBufferTest31, ScalarDataInMatrixInSSBO)
1000 {
1001     constexpr char kComputeShaderSource[] =
1002         R"(#version 310 es
1003 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1004 layout(std140, binding = 0) buffer blockIn {
1005     mat2x3 data;
1006 } instanceIn;
1007 layout(std140, binding = 1) buffer blockOut {
1008     mat2x3 data;
1009 } instanceOut;
1010 void main()
1011 {
1012     instanceOut.data[0][0] = instanceIn.data[0][0];
1013     instanceOut.data[0][1] = instanceIn.data[0][1];
1014     instanceOut.data[0][2] = instanceIn.data[0][2];
1015     instanceOut.data[1][0] = instanceIn.data[1][0];
1016     instanceOut.data[1][1] = instanceIn.data[1][1];
1017     instanceOut.data[1][2] = instanceIn.data[1][2];
1018 }
1019 )";
1020 
1021     constexpr unsigned int kColumns                                             = 2;
1022     constexpr unsigned int kRows                                                = 3;
1023     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
1024     constexpr unsigned int kMatrixStride                                        = 16;
1025     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
1026         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
1027     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
1028     runMatrixTest(matrixCase);
1029 }
1030 
TEST_P(ShaderStorageBufferTest31,VectorDataInMatrixInSSBOWithColumnMajorQualifier)1031 TEST_P(ShaderStorageBufferTest31, VectorDataInMatrixInSSBOWithColumnMajorQualifier)
1032 {
1033     constexpr char kComputeShaderSource[] =
1034         R"(#version 310 es
1035 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1036 layout(std140, binding = 0) buffer blockIn {
1037     layout(column_major) mat2x3 data;
1038 } instanceIn;
1039 layout(std140, binding = 1) buffer blockOut {
1040     layout(column_major) mat2x3 data;
1041 } instanceOut;
1042 void main()
1043 {
1044     instanceOut.data[0] = instanceIn.data[0];
1045     instanceOut.data[1] = instanceIn.data[1];
1046 }
1047 )";
1048 
1049     constexpr unsigned int kColumns                                             = 2;
1050     constexpr unsigned int kRows                                                = 3;
1051     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
1052     constexpr unsigned int kMatrixStride                                        = 16;
1053     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
1054         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
1055     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
1056     runMatrixTest(matrixCase);
1057 }
1058 
TEST_P(ShaderStorageBufferTest31,MatrixDataInSSBOWithColumnMajorQualifier)1059 TEST_P(ShaderStorageBufferTest31, MatrixDataInSSBOWithColumnMajorQualifier)
1060 {
1061     constexpr char kComputeShaderSource[] =
1062         R"(#version 310 es
1063 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1064 layout(std140, binding = 0) buffer blockIn {
1065     layout(column_major) mat2x3 data;
1066 } instanceIn;
1067 layout(std140, binding = 1) buffer blockOut {
1068     layout(column_major) mat2x3 data;
1069 } instanceOut;
1070 void main()
1071 {
1072     instanceOut.data = instanceIn.data;
1073 }
1074 )";
1075 
1076     constexpr unsigned int kColumns                                             = 2;
1077     constexpr unsigned int kRows                                                = 3;
1078     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
1079     constexpr unsigned int kMatrixStride                                        = 16;
1080     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
1081         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
1082     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
1083     runMatrixTest(matrixCase);
1084 }
1085 
1086 // Test that access/write to structure data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferStructureArray)1087 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferStructureArray)
1088 {
1089     constexpr char kComputeShaderSource[] =
1090         R"(#version 310 es
1091 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1092 struct S
1093 {
1094     uvec2 uvData;
1095     uint uiData[2];
1096 };
1097 layout(std140, binding = 0) buffer blockIn {
1098     S s[2];
1099     uint lastData;
1100 } instanceIn;
1101 layout(std140, binding = 1) buffer blockOut {
1102     S s[2];
1103     uint lastData;
1104 } instanceOut;
1105 void main()
1106 {
1107     instanceOut.s[0].uvData = instanceIn.s[0].uvData;
1108     instanceOut.s[0].uiData[0] = instanceIn.s[0].uiData[0];
1109     instanceOut.s[0].uiData[1] = instanceIn.s[0].uiData[1];
1110     instanceOut.s[1].uvData = instanceIn.s[1].uvData;
1111     instanceOut.s[1].uiData[0] = instanceIn.s[1].uiData[0];
1112     instanceOut.s[1].uiData[1] = instanceIn.s[1].uiData[1];
1113     instanceOut.lastData = instanceIn.lastData;
1114 }
1115 )";
1116 
1117     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1118 
1119     glUseProgram(program);
1120 
1121     std::array<GLuint, 4> kUVData = {{
1122         1u,
1123         2u,
1124         0u,
1125         0u,
1126     }};
1127     std::array<GLuint, 8> kUIData = {{
1128         3u,
1129         0u,
1130         0u,
1131         0u,
1132         4u,
1133         0u,
1134         0u,
1135         0u,
1136     }};
1137     GLuint kLastData              = 5u;
1138 
1139     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
1140     constexpr unsigned int kStructureStride   = 48;
1141     constexpr unsigned int totalSize          = kStructureStride * 2 + sizeof(kLastData);
1142 
1143     // Create shader storage buffer
1144     GLBuffer shaderStorageBuffer[2];
1145     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1146     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1147     GLint offset = 0;
1148     // upload data to instanceIn.s[0]
1149     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1150                     kUVData.data());
1151     offset += (kUVData.size() * kBytesPerComponent);
1152     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1153                     kUIData.data());
1154     offset += (kUIData.size() * kBytesPerComponent);
1155     // upload data to instanceIn.s[1]
1156     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1157                     kUVData.data());
1158     offset += (kUVData.size() * kBytesPerComponent);
1159     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1160                     kUIData.data());
1161     offset += (kUIData.size() * kBytesPerComponent);
1162     // upload data to instanceIn.lastData
1163     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, sizeof(kLastData), &kLastData);
1164 
1165     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1166     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1167 
1168     // Bind shader storage buffer
1169     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1170     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1171 
1172     glDispatchCompute(1, 1, 1);
1173     glFinish();
1174 
1175     // Read back shader storage buffer
1176     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1177     constexpr float kExpectedValues[5] = {1u, 2u, 3u, 4u, 5u};
1178     const GLuint *ptr                  = reinterpret_cast<const GLuint *>(
1179         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, totalSize, GL_MAP_READ_BIT));
1180     // instanceOut.s[0]
1181     EXPECT_EQ(kExpectedValues[0], *ptr);
1182     EXPECT_EQ(kExpectedValues[1], *(ptr + 1));
1183     EXPECT_EQ(kExpectedValues[2], *(ptr + 4));
1184     EXPECT_EQ(kExpectedValues[3], *(ptr + 8));
1185     // instanceOut.s[1]
1186     ptr += kStructureStride / kBytesPerComponent;
1187     EXPECT_EQ(kExpectedValues[0], *ptr);
1188     EXPECT_EQ(kExpectedValues[1], *(ptr + 1));
1189     EXPECT_EQ(kExpectedValues[2], *(ptr + 4));
1190     EXPECT_EQ(kExpectedValues[3], *(ptr + 8));
1191     // instanceOut.lastData
1192     ptr += kStructureStride / kBytesPerComponent;
1193     EXPECT_EQ(kExpectedValues[4], *(ptr));
1194 
1195     EXPECT_GL_NO_ERROR();
1196 }
1197 
1198 // Test that access/write to array of array structure data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferStructureArrayOfArray)1199 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferStructureArrayOfArray)
1200 {
1201     constexpr char kComputeShaderSource[] = R"(#version 310 es
1202 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1203 struct S
1204 {
1205     uvec2 uvData;
1206     uint uiData[2];
1207 };
1208 layout(std140, binding = 0) buffer blockIn {
1209     S s[3][2];
1210     uint lastData;
1211 } instanceIn;
1212 layout(std140, binding = 1) buffer blockOut {
1213     S s[3][2];
1214     uint lastData;
1215 } instanceOut;
1216 void main()
1217 {
1218     instanceOut.s[1][0].uvData = instanceIn.s[1][0].uvData;
1219     instanceOut.s[1][0].uiData[0] = instanceIn.s[1][0].uiData[0];
1220     instanceOut.s[1][0].uiData[1] = instanceIn.s[1][0].uiData[1];
1221     instanceOut.s[1][1].uvData = instanceIn.s[1][1].uvData;
1222     instanceOut.s[1][1].uiData[0] = instanceIn.s[1][1].uiData[0];
1223     instanceOut.s[1][1].uiData[1] = instanceIn.s[1][1].uiData[1];
1224 
1225     instanceOut.lastData = instanceIn.lastData;
1226 }
1227 )";
1228 
1229     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1230 
1231     glUseProgram(program);
1232 
1233     std::array<GLuint, 4> kUVData = {{
1234         1u,
1235         2u,
1236         0u,
1237         0u,
1238     }};
1239     std::array<GLuint, 8> kUIData = {{
1240         3u,
1241         0u,
1242         0u,
1243         0u,
1244         4u,
1245         0u,
1246         0u,
1247         0u,
1248     }};
1249     GLuint kLastData              = 5u;
1250 
1251     constexpr unsigned int kBytesPerComponent        = sizeof(GLuint);
1252     constexpr unsigned int kStructureStride          = 48;
1253     constexpr unsigned int kStructureArrayDimension0 = 3;
1254     constexpr unsigned int kStructureArrayDimension1 = 2;
1255     constexpr unsigned int kLastDataOffset =
1256         kStructureStride * kStructureArrayDimension0 * kStructureArrayDimension1;
1257     constexpr unsigned int totalSize = kLastDataOffset + sizeof(kLastData);
1258 
1259     GLBuffer shaderStorageBuffer[2];
1260     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1261     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1262     // offset of instanceIn.s[1][0]
1263     GLint offset      = kStructureStride * (kStructureArrayDimension1 * 1 + 0);
1264     GLuint uintOffset = offset / kBytesPerComponent;
1265     // upload data to instanceIn.s[1][0]
1266     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1267                     kUVData.data());
1268     offset += (kUVData.size() * kBytesPerComponent);
1269     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1270                     kUIData.data());
1271     offset += (kUIData.size() * kBytesPerComponent);
1272     // upload data to instanceIn.s[1][1]
1273     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1274                     kUVData.data());
1275     offset += (kUVData.size() * kBytesPerComponent);
1276     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1277                     kUIData.data());
1278     // upload data to instanceIn.lastData
1279     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kLastDataOffset, sizeof(kLastData), &kLastData);
1280 
1281     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1282     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1283 
1284     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1285     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1286 
1287     glDispatchCompute(1, 1, 1);
1288     glFinish();
1289 
1290     // Read back shader storage buffer
1291     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1292     constexpr float kExpectedValues[5] = {1u, 2u, 3u, 4u, 5u};
1293     const GLuint *ptr                  = reinterpret_cast<const GLuint *>(
1294         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, totalSize, GL_MAP_READ_BIT));
1295 
1296     // instanceOut.s[0][0]
1297     EXPECT_EQ(kExpectedValues[0], *(ptr + uintOffset));
1298     EXPECT_EQ(kExpectedValues[1], *(ptr + uintOffset + 1));
1299     EXPECT_EQ(kExpectedValues[2], *(ptr + uintOffset + 4));
1300     EXPECT_EQ(kExpectedValues[3], *(ptr + uintOffset + 8));
1301 
1302     // instanceOut.s[0][1]
1303     EXPECT_EQ(kExpectedValues[0], *(ptr + uintOffset + 12));
1304     EXPECT_EQ(kExpectedValues[1], *(ptr + uintOffset + 13));
1305     EXPECT_EQ(kExpectedValues[2], *(ptr + uintOffset + 16));
1306     EXPECT_EQ(kExpectedValues[3], *(ptr + uintOffset + 20));
1307 
1308     // instanceOut.lastData
1309     EXPECT_EQ(kExpectedValues[4], *(ptr + (kLastDataOffset / kBytesPerComponent)));
1310 
1311     EXPECT_GL_NO_ERROR();
1312 }
1313 
1314 // Test that access/write to vector data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorArrayInSSBOWithStd430Qualifier)1315 TEST_P(ShaderStorageBufferTest31, VectorArrayInSSBOWithStd430Qualifier)
1316 {
1317     constexpr char kComputeShaderSource[] = R"(#version 310 es
1318 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1319 layout(std430, binding = 0) buffer blockIn {
1320     uvec2 data[2];
1321 } instanceIn;
1322 layout(std430, binding = 1) buffer blockOut {
1323     uvec2 data[2];
1324 } instanceOut;
1325 void main()
1326 {
1327     instanceOut.data[0] = instanceIn.data[0];
1328     instanceOut.data[1] = instanceIn.data[1];
1329 }
1330 )";
1331 
1332     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1333 
1334     glUseProgram(program);
1335 
1336     constexpr unsigned int kElementCount      = 2;
1337     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
1338     constexpr unsigned int kArrayStride       = 8;
1339     constexpr unsigned int kComponentCount    = kArrayStride / kBytesPerComponent;
1340     constexpr unsigned int kExpectedValues[kElementCount][kComponentCount] = {{1u, 2u}, {3u, 4u}};
1341     // Create shader storage buffer
1342     GLBuffer shaderStorageBuffer[2];
1343     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1344     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, kExpectedValues,
1345                  GL_STATIC_DRAW);
1346     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1347     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, nullptr, GL_STATIC_DRAW);
1348 
1349     // Bind shader storage buffer
1350     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1351     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1352 
1353     glDispatchCompute(1, 1, 1);
1354 
1355     glFinish();
1356 
1357     // Read back shader storage buffer
1358     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1359     const GLuint *ptr = reinterpret_cast<const GLuint *>(glMapBufferRange(
1360         GL_SHADER_STORAGE_BUFFER, 0, kElementCount * kArrayStride, GL_MAP_READ_BIT));
1361     for (unsigned int idx = 0; idx < kElementCount; idx++)
1362     {
1363         for (unsigned int idy = 0; idy < kComponentCount; idy++)
1364         {
1365             EXPECT_EQ(kExpectedValues[idx][idy], *(ptr + idx * kComponentCount + idy));
1366         }
1367     }
1368 
1369     EXPECT_GL_NO_ERROR();
1370 }
1371 
1372 // Test that access/write to matrix data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,MatrixInSSBOWithStd430Qualifier)1373 TEST_P(ShaderStorageBufferTest31, MatrixInSSBOWithStd430Qualifier)
1374 {
1375     constexpr char kComputeShaderSource[] = R"(#version 310 es
1376 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1377 layout(std430, binding = 0) buffer blockIn {
1378     mat2 data;
1379 } instanceIn;
1380 layout(std430, binding = 1) buffer blockOut {
1381     mat2 data;
1382 } instanceOut;
1383 void main()
1384 {
1385     instanceOut.data = instanceIn.data;
1386 }
1387 )";
1388 
1389     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1390 
1391     glUseProgram(program);
1392 
1393     constexpr unsigned int kColumns              = 2;
1394     constexpr unsigned int kRows                 = 2;
1395     constexpr unsigned int kBytesPerComponent    = sizeof(float);
1396     constexpr unsigned int kMatrixStride         = kRows * kBytesPerComponent;
1397     constexpr float kInputDada[kColumns * kRows] = {0.1, 0.2, 0.4, 0.5};
1398     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
1399     runMatrixTest(matrixCase);
1400 }
1401 
1402 // Test that access/write to structure data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,StructureInSSBOWithStd430Qualifier)1403 TEST_P(ShaderStorageBufferTest31, StructureInSSBOWithStd430Qualifier)
1404 {
1405     constexpr char kComputeShaderSource[] = R"(#version 310 es
1406 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1407 struct S
1408 {
1409     uvec2 u;
1410 };
1411 layout(std430, binding = 0) buffer blockIn {
1412     uint i1;
1413     S s;
1414     uint i2;
1415 } instanceIn;
1416 layout(std430, binding = 1) buffer blockOut {
1417     uint i1;
1418     S s;
1419     uint i2;
1420 } instanceOut;
1421 void main()
1422 {
1423     instanceOut.i1 = instanceIn.i1;
1424     instanceOut.s.u = instanceIn.s.u;
1425     instanceOut.i2 = instanceIn.i2;
1426 }
1427 )";
1428 
1429     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1430     glUseProgram(program);
1431 
1432     GLuint kI1Data               = 1u;
1433     std::array<GLuint, 2> kUData = {{
1434         2u,
1435         3u,
1436     }};
1437     GLuint kI2Data               = 4u;
1438 
1439     constexpr unsigned int kBytesPerComponent    = sizeof(GLuint);
1440     constexpr unsigned int kStructureStartOffset = 8;
1441     constexpr unsigned int kStructureSize        = 8;
1442     constexpr unsigned int kTotalSize = kStructureStartOffset + kStructureSize + kBytesPerComponent;
1443 
1444     // Create shader storage buffer
1445     GLBuffer shaderStorageBuffer[2];
1446     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1447     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1448     // upload data to instanceIn.i1
1449     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, &kI1Data);
1450     // upload data to instanceIn.s.u
1451     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureStartOffset, kStructureSize, kUData.data());
1452     // upload data to instanceIn.i2
1453     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureStartOffset + kStructureSize,
1454                     kBytesPerComponent, &kI2Data);
1455 
1456     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1457     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1458 
1459     // Bind shader storage buffer
1460     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1461     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1462 
1463     glDispatchCompute(1, 1, 1);
1464     glFinish();
1465 
1466     // Read back shader storage buffer
1467     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1468     GLuint kExpectedValues[4] = {1u, 2u, 3u, 4u};
1469     const GLuint *ptr         = reinterpret_cast<const GLuint *>(
1470         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kTotalSize, GL_MAP_READ_BIT));
1471     EXPECT_EQ(kExpectedValues[0], *ptr);
1472     ptr += (kStructureStartOffset / kBytesPerComponent);
1473     EXPECT_EQ(kExpectedValues[1], *ptr);
1474     EXPECT_EQ(kExpectedValues[2], *(ptr + 1));
1475     ptr += (kStructureSize / kBytesPerComponent);
1476     EXPECT_EQ(kExpectedValues[3], *ptr);
1477 
1478     EXPECT_GL_NO_ERROR();
1479 }
1480 
1481 // Test that access/write to structure of structure data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,StructureOfStructureInSSBOWithStd430Qualifier)1482 TEST_P(ShaderStorageBufferTest31, StructureOfStructureInSSBOWithStd430Qualifier)
1483 {
1484     constexpr char kComputeShaderSource[] = R"(#version 310 es
1485 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1486 struct S2
1487 {
1488     uvec3 u2;
1489 };
1490 struct S1
1491 {
1492     uvec2 u1;
1493     S2 s2;
1494 };
1495 layout(std430, binding = 0) buffer blockIn {
1496     uint i1;
1497     S1 s1;
1498     uint i2;
1499 } instanceIn;
1500 layout(std430, binding = 1) buffer blockOut {
1501     uint i1;
1502     S1 s1;
1503     uint i2;
1504 } instanceOut;
1505 void main()
1506 {
1507     instanceOut.i1 = instanceIn.i1;
1508     instanceOut.s1.u1 = instanceIn.s1.u1;
1509     instanceOut.s1.s2.u2 = instanceIn.s1.s2.u2;
1510     instanceOut.i2 = instanceIn.i2;
1511 }
1512 )";
1513 
1514     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1515     glUseProgram(program);
1516 
1517     constexpr unsigned int kBytesPerComponent      = sizeof(GLuint);
1518     constexpr unsigned int kStructureS1StartOffset = 16;
1519     constexpr unsigned int kStructureS2StartOffset = 32;
1520     constexpr unsigned int kStructureS1Size        = 32;
1521     constexpr unsigned int kTotalSize =
1522         kStructureS1StartOffset + kStructureS1Size + kBytesPerComponent;
1523 
1524     GLuint kI1Data                = 1u;
1525     std::array<GLuint, 2> kU1Data = {{2u, 3u}};
1526     std::array<GLuint, 3> kU2Data = {{4u, 5u, 6u}};
1527     GLuint kI2Data                = 7u;
1528 
1529     // Create shader storage buffer
1530     GLBuffer shaderStorageBuffer[2];
1531     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1532     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1533     // upload data to instanceIn.i1
1534     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, &kI1Data);
1535     // upload data to instanceIn.s1.u1
1536     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureS1StartOffset,
1537                     kU1Data.size() * kBytesPerComponent, kU1Data.data());
1538     // upload data to instanceIn.s1.s2.u2
1539     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureS2StartOffset,
1540                     kU2Data.size() * kBytesPerComponent, kU2Data.data());
1541     // upload data to instanceIn.i2
1542     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureS1StartOffset + kStructureS1Size,
1543                     kBytesPerComponent, &kI2Data);
1544 
1545     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1546     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1547 
1548     // Bind shader storage buffer
1549     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1550     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1551 
1552     glDispatchCompute(1, 1, 1);
1553     glFinish();
1554 
1555     // Read back shader storage buffer
1556     GLuint kExpectedValues[7] = {1u, 2u, 3u, 4u, 5u, 6u, 7u};
1557     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1558     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1559         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kTotalSize, GL_MAP_READ_BIT));
1560     EXPECT_EQ(kExpectedValues[0], *ptr);
1561     ptr += (kStructureS1StartOffset / kBytesPerComponent);
1562     EXPECT_EQ(kExpectedValues[1], *ptr);
1563     EXPECT_EQ(kExpectedValues[2], *(ptr + 1));
1564     ptr += ((kStructureS2StartOffset - kStructureS1StartOffset) / kBytesPerComponent);
1565     EXPECT_EQ(kExpectedValues[3], *ptr);
1566     EXPECT_EQ(kExpectedValues[4], *(ptr + 1));
1567     EXPECT_EQ(kExpectedValues[5], *(ptr + 2));
1568     ptr += ((kStructureS1Size - kStructureS2StartOffset) / kBytesPerComponent);
1569     EXPECT_EQ(kExpectedValues[6], *(ptr + 4));
1570 
1571     EXPECT_GL_NO_ERROR();
1572 }
1573 
1574 // Test atomic memory functions.
TEST_P(ShaderStorageBufferTest31,AtomicMemoryFunctions)1575 TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions)
1576 {
1577     constexpr char kCS[] = R"(#version 310 es
1578 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1579 layout(std140, binding = 1) buffer blockName {
1580     uint data[2];
1581 } instanceName;
1582 
1583 void main()
1584 {
1585     instanceName.data[0] = 0u;
1586     instanceName.data[1] = 0u;
1587     atomicAdd(instanceName.data[0], 5u);
1588     atomicMax(instanceName.data[1], 7u);
1589 })";
1590 
1591     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1592 
1593     glUseProgram(program);
1594 
1595     constexpr unsigned int kElementCount = 2;
1596     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
1597     constexpr unsigned int kArrayStride = 16;
1598     // Create shader storage buffer
1599     GLBuffer shaderStorageBuffer;
1600     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
1601     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, nullptr, GL_STATIC_DRAW);
1602 
1603     // Bind shader storage buffer
1604     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
1605 
1606     // Dispath compute
1607     glDispatchCompute(1, 1, 1);
1608 
1609     glFinish();
1610 
1611     // Read back shader storage buffer
1612     constexpr unsigned int kExpectedValues[2] = {5u, 7u};
1613     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
1614     void *ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kElementCount * kArrayStride,
1615                                  GL_MAP_READ_BIT);
1616     for (unsigned int idx = 0; idx < kElementCount; idx++)
1617     {
1618         EXPECT_EQ(kExpectedValues[idx],
1619                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
1620                                                      idx * kArrayStride)));
1621     }
1622     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1623     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1624 
1625     EXPECT_GL_NO_ERROR();
1626 }
1627 
1628 // Test multiple storage buffers work correctly when program switching. In angle, storage buffer
1629 // bindings are updated accord to current program. If switch program, need to update storage buffer
1630 // bindings again.
TEST_P(ShaderStorageBufferTest31,MultiStorageBuffersForMultiPrograms)1631 TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms)
1632 {
1633     constexpr char kCS1[] = R"(#version 310 es
1634 layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
1635 layout(binding = 1) buffer Output {
1636     uint result1[];
1637 } sb_out1;
1638 void main()
1639 {
1640     highp uint offset = gl_LocalInvocationID.x;
1641     sb_out1.result1[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 1u;
1642 })";
1643 
1644     constexpr char kCS2[] = R"(#version 310 es
1645 layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
1646 layout(binding = 2) buffer Output {
1647     uint result2[];
1648 } sb_out2;
1649 void main()
1650 {
1651     highp uint offset = gl_LocalInvocationID.x;
1652     sb_out2.result2[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 2u;
1653 })";
1654 
1655     constexpr unsigned int numInvocations = 3;
1656     int arrayStride1 = 0, arrayStride2 = 0;
1657     GLenum props[] = {GL_ARRAY_STRIDE};
1658     GLBuffer shaderStorageBuffer1, shaderStorageBuffer2;
1659 
1660     ANGLE_GL_COMPUTE_PROGRAM(program1, kCS1);
1661     ANGLE_GL_COMPUTE_PROGRAM(program2, kCS2);
1662     EXPECT_GL_NO_ERROR();
1663 
1664     unsigned int outVarIndex1 =
1665         glGetProgramResourceIndex(program1, GL_BUFFER_VARIABLE, "Output.result1");
1666     glGetProgramResourceiv(program1, GL_BUFFER_VARIABLE, outVarIndex1, 1, props, 1, 0,
1667                            &arrayStride1);
1668     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
1669     glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride1, nullptr, GL_STREAM_READ);
1670     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer1);
1671     EXPECT_GL_NO_ERROR();
1672 
1673     unsigned int outVarIndex2 =
1674         glGetProgramResourceIndex(program2, GL_BUFFER_VARIABLE, "Output.result2");
1675     glGetProgramResourceiv(program2, GL_BUFFER_VARIABLE, outVarIndex2, 1, props, 1, 0,
1676                            &arrayStride2);
1677     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
1678     glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride2, nullptr, GL_STREAM_READ);
1679     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBuffer2);
1680     EXPECT_GL_NO_ERROR();
1681 
1682     glUseProgram(program1);
1683     glDispatchCompute(1, 1, 1);
1684     EXPECT_GL_NO_ERROR();
1685     glUseProgram(program2);
1686     glDispatchCompute(1, 1, 1);
1687     EXPECT_GL_NO_ERROR();
1688 
1689     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
1690     const void *ptr1 =
1691         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride1, GL_MAP_READ_BIT);
1692     for (unsigned int idx = 0; idx < numInvocations; idx++)
1693     {
1694         EXPECT_EQ(idx + 1, *((const GLuint *)((const GLbyte *)ptr1 + idx * arrayStride1)));
1695     }
1696     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1697     EXPECT_GL_NO_ERROR();
1698 
1699     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
1700     const void *ptr2 =
1701         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride2, GL_MAP_READ_BIT);
1702     EXPECT_GL_NO_ERROR();
1703     for (unsigned int idx = 0; idx < numInvocations; idx++)
1704     {
1705         EXPECT_EQ(idx + 2, *((const GLuint *)((const GLbyte *)ptr2 + idx * arrayStride2)));
1706     }
1707     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1708     EXPECT_GL_NO_ERROR();
1709 
1710     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1711     EXPECT_GL_NO_ERROR();
1712 }
1713 
1714 // Test that function calling is supported in SSBO access chain.
TEST_P(ShaderStorageBufferTest31,FunctionCallInSSBOAccessChain)1715 TEST_P(ShaderStorageBufferTest31, FunctionCallInSSBOAccessChain)
1716 {
1717     constexpr char kComputeShaderSource[] = R"(#version 310 es
1718 layout (local_size_x=4) in;
1719 highp uint getIndex (in highp uvec2 localID, uint element)
1720 {
1721     return localID.x + element;
1722 }
1723 layout(binding=0, std430) buffer Storage
1724 {
1725     highp uint values[];
1726 } sb_store;
1727 
1728 void main()
1729 {
1730     sb_store.values[getIndex(gl_LocalInvocationID.xy, 0u)] = gl_LocalInvocationIndex;
1731 }
1732 )";
1733 
1734     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1735     EXPECT_GL_NO_ERROR();
1736 }
1737 
1738 // Test that unary operator is supported in SSBO access chain.
TEST_P(ShaderStorageBufferTest31,UnaryOperatorInSSBOAccessChain)1739 TEST_P(ShaderStorageBufferTest31, UnaryOperatorInSSBOAccessChain)
1740 {
1741     constexpr char kComputeShaderSource[] = R"(#version 310 es
1742 layout (local_size_x=4) in;
1743 layout(binding=0, std430) buffer Storage
1744 {
1745     highp uint values[];
1746 } sb_store;
1747 
1748 void main()
1749 {
1750     uint invocationNdx = gl_LocalInvocationIndex;
1751     sb_store.values[++invocationNdx] = invocationNdx;
1752 }
1753 )";
1754 
1755     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1756     EXPECT_GL_NO_ERROR();
1757 }
1758 
1759 // Test that ternary operator is supported in SSBO access chain.
TEST_P(ShaderStorageBufferTest31,TernaryOperatorInSSBOAccessChain)1760 TEST_P(ShaderStorageBufferTest31, TernaryOperatorInSSBOAccessChain)
1761 {
1762     constexpr char kComputeShaderSource[] = R"(#version 310 es
1763 layout (local_size_x=4) in;
1764 layout(binding=0, std430) buffer Storage
1765 {
1766     highp uint values[];
1767 } sb_store;
1768 
1769 void main()
1770 {
1771     sb_store.values[gl_LocalInvocationIndex > 2u ? gl_NumWorkGroups.x : gl_NumWorkGroups.y]
1772             = gl_LocalInvocationIndex;
1773 }
1774 )";
1775 
1776     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1777     EXPECT_GL_NO_ERROR();
1778 }
1779 
1780 // Tests that alignment is correct for bools inside a SSB and that the values
1781 // are written correctly by a trivial shader. Currently tests only the alignment
1782 // of the initial block.
TEST_P(ShaderStorageBufferTest31,LoadAndStoreBooleanValue)1783 TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanValue)
1784 {
1785     // TODO([email protected]): Figure out why it fails on Intel Linux platform.
1786     // http://anglebug.com/40644618
1787     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
1788 
1789     constexpr char kComputeShaderSource[] = R"(#version 310 es
1790 layout (local_size_x=1) in;
1791 layout(binding=0, std140) buffer Storage0
1792 {
1793     bool b1;
1794     bool b2;
1795     bool b3;
1796 } sb_load;
1797 layout(binding=1, std140) buffer Storage1
1798 {
1799     bool b1;
1800     bool b2;
1801     bool b3;
1802 } sb_store;
1803 void main()
1804 {
1805    sb_store.b1 = sb_load.b1;
1806    sb_store.b2 = sb_load.b2;
1807    sb_store.b3 = sb_load.b3;
1808 }
1809 )";
1810 
1811     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1812     EXPECT_GL_NO_ERROR();
1813 
1814     glUseProgram(program);
1815 
1816     constexpr GLuint kB1Value                 = 1u;
1817     constexpr GLuint kB2Value[2]              = {0u, 1u};
1818     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
1819     // Create shader storage buffer
1820     GLBuffer shaderStorageBuffer[2];
1821     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1822     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, nullptr, GL_STATIC_DRAW);
1823     GLint offset = 0;
1824     // upload data to sb_load.b1
1825     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kBytesPerComponent, &kB1Value);
1826     offset += kBytesPerComponent;
1827     // upload data to sb_load.b2
1828     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, 2 * kBytesPerComponent, kB2Value);
1829 
1830     constexpr GLuint kStoreBufferContents[3] = {0x1BCD1234, 0x2BCD1234, 0x3BCD1234};
1831     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1832     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, kStoreBufferContents,
1833                  GL_STATIC_DRAW);
1834 
1835     // Bind shader storage buffer
1836     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1837     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1838 
1839     glDispatchCompute(1, 1, 1);
1840     glFinish();
1841 
1842     // Read back shader storage buffer
1843     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1844     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1845         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * kBytesPerComponent, GL_MAP_READ_BIT));
1846     EXPECT_EQ(kB1Value, ptr[0]);
1847     EXPECT_EQ(kB2Value[0], ptr[1]);
1848     EXPECT_EQ(kB2Value[1], ptr[2]);
1849 
1850     EXPECT_GL_NO_ERROR();
1851 }
1852 
1853 // Tests that alignment is correct for bvecs3 inside a SSB and that the
1854 // values are written correctly by a trivial shader. Currently tests only the
1855 // alignment of the initial block.
TEST_P(ShaderStorageBufferTest31,LoadAndStoreBooleanVec3)1856 TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanVec3)
1857 {
1858     // TODO([email protected]): Figure out why it fails on Intel Linux platform.
1859     // http://anglebug.com/40644618
1860     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
1861 
1862     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
1863 
1864     constexpr char kComputeShaderSource[] = R"(#version 310 es
1865 layout (local_size_x=1) in;
1866 layout(binding=0, std140) buffer Storage0
1867 {
1868     bvec3 b;
1869 } sb_load;
1870 layout(binding=1, std140) buffer Storage1
1871 {
1872     bvec3 b;
1873 } sb_store;
1874 void main()
1875 {
1876    sb_store.b = sb_load.b;
1877 }
1878 )";
1879 
1880     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1881     EXPECT_GL_NO_ERROR();
1882 
1883     glUseProgram(program);
1884 
1885     constexpr GLuint kBValues[3]              = {1u, 0u, 1u};
1886     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
1887     // Create shader storage buffer
1888     GLBuffer shaderStorageBuffer[2];
1889     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1890     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, nullptr, GL_STATIC_DRAW);
1891     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, 3 * kBytesPerComponent, &kBValues);
1892 
1893     constexpr GLuint kStoreBufferContents[3] = {0x1BCD1234, 0x2BCD1234, 0x3BCD1234};
1894     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1895     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, kStoreBufferContents,
1896                  GL_STATIC_DRAW);
1897 
1898     // Bind shader storage buffer
1899     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1900     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1901 
1902     glDispatchCompute(1, 1, 1);
1903     glFinish();
1904 
1905     // Read back shader storage buffer
1906     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1907     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1908         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * kBytesPerComponent, GL_MAP_READ_BIT));
1909     EXPECT_EQ(kBValues[0], ptr[0]);
1910     EXPECT_EQ(kBValues[1], ptr[1]);
1911     EXPECT_EQ(kBValues[2], ptr[2]);
1912 
1913     EXPECT_GL_NO_ERROR();
1914 }
1915 
1916 // Tests that alignment is correct for bool + bvecs2 inside a SSB and that the
1917 // values are written correctly by a trivial shader. Currently tests only the
1918 // alignment of the initial block. Compare to LoadAndStoreBooleanVec3 to see how
1919 // the alignment rules affect the memory layout.
TEST_P(ShaderStorageBufferTest31,LoadAndStoreBooleanVarAndVec2)1920 TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanVarAndVec2)
1921 {
1922     // TODO([email protected]): Figure out why it fails on Intel Linux platform.
1923     // http://anglebug.com/40644618
1924     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
1925 
1926     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
1927 
1928     constexpr char kComputeShaderSource[] = R"(#version 310 es
1929 layout (local_size_x=1) in;
1930 layout(binding=0, std140) buffer Storage0
1931 {
1932     bool b1;
1933     bvec2 b2;
1934 } sb_load;
1935 layout(binding=1, std140) buffer Storage1
1936 {
1937     bool b1;
1938     bvec2 b2;
1939 } sb_store;
1940 void main()
1941 {
1942    sb_store.b1 = sb_load.b1;
1943    sb_store.b2 = sb_load.b2;
1944 }
1945 )";
1946     // https://www.khronos.org/registry/OpenGL/specs/es/3.1/es_spec_3.1.pdf
1947     // 7.6.2.2 Standard Uniform Block Layout
1948 
1949     // ... A structure and each structure member have a base offset and a base
1950     // alignment, from which an aligned offset is computed by rounding the base
1951     // offset up to a multiple of the base alignment. The base offset of the
1952     // first member of a structure is taken from the aligned offset of the
1953     // structure itself. ... The members of a toplevel uniform block are laid
1954     // out in buffer storage by treating the uniform block as a structure with a
1955     // base offset of zero.
1956 
1957     // 1. If the member is a scalar consuming N basic machine units, the base
1958     // alignment is N.
1959 
1960     // 2. If the member is a two- or four-component vector with components
1961     // consuming N basic machine units, the base alignment is 2N or 4N,
1962     // respectively
1963 
1964     // b1 N == 4, basic offset 0, alignment 4, is at 0..3
1965     // b2 N == 4, basic offset 4, alignment 2*4 = 8, is at 8..16.
1966 
1967     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1968     EXPECT_GL_NO_ERROR();
1969 
1970     glUseProgram(program);
1971     constexpr GLuint kAlignPadding  = 0x1abcd789u;
1972     constexpr GLuint kBValues[]     = {1u, kAlignPadding, 0u, 1u};
1973     constexpr unsigned int kSsbSize = sizeof(kBValues);
1974     // Create shader storage buffer
1975     GLBuffer shaderStorageBuffer[2];
1976     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1977     glBufferData(GL_SHADER_STORAGE_BUFFER, kSsbSize, nullptr, GL_STATIC_DRAW);
1978     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kSsbSize, &kBValues);
1979 
1980     constexpr GLuint kStoreBufferContents[4] = {0x1BCD1234, 0x2BCD1234, 0x3BCD1234, 0x3BCD1277};
1981     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1982     glBufferData(GL_SHADER_STORAGE_BUFFER, kSsbSize, kStoreBufferContents, GL_STATIC_DRAW);
1983 
1984     // Bind shader storage buffer
1985     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1986     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1987 
1988     glDispatchCompute(1, 1, 1);
1989     glFinish();
1990 
1991     // Read back shader storage buffer
1992     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1993     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1994         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSsbSize, GL_MAP_READ_BIT));
1995     EXPECT_EQ(kBValues[0], ptr[0]);
1996     // Index 1 is padding.
1997     EXPECT_EQ(kBValues[2], ptr[2]);
1998     EXPECT_EQ(kBValues[3], ptr[3]);
1999 
2000     EXPECT_GL_NO_ERROR();
2001 }
2002 
2003 // Test that non-structure array of arrays is supported in SSBO.
TEST_P(ShaderStorageBufferTest31,SimpleArrayOfArrays)2004 TEST_P(ShaderStorageBufferTest31, SimpleArrayOfArrays)
2005 {
2006     constexpr char kComputeShaderSource[] = R"(#version 310 es
2007 layout (local_size_x=1) in;
2008 layout(binding=0, std140) buffer Storage0
2009 {
2010     uint a[2][2][2];
2011     uint b;
2012 } sb_load;
2013 layout(binding=1, std140) buffer Storage1
2014 {
2015     uint a[2][2][2];
2016     uint b;
2017 } sb_store;
2018 void main()
2019 {
2020    sb_store.a[0][0][0] = sb_load.a[0][0][0];
2021    sb_store.a[0][0][1] = sb_load.a[0][0][1];
2022    sb_store.a[0][1][0] = sb_load.a[0][1][0];
2023    sb_store.a[0][1][1] = sb_load.a[0][1][1];
2024    sb_store.a[1][0][0] = sb_load.a[1][0][0];
2025    sb_store.a[1][0][1] = sb_load.a[1][0][1];
2026    sb_store.a[1][1][0] = sb_load.a[1][1][0];
2027    sb_store.a[1][1][1] = sb_load.a[1][1][1];
2028    sb_store.b = sb_load.b;
2029 }
2030 )";
2031 
2032     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2033     glUseProgram(program);
2034 
2035     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
2036     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
2037     constexpr unsigned int kArrayStride                 = 16;
2038     constexpr unsigned int kDimension0                  = 2;
2039     constexpr unsigned int kDimension1                  = 2;
2040     constexpr unsigned int kDimension2                  = 2;
2041     constexpr unsigned int kAElementCount               = kDimension0 * kDimension1 * kDimension2;
2042     constexpr unsigned int kAComponentCountPerDimension = kArrayStride / kBytesPerComponent;
2043     constexpr unsigned int kTotalSize = kArrayStride * kAElementCount + kBytesPerComponent;
2044 
2045     constexpr GLuint kInputADatas[kAElementCount * kAComponentCountPerDimension] = {
2046         1u, 0u, 0u, 0u, 2u, 0u, 0u, 0u, 3u, 0u, 0u, 0u, 4u, 0u, 0u, 0u,
2047         5u, 0u, 0u, 0u, 6u, 0u, 0u, 0u, 7u, 0u, 0u, 0u, 8u, 0u, 0u, 0u};
2048     constexpr GLuint kInputBData = 9u;
2049 
2050     // Create shader storage buffer
2051     GLBuffer shaderStorageBuffer[2];
2052     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2053     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
2054     GLint offset = 0;
2055     // upload data to sb_load.a
2056     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kAElementCount * kArrayStride, kInputADatas);
2057     offset += (kAElementCount * kArrayStride);
2058     // upload data to sb_load.b
2059     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kBytesPerComponent, &kInputBData);
2060 
2061     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2062     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
2063 
2064     // Bind shader storage buffer
2065     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2066     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2067 
2068     glDispatchCompute(1, 1, 1);
2069     glFinish();
2070 
2071     // Read back shader storage buffer
2072     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2073     constexpr GLuint kExpectedADatas[kAElementCount] = {1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u};
2074     const GLuint *ptr                                = reinterpret_cast<const GLuint *>(
2075         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kTotalSize, GL_MAP_READ_BIT));
2076     for (unsigned i = 0u; i < kDimension0; i++)
2077     {
2078         for (unsigned j = 0u; j < kDimension1; j++)
2079         {
2080             for (unsigned k = 0u; k < kDimension2; k++)
2081             {
2082                 unsigned index = i * (kDimension1 * kDimension2) + j * kDimension2 + k;
2083                 EXPECT_EQ(kExpectedADatas[index],
2084                           *(ptr + index * (kArrayStride / kBytesPerComponent)));
2085             }
2086         }
2087     }
2088 
2089     ptr += (kAElementCount * (kArrayStride / kBytesPerComponent));
2090     EXPECT_EQ(kInputBData, *ptr);
2091 
2092     EXPECT_GL_NO_ERROR();
2093 }
2094 
2095 // Test that the length of unsized array is supported.
TEST_P(ShaderStorageBufferTest31,UnsizedArrayLength)2096 TEST_P(ShaderStorageBufferTest31, UnsizedArrayLength)
2097 {
2098     constexpr char kComputeShaderSource[] =
2099         R"(#version 310 es
2100 layout (local_size_x=1) in;
2101 layout(std430, binding = 0) buffer Storage0 {
2102   uint buf1[2];
2103   uint buf2[];
2104 } sb_load;
2105 layout(std430, binding = 1) buffer Storage1 {
2106   int unsizedArrayLength;
2107   uint buf1[2];
2108   uint buf2[];
2109 } sb_store;
2110 
2111 void main()
2112 {
2113   sb_store.unsizedArrayLength = sb_store.buf2.length();
2114   for (int i = 0; i < sb_load.buf1.length(); i++) {
2115     sb_store.buf1[i] = sb_load.buf1[i];
2116   }
2117   for (int i = 0; i < sb_load.buf2.length(); i++) {
2118     sb_store.buf2[i] = sb_load.buf2[i];
2119   }
2120 }
2121 )";
2122 
2123     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2124     glUseProgram(program);
2125 
2126     constexpr unsigned int kBytesPerComponent                       = sizeof(unsigned int);
2127     constexpr unsigned int kLoadBlockElementCount                   = 5;
2128     constexpr unsigned int kStoreBlockElementCount                  = 6;
2129     constexpr unsigned int kInputValues[kLoadBlockElementCount]     = {1u, 2u, 3u, 4u, 5u};
2130     constexpr unsigned int kExpectedValues[kStoreBlockElementCount] = {3u, 1u, 2u, 3u, 4u, 5u};
2131     GLBuffer shaderStorageBuffer[2];
2132     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2133     glBufferData(GL_SHADER_STORAGE_BUFFER, kLoadBlockElementCount * kBytesPerComponent,
2134                  &kInputValues, GL_STATIC_DRAW);
2135     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2136     glBufferData(GL_SHADER_STORAGE_BUFFER, kStoreBlockElementCount * kBytesPerComponent, nullptr,
2137                  GL_STATIC_DRAW);
2138 
2139     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2140     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2141 
2142     glDispatchCompute(1, 1, 1);
2143     glFinish();
2144 
2145     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2146     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2147         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kStoreBlockElementCount * kBytesPerComponent,
2148                          GL_MAP_READ_BIT));
2149     for (unsigned int i = 0; i < kStoreBlockElementCount; i++)
2150     {
2151         EXPECT_EQ(kExpectedValues[i], *(ptr + i));
2152     }
2153 
2154     EXPECT_GL_NO_ERROR();
2155 }
2156 
2157 // Test back to back that the length of unsized array is correct after respecifying the buffer
2158 // size to be smaller than the first
TEST_P(ShaderStorageBufferTest31,UnsizedArrayLengthRespecifySize)2159 TEST_P(ShaderStorageBufferTest31, UnsizedArrayLengthRespecifySize)
2160 {
2161     // http://anglebug.com/42263171
2162     ANGLE_SKIP_TEST_IF(IsD3D11() || (IsAndroid() && IsOpenGLES()));
2163 
2164     constexpr char kComputeShaderSource[] =
2165         R"(#version 310 es
2166 layout (local_size_x=1) in;
2167 layout(std430, binding = 0) buffer Storage0 {
2168   uint buf1[2];
2169   uint buf2[];
2170 } sb_load;
2171 layout(std430, binding = 1) buffer Storage1 {
2172   int unsizedArrayLength;
2173   uint buf1[2];
2174   uint buf2[];
2175 } sb_store;
2176 
2177 void main()
2178 {
2179   sb_store.unsizedArrayLength = sb_store.buf2.length();
2180   for (int i = 0; i < sb_load.buf1.length(); i++) {
2181     sb_store.buf1[i] = sb_load.buf1[i];
2182   }
2183   for (int i = 0; i < sb_load.buf2.length(); i++) {
2184     sb_store.buf2[i] = sb_load.buf2[i];
2185   }
2186 }
2187 )";
2188 
2189     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2190     glUseProgram(program);
2191 
2192     constexpr unsigned int kBytesPerComponent                       = sizeof(unsigned int);
2193     constexpr unsigned int kLoadBlockElementCount                   = 5;
2194     constexpr unsigned int kStoreBlockElementCount                  = 6;
2195     constexpr unsigned int kInputValues[kLoadBlockElementCount]     = {1u, 2u, 3u, 4u, 5u};
2196     constexpr unsigned int kExpectedValues[kStoreBlockElementCount] = {3u, 1u, 2u, 3u, 4u, 5u};
2197     GLBuffer shaderStorageBuffer[2];
2198     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2199     glBufferData(GL_SHADER_STORAGE_BUFFER, kLoadBlockElementCount * kBytesPerComponent,
2200                  &kInputValues, GL_STATIC_DRAW);
2201     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2202     glBufferData(GL_SHADER_STORAGE_BUFFER, kStoreBlockElementCount * kBytesPerComponent, nullptr,
2203                  GL_STATIC_DRAW);
2204 
2205     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2206     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2207 
2208     glDispatchCompute(1, 1, 1);
2209     glFinish();
2210 
2211     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2212     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2213         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kStoreBlockElementCount * kBytesPerComponent,
2214                          GL_MAP_READ_BIT));
2215     for (unsigned int i = 0; i < kStoreBlockElementCount; i++)
2216     {
2217         EXPECT_EQ(kExpectedValues[i], *(ptr + i));
2218     }
2219     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2220 
2221     EXPECT_GL_NO_ERROR();
2222 
2223     // Respecify these SSBOs to be smaller
2224     constexpr unsigned int kSmallerLoadBlockElementCount                          = 3;
2225     constexpr unsigned int kSmallerStoreBlockElementCount                         = 4;
2226     constexpr unsigned int kSmallerInputValues[kSmallerLoadBlockElementCount]     = {1u, 2u, 3u};
2227     constexpr unsigned int kSmallerExpectedValues[kSmallerStoreBlockElementCount] = {1u, 1u, 2u,
2228                                                                                      3u};
2229 
2230     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2231     glBufferData(GL_SHADER_STORAGE_BUFFER, kSmallerLoadBlockElementCount * kBytesPerComponent,
2232                  &kSmallerInputValues, GL_STATIC_DRAW);
2233     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2234     glBufferData(GL_SHADER_STORAGE_BUFFER, kSmallerStoreBlockElementCount * kBytesPerComponent,
2235                  nullptr, GL_STATIC_DRAW);
2236 
2237     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2238     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2239 
2240     glDispatchCompute(1, 1, 1);
2241     glFinish();
2242 
2243     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2244     const GLuint *ptr2 = reinterpret_cast<const GLuint *>(
2245         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
2246                          kSmallerStoreBlockElementCount * kBytesPerComponent, GL_MAP_READ_BIT));
2247     for (unsigned int i = 0; i < kSmallerStoreBlockElementCount; i++)
2248     {
2249         EXPECT_EQ(kSmallerExpectedValues[i], *(ptr2 + i));
2250     }
2251 
2252     EXPECT_GL_NO_ERROR();
2253 }
2254 
2255 // Test that compond assignment operator for buffer variable is correctly handled.
TEST_P(ShaderStorageBufferTest31,CompoundAssignmentOperator)2256 TEST_P(ShaderStorageBufferTest31, CompoundAssignmentOperator)
2257 {
2258     constexpr char kComputeShaderSource[] =
2259         R"(#version 310 es
2260 layout (local_size_x=1) in;
2261 layout(binding=0, std140) buffer Storage0
2262 {
2263     uint b;
2264 } sb_load;
2265 layout(binding=1, std140) buffer Storage1
2266 {
2267     uint b;
2268 } sb_store;
2269 void main()
2270 {
2271     uint temp = 2u;
2272     temp += sb_load.b;
2273     sb_store.b += temp;
2274     sb_store.b += sb_load.b;
2275 }
2276 )";
2277 
2278     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2279     glUseProgram(program);
2280 
2281     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
2282     constexpr unsigned int kInputValue        = 1u;
2283     constexpr unsigned int kExpectedValue     = 5u;
2284     GLBuffer shaderStorageBuffer[2];
2285     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2286     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2287     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2288     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2289 
2290     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2291     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2292 
2293     glDispatchCompute(1, 1, 1);
2294     glFinish();
2295 
2296     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2297     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2298         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT));
2299     EXPECT_EQ(kExpectedValue, *ptr);
2300 
2301     EXPECT_GL_NO_ERROR();
2302 }
2303 
2304 // Test that BufferData change propagate to context state.
TEST_P(ShaderStorageBufferTest31,DependentBufferChange)2305 TEST_P(ShaderStorageBufferTest31, DependentBufferChange)
2306 {
2307     // Test fail on Nexus devices. http://anglebug.com/42264770
2308     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
2309 
2310     constexpr char kComputeShaderSource[] =
2311         R"(#version 310 es
2312 layout (local_size_x=1) in;
2313 layout(binding=0, std140) buffer Storage0
2314 {
2315     uint b;
2316 } sb_load;
2317 layout(binding=1, std140) buffer Storage1
2318 {
2319     uint b;
2320 } sb_store;
2321 void main()
2322 {
2323     sb_store.b += sb_load.b;
2324 }
2325 )";
2326 
2327     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2328     glUseProgram(program);
2329 
2330     constexpr unsigned int kBufferSize                        = 4096;
2331     constexpr unsigned int kBufferElementCount                = kBufferSize / sizeof(unsigned int);
2332     std::array<unsigned int, kBufferElementCount> kBufferData = {};
2333     GLBuffer shaderStorageBuffer[2];
2334     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2335     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2336     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2337     kBufferData[0] = 5;  // initial value
2338     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2339 
2340     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2341     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2342 
2343     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2344     kBufferData[0] = 7;
2345     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2346     glDispatchCompute(1, 1, 1);
2347     kBufferData[0] = 11;
2348     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT);
2349     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2350     glDispatchCompute(1, 1, 1);
2351 
2352     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2353     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2354     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2355         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
2356     constexpr unsigned int kExpectedValue = 5 + 7 + 11;
2357     EXPECT_EQ(kExpectedValue, *ptr);
2358 
2359     EXPECT_GL_NO_ERROR();
2360 }
2361 
2362 // Test that readonly binary operator for buffer variable is correctly handled.
TEST_P(ShaderStorageBufferTest31,ReadonlyBinaryOperator)2363 TEST_P(ShaderStorageBufferTest31, ReadonlyBinaryOperator)
2364 {
2365     constexpr char kComputeShaderSource[] =
2366         R"(#version 310 es
2367  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2368  layout(std430, binding = 0) buffer blockIn1 {
2369      uvec2 data1;
2370  };
2371  layout(std430, binding = 1) buffer blockIn2 {
2372      uvec2 data2;
2373  };
2374  layout(std430, binding = 2) buffer blockIn3 {
2375      uvec2 data;
2376  } instanceIn3;
2377  layout(std430, binding = 3) buffer blockOut {
2378      uvec2 data;
2379  } instanceOut;
2380  void main()
2381  {
2382      instanceOut.data = data1 + data2 + instanceIn3.data;
2383  }
2384  )";
2385 
2386     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2387     glUseProgram(program);
2388 
2389     constexpr unsigned int kComponentCount                = 2;
2390     constexpr unsigned int kBytesPerComponent             = sizeof(unsigned int);
2391     constexpr unsigned int kInputValues1[kComponentCount] = {1u, 2u};
2392     constexpr unsigned int kInputValues2[kComponentCount] = {3u, 4u};
2393     constexpr unsigned int kInputValues3[kComponentCount] = {5u, 6u};
2394     // Create shader storage buffer
2395     GLBuffer shaderStorageBuffer[4];
2396     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2397     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, kInputValues1,
2398                  GL_STATIC_DRAW);
2399     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2400     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, kInputValues2,
2401                  GL_STATIC_DRAW);
2402     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[2]);
2403     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, kInputValues3,
2404                  GL_STATIC_DRAW);
2405     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[3]);
2406     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, nullptr,
2407                  GL_STATIC_DRAW);
2408 
2409     // Bind shader storage buffer
2410     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2411     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2412     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBuffer[2]);
2413     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, shaderStorageBuffer[3]);
2414 
2415     glDispatchCompute(1, 1, 1);
2416     glFinish();
2417 
2418     // Read back shader storage buffer
2419     constexpr unsigned int kExpectedValues[kComponentCount] = {9u, 12u};
2420     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[3]);
2421     const GLuint *ptr = reinterpret_cast<const GLuint *>(glMapBufferRange(
2422         GL_SHADER_STORAGE_BUFFER, 0, kComponentCount * kBytesPerComponent, GL_MAP_READ_BIT));
2423     for (unsigned int idx = 0; idx < kComponentCount; idx++)
2424     {
2425         EXPECT_EQ(kExpectedValues[idx], *(ptr + idx));
2426     }
2427 
2428     EXPECT_GL_NO_ERROR();
2429 }
2430 
2431 // Test that ssbo as an argument of a function can be translated.
TEST_P(ShaderStorageBufferTest31,SSBOAsFunctionArgument)2432 TEST_P(ShaderStorageBufferTest31, SSBOAsFunctionArgument)
2433 {
2434     constexpr char kComputeShaderSource[] =
2435         R"(#version 310 es
2436 layout(local_size_x = 1) in;
2437 
2438 layout(std430, binding = 0) buffer Block
2439 {
2440     uint var1;
2441     uint var2;
2442 };
2443 
2444 bool compare(uint a, uint b)
2445 {
2446     return a == b;
2447 }
2448 
2449 uint increase(inout uint a)
2450 {
2451     a++;
2452     return a;
2453 }
2454 
2455 void main(void)
2456 {
2457     bool isEqual = compare(var1, 2u);
2458     if (isEqual)
2459     {
2460         var2 += increase(var1);
2461     }
2462 }
2463 )";
2464 
2465     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2466     glUseProgram(program);
2467 
2468     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
2469     constexpr unsigned int kInputValues[2]    = {2u, 2u};
2470     constexpr unsigned int kExpectedValues[2] = {3u, 5u};
2471     GLBuffer shaderStorageBuffer;
2472     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
2473     glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * kBytesPerComponent, &kInputValues, GL_STATIC_DRAW);
2474 
2475     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
2476 
2477     glDispatchCompute(1, 1, 1);
2478     glFinish();
2479 
2480     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
2481     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2482         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 2 * kBytesPerComponent, GL_MAP_READ_BIT));
2483     EXPECT_EQ(kExpectedValues[0], *ptr);
2484     EXPECT_EQ(kExpectedValues[1], *(ptr + 1));
2485 
2486     EXPECT_GL_NO_ERROR();
2487 }
2488 
2489 // Test that ssbo as unary operand works well.
TEST_P(ShaderStorageBufferTest31,SSBOAsUnaryOperand)2490 TEST_P(ShaderStorageBufferTest31, SSBOAsUnaryOperand)
2491 {
2492     constexpr char kComputeShaderSource[] =
2493         R"(#version 310 es
2494 layout (local_size_x=1) in;
2495 layout(binding=0, std140) buffer Storage0
2496 {
2497     uint b;
2498 } sb_load;
2499 layout(binding=1, std140) buffer Storage1
2500 {
2501     uint i;
2502 } sb_store;
2503 void main()
2504 {
2505     sb_store.i = +sb_load.b;
2506     ++sb_store.i;
2507 }
2508 )";
2509 
2510     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2511     glUseProgram(program);
2512 
2513     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
2514     constexpr unsigned kInputValue            = 1u;
2515     constexpr unsigned int kExpectedValue     = 2u;
2516     GLBuffer shaderStorageBuffer[2];
2517     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2518     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2519     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2520     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2521 
2522     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2523     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2524 
2525     glDispatchCompute(1, 1, 1);
2526     glFinish();
2527 
2528     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2529     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2530         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT));
2531     EXPECT_EQ(kExpectedValue, *ptr);
2532 
2533     EXPECT_GL_NO_ERROR();
2534 }
2535 
2536 // Test that uniform can be used as the index of buffer variable.
TEST_P(ShaderStorageBufferTest31,UniformUsedAsIndexOfBufferVariable)2537 TEST_P(ShaderStorageBufferTest31, UniformUsedAsIndexOfBufferVariable)
2538 {
2539     constexpr char kComputeShaderSource[] =
2540         R"(#version 310 es
2541 layout (local_size_x=4) in;
2542 layout(std140, binding = 0) uniform CB
2543 {
2544     uint index;
2545 } cb;
2546 
2547 layout(binding=0, std140) buffer Storage0
2548 {
2549     uint data[];
2550 } sb_load;
2551 layout(binding=1, std140) buffer Storage1
2552 {
2553     uint data[];
2554 } sb_store;
2555 void main()
2556 {
2557     sb_store.data[gl_LocalInvocationIndex] = sb_load.data[gl_LocalInvocationID.x + cb.index];
2558 }
2559 )";
2560 
2561     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2562     EXPECT_GL_NO_ERROR();
2563 }
2564 
2565 // Test that inactive but statically used SSBOs with unsized array are handled correctly.
2566 //
2567 // Glslang wrapper used to replace the layout/qualifier of an inactive SSBO with |struct|,
2568 // effectively turning the interface block declaration into a struct definition.  This generally
2569 // worked except for SSBOs with an unsized array.  This test makes sure this special case is
2570 // now properly handled.
TEST_P(ShaderStorageBufferTest31,InactiveButStaticallyUsedWithUnsizedArray)2571 TEST_P(ShaderStorageBufferTest31, InactiveButStaticallyUsedWithUnsizedArray)
2572 {
2573     constexpr char kComputeShaderSource[] =
2574         R"(#version 310 es
2575 layout (local_size_x=1) in;
2576 layout(binding=0, std140) buffer Storage
2577 {
2578     uint data[];
2579 } sb;
2580 void main()
2581 {
2582     if (false)
2583     {
2584         sb.data[0] = 1u;
2585     }
2586 }
2587 )";
2588 
2589     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2590     EXPECT_GL_NO_ERROR();
2591 
2592     glUseProgram(program);
2593     glDispatchCompute(1, 1, 1);
2594     EXPECT_GL_NO_ERROR();
2595 }
2596 
2597 // Verify the size of the buffer with unsized struct array is calculated correctly
TEST_P(ShaderStorageBufferTest31,BigStructUnsizedStructArraySize)2598 TEST_P(ShaderStorageBufferTest31, BigStructUnsizedStructArraySize)
2599 {
2600     // TODO(http://anglebug.com/42262259)
2601     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
2602 
2603     constexpr char kComputeShaderSource[] =
2604         R"(#version 310 es
2605 layout (local_size_x=1) in;
2606 
2607 struct S
2608 {
2609     mat4 m;     // 4 vec4 = 16 floats
2610     vec4 a[10]; // 10 vec4 = 40 floats
2611 };
2612 
2613 layout(binding=0) buffer B
2614 {
2615     vec4 precedingMember;               // 4 floats
2616     S precedingMemberUnsizedArray[];    // 56 floats
2617 } b;
2618 
2619 void main()
2620 {
2621     if (false)
2622     {
2623         b.precedingMember = vec4(1.0, 1.0, 1.0, 1.0);
2624     }
2625 }
2626 )";
2627 
2628     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2629     EXPECT_GL_NO_ERROR();
2630 
2631     glUseProgram(program);
2632     glDispatchCompute(1, 1, 1);
2633     EXPECT_GL_NO_ERROR();
2634 
2635     GLuint resourceIndex = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "B");
2636     EXPECT_GL_NO_ERROR();
2637     EXPECT_NE(resourceIndex, 0xFFFFFFFF);
2638 
2639     GLenum property = GL_BUFFER_DATA_SIZE;
2640     GLint queryData = -1;
2641     glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &property, 1,
2642                            nullptr, &queryData);
2643     EXPECT_GL_NO_ERROR();
2644 
2645     // 60 * sizeof(float) = 240
2646     // Vulkan rounds up to the required buffer alignment, so >= 240
2647     EXPECT_GE(queryData, 240);
2648 }
2649 
2650 // Verify the size of the buffer with unsized float array is calculated correctly
TEST_P(ShaderStorageBufferTest31,BigStructUnsizedFloatArraySize)2651 TEST_P(ShaderStorageBufferTest31, BigStructUnsizedFloatArraySize)
2652 {
2653     // TODO(http://anglebug.com/42262259)
2654     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
2655 
2656     constexpr char kComputeShaderSource[] =
2657         R"(#version 310 es
2658 layout (local_size_x=1) in;
2659 
2660 layout(binding=0) buffer B
2661 {
2662     vec4 precedingMember;                   // 4 floats
2663     float precedingMemberUnsizedArray[];    // "1" float
2664 } b;
2665 
2666 void main()
2667 {
2668     if (false)
2669     {
2670         b.precedingMember = vec4(1.0, 1.0, 1.0, 1.0);
2671     }
2672 }
2673 )";
2674 
2675     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2676     EXPECT_GL_NO_ERROR();
2677 
2678     glUseProgram(program);
2679     glDispatchCompute(1, 1, 1);
2680     EXPECT_GL_NO_ERROR();
2681 
2682     GLuint resourceIndex = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "B");
2683     EXPECT_GL_NO_ERROR();
2684     EXPECT_NE(resourceIndex, 0xFFFFFFFF);
2685 
2686     GLenum property = GL_BUFFER_DATA_SIZE;
2687     GLint queryData = -1;
2688     glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &property, 1,
2689                            nullptr, &queryData);
2690     EXPECT_GL_NO_ERROR();
2691 
2692     // 5 * sizeof(float) = 20
2693     // Vulkan rounds up to the required buffer alignment, so >= 20
2694     EXPECT_GE(queryData, 20);
2695 }
2696 
2697 // Tests that shader write before pixel pack/unpack works
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferWriteThenPixelPackUnpack)2698 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferWriteThenPixelPackUnpack)
2699 {
2700     // Create two textures and framebuffers and make sure they are initialized.
2701     GLTexture color1;
2702     glBindTexture(GL_TEXTURE_2D, color1);
2703     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2704 
2705     GLFramebuffer framebuffer1;
2706     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2707     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color1, 0);
2708 
2709     glClearColor(255, 0, 255, 255);
2710     glClear(GL_COLOR_BUFFER_BIT);
2711     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
2712 
2713     GLTexture color2;
2714     glBindTexture(GL_TEXTURE_2D, color2);
2715     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2716 
2717     GLFramebuffer framebuffer2;
2718     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
2719     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color2, 0);
2720 
2721     glClearColor(0, 0, 255, 255);
2722     glClear(GL_COLOR_BUFFER_BIT);
2723     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2724 
2725     constexpr char kComputeShaderSource[] =
2726         R"(#version 310 es
2727 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2728 layout(std430, binding = 0) buffer block {
2729     uint data[2];
2730 } outBlock;
2731 void main()
2732 {
2733     // Output red to index 0, and green to index 1.
2734     outBlock.data[0] = 0xFF0000FFu;
2735     outBlock.data[1] = 0xFF00FF00u;
2736 }
2737 )";
2738 
2739     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2740 
2741     glUseProgram(program);
2742 
2743     constexpr GLsizei kBufferSize                   = sizeof(GLuint) * 2;
2744     constexpr std::array<GLuint, 2> kBufferInitData = {0x01234567u, 0x89ABCDEFu};
2745 
2746     // Create a shader storage buffer
2747     GLBuffer buffer;
2748 
2749     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2750     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferInitData.data(), GL_STATIC_DRAW);
2751 
2752     // Bind shader storage buffer and write to it.
2753     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
2754 
2755     glDispatchCompute(1, 1, 1);
2756     EXPECT_GL_NO_ERROR();
2757 
2758     // Issue a memory barrier for pixel pack/unpack operations.
2759     glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
2760     EXPECT_GL_NO_ERROR();
2761 
2762     // Use a pixel pack operation to overwrite the output of the compute shader at index 0.  Uses
2763     // the second framebuffer which is blue.
2764     glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
2765     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2766     EXPECT_GL_NO_ERROR();
2767 
2768     // Use a pixel unpack operation to re-initialize the other framebuffer with the results from the
2769     // compute shader.
2770     glBindTexture(GL_TEXTURE_2D, color1);
2771     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
2772     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2773                     reinterpret_cast<void *>(sizeof(GLuint)));
2774     EXPECT_GL_NO_ERROR();
2775 
2776     // Verify that the first framebuffer is now green
2777     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2778     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer1);
2779     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2780 
2781     // Verify the contents of the buffer.  It should have blue as the first index and green as the
2782     // second.
2783     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2784     GLColor *bufferContents = static_cast<GLColor *>(
2785         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
2786     EXPECT_GL_NO_ERROR();
2787 
2788     EXPECT_EQ(GLColor::blue, bufferContents[0]);
2789     EXPECT_EQ(GLColor::green, bufferContents[1]);
2790     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2791     EXPECT_GL_NO_ERROR();
2792 }
2793 
2794 // Tests that shader write after pixel pack/unpack works
TEST_P(ShaderStorageBufferTest31,PixelPackUnpackThenShaderStorageBufferWrite)2795 TEST_P(ShaderStorageBufferTest31, PixelPackUnpackThenShaderStorageBufferWrite)
2796 {
2797     swapBuffers();
2798     // Create two textures and framebuffers and make sure they are initialized.
2799     GLTexture color1;
2800     glBindTexture(GL_TEXTURE_2D, color1);
2801     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2802 
2803     GLFramebuffer framebuffer1;
2804     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2805     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color1, 0);
2806 
2807     glClearColor(255, 0, 255, 255);
2808     glClear(GL_COLOR_BUFFER_BIT);
2809     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
2810 
2811     GLTexture color2;
2812     glBindTexture(GL_TEXTURE_2D, color2);
2813     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2814 
2815     GLFramebuffer framebuffer2;
2816     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
2817     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color2, 0);
2818 
2819     glClearColor(0, 0, 255, 255);
2820     glClear(GL_COLOR_BUFFER_BIT);
2821     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2822 
2823     constexpr GLsizei kBufferSize                   = sizeof(GLuint) * 2;
2824     constexpr std::array<GLuint, 2> kBufferInitData = {0x01234567u, 0xFF00FF00u};
2825 
2826     // Create a shader storage buffer
2827     GLBuffer buffer;
2828 
2829     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2830     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferInitData.data(), GL_STATIC_DRAW);
2831 
2832     // Use a pixel pack operation to overwrite the buffer at index 0.  Uses the second framebuffer
2833     // which is blue.
2834     glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
2835     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2836     EXPECT_GL_NO_ERROR();
2837 
2838     // Use a pixel unpack operation to re-initialize the other framebuffer with the contents of the
2839     // buffer, which is green.
2840     glBindTexture(GL_TEXTURE_2D, color1);
2841     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
2842     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2843                     reinterpret_cast<void *>(sizeof(GLuint)));
2844     EXPECT_GL_NO_ERROR();
2845 
2846     // Issue a memory barrier for pixel pack/unpack operations.
2847     glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
2848 
2849     // Issue a dispatch call that overwrites the buffer, also verifying that the results of the pack
2850     // operation is correct.
2851     constexpr char kComputeShaderSource[] =
2852         R"(#version 310 es
2853 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2854 layout(std430, binding = 0) buffer block {
2855     uint data[2];
2856 } outBlock;
2857 void main()
2858 {
2859     if (outBlock.data[0] == 0xFFFF0000u)
2860     {
2861         outBlock.data[0] = 0x11223344u;
2862     }
2863     else
2864     {
2865         outBlock.data[0] = 0xABCDABCDu;
2866     }
2867     outBlock.data[1] = 0x55667788u;
2868 }
2869 )";
2870 
2871     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2872 
2873     glUseProgram(program);
2874 
2875     // Bind shader storage buffer and write to it.
2876     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
2877 
2878     glDispatchCompute(1, 1, 1);
2879     EXPECT_GL_NO_ERROR();
2880 
2881     // Verify that the first framebuffer is now green
2882     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2883     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer1);
2884     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2885 
2886     // Verify that the second framebuffer is still blue
2887     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2888     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer2);
2889     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2890 
2891     // Verify the contents of the buffer.
2892     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2893     uint32_t *bufferContents = static_cast<uint32_t *>(
2894         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
2895     EXPECT_GL_NO_ERROR();
2896 
2897     EXPECT_EQ(bufferContents[0], 0x11223344u);
2898     EXPECT_EQ(bufferContents[1], 0x55667788u);
2899     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2900     EXPECT_GL_NO_ERROR();
2901 }
2902 
2903 // Tests that reading from an SSBO inside a function in the fragment shader works.
TEST_P(ShaderStorageBufferTest31,FragReadSSBOInFunction)2904 TEST_P(ShaderStorageBufferTest31, FragReadSSBOInFunction)
2905 {
2906     GLint maxFragmentShaderStorageBlocks;
2907     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2908 
2909     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks < 1);
2910 
2911     constexpr std::array<float, 4> kBufferInitValue = {1.0f, 0.0f, 1.0f, 1.0f};
2912     GLBuffer buffer;
2913     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2914     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferInitValue), kBufferInitValue.data(),
2915                  GL_STATIC_DRAW);
2916     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
2917 
2918     // Create a program that reads from the SSBO in the fragment shader.
2919     constexpr char kFS[] = R"(#version 310 es
2920 precision mediump float;
2921 
2922 out vec4 colorOut;
2923 
2924 layout(binding = 0, std430) buffer block {
2925   vec4 color;
2926 } instance;
2927 
2928 vec4 func() {
2929   vec4 temp = instance.color;
2930   return temp;
2931 }
2932 
2933 void main() {
2934   colorOut = func();
2935 })";
2936 
2937     GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Simple());
2938     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
2939 
2940     const GLuint program = glCreateProgram();
2941     glAttachShader(program, vs);
2942     glAttachShader(program, fs);
2943     glLinkProgram(program);
2944     CheckLinkStatusAndReturnProgram(program, true);
2945 
2946     glUseProgram(program);
2947     GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib());
2948     ASSERT_NE(-1, positionLoc);
2949 
2950     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
2951     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
2952 
2953     GLBuffer posBuffer;
2954     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
2955     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
2956     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
2957     glEnableVertexAttribArray(positionLoc);
2958 
2959     glUseProgram(program);
2960 
2961     glDrawArrays(GL_TRIANGLES, 0, 6);
2962     EXPECT_GL_NO_ERROR();
2963 
2964     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
2965 }
2966 
2967 // Tests reading from an SSBO in a function. In this case, we also modify SSBO to check the result.
TEST_P(ShaderStorageBufferTest31,ReadSSBOInFunction)2968 TEST_P(ShaderStorageBufferTest31, ReadSSBOInFunction)
2969 {
2970     constexpr char kCS[] = R"(#version 310 es
2971 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2972 
2973 layout(std430, binding = 0) buffer block {
2974     uint data;
2975 } instance;
2976 
2977 uint func()
2978 {
2979     return instance.data;
2980 }
2981 void main() {
2982     instance.data = func() + 1u;
2983 })";
2984 
2985     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
2986 
2987     glUseProgram(program);
2988 
2989     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
2990     constexpr unsigned int kInitialData       = 123u;
2991 
2992     // Create shader storage buffer
2993     GLBuffer shaderStorageBuffer;
2994 
2995     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
2996     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInitialData, GL_STATIC_DRAW);
2997 
2998     // Bind shader storage buffer
2999     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
3000 
3001     glDispatchCompute(1, 1, 1);
3002 
3003     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
3004 
3005     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
3006     const void *bufferData =
3007         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT);
3008 
3009     constexpr unsigned int kExpectedData = 124u;
3010     EXPECT_EQ(kExpectedData, *static_cast<const GLuint *>(bufferData));
3011     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3012 
3013     EXPECT_GL_NO_ERROR();
3014 }
3015 
3016 // Tests whole-array assignment to an SSBO.
TEST_P(ShaderStorageBufferTest31,AggregateArrayAssignmentSSBO)3017 TEST_P(ShaderStorageBufferTest31, AggregateArrayAssignmentSSBO)
3018 {
3019     constexpr char kCS[] = R"(#version 310 es
3020 
3021 layout(std430, binding = 0) buffer block {
3022   int a[4];
3023 } instance;
3024 
3025 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
3026 void main() {
3027   instance.a = int[4](0, 1, 2, 3);
3028 })";
3029 
3030     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3031 
3032     glUseProgram(program);
3033 
3034     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
3035     constexpr unsigned int kElementCount      = 4;
3036 
3037     // Create shader storage buffer
3038     GLBuffer shaderStorageBuffer;
3039 
3040     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
3041     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kBytesPerComponent, nullptr,
3042                  GL_STATIC_DRAW);
3043 
3044     // Bind shader storage buffer
3045     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
3046 
3047     glDispatchCompute(1, 1, 1);
3048 
3049     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
3050 
3051     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
3052     const void *bufferData = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
3053                                               kElementCount * kBytesPerComponent, GL_MAP_READ_BIT);
3054 
3055     for (unsigned int idx = 0; idx < kElementCount; idx++)
3056     {
3057         EXPECT_EQ(static_cast<const GLuint *>(bufferData)[idx], idx);
3058     }
3059     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3060 
3061     EXPECT_GL_NO_ERROR();
3062 }
3063 
3064 // Tests whole-struct assignment to an SSBO.
TEST_P(ShaderStorageBufferTest31,AggregateStructAssignmentSSBO)3065 TEST_P(ShaderStorageBufferTest31, AggregateStructAssignmentSSBO)
3066 {
3067     constexpr char kCS[] = R"(#version 310 es
3068 
3069 struct StructValues {
3070     float f;
3071     int i;
3072 };
3073 
3074 
3075 layout(std430, binding = 0) buffer block {
3076     StructValues s;
3077 } instance;
3078 
3079 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
3080 void main() {
3081     instance.s = StructValues(123.0f, 321);
3082 })";
3083 
3084     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3085 
3086     glUseProgram(program);
3087 
3088     constexpr size_t kSize = sizeof(GLfloat) + sizeof(GLint);
3089 
3090     // Create shader storage buffer
3091     GLBuffer shaderStorageBuffer;
3092 
3093     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
3094     glBufferData(GL_SHADER_STORAGE_BUFFER, kSize, nullptr, GL_STATIC_DRAW);
3095 
3096     // Bind shader storage buffer
3097     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
3098 
3099     glDispatchCompute(1, 1, 1);
3100 
3101     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
3102 
3103     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
3104     const void *bufferData = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize, GL_MAP_READ_BIT);
3105 
3106     EXPECT_EQ(static_cast<const GLfloat *>(bufferData)[0], 123.0f);
3107     EXPECT_EQ(static_cast<const GLint *>(bufferData)[1], 321);
3108 
3109     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3110 
3111     EXPECT_GL_NO_ERROR();
3112 }
3113 
3114 // Test that certain floating-point values are unchanged after constant folding.
TEST_P(ShaderStorageBufferTest31,ConstantFoldingPrecision)3115 TEST_P(ShaderStorageBufferTest31, ConstantFoldingPrecision)
3116 {
3117     constexpr char kCS[] = R"(#version 310 es
3118 
3119 layout(std430, binding = 0) buffer block {
3120     float f;
3121 } instance;
3122 
3123 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
3124 void main() {
3125     instance.f = intBitsToFloat(0x0da5cc2f);
3126 })";
3127 
3128     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3129 
3130     glUseProgram(program);
3131 
3132     constexpr size_t kSize = sizeof(GLfloat);
3133 
3134     // Create shader storage buffer
3135     GLBuffer shaderStorageBuffer;
3136 
3137     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
3138     glBufferData(GL_SHADER_STORAGE_BUFFER, kSize, nullptr, GL_STATIC_DRAW);
3139 
3140     // Bind shader storage buffer
3141     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
3142 
3143     glDispatchCompute(1, 1, 1);
3144 
3145     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
3146 
3147     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
3148     const void *bufferData = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize, GL_MAP_READ_BIT);
3149 
3150     int32_t result = static_cast<const int32_t *>(bufferData)[0];
3151 
3152     // Compare against the int32_t representation of the float passed to
3153     // intBitsToFloat() in the shader.
3154     EXPECT_EQ(result, 0x0da5cc2f);
3155 
3156     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3157 
3158     EXPECT_GL_NO_ERROR();
3159 }
3160 
3161 // Tests two SSBOs in the fragment shader.
TEST_P(ShaderStorageBufferTest31,TwoSSBOsInFragmentShader)3162 TEST_P(ShaderStorageBufferTest31, TwoSSBOsInFragmentShader)
3163 {
3164     constexpr char kFS[] = R"(#version 310 es
3165 precision mediump float;
3166 
3167 layout(binding = 0, std430) buffer block0 {
3168     float value;
3169 } result0;
3170 
3171 layout(binding = 1, std430) buffer block1 {
3172     float value;
3173 } result1;
3174 
3175 void main() {
3176     result0.value = 0.5f;
3177     result1.value = 42.0f;
3178 }
3179 )";
3180 
3181     constexpr size_t kSize[2] = {sizeof(GLfloat), sizeof(GLfloat)};
3182     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
3183 
3184     // Create shader storage buffers
3185     GLBuffer shaderStorageBuffer[2];
3186 
3187     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
3188     glBufferData(GL_SHADER_STORAGE_BUFFER, kSize[0], nullptr, GL_STATIC_DRAW);
3189 
3190     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
3191     glBufferData(GL_SHADER_STORAGE_BUFFER, kSize[1], nullptr, GL_STATIC_DRAW);
3192 
3193     // Bind shader storage buffers
3194     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
3195     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
3196 
3197     drawQuad(program, essl31_shaders::PositionAttrib(), 0.95f);
3198     ASSERT_GL_NO_ERROR();
3199 
3200     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
3201     const void *buffer0Data =
3202         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize[0], GL_MAP_READ_BIT);
3203     EXPECT_EQ(static_cast<const GLfloat *>(buffer0Data)[0], 0.5f);
3204 
3205     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3206 
3207     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
3208     const void *buffer1Data =
3209         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize[1], GL_MAP_READ_BIT);
3210     EXPECT_EQ(static_cast<const GLfloat *>(buffer1Data)[0], 42.0f);
3211 
3212     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3213 
3214     EXPECT_GL_NO_ERROR();
3215 }
3216 
3217 // Tests two SSBOs in a compute shader.
TEST_P(ShaderStorageBufferTest31,TwoSSBOsInComputeShader)3218 TEST_P(ShaderStorageBufferTest31, TwoSSBOsInComputeShader)
3219 {
3220     constexpr char kCS[] = R"(#version 310 es
3221 
3222 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3223 
3224 layout(binding = 0, std430) buffer block0 {
3225     float value;
3226 } result0;
3227 
3228 layout(binding = 1, std430) buffer block1 {
3229     float value;
3230 } result1;
3231 
3232 void main() {
3233     result0.value = 0.5f;
3234     result1.value = 42.0f;
3235 }
3236 )";
3237 
3238     constexpr size_t kSize[2] = {sizeof(GLfloat), sizeof(GLfloat)};
3239     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3240     glUseProgram(program);
3241 
3242     // Create shader storage buffers
3243     GLBuffer shaderStorageBuffer[2];
3244 
3245     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
3246     glBufferData(GL_SHADER_STORAGE_BUFFER, kSize[0], nullptr, GL_STATIC_DRAW);
3247 
3248     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
3249     glBufferData(GL_SHADER_STORAGE_BUFFER, kSize[1], nullptr, GL_STATIC_DRAW);
3250 
3251     // Bind shader storage buffers
3252     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
3253     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
3254 
3255     glDispatchCompute(1, 1, 1);
3256     ASSERT_GL_NO_ERROR();
3257 
3258     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3259 
3260     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
3261     const void *buffer0Data =
3262         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize[0], GL_MAP_READ_BIT);
3263     EXPECT_EQ(static_cast<const GLfloat *>(buffer0Data)[0], 0.5f);
3264 
3265     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3266 
3267     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
3268     const void *buffer1Data =
3269         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize[1], GL_MAP_READ_BIT);
3270     EXPECT_EQ(static_cast<const GLfloat *>(buffer1Data)[0], 42.0f);
3271 
3272     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3273 
3274     EXPECT_GL_NO_ERROR();
3275 }
3276 
3277 // Test that buffer self-copy works when buffer is used as SSBO
TEST_P(ShaderStorageBufferTest31,CopyBufferSubDataSelfDependency)3278 TEST_P(ShaderStorageBufferTest31, CopyBufferSubDataSelfDependency)
3279 {
3280     constexpr char kCS[] = R"(#version 310 es
3281 
3282 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3283 
3284 layout(binding = 0, std430) buffer SSBO
3285 {
3286     uvec4 data[128];
3287 };
3288 
3289 void main()
3290 {
3291     data[12] += uvec4(1);
3292     data[12+64] += uvec4(10);
3293 }
3294 )";
3295 
3296     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3297     glUseProgram(program);
3298 
3299     constexpr uint32_t kUVec4Size   = 4 * sizeof(uint32_t);
3300     constexpr uint32_t kSSBOSize    = 128 * kUVec4Size;
3301     constexpr uint32_t kData1Offset = 12 * kUVec4Size;
3302     constexpr uint32_t kData2Offset = 76 * kUVec4Size;
3303 
3304     // Init data is 4 times the size of SSBO as the buffer is created larger than the SSBO
3305     // throughout the test.
3306     constexpr uint32_t kInitValue = 12345;
3307     const std::vector<uint32_t> kInitData(kSSBOSize, kInitValue);
3308 
3309     // Set up a throw-away buffer just to make buffer suballocations not use offset 0.
3310     GLBuffer throwaway;
3311     glBindBuffer(GL_SHADER_STORAGE_BUFFER, throwaway);
3312     glBufferData(GL_SHADER_STORAGE_BUFFER, 1024, nullptr, GL_DYNAMIC_DRAW);
3313 
3314     // Set up the buffer
3315     GLBuffer buffer;
3316     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
3317     glBufferData(GL_SHADER_STORAGE_BUFFER, kSSBOSize * 2, kInitData.data(), GL_DYNAMIC_DRAW);
3318 
3319     // Bind at offset 0.  After the dispatch call: [12] is +1, [76] is +10
3320     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kSSBOSize);
3321     glDispatchCompute(1, 1, 1);
3322 
3323     // Duplicate the buffer in the second half.  Barrier needed for glCopyBufferSubData.  After the
3324     // copy: [128+12] is +1, [128+76] is +10
3325     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3326     glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, kSSBOSize,
3327                         kSSBOSize);
3328 
3329     // Barrier needed before writing to the buffer in the shader.
3330     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
3331 
3332     // Bind at offset 128.  After the dispatch call: [128+12] is +2, [128+76] is +20
3333     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, kSSBOSize, kSSBOSize);
3334     glDispatchCompute(1, 1, 1);
3335 
3336     // Do a small self-copy.  Barrier needed for glCopyBufferSubData.
3337     // After the copy: [64+12] = [128+12] (i.e. +2)
3338     constexpr uint32_t kCopySrcOffset = (128 + 4) * kUVec4Size;
3339     constexpr uint32_t kCopyDstOffset = (64 + 4) * kUVec4Size;
3340     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3341     glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_SHADER_STORAGE_BUFFER, kCopySrcOffset,
3342                         kCopyDstOffset, kData1Offset);
3343 
3344     // Barrier needed before writing to the buffer in the shader.
3345     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
3346 
3347     // Bind at offset 64.  After the dispatch call: [64+12] is +3, [64+76] (i.e. [128+12]) is +12
3348     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, kCopySrcOffset - kCopyDstOffset,
3349                       kSSBOSize);
3350     glDispatchCompute(1, 1, 1);
3351 
3352     // Validate results.  Barrier needed for glMapBufferRange
3353     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3354     std::vector<uint32_t> result(kSSBOSize / 2);
3355     const void *bufferData =
3356         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSSBOSize * 2, GL_MAP_READ_BIT);
3357     memcpy(result.data(), bufferData, kSSBOSize * 2);
3358     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3359 
3360     for (size_t index = 0; index < kSSBOSize * 2 / kUVec4Size; ++index)
3361     {
3362         size_t offset      = index * 4;
3363         uint32_t increment = 0;
3364         if (index == kData1Offset / kUVec4Size)
3365         {
3366             increment = 1;
3367         }
3368         else if (index == kData2Offset / kUVec4Size)
3369         {
3370             increment = 3;
3371         }
3372         else if (index == (kSSBOSize + kData1Offset) / kUVec4Size)
3373         {
3374             increment = 12;
3375         }
3376         else if (index == (kSSBOSize + kData2Offset) / kUVec4Size)
3377         {
3378             increment = 20;
3379         }
3380 
3381         for (size_t component = 0; component < 4; ++component)
3382         {
3383             EXPECT_EQ(result[offset + component], kInitValue + increment)
3384                 << component << " " << index << " " << increment;
3385         }
3386     }
3387 
3388     // Do a big copy again, but this time the buffer is unused by the GPU.
3389     // After this call: [12] is +12, [76] is +20
3390     glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_SHADER_STORAGE_BUFFER, kSSBOSize, 0,
3391                         kSSBOSize);
3392 
3393     // Barrier needed before writing to the buffer in the shader.
3394     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
3395 
3396     // Bind at offset 0.  After the dispatch call: [12] is +13, [76] is +30
3397     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kSSBOSize);
3398     glDispatchCompute(1, 1, 1);
3399 
3400     // Validate results.  Barrier needed for glMapBufferRange
3401     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3402     bufferData = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSSBOSize * 2, GL_MAP_READ_BIT);
3403     memcpy(result.data(), bufferData, kSSBOSize * 2);
3404     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3405 
3406     for (size_t index = 0; index < kSSBOSize * 2 / kUVec4Size; ++index)
3407     {
3408         size_t offset      = index * 4;
3409         uint32_t increment = 0;
3410         if (index == kData1Offset / kUVec4Size)
3411         {
3412             increment = 13;
3413         }
3414         else if (index == kData2Offset / kUVec4Size)
3415         {
3416             increment = 30;
3417         }
3418         else if (index == (kSSBOSize + kData1Offset) / kUVec4Size)
3419         {
3420             increment = 12;
3421         }
3422         else if (index == (kSSBOSize + kData2Offset) / kUVec4Size)
3423         {
3424             increment = 20;
3425         }
3426 
3427         for (size_t component = 0; component < 4; ++component)
3428         {
3429             EXPECT_EQ(result[offset + component], kInitValue + increment)
3430                 << component << " " << index << " " << increment;
3431         }
3432     }
3433 }
3434 
3435 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShaderStorageBufferTest31);
3436 ANGLE_INSTANTIATE_TEST_ES31_AND(ShaderStorageBufferTest31,
3437                                 ES31_VULKAN().enable(Feature::PreferCPUForBufferSubData));
3438 
3439 }  // namespace
3440