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