1 //
2 // Copyright 2021 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 // MemoryBarrierTest:
7 // Ensure that implementation of glMemoryBarrier is correct both in terms of memory barriers
8 // issued and potential reordering of commands.
9 //
10 // The barrier bits accepted by glMemoryBarrier are used for synchronization as such:
11 //
12 // VERTEX_ATTRIB_ARRAY_BARRIER_BIT: shader write -> vertex read
13 // ELEMENT_ARRAY_BARRIER_BIT: shader write -> index read
14 // UNIFORM_BARRIER_BIT: shader write -> uniform read
15 // TEXTURE_FETCH_BARRIER_BIT: shader write -> texture sample
16 // SHADER_IMAGE_ACCESS_BARRIER_BIT: shader write -> image access
17 // any access -> image write
18 // COMMAND_BARRIER_BIT: shader write -> indirect buffer read
19 // PIXEL_BUFFER_BARRIER_BIT: shader write -> pbo access
20 // TEXTURE_UPDATE_BARRIER_BIT: shader write -> texture data upload
21 // BUFFER_UPDATE_BARRIER_BIT: shader write -> buffer data upload/map
22 // FRAMEBUFFER_BARRIER_BIT: shader write -> access through framebuffer
23 // TRANSFORM_FEEDBACK_BARRIER_BIT: shader write -> transform feedback write
24 // ATOMIC_COUNTER_BARRIER_BIT: shader write -> atomic counter access
25 // SHADER_STORAGE_BARRIER_BIT: shader write -> buffer access
26 // any access -> buffer write
27 //
28 // In summary, every bit defines a memory barrier for some access after a shader write.
29 // Additionally, SHADER_IMAGE_ACCESS_BARRIER_BIT and SHADER_STORAGE_BARRIER_BIT bits are used to
30 // define a memory barrier for shader writes after other accesses.
31
32 #include "test_utils/ANGLETest.h"
33 #include "test_utils/gl_raii.h"
34 #include "util/random_utils.h"
35
36 using namespace angle;
37
38 namespace
39 {
40 enum class ShaderWritePipeline
41 {
42 Graphics,
43 Compute,
44 };
45
46 enum class WriteResource
47 {
48 Image,
49 ImageBuffer,
50 Buffer,
51 };
52
53 enum class NoopOp
54 {
55 None,
56 Draw,
57 Dispatch,
58 };
59
60 // Variations corresponding to enums above.
61 using MemoryBarrierVariationsTestParams =
62 std::tuple<angle::PlatformParameters, ShaderWritePipeline, WriteResource, NoopOp, NoopOp>;
63
ParseMemoryBarrierVariationsTestParams(const MemoryBarrierVariationsTestParams & params,ShaderWritePipeline * writePipelineOut,WriteResource * writeResourceOut,NoopOp * preBarrierOpOut,NoopOp * postBarrierOpOut)64 void ParseMemoryBarrierVariationsTestParams(const MemoryBarrierVariationsTestParams ¶ms,
65 ShaderWritePipeline *writePipelineOut,
66 WriteResource *writeResourceOut,
67 NoopOp *preBarrierOpOut,
68 NoopOp *postBarrierOpOut)
69 {
70 *writePipelineOut = std::get<1>(params);
71 *writeResourceOut = std::get<2>(params);
72 *preBarrierOpOut = std::get<3>(params);
73 *postBarrierOpOut = std::get<4>(params);
74 }
75
MemoryBarrierVariationsTestPrint(const::testing::TestParamInfo<MemoryBarrierVariationsTestParams> & paramsInfo)76 std::string MemoryBarrierVariationsTestPrint(
77 const ::testing::TestParamInfo<MemoryBarrierVariationsTestParams> ¶msInfo)
78 {
79 const MemoryBarrierVariationsTestParams ¶ms = paramsInfo.param;
80 std::ostringstream out;
81
82 out << std::get<0>(params);
83
84 ShaderWritePipeline writePipeline;
85 WriteResource writeResource;
86 NoopOp preBarrierOp;
87 NoopOp postBarrierOp;
88
89 ParseMemoryBarrierVariationsTestParams(params, &writePipeline, &writeResource, &preBarrierOp,
90 &postBarrierOp);
91
92 out << "_";
93
94 if (writePipeline == ShaderWritePipeline::Graphics)
95 {
96 out << "_graphics";
97 }
98 else
99 {
100 out << "_compute";
101 }
102
103 switch (writeResource)
104 {
105 case WriteResource::Image:
106 out << "_image";
107 break;
108 case WriteResource::Buffer:
109 out << "_buffer";
110 break;
111 case WriteResource::ImageBuffer:
112 out << "_imagebuffer";
113 break;
114 }
115
116 if (preBarrierOp == NoopOp::Draw)
117 {
118 out << "_prebarrierNoopDraw";
119 }
120 else if (preBarrierOp == NoopOp::Dispatch)
121 {
122 out << "_prebarrierNoopDispatch";
123 }
124
125 if (postBarrierOp == NoopOp::Draw)
126 {
127 out << "_postbarrierNoopDraw";
128 }
129 else if (postBarrierOp == NoopOp::Dispatch)
130 {
131 out << "_postbarrierNoopDispatch";
132 }
133
134 return out.str();
135 }
136
137 class MemoryBarrierTestBase
138 {
139 protected:
140 bool hasExtensions(WriteResource writeResource);
141
142 // Helper functions
143 void createFramebuffer(GLuint color, GLuint fbo, GLColor initialColor);
144 void createStorageBuffer(WriteResource writeResource,
145 GLuint buffer,
146 GLuint textureBuffer,
147 size_t size,
148 const void *initialData);
149 void createStorageImage(WriteResource writeResource,
150 GLuint bufferStorage,
151 GLuint texture,
152 const std::array<float, 4> &initialData);
153 void createProgram(ShaderWritePipeline writePipeline,
154 WriteResource writeResource,
155 GLProgram *programOut);
156 void createNoopGraphicsProgram(GLProgram *programOut);
157 void createNoopComputeProgram(GLProgram *programOut);
158 void createQuadVertexArray(GLuint positionBuffer);
159 void setupVertexArray(ShaderWritePipeline writePipeline, GLuint program);
160 void setUniformData(GLuint program, const std::array<float, 4> &data);
161 void noopOp(NoopOp op);
162
163 template <typename T>
164 void verifyBufferContents(const std::array<T, 4> &expected);
165
166 void verifyImageContents(GLuint texture, const std::array<float, 4> &expected);
167
168 template <typename T>
169 void verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,
170 const std::array<T, 4> &expected);
171
172 void verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,
173 WriteResource writeResource,
174 GLuint texture,
175 const std::array<float, 4> &expected);
176
177 // Barrier bits affecting only buffers and imageBuffers
178 void createVertexVerifyProgram(GLuint vertexBuffer, GLProgram *programOut);
179 void vertexAttribArrayBitBufferWriteThenVertexRead(ShaderWritePipeline writePipeline,
180 WriteResource writeResource,
181 NoopOp preBarrierOp,
182 NoopOp postBarrierOp);
183 void vertexAttribArrayBitVertexReadThenBufferWrite(ShaderWritePipeline writePipeline,
184 WriteResource writeResource,
185 NoopOp preBarrierOp,
186 NoopOp postBarrierOp,
187 GLbitfield barrierBit);
188
189 void createIndexVerifyProgram(GLuint indexBuffer, GLProgram *programOut);
190 void elementArrayBitBufferWriteThenIndexRead(ShaderWritePipeline writePipeline,
191 WriteResource writeResource,
192 NoopOp preBarrierOp,
193 NoopOp postBarrierOp);
194 void elementArrayBitIndexReadThenBufferWrite(ShaderWritePipeline writePipeline,
195 WriteResource writeResource,
196 NoopOp preBarrierOp,
197 NoopOp postBarrierOp,
198 GLbitfield barrierBit);
199
200 void createUBOVerifyProgram(GLuint buffer, GLProgram *programOut);
201 void uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,
202 WriteResource writeResource,
203 NoopOp preBarrierOp,
204 NoopOp postBarrierOp);
205 void uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,
206 WriteResource writeResource,
207 NoopOp preBarrierOp,
208 NoopOp postBarrierOp,
209 GLbitfield barrierBit);
210
211 void createIndirectVerifyProgram(GLuint buffer, GLProgram *programOut);
212 void commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,
213 WriteResource writeResource,
214 NoopOp preBarrierOp,
215 NoopOp postBarrierOp);
216 void commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,
217 WriteResource writeResource,
218 NoopOp preBarrierOp,
219 NoopOp postBarrierOp,
220 GLbitfield barrierBit);
221
222 void pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,
223 WriteResource writeResource,
224 NoopOp preBarrierOp,
225 NoopOp postBarrierOp);
226 void pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,
227 WriteResource writeResource,
228 NoopOp preBarrierOp,
229 NoopOp postBarrierOp);
230 void pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,
231 WriteResource writeResource,
232 NoopOp preBarrierOp,
233 NoopOp postBarrierOp,
234 GLbitfield barrierBit);
235 void pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,
236 WriteResource writeResource,
237 NoopOp preBarrierOp,
238 NoopOp postBarrierOp,
239 GLbitfield barrierBit);
240
241 void bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,
242 WriteResource writeResource,
243 NoopOp preBarrierOp,
244 NoopOp postBarrierOp);
245 void bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,
246 WriteResource writeResource,
247 NoopOp preBarrierOp,
248 NoopOp postBarrierOp,
249 GLbitfield barrierBit);
250
251 void createXfbVerifyProgram(GLuint buffer, GLProgram *programOut);
252 void transformFeedbackBitBufferWriteThenCapture(ShaderWritePipeline writePipeline,
253 WriteResource writeResource,
254 NoopOp preBarrierOp,
255 NoopOp postBarrierOp);
256 void transformFeedbackBitCaptureThenBufferWrite(ShaderWritePipeline writePipeline,
257 WriteResource writeResource,
258 NoopOp preBarrierOp,
259 NoopOp postBarrierOp,
260 GLbitfield barrierBit);
261
262 void createAtomicCounterVerifyProgram(GLuint buffer, GLProgram *programOut);
263 void atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,
264 WriteResource writeResource,
265 NoopOp preBarrierOp,
266 NoopOp postBarrierOp);
267 void atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,
268 WriteResource writeResource,
269 NoopOp preBarrierOp,
270 NoopOp postBarrierOp,
271 GLbitfield barrierBit);
272
273 void createSsboVerifyProgram(WriteResource writeResourcee, GLProgram *programOut);
274 void shaderStorageBitBufferWriteThenBufferRead(ShaderWritePipeline writePipeline,
275 WriteResource writeResource,
276 NoopOp preBarrierOp,
277 NoopOp postBarrierOp);
278 void shaderStorageBitBufferReadThenBufferWrite(ShaderWritePipeline writePipeline,
279 WriteResource writeResource,
280 NoopOp preBarrierOp,
281 NoopOp postBarrierOp,
282 GLbitfield barrierBit);
283
284 // Barrier bits affecting only images and imageBuffers
285 void createTextureVerifyProgram(WriteResource writeResource,
286 GLuint texture,
287 GLProgram *programOut);
288 void textureFetchBitImageWriteThenSamplerRead(ShaderWritePipeline writePipeline,
289 WriteResource writeResource,
290 NoopOp preBarrierOp,
291 NoopOp postBarrierOp);
292 void textureFetchBitSamplerReadThenImageWrite(ShaderWritePipeline writePipeline,
293 WriteResource writeResource,
294 NoopOp preBarrierOp,
295 NoopOp postBarrierOp,
296 GLbitfield barrierBit);
297
298 void createImageVerifyProgram(WriteResource writeResource,
299 GLuint texture,
300 GLProgram *programOut);
301 void shaderImageAccessBitImageWriteThenImageRead(ShaderWritePipeline writePipeline,
302 WriteResource writeResource,
303 NoopOp preBarrierOp,
304 NoopOp postBarrierOp);
305 void shaderImageAccessBitImageReadThenImageWrite(ShaderWritePipeline writePipeline,
306 WriteResource writeResource,
307 NoopOp preBarrierOp,
308 NoopOp postBarrierOp);
309
310 // Barrier bits affecting only images
311 void textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
312 WriteResource writeResource,
313 NoopOp preBarrierOp,
314 NoopOp postBarrierOp);
315 void textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
316 WriteResource writeResource,
317 NoopOp preBarrierOp,
318 NoopOp postBarrierOp,
319 GLbitfield barrierBit);
320
321 void framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,
322 WriteResource writeResource,
323 NoopOp preBarrierOp,
324 NoopOp postBarrierOp);
325 void framebufferBitImageWriteThenReadPixels(ShaderWritePipeline writePipeline,
326 WriteResource writeResource,
327 NoopOp preBarrierOp,
328 NoopOp postBarrierOp);
329 void framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
330 WriteResource writeResource,
331 NoopOp preBarrierOp,
332 NoopOp postBarrierOp);
333 void framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,
334 WriteResource writeResource,
335 NoopOp preBarrierOp,
336 NoopOp postBarrierOp);
337 void framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,
338 WriteResource writeResource,
339 NoopOp preBarrierOp,
340 NoopOp postBarrierOp,
341 GLbitfield barrierBit);
342 void framebufferBitReadPixelsThenImageWrite(ShaderWritePipeline writePipeline,
343 WriteResource writeResource,
344 NoopOp preBarrierOp,
345 NoopOp postBarrierOp,
346 GLbitfield barrierBit);
347 void framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
348 WriteResource writeResource,
349 NoopOp preBarrierOp,
350 NoopOp postBarrierOp,
351 GLbitfield barrierBit);
352 void framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,
353 WriteResource writeResource,
354 NoopOp preBarrierOp,
355 NoopOp postBarrierOp,
356 GLbitfield barrierBit);
357
358 static constexpr int kTextureSize = 1;
359 static constexpr char kUniformName[] = "uniformData";
360 };
361
362 // Can be removed with C++17
363 constexpr char MemoryBarrierTestBase::kUniformName[];
364
hasExtensions(WriteResource writeResource)365 bool MemoryBarrierTestBase::hasExtensions(WriteResource writeResource)
366 {
367 return writeResource != WriteResource::ImageBuffer ||
368 IsGLExtensionEnabled("GL_OES_texture_buffer");
369 }
370
createFramebuffer(GLuint color,GLuint fbo,GLColor initialColor)371 void MemoryBarrierTestBase::createFramebuffer(GLuint color, GLuint fbo, GLColor initialColor)
372 {
373 glBindTexture(GL_TEXTURE_2D, color);
374 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
375 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
376 &initialColor);
377 EXPECT_GL_NO_ERROR();
378
379 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
380 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
381 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
382 EXPECT_GL_NO_ERROR();
383
384 // Ensure all staged data is flushed.
385 EXPECT_PIXEL_COLOR_EQ(0, 0, initialColor);
386 }
387
createStorageBuffer(WriteResource writeResource,GLuint buffer,GLuint textureBuffer,size_t size,const void * initialData)388 void MemoryBarrierTestBase::createStorageBuffer(WriteResource writeResource,
389 GLuint buffer,
390 GLuint textureBuffer,
391 size_t size,
392 const void *initialData)
393 {
394 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
395 glBufferData(GL_SHADER_STORAGE_BUFFER, size, initialData, GL_STATIC_DRAW);
396 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
397 EXPECT_GL_NO_ERROR();
398
399 if (writeResource == WriteResource::ImageBuffer)
400 {
401 glBindTexture(GL_TEXTURE_BUFFER, textureBuffer);
402 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, buffer);
403 glBindImageTexture(0, textureBuffer, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
404 EXPECT_GL_NO_ERROR();
405 }
406 }
407
createStorageImage(WriteResource writeResource,GLuint bufferStorage,GLuint texture,const std::array<float,4> & initialData)408 void MemoryBarrierTestBase::createStorageImage(WriteResource writeResource,
409 GLuint bufferStorage,
410 GLuint texture,
411 const std::array<float, 4> &initialData)
412 {
413 const std::array<uint8_t, 4> initialDataAsUnorm = {
414 static_cast<uint8_t>(initialData[0] * 255),
415 static_cast<uint8_t>(initialData[1] * 255),
416 static_cast<uint8_t>(initialData[2] * 255),
417 static_cast<uint8_t>(initialData[3] * 255),
418 };
419
420 if (writeResource == WriteResource::ImageBuffer)
421 {
422 glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferStorage);
423 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(initialData), initialData.data(),
424 GL_STATIC_DRAW);
425 EXPECT_GL_NO_ERROR();
426
427 glBindTexture(GL_TEXTURE_BUFFER, texture);
428 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferStorage);
429 glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
430 EXPECT_GL_NO_ERROR();
431 }
432 else
433 {
434 glBindTexture(GL_TEXTURE_2D, texture);
435 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
436 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA,
437 GL_UNSIGNED_BYTE, initialDataAsUnorm.data());
438 glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
439 }
440 }
441
createProgram(ShaderWritePipeline writePipeline,WriteResource writeResource,GLProgram * programOut)442 void MemoryBarrierTestBase::createProgram(ShaderWritePipeline writePipeline,
443 WriteResource writeResource,
444 GLProgram *programOut)
445 {
446 constexpr char kGraphicsImageFS[] = R"(#version 310 es
447 precision mediump float;
448 layout(rgba8, binding = 0) uniform highp writeonly image2D dst;
449 uniform vec4 uniformData;
450 out vec4 colorOut;
451 void main()
452 {
453 colorOut = vec4(0, 0, 1.0, 1.0);
454 imageStore(dst, ivec2(gl_FragCoord.xy), uniformData);
455 })";
456
457 constexpr char kGraphicsBufferFS[] = R"(#version 310 es
458 precision mediump float;
459 uniform vec4 uniformData;
460 layout(std430, binding = 0) buffer block {
461 vec4 data;
462 } outBlock;
463 out vec4 colorOut;
464 void main()
465 {
466 colorOut = vec4(0, 0, 1.0, 1.0);
467 outBlock.data = uniformData;
468 }
469 )";
470
471 constexpr char kGraphicsImageBufferFS[] = R"(#version 310 es
472 #extension GL_OES_texture_buffer : require
473 precision mediump float;
474 layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
475 uniform vec4 uniformData;
476 out vec4 colorOut;
477 void main()
478 {
479 colorOut = vec4(0, 0, 1.0, 1.0);
480 imageStore(dst, int(gl_FragCoord.x), uniformData);
481 })";
482
483 constexpr char kComputeImage[] = R"(#version 310 es
484 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
485 layout(rgba8, binding = 0) uniform highp writeonly image2D dst;
486 uniform vec4 uniformData;
487 void main()
488 {
489 imageStore(dst, ivec2(gl_GlobalInvocationID.xy), uniformData);
490 })";
491
492 constexpr char kComputeBuffer[] = R"(#version 310 es
493 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
494 uniform vec4 uniformData;
495 layout(std430, binding = 0) buffer block {
496 vec4 data;
497 } outBlock;
498 void main()
499 {
500 outBlock.data = uniformData;
501 }
502 )";
503
504 constexpr char kComputeImageBuffer[] = R"(#version 310 es
505 #extension GL_OES_texture_buffer : require
506 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
507 layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
508 uniform vec4 uniformData;
509 void main()
510 {
511 imageStore(dst, int(gl_GlobalInvocationID.x), uniformData);
512 })";
513
514 if (writePipeline == ShaderWritePipeline::Graphics)
515 {
516 const char *fs = "";
517 switch (writeResource)
518 {
519 case WriteResource::Image:
520 fs = kGraphicsImageFS;
521 break;
522 case WriteResource::Buffer:
523 fs = kGraphicsBufferFS;
524 break;
525 case WriteResource::ImageBuffer:
526 fs = kGraphicsImageBufferFS;
527 break;
528 }
529
530 programOut->makeRaster(essl31_shaders::vs::Simple(), fs);
531 }
532 else
533 {
534 const char *cs = "";
535 switch (writeResource)
536 {
537 case WriteResource::Image:
538 cs = kComputeImage;
539 break;
540 case WriteResource::Buffer:
541 cs = kComputeBuffer;
542 break;
543 case WriteResource::ImageBuffer:
544 cs = kComputeImageBuffer;
545 break;
546 }
547
548 programOut->makeCompute(cs);
549 }
550
551 ASSERT_TRUE(programOut->valid());
552 glUseProgram(*programOut);
553 }
554
createNoopGraphicsProgram(GLProgram * programOut)555 void MemoryBarrierTestBase::createNoopGraphicsProgram(GLProgram *programOut)
556 {
557 programOut->makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
558 ASSERT_TRUE(programOut->valid());
559 }
560
createNoopComputeProgram(GLProgram * programOut)561 void MemoryBarrierTestBase::createNoopComputeProgram(GLProgram *programOut)
562 {
563 constexpr char kCS[] = R"(#version 310 es
564 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
565 void main()
566 {
567 })";
568
569 programOut->makeCompute(kCS);
570 ASSERT_TRUE(programOut->valid());
571 }
572
createQuadVertexArray(GLuint positionBuffer)573 void MemoryBarrierTestBase::createQuadVertexArray(GLuint positionBuffer)
574 {
575 const std::array<Vector3, 6> kQuadVertices = {{
576 Vector3(-1.0f, 1.0f, 0.5f),
577 Vector3(-1.0f, -1.0f, 0.5f),
578 Vector3(1.0f, -1.0f, 0.5f),
579 Vector3(-1.0f, 1.0f, 0.5f),
580 Vector3(1.0f, -1.0f, 0.5f),
581 Vector3(1.0f, 1.0f, 0.5f),
582 }};
583
584 const size_t bufferSize = kQuadVertices.size() * sizeof(Vector3);
585
586 glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
587 glBufferData(GL_ARRAY_BUFFER, bufferSize, kQuadVertices.data(), GL_STATIC_DRAW);
588 EXPECT_GL_NO_ERROR();
589 }
590
setupVertexArray(ShaderWritePipeline writePipeline,GLuint program)591 void MemoryBarrierTestBase::setupVertexArray(ShaderWritePipeline writePipeline, GLuint program)
592 {
593 if (writePipeline == ShaderWritePipeline::Compute)
594 {
595 return;
596 }
597
598 GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib());
599 ASSERT_NE(-1, positionLoc);
600
601 glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
602 glEnableVertexAttribArray(positionLoc);
603 EXPECT_GL_NO_ERROR();
604 }
605
setUniformData(GLuint program,const std::array<float,4> & data)606 void MemoryBarrierTestBase::setUniformData(GLuint program, const std::array<float, 4> &data)
607 {
608 GLint uniformLocation = glGetUniformLocation(program, kUniformName);
609 ASSERT_NE(uniformLocation, -1);
610
611 glUniform4f(uniformLocation, data[0], data[1], data[2], data[3]);
612 EXPECT_GL_NO_ERROR();
613 }
614
noopOp(NoopOp op)615 void MemoryBarrierTestBase::noopOp(NoopOp op)
616 {
617 if (op == NoopOp::None)
618 {
619 return;
620 }
621
622 GLProgram noopProgram;
623 if (op == NoopOp::Draw)
624 {
625 createNoopGraphicsProgram(&noopProgram);
626
627 glEnable(GL_BLEND);
628 glBlendFunc(GL_ZERO, GL_ONE);
629
630 glUseProgram(noopProgram);
631 glDrawArrays(GL_TRIANGLES, 0, 3);
632
633 glDisable(GL_BLEND);
634 }
635 else
636 {
637 createNoopComputeProgram(&noopProgram);
638 glUseProgram(noopProgram);
639 glDispatchCompute(1, 1, 1);
640 }
641
642 EXPECT_GL_NO_ERROR();
643 }
644
645 template <typename T>
verifyBufferContents(const std::array<T,4> & expected)646 void MemoryBarrierTestBase::verifyBufferContents(const std::array<T, 4> &expected)
647 {
648 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
649 T *bufferContents = static_cast<T *>(
650 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(expected), GL_MAP_READ_BIT));
651 EXPECT_GL_NO_ERROR();
652
653 EXPECT_EQ(bufferContents[0], expected[0]);
654 EXPECT_EQ(bufferContents[1], expected[1]);
655 EXPECT_EQ(bufferContents[2], expected[2]);
656 EXPECT_EQ(bufferContents[3], expected[3]);
657 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
658 }
659
verifyImageContents(GLuint texture,const std::array<float,4> & expected)660 void MemoryBarrierTestBase::verifyImageContents(GLuint texture,
661 const std::array<float, 4> &expected)
662 {
663 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
664 glBindTexture(GL_TEXTURE_2D, texture);
665 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
666 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
667 EXPECT_GL_NO_ERROR();
668
669 const GLColor kExpected(expected[0] * 255, expected[1] * 255, expected[2] * 255,
670 expected[3] * 255);
671 EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
672 }
673
674 template <typename T>
verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,const std::array<T,4> & expected)675 void MemoryBarrierTestBase::verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,
676 const std::array<T, 4> &expected)
677 {
678 // Verify the result of the verify shader
679 const GLColor kExpected =
680 writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
681 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);
682
683 // Verify the contents of the buffer
684 verifyBufferContents(expected);
685 }
686
verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,WriteResource writeResource,GLuint texture,const std::array<float,4> & expected)687 void MemoryBarrierTestBase::verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,
688 WriteResource writeResource,
689 GLuint texture,
690 const std::array<float, 4> &expected)
691 {
692 // Verify the result of the verify shader
693 const GLColor kExpected =
694 writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
695 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);
696
697 if (writeResource == WriteResource::ImageBuffer)
698 {
699 // Verify the contents of the buffer
700 verifyBufferContents(expected);
701 }
702 else
703 {
704 // Verify the contents of the image
705 verifyImageContents(texture, expected);
706 }
707 }
708
createVertexVerifyProgram(GLuint vertexBuffer,GLProgram * programOut)709 void MemoryBarrierTestBase::createVertexVerifyProgram(GLuint vertexBuffer, GLProgram *programOut)
710 {
711 constexpr char kVS[] = R"(#version 310 es
712 in float attribIn;
713 out float v;
714
715 void main()
716 {
717 v = attribIn;
718 // gl_VertexID x y
719 // 0 -1 -1
720 // 1 1 -1
721 // 2 -1 1
722 // 3 1 1
723 int bit0 = gl_VertexID & 1;
724 int bit1 = gl_VertexID >> 1;
725 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
726 })";
727
728 constexpr char kFS[] = R"(#version 310 es
729 precision mediump float;
730 in float v;
731 out vec4 colorOut;
732 void main()
733 {
734 if (v == 2.0)
735 colorOut = vec4(0, 1.0, 0, 1.0);
736 else
737 colorOut = vec4(1.0, 0, 0, 1.0);
738 })";
739
740 programOut->makeRaster(kVS, kFS);
741 ASSERT_TRUE(programOut->valid());
742 glUseProgram(*programOut);
743
744 GLint attribLoc = glGetAttribLocation(*programOut, "attribIn");
745 ASSERT_NE(-1, attribLoc);
746
747 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
748 glVertexAttribPointer(attribLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
749 glEnableVertexAttribArray(attribLoc);
750 EXPECT_GL_NO_ERROR();
751 }
752
vertexAttribArrayBitBufferWriteThenVertexRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)753 void MemoryBarrierTestBase::vertexAttribArrayBitBufferWriteThenVertexRead(
754 ShaderWritePipeline writePipeline,
755 WriteResource writeResource,
756 NoopOp preBarrierOp,
757 NoopOp postBarrierOp)
758 {
759 GLTexture color;
760 GLFramebuffer fbo;
761 GLProgram writeProgram;
762
763 createFramebuffer(color, fbo, GLColor::black);
764 createProgram(writePipeline, writeResource, &writeProgram);
765
766 GLBuffer positionBuffer;
767 createQuadVertexArray(positionBuffer);
768 setupVertexArray(writePipeline, writeProgram);
769
770 GLBuffer vertexBuffer;
771 GLTexture vertexTextureBuffer;
772 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
773 createStorageBuffer(writeResource, vertexBuffer, vertexTextureBuffer, sizeof(kInitData),
774 kInitData.data());
775
776 constexpr std::array<float, 4> kWriteData = {2.0, 2.0, 2.0, 2.0};
777 setUniformData(writeProgram, kWriteData);
778
779 // Fill the buffer
780 if (writePipeline == ShaderWritePipeline::Graphics)
781 {
782 glDrawArrays(GL_TRIANGLES, 0, 6);
783 }
784 else
785 {
786 glDispatchCompute(1, 1, 1);
787 }
788
789 noopOp(preBarrierOp);
790
791 // Issue the appropriate memory barrier
792 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
793
794 noopOp(postBarrierOp);
795
796 // Use the buffer
797 GLProgram readProgram;
798 createVertexVerifyProgram(vertexBuffer, &readProgram);
799
800 glEnable(GL_BLEND);
801 glBlendFunc(GL_ONE, GL_ONE);
802 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
803 EXPECT_GL_NO_ERROR();
804
805 // Verify the vertex data was read correctly
806 const GLColor kExpected =
807 writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
808 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);
809
810 // Verify the contents of the buffer
811 verifyBufferContents(kWriteData);
812 }
813
vertexAttribArrayBitVertexReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)814 void MemoryBarrierTestBase::vertexAttribArrayBitVertexReadThenBufferWrite(
815 ShaderWritePipeline writePipeline,
816 WriteResource writeResource,
817 NoopOp preBarrierOp,
818 NoopOp postBarrierOp,
819 GLbitfield barrierBit)
820 {
821 GLTexture color;
822 GLFramebuffer fbo;
823 GLProgram writeProgram;
824
825 createFramebuffer(color, fbo, GLColor::black);
826
827 GLBuffer vertexBuffer;
828 GLTexture vertexTextureBuffer;
829 constexpr std::array<float, 4> kInitData = {2.0, 2.0, 2.0, 2.0};
830 createStorageBuffer(writeResource, vertexBuffer, vertexTextureBuffer, sizeof(kInitData),
831 kInitData.data());
832
833 // Use the buffer
834 GLProgram readProgram;
835 createVertexVerifyProgram(vertexBuffer, &readProgram);
836
837 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
838 EXPECT_GL_NO_ERROR();
839
840 GLint attribLoc = glGetAttribLocation(readProgram, "attribIn");
841 glDisableVertexAttribArray(attribLoc);
842
843 noopOp(preBarrierOp);
844
845 // Issue the appropriate memory barrier
846 glMemoryBarrier(barrierBit);
847
848 noopOp(postBarrierOp);
849
850 // Fill the buffer
851 createProgram(writePipeline, writeResource, &writeProgram);
852
853 GLBuffer positionBuffer;
854 createQuadVertexArray(positionBuffer);
855 setupVertexArray(writePipeline, writeProgram);
856
857 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
858 setUniformData(writeProgram, kWriteData);
859
860 if (writePipeline == ShaderWritePipeline::Graphics)
861 {
862 glEnable(GL_BLEND);
863 glBlendFunc(GL_ONE, GL_ONE);
864 glDrawArrays(GL_TRIANGLES, 0, 6);
865 }
866 else
867 {
868 glDispatchCompute(1, 1, 1);
869 }
870
871 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
872 }
873
createIndexVerifyProgram(GLuint indexBuffer,GLProgram * programOut)874 void MemoryBarrierTestBase::createIndexVerifyProgram(GLuint indexBuffer, GLProgram *programOut)
875 {
876 constexpr char kVS[] = R"(#version 310 es
877 void main()
878 {
879 // gl_VertexID x y
880 // 0 -1 -1
881 // 1 1 -1
882 // 2 -1 1
883 // 3 1 1
884 int bit0 = gl_VertexID & 1;
885 int bit1 = gl_VertexID >> 1;
886 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
887 })";
888
889 constexpr char kFS[] = R"(#version 310 es
890 precision mediump float;
891 out vec4 colorOut;
892 void main()
893 {
894 colorOut = vec4(0, 1.0, 0, 1.0);
895 })";
896
897 programOut->makeRaster(kVS, kFS);
898 ASSERT_TRUE(programOut->valid());
899 glUseProgram(*programOut);
900
901 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
902 EXPECT_GL_NO_ERROR();
903 }
904
elementArrayBitBufferWriteThenIndexRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)905 void MemoryBarrierTestBase::elementArrayBitBufferWriteThenIndexRead(
906 ShaderWritePipeline writePipeline,
907 WriteResource writeResource,
908 NoopOp preBarrierOp,
909 NoopOp postBarrierOp)
910 {
911 GLTexture color;
912 GLFramebuffer fbo;
913 GLProgram writeProgram;
914
915 createFramebuffer(color, fbo, GLColor::black);
916 createProgram(writePipeline, writeResource, &writeProgram);
917
918 GLBuffer positionBuffer;
919 createQuadVertexArray(positionBuffer);
920 setupVertexArray(writePipeline, writeProgram);
921
922 GLBuffer indexBuffer;
923 GLTexture indexTextureBuffer;
924 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
925 createStorageBuffer(writeResource, indexBuffer, indexTextureBuffer, sizeof(kInitData),
926 kInitData.data());
927
928 constexpr std::array<uint32_t, 4> kWriteData = {0, 1, 2, 3};
929 const std::array<float, 4> kWriteDataAsFloat = {
930 *reinterpret_cast<const float *>(&kWriteData[0]),
931 *reinterpret_cast<const float *>(&kWriteData[1]),
932 *reinterpret_cast<const float *>(&kWriteData[2]),
933 *reinterpret_cast<const float *>(&kWriteData[3]),
934 };
935 setUniformData(writeProgram, kWriteDataAsFloat);
936
937 // Fill the buffer
938 if (writePipeline == ShaderWritePipeline::Graphics)
939 {
940 glDrawArrays(GL_TRIANGLES, 0, 6);
941 }
942 else
943 {
944 glDispatchCompute(1, 1, 1);
945 }
946
947 noopOp(preBarrierOp);
948
949 // Issue the appropriate memory barrier
950 glMemoryBarrier(GL_ELEMENT_ARRAY_BARRIER_BIT);
951
952 noopOp(postBarrierOp);
953
954 // Use the buffer
955 GLProgram readProgram;
956 createIndexVerifyProgram(indexBuffer, &readProgram);
957
958 glEnable(GL_BLEND);
959 glBlendFunc(GL_ONE, GL_ONE);
960 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
961 EXPECT_GL_NO_ERROR();
962
963 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
964 }
965
elementArrayBitIndexReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)966 void MemoryBarrierTestBase::elementArrayBitIndexReadThenBufferWrite(
967 ShaderWritePipeline writePipeline,
968 WriteResource writeResource,
969 NoopOp preBarrierOp,
970 NoopOp postBarrierOp,
971 GLbitfield barrierBit)
972 {
973 GLTexture color;
974 GLFramebuffer fbo;
975 GLProgram writeProgram;
976
977 createFramebuffer(color, fbo, GLColor::black);
978
979 GLBuffer indexBuffer;
980 GLTexture indexTextureBuffer;
981 constexpr std::array<uint32_t, 4> kInitData = {0, 1, 2, 3};
982 createStorageBuffer(writeResource, indexBuffer, indexTextureBuffer, sizeof(kInitData),
983 kInitData.data());
984
985 // Use the buffer
986 GLProgram readProgram;
987 createIndexVerifyProgram(indexBuffer, &readProgram);
988
989 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
990 EXPECT_GL_NO_ERROR();
991
992 noopOp(preBarrierOp);
993
994 // Issue the appropriate memory barrier
995 glMemoryBarrier(barrierBit);
996
997 noopOp(postBarrierOp);
998
999 // Fill the buffer
1000 createProgram(writePipeline, writeResource, &writeProgram);
1001
1002 GLBuffer positionBuffer;
1003 createQuadVertexArray(positionBuffer);
1004 setupVertexArray(writePipeline, writeProgram);
1005
1006 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1007 setUniformData(writeProgram, kWriteData);
1008
1009 if (writePipeline == ShaderWritePipeline::Graphics)
1010 {
1011 glEnable(GL_BLEND);
1012 glBlendFunc(GL_ONE, GL_ONE);
1013 glDrawArrays(GL_TRIANGLES, 0, 6);
1014 }
1015 else
1016 {
1017 glDispatchCompute(1, 1, 1);
1018 }
1019
1020 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1021 }
1022
createUBOVerifyProgram(GLuint buffer,GLProgram * programOut)1023 void MemoryBarrierTestBase::createUBOVerifyProgram(GLuint buffer, GLProgram *programOut)
1024 {
1025 constexpr char kVS[] = R"(#version 310 es
1026 void main()
1027 {
1028 // gl_VertexID x y
1029 // 0 -1 -1
1030 // 1 1 -1
1031 // 2 -1 1
1032 // 3 1 1
1033 int bit0 = gl_VertexID & 1;
1034 int bit1 = gl_VertexID >> 1;
1035 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1036 })";
1037
1038 constexpr char kFS[] = R"(#version 310 es
1039 precision mediump float;
1040 layout(binding = 0) uniform block {
1041 vec4 data;
1042 } ubo;
1043 out vec4 colorOut;
1044 void main()
1045 {
1046 if (ubo.data == vec4(1.5, 3.75, 5.0, 12.125))
1047 colorOut = vec4(0, 1.0, 0, 1.0);
1048 else
1049 colorOut = vec4(1.0, 0, 0, 1.0);
1050 })";
1051
1052 programOut->makeRaster(kVS, kFS);
1053 ASSERT_TRUE(programOut->valid());
1054 glUseProgram(*programOut);
1055
1056 glBindBuffer(GL_UNIFORM_BUFFER, buffer);
1057 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
1058 EXPECT_GL_NO_ERROR();
1059 }
1060
uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1061 void MemoryBarrierTestBase::uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,
1062 WriteResource writeResource,
1063 NoopOp preBarrierOp,
1064 NoopOp postBarrierOp)
1065 {
1066 GLTexture color;
1067 GLFramebuffer fbo;
1068 GLProgram writeProgram;
1069
1070 createFramebuffer(color, fbo, GLColor::black);
1071 createProgram(writePipeline, writeResource, &writeProgram);
1072
1073 GLBuffer positionBuffer;
1074 createQuadVertexArray(positionBuffer);
1075 setupVertexArray(writePipeline, writeProgram);
1076
1077 GLBuffer uniformBuffer;
1078 GLTexture uniformTextureBuffer;
1079 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1080 createStorageBuffer(writeResource, uniformBuffer, uniformTextureBuffer, sizeof(kInitData),
1081 kInitData.data());
1082
1083 constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1084 setUniformData(writeProgram, kWriteData);
1085
1086 // Fill the buffer
1087 if (writePipeline == ShaderWritePipeline::Graphics)
1088 {
1089 glDrawArrays(GL_TRIANGLES, 0, 6);
1090 }
1091 else
1092 {
1093 glDispatchCompute(1, 1, 1);
1094 }
1095
1096 noopOp(preBarrierOp);
1097
1098 // Issue the appropriate memory barrier
1099 glMemoryBarrier(GL_UNIFORM_BARRIER_BIT);
1100
1101 noopOp(postBarrierOp);
1102
1103 // Use the buffer
1104 GLProgram readProgram;
1105 createUBOVerifyProgram(uniformBuffer, &readProgram);
1106
1107 glEnable(GL_BLEND);
1108 glBlendFunc(GL_ONE, GL_ONE);
1109 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1110 EXPECT_GL_NO_ERROR();
1111
1112 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1113 }
1114
uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1115 void MemoryBarrierTestBase::uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,
1116 WriteResource writeResource,
1117 NoopOp preBarrierOp,
1118 NoopOp postBarrierOp,
1119 GLbitfield barrierBit)
1120 {
1121 GLTexture color;
1122 GLFramebuffer fbo;
1123 GLProgram writeProgram;
1124
1125 createFramebuffer(color, fbo, GLColor::black);
1126
1127 GLBuffer uniformBuffer;
1128 GLTexture uniformTextureBuffer;
1129 constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1130 createStorageBuffer(writeResource, uniformBuffer, uniformTextureBuffer, sizeof(kInitData),
1131 kInitData.data());
1132
1133 // Use the buffer
1134 GLProgram readProgram;
1135 createUBOVerifyProgram(uniformBuffer, &readProgram);
1136
1137 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1138 EXPECT_GL_NO_ERROR();
1139
1140 noopOp(preBarrierOp);
1141
1142 // Issue the appropriate memory barrier
1143 glMemoryBarrier(barrierBit);
1144
1145 noopOp(postBarrierOp);
1146
1147 // Fill the buffer
1148 createProgram(writePipeline, writeResource, &writeProgram);
1149
1150 GLBuffer positionBuffer;
1151 createQuadVertexArray(positionBuffer);
1152 setupVertexArray(writePipeline, writeProgram);
1153
1154 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1155 setUniformData(writeProgram, kWriteData);
1156
1157 if (writePipeline == ShaderWritePipeline::Graphics)
1158 {
1159 glEnable(GL_BLEND);
1160 glBlendFunc(GL_ONE, GL_ONE);
1161 glDrawArrays(GL_TRIANGLES, 0, 6);
1162 }
1163 else
1164 {
1165 glDispatchCompute(1, 1, 1);
1166 }
1167
1168 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1169 }
1170
createIndirectVerifyProgram(GLuint buffer,GLProgram * programOut)1171 void MemoryBarrierTestBase::createIndirectVerifyProgram(GLuint buffer, GLProgram *programOut)
1172 {
1173 constexpr char kVS[] = R"(#version 310 es
1174 void main()
1175 {
1176 // gl_VertexID x y
1177 // 0 -1 -1
1178 // 1 1 -1
1179 // 2 -1 1
1180 // 3 1 1
1181 int bit0 = gl_VertexID & 1;
1182 int bit1 = gl_VertexID >> 1;
1183 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1184 })";
1185
1186 constexpr char kFS[] = R"(#version 310 es
1187 precision mediump float;
1188 out vec4 colorOut;
1189 void main()
1190 {
1191 colorOut = vec4(0, 1.0, 0, 1.0);
1192 })";
1193
1194 programOut->makeRaster(kVS, kFS);
1195 ASSERT_TRUE(programOut->valid());
1196 glUseProgram(*programOut);
1197
1198 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
1199 EXPECT_GL_NO_ERROR();
1200 }
1201
commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1202 void MemoryBarrierTestBase::commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,
1203 WriteResource writeResource,
1204 NoopOp preBarrierOp,
1205 NoopOp postBarrierOp)
1206 {
1207 GLTexture color;
1208 GLFramebuffer fbo;
1209 GLProgram writeProgram;
1210
1211 createFramebuffer(color, fbo, GLColor::black);
1212 createProgram(writePipeline, writeResource, &writeProgram);
1213
1214 GLBuffer positionBuffer;
1215 createQuadVertexArray(positionBuffer);
1216 setupVertexArray(writePipeline, writeProgram);
1217
1218 GLBuffer indirectBuffer;
1219 GLTexture indirectTextureBuffer;
1220 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1221 createStorageBuffer(writeResource, indirectBuffer, indirectTextureBuffer, sizeof(kInitData),
1222 kInitData.data());
1223
1224 constexpr std::array<uint32_t, 4> kWriteData = {4, 1, 0, 0};
1225 const std::array<float, 4> kWriteDataAsFloat = {
1226 *reinterpret_cast<const float *>(&kWriteData[0]),
1227 *reinterpret_cast<const float *>(&kWriteData[1]),
1228 *reinterpret_cast<const float *>(&kWriteData[2]),
1229 *reinterpret_cast<const float *>(&kWriteData[3]),
1230 };
1231 setUniformData(writeProgram, kWriteDataAsFloat);
1232
1233 // Fill the buffer
1234 if (writePipeline == ShaderWritePipeline::Graphics)
1235 {
1236 glDrawArrays(GL_TRIANGLES, 0, 6);
1237 }
1238 else
1239 {
1240 glDispatchCompute(1, 1, 1);
1241 }
1242
1243 noopOp(preBarrierOp);
1244
1245 // Issue the appropriate memory barrier
1246 glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
1247
1248 noopOp(postBarrierOp);
1249
1250 // Use the buffer
1251 GLProgram readProgram;
1252 createIndirectVerifyProgram(indirectBuffer, &readProgram);
1253
1254 GLVertexArray vao;
1255 glBindVertexArray(vao);
1256
1257 glEnable(GL_BLEND);
1258 glBlendFunc(GL_ONE, GL_ONE);
1259 glDrawArraysIndirect(GL_TRIANGLE_STRIP, nullptr);
1260 EXPECT_GL_NO_ERROR();
1261
1262 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1263 }
1264
commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1265 void MemoryBarrierTestBase::commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,
1266 WriteResource writeResource,
1267 NoopOp preBarrierOp,
1268 NoopOp postBarrierOp,
1269 GLbitfield barrierBit)
1270 {
1271 GLTexture color;
1272 GLFramebuffer fbo;
1273 GLProgram writeProgram;
1274
1275 createFramebuffer(color, fbo, GLColor::black);
1276
1277 GLBuffer indirectBuffer;
1278 GLTexture indirectTextureBuffer;
1279 constexpr std::array<uint32_t, 4> kInitData = {4, 1, 0, 0};
1280 createStorageBuffer(writeResource, indirectBuffer, indirectTextureBuffer, sizeof(kInitData),
1281 kInitData.data());
1282
1283 // Use the buffer
1284 GLProgram readProgram;
1285 createIndirectVerifyProgram(indirectBuffer, &readProgram);
1286
1287 GLVertexArray vao;
1288 glBindVertexArray(vao);
1289
1290 glDrawArraysIndirect(GL_TRIANGLE_STRIP, nullptr);
1291 EXPECT_GL_NO_ERROR();
1292
1293 glBindVertexArray(0);
1294
1295 noopOp(preBarrierOp);
1296
1297 // Issue the appropriate memory barrier
1298 glMemoryBarrier(barrierBit);
1299
1300 noopOp(postBarrierOp);
1301
1302 // Fill the buffer
1303 createProgram(writePipeline, writeResource, &writeProgram);
1304
1305 GLBuffer positionBuffer;
1306 createQuadVertexArray(positionBuffer);
1307 setupVertexArray(writePipeline, writeProgram);
1308
1309 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1310 setUniformData(writeProgram, kWriteData);
1311
1312 if (writePipeline == ShaderWritePipeline::Graphics)
1313 {
1314 glEnable(GL_BLEND);
1315 glBlendFunc(GL_ONE, GL_ONE);
1316 glDrawArrays(GL_TRIANGLES, 0, 6);
1317 }
1318 else
1319 {
1320 glDispatchCompute(1, 1, 1);
1321 }
1322
1323 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1324 }
1325
pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1326 void MemoryBarrierTestBase::pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,
1327 WriteResource writeResource,
1328 NoopOp preBarrierOp,
1329 NoopOp postBarrierOp)
1330 {
1331 GLTexture color;
1332 GLFramebuffer fbo;
1333 GLProgram writeProgram;
1334
1335 createFramebuffer(color, fbo, GLColor::green);
1336 createProgram(writePipeline, writeResource, &writeProgram);
1337
1338 GLBuffer positionBuffer;
1339 createQuadVertexArray(positionBuffer);
1340 setupVertexArray(writePipeline, writeProgram);
1341
1342 GLBuffer packBuffer;
1343 GLTexture packTextureBuffer;
1344 constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1345 createStorageBuffer(writeResource, packBuffer, packTextureBuffer, sizeof(kInitData),
1346 kInitData.data());
1347
1348 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1349 setUniformData(writeProgram, kWriteData);
1350
1351 // Fill the buffer
1352 if (writePipeline == ShaderWritePipeline::Graphics)
1353 {
1354 glEnable(GL_BLEND);
1355 glBlendFunc(GL_ONE, GL_ONE);
1356 glDrawArrays(GL_TRIANGLES, 0, 6);
1357 glDisable(GL_BLEND);
1358 }
1359 else
1360 {
1361 glDispatchCompute(1, 1, 1);
1362 }
1363
1364 noopOp(preBarrierOp);
1365
1366 // Issue the appropriate memory barrier
1367 glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
1368
1369 noopOp(postBarrierOp);
1370
1371 // Use the buffer
1372 glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
1373 glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1374 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1375
1376 const std::array<uint32_t, 4> kExpectedData = {
1377 writePipeline == ShaderWritePipeline::Graphics ? 0xFFFFFF00u : 0xFF00FF00u,
1378 *reinterpret_cast<const uint32_t *>(&kWriteData[1]),
1379 *reinterpret_cast<const uint32_t *>(&kWriteData[2]),
1380 *reinterpret_cast<const uint32_t *>(&kWriteData[3]),
1381 };
1382 verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1383 }
1384
pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1385 void MemoryBarrierTestBase::pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,
1386 WriteResource writeResource,
1387 NoopOp preBarrierOp,
1388 NoopOp postBarrierOp)
1389 {
1390 GLTexture color;
1391 GLFramebuffer fbo;
1392 GLProgram writeProgram;
1393
1394 createFramebuffer(color, fbo, GLColor::black);
1395 createProgram(writePipeline, writeResource, &writeProgram);
1396
1397 GLBuffer positionBuffer;
1398 createQuadVertexArray(positionBuffer);
1399 setupVertexArray(writePipeline, writeProgram);
1400
1401 GLBuffer unpackBuffer;
1402 GLTexture unpackTextureBuffer;
1403 constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1404 createStorageBuffer(writeResource, unpackBuffer, unpackTextureBuffer, sizeof(kInitData),
1405 kInitData.data());
1406
1407 const std::array<float, 4> kWriteData = {*reinterpret_cast<const float *>(&GLColor::green), 5.6,
1408 78.91, 123.456};
1409 setUniformData(writeProgram, kWriteData);
1410
1411 // Fill the buffer
1412 if (writePipeline == ShaderWritePipeline::Graphics)
1413 {
1414 glEnable(GL_BLEND);
1415 glBlendFunc(GL_ONE, GL_ONE);
1416 glDrawArrays(GL_TRIANGLES, 0, 6);
1417 glDisable(GL_BLEND);
1418 }
1419 else
1420 {
1421 glDispatchCompute(1, 1, 1);
1422 }
1423
1424 noopOp(preBarrierOp);
1425
1426 // Issue the appropriate memory barrier
1427 glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
1428
1429 noopOp(postBarrierOp);
1430
1431 // Use the buffer
1432 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
1433 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
1434 0);
1435 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1436
1437 // Verify the result of the unpack operation
1438 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1439
1440 // Verify the contents of the buffer
1441 verifyBufferContents(kWriteData);
1442 }
1443
pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1444 void MemoryBarrierTestBase::pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,
1445 WriteResource writeResource,
1446 NoopOp preBarrierOp,
1447 NoopOp postBarrierOp,
1448 GLbitfield barrierBit)
1449 {
1450 GLTexture color;
1451 GLFramebuffer fbo;
1452 GLProgram writeProgram;
1453
1454 createFramebuffer(color, fbo, GLColor::green);
1455
1456 GLBuffer packBuffer;
1457 GLTexture packTextureBuffer;
1458 constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1459 createStorageBuffer(writeResource, packBuffer, packTextureBuffer, sizeof(kInitData),
1460 kInitData.data());
1461
1462 // Use the buffer
1463 glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
1464 glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1465 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1466
1467 noopOp(preBarrierOp);
1468
1469 // Issue the appropriate memory barrier
1470 glMemoryBarrier(barrierBit);
1471
1472 noopOp(postBarrierOp);
1473
1474 // Fill the buffer
1475 createProgram(writePipeline, writeResource, &writeProgram);
1476
1477 GLBuffer positionBuffer;
1478 createQuadVertexArray(positionBuffer);
1479 setupVertexArray(writePipeline, writeProgram);
1480
1481 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1482 setUniformData(writeProgram, kWriteData);
1483
1484 if (writePipeline == ShaderWritePipeline::Graphics)
1485 {
1486 glEnable(GL_BLEND);
1487 glBlendFunc(GL_ONE, GL_ONE);
1488 glDrawArrays(GL_TRIANGLES, 0, 6);
1489 }
1490 else
1491 {
1492 glDispatchCompute(1, 1, 1);
1493 }
1494
1495 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1496 }
1497
pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1498 void MemoryBarrierTestBase::pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,
1499 WriteResource writeResource,
1500 NoopOp preBarrierOp,
1501 NoopOp postBarrierOp,
1502 GLbitfield barrierBit)
1503 {
1504 GLTexture color;
1505 GLFramebuffer fbo;
1506 GLProgram writeProgram;
1507
1508 createFramebuffer(color, fbo, GLColor::black);
1509
1510 GLBuffer unpackBuffer;
1511 GLTexture unpackTextureBuffer;
1512 const std::array<float, 4> kInitData = {*reinterpret_cast<const float *>(&GLColor::green), 3.75,
1513 5.0, 12.125};
1514 createStorageBuffer(writeResource, unpackBuffer, unpackTextureBuffer, sizeof(kInitData),
1515 kInitData.data());
1516
1517 // Use the buffer
1518 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
1519 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
1520 0);
1521 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1522
1523 noopOp(preBarrierOp);
1524
1525 // Issue the appropriate memory barrier
1526 glMemoryBarrier(barrierBit);
1527
1528 noopOp(postBarrierOp);
1529
1530 // Fill the buffer
1531 createProgram(writePipeline, writeResource, &writeProgram);
1532
1533 GLBuffer positionBuffer;
1534 createQuadVertexArray(positionBuffer);
1535 setupVertexArray(writePipeline, writeProgram);
1536
1537 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1538 setUniformData(writeProgram, kWriteData);
1539
1540 if (writePipeline == ShaderWritePipeline::Graphics)
1541 {
1542 glEnable(GL_BLEND);
1543 glBlendFunc(GL_ONE, GL_ONE);
1544 glDrawArrays(GL_TRIANGLES, 0, 6);
1545 }
1546 else
1547 {
1548 glDispatchCompute(1, 1, 1);
1549 }
1550
1551 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1552 }
1553
bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1554 void MemoryBarrierTestBase::bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,
1555 WriteResource writeResource,
1556 NoopOp preBarrierOp,
1557 NoopOp postBarrierOp)
1558 {
1559 GLBuffer srcBuffer;
1560 GLTexture srcTextureBuffer;
1561 constexpr std::array<float, 4> kSrcInitData = {9.3, 3.7, 11.34, 0.65};
1562 createStorageBuffer(WriteResource::Buffer, srcBuffer, srcTextureBuffer, sizeof(kSrcInitData),
1563 kSrcInitData.data());
1564
1565 GLTexture color;
1566 GLFramebuffer fbo;
1567 GLProgram writeProgram;
1568
1569 createFramebuffer(color, fbo, GLColor::green);
1570 createProgram(writePipeline, writeResource, &writeProgram);
1571
1572 GLBuffer positionBuffer;
1573 createQuadVertexArray(positionBuffer);
1574 setupVertexArray(writePipeline, writeProgram);
1575
1576 GLBuffer writeBuffer;
1577 GLTexture writeTextureBuffer;
1578 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1579 createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
1580 kInitData.data());
1581
1582 constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1583 setUniformData(writeProgram, kWriteData);
1584
1585 // Fill the buffer
1586 if (writePipeline == ShaderWritePipeline::Graphics)
1587 {
1588 glEnable(GL_BLEND);
1589 glBlendFunc(GL_ONE, GL_ONE);
1590 glDrawArrays(GL_TRIANGLES, 0, 6);
1591 glDisable(GL_BLEND);
1592 }
1593 else
1594 {
1595 glDispatchCompute(1, 1, 1);
1596 }
1597
1598 noopOp(preBarrierOp);
1599
1600 // Issue the appropriate memory barrier
1601 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1602
1603 noopOp(postBarrierOp);
1604
1605 // Copy from src buffer over the buffer
1606 glBindBuffer(GL_UNIFORM_BUFFER, srcBuffer);
1607 glCopyBufferSubData(GL_UNIFORM_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(kInitData));
1608
1609 verifyFramebufferAndBufferContents(writePipeline, kSrcInitData);
1610
1611 // Verify the src buffer is unaffected
1612 glBindBuffer(GL_SHADER_STORAGE_BUFFER, srcBuffer);
1613 verifyBufferContents(kSrcInitData);
1614 }
1615
bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1616 void MemoryBarrierTestBase::bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,
1617 WriteResource writeResource,
1618 NoopOp preBarrierOp,
1619 NoopOp postBarrierOp,
1620 GLbitfield barrierBit)
1621 {
1622 GLBuffer srcBuffer;
1623 GLTexture srcTextureBuffer;
1624 constexpr std::array<float, 4> kSrcInitData = {9.3, 3.7, 11.34, 0.65};
1625 createStorageBuffer(WriteResource::Buffer, srcBuffer, srcTextureBuffer, sizeof(kSrcInitData),
1626 kSrcInitData.data());
1627
1628 GLTexture color;
1629 GLFramebuffer fbo;
1630 GLProgram writeProgram;
1631
1632 createFramebuffer(color, fbo, GLColor::green);
1633
1634 GLBuffer writeBuffer;
1635 GLTexture writeTextureBuffer;
1636 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1637 createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
1638 kInitData.data());
1639
1640 // Copy from src buffer over the buffer
1641 glBindBuffer(GL_UNIFORM_BUFFER, srcBuffer);
1642 glCopyBufferSubData(GL_UNIFORM_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(kInitData));
1643
1644 noopOp(preBarrierOp);
1645
1646 // Issue the appropriate memory barrier
1647 glMemoryBarrier(barrierBit);
1648
1649 noopOp(postBarrierOp);
1650
1651 // Fill the buffer
1652 createProgram(writePipeline, writeResource, &writeProgram);
1653
1654 GLBuffer positionBuffer;
1655 createQuadVertexArray(positionBuffer);
1656 setupVertexArray(writePipeline, writeProgram);
1657
1658 constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1659 setUniformData(writeProgram, kWriteData);
1660
1661 if (writePipeline == ShaderWritePipeline::Graphics)
1662 {
1663 glEnable(GL_BLEND);
1664 glBlendFunc(GL_ONE, GL_ONE);
1665 glDrawArrays(GL_TRIANGLES, 0, 6);
1666 }
1667 else
1668 {
1669 glDispatchCompute(1, 1, 1);
1670 }
1671
1672 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1673
1674 // Verify the src buffer is unaffected
1675 glBindBuffer(GL_SHADER_STORAGE_BUFFER, srcBuffer);
1676 verifyBufferContents(kSrcInitData);
1677 }
1678
createXfbVerifyProgram(GLuint buffer,GLProgram * programOut)1679 void MemoryBarrierTestBase::createXfbVerifyProgram(GLuint buffer, GLProgram *programOut)
1680 {
1681 constexpr char kVS[] = R"(#version 310 es
1682 void main()
1683 {
1684 // gl_VertexID x y
1685 // 0 (000) -1 -1
1686 // 1 (001) 1 -1
1687 // 2 (010) -1 1
1688 // 3 (011) 1 1
1689 // 4 (100) -1 1
1690 // 5 (101) 1 -1
1691 int bit0 = gl_VertexID & 1;
1692 int bit1 = gl_VertexID < 4 ? gl_VertexID >> 1 & 1 : ~bit0 & 1;
1693 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1694 })";
1695
1696 constexpr char kFS[] = R"(#version 310 es
1697 precision mediump float;
1698 out vec4 colorOut;
1699 void main()
1700 {
1701 colorOut = vec4(0, 1.0, 0, 1.0);
1702 })";
1703
1704 const std::vector<std::string> &tfVaryings = {"gl_Position"};
1705
1706 programOut->makeRasterWithTransformFeedback(kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
1707 ASSERT_TRUE(programOut->valid());
1708 glUseProgram(*programOut);
1709
1710 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
1711 EXPECT_GL_NO_ERROR();
1712 }
1713
transformFeedbackBitBufferWriteThenCapture(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1714 void MemoryBarrierTestBase::transformFeedbackBitBufferWriteThenCapture(
1715 ShaderWritePipeline writePipeline,
1716 WriteResource writeResource,
1717 NoopOp preBarrierOp,
1718 NoopOp postBarrierOp)
1719 {
1720 GLTexture color;
1721 GLFramebuffer fbo;
1722 GLProgram writeProgram;
1723
1724 createFramebuffer(color, fbo, GLColor::black);
1725 createProgram(writePipeline, writeResource, &writeProgram);
1726
1727 GLBuffer positionBuffer;
1728 createQuadVertexArray(positionBuffer);
1729 setupVertexArray(writePipeline, writeProgram);
1730
1731 GLBuffer xfbBuffer;
1732 GLTexture xfbTextureBuffer;
1733 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1734 createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer, sizeof(kInitData) * 6,
1735 kInitData.data());
1736
1737 constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1738 setUniformData(writeProgram, kWriteData);
1739
1740 // Fill the buffer
1741 if (writePipeline == ShaderWritePipeline::Graphics)
1742 {
1743 glDrawArrays(GL_TRIANGLES, 0, 6);
1744 }
1745 else
1746 {
1747 glDispatchCompute(1, 1, 1);
1748 }
1749
1750 noopOp(preBarrierOp);
1751
1752 // Issue the appropriate memory barrier
1753 glMemoryBarrier(GL_TRANSFORM_FEEDBACK_BARRIER_BIT);
1754
1755 noopOp(postBarrierOp);
1756
1757 // Use the buffer
1758 GLProgram xfbProgram;
1759 createXfbVerifyProgram(xfbBuffer, &xfbProgram);
1760
1761 glBeginTransformFeedback(GL_TRIANGLES);
1762 glEnable(GL_BLEND);
1763 glBlendFunc(GL_ONE, GL_ONE);
1764 glDrawArrays(GL_TRIANGLES, 0, 6);
1765 glEndTransformFeedback();
1766 EXPECT_GL_NO_ERROR();
1767
1768 const std::array<float, 4> kExpectedData = {-1.0, -1.0, 0.0, 1.0};
1769 verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1770 }
1771
transformFeedbackBitCaptureThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1772 void MemoryBarrierTestBase::transformFeedbackBitCaptureThenBufferWrite(
1773 ShaderWritePipeline writePipeline,
1774 WriteResource writeResource,
1775 NoopOp preBarrierOp,
1776 NoopOp postBarrierOp,
1777 GLbitfield barrierBit)
1778 {
1779 GLTexture color;
1780 GLFramebuffer fbo;
1781 GLProgram writeProgram;
1782
1783 createFramebuffer(color, fbo, GLColor::black);
1784
1785 GLBuffer xfbBuffer;
1786 GLTexture xfbTextureBuffer;
1787 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1788 createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer, sizeof(kInitData) * 6,
1789 kInitData.data());
1790
1791 // Use the buffer
1792 GLProgram xfbProgram;
1793 createXfbVerifyProgram(xfbBuffer, &xfbProgram);
1794
1795 glBeginTransformFeedback(GL_TRIANGLES);
1796 glDrawArrays(GL_TRIANGLES, 0, 6);
1797 glEndTransformFeedback();
1798 EXPECT_GL_NO_ERROR();
1799
1800 noopOp(preBarrierOp);
1801
1802 // Issue the appropriate memory barrier
1803 glMemoryBarrier(barrierBit);
1804
1805 noopOp(postBarrierOp);
1806
1807 // Fill the buffer
1808 createProgram(writePipeline, writeResource, &writeProgram);
1809
1810 GLBuffer positionBuffer;
1811 createQuadVertexArray(positionBuffer);
1812 setupVertexArray(writePipeline, writeProgram);
1813
1814 constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1815 setUniformData(writeProgram, kWriteData);
1816
1817 if (writePipeline == ShaderWritePipeline::Graphics)
1818 {
1819 glEnable(GL_BLEND);
1820 glBlendFunc(GL_ONE, GL_ONE);
1821 glDrawArrays(GL_TRIANGLES, 0, 6);
1822 }
1823 else
1824 {
1825 glDispatchCompute(1, 1, 1);
1826 }
1827
1828 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1829 }
1830
createAtomicCounterVerifyProgram(GLuint buffer,GLProgram * programOut)1831 void MemoryBarrierTestBase::createAtomicCounterVerifyProgram(GLuint buffer, GLProgram *programOut)
1832 {
1833 constexpr char kVS[] = R"(#version 310 es
1834 void main()
1835 {
1836 // gl_VertexID x y
1837 // 0 -1 -1
1838 // 1 1 -1
1839 // 2 -1 1
1840 // 3 1 1
1841 int bit0 = gl_VertexID & 1;
1842 int bit1 = gl_VertexID >> 1;
1843 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1844 })";
1845
1846 constexpr char kFS[] = R"(#version 310 es
1847 precision mediump float;
1848 layout(binding = 0, offset = 0) uniform atomic_uint ac[4];
1849 out vec4 colorOut;
1850 void main()
1851 {
1852 uvec4 acValue = uvec4(atomicCounterIncrement(ac[0]),
1853 atomicCounterIncrement(ac[1]),
1854 atomicCounterIncrement(ac[2]),
1855 atomicCounterIncrement(ac[3]));
1856
1857 if (all(equal(acValue, uvec4(10, 20, 30, 40))))
1858 colorOut = vec4(0, 1.0, 0, 1.0);
1859 else
1860 colorOut = vec4(1.0, 0, 0, 1.0);
1861 })";
1862
1863 programOut->makeRaster(kVS, kFS);
1864 ASSERT_TRUE(programOut->valid());
1865 glUseProgram(*programOut);
1866
1867 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer);
1868 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, buffer);
1869 EXPECT_GL_NO_ERROR();
1870 }
1871
atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1872 void MemoryBarrierTestBase::atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,
1873 WriteResource writeResource,
1874 NoopOp preBarrierOp,
1875 NoopOp postBarrierOp)
1876 {
1877 GLTexture color;
1878 GLFramebuffer fbo;
1879 GLProgram writeProgram;
1880
1881 createFramebuffer(color, fbo, GLColor::black);
1882 createProgram(writePipeline, writeResource, &writeProgram);
1883
1884 GLBuffer positionBuffer;
1885 createQuadVertexArray(positionBuffer);
1886 setupVertexArray(writePipeline, writeProgram);
1887
1888 GLBuffer atomicCounterBuffer;
1889 GLTexture atomicCounterTextureBuffer;
1890 constexpr std::array<uint32_t, 4> kInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
1891 0x2468ACE0u};
1892 createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
1893 sizeof(kInitData), kInitData.data());
1894
1895 constexpr std::array<uint32_t, 4> kWriteData = {10, 20, 30, 40};
1896 const std::array<float, 4> kWriteDataAsFloat = {
1897 *reinterpret_cast<const float *>(&kWriteData[0]),
1898 *reinterpret_cast<const float *>(&kWriteData[1]),
1899 *reinterpret_cast<const float *>(&kWriteData[2]),
1900 *reinterpret_cast<const float *>(&kWriteData[3]),
1901 };
1902 setUniformData(writeProgram, kWriteDataAsFloat);
1903
1904 // Fill the buffer
1905 if (writePipeline == ShaderWritePipeline::Graphics)
1906 {
1907 glDrawArrays(GL_TRIANGLES, 0, 6);
1908 }
1909 else
1910 {
1911 glDispatchCompute(1, 1, 1);
1912 }
1913
1914 noopOp(preBarrierOp);
1915
1916 // Issue the appropriate memory barrier
1917 glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
1918
1919 noopOp(postBarrierOp);
1920
1921 // Use the buffer
1922 GLProgram readProgram;
1923 createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);
1924
1925 glEnable(GL_BLEND);
1926 glBlendFunc(GL_ONE, GL_ONE);
1927 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1928 EXPECT_GL_NO_ERROR();
1929
1930 constexpr std::array<uint32_t, 4> kExpectedData = {11, 21, 31, 41};
1931 verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1932 }
1933
atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1934 void MemoryBarrierTestBase::atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,
1935 WriteResource writeResource,
1936 NoopOp preBarrierOp,
1937 NoopOp postBarrierOp,
1938 GLbitfield barrierBit)
1939 {
1940 GLTexture color;
1941 GLFramebuffer fbo;
1942 GLProgram writeProgram;
1943
1944 createFramebuffer(color, fbo, GLColor::black);
1945
1946 GLBuffer atomicCounterBuffer;
1947 GLTexture atomicCounterTextureBuffer;
1948 constexpr std::array<uint32_t, 4> kInitData = {10, 20, 30, 40};
1949 createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
1950 sizeof(kInitData), kInitData.data());
1951
1952 // Use the buffer
1953 GLProgram readProgram;
1954 createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);
1955
1956 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1957 EXPECT_GL_NO_ERROR();
1958
1959 noopOp(preBarrierOp);
1960
1961 // Issue the appropriate memory barrier
1962 glMemoryBarrier(barrierBit);
1963
1964 noopOp(postBarrierOp);
1965
1966 // Fill the buffer
1967 createProgram(writePipeline, writeResource, &writeProgram);
1968
1969 GLBuffer positionBuffer;
1970 createQuadVertexArray(positionBuffer);
1971 setupVertexArray(writePipeline, writeProgram);
1972
1973 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1974 setUniformData(writeProgram, kWriteData);
1975
1976 if (writePipeline == ShaderWritePipeline::Graphics)
1977 {
1978 glEnable(GL_BLEND);
1979 glBlendFunc(GL_ONE, GL_ONE);
1980 glDrawArrays(GL_TRIANGLES, 0, 6);
1981 }
1982 else
1983 {
1984 glDispatchCompute(1, 1, 1);
1985 }
1986
1987 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1988 }
1989
createSsboVerifyProgram(WriteResource writeResource,GLProgram * programOut)1990 void MemoryBarrierTestBase::createSsboVerifyProgram(WriteResource writeResource,
1991 GLProgram *programOut)
1992 {
1993 constexpr char kVS[] = R"(#version 310 es
1994 void main()
1995 {
1996 // gl_VertexID x y
1997 // 0 -1 -1
1998 // 1 1 -1
1999 // 2 -1 1
2000 // 3 1 1
2001 int bit0 = gl_VertexID & 1;
2002 int bit1 = gl_VertexID >> 1;
2003 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2004 })";
2005
2006 constexpr char kFS[] = R"(#version 310 es
2007 precision mediump float;
2008 layout(std430, binding = 0) buffer block {
2009 vec4 data;
2010 } inBlock;
2011 out vec4 colorOut;
2012 void main()
2013 {
2014 if (all(lessThan(abs(inBlock.data - vec4(1.5, 3.75, 5.0, 12.125)), vec4(0.01))))
2015 colorOut = vec4(0, 1.0, 0, 1.0);
2016 else
2017 colorOut = vec4(1.0, 0, 0, 1.0);
2018 })";
2019
2020 programOut->makeRaster(kVS, kFS);
2021 ASSERT_TRUE(programOut->valid());
2022 glUseProgram(*programOut);
2023 }
2024
shaderStorageBitBufferWriteThenBufferRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2025 void MemoryBarrierTestBase::shaderStorageBitBufferWriteThenBufferRead(
2026 ShaderWritePipeline writePipeline,
2027 WriteResource writeResource,
2028 NoopOp preBarrierOp,
2029 NoopOp postBarrierOp)
2030 {
2031 GLTexture color;
2032 GLFramebuffer fbo;
2033 GLProgram writeProgram;
2034
2035 createFramebuffer(color, fbo, GLColor::black);
2036 createProgram(writePipeline, writeResource, &writeProgram);
2037
2038 GLBuffer positionBuffer;
2039 createQuadVertexArray(positionBuffer);
2040 setupVertexArray(writePipeline, writeProgram);
2041
2042 GLBuffer writeBuffer;
2043 GLTexture writeTextureBuffer;
2044 constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
2045 createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
2046 kInitData.data());
2047
2048 constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
2049 setUniformData(writeProgram, kWriteData);
2050
2051 // Fill the buffer
2052 if (writePipeline == ShaderWritePipeline::Graphics)
2053 {
2054 glDrawArrays(GL_TRIANGLES, 0, 6);
2055 }
2056 else
2057 {
2058 glDispatchCompute(1, 1, 1);
2059 }
2060
2061 noopOp(preBarrierOp);
2062
2063 // Issue the appropriate memory barrier
2064 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
2065
2066 noopOp(postBarrierOp);
2067
2068 // Use the buffer
2069 GLProgram readProgram;
2070 createSsboVerifyProgram(writeResource, &readProgram);
2071
2072 glEnable(GL_BLEND);
2073 glBlendFunc(GL_ONE, GL_ONE);
2074 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2075 EXPECT_GL_NO_ERROR();
2076
2077 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
2078 }
2079
shaderStorageBitBufferReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2080 void MemoryBarrierTestBase::shaderStorageBitBufferReadThenBufferWrite(
2081 ShaderWritePipeline writePipeline,
2082 WriteResource writeResource,
2083 NoopOp preBarrierOp,
2084 NoopOp postBarrierOp,
2085 GLbitfield barrierBit)
2086 {
2087 GLTexture color;
2088 GLFramebuffer fbo;
2089 GLProgram writeProgram;
2090
2091 createFramebuffer(color, fbo, GLColor::black);
2092
2093 GLBuffer writeBuffer;
2094 GLTexture writeTextureBuffer;
2095 constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
2096 createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
2097 kInitData.data());
2098
2099 // Use the buffer
2100 GLProgram readProgram;
2101 createSsboVerifyProgram(writeResource, &readProgram);
2102
2103 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2104 EXPECT_GL_NO_ERROR();
2105
2106 noopOp(preBarrierOp);
2107
2108 // Issue the appropriate memory barrier
2109 glMemoryBarrier(barrierBit);
2110
2111 noopOp(postBarrierOp);
2112
2113 // Fill the image
2114 createProgram(writePipeline, writeResource, &writeProgram);
2115
2116 GLBuffer positionBuffer;
2117 createQuadVertexArray(positionBuffer);
2118 setupVertexArray(writePipeline, writeProgram);
2119
2120 constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
2121 setUniformData(writeProgram, kWriteData);
2122
2123 if (writePipeline == ShaderWritePipeline::Graphics)
2124 {
2125 glEnable(GL_BLEND);
2126 glBlendFunc(GL_ONE, GL_ONE);
2127 glDrawArrays(GL_TRIANGLES, 0, 6);
2128 }
2129 else
2130 {
2131 glDispatchCompute(1, 1, 1);
2132 }
2133
2134 verifyFramebufferAndBufferContents(writePipeline, kWriteData);
2135 }
2136
createTextureVerifyProgram(WriteResource writeResource,GLuint texture,GLProgram * programOut)2137 void MemoryBarrierTestBase::createTextureVerifyProgram(WriteResource writeResource,
2138 GLuint texture,
2139 GLProgram *programOut)
2140 {
2141 constexpr char kVS[] = R"(#version 310 es
2142 void main()
2143 {
2144 // gl_VertexID x y
2145 // 0 -1 -1
2146 // 1 1 -1
2147 // 2 -1 1
2148 // 3 1 1
2149 int bit0 = gl_VertexID & 1;
2150 int bit1 = gl_VertexID >> 1;
2151 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2152 })";
2153
2154 constexpr char kImageFS[] = R"(#version 310 es
2155 precision mediump float;
2156 uniform sampler2D s;
2157 out vec4 colorOut;
2158 void main()
2159 {
2160 if (all(lessThan(abs(texelFetch(s, ivec2(0, 0), 0)- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
2161 colorOut = vec4(0, 1.0, 0, 1.0);
2162 else
2163 colorOut = vec4(1.0, 0, 0, 1.0);
2164 })";
2165
2166 constexpr char kImageBufferFS[] = R"(#version 310 es
2167 #extension GL_OES_texture_buffer : require
2168 precision mediump float;
2169 uniform highp samplerBuffer s;
2170 out vec4 colorOut;
2171 void main()
2172 {
2173 if (texelFetch(s, 0) == vec4(0.125, 0.25, 0.5, 0.75))
2174 colorOut = vec4(0, 1.0, 0, 1.0);
2175 else
2176 colorOut = vec4(1.0, 0, 0, 1.0);
2177 })";
2178
2179 programOut->makeRaster(kVS,
2180 writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
2181 ASSERT_TRUE(programOut->valid());
2182 glUseProgram(*programOut);
2183
2184 glBindTexture(writeResource == WriteResource::ImageBuffer ? GL_TEXTURE_BUFFER : GL_TEXTURE_2D,
2185 texture);
2186 EXPECT_GL_NO_ERROR();
2187 }
2188
textureFetchBitImageWriteThenSamplerRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2189 void MemoryBarrierTestBase::textureFetchBitImageWriteThenSamplerRead(
2190 ShaderWritePipeline writePipeline,
2191 WriteResource writeResource,
2192 NoopOp preBarrierOp,
2193 NoopOp postBarrierOp)
2194 {
2195 GLTexture color;
2196 GLFramebuffer fbo;
2197 GLProgram writeProgram;
2198
2199 createFramebuffer(color, fbo, GLColor::black);
2200 createProgram(writePipeline, writeResource, &writeProgram);
2201
2202 GLBuffer positionBuffer;
2203 createQuadVertexArray(positionBuffer);
2204 setupVertexArray(writePipeline, writeProgram);
2205
2206 GLBuffer textureBufferStorage;
2207 GLTexture texture;
2208 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2209 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2210
2211 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2212 setUniformData(writeProgram, kWriteData);
2213
2214 // Fill the image
2215 if (writePipeline == ShaderWritePipeline::Graphics)
2216 {
2217 glDrawArrays(GL_TRIANGLES, 0, 6);
2218 }
2219 else
2220 {
2221 glDispatchCompute(1, 1, 1);
2222 }
2223
2224 noopOp(preBarrierOp);
2225
2226 // Issue the appropriate memory barrier
2227 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
2228
2229 noopOp(postBarrierOp);
2230
2231 // Use the image
2232 GLProgram readProgram;
2233 createTextureVerifyProgram(writeResource, texture, &readProgram);
2234
2235 glEnable(GL_BLEND);
2236 glBlendFunc(GL_ONE, GL_ONE);
2237 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2238 EXPECT_GL_NO_ERROR();
2239
2240 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2241 }
2242
textureFetchBitSamplerReadThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2243 void MemoryBarrierTestBase::textureFetchBitSamplerReadThenImageWrite(
2244 ShaderWritePipeline writePipeline,
2245 WriteResource writeResource,
2246 NoopOp preBarrierOp,
2247 NoopOp postBarrierOp,
2248 GLbitfield barrierBit)
2249 {
2250 GLTexture color;
2251 GLFramebuffer fbo;
2252 GLProgram writeProgram;
2253
2254 createFramebuffer(color, fbo, GLColor::black);
2255
2256 GLBuffer textureBufferStorage;
2257 GLTexture texture;
2258 constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
2259 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2260
2261 // Use the image
2262 GLProgram readProgram;
2263 createTextureVerifyProgram(writeResource, texture, &readProgram);
2264
2265 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2266 EXPECT_GL_NO_ERROR();
2267
2268 noopOp(preBarrierOp);
2269
2270 // Issue the appropriate memory barrier
2271 glMemoryBarrier(barrierBit);
2272
2273 noopOp(postBarrierOp);
2274
2275 // Fill the image
2276 createProgram(writePipeline, writeResource, &writeProgram);
2277
2278 GLBuffer positionBuffer;
2279 createQuadVertexArray(positionBuffer);
2280 setupVertexArray(writePipeline, writeProgram);
2281
2282 constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
2283 setUniformData(writeProgram, kWriteData);
2284
2285 if (writePipeline == ShaderWritePipeline::Graphics)
2286 {
2287 glEnable(GL_BLEND);
2288 glBlendFunc(GL_ONE, GL_ONE);
2289 glDrawArrays(GL_TRIANGLES, 0, 6);
2290 }
2291 else
2292 {
2293 glDispatchCompute(1, 1, 1);
2294 }
2295
2296 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2297 }
2298
createImageVerifyProgram(WriteResource writeResource,GLuint texture,GLProgram * programOut)2299 void MemoryBarrierTestBase::createImageVerifyProgram(WriteResource writeResource,
2300 GLuint texture,
2301 GLProgram *programOut)
2302 {
2303 constexpr char kVS[] = R"(#version 310 es
2304 void main()
2305 {
2306 // gl_VertexID x y
2307 // 0 -1 -1
2308 // 1 1 -1
2309 // 2 -1 1
2310 // 3 1 1
2311 int bit0 = gl_VertexID & 1;
2312 int bit1 = gl_VertexID >> 1;
2313 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2314 })";
2315
2316 constexpr char kImageFS[] = R"(#version 310 es
2317 precision mediump float;
2318 layout(rgba8, binding = 0) uniform highp readonly image2D img;
2319 out vec4 colorOut;
2320 void main()
2321 {
2322 if (all(lessThan(abs(imageLoad(img, ivec2(0, 0))- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
2323 colorOut = vec4(0, 1.0, 0, 1.0);
2324 else
2325 colorOut = vec4(1.0, 0, 0, 1.0);
2326 })";
2327
2328 constexpr char kImageBufferFS[] = R"(#version 310 es
2329 #extension GL_OES_texture_buffer : require
2330 precision mediump float;
2331 layout(rgba32f, binding = 0) uniform highp readonly imageBuffer img;
2332 out vec4 colorOut;
2333 void main()
2334 {
2335 if (imageLoad(img, 0) == vec4(0.125, 0.25, 0.5, 0.75))
2336 colorOut = vec4(0, 1.0, 0, 1.0);
2337 else
2338 colorOut = vec4(1.0, 0, 0, 1.0);
2339 })";
2340
2341 programOut->makeRaster(kVS,
2342 writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
2343 ASSERT_TRUE(programOut->valid());
2344 glUseProgram(*programOut);
2345
2346 if (writeResource == WriteResource::ImageBuffer)
2347 {
2348 glBindTexture(GL_TEXTURE_BUFFER, texture);
2349 glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
2350 }
2351 else
2352 {
2353 glBindTexture(GL_TEXTURE_2D, texture);
2354 glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
2355 }
2356 EXPECT_GL_NO_ERROR();
2357 }
2358
shaderImageAccessBitImageWriteThenImageRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2359 void MemoryBarrierTestBase::shaderImageAccessBitImageWriteThenImageRead(
2360 ShaderWritePipeline writePipeline,
2361 WriteResource writeResource,
2362 NoopOp preBarrierOp,
2363 NoopOp postBarrierOp)
2364 {
2365 GLTexture color;
2366 GLFramebuffer fbo;
2367 GLProgram writeProgram;
2368
2369 createFramebuffer(color, fbo, GLColor::black);
2370 createProgram(writePipeline, writeResource, &writeProgram);
2371
2372 GLBuffer positionBuffer;
2373 createQuadVertexArray(positionBuffer);
2374 setupVertexArray(writePipeline, writeProgram);
2375
2376 GLBuffer textureBufferStorage;
2377 GLTexture texture;
2378 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2379 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2380
2381 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2382 setUniformData(writeProgram, kWriteData);
2383
2384 // Fill the image
2385 if (writePipeline == ShaderWritePipeline::Graphics)
2386 {
2387 glDrawArrays(GL_TRIANGLES, 0, 6);
2388 }
2389 else
2390 {
2391 glDispatchCompute(1, 1, 1);
2392 }
2393
2394 noopOp(preBarrierOp);
2395
2396 // Issue the appropriate memory barrier
2397 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2398
2399 noopOp(postBarrierOp);
2400
2401 // Use the image
2402 GLProgram readProgram;
2403 createImageVerifyProgram(writeResource, texture, &readProgram);
2404
2405 glEnable(GL_BLEND);
2406 glBlendFunc(GL_ONE, GL_ONE);
2407 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2408 EXPECT_GL_NO_ERROR();
2409
2410 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2411 }
2412
shaderImageAccessBitImageReadThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2413 void MemoryBarrierTestBase::shaderImageAccessBitImageReadThenImageWrite(
2414 ShaderWritePipeline writePipeline,
2415 WriteResource writeResource,
2416 NoopOp preBarrierOp,
2417 NoopOp postBarrierOp)
2418 {
2419 GLTexture color;
2420 GLFramebuffer fbo;
2421 GLProgram writeProgram;
2422
2423 createFramebuffer(color, fbo, GLColor::black);
2424
2425 GLBuffer textureBufferStorage;
2426 GLTexture texture;
2427 constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
2428 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2429
2430 // Use the image
2431 GLProgram readProgram;
2432 createImageVerifyProgram(writeResource, texture, &readProgram);
2433
2434 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2435 EXPECT_GL_NO_ERROR();
2436
2437 noopOp(preBarrierOp);
2438
2439 // Issue the appropriate memory barrier
2440 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2441
2442 noopOp(postBarrierOp);
2443
2444 // Fill the image
2445 createProgram(writePipeline, writeResource, &writeProgram);
2446
2447 GLBuffer positionBuffer;
2448 createQuadVertexArray(positionBuffer);
2449 setupVertexArray(writePipeline, writeProgram);
2450
2451 constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
2452 setUniformData(writeProgram, kWriteData);
2453
2454 if (writePipeline == ShaderWritePipeline::Graphics)
2455 {
2456 glEnable(GL_BLEND);
2457 glBlendFunc(GL_ONE, GL_ONE);
2458 glDrawArrays(GL_TRIANGLES, 0, 6);
2459 }
2460 else
2461 {
2462 glDispatchCompute(1, 1, 1);
2463 }
2464
2465 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2466 }
2467
textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2468 void MemoryBarrierTestBase::textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
2469 WriteResource writeResource,
2470 NoopOp preBarrierOp,
2471 NoopOp postBarrierOp)
2472 {
2473 GLTexture color;
2474 GLFramebuffer fbo;
2475 GLProgram writeProgram;
2476
2477 createFramebuffer(color, fbo, GLColor::green);
2478 createProgram(writePipeline, writeResource, &writeProgram);
2479
2480 GLBuffer positionBuffer;
2481 createQuadVertexArray(positionBuffer);
2482 setupVertexArray(writePipeline, writeProgram);
2483
2484 GLBuffer textureBufferStorage;
2485 GLTexture texture;
2486 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2487 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2488
2489 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2490 setUniformData(writeProgram, kWriteData);
2491
2492 // Fill the image
2493 if (writePipeline == ShaderWritePipeline::Graphics)
2494 {
2495 glEnable(GL_BLEND);
2496 glBlendFunc(GL_ONE, GL_ONE);
2497 glDrawArrays(GL_TRIANGLES, 0, 6);
2498 glDisable(GL_BLEND);
2499 }
2500 else
2501 {
2502 glDispatchCompute(1, 1, 1);
2503 }
2504
2505 noopOp(preBarrierOp);
2506
2507 // Issue the appropriate memory barrier
2508 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2509
2510 noopOp(postBarrierOp);
2511
2512 // Copy from framebuffer over the texture
2513 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2514
2515 const std::array<float, 4> kExpectedData = {
2516 0, 1.0f, writePipeline == ShaderWritePipeline::Graphics ? 1.0f : 0, 1.0f};
2517 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
2518 }
2519
textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2520 void MemoryBarrierTestBase::textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
2521 WriteResource writeResource,
2522 NoopOp preBarrierOp,
2523 NoopOp postBarrierOp,
2524 GLbitfield barrierBit)
2525 {
2526 GLTexture color;
2527 GLFramebuffer fbo;
2528 GLProgram writeProgram;
2529
2530 createFramebuffer(color, fbo, GLColor::green);
2531
2532 GLBuffer textureBufferStorage;
2533 GLTexture texture;
2534 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2535 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2536
2537 // Copy from framebuffer over the texture
2538 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2539
2540 noopOp(preBarrierOp);
2541
2542 // Issue the appropriate memory barrier
2543 glMemoryBarrier(barrierBit);
2544
2545 noopOp(postBarrierOp);
2546
2547 // Fill the image
2548 createProgram(writePipeline, writeResource, &writeProgram);
2549
2550 GLBuffer positionBuffer;
2551 createQuadVertexArray(positionBuffer);
2552 setupVertexArray(writePipeline, writeProgram);
2553
2554 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2555 setUniformData(writeProgram, kWriteData);
2556
2557 if (writePipeline == ShaderWritePipeline::Graphics)
2558 {
2559 glEnable(GL_BLEND);
2560 glBlendFunc(GL_ONE, GL_ONE);
2561 glDrawArrays(GL_TRIANGLES, 0, 6);
2562 }
2563 else
2564 {
2565 glDispatchCompute(1, 1, 1);
2566 }
2567
2568 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2569 }
2570
framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2571 void MemoryBarrierTestBase::framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,
2572 WriteResource writeResource,
2573 NoopOp preBarrierOp,
2574 NoopOp postBarrierOp)
2575 {
2576 GLTexture color;
2577 GLFramebuffer fbo;
2578 GLProgram writeProgram;
2579
2580 createFramebuffer(color, fbo, GLColor::green);
2581 createProgram(writePipeline, writeResource, &writeProgram);
2582
2583 GLBuffer positionBuffer;
2584 createQuadVertexArray(positionBuffer);
2585 setupVertexArray(writePipeline, writeProgram);
2586
2587 GLBuffer textureBufferStorage;
2588 GLTexture texture;
2589 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2590 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2591
2592 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2593 setUniformData(writeProgram, kWriteData);
2594
2595 // Fill the image
2596 if (writePipeline == ShaderWritePipeline::Graphics)
2597 {
2598 glEnable(GL_BLEND);
2599 glBlendFunc(GL_ONE, GL_ONE);
2600 glDrawArrays(GL_TRIANGLES, 0, 6);
2601 glDisable(GL_BLEND);
2602 }
2603 else
2604 {
2605 glDispatchCompute(1, 1, 1);
2606 }
2607
2608 noopOp(preBarrierOp);
2609
2610 // Issue the appropriate memory barrier
2611 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2612
2613 noopOp(postBarrierOp);
2614
2615 // Draw to image via framebuffer
2616 ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2617 glUseProgram(verifyProgram);
2618 GLint colorUniformLocation =
2619 glGetUniformLocation(verifyProgram, angle::essl1_shaders::ColorUniform());
2620 ASSERT_NE(colorUniformLocation, -1);
2621 setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);
2622
2623 GLFramebuffer drawFbo;
2624 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
2625 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2626 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2627
2628 constexpr std::array<float, 4> kBlendData = {0.125, 0.25, 0.5, 0.25};
2629 glUniform4fv(colorUniformLocation, 1, kBlendData.data());
2630
2631 glEnable(GL_BLEND);
2632 glBlendFunc(GL_ONE, GL_ONE);
2633 glDrawArrays(GL_TRIANGLES, 0, 6);
2634 glDisable(GL_BLEND);
2635 EXPECT_GL_NO_ERROR();
2636
2637 const std::array<float, 4> kExpectedData = {
2638 kWriteData[0] + kBlendData[0],
2639 kWriteData[1] + kBlendData[1],
2640 kWriteData[2] + kBlendData[2],
2641 kWriteData[3] + kBlendData[3],
2642 };
2643 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
2644 }
2645
framebufferBitImageWriteThenReadPixels(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2646 void MemoryBarrierTestBase::framebufferBitImageWriteThenReadPixels(
2647 ShaderWritePipeline writePipeline,
2648 WriteResource writeResource,
2649 NoopOp preBarrierOp,
2650 NoopOp postBarrierOp)
2651 {
2652 GLTexture color;
2653 GLFramebuffer fbo;
2654 GLProgram writeProgram;
2655
2656 createFramebuffer(color, fbo, GLColor::green);
2657 createProgram(writePipeline, writeResource, &writeProgram);
2658
2659 GLBuffer positionBuffer;
2660 createQuadVertexArray(positionBuffer);
2661 setupVertexArray(writePipeline, writeProgram);
2662
2663 GLBuffer textureBufferStorage;
2664 GLTexture texture;
2665 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2666 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2667
2668 constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2669 setUniformData(writeProgram, kWriteData);
2670
2671 // Fill the image
2672 if (writePipeline == ShaderWritePipeline::Graphics)
2673 {
2674 glEnable(GL_BLEND);
2675 glBlendFunc(GL_ONE, GL_ONE);
2676 glDrawArrays(GL_TRIANGLES, 0, 6);
2677 glDisable(GL_BLEND);
2678 }
2679 else
2680 {
2681 glDispatchCompute(1, 1, 1);
2682 }
2683
2684 noopOp(preBarrierOp);
2685
2686 // Issue the appropriate memory barrier
2687 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2688
2689 noopOp(postBarrierOp);
2690
2691 // Read from image via framebuffer
2692 GLBuffer packBuffer;
2693 glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
2694 constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
2695 0x2468ACE0u};
2696 glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
2697 EXPECT_GL_NO_ERROR();
2698
2699 GLFramebuffer readFbo;
2700 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2701 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2702 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2703
2704 glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2705 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2706 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2707 EXPECT_GL_NO_ERROR();
2708
2709 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2710
2711 // Verify the PBO for completeness
2712 glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
2713 constexpr std::array<uint32_t, 4> kExpectedData = {
2714 0xFF00FFFFu,
2715 kPBOInitData[1],
2716 kPBOInitData[2],
2717 kPBOInitData[3],
2718 };
2719 verifyBufferContents(kExpectedData);
2720 }
2721
framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2722 void MemoryBarrierTestBase::framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
2723 WriteResource writeResource,
2724 NoopOp preBarrierOp,
2725 NoopOp postBarrierOp)
2726 {
2727 GLTexture color;
2728 GLFramebuffer fbo;
2729 GLProgram writeProgram;
2730
2731 createFramebuffer(color, fbo, GLColor::green);
2732 createProgram(writePipeline, writeResource, &writeProgram);
2733
2734 GLBuffer positionBuffer;
2735 createQuadVertexArray(positionBuffer);
2736 setupVertexArray(writePipeline, writeProgram);
2737
2738 GLBuffer textureBufferStorage;
2739 GLTexture texture;
2740 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2741 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2742
2743 constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2744 setUniformData(writeProgram, kWriteData);
2745
2746 // Fill the image
2747 if (writePipeline == ShaderWritePipeline::Graphics)
2748 {
2749 glEnable(GL_BLEND);
2750 glBlendFunc(GL_ONE, GL_ONE);
2751 glDrawArrays(GL_TRIANGLES, 0, 6);
2752 glDisable(GL_BLEND);
2753 }
2754 else
2755 {
2756 glDispatchCompute(1, 1, 1);
2757 }
2758
2759 noopOp(preBarrierOp);
2760
2761 // Issue the appropriate memory barrier
2762 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2763
2764 noopOp(postBarrierOp);
2765
2766 // Copy from framebuffer to another texture
2767 GLFramebuffer readFbo;
2768 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2769 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2770 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2771
2772 GLTexture copyTexture;
2773 glBindTexture(GL_TEXTURE_2D, copyTexture);
2774 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
2775 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2776
2777 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2778 EXPECT_GL_NO_ERROR();
2779
2780 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2781
2782 // Verify the copy texture for completeness
2783 verifyImageContents(copyTexture, kWriteData);
2784 }
2785
framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2786 void MemoryBarrierTestBase::framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,
2787 WriteResource writeResource,
2788 NoopOp preBarrierOp,
2789 NoopOp postBarrierOp)
2790 {
2791 GLTexture blitColor;
2792 GLFramebuffer blitFbo;
2793 createFramebuffer(blitColor, blitFbo, GLColor::black);
2794
2795 GLTexture color;
2796 GLFramebuffer fbo;
2797 GLProgram writeProgram;
2798
2799 createFramebuffer(color, fbo, GLColor::green);
2800 createProgram(writePipeline, writeResource, &writeProgram);
2801
2802 GLBuffer positionBuffer;
2803 createQuadVertexArray(positionBuffer);
2804 setupVertexArray(writePipeline, writeProgram);
2805
2806 GLBuffer textureBufferStorage;
2807 GLTexture texture;
2808 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2809 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2810
2811 constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2812 setUniformData(writeProgram, kWriteData);
2813
2814 // Fill the image
2815 if (writePipeline == ShaderWritePipeline::Graphics)
2816 {
2817 glEnable(GL_BLEND);
2818 glBlendFunc(GL_ONE, GL_ONE);
2819 glDrawArrays(GL_TRIANGLES, 0, 6);
2820 glDisable(GL_BLEND);
2821 }
2822 else
2823 {
2824 glDispatchCompute(1, 1, 1);
2825 }
2826
2827 noopOp(preBarrierOp);
2828
2829 // Issue the appropriate memory barrier
2830 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2831
2832 noopOp(postBarrierOp);
2833
2834 // Blit from framebuffer to another framebuffer
2835 GLFramebuffer readFbo;
2836 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2837 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2838 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2839
2840 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
2841 glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
2842 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2843 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2844 EXPECT_GL_NO_ERROR();
2845
2846 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2847
2848 // Verify the blit fbo for completeness
2849 glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
2850 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
2851 }
2852
framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2853 void MemoryBarrierTestBase::framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,
2854 WriteResource writeResource,
2855 NoopOp preBarrierOp,
2856 NoopOp postBarrierOp,
2857 GLbitfield barrierBit)
2858 {
2859 GLTexture color;
2860 GLFramebuffer fbo;
2861 GLProgram writeProgram;
2862
2863 createFramebuffer(color, fbo, GLColor::green);
2864
2865 GLBuffer textureBufferStorage;
2866 GLTexture texture;
2867 constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2868 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2869
2870 // Draw to image via framebuffer
2871 ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2872 glUseProgram(verifyProgram);
2873
2874 GLBuffer positionBuffer;
2875 createQuadVertexArray(positionBuffer);
2876 setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);
2877
2878 GLFramebuffer drawFbo;
2879 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
2880 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2881 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2882
2883 glDrawArrays(GL_TRIANGLES, 0, 6);
2884 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2885 EXPECT_GL_NO_ERROR();
2886
2887 noopOp(preBarrierOp);
2888
2889 // Issue the appropriate memory barrier
2890 glMemoryBarrier(barrierBit);
2891
2892 noopOp(postBarrierOp);
2893
2894 // Fill the image
2895 createProgram(writePipeline, writeResource, &writeProgram);
2896
2897 setupVertexArray(writePipeline, writeProgram);
2898
2899 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2900 setUniformData(writeProgram, kWriteData);
2901
2902 if (writePipeline == ShaderWritePipeline::Graphics)
2903 {
2904 glEnable(GL_BLEND);
2905 glBlendFunc(GL_ONE, GL_ONE);
2906 glDrawArrays(GL_TRIANGLES, 0, 6);
2907 }
2908 else
2909 {
2910 glDispatchCompute(1, 1, 1);
2911 }
2912
2913 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2914 }
2915
framebufferBitReadPixelsThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2916 void MemoryBarrierTestBase::framebufferBitReadPixelsThenImageWrite(
2917 ShaderWritePipeline writePipeline,
2918 WriteResource writeResource,
2919 NoopOp preBarrierOp,
2920 NoopOp postBarrierOp,
2921 GLbitfield barrierBit)
2922 {
2923 GLTexture color;
2924 GLFramebuffer fbo;
2925 GLProgram writeProgram;
2926
2927 createFramebuffer(color, fbo, GLColor::green);
2928
2929 GLBuffer textureBufferStorage;
2930 GLTexture texture;
2931 constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
2932 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2933
2934 // Read from image via framebuffer
2935 GLBuffer packBuffer;
2936 glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
2937 constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
2938 0x2468ACE0u};
2939 glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
2940 EXPECT_GL_NO_ERROR();
2941
2942 GLFramebuffer readFbo;
2943 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2944 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2945 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2946
2947 glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2948 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2949 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2950 EXPECT_GL_NO_ERROR();
2951
2952 noopOp(preBarrierOp);
2953
2954 // Issue the appropriate memory barrier
2955 glMemoryBarrier(barrierBit);
2956
2957 noopOp(postBarrierOp);
2958
2959 // Fill the image
2960 createProgram(writePipeline, writeResource, &writeProgram);
2961
2962 GLBuffer positionBuffer;
2963 createQuadVertexArray(positionBuffer);
2964 setupVertexArray(writePipeline, writeProgram);
2965
2966 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2967 setUniformData(writeProgram, kWriteData);
2968
2969 if (writePipeline == ShaderWritePipeline::Graphics)
2970 {
2971 glEnable(GL_BLEND);
2972 glBlendFunc(GL_ONE, GL_ONE);
2973 glDrawArrays(GL_TRIANGLES, 0, 6);
2974 }
2975 else
2976 {
2977 glDispatchCompute(1, 1, 1);
2978 }
2979
2980 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2981
2982 // Verify the PBO for completeness
2983 glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
2984 constexpr std::array<uint32_t, 4> kExpectedData = {
2985 0xFF00FFFFu,
2986 kPBOInitData[1],
2987 kPBOInitData[2],
2988 kPBOInitData[3],
2989 };
2990 verifyBufferContents(kExpectedData);
2991 }
2992
framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2993 void MemoryBarrierTestBase::framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
2994 WriteResource writeResource,
2995 NoopOp preBarrierOp,
2996 NoopOp postBarrierOp,
2997 GLbitfield barrierBit)
2998 {
2999 GLTexture color;
3000 GLFramebuffer fbo;
3001 GLProgram writeProgram;
3002
3003 createFramebuffer(color, fbo, GLColor::green);
3004
3005 GLBuffer textureBufferStorage;
3006 GLTexture texture;
3007 constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
3008 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
3009
3010 // Copy from framebuffer to another texture
3011 GLFramebuffer readFbo;
3012 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3013 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3014 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3015
3016 GLTexture copyTexture;
3017 glBindTexture(GL_TEXTURE_2D, copyTexture);
3018 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
3019 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
3020
3021 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3022 EXPECT_GL_NO_ERROR();
3023
3024 noopOp(preBarrierOp);
3025
3026 // Issue the appropriate memory barrier
3027 glMemoryBarrier(barrierBit);
3028
3029 noopOp(postBarrierOp);
3030
3031 // Fill the image
3032 createProgram(writePipeline, writeResource, &writeProgram);
3033
3034 GLBuffer positionBuffer;
3035 createQuadVertexArray(positionBuffer);
3036 setupVertexArray(writePipeline, writeProgram);
3037
3038 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
3039 setUniformData(writeProgram, kWriteData);
3040
3041 if (writePipeline == ShaderWritePipeline::Graphics)
3042 {
3043 glEnable(GL_BLEND);
3044 glBlendFunc(GL_ONE, GL_ONE);
3045 glDrawArrays(GL_TRIANGLES, 0, 6);
3046 }
3047 else
3048 {
3049 glDispatchCompute(1, 1, 1);
3050 }
3051
3052 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
3053
3054 // Verify the copy texture for completeness
3055 verifyImageContents(copyTexture, kInitData);
3056 }
3057
framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)3058 void MemoryBarrierTestBase::framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,
3059 WriteResource writeResource,
3060 NoopOp preBarrierOp,
3061 NoopOp postBarrierOp,
3062 GLbitfield barrierBit)
3063 {
3064 GLTexture blitColor;
3065 GLFramebuffer blitFbo;
3066 createFramebuffer(blitColor, blitFbo, GLColor::black);
3067
3068 GLTexture color;
3069 GLFramebuffer fbo;
3070 GLProgram writeProgram;
3071
3072 createFramebuffer(color, fbo, GLColor::green);
3073
3074 GLBuffer textureBufferStorage;
3075 GLTexture texture;
3076 constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
3077 createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
3078
3079 // Blit from framebuffer to another framebuffer
3080 GLFramebuffer readFbo;
3081 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3082 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3083 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3084
3085 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
3086 glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
3087 GL_COLOR_BUFFER_BIT, GL_NEAREST);
3088 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3089 EXPECT_GL_NO_ERROR();
3090
3091 noopOp(preBarrierOp);
3092
3093 // Issue the appropriate memory barrier
3094 glMemoryBarrier(barrierBit);
3095
3096 noopOp(postBarrierOp);
3097
3098 // Fill the image
3099 createProgram(writePipeline, writeResource, &writeProgram);
3100
3101 GLBuffer positionBuffer;
3102 createQuadVertexArray(positionBuffer);
3103 setupVertexArray(writePipeline, writeProgram);
3104
3105 constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
3106 setUniformData(writeProgram, kWriteData);
3107
3108 if (writePipeline == ShaderWritePipeline::Graphics)
3109 {
3110 glEnable(GL_BLEND);
3111 glBlendFunc(GL_ONE, GL_ONE);
3112 glDrawArrays(GL_TRIANGLES, 0, 6);
3113 }
3114 else
3115 {
3116 glDispatchCompute(1, 1, 1);
3117 }
3118
3119 verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
3120
3121 // Verify the blit fbo for completeness
3122 glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
3123 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3124 }
3125
3126 class MemoryBarrierBufferTest : public MemoryBarrierTestBase,
3127 public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3128 {
3129 protected:
MemoryBarrierBufferTest()3130 MemoryBarrierBufferTest()
3131 {
3132 setWindowWidth(16);
3133 setWindowHeight(32);
3134 setConfigRedBits(8);
3135 setConfigGreenBits(8);
3136 setConfigBlueBits(8);
3137 setConfigAlphaBits(8);
3138 }
3139 };
3140
3141 class MemoryBarrierImageTest : public MemoryBarrierTestBase,
3142 public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3143 {
3144 protected:
MemoryBarrierImageTest()3145 MemoryBarrierImageTest()
3146 {
3147 setWindowWidth(16);
3148 setWindowHeight(32);
3149 setConfigRedBits(8);
3150 setConfigGreenBits(8);
3151 setConfigBlueBits(8);
3152 setConfigAlphaBits(8);
3153 }
3154 };
3155
3156 class MemoryBarrierImageBufferOnlyTest
3157 : public MemoryBarrierTestBase,
3158 public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3159 {
3160 protected:
MemoryBarrierImageBufferOnlyTest()3161 MemoryBarrierImageBufferOnlyTest()
3162 {
3163 setWindowWidth(16);
3164 setWindowHeight(32);
3165 setConfigRedBits(8);
3166 setConfigGreenBits(8);
3167 setConfigBlueBits(8);
3168 setConfigAlphaBits(8);
3169 }
3170 };
3171
3172 class MemoryBarrierImageOnlyTest : public MemoryBarrierTestBase,
3173 public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3174 {
3175 protected:
MemoryBarrierImageOnlyTest()3176 MemoryBarrierImageOnlyTest()
3177 {
3178 setWindowWidth(16);
3179 setWindowHeight(32);
3180 setConfigRedBits(8);
3181 setConfigGreenBits(8);
3182 setConfigBlueBits(8);
3183 setConfigAlphaBits(8);
3184 }
3185 };
3186
3187 class MemoryBarrierBufferOnlyTest : public MemoryBarrierTestBase,
3188 public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3189 {
3190 protected:
MemoryBarrierBufferOnlyTest()3191 MemoryBarrierBufferOnlyTest()
3192 {
3193 setWindowWidth(16);
3194 setWindowHeight(32);
3195 setConfigRedBits(8);
3196 setConfigGreenBits(8);
3197 setConfigBlueBits(8);
3198 setConfigAlphaBits(8);
3199 }
3200 };
3201
3202 // Test GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; shader write -> vertex read
TEST_P(MemoryBarrierBufferTest,VertexAtrribArrayBitWriteThenVertexRead)3203 TEST_P(MemoryBarrierBufferTest, VertexAtrribArrayBitWriteThenVertexRead)
3204 {
3205 ShaderWritePipeline writePipeline;
3206 WriteResource writeResource;
3207 NoopOp preBarrierOp;
3208 NoopOp postBarrierOp;
3209 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3210 &preBarrierOp, &postBarrierOp);
3211
3212 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3213
3214 vertexAttribArrayBitBufferWriteThenVertexRead(writePipeline, writeResource, preBarrierOp,
3215 postBarrierOp);
3216 }
3217
3218 // Test GL_ELEMENT_ARRAY_BARRIER_BIT; shader write -> index read
TEST_P(MemoryBarrierBufferTest,ElementArrayBitWriteThenIndexRead)3219 TEST_P(MemoryBarrierBufferTest, ElementArrayBitWriteThenIndexRead)
3220 {
3221 ShaderWritePipeline writePipeline;
3222 WriteResource writeResource;
3223 NoopOp preBarrierOp;
3224 NoopOp postBarrierOp;
3225 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3226 &preBarrierOp, &postBarrierOp);
3227
3228 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3229
3230 elementArrayBitBufferWriteThenIndexRead(writePipeline, writeResource, preBarrierOp,
3231 postBarrierOp);
3232 }
3233
3234 // Test GL_UNIFORM_BARRIER_BIT; shader write -> ubo read
TEST_P(MemoryBarrierBufferTest,UniformBitWriteThenUBORead)3235 TEST_P(MemoryBarrierBufferTest, UniformBitWriteThenUBORead)
3236 {
3237 ShaderWritePipeline writePipeline;
3238 WriteResource writeResource;
3239 NoopOp preBarrierOp;
3240 NoopOp postBarrierOp;
3241 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3242 &preBarrierOp, &postBarrierOp);
3243
3244 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3245
3246 uniformBitBufferWriteThenUBORead(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3247 }
3248
3249 // Test GL_TEXTURE_FETCH_BARRIER_BIT; shader write -> sampler read
TEST_P(MemoryBarrierImageTest,TextureFetchBitWriteThenSamplerRead)3250 TEST_P(MemoryBarrierImageTest, TextureFetchBitWriteThenSamplerRead)
3251 {
3252 ShaderWritePipeline writePipeline;
3253 WriteResource writeResource;
3254 NoopOp preBarrierOp;
3255 NoopOp postBarrierOp;
3256 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3257 &preBarrierOp, &postBarrierOp);
3258
3259 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3260
3261 textureFetchBitImageWriteThenSamplerRead(writePipeline, writeResource, preBarrierOp,
3262 postBarrierOp);
3263 }
3264
3265 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; shader write -> image read
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitWriteThenImageRead)3266 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitWriteThenImageRead)
3267 {
3268 ShaderWritePipeline writePipeline;
3269 WriteResource writeResource;
3270 NoopOp preBarrierOp;
3271 NoopOp postBarrierOp;
3272 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3273 &preBarrierOp, &postBarrierOp);
3274
3275 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3276
3277 shaderImageAccessBitImageWriteThenImageRead(writePipeline, writeResource, preBarrierOp,
3278 postBarrierOp);
3279 }
3280
3281 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; image read -> shader write
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitImageReadThenWrite)3282 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitImageReadThenWrite)
3283 {
3284 ShaderWritePipeline writePipeline;
3285 WriteResource writeResource;
3286 NoopOp preBarrierOp;
3287 NoopOp postBarrierOp;
3288 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3289 &preBarrierOp, &postBarrierOp);
3290
3291 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3292
3293 // Looks like the implementation is missing this line from the spec:
3294 //
3295 // > Additionally, image stores issued after the barrier will not execute until all memory
3296 // > accesses (e.g., loads, stores, texture fetches, vertex fetches) initiated prior to the
3297 // > barrier complete.
3298 //
3299 // http://anglebug.com/5650
3300 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && writeResource == WriteResource::Image);
3301
3302 shaderImageAccessBitImageReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
3303 postBarrierOp);
3304 }
3305
3306 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitVertexReadThenWrite)3307 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitVertexReadThenWrite)
3308 {
3309 ShaderWritePipeline writePipeline;
3310 WriteResource writeResource;
3311 NoopOp preBarrierOp;
3312 NoopOp postBarrierOp;
3313 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3314 &preBarrierOp, &postBarrierOp);
3315
3316 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3317
3318 vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3319 postBarrierOp,
3320 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3321 }
3322
3323 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitIndexReadThenWrite)3324 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndexReadThenWrite)
3325 {
3326 ShaderWritePipeline writePipeline;
3327 WriteResource writeResource;
3328 NoopOp preBarrierOp;
3329 NoopOp postBarrierOp;
3330 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3331 &preBarrierOp, &postBarrierOp);
3332
3333 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3334
3335 elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3336 postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3337 }
3338
3339 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitUBOReadThenWrite)3340 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUBOReadThenWrite)
3341 {
3342 ShaderWritePipeline writePipeline;
3343 WriteResource writeResource;
3344 NoopOp preBarrierOp;
3345 NoopOp postBarrierOp;
3346 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3347 &preBarrierOp, &postBarrierOp);
3348
3349 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3350
3351 uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3352 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3353 }
3354
3355 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; sampler read -> shader write
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitSamplerReadThenWrite)3356 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitSamplerReadThenWrite)
3357 {
3358 ShaderWritePipeline writePipeline;
3359 WriteResource writeResource;
3360 NoopOp preBarrierOp;
3361 NoopOp postBarrierOp;
3362 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3363 &preBarrierOp, &postBarrierOp);
3364
3365 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3366
3367 textureFetchBitSamplerReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
3368 postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3369 }
3370
3371 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitIndirectReadThenWrite)3372 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndirectReadThenWrite)
3373 {
3374 ShaderWritePipeline writePipeline;
3375 WriteResource writeResource;
3376 NoopOp preBarrierOp;
3377 NoopOp postBarrierOp;
3378 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3379 &preBarrierOp, &postBarrierOp);
3380
3381 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3382
3383 commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3384 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3385 }
3386
3387 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitPackThenWrite)3388 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitPackThenWrite)
3389 {
3390 ShaderWritePipeline writePipeline;
3391 WriteResource writeResource;
3392 NoopOp preBarrierOp;
3393 NoopOp postBarrierOp;
3394 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3395 &preBarrierOp, &postBarrierOp);
3396
3397 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3398
3399 pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3400 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3401 }
3402
3403 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitUnpackThenWrite)3404 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUnpackThenWrite)
3405 {
3406 ShaderWritePipeline writePipeline;
3407 WriteResource writeResource;
3408 NoopOp preBarrierOp;
3409 NoopOp postBarrierOp;
3410 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3411 &preBarrierOp, &postBarrierOp);
3412
3413 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3414
3415 pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3416 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3417 }
3418
3419 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; texture copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitCopyThenWrite)3420 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitCopyThenWrite)
3421 {
3422 ShaderWritePipeline writePipeline;
3423 WriteResource writeResource;
3424 NoopOp preBarrierOp;
3425 NoopOp postBarrierOp;
3426 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3427 &preBarrierOp, &postBarrierOp);
3428
3429 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3430
3431 textureUpdateBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3432 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3433 }
3434
3435 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitCopyThenWrite)3436 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCopyThenWrite)
3437 {
3438 ShaderWritePipeline writePipeline;
3439 WriteResource writeResource;
3440 NoopOp preBarrierOp;
3441 NoopOp postBarrierOp;
3442 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3443 &preBarrierOp, &postBarrierOp);
3444
3445 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3446
3447 bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3448 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3449 }
3450
3451 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; draw -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitDrawThenWrite)3452 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitDrawThenWrite)
3453 {
3454 ShaderWritePipeline writePipeline;
3455 WriteResource writeResource;
3456 NoopOp preBarrierOp;
3457 NoopOp postBarrierOp;
3458 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3459 &preBarrierOp, &postBarrierOp);
3460
3461 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3462
3463 framebufferBitDrawThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3464 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3465 }
3466
3467 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; read pixels -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitReadPixelsThenWrite)3468 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitReadPixelsThenWrite)
3469 {
3470 ShaderWritePipeline writePipeline;
3471 WriteResource writeResource;
3472 NoopOp preBarrierOp;
3473 NoopOp postBarrierOp;
3474 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3475 &preBarrierOp, &postBarrierOp);
3476
3477 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3478
3479 framebufferBitReadPixelsThenImageWrite(writePipeline, writeResource, preBarrierOp,
3480 postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3481 }
3482
3483 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; fbo copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitFBOCopyThenWrite)3484 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitFBOCopyThenWrite)
3485 {
3486 ShaderWritePipeline writePipeline;
3487 WriteResource writeResource;
3488 NoopOp preBarrierOp;
3489 NoopOp postBarrierOp;
3490 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3491 &preBarrierOp, &postBarrierOp);
3492
3493 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3494
3495 framebufferBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3496 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3497 }
3498
3499 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; blit -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitBlitThenWrite)3500 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitBlitThenWrite)
3501 {
3502 ShaderWritePipeline writePipeline;
3503 WriteResource writeResource;
3504 NoopOp preBarrierOp;
3505 NoopOp postBarrierOp;
3506 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3507 &preBarrierOp, &postBarrierOp);
3508
3509 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3510
3511 framebufferBitBlitThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3512 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3513 }
3514
3515 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitCaptureThenWrite)3516 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCaptureThenWrite)
3517 {
3518 ShaderWritePipeline writePipeline;
3519 WriteResource writeResource;
3520 NoopOp preBarrierOp;
3521 NoopOp postBarrierOp;
3522 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3523 &preBarrierOp, &postBarrierOp);
3524
3525 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3526
3527 transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3528 postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3529 }
3530
3531 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitAtomicThenWrite)3532 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitAtomicThenWrite)
3533 {
3534 ShaderWritePipeline writePipeline;
3535 WriteResource writeResource;
3536 NoopOp preBarrierOp;
3537 NoopOp postBarrierOp;
3538 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3539 &preBarrierOp, &postBarrierOp);
3540
3541 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3542
3543 atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3544 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3545 }
3546
3547 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitBufferReadThenWrite)3548 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitBufferReadThenWrite)
3549 {
3550 ShaderWritePipeline writePipeline;
3551 WriteResource writeResource;
3552 NoopOp preBarrierOp;
3553 NoopOp postBarrierOp;
3554 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3555 &preBarrierOp, &postBarrierOp);
3556
3557 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3558
3559 shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3560 postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3561 }
3562
3563 // Test GL_COMMAND_BARRIER_BIT; shader write -> indirect read
TEST_P(MemoryBarrierBufferTest,CommandBitWriteThenIndirectRead)3564 TEST_P(MemoryBarrierBufferTest, CommandBitWriteThenIndirectRead)
3565 {
3566 ShaderWritePipeline writePipeline;
3567 WriteResource writeResource;
3568 NoopOp preBarrierOp;
3569 NoopOp postBarrierOp;
3570 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3571 &preBarrierOp, &postBarrierOp);
3572
3573 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3574
3575 commandBitBufferWriteThenIndirectRead(writePipeline, writeResource, preBarrierOp,
3576 postBarrierOp);
3577 }
3578
3579 // Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel pack
TEST_P(MemoryBarrierBufferTest,PixelBufferBitWriteThenPack)3580 TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenPack)
3581 {
3582 ShaderWritePipeline writePipeline;
3583 WriteResource writeResource;
3584 NoopOp preBarrierOp;
3585 NoopOp postBarrierOp;
3586 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3587 &preBarrierOp, &postBarrierOp);
3588
3589 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3590
3591 pixelBufferBitBufferWriteThenPack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3592 }
3593
3594 // Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel unpack
TEST_P(MemoryBarrierBufferTest,PixelBufferBitWriteThenUnpack)3595 TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenUnpack)
3596 {
3597 ShaderWritePipeline writePipeline;
3598 WriteResource writeResource;
3599 NoopOp preBarrierOp;
3600 NoopOp postBarrierOp;
3601 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3602 &preBarrierOp, &postBarrierOp);
3603
3604 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3605
3606 pixelBufferBitBufferWriteThenUnpack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3607 }
3608
3609 // Test GL_TEXTURE_UPDATE_BARRIER_BIT; shader write -> texture copy
TEST_P(MemoryBarrierImageOnlyTest,TextureUpdateBitWriteThenCopy)3610 TEST_P(MemoryBarrierImageOnlyTest, TextureUpdateBitWriteThenCopy)
3611 {
3612 ShaderWritePipeline writePipeline;
3613 WriteResource writeResource;
3614 NoopOp preBarrierOp;
3615 NoopOp postBarrierOp;
3616 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3617 &preBarrierOp, &postBarrierOp);
3618
3619 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3620
3621 textureUpdateBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3622 }
3623
3624 // Test GL_BUFFER_UPDATE_BARRIER_BIT; shader write -> buffer copy
TEST_P(MemoryBarrierBufferTest,BufferUpdateBitWriteThenCopy)3625 TEST_P(MemoryBarrierBufferTest, BufferUpdateBitWriteThenCopy)
3626 {
3627 ShaderWritePipeline writePipeline;
3628 WriteResource writeResource;
3629 NoopOp preBarrierOp;
3630 NoopOp postBarrierOp;
3631 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3632 &preBarrierOp, &postBarrierOp);
3633
3634 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3635
3636 bufferUpdateBitBufferWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3637 }
3638
3639 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> draw
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenDraw)3640 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenDraw)
3641 {
3642 ShaderWritePipeline writePipeline;
3643 WriteResource writeResource;
3644 NoopOp preBarrierOp;
3645 NoopOp postBarrierOp;
3646 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3647 &preBarrierOp, &postBarrierOp);
3648
3649 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3650
3651 framebufferBitImageWriteThenDraw(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3652 }
3653
3654 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> read pixels
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenReadPixels)3655 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenReadPixels)
3656 {
3657 ShaderWritePipeline writePipeline;
3658 WriteResource writeResource;
3659 NoopOp preBarrierOp;
3660 NoopOp postBarrierOp;
3661 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3662 &preBarrierOp, &postBarrierOp);
3663
3664 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3665
3666 framebufferBitImageWriteThenReadPixels(writePipeline, writeResource, preBarrierOp,
3667 postBarrierOp);
3668 }
3669
3670 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> copy
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenCopy)3671 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenCopy)
3672 {
3673 ShaderWritePipeline writePipeline;
3674 WriteResource writeResource;
3675 NoopOp preBarrierOp;
3676 NoopOp postBarrierOp;
3677 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3678 &preBarrierOp, &postBarrierOp);
3679
3680 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3681
3682 framebufferBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3683 }
3684
3685 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> blit
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenBlit)3686 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenBlit)
3687 {
3688 ShaderWritePipeline writePipeline;
3689 WriteResource writeResource;
3690 NoopOp preBarrierOp;
3691 NoopOp postBarrierOp;
3692 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3693 &preBarrierOp, &postBarrierOp);
3694
3695 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3696
3697 framebufferBitImageWriteThenBlit(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3698 }
3699
3700 // Test GL_TRANSFORM_FEEDBACK_BARRIER_BIT; shader write -> xfb capture
TEST_P(MemoryBarrierBufferTest,TransformFeedbackBitWriteThenCapture)3701 TEST_P(MemoryBarrierBufferTest, TransformFeedbackBitWriteThenCapture)
3702 {
3703 ShaderWritePipeline writePipeline;
3704 WriteResource writeResource;
3705 NoopOp preBarrierOp;
3706 NoopOp postBarrierOp;
3707 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3708 &preBarrierOp, &postBarrierOp);
3709
3710 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3711
3712 transformFeedbackBitBufferWriteThenCapture(writePipeline, writeResource, preBarrierOp,
3713 postBarrierOp);
3714 }
3715
3716 // Test GL_ATOMIC_COUNTER_BARRIER_BIT; shader write -> atomic write
TEST_P(MemoryBarrierBufferTest,AtomicCounterBitWriteThenAtomic)3717 TEST_P(MemoryBarrierBufferTest, AtomicCounterBitWriteThenAtomic)
3718 {
3719 ShaderWritePipeline writePipeline;
3720 WriteResource writeResource;
3721 NoopOp preBarrierOp;
3722 NoopOp postBarrierOp;
3723 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3724 &preBarrierOp, &postBarrierOp);
3725
3726 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3727
3728 atomicCounterBitBufferWriteThenAtomic(writePipeline, writeResource, preBarrierOp,
3729 postBarrierOp);
3730 }
3731
3732 // Test GL_SHADER_STORAGE_BARRIER_BIT; shader write -> shader read
TEST_P(MemoryBarrierBufferTest,ShaderStorageBitWriteThenRead)3733 TEST_P(MemoryBarrierBufferTest, ShaderStorageBitWriteThenRead)
3734 {
3735 ShaderWritePipeline writePipeline;
3736 WriteResource writeResource;
3737 NoopOp preBarrierOp;
3738 NoopOp postBarrierOp;
3739 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3740 &preBarrierOp, &postBarrierOp);
3741
3742 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3743
3744 shaderStorageBitBufferWriteThenBufferRead(writePipeline, writeResource, preBarrierOp,
3745 postBarrierOp);
3746 }
3747
3748 // Test GL_SHADER_STORAGE_BARRIER_BIT; shader read -> buffer write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitReadThenWrite)3749 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitReadThenWrite)
3750 {
3751 ShaderWritePipeline writePipeline;
3752 WriteResource writeResource;
3753 NoopOp preBarrierOp;
3754 NoopOp postBarrierOp;
3755 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3756 &preBarrierOp, &postBarrierOp);
3757
3758 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3759
3760 shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3761 postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3762 }
3763
3764 // Test GL_SHADER_STORAGE_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitVertexReadThenWrite)3765 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitVertexReadThenWrite)
3766 {
3767 ShaderWritePipeline writePipeline;
3768 WriteResource writeResource;
3769 NoopOp preBarrierOp;
3770 NoopOp postBarrierOp;
3771 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3772 &preBarrierOp, &postBarrierOp);
3773
3774 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3775
3776 vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3777 postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3778 }
3779
3780 // Test GL_SHADER_STORAGE_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitIndexReadThenWrite)3781 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndexReadThenWrite)
3782 {
3783 ShaderWritePipeline writePipeline;
3784 WriteResource writeResource;
3785 NoopOp preBarrierOp;
3786 NoopOp postBarrierOp;
3787 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3788 &preBarrierOp, &postBarrierOp);
3789
3790 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3791
3792 elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3793 postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3794 }
3795
3796 // Test GL_SHADER_STORAGE_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitUBOReadThenWrite)3797 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUBOReadThenWrite)
3798 {
3799 ShaderWritePipeline writePipeline;
3800 WriteResource writeResource;
3801 NoopOp preBarrierOp;
3802 NoopOp postBarrierOp;
3803 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3804 &preBarrierOp, &postBarrierOp);
3805
3806 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3807
3808 uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3809 GL_SHADER_STORAGE_BARRIER_BIT);
3810 }
3811
3812 // Test GL_SHADER_STORAGE_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitIndirectReadThenWrite)3813 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndirectReadThenWrite)
3814 {
3815 ShaderWritePipeline writePipeline;
3816 WriteResource writeResource;
3817 NoopOp preBarrierOp;
3818 NoopOp postBarrierOp;
3819 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3820 &preBarrierOp, &postBarrierOp);
3821
3822 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3823
3824 commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3825 GL_SHADER_STORAGE_BARRIER_BIT);
3826 }
3827
3828 // Test GL_SHADER_STORAGE_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitPackThenWrite)3829 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitPackThenWrite)
3830 {
3831 ShaderWritePipeline writePipeline;
3832 WriteResource writeResource;
3833 NoopOp preBarrierOp;
3834 NoopOp postBarrierOp;
3835 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3836 &preBarrierOp, &postBarrierOp);
3837
3838 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3839
3840 pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3841 GL_SHADER_STORAGE_BARRIER_BIT);
3842 }
3843
3844 // Test GL_SHADER_STORAGE_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitUnpackThenWrite)3845 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUnpackThenWrite)
3846 {
3847 ShaderWritePipeline writePipeline;
3848 WriteResource writeResource;
3849 NoopOp preBarrierOp;
3850 NoopOp postBarrierOp;
3851 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3852 &preBarrierOp, &postBarrierOp);
3853
3854 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3855
3856 pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3857 GL_SHADER_STORAGE_BARRIER_BIT);
3858 }
3859
3860 // Test GL_SHADER_STORAGE_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitCopyThenWrite)3861 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCopyThenWrite)
3862 {
3863 ShaderWritePipeline writePipeline;
3864 WriteResource writeResource;
3865 NoopOp preBarrierOp;
3866 NoopOp postBarrierOp;
3867 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3868 &preBarrierOp, &postBarrierOp);
3869
3870 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3871
3872 bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3873 GL_SHADER_STORAGE_BARRIER_BIT);
3874 }
3875
3876 // Test GL_SHADER_STORAGE_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitCaptureThenWrite)3877 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCaptureThenWrite)
3878 {
3879 ShaderWritePipeline writePipeline;
3880 WriteResource writeResource;
3881 NoopOp preBarrierOp;
3882 NoopOp postBarrierOp;
3883 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3884 &preBarrierOp, &postBarrierOp);
3885
3886 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3887
3888 transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3889 postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3890 }
3891
3892 // Test GL_SHADER_STORAGE_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitAtomicThenWrite)3893 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitAtomicThenWrite)
3894 {
3895 ShaderWritePipeline writePipeline;
3896 WriteResource writeResource;
3897 NoopOp preBarrierOp;
3898 NoopOp postBarrierOp;
3899 ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3900 &preBarrierOp, &postBarrierOp);
3901
3902 ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3903
3904 atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3905 GL_SHADER_STORAGE_BARRIER_BIT);
3906 }
3907
3908 constexpr ShaderWritePipeline kWritePipelines[] = {
3909 ShaderWritePipeline::Graphics,
3910 ShaderWritePipeline::Compute,
3911 };
3912 constexpr WriteResource kBufferWriteResources[] = {
3913 WriteResource::Buffer,
3914 WriteResource::ImageBuffer,
3915 };
3916 constexpr WriteResource kImageWriteResources[] = {
3917 WriteResource::Image,
3918 WriteResource::ImageBuffer,
3919 };
3920 constexpr WriteResource kImageBufferOnlyWriteResources[] = {
3921 WriteResource::ImageBuffer,
3922 };
3923 constexpr WriteResource kImageOnlyWriteResources[] = {
3924 WriteResource::Image,
3925 };
3926 constexpr WriteResource kBufferOnlyWriteResources[] = {
3927 WriteResource::Buffer,
3928 };
3929 constexpr NoopOp kNoopOps[] = {
3930 NoopOp::None,
3931 NoopOp::Draw,
3932 NoopOp::Dispatch,
3933 };
3934
3935 // Note: due to large number of tests, these are only run on Vulkan and a single configuration
3936 // (swiftshader).
3937
3938 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferTest);
3939 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferTest,
3940 MemoryBarrierVariationsTestPrint,
3941 testing::ValuesIn(kWritePipelines),
3942 testing::ValuesIn(kBufferWriteResources),
3943 testing::ValuesIn(kNoopOps),
3944 testing::ValuesIn(kNoopOps),
3945 ES31_VULKAN_SWIFTSHADER());
3946
3947 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageTest);
3948 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageTest,
3949 MemoryBarrierVariationsTestPrint,
3950 testing::ValuesIn(kWritePipelines),
3951 testing::ValuesIn(kImageWriteResources),
3952 testing::ValuesIn(kNoopOps),
3953 testing::ValuesIn(kNoopOps),
3954 ES31_VULKAN_SWIFTSHADER());
3955
3956 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageBufferOnlyTest);
3957 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageBufferOnlyTest,
3958 MemoryBarrierVariationsTestPrint,
3959 testing::ValuesIn(kWritePipelines),
3960 testing::ValuesIn(kImageBufferOnlyWriteResources),
3961 testing::ValuesIn(kNoopOps),
3962 testing::ValuesIn(kNoopOps),
3963 ES31_VULKAN_SWIFTSHADER());
3964
3965 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageOnlyTest);
3966 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageOnlyTest,
3967 MemoryBarrierVariationsTestPrint,
3968 testing::ValuesIn(kWritePipelines),
3969 testing::ValuesIn(kImageOnlyWriteResources),
3970 testing::ValuesIn(kNoopOps),
3971 testing::ValuesIn(kNoopOps),
3972 ES31_VULKAN_SWIFTSHADER());
3973
3974 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferOnlyTest);
3975 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferOnlyTest,
3976 MemoryBarrierVariationsTestPrint,
3977 testing::ValuesIn(kWritePipelines),
3978 testing::ValuesIn(kBufferOnlyWriteResources),
3979 testing::ValuesIn(kNoopOps),
3980 testing::ValuesIn(kNoopOps),
3981 ES31_VULKAN_SWIFTSHADER());
3982
3983 } // anonymous namespace
3984