• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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__anon28bf05f70111::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__anon28bf05f70111::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 // Test shader storage buffer read write.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWrite)264 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite)
265 {
266     constexpr char kCS[] =
267         "#version 310 es\n"
268         "layout(local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
269         "layout(std140, binding = 1) buffer blockName {\n"
270         "    uint data[2];\n"
271         "} instanceName;\n"
272         "void main()\n"
273         "{\n"
274         "    instanceName.data[0] = 3u;\n"
275         "    instanceName.data[1] = 4u;\n"
276         "}\n";
277 
278     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
279 
280     glUseProgram(program.get());
281 
282     constexpr unsigned int kElementCount = 2;
283     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
284     constexpr unsigned int kArrayStride = 16;
285     // Create shader storage buffer
286     GLBuffer shaderStorageBuffer;
287     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
288     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, nullptr, GL_STATIC_DRAW);
289 
290     // Bind shader storage buffer
291     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
292 
293     // Dispath compute
294     glDispatchCompute(1, 1, 1);
295 
296     glFinish();
297 
298     // Read back shader storage buffer
299     constexpr unsigned int kExpectedValues[2] = {3u, 4u};
300     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
301     void *ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kElementCount * kArrayStride,
302                                  GL_MAP_READ_BIT);
303     for (unsigned int idx = 0; idx < kElementCount; idx++)
304     {
305         EXPECT_EQ(kExpectedValues[idx],
306                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
307                                                      idx * kArrayStride)));
308     }
309     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
310     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
311 
312     EXPECT_GL_NO_ERROR();
313 }
314 
315 // Test shader storage buffer write followed by glTexSUbData and followed by shader storage write
316 // again.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWriteAndBufferSubData)317 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteAndBufferSubData)
318 {
319     constexpr char kCS[] =
320         "#version 310 es\n"
321         "layout(local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
322         "layout(std140, binding = 1) buffer blockName {\n"
323         "    uint data[2];\n"
324         "} instanceName;\n"
325         "void main()\n"
326         "{\n"
327         "    instanceName.data[0] = 3u;\n"
328         "    instanceName.data[1] = 4u;\n"
329         "}\n";
330 
331     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
332 
333     glUseProgram(program.get());
334 
335     int bufferAlignOffset;
336     glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &bufferAlignOffset);
337 
338     constexpr unsigned int kElementCount = 2;
339     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
340     constexpr unsigned int kArrayStride       = 16;
341     constexpr unsigned int kMiddlePaddingSize = 1024;
342     unsigned int kShaderUsedSize              = kElementCount * kArrayStride;
343     unsigned int kOffset1    = (kShaderUsedSize + bufferAlignOffset - 1) & ~(bufferAlignOffset - 1);
344     unsigned int kOffset2    = kOffset1 + kMiddlePaddingSize;
345     unsigned int kBufferSize = kOffset2 + kShaderUsedSize;
346 
347     for (int loop = 0; loop < 2; loop++)
348     {
349         // Create shader storage buffer
350         GLBuffer shaderStorageBuffer;
351         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
352         glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_DYNAMIC_DRAW);
353 
354         // Bind shader storage buffer and dispath compute
355         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
356         glDispatchCompute(1, 1, 1);
357         glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
358         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer, kOffset2,
359                           kShaderUsedSize);
360         glDispatchCompute(1, 1, 1);
361         EXPECT_GL_NO_ERROR();
362 
363         if (loop == 1)
364         {
365             // Make write operation finished but read operation pending. We don't care actual
366             // rendering result but just to have a unflushed rendering using the buffer so that it
367             // will appears as pending.
368             glFinish();
369             constexpr char kVS[] = R"(attribute vec4 in_attrib;
370                                     varying vec4 v_attrib;
371                                     void main()
372                                     {
373                                         v_attrib = in_attrib;
374                                         gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
375                                         gl_PointSize = 100.0;
376                                     })";
377             constexpr char kFS[] = R"(precision mediump float;
378                                     varying vec4 v_attrib;
379                                     void main()
380                                     {
381                                         gl_FragColor = v_attrib;
382                                     })";
383             GLuint readProgram   = CompileProgram(kVS, kFS);
384             ASSERT_NE(readProgram, 0U);
385             GLint attribLocation = glGetAttribLocation(readProgram, "in_attrib");
386             ASSERT_NE(attribLocation, -1);
387             glUseProgram(readProgram);
388             ASSERT_GL_NO_ERROR();
389             glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT);
390             glBindBuffer(GL_ARRAY_BUFFER, shaderStorageBuffer);
391             glVertexAttribPointer(attribLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4, nullptr);
392             glEnableVertexAttribArray(attribLocation);
393             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shaderStorageBuffer);
394             glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
395             glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, nullptr);
396             ASSERT_GL_NO_ERROR();
397         }
398 
399         // Use subData to update middle portion of data to trigger acquireAndUpdate code path in
400         // ANGLE
401         glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
402         glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
403         constexpr unsigned int kMiddlePaddingValue = 0x55555555u;
404         std::vector<unsigned int> kMiddlePaddingValues(kMiddlePaddingSize / sizeof(unsigned int),
405                                                        kMiddlePaddingValue);
406         glBufferSubData(GL_SHADER_STORAGE_BUFFER, kOffset1, kMiddlePaddingSize,
407                         kMiddlePaddingValues.data());
408 
409         // Read back shader storage buffer
410         constexpr unsigned int kExpectedValues[2] = {3u, 4u};
411         const GLbyte *ptr0                        = reinterpret_cast<const GLbyte *>(
412             glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
413         for (unsigned int idx = 0; idx < kElementCount; idx++)
414         {
415             EXPECT_EQ(kExpectedValues[idx],
416                       *(reinterpret_cast<const GLuint *>(ptr0 + idx * kArrayStride)));
417         }
418 
419         const GLbyte *ptr1 = reinterpret_cast<const GLbyte *>(ptr0 + kOffset1);
420         for (unsigned int idx = 0; idx < kMiddlePaddingSize / sizeof(unsigned int); idx++)
421         {
422             EXPECT_EQ(kMiddlePaddingValue, reinterpret_cast<const GLuint *>(ptr1)[idx]);
423         }
424 
425         const GLbyte *ptr2 = ptr1 + kMiddlePaddingSize;
426         for (unsigned int idx = 0; idx < kElementCount; idx++)
427         {
428             EXPECT_EQ(kExpectedValues[idx],
429                       *(reinterpret_cast<const GLuint *>(ptr2 + idx * kArrayStride)));
430         }
431 
432         glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
433         glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
434 
435         EXPECT_GL_NO_ERROR();
436     }
437 }
438 
439 // Tests modifying an existing shader storage buffer
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWriteSame)440 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteSame)
441 {
442     constexpr char kComputeShaderSource[] =
443         R"(#version 310 es
444 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
445 layout(std140, binding = 0) buffer block {
446     uint data;
447 } instance;
448 void main()
449 {
450     uint temp = instance.data;
451     instance.data = temp + 1u;
452 }
453 )";
454 
455     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
456 
457     glUseProgram(program);
458 
459     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
460     constexpr unsigned int kInitialData       = 123u;
461 
462     // Create shader storage buffer
463     GLBuffer shaderStorageBuffer;
464 
465     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
466     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInitialData, GL_STATIC_DRAW);
467 
468     // Bind shader storage buffer
469     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
470 
471     glDispatchCompute(1, 1, 1);
472 
473     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
474 
475     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
476     const void *bufferData =
477         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT);
478 
479     constexpr unsigned int kExpectedData = 124u;
480     EXPECT_EQ(kExpectedData, *static_cast<const GLuint *>(bufferData));
481     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
482 
483     // Running shader twice to make sure that the buffer gets updated correctly 123->124->125
484     glDispatchCompute(1, 1, 1);
485 
486     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT);
487 
488     bufferData = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT);
489 
490     constexpr unsigned int kExpectedData2 = 125u;
491     EXPECT_EQ(kExpectedData2, *static_cast<const GLuint *>(bufferData));
492 
493     // Verify re-using the SSBO buffer with a PBO contains expected data.
494     // This will read-back from FBO using a PBO into the same SSBO buffer.
495 
496     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
497 
498     GLTexture texture;
499     glBindTexture(GL_TEXTURE_2D, texture);
500     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
501 
502     GLFramebuffer framebuffer;
503     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
504     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
505 
506     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
507     glClear(GL_COLOR_BUFFER_BIT);
508 
509     glBindBuffer(GL_PIXEL_PACK_BUFFER, shaderStorageBuffer);
510     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
511     EXPECT_GL_NO_ERROR();
512 
513     void *mappedPtr =
514         glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT);
515     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
516     EXPECT_GL_NO_ERROR();
517 
518     EXPECT_EQ(GLColor::red, dataColor[0]);
519     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
520     EXPECT_GL_NO_ERROR();
521 
522     // Verify that binding the buffer back to the SSBO keeps the expected data.
523 
524     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
525 
526     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
527     const GLColor *ptr = reinterpret_cast<GLColor *>(
528         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT));
529     EXPECT_EQ(GLColor::red, *ptr);
530 
531     EXPECT_GL_NO_ERROR();
532 }
533 
534 // Tests reading and writing to a shader storage buffer bound at an offset.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferReadWriteOffset)535 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteOffset)
536 {
537     constexpr char kCS[] = R"(#version 310 es
538 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
539 
540 layout(std140, binding = 0) buffer block0 {
541     uint data[2];
542 } instance0;
543 
544 void main()
545 {
546     instance0.data[0] = 3u;
547     instance0.data[1] = 4u;
548 }
549 )";
550 
551     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
552 
553     glUseProgram(program);
554 
555     constexpr unsigned int kElementCount = 2;
556     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
557     constexpr unsigned int kArrayStride = 16;
558     // Create shader storage buffer
559     GLBuffer shaderStorageBuffer;
560     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
561 
562     int bufferAlignOffset;
563     glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &bufferAlignOffset);
564 
565     constexpr int kBufferSize = kElementCount * kArrayStride;
566     const int unalignedBytes  = kBufferSize % bufferAlignOffset;
567     const int alignCorrection = unalignedBytes == 0 ? 0 : bufferAlignOffset - unalignedBytes;
568     const int kBufferOffset   = kBufferSize + alignCorrection;
569 
570     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferOffset + kBufferSize, nullptr, GL_STATIC_DRAW);
571 
572     // Bind shader storage buffer at an offset
573     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer, kBufferOffset, kBufferSize);
574     EXPECT_GL_NO_ERROR();
575 
576     glDispatchCompute(1, 1, 1);
577     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
578 
579     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
580 
581     // Bind the buffer at a separate location
582     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer, 0, kBufferSize);
583     EXPECT_GL_NO_ERROR();
584 
585     glDispatchCompute(1, 1, 1);
586     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
587 
588     // Read back shader storage buffer
589     constexpr unsigned int kExpectedValues[2] = {3u, 4u};
590     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
591     void *ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT);
592     for (unsigned int idx = 0; idx < kElementCount; idx++)
593     {
594         EXPECT_EQ(kExpectedValues[idx],
595                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
596                                                      idx * kArrayStride)));
597     }
598     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
599 
600     ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, kBufferOffset, kBufferSize, GL_MAP_READ_BIT);
601     for (unsigned int idx = 0; idx < kElementCount; idx++)
602     {
603         EXPECT_EQ(kExpectedValues[idx],
604                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
605                                                      idx * kArrayStride)));
606     }
607     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
608 
609     EXPECT_GL_NO_ERROR();
610 }
611 
612 // Test that access/write to vector data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferVector)613 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferVector)
614 {
615     constexpr char kComputeShaderSource[] =
616         R"(#version 310 es
617  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
618  layout(std140, binding = 0) buffer blockIn {
619      uvec2 data;
620  } instanceIn;
621  layout(std140, binding = 1) buffer blockOut {
622      uvec2 data;
623  } instanceOut;
624  void main()
625  {
626      instanceOut.data[0] = instanceIn.data[0];
627      instanceOut.data[1] = instanceIn.data[1];
628  }
629  )";
630 
631     constexpr unsigned int kComponentCount         = 2;
632     constexpr GLuint kInputValues[kComponentCount] = {3u, 4u};
633 
634     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kInputValues);
635     runVectorTest(vectorCase);
636 }
637 
638 // Test that the shader works well with an active SSBO but not statically used.
TEST_P(ShaderStorageBufferTest31,ActiveSSBOButNotStaticallyUsed)639 TEST_P(ShaderStorageBufferTest31, ActiveSSBOButNotStaticallyUsed)
640 {
641     // http://anglebug.com/3725
642     ANGLE_SKIP_TEST_IF(IsAndroid() && IsPixel2() && IsVulkan());
643 
644     constexpr char kComputeShaderSource[] =
645         R"(#version 310 es
646  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
647  layout(std140, binding = 0) buffer blockIn {
648      uvec2 data;
649  } instanceIn;
650  layout(std140, binding = 1) buffer blockOut {
651      uvec2 data;
652  } instanceOut;
653  layout(std140, binding = 2) buffer blockC {
654      uvec2 data;
655  } instanceC;
656  void main()
657  {
658      instanceOut.data[0] = instanceIn.data[0];
659      instanceOut.data[1] = instanceIn.data[1];
660  }
661  )";
662 
663     GLBuffer shaderStorageBufferC;
664     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBufferC);
665     glBufferData(GL_SHADER_STORAGE_BUFFER, 32, nullptr, GL_STATIC_DRAW);
666     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBufferC);
667 
668     constexpr unsigned int kComponentCount         = 2;
669     constexpr GLuint kInputValues[kComponentCount] = {3u, 4u};
670 
671     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kInputValues);
672     runVectorTest(vectorCase);
673 }
674 
675 // Test that access/write to swizzle scalar data in shader storage block.
TEST_P(ShaderStorageBufferTest31,ScalarSwizzleTest)676 TEST_P(ShaderStorageBufferTest31, ScalarSwizzleTest)
677 {
678     constexpr char kComputeShaderSource[] =
679         R"(#version 310 es
680  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
681  layout(std140, binding = 0) buffer blockIn {
682      uvec2 data;
683  } instanceIn;
684  layout(std140, binding = 1) buffer blockOut {
685      uvec2 data;
686  } instanceOut;
687  void main()
688  {
689      instanceOut.data.x = instanceIn.data.y;
690      instanceOut.data.y = instanceIn.data.x;
691  }
692  )";
693 
694     constexpr unsigned int kComponentCount            = 2;
695     constexpr GLuint kInputValues[kComponentCount]    = {3u, 4u};
696     constexpr GLuint kExpectedValues[kComponentCount] = {4u, 3u};
697 
698     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kExpectedValues);
699     runVectorTest(vectorCase);
700 }
701 
702 // Test that access/write to swizzle vector data in shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorSwizzleTest)703 TEST_P(ShaderStorageBufferTest31, VectorSwizzleTest)
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  void main()
715  {
716      instanceOut.data.yx = instanceIn.data.xy;
717  }
718  )";
719 
720     constexpr unsigned int kComponentCount            = 2;
721     constexpr GLuint kInputValues[kComponentCount]    = {3u, 4u};
722     constexpr GLuint kExpectedValues[kComponentCount] = {4u, 3u};
723 
724     VectorCase vectorCase(kComponentCount, kComputeShaderSource, kInputValues, kExpectedValues);
725     runVectorTest(vectorCase);
726 }
727 
728 // Test that access/write to swizzle vector data in column_major matrix in shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorSwizzleInColumnMajorMatrixTest)729 TEST_P(ShaderStorageBufferTest31, VectorSwizzleInColumnMajorMatrixTest)
730 {
731     constexpr char kComputeShaderSource[] =
732         R"(#version 310 es
733  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
734  layout(std140, binding = 0) buffer blockIn {
735      layout(column_major) mat2x3 data;
736  } instanceIn;
737  layout(std140, binding = 1) buffer blockOut {
738      layout(column_major) mat2x3 data;
739  } instanceOut;
740  void main()
741  {
742      instanceOut.data[0].xyz = instanceIn.data[0].xyz;
743      instanceOut.data[1].xyz = instanceIn.data[1].xyz;
744  }
745  )";
746 
747     constexpr unsigned int kColumns                                             = 2;
748     constexpr unsigned int kRows                                                = 3;
749     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
750     constexpr unsigned int kMatrixStride                                        = 16;
751     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
752         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
753     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
754     runMatrixTest(matrixCase);
755 }
756 
757 // Test that access/write to swizzle vector data in row_major matrix in shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorSwizzleInRowMajorMatrixTest)758 TEST_P(ShaderStorageBufferTest31, VectorSwizzleInRowMajorMatrixTest)
759 {
760     ANGLE_SKIP_TEST_IF(IsAndroid());
761 
762     constexpr char kComputeShaderSource[] =
763         R"(#version 310 es
764  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
765  layout(std140, binding = 0) buffer blockIn {
766      layout(row_major) mat2x3 data;
767  } instanceIn;
768  layout(std140, binding = 1) buffer blockOut {
769      layout(row_major) mat2x3 data;
770  } instanceOut;
771  void main()
772  {
773      instanceOut.data[0].xyz = instanceIn.data[0].xyz;
774      instanceOut.data[1].xyz = instanceIn.data[1].xyz;
775  }
776  )";
777 
778     constexpr unsigned int kColumns           = 2;
779     constexpr unsigned int kRows              = 3;
780     constexpr unsigned int kBytesPerComponent = sizeof(float);
781     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
782     // rounded up a multiple of the base alignment of a vec4.
783     constexpr unsigned int kMatrixStride                                     = 16;
784     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
785         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
786     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
787     runMatrixTest(matrixCase);
788 }
789 
790 // Test that access/write to scalar data in matrix in shader storage block with row major.
TEST_P(ShaderStorageBufferTest31,ScalarDataInMatrixInSSBOWithRowMajorQualifier)791 TEST_P(ShaderStorageBufferTest31, ScalarDataInMatrixInSSBOWithRowMajorQualifier)
792 {
793     // TODO(jiajia.qin@intel.com): Figure out why it fails on Intel Linux platform.
794     // http://anglebug.com/1951
795     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
796     ANGLE_SKIP_TEST_IF(IsAndroid());
797 
798     constexpr char kComputeShaderSource[] =
799         R"(#version 310 es
800 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
801 layout(std140, binding = 0) buffer blockIn {
802     layout(row_major) mat2x3 data;
803 } instanceIn;
804 layout(std140, binding = 1) buffer blockOut {
805     layout(row_major) mat2x3 data;
806 } instanceOut;
807 void main()
808 {
809     instanceOut.data[0][0] = instanceIn.data[0][0];
810     instanceOut.data[0][1] = instanceIn.data[0][1];
811     instanceOut.data[0][2] = instanceIn.data[0][2];
812     instanceOut.data[1][0] = instanceIn.data[1][0];
813     instanceOut.data[1][1] = instanceIn.data[1][1];
814     instanceOut.data[1][2] = instanceIn.data[1][2];
815 }
816 )";
817 
818     constexpr unsigned int kColumns           = 2;
819     constexpr unsigned int kRows              = 3;
820     constexpr unsigned int kBytesPerComponent = sizeof(float);
821     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
822     // rounded up a multiple of the base alignment of a vec4.
823     constexpr unsigned int kMatrixStride                                     = 16;
824     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
825         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
826     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
827     runMatrixTest(matrixCase);
828 }
829 
TEST_P(ShaderStorageBufferTest31,VectorDataInMatrixInSSBOWithRowMajorQualifier)830 TEST_P(ShaderStorageBufferTest31, VectorDataInMatrixInSSBOWithRowMajorQualifier)
831 {
832     ANGLE_SKIP_TEST_IF(IsAndroid());
833 
834     constexpr char kComputeShaderSource[] =
835         R"(#version 310 es
836 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
837 layout(std140, binding = 0) buffer blockIn {
838     layout(row_major) mat2x3 data;
839 } instanceIn;
840 layout(std140, binding = 1) buffer blockOut {
841     layout(row_major) mat2x3 data;
842 } instanceOut;
843 void main()
844 {
845     instanceOut.data[0] = instanceIn.data[0];
846     instanceOut.data[1] = instanceIn.data[1];
847 }
848 )";
849 
850     constexpr unsigned int kColumns           = 2;
851     constexpr unsigned int kRows              = 3;
852     constexpr unsigned int kBytesPerComponent = sizeof(float);
853     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
854     // rounded up a multiple of the base alignment of a vec4.
855     constexpr unsigned int kMatrixStride                                     = 16;
856     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
857         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
858     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
859     runMatrixTest(matrixCase);
860 }
861 
TEST_P(ShaderStorageBufferTest31,MatrixDataInSSBOWithRowMajorQualifier)862 TEST_P(ShaderStorageBufferTest31, MatrixDataInSSBOWithRowMajorQualifier)
863 {
864     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
865 
866     constexpr char kComputeShaderSource[] =
867         R"(#version 310 es
868 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
869 layout(std140, binding = 0) buffer blockIn {
870     layout(row_major) mat2x3 data;
871 } instanceIn;
872 layout(std140, binding = 1) buffer blockOut {
873     layout(row_major) mat2x3 data;
874 } instanceOut;
875 void main()
876 {
877     instanceOut.data = instanceIn.data;
878 }
879 )";
880 
881     constexpr unsigned int kColumns           = 2;
882     constexpr unsigned int kRows              = 3;
883     constexpr unsigned int kBytesPerComponent = sizeof(float);
884     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
885     // rounded up a multiple of the base alignment of a vec4.
886     constexpr unsigned int kMatrixStride                                     = 16;
887     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
888         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
889     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
890     runMatrixTest(matrixCase);
891 }
892 
893 // Test that access/write to scalar data in structure matrix in shader storage block with row major.
TEST_P(ShaderStorageBufferTest31,ScalarDataInMatrixInStructureInSSBOWithRowMajorQualifier)894 TEST_P(ShaderStorageBufferTest31, ScalarDataInMatrixInStructureInSSBOWithRowMajorQualifier)
895 {
896     // TODO(jiajia.qin@intel.com): Figure out why it fails on Intel Linux platform.
897     // http://anglebug.com/1951
898     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
899     ANGLE_SKIP_TEST_IF(IsAndroid());
900 
901     constexpr char kComputeShaderSource[] =
902         R"(#version 310 es
903 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
904 struct S
905 {
906     mat2x3 data;
907 };
908 layout(std140, binding = 0) buffer blockIn {
909     layout(row_major) S s;
910 } instanceIn;
911 layout(std140, binding = 1) buffer blockOut {
912     layout(row_major) S s;
913 } instanceOut;
914 void main()
915 {
916     instanceOut.s.data[0][0] = instanceIn.s.data[0][0];
917     instanceOut.s.data[0][1] = instanceIn.s.data[0][1];
918     instanceOut.s.data[0][2] = instanceIn.s.data[0][2];
919     instanceOut.s.data[1][0] = instanceIn.s.data[1][0];
920     instanceOut.s.data[1][1] = instanceIn.s.data[1][1];
921     instanceOut.s.data[1][2] = instanceIn.s.data[1][2];
922 }
923 )";
924 
925     constexpr unsigned int kColumns           = 2;
926     constexpr unsigned int kRows              = 3;
927     constexpr unsigned int kBytesPerComponent = sizeof(float);
928     // std140 layout requires that base alignment and stride of arrays of scalars and vectors are
929     // rounded up a multiple of the base alignment of a vec4.
930     constexpr unsigned int kMatrixStride                                     = 16;
931     constexpr float kInputDada[kRows * (kMatrixStride / kBytesPerComponent)] = {
932         0.1, 0.2, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0};
933     MatrixCase matrixCase(kColumns, kRows, kMatrixStride, kComputeShaderSource, kInputDada);
934     runMatrixTest(matrixCase);
935 }
936 
937 // Test that access/write to column major matrix data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ScalarDataInMatrixInSSBO)938 TEST_P(ShaderStorageBufferTest31, ScalarDataInMatrixInSSBO)
939 {
940     constexpr char kComputeShaderSource[] =
941         R"(#version 310 es
942 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
943 layout(std140, binding = 0) buffer blockIn {
944     mat2x3 data;
945 } instanceIn;
946 layout(std140, binding = 1) buffer blockOut {
947     mat2x3 data;
948 } instanceOut;
949 void main()
950 {
951     instanceOut.data[0][0] = instanceIn.data[0][0];
952     instanceOut.data[0][1] = instanceIn.data[0][1];
953     instanceOut.data[0][2] = instanceIn.data[0][2];
954     instanceOut.data[1][0] = instanceIn.data[1][0];
955     instanceOut.data[1][1] = instanceIn.data[1][1];
956     instanceOut.data[1][2] = instanceIn.data[1][2];
957 }
958 )";
959 
960     constexpr unsigned int kColumns                                             = 2;
961     constexpr unsigned int kRows                                                = 3;
962     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
963     constexpr unsigned int kMatrixStride                                        = 16;
964     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
965         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
966     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
967     runMatrixTest(matrixCase);
968 }
969 
TEST_P(ShaderStorageBufferTest31,VectorDataInMatrixInSSBOWithColumnMajorQualifier)970 TEST_P(ShaderStorageBufferTest31, VectorDataInMatrixInSSBOWithColumnMajorQualifier)
971 {
972     constexpr char kComputeShaderSource[] =
973         R"(#version 310 es
974 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
975 layout(std140, binding = 0) buffer blockIn {
976     layout(column_major) mat2x3 data;
977 } instanceIn;
978 layout(std140, binding = 1) buffer blockOut {
979     layout(column_major) mat2x3 data;
980 } instanceOut;
981 void main()
982 {
983     instanceOut.data[0] = instanceIn.data[0];
984     instanceOut.data[1] = instanceIn.data[1];
985 }
986 )";
987 
988     constexpr unsigned int kColumns                                             = 2;
989     constexpr unsigned int kRows                                                = 3;
990     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
991     constexpr unsigned int kMatrixStride                                        = 16;
992     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
993         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
994     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
995     runMatrixTest(matrixCase);
996 }
997 
TEST_P(ShaderStorageBufferTest31,MatrixDataInSSBOWithColumnMajorQualifier)998 TEST_P(ShaderStorageBufferTest31, MatrixDataInSSBOWithColumnMajorQualifier)
999 {
1000     constexpr char kComputeShaderSource[] =
1001         R"(#version 310 es
1002 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1003 layout(std140, binding = 0) buffer blockIn {
1004     layout(column_major) mat2x3 data;
1005 } instanceIn;
1006 layout(std140, binding = 1) buffer blockOut {
1007     layout(column_major) mat2x3 data;
1008 } instanceOut;
1009 void main()
1010 {
1011     instanceOut.data = instanceIn.data;
1012 }
1013 )";
1014 
1015     constexpr unsigned int kColumns                                             = 2;
1016     constexpr unsigned int kRows                                                = 3;
1017     constexpr unsigned int kBytesPerComponent                                   = sizeof(float);
1018     constexpr unsigned int kMatrixStride                                        = 16;
1019     constexpr float kInputDada[kColumns * (kMatrixStride / kBytesPerComponent)] = {
1020         0.1, 0.2, 0.3, 0.0, 0.4, 0.5, 0.6, 0.0};
1021     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
1022     runMatrixTest(matrixCase);
1023 }
1024 
1025 // Test that access/write to structure data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferStructureArray)1026 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferStructureArray)
1027 {
1028     constexpr char kComputeShaderSource[] =
1029         R"(#version 310 es
1030 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1031 struct S
1032 {
1033     uvec2 uvData;
1034     uint uiData[2];
1035 };
1036 layout(std140, binding = 0) buffer blockIn {
1037     S s[2];
1038     uint lastData;
1039 } instanceIn;
1040 layout(std140, binding = 1) buffer blockOut {
1041     S s[2];
1042     uint lastData;
1043 } instanceOut;
1044 void main()
1045 {
1046     instanceOut.s[0].uvData = instanceIn.s[0].uvData;
1047     instanceOut.s[0].uiData[0] = instanceIn.s[0].uiData[0];
1048     instanceOut.s[0].uiData[1] = instanceIn.s[0].uiData[1];
1049     instanceOut.s[1].uvData = instanceIn.s[1].uvData;
1050     instanceOut.s[1].uiData[0] = instanceIn.s[1].uiData[0];
1051     instanceOut.s[1].uiData[1] = instanceIn.s[1].uiData[1];
1052     instanceOut.lastData = instanceIn.lastData;
1053 }
1054 )";
1055 
1056     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1057 
1058     glUseProgram(program);
1059 
1060     std::array<GLuint, 4> kUVData = {{
1061         1u,
1062         2u,
1063         0u,
1064         0u,
1065     }};
1066     std::array<GLuint, 8> kUIData = {{
1067         3u,
1068         0u,
1069         0u,
1070         0u,
1071         4u,
1072         0u,
1073         0u,
1074         0u,
1075     }};
1076     GLuint kLastData              = 5u;
1077 
1078     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
1079     constexpr unsigned int kStructureStride   = 48;
1080     constexpr unsigned int totalSize          = kStructureStride * 2 + sizeof(kLastData);
1081 
1082     // Create shader storage buffer
1083     GLBuffer shaderStorageBuffer[2];
1084     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1085     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1086     GLint offset = 0;
1087     // upload data to instanceIn.s[0]
1088     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1089                     kUVData.data());
1090     offset += (kUVData.size() * kBytesPerComponent);
1091     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1092                     kUIData.data());
1093     offset += (kUIData.size() * kBytesPerComponent);
1094     // upload data to instanceIn.s[1]
1095     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1096                     kUVData.data());
1097     offset += (kUVData.size() * kBytesPerComponent);
1098     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1099                     kUIData.data());
1100     offset += (kUIData.size() * kBytesPerComponent);
1101     // upload data to instanceIn.lastData
1102     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, sizeof(kLastData), &kLastData);
1103 
1104     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1105     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1106 
1107     // Bind shader storage buffer
1108     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1109     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1110 
1111     glDispatchCompute(1, 1, 1);
1112     glFinish();
1113 
1114     // Read back shader storage buffer
1115     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1116     constexpr float kExpectedValues[5] = {1u, 2u, 3u, 4u, 5u};
1117     const GLuint *ptr                  = reinterpret_cast<const GLuint *>(
1118         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, totalSize, GL_MAP_READ_BIT));
1119     // instanceOut.s[0]
1120     EXPECT_EQ(kExpectedValues[0], *ptr);
1121     EXPECT_EQ(kExpectedValues[1], *(ptr + 1));
1122     EXPECT_EQ(kExpectedValues[2], *(ptr + 4));
1123     EXPECT_EQ(kExpectedValues[3], *(ptr + 8));
1124     // instanceOut.s[1]
1125     ptr += kStructureStride / kBytesPerComponent;
1126     EXPECT_EQ(kExpectedValues[0], *ptr);
1127     EXPECT_EQ(kExpectedValues[1], *(ptr + 1));
1128     EXPECT_EQ(kExpectedValues[2], *(ptr + 4));
1129     EXPECT_EQ(kExpectedValues[3], *(ptr + 8));
1130     // instanceOut.lastData
1131     ptr += kStructureStride / kBytesPerComponent;
1132     EXPECT_EQ(kExpectedValues[4], *(ptr));
1133 
1134     EXPECT_GL_NO_ERROR();
1135 }
1136 
1137 // Test that access/write to array of array structure data in shader storage buffer.
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferStructureArrayOfArray)1138 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferStructureArrayOfArray)
1139 {
1140     constexpr char kComputeShaderSource[] = R"(#version 310 es
1141 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1142 struct S
1143 {
1144     uvec2 uvData;
1145     uint uiData[2];
1146 };
1147 layout(std140, binding = 0) buffer blockIn {
1148     S s[3][2];
1149     uint lastData;
1150 } instanceIn;
1151 layout(std140, binding = 1) buffer blockOut {
1152     S s[3][2];
1153     uint lastData;
1154 } instanceOut;
1155 void main()
1156 {
1157     instanceOut.s[1][0].uvData = instanceIn.s[1][0].uvData;
1158     instanceOut.s[1][0].uiData[0] = instanceIn.s[1][0].uiData[0];
1159     instanceOut.s[1][0].uiData[1] = instanceIn.s[1][0].uiData[1];
1160     instanceOut.s[1][1].uvData = instanceIn.s[1][1].uvData;
1161     instanceOut.s[1][1].uiData[0] = instanceIn.s[1][1].uiData[0];
1162     instanceOut.s[1][1].uiData[1] = instanceIn.s[1][1].uiData[1];
1163 
1164     instanceOut.lastData = instanceIn.lastData;
1165 }
1166 )";
1167 
1168     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1169 
1170     glUseProgram(program);
1171 
1172     std::array<GLuint, 4> kUVData = {{
1173         1u,
1174         2u,
1175         0u,
1176         0u,
1177     }};
1178     std::array<GLuint, 8> kUIData = {{
1179         3u,
1180         0u,
1181         0u,
1182         0u,
1183         4u,
1184         0u,
1185         0u,
1186         0u,
1187     }};
1188     GLuint kLastData              = 5u;
1189 
1190     constexpr unsigned int kBytesPerComponent        = sizeof(GLuint);
1191     constexpr unsigned int kStructureStride          = 48;
1192     constexpr unsigned int kStructureArrayDimension0 = 3;
1193     constexpr unsigned int kStructureArrayDimension1 = 2;
1194     constexpr unsigned int kLastDataOffset =
1195         kStructureStride * kStructureArrayDimension0 * kStructureArrayDimension1;
1196     constexpr unsigned int totalSize = kLastDataOffset + sizeof(kLastData);
1197 
1198     GLBuffer shaderStorageBuffer[2];
1199     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1200     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1201     // offset of instanceIn.s[1][0]
1202     GLint offset      = kStructureStride * (kStructureArrayDimension1 * 1 + 0);
1203     GLuint uintOffset = offset / kBytesPerComponent;
1204     // upload data to instanceIn.s[1][0]
1205     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1206                     kUVData.data());
1207     offset += (kUVData.size() * kBytesPerComponent);
1208     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1209                     kUIData.data());
1210     offset += (kUIData.size() * kBytesPerComponent);
1211     // upload data to instanceIn.s[1][1]
1212     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUVData.size() * kBytesPerComponent,
1213                     kUVData.data());
1214     offset += (kUVData.size() * kBytesPerComponent);
1215     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kUIData.size() * kBytesPerComponent,
1216                     kUIData.data());
1217     // upload data to instanceIn.lastData
1218     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kLastDataOffset, sizeof(kLastData), &kLastData);
1219 
1220     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1221     glBufferData(GL_SHADER_STORAGE_BUFFER, totalSize, nullptr, GL_STATIC_DRAW);
1222 
1223     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1224     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1225 
1226     glDispatchCompute(1, 1, 1);
1227     glFinish();
1228 
1229     // Read back shader storage buffer
1230     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1231     constexpr float kExpectedValues[5] = {1u, 2u, 3u, 4u, 5u};
1232     const GLuint *ptr                  = reinterpret_cast<const GLuint *>(
1233         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, totalSize, GL_MAP_READ_BIT));
1234 
1235     // instanceOut.s[0][0]
1236     EXPECT_EQ(kExpectedValues[0], *(ptr + uintOffset));
1237     EXPECT_EQ(kExpectedValues[1], *(ptr + uintOffset + 1));
1238     EXPECT_EQ(kExpectedValues[2], *(ptr + uintOffset + 4));
1239     EXPECT_EQ(kExpectedValues[3], *(ptr + uintOffset + 8));
1240 
1241     // instanceOut.s[0][1]
1242     EXPECT_EQ(kExpectedValues[0], *(ptr + uintOffset + 12));
1243     EXPECT_EQ(kExpectedValues[1], *(ptr + uintOffset + 13));
1244     EXPECT_EQ(kExpectedValues[2], *(ptr + uintOffset + 16));
1245     EXPECT_EQ(kExpectedValues[3], *(ptr + uintOffset + 20));
1246 
1247     // instanceOut.lastData
1248     EXPECT_EQ(kExpectedValues[4], *(ptr + (kLastDataOffset / kBytesPerComponent)));
1249 
1250     EXPECT_GL_NO_ERROR();
1251 }
1252 
1253 // Test that access/write to vector data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,VectorArrayInSSBOWithStd430Qualifier)1254 TEST_P(ShaderStorageBufferTest31, VectorArrayInSSBOWithStd430Qualifier)
1255 {
1256     constexpr char kComputeShaderSource[] = R"(#version 310 es
1257 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1258 layout(std430, binding = 0) buffer blockIn {
1259     uvec2 data[2];
1260 } instanceIn;
1261 layout(std430, binding = 1) buffer blockOut {
1262     uvec2 data[2];
1263 } instanceOut;
1264 void main()
1265 {
1266     instanceOut.data[0] = instanceIn.data[0];
1267     instanceOut.data[1] = instanceIn.data[1];
1268 }
1269 )";
1270 
1271     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1272 
1273     glUseProgram(program);
1274 
1275     constexpr unsigned int kElementCount      = 2;
1276     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
1277     constexpr unsigned int kArrayStride       = 8;
1278     constexpr unsigned int kComponentCount    = kArrayStride / kBytesPerComponent;
1279     constexpr unsigned int kExpectedValues[kElementCount][kComponentCount] = {{1u, 2u}, {3u, 4u}};
1280     // Create shader storage buffer
1281     GLBuffer shaderStorageBuffer[2];
1282     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1283     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, kExpectedValues,
1284                  GL_STATIC_DRAW);
1285     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1286     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, nullptr, GL_STATIC_DRAW);
1287 
1288     // Bind shader storage buffer
1289     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1290     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1291 
1292     glDispatchCompute(1, 1, 1);
1293 
1294     glFinish();
1295 
1296     // Read back shader storage buffer
1297     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1298     const GLuint *ptr = reinterpret_cast<const GLuint *>(glMapBufferRange(
1299         GL_SHADER_STORAGE_BUFFER, 0, kElementCount * kArrayStride, GL_MAP_READ_BIT));
1300     for (unsigned int idx = 0; idx < kElementCount; idx++)
1301     {
1302         for (unsigned int idy = 0; idy < kComponentCount; idy++)
1303         {
1304             EXPECT_EQ(kExpectedValues[idx][idy], *(ptr + idx * kComponentCount + idy));
1305         }
1306     }
1307 
1308     EXPECT_GL_NO_ERROR();
1309 }
1310 
1311 // Test that access/write to matrix data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,MatrixInSSBOWithStd430Qualifier)1312 TEST_P(ShaderStorageBufferTest31, MatrixInSSBOWithStd430Qualifier)
1313 {
1314     constexpr char kComputeShaderSource[] = R"(#version 310 es
1315 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1316 layout(std430, binding = 0) buffer blockIn {
1317     mat2 data;
1318 } instanceIn;
1319 layout(std430, binding = 1) buffer blockOut {
1320     mat2 data;
1321 } instanceOut;
1322 void main()
1323 {
1324     instanceOut.data = instanceIn.data;
1325 }
1326 )";
1327 
1328     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1329 
1330     glUseProgram(program);
1331 
1332     constexpr unsigned int kColumns              = 2;
1333     constexpr unsigned int kRows                 = 2;
1334     constexpr unsigned int kBytesPerComponent    = sizeof(float);
1335     constexpr unsigned int kMatrixStride         = kRows * kBytesPerComponent;
1336     constexpr float kInputDada[kColumns * kRows] = {0.1, 0.2, 0.4, 0.5};
1337     MatrixCase matrixCase(kRows, kColumns, kMatrixStride, kComputeShaderSource, kInputDada);
1338     runMatrixTest(matrixCase);
1339 }
1340 
1341 // Test that access/write to structure data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,StructureInSSBOWithStd430Qualifier)1342 TEST_P(ShaderStorageBufferTest31, StructureInSSBOWithStd430Qualifier)
1343 {
1344     constexpr char kComputeShaderSource[] = R"(#version 310 es
1345 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1346 struct S
1347 {
1348     uvec2 u;
1349 };
1350 layout(std430, binding = 0) buffer blockIn {
1351     uint i1;
1352     S s;
1353     uint i2;
1354 } instanceIn;
1355 layout(std430, binding = 1) buffer blockOut {
1356     uint i1;
1357     S s;
1358     uint i2;
1359 } instanceOut;
1360 void main()
1361 {
1362     instanceOut.i1 = instanceIn.i1;
1363     instanceOut.s.u = instanceIn.s.u;
1364     instanceOut.i2 = instanceIn.i2;
1365 }
1366 )";
1367 
1368     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1369     glUseProgram(program);
1370 
1371     GLuint kI1Data               = 1u;
1372     std::array<GLuint, 2> kUData = {{
1373         2u,
1374         3u,
1375     }};
1376     GLuint kI2Data               = 4u;
1377 
1378     constexpr unsigned int kBytesPerComponent    = sizeof(GLuint);
1379     constexpr unsigned int kStructureStartOffset = 8;
1380     constexpr unsigned int kStructureSize        = 8;
1381     constexpr unsigned int kTotalSize = kStructureStartOffset + kStructureSize + kBytesPerComponent;
1382 
1383     // Create shader storage buffer
1384     GLBuffer shaderStorageBuffer[2];
1385     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1386     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1387     // upload data to instanceIn.i1
1388     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, &kI1Data);
1389     // upload data to instanceIn.s.u
1390     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureStartOffset, kStructureSize, kUData.data());
1391     // upload data to instanceIn.i2
1392     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureStartOffset + kStructureSize,
1393                     kBytesPerComponent, &kI2Data);
1394 
1395     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1396     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1397 
1398     // Bind shader storage buffer
1399     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1400     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1401 
1402     glDispatchCompute(1, 1, 1);
1403     glFinish();
1404 
1405     // Read back shader storage buffer
1406     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1407     GLuint kExpectedValues[4] = {1u, 2u, 3u, 4u};
1408     const GLuint *ptr         = reinterpret_cast<const GLuint *>(
1409         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kTotalSize, GL_MAP_READ_BIT));
1410     EXPECT_EQ(kExpectedValues[0], *ptr);
1411     ptr += (kStructureStartOffset / kBytesPerComponent);
1412     EXPECT_EQ(kExpectedValues[1], *ptr);
1413     EXPECT_EQ(kExpectedValues[2], *(ptr + 1));
1414     ptr += (kStructureSize / kBytesPerComponent);
1415     EXPECT_EQ(kExpectedValues[3], *ptr);
1416 
1417     EXPECT_GL_NO_ERROR();
1418 }
1419 
1420 // Test that access/write to structure of structure data in std430 shader storage block.
TEST_P(ShaderStorageBufferTest31,StructureOfStructureInSSBOWithStd430Qualifier)1421 TEST_P(ShaderStorageBufferTest31, StructureOfStructureInSSBOWithStd430Qualifier)
1422 {
1423     constexpr char kComputeShaderSource[] = R"(#version 310 es
1424 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1425 struct S2
1426 {
1427     uvec3 u2;
1428 };
1429 struct S1
1430 {
1431     uvec2 u1;
1432     S2 s2;
1433 };
1434 layout(std430, binding = 0) buffer blockIn {
1435     uint i1;
1436     S1 s1;
1437     uint i2;
1438 } instanceIn;
1439 layout(std430, binding = 1) buffer blockOut {
1440     uint i1;
1441     S1 s1;
1442     uint i2;
1443 } instanceOut;
1444 void main()
1445 {
1446     instanceOut.i1 = instanceIn.i1;
1447     instanceOut.s1.u1 = instanceIn.s1.u1;
1448     instanceOut.s1.s2.u2 = instanceIn.s1.s2.u2;
1449     instanceOut.i2 = instanceIn.i2;
1450 }
1451 )";
1452 
1453     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1454     glUseProgram(program);
1455 
1456     constexpr unsigned int kBytesPerComponent      = sizeof(GLuint);
1457     constexpr unsigned int kStructureS1StartOffset = 16;
1458     constexpr unsigned int kStructureS2StartOffset = 32;
1459     constexpr unsigned int kStructureS1Size        = 32;
1460     constexpr unsigned int kTotalSize =
1461         kStructureS1StartOffset + kStructureS1Size + kBytesPerComponent;
1462 
1463     GLuint kI1Data                = 1u;
1464     std::array<GLuint, 2> kU1Data = {{2u, 3u}};
1465     std::array<GLuint, 3> kU2Data = {{4u, 5u, 6u}};
1466     GLuint kI2Data                = 7u;
1467 
1468     // Create shader storage buffer
1469     GLBuffer shaderStorageBuffer[2];
1470     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1471     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1472     // upload data to instanceIn.i1
1473     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, &kI1Data);
1474     // upload data to instanceIn.s1.u1
1475     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureS1StartOffset,
1476                     kU1Data.size() * kBytesPerComponent, kU1Data.data());
1477     // upload data to instanceIn.s1.s2.u2
1478     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureS2StartOffset,
1479                     kU2Data.size() * kBytesPerComponent, kU2Data.data());
1480     // upload data to instanceIn.i2
1481     glBufferSubData(GL_SHADER_STORAGE_BUFFER, kStructureS1StartOffset + kStructureS1Size,
1482                     kBytesPerComponent, &kI2Data);
1483 
1484     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1485     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1486 
1487     // Bind shader storage buffer
1488     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1489     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1490 
1491     glDispatchCompute(1, 1, 1);
1492     glFinish();
1493 
1494     // Read back shader storage buffer
1495     GLuint kExpectedValues[7] = {1u, 2u, 3u, 4u, 5u, 6u, 7u};
1496     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1497     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1498         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kTotalSize, GL_MAP_READ_BIT));
1499     EXPECT_EQ(kExpectedValues[0], *ptr);
1500     ptr += (kStructureS1StartOffset / kBytesPerComponent);
1501     EXPECT_EQ(kExpectedValues[1], *ptr);
1502     EXPECT_EQ(kExpectedValues[2], *(ptr + 1));
1503     ptr += ((kStructureS2StartOffset - kStructureS1StartOffset) / kBytesPerComponent);
1504     EXPECT_EQ(kExpectedValues[3], *ptr);
1505     EXPECT_EQ(kExpectedValues[4], *(ptr + 1));
1506     EXPECT_EQ(kExpectedValues[5], *(ptr + 2));
1507     ptr += ((kStructureS1Size - kStructureS2StartOffset) / kBytesPerComponent);
1508     EXPECT_EQ(kExpectedValues[6], *(ptr + 4));
1509 
1510     EXPECT_GL_NO_ERROR();
1511 }
1512 
1513 // Test atomic memory functions.
TEST_P(ShaderStorageBufferTest31,AtomicMemoryFunctions)1514 TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions)
1515 {
1516     constexpr char kCS[] = R"(#version 310 es
1517 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1518 layout(std140, binding = 1) buffer blockName {
1519     uint data[2];
1520 } instanceName;
1521 
1522 void main()
1523 {
1524     instanceName.data[0] = 0u;
1525     instanceName.data[1] = 0u;
1526     atomicAdd(instanceName.data[0], 5u);
1527     atomicMax(instanceName.data[1], 7u);
1528 })";
1529 
1530     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
1531 
1532     glUseProgram(program.get());
1533 
1534     constexpr unsigned int kElementCount = 2;
1535     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
1536     constexpr unsigned int kArrayStride = 16;
1537     // Create shader storage buffer
1538     GLBuffer shaderStorageBuffer;
1539     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
1540     glBufferData(GL_SHADER_STORAGE_BUFFER, kElementCount * kArrayStride, nullptr, GL_STATIC_DRAW);
1541 
1542     // Bind shader storage buffer
1543     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer);
1544 
1545     // Dispath compute
1546     glDispatchCompute(1, 1, 1);
1547 
1548     glFinish();
1549 
1550     // Read back shader storage buffer
1551     constexpr unsigned int kExpectedValues[2] = {5u, 7u};
1552     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
1553     void *ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kElementCount * kArrayStride,
1554                                  GL_MAP_READ_BIT);
1555     for (unsigned int idx = 0; idx < kElementCount; idx++)
1556     {
1557         EXPECT_EQ(kExpectedValues[idx],
1558                   *(reinterpret_cast<const GLuint *>(reinterpret_cast<const GLbyte *>(ptr) +
1559                                                      idx * kArrayStride)));
1560     }
1561     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1562     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1563 
1564     EXPECT_GL_NO_ERROR();
1565 }
1566 
1567 // Test multiple storage buffers work correctly when program switching. In angle, storage buffer
1568 // bindings are updated accord to current program. If switch program, need to update storage buffer
1569 // bindings again.
TEST_P(ShaderStorageBufferTest31,MultiStorageBuffersForMultiPrograms)1570 TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms)
1571 {
1572     constexpr char kCS1[] = R"(#version 310 es
1573 layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
1574 layout(binding = 1) buffer Output {
1575     uint result1[];
1576 } sb_out1;
1577 void main()
1578 {
1579     highp uint offset = gl_LocalInvocationID.x;
1580     sb_out1.result1[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 1u;
1581 })";
1582 
1583     constexpr char kCS2[] = R"(#version 310 es
1584 layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
1585 layout(binding = 2) buffer Output {
1586     uint result2[];
1587 } sb_out2;
1588 void main()
1589 {
1590     highp uint offset = gl_LocalInvocationID.x;
1591     sb_out2.result2[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 2u;
1592 })";
1593 
1594     constexpr unsigned int numInvocations = 3;
1595     int arrayStride1 = 0, arrayStride2 = 0;
1596     GLenum props[] = {GL_ARRAY_STRIDE};
1597     GLBuffer shaderStorageBuffer1, shaderStorageBuffer2;
1598 
1599     ANGLE_GL_COMPUTE_PROGRAM(program1, kCS1);
1600     ANGLE_GL_COMPUTE_PROGRAM(program2, kCS2);
1601     EXPECT_GL_NO_ERROR();
1602 
1603     unsigned int outVarIndex1 =
1604         glGetProgramResourceIndex(program1.get(), GL_BUFFER_VARIABLE, "Output.result1");
1605     glGetProgramResourceiv(program1.get(), GL_BUFFER_VARIABLE, outVarIndex1, 1, props, 1, 0,
1606                            &arrayStride1);
1607     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
1608     glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride1, nullptr, GL_STREAM_READ);
1609     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer1);
1610     EXPECT_GL_NO_ERROR();
1611 
1612     unsigned int outVarIndex2 =
1613         glGetProgramResourceIndex(program2.get(), GL_BUFFER_VARIABLE, "Output.result2");
1614     glGetProgramResourceiv(program2.get(), GL_BUFFER_VARIABLE, outVarIndex2, 1, props, 1, 0,
1615                            &arrayStride2);
1616     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
1617     glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride2, nullptr, GL_STREAM_READ);
1618     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBuffer2);
1619     EXPECT_GL_NO_ERROR();
1620 
1621     glUseProgram(program1.get());
1622     glDispatchCompute(1, 1, 1);
1623     EXPECT_GL_NO_ERROR();
1624     glUseProgram(program2.get());
1625     glDispatchCompute(1, 1, 1);
1626     EXPECT_GL_NO_ERROR();
1627 
1628     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
1629     const void *ptr1 =
1630         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride1, GL_MAP_READ_BIT);
1631     for (unsigned int idx = 0; idx < numInvocations; idx++)
1632     {
1633         EXPECT_EQ(idx + 1, *((const GLuint *)((const GLbyte *)ptr1 + idx * arrayStride1)));
1634     }
1635     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1636     EXPECT_GL_NO_ERROR();
1637 
1638     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
1639     const void *ptr2 =
1640         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride2, GL_MAP_READ_BIT);
1641     EXPECT_GL_NO_ERROR();
1642     for (unsigned int idx = 0; idx < numInvocations; idx++)
1643     {
1644         EXPECT_EQ(idx + 2, *((const GLuint *)((const GLbyte *)ptr2 + idx * arrayStride2)));
1645     }
1646     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1647     EXPECT_GL_NO_ERROR();
1648 
1649     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1650     EXPECT_GL_NO_ERROR();
1651 }
1652 
1653 // Test that function calling is supported in SSBO access chain.
TEST_P(ShaderStorageBufferTest31,FunctionCallInSSBOAccessChain)1654 TEST_P(ShaderStorageBufferTest31, FunctionCallInSSBOAccessChain)
1655 {
1656     constexpr char kComputeShaderSource[] = R"(#version 310 es
1657 layout (local_size_x=4) in;
1658 highp uint getIndex (in highp uvec2 localID, uint element)
1659 {
1660     return localID.x + element;
1661 }
1662 layout(binding=0, std430) buffer Storage
1663 {
1664     highp uint values[];
1665 } sb_store;
1666 
1667 void main()
1668 {
1669     sb_store.values[getIndex(gl_LocalInvocationID.xy, 0u)] = gl_LocalInvocationIndex;
1670 }
1671 )";
1672 
1673     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1674     EXPECT_GL_NO_ERROR();
1675 }
1676 
1677 // Test that unary operator is supported in SSBO access chain.
TEST_P(ShaderStorageBufferTest31,UnaryOperatorInSSBOAccessChain)1678 TEST_P(ShaderStorageBufferTest31, UnaryOperatorInSSBOAccessChain)
1679 {
1680     constexpr char kComputeShaderSource[] = R"(#version 310 es
1681 layout (local_size_x=4) in;
1682 layout(binding=0, std430) buffer Storage
1683 {
1684     highp uint values[];
1685 } sb_store;
1686 
1687 void main()
1688 {
1689     uint invocationNdx = gl_LocalInvocationIndex;
1690     sb_store.values[++invocationNdx] = invocationNdx;
1691 }
1692 )";
1693 
1694     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1695     EXPECT_GL_NO_ERROR();
1696 }
1697 
1698 // Test that ternary operator is supported in SSBO access chain.
TEST_P(ShaderStorageBufferTest31,TernaryOperatorInSSBOAccessChain)1699 TEST_P(ShaderStorageBufferTest31, TernaryOperatorInSSBOAccessChain)
1700 {
1701     constexpr char kComputeShaderSource[] = R"(#version 310 es
1702 layout (local_size_x=4) in;
1703 layout(binding=0, std430) buffer Storage
1704 {
1705     highp uint values[];
1706 } sb_store;
1707 
1708 void main()
1709 {
1710     sb_store.values[gl_LocalInvocationIndex > 2u ? gl_NumWorkGroups.x : gl_NumWorkGroups.y]
1711             = gl_LocalInvocationIndex;
1712 }
1713 )";
1714 
1715     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1716     EXPECT_GL_NO_ERROR();
1717 }
1718 
1719 // Tests that alignment is correct for bools inside a SSB and that the values
1720 // are written correctly by a trivial shader. Currently tests only the alignment
1721 // of the initial block.
TEST_P(ShaderStorageBufferTest31,LoadAndStoreBooleanValue)1722 TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanValue)
1723 {
1724     // TODO(jiajia.qin@intel.com): Figure out why it fails on Intel Linux platform.
1725     // http://anglebug.com/1951
1726     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
1727 
1728     constexpr char kComputeShaderSource[] = R"(#version 310 es
1729 layout (local_size_x=1) in;
1730 layout(binding=0, std140) buffer Storage0
1731 {
1732     bool b1;
1733     bool b2;
1734     bool b3;
1735 } sb_load;
1736 layout(binding=1, std140) buffer Storage1
1737 {
1738     bool b1;
1739     bool b2;
1740     bool b3;
1741 } sb_store;
1742 void main()
1743 {
1744    sb_store.b1 = sb_load.b1;
1745    sb_store.b2 = sb_load.b2;
1746    sb_store.b3 = sb_load.b3;
1747 }
1748 )";
1749 
1750     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1751     EXPECT_GL_NO_ERROR();
1752 
1753     glUseProgram(program);
1754 
1755     constexpr GLuint kB1Value                 = 1u;
1756     constexpr GLuint kB2Value[2]              = {0u, 1u};
1757     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
1758     // Create shader storage buffer
1759     GLBuffer shaderStorageBuffer[2];
1760     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1761     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, nullptr, GL_STATIC_DRAW);
1762     GLint offset = 0;
1763     // upload data to sb_load.b1
1764     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kBytesPerComponent, &kB1Value);
1765     offset += kBytesPerComponent;
1766     // upload data to sb_load.b2
1767     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, 2 * kBytesPerComponent, kB2Value);
1768 
1769     constexpr GLuint kStoreBufferContents[3] = {0x1BCD1234, 0x2BCD1234, 0x3BCD1234};
1770     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1771     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, kStoreBufferContents,
1772                  GL_STATIC_DRAW);
1773 
1774     // Bind shader storage buffer
1775     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1776     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1777 
1778     glDispatchCompute(1, 1, 1);
1779     glFinish();
1780 
1781     // Read back shader storage buffer
1782     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1783     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1784         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * kBytesPerComponent, GL_MAP_READ_BIT));
1785     EXPECT_EQ(kB1Value, ptr[0]);
1786     EXPECT_EQ(kB2Value[0], ptr[1]);
1787     EXPECT_EQ(kB2Value[1], ptr[2]);
1788 
1789     EXPECT_GL_NO_ERROR();
1790 }
1791 
1792 // Tests that alignment is correct for bvecs3 inside a SSB and that the
1793 // values are written correctly by a trivial shader. Currently tests only the
1794 // alignment of the initial block.
TEST_P(ShaderStorageBufferTest31,LoadAndStoreBooleanVec3)1795 TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanVec3)
1796 {
1797     // TODO(jiajia.qin@intel.com): Figure out why it fails on Intel Linux platform.
1798     // http://anglebug.com/1951
1799     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
1800 
1801     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
1802 
1803     constexpr char kComputeShaderSource[] = R"(#version 310 es
1804 layout (local_size_x=1) in;
1805 layout(binding=0, std140) buffer Storage0
1806 {
1807     bvec3 b;
1808 } sb_load;
1809 layout(binding=1, std140) buffer Storage1
1810 {
1811     bvec3 b;
1812 } sb_store;
1813 void main()
1814 {
1815    sb_store.b = sb_load.b;
1816 }
1817 )";
1818 
1819     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1820     EXPECT_GL_NO_ERROR();
1821 
1822     glUseProgram(program);
1823 
1824     constexpr GLuint kBValues[3]              = {1u, 0u, 1u};
1825     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
1826     // Create shader storage buffer
1827     GLBuffer shaderStorageBuffer[2];
1828     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1829     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, nullptr, GL_STATIC_DRAW);
1830     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, 3 * kBytesPerComponent, &kBValues);
1831 
1832     constexpr GLuint kStoreBufferContents[3] = {0x1BCD1234, 0x2BCD1234, 0x3BCD1234};
1833     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1834     glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * kBytesPerComponent, kStoreBufferContents,
1835                  GL_STATIC_DRAW);
1836 
1837     // Bind shader storage buffer
1838     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1839     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1840 
1841     glDispatchCompute(1, 1, 1);
1842     glFinish();
1843 
1844     // Read back shader storage buffer
1845     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1846     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1847         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * kBytesPerComponent, GL_MAP_READ_BIT));
1848     EXPECT_EQ(kBValues[0], ptr[0]);
1849     EXPECT_EQ(kBValues[1], ptr[1]);
1850     EXPECT_EQ(kBValues[2], ptr[2]);
1851 
1852     EXPECT_GL_NO_ERROR();
1853 }
1854 
1855 // Tests that alignment is correct for bool + bvecs2 inside a SSB and that the
1856 // values are written correctly by a trivial shader. Currently tests only the
1857 // alignment of the initial block. Compare to LoadAndStoreBooleanVec3 to see how
1858 // the alignment rules affect the memory layout.
TEST_P(ShaderStorageBufferTest31,LoadAndStoreBooleanVarAndVec2)1859 TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanVarAndVec2)
1860 {
1861     // TODO(jiajia.qin@intel.com): Figure out why it fails on Intel Linux platform.
1862     // http://anglebug.com/1951
1863     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
1864 
1865     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
1866 
1867     constexpr char kComputeShaderSource[] = R"(#version 310 es
1868 layout (local_size_x=1) in;
1869 layout(binding=0, std140) buffer Storage0
1870 {
1871     bool b1;
1872     bvec2 b2;
1873 } sb_load;
1874 layout(binding=1, std140) buffer Storage1
1875 {
1876     bool b1;
1877     bvec2 b2;
1878 } sb_store;
1879 void main()
1880 {
1881    sb_store.b1 = sb_load.b1;
1882    sb_store.b2 = sb_load.b2;
1883 }
1884 )";
1885     // https://www.khronos.org/registry/OpenGL/specs/es/3.1/es_spec_3.1.pdf
1886     // 7.6.2.2 Standard Uniform Block Layout
1887 
1888     // ... A structure and each structure member have a base offset and a base
1889     // alignment, from which an aligned offset is computed by rounding the base
1890     // offset up to a multiple of the base alignment. The base offset of the
1891     // first member of a structure is taken from the aligned offset of the
1892     // structure itself. ... The members of a toplevel uniform block are laid
1893     // out in buffer storage by treating the uniform block as a structure with a
1894     // base offset of zero.
1895 
1896     // 1. If the member is a scalar consuming N basic machine units, the base
1897     // alignment is N.
1898 
1899     // 2. If the member is a two- or four-component vector with components
1900     // consuming N basic machine units, the base alignment is 2N or 4N,
1901     // respectively
1902 
1903     // b1 N == 4, basic offset 0, alignment 4, is at 0..3
1904     // b2 N == 4, basic offset 4, alignment 2*4 = 8, is at 8..16.
1905 
1906     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1907     EXPECT_GL_NO_ERROR();
1908 
1909     glUseProgram(program);
1910     constexpr GLuint kAlignPadding  = 0x1abcd789u;
1911     constexpr GLuint kBValues[]     = {1u, kAlignPadding, 0u, 1u};
1912     constexpr unsigned int kSsbSize = sizeof(kBValues);
1913     // Create shader storage buffer
1914     GLBuffer shaderStorageBuffer[2];
1915     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1916     glBufferData(GL_SHADER_STORAGE_BUFFER, kSsbSize, nullptr, GL_STATIC_DRAW);
1917     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kSsbSize, &kBValues);
1918 
1919     constexpr GLuint kStoreBufferContents[4] = {0x1BCD1234, 0x2BCD1234, 0x3BCD1234, 0x3BCD1277};
1920     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1921     glBufferData(GL_SHADER_STORAGE_BUFFER, kSsbSize, kStoreBufferContents, GL_STATIC_DRAW);
1922 
1923     // Bind shader storage buffer
1924     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
1925     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
1926 
1927     glDispatchCompute(1, 1, 1);
1928     glFinish();
1929 
1930     // Read back shader storage buffer
1931     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
1932     const GLuint *ptr = reinterpret_cast<const GLuint *>(
1933         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSsbSize, GL_MAP_READ_BIT));
1934     EXPECT_EQ(kBValues[0], ptr[0]);
1935     // Index 1 is padding.
1936     EXPECT_EQ(kBValues[2], ptr[2]);
1937     EXPECT_EQ(kBValues[3], ptr[3]);
1938 
1939     EXPECT_GL_NO_ERROR();
1940 }
1941 
1942 // Test that non-structure array of arrays is supported in SSBO.
TEST_P(ShaderStorageBufferTest31,SimpleArrayOfArrays)1943 TEST_P(ShaderStorageBufferTest31, SimpleArrayOfArrays)
1944 {
1945     constexpr char kComputeShaderSource[] = R"(#version 310 es
1946 layout (local_size_x=1) in;
1947 layout(binding=0, std140) buffer Storage0
1948 {
1949     uint a[2][2][2];
1950     uint b;
1951 } sb_load;
1952 layout(binding=1, std140) buffer Storage1
1953 {
1954     uint a[2][2][2];
1955     uint b;
1956 } sb_store;
1957 void main()
1958 {
1959    sb_store.a[0][0][0] = sb_load.a[0][0][0];
1960    sb_store.a[0][0][1] = sb_load.a[0][0][1];
1961    sb_store.a[0][1][0] = sb_load.a[0][1][0];
1962    sb_store.a[0][1][1] = sb_load.a[0][1][1];
1963    sb_store.a[1][0][0] = sb_load.a[1][0][0];
1964    sb_store.a[1][0][1] = sb_load.a[1][0][1];
1965    sb_store.a[1][1][0] = sb_load.a[1][1][0];
1966    sb_store.a[1][1][1] = sb_load.a[1][1][1];
1967    sb_store.b = sb_load.b;
1968 }
1969 )";
1970 
1971     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
1972     glUseProgram(program);
1973 
1974     constexpr unsigned int kBytesPerComponent = sizeof(GLuint);
1975     // The array stride are rounded up to the base alignment of a vec4 for std140 layout.
1976     constexpr unsigned int kArrayStride                 = 16;
1977     constexpr unsigned int kDimension0                  = 2;
1978     constexpr unsigned int kDimension1                  = 2;
1979     constexpr unsigned int kDimension2                  = 2;
1980     constexpr unsigned int kAElementCount               = kDimension0 * kDimension1 * kDimension2;
1981     constexpr unsigned int kAComponentCountPerDimension = kArrayStride / kBytesPerComponent;
1982     constexpr unsigned int kTotalSize = kArrayStride * kAElementCount + kBytesPerComponent;
1983 
1984     constexpr GLuint kInputADatas[kAElementCount * kAComponentCountPerDimension] = {
1985         1u, 0u, 0u, 0u, 2u, 0u, 0u, 0u, 3u, 0u, 0u, 0u, 4u, 0u, 0u, 0u,
1986         5u, 0u, 0u, 0u, 6u, 0u, 0u, 0u, 7u, 0u, 0u, 0u, 8u, 0u, 0u, 0u};
1987     constexpr GLuint kInputBData = 9u;
1988 
1989     // Create shader storage buffer
1990     GLBuffer shaderStorageBuffer[2];
1991     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
1992     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
1993     GLint offset = 0;
1994     // upload data to sb_load.a
1995     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kAElementCount * kArrayStride, kInputADatas);
1996     offset += (kAElementCount * kArrayStride);
1997     // upload data to sb_load.b
1998     glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, kBytesPerComponent, &kInputBData);
1999 
2000     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2001     glBufferData(GL_SHADER_STORAGE_BUFFER, kTotalSize, nullptr, GL_STATIC_DRAW);
2002 
2003     // Bind shader storage buffer
2004     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2005     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2006 
2007     glDispatchCompute(1, 1, 1);
2008     glFinish();
2009 
2010     // Read back shader storage buffer
2011     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2012     constexpr GLuint kExpectedADatas[kAElementCount] = {1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u};
2013     const GLuint *ptr                                = reinterpret_cast<const GLuint *>(
2014         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kTotalSize, GL_MAP_READ_BIT));
2015     for (unsigned i = 0u; i < kDimension0; i++)
2016     {
2017         for (unsigned j = 0u; j < kDimension1; j++)
2018         {
2019             for (unsigned k = 0u; k < kDimension2; k++)
2020             {
2021                 unsigned index = i * (kDimension1 * kDimension2) + j * kDimension2 + k;
2022                 EXPECT_EQ(kExpectedADatas[index],
2023                           *(ptr + index * (kArrayStride / kBytesPerComponent)));
2024             }
2025         }
2026     }
2027 
2028     ptr += (kAElementCount * (kArrayStride / kBytesPerComponent));
2029     EXPECT_EQ(kInputBData, *ptr);
2030 
2031     EXPECT_GL_NO_ERROR();
2032 }
2033 
2034 // Test that the length of unsized array is supported.
TEST_P(ShaderStorageBufferTest31,UnsizedArrayLength)2035 TEST_P(ShaderStorageBufferTest31, UnsizedArrayLength)
2036 {
2037     constexpr char kComputeShaderSource[] =
2038         R"(#version 310 es
2039 layout (local_size_x=1) in;
2040 layout(std430, binding = 0) buffer Storage0 {
2041   uint buf1[2];
2042   uint buf2[];
2043 } sb_load;
2044 layout(std430, binding = 1) buffer Storage1 {
2045   int unsizedArrayLength;
2046   uint buf1[2];
2047   uint buf2[];
2048 } sb_store;
2049 
2050 void main()
2051 {
2052   sb_store.unsizedArrayLength = sb_store.buf2.length();
2053   for (int i = 0; i < sb_load.buf1.length(); i++) {
2054     sb_store.buf1[i] = sb_load.buf1[i];
2055   }
2056   for (int i = 0; i < sb_load.buf2.length(); i++) {
2057     sb_store.buf2[i] = sb_load.buf2[i];
2058   }
2059 }
2060 )";
2061 
2062     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2063     glUseProgram(program);
2064 
2065     constexpr unsigned int kBytesPerComponent                       = sizeof(unsigned int);
2066     constexpr unsigned int kLoadBlockElementCount                   = 5;
2067     constexpr unsigned int kStoreBlockElementCount                  = 6;
2068     constexpr unsigned int kInputValues[kLoadBlockElementCount]     = {1u, 2u, 3u, 4u, 5u};
2069     constexpr unsigned int kExpectedValues[kStoreBlockElementCount] = {3u, 1u, 2u, 3u, 4u, 5u};
2070     GLBuffer shaderStorageBuffer[2];
2071     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2072     glBufferData(GL_SHADER_STORAGE_BUFFER, kLoadBlockElementCount * kBytesPerComponent,
2073                  &kInputValues, GL_STATIC_DRAW);
2074     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2075     glBufferData(GL_SHADER_STORAGE_BUFFER, kStoreBlockElementCount * kBytesPerComponent, nullptr,
2076                  GL_STATIC_DRAW);
2077 
2078     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2079     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2080 
2081     glDispatchCompute(1, 1, 1);
2082     glFinish();
2083 
2084     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2085     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2086         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kStoreBlockElementCount * kBytesPerComponent,
2087                          GL_MAP_READ_BIT));
2088     for (unsigned int i = 0; i < kStoreBlockElementCount; i++)
2089     {
2090         EXPECT_EQ(kExpectedValues[i], *(ptr + i));
2091     }
2092 
2093     EXPECT_GL_NO_ERROR();
2094 }
2095 
2096 // Test back to back that the length of unsized array is correct after respecifying the buffer
2097 // size to be smaller than the first
TEST_P(ShaderStorageBufferTest31,UnsizedArrayLengthRespecifySize)2098 TEST_P(ShaderStorageBufferTest31, UnsizedArrayLengthRespecifySize)
2099 {
2100     // http://anglebug.com/4566
2101     ANGLE_SKIP_TEST_IF(IsD3D11() || (IsAndroid() && IsOpenGLES()));
2102 
2103     constexpr char kComputeShaderSource[] =
2104         R"(#version 310 es
2105 layout (local_size_x=1) in;
2106 layout(std430, binding = 0) buffer Storage0 {
2107   uint buf1[2];
2108   uint buf2[];
2109 } sb_load;
2110 layout(std430, binding = 1) buffer Storage1 {
2111   int unsizedArrayLength;
2112   uint buf1[2];
2113   uint buf2[];
2114 } sb_store;
2115 
2116 void main()
2117 {
2118   sb_store.unsizedArrayLength = sb_store.buf2.length();
2119   for (int i = 0; i < sb_load.buf1.length(); i++) {
2120     sb_store.buf1[i] = sb_load.buf1[i];
2121   }
2122   for (int i = 0; i < sb_load.buf2.length(); i++) {
2123     sb_store.buf2[i] = sb_load.buf2[i];
2124   }
2125 }
2126 )";
2127 
2128     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2129     glUseProgram(program);
2130 
2131     constexpr unsigned int kBytesPerComponent                       = sizeof(unsigned int);
2132     constexpr unsigned int kLoadBlockElementCount                   = 5;
2133     constexpr unsigned int kStoreBlockElementCount                  = 6;
2134     constexpr unsigned int kInputValues[kLoadBlockElementCount]     = {1u, 2u, 3u, 4u, 5u};
2135     constexpr unsigned int kExpectedValues[kStoreBlockElementCount] = {3u, 1u, 2u, 3u, 4u, 5u};
2136     GLBuffer shaderStorageBuffer[2];
2137     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2138     glBufferData(GL_SHADER_STORAGE_BUFFER, kLoadBlockElementCount * kBytesPerComponent,
2139                  &kInputValues, GL_STATIC_DRAW);
2140     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2141     glBufferData(GL_SHADER_STORAGE_BUFFER, kStoreBlockElementCount * kBytesPerComponent, nullptr,
2142                  GL_STATIC_DRAW);
2143 
2144     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2145     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2146 
2147     glDispatchCompute(1, 1, 1);
2148     glFinish();
2149 
2150     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2151     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2152         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kStoreBlockElementCount * kBytesPerComponent,
2153                          GL_MAP_READ_BIT));
2154     for (unsigned int i = 0; i < kStoreBlockElementCount; i++)
2155     {
2156         EXPECT_EQ(kExpectedValues[i], *(ptr + i));
2157     }
2158     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2159 
2160     EXPECT_GL_NO_ERROR();
2161 
2162     // Respecify these SSBOs to be smaller
2163     constexpr unsigned int kSmallerLoadBlockElementCount                          = 3;
2164     constexpr unsigned int kSmallerStoreBlockElementCount                         = 4;
2165     constexpr unsigned int kSmallerInputValues[kSmallerLoadBlockElementCount]     = {1u, 2u, 3u};
2166     constexpr unsigned int kSmallerExpectedValues[kSmallerStoreBlockElementCount] = {1u, 1u, 2u,
2167                                                                                      3u};
2168 
2169     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2170     glBufferData(GL_SHADER_STORAGE_BUFFER, kSmallerLoadBlockElementCount * kBytesPerComponent,
2171                  &kSmallerInputValues, GL_STATIC_DRAW);
2172     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2173     glBufferData(GL_SHADER_STORAGE_BUFFER, kSmallerStoreBlockElementCount * kBytesPerComponent,
2174                  nullptr, GL_STATIC_DRAW);
2175 
2176     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2177     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2178 
2179     glDispatchCompute(1, 1, 1);
2180     glFinish();
2181 
2182     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2183     const GLuint *ptr2 = reinterpret_cast<const GLuint *>(
2184         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
2185                          kSmallerStoreBlockElementCount * kBytesPerComponent, GL_MAP_READ_BIT));
2186     for (unsigned int i = 0; i < kSmallerStoreBlockElementCount; i++)
2187     {
2188         EXPECT_EQ(kSmallerExpectedValues[i], *(ptr2 + i));
2189     }
2190 
2191     EXPECT_GL_NO_ERROR();
2192 }
2193 
2194 // Test that compond assignment operator for buffer variable is correctly handled.
TEST_P(ShaderStorageBufferTest31,CompoundAssignmentOperator)2195 TEST_P(ShaderStorageBufferTest31, CompoundAssignmentOperator)
2196 {
2197     constexpr char kComputeShaderSource[] =
2198         R"(#version 310 es
2199 layout (local_size_x=1) in;
2200 layout(binding=0, std140) buffer Storage0
2201 {
2202     uint b;
2203 } sb_load;
2204 layout(binding=1, std140) buffer Storage1
2205 {
2206     uint b;
2207 } sb_store;
2208 void main()
2209 {
2210     uint temp = 2u;
2211     temp += sb_load.b;
2212     sb_store.b += temp;
2213     sb_store.b += sb_load.b;
2214 }
2215 )";
2216 
2217     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2218     glUseProgram(program);
2219 
2220     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
2221     constexpr unsigned int kInputValue        = 1u;
2222     constexpr unsigned int kExpectedValue     = 5u;
2223     GLBuffer shaderStorageBuffer[2];
2224     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2225     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2226     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2227     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2228 
2229     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2230     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2231 
2232     glDispatchCompute(1, 1, 1);
2233     glFinish();
2234 
2235     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2236     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2237         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT));
2238     EXPECT_EQ(kExpectedValue, *ptr);
2239 
2240     EXPECT_GL_NO_ERROR();
2241 }
2242 
2243 // Test that BufferData change propagate to context state.
TEST_P(ShaderStorageBufferTest31,DependentBufferChange)2244 TEST_P(ShaderStorageBufferTest31, DependentBufferChange)
2245 {
2246     // Test fail on Nexus devices. http://anglebug.com/6251
2247     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
2248 
2249     constexpr char kComputeShaderSource[] =
2250         R"(#version 310 es
2251 layout (local_size_x=1) in;
2252 layout(binding=0, std140) buffer Storage0
2253 {
2254     uint b;
2255 } sb_load;
2256 layout(binding=1, std140) buffer Storage1
2257 {
2258     uint b;
2259 } sb_store;
2260 void main()
2261 {
2262     sb_store.b += sb_load.b;
2263 }
2264 )";
2265 
2266     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2267     glUseProgram(program);
2268 
2269     constexpr unsigned int kBufferSize                        = 4096;
2270     constexpr unsigned int kBufferElementCount                = kBufferSize / sizeof(unsigned int);
2271     std::array<unsigned int, kBufferElementCount> kBufferData = {};
2272     GLBuffer shaderStorageBuffer[2];
2273     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2274     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2275     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2276     kBufferData[0] = 5;  // initial value
2277     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2278 
2279     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2280     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2281 
2282     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2283     kBufferData[0] = 7;
2284     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2285     glDispatchCompute(1, 1, 1);
2286     kBufferData[0] = 11;
2287     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT);
2288     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferData.data(), GL_STATIC_DRAW);
2289     glDispatchCompute(1, 1, 1);
2290 
2291     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2292     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2293     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2294         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
2295     constexpr unsigned int kExpectedValue = 5 + 7 + 11;
2296     EXPECT_EQ(kExpectedValue, *ptr);
2297 
2298     EXPECT_GL_NO_ERROR();
2299 }
2300 
2301 // Test that readonly binary operator for buffer variable is correctly handled.
TEST_P(ShaderStorageBufferTest31,ReadonlyBinaryOperator)2302 TEST_P(ShaderStorageBufferTest31, ReadonlyBinaryOperator)
2303 {
2304     constexpr char kComputeShaderSource[] =
2305         R"(#version 310 es
2306  layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2307  layout(std430, binding = 0) buffer blockIn1 {
2308      uvec2 data1;
2309  };
2310  layout(std430, binding = 1) buffer blockIn2 {
2311      uvec2 data2;
2312  };
2313  layout(std430, binding = 2) buffer blockIn3 {
2314      uvec2 data;
2315  } instanceIn3;
2316  layout(std430, binding = 3) buffer blockOut {
2317      uvec2 data;
2318  } instanceOut;
2319  void main()
2320  {
2321      instanceOut.data = data1 + data2 + instanceIn3.data;
2322  }
2323  )";
2324 
2325     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2326     glUseProgram(program);
2327 
2328     constexpr unsigned int kComponentCount                = 2;
2329     constexpr unsigned int kBytesPerComponent             = sizeof(unsigned int);
2330     constexpr unsigned int kInputValues1[kComponentCount] = {1u, 2u};
2331     constexpr unsigned int kInputValues2[kComponentCount] = {3u, 4u};
2332     constexpr unsigned int kInputValues3[kComponentCount] = {5u, 6u};
2333     // Create shader storage buffer
2334     GLBuffer shaderStorageBuffer[4];
2335     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2336     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, kInputValues1,
2337                  GL_STATIC_DRAW);
2338     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2339     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, kInputValues2,
2340                  GL_STATIC_DRAW);
2341     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[2]);
2342     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, kInputValues3,
2343                  GL_STATIC_DRAW);
2344     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[3]);
2345     glBufferData(GL_SHADER_STORAGE_BUFFER, kComponentCount * kBytesPerComponent, nullptr,
2346                  GL_STATIC_DRAW);
2347 
2348     // Bind shader storage buffer
2349     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2350     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2351     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBuffer[2]);
2352     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, shaderStorageBuffer[3]);
2353 
2354     glDispatchCompute(1, 1, 1);
2355     glFinish();
2356 
2357     // Read back shader storage buffer
2358     constexpr unsigned int kExpectedValues[kComponentCount] = {9u, 12u};
2359     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[3]);
2360     const GLuint *ptr = reinterpret_cast<const GLuint *>(glMapBufferRange(
2361         GL_SHADER_STORAGE_BUFFER, 0, kComponentCount * kBytesPerComponent, GL_MAP_READ_BIT));
2362     for (unsigned int idx = 0; idx < kComponentCount; idx++)
2363     {
2364         EXPECT_EQ(kExpectedValues[idx], *(ptr + idx));
2365     }
2366 
2367     EXPECT_GL_NO_ERROR();
2368 }
2369 
2370 // Test that ssbo as an argument of a function can be translated.
TEST_P(ShaderStorageBufferTest31,SSBOAsFunctionArgument)2371 TEST_P(ShaderStorageBufferTest31, SSBOAsFunctionArgument)
2372 {
2373     constexpr char kComputeShaderSource[] =
2374         R"(#version 310 es
2375 layout(local_size_x = 1) in;
2376 
2377 layout(std430, binding = 0) buffer Block
2378 {
2379     uint var1;
2380     uint var2;
2381 };
2382 
2383 bool compare(uint a, uint b)
2384 {
2385     return a == b;
2386 }
2387 
2388 uint increase(inout uint a)
2389 {
2390     a++;
2391     return a;
2392 }
2393 
2394 void main(void)
2395 {
2396     bool isEqual = compare(var1, 2u);
2397     if (isEqual)
2398     {
2399         var2 += increase(var1);
2400     }
2401 }
2402 )";
2403 
2404     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2405     glUseProgram(program);
2406 
2407     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
2408     constexpr unsigned int kInputValues[2]    = {2u, 2u};
2409     constexpr unsigned int kExpectedValues[2] = {3u, 5u};
2410     GLBuffer shaderStorageBuffer;
2411     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
2412     glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * kBytesPerComponent, &kInputValues, GL_STATIC_DRAW);
2413 
2414     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer);
2415 
2416     glDispatchCompute(1, 1, 1);
2417     glFinish();
2418 
2419     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer);
2420     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2421         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 2 * kBytesPerComponent, GL_MAP_READ_BIT));
2422     EXPECT_EQ(kExpectedValues[0], *ptr);
2423     EXPECT_EQ(kExpectedValues[1], *(ptr + 1));
2424 
2425     EXPECT_GL_NO_ERROR();
2426 }
2427 
2428 // Test that ssbo as unary operand works well.
TEST_P(ShaderStorageBufferTest31,SSBOAsUnaryOperand)2429 TEST_P(ShaderStorageBufferTest31, SSBOAsUnaryOperand)
2430 {
2431     constexpr char kComputeShaderSource[] =
2432         R"(#version 310 es
2433 layout (local_size_x=1) in;
2434 layout(binding=0, std140) buffer Storage0
2435 {
2436     uint b;
2437 } sb_load;
2438 layout(binding=1, std140) buffer Storage1
2439 {
2440     uint i;
2441 } sb_store;
2442 void main()
2443 {
2444     sb_store.i = +sb_load.b;
2445     ++sb_store.i;
2446 }
2447 )";
2448 
2449     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2450     glUseProgram(program);
2451 
2452     constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
2453     constexpr unsigned kInputValue            = 1u;
2454     constexpr unsigned int kExpectedValue     = 2u;
2455     GLBuffer shaderStorageBuffer[2];
2456     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
2457     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2458     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2459     glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
2460 
2461     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
2462     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
2463 
2464     glDispatchCompute(1, 1, 1);
2465     glFinish();
2466 
2467     glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
2468     const GLuint *ptr = reinterpret_cast<const GLuint *>(
2469         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT));
2470     EXPECT_EQ(kExpectedValue, *ptr);
2471 
2472     EXPECT_GL_NO_ERROR();
2473 }
2474 
2475 // Test that uniform can be used as the index of buffer variable.
TEST_P(ShaderStorageBufferTest31,UniformUsedAsIndexOfBufferVariable)2476 TEST_P(ShaderStorageBufferTest31, UniformUsedAsIndexOfBufferVariable)
2477 {
2478     constexpr char kComputeShaderSource[] =
2479         R"(#version 310 es
2480 layout (local_size_x=4) in;
2481 layout(std140, binding = 0) uniform CB
2482 {
2483     uint index;
2484 } cb;
2485 
2486 layout(binding=0, std140) buffer Storage0
2487 {
2488     uint data[];
2489 } sb_load;
2490 layout(binding=1, std140) buffer Storage1
2491 {
2492     uint data[];
2493 } sb_store;
2494 void main()
2495 {
2496     sb_store.data[gl_LocalInvocationIndex] = sb_load.data[gl_LocalInvocationID.x + cb.index];
2497 }
2498 )";
2499 
2500     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2501     EXPECT_GL_NO_ERROR();
2502 }
2503 
2504 // Test that inactive but statically used SSBOs with unsized array are handled correctly.
2505 //
2506 // Glslang wrapper used to replace the layout/qualifier of an inactive SSBO with |struct|,
2507 // effectively turning the interface block declaration into a struct definition.  This generally
2508 // worked except for SSBOs with an unsized array.  This test makes sure this special case is
2509 // now properly handled.
TEST_P(ShaderStorageBufferTest31,InactiveButStaticallyUsedWithUnsizedArray)2510 TEST_P(ShaderStorageBufferTest31, InactiveButStaticallyUsedWithUnsizedArray)
2511 {
2512     constexpr char kComputeShaderSource[] =
2513         R"(#version 310 es
2514 layout (local_size_x=1) in;
2515 layout(binding=0, std140) buffer Storage
2516 {
2517     uint data[];
2518 } sb;
2519 void main()
2520 {
2521     if (false)
2522     {
2523         sb.data[0] = 1u;
2524     }
2525 }
2526 )";
2527 
2528     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2529     EXPECT_GL_NO_ERROR();
2530 
2531     glUseProgram(program);
2532     glDispatchCompute(1, 1, 1);
2533     EXPECT_GL_NO_ERROR();
2534 }
2535 
2536 // Verify the size of the buffer with unsized struct array is calculated correctly
TEST_P(ShaderStorageBufferTest31,BigStructUnsizedStructArraySize)2537 TEST_P(ShaderStorageBufferTest31, BigStructUnsizedStructArraySize)
2538 {
2539     // TODO(http://anglebug.com/3596)
2540     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
2541 
2542     constexpr char kComputeShaderSource[] =
2543         R"(#version 310 es
2544 layout (local_size_x=1) in;
2545 
2546 struct S
2547 {
2548     mat4 m;     // 4 vec4 = 16 floats
2549     vec4 a[10]; // 10 vec4 = 40 floats
2550 };
2551 
2552 layout(binding=0) buffer B
2553 {
2554     vec4 precedingMember;               // 4 floats
2555     S precedingMemberUnsizedArray[];    // 56 floats
2556 } b;
2557 
2558 void main()
2559 {
2560     if (false)
2561     {
2562         b.precedingMember = vec4(1.0, 1.0, 1.0, 1.0);
2563     }
2564 }
2565 )";
2566 
2567     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2568     EXPECT_GL_NO_ERROR();
2569 
2570     glUseProgram(program);
2571     glDispatchCompute(1, 1, 1);
2572     EXPECT_GL_NO_ERROR();
2573 
2574     GLuint resourceIndex = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "B");
2575     EXPECT_GL_NO_ERROR();
2576     EXPECT_NE(resourceIndex, 0xFFFFFFFF);
2577 
2578     GLenum property = GL_BUFFER_DATA_SIZE;
2579     GLint queryData = -1;
2580     glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &property, 1,
2581                            nullptr, &queryData);
2582     EXPECT_GL_NO_ERROR();
2583 
2584     // 60 * sizeof(float) = 240
2585     // Vulkan rounds up to the required buffer alignment, so >= 240
2586     EXPECT_GE(queryData, 240);
2587 }
2588 
2589 // Verify the size of the buffer with unsized float array is calculated correctly
TEST_P(ShaderStorageBufferTest31,BigStructUnsizedFloatArraySize)2590 TEST_P(ShaderStorageBufferTest31, BigStructUnsizedFloatArraySize)
2591 {
2592     // TODO(http://anglebug.com/3596)
2593     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
2594 
2595     constexpr char kComputeShaderSource[] =
2596         R"(#version 310 es
2597 layout (local_size_x=1) in;
2598 
2599 layout(binding=0) buffer B
2600 {
2601     vec4 precedingMember;                   // 4 floats
2602     float precedingMemberUnsizedArray[];    // "1" float
2603 } b;
2604 
2605 void main()
2606 {
2607     if (false)
2608     {
2609         b.precedingMember = vec4(1.0, 1.0, 1.0, 1.0);
2610     }
2611 }
2612 )";
2613 
2614     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2615     EXPECT_GL_NO_ERROR();
2616 
2617     glUseProgram(program);
2618     glDispatchCompute(1, 1, 1);
2619     EXPECT_GL_NO_ERROR();
2620 
2621     GLuint resourceIndex = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "B");
2622     EXPECT_GL_NO_ERROR();
2623     EXPECT_NE(resourceIndex, 0xFFFFFFFF);
2624 
2625     GLenum property = GL_BUFFER_DATA_SIZE;
2626     GLint queryData = -1;
2627     glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &property, 1,
2628                            nullptr, &queryData);
2629     EXPECT_GL_NO_ERROR();
2630 
2631     // 5 * sizeof(float) = 20
2632     // Vulkan rounds up to the required buffer alignment, so >= 20
2633     EXPECT_GE(queryData, 20);
2634 }
2635 
2636 // Tests that shader write before pixel pack/unpack works
TEST_P(ShaderStorageBufferTest31,ShaderStorageBufferWriteThenPixelPackUnpack)2637 TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferWriteThenPixelPackUnpack)
2638 {
2639     // Create two textures and framebuffers and make sure they are initialized.
2640     GLTexture color1;
2641     glBindTexture(GL_TEXTURE_2D, color1);
2642     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2643 
2644     GLFramebuffer framebuffer1;
2645     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2646     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color1, 0);
2647 
2648     glClearColor(255, 0, 255, 255);
2649     glClear(GL_COLOR_BUFFER_BIT);
2650     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
2651 
2652     GLTexture color2;
2653     glBindTexture(GL_TEXTURE_2D, color2);
2654     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2655 
2656     GLFramebuffer framebuffer2;
2657     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
2658     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color2, 0);
2659 
2660     glClearColor(0, 0, 255, 255);
2661     glClear(GL_COLOR_BUFFER_BIT);
2662     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2663 
2664     constexpr char kComputeShaderSource[] =
2665         R"(#version 310 es
2666 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2667 layout(std430, binding = 0) buffer block {
2668     uint data[2];
2669 } outBlock;
2670 void main()
2671 {
2672     // Output red to index 0, and green to index 1.
2673     outBlock.data[0] = 0xFF0000FFu;
2674     outBlock.data[1] = 0xFF00FF00u;
2675 }
2676 )";
2677 
2678     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2679 
2680     glUseProgram(program);
2681 
2682     constexpr GLsizei kBufferSize                   = sizeof(GLuint) * 2;
2683     constexpr std::array<GLuint, 2> kBufferInitData = {0x01234567u, 0x89ABCDEFu};
2684 
2685     // Create a shader storage buffer
2686     GLBuffer buffer;
2687 
2688     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2689     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferInitData.data(), GL_STATIC_DRAW);
2690 
2691     // Bind shader storage buffer and write to it.
2692     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
2693 
2694     glDispatchCompute(1, 1, 1);
2695     EXPECT_GL_NO_ERROR();
2696 
2697     // Issue a memory barrier for pixel pack/unpack operations.
2698     glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
2699     EXPECT_GL_NO_ERROR();
2700 
2701     // Use a pixel pack operation to overwrite the output of the compute shader at index 0.  Uses
2702     // the second framebuffer which is blue.
2703     glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
2704     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2705     EXPECT_GL_NO_ERROR();
2706 
2707     // Use a pixel unpack operation to re-initialize the other framebuffer with the results from the
2708     // compute shader.
2709     glBindTexture(GL_TEXTURE_2D, color1);
2710     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
2711     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2712                     reinterpret_cast<void *>(sizeof(GLuint)));
2713     EXPECT_GL_NO_ERROR();
2714 
2715     // Verify that the first framebuffer is now green
2716     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2717     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer1);
2718     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2719 
2720     // Verify the contents of the buffer.  It should have blue as the first index and green as the
2721     // second.
2722     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2723     GLColor *bufferContents = static_cast<GLColor *>(
2724         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
2725     EXPECT_GL_NO_ERROR();
2726 
2727     EXPECT_EQ(GLColor::blue, bufferContents[0]);
2728     EXPECT_EQ(GLColor::green, bufferContents[1]);
2729     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2730     EXPECT_GL_NO_ERROR();
2731 }
2732 
2733 // Tests that shader write after pixel pack/unpack works
TEST_P(ShaderStorageBufferTest31,PixelPackUnpackThenShaderStorageBufferWrite)2734 TEST_P(ShaderStorageBufferTest31, PixelPackUnpackThenShaderStorageBufferWrite)
2735 {
2736     swapBuffers();
2737     // Create two textures and framebuffers and make sure they are initialized.
2738     GLTexture color1;
2739     glBindTexture(GL_TEXTURE_2D, color1);
2740     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2741 
2742     GLFramebuffer framebuffer1;
2743     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2744     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color1, 0);
2745 
2746     glClearColor(255, 0, 255, 255);
2747     glClear(GL_COLOR_BUFFER_BIT);
2748     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
2749 
2750     GLTexture color2;
2751     glBindTexture(GL_TEXTURE_2D, color2);
2752     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2753 
2754     GLFramebuffer framebuffer2;
2755     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
2756     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color2, 0);
2757 
2758     glClearColor(0, 0, 255, 255);
2759     glClear(GL_COLOR_BUFFER_BIT);
2760     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2761 
2762     constexpr GLsizei kBufferSize                   = sizeof(GLuint) * 2;
2763     constexpr std::array<GLuint, 2> kBufferInitData = {0x01234567u, 0xFF00FF00u};
2764 
2765     // Create a shader storage buffer
2766     GLBuffer buffer;
2767 
2768     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2769     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, kBufferInitData.data(), GL_STATIC_DRAW);
2770 
2771     // Use a pixel pack operation to overwrite the buffer at index 0.  Uses the second framebuffer
2772     // which is blue.
2773     glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
2774     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2775     EXPECT_GL_NO_ERROR();
2776 
2777     // Use a pixel unpack operation to re-initialize the other framebuffer with the contents of the
2778     // buffer, which is green.
2779     glBindTexture(GL_TEXTURE_2D, color1);
2780     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
2781     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2782                     reinterpret_cast<void *>(sizeof(GLuint)));
2783     EXPECT_GL_NO_ERROR();
2784 
2785     // Issue a memory barrier for pixel pack/unpack operations.
2786     glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
2787 
2788     // Issue a dispatch call that overwrites the buffer, also verifying that the results of the pack
2789     // operation is correct.
2790     constexpr char kComputeShaderSource[] =
2791         R"(#version 310 es
2792 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
2793 layout(std430, binding = 0) buffer block {
2794     uint data[2];
2795 } outBlock;
2796 void main()
2797 {
2798     if (outBlock.data[0] == 0xFFFF0000u)
2799     {
2800         outBlock.data[0] = 0x11223344u;
2801     }
2802     else
2803     {
2804         outBlock.data[0] = 0xABCDABCDu;
2805     }
2806     outBlock.data[1] = 0x55667788u;
2807 }
2808 )";
2809 
2810     ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
2811 
2812     glUseProgram(program);
2813 
2814     // Bind shader storage buffer and write to it.
2815     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
2816 
2817     glDispatchCompute(1, 1, 1);
2818     EXPECT_GL_NO_ERROR();
2819 
2820     // Verify that the first framebuffer is now green
2821     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2822     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer1);
2823     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2824 
2825     // Verify that the second framebuffer is still blue
2826     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2827     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer2);
2828     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2829 
2830     // Verify the contents of the buffer.
2831     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2832     uint32_t *bufferContents = static_cast<uint32_t *>(
2833         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
2834     EXPECT_GL_NO_ERROR();
2835 
2836     EXPECT_EQ(bufferContents[0], 0x11223344u);
2837     EXPECT_EQ(bufferContents[1], 0x55667788u);
2838     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2839     EXPECT_GL_NO_ERROR();
2840 }
2841 
2842 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShaderStorageBufferTest31);
2843 ANGLE_INSTANTIATE_TEST_ES31(ShaderStorageBufferTest31);
2844 
2845 }  // namespace
2846