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