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