1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file
21 * \brief
22 */ /*-------------------------------------------------------------------*/
23
24 #include "deInt32.h"
25 #include "es31cShaderStorageBufferObjectTests.hpp"
26 #include "glwEnums.hpp"
27 #include "tcuMatrix.hpp"
28 #include "tcuMatrixUtil.hpp"
29 #include "tcuRenderTarget.hpp"
30 #include <assert.h>
31 #include <cmath>
32 #include <cstdarg>
33
34 namespace glcts
35 {
36 using namespace glw;
37
38 namespace
39 {
40 typedef tcu::Vec2 vec2;
41 typedef tcu::Vec3 vec3;
42 typedef tcu::Vec4 vec4;
43 typedef tcu::IVec4 ivec4;
44 typedef tcu::UVec4 uvec4;
45 typedef tcu::Mat4 mat4;
46
47 enum ShaderStage
48 {
49 vertex,
50 fragment,
51 compute
52 };
53 enum BufferLayout
54 {
55 std140,
56 std430,
57 shared,
58 packed
59 };
60 enum ElementType
61 {
62 vector,
63 matrix_cm,
64 matrix_rm,
65 structure
66 };
67 enum BindingSeq
68 {
69 bindbasebefore,
70 bindbaseafter,
71 bindrangeoffset,
72 bindrangesize
73 };
74
75 const char *const kGLSLVer = "#version 310 es" NL "precision highp float;" NL "precision highp int;";
76
77 class ShaderStorageBufferObjectBase : public glcts::SubcaseBase
78 {
Title()79 virtual std::string Title()
80 {
81 return "";
82 }
83
Purpose()84 virtual std::string Purpose()
85 {
86 return "";
87 }
88
Method()89 virtual std::string Method()
90 {
91 return "";
92 }
93
PassCriteria()94 virtual std::string PassCriteria()
95 {
96 return "";
97 }
98
99 public:
IsVSFSAvailable(int requiredVS,int requiredFS)100 bool IsVSFSAvailable(int requiredVS, int requiredFS)
101 {
102 GLint blocksVS, blocksFS;
103 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &blocksVS);
104 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &blocksFS);
105 if (blocksVS >= requiredVS && blocksFS >= requiredFS)
106 return true;
107 else
108 {
109 std::ostringstream reason;
110 reason << "Required " << requiredVS << " VS storage blocks but only " << blocksVS << " available."
111 << std::endl
112 << "Required " << requiredFS << " FS storage blocks but only " << blocksFS << " available."
113 << std::endl;
114 OutputNotSupported(reason.str());
115 return false;
116 }
117 }
118
getWindowWidth()119 int getWindowWidth()
120 {
121 const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
122 return renderTarget.getWidth();
123 }
124
getWindowHeight()125 int getWindowHeight()
126 {
127 const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
128 return renderTarget.getHeight();
129 }
130
CheckProgram(GLuint program)131 bool CheckProgram(GLuint program)
132 {
133 GLint status;
134 glGetProgramiv(program, GL_LINK_STATUS, &status);
135
136 if (status == GL_FALSE)
137 {
138 GLint attached_shaders;
139 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
140
141 if (attached_shaders > 0)
142 {
143 std::vector<GLuint> shaders(attached_shaders);
144 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
145
146 for (GLint i = 0; i < attached_shaders; ++i)
147 {
148 GLenum type;
149 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
150 switch (type)
151 {
152 case GL_VERTEX_SHADER:
153 m_context.getTestContext().getLog()
154 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
155 break;
156 case GL_FRAGMENT_SHADER:
157 m_context.getTestContext().getLog()
158 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
159 break;
160 default:
161 m_context.getTestContext().getLog()
162 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
163 break;
164 }
165 GLint length;
166 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
167 if (length > 0)
168 {
169 std::vector<GLchar> source(length);
170 glGetShaderSource(shaders[i], length, NULL, &source[0]);
171 m_context.getTestContext().getLog()
172 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
173 }
174 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
175 if (length > 0)
176 {
177 std::vector<GLchar> log(length);
178 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
179 m_context.getTestContext().getLog()
180 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
181 }
182 }
183 }
184 GLint length;
185 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
186 if (length > 0)
187 {
188 std::vector<GLchar> log(length);
189 glGetProgramInfoLog(program, length, NULL, &log[0]);
190 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
191 }
192 }
193
194 return status == GL_TRUE ? true : false;
195 }
196
CreateProgram(const std::string & vs,const std::string & fs)197 GLuint CreateProgram(const std::string &vs, const std::string &fs)
198 {
199 const GLuint p = glCreateProgram();
200
201 if (!vs.empty())
202 {
203 const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
204 glAttachShader(p, sh);
205 glDeleteShader(sh);
206 const char *const src[2] = {kGLSLVer, vs.c_str()};
207 glShaderSource(sh, 2, src, NULL);
208 glCompileShader(sh);
209 }
210 if (!fs.empty())
211 {
212 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
213 glAttachShader(p, sh);
214 glDeleteShader(sh);
215 const char *const src[2] = {kGLSLVer, fs.c_str()};
216 glShaderSource(sh, 2, src, NULL);
217 glCompileShader(sh);
218 }
219
220 return p;
221 }
222
CreateProgramCS(const std::string & cs)223 GLuint CreateProgramCS(const std::string &cs)
224 {
225 const GLuint p = glCreateProgram();
226
227 if (!cs.empty())
228 {
229 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
230 glAttachShader(p, sh);
231 glDeleteShader(sh);
232 const char *const src[2] = {kGLSLVer, cs.c_str()};
233 glShaderSource(sh, 2, src, NULL);
234 glCompileShader(sh);
235 }
236 return p;
237 }
238
BuildShaderProgram(GLenum type,const std::string & source)239 GLuint BuildShaderProgram(GLenum type, const std::string &source)
240 {
241 const char *const src[2] = {kGLSLVer, source.c_str()};
242 return glCreateShaderProgramv(type, 2, src);
243 }
244
ColorEqual(int x,int y,const vec3 & c0,const vec3 & expected,const vec3 & epsilon,const vec3 & color_max)245 bool ColorEqual(int x, int y, const vec3 &c0, const vec3 &expected, const vec3 &epsilon, const vec3 &color_max)
246 {
247 bool status = true;
248 if (fabs(c0[0] / color_max[0] - expected[0]) > epsilon[0])
249 status = false;
250 if (fabs(c0[1] / color_max[1] - expected[1]) > epsilon[1])
251 status = false;
252 if (fabs(c0[2] / color_max[2] - expected[2]) > epsilon[2])
253 status = false;
254
255 if (!status)
256 m_context.getTestContext().getLog()
257 << tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << " " << y << "). Color is ("
258 << c0[0] / color_max[0] << " " << c0[1] / color_max[1] << " " << c0[2] / color_max[2]
259 << "). Color should be (" << expected[0] << " " << expected[1] << " " << expected[2] << ")."
260 << tcu::TestLog::EndMessage;
261 return status;
262 }
263
CheckFB(vec3 expected)264 bool CheckFB(vec3 expected)
265 {
266 const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
267 const tcu::PixelFormat &pixelFormat = renderTarget.getPixelFormat();
268 vec3 g_color_eps = vec3(1.f / static_cast<float>(1 << pixelFormat.redBits),
269 1.f / static_cast<float>(1 << pixelFormat.greenBits),
270 1.f / static_cast<float>(1 << pixelFormat.blueBits));
271 vec3 g_color_max = vec3(255);
272 std::vector<GLubyte> fb(getWindowWidth() * getWindowHeight() * 4);
273 int fb_w = getWindowWidth();
274 int fb_h = getWindowHeight();
275 glReadPixels(0, 0, fb_w, fb_h, GL_RGBA, GL_UNSIGNED_BYTE, &fb[0]);
276 for (GLint i = 0, y = 0; y < fb_h; ++y)
277 for (GLint x = 0; x < fb_w; ++x, i += 4)
278 {
279 if (fabs(fb[i + 0] / g_color_max[0] - expected[0]) > g_color_eps[0] ||
280 fabs(fb[i + 1] / g_color_max[1] - expected[1]) > g_color_eps[1] ||
281 fabs(fb[i + 2] / g_color_max[2] - expected[2]) > g_color_eps[2])
282 {
283 m_context.getTestContext().getLog()
284 << tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << " " << y
285 << "). Color is (" << fb[i + 0] / g_color_max[0] << " " << fb[i + 1] / g_color_max[1] << " "
286 << fb[i + 2] / g_color_max[2] << "). Color should be (" << expected[0] << " " << expected[1]
287 << " " << expected[2] << ")." << tcu::TestLog::EndMessage;
288 return false;
289 }
290 }
291 return true;
292 }
293
ValidateWindow4Quads(const vec3 & lb,const vec3 & rb,const vec3 & rt,const vec3 & lt,int * bad_pixels=NULL)294 bool ValidateWindow4Quads(const vec3 &lb, const vec3 &rb, const vec3 &rt, const vec3 <, int *bad_pixels = NULL)
295 {
296 const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
297 const tcu::PixelFormat &pixelFormat = renderTarget.getPixelFormat();
298 vec3 g_color_eps = vec3(1.f / static_cast<float>(1 << pixelFormat.redBits),
299 1.f / static_cast<float>(1 << pixelFormat.greenBits),
300 1.f / static_cast<float>(1 << pixelFormat.blueBits));
301 vec3 g_color_max = vec3(255);
302
303 const int width = 100;
304 const int height = 100;
305 std::vector<GLubyte> fb(width * height * 4);
306 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &fb[0]);
307
308 bool status = true;
309 int bad = 0;
310
311 // left-bottom quad
312 for (int y = 10, i = (100 * 10 + 10) * 4; y < height / 2 - 10; ++y, i += 70 * 4)
313 {
314 for (int x = 10; x < width / 2 - 10; ++x, i += 4)
315 {
316 const vec3 c = vec3(fb[i], fb[i + 1], fb[i + 2]);
317 if (!ColorEqual(x, y, c, lb, g_color_eps, g_color_max))
318 {
319 status = false;
320 bad++;
321 }
322 }
323 }
324 if (!status)
325 {
326 m_context.getTestContext().getLog()
327 << tcu::TestLog::Message << "Left-bottom quad checking failed. Bad pixels: " << bad
328 << tcu::TestLog::EndMessage;
329 //return status;
330 }
331 // right-bottom quad
332 for (int y = 10, i = (100 * 10 + 60) * 4; y < height / 2 - 10; ++y, i += 70 * 4)
333 {
334 for (int x = width / 2 + 10; x < width - 10; ++x, i += 4)
335 {
336 const vec3 c = vec3(fb[i], fb[i + 1], fb[i + 2]);
337 if (!ColorEqual(x, y, c, rb, g_color_eps, g_color_max))
338 {
339 status = false;
340 bad++;
341 }
342 }
343 }
344 if (!status)
345 {
346 m_context.getTestContext().getLog()
347 << tcu::TestLog::Message << "Right-bottom quad checking failed. Bad pixels: " << bad
348 << tcu::TestLog::EndMessage;
349 //return status;
350 }
351 // right-top quad
352 for (int y = height / 2 + 10, i = (100 * 60 + 60) * 4; y < height - 10; ++y, i += 70 * 4)
353 {
354 for (int x = width / 2 + 10; x < width - 10; ++x, i += 4)
355 {
356 const vec3 c = vec3(fb[i], fb[i + 1], fb[i + 2]);
357 if (!ColorEqual(x, y, c, rt, g_color_eps, g_color_max))
358 {
359 status = false;
360 bad++;
361 }
362 }
363 }
364 if (!status)
365 {
366 m_context.getTestContext().getLog()
367 << tcu::TestLog::Message << "Right-top quad checking failed. Bad pixels: " << bad
368 << tcu::TestLog::EndMessage;
369 //return status;
370 }
371 // left-top quad
372 for (int y = height / 2 + 10, i = (100 * 60 + 10) * 4; y < height - 10; ++y, i += 70 * 4)
373 {
374 for (int x = 10; x < width / 2 - 10; ++x, i += 4)
375 {
376 const vec3 c = vec3(fb[i], fb[i + 1], fb[i + 2]);
377 if (!ColorEqual(x, y, c, lt, g_color_eps, g_color_max))
378 {
379 status = false;
380 bad++;
381 }
382 }
383 }
384 if (!status)
385 {
386 m_context.getTestContext().getLog()
387 << tcu::TestLog::Message << "Left-top quad checking failed. Bad pixels: " << bad
388 << tcu::TestLog::EndMessage;
389 //return status;
390 }
391 // middle horizontal line should be black
392 for (int y = height / 2 - 2, i = (100 * 48) * 4; y < height / 2 + 2; ++y)
393 {
394 for (int x = 0; x < width; ++x, i += 4)
395 {
396 const vec3 c = vec3(fb[i], fb[i + 1], fb[i + 2]);
397 if (!ColorEqual(x, y, c, vec3(0), g_color_eps, g_color_max))
398 {
399 status = false;
400 bad++;
401 }
402 }
403 }
404 if (!status)
405 {
406 m_context.getTestContext().getLog()
407 << tcu::TestLog::Message << "Middle horizontal line checking failed. Bad pixels: " << bad
408 << tcu::TestLog::EndMessage;
409 //return status;
410 }
411 // middle vertical line should be black
412 for (int y = 0, i = 48 * 4; y < height; ++y, i += 96 * 4)
413 {
414 for (int x = width / 2 - 2; x < width / 2 + 2; ++x, i += 4)
415 {
416 const vec3 c = vec3(fb[i], fb[i + 1], fb[i + 2]);
417 if (!ColorEqual(x, y, c, vec3(0), g_color_eps, g_color_max))
418 {
419 status = false;
420 bad++;
421 }
422 }
423 }
424 if (!status)
425 {
426 m_context.getTestContext().getLog()
427 << tcu::TestLog::Message << "Middle vertical line checking failed. Bad pixels: " << bad
428 << tcu::TestLog::EndMessage;
429 //return status;
430 }
431
432 if (bad_pixels)
433 *bad_pixels = bad;
434 m_context.getTestContext().getLog()
435 << tcu::TestLog::Message << "Bad pixels: " << (bad_pixels == NULL ? 0 : *bad_pixels)
436 << ", counted bad: " << bad << tcu::TestLog::EndMessage;
437 return status;
438 }
439
Translation(float tx,float ty,float tz)440 const mat4 Translation(float tx, float ty, float tz)
441 {
442 float d[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, tx, ty, tz, 1.0f};
443 return mat4(d);
444 }
445
GLenumToString(GLenum e)446 const char *GLenumToString(GLenum e)
447 {
448 switch (e)
449 {
450 case GL_SHADER_STORAGE_BUFFER_BINDING:
451 return "GL_SHADER_STORAGE_BUFFER_BINDING";
452 case GL_SHADER_STORAGE_BUFFER_START:
453 return "GL_SHADER_STORAGE_BUFFER_START";
454 case GL_SHADER_STORAGE_BUFFER_SIZE:
455 return "GL_SHADER_STORAGE_BUFFER_SIZE";
456 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
457 return "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS";
458 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
459 return "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS";
460 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
461 return "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS";
462 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
463 return "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS";
464 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
465 return "GL_MAX_SHADER_STORAGE_BLOCK_SIZE";
466 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
467 return "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS";
468 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
469 return "GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES";
470 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
471 return "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT";
472
473 default:
474 assert(0);
475 break;
476 }
477 return NULL;
478 }
479 };
480
481 //-----------------------------------------------------------------------------
482 // 1.1 BasicBasic
483 //-----------------------------------------------------------------------------
484 class BasicBasicVS : public ShaderStorageBufferObjectBase
485 {
486 GLuint m_program;
487 GLuint m_buffer;
488 GLuint m_vertex_array;
489
Setup()490 virtual long Setup()
491 {
492 m_program = 0;
493 m_buffer = 0;
494 m_vertex_array = 0;
495 return NO_ERROR;
496 }
497
Run()498 virtual long Run()
499 {
500 if (!IsVSFSAvailable(1, 0))
501 return NOT_SUPPORTED;
502 const char *const glsl_vs =
503 NL "layout(std430, binding = 1) buffer InputBuffer {" NL " vec4 position[3];" NL "} g_input_buffer;" NL
504 "void main() {" NL " gl_Position = g_input_buffer.position[gl_VertexID];" NL "}";
505 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
506 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
507 m_program = CreateProgram(glsl_vs, glsl_fs);
508 glLinkProgram(m_program);
509 if (!CheckProgram(m_program))
510 return ERROR;
511
512 const float data[12] = {-1.0f, -1.0f, 0.0f, 1.0f, 3.0f, -1.0f, 0.0f, 1.0f, -1.0f, 3.0f, 0.0f, 1.0f};
513 glGenBuffers(1, &m_buffer);
514 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer);
515 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
516 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
517
518 glGenVertexArrays(1, &m_vertex_array);
519 glBindVertexArray(m_vertex_array);
520
521 glUseProgram(m_program);
522 glClear(GL_COLOR_BUFFER_BIT);
523 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer);
524 glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1);
525 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
526
527 if (!CheckFB(vec3(0, 1, 0)))
528 return ERROR;
529 else
530 return NO_ERROR;
531 }
532
Cleanup()533 virtual long Cleanup()
534 {
535 glUseProgram(0);
536 glDeleteProgram(m_program);
537 glDeleteBuffers(1, &m_buffer);
538 glDeleteVertexArrays(1, &m_vertex_array);
539 return NO_ERROR;
540 }
541 };
542
543 class BasicBasicCS : public ShaderStorageBufferObjectBase
544 {
545 GLuint m_program;
546 GLuint m_buffer;
547
Setup()548 virtual long Setup()
549 {
550 m_program = 0;
551 m_buffer = 0;
552 return NO_ERROR;
553 }
554
Run()555 virtual long Run()
556 {
557 const char *const glsl_cs = NL "layout(local_size_x = 1) in;" NL "buffer Buffer {" NL " int result;" NL "};" NL
558 "void main() {" NL " result = 7;" NL "}";
559 m_program = CreateProgramCS(glsl_cs);
560 glLinkProgram(m_program);
561 if (!CheckProgram(m_program))
562 return ERROR;
563
564 glGenBuffers(1, &m_buffer);
565 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer);
566 glBufferData(GL_SHADER_STORAGE_BUFFER, 4, 0, GL_STATIC_READ);
567 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
568
569 glUseProgram(m_program);
570 glDispatchCompute(1, 1, 1);
571 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
572
573 GLint *out_data = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
574 if (!out_data)
575 return ERROR;
576 if (*out_data == 7)
577 return NO_ERROR;
578 else
579 return ERROR;
580 }
581
Cleanup()582 virtual long Cleanup()
583 {
584 glUseProgram(0);
585 glDeleteProgram(m_program);
586 glDeleteBuffers(1, &m_buffer);
587 return NO_ERROR;
588 }
589 };
590
591 //-----------------------------------------------------------------------------
592 // 1.2 BasicMax
593 //-----------------------------------------------------------------------------
594 class BasicMax : public ShaderStorageBufferObjectBase
595 {
Check(GLenum e,GLint64 value,bool max_value)596 bool Check(GLenum e, GLint64 value, bool max_value)
597 {
598 GLint i;
599 GLint64 i64;
600 GLfloat f;
601 GLboolean b;
602
603 glGetIntegerv(e, &i);
604 glGetInteger64v(e, &i64);
605 glGetFloatv(e, &f);
606 glGetBooleanv(e, &b);
607
608 bool status = true;
609 if (max_value)
610 {
611 if (static_cast<GLint64>(i) < value)
612 status = false;
613 if (i64 < value)
614 status = false;
615 if (static_cast<GLint64>(f) < value)
616 status = false;
617
618 if (!status)
619 {
620 m_context.getTestContext().getLog()
621 << tcu::TestLog::Message << GLenumToString(e) << " is " << i << " should be at least "
622 << static_cast<GLint>(value) << tcu::TestLog::EndMessage;
623 }
624 }
625 else
626 {
627 if (static_cast<GLint64>(i) > value)
628 status = false;
629 if (i64 > value)
630 status = false;
631 if (static_cast<GLint64>(f) > value)
632 status = false;
633
634 if (!status)
635 {
636 m_context.getTestContext().getLog()
637 << tcu::TestLog::Message << GLenumToString(e) << " is " << i << " should be at most "
638 << static_cast<GLint>(value) << tcu::TestLog::EndMessage;
639 }
640 }
641 return status;
642 }
643
Run()644 virtual long Run()
645 {
646 if (!Check(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, 0, true))
647 return ERROR;
648 if (!Check(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, 0, true))
649 return ERROR;
650 if (!Check(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, 4, true))
651 return ERROR;
652 if (!Check(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, 4, true))
653 return ERROR;
654 if (!Check(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, 134217728 /* 2^27 */, true))
655 return ERROR;
656 if (!Check(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, 4, true))
657 return ERROR;
658 if (!Check(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, 4, true))
659 return ERROR;
660 if (!Check(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, 256, false))
661 return ERROR;
662 return NO_ERROR;
663 }
664 };
665 //-----------------------------------------------------------------------------
666 // 1.3 BasicBinding
667 //-----------------------------------------------------------------------------
668 class BasicBinding : public ShaderStorageBufferObjectBase
669 {
670 GLuint m_buffer[4];
671
Check(GLenum e,GLuint expected)672 bool Check(GLenum e, GLuint expected)
673 {
674 GLint i;
675 GLint64 i64;
676 GLfloat f;
677 GLboolean b;
678
679 GLfloat expectedFloat = static_cast<GLfloat>(expected);
680
681 glGetIntegerv(e, &i);
682 glGetInteger64v(e, &i64);
683 glGetFloatv(e, &f);
684 glGetBooleanv(e, &b);
685
686 bool status = true;
687 if (static_cast<GLuint>(i) != expected)
688 status = false;
689 if (static_cast<GLuint>(i64) != expected)
690 status = false;
691 if (static_cast<GLuint>(f) != expectedFloat)
692 status = false;
693 if (b != (expected != 0 ? GL_TRUE : GL_FALSE))
694 status = false;
695
696 if (!status)
697 {
698 m_context.getTestContext().getLog() << tcu::TestLog::Message << GLenumToString(e) << " is " << i
699 << " should be " << expected << tcu::TestLog::EndMessage;
700 }
701 return status;
702 }
703
CheckIndexed(GLenum e,GLuint index,GLuint expected)704 bool CheckIndexed(GLenum e, GLuint index, GLuint expected)
705 {
706 GLint i;
707 GLint64 i64;
708
709 glGetIntegeri_v(e, index, &i);
710 glGetInteger64i_v(e, index, &i64);
711
712 bool status = true;
713 if (static_cast<GLuint>(i) != expected)
714 status = false;
715 if (static_cast<GLuint>(i64) != expected)
716 status = false;
717
718 if (!status)
719 {
720 m_context.getTestContext().getLog() << tcu::TestLog::Message << GLenumToString(e) << " at index " << index
721 << " is " << i << " should be " << expected << tcu::TestLog::EndMessage;
722 }
723 return status;
724 }
725
Setup()726 virtual long Setup()
727 {
728 memset(m_buffer, 0, sizeof(m_buffer));
729 return NO_ERROR;
730 }
731
Run()732 virtual long Run()
733 {
734 GLint maxShaderStorageBufferBindings = 0;
735 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
736
737 GLint alignment;
738 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
739
740 // check default state
741 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, 0))
742 return ERROR;
743 for (GLint i = 0; i < maxShaderStorageBufferBindings; ++i)
744 {
745 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, i, 0))
746 return ERROR;
747 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, i, 0))
748 return ERROR;
749 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, i, 0))
750 return ERROR;
751 }
752
753 glGenBuffers(4, m_buffer);
754 for (GLint i = 0; i < maxShaderStorageBufferBindings; ++i)
755 {
756 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_buffer[0]);
757
758 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, m_buffer[0]))
759 return ERROR;
760 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, i, m_buffer[0]))
761 return ERROR;
762 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, i, 0))
763 return ERROR;
764 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, i, 0))
765 return ERROR;
766
767 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, 0);
768
769 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, 0))
770 return ERROR;
771 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, i, 0))
772 return ERROR;
773 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, i, 0))
774 return ERROR;
775 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, i, 0))
776 return ERROR;
777 }
778
779 GLint offset = deRoundUp32(256, alignment);
780 for (GLint i = 0; i < maxShaderStorageBufferBindings; ++i)
781 {
782 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, m_buffer[0], offset, 512);
783
784 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, m_buffer[0]))
785 return ERROR;
786 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, i, m_buffer[0]))
787 return ERROR;
788 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, i, offset))
789 return ERROR;
790 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, i, 512))
791 return ERROR;
792
793 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, 0, offset * 2, 128);
794
795 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, 0))
796 return ERROR;
797 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, i, 0))
798 return ERROR;
799 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, i, 0))
800 return ERROR;
801 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, i, 0))
802 return ERROR;
803
804 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, 0, 0, 0);
805
806 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, 0))
807 return ERROR;
808 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, i, 0))
809 return ERROR;
810 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, i, 0))
811 return ERROR;
812 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, i, 0))
813 return ERROR;
814 }
815
816 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[2]);
817 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, m_buffer[2]))
818 return ERROR;
819 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, 0, m_buffer[2]))
820 return ERROR;
821 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, 0, 0))
822 return ERROR;
823 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, 0, 0))
824 return ERROR;
825
826 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, m_buffer[3]);
827 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, m_buffer[3]))
828 return ERROR;
829 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, 5, m_buffer[3]))
830 return ERROR;
831 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, 5, 0))
832 return ERROR;
833 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, 5, 0))
834 return ERROR;
835
836 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 7, m_buffer[1], offset * 8, 1000);
837 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, m_buffer[1]))
838 return ERROR;
839 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, 7, m_buffer[1]))
840 return ERROR;
841 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_START, 7, offset * 8))
842 return ERROR;
843 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_SIZE, 7, 1000))
844 return ERROR;
845
846 glDeleteBuffers(4, m_buffer);
847 memset(m_buffer, 0, sizeof(m_buffer));
848
849 if (!Check(GL_SHADER_STORAGE_BUFFER_BINDING, 0))
850 return ERROR;
851 for (GLint i = 0; i < maxShaderStorageBufferBindings; ++i)
852 {
853 if (!CheckIndexed(GL_SHADER_STORAGE_BUFFER_BINDING, i, 0))
854 return ERROR;
855 }
856
857 return NO_ERROR;
858 }
859
Cleanup()860 virtual long Cleanup()
861 {
862 glDeleteBuffers(4, m_buffer);
863 return NO_ERROR;
864 }
865 };
866 //-----------------------------------------------------------------------------
867 // 1.4 BasicSyntax
868 //-----------------------------------------------------------------------------
869 class BasicSyntaxVS : public ShaderStorageBufferObjectBase
870 {
871 GLuint m_program;
872 GLuint m_buffer;
873 GLuint m_vertex_array;
874
RunIteration(const char * vs,const char * fs)875 bool RunIteration(const char *vs, const char *fs)
876 {
877 if (m_program != 0)
878 glDeleteProgram(m_program);
879 m_program = CreateProgram(vs, fs);
880 glLinkProgram(m_program);
881 if (!CheckProgram(m_program))
882 return false;
883
884 glClear(GL_COLOR_BUFFER_BIT);
885 glUseProgram(m_program);
886 glDrawArrays(GL_TRIANGLES, 0, 3);
887
888 return CheckFB(vec3(0, 1, 0));
889 }
890
Setup()891 virtual long Setup()
892 {
893 m_program = 0;
894 m_buffer = 0;
895 m_vertex_array = 0;
896 return NO_ERROR;
897 }
898
Run()899 virtual long Run()
900 {
901 if (!IsVSFSAvailable(1, 0))
902 return NOT_SUPPORTED;
903
904 const int kCount = 8;
905 const char *const glsl_vs[kCount] = {
906 NL "layout(std430) buffer Buffer {" NL " vec4 position[3];" NL "} g_input_buffer;" NL "void main() {" NL
907 " gl_Position = g_input_buffer.position[gl_VertexID];" NL "}",
908 NL "coherent buffer Buffer {" NL " buffer vec4 position0;" NL " coherent vec4 position1;" NL
909 " restrict readonly vec4 position2;" NL "} g_input_buffer;" NL "void main() {" NL
910 " if (gl_VertexID == 0) gl_Position = g_input_buffer.position0;" NL
911 " if (gl_VertexID == 1) gl_Position = g_input_buffer.position1;" NL
912 " if (gl_VertexID == 2) gl_Position = g_input_buffer.position2;" NL "}",
913 NL "layout(std140, binding = 0) readonly buffer Buffer {" NL " readonly vec4 position[];" NL "};" NL
914 "void main() {" NL " gl_Position = position[gl_VertexID];" NL "}",
915 NL "layout(std430, column_major, std140, std430, row_major, packed, shared) buffer;" NL
916 "layout(std430) buffer;" NL "coherent restrict volatile buffer Buffer {" NL
917 " restrict coherent vec4 position[];" NL "} g_buffer;" NL "void main() {" NL
918 " gl_Position = g_buffer.position[gl_VertexID];" NL "}",
919 NL "buffer Buffer {" NL " vec4 position[3];" //
920 NL "} g_buffer[1];" NL "void main() {" NL " gl_Position = g_buffer[0].position[gl_VertexID];" NL "}",
921 NL "layout(shared) coherent buffer Buffer {" NL " restrict volatile vec4 position0;" NL
922 " buffer readonly vec4 position1;" NL " vec4 position2;" NL "} g_buffer[1];" NL "void main() {" NL
923 " if (gl_VertexID == 0) gl_Position = g_buffer[0].position0;" NL
924 " else if (gl_VertexID == 1) gl_Position = g_buffer[0].position1;" NL
925 " else if (gl_VertexID == 2) gl_Position = g_buffer[0].position2;" NL "}",
926 NL "layout(packed) coherent buffer Buffer {" NL " vec4 position01[2];" NL " vec4 position2;" NL
927 "} g_buffer;" NL "void main() {" NL " if (gl_VertexID == 0) gl_Position = g_buffer.position01[0];" NL
928 " else if (gl_VertexID == 1) gl_Position = g_buffer.position01[1];" NL
929 " else if (gl_VertexID == 2) gl_Position = g_buffer.position2;" NL "}",
930 NL "layout(std430) coherent buffer Buffer {" NL " coherent vec4 position01[2];" NL " vec4 position2[];" NL
931 "} g_buffer;" NL "void main() {" NL " switch (gl_VertexID) {" NL
932 " case 0: gl_Position = g_buffer.position01[0]; break;" NL
933 " case 1: gl_Position = g_buffer.position01[1]; break;" NL
934 " case 2: gl_Position = g_buffer.position2[gl_VertexID - 2]; break;" NL " }" NL "}",
935 };
936 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
937 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
938
939 const float data[12] = {-1.0f, -1.0f, 0.0f, 1.0f, 3.0f, -1.0f, 0.0f, 1.0f, -1.0f, 3.0f, 0.0f, 1.0f};
940 glGenBuffers(1, &m_buffer);
941 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
942 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
943
944 glGenVertexArrays(1, &m_vertex_array);
945 glBindVertexArray(m_vertex_array);
946
947 for (int i = 0; i < kCount; ++i)
948 {
949 if (!RunIteration(glsl_vs[i], glsl_fs))
950 return ERROR;
951 }
952
953 return NO_ERROR;
954 }
955
Cleanup()956 virtual long Cleanup()
957 {
958 glUseProgram(0);
959 glDeleteProgram(m_program);
960 glDeleteBuffers(1, &m_buffer);
961 glDeleteVertexArrays(1, &m_vertex_array);
962 return NO_ERROR;
963 }
964 };
965
966 class BasicSyntaxCS : public ShaderStorageBufferObjectBase
967 {
968 GLuint m_program;
969 GLuint m_buffer[2];
970
RunIteration(const char * cs)971 bool RunIteration(const char *cs)
972 {
973 std::stringstream ss;
974 ss << "layout(local_size_x = 3) in;" NL "layout (std430) buffer Result {" NL " int result[3];" NL "};" << cs;
975
976 if (m_program != 0)
977 glDeleteProgram(m_program);
978 m_program = CreateProgramCS(ss.str());
979 glLinkProgram(m_program);
980 if (!CheckProgram(m_program))
981 return false;
982
983 glUseProgram(m_program);
984 glDispatchCompute(1, 1, 1);
985 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
986
987 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[0]);
988 GLint *out_data = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 3, GL_MAP_READ_BIT);
989 if (!out_data)
990 return false;
991 bool result = out_data[0] == 7 && out_data[1] == 17 && out_data[2] == 23;
992 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
993 GLint data[3] = {0};
994 glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 3, data, GL_STATIC_READ);
995
996 return result;
997 }
998
Setup()999 virtual long Setup()
1000 {
1001 m_program = 0;
1002 memset(m_buffer, 0, sizeof(m_buffer));
1003 return NO_ERROR;
1004 }
1005
Run()1006 virtual long Run()
1007 {
1008 const int kCount = 8;
1009 const char *const glsl_cs[kCount] = {
1010 NL "layout(std430, binding = 1) buffer Buffer {" NL " vec4 indata[3];" NL "} g_input_buffer;" NL
1011 "void main() {" NL
1012 " result[gl_LocalInvocationIndex] = int(g_input_buffer.indata[gl_LocalInvocationID.x].z);" NL "}",
1013
1014 NL "layout(binding = 1) coherent buffer Buffer {" NL " buffer vec4 indata0;" NL
1015 " coherent vec4 indata1;" NL " restrict readonly vec4 indata2;" NL "} g_input_buffer;" NL
1016 "void main() {" NL
1017 " if (gl_LocalInvocationID.x == 0u) result[gl_LocalInvocationIndex] = int(g_input_buffer.indata0.z);" NL
1018 " if (gl_LocalInvocationID.x == 1u) result[gl_LocalInvocationIndex] = int(g_input_buffer.indata1.z);" NL
1019 " if (gl_LocalInvocationID.x == 2u) result[gl_LocalInvocationIndex] = int(g_input_buffer.indata2.z);" NL
1020 "}",
1021
1022 NL "layout(std140, binding = 1) readonly buffer Buffer {" NL " readonly vec4 indata[];" NL "};" NL
1023 "void main() {" NL " result[gl_LocalInvocationIndex] = int(indata[gl_LocalInvocationID.x].z);" NL "}",
1024
1025 NL "layout(std430, column_major, std140, std430, row_major, packed, shared) buffer;" NL
1026 "layout(std430) buffer;" NL "layout(binding = 1) coherent restrict volatile buffer Buffer {" NL
1027 " restrict coherent vec4 indata[];" NL "} g_buffer;" NL "void main() {" NL
1028 " result[gl_LocalInvocationIndex] = int(g_buffer.indata[gl_LocalInvocationID.x].z);" NL "}",
1029
1030 NL "layout(binding = 1) buffer Buffer {" NL " vec4 indata[3];" //
1031 NL "} g_buffer[1];" NL "void main() {" NL
1032 " result[gl_LocalInvocationIndex] = int(g_buffer[0].indata[gl_LocalInvocationID.x].z);" NL "}",
1033
1034 NL
1035 "layout(shared, binding = 1) coherent buffer Buffer {" NL " restrict volatile vec4 indata0;" NL
1036 " buffer readonly vec4 indata1;" NL " vec4 indata2;" NL "} g_buffer[1];" NL "void main() {" NL
1037 " if (gl_LocalInvocationID.x == 0u) result[gl_LocalInvocationIndex] = int(g_buffer[0].indata0.z);" NL
1038 " else if (gl_LocalInvocationID.x == 1u) result[gl_LocalInvocationIndex] = int(g_buffer[0].indata1.z);" NL
1039 " else if (gl_LocalInvocationID.x == 2u) result[gl_LocalInvocationIndex] = int(g_buffer[0].indata2.z);" NL
1040 "}",
1041
1042 NL
1043 "layout(packed, binding = 1) coherent buffer Buffer {" NL " vec4 indata01[2];" NL " vec4 indata2;" NL
1044 "} g_buffer;" NL "void main() {" NL
1045 " if (gl_LocalInvocationID.x == 0u) result[gl_LocalInvocationIndex] = int(g_buffer.indata01[0].z);" NL
1046 " else if (gl_LocalInvocationID.x == 1u) result[gl_LocalInvocationIndex] = int(g_buffer.indata01[1].z);" NL
1047 " else if (gl_LocalInvocationID.x == 2u) result[gl_LocalInvocationIndex] = int(g_buffer.indata2.z);" NL
1048 "}",
1049
1050 NL "layout(std430, binding = 1) coherent buffer Buffer {" NL " coherent vec4 indata01[2];" NL
1051 " vec4 indata2[];" NL "} g_buffer;" NL "void main() {" NL " switch (gl_LocalInvocationID.x) {" NL
1052 " case 0u: result[gl_LocalInvocationIndex] = int(g_buffer.indata01[0].z); break;" NL
1053 " case 1u: result[gl_LocalInvocationIndex] = int(g_buffer.indata01[1].z); break;" NL
1054 " case 2u: result[gl_LocalInvocationIndex] = int(g_buffer.indata2[gl_LocalInvocationIndex-2u].z); "
1055 "break;" NL " }" NL "}",
1056 };
1057
1058 glGenBuffers(2, m_buffer);
1059 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
1060 glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 3, 0, GL_STATIC_READ);
1061 const float data[12] = {-1.0f, -1.0f, 7.0f, 1.0f, 3.0f, -1.0f, 17.0f, 1.0f, -1.0f, 3.0f, 23.0f, 1.0f};
1062 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
1063 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
1064 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1065
1066 for (int i = 0; i < kCount; ++i)
1067 {
1068 if (!RunIteration(glsl_cs[i]))
1069 return ERROR;
1070 }
1071
1072 return NO_ERROR;
1073 }
1074
Cleanup()1075 virtual long Cleanup()
1076 {
1077 glUseProgram(0);
1078 glDeleteProgram(m_program);
1079 glDeleteBuffers(2, m_buffer);
1080 return NO_ERROR;
1081 }
1082 };
1083 //-----------------------------------------------------------------------------
1084 // 1.5 BasicSyntaxSSO
1085 //-----------------------------------------------------------------------------
1086 class BasicSyntaxSSO : public ShaderStorageBufferObjectBase
1087 {
1088 GLuint m_pipeline;
1089 GLuint m_vsp, m_fsp;
1090 GLuint m_buffer;
1091 GLuint m_vertex_array;
1092
RunIteration(const char * vs)1093 bool RunIteration(const char *vs)
1094 {
1095 if (m_vsp != 0)
1096 glDeleteProgram(m_vsp);
1097 m_vsp = BuildShaderProgram(GL_VERTEX_SHADER, vs);
1098 if (!CheckProgram(m_vsp))
1099 return false;
1100
1101 glClear(GL_COLOR_BUFFER_BIT);
1102 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_vsp);
1103 glDrawArrays(GL_TRIANGLES, 0, 3);
1104
1105 return CheckFB(vec3(0, 1, 0));
1106 }
1107
Setup()1108 virtual long Setup()
1109 {
1110 m_pipeline = 0;
1111 m_vsp = m_fsp = 0;
1112 m_buffer = 0;
1113 m_vertex_array = 0;
1114 return NO_ERROR;
1115 }
1116
Run()1117 virtual long Run()
1118 {
1119 if (!IsVSFSAvailable(1, 0))
1120 return NOT_SUPPORTED;
1121 const int kCount = 8;
1122 const char *const glsl_vs[kCount] = {
1123 NL "layout(std430) buffer Buffer {" NL " vec4 position[3];" NL "} g_input_buffer;" NL "void main() {" NL
1124 " gl_Position = g_input_buffer.position[gl_VertexID];" NL "}",
1125 NL "coherent buffer Buffer {" NL " vec4 position0;" NL " coherent vec4 position1;" NL
1126 " restrict readonly vec4 position2;" NL "} g_input_buffer;" NL "void main() {" NL
1127 " if (gl_VertexID == 0) gl_Position = g_input_buffer.position0;" NL
1128 " if (gl_VertexID == 1) gl_Position = g_input_buffer.position1;" NL
1129 " if (gl_VertexID == 2) gl_Position = g_input_buffer.position2;" NL "}",
1130 NL "layout(std140, binding = 0) readonly buffer Buffer {" NL " readonly vec4 position[];" NL "};" NL
1131 "void main() {" NL " gl_Position = position[gl_VertexID];" NL "}",
1132 NL "layout(std430, column_major, std140, std430, row_major, packed, shared) buffer;" NL
1133 "layout(std430) buffer;" NL "coherent restrict volatile buffer Buffer {" NL
1134 " restrict coherent vec4 position[];" NL "} g_buffer;" NL "void main() {" NL
1135 " gl_Position = g_buffer.position[gl_VertexID];" NL "}",
1136 NL "buffer Buffer {" NL " vec4 position[3];" //
1137 NL "} g_buffer[1];" NL "void main() {" NL " gl_Position = g_buffer[0].position[gl_VertexID];" NL "}",
1138 NL "layout(shared) coherent buffer Buffer {" NL " restrict volatile vec4 position0;" NL
1139 " readonly vec4 position1;" NL " vec4 position2;" NL "} g_buffer[1];" NL "void main() {" NL
1140 " if (gl_VertexID == 0) gl_Position = g_buffer[0].position0;" NL
1141 " else if (gl_VertexID == 1) gl_Position = g_buffer[0].position1;" NL
1142 " else if (gl_VertexID == 2) gl_Position = g_buffer[0].position2;" NL "}",
1143 NL "layout(packed) coherent buffer Buffer {" NL " vec4 position01[2];" NL " vec4 position2;" NL
1144 "} g_buffer;" NL "void main() {" NL " if (gl_VertexID == 0) gl_Position = g_buffer.position01[0];" NL
1145 " else if (gl_VertexID == 1) gl_Position = g_buffer.position01[1];" NL
1146 " else if (gl_VertexID == 2) gl_Position = g_buffer.position2;" NL "}",
1147 NL "layout(std430) coherent buffer Buffer {" NL " coherent vec4 position01[2];" NL " vec4 position2[];" NL
1148 "} g_buffer;" NL "void main() {" NL " switch (gl_VertexID) {" NL
1149 " case 0: gl_Position = g_buffer.position01[0]; break;" NL
1150 " case 1: gl_Position = g_buffer.position01[1]; break;" NL
1151 " case 2: gl_Position = g_buffer.position2[gl_VertexID - 2]; break;" NL " }" NL "}",
1152 };
1153
1154 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
1155 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
1156 m_fsp = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs);
1157 if (!CheckProgram(m_fsp))
1158 return ERROR;
1159
1160 glGenProgramPipelines(1, &m_pipeline);
1161 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_fsp);
1162
1163 const float data[12] = {-1.0f, -1.0f, 0.0f, 1.0f, 3.0f, -1.0f, 0.0f, 1.0f, -1.0f, 3.0f, 0.0f, 1.0f};
1164 glGenBuffers(1, &m_buffer);
1165 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
1166 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
1167
1168 glBindProgramPipeline(m_pipeline);
1169
1170 glGenVertexArrays(1, &m_vertex_array);
1171 glBindVertexArray(m_vertex_array);
1172
1173 for (int i = 0; i < kCount; ++i)
1174 {
1175 if (!RunIteration(glsl_vs[i]))
1176 return ERROR;
1177 }
1178
1179 return NO_ERROR;
1180 }
1181
Cleanup()1182 virtual long Cleanup()
1183 {
1184 glDeleteProgramPipelines(1, &m_pipeline);
1185 glDeleteProgram(m_vsp);
1186 glDeleteProgram(m_fsp);
1187 glDeleteBuffers(1, &m_buffer);
1188 glDeleteVertexArrays(1, &m_vertex_array);
1189 return NO_ERROR;
1190 }
1191 };
1192 //-----------------------------------------------------------------------------
1193 // 1.6.x BasicStdLayoutBase
1194 //-----------------------------------------------------------------------------
1195 class BasicStdLayoutBaseVS : public ShaderStorageBufferObjectBase
1196 {
1197 GLuint m_program;
1198 GLuint m_buffer[2];
1199 GLuint m_vertex_array;
1200
1201 virtual const char *GetInput(std::vector<GLubyte> &in_data) = 0;
1202
Setup()1203 virtual long Setup()
1204 {
1205 m_program = 0;
1206 memset(m_buffer, 0, sizeof(m_buffer));
1207 m_vertex_array = 0;
1208 return NO_ERROR;
1209 }
1210
Run()1211 virtual long Run()
1212 {
1213 if (!IsVSFSAvailable(2, 0))
1214 return NOT_SUPPORTED;
1215 std::vector<GLubyte> in_data;
1216 const char *glsl_vs = GetInput(in_data);
1217 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
1218 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
1219
1220 m_program = CreateProgram(glsl_vs, glsl_fs);
1221 glLinkProgram(m_program);
1222 if (!CheckProgram(m_program))
1223 return ERROR;
1224
1225 glGenBuffers(2, m_buffer);
1226
1227 std::vector<GLubyte> out_d(in_data.size());
1228 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
1229 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data.size(), &out_d[0], GL_STATIC_DRAW);
1230
1231 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
1232 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data.size(), &in_data[0], GL_STATIC_DRAW);
1233
1234 glGenVertexArrays(1, &m_vertex_array);
1235 glEnable(GL_RASTERIZER_DISCARD);
1236
1237 glUseProgram(m_program);
1238 glBindVertexArray(m_vertex_array);
1239 glDrawArrays(GL_POINTS, 0, 1);
1240
1241 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
1242 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1243 GLubyte *out_data =
1244 (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data.size(), GL_MAP_READ_BIT);
1245 if (!out_data)
1246 return ERROR;
1247
1248 bool status = true;
1249 for (size_t i = 0; i < in_data.size(); ++i)
1250 {
1251 if (in_data[i] != out_data[i])
1252 {
1253 m_context.getTestContext().getLog()
1254 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
1255 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[i]) << tcu::TestLog::EndMessage;
1256 status = false;
1257 }
1258 }
1259 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1260 if (!status)
1261 return ERROR;
1262 return NO_ERROR;
1263 }
1264
Cleanup()1265 virtual long Cleanup()
1266 {
1267 glDisable(GL_RASTERIZER_DISCARD);
1268 glUseProgram(0);
1269 glDeleteProgram(m_program);
1270 glDeleteBuffers(2, m_buffer);
1271 glDeleteVertexArrays(1, &m_vertex_array);
1272 return NO_ERROR;
1273 }
1274 };
1275
1276 class BasicStdLayoutBaseCS : public ShaderStorageBufferObjectBase
1277 {
1278 GLuint m_program;
1279 GLuint m_buffer[2];
1280
1281 virtual const char *GetInput(std::vector<GLubyte> &in_data) = 0;
1282
Setup()1283 virtual long Setup()
1284 {
1285 m_program = 0;
1286 memset(m_buffer, 0, sizeof(m_buffer));
1287 return NO_ERROR;
1288 }
1289
Run()1290 virtual long Run()
1291 {
1292 std::vector<GLubyte> in_data;
1293 std::stringstream ss;
1294 ss << "layout(local_size_x = 1) in;\n" << GetInput(in_data);
1295
1296 m_program = CreateProgramCS(ss.str());
1297 glLinkProgram(m_program);
1298 if (!CheckProgram(m_program))
1299 return ERROR;
1300
1301 glGenBuffers(2, m_buffer);
1302
1303 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
1304 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data.size(), &in_data[0], GL_STATIC_DRAW);
1305 std::vector<GLubyte> out_d(in_data.size());
1306 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
1307 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)out_d.size(), &out_d[0], GL_STATIC_DRAW);
1308
1309 glUseProgram(m_program);
1310 glDispatchCompute(1, 1, 1);
1311
1312 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1313 GLubyte *out_data =
1314 (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data.size(), GL_MAP_READ_BIT);
1315 if (!out_data)
1316 return ERROR;
1317
1318 bool status = true;
1319
1320 for (size_t i = 0; i < in_data.size(); ++i)
1321 {
1322 if (in_data[i] != out_data[i])
1323 {
1324 m_context.getTestContext().getLog()
1325 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
1326 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[i]) << tcu::TestLog::EndMessage;
1327 status = false;
1328 }
1329 else
1330 {
1331 }
1332 }
1333 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1334 if (!status)
1335 return ERROR;
1336 return NO_ERROR;
1337 }
1338
Cleanup()1339 virtual long Cleanup()
1340 {
1341 glUseProgram(0);
1342 glDeleteProgram(m_program);
1343 glDeleteBuffers(2, m_buffer);
1344 return NO_ERROR;
1345 }
1346 };
1347 //-----------------------------------------------------------------------------
1348 // 1.6.1 BasicStd430LayoutCase1
1349 //-----------------------------------------------------------------------------
GetInput430c1(std::vector<GLubyte> & in_data)1350 const char *GetInput430c1(std::vector<GLubyte> &in_data)
1351 {
1352 in_data.resize(6 * 4);
1353 float *fp = reinterpret_cast<float *>(&in_data[0]);
1354 int *ip = reinterpret_cast<int *>(&in_data[0]);
1355 fp[0] = 1.0f;
1356 fp[1] = 2.0f;
1357 fp[2] = 3.0f;
1358 fp[3] = 4.0f;
1359 ip[4] = 5;
1360 ip[5] = 6;
1361 return NL "layout(std430, binding = 0) buffer Input {" NL " float data0;" NL " float data1[3];" NL
1362 " ivec2 data2;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL " float data0;" NL
1363 " float data1[3];" NL " ivec2 data2;" NL "} g_output;" NL "void main() {" NL
1364 " g_output.data0 = g_input.data0;" NL
1365 " for (int i = 0; i < g_input.data1.length(); ++i) g_output.data1[i] = g_input.data1[i];" NL
1366 " g_output.data2 = g_input.data2;" NL "}";
1367 }
1368
1369 class BasicStd430LayoutCase1VS : public BasicStdLayoutBaseVS
1370 {
GetInput(std::vector<GLubyte> & in_data)1371 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1372 {
1373 return GetInput430c1(in_data);
1374 }
1375 };
1376
1377 class BasicStd430LayoutCase1CS : public BasicStdLayoutBaseCS
1378 {
GetInput(std::vector<GLubyte> & in_data)1379 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1380 {
1381 return GetInput430c1(in_data);
1382 }
1383 };
1384 //-----------------------------------------------------------------------------
1385 // 1.6.2 BasicStd430LayoutCase2
1386 //-----------------------------------------------------------------------------
GetInput430c2(std::vector<GLubyte> & in_data)1387 const char *GetInput430c2(std::vector<GLubyte> &in_data)
1388 {
1389 in_data.resize(17 * 4);
1390 float *fp = reinterpret_cast<float *>(&in_data[0]);
1391 fp[0] = 1.0f;
1392 fp[1] = 2.0f;
1393 fp[2] = 3.0f;
1394 fp[3] = 4.0f;
1395 fp[4] = 5.0f;
1396 fp[5] = 6.0f;
1397 fp[8] = 7.0f;
1398 fp[9] = 8.0f;
1399 fp[10] = 9.0f;
1400 fp[12] = 10.0f;
1401 fp[13] = 11.0f;
1402 fp[14] = 12.0f;
1403 fp[16] = 13.0f;
1404
1405 return NL "layout(std430, binding = 0) buffer Input {" NL " float data0;" NL " float data1[3];" NL
1406 " vec2 data2;" NL " readonly vec3 data3[2];" NL " float data4;" NL "} g_input;" NL
1407 "layout(std430, binding = 1) buffer Output {" NL " float data0;" NL " float data1[3];" NL
1408 " vec2 data2;" NL " vec3 data3[2];" NL " float data4;" NL "} g_output;" NL "void main() {" NL
1409 " g_output.data0 = g_input.data0;" NL
1410 " for (int i = 0; i < g_input.data1.length(); ++i) g_output.data1[i] = g_input.data1[i];" NL
1411 " g_output.data2 = g_input.data2;" NL
1412 " for (int i = 0; i < g_input.data3.length(); ++i) g_output.data3[i] = g_input.data3[i];" NL
1413 " g_output.data4 = g_input.data4;" NL "}";
1414 }
1415
1416 class BasicStd430LayoutCase2VS : public BasicStdLayoutBaseVS
1417 {
GetInput(std::vector<GLubyte> & in_data)1418 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1419 {
1420 return GetInput430c2(in_data);
1421 }
1422 };
1423
1424 class BasicStd430LayoutCase2CS : public BasicStdLayoutBaseCS
1425 {
GetInput(std::vector<GLubyte> & in_data)1426 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1427 {
1428 return GetInput430c2(in_data);
1429 }
1430 };
1431
1432 //-----------------------------------------------------------------------------
1433 // 1.6.3 BasicStd430LayoutCase3
1434 //-----------------------------------------------------------------------------
GetInput430c3(std::vector<GLubyte> & in_data)1435 const char *GetInput430c3(std::vector<GLubyte> &in_data)
1436 {
1437 in_data.resize(16 * 4);
1438 float *fp = reinterpret_cast<float *>(&in_data[0]);
1439 fp[0] = 1.0f;
1440 fp[1] = 2.0f;
1441 fp[2] = 3.0f;
1442 fp[3] = 0.0f;
1443 fp[4] = 4.0f;
1444 fp[5] = 5.0f;
1445 fp[6] = 6.0f;
1446 fp[7] = 0.0f;
1447 fp[8] = 7.0f;
1448 fp[9] = 8.0f;
1449 fp[10] = 9.0f;
1450 fp[11] = 10.0f;
1451 fp[12] = 11.0f;
1452 fp[13] = 12.0f;
1453 fp[14] = 13.0f;
1454 fp[15] = 14.0f;
1455
1456 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(column_major) mat2x3 data0;" NL
1457 " layout(row_major) mat4x2 data1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
1458 " layout(column_major) mat2x3 data0;" NL " layout(row_major) mat4x2 data1;" NL "} g_output;" NL
1459 "void main() {" NL " g_output.data0 = g_input.data0;" NL " g_output.data1 = g_input.data1;" NL "}";
1460 }
1461
1462 class BasicStd430LayoutCase3VS : public BasicStdLayoutBaseVS
1463 {
GetInput(std::vector<GLubyte> & in_data)1464 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1465 {
1466 return GetInput430c3(in_data);
1467 }
1468 };
1469
1470 class BasicStd430LayoutCase3CS : public BasicStdLayoutBaseCS
1471 {
GetInput(std::vector<GLubyte> & in_data)1472 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1473 {
1474 return GetInput430c3(in_data);
1475 }
1476 };
1477
1478 //-----------------------------------------------------------------------------
1479 // 1.6.4 BasicStd430LayoutCase4
1480 //-----------------------------------------------------------------------------
GetInput430c4(std::vector<GLubyte> & in_data)1481 const char *GetInput430c4(std::vector<GLubyte> &in_data)
1482 {
1483 in_data.resize(17 * 4);
1484 float *fp = reinterpret_cast<float *>(&in_data[0]);
1485 fp[0] = 1.0f;
1486 fp[1] = 2.0f;
1487 fp[2] = 3.0f;
1488 fp[3] = 4.0f;
1489 fp[4] = 5.0f;
1490 fp[5] = 6.0f;
1491 fp[6] = 7.0f;
1492 fp[7] = 8.0f;
1493 fp[8] = 9.0f;
1494 fp[9] = 10.0f;
1495 fp[10] = 11.0f;
1496 fp[12] = 12.0f;
1497 fp[13] = 13.0f;
1498 fp[14] = 14.0f;
1499 fp[16] = 15.0f;
1500
1501 return NL "layout(std430, binding = 0) buffer Input {" NL " mat4x2 data0;" NL " mat2x3 data1;" NL
1502 " float data2;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL " mat4x2 data0;" NL
1503 " mat2x3 data1;" NL " float data2;" NL "} g_output;" NL "void main() {" NL
1504 " g_output.data0 = g_input.data0;" NL " g_output.data1 = g_input.data1;" NL
1505 " g_output.data2 = g_input.data2;" NL "}";
1506 }
1507
1508 class BasicStd430LayoutCase4VS : public BasicStdLayoutBaseVS
1509 {
GetInput(std::vector<GLubyte> & in_data)1510 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1511 {
1512 return GetInput430c4(in_data);
1513 }
1514 };
1515
1516 class BasicStd430LayoutCase4CS : public BasicStdLayoutBaseCS
1517 {
GetInput(std::vector<GLubyte> & in_data)1518 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1519 {
1520 return GetInput430c4(in_data);
1521 }
1522 };
1523
1524 //-----------------------------------------------------------------------------
1525 // 1.6.5 BasicStd430LayoutCase5
1526 //-----------------------------------------------------------------------------
GetInput430c5(std::vector<GLubyte> & in_data)1527 const char *GetInput430c5(std::vector<GLubyte> &in_data)
1528 {
1529 in_data.resize(8 * 4);
1530 float *fp = reinterpret_cast<float *>(&in_data[0]);
1531 fp[0] = 1.0f;
1532 fp[1] = 3.0f;
1533 fp[2] = 5.0f;
1534 fp[3] = 7.0f;
1535 fp[4] = 2.0f;
1536 fp[5] = 4.0f;
1537 fp[6] = 6.0f;
1538 fp[7] = 8.0f;
1539
1540 return NL "layout(std430, binding = 0, row_major) buffer Input {" NL " mat4x2 data0;" NL "} g_input;" NL
1541 "layout(std430, binding = 1, row_major) buffer Output {" NL " mat4x2 data0;" NL "} g_output;" NL
1542 "void main() {" NL " g_output.data0 = g_input.data0;" NL "}";
1543 }
1544
1545 class BasicStd430LayoutCase5VS : public BasicStdLayoutBaseVS
1546 {
GetInput(std::vector<GLubyte> & in_data)1547 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1548 {
1549 return GetInput430c5(in_data);
1550 }
1551 };
1552
1553 class BasicStd430LayoutCase5CS : public BasicStdLayoutBaseCS
1554 {
GetInput(std::vector<GLubyte> & in_data)1555 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1556 {
1557 return GetInput430c5(in_data);
1558 }
1559 };
1560
1561 //-----------------------------------------------------------------------------
1562 // 1.6.6 BasicStd430LayoutCase6
1563 //-----------------------------------------------------------------------------
GetInput430c6(std::vector<GLubyte> & in_data)1564 const char *GetInput430c6(std::vector<GLubyte> &in_data)
1565 {
1566 in_data.resize(92 * 4);
1567 float *fp = reinterpret_cast<float *>(&in_data[0]);
1568 fp[0] = 1.0f;
1569 fp[1] = 2.0f;
1570 fp[2] = 3.0f;
1571 fp[3] = 4.0f;
1572 fp[4] = 5.0f;
1573 fp[5] = 0.0f;
1574 fp[6] = 6.0f;
1575 fp[7] = 7.0f;
1576 fp[8] = 8.0f;
1577 fp[9] = 9.0f;
1578 fp[10] = 10.0f;
1579 fp[11] = 11.0f;
1580 fp[12] = 12.0f;
1581 fp[13] = 0.0f;
1582 fp[14] = 0.0f;
1583 fp[15] = 0.0f;
1584 fp[16] = 13.0f;
1585 fp[17] = 14.0f;
1586 fp[18] = 15.0f;
1587 fp[19] = 0.0f;
1588 fp[20] = 16.0f;
1589 fp[21] = 17.0f;
1590 fp[22] = 18.0f;
1591 fp[23] = 0.0f;
1592 fp[24] = 19.0f;
1593 fp[25] = 20.0f;
1594 fp[26] = 21.0f;
1595 fp[27] = 22.0f;
1596 fp[28] = 23.0f;
1597 fp[29] = 24.0f;
1598 fp[30] = 25.0f;
1599 fp[31] = 26.0f;
1600 fp[32] = 27.0f;
1601 fp[33] = 28.0f;
1602 fp[34] = 0.0f;
1603 fp[35] = 0.0f;
1604 fp[36] = 29.0f;
1605 fp[37] = 30.0f;
1606 fp[38] = 31.0f;
1607 fp[39] = 0.0f;
1608 fp[40] = 32.0f;
1609 fp[41] = 33.0f;
1610 fp[42] = 34.0f;
1611 fp[43] = 0.0f;
1612 fp[44] = 35.0f;
1613 fp[45] = 36.0f;
1614 fp[46] = 37.0f;
1615 fp[47] = 0.0f;
1616 fp[48] = 38.0f;
1617 fp[49] = 39.0f;
1618 fp[50] = 40.0f;
1619 fp[51] = 0.0f;
1620 fp[52] = 41.0f;
1621 fp[53] = 42.0f;
1622 fp[54] = 43.0f;
1623 fp[55] = 0.0f;
1624 fp[56] = 44.0f;
1625 fp[57] = 45.0f;
1626 fp[58] = 46.0f;
1627 fp[59] = 0.0f;
1628 fp[60] = 47.0f;
1629 fp[61] = 48.0f;
1630 fp[62] = 49.0f;
1631 fp[63] = 50.0f;
1632 fp[64] = 51.0f;
1633 fp[65] = 52.0f;
1634 fp[66] = 53.0f;
1635 fp[67] = 54.0f;
1636 fp[68] = 55.0f;
1637 fp[69] = 56.0f;
1638 fp[70] = 57.0f;
1639 fp[71] = 58.0f;
1640 fp[72] = 59.0f;
1641 fp[73] = 60.0f;
1642 fp[74] = 61.0f;
1643 fp[75] = 62.0f;
1644 fp[76] = 63.0f;
1645 fp[77] = 64.0f;
1646 fp[78] = 65.0f;
1647 fp[79] = 66.0f;
1648 fp[80] = 67.0f;
1649 fp[81] = 68.0f;
1650 fp[82] = 69.0f;
1651 fp[83] = 70.0f;
1652 fp[84] = 71.0f;
1653 fp[85] = 72.0f;
1654 fp[86] = 73.0f;
1655 fp[87] = 74.0f;
1656 fp[88] = 75.0f;
1657 fp[89] = 76.0f;
1658 fp[90] = 77.0f;
1659 fp[91] = 78.0f;
1660
1661 return NL "layout(std430, binding = 0) buffer Input {" NL " float data0[2];" NL " float data1[3];" NL
1662 " vec2 data2;" NL " float data3[5];" NL " vec3 data4[2];" NL " float data5[2];" NL
1663 " mat2 data6[2];" NL " mat3 data7[2];" NL " mat4 data8[2];" NL "} g_input;" NL
1664 "layout(std430, binding = 1) buffer Output {" NL " float data0[2];" NL " float data1[3];" NL
1665 " vec2 data2;" NL " float data3[5];" NL " vec3 data4[2];" NL " float data5[2];" NL
1666 " mat2 data6[2];" NL " mat3 data7[2];" NL " mat4 data8[2];" NL "} g_output;" NL "void main() {" NL
1667 " for (int i = 0; i < g_input.data0.length(); ++i) g_output.data0[i] = g_input.data0[i];" NL
1668 " for (int i = 0; i < g_input.data1.length(); ++i) g_output.data1[i] = g_input.data1[i];" NL
1669 " g_output.data2 = g_input.data2;" NL
1670 " for (int i = 0; i < g_input.data3.length(); ++i) g_output.data3[i] = g_input.data3[i];" NL
1671 " for (int i = 0; i < g_input.data4.length(); ++i) g_output.data4[i] = g_input.data4[i];" NL
1672 " for (int i = 0; i < g_input.data5.length(); ++i) g_output.data5[i] = g_input.data5[i];" NL
1673 " for (int i = 0; i < g_input.data6.length(); ++i) g_output.data6[i] = g_input.data6[i];" NL
1674 " for (int i = 0; i < g_input.data7.length(); ++i) g_output.data7[i] = g_input.data7[i];" NL
1675 " for (int i = 0; i < g_input.data8.length(); ++i) g_output.data8[i] = g_input.data8[i];" NL "}";
1676 }
1677
1678 class BasicStd430LayoutCase6VS : public BasicStdLayoutBaseVS
1679 {
GetInput(std::vector<GLubyte> & in_data)1680 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1681 {
1682 return GetInput430c6(in_data);
1683 }
1684 };
1685
1686 class BasicStd430LayoutCase6CS : public BasicStdLayoutBaseCS
1687 {
GetInput(std::vector<GLubyte> & in_data)1688 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1689 {
1690 return GetInput430c6(in_data);
1691 }
1692 };
1693
1694 //-----------------------------------------------------------------------------
1695 // 1.6.7 BasicStd430LayoutCase7
1696 //-----------------------------------------------------------------------------
GetInput430c7(std::vector<GLubyte> & in_data)1697 const char *GetInput430c7(std::vector<GLubyte> &in_data)
1698 {
1699 in_data.resize(36 * 4);
1700 int *ip = reinterpret_cast<int *>(&in_data[0]);
1701 float *fp = reinterpret_cast<float *>(&in_data[0]);
1702 ip[0] = 1;
1703 ip[1] = 0;
1704 ip[2] = 2;
1705 ip[3] = 3;
1706 fp[4] = 4.0f;
1707 fp[5] = 0.0f;
1708 fp[6] = 0.0f;
1709 fp[7] = 0.0f;
1710 fp[8] = 5.0f;
1711 fp[9] = 6.0f;
1712 fp[10] = 7.0f;
1713 fp[11] = 0.0f;
1714 fp[12] = 8.0f;
1715 fp[13] = 0.0f;
1716 fp[14] = 0.0f;
1717 fp[15] = 0.0f;
1718 fp[16] = 9.0f;
1719 fp[17] = 10.0f;
1720 fp[18] = 11.0f;
1721 fp[19] = 0.0f;
1722 ip[20] = 12;
1723 ip[21] = 13;
1724 ip[22] = 14;
1725 ip[23] = 15;
1726 fp[24] = 16.0f;
1727 fp[25] = 0.0f;
1728 fp[26] = 0.0f;
1729 fp[27] = 0.0f;
1730 fp[28] = 17.0f;
1731 fp[29] = 18.0f;
1732 fp[30] = 19.0f;
1733 fp[31] = 0.0f;
1734 ip[32] = 20;
1735 ip[33] = 21;
1736 ip[34] = 22;
1737 ip[35] = 23;
1738
1739 return NL "struct Struct0 {" NL " ivec2 m0;" NL "};" NL "struct Struct1 {" NL " vec3 m0;" NL "};" NL
1740 "struct Struct3 {" NL " int m0;" NL "};" NL "struct Struct2 {" NL " float m0;" // offset = 0
1741 NL " Struct1 m1;" // offset = 16
1742 NL " Struct0 m2;" // offset = 32
1743 NL " int m3;" // offset = 40
1744 NL " Struct3 m4;" // offset = 44
1745 NL "};" NL "layout(std430, binding = 0) buffer Input {" NL " int data0;" // offset = 0
1746 NL " Struct0 data1;" // offset = 8
1747 NL " float data2;" // offset = 16
1748 NL " Struct1 data3;" // offset = 32
1749 NL " Struct2 data4[2];" // offset = 48
1750 NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL " int data0;" NL " Struct0 data1;" NL
1751 " float data2;" NL " Struct1 data3;" NL " Struct2 data4[2];" NL "} g_output;" NL "void main() {" NL
1752 " g_output.data0 = g_input.data0;" NL " g_output.data1 = g_input.data1;" NL
1753 " g_output.data2 = g_input.data2;" NL " g_output.data3 = g_input.data3;" NL
1754 " for (int i = 0; i < g_input.data4.length(); ++i) g_output.data4[i] = g_input.data4[i];" NL "}";
1755 }
1756
1757 class BasicStd430LayoutCase7VS : public BasicStdLayoutBaseVS
1758 {
GetInput(std::vector<GLubyte> & in_data)1759 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1760 {
1761 return GetInput430c7(in_data);
1762 }
1763 };
1764
1765 class BasicStd430LayoutCase7CS : public BasicStdLayoutBaseCS
1766 {
GetInput(std::vector<GLubyte> & in_data)1767 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1768 {
1769 return GetInput430c7(in_data);
1770 }
1771 };
1772
1773 //-----------------------------------------------------------------------------
1774 // 1.7.1 BasicStd140LayoutCase1
1775 //-----------------------------------------------------------------------------
GetInput140c1(std::vector<GLubyte> & in_data)1776 const char *GetInput140c1(std::vector<GLubyte> &in_data)
1777 {
1778 in_data.resize(5 * 4);
1779 float *fp = reinterpret_cast<float *>(&in_data[0]);
1780 fp[0] = 1.0f;
1781 fp[1] = 0.0f;
1782 fp[2] = 0.0f;
1783 fp[3] = 0.0f;
1784 fp[4] = 2.0f;
1785
1786 return NL "layout(std140, binding = 0) buffer Input {" NL " float data0[2];" NL "} g_input;" NL
1787 "layout(std140, binding = 1) buffer Output {" NL " float data0[2];" NL "} g_output;" NL
1788 "void main() {" NL
1789 " for (int i = 0; i < g_input.data0.length(); ++i) g_output.data0[i] = g_input.data0[i];" NL "}";
1790 }
1791
1792 class BasicStd140LayoutCase1VS : public BasicStdLayoutBaseVS
1793 {
GetInput(std::vector<GLubyte> & in_data)1794 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1795 {
1796 return GetInput140c1(in_data);
1797 }
1798 };
1799
1800 class BasicStd140LayoutCase1CS : public BasicStdLayoutBaseCS
1801 {
GetInput(std::vector<GLubyte> & in_data)1802 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1803 {
1804 return GetInput140c1(in_data);
1805 }
1806 };
1807 //-----------------------------------------------------------------------------
1808 // 1.7.2 BasicStd140LayoutCase2
1809 //-----------------------------------------------------------------------------
GetInput140c2(std::vector<GLubyte> & in_data)1810 const char *GetInput140c2(std::vector<GLubyte> &in_data)
1811 {
1812 in_data.resize(18 * 4);
1813 float *fp = reinterpret_cast<float *>(&in_data[0]);
1814 int *ip = reinterpret_cast<int *>(&in_data[0]);
1815 fp[0] = 1.0f;
1816 fp[1] = 0.0f;
1817 fp[2] = 0.0f;
1818 fp[3] = 0.0f;
1819 fp[4] = 2.0f;
1820 fp[5] = 0.0f;
1821 fp[6] = 0.0f;
1822 fp[7] = 0.0f;
1823 fp[8] = 3.0f;
1824 fp[9] = 0.0f;
1825 fp[10] = 0.0f;
1826 fp[11] = 0.0f;
1827 fp[12] = 4.0f;
1828 fp[13] = 0.0f;
1829 fp[14] = 0.0f;
1830 fp[15] = 0.0f;
1831 ip[16] = 5;
1832 ip[17] = 6;
1833
1834 return NL "layout(std140, binding = 0) buffer Input {" NL " float data0;" NL " float data1[3];" NL
1835 " ivec2 data2;" NL "} g_input;" NL "layout(std140, binding = 1) buffer Output {" NL " float data0;" NL
1836 " float data1[3];" NL " ivec2 data2;" NL "} g_output;" NL "void main() {" NL
1837 " g_output.data0 = g_input.data0;" NL
1838 " for (int i = 0; i < g_input.data1.length(); ++i) g_output.data1[i] = g_input.data1[i];" NL
1839 " g_output.data2 = g_input.data2;" NL "}";
1840 }
1841
1842 class BasicStd140LayoutCase2VS : public BasicStdLayoutBaseVS
1843 {
GetInput(std::vector<GLubyte> & in_data)1844 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1845 {
1846 return GetInput140c2(in_data);
1847 }
1848 };
1849
1850 class BasicStd140LayoutCase2CS : public BasicStdLayoutBaseCS
1851 {
GetInput(std::vector<GLubyte> & in_data)1852 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1853 {
1854 return GetInput140c2(in_data);
1855 }
1856 };
1857
1858 //-----------------------------------------------------------------------------
1859 // 1.7.3 BasicStd140LayoutCase3
1860 //-----------------------------------------------------------------------------
GetInput140c3(std::vector<GLubyte> & in_data)1861 const char *GetInput140c3(std::vector<GLubyte> &in_data)
1862 {
1863 in_data.resize(29 * 4);
1864 float *fp = reinterpret_cast<float *>(&in_data[0]);
1865 fp[0] = 1.0f;
1866 fp[1] = 0.0f;
1867 fp[2] = 0.0f;
1868 fp[3] = 0.0f;
1869 fp[4] = 2.0f;
1870 fp[5] = 0.0f;
1871 fp[6] = 0.0f;
1872 fp[7] = 0.0f;
1873 fp[8] = 3.0f;
1874 fp[9] = 0.0f;
1875 fp[10] = 0.0f;
1876 fp[11] = 0.0f;
1877 fp[12] = 4.0f;
1878 fp[13] = 0.0f;
1879 fp[14] = 0.0f;
1880 fp[15] = 0.0f;
1881 fp[16] = 5.0f;
1882 fp[17] = 6.0f;
1883 fp[18] = 0.0f;
1884 fp[19] = 0.0f;
1885 fp[20] = 7.0f;
1886 fp[21] = 8.0f;
1887 fp[22] = 9.0f;
1888 fp[23] = 0.0f;
1889 fp[24] = 10.0f;
1890 fp[25] = 11.0f;
1891 fp[26] = 12.0f;
1892 fp[27] = 0.0f;
1893 fp[28] = 13.0f;
1894
1895 return NL "layout(std140, binding = 0) buffer Input {" NL " float data0;" NL " float data1[3];" NL
1896 " vec2 data2;" NL " readonly vec3 data3[2];" NL " float data4;" NL "} g_input;" NL
1897 "layout(std140, binding = 1) buffer Output {" NL " float data0;" NL " float data1[3];" NL
1898 " vec2 data2;" NL " vec3 data3[2];" NL " float data4;" NL "} g_output;" NL "void main() {" NL
1899 " g_output.data0 = g_input.data0;" NL
1900 " for (int i = 0; i < g_input.data1.length(); ++i) g_output.data1[i] = g_input.data1[i];" NL
1901 " g_output.data2 = g_input.data2;" NL
1902 " for (int i = 0; i < g_input.data3.length(); ++i) g_output.data3[i] = g_input.data3[i];" NL
1903 " g_output.data4 = g_input.data4;" NL "}";
1904 }
1905
1906 class BasicStd140LayoutCase3VS : public BasicStdLayoutBaseVS
1907 {
GetInput(std::vector<GLubyte> & in_data)1908 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1909 {
1910 return GetInput140c3(in_data);
1911 }
1912 };
1913
1914 class BasicStd140LayoutCase3CS : public BasicStdLayoutBaseCS
1915 {
GetInput(std::vector<GLubyte> & in_data)1916 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1917 {
1918 return GetInput140c3(in_data);
1919 }
1920 };
1921
1922 //-----------------------------------------------------------------------------
1923 // 1.7.4 BasicStd140LayoutCase4
1924 //-----------------------------------------------------------------------------
GetInput140c4(std::vector<GLubyte> & in_data)1925 const char *GetInput140c4(std::vector<GLubyte> &in_data)
1926 {
1927 in_data.resize(25 * 4);
1928 float *fp = reinterpret_cast<float *>(&in_data[0]);
1929 fp[0] = 1.0f;
1930 fp[1] = 2.0f;
1931 fp[2] = 0.0f;
1932 fp[3] = 0.0f;
1933 fp[4] = 3.0f;
1934 fp[5] = 4.0f;
1935 fp[6] = 0.0f;
1936 fp[7] = 0.0f;
1937 fp[8] = 5.0f;
1938 fp[9] = 6.0f;
1939 fp[10] = 0.0f;
1940 fp[11] = 0.0f;
1941 fp[12] = 7.0f;
1942 fp[13] = 8.0f;
1943 fp[14] = 0.0f;
1944 fp[15] = 0.0f;
1945 fp[16] = 9.0f;
1946 fp[17] = 10.0f;
1947 fp[18] = 11.0f;
1948 fp[19] = 0.0f;
1949 fp[20] = 12.0f;
1950 fp[21] = 13.0f;
1951 fp[22] = 14.0f;
1952 fp[23] = 0.0f;
1953 fp[24] = 15.0f;
1954
1955 return NL "layout(std140, binding = 0) buffer Input {" NL " mat4x2 data0;" NL " mat2x3 data1;" NL
1956 " float data2;" NL "} g_input;" NL "layout(std140, binding = 1) buffer Output {" NL " mat4x2 data0;" NL
1957 " mat2x3 data1;" NL " float data2;" NL "} g_output;" NL "void main() {" NL
1958 " g_output.data0 = g_input.data0;" NL " g_output.data1 = g_input.data1;" NL
1959 " g_output.data2 = g_input.data2;" NL "}";
1960 }
1961
1962 class BasicStd140LayoutCase4VS : public BasicStdLayoutBaseVS
1963 {
GetInput(std::vector<GLubyte> & in_data)1964 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1965 {
1966 return GetInput140c4(in_data);
1967 }
1968 };
1969
1970 class BasicStd140LayoutCase4CS : public BasicStdLayoutBaseCS
1971 {
GetInput(std::vector<GLubyte> & in_data)1972 virtual const char *GetInput(std::vector<GLubyte> &in_data)
1973 {
1974 return GetInput140c4(in_data);
1975 }
1976 };
1977
1978 //-----------------------------------------------------------------------------
1979 // 1.7.5 BasicStd140LayoutCase5
1980 //-----------------------------------------------------------------------------
GetInput140c5(std::vector<GLubyte> & in_data)1981 const char *GetInput140c5(std::vector<GLubyte> &in_data)
1982 {
1983 in_data.resize(8 * 4);
1984 float *fp = reinterpret_cast<float *>(&in_data[0]);
1985 fp[0] = 1.0f;
1986 fp[1] = 2.0f;
1987 fp[2] = 3.0f;
1988 fp[3] = 4.0f;
1989 fp[4] = 5.0f;
1990 fp[5] = 6.0f;
1991 fp[6] = 7.0f;
1992 fp[7] = 8.0f;
1993
1994 return NL "layout(std140, binding = 0, row_major) buffer Input {" NL " mat4x2 data0;" NL "} g_input;" NL
1995 "layout(std140, binding = 1, row_major) buffer Output {" NL " mat4x2 data0;" NL "} g_output;" NL
1996 "void main() {" NL " g_output.data0 = g_input.data0;" NL "}";
1997 }
1998
1999 class BasicStd140LayoutCase5VS : public BasicStdLayoutBaseVS
2000 {
GetInput(std::vector<GLubyte> & in_data)2001 virtual const char *GetInput(std::vector<GLubyte> &in_data)
2002 {
2003 return GetInput140c5(in_data);
2004 }
2005 };
2006
2007 class BasicStd140LayoutCase5CS : public BasicStdLayoutBaseCS
2008 {
GetInput(std::vector<GLubyte> & in_data)2009 virtual const char *GetInput(std::vector<GLubyte> &in_data)
2010 {
2011 return GetInput140c5(in_data);
2012 }
2013 };
2014
2015 //-----------------------------------------------------------------------------
2016 // 1.7.6 BasicStd140LayoutCase6
2017 //-----------------------------------------------------------------------------
GetInput140c6(std::vector<GLubyte> & in_data)2018 const char *GetInput140c6(std::vector<GLubyte> &in_data)
2019 {
2020 in_data.resize(96 * 4);
2021 float *fp = reinterpret_cast<float *>(&in_data[0]);
2022 fp[0] = 1.0f;
2023 fp[1] = 0.0f;
2024 fp[2] = 0.0f;
2025 fp[3] = 0.0f;
2026 fp[4] = 2.0f;
2027 fp[5] = 0.0f;
2028 fp[6] = 0.0f;
2029 fp[7] = 0.0f;
2030 fp[8] = 3.0f;
2031 fp[9] = 0.0f;
2032 fp[10] = 0.0f;
2033 fp[11] = 0.0f;
2034 fp[12] = 4.0f;
2035 fp[13] = 0.0f;
2036 fp[14] = 0.0f;
2037 fp[15] = 0.0f;
2038 fp[16] = 5.0f;
2039 fp[17] = 0.0f;
2040 fp[18] = 0.0f;
2041 fp[19] = 0.0f;
2042 fp[20] = 6.0f;
2043 fp[21] = 7.0f;
2044 fp[22] = 8.0f;
2045 fp[23] = 9.0f;
2046 fp[24] = 10.0f;
2047 fp[25] = 11.0f;
2048 fp[26] = 0.0f;
2049 fp[27] = 0.0f;
2050 fp[28] = 12.0f;
2051 fp[29] = 13.0f;
2052 fp[30] = 0.0f;
2053 fp[31] = 0.0f;
2054 fp[32] = 14.0f;
2055 fp[33] = 15.0f;
2056 fp[34] = 0.0f;
2057 fp[35] = 0.0f;
2058 fp[36] = 16.0f;
2059 fp[37] = 17.0f;
2060 fp[38] = 0.0f;
2061 fp[39] = 0.0f;
2062 fp[40] = 18.0f;
2063 fp[41] = 19.0f;
2064 fp[42] = 20.0f;
2065 fp[43] = 0.0f;
2066 fp[44] = 21.0f;
2067 fp[45] = 22.0f;
2068 fp[46] = 23.0f;
2069 fp[47] = 0.0f;
2070 fp[48] = 24.0f;
2071 fp[49] = 25.0f;
2072 fp[50] = 26.0f;
2073 fp[51] = 0.0f;
2074 fp[52] = 27.0f;
2075 fp[53] = 28.0f;
2076 fp[54] = 29.0f;
2077 fp[55] = 0.0f;
2078 fp[56] = 30.0f;
2079 fp[57] = 31.0f;
2080 fp[58] = 32.0f;
2081 fp[59] = 0.0f;
2082 fp[60] = 33.0f;
2083 fp[61] = 34.0f;
2084 fp[62] = 35.0f;
2085 fp[63] = 0.0f;
2086 fp[64] = 36.0f;
2087 fp[65] = 37.0f;
2088 fp[66] = 38.0f;
2089 fp[67] = 39.0f;
2090 fp[68] = 40.0f;
2091 fp[69] = 41.0f;
2092 fp[70] = 42.0f;
2093 fp[71] = 43.0f;
2094 fp[72] = 44.0f;
2095 fp[73] = 45.0f;
2096 fp[74] = 46.0f;
2097 fp[75] = 47.0f;
2098 fp[76] = 48.0f;
2099 fp[77] = 49.0f;
2100 fp[78] = 50.0f;
2101 fp[79] = 51.0f;
2102 fp[80] = 52.0f;
2103 fp[81] = 68.0f;
2104 fp[82] = 69.0f;
2105 fp[83] = 70.0f;
2106 fp[84] = 56.0f;
2107 fp[85] = 72.0f;
2108 fp[86] = 73.0f;
2109 fp[87] = 74.0f;
2110 fp[88] = 60.0f;
2111 fp[89] = 76.0f;
2112 fp[90] = 77.0f;
2113 fp[91] = 78.0f;
2114 fp[92] = 64.0f;
2115 fp[93] = 80.0f;
2116 fp[94] = 81.0f;
2117 fp[95] = 82.0f;
2118
2119 return NL "layout(std140, binding = 0) buffer Input {" NL " float data0[2];" NL " float data1[3];" NL
2120 " vec2 data2;" NL " vec2 data3;" NL " mat2 data4[2];" NL " mat3 data5[2];" NL " mat4 data6[2];" NL
2121 "} g_input;" NL "layout(std140, binding = 1) buffer Output {" NL " float data0[2];" NL
2122 " float data1[3];" NL " vec2 data2;" NL " vec2 data3;" NL " mat2 data4[2];" NL " mat3 data5[2];" NL
2123 " mat4 data6[2];" NL "} g_output;" NL "void main() {" NL
2124 " for (int i = 0; i < g_input.data0.length(); ++i) g_output.data0[i] = g_input.data0[i];" NL
2125 " for (int i = 0; i < g_input.data1.length(); ++i) g_output.data1[i] = g_input.data1[i];" NL
2126 " g_output.data2 = g_input.data2;" NL " g_output.data3 = g_input.data3;" NL
2127 " for (int i = 0; i < g_input.data4.length(); ++i) g_output.data4[i] = g_input.data4[i];" NL
2128 " for (int i = 0; i < g_input.data5.length(); ++i) g_output.data5[i] = g_input.data5[i];" NL
2129 " for (int i = 0; i < g_input.data6.length(); ++i) g_output.data6[i] = g_input.data6[i];" NL "}";
2130 }
2131
2132 class BasicStd140LayoutCase6VS : public BasicStdLayoutBaseVS
2133 {
GetInput(std::vector<GLubyte> & in_data)2134 virtual const char *GetInput(std::vector<GLubyte> &in_data)
2135 {
2136 return GetInput140c6(in_data);
2137 }
2138 };
2139
2140 class BasicStd140LayoutCase6CS : public BasicStdLayoutBaseCS
2141 {
GetInput(std::vector<GLubyte> & in_data)2142 virtual const char *GetInput(std::vector<GLubyte> &in_data)
2143 {
2144 return GetInput140c6(in_data);
2145 }
2146 };
2147
2148 //-----------------------------------------------------------------------------
2149 // 1.8.1 BasicAtomicCase1
2150 //-----------------------------------------------------------------------------
2151 class BasicAtomicCase1VSFS : public ShaderStorageBufferObjectBase
2152 {
2153 GLuint m_program;
2154 GLuint m_storage_buffer[4];
2155 GLuint m_vertex_array;
2156 GLuint m_vertex_buffer;
2157
Setup()2158 virtual long Setup()
2159 {
2160 m_program = 0;
2161 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
2162 m_vertex_array = 0;
2163 m_vertex_buffer = 0;
2164 return NO_ERROR;
2165 }
Run()2166 virtual long Run()
2167 {
2168 if (!IsVSFSAvailable(2, 2))
2169 return NOT_SUPPORTED;
2170 const char *const glsl_vs = NL
2171 "layout(location = 0) in vec4 g_in_position;" NL "layout(std430, binding = 0) coherent buffer VSuint {" NL
2172 " uint g_uint_out[4];" NL "};" NL "layout(std430, binding = 1) coherent buffer VSint {" NL
2173 " int data[4];" NL "} g_int_out;" NL "uniform uint g_uint_value[8];" NL "flat out int vertexid;" NL
2174 "void main() {" NL " gl_Position = g_in_position;" NL " vertexid = gl_VertexID;" NL "#ifdef GL_ES" NL
2175 " gl_PointSize = 1.0f;" NL "#endif" NL NL
2176 " // 0 is the initial value of g_uint_out while 7 is the value at the end shader execution." NL
2177 " // Since vertex shader can be executed multiple times due to implementation dependent reasons," NL
2178 " // initial validation should consider both value as possibility." NL
2179 " uint ret = atomicExchange(g_uint_out[gl_VertexID], g_uint_value[1]);" NL
2180 " if ((ret != 0u) && (ret != 7u)) return;" NL
2181 " if (atomicAdd(g_uint_out[gl_VertexID], g_uint_value[2]) != 1u) return;" NL
2182 " if (atomicMin(g_uint_out[gl_VertexID], g_uint_value[1]) != 3u) return;" NL
2183 " if (atomicMax(g_uint_out[gl_VertexID], g_uint_value[2]) != 1u) return;" NL
2184 " if (atomicAnd(g_uint_out[gl_VertexID], g_uint_value[3]) != 2u) return;" NL
2185 " if (atomicOr(g_uint_out[gl_VertexID], g_uint_value[4]) != 0u) return;" NL
2186 " if (g_uint_value[0] > 0u) {" NL
2187 " if (atomicXor(g_uint_out[gl_VertexID], g_uint_value[5]) != 3u) return;" NL " }" NL
2188 " if (atomicCompSwap(g_uint_out[gl_VertexID], g_uint_value[6], g_uint_value[7]) != 2u) {" NL
2189 " g_uint_out[gl_VertexID] = 1u;" NL " return;" NL " }" NL NL
2190 " int ret2 = atomicExchange(g_int_out.data[gl_VertexID], 1);" NL
2191 " if ((ret2 != 0) && (ret2 != 7)) return;" NL
2192 " if (atomicAdd(g_int_out.data[gl_VertexID], 2) != 1) return;" NL
2193 " if (atomicMin(g_int_out.data[gl_VertexID], 1) != 3) return;" NL
2194 " if (atomicMax(g_int_out.data[gl_VertexID], 2) != 1) return;" NL
2195 " if (atomicAnd(g_int_out.data[gl_VertexID], 0x1) != 2) return;" NL
2196 " if (atomicOr(g_int_out.data[gl_VertexID], 0x3) != 0) return;" NL
2197 " if (atomicXor(g_int_out.data[gl_VertexID], 0x1) != 3) return;" NL
2198 " if (atomicCompSwap(g_int_out.data[gl_VertexID], 0x2, 0x7) != 2) {" NL
2199 " g_int_out.data[gl_VertexID] = 1;" NL " return;" NL " }" NL "}";
2200
2201 const char *const glsl_fs = NL
2202 "flat in int vertexid;" NL "layout(location = 0) out vec4 g_fs_out;" NL
2203 "layout(std430, binding = 2) coherent buffer FSuint {" NL " uint data[4];" NL "} g_uint_fs;" NL
2204 "layout(std430, binding = 3) coherent buffer FSint {" NL " int data[4];" NL "} g_int_fs;" NL
2205 "uniform uint g_uint_value[8];" NL "void main() {" NL " g_fs_out = vec4(0, 1, 0, 1);" NL NL
2206 " if (atomicExchange(g_uint_fs.data[vertexid], g_uint_value[1]) != 0u) return;" // 0, 1
2207 NL " if (atomicAdd(g_uint_fs.data[vertexid], g_uint_value[2]) != 1u) return;" // 1, 2
2208 NL " if (atomicMin(g_uint_fs.data[vertexid], g_uint_value[1]) != 3u) return;" // 3, 1
2209 NL " if (atomicMax(g_uint_fs.data[vertexid], g_uint_value[2]) != 1u) return;" // 1, 2
2210 NL " if (atomicAnd(g_uint_fs.data[vertexid], g_uint_value[3]) != 2u) return;" // 2, 0x1
2211 NL " if (atomicOr(g_uint_fs.data[vertexid], g_uint_value[4]) != 0u) return;" // 0, 0x3
2212 NL " if (g_uint_value[0] > 0u) {" NL
2213 " if (atomicXor(g_uint_fs.data[vertexid], g_uint_value[5]) != 3u) return;" // 0x3, 0x1
2214 NL " }" NL
2215 " if (atomicCompSwap(g_uint_fs.data[vertexid], g_uint_value[6], g_uint_value[7]) != 2u) {" // 2, 0x2, 0x7
2216 NL " g_uint_fs.data[vertexid] = 1u;" NL " return;" NL " }" NL NL
2217 " if (atomicExchange(g_int_fs.data[vertexid], 1) != 0) return;" NL
2218 " if (atomicAdd(g_int_fs.data[vertexid], 2) != 1) return;" NL
2219 " if (atomicMin(g_int_fs.data[vertexid], 1) != 3) return;" NL
2220 " if (atomicMax(g_int_fs.data[vertexid], 2) != 1) return;" NL
2221 " if (atomicAnd(g_int_fs.data[vertexid], 0x1) != 2) return;" NL
2222 " if (atomicOr(g_int_fs.data[vertexid], 0x3) != 0) return;" NL
2223 " if (atomicXor(g_int_fs.data[vertexid], 0x1) != 3) return;" NL
2224 " if (atomicCompSwap(g_int_fs.data[vertexid], 0x2, 0x7) != 2) {" NL " g_int_fs.data[vertexid] = 1;" NL
2225 " return;" NL " }" NL "}";
2226 m_program = CreateProgram(glsl_vs, glsl_fs);
2227 glLinkProgram(m_program);
2228 if (!CheckProgram(m_program))
2229 return ERROR;
2230
2231 glGenBuffers(4, m_storage_buffer);
2232 for (GLuint i = 0; i < 4; ++i)
2233 {
2234 const int data[4] = {0};
2235 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
2236 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
2237 }
2238
2239 /* vertex buffer */
2240 {
2241 const float data[] = {-0.8f, -0.8f, 0.8f, -0.8f, -0.8f, 0.8f, 0.8f, 0.8f};
2242 glGenBuffers(1, &m_vertex_buffer);
2243 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2244 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
2245 glBindBuffer(GL_ARRAY_BUFFER, 0);
2246 }
2247
2248 glGenVertexArrays(1, &m_vertex_array);
2249 glBindVertexArray(m_vertex_array);
2250 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2251 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
2252 glBindBuffer(GL_ARRAY_BUFFER, 0);
2253 glEnableVertexAttribArray(0);
2254 glBindVertexArray(0);
2255
2256 glClear(GL_COLOR_BUFFER_BIT);
2257 glUseProgram(m_program);
2258 GLuint unif[8] = {3, 1, 2, 1, 3, 1, 2, 7};
2259 glUniform1uiv(glGetUniformLocation(m_program, "g_uint_value[0]"), 8, unif);
2260
2261 glBindVertexArray(m_vertex_array);
2262 glDrawArrays(GL_POINTS, 0, 4);
2263 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2264
2265 for (int ii = 0; ii < 2; ++ii)
2266 {
2267 /* uint data */
2268 {
2269 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[ii * 2 + 0]);
2270 GLuint *data = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
2271 if (!data)
2272 return ERROR;
2273 for (GLuint i = 0; i < 4; ++i)
2274 {
2275 if (data[i] != 7)
2276 {
2277 m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is "
2278 << data[i] << " should be 7." << tcu::TestLog::EndMessage;
2279 return ERROR;
2280 }
2281 }
2282 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2283 }
2284 /* int data */
2285 {
2286 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[ii * 2 + 1]);
2287 GLint *data = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
2288 if (!data)
2289 return ERROR;
2290 for (GLint i = 0; i < 4; ++i)
2291 {
2292 if (data[i] != 7)
2293 {
2294 m_context.getTestContext().getLog() << tcu::TestLog::Message << "iData at index " << i << " is "
2295 << data[i] << " should be 7." << tcu::TestLog::EndMessage;
2296 return ERROR;
2297 }
2298 }
2299 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2300 }
2301 }
2302 return NO_ERROR;
2303 }
Cleanup()2304 virtual long Cleanup()
2305 {
2306 glUseProgram(0);
2307 glDeleteProgram(m_program);
2308 glDeleteBuffers(4, m_storage_buffer);
2309 glDeleteBuffers(1, &m_vertex_buffer);
2310 glDeleteVertexArrays(1, &m_vertex_array);
2311 return NO_ERROR;
2312 }
2313 };
2314
2315 class BasicAtomicCase1CS : public ShaderStorageBufferObjectBase
2316 {
2317 GLuint m_program;
2318 GLuint m_storage_buffer[2];
2319
Setup()2320 virtual long Setup()
2321 {
2322 m_program = 0;
2323 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
2324 return NO_ERROR;
2325 }
2326
Run()2327 virtual long Run()
2328 {
2329 const char *const glsl_cs =
2330 NL "layout(local_size_x = 4) in;" NL "layout(std430, binding = 2) coherent buffer FSuint {" NL
2331 " uint data[4];" NL "} g_uint_fs;" NL "layout(std430, binding = 3) coherent buffer FSint {" NL
2332 " int data[4];" NL "} g_int_fs;" NL "uniform uint g_uint_value[8];" NL "void main() {" NL
2333 " if (atomicExchange(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[1]) != 0u) return;" // 0, 1
2334 NL " if (atomicAdd(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[2]) != 1u) return;" // 1, 2
2335 NL " if (atomicMin(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[1]) != 3u) return;" // 3, 1
2336 NL " if (atomicMax(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[2]) != 1u) return;" // 1, 2
2337 NL " if (atomicAnd(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[3]) != 2u) return;" // 2, 0x1
2338 NL " if (atomicOr(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[4]) != 0u) return;" // 0, 0x3
2339 NL " if (g_uint_value[0] > 0u) {" NL
2340 " if (atomicXor(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[5]) != 3u) return;" // 0x3, 0x1
2341 NL " }" NL " if (atomicCompSwap(g_uint_fs.data[gl_LocalInvocationIndex], g_uint_value[6], "
2342 "g_uint_value[7]) != 2u) {" // 2, 0x2, 0x7
2343 NL " g_uint_fs.data[gl_LocalInvocationIndex] = 1u;" NL " return;" NL " }" NL
2344 " if (atomicExchange(g_int_fs.data[gl_LocalInvocationIndex], 1) != 0) return;" NL
2345 " if (atomicAdd(g_int_fs.data[gl_LocalInvocationIndex], 2) != 1) return;" NL
2346 " if (atomicMin(g_int_fs.data[gl_LocalInvocationIndex], 1) != 3) return;" NL
2347 " if (atomicMax(g_int_fs.data[gl_LocalInvocationIndex], 2) != 1) return;" NL
2348 " if (atomicAnd(g_int_fs.data[gl_LocalInvocationIndex], 0x1) != 2) return;" NL
2349 " if (atomicOr(g_int_fs.data[gl_LocalInvocationIndex], 0x3) != 0) return;" NL
2350 " if (atomicXor(g_int_fs.data[gl_LocalInvocationIndex], 0x1) != 3) return;" NL
2351 " if (atomicCompSwap(g_int_fs.data[gl_LocalInvocationIndex], 0x2, 0x7) != 2) {" NL
2352 " g_int_fs.data[gl_LocalInvocationIndex] = 1;" NL " return;" NL " }" NL "}";
2353 m_program = CreateProgramCS(glsl_cs);
2354 glLinkProgram(m_program);
2355 if (!CheckProgram(m_program))
2356 return ERROR;
2357
2358 glGenBuffers(2, m_storage_buffer);
2359 for (GLuint i = 0; i < 2; ++i)
2360 {
2361 const int data[4] = {0};
2362 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i + 2, m_storage_buffer[i]);
2363 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
2364 }
2365
2366 glUseProgram(m_program);
2367 GLuint unif[8] = {3, 1, 2, 1, 3, 1, 2, 7};
2368 glUniform1uiv(glGetUniformLocation(m_program, "g_uint_value[0]"), 8, unif);
2369 glDispatchCompute(1, 1, 1);
2370 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2371
2372 /* uint data */
2373 {
2374 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
2375 GLuint *data = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
2376 if (!data)
2377 return ERROR;
2378 for (GLuint i = 0; i < 4; ++i)
2379 {
2380 if (data[i] != 7)
2381 {
2382 m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is "
2383 << data[i] << " should be 7." << tcu::TestLog::EndMessage;
2384 return ERROR;
2385 }
2386 }
2387 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2388 }
2389 /* int data */
2390 {
2391 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
2392 GLint *data = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
2393 if (!data)
2394 return ERROR;
2395 for (GLint i = 0; i < 4; ++i)
2396 {
2397 if (data[i] != 7)
2398 {
2399 m_context.getTestContext().getLog() << tcu::TestLog::Message << "iData at index " << i << " is "
2400 << data[i] << " should be 7." << tcu::TestLog::EndMessage;
2401 return ERROR;
2402 }
2403 }
2404 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2405 }
2406 return NO_ERROR;
2407 }
2408
Cleanup()2409 virtual long Cleanup()
2410 {
2411 glUseProgram(0);
2412 glDeleteProgram(m_program);
2413 glDeleteBuffers(2, m_storage_buffer);
2414 return NO_ERROR;
2415 }
2416 };
2417
2418 //-----------------------------------------------------------------------------
2419 // 1.8.3 BasicAtomicCase3
2420 //-----------------------------------------------------------------------------
2421 class BasicAtomicCase3VSFS : public ShaderStorageBufferObjectBase
2422 {
2423 GLuint m_program;
2424 GLuint m_storage_buffer;
2425 GLuint m_vertex_array;
2426 GLuint m_vertex_buffer;
2427
Setup()2428 virtual long Setup()
2429 {
2430 m_program = 0;
2431 m_storage_buffer = 0;
2432 m_vertex_array = 0;
2433 m_vertex_buffer = 0;
2434 return NO_ERROR;
2435 }
Run()2436 virtual long Run()
2437 {
2438 if (!IsVSFSAvailable(1, 1))
2439 return NOT_SUPPORTED;
2440
2441 const char *const glsl_vs = NL
2442 "layout(location = 0) in vec4 g_in_position;" NL "layout(std430, binding = 0) coherent buffer Buffer {" NL
2443 " uvec4 u[4];" NL " ivec3 i[4];" NL "} g_vs_buffer;" NL "flat out int vertexid;" NL "void main() {" NL
2444 " vertexid = gl_VertexID;" NL " gl_Position = g_in_position;" NL "#ifdef GL_ES" NL
2445 " gl_PointSize = 1.0f;" NL "#endif" NL " atomicAdd(g_vs_buffer.u[0].x, g_vs_buffer.u[gl_VertexID][1]);" NL
2446 " atomicAdd(g_vs_buffer.u[0][0], g_vs_buffer.u[gl_VertexID].z);" NL
2447 " atomicAdd(g_vs_buffer.i[0].x, g_vs_buffer.i[gl_VertexID][1]);" NL
2448 " atomicAdd(g_vs_buffer.i[0][0], g_vs_buffer.i[gl_VertexID].z);" NL "}";
2449
2450 const char *const glsl_fs =
2451 NL "layout(location = 0) out vec4 g_fs_out;" NL "layout(std430, binding = 0) coherent buffer Buffer {" NL
2452 " uvec4 u[4];" NL " ivec3 i[4];" NL "} g_fs_buffer;" NL "flat in int vertexid;" NL "void main() {" NL
2453 " g_fs_out = vec4(0, 1, 0, 1);" NL " atomicAdd(g_fs_buffer.u[0].x, g_fs_buffer.u[vertexid][1]);" NL
2454 " atomicAdd(g_fs_buffer.i[0].x, g_fs_buffer.i[vertexid][1]);" NL "}";
2455 m_program = CreateProgram(glsl_vs, glsl_fs);
2456 glLinkProgram(m_program);
2457 if (!CheckProgram(m_program))
2458 return ERROR;
2459
2460 /* init storage buffer */
2461 {
2462 glGenBuffers(1, &m_storage_buffer);
2463 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
2464 glBufferData(GL_SHADER_STORAGE_BUFFER, 8 * sizeof(int) * 4, NULL, GL_DYNAMIC_DRAW);
2465 ivec4 *ptr = reinterpret_cast<ivec4 *>(
2466 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8 * sizeof(int) * 4, GL_MAP_WRITE_BIT));
2467 if (!ptr)
2468 return ERROR;
2469 for (int i = 0; i < 4; ++i)
2470 {
2471 ptr[i * 2] = ivec4(0, 1, 2, 0);
2472 ptr[i * 2 + 1] = ivec4(0, 1, 2, 0);
2473 }
2474 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2475 }
2476
2477 /* init vertex buffer */
2478 {
2479 const float data[] = {-0.8f, -0.8f, 0.8f, -0.8f, -0.8f, 0.8f, 0.8f, 0.8f};
2480 glGenBuffers(1, &m_vertex_buffer);
2481 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2482 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
2483 glBindBuffer(GL_ARRAY_BUFFER, 0);
2484 }
2485
2486 glGenVertexArrays(1, &m_vertex_array);
2487 glBindVertexArray(m_vertex_array);
2488 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2489 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
2490 glBindBuffer(GL_ARRAY_BUFFER, 0);
2491 glEnableVertexAttribArray(0);
2492 glBindVertexArray(0);
2493
2494 glClear(GL_COLOR_BUFFER_BIT);
2495 glUseProgram(m_program);
2496 glBindVertexArray(m_vertex_array);
2497 glDrawArrays(GL_POINTS, 0, 4);
2498 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2499
2500 GLuint *u = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
2501 if (!u)
2502 return ERROR;
2503 /* g_vs_buffer.u updated in VS which can be invoked multiple times per vertex */
2504 if (*u < 16)
2505 {
2506 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at offset 0 is " << *u
2507 << " should be at least 16." << tcu::TestLog::EndMessage;
2508 return ERROR;
2509 }
2510 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2511 GLint *i = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 64, 4, GL_MAP_READ_BIT);
2512 if (!i)
2513 return ERROR;
2514 /* g_vs_buffer.i updated in VS which can be invoked multiple times per vertex */
2515 if (*i < 16)
2516 {
2517 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at offset 0 is " << *i
2518 << " should be at least 16." << tcu::TestLog::EndMessage;
2519 return ERROR;
2520 }
2521 /* g_vs_buffer.u should be equivalent to g_vs_buffer.i */
2522 if (*u != static_cast<GLuint>(*i))
2523 {
2524 m_context.getTestContext().getLog() << tcu::TestLog::Message << "uvec data " << *u << "and ivec data " << *i
2525 << "should match" << tcu::TestLog::EndMessage;
2526 return ERROR;
2527 }
2528 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2529
2530 return NO_ERROR;
2531 }
Cleanup()2532 virtual long Cleanup()
2533 {
2534 glUseProgram(0);
2535 glDeleteProgram(m_program);
2536 glDeleteBuffers(1, &m_storage_buffer);
2537 glDeleteBuffers(1, &m_vertex_buffer);
2538 glDeleteVertexArrays(1, &m_vertex_array);
2539 return NO_ERROR;
2540 }
2541 };
2542
2543 class BasicAtomicCase3CS : public ShaderStorageBufferObjectBase
2544 {
2545 GLuint m_program;
2546 GLuint m_storage_buffer;
2547
Setup()2548 virtual long Setup()
2549 {
2550 m_program = 0;
2551 m_storage_buffer = 0;
2552 return NO_ERROR;
2553 }
Run()2554 virtual long Run()
2555 {
2556 const char *const glsl_cs =
2557 NL "layout(local_size_y = 4) in;" NL "layout(std430) coherent buffer Buffer {" NL " uvec4 u[4];" NL
2558 " ivec3 i[4];" NL "} g_fs_buffer;" NL "void main() {" NL
2559 " atomicAdd(g_fs_buffer.u[0].x, g_fs_buffer.u[gl_LocalInvocationID.y][2]);" NL
2560 " atomicAdd(g_fs_buffer.i[0].x, 2 * g_fs_buffer.i[gl_LocalInvocationID.y][1]);" NL
2561 " atomicAdd(g_fs_buffer.u[0].x, g_fs_buffer.u[gl_LocalInvocationID.y].z);" NL
2562 " atomicAdd(g_fs_buffer.i[0].x, 2 * g_fs_buffer.i[gl_LocalInvocationID.y].y);" NL "}";
2563 m_program = CreateProgramCS(glsl_cs);
2564 glLinkProgram(m_program);
2565 if (!CheckProgram(m_program))
2566 return ERROR;
2567
2568 /* init storage buffer */
2569 {
2570 glGenBuffers(1, &m_storage_buffer);
2571 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
2572 glBufferData(GL_SHADER_STORAGE_BUFFER, 8 * sizeof(int) * 4, NULL, GL_DYNAMIC_DRAW);
2573 ivec4 *ptr = reinterpret_cast<ivec4 *>(
2574 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8 * sizeof(int) * 4, GL_MAP_WRITE_BIT));
2575 if (!ptr)
2576 return ERROR;
2577 for (int i = 0; i < 4; ++i)
2578 {
2579 ptr[i * 2] = ivec4(0, 1, 2, 0);
2580 ptr[i * 2 + 1] = ivec4(0, 1, 2, 0);
2581 }
2582 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2583 }
2584
2585 glUseProgram(m_program);
2586 glDispatchCompute(1, 1, 1);
2587 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2588
2589 GLuint *u = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
2590 if (!u)
2591 return ERROR;
2592 if (*u != 16)
2593 {
2594 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at offset 0 is " << *u
2595 << " should be 16." << tcu::TestLog::EndMessage;
2596 return ERROR;
2597 }
2598 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2599 GLint *i = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 64, 4, GL_MAP_READ_BIT);
2600 if (!i)
2601 return ERROR;
2602 if (*i != 16)
2603 {
2604 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at offset 0 is " << *i
2605 << " should be 16." << tcu::TestLog::EndMessage;
2606 return ERROR;
2607 }
2608 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2609
2610 return NO_ERROR;
2611 }
Cleanup()2612 virtual long Cleanup()
2613 {
2614 glUseProgram(0);
2615 glDeleteProgram(m_program);
2616 glDeleteBuffers(1, &m_storage_buffer);
2617 return NO_ERROR;
2618 }
2619 };
2620
2621 //-----------------------------------------------------------------------------
2622 // 1.8.4 BasicAtomicCase4
2623 //-----------------------------------------------------------------------------
2624 class BasicAtomicCase4VSFS : public ShaderStorageBufferObjectBase
2625 {
2626 GLuint m_program;
2627 GLuint m_storage_buffer[3];
2628 GLuint m_vertex_array;
2629 GLuint m_vertex_buffer;
2630
Setup()2631 virtual long Setup()
2632 {
2633 m_program = 0;
2634 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
2635 m_vertex_array = 0;
2636 m_vertex_buffer = 0;
2637 return NO_ERROR;
2638 }
Run()2639 virtual long Run()
2640 {
2641 if (!IsVSFSAvailable(2, 2))
2642 return NOT_SUPPORTED;
2643 const char *const glsl_vs = NL
2644 "layout(location = 0) in vec4 g_in_position;" NL "layout(std430, binding = 0) coherent buffer Counters {" NL
2645 " uint g_uint_counter;" NL " int g_int_counter;" NL "};" NL
2646 "layout(std430, binding = 1) buffer OutputU {" NL " uint udata[8];" NL "} g_outputU;" NL
2647 "layout(std430, binding = 2) buffer OutputI {" NL " int idata[8];" NL "} g_outputI;" NL "void main() {" NL
2648 " gl_Position = g_in_position;" NL "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL
2649 " uint uidx = atomicAdd(g_uint_counter, 1u);" NL " int iidx = atomicAdd(g_int_counter, -1);" NL
2650 " g_outputU.udata[uidx] = uidx;" NL " g_outputI.idata[iidx] = iidx;" NL "}";
2651 const char *const glsl_fs =
2652 NL "layout(location = 0) out vec4 g_fs_out;" NL "layout(std430, binding = 0) coherent buffer Counters {" NL
2653 " uint g_uint_counter;" NL " int g_int_counter;" NL "};" NL
2654 "layout(std430, binding = 1) buffer OutputU {" NL " uint udata[8];" NL "} g_outputU;" NL
2655 "layout(std430, binding = 2) buffer OutputI {" NL " int idata[8];" NL "} g_outputI;" NL
2656 "void main() {" NL " g_fs_out = vec4(0, 1, 0, 1);" NL " uint uidx = atomicAdd(g_uint_counter, 1u);" NL
2657 " int iidx = atomicAdd(g_int_counter, -1);" NL " g_outputU.udata[uidx] = uidx;" NL
2658 " g_outputI.idata[iidx] = iidx;" NL "}";
2659 m_program = CreateProgram(glsl_vs, glsl_fs);
2660 glLinkProgram(m_program);
2661 if (!CheckProgram(m_program))
2662 return ERROR;
2663
2664 glGenBuffers(3, m_storage_buffer);
2665 /* counter buffer */
2666 {
2667 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
2668 glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2669 int *ptr = reinterpret_cast<int *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_WRITE_BIT));
2670 if (!ptr)
2671 return ERROR;
2672 *ptr++ = 0;
2673 *ptr++ = 7;
2674 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2675 }
2676 /* output buffers */
2677 {
2678 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
2679 glBufferData(GL_SHADER_STORAGE_BUFFER, 8 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2680 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
2681 glBufferData(GL_SHADER_STORAGE_BUFFER, 8 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2682 }
2683 /* vertex buffer */
2684 {
2685 const float data[] = {-0.8f, -0.8f, 0.8f, -0.8f, -0.8f, 0.8f, 0.8f, 0.8f};
2686 glGenBuffers(1, &m_vertex_buffer);
2687 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2688 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
2689 glBindBuffer(GL_ARRAY_BUFFER, 0);
2690 }
2691
2692 glGenVertexArrays(1, &m_vertex_array);
2693 glBindVertexArray(m_vertex_array);
2694 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2695 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
2696 glBindBuffer(GL_ARRAY_BUFFER, 0);
2697 glEnableVertexAttribArray(0);
2698 glBindVertexArray(0);
2699
2700 glClear(GL_COLOR_BUFFER_BIT);
2701 glUseProgram(m_program);
2702 glBindVertexArray(m_vertex_array);
2703 glDrawArrays(GL_POINTS, 0, 4);
2704 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2705
2706 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
2707 GLuint *udata = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_READ_BIT);
2708 if (!udata)
2709 return ERROR;
2710 for (GLuint i = 0; i < 8; ++i)
2711 {
2712 if (udata[i] != i)
2713 {
2714 m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is "
2715 << udata[i] << " should be " << i << tcu::TestLog::EndMessage;
2716 return ERROR;
2717 }
2718 }
2719 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2720
2721 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
2722 GLint *idata = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_READ_BIT);
2723 if (!idata)
2724 return ERROR;
2725 for (GLint i = 0; i < 8; ++i)
2726 {
2727 if (idata[i] != i)
2728 {
2729 m_context.getTestContext().getLog() << tcu::TestLog::Message << "iData at index " << i << " is "
2730 << idata[i] << " should be " << i << tcu::TestLog::EndMessage;
2731 return ERROR;
2732 }
2733 }
2734 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2735 return NO_ERROR;
2736 }
Cleanup()2737 virtual long Cleanup()
2738 {
2739 glUseProgram(0);
2740 glDeleteProgram(m_program);
2741 glDeleteBuffers(3, m_storage_buffer);
2742 glDeleteBuffers(1, &m_vertex_buffer);
2743 glDeleteVertexArrays(1, &m_vertex_array);
2744 return NO_ERROR;
2745 }
2746 };
2747
2748 class BasicAtomicCase4CS : public ShaderStorageBufferObjectBase
2749 {
2750 GLuint m_program;
2751 GLuint m_storage_buffer[2];
2752
Setup()2753 virtual long Setup()
2754 {
2755 m_program = 0;
2756 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
2757 return NO_ERROR;
2758 }
Run()2759 virtual long Run()
2760 {
2761 const char *const glsl_cs =
2762 NL "layout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;" NL
2763 "layout(std430, binding = 0) coherent buffer Counters {" NL " uint g_uint_counter;" NL
2764 " int g_int_counter;" NL "};" NL "layout(std430, binding = 1) buffer Output {" NL " uint udata[8];" NL
2765 " int idata[8];" NL "} g_output;" NL "void main() {" NL
2766 " uint uidx = atomicAdd(g_uint_counter, 1u);" NL " int iidx = atomicAdd(g_int_counter, -1);" NL
2767 " g_output.udata[uidx] = uidx;" NL " g_output.idata[iidx] = iidx;" NL "}";
2768 m_program = CreateProgramCS(glsl_cs);
2769 glLinkProgram(m_program);
2770 if (!CheckProgram(m_program))
2771 return ERROR;
2772
2773 glGenBuffers(2, m_storage_buffer);
2774 /* counter buffer */
2775 {
2776 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
2777 glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2778 int *ptr = reinterpret_cast<int *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_WRITE_BIT));
2779 if (!ptr)
2780 return ERROR;
2781 *ptr++ = 0;
2782 *ptr++ = 7;
2783 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2784 }
2785 /* output buffer */
2786 {
2787 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
2788 glBufferData(GL_SHADER_STORAGE_BUFFER, 16 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2789 }
2790 glUseProgram(m_program);
2791 glDispatchCompute(1, 1, 1);
2792 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2793
2794 GLuint *udata = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_READ_BIT);
2795 if (!udata)
2796 return ERROR;
2797 for (GLuint i = 0; i < 8; ++i)
2798 {
2799 if (udata[i] != i)
2800 {
2801 m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is "
2802 << udata[i] << " should be " << i << tcu::TestLog::EndMessage;
2803 return ERROR;
2804 }
2805 }
2806 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2807 GLint *idata = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 32, 32, GL_MAP_READ_BIT);
2808 if (!idata)
2809 return ERROR;
2810 for (GLint i = 0; i < 8; ++i)
2811 {
2812 if (idata[i] != i)
2813 {
2814 m_context.getTestContext().getLog() << tcu::TestLog::Message << "iData at index " << i << " is "
2815 << idata[i] << " should be " << i << tcu::TestLog::EndMessage;
2816 return ERROR;
2817 }
2818 }
2819 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2820 return NO_ERROR;
2821 }
Cleanup()2822 virtual long Cleanup()
2823 {
2824 glUseProgram(0);
2825 glDeleteProgram(m_program);
2826 glDeleteBuffers(2, m_storage_buffer);
2827 return NO_ERROR;
2828 }
2829 };
2830
2831 //-----------------------------------------------------------------------------
2832 // 1.9.x BasicStdLayoutBase2
2833 //-----------------------------------------------------------------------------
2834 class BasicStdLayoutBase2VS : public ShaderStorageBufferObjectBase
2835 {
2836 GLuint m_program;
2837 GLuint m_buffer[8];
2838 GLuint m_vertex_array;
2839
2840 virtual const char *GetInput(std::vector<GLubyte> in_data[4]) = 0;
2841
Setup()2842 virtual long Setup()
2843 {
2844 m_program = 0;
2845 memset(m_buffer, 0, sizeof(m_buffer));
2846 m_vertex_array = 0;
2847 return NO_ERROR;
2848 }
Run()2849 virtual long Run()
2850 {
2851 if (!IsVSFSAvailable(8, 0))
2852 return NOT_SUPPORTED;
2853 std::vector<GLubyte> in_data[4];
2854 const char *glsl_vs = GetInput(in_data);
2855 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
2856 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
2857
2858 m_program = CreateProgram(glsl_vs, glsl_fs);
2859 glLinkProgram(m_program);
2860 if (!CheckProgram(m_program))
2861 return ERROR;
2862
2863 glGenBuffers(8, m_buffer);
2864
2865 for (GLuint i = 0; i < 4; ++i)
2866 {
2867 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_buffer[i]);
2868 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &in_data[i][0], GL_STATIC_DRAW);
2869
2870 std::vector<GLubyte> out_data(in_data[i].size());
2871 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i + 4, m_buffer[i + 4]);
2872 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &out_data[0], GL_STATIC_DRAW);
2873 }
2874
2875 glGenVertexArrays(1, &m_vertex_array);
2876 glEnable(GL_RASTERIZER_DISCARD);
2877
2878 glUseProgram(m_program);
2879 glBindVertexArray(m_vertex_array);
2880 glDrawArrays(GL_POINTS, 0, 1);
2881
2882 bool status = true;
2883 for (int j = 0; j < 4; ++j)
2884 {
2885 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 4]);
2886 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2887 GLubyte *out_data = (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(),
2888 GL_MAP_READ_BIT);
2889 if (!out_data)
2890 return ERROR;
2891
2892 for (size_t i = 0; i < in_data[j].size(); ++i)
2893 {
2894 if (in_data[j][i] != out_data[i])
2895 {
2896 m_context.getTestContext().getLog()
2897 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
2898 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
2899 << tcu::TestLog::EndMessage;
2900 status = false;
2901 }
2902 }
2903 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2904 }
2905 if (!status)
2906 return ERROR;
2907 return NO_ERROR;
2908 }
Cleanup()2909 virtual long Cleanup()
2910 {
2911 glDisable(GL_RASTERIZER_DISCARD);
2912 glUseProgram(0);
2913 glDeleteProgram(m_program);
2914 glDeleteBuffers(8, m_buffer);
2915 glDeleteVertexArrays(1, &m_vertex_array);
2916 return NO_ERROR;
2917 }
2918 };
2919
2920 class BasicStdLayoutBase2CS : public ShaderStorageBufferObjectBase
2921 {
2922 GLuint m_program;
2923 GLuint m_buffer[8];
2924
2925 virtual const char *GetInput(std::vector<GLubyte> in_data[4]) = 0;
2926
Setup()2927 virtual long Setup()
2928 {
2929 m_program = 0;
2930 memset(m_buffer, 0, sizeof(m_buffer));
2931 return NO_ERROR;
2932 }
2933
Run()2934 virtual long Run()
2935 {
2936 std::vector<GLubyte> in_data[4];
2937 std::stringstream ss;
2938 GLint blocksCS;
2939 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &blocksCS);
2940 if (blocksCS < 8)
2941 return NO_ERROR;
2942 ss << "layout(local_size_x = 1) in;\n" << GetInput(in_data);
2943 m_program = CreateProgramCS(ss.str());
2944 glLinkProgram(m_program);
2945 if (!CheckProgram(m_program))
2946 return ERROR;
2947
2948 glGenBuffers(8, m_buffer);
2949
2950 for (GLuint i = 0; i < 4; ++i)
2951 {
2952 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_buffer[i]);
2953 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &in_data[i][0], GL_STATIC_DRAW);
2954
2955 std::vector<GLubyte> out_data(in_data[i].size());
2956 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i + 4, m_buffer[i + 4]);
2957 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &out_data[0], GL_STATIC_DRAW);
2958 }
2959
2960 glUseProgram(m_program);
2961 glDispatchCompute(1, 1, 1);
2962 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2963
2964 bool status = true;
2965 for (int j = 0; j < 4; ++j)
2966 {
2967 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 4]);
2968 GLubyte *out_data = (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(),
2969 GL_MAP_READ_BIT);
2970 if (!out_data)
2971 return ERROR;
2972
2973 for (size_t i = 0; i < in_data[j].size(); ++i)
2974 {
2975 if (in_data[j][i] != out_data[i])
2976 {
2977 m_context.getTestContext().getLog()
2978 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
2979 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
2980 << tcu::TestLog::EndMessage;
2981 status = false;
2982 }
2983 }
2984 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2985 }
2986 if (!status)
2987 return ERROR;
2988 return NO_ERROR;
2989 }
2990
Cleanup()2991 virtual long Cleanup()
2992 {
2993 glUseProgram(0);
2994 glDeleteProgram(m_program);
2995 glDeleteBuffers(8, m_buffer);
2996 return NO_ERROR;
2997 }
2998 };
2999 //-----------------------------------------------------------------------------
3000 // 1.9.1 BasicStdLayoutCase1
3001 //-----------------------------------------------------------------------------
GetInputC1(std::vector<GLubyte> in_data[4])3002 const char *GetInputC1(std::vector<GLubyte> in_data[4])
3003 {
3004 for (int i = 0; i < 4; ++i)
3005 {
3006 in_data[i].resize(1 * 4);
3007 float *fp = reinterpret_cast<float *>(&in_data[i][0]);
3008 fp[0] = static_cast<float>(i + 1) * 1.0f;
3009 }
3010 return NL "layout(std430, binding = 0) buffer Input {" NL " float data0;" NL "} g_input[4];" NL
3011 "layout(std430, binding = 4) buffer Output {" NL " float data0;" NL "} g_output[4];" NL
3012 "void main() {" NL " g_output[0].data0 = g_input[0].data0;" NL
3013 " g_output[1].data0 = g_input[1].data0;" NL " g_output[2].data0 = g_input[2].data0;" NL
3014 " g_output[3].data0 = g_input[3].data0;" NL "}";
3015 }
3016
3017 class BasicStdLayoutCase1VS : public BasicStdLayoutBase2VS
3018 {
GetInput(std::vector<GLubyte> in_data[4])3019 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3020 {
3021 return GetInputC1(in_data);
3022 }
3023 };
3024
3025 class BasicStdLayoutCase1CS : public BasicStdLayoutBase2CS
3026 {
GetInput(std::vector<GLubyte> in_data[4])3027 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3028 {
3029 return GetInputC1(in_data);
3030 }
3031 };
3032
3033 //-----------------------------------------------------------------------------
3034 // 1.9.2 BasicStdLayoutCase2
3035 //-----------------------------------------------------------------------------
GetInputC2(std::vector<GLubyte> in_data[4])3036 const char *GetInputC2(std::vector<GLubyte> in_data[4])
3037 {
3038 /* input 0, std140 */
3039 {
3040 in_data[0].resize(12 * 4);
3041 float *fp = reinterpret_cast<float *>(&in_data[0][0]);
3042 fp[0] = 1.0f;
3043 fp[1] = 0.0f;
3044 fp[2] = 0.0f;
3045 fp[3] = 0.0f;
3046 fp[4] = 2.0f;
3047 fp[5] = 0.0f;
3048 fp[6] = 0.0f;
3049 fp[7] = 0.0f;
3050 fp[8] = 3.0f;
3051 fp[9] = 0.0f;
3052 fp[10] = 0.0f;
3053 fp[11] = 0.0f;
3054 }
3055 /* input 1, std430 */
3056 {
3057 in_data[1].resize(3 * 4);
3058 float *fp = reinterpret_cast<float *>(&in_data[1][0]);
3059 fp[0] = 4.0f;
3060 fp[1] = 5.0f;
3061 fp[2] = 6.0f;
3062 }
3063 /* input 2, std140 */
3064 {
3065 in_data[2].resize(12 * 4);
3066 float *fp = reinterpret_cast<float *>(&in_data[2][0]);
3067 fp[0] = 7.0f;
3068 fp[1] = 0.0f;
3069 fp[2] = 0.0f;
3070 fp[3] = 0.0f;
3071 fp[4] = 8.0f;
3072 fp[5] = 0.0f;
3073 fp[6] = 0.0f;
3074 fp[7] = 0.0f;
3075 fp[8] = 9.0f;
3076 fp[9] = 0.0f;
3077 fp[10] = 0.0f;
3078 fp[11] = 0.0f;
3079 }
3080 /* input 3, std430 */
3081 {
3082 in_data[3].resize(3 * 4);
3083 float *fp = reinterpret_cast<float *>(&in_data[3][0]);
3084 fp[0] = 10.0f;
3085 fp[1] = 11.0f;
3086 fp[2] = 12.0f;
3087 }
3088 return NL "layout(std140, binding = 0) buffer Input0 {" NL " float data0[3];" NL "} g_input0;" NL
3089 "layout(std430, binding = 1) buffer Input1 {" NL " float data0[3];" NL "} g_input1;" NL
3090 "layout(std140, binding = 2) buffer Input2 {" NL " float data0[3];" NL "} g_input2;" NL
3091 "layout(std430, binding = 3) buffer Input3 {" NL " float data0[3];" NL "} g_input3;" NL
3092 "layout(std140, binding = 4) buffer Output0 {" NL " float data0[3];" NL "} g_output0;" NL
3093 "layout(std430, binding = 5) buffer Output1 {" NL " float data0[3];" NL "} g_output1;" NL
3094 "layout(std140, binding = 6) buffer Output2 {" NL " float data0[3];" NL "} g_output2;" NL
3095 "layout(std430, binding = 7) buffer Output3 {" NL " float data0[3];" NL "} g_output3;" NL
3096 "void main() {" NL
3097 " for (int i = 0; i < g_input0.data0.length(); ++i) g_output0.data0[i] = g_input0.data0[i];" NL
3098 " for (int i = 0; i < g_input1.data0.length(); ++i) g_output1.data0[i] = g_input1.data0[i];" NL
3099 " for (int i = 0; i < g_input2.data0.length(); ++i) g_output2.data0[i] = g_input2.data0[i];" NL
3100 " for (int i = 0; i < g_input3.data0.length(); ++i) g_output3.data0[i] = g_input3.data0[i];" NL "}";
3101 }
3102
3103 class BasicStdLayoutCase2VS : public BasicStdLayoutBase2VS
3104 {
GetInput(std::vector<GLubyte> in_data[4])3105 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3106 {
3107 return GetInputC2(in_data);
3108 }
3109 };
3110
3111 class BasicStdLayoutCase2CS : public BasicStdLayoutBase2CS
3112 {
GetInput(std::vector<GLubyte> in_data[4])3113 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3114 {
3115 return GetInputC2(in_data);
3116 }
3117 };
3118
3119 //-----------------------------------------------------------------------------
3120 // 1.9.3 BasicStdLayoutCase3
3121 //-----------------------------------------------------------------------------
GetInputC3(std::vector<GLubyte> in_data[4])3122 const char *GetInputC3(std::vector<GLubyte> in_data[4])
3123 {
3124 /* input 0, std140 */
3125 {
3126 in_data[0].resize(62 * 4);
3127 float *fp = reinterpret_cast<float *>(&in_data[0][0]);
3128 int *ip = reinterpret_cast<int *>(&in_data[0][0]);
3129 ip[0] = 1;
3130 ip[1] = 0;
3131 ip[2] = 0;
3132 ip[3] = 0;
3133 fp[4] = 2.0f;
3134 fp[5] = 0.0f;
3135 fp[6] = 0.0f;
3136 fp[7] = 0.0f;
3137 fp[8] = 3.0f;
3138 fp[9] = 0.0f;
3139 fp[10] = 0.0f;
3140 fp[11] = 0.0f;
3141 fp[12] = 4.0f;
3142 fp[13] = 0.0f;
3143 fp[14] = 0.0f;
3144 fp[15] = 0.0f;
3145 fp[16] = 5.0f;
3146 fp[17] = 0.0f;
3147 fp[18] = 0.0f;
3148 fp[19] = 0.0f;
3149 fp[20] = 6.0f;
3150 fp[21] = 0.0f;
3151 fp[22] = 0.0f;
3152 fp[23] = 0.0f;
3153 fp[24] = 7.0f;
3154 fp[25] = 8.0f;
3155 fp[26] = 0.0f;
3156 fp[27] = 0.0f;
3157 fp[28] = 9.0f;
3158 fp[29] = 10.0f;
3159 fp[30] = 0.0f;
3160 fp[31] = 0.0f;
3161 fp[32] = 11.0f;
3162 fp[33] = 12.0f;
3163 fp[34] = 0.0f;
3164 fp[35] = 0.0f;
3165 fp[36] = 13.0f;
3166 fp[37] = 0.0f;
3167 fp[38] = 0.0f;
3168 fp[39] = 0.0f;
3169 fp[40] = 14.0f;
3170 fp[41] = 0.0f;
3171 fp[42] = 0.0f;
3172 fp[43] = 0.0f;
3173 fp[44] = 15.0f;
3174 fp[45] = 0.0f;
3175 fp[46] = 0.0f;
3176 fp[47] = 0.0f;
3177 ip[48] = 16;
3178 ip[49] = 0;
3179 ip[50] = 0;
3180 ip[51] = 0;
3181 ip[52] = 17;
3182 ip[53] = 18;
3183 ip[54] = 19;
3184 ip[55] = 0;
3185 }
3186 /* input 1, std430 */
3187 {
3188 in_data[1].resize(30 * 4);
3189 float *fp = reinterpret_cast<float *>(&in_data[1][0]);
3190 int *ip = reinterpret_cast<int *>(&in_data[1][0]);
3191 ip[0] = 1;
3192 fp[1] = 2.0f;
3193 fp[2] = 3.0f;
3194 fp[3] = 4.0f;
3195 fp[4] = 5.0f;
3196 fp[5] = 6.0f;
3197 fp[6] = 7.0f;
3198 fp[7] = 8.0f;
3199 fp[8] = 9.0f;
3200 fp[9] = 10.0f;
3201 fp[10] = 11.0f;
3202 fp[11] = 12.0f;
3203 fp[12] = 13.0f;
3204 fp[13] = 14.0f;
3205 fp[14] = 15.0f;
3206 ip[15] = 16;
3207 ip[16] = 17;
3208 ip[17] = 18;
3209 ip[18] = 19;
3210 }
3211 /* input 2, std140 */
3212 {
3213 in_data[2].resize(5 * 4);
3214 int *ip = reinterpret_cast<int *>(&in_data[2][0]);
3215 ip[0] = 1;
3216 ip[1] = 0;
3217 ip[2] = 0;
3218 ip[3] = 0;
3219 ip[4] = 2;
3220 }
3221 /* input 3, std430 */
3222 {
3223 in_data[3].resize(2 * 4);
3224 int *ip = reinterpret_cast<int *>(&in_data[3][0]);
3225 ip[0] = 1;
3226 ip[1] = 2;
3227 }
3228 return NL "layout(std140, binding = 0) buffer Input0 {" NL " int data0;" //BA=4, OF=[0]0, next=4
3229 NL " float data1[5];" //BA=16, OF=[4]16, next=96
3230 NL " mat3x2 data2;" //BA=16, OF=[24]96, next=144
3231 NL " float data3;" //BA=4, OF=[36]144,next=148
3232 NL " float data4[2];" //BA=16, OF=[40]160,next=192
3233 NL " int data5;" //BA=4, OF=[48]192,next=196
3234 NL " ivec3 data6;" //BA=16, OF=[52]208
3235 NL "} g_input0;" NL "layout(std430, binding = 1) buffer Input1 {" NL " int data0;" //BA=4, OF=[0], next=[1]
3236 NL " float data1[5];" //BA=4, OF=[1], next=[6]
3237 NL " mat3x2 data2;" //BA=8, OF=[6], next=[12]
3238 NL " float data3;" //BA=4, OF=[12], next=[13]
3239 NL " float data4[2];" //BA=4, OF=[13], next=[15]
3240 NL " int data5;" //BA=4, OF=[15], next=[16]
3241 NL " ivec3 data6;" //BA=16,OF=[16]
3242 NL "} g_input1;" NL "struct Struct0 {" NL " int data0;" NL "};" NL
3243 "layout(std140, binding = 2) buffer Input2 {" NL " int data0;" // offset 0
3244 NL " Struct0 data1;" // offset 16, struct should be aligned to a multiple of 16 bytes
3245 NL "} g_input2;" NL "layout(std430, binding = 3) buffer Input3 {" NL " int data0;" // offset 0
3246 NL " Struct0 data1;" // offset 4
3247 NL "} g_input3;"
3248
3249 NL "layout(std140, binding = 4) buffer Output0 {" NL " int data0;" NL " float data1[5];" NL
3250 " mat3x2 data2;" NL " float data3;" NL " float data4[2];" NL " int data5;" NL " ivec3 data6;" NL
3251 "} g_output0;" NL "layout(std430, binding = 5) buffer Output1 {" NL " int data0;" NL
3252 " float data1[5];" NL " mat3x2 data2;" NL " float data3;" NL " float data4[2];" NL " int data5;" NL
3253 " ivec3 data6;" NL "} g_output1;" NL "layout(std140, binding = 6) buffer Output2 {" NL " int data0;" NL
3254 " Struct0 data1;" NL "} g_output2;" NL "layout(std430, binding = 7) buffer Output3 {" NL
3255 " int data0;" NL " Struct0 data1;" NL "} g_output3;" NL "void main() {" NL
3256 " g_output0.data0 = g_input0.data0;" NL
3257 " for (int i = 0; i < g_input0.data1.length(); ++i) g_output0.data1[i] = g_input0.data1[i];" NL
3258 " g_output0.data2 = g_input0.data2;" NL " g_output0.data3 = g_input0.data3;" NL
3259 " for (int i = 0; i < g_input0.data4.length(); ++i) g_output0.data4[i] = g_input0.data4[i];" NL
3260 " g_output0.data5 = g_input0.data5;" NL " g_output0.data6 = g_input0.data6;"
3261
3262 NL " g_output1.data0 = g_input1.data0;" NL
3263 " for (int i = 0; i < g_input1.data1.length(); ++i) g_output1.data1[i] = g_input1.data1[i];" NL
3264 " g_output1.data2 = g_input1.data2;" NL " g_output1.data3 = g_input1.data3;" NL
3265 " for (int i = 0; i < g_input1.data4.length(); ++i) g_output1.data4[i] = g_input1.data4[i];" NL
3266 " g_output1.data5 = g_input1.data5;" NL " g_output1.data6 = g_input1.data6;"
3267
3268 NL " g_output2.data0 = g_input2.data0;" NL " g_output2.data1 = g_input2.data1;"
3269
3270 NL " g_output3.data0 = g_input3.data0;" NL " g_output3.data1 = g_input3.data1;" NL "}";
3271 }
3272
3273 class BasicStdLayoutCase3VS : public BasicStdLayoutBase2VS
3274 {
GetInput(std::vector<GLubyte> in_data[4])3275 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3276 {
3277 return GetInputC3(in_data);
3278 }
3279 };
3280
3281 class BasicStdLayoutCase3CS : public BasicStdLayoutBase2CS
3282 {
GetInput(std::vector<GLubyte> in_data[4])3283 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3284 {
3285 return GetInputC3(in_data);
3286 }
3287 };
3288
3289 //-----------------------------------------------------------------------------
3290 // 1.9.4 BasicStdLayoutCase4
3291 //-----------------------------------------------------------------------------
GetInputC4(std::vector<GLubyte> in_data[4])3292 const char *GetInputC4(std::vector<GLubyte> in_data[4])
3293 {
3294 /* input 0, std140 */
3295 {
3296 in_data[0].resize(57 * 4);
3297 float *fp = reinterpret_cast<float *>(&in_data[0][0]);
3298 int *ip = reinterpret_cast<int *>(&in_data[0][0]);
3299 ip[0] = 1;
3300 ip[1] = 0;
3301 ip[2] = 0;
3302 ip[3] = 0;
3303 ip[4] = 2;
3304 ip[5] = 3;
3305 ip[6] = 0;
3306 ip[7] = 0;
3307 ip[8] = 4;
3308 ip[9] = 5;
3309 ip[10] = 0;
3310 ip[11] = 0;
3311 fp[12] = 6.0f;
3312 fp[13] = 0.0f;
3313 fp[14] = 0.0f;
3314 fp[15] = 0.0f;
3315 fp[16] = 7.0f;
3316 fp[17] = 8.0f;
3317 fp[18] = 0.0f;
3318 fp[19] = 0.0f;
3319 ip[20] = 9;
3320 ip[21] = 10;
3321 ip[22] = 11;
3322 ip[23] = 0;
3323 fp[24] = 12.0f;
3324 fp[25] = 13.0f;
3325 fp[26] = 0.0f;
3326 fp[27] = 0.0f;
3327 ip[28] = 14;
3328 ip[29] = 15;
3329 ip[30] = 16;
3330 ip[31] = 0;
3331 fp[32] = 17.0f;
3332 fp[33] = 0.0f;
3333 fp[34] = 0.0f;
3334 fp[35] = 0.0f;
3335 ip[36] = 18;
3336 ip[37] = 0;
3337 ip[38] = 0;
3338 ip[39] = 0;
3339 ip[40] = 19;
3340 ip[41] = 20;
3341 ip[42] = 0;
3342 ip[43] = 0;
3343 ip[44] = 21;
3344 ip[45] = 0;
3345 ip[45] = 0;
3346 ip[45] = 0;
3347 fp[48] = 22.0f;
3348 fp[49] = 23.0f;
3349 fp[50] = 0.0f;
3350 fp[51] = 0.0f;
3351 ip[52] = 24;
3352 ip[53] = 25;
3353 ip[54] = 26;
3354 ip[55] = 0;
3355 fp[56] = 27.0f;
3356 }
3357 /* input 1, std140 */
3358 {
3359 in_data[1].resize(57 * 4);
3360 float *fp = reinterpret_cast<float *>(&in_data[1][0]);
3361 int *ip = reinterpret_cast<int *>(&in_data[1][0]);
3362 ip[0] = 101;
3363 ip[1] = 0;
3364 ip[2] = 0;
3365 ip[3] = 0;
3366 ip[4] = 102;
3367 ip[5] = 103;
3368 ip[6] = 0;
3369 ip[7] = 0;
3370 ip[8] = 104;
3371 ip[9] = 105;
3372 ip[10] = 0;
3373 ip[11] = 0;
3374 fp[12] = 106.0f;
3375 fp[13] = 0.0f;
3376 fp[14] = 0.0f;
3377 fp[15] = 0.0f;
3378 fp[16] = 107.0f;
3379 fp[17] = 108.0f;
3380 fp[18] = 0.0f;
3381 fp[19] = 0.0f;
3382 ip[20] = 109;
3383 ip[21] = 110;
3384 ip[22] = 111;
3385 ip[23] = 0;
3386 fp[24] = 112.0f;
3387 fp[25] = 113.0f;
3388 fp[26] = 0.0f;
3389 fp[27] = 0.0f;
3390 ip[28] = 114;
3391 ip[29] = 115;
3392 ip[30] = 116;
3393 ip[31] = 0;
3394 fp[32] = 117.0f;
3395 fp[33] = 0.0f;
3396 fp[34] = 0.0f;
3397 fp[35] = 0.0f;
3398 ip[36] = 118;
3399 ip[37] = 0;
3400 ip[38] = 0;
3401 ip[39] = 0;
3402 ip[40] = 119;
3403 ip[41] = 120;
3404 ip[42] = 0;
3405 ip[43] = 0;
3406 ip[44] = 121;
3407 ip[45] = 0;
3408 ip[45] = 0;
3409 ip[45] = 0;
3410 fp[48] = 122.0f;
3411 fp[49] = 123.0f;
3412 fp[50] = 0.0f;
3413 fp[51] = 0.0f;
3414 ip[52] = 124;
3415 ip[53] = 125;
3416 ip[54] = 126;
3417 ip[55] = 0;
3418 fp[56] = 127.0f;
3419 }
3420 /* input 2, std430 */
3421 {
3422 in_data[2].resize(45 * 4);
3423 float *fp = reinterpret_cast<float *>(&in_data[2][0]);
3424 int *ip = reinterpret_cast<int *>(&in_data[2][0]);
3425 ip[0] = 1000;
3426 ip[1] = 0;
3427 ip[2] = 1001;
3428 ip[3] = 1002;
3429 ip[4] = 1003;
3430 ip[5] = 1004;
3431 fp[6] = 1005.0f;
3432 fp[7] = 0.0f;
3433 fp[8] = 1006.0f;
3434 fp[9] = 1007.0f;
3435 fp[10] = 0.0f;
3436 fp[11] = 0.0f;
3437 ip[12] = 1008;
3438 ip[13] = 1009;
3439 ip[14] = 1010;
3440 ip[15] = 0;
3441 fp[16] = 1011.0f;
3442 fp[17] = 1012.0f;
3443 fp[18] = 0.0f;
3444 fp[19] = 0.0f;
3445 ip[20] = 1013;
3446 ip[21] = 1014;
3447 ip[22] = 1015;
3448 ip[23] = 0;
3449 fp[24] = 1016.0f;
3450 fp[25] = 0.0f;
3451 fp[26] = 0.0f;
3452 fp[27] = 0.0f;
3453 ip[28] = 1017;
3454 ip[29] = 0;
3455 ip[30] = 1018;
3456 ip[31] = 1019;
3457 ip[32] = 1020;
3458 ip[33] = 0;
3459 ip[34] = 0;
3460 ip[35] = 0;
3461 fp[36] = 1021.0f;
3462 fp[37] = 1022.0f;
3463 fp[38] = 0.0f;
3464 fp[39] = 0.0f;
3465 ip[40] = 1023;
3466 ip[41] = 1024;
3467 ip[42] = 1025;
3468 ip[43] = 0;
3469 fp[44] = 1026.0f;
3470 }
3471 /* input 3, std430 */
3472 {
3473 in_data[3].resize(45 * 4);
3474 float *fp = reinterpret_cast<float *>(&in_data[3][0]);
3475 int *ip = reinterpret_cast<int *>(&in_data[3][0]);
3476 ip[0] = 10000;
3477 ip[1] = 0;
3478 ip[2] = 10001;
3479 ip[3] = 10002;
3480 ip[4] = 10003;
3481 ip[5] = 10004;
3482 fp[6] = 10005.0f;
3483 fp[7] = 0.0f;
3484 fp[8] = 10006.0f;
3485 fp[9] = 10007.0f;
3486 fp[10] = 0.0f;
3487 fp[11] = 0.0f;
3488 ip[12] = 10008;
3489 ip[13] = 10009;
3490 ip[14] = 10010;
3491 ip[15] = 0;
3492 fp[16] = 10011.0f;
3493 fp[17] = 10012.0f;
3494 fp[18] = 0.0f;
3495 fp[19] = 0.0f;
3496 ip[20] = 10013;
3497 ip[21] = 10014;
3498 ip[22] = 10015;
3499 ip[23] = 0;
3500 fp[24] = 10016.0f;
3501 fp[25] = 0.0f;
3502 fp[26] = 0.0f;
3503 fp[27] = 0.0f;
3504 ip[28] = 10017;
3505 ip[29] = 0;
3506 ip[30] = 10018;
3507 ip[31] = 10019;
3508 ip[32] = 10020;
3509 ip[33] = 0;
3510 ip[34] = 0;
3511 ip[35] = 0;
3512 fp[36] = 10021.0f;
3513 fp[37] = 10022.0f;
3514 fp[38] = 0.0f;
3515 fp[39] = 0.0f;
3516 ip[40] = 10023;
3517 ip[41] = 10024;
3518 ip[42] = 10025;
3519 ip[43] = 0;
3520 fp[44] = 10026.0f;
3521 }
3522 return NL
3523 "struct Struct0 {" NL " ivec2 data0;" NL "};" NL "struct Struct1 {" NL " vec2 data0;" // offset 0
3524 NL " ivec3 data1;" // offset 16
3525 NL "};" NL "struct Struct2 {" NL " int data0;" // offset 0
3526 NL " Struct0 data1;" // offset std430 8, std140 16
3527 NL " int data2;" // offset std430 16, std140 32
3528 NL " Struct1 data3;" // offset std430 32, std140 48
3529 NL " float data4;" // offset std430 64, std140 80
3530 NL "};" NL "layout(std140, binding = 0) buffer Input01 {" NL " int data0;" // offset 0
3531 NL " Struct0 data1[2];" // offset 16
3532 NL " float data2;" // offset 48
3533 NL " Struct1 data3[2];" // offset 64
3534 NL " float data4;" // offset 128
3535 NL " Struct2 data5;" // offset 144
3536 NL "} g_input01[2];" NL "layout(std430, binding = 2) buffer Input23 {" NL " int data0;" // offset 0
3537 NL " Struct0 data1[2];" // offset 8
3538 NL " float data2;" // offset 24
3539 NL " Struct1 data3[2];" // offset 32
3540 NL " float data4;" // offset 96
3541 NL " Struct2 data5;" // offset 112
3542 NL "} g_input23[2];"
3543
3544 NL "layout(std140, binding = 4) buffer Output01 {" NL " int data0;" NL " Struct0 data1[2];" NL
3545 " float data2;" NL " Struct1 data3[2];" NL " float data4;" NL " Struct2 data5;" NL "} g_output01[2];" NL
3546 "layout(std430, binding = 6) buffer Output23 {" NL " int data0;" NL " Struct0 data1[2];" NL
3547 " float data2;" NL " Struct1 data3[2];" NL " float data4;" NL " Struct2 data5;" NL "} g_output23[2];" NL NL
3548 "void main() {" NL " g_output01[0].data0 = g_input01[0].data0;" NL
3549 " for (int i = 0; i < g_input01[0].data1.length(); ++i) g_output01[0].data1[i] = g_input01[0].data1[i];" NL
3550 " g_output01[0].data2 = g_input01[0].data2;" NL " g_output01[0].data3[0] = g_input01[0].data3[0];" NL
3551 " g_output01[0].data3[1] = g_input01[0].data3[1];" NL " g_output01[0].data4 = g_input01[0].data4;" NL
3552 " g_output01[1].data0 = g_input01[1].data0;" NL
3553 " for (int i = 0; i < g_input01[1].data1.length(); ++i) g_output01[1].data1[i] = g_input01[1].data1[i];" NL
3554 " g_output01[1].data2 = g_input01[1].data2;" NL " g_output01[1].data3[0] = g_input01[1].data3[0];" NL
3555 " g_output01[1].data3[1] = g_input01[1].data3[1];" NL " g_output01[1].data4 = g_input01[1].data4;" NL
3556 " g_output01[0].data5 = g_input01[0].data5;" NL " g_output01[1].data5 = g_input01[1].data5;" NL NL
3557 " g_output23[0].data0 = g_input23[0].data0;" NL
3558 " for (int i = 0; i < g_input23[0].data1.length(); ++i) g_output23[0].data1[i] = g_input23[0].data1[i];" NL
3559 " g_output23[0].data2 = g_input23[0].data2;" NL " g_output23[0].data3[0] = g_input23[0].data3[0];" NL
3560 " g_output23[0].data3[1] = g_input23[0].data3[1];" NL " g_output23[0].data4 = g_input23[0].data4;" NL
3561 " g_output23[1].data0 = g_input23[1].data0;" NL
3562 " for (int i = 0; i < g_input23[1].data1.length(); ++i) g_output23[1].data1[i] = g_input23[1].data1[i];" NL
3563 " g_output23[1].data2 = g_input23[1].data2;" NL " g_output23[1].data3[0] = g_input23[1].data3[0];" NL
3564 " g_output23[1].data3[1] = g_input23[1].data3[1];" NL " g_output23[1].data4 = g_input23[1].data4;" NL
3565 " g_output23[0].data5 = g_input23[0].data5;" NL " g_output23[1].data5 = g_input23[1].data5;" NL "}";
3566 }
3567
3568 class BasicStdLayoutCase4VS : public BasicStdLayoutBase2VS
3569 {
GetInput(std::vector<GLubyte> in_data[4])3570 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3571 {
3572 return GetInputC4(in_data);
3573 }
3574 };
3575
3576 class BasicStdLayoutCase4CS : public BasicStdLayoutBase2CS
3577 {
GetInput(std::vector<GLubyte> in_data[4])3578 virtual const char *GetInput(std::vector<GLubyte> in_data[4])
3579 {
3580 return GetInputC4(in_data);
3581 }
3582 };
3583
3584 //-----------------------------------------------------------------------------
3585 // 1.10.x BasicOperationsBase
3586 //-----------------------------------------------------------------------------
3587 class BasicOperationsBaseVS : public ShaderStorageBufferObjectBase
3588 {
3589 GLuint m_program;
3590 GLuint m_buffer[2];
3591 GLuint m_vertex_array;
3592
3593 virtual const char *GetInput(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data) = 0;
3594
Setup()3595 virtual long Setup()
3596 {
3597 m_program = 0;
3598 memset(m_buffer, 0, sizeof(m_buffer));
3599 m_vertex_array = 0;
3600 return NO_ERROR;
3601 }
3602
Run()3603 virtual long Run()
3604 {
3605 if (!IsVSFSAvailable(2, 0))
3606 return NOT_SUPPORTED;
3607 std::vector<GLubyte> in_data;
3608 std::vector<GLubyte> expected_data;
3609 const char *glsl_vs = GetInput(in_data, expected_data);
3610 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
3611 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
3612
3613 m_program = CreateProgram(glsl_vs, glsl_fs);
3614 glLinkProgram(m_program);
3615 if (!CheckProgram(m_program))
3616 return ERROR;
3617
3618 glGenBuffers(2, m_buffer);
3619
3620 /* output buffer */
3621 {
3622 std::vector<GLubyte> zero(expected_data.size());
3623 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
3624 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)expected_data.size(), &zero[0], GL_STATIC_DRAW);
3625 }
3626 // input buffer
3627 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
3628 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data.size(), &in_data[0], GL_STATIC_DRAW);
3629
3630 glGenVertexArrays(1, &m_vertex_array);
3631 glEnable(GL_RASTERIZER_DISCARD);
3632
3633 glUseProgram(m_program);
3634 glBindVertexArray(m_vertex_array);
3635
3636 glUniform3f(glGetUniformLocation(m_program, "g_value0"), 10.0, 20.0, 30.0);
3637 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
3638 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
3639
3640 glDrawArrays(GL_POINTS, 0, 1);
3641
3642 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
3643 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3644 GLubyte *out_data =
3645 (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)expected_data.size(), GL_MAP_READ_BIT);
3646 if (!out_data)
3647 return ERROR;
3648
3649 bool status = true;
3650 for (size_t i = 0; i < expected_data.size(); ++i)
3651 {
3652 if (expected_data[i] != out_data[i])
3653 {
3654 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i)
3655 << " is " << tcu::toHex(out_data[i]) << " should be "
3656 << tcu::toHex(expected_data[i]) << tcu::TestLog::EndMessage;
3657 status = false;
3658 }
3659 }
3660 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3661 if (!status)
3662 return ERROR;
3663 return NO_ERROR;
3664 }
3665
Cleanup()3666 virtual long Cleanup()
3667 {
3668 glDisable(GL_RASTERIZER_DISCARD);
3669 glUseProgram(0);
3670 glDeleteProgram(m_program);
3671 glDeleteBuffers(2, m_buffer);
3672 glDeleteVertexArrays(1, &m_vertex_array);
3673 return NO_ERROR;
3674 }
3675 };
3676
3677 class BasicOperationsBaseCS : public ShaderStorageBufferObjectBase
3678 {
3679 GLuint m_program;
3680 GLuint m_buffer[2];
3681
3682 virtual const char *GetInput(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data) = 0;
3683
Setup()3684 virtual long Setup()
3685 {
3686 m_program = 0;
3687 memset(m_buffer, 0, sizeof(m_buffer));
3688 return NO_ERROR;
3689 }
3690
Run()3691 virtual long Run()
3692 {
3693 std::vector<GLubyte> in_data;
3694 std::vector<GLubyte> expected_data;
3695
3696 std::stringstream ss;
3697 ss << "layout(local_size_x = 1) in;\n" << GetInput(in_data, expected_data);
3698 m_program = CreateProgramCS(ss.str());
3699 glLinkProgram(m_program);
3700 if (!CheckProgram(m_program))
3701 return ERROR;
3702
3703 glGenBuffers(2, m_buffer);
3704
3705 /* output buffer */
3706 {
3707 std::vector<GLubyte> zero(expected_data.size());
3708 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
3709 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)expected_data.size(), &zero[0], GL_STATIC_DRAW);
3710 }
3711 // input buffer
3712 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
3713 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data.size(), &in_data[0], GL_STATIC_DRAW);
3714
3715 glUseProgram(m_program);
3716 glUniform3f(glGetUniformLocation(m_program, "g_value0"), 10.0, 20.0, 30.0);
3717 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
3718 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
3719 glDispatchCompute(1, 1, 1);
3720
3721 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
3722 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3723 GLubyte *out_data =
3724 (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)expected_data.size(), GL_MAP_READ_BIT);
3725 if (!out_data)
3726 return ERROR;
3727
3728 bool status = true;
3729 for (size_t i = 0; i < expected_data.size(); ++i)
3730 {
3731 if (expected_data[i] != out_data[i])
3732 {
3733 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i)
3734 << " is " << tcu::toHex(out_data[i]) << " should be "
3735 << tcu::toHex(expected_data[i]) << tcu::TestLog::EndMessage;
3736 status = false;
3737 }
3738 }
3739 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3740 if (!status)
3741 return ERROR;
3742 return NO_ERROR;
3743 }
3744
Cleanup()3745 virtual long Cleanup()
3746 {
3747 glUseProgram(0);
3748 glDeleteProgram(m_program);
3749 glDeleteBuffers(2, m_buffer);
3750 return NO_ERROR;
3751 }
3752 };
3753
3754 //-----------------------------------------------------------------------------
3755 // 1.10.1 BasicOperationsCase1
3756 //-----------------------------------------------------------------------------
GetInputOp1(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3757 const char *GetInputOp1(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data)
3758 {
3759 /* input */
3760 {
3761 in_data.resize(16 * 9);
3762 int *ip = reinterpret_cast<int *>(&in_data[0]);
3763 float *fp = reinterpret_cast<float *>(&in_data[0]);
3764 ip[0] = 1;
3765 ip[1] = 2;
3766 ip[2] = 3;
3767 ip[3] = 4; // data0
3768 fp[4] = 1.0f;
3769 fp[5] = 2.0f;
3770 fp[6] = 3.0f;
3771 fp[7] = 0.0f; // data1
3772 ip[8] = 1;
3773 ip[9] = 2;
3774 ip[10] = 3;
3775 ip[11] = 4; // data2
3776 ip[12] = 1;
3777 ip[13] = -2;
3778 ip[14] = 3;
3779 ip[15] = 4; // data3
3780 fp[16] = 1.0f;
3781 fp[17] = 2.0f;
3782 fp[18] = 3.0f;
3783 fp[19] = 4.0f; // data4
3784 fp[20] = 1.0f;
3785 fp[21] = 2.0f;
3786 fp[22] = 3.0f;
3787 fp[23] = 4.0f; // data5
3788 fp[24] = 1.0f;
3789 fp[25] = 2.0f;
3790 fp[26] = 3.0f;
3791 fp[27] = 4.0f; // data5
3792 fp[28] = 1.0f;
3793 fp[29] = 2.0f;
3794 fp[30] = 3.0f;
3795 fp[31] = 4.0f; // data5
3796 fp[32] = 1.0f;
3797 fp[33] = 0.0f;
3798 fp[34] = 0.0f;
3799 fp[35] = 4.0f; // data5
3800 }
3801 /* expected output */
3802 {
3803 out_data.resize(16 * 9);
3804 int *ip = reinterpret_cast<int *>(&out_data[0]);
3805 float *fp = reinterpret_cast<float *>(&out_data[0]);
3806 ip[0] = 4;
3807 ip[1] = 3;
3808 ip[2] = 2;
3809 ip[3] = 1;
3810 fp[4] = 3.0f;
3811 fp[5] = 2.0f;
3812 fp[6] = 1.0f;
3813 fp[7] = 0.0f;
3814 ip[8] = 4;
3815 ip[9] = 1;
3816 ip[10] = 0;
3817 ip[11] = 3;
3818 ip[12] = 10;
3819 ip[13] = 4;
3820 ip[14] = -2;
3821 ip[15] = 20;
3822 fp[16] = 50.0f;
3823 fp[17] = 5.0f;
3824 fp[18] = 2.0f;
3825 fp[19] = 30.0f;
3826 fp[20] = 4.0f;
3827 fp[21] = 2.0f;
3828 fp[22] = 3.0f;
3829 fp[23] = 1.0f; // data5
3830 fp[24] = 4.0f;
3831 fp[25] = 3.0f;
3832 fp[26] = 2.0f;
3833 fp[27] = 1.0f; // data5
3834 fp[28] = 2.0f;
3835 fp[29] = 2.0f;
3836 fp[30] = 2.0f;
3837 fp[31] = 2.0f; // data5
3838 fp[32] = 4.0f;
3839 fp[33] = 0.0f;
3840 fp[34] = 0.0f;
3841 fp[35] = 1.0f; // data5
3842 }
3843 return NL "layout(std430, binding = 0) buffer Input {" NL " ivec4 data0;" NL " vec3 data1;" NL " uvec4 data2;" NL
3844 " ivec4 data3;" NL " vec4 data4;" NL " mat4 data5;" NL "} g_input;" NL
3845 "layout(std430, binding = 1) buffer Output {" NL " ivec4 data0;" NL " vec3 data1;" NL
3846 " uvec4 data2;" NL " ivec4 data3;" NL " vec4 data4;" NL " mat4 data5;" NL "} g_output;" NL
3847 "uniform vec3 g_value0;" NL "uniform int g_index1;" NL "void main() {" NL " int index0 = 0;" NL
3848 " g_output.data0.wzyx = g_input.data0;" NL " g_output.data1 = g_input.data1.zyx;" NL
3849 " g_output.data2.xwy = g_input.data2.wzx;" NL " g_output.data3.xw = ivec2(10, 20);" NL
3850 " g_output.data3.zy = g_input.data3.yw;" NL " g_output.data4.wx = g_value0.xz;" // w == 10.0, x == 30.0
3851 NL " g_output.data4.wx += g_value0.yy;" // w == 30.0, x == 50.0
3852 NL " g_output.data4.yz = g_input.data4.xx + g_input.data4.wx;" // y == 5.0, z == 2.0
3853 NL " g_output.data5[g_index1 - 1].wyzx = vec4(1, 2, 3, 4);" NL
3854 " g_output.data5[g_index1 + index0] = g_input.data5[g_index1].wzyx;" NL
3855 " g_output.data5[1 + g_index1] = g_input.data5[g_index1 + 1].yyyy;" NL
3856 " g_output.data5[5 - g_index1 - 1].wx = g_input.data5[4 - g_index1].xw;" NL "}";
3857 }
3858
3859 class BasicOperationsCase1VS : public BasicOperationsBaseVS
3860 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3861 virtual const char *GetInput(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data)
3862 {
3863 return GetInputOp1(in_data, out_data);
3864 }
3865 };
3866
3867 class BasicOperationsCase1CS : public BasicOperationsBaseCS
3868 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3869 virtual const char *GetInput(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data)
3870 {
3871 return GetInputOp1(in_data, out_data);
3872 }
3873 };
3874
3875 //-----------------------------------------------------------------------------
3876 // 1.10.2 BasicOperationsCase2
3877 //-----------------------------------------------------------------------------
GetInputOp2(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3878 const char *GetInputOp2(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data)
3879 {
3880 /* input */
3881 {
3882 in_data.resize(16 * 8);
3883 float *fp = reinterpret_cast<float *>(&in_data[0]);
3884 fp[0] = 1.0f;
3885 fp[1] = 0.0f;
3886 fp[2] = 0.0f;
3887 fp[3] = 0.0f;
3888 fp[4] = 0.0f;
3889 fp[5] = 1.0f;
3890 fp[6] = 0.0f;
3891 fp[7] = 0.0f;
3892 fp[8] = 0.0f;
3893 fp[9] = 0.0f;
3894 fp[10] = 1.0f;
3895 fp[11] = 0.0f;
3896 fp[12] = 0.0f;
3897 fp[13] = 0.0f;
3898 fp[14] = 0.0f;
3899 fp[15] = 1.0f;
3900
3901 fp[16] = 2.0f;
3902 fp[17] = 0.0f;
3903 fp[18] = 0.0f;
3904 fp[19] = 0.0f;
3905 fp[20] = 0.0f;
3906 fp[21] = 3.0f;
3907 fp[22] = 0.0f;
3908 fp[23] = 0.0f;
3909 fp[24] = 0.0f;
3910 fp[25] = 0.0f;
3911 fp[26] = 4.0f;
3912 fp[27] = 0.0f;
3913 fp[28] = 0.0f;
3914 fp[29] = 0.0f;
3915 fp[30] = 0.0f;
3916 fp[31] = 5.0f;
3917 }
3918 /* expected output */
3919 {
3920 out_data.resize(16 * 5);
3921 float *fp = reinterpret_cast<float *>(&out_data[0]);
3922 fp[0] = 2.0f;
3923 fp[1] = 0.0f;
3924 fp[2] = 0.0f;
3925 fp[3] = 0.0f;
3926 fp[4] = 0.0f;
3927 fp[5] = 3.0f;
3928 fp[6] = 0.0f;
3929 fp[7] = 0.0f;
3930 fp[8] = 0.0f;
3931 fp[9] = 0.0f;
3932 fp[10] = 4.0f;
3933 fp[11] = 0.0f;
3934 fp[12] = 0.0f;
3935 fp[13] = 0.0f;
3936 fp[14] = 0.0f;
3937 fp[15] = 5.0f;
3938
3939 fp[16] = 0.0f;
3940 fp[17] = 1.0f;
3941 fp[18] = 4.0f;
3942 fp[19] = 0.0f;
3943 }
3944 return NL "layout(std430, binding = 0) buffer Input {" NL " mat4 data0;" NL " mat4 data1;" NL "} g_input;" NL
3945 "layout(std430, binding = 1) buffer Output {" NL " mat4 data0;" NL " vec4 data1;" NL "} g_output;" NL
3946 "uniform int g_index2;" NL "void main() {" NL
3947 " g_output.data0 = matrixCompMult(g_input.data0, g_input.data1);" NL
3948 " g_output.data1 = g_input.data0[1] + g_input.data1[g_index2];" NL "}";
3949 }
3950
3951 class BasicOperationsCase2VS : public BasicOperationsBaseVS
3952 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3953 virtual const char *GetInput(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data)
3954 {
3955 return GetInputOp2(in_data, out_data);
3956 }
3957 };
3958
3959 class BasicOperationsCase2CS : public BasicOperationsBaseCS
3960 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3961 virtual const char *GetInput(std::vector<GLubyte> &in_data, std::vector<GLubyte> &out_data)
3962 {
3963 return GetInputOp2(in_data, out_data);
3964 }
3965 };
3966
3967 //-----------------------------------------------------------------------------
3968 // 1.11.x BasicStdLayoutBase3
3969 //-----------------------------------------------------------------------------
3970 class BasicStdLayoutBase3VS : public ShaderStorageBufferObjectBase
3971 {
3972 GLuint m_program;
3973 GLuint m_buffer[4];
3974 GLuint m_vertex_array;
3975
3976 virtual const char *GetInput(std::vector<GLubyte> in_data[2]) = 0;
3977
Setup()3978 virtual long Setup()
3979 {
3980 m_program = 0;
3981 memset(m_buffer, 0, sizeof(m_buffer));
3982 m_vertex_array = 0;
3983 return NO_ERROR;
3984 }
3985
Run()3986 virtual long Run()
3987 {
3988 if (!IsVSFSAvailable(4, 0))
3989 return NOT_SUPPORTED;
3990 std::vector<GLubyte> in_data[2];
3991 const char *glsl_vs = GetInput(in_data);
3992 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
3993 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
3994
3995 m_program = CreateProgram(glsl_vs, glsl_fs);
3996 glLinkProgram(m_program);
3997 if (!CheckProgram(m_program))
3998 return ERROR;
3999
4000 glGenBuffers(4, m_buffer);
4001
4002 // input buffers
4003 glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_buffer[0]);
4004 glBufferData(GL_UNIFORM_BUFFER, (GLsizeiptr)in_data[0].size(), &in_data[0][0], GL_STATIC_DRAW);
4005
4006 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]);
4007 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &in_data[1][0], GL_STATIC_DRAW);
4008
4009 /* output buffer 0 */
4010 {
4011 std::vector<GLubyte> out_data(in_data[0].size());
4012 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[2]);
4013 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[0].size(), &out_data[0], GL_STATIC_DRAW);
4014 }
4015 /* output buffer 1 */
4016 {
4017 std::vector<GLubyte> out_data(in_data[1].size());
4018 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]);
4019 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &out_data[0], GL_STATIC_DRAW);
4020 }
4021
4022 glGenVertexArrays(1, &m_vertex_array);
4023 glEnable(GL_RASTERIZER_DISCARD);
4024
4025 glUseProgram(m_program);
4026 glBindVertexArray(m_vertex_array);
4027
4028 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
4029
4030 glDrawArrays(GL_POINTS, 0, 1);
4031
4032 bool status = true;
4033 for (int j = 0; j < 2; ++j)
4034 {
4035 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 2]);
4036 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4037 GLubyte *out_data = (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(),
4038 GL_MAP_READ_BIT);
4039 if (!out_data)
4040 return ERROR;
4041
4042 for (size_t i = 0; i < in_data[j].size(); ++i)
4043 {
4044 if (in_data[j][i] != out_data[i])
4045 {
4046 m_context.getTestContext().getLog()
4047 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
4048 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
4049 << tcu::TestLog::EndMessage;
4050 status = false;
4051 }
4052 }
4053 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4054 }
4055 if (!status)
4056 return ERROR;
4057 return NO_ERROR;
4058 }
Cleanup()4059 virtual long Cleanup()
4060 {
4061 glDisable(GL_RASTERIZER_DISCARD);
4062 glUseProgram(0);
4063 glDeleteProgram(m_program);
4064 glDeleteBuffers(4, m_buffer);
4065 glDeleteVertexArrays(1, &m_vertex_array);
4066 return NO_ERROR;
4067 }
4068 };
4069
4070 class BasicStdLayoutBase3CS : public ShaderStorageBufferObjectBase
4071 {
4072 GLuint m_program;
4073 GLuint m_buffer[4];
4074
4075 virtual const char *GetInput(std::vector<GLubyte> in_data[2]) = 0;
4076
Setup()4077 virtual long Setup()
4078 {
4079 m_program = 0;
4080 memset(m_buffer, 0, sizeof(m_buffer));
4081 return NO_ERROR;
4082 }
Run()4083 virtual long Run()
4084 {
4085 std::vector<GLubyte> in_data[2];
4086
4087 std::stringstream ss;
4088 ss << "layout(local_size_x = 1) in;\n" << GetInput(in_data);
4089 m_program = CreateProgramCS(ss.str());
4090 glLinkProgram(m_program);
4091 if (!CheckProgram(m_program))
4092 return ERROR;
4093
4094 glGenBuffers(4, m_buffer);
4095
4096 // input buffers
4097 glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_buffer[0]);
4098 glBufferData(GL_UNIFORM_BUFFER, (GLsizeiptr)in_data[0].size(), &in_data[0][0], GL_STATIC_DRAW);
4099
4100 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]);
4101 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &in_data[1][0], GL_STATIC_DRAW);
4102
4103 /* output buffer 0 */
4104 {
4105 std::vector<GLubyte> out_data(in_data[0].size());
4106 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[2]);
4107 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[0].size(), &out_data[0], GL_STATIC_DRAW);
4108 }
4109 /* output buffer 1 */
4110 {
4111 std::vector<GLubyte> out_data(in_data[1].size());
4112 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]);
4113 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &out_data[0], GL_STATIC_DRAW);
4114 }
4115
4116 glUseProgram(m_program);
4117 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
4118 glDispatchCompute(1, 1, 1);
4119
4120 bool status = true;
4121 for (int j = 0; j < 2; ++j)
4122 {
4123 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 2]);
4124 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4125 GLubyte *out_data = (GLubyte *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(),
4126 GL_MAP_READ_BIT);
4127 if (!out_data)
4128 return ERROR;
4129
4130 for (size_t i = 0; i < in_data[j].size(); ++i)
4131 {
4132 if (in_data[j][i] != out_data[i])
4133 {
4134 m_context.getTestContext().getLog()
4135 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
4136 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
4137 << tcu::TestLog::EndMessage;
4138 status = false;
4139 }
4140 }
4141 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4142 }
4143 if (!status)
4144 return ERROR;
4145 return NO_ERROR;
4146 }
Cleanup()4147 virtual long Cleanup()
4148 {
4149 glUseProgram(0);
4150 glDeleteProgram(m_program);
4151 glDeleteBuffers(4, m_buffer);
4152 return NO_ERROR;
4153 }
4154 };
4155
4156 //-----------------------------------------------------------------------------
4157 // 1.11.1 Basic_UBO_SSBO_LayoutCase1
4158 //-----------------------------------------------------------------------------
GetInputUBO1(std::vector<GLubyte> in_data[2])4159 const char *GetInputUBO1(std::vector<GLubyte> in_data[2])
4160 {
4161 /* UBO */
4162 {
4163 in_data[0].resize(12 * 4);
4164 float *fp = reinterpret_cast<float *>(&in_data[0][0]);
4165 fp[0] = 1.0f;
4166 fp[1] = 0.0f;
4167 fp[2] = 0.0f;
4168 fp[3] = 0.0f;
4169 fp[4] = 2.0f;
4170 fp[5] = 0.0f;
4171 fp[6] = 0.0f;
4172 fp[7] = 0.0f;
4173 fp[8] = 3.0f;
4174 fp[9] = 0.0f;
4175 fp[10] = 0.0f;
4176 fp[11] = 0.0f;
4177 }
4178 /* SSBO */
4179 {
4180 in_data[1].resize(3 * 4);
4181 float *fp = reinterpret_cast<float *>(&in_data[1][0]);
4182 fp[0] = 1.0f;
4183 fp[1] = 2.0f;
4184 fp[2] = 3.0f;
4185 }
4186 return NL
4187 "layout(std140, binding = 0) uniform InputUBO {" NL " float data0;" NL " float data1[2];" NL
4188 "} g_input_ubo;" NL "layout(std430, binding = 0) buffer InputSSBO {" NL " float data0;" NL
4189 " float data1[2];" NL "} g_input_ssbo;" NL "layout(std140, binding = 1) buffer OutputUBO {" NL
4190 " float data0;" NL " float data1[2];" NL "} g_output_ubo;" NL
4191 "layout(std430, binding = 2) buffer OutputSSBO {" NL " float data0;" NL " float data1[2];" NL
4192 "} g_output_ssbo;" NL "void main() {" NL " g_output_ubo.data0 = g_input_ubo.data0;" NL
4193 " for (int i = 0; i < g_input_ubo.data1.length(); ++i) g_output_ubo.data1[i] = g_input_ubo.data1[i];" NL
4194 " g_output_ssbo.data0 = g_input_ssbo.data0;" NL
4195 " for (int i = 0; i < g_input_ssbo.data1.length(); ++i) g_output_ssbo.data1[i] = g_input_ssbo.data1[i];" NL
4196 "}";
4197 }
4198
4199 class Basic_UBO_SSBO_LayoutCase1VS : public BasicStdLayoutBase3VS
4200 {
GetInput(std::vector<GLubyte> in_data[2])4201 virtual const char *GetInput(std::vector<GLubyte> in_data[2])
4202 {
4203 return GetInputUBO1(in_data);
4204 }
4205 };
4206
4207 class Basic_UBO_SSBO_LayoutCase1CS : public BasicStdLayoutBase3CS
4208 {
GetInput(std::vector<GLubyte> in_data[2])4209 virtual const char *GetInput(std::vector<GLubyte> in_data[2])
4210 {
4211 return GetInputUBO1(in_data);
4212 }
4213 };
4214
4215 //-----------------------------------------------------------------------------
4216 // 1.11.2 Basic_UBO_SSBO_LayoutCase2
4217 //-----------------------------------------------------------------------------
GetInputUBO2(std::vector<GLubyte> in_data[2])4218 const char *GetInputUBO2(std::vector<GLubyte> in_data[2])
4219 {
4220 /* UBO */
4221 {
4222 in_data[0].resize(280 * 4);
4223 float *fp = reinterpret_cast<float *>(&in_data[0][0]);
4224 int *ip = reinterpret_cast<int *>(&in_data[0][0]);
4225 fp[0] = 1.0f;
4226 fp[1] = 2.0f;
4227 fp[2] = 3.0f;
4228 fp[3] = 4.0f;
4229 fp[4] = 5.0f;
4230 fp[5] = 6.0f;
4231 fp[6] = 7.0f;
4232 fp[8] = 9.0f;
4233 fp[12] = 10.0f;
4234 fp[16] = 11.0f;
4235 fp[20] = 12.0f;
4236 fp[24] = 13.0f;
4237
4238 ip[28] = 14;
4239 for (int i = 0; i < 20; ++i)
4240 {
4241 fp[32 + i * 4] = static_cast<float>(15 + i);
4242 }
4243 ip[112] = 140;
4244 for (int i = 0; i < 20; ++i)
4245 {
4246 fp[116 + i * 4] = static_cast<float>(150 + i);
4247 }
4248 ip[196] = 1400;
4249 for (int i = 0; i < 20; ++i)
4250 {
4251 fp[200 + i * 4] = static_cast<float>(1500 + i);
4252 }
4253 }
4254 /* SSBO */
4255 {
4256 in_data[1].resize(76 * 4);
4257 float *fp = reinterpret_cast<float *>(&in_data[1][0]);
4258 int *ip = reinterpret_cast<int *>(&in_data[1][0]);
4259 fp[0] = 1.0f;
4260 fp[1] = 2.0f;
4261 fp[2] = 3.0f;
4262 fp[3] = 4.0f;
4263 fp[4] = 5.0f;
4264 fp[5] = 6.0f;
4265 fp[6] = 7.0f;
4266 fp[7] = 8.0f;
4267 fp[8] = 9.0f;
4268 fp[9] = 10.0f;
4269 fp[10] = 11.0f;
4270 fp[11] = 12.0f;
4271 fp[12] = 13.0f;
4272 ip[13] = 14;
4273 fp[14] = 15.0f;
4274 fp[15] = 16.0f;
4275 fp[16] = 17.0f;
4276 fp[17] = 18.0f;
4277 fp[18] = 19.0f;
4278 fp[19] = 20.0f;
4279 fp[20] = 21.0f;
4280 fp[21] = 22.0f;
4281 fp[22] = 23.0f;
4282 fp[23] = 24.0f;
4283 fp[24] = 25.0f;
4284 fp[25] = 26.0f;
4285 fp[26] = 27.0f;
4286 fp[27] = 28.0f;
4287 fp[28] = 29.0f;
4288 fp[29] = 30.0f;
4289 fp[30] = 31.0f;
4290 fp[31] = 32.0f;
4291 fp[32] = 33.0f;
4292 fp[33] = 34.0f;
4293 ip[34] = 35;
4294 fp[35] = 36.0f;
4295 fp[36] = 37.0f;
4296 fp[37] = 38.0f;
4297 fp[38] = 39.0f;
4298 fp[39] = 40.0f;
4299 fp[40] = 41.0f;
4300 fp[41] = 42.0f;
4301 fp[42] = 43.0f;
4302 fp[43] = 44.0f;
4303 fp[44] = 45.0f;
4304 fp[45] = 46.0f;
4305 fp[46] = 47.0f;
4306 fp[47] = 48.0f;
4307 fp[48] = 49.0f;
4308 fp[49] = 50.0f;
4309 fp[50] = 51.0f;
4310 fp[51] = 52.0f;
4311 fp[52] = 53.0f;
4312 fp[53] = 54.0f;
4313 fp[54] = 55.0f;
4314 ip[55] = 56;
4315 fp[56] = 57.0f;
4316 fp[57] = 58.0f;
4317 fp[58] = 59.0f;
4318 fp[59] = 60.0f;
4319 fp[60] = 61.0f;
4320 fp[61] = 62.0f;
4321 fp[62] = 63.0f;
4322 fp[63] = 64.0f;
4323 fp[64] = 65.0f;
4324 fp[65] = 66.0f;
4325 fp[66] = 67.0f;
4326 fp[67] = 68.0f;
4327 fp[68] = 69.0f;
4328 fp[69] = 70.0f;
4329 fp[70] = 71.0f;
4330 fp[71] = 72.0f;
4331 fp[72] = 73.0f;
4332 fp[73] = 74.0f;
4333 fp[74] = 75.0f;
4334 fp[75] = 76.0f;
4335 }
4336 return NL
4337 "struct MM {" NL " float mm_a[5];" NL "};" NL "struct TT {" NL " int tt_a;" NL " MM tt_b[4];" NL "};" NL
4338 "layout(std140, binding = 0) uniform InputUBO {" NL " vec4 a;" NL " vec4 b;" NL " float c;" NL
4339 " float d[4];" NL " TT e[3];" NL "} g_input_ubo;" NL "layout(std430, binding = 0) buffer InputSSBO {" NL
4340 " vec4 a;" NL " vec4 b;" NL " float c;" NL " float d[4];" NL " TT e[3];" NL "} g_input_ssbo;" NL
4341 "layout(std140, binding = 1) buffer OutputUBO {" NL " vec4 a;" NL " vec4 b;" NL " float c;" NL
4342 " float d[4];" NL " TT e[3];" NL "} g_output_ubo;" NL "layout(std430, binding = 2) buffer OutputSSBO {" NL
4343 " vec4 a;" NL " vec4 b;" NL " float c;" NL " float d[4];" NL " TT e[3];" NL "} g_output_ssbo;" NL
4344 "uniform int g_index1;" NL "void main() {" NL " int index0 = 0;" NL NL " g_output_ubo.a = g_input_ubo.a;" NL
4345 " g_output_ubo.b = g_input_ubo.b;" NL " g_output_ubo.c = g_input_ubo.c;" NL
4346 " for (int i = 0; i < g_input_ubo.d.length(); ++i) g_output_ubo.d[i] = g_input_ubo.d[i];" NL
4347 " for (int j = 0; j < g_input_ubo.e.length(); ++j) {" NL
4348 " g_output_ubo.e[j].tt_a = g_input_ubo.e[j].tt_a;" NL
4349 " for (int i = 0; i < g_input_ubo.e[j].tt_b.length(); ++i) {" NL
4350 " g_output_ubo.e[j].tt_b[i].mm_a[0] = g_input_ubo.e[j].tt_b[i].mm_a[0];" NL
4351 " g_output_ubo.e[j].tt_b[index0 + i].mm_a[1] = g_input_ubo.e[j].tt_b[i].mm_a[1];" NL
4352 " g_output_ubo.e[j].tt_b[i].mm_a[2] = g_input_ubo.e[j].tt_b[i].mm_a[2 + index0];" NL
4353 " g_output_ubo.e[j + 1 - g_index1].tt_b[i].mm_a[4 - g_index1] = g_input_ubo.e[j].tt_b[i].mm_a[2 + "
4354 "g_index1];" NL " g_output_ubo.e[j].tt_b[i].mm_a[4] = g_input_ubo.e[j].tt_b[i - index0].mm_a[4];" NL
4355 " }" NL " }" NL NL " g_output_ssbo.a = g_input_ssbo.a;" NL " g_output_ssbo.b = g_input_ssbo.b;" NL
4356 " g_output_ssbo.c = g_input_ssbo.c;" NL
4357 " for (int i = 0; i < g_input_ssbo.d.length(); ++i) g_output_ssbo.d[i] = g_input_ssbo.d[i];" NL
4358 " for (int j = 0; j < g_input_ssbo.e.length(); ++j) {" NL
4359 " g_output_ssbo.e[j].tt_a = g_input_ssbo.e[j].tt_a;" NL
4360 " for (int i = 0; i < g_input_ssbo.e[j].tt_b.length(); ++i) {" NL
4361 " g_output_ssbo.e[j + index0].tt_b[i].mm_a[0] = g_input_ssbo.e[j].tt_b[i].mm_a[index0];" NL
4362 " g_output_ssbo.e[j].tt_b[i + index0].mm_a[1] = g_input_ssbo.e[j].tt_b[i].mm_a[g_index1];" NL
4363 " g_output_ssbo.e[j].tt_b[i].mm_a[2] = g_input_ssbo.e[j].tt_b[i].mm_a[1 + g_index1];" NL
4364 " g_output_ssbo.e[j - index0].tt_b[i].mm_a[g_index1 + 2] = g_input_ssbo.e[j].tt_b[i].mm_a[4 - "
4365 "g_index1];" NL " g_output_ssbo.e[j].tt_b[i].mm_a[4] = g_input_ssbo.e[j].tt_b[i].mm_a[4];" NL " }" NL
4366 " }" NL "}";
4367 }
4368
4369 class Basic_UBO_SSBO_LayoutCase2VS : public BasicStdLayoutBase3VS
4370 {
GetInput(std::vector<GLubyte> in_data[2])4371 virtual const char *GetInput(std::vector<GLubyte> in_data[2])
4372 {
4373 return GetInputUBO2(in_data);
4374 }
4375 };
4376
4377 class Basic_UBO_SSBO_LayoutCase2CS : public BasicStdLayoutBase3CS
4378 {
GetInput(std::vector<GLubyte> in_data[2])4379 virtual const char *GetInput(std::vector<GLubyte> in_data[2])
4380 {
4381 return GetInputUBO2(in_data);
4382 }
4383 };
4384
4385 //-----------------------------------------------------------------------------
4386 // 1.12.x BasicMatrixOperationsBase
4387 //-----------------------------------------------------------------------------
4388 class BasicMatrixOperationsBaseVS : public ShaderStorageBufferObjectBase
4389 {
4390 GLuint m_program;
4391 GLuint m_buffer[2];
4392 GLuint m_vertex_array;
4393
4394 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected) = 0;
4395
Equal(float a,float b)4396 static bool Equal(float a, float b)
4397 {
4398 return fabsf(a - b) < 0.001f;
4399 }
Setup()4400 virtual long Setup()
4401 {
4402 m_program = 0;
4403 memset(m_buffer, 0, sizeof(m_buffer));
4404 m_vertex_array = 0;
4405 return NO_ERROR;
4406 }
Run()4407 virtual long Run()
4408 {
4409 if (!IsVSFSAvailable(2, 0))
4410 return NOT_SUPPORTED;
4411 std::vector<float> in;
4412 std::vector<float> expected;
4413 const char *glsl_vs = GetInput(in, expected);
4414 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
4415 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
4416
4417 m_program = CreateProgram(glsl_vs, glsl_fs);
4418 glLinkProgram(m_program);
4419 if (!CheckProgram(m_program))
4420 return ERROR;
4421
4422 glGenBuffers(2, m_buffer);
4423
4424 /* output buffer */
4425 {
4426 std::vector<float> zero(expected.size());
4427 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
4428 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(expected.size() * sizeof(float)), &zero[0],
4429 GL_STATIC_DRAW);
4430 }
4431 // input buffer
4432 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
4433 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(in.size() * sizeof(float)), &in[0], GL_STATIC_DRAW);
4434
4435 glGenVertexArrays(1, &m_vertex_array);
4436 glEnable(GL_RASTERIZER_DISCARD);
4437
4438 glUseProgram(m_program);
4439 glBindVertexArray(m_vertex_array);
4440 glDrawArrays(GL_POINTS, 0, 1);
4441
4442 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
4443 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4444 float *out_data = (float *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
4445 (GLsizeiptr)(expected.size() * sizeof(float)), GL_MAP_READ_BIT);
4446 if (!out_data)
4447 return ERROR;
4448
4449 bool status = true;
4450 for (size_t i = 0; i < expected.size(); ++i)
4451 {
4452 if (!Equal(expected[i], out_data[i]))
4453 {
4454 m_context.getTestContext().getLog()
4455 << tcu::TestLog::Message << "Float at index " << static_cast<int>(i) << " is " << out_data[i]
4456 << " should be " << expected[i] << tcu::TestLog::EndMessage;
4457 status = false;
4458 }
4459 }
4460 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4461 if (!status)
4462 return ERROR;
4463 return NO_ERROR;
4464 }
Cleanup()4465 virtual long Cleanup()
4466 {
4467 glDisable(GL_RASTERIZER_DISCARD);
4468 glUseProgram(0);
4469 glDeleteProgram(m_program);
4470 glDeleteBuffers(2, m_buffer);
4471 glDeleteVertexArrays(1, &m_vertex_array);
4472 return NO_ERROR;
4473 }
4474 };
4475
4476 class BasicMatrixOperationsBaseCS : public ShaderStorageBufferObjectBase
4477 {
4478 GLuint m_program;
4479 GLuint m_buffer[2];
4480
4481 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected) = 0;
4482
Equal(float a,float b)4483 static bool Equal(float a, float b)
4484 {
4485 return fabsf(a - b) < 0.001f;
4486 }
4487
Setup()4488 virtual long Setup()
4489 {
4490 m_program = 0;
4491 memset(m_buffer, 0, sizeof(m_buffer));
4492 return NO_ERROR;
4493 }
4494
Run()4495 virtual long Run()
4496 {
4497 std::vector<float> in;
4498 std::vector<float> expected;
4499 std::stringstream ss;
4500 ss << "layout(local_size_x = 1) in;\n" << GetInput(in, expected);
4501 m_program = CreateProgramCS(ss.str());
4502 glLinkProgram(m_program);
4503 if (!CheckProgram(m_program))
4504 return ERROR;
4505
4506 glGenBuffers(2, m_buffer);
4507
4508 /* output buffer */
4509 {
4510 std::vector<float> zero(expected.size());
4511 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
4512 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(expected.size() * sizeof(float)), &zero[0],
4513 GL_STATIC_DRAW);
4514 }
4515 // input buffer
4516 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
4517 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(in.size() * sizeof(float)), &in[0], GL_STATIC_DRAW);
4518
4519 glUseProgram(m_program);
4520 glDispatchCompute(1, 1, 1);
4521
4522 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
4523 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4524 float *out_data = (float *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
4525 (GLsizeiptr)(expected.size() * sizeof(float)), GL_MAP_READ_BIT);
4526 if (!out_data)
4527 return ERROR;
4528
4529 bool status = true;
4530 for (size_t i = 0; i < expected.size(); ++i)
4531 {
4532 if (!Equal(expected[i], out_data[i]))
4533 {
4534 m_context.getTestContext().getLog()
4535 << tcu::TestLog::Message << "Float at index " << static_cast<int>(i) << " is " << out_data[i]
4536 << " should be " << expected[i] << tcu::TestLog::EndMessage;
4537 status = false;
4538 }
4539 }
4540 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4541 if (!status)
4542 return ERROR;
4543 return NO_ERROR;
4544 }
4545
Cleanup()4546 virtual long Cleanup()
4547 {
4548 glUseProgram(0);
4549 glDeleteProgram(m_program);
4550 glDeleteBuffers(2, m_buffer);
4551 return NO_ERROR;
4552 }
4553 };
4554
4555 //-----------------------------------------------------------------------------
4556 // 1.12.1 BasicMatrixOperationsCase1
4557 //-----------------------------------------------------------------------------
GetInputM1(std::vector<float> & in,std::vector<float> & expected)4558 const char *GetInputM1(std::vector<float> &in, std::vector<float> &expected)
4559 {
4560 in.resize(8);
4561 in[0] = 1.0f;
4562 in[2] = 3.0f;
4563 in[1] = 2.0f;
4564 in[3] = 4.0f;
4565 in[4] = 1.0f;
4566 in[6] = 3.0f;
4567 in[5] = 2.0f;
4568 in[7] = 4.0f;
4569 expected.resize(4);
4570 expected[0] = 7.0f;
4571 expected[2] = 15.0f;
4572 expected[1] = 10.0f;
4573 expected[3] = 22.0f;
4574 return NL "layout(std430, binding = 0) buffer Input {" NL " mat2 m0;" NL " mat2 m1;" NL "} g_input;" NL
4575 "layout(std430, binding = 1) buffer Output {" NL " mat2 m;" NL "} g_output;" NL
4576 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4577 }
4578
4579 class BasicMatrixOperationsCase1VS : public BasicMatrixOperationsBaseVS
4580 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4581 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4582 {
4583 return GetInputM1(in, expected);
4584 }
4585 };
4586
4587 class BasicMatrixOperationsCase1CS : public BasicMatrixOperationsBaseCS
4588 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4589 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4590 {
4591 return GetInputM1(in, expected);
4592 }
4593 };
4594
4595 //-----------------------------------------------------------------------------
4596 // 1.12.2 BasicMatrixOperationsCase2
4597 //-----------------------------------------------------------------------------
GetInputM2(std::vector<float> & in,std::vector<float> & expected)4598 const char *GetInputM2(std::vector<float> &in, std::vector<float> &expected)
4599 {
4600 in.resize(15);
4601 expected.resize(4);
4602 // mat3x2
4603 in[0] = 1.0f;
4604 in[2] = 3.0f;
4605 in[4] = 5.0f;
4606 in[1] = 2.0f;
4607 in[3] = 4.0f;
4608 in[5] = 6.0f;
4609 // mat2x3
4610 in[8] = 1.0f;
4611 in[12] = 4.0f;
4612 in[9] = 2.0f;
4613 in[13] = 5.0f;
4614 in[10] = 3.0f;
4615 in[14] = 6.0f;
4616 // mat2
4617 expected[0] = 22.0f;
4618 expected[2] = 49.0f;
4619 expected[1] = 28.0f;
4620 expected[3] = 64.0f;
4621 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(column_major) mat3x2 m0;" NL
4622 " layout(column_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4623 " layout(column_major) mat2 m;" NL "} g_output;" NL
4624 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4625 }
4626
4627 class BasicMatrixOperationsCase2VS : public BasicMatrixOperationsBaseVS
4628 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4629 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4630 {
4631 return GetInputM2(in, expected);
4632 }
4633 };
4634
4635 class BasicMatrixOperationsCase2CS : public BasicMatrixOperationsBaseCS
4636 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4637 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4638 {
4639 return GetInputM2(in, expected);
4640 }
4641 };
4642
4643 //-----------------------------------------------------------------------------
4644 // 1.12.3 BasicMatrixOperationsCase3
4645 //-----------------------------------------------------------------------------
GetInputM3(std::vector<float> & in,std::vector<float> & expected)4646 const char *GetInputM3(std::vector<float> &in, std::vector<float> &expected)
4647 {
4648 in.resize(15);
4649 expected.resize(4);
4650 // row major mat3x2
4651 in[0] = 1.0f;
4652 in[1] = 3.0f;
4653 in[2] = 5.0f;
4654 in[4] = 2.0f;
4655 in[5] = 4.0f;
4656 in[6] = 6.0f;
4657 // row major mat2x3
4658 in[8] = 1.0f;
4659 in[9] = 4.0f;
4660 in[10] = 2.0f;
4661 in[11] = 5.0f;
4662 in[12] = 3.0f;
4663 in[13] = 6.0f;
4664 // row major mat2
4665 expected[0] = 22.0f;
4666 expected[1] = 49.0f;
4667 expected[2] = 28.0f;
4668 expected[3] = 64.0f;
4669 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(row_major) mat3x2 m0;" NL
4670 " layout(row_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4671 " layout(row_major) mat2 m;" NL "} g_output;" NL "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4672 }
4673
4674 class BasicMatrixOperationsCase3VS : public BasicMatrixOperationsBaseVS
4675 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4676 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4677 {
4678 return GetInputM3(in, expected);
4679 }
4680 };
4681
4682 class BasicMatrixOperationsCase3CS : public BasicMatrixOperationsBaseCS
4683 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4684 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4685 {
4686 return GetInputM3(in, expected);
4687 }
4688 };
4689
4690 //-----------------------------------------------------------------------------
4691 // 1.12.4 BasicMatrixOperationsCase4
4692 //-----------------------------------------------------------------------------
GetInputM4(std::vector<float> & in,std::vector<float> & expected)4693 const char *GetInputM4(std::vector<float> &in, std::vector<float> &expected)
4694 {
4695 in.resize(15);
4696 expected.resize(4);
4697 // column major mat3x2
4698 in[0] = 1.0f;
4699 in[2] = 3.0f;
4700 in[4] = 5.0f;
4701 in[1] = 2.0f;
4702 in[3] = 4.0f;
4703 in[5] = 6.0f;
4704 // row major mat2x3
4705 in[8] = 1.0f;
4706 in[9] = 4.0f;
4707 in[10] = 2.0f;
4708 in[11] = 5.0f;
4709 in[12] = 3.0f;
4710 in[13] = 6.0f;
4711 // column major mat2
4712 expected[0] = 13.0f;
4713 expected[1] = 16.0f;
4714 expected[2] = 37.0f;
4715 expected[3] = 46.0f;
4716 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(column_major) mat3x2 m0;" NL
4717 " layout(row_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4718 " layout(column_major) mat2 m;" NL "} g_output;" NL
4719 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4720 }
4721
4722 class BasicMatrixOperationsCase4VS : public BasicMatrixOperationsBaseVS
4723 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4724 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4725 {
4726 return GetInputM4(in, expected);
4727 }
4728 };
4729
4730 class BasicMatrixOperationsCase4CS : public BasicMatrixOperationsBaseCS
4731 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4732 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4733 {
4734 return GetInputM4(in, expected);
4735 }
4736 };
4737
4738 //-----------------------------------------------------------------------------
4739 // 1.12.5 BasicMatrixOperationsCase5
4740 //-----------------------------------------------------------------------------
GetInputM5(std::vector<float> & in,std::vector<float> & expected)4741 const char *GetInputM5(std::vector<float> &in, std::vector<float> &expected)
4742 {
4743 in.resize(15);
4744 expected.resize(4);
4745 // column major mat3x2
4746 in[0] = 1.0f;
4747 in[2] = 3.0f;
4748 in[4] = 5.0f;
4749 in[1] = 2.0f;
4750 in[3] = 4.0f;
4751 in[5] = 6.0f;
4752 // row major mat2x3
4753 in[8] = 1.0f;
4754 in[9] = 4.0f;
4755 in[10] = 2.0f;
4756 in[11] = 5.0f;
4757 in[12] = 3.0f;
4758 in[13] = 6.0f;
4759 // row major mat2
4760 expected[0] = 13.0f;
4761 expected[1] = 37.0f;
4762 expected[2] = 16.0f;
4763 expected[3] = 46.0f;
4764 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(column_major) mat3x2 m0;" NL
4765 " layout(row_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4766 " layout(row_major) mat2 m;" NL "} g_output;" NL "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4767 }
4768
4769 class BasicMatrixOperationsCase5VS : public BasicMatrixOperationsBaseVS
4770 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4771 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4772 {
4773 return GetInputM5(in, expected);
4774 }
4775 };
4776
4777 class BasicMatrixOperationsCase5CS : public BasicMatrixOperationsBaseCS
4778 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4779 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4780 {
4781 return GetInputM5(in, expected);
4782 }
4783 };
4784 //-----------------------------------------------------------------------------
4785 // 1.12.6 BasicMatrixOperationsCase6
4786 //-----------------------------------------------------------------------------
GetInputM6(std::vector<float> & in,std::vector<float> & expected)4787 const char *GetInputM6(std::vector<float> &in, std::vector<float> &expected)
4788 {
4789 in.resize(20);
4790 expected.resize(4);
4791 // row major mat3x2
4792 in[0] = 1.0f;
4793 in[1] = 3.0f;
4794 in[2] = 5.0f;
4795 in[4] = 2.0f;
4796 in[5] = 4.0f;
4797 in[6] = 6.0f;
4798 // column major mat2x3
4799 in[8] = 1.0f;
4800 in[12] = 4.0f;
4801 in[9] = 2.0f;
4802 in[13] = 5.0f;
4803 in[10] = 3.0f;
4804 in[14] = 6.0f;
4805 // column major mat2
4806 expected[0] = 22.0f;
4807 expected[1] = 28.0f;
4808 expected[2] = 49.0f;
4809 expected[3] = 64.0f;
4810 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(row_major) mat3x2 m0;" NL
4811 " layout(column_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4812 " layout(column_major) mat2 m;" NL "} g_output;" NL
4813 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4814 }
4815
4816 class BasicMatrixOperationsCase6VS : public BasicMatrixOperationsBaseVS
4817 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4818 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4819 {
4820 return GetInputM6(in, expected);
4821 }
4822 };
4823
4824 class BasicMatrixOperationsCase6CS : public BasicMatrixOperationsBaseCS
4825 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4826 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4827 {
4828 return GetInputM6(in, expected);
4829 }
4830 };
4831
4832 //-----------------------------------------------------------------------------
4833 // 1.12.7 BasicMatrixOperationsCase7
4834 //-----------------------------------------------------------------------------
GetInputM7(std::vector<float> & in,std::vector<float> & expected)4835 const char *GetInputM7(std::vector<float> &in, std::vector<float> &expected)
4836 {
4837 in.resize(20);
4838 expected.resize(4);
4839 // row major mat3x2
4840 in[0] = 1.0f;
4841 in[1] = 3.0f;
4842 in[2] = 5.0f;
4843 in[4] = 2.0f;
4844 in[5] = 4.0f;
4845 in[6] = 6.0f;
4846 // column major mat2x3
4847 in[8] = 1.0f;
4848 in[12] = 4.0f;
4849 in[9] = 2.0f;
4850 in[13] = 5.0f;
4851 in[10] = 3.0f;
4852 in[14] = 6.0f;
4853 // row major mat2
4854 expected[0] = 22.0f;
4855 expected[1] = 49.0f;
4856 expected[2] = 28.0f;
4857 expected[3] = 64.0f;
4858 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(row_major) mat3x2 m0;" NL
4859 " layout(column_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4860 " layout(row_major) mat2 m;" NL "} g_output;" NL "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4861 }
4862
4863 class BasicMatrixOperationsCase7VS : public BasicMatrixOperationsBaseVS
4864 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4865 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4866 {
4867 return GetInputM7(in, expected);
4868 }
4869 };
4870
4871 class BasicMatrixOperationsCase7CS : public BasicMatrixOperationsBaseCS
4872 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4873 virtual const char *GetInput(std::vector<float> &in, std::vector<float> &expected)
4874 {
4875 return GetInputM7(in, expected);
4876 }
4877 };
4878
4879 //----------------------------------------------------------------------------
4880 // 1.13 BasicReadonlyWriteonly
4881 //-----------------------------------------------------------------------------
4882 class BasicReadonlyWriteonly : public ShaderStorageBufferObjectBase
4883 {
4884 GLuint m_program;
4885 GLuint m_storage_buffer[2];
4886
Setup()4887 virtual long Setup()
4888 {
4889 m_program = 0;
4890 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
4891 return NO_ERROR;
4892 }
4893
Run()4894 virtual long Run()
4895 {
4896 const char *const glsl_cs =
4897 NL "layout(local_size_x = 1) in;" NL "layout(std430, binding = 0) buffer Input {" NL
4898 " readonly writeonly int g_in[];" NL "};" NL "layout(std430, binding = 1) buffer Output {" NL
4899 " int count;" NL "} g_output;" NL "void main() {" NL " g_output.count = g_in.length();" NL "}";
4900
4901 m_program = CreateProgramCS(glsl_cs);
4902 glLinkProgram(m_program);
4903 if (!CheckProgram(m_program))
4904 return ERROR;
4905
4906 glGenBuffers(2, m_storage_buffer);
4907
4908 /* Input */
4909 int input_data[] = {1, 2, 3};
4910 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
4911 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(input_data), input_data, GL_STATIC_DRAW);
4912
4913 /* Output */
4914 int output_data[] = {0};
4915 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
4916 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(output_data), output_data, GL_DYNAMIC_COPY);
4917
4918 glUseProgram(m_program);
4919 glDispatchCompute(1, 1, 1);
4920 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4921
4922 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
4923 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
4924 if (!data)
4925 return ERROR;
4926 if (*data != DE_LENGTH_OF_ARRAY(input_data))
4927 {
4928 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer data is " << *data << " should be "
4929 << sizeof(input_data) << tcu::TestLog::EndMessage;
4930 return ERROR;
4931 }
4932 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4933 return NO_ERROR;
4934 }
4935
Cleanup()4936 virtual long Cleanup()
4937 {
4938 glUseProgram(0);
4939 glDeleteProgram(m_program);
4940 glDeleteBuffers(2, m_storage_buffer);
4941 return NO_ERROR;
4942 }
4943 };
4944
4945 //----------------------------------------------------------------------------
4946 // 1.15 BasicNameMatch
4947 //-----------------------------------------------------------------------------
4948 class BasicNameMatch : public ShaderStorageBufferObjectBase
4949 {
Run()4950 virtual long Run()
4951 {
4952 GLint blocksVS, blocksFS;
4953 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &blocksVS);
4954 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &blocksFS);
4955 if ((blocksVS == 0) || (blocksFS == 0))
4956 return NOT_SUPPORTED;
4957
4958 // check if link error is generated when one of matched blocks has instance name and other doesn't
4959 std::string vs1("buffer Buf { float x; };\n"
4960 "void main() {\n"
4961 " gl_Position = vec4(x);\n"
4962 "}");
4963 std::string fs1("buffer Buf { float x; } b;\n"
4964 "out vec4 color;\n"
4965 "void main() {\n"
4966 " color = vec4(b.x);\n"
4967 "}");
4968 if (Link(vs1, fs1))
4969 {
4970 m_context.getTestContext().getLog()
4971 << tcu::TestLog::Message << "Linking should fail." << tcu::TestLog::EndMessage;
4972 return ERROR;
4973 }
4974
4975 // check if linking succeeds when both matched blocks are lacking an instance name
4976 std::string vs2("buffer Buf { float x; };\n"
4977 "void main() {\n"
4978 " gl_Position = vec4(x);\n"
4979 "}");
4980 std::string fs2("buffer Buf { float x; };\n"
4981 "out vec4 color;\n"
4982 "void main() {\n"
4983 " color = vec4(x);\n"
4984 "}");
4985 if (!Link(vs2, fs2))
4986 {
4987 m_context.getTestContext().getLog()
4988 << tcu::TestLog::Message << "Linking should succeed." << tcu::TestLog::EndMessage;
4989 return ERROR;
4990 }
4991
4992 // check if linking succeeds when both matched blocks have different instance names
4993 std::string vs3("buffer Buf { float x; } a;\n"
4994 "void main() {\n"
4995 " gl_Position = vec4(a.x);\n"
4996 "}");
4997 std::string fs3("buffer Buf { float x; } b;\n"
4998 "out vec4 color;\n"
4999 "void main() {\n"
5000 " color = vec4(b.x);\n"
5001 "}");
5002 if (!Link(vs3, fs3))
5003 {
5004 m_context.getTestContext().getLog()
5005 << tcu::TestLog::Message << "Linking should succeed." << tcu::TestLog::EndMessage;
5006 return ERROR;
5007 }
5008
5009 return NO_ERROR;
5010 }
5011
Link(const std::string & vs,const std::string & fs)5012 bool Link(const std::string &vs, const std::string &fs)
5013 {
5014 GLuint program = CreateProgram(vs, fs);
5015 glLinkProgram(program);
5016 GLint status;
5017 glGetProgramiv(program, GL_LINK_STATUS, &status);
5018 glDeleteProgram(program);
5019 return (status == GL_TRUE);
5020 }
5021 };
5022
5023 //-----------------------------------------------------------------------------
5024 // 2.1 AdvancedSwitchBuffers
5025 //-----------------------------------------------------------------------------
5026 class AdvancedSwitchBuffersVS : public ShaderStorageBufferObjectBase
5027 {
PassCriteria()5028 virtual std::string PassCriteria()
5029 {
5030 return NL "Everything works as expected.";
5031 }
5032
5033 GLuint m_program;
5034 GLuint m_storage_buffer[5];
5035 GLuint m_vertex_array;
5036 GLuint m_fbo, m_rt;
5037
Setup()5038 virtual long Setup()
5039 {
5040 m_program = 0;
5041 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5042 m_vertex_array = 0;
5043 glGenFramebuffers(1, &m_fbo);
5044 glGenTextures(1, &m_rt);
5045 return NO_ERROR;
5046 }
Run()5047 virtual long Run()
5048 {
5049 if (!IsVSFSAvailable(1, 0))
5050 return NOT_SUPPORTED;
5051 const char *const glsl_vs = NL "struct VertexData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL
5052 "layout(binding = 0, std430) buffer Input {" NL " VertexData vertex[4];" NL
5053 "} g_vs_in;" NL "out vec3 StageData_color;" NL "void main() {" NL
5054 " gl_Position = vec4(g_vs_in.vertex[gl_VertexID].position, 0, 1);" NL
5055 " StageData_color = g_vs_in.vertex[gl_VertexID].color;" NL "}";
5056 const char *const glsl_fs = NL "in vec3 StageData_color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5057 "void main() {" NL " g_fs_out = vec4(StageData_color, 1);" NL "}";
5058 m_program = CreateProgram(glsl_vs, glsl_fs);
5059 glLinkProgram(m_program);
5060 if (!CheckProgram(m_program))
5061 return ERROR;
5062
5063 glGenBuffers(5, m_storage_buffer);
5064
5065 /* left, bottom, red quad */
5066 {
5067 const float data[] = {-0.4f - 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5068 0.4f - 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5069 -0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5070 0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f};
5071 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
5072 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5073 }
5074 /* right, bottom, green quad */
5075 {
5076 const float data[] = {-0.4f + 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5077 0.4f + 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5078 -0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5079 0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
5080 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
5081 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5082 }
5083 /* left, top, blue quad */
5084 {
5085 const float data[] = {-0.4f - 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5086 0.4f - 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5087 -0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5088 0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
5089 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
5090 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5091 }
5092 /* right, top, yellow quad */
5093 {
5094 const float data[] = {-0.4f + 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5095 0.4f + 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5096 -0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5097 0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f};
5098 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
5099 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5100 }
5101
5102 GLint alignment;
5103 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
5104 GLint offset = deRoundUp32(sizeof(float) * 32, alignment);
5105
5106 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
5107 glBufferData(GL_SHADER_STORAGE_BUFFER, offset * 4, NULL, GL_STATIC_DRAW);
5108
5109 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[0]);
5110 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(float) * 32);
5111 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[1]);
5112 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, offset, sizeof(float) * 32);
5113 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[2]);
5114 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 2 * offset, sizeof(float) * 32);
5115 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[3]);
5116 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 3 * offset, sizeof(float) * 32);
5117
5118 glBindTexture(GL_TEXTURE_2D, m_rt);
5119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5121 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5122 glBindTexture(GL_TEXTURE_2D, 0);
5123 glViewport(0, 0, 100, 100);
5124 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5125 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5126
5127 glGenVertexArrays(1, &m_vertex_array);
5128
5129 glUseProgram(m_program);
5130 glBindVertexArray(m_vertex_array);
5131
5132 glClear(GL_COLOR_BUFFER_BIT);
5133 for (int i = 0; i < 4; ++i)
5134 {
5135 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[i]);
5136 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5137 }
5138 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5139 {
5140 return ERROR;
5141 }
5142
5143 glClear(GL_COLOR_BUFFER_BIT);
5144 for (int i = 0; i < 4; ++i)
5145 {
5146 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[4], i * offset, sizeof(float) * 32);
5147 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
5148 }
5149 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5150 {
5151 return ERROR;
5152 }
5153
5154 return NO_ERROR;
5155 }
Cleanup()5156 virtual long Cleanup()
5157 {
5158 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5159 glUseProgram(0);
5160 glDeleteProgram(m_program);
5161 glDeleteBuffers(5, m_storage_buffer);
5162 glDeleteVertexArrays(1, &m_vertex_array);
5163 glDeleteFramebuffers(1, &m_fbo);
5164 glDeleteTextures(1, &m_rt);
5165 return NO_ERROR;
5166 }
5167 };
5168
5169 class AdvancedSwitchBuffersCS : public ShaderStorageBufferObjectBase
5170 {
5171 GLuint m_program;
5172 GLuint m_storage_buffer[6];
5173
Setup()5174 virtual long Setup()
5175 {
5176 m_program = 0;
5177 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5178 return NO_ERROR;
5179 }
Run()5180 virtual long Run()
5181 {
5182 const char *const glsl_cs =
5183 NL "layout(local_size_x = 1) in;" NL "layout(binding = 0, std430) buffer Input {" NL " uint cookie[4];" NL
5184 "} g_in;" NL "layout(binding = 1, std430) buffer Output {" NL " uvec4 digest;" NL "} ;" NL
5185 "void main() {" NL " switch (g_in.cookie[0]+g_in.cookie[1]+g_in.cookie[2]+g_in.cookie[3]) {" NL
5186 " case 0x000000ffu: digest.x = 0xff000000u; break;" NL
5187 " case 0x0000ff00u: digest.y = 0x00ff0000u; break;" NL
5188 " case 0x00ff0000u: digest.z = 0x0000ff00u; break;" NL
5189 " case 0xff000000u: digest.w = 0x000000ffu; break;" NL " }" NL "}";
5190 m_program = CreateProgramCS(glsl_cs);
5191 glLinkProgram(m_program);
5192 if (!CheckProgram(m_program))
5193 return ERROR;
5194
5195 glGenBuffers(6, m_storage_buffer);
5196
5197 const GLubyte data0[] = {0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x88, 0, 0, 0, 0x22};
5198 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
5199 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data0), data0, GL_STATIC_DRAW);
5200 const GLubyte data1[] = {0, 0, 0x44, 0, 0, 0, 0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0};
5201 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
5202 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data1), data1, GL_STATIC_DRAW);
5203 const GLubyte data2[] = {0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x22, 0, 0};
5204 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
5205 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW);
5206 const GLubyte data3[] = {0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0};
5207 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
5208 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data3), data3, GL_STATIC_DRAW);
5209
5210 GLint alignment;
5211 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
5212 GLint offset = deRoundUp32(sizeof(data0), alignment);
5213 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
5214 glBufferData(GL_SHADER_STORAGE_BUFFER, offset * 4, NULL, GL_STATIC_DRAW);
5215
5216 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[0]);
5217 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(data0));
5218 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[1]);
5219 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, offset, sizeof(data0));
5220 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[2]);
5221 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 2 * offset, sizeof(data0));
5222 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[3]);
5223 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 3 * offset, sizeof(data0));
5224
5225 const GLubyte data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
5226 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[5]);
5227 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5228
5229 glUseProgram(m_program);
5230 for (int i = 0; i < 4; ++i)
5231 {
5232 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[i]);
5233 glDispatchCompute(1, 1, 1);
5234 }
5235 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
5236 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5237 GLuint *out_data = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data0), GL_MAP_READ_BIT);
5238 if (!out_data)
5239 return ERROR;
5240 GLuint expected[4] = {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff};
5241 if (out_data[0] != expected[0] || out_data[1] != expected[1] || out_data[2] != expected[2] ||
5242 out_data[3] != expected[3])
5243 {
5244 m_context.getTestContext().getLog()
5245 << tcu::TestLog::Message << "Received: " << out_data[0] << ", " << out_data[1] << ", " << out_data[2]
5246 << ", " << out_data[3] << ", but expected: " << expected[0] << ", " << expected[1] << ", "
5247 << expected[2] << ", " << expected[3] << tcu::TestLog::EndMessage;
5248 return ERROR;
5249 }
5250 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5251 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5252
5253 for (int i = 0; i < 4; ++i)
5254 {
5255 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[4], i * offset, sizeof(data0));
5256 glDispatchCompute(1, 1, 1);
5257 }
5258 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
5259 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5260 out_data = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data0), GL_MAP_READ_BIT);
5261 if (!out_data)
5262 return ERROR;
5263 if (out_data[0] != expected[0] || out_data[1] != expected[1] || out_data[2] != expected[2] ||
5264 out_data[3] != expected[3])
5265 {
5266 m_context.getTestContext().getLog()
5267 << tcu::TestLog::Message << "Received: " << tcu::toHex(out_data[0]) << ", " << tcu::toHex(out_data[1])
5268 << ", " << tcu::toHex(out_data[2]) << ", " << tcu::toHex(out_data[3])
5269 << ", but expected: " << tcu::toHex(expected[0]) << ", " << tcu::toHex(expected[1]) << ", "
5270 << tcu::toHex(expected[2]) << ", " << tcu::toHex(expected[3]) << tcu::TestLog::EndMessage;
5271 return ERROR;
5272 }
5273
5274 return NO_ERROR;
5275 }
Cleanup()5276 virtual long Cleanup()
5277 {
5278 glUseProgram(0);
5279 glDeleteProgram(m_program);
5280 glDeleteBuffers(6, m_storage_buffer);
5281 return NO_ERROR;
5282 }
5283 };
5284
5285 //-----------------------------------------------------------------------------
5286 // 2.2 AdvancedSwitchPrograms
5287 //-----------------------------------------------------------------------------
5288 class AdvancedSwitchProgramsVS : public ShaderStorageBufferObjectBase
5289 {
5290 GLuint m_program[4];
5291 GLuint m_storage_buffer[4];
5292 GLuint m_vertex_array;
5293 GLuint m_fbo, m_rt;
5294
GenSource(int binding)5295 std::string GenSource(int binding)
5296 {
5297 std::stringstream ss;
5298 ss << NL "struct VertexData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL "layout(binding = "
5299 << binding
5300 << ", std430) buffer Input {" NL " VertexData vertex[4];" NL "} g_vs_in;" NL "out vec3 StageData_color;" NL
5301 "void main() {" NL " gl_Position = vec4(g_vs_in.vertex[gl_VertexID].position, 0, 1);" NL
5302 " StageData_color = g_vs_in.vertex[gl_VertexID].color;" NL "}";
5303 return ss.str();
5304 }
5305
Setup()5306 virtual long Setup()
5307 {
5308 memset(m_program, 0, sizeof(m_program));
5309 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5310 m_vertex_array = 0;
5311 glGenFramebuffers(1, &m_fbo);
5312 glGenTextures(1, &m_rt);
5313 return NO_ERROR;
5314 }
5315
Run()5316 virtual long Run()
5317 {
5318 if (!IsVSFSAvailable(1, 0))
5319 return NOT_SUPPORTED;
5320 const char *const glsl_fs = NL "in vec3 StageData_color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5321 "void main() {" NL " g_fs_out = vec4(StageData_color, 1);" NL "}";
5322 for (int i = 0; i < 4; ++i)
5323 {
5324 m_program[i] = CreateProgram(GenSource(i), glsl_fs);
5325 glLinkProgram(m_program[i]);
5326 if (!CheckProgram(m_program[i]))
5327 return ERROR;
5328 }
5329
5330 glGenBuffers(4, m_storage_buffer);
5331
5332 /* left, bottom, red quad */
5333 {
5334 const float data[] = {-0.4f - 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5335 0.4f - 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5336 -0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5337 0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f};
5338 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5339 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5340 }
5341 /* right, bottom, green quad */
5342 {
5343 const float data[] = {-0.4f + 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5344 0.4f + 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5345 -0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5346 0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
5347 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5348 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5349 }
5350 /* left, top, blue quad */
5351 {
5352 const float data[] = {-0.4f - 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5353 0.4f - 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5354 -0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5355 0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
5356 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5357 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5358 }
5359 /* right, top, yellow quad */
5360 {
5361 const float data[] = {-0.4f + 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5362 0.4f + 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5363 -0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5364 0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f};
5365 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5366 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5367 }
5368
5369 glBindTexture(GL_TEXTURE_2D, m_rt);
5370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5371 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5372 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5373 glBindTexture(GL_TEXTURE_2D, 0);
5374 glViewport(0, 0, 100, 100);
5375 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5376 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5377
5378 glGenVertexArrays(1, &m_vertex_array);
5379 glBindVertexArray(m_vertex_array);
5380
5381 glClear(GL_COLOR_BUFFER_BIT);
5382 for (int i = 0; i < 4; ++i)
5383 {
5384 glUseProgram(m_program[i]);
5385 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5386 }
5387 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5388 {
5389 return ERROR;
5390 }
5391
5392 return NO_ERROR;
5393 }
5394
Cleanup()5395 virtual long Cleanup()
5396 {
5397 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5398 glUseProgram(0);
5399 for (int i = 0; i < 4; ++i)
5400 glDeleteProgram(m_program[i]);
5401 glDeleteBuffers(4, m_storage_buffer);
5402 glDeleteVertexArrays(1, &m_vertex_array);
5403 glDeleteFramebuffers(1, &m_fbo);
5404 glDeleteTextures(1, &m_rt);
5405 return NO_ERROR;
5406 }
5407 };
5408
5409 class AdvancedSwitchProgramsCS : public ShaderStorageBufferObjectBase
5410 {
5411 GLuint m_program[4];
5412 GLuint m_storage_buffer[5];
5413
Setup()5414 virtual long Setup()
5415 {
5416 memset(m_program, 0, sizeof(m_program));
5417 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5418 return NO_ERROR;
5419 }
5420
GenSource(int binding)5421 std::string GenSource(int binding)
5422 {
5423 std::stringstream ss;
5424 ss << NL "layout(local_size_x = 1) in;" NL "layout(binding = " << binding
5425 << ", std430) buffer Input {" NL " uint cookie[4];" NL "} g_in;" NL
5426 "layout(binding = 0, std430) buffer Output {" NL " uvec4 digest;" NL "} ;" NL "void main() {" NL
5427 " switch (g_in.cookie[0]+g_in.cookie[1]+g_in.cookie[2]+g_in.cookie[3]) {" NL
5428 " case 0x000000ffu: digest.x = 0xff000000u; break;" NL
5429 " case 0x0000ff00u: digest.y = 0x00ff0000u; break;" NL
5430 " case 0x00ff0000u: digest.z = 0x0000ff00u; break;" NL
5431 " case 0xff000000u: digest.w = 0x000000ffu; break;" NL " }" NL "}";
5432 return ss.str();
5433 }
5434
Run()5435 virtual long Run()
5436 {
5437 for (int i = 0; i < 4; ++i)
5438 {
5439 m_program[i] = CreateProgramCS(GenSource(i + 1));
5440 glLinkProgram(m_program[i]);
5441 if (!CheckProgram(m_program[i]))
5442 return ERROR;
5443 }
5444
5445 glGenBuffers(5, m_storage_buffer);
5446
5447 const GLubyte data0[] = {0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x88, 0, 0, 0, 0x22};
5448 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5449 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data0), data0, GL_STATIC_DRAW);
5450 const GLubyte data1[] = {0, 0, 0x44, 0, 0, 0, 0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0};
5451 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5452 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data1), data1, GL_STATIC_DRAW);
5453 const GLubyte data2[] = {0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x22, 0, 0};
5454 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5455 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW);
5456 const GLubyte data3[] = {0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0};
5457 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
5458 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data3), data3, GL_STATIC_DRAW);
5459
5460 const GLubyte data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
5461 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5462 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5463
5464 for (int i = 0; i < 4; ++i)
5465 {
5466 glUseProgram(m_program[i]);
5467 glDispatchCompute(1, 1, 1);
5468 }
5469 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
5470 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5471 GLuint *out_data = (GLuint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data0), GL_MAP_READ_BIT);
5472 if (!out_data)
5473 return ERROR;
5474 GLuint expected[4] = {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff};
5475 if (out_data[0] != expected[0] || out_data[1] != expected[1] || out_data[2] != expected[2] ||
5476 out_data[3] != expected[3])
5477 {
5478 m_context.getTestContext().getLog()
5479 << tcu::TestLog::Message << "Received: " << tcu::toHex(out_data[0]) << ", " << tcu::toHex(out_data[1])
5480 << ", " << tcu::toHex(out_data[2]) << ", " << tcu::toHex(out_data[3])
5481 << ", but expected: " << tcu::toHex(expected[0]) << ", " << tcu::toHex(expected[1]) << ", "
5482 << tcu::toHex(expected[2]) << ", " << tcu::toHex(expected[3]) << tcu::TestLog::EndMessage;
5483 return ERROR;
5484 }
5485 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5486
5487 return NO_ERROR;
5488 }
Cleanup()5489 virtual long Cleanup()
5490 {
5491 glUseProgram(0);
5492 for (int i = 0; i < 4; ++i)
5493 glDeleteProgram(m_program[i]);
5494 glDeleteBuffers(5, m_storage_buffer);
5495 return NO_ERROR;
5496 }
5497 };
5498 //-----------------------------------------------------------------------------
5499 // 2.3.1 AdvancedWriteFragment
5500 //-----------------------------------------------------------------------------
5501 class AdvancedWriteFragmentFS : public ShaderStorageBufferObjectBase
5502 {
5503 GLuint m_program[2];
5504 GLuint m_storage_buffer;
5505 GLuint m_counter_buffer;
5506 GLuint m_attribless_vertex_array;
5507 GLuint m_draw_vertex_array;
5508 GLuint m_fbo, m_rt;
5509
Setup()5510 virtual long Setup()
5511 {
5512 memset(m_program, 0, sizeof(m_program));
5513 m_storage_buffer = 0;
5514 m_counter_buffer = 0;
5515 m_attribless_vertex_array = 0;
5516 m_draw_vertex_array = 0;
5517 glGenFramebuffers(1, &m_fbo);
5518 glGenTextures(1, &m_rt);
5519 return NO_ERROR;
5520 }
5521
Run()5522 virtual long Run()
5523 {
5524 if (!IsVSFSAvailable(0, 1))
5525 return NOT_SUPPORTED;
5526 const char *const glsl_vs0 =
5527 NL "out vec2 position;" NL "out vec3 color;" NL
5528 "vec2 g_quad[4] = vec2[4](vec2(-0.4, -0.4), vec2(0.4, -0.4), vec2(-0.4, 0.4), vec2(0.4, 0.4));" NL
5529 "vec2 g_offset[4] = vec2[4](vec2(-0.5, -0.5), vec2(0.5, -0.5), vec2(-0.5, 0.5), vec2(0.5, 0.5));" NL
5530 "vec3 g_color[4] = vec3[4](vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1), vec3(1, 1, 0));" NL
5531 "void main() {" NL " vec2 pos = g_quad[gl_VertexID] + g_offset[gl_InstanceID];" NL
5532 " gl_Position = vec4(pos, 0, 1);" NL " position = pos;" NL " color = g_color[gl_InstanceID];" NL "}";
5533 const char *const glsl_fs0 =
5534 NL "in vec2 position;" NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5535 "struct FragmentData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL
5536 "layout(std430, binding = 3) buffer Output {" NL " FragmentData g_fragment[6400];" NL "};" NL
5537 "uniform uint g_max_fragment_count;" NL
5538 "layout(binding = 2, offset = 0) uniform atomic_uint g_fragment_counter;" NL "void main() {" NL
5539 " uint fragment_number = atomicCounterIncrement(g_fragment_counter);" NL
5540 " if (fragment_number < g_max_fragment_count) {" NL
5541 " g_fragment[fragment_number].position = position;" NL
5542 " g_fragment[fragment_number].color = color;" NL " }" NL " g_fs_out = vec4(color, 1);" NL "}";
5543 m_program[0] = CreateProgram(glsl_vs0, glsl_fs0);
5544 glLinkProgram(m_program[0]);
5545 if (!CheckProgram(m_program[0]))
5546 return ERROR;
5547
5548 const char *const glsl_vs1 =
5549 NL "layout(location = 0) in vec4 g_in_position;" NL "layout(location = 1) in vec4 g_in_color;" NL
5550 "out vec3 color;" NL "void main() {" NL " gl_Position = vec4(g_in_position.xy, 0, 1);" NL
5551 "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL " color = g_in_color.rgb;" NL "}";
5552 const char *const glsl_fs1 = NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5553 "void main() {" NL " g_fs_out = vec4(color, 1);" NL "}";
5554 m_program[1] = CreateProgram(glsl_vs1, glsl_fs1);
5555 glLinkProgram(m_program[1]);
5556 if (!CheckProgram(m_program[1]))
5557 return ERROR;
5558
5559 // The first pass renders four squares on-screen, and writes a
5560 // record to the SSBO for each fragment processed. The rectangles
5561 // will be 40x40 when using a 100x100 viewport, so we expect 1600
5562 // pixels per rectangle or 6400 pixels total. Size the SSBO
5563 // accordingly, and render the second pass (sourcing the SSBO as a
5564 // vertex buffer) with an identical number of points. If we have
5565 // a larger buffer and draw more points on the second pass, those
5566 // may overwrite "real" points using garbage position/color.
5567 int expectedPixels = 6400;
5568
5569 glGenBuffers(1, &m_storage_buffer);
5570 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer);
5571 glBufferData(GL_SHADER_STORAGE_BUFFER, expectedPixels * 32, NULL, GL_DYNAMIC_DRAW);
5572
5573 glGenBuffers(1, &m_counter_buffer);
5574 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 2, m_counter_buffer);
5575 glBufferData(GL_ATOMIC_COUNTER_BUFFER, 4, NULL, GL_DYNAMIC_DRAW);
5576 uvec4 zero(0);
5577 glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, 4, &zero);
5578
5579 glBindTexture(GL_TEXTURE_2D, m_rt);
5580 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5581 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5582 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5583 glBindTexture(GL_TEXTURE_2D, 0);
5584 glViewport(0, 0, 100, 100);
5585 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5586 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5587
5588 glGenVertexArrays(1, &m_attribless_vertex_array);
5589
5590 glGenVertexArrays(1, &m_draw_vertex_array);
5591 glBindVertexArray(m_draw_vertex_array);
5592 glBindBuffer(GL_ARRAY_BUFFER, m_storage_buffer);
5593 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 32, 0);
5594 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 32, reinterpret_cast<void *>(16));
5595 glBindBuffer(GL_ARRAY_BUFFER, 0);
5596 glEnableVertexAttribArray(0);
5597 glEnableVertexAttribArray(1);
5598 glBindVertexArray(0);
5599
5600 glClear(GL_COLOR_BUFFER_BIT);
5601 glUseProgram(m_program[0]);
5602 glUniform1ui(glGetUniformLocation(m_program[0], "g_max_fragment_count"), expectedPixels);
5603 glBindVertexArray(m_attribless_vertex_array);
5604 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
5605 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5606 {
5607 return ERROR;
5608 }
5609
5610 glClear(GL_COLOR_BUFFER_BIT);
5611 glUseProgram(m_program[1]);
5612 glBindVertexArray(m_draw_vertex_array);
5613 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
5614 glDrawArrays(GL_POINTS, 0, expectedPixels);
5615 int bad_pixels;
5616 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1), &bad_pixels) &&
5617 bad_pixels > 2)
5618 {
5619 return ERROR;
5620 }
5621
5622 return NO_ERROR;
5623 }
5624
Cleanup()5625 virtual long Cleanup()
5626 {
5627 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5628 glUseProgram(0);
5629 for (int i = 0; i < 2; ++i)
5630 glDeleteProgram(m_program[i]);
5631 glDeleteBuffers(1, &m_storage_buffer);
5632 glDeleteBuffers(1, &m_counter_buffer);
5633 glDeleteVertexArrays(1, &m_attribless_vertex_array);
5634 glDeleteVertexArrays(1, &m_draw_vertex_array);
5635 glDeleteFramebuffers(1, &m_fbo);
5636 glDeleteTextures(1, &m_rt);
5637 return NO_ERROR;
5638 }
5639 };
5640
5641 class AdvancedWriteFragmentCS : public ShaderStorageBufferObjectBase
5642 {
5643 GLuint m_program[2];
5644 GLuint m_storage_buffer;
5645 GLuint m_counter_buffer;
5646 GLuint m_draw_vertex_array;
5647 GLuint m_fbo, m_rt;
5648
Setup()5649 virtual long Setup()
5650 {
5651 memset(m_program, 0, sizeof(m_program));
5652 m_storage_buffer = 0;
5653 m_counter_buffer = 0;
5654 m_draw_vertex_array = 0;
5655 glGenFramebuffers(1, &m_fbo);
5656 glGenTextures(1, &m_rt);
5657 return NO_ERROR;
5658 }
5659
Run()5660 virtual long Run()
5661 {
5662 const char *const glsl_cs = NL
5663 "layout(local_size_x = 10, local_size_y = 10) in;" NL "uniform uint g_max_point_count;" NL
5664 "uniform uint g_brick;" NL
5665 "vec3 g_color[5] = vec3[5](vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1), vec3(0, 0, 0));" NL
5666 "struct PointData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL
5667 "layout(std430, binding = 3) buffer Output {" NL " PointData g_point[];" NL "};" NL
5668 "layout(binding = 0, offset = 0) uniform atomic_uint g_point_counter;" NL "void main() {" NL
5669 " uint g_offset[4] = uint[4](g_brick, 9u*g_brick, 11u*g_brick, 19u*g_brick);" NL
5670 " uint point_number = atomicCounterIncrement(g_point_counter);" NL
5671 " uint giidx = gl_GlobalInvocationID.x;" NL " uint giidy = gl_GlobalInvocationID.y;" NL
5672 " g_point[point_number].position = vec2(gl_GlobalInvocationID.xy * 2u) / 100.0 - 1.0;" NL
5673 " g_point[point_number].color = g_color[4];" NL " if (point_number < g_max_point_count) {" NL
5674 " if (giidx > g_offset[0] && giidx < g_offset[1] && giidy > g_offset[0] && giidy < g_offset[1]) {" NL
5675 " g_point[point_number].color = g_color[0];" NL " }" NL
5676 " if (giidx > g_offset[2] && giidx < g_offset[3] && giidy > g_offset[0] && giidy < g_offset[1]) {" NL
5677 " g_point[point_number].color = g_color[1];" NL " }" NL
5678 " if (giidx > g_offset[2] && giidx < g_offset[3] && giidy > g_offset[2] && giidy < g_offset[3]) {" NL
5679 " g_point[point_number].color = g_color[2];" NL " }" NL
5680 " if (giidx > g_offset[0] && giidx < g_offset[1] && giidy > g_offset[2] && giidy < g_offset[3]) {" NL
5681 " g_point[point_number].color = g_color[3];" NL " }" NL " }" NL "}";
5682
5683 m_program[0] = CreateProgramCS(glsl_cs);
5684 glLinkProgram(m_program[0]);
5685 if (!CheckProgram(m_program[0]))
5686 return ERROR;
5687
5688 const char *const glsl_vs1 =
5689 NL "layout(location = 0) in vec4 g_in_position;" NL "layout(location = 1) in vec4 g_in_color;" NL
5690 "out vec3 color;" NL "void main() {" NL " gl_Position = vec4(g_in_position.xy, 0, 1);" NL
5691 "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL " color = g_in_color.rgb;" NL "}";
5692
5693 const char *const glsl_fs1 = NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5694 "void main() {" NL " g_fs_out = vec4(color, 1);" NL "}";
5695
5696 m_program[1] = CreateProgram(glsl_vs1, glsl_fs1);
5697 glLinkProgram(m_program[1]);
5698 if (!CheckProgram(m_program[1]))
5699 return ERROR;
5700
5701 glGenBuffers(1, &m_storage_buffer);
5702 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer);
5703 glBufferData(GL_SHADER_STORAGE_BUFFER, 100 * 100 * 32, NULL, GL_DYNAMIC_DRAW);
5704
5705 glGenBuffers(1, &m_counter_buffer);
5706 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_counter_buffer);
5707 glBufferData(GL_ATOMIC_COUNTER_BUFFER, 4, NULL, GL_DYNAMIC_DRAW);
5708 uvec4 zero(0);
5709 glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, 4, &zero);
5710
5711 glGenVertexArrays(1, &m_draw_vertex_array);
5712 glBindVertexArray(m_draw_vertex_array);
5713 glBindBuffer(GL_ARRAY_BUFFER, m_storage_buffer);
5714 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 32, 0);
5715 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 32, reinterpret_cast<void *>(16));
5716 glBindBuffer(GL_ARRAY_BUFFER, 0);
5717 glEnableVertexAttribArray(0);
5718 glEnableVertexAttribArray(1);
5719 glBindVertexArray(0);
5720
5721 glUseProgram(m_program[0]);
5722 glUniform1ui(glGetUniformLocation(m_program[0], "g_max_point_count"), 100 * 100);
5723 glUniform1ui(glGetUniformLocation(m_program[0], "g_brick"), 5);
5724 glDispatchCompute(10, 10, 1);
5725
5726 glBindTexture(GL_TEXTURE_2D, m_rt);
5727 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5728 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5729 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5730 glBindTexture(GL_TEXTURE_2D, 0);
5731 glViewport(0, 0, 100, 100);
5732 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5733 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5734
5735 glClear(GL_COLOR_BUFFER_BIT);
5736 glUseProgram(m_program[1]);
5737 glBindVertexArray(m_draw_vertex_array);
5738 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
5739 glDrawArrays(GL_POINTS, 0, 100 * 100);
5740 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5741 {
5742 return ERROR;
5743 }
5744
5745 return NO_ERROR;
5746 }
Cleanup()5747 virtual long Cleanup()
5748 {
5749 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5750 glUseProgram(0);
5751 for (int i = 0; i < 2; ++i)
5752 glDeleteProgram(m_program[i]);
5753 glDeleteBuffers(1, &m_storage_buffer);
5754 glDeleteBuffers(1, &m_counter_buffer);
5755 glDeleteVertexArrays(1, &m_draw_vertex_array);
5756 glDeleteFramebuffers(1, &m_fbo);
5757 glDeleteTextures(1, &m_rt);
5758 return NO_ERROR;
5759 }
5760 };
5761 //-----------------------------------------------------------------------------
5762 // 2.4.1 AdvancedIndirectAddressingCase1
5763 //-----------------------------------------------------------------------------
5764 class AdvancedIndirectAddressingCase1VS : public ShaderStorageBufferObjectBase
5765 {
5766 GLuint m_program;
5767 GLuint m_storage_buffer[4];
5768 GLuint m_vertex_array;
5769 GLuint m_vertex_buffer;
5770 GLuint m_fbo, m_rt;
5771
Setup()5772 virtual long Setup()
5773 {
5774 m_program = 0;
5775 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5776 m_vertex_array = 0;
5777 m_vertex_buffer = 0;
5778 glGenFramebuffers(1, &m_fbo);
5779 glGenTextures(1, &m_rt);
5780 return NO_ERROR;
5781 }
5782
Run()5783 virtual long Run()
5784 {
5785 if (!IsVSFSAvailable(4, 0))
5786 return NOT_SUPPORTED;
5787 const char *const glsl_vs =
5788 NL "layout(location = 0) in vec2 g_in_position;" NL "struct Material {" NL " vec3 color;" NL "};" NL
5789 "layout(binding = 0, std430) buffer MaterialBuffer {" NL " Material g_material[4];" NL "};" NL
5790 "layout(binding = 1, std430) buffer MaterialIDBuffer {" NL " uint g_material_id[4];" NL "};" NL
5791 "layout(binding = 2, std430) buffer TransformBuffer {" NL " vec2 translation[4];" NL "} g_transform;" NL
5792 "layout(binding = 3, std430) buffer TransformIDBuffer {" NL " uint g_transform_id[4];" NL "};" NL
5793 "out vec3 color;" NL "void main() {" NL " uint mid = g_material_id[gl_InstanceID];" NL
5794 " Material m = g_material[mid];" NL " uint tid = g_transform_id[gl_InstanceID];" NL
5795 " vec2 t = g_transform.translation[tid];" NL " gl_Position = vec4(g_in_position + t, 0, 1);" NL
5796 " color = m.color;" NL "}";
5797 const char *const glsl_fs = NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5798 "void main() {" NL " g_fs_out = vec4(color, 1);" NL "}";
5799 m_program = CreateProgram(glsl_vs, glsl_fs);
5800 glLinkProgram(m_program);
5801 if (!CheckProgram(m_program))
5802 return ERROR;
5803
5804 glGenBuffers(4, m_storage_buffer);
5805
5806 /* material buffer */
5807 {
5808 const float data[] = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
5809 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
5810 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5811 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5812 }
5813 /* material id buffer */
5814 {
5815 const unsigned int data[] = {2, 3, 0, 2};
5816 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5817 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5818 }
5819 /* transform buffer */
5820 {
5821 const float data[] = {-0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f};
5822 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5823 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5824 }
5825 /* transform id buffer */
5826 {
5827 const unsigned int data[] = {3, 1, 0, 2};
5828 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5829 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5830 }
5831
5832 /* vertex buffer */
5833 {
5834 const float data[] = {-0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.4f, 0.4f};
5835 glGenBuffers(1, &m_vertex_buffer);
5836 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
5837 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5838 glBindBuffer(GL_ARRAY_BUFFER, 0);
5839 }
5840
5841 glBindTexture(GL_TEXTURE_2D, m_rt);
5842 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5843 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5844 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5845 glBindTexture(GL_TEXTURE_2D, 0);
5846 glViewport(0, 0, 100, 100);
5847 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5848 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5849
5850 glGenVertexArrays(1, &m_vertex_array);
5851 glBindVertexArray(m_vertex_array);
5852 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
5853 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
5854 glBindBuffer(GL_ARRAY_BUFFER, 0);
5855 glEnableVertexAttribArray(0);
5856 glBindVertexArray(0);
5857
5858 glClear(GL_COLOR_BUFFER_BIT);
5859 glUseProgram(m_program);
5860 glBindVertexArray(m_vertex_array);
5861 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
5862 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(1, 1, 0), vec3(0, 0, 1), vec3(0, 0, 1)))
5863 {
5864 return ERROR;
5865 }
5866
5867 /* update material id buffer with BufferSubData */
5868 {
5869 const unsigned int data[] = {3, 2, 1, 0};
5870 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
5871 glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), data);
5872 }
5873
5874 /* update transform id buffer with BufferData */
5875 {
5876 const unsigned int data[] = {0, 1, 2, 3};
5877 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
5878 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5879 }
5880
5881 glClear(GL_COLOR_BUFFER_BIT);
5882 glUseProgram(m_program);
5883 glBindVertexArray(m_vertex_array);
5884 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
5885 if (!ValidateWindow4Quads(vec3(1, 1, 0), vec3(0, 0, 1), vec3(1, 0, 0), vec3(0, 1, 0)))
5886 {
5887 return ERROR;
5888 }
5889
5890 return NO_ERROR;
5891 }
5892
Cleanup()5893 virtual long Cleanup()
5894 {
5895 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5896 glUseProgram(0);
5897 glDeleteProgram(m_program);
5898 glDeleteBuffers(4, m_storage_buffer);
5899 glDeleteBuffers(1, &m_vertex_buffer);
5900 glDeleteVertexArrays(1, &m_vertex_array);
5901 glDeleteFramebuffers(1, &m_fbo);
5902 glDeleteTextures(1, &m_rt);
5903 return NO_ERROR;
5904 }
5905 };
5906
5907 class AdvancedIndirectAddressingCase1CS : public ShaderStorageBufferObjectBase
5908 {
5909 GLuint m_program;
5910 GLuint m_storage_buffer[5];
5911
Setup()5912 virtual long Setup()
5913 {
5914 m_program = 0;
5915 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5916 return NO_ERROR;
5917 }
5918
Run()5919 virtual long Run()
5920 {
5921 bool status = true;
5922 const char *const glsl_cs =
5923 NL "layout(local_size_x = 2, local_size_y = 2) in;" NL "struct Material {" NL " vec3 color;" NL "};" NL
5924 "layout(binding = 0, std430) buffer MaterialBuffer {" NL " Material g_material[4];" NL "};" NL
5925 "layout(binding = 1, std430) buffer MaterialIDBuffer {" NL " uint g_material_id[4];" NL "};" NL
5926 "layout(binding = 2, std430) buffer TransformBuffer {" NL " vec2 translation[4];" NL "} g_transform;" NL
5927 "layout(binding = 3, std430) buffer TransformIDBuffer {" NL " uint g_transform_id[4];" NL "};" NL
5928 "layout(binding = 4, std430) buffer OutputBuffer {" NL " vec3 color[16];" NL " vec2 pos[16];" NL
5929 "};" NL "vec2 g_in_position[4] = vec2[4](vec2(-0.4f, -0.4f), vec2(0.4f, -0.4f), vec2(-0.4f, 0.4f), "
5930 "vec2(0.4f, 0.4f));" NL "void main() {" NL " uint mid = g_material_id[gl_WorkGroupID.x];" NL
5931 " Material m = g_material[mid];" NL " uint tid = g_transform_id[gl_WorkGroupID.x];" NL
5932 " vec2 t = g_transform.translation[tid];" NL
5933 " pos[gl_LocalInvocationIndex + gl_WorkGroupID.x * gl_WorkGroupSize.x * gl_WorkGroupSize.y] " NL
5934 " = g_in_position[gl_LocalInvocationIndex] + t;" NL " color[gl_LocalInvocationIndex + "
5935 "gl_WorkGroupID.x * gl_WorkGroupSize.x * "
5936 "gl_WorkGroupSize.y] = m.color;" NL "}";
5937
5938 m_program = CreateProgramCS(glsl_cs);
5939 glLinkProgram(m_program);
5940 if (!CheckProgram(m_program))
5941 return ERROR;
5942
5943 glGenBuffers(5, m_storage_buffer);
5944
5945 /* material buffer */
5946 {
5947 const float data[] = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
5948 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
5949 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5950 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5951 }
5952 /* material id buffer */
5953 {
5954 const unsigned int data[] = {2, 3, 0, 2};
5955 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5956 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5957 }
5958 /* transform buffer */
5959 {
5960 const float data[] = {-0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f};
5961 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5962 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5963 }
5964 /* transform id buffer */
5965 {
5966 const unsigned int data[] = {3, 1, 0, 2};
5967 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5968 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5969 }
5970
5971 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
5972 glBufferData(GL_SHADER_STORAGE_BUFFER, 16 * 4 * 4 + 16 * 2 * 4, 0, GL_STATIC_DRAW);
5973
5974 glUseProgram(m_program);
5975 glDispatchCompute(4, 1, 1);
5976 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5977 GLfloat *out_data =
5978 (GLfloat *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16 * 4 * 4 + 16 * 2 * 4, GL_MAP_READ_BIT);
5979 if (!out_data)
5980 return ERROR;
5981
5982 GLfloat expected[16 * 4 + 16 * 2] = {
5983 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5984 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5985 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5986 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5987 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.1f, 0.1f, 0.9f, 0.1f, 0.1f, 0.9f,
5988 0.9f, 0.9f, 0.1f, -0.9f, 0.9f, -0.9f, 0.1f, -0.1f, 0.9f, -0.1f, -0.9f, -0.9f, -0.1f, -0.9f,
5989 -0.9f, -0.1f, -0.1f, -0.1f, -0.9f, 0.1f, -0.1f, 0.1f, -0.9f, 0.9f, -0.1f, 0.9f};
5990
5991 for (int i = 0; i < 16; ++i)
5992 {
5993 if (out_data[i * 4 + 0] != expected[i * 4 + 0] || out_data[i * 4 + 1] != expected[i * 4 + 1] ||
5994 out_data[i * 4 + 2] != expected[i * 4 + 2])
5995 {
5996 m_context.getTestContext().getLog()
5997 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 0] << ", " << out_data[i * 4 + 1]
5998 << ", " << out_data[i * 4 + 2] << ", but expected: " << expected[i * 4 + 0] << ", "
5999 << expected[i * 4 + 1] << ", " << expected[i * 4 + 2] << tcu::TestLog::EndMessage;
6000 status = false;
6001 }
6002 }
6003 for (int i = 32; i < 32 + 16; ++i)
6004 {
6005 if (fabs(out_data[i * 2 + 0] - expected[i * 2 + 0]) > 1e-6 ||
6006 fabs(out_data[i * 2 + 1] - expected[i * 2 + 1]) > 1e-6)
6007 {
6008 m_context.getTestContext().getLog()
6009 << tcu::TestLog::Message << "Received: " << out_data[i * 2 + 0] << ", " << out_data[i * 2 + 1]
6010 << ", but expected: " << expected[i * 2 + 0] << ", " << expected[i * 2 + 1]
6011 << tcu::TestLog::EndMessage;
6012 status = false;
6013 }
6014 }
6015 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6016
6017 /* update material id buffer with BufferSubData */
6018 {
6019 const unsigned int data[] = {3, 2, 1, 0};
6020 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
6021 glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), data);
6022 }
6023
6024 /* update transform id buffer with BufferData */
6025 {
6026 const unsigned int data[] = {0, 1, 2, 3};
6027 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
6028 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
6029 }
6030
6031 glUseProgram(m_program);
6032 glDispatchCompute(4, 1, 1);
6033 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
6034 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6035 GLfloat *out_data2 =
6036 (GLfloat *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16 * 4 * 4 + 16 * 2 * 4, GL_MAP_READ_BIT);
6037 if (!out_data2)
6038 return ERROR;
6039
6040 GLfloat expected2[16 * 4 + 16 * 2] = {
6041 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
6042 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
6043 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
6044 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
6045 -0.9f, -0.9f, -0.1f, -0.9f, -0.9f, -0.1f, -0.1f, -0.1f, 0.1f, -0.9f, 0.9f, -0.9f, 0.1f, -0.1f, 0.9f, -0.1f,
6046 -0.9f, 0.1f, -0.1f, 0.1f, -0.9f, 0.9f, -0.1f, 0.9f, 0.1f, 0.1f, 0.9f, 0.1f, 0.1f, 0.9f, 0.9f, 0.9f};
6047 for (int i = 0; i < 16; ++i)
6048 {
6049 if (out_data2[i * 4 + 0] != expected2[i * 4 + 0] || out_data2[i * 4 + 1] != expected2[i * 4 + 1] ||
6050 out_data2[i * 4 + 2] != expected2[i * 4 + 2])
6051 {
6052 m_context.getTestContext().getLog()
6053 << tcu::TestLog::Message << "Received: " << out_data2[i * 4 + 0] << ", " << out_data2[i * 4 + 1]
6054 << ", " << out_data2[i * 4 + 2] << ", but expected: " << expected2[i * 4 + 0] << ", "
6055 << expected2[i * 4 + 1] << ", " << expected2[i * 4 + 2] << tcu::TestLog::EndMessage;
6056 status = false;
6057 }
6058 }
6059 for (int i = 32; i < 32 + 16; ++i)
6060 {
6061 if (fabs(out_data2[i * 2 + 0] - expected2[i * 2 + 0]) > 1e-6 ||
6062 fabs(out_data2[i * 2 + 1] - expected2[i * 2 + 1]) > 1e-6)
6063 {
6064 m_context.getTestContext().getLog()
6065 << tcu::TestLog::Message << "Received: " << out_data2[i * 2 + 0] << ", " << out_data2[i * 2 + 1]
6066 << ", but expected: " << expected2[i * 2 + 0] << ", " << expected2[i * 2 + 1]
6067 << tcu::TestLog::EndMessage;
6068 status = false;
6069 }
6070 }
6071
6072 if (status)
6073 return NO_ERROR;
6074 else
6075 return ERROR;
6076 }
6077
Cleanup()6078 virtual long Cleanup()
6079 {
6080 glUseProgram(0);
6081 glDeleteProgram(m_program);
6082 glDeleteBuffers(5, m_storage_buffer);
6083 return NO_ERROR;
6084 }
6085 };
6086
6087 //-----------------------------------------------------------------------------
6088 // 2.4.2 AdvancedIndirectAddressingCase2
6089 //-----------------------------------------------------------------------------
6090 class AdvancedIndirectAddressingCase2VSFS : public ShaderStorageBufferObjectBase
6091 {
6092 GLuint m_program;
6093 GLuint m_storage_buffer[8];
6094 GLuint m_vertex_array;
6095 GLuint m_vertex_buffer;
6096 GLuint m_fbo, m_rt;
6097
Setup()6098 virtual long Setup()
6099 {
6100 m_program = 0;
6101 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6102 m_vertex_array = 0;
6103 m_vertex_buffer = 0;
6104 glGenFramebuffers(1, &m_fbo);
6105 glGenTextures(1, &m_rt);
6106 return NO_ERROR;
6107 }
6108
Run()6109 virtual long Run()
6110 {
6111 if (!IsVSFSAvailable(4, 4))
6112 return NOT_SUPPORTED;
6113 GLint blocksC;
6114 glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &blocksC);
6115 if (blocksC < 8)
6116 return NOT_SUPPORTED;
6117 const char *const glsl_vs =
6118 NL "layout(location = 1) in vec2 g_in_position;" NL "layout(binding = 0, std430) buffer Transform {" NL
6119 " vec2 translation;" NL "} g_transform[4];" NL "uniform uint g_transform_id;" NL "void main() {" NL
6120 " vec2 translation = vec2(0);" NL " switch (g_transform_id) {" NL " case 0u:" NL
6121 " translation = g_transform[0].translation;" NL " break;" NL " case 1u:" NL
6122 " translation = g_transform[1].translation;" NL " break;" NL " case 2u:" NL
6123 " translation = g_transform[2].translation;" NL " break;" NL " case 3u:" NL
6124 " translation = g_transform[3].translation;" NL " break;" NL " }" NL
6125 " gl_Position = vec4(g_in_position + translation, 0, 1);" NL "}";
6126 const char *const glsl_fs = NL
6127 "layout(location = 0) out vec4 g_fs_out;" NL "layout(binding = 4, std430) buffer Material {" NL
6128 " vec3 color;" NL "} g_material[4];" NL "uniform int g_material_id;" NL "void main() {" NL
6129 " vec3 color = vec3(0);" NL " switch (g_material_id) {" NL " case 0:" NL
6130 " color = g_material[0].color;" NL " break;" NL " case 1:" NL " color = g_material[1].color;" NL
6131 " break;" NL " case 2:" NL " color = g_material[2].color;" NL " break;" NL " case 3:" NL
6132 " color = g_material[3].color;" NL " break;" NL " }" NL " g_fs_out = vec4(color, 1);" NL "}";
6133 m_program = CreateProgram(glsl_vs, glsl_fs);
6134 glLinkProgram(m_program);
6135 if (!CheckProgram(m_program))
6136 return ERROR;
6137
6138 glGenBuffers(8, m_storage_buffer);
6139
6140 /* transform buffers */
6141 {
6142 const float data[4][2] = {{-0.5f, -0.5f}, {0.5f, -0.5f}, {-0.5f, 0.5f}, {0.5f, 0.5f}};
6143 for (GLuint i = 0; i < 4; ++i)
6144 {
6145 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
6146 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data[i]), data[i], GL_DYNAMIC_DRAW);
6147 }
6148 }
6149 /* material buffers */
6150 {
6151 const float data[4][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f}};
6152 for (GLuint i = 0; i < 4; ++i)
6153 {
6154 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i + 4, m_storage_buffer[i + 4]);
6155 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data[i]), data[i], GL_DYNAMIC_DRAW);
6156 }
6157 }
6158
6159 /* vertex buffer */
6160 {
6161 const float data[] = {-0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.4f, 0.4f};
6162 glGenBuffers(1, &m_vertex_buffer);
6163 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6164 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6165 glBindBuffer(GL_ARRAY_BUFFER, 0);
6166 }
6167
6168 glBindTexture(GL_TEXTURE_2D, m_rt);
6169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6171 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
6172 glBindTexture(GL_TEXTURE_2D, 0);
6173 glViewport(0, 0, 100, 100);
6174 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
6175 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
6176
6177 glGenVertexArrays(1, &m_vertex_array);
6178 glBindVertexArray(m_vertex_array);
6179 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6180 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
6181 glBindBuffer(GL_ARRAY_BUFFER, 0);
6182 glEnableVertexAttribArray(1);
6183 glBindVertexArray(0);
6184
6185 glUseProgram(m_program);
6186 glBindVertexArray(m_vertex_array);
6187
6188 glClear(GL_COLOR_BUFFER_BIT);
6189 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 2);
6190 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 1);
6191 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6192 if (!ValidateWindow4Quads(vec3(0), vec3(0), vec3(0), vec3(0, 1, 0)))
6193 {
6194 return ERROR;
6195 }
6196
6197 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 0);
6198 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 2);
6199 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6200 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(0), vec3(0), vec3(0, 1, 0)))
6201 {
6202 return ERROR;
6203 }
6204
6205 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 1);
6206 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 3);
6207 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
6208 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(1, 1, 0), vec3(0), vec3(0, 1, 0)))
6209 {
6210 return ERROR;
6211 }
6212
6213 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 3);
6214 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 0);
6215 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6216 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(1, 1, 0), vec3(1, 0, 0), vec3(0, 1, 0)))
6217 {
6218 return ERROR;
6219 }
6220
6221 // once again with only one validation at the end
6222 glClear(GL_COLOR_BUFFER_BIT);
6223 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 2);
6224 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 1);
6225 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6226
6227 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 0);
6228 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 2);
6229 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6230
6231 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 1);
6232 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 3);
6233 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6234
6235 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 3);
6236 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 0);
6237 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[7]);
6238 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6239
6240 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(1, 1, 0), vec3(1, 1, 0), vec3(0, 1, 0)))
6241 {
6242 return ERROR;
6243 }
6244 return NO_ERROR;
6245 }
Cleanup()6246 virtual long Cleanup()
6247 {
6248 glViewport(0, 0, getWindowWidth(), getWindowHeight());
6249 glUseProgram(0);
6250 glDeleteProgram(m_program);
6251 glDeleteBuffers(8, m_storage_buffer);
6252 glDeleteBuffers(1, &m_vertex_buffer);
6253 glDeleteVertexArrays(1, &m_vertex_array);
6254 glDeleteFramebuffers(1, &m_fbo);
6255 glDeleteTextures(1, &m_rt);
6256 return NO_ERROR;
6257 }
6258 };
6259 class AdvancedIndirectAddressingCase2CS : public ShaderStorageBufferObjectBase
6260 {
6261 GLuint m_program;
6262 GLuint m_storage_buffer[5];
6263
Setup()6264 virtual long Setup()
6265 {
6266 m_program = 0;
6267 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6268 return NO_ERROR;
6269 }
6270
Run()6271 virtual long Run()
6272 {
6273 GLint blocksC;
6274 glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &blocksC);
6275 if (blocksC < 8)
6276 return NOT_SUPPORTED;
6277 bool status = true;
6278 const char *const glsl_cs =
6279 NL "layout(local_size_x = 4) in;" NL "layout(binding = 0, std430) buffer Material {" NL " vec3 color;" NL
6280 "} g_material[4];" NL "layout(binding = 4, std430) buffer OutputBuffer {" NL " vec3 color[4];" NL
6281 "};" NL "uniform int g_material_id;" NL "void main() {" NL
6282 " if (g_material_id == 0) color[gl_LocalInvocationIndex] = g_material[0].color;" NL
6283 " else if (g_material_id == 1) color[gl_LocalInvocationIndex] = g_material[1].color;" NL
6284 " else if (g_material_id == 2) color[gl_LocalInvocationIndex] = g_material[2].color;" NL
6285 " else if (g_material_id == 3) color[gl_LocalInvocationIndex] = g_material[3].color;" NL "}";
6286 m_program = CreateProgramCS(glsl_cs);
6287 glLinkProgram(m_program);
6288 if (!CheckProgram(m_program))
6289 return ERROR;
6290
6291 glGenBuffers(5, m_storage_buffer);
6292
6293 /* material buffers */
6294 const float data[4][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f}};
6295 for (GLuint i = 0; i < 4; ++i)
6296 {
6297 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
6298 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data[i]), data[i], GL_DYNAMIC_DRAW);
6299 }
6300
6301 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
6302 glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW);
6303
6304 glUseProgram(m_program);
6305 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 1);
6306 glDispatchCompute(1, 1, 1);
6307 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
6308 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6309 GLfloat *out_data = (GLfloat *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4 * 4, GL_MAP_READ_BIT);
6310 if (!out_data)
6311 return ERROR;
6312 const float *expected = &data[1][0];
6313 for (int i = 0; i < 4; ++i)
6314 {
6315 if (out_data[i * 4 + 0] != expected[0] || out_data[i * 4 + 1] != expected[1] ||
6316 out_data[i * 4 + 2] != expected[2])
6317 {
6318 m_context.getTestContext().getLog()
6319 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 0] << ", " << out_data[i * 4 + 1]
6320 << ", " << out_data[i * 4 + 2] << ", but expected: " << expected[0] << ", " << expected[1] << ", "
6321 << expected[2] << tcu::TestLog::EndMessage;
6322 status = false;
6323 }
6324 }
6325 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6326 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 3);
6327 glDispatchCompute(1, 1, 1);
6328 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6329 out_data = (GLfloat *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4 * 4, GL_MAP_READ_BIT);
6330 if (!out_data)
6331 return ERROR;
6332 expected = &data[3][0];
6333 for (int i = 0; i < 4; ++i)
6334 {
6335 if (out_data[i * 4 + 0] != expected[0] || out_data[i * 4 + 1] != expected[1] ||
6336 out_data[i * 4 + 2] != expected[2])
6337 {
6338 m_context.getTestContext().getLog()
6339 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 0] << ", " << out_data[i * 4 + 1]
6340 << ", " << out_data[i * 4 + 2] << ", but expected: " << expected[0] << ", " << expected[1] << ", "
6341 << expected[2] << tcu::TestLog::EndMessage;
6342 status = false;
6343 }
6344 }
6345
6346 if (!status)
6347 {
6348 return ERROR;
6349 }
6350 return NO_ERROR;
6351 }
6352
Cleanup()6353 virtual long Cleanup()
6354 {
6355 glUseProgram(0);
6356 glDeleteProgram(m_program);
6357 glDeleteBuffers(5, m_storage_buffer);
6358 return NO_ERROR;
6359 }
6360 };
6361 //-----------------------------------------------------------------------------
6362 // 2.5.1 AdvancedReadWriteCase1
6363 //-----------------------------------------------------------------------------
6364 class AdvancedReadWriteCase1VSFS : public ShaderStorageBufferObjectBase
6365 {
6366 GLuint m_program;
6367 GLuint m_storage_buffer;
6368 GLuint m_vertex_array;
6369 GLuint m_vertex_buffer;
6370
Setup()6371 virtual long Setup()
6372 {
6373 m_program = 0;
6374 m_storage_buffer = 0;
6375 m_vertex_array = 0;
6376 m_vertex_buffer = 0;
6377 return NO_ERROR;
6378 }
6379
Run()6380 virtual long Run()
6381 {
6382 if (!IsVSFSAvailable(1, 1))
6383 return NOT_SUPPORTED;
6384 const char *const glsl_vs = NL "layout(location = 0) in vec4 g_in_position;" NL "coherent buffer Buffer {" NL
6385 " vec4 in_color;" NL " vec4 out_color;" NL "} g_buffer;" NL "void main() {" NL
6386 " if (gl_VertexID == 0) {" NL " g_buffer.out_color = g_buffer.in_color;" NL
6387 " memoryBarrier();" NL " }" NL " gl_Position = g_in_position;" NL "}";
6388 const char *const glsl_fs =
6389 NL "layout(location = 0) out vec4 g_fs_out;" NL "coherent buffer Buffer {" NL " vec4 in_color;" NL
6390 " vec4 out_color;" NL "} g_buffer;" NL "void main() {" NL " g_fs_out = g_buffer.out_color;" NL "}";
6391 m_program = CreateProgram(glsl_vs, glsl_fs);
6392 glLinkProgram(m_program);
6393 if (!CheckProgram(m_program))
6394 return ERROR;
6395
6396 glGenBuffers(1, &m_storage_buffer);
6397 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
6398 glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * sizeof(float) * 4, NULL, GL_DYNAMIC_DRAW);
6399 float *ptr = reinterpret_cast<float *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_WRITE_BIT));
6400 if (!ptr)
6401 return ERROR;
6402 *ptr++ = 0.0f;
6403 *ptr++ = 1.0f;
6404 *ptr++ = 0.0f;
6405 *ptr++ = 1.0f;
6406 *ptr++ = 0.0f;
6407 *ptr++ = 0.0f;
6408 *ptr++ = 0.0f;
6409 *ptr++ = 0.0f;
6410 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6411
6412 /* vertex buffer */
6413 {
6414 const float data[] = {-1, -1, 1, -1, -1, 1, 1, 1};
6415 glGenBuffers(1, &m_vertex_buffer);
6416 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6417 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6418 glBindBuffer(GL_ARRAY_BUFFER, 0);
6419 }
6420
6421 glGenVertexArrays(1, &m_vertex_array);
6422 glBindVertexArray(m_vertex_array);
6423 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6424 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
6425 glBindBuffer(GL_ARRAY_BUFFER, 0);
6426 glEnableVertexAttribArray(0);
6427 glBindVertexArray(0);
6428
6429 glClear(GL_COLOR_BUFFER_BIT);
6430 glUseProgram(m_program);
6431 glBindVertexArray(m_vertex_array);
6432 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6433 if (!CheckFB(vec3(0, 1, 0)))
6434 {
6435 return ERROR;
6436 }
6437
6438 ptr = reinterpret_cast<float *>(
6439 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(float) * 4, GL_MAP_WRITE_BIT));
6440 if (!ptr)
6441 return ERROR;
6442 *ptr++ = 1.0f;
6443 *ptr++ = 0.0f;
6444 *ptr++ = 1.0f;
6445 *ptr++ = 1.0f;
6446 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6447
6448 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6449 if (!CheckFB(vec3(1, 0, 1)))
6450 {
6451 return ERROR;
6452 }
6453
6454 return NO_ERROR;
6455 }
Cleanup()6456 virtual long Cleanup()
6457 {
6458 glUseProgram(0);
6459 glDeleteProgram(m_program);
6460 glDeleteBuffers(1, &m_storage_buffer);
6461 glDeleteBuffers(1, &m_vertex_buffer);
6462 glDeleteVertexArrays(1, &m_vertex_array);
6463 return NO_ERROR;
6464 }
6465 };
6466
6467 class AdvancedReadWriteCase1CS : public ShaderStorageBufferObjectBase
6468 {
6469 GLuint m_program;
6470 GLuint m_storage_buffer;
6471
Setup()6472 virtual long Setup()
6473 {
6474 m_program = 0;
6475 m_storage_buffer = 0;
6476 return NO_ERROR;
6477 }
Run()6478 virtual long Run()
6479 {
6480 bool status = true;
6481 const char *const glsl_cs = NL
6482 "layout(local_size_x = 128) in;" NL "struct s {" NL " int ene;" NL " int due;" NL " int like;" NL
6483 " int fake;" NL "};" NL "layout(std430) coherent buffer Buffer {" NL " s a[128];" NL "} g_buffer;" NL
6484 "void main() {" NL " g_buffer.a[gl_LocalInvocationIndex].due = g_buffer.a[gl_LocalInvocationIndex].ene;" NL
6485 " groupMemoryBarrier();" NL " barrier();" NL " g_buffer.a[(gl_LocalInvocationIndex + 1u) % 128u].like = "
6486 "g_buffer.a[(gl_LocalInvocationIndex + 1u) % 128u].due;" NL " groupMemoryBarrier();" NL " barrier();" NL
6487 " g_buffer.a[(gl_LocalInvocationIndex + 17u) % 128u].fake "
6488 "= g_buffer.a[(gl_LocalInvocationIndex + 17u) % "
6489 "128u].like;" NL "}";
6490 m_program = CreateProgramCS(glsl_cs);
6491 glLinkProgram(m_program);
6492 if (!CheckProgram(m_program))
6493 return ERROR;
6494
6495 glGenBuffers(1, &m_storage_buffer);
6496 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
6497 GLint data[128 * 4];
6498 for (int i = 0; i < 128; ++i)
6499 {
6500 data[i * 4] = i + 256;
6501 data[i * 4 + 1] = 0;
6502 data[i * 4 + 2] = 0;
6503 data[i * 4 + 3] = 0;
6504 }
6505 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data[0], GL_DYNAMIC_DRAW);
6506
6507 glUseProgram(m_program);
6508 glDispatchCompute(1, 1, 1);
6509 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6510 GLint *out_data = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), GL_MAP_READ_BIT);
6511 if (!out_data)
6512 return ERROR;
6513 for (int i = 0; i < 128; ++i)
6514 {
6515 if (out_data[i * 4 + 3] != data[i * 4])
6516 {
6517 m_context.getTestContext().getLog()
6518 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 3] << ", but expected: " << data[i * 4]
6519 << " -> " << out_data[i * 4 + 1] << " -> " << out_data[i * 4 + 2] << tcu::TestLog::EndMessage;
6520 status = false;
6521 }
6522 }
6523 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6524 for (int i = 0; i < 128; ++i)
6525 {
6526 data[i * 4] = i + 512;
6527 data[i * 4 + 1] = 0;
6528 data[i * 4 + 2] = 0;
6529 data[i * 4 + 3] = 0;
6530 }
6531 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data[0], GL_DYNAMIC_DRAW);
6532
6533 glDispatchCompute(1, 1, 1);
6534 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6535 out_data = (GLint *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), GL_MAP_READ_BIT);
6536 if (!out_data)
6537 return ERROR;
6538 for (int i = 0; i < 128; ++i)
6539 {
6540 if (out_data[i * 4 + 3] != data[i * 4])
6541 {
6542 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 3]
6543 << ", but expected: " << data[i * 4] << tcu::TestLog::EndMessage;
6544 status = false;
6545 }
6546 }
6547 if (status)
6548 return NO_ERROR;
6549 else
6550 return ERROR;
6551 }
6552
Cleanup()6553 virtual long Cleanup()
6554 {
6555 glUseProgram(0);
6556 glDeleteProgram(m_program);
6557 glDeleteBuffers(1, &m_storage_buffer);
6558 return NO_ERROR;
6559 }
6560 };
6561 //-----------------------------------------------------------------------------
6562 // 2.6.1 AdvancedUsageCase1
6563 //-----------------------------------------------------------------------------
6564 class AdvancedUsageCase1 : public ShaderStorageBufferObjectBase
6565 {
6566 GLuint m_program;
6567 GLuint m_storage_buffer[3];
6568 GLuint m_vertex_array;
6569 GLuint m_vertex_buffer;
6570 GLuint m_fbo, m_rt;
6571
Setup()6572 virtual long Setup()
6573 {
6574 m_program = 0;
6575 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6576 m_vertex_array = 0;
6577 m_vertex_buffer = 0;
6578 glGenFramebuffers(1, &m_fbo);
6579 glGenTextures(1, &m_rt);
6580 return NO_ERROR;
6581 }
Run()6582 virtual long Run()
6583 {
6584 using namespace tcu;
6585
6586 if (!IsVSFSAvailable(2, 2))
6587 return NOT_SUPPORTED;
6588 const char *const glsl_vs =
6589 NL "layout(location = 0) in vec4 g_position;" NL "layout(location = 1) in int g_object_id;" NL
6590 "flat out int object_id;" NL "layout(binding = 0) buffer TransformBuffer {" NL
6591 " mat4 g_transform[4];" NL "};" NL "void main() {" NL " mat4 mvp = g_transform[g_object_id];" NL
6592 " gl_Position = mvp * g_position;" NL " object_id = g_object_id;" NL "}";
6593 const char *const glsl_fs =
6594 NL "flat in int object_id;" NL "layout(location = 0) out vec4 g_fs_out;" NL "struct Material {" NL
6595 " vec3 color;" NL "};" NL "layout(binding = 1, std430) buffer MaterialBuffer {" NL
6596 " Material g_material[4];" NL "};" NL "layout(binding = 2, std430) buffer MaterialIDBuffer {" NL
6597 " int g_material_id[4];" NL "};" NL "void main() {" NL " int mid = g_material_id[object_id];" NL
6598 " Material m = g_material[mid];" NL " g_fs_out = vec4(m.color, 1);" NL "}";
6599 m_program = CreateProgram(glsl_vs, glsl_fs);
6600 glLinkProgram(m_program);
6601 if (!CheckProgram(m_program))
6602 return ERROR;
6603
6604 glGenBuffers(3, m_storage_buffer);
6605
6606 /* transform buffer */
6607 {
6608 mat4 data[] = {transpose(Translation(-0.5f, -0.5f, 0.0f)), transpose(Translation(0.5f, -0.5f, 0.0f)),
6609 transpose(Translation(-0.5f, 0.5f, 0.0f)), transpose(Translation(0.5f, 0.5f, 0.0f))};
6610 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
6611 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6612 }
6613 /* material buffer */
6614 {
6615 vec4 data[] = {vec4(1, 0, 0, 1), vec4(0, 1, 0, 1), vec4(0, 0, 1, 0), vec4(1, 1, 0, 1)};
6616 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
6617 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6618 }
6619 /* material id buffer */
6620 {
6621 int data[] = {0, 1, 2, 3};
6622 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
6623 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6624 }
6625 /* vertex buffer */
6626 {
6627 struct
6628 {
6629 vec2 position;
6630 int object_id;
6631 } data[] = {{vec2(-0.4f, -0.4f), 0}, {vec2(0.4f, -0.4f), 0}, {vec2(-0.4f, 0.4f), 0}, {vec2(0.4f, 0.4f), 0},
6632 {vec2(-0.4f, -0.4f), 1}, {vec2(0.4f, -0.4f), 1}, {vec2(-0.4f, 0.4f), 1}, {vec2(0.4f, 0.4f), 1},
6633 {vec2(-0.4f, -0.4f), 2}, {vec2(0.4f, -0.4f), 2}, {vec2(-0.4f, 0.4f), 2}, {vec2(0.4f, 0.4f), 2},
6634 {vec2(-0.4f, -0.4f), 3}, {vec2(0.4f, -0.4f), 3}, {vec2(-0.4f, 0.4f), 3}, {vec2(0.4f, 0.4f), 3}};
6635 glGenBuffers(1, &m_vertex_buffer);
6636 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6637 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6638 glBindBuffer(GL_ARRAY_BUFFER, 0);
6639 }
6640
6641 glBindTexture(GL_TEXTURE_2D, m_rt);
6642 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6643 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6644 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
6645 glBindTexture(GL_TEXTURE_2D, 0);
6646 glViewport(0, 0, 100, 100);
6647 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
6648 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
6649
6650 glGenVertexArrays(1, &m_vertex_array);
6651 glBindVertexArray(m_vertex_array);
6652 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6653 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vec2) + sizeof(int), 0);
6654 glVertexAttribIPointer(1, 1, GL_INT, sizeof(vec2) + sizeof(int), reinterpret_cast<void *>(sizeof(vec2)));
6655 glBindBuffer(GL_ARRAY_BUFFER, 0);
6656 glEnableVertexAttribArray(0);
6657 glEnableVertexAttribArray(1);
6658 glBindVertexArray(0);
6659
6660 glClear(GL_COLOR_BUFFER_BIT);
6661 glUseProgram(m_program);
6662 glBindVertexArray(m_vertex_array);
6663 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6664 glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
6665 glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
6666 glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
6667 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
6668 {
6669 return ERROR;
6670 }
6671 return NO_ERROR;
6672 }
6673
Cleanup()6674 virtual long Cleanup()
6675 {
6676 glViewport(0, 0, getWindowWidth(), getWindowHeight());
6677 glUseProgram(0);
6678 glDeleteProgram(m_program);
6679 glDeleteBuffers(3, m_storage_buffer);
6680 glDeleteBuffers(1, &m_vertex_buffer);
6681 glDeleteVertexArrays(1, &m_vertex_array);
6682 glDeleteFramebuffers(1, &m_fbo);
6683 glDeleteTextures(1, &m_rt);
6684 return NO_ERROR;
6685 }
6686 };
6687 //-----------------------------------------------------------------------------
6688 // 2.6.2 AdvancedUsageSync
6689 //-----------------------------------------------------------------------------
6690 class AdvancedUsageSyncVSFS : public ShaderStorageBufferObjectBase
6691 {
6692 GLuint m_program;
6693 GLuint m_storage_buffer[7];
6694 GLuint m_vertex_array;
6695
Setup()6696 virtual long Setup()
6697 {
6698 m_program = 0;
6699 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6700 m_vertex_array = 0;
6701 return NO_ERROR;
6702 }
Run()6703 virtual long Run()
6704 {
6705 if (!IsVSFSAvailable(3, 4))
6706 return NOT_SUPPORTED;
6707 const char *const glsl_vs = NL
6708 "layout(std430, binding = 0) coherent buffer Buffer0 {" NL " int g_data0, g_inc0;" NL
6709 " int g_data1, g_inc1;" NL "};" NL "layout(std430, binding = 1) buffer Buffer12 {" NL " int inc, data;" NL
6710 "} g_buffer12[2];" NL "flat out int primitive_id;" NL NL "void Modify(int path) {" NL
6711 " if (path == 0) {" NL " atomicAdd(g_data0, g_inc0);" NL " atomicAdd(g_data1, g_inc0);" NL
6712 " } else if (path == 1) {" NL " atomicAdd(g_data0, - g_inc0);" NL " atomicAdd(g_data1, - g_inc0);" NL
6713 " } else if (path == 2) {" NL " atomicAdd(g_data0, g_inc1);" NL " atomicAdd(g_data1, g_inc1);" NL
6714 " }" NL NL " if (path == 0) {" NL " g_buffer12[0].data += g_buffer12[1].inc;" NL
6715 " } else if (path == 1) {" NL " g_buffer12[1].data += g_buffer12[0].inc;" NL " }" NL "}" NL NL
6716 "void main() {" NL " Modify(gl_VertexID);" NL " primitive_id = gl_VertexID;" NL
6717 " gl_Position = vec4(0, 0, 0, 1);" NL "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL "}";
6718 const char *glsl_fs =
6719 NL "layout(binding = 3, std430) coherent buffer Buffer3 {" NL " int data;" NL "} g_buffer3;" NL
6720 "layout(std430, binding = 4) coherent buffer Buffer4 {" NL " int data0, inc0;" NL
6721 " int data1, inc1;" NL "} g_buffer4;" NL "layout(std430, binding = 5) buffer Buffer56 {" NL
6722 " int inc, data;" NL "} g_buffer56[2];" NL "flat in int primitive_id;" NL NL
6723 "void ModifyFS(int path) {" NL " if (path == 0) {" NL
6724 " atomicAdd(g_buffer4.data0, g_buffer4.inc0);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc0);" NL
6725 " } else if (path == 1) {" NL " atomicAdd(g_buffer4.data0, - g_buffer4.inc0);" NL
6726 " atomicAdd(g_buffer4.data1, - g_buffer4.inc0);" NL " } else if (path == 2) {" NL
6727 " atomicAdd(g_buffer4.data0, g_buffer4.inc1);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc1);" NL
6728 " }" NL NL " if (path == 0) {" NL " g_buffer56[0].data += g_buffer56[1].inc;" NL
6729 " } else if (path == 1) {" NL " g_buffer56[1].data += g_buffer56[0].inc;" NL " }" NL "}" NL
6730 "void main() {" NL " atomicAdd(g_buffer3.data, 1);" NL " ModifyFS(primitive_id);" NL "}";
6731 m_program = CreateProgram(glsl_vs, glsl_fs);
6732 glLinkProgram(m_program);
6733 if (!CheckProgram(m_program))
6734 return ERROR;
6735
6736 glGenVertexArrays(1, &m_vertex_array);
6737 glGenBuffers(7, m_storage_buffer);
6738
6739 /* Buffer0 */
6740 {
6741 int data[4] = {0, 1, 0, 2};
6742 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
6743 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6744 }
6745 /* Buffer1 */
6746 {
6747 int data[2] = {3, 1};
6748 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
6749 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6750 }
6751 /* Buffer2 */
6752 {
6753 int data[2] = {2, 4};
6754 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
6755 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6756 }
6757 /* Buffer3 */
6758 {
6759 int data[1] = {0};
6760 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
6761 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6762 }
6763 /* Buffer4 */
6764 {
6765 int data[4] = {0, 1, 0, 2};
6766 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
6767 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6768 }
6769 /* Buffer5 */
6770 {
6771 int data[2] = {3, 1};
6772 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, m_storage_buffer[5]);
6773 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6774 }
6775 /* Buffer6 */
6776 {
6777 int data[2] = {2, 4};
6778 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, m_storage_buffer[6]);
6779 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6780 }
6781
6782 glUseProgram(m_program);
6783 glBindVertexArray(m_vertex_array);
6784
6785 glDrawArrays(GL_POINTS, 0, 3);
6786 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
6787 glDrawArrays(GL_POINTS, 0, 3);
6788 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6789
6790 /* Buffer0 */
6791 {
6792 const int ref_data[4] = {4, 1, 4, 2};
6793 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
6794 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
6795 if (!data)
6796 return ERROR;
6797 for (int i = 0; i < 4; ++i)
6798 {
6799 if (data[i] != ref_data[i])
6800 {
6801 m_context.getTestContext().getLog()
6802 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
6803 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6804 return ERROR;
6805 }
6806 }
6807 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6808 }
6809 /* Buffer1 */
6810 {
6811 const int ref_data[2] = {3, 5};
6812 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
6813 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6814 if (!data)
6815 return ERROR;
6816 for (int i = 0; i < 2; ++i)
6817 {
6818 if (data[i] != ref_data[i])
6819 {
6820 m_context.getTestContext().getLog()
6821 << tcu::TestLog::Message << "[Buffer1] Data at index " << i << " is " << data[i]
6822 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6823 return ERROR;
6824 }
6825 }
6826 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6827 }
6828 /* Buffer2 */
6829 {
6830 const int ref_data[2] = {2, 10};
6831 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
6832 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6833 if (!data)
6834 return ERROR;
6835 for (int i = 0; i < 2; ++i)
6836 {
6837 if (data[i] != ref_data[i])
6838 {
6839 m_context.getTestContext().getLog()
6840 << tcu::TestLog::Message << "[Buffer2] Data at index " << i << " is " << data[i]
6841 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6842 return ERROR;
6843 }
6844 }
6845 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6846 }
6847 /* Buffer3 */
6848 {
6849 const int ref_data[1] = {6};
6850 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
6851 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
6852 if (!data)
6853 return ERROR;
6854 for (int i = 0; i < 1; ++i)
6855 {
6856 if (data[i] != ref_data[i])
6857 {
6858 m_context.getTestContext().getLog()
6859 << tcu::TestLog::Message << "[Buffer3] Data at index " << i << " is " << data[i]
6860 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6861 return ERROR;
6862 }
6863 }
6864 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6865 }
6866 /* Buffer4 */
6867 {
6868 const int ref_data[4] = {4, 1, 4, 2};
6869 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
6870 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
6871 if (!data)
6872 return ERROR;
6873 for (int i = 0; i < 4; ++i)
6874 {
6875 if (data[i] != ref_data[i])
6876 {
6877 m_context.getTestContext().getLog()
6878 << tcu::TestLog::Message << "[Buffer4] Data at index " << i << " is " << data[i]
6879 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6880 return ERROR;
6881 }
6882 }
6883 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6884 }
6885 /* Buffer5 */
6886 {
6887 const int ref_data[2] = {3, 5};
6888 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
6889 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6890 if (!data)
6891 return ERROR;
6892 for (int i = 0; i < 2; ++i)
6893 {
6894 if (data[i] != ref_data[i])
6895 {
6896 m_context.getTestContext().getLog()
6897 << tcu::TestLog::Message << "[Buffer5] Data at index " << i << " is " << data[i]
6898 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6899 return ERROR;
6900 }
6901 }
6902 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6903 }
6904 /* Buffer6 */
6905 {
6906 const int ref_data[2] = {2, 10};
6907 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[6]);
6908 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6909 if (!data)
6910 return ERROR;
6911 for (int i = 0; i < 2; ++i)
6912 {
6913 if (data[i] != ref_data[i])
6914 {
6915 m_context.getTestContext().getLog()
6916 << tcu::TestLog::Message << "[Buffer6] Data at index " << i << " is " << data[i]
6917 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6918 return ERROR;
6919 }
6920 }
6921 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6922 }
6923
6924 return NO_ERROR;
6925 }
6926
Cleanup()6927 virtual long Cleanup()
6928 {
6929 glUseProgram(0);
6930 glDeleteProgram(m_program);
6931 glDeleteBuffers(7, m_storage_buffer);
6932 glDeleteVertexArrays(1, &m_vertex_array);
6933 return NO_ERROR;
6934 }
6935 };
6936
6937 class AdvancedUsageSyncCS : public ShaderStorageBufferObjectBase
6938 {
6939 GLuint m_program;
6940 GLuint m_storage_buffer[7];
6941
Setup()6942 virtual long Setup()
6943 {
6944 m_program = 0;
6945 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6946 return NO_ERROR;
6947 }
6948
Run()6949 virtual long Run()
6950 {
6951 const char *const glsl_cs =
6952 NL "layout(local_size_x = 1) in;" NL "layout(std430, binding = 0) coherent buffer Buffer0 {" NL
6953 " int g_data0, g_inc0;" NL " int g_data1, g_inc1;" NL "};" NL
6954 "layout(std430, binding = 1) buffer Buffer12 {" NL " int inc, data;" NL "} g_buffer12[2];" NL
6955 "layout(binding = 3, std430) coherent buffer Buffer3 {" NL " int data;" NL "} g_buffer3;" NL
6956 "layout(std430, binding = 4) coherent buffer Buffer4 {" NL " int data0, inc0;" NL
6957 " int data1, inc1;" NL "} g_buffer4;" NL "layout(std430, binding = 5) buffer Buffer56 {" NL
6958 " int inc, data;" NL "} g_buffer56[2];" NL NL "void Modify1(int path) {" NL " if (path == 0) {" NL
6959 " atomicAdd(g_data0, g_inc0);" NL " atomicAdd(g_data1, g_inc0);" NL " } else if (path == 1) {" NL
6960 " atomicAdd(g_data0, - g_inc0);" NL " atomicAdd(g_data1, - g_inc0);" NL
6961 " } else if (path == 2) {" NL " atomicAdd(g_data0, g_inc1);" NL " atomicAdd(g_data1, g_inc1);" NL
6962 " }" NL " if (path == 0) {" NL " g_buffer12[0].data += g_buffer12[1].inc;" NL
6963 " } else if (path == 1) {" NL " g_buffer12[1].data += g_buffer12[0].inc;" NL " }" NL "}" NL NL
6964 "void Modify2(int path) {" NL " if (path == 0) {" NL
6965 " atomicAdd(g_buffer4.data0, g_buffer4.inc0);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc0);" NL
6966 " } else if (path == 1) {" NL " atomicAdd(g_buffer4.data0, - g_buffer4.inc0);" NL
6967 " atomicAdd(g_buffer4.data1, - g_buffer4.inc0);" NL " } else if (path == 2) {" NL
6968 " atomicAdd(g_buffer4.data0, g_buffer4.inc1);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc1);" NL
6969 " }" NL " if (path == 0) {" NL " g_buffer56[0].data += g_buffer56[1].inc;" NL
6970 " } else if (path == 1) {" NL " g_buffer56[1].data += g_buffer56[0].inc;" NL " }" NL "}" NL NL
6971 "void main() {" NL " Modify1(int(gl_WorkGroupID.z));" NL " atomicAdd(g_buffer3.data, 1);" NL
6972 " Modify2(int(gl_WorkGroupID.z));" NL "}";
6973 m_program = CreateProgramCS(glsl_cs);
6974 glLinkProgram(m_program);
6975 if (!CheckProgram(m_program))
6976 return ERROR;
6977
6978 glGenBuffers(7, m_storage_buffer);
6979
6980 /* Buffer0 */
6981 {
6982 int data[4] = {0, 1, 0, 2};
6983 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
6984 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6985 }
6986 /* Buffer1 */
6987 {
6988 int data[2] = {3, 1};
6989 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
6990 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6991 }
6992 /* Buffer2 */
6993 {
6994 int data[2] = {2, 4};
6995 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
6996 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6997 }
6998 /* Buffer3 */
6999 {
7000 int data[1] = {0};
7001 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
7002 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7003 }
7004 /* Buffer4 */
7005 {
7006 int data[4] = {0, 1, 0, 2};
7007 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
7008 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7009 }
7010 /* Buffer5 */
7011 {
7012 int data[2] = {3, 1};
7013 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, m_storage_buffer[5]);
7014 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7015 }
7016 /* Buffer6 */
7017 {
7018 int data[2] = {2, 4};
7019 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, m_storage_buffer[6]);
7020 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7021 }
7022
7023 glUseProgram(m_program);
7024
7025 glDispatchCompute(1, 1, 3);
7026 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
7027 glDispatchCompute(1, 1, 3);
7028
7029 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7030
7031 /* Buffer0 */
7032 {
7033 const int ref_data[4] = {4, 1, 4, 2};
7034 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
7035 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7036 if (!data)
7037 return ERROR;
7038 for (int i = 0; i < 2; ++i)
7039 {
7040 /* g_data incremented in VS which can be invoked multiple times per vertex */
7041 if (data[2 * i] < ref_data[2 * i])
7042 {
7043 m_context.getTestContext().getLog()
7044 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7045 << " should be at least" << ref_data[i] << tcu::TestLog::EndMessage;
7046 return ERROR;
7047 }
7048 /* g_inc */
7049 if (data[2 * i + 1] != ref_data[2 * i + 1])
7050 {
7051 m_context.getTestContext().getLog()
7052 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7053 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7054 return ERROR;
7055 }
7056 }
7057 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7058 }
7059 /* Buffer1 */
7060 {
7061 const int ref_data[2] = {3, 5};
7062 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
7063 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7064 if (!data)
7065 return ERROR;
7066 /* inc */
7067 if (data[0] != ref_data[0])
7068 {
7069 m_context.getTestContext().getLog()
7070 << tcu::TestLog::Message << "[Buffer1] Data at index 0 is " << data[0] << " should be "
7071 << ref_data[0] << tcu::TestLog::EndMessage;
7072 return ERROR;
7073 }
7074 /* data incremented in VS which can be invoked multiple times per vertex */
7075 if (data[1] < ref_data[1])
7076 {
7077 m_context.getTestContext().getLog()
7078 << tcu::TestLog::Message << "[Buffer1] Data at index 1 is " << data[1] << " should be at least"
7079 << ref_data[1] << tcu::TestLog::EndMessage;
7080 return ERROR;
7081 }
7082 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7083 }
7084 /* Buffer2 */
7085 {
7086 const int ref_data[2] = {2, 10};
7087 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
7088 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7089 if (!data)
7090 return ERROR;
7091 /* inc */
7092 if (data[0] != ref_data[0])
7093 {
7094 m_context.getTestContext().getLog()
7095 << tcu::TestLog::Message << "[Buffer2] Data at index 0 is " << data[0] << " should be "
7096 << ref_data[0] << tcu::TestLog::EndMessage;
7097 return ERROR;
7098 }
7099 /* data incremented in VS which can be invoked multiple times per vertex */
7100 if (data[1] < ref_data[1])
7101 {
7102 m_context.getTestContext().getLog()
7103 << tcu::TestLog::Message << "[Buffer2] Data at index 1 is " << data[1] << " should be at least"
7104 << ref_data[1] << tcu::TestLog::EndMessage;
7105 return ERROR;
7106 }
7107 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7108 }
7109 /* Buffer3 */
7110 {
7111 const int ref_data[1] = {6};
7112 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
7113 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
7114 if (!data)
7115 return ERROR;
7116 for (int i = 0; i < 1; ++i)
7117 {
7118 if (data[i] != ref_data[i])
7119 {
7120 m_context.getTestContext().getLog()
7121 << tcu::TestLog::Message << "[Buffer3] Data at index " << i << " is " << data[i]
7122 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7123 return ERROR;
7124 }
7125 }
7126 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7127 }
7128 /* Buffer4 */
7129 {
7130 const int ref_data[4] = {4, 1, 4, 2};
7131 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
7132 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7133 if (!data)
7134 return ERROR;
7135 for (int i = 0; i < 4; ++i)
7136 {
7137 if (data[i] != ref_data[i])
7138 {
7139 m_context.getTestContext().getLog()
7140 << tcu::TestLog::Message << "[Buffer4] Data at index " << i << " is " << data[i]
7141 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7142 return ERROR;
7143 }
7144 }
7145 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7146 }
7147 /* Buffer5 */
7148 {
7149 const int ref_data[2] = {3, 5};
7150 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
7151 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7152 if (!data)
7153 return ERROR;
7154 for (int i = 0; i < 2; ++i)
7155 {
7156 if (data[i] != ref_data[i])
7157 {
7158 m_context.getTestContext().getLog()
7159 << tcu::TestLog::Message << "[Buffer5] Data at index " << i << " is " << data[i]
7160 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7161 return ERROR;
7162 }
7163 }
7164 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7165 }
7166 /* Buffer6 */
7167 {
7168 const int ref_data[2] = {2, 10};
7169 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[6]);
7170 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7171 if (!data)
7172 return ERROR;
7173 for (int i = 0; i < 2; ++i)
7174 {
7175 if (data[i] != ref_data[i])
7176 {
7177 m_context.getTestContext().getLog()
7178 << tcu::TestLog::Message << "[Buffer6] Data at index " << i << " is " << data[i]
7179 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7180 return ERROR;
7181 }
7182 }
7183 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7184 }
7185
7186 return NO_ERROR;
7187 }
7188
Cleanup()7189 virtual long Cleanup()
7190 {
7191 glUseProgram(0);
7192 glDeleteProgram(m_program);
7193 glDeleteBuffers(7, m_storage_buffer);
7194 return NO_ERROR;
7195 }
7196 };
7197 //-----------------------------------------------------------------------------
7198 // 2.6.3 AdvancedUsageOperators
7199 //-----------------------------------------------------------------------------
7200 class AdvancedUsageOperatorsVS : public ShaderStorageBufferObjectBase
7201 {
7202 GLuint m_program;
7203 GLuint m_storage_buffer[2];
7204 GLuint m_vertex_array;
7205
Setup()7206 virtual long Setup()
7207 {
7208 m_program = 0;
7209 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7210 m_vertex_array = 0;
7211 return NO_ERROR;
7212 }
7213
Run()7214 virtual long Run()
7215 {
7216 if (!IsVSFSAvailable(2, 0))
7217 return NOT_SUPPORTED;
7218 const char *const glsl_vs =
7219 NL "layout(std430, binding = 0) buffer Buffer0 {" NL " readonly int g_i0;" NL " int g_o0;" NL "};" NL
7220 "layout(std430, binding = 1) buffer Buffer1 {" NL " int i0;" NL "} g_buffer1;" NL
7221 "const int g_values[6] = int[](1, 2, 3, 4, 5, 6);" NL "void main() {" NL " g_o0 += g_i0;" NL
7222 " g_o0 <<= 1;" NL " g_o0 = g_i0 > g_o0 ? g_i0 : g_o0;" NL " g_o0 *= g_i0;" NL
7223 " g_o0 = --g_o0 + g_values[g_i0];" NL " g_o0++;" NL " ++g_o0;" NL " g_buffer1.i0 = 0xff2f;" NL
7224 " g_o0 &= g_buffer1.i0;" NL "}";
7225 const char *const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
7226 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
7227
7228 m_program = CreateProgram(glsl_vs, glsl_fs);
7229 glLinkProgram(m_program);
7230 if (!CheckProgram(m_program))
7231 return ERROR;
7232
7233 glGenVertexArrays(1, &m_vertex_array);
7234 glGenBuffers(2, m_storage_buffer);
7235
7236 /* Buffer0 */
7237 {
7238 int data[4] = {3, 5};
7239 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
7240 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7241 }
7242 /* Buffer1 */
7243 {
7244 int data[1] = {0};
7245 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
7246 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7247 }
7248
7249 glEnable(GL_RASTERIZER_DISCARD);
7250 glUseProgram(m_program);
7251 glBindVertexArray(m_vertex_array);
7252 glDrawArrays(GL_POINTS, 0, 1);
7253 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7254
7255 /* Buffer0 */
7256 {
7257 const int ref_data[2] = {3, 37};
7258 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
7259 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7260 if (!data)
7261 return ERROR;
7262 for (int i = 0; i < 2; ++i)
7263 {
7264 if (data[i] != ref_data[i])
7265 {
7266 m_context.getTestContext().getLog()
7267 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7268 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7269 return ERROR;
7270 }
7271 }
7272 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7273 }
7274 /* Buffer0 */
7275 {
7276 const int ref_data[1] = {0xff2f};
7277 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
7278 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
7279 if (!data)
7280 return ERROR;
7281 for (int i = 0; i < 1; ++i)
7282 {
7283 if (data[i] != ref_data[i])
7284 {
7285 m_context.getTestContext().getLog()
7286 << tcu::TestLog::Message << "[Buffer1] Data at index " << i << " is " << data[i]
7287 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7288 return ERROR;
7289 }
7290 }
7291 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7292 }
7293
7294 return NO_ERROR;
7295 }
7296
Cleanup()7297 virtual long Cleanup()
7298 {
7299 glDisable(GL_RASTERIZER_DISCARD);
7300 glUseProgram(0);
7301 glDeleteProgram(m_program);
7302 glDeleteBuffers(2, m_storage_buffer);
7303 glDeleteVertexArrays(1, &m_vertex_array);
7304 return NO_ERROR;
7305 }
7306 };
7307
7308 class AdvancedUsageOperatorsCS : public ShaderStorageBufferObjectBase
7309 {
7310 GLuint m_program;
7311 GLuint m_storage_buffer[2];
7312
Setup()7313 virtual long Setup()
7314 {
7315 m_program = 0;
7316 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7317 return NO_ERROR;
7318 }
Run()7319 virtual long Run()
7320 {
7321 const char *const glsl_cs =
7322 NL "layout(local_size_x = 1) in;" NL "layout(std430, binding = 0) buffer Buffer0 {" NL
7323 " readonly int g_i0;" NL " int g_o0;" NL "};" NL "layout(std430, binding = 1) buffer Buffer1 {" NL
7324 " int i0;" NL "} g_buffer1;" NL "const int g_values[6] = int[](1, 2, 3, 4, 5, 6);" NL "void main() {" NL
7325 " g_o0 += g_i0;" NL " g_o0 <<= 1;" NL " g_o0 = g_i0 > g_o0 ? g_i0 : g_o0;" NL " g_o0 *= g_i0;" NL
7326 " g_o0 = --g_o0 + g_values[g_i0];" NL " g_o0++;" NL " ++g_o0;" NL " g_buffer1.i0 = 0xff2f;" NL
7327 " g_o0 &= g_buffer1.i0;" NL "}";
7328
7329 m_program = CreateProgramCS(glsl_cs);
7330 glLinkProgram(m_program);
7331 if (!CheckProgram(m_program))
7332 return ERROR;
7333
7334 glGenBuffers(2, m_storage_buffer);
7335
7336 /* Buffer0 */
7337 {
7338 int data[4] = {3, 5};
7339 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
7340 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7341 }
7342 /* Buffer1 */
7343 {
7344 int data[1] = {0};
7345 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
7346 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7347 }
7348
7349 glUseProgram(m_program);
7350 glDispatchCompute(1, 1, 1);
7351 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7352
7353 /* Buffer0 */
7354 {
7355 const int ref_data[2] = {3, 37};
7356 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
7357 int *data = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7358 if (!data)
7359 return ERROR;
7360 for (int i = 0; i < 2; ++i)
7361 {
7362 if (data[i] != ref_data[i])
7363 {
7364 m_context.getTestContext().getLog()
7365 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7366 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7367 return ERROR;
7368 }
7369 }
7370 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7371 }
7372
7373 return NO_ERROR;
7374 }
7375
Cleanup()7376 virtual long Cleanup()
7377 {
7378 glUseProgram(0);
7379 glDeleteProgram(m_program);
7380 glDeleteBuffers(2, m_storage_buffer);
7381 return NO_ERROR;
7382 }
7383 };
7384
7385 //-----------------------------------------------------------------------------
7386 // 2.7 AdvancedUnsizedArrayLength
7387 //-----------------------------------------------------------------------------
7388 template <int stage>
7389 class AdvancedUnsizedArrayLength : public ShaderStorageBufferObjectBase
7390 {
7391 GLuint m_program;
7392 GLuint m_storage_buffer[4];
7393 GLuint m_vertex_array;
7394
Setup()7395 virtual long Setup()
7396 {
7397 m_program = 0;
7398 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7399 m_vertex_array = 0;
7400 return NO_ERROR;
7401 }
Cleanup()7402 virtual long Cleanup()
7403 {
7404 glUseProgram(0);
7405 glDeleteProgram(m_program);
7406 glDeleteBuffers(4, m_storage_buffer);
7407 if (stage != compute)
7408 glDeleteVertexArrays(1, &m_vertex_array);
7409 return NO_ERROR;
7410 }
BuildShaderPT(int st)7411 std::string BuildShaderPT(int st)
7412 {
7413 std::ostringstream os;
7414 if (st == vertex)
7415 {
7416 os << NL "void main() {" NL " gl_Position = vec4(0,0,0,1);" NL "#ifdef GL_ES" NL
7417 " gl_PointSize = 1.0f;" NL "#endif";
7418 }
7419 if (st == fragment)
7420 {
7421 os << NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
7422 " o_color = vec4(0.0, 1.0, 0.0, 1.0);";
7423 }
7424 os << NL "}";
7425 return os.str();
7426 }
BuildShader()7427 std::string BuildShader()
7428 {
7429 std::ostringstream os;
7430 std::string decl =
7431 NL "layout(std430, binding = 0) readonly buffer Input0 {" NL " uint g_input0[];" NL "};" NL
7432 "layout(std430, binding = 1) readonly buffer Input23 {" NL " float data[];" NL "} g_input23[2];" NL
7433 "layout(std430, binding = 3) buffer Output {" NL " int g_length2;" NL " int g_length[];" NL "};";
7434 std::string expr = NL " g_length[0] = g_input0.length();" NL " g_length[1] = g_input23[0].data.length();" NL
7435 " g_length[2] = g_input23[1].data.length();" NL " g_length2 = g_length.length();";
7436 if (stage == vertex)
7437 {
7438 os << decl
7439 << NL "void main() {" NL "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL
7440 " gl_Position = vec4(0,0,0,1);"
7441 << expr;
7442 }
7443 if (stage == fragment)
7444 {
7445 os << NL "layout(location = 0) out vec4 o_color;" << decl
7446 << NL "void main() {" NL " o_color = vec4(0.0, 1.0, 0.0, 1.0);" << expr;
7447 }
7448 if (stage == compute)
7449 {
7450 os << NL "layout(local_size_x = 1) in;" << decl << NL "void main() {" << expr;
7451 }
7452 os << NL "}";
7453 return os.str();
7454 }
7455
Run()7456 virtual long Run()
7457 {
7458 const int kSize = 10000;
7459 const int kBufs = 4;
7460 if ((stage == vertex && !IsVSFSAvailable(kBufs, 0)) || (stage == fragment && !IsVSFSAvailable(0, kBufs)))
7461 return NOT_SUPPORTED;
7462 if (stage == vertex)
7463 {
7464 std::string glsl_vs = BuildShader();
7465 std::string glsl_fs = BuildShaderPT(fragment);
7466 m_program = CreateProgram(glsl_vs, glsl_fs);
7467 }
7468 else if (stage == fragment)
7469 {
7470 std::string glsl_vs = BuildShaderPT(vertex);
7471 std::string glsl_fs = BuildShader();
7472 m_program = CreateProgram(glsl_vs, glsl_fs);
7473 }
7474 else
7475 { // compute
7476 std::string glsl_cs = BuildShader();
7477 m_program = CreateProgramCS(glsl_cs);
7478 }
7479 glLinkProgram(m_program);
7480 if (!CheckProgram(m_program))
7481 return ERROR;
7482 glUseProgram(m_program);
7483
7484 glGenBuffers(kBufs, m_storage_buffer);
7485 int sizes[kBufs] = {7, 3, 4, 5};
7486 std::vector<int> data(kSize, 41);
7487 for (int i = 0; i < kBufs; ++i)
7488 {
7489 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
7490 glBufferData(GL_SHADER_STORAGE_BUFFER, sizes[i] * 4, &data[0], GL_DYNAMIC_COPY);
7491 }
7492
7493 if (stage != compute)
7494 {
7495 glGenVertexArrays(1, &m_vertex_array);
7496 glBindVertexArray(m_vertex_array);
7497 glDrawArrays(GL_POINTS, 0, 1);
7498 }
7499 else
7500 {
7501 glDispatchCompute(1, 1, 1);
7502 }
7503 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7504
7505 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
7506 int *dataout = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizes[kBufs - 1], GL_MAP_READ_BIT);
7507 if (!dataout)
7508 return ERROR;
7509 bool status = true;
7510 for (int i = 0; i < kBufs - 1; ++i)
7511 if (dataout[i + 1] != sizes[i])
7512 {
7513 m_context.getTestContext().getLog()
7514 << tcu::TestLog::Message << "Array " << i << " length is " << dataout[i + 1] << " should be "
7515 << sizes[i] << tcu::TestLog::EndMessage;
7516 status = false;
7517 }
7518 if (dataout[0] != sizes[kBufs - 1] - 1)
7519 {
7520 m_context.getTestContext().getLog()
7521 << tcu::TestLog::Message << "Array " << (kBufs - 1) << " length is " << dataout[0] << " should be "
7522 << (sizes[kBufs - 1] - 1) << tcu::TestLog::EndMessage;
7523 status = false;
7524 }
7525 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7526
7527 if (!status)
7528 return ERROR;
7529
7530 return NO_ERROR;
7531 }
7532 };
7533
7534 class AdvancedUnsizedArrayLength2 : public ShaderStorageBufferObjectBase
7535 {
7536 GLuint m_program;
7537 GLuint m_storage_buffer[8];
7538 GLuint m_vertex_array;
7539 virtual void SetPath() = 0;
7540
Setup()7541 virtual long Setup()
7542 {
7543 m_program = 0;
7544 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7545 m_vertex_array = 0;
7546 return NO_ERROR;
7547 }
Cleanup()7548 virtual long Cleanup()
7549 {
7550 glUseProgram(0);
7551 glDeleteProgram(m_program);
7552 glDeleteBuffers(8, m_storage_buffer);
7553 if (stage != compute)
7554 glDeleteVertexArrays(1, &m_vertex_array);
7555 return NO_ERROR;
7556 }
BuildShaderPT(int stagept)7557 std::string BuildShaderPT(int stagept)
7558 {
7559 std::ostringstream os;
7560 if (stagept == vertex)
7561 {
7562 os << NL "void main() {" NL " gl_Position = vec4(0,0,0,1);" NL "#ifdef GL_ES" NL
7563 " gl_PointSize = 1.0f;" NL "#endif";
7564 }
7565 if (stagept == fragment)
7566 {
7567 os << NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
7568 " o_color = vec4(0.0, 1.0, 0.0, 1.0);";
7569 }
7570 os << NL "}";
7571 return os.str();
7572 }
BuildShader()7573 std::string BuildShader()
7574 {
7575 std::ostringstream os;
7576 std::string e[4][7] = {{"bvec3", "vec4", "ivec3", "ivec3", "uvec2", "vec2", "uvec4"},
7577 {"mat2", "mat3", "mat4", "mat4", "mat2x3", "mat3x2", "mat4x2"},
7578 {"mat2", "mat3", "mat4", "mat4", "mat2x3", "mat3x2", "mat4x2"},
7579 {"S0", "S1", "S2", "S2", "S4", "S5", "S6"}};
7580 std::string sd =
7581 NL "struct S0 {" NL " float f;" NL " int i;" NL " uint ui;" NL " bool b;" NL "};" NL "struct S1 {" NL
7582 " ivec3 iv;" NL " bvec2 bv;" NL " vec4 v;" NL " uvec2 uv;" NL "};" NL "struct S2 {" NL
7583 " mat2x2 m22;" NL " mat4x4 m44;" NL " mat2x3 m23;" NL " mat4x2 m42;" NL " mat3x4 m34;" NL "};" NL
7584 "struct S4 {" NL " float f[1];" NL " int i[2];" NL " uint ui[3];" NL " bool b[4];" NL
7585 " ivec3 iv[5];" NL " bvec2 bv[6];" NL " vec4 v[7];" NL " uvec2 uv[8];" NL "};" NL "struct S5 {" NL
7586 " S0 s0;" NL " S1 s1;" NL " S2 s2;" NL "};" NL "struct S6 {" NL " S4 s4[3];" NL "};";
7587
7588 std::string lo = "";
7589 std::string l[4] = {"std140", "std430", "shared", "packed"};
7590 lo += l[layout];
7591 if (etype == matrix_rm)
7592 lo += ", row_major";
7593
7594 std::string decl = sd + NL "layout(" + lo + ") buffer;" NL "layout(binding = 0) readonly buffer Input0 {" +
7595 ((other_members) ? ("\n " + e[etype][0] + " pad0;") : "") + NL " " + e[etype][0] +
7596 " g_input0[];" NL "};" NL "layout(binding = 1) readonly buffer Input1 {" +
7597 ((other_members) ? ("\n " + e[etype][1] + " pad1;") : "") + NL " " + e[etype][1] +
7598 " data[];" NL "} g_input1;" NL "layout(binding = 2) readonly buffer Input23 {" +
7599 ((other_members) ? ("\n " + e[etype][2] + " pad2;") : "") + NL " " + e[etype][2] +
7600 " data[];" NL "} g_input23[2];" NL "layout(binding = 4) buffer Output0 {" +
7601 ((other_members) ? ("\n " + e[etype][4] + " pad4;") : "") + NL " " + e[etype][4] +
7602 " data[];" NL "} g_output0;" NL "layout(binding = 5) readonly buffer Input4 {" +
7603 ((other_members) ? ("\n " + e[etype][5] + " pad5;") : "") + NL " " + e[etype][5] +
7604 " data[];" NL "} g_input4;" NL "layout(binding = 6) buffer Output1 {" +
7605 ((other_members) ? ("\n " + e[etype][6] + " pad6;") : "") + NL " " + e[etype][6] +
7606 " data[];" NL "} g_output1;" NL "layout(std430, binding = 7) buffer Output {" NL
7607 " int g_length[];" NL "};";
7608 std::string expr =
7609 NL " g_length[0] = g_input0.length();" NL " g_length[1] = g_input1.data.length();" NL
7610 " g_length[2] = g_input23[0].data.length();" NL " g_length[3] = g_input23[1].data.length();" NL
7611 " g_length[4] = g_output0.data.length();" NL " g_length[5] = g_input4.data.length();" NL
7612 " g_length[6] = g_output1.data.length();";
7613 std::string lastelemexpr =
7614 NL " g_output0.data[g_output0.data.length()-2] += g_output0.data[g_output0.data.length()-1];" NL
7615 " g_output1.data[g_output1.data.length()-2] += g_output1.data[g_output1.data.length()-1];";
7616 if (length_as_index)
7617 expr += lastelemexpr;
7618 if (stage == vertex)
7619 {
7620 os << decl
7621 << NL "void main() {" NL "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL
7622 " gl_Position = vec4(0,0,0,1);"
7623 << expr;
7624 }
7625 if (stage == fragment)
7626 {
7627 os << NL "layout(location = 0) out vec4 o_color;" << decl
7628 << NL "void main() {" NL " o_color = vec4(0.0, 1.0, 0.0, 1.0);" << expr;
7629 }
7630 if (stage == compute)
7631 {
7632 os << NL "layout(local_size_x = 1) in;" << decl << NL "void main() {" << expr;
7633 }
7634 os << NL "}";
7635 return os.str();
7636 }
7637
Run()7638 virtual long Run()
7639 {
7640 const int kSize = 100000;
7641 const int kBufs = 8;
7642 SetPath();
7643 if ((stage == vertex && !IsVSFSAvailable(kBufs, 0)) || (stage == fragment && !IsVSFSAvailable(0, kBufs)))
7644 return NOT_SUPPORTED;
7645 GLint blocksC;
7646 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &blocksC);
7647 GLint minA;
7648 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &minA);
7649 if (blocksC < kBufs)
7650 return NOT_SUPPORTED;
7651 if (stage == vertex)
7652 {
7653 std::string glsl_vs = BuildShader();
7654 std::string glsl_fs = BuildShaderPT(fragment);
7655 m_program = CreateProgram(glsl_vs, glsl_fs);
7656 }
7657 else if (stage == fragment)
7658 {
7659 std::string glsl_vs = BuildShaderPT(vertex);
7660 std::string glsl_fs = BuildShader();
7661 m_program = CreateProgram(glsl_vs, glsl_fs);
7662 }
7663 else
7664 { // compute
7665 std::string glsl_cs = BuildShader();
7666 m_program = CreateProgramCS(glsl_cs);
7667 }
7668 glLinkProgram(m_program);
7669 if (!CheckProgram(m_program))
7670 return ERROR;
7671 glUseProgram(m_program);
7672
7673 glGenBuffers(kBufs, m_storage_buffer);
7674 int sizes[kBufs] = {7, 5, 3, 4, 23, 123, 419, 8};
7675 int columns[4][kBufs] = {
7676 {1, 1, 1, 1, 1, 1, 1, 1}, // vector: 1 col
7677 {2, 3, 4, 4, 2, 3, 4, 1}, // mat: # of cols
7678 {2, 3, 4, 4, 3, 2, 2, 1}, // RM mat: # of rows
7679 {1, 1, 1, 1, 1, 1, 1, 1} // structure: not used
7680 };
7681
7682 int scalars[4][kBufs] = {
7683 {4, 4, 4, 4, 2, 2, 4, 1}, //vector: size
7684 {2, 4, 4, 4, 4, 2, 2, 1}, //matrix column_major: rows
7685 {2, 4, 4, 4, 2, 4, 4, 1}, //matrix row_major: columns
7686 {1, 1, 1, 1, 1, 1, 1, 1} //structure: not used
7687 };
7688 int mindw[4][kBufs] = {{3, 4, 3, 3, 2, 2, 4, 1}, // # of real 32bit items
7689 {4, 9, 16, 16, 6, 6, 8, 1},
7690 {4, 9, 16, 16, 6, 6, 8, 1},
7691 {4, 11, 35, 35, 81, 127, 381, 1}};
7692 int std430struct[kBufs] = {4, 16, 48, 48, 88, 68, 264, 1};
7693 int std140struct[kBufs] = {4, 16, 60, 60, 144, 80, 432, 1};
7694 int bufsize[kBufs][2] = {{0}, {0}};
7695
7696 std::vector<ivec4> data(kSize, ivec4(41));
7697 for (int i = 0; i < kBufs; ++i)
7698 {
7699 if (layout == std430)
7700 {
7701 bufsize[i][1] = 4 * columns[etype][i] * scalars[etype][i];
7702 if (etype == structure)
7703 {
7704 bufsize[i][1] = 4 * std430struct[i];
7705 }
7706 }
7707 else if (layout == std140)
7708 {
7709 bufsize[i][1] = 4 * columns[etype][i] * 4;
7710 if (etype == structure)
7711 {
7712 bufsize[i][1] = 4 * std140struct[i];
7713 }
7714 }
7715 else
7716 {
7717 bufsize[i][1] = 4 * mindw[etype][i];
7718 }
7719 bufsize[i][0] = sizes[i] * bufsize[i][1];
7720 if (i == kBufs - 1 || bind_seq == bindbasebefore)
7721 { // never trim feedback storage
7722 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
7723 glBufferData(GL_SHADER_STORAGE_BUFFER, bufsize[i][0], &data[0], GL_DYNAMIC_COPY);
7724 }
7725 else
7726 {
7727 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[i]);
7728 glBufferData(GL_SHADER_STORAGE_BUFFER, bufsize[i][0], &data[0], GL_DYNAMIC_COPY);
7729 if (bind_seq == bindbaseafter)
7730 {
7731 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
7732 }
7733 else if (bind_seq == bindrangeoffset && 2 * bufsize[i][1] >= minA)
7734 {
7735 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i], 2 * bufsize[i][1],
7736 bufsize[i][0] - 2 * bufsize[i][1]); // without 2 elements
7737 }
7738 else
7739 { // bind_seq == bindrangesize || 2*bufsize[i][1] < minA
7740 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i], 0,
7741 bufsize[i][0] - 2 * bufsize[i][1]); // without 2 elements
7742 }
7743 }
7744 }
7745
7746 if (stage != compute)
7747 {
7748 glGenVertexArrays(1, &m_vertex_array);
7749 glBindVertexArray(m_vertex_array);
7750 glDrawArrays(GL_POINTS, 0, 1);
7751 }
7752 else
7753 {
7754 glDispatchCompute(1, 1, 1);
7755 }
7756 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7757
7758 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[kBufs - 1]);
7759 int *dataout = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizes[kBufs - 1], GL_MAP_READ_BIT);
7760 if (!dataout)
7761 return ERROR;
7762 bool status = true;
7763 for (int i = 0; i < kBufs - 1; ++i)
7764 {
7765 if (other_members)
7766 sizes[i] -= 1; // space consumed by a pad
7767 if (bind_seq == bindrangesize || bind_seq == bindrangeoffset)
7768 sizes[i] -= 2; // space constrained by offset of range size
7769 if ((layout == std140 || layout == std430) && dataout[i] != sizes[i])
7770 {
7771 m_context.getTestContext().getLog()
7772 << tcu::TestLog::Message << "Array " << i << " length is " << dataout[i] << " should be "
7773 << sizes[i] << tcu::TestLog::EndMessage;
7774 status = false;
7775 }
7776 if ((layout == packed || layout == shared) && (dataout[i] > sizes[i]))
7777 {
7778 m_context.getTestContext().getLog()
7779 << tcu::TestLog::Message << "Array " << i << " length is " << dataout[i]
7780 << " should be not greater that " << sizes[i] << tcu::TestLog::EndMessage;
7781 status = false;
7782 }
7783 }
7784 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7785
7786 if (length_as_index)
7787 {
7788 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
7789 dataout = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bufsize[4][0], GL_MAP_READ_BIT);
7790 if (!dataout)
7791 return ERROR;
7792 int i = (sizes[4] - 2) * columns[etype][4] * scalars[etype][4];
7793 if (dataout[i] != 82)
7794 {
7795 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Array 4 index " << i << " is "
7796 << dataout[i] << " should be 82" << tcu::TestLog::EndMessage;
7797 status = false;
7798 }
7799 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7800 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[6]);
7801 dataout = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bufsize[6][0], GL_MAP_READ_BIT);
7802 if (!dataout)
7803 return ERROR;
7804 i = (sizes[6] - 2) * columns[etype][6] * scalars[etype][6];
7805 if (dataout[i] != 82)
7806 {
7807 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Array 6 index " << i << " is "
7808 << dataout[i] << " should be 82" << tcu::TestLog::EndMessage;
7809 status = false;
7810 }
7811 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7812 }
7813
7814 if (!status)
7815 return ERROR;
7816
7817 return NO_ERROR;
7818 }
7819
7820 public:
7821 int stage;
7822 int etype;
7823 int layout;
7824 bool other_members;
7825 int bind_seq;
7826 bool length_as_index;
7827
AdvancedUnsizedArrayLength2()7828 AdvancedUnsizedArrayLength2()
7829 : m_program(0)
7830 , m_vertex_array(0)
7831 , stage(compute)
7832 , etype(vector)
7833 , layout(std430)
7834 , other_members(false)
7835 , bind_seq(bindbasebefore)
7836 , length_as_index(false)
7837 {
7838 }
7839 };
7840
7841 class AdvancedUnsizedArrayLength_cs_std430_vec_indexing : public AdvancedUnsizedArrayLength2
7842 {
7843 public:
SetPath()7844 virtual void SetPath()
7845 {
7846 length_as_index = true;
7847 }
7848 };
7849
7850 class AdvancedUnsizedArrayLength_cs_std430_vec_after : public AdvancedUnsizedArrayLength2
7851 {
7852 public:
SetPath()7853 virtual void SetPath()
7854 {
7855 bind_seq = bindbaseafter;
7856 }
7857 };
7858
7859 class AdvancedUnsizedArrayLength_cs_std430_vec_offset : public AdvancedUnsizedArrayLength2
7860 {
7861 public:
SetPath()7862 virtual void SetPath()
7863 {
7864 bind_seq = bindrangeoffset;
7865 }
7866 };
7867
7868 class AdvancedUnsizedArrayLength_cs_std430_vec_size : public AdvancedUnsizedArrayLength2
7869 {
7870 public:
SetPath()7871 virtual void SetPath()
7872 {
7873 bind_seq = bindrangesize;
7874 }
7875 };
7876
7877 class AdvancedUnsizedArrayLength_cs_std430_vec : public AdvancedUnsizedArrayLength2
7878 {
7879 public:
SetPath()7880 virtual void SetPath()
7881 {
7882 etype = vector;
7883 }
7884 };
7885
7886 class AdvancedUnsizedArrayLength_cs_std430_matC : public AdvancedUnsizedArrayLength2
7887 {
7888 public:
SetPath()7889 virtual void SetPath()
7890 {
7891 etype = matrix_cm;
7892 }
7893 };
7894
7895 class AdvancedUnsizedArrayLength_cs_std430_matR : public AdvancedUnsizedArrayLength2
7896 {
7897 public:
SetPath()7898 virtual void SetPath()
7899 {
7900 etype = matrix_rm;
7901 }
7902 };
7903
7904 class AdvancedUnsizedArrayLength_cs_std430_struct : public AdvancedUnsizedArrayLength2
7905 {
7906 public:
SetPath()7907 virtual void SetPath()
7908 {
7909 etype = structure;
7910 }
7911 };
7912
7913 class AdvancedUnsizedArrayLength_cs_std140_vec : public AdvancedUnsizedArrayLength2
7914 {
7915 public:
SetPath()7916 virtual void SetPath()
7917 {
7918 stage = compute;
7919 layout = std140;
7920 }
7921 };
7922
7923 class AdvancedUnsizedArrayLength_cs_std140_matC : public AdvancedUnsizedArrayLength2
7924 {
7925 public:
SetPath()7926 virtual void SetPath()
7927 {
7928 etype = matrix_cm;
7929 layout = std140;
7930 }
7931 };
7932
7933 class AdvancedUnsizedArrayLength_cs_std140_matR : public AdvancedUnsizedArrayLength2
7934 {
7935 public:
SetPath()7936 virtual void SetPath()
7937 {
7938 etype = matrix_rm;
7939 layout = std140;
7940 }
7941 };
7942
7943 class AdvancedUnsizedArrayLength_cs_std140_struct : public AdvancedUnsizedArrayLength2
7944 {
7945 public:
SetPath()7946 virtual void SetPath()
7947 {
7948 etype = structure;
7949 layout = std140;
7950 }
7951 };
7952
7953 class AdvancedUnsizedArrayLength_cs_packed_vec : public AdvancedUnsizedArrayLength2
7954 {
7955 public:
SetPath()7956 virtual void SetPath()
7957 {
7958 etype = vector;
7959 layout = packed;
7960 }
7961 };
7962
7963 class AdvancedUnsizedArrayLength_cs_packed_matC : public AdvancedUnsizedArrayLength2
7964 {
7965 public:
SetPath()7966 virtual void SetPath()
7967 {
7968 etype = matrix_cm;
7969 layout = packed;
7970 }
7971 };
7972
7973 class AdvancedUnsizedArrayLength_cs_shared_matR : public AdvancedUnsizedArrayLength2
7974 {
7975 public:
SetPath()7976 virtual void SetPath()
7977 {
7978 etype = matrix_rm;
7979 layout = shared;
7980 }
7981 };
7982
7983 class AdvancedUnsizedArrayLength_fs_std430_vec : public AdvancedUnsizedArrayLength2
7984 {
7985 public:
SetPath()7986 virtual void SetPath()
7987 {
7988 stage = fragment;
7989 etype = vector;
7990 layout = std430;
7991 }
7992 };
7993
7994 class AdvancedUnsizedArrayLength_fs_std430_matC_pad : public AdvancedUnsizedArrayLength2
7995 {
7996 public:
SetPath()7997 virtual void SetPath()
7998 {
7999 stage = fragment;
8000 etype = matrix_cm;
8001 layout = std430;
8002 other_members = true;
8003 }
8004 };
8005
8006 class AdvancedUnsizedArrayLength_fs_std140_matR : public AdvancedUnsizedArrayLength2
8007 {
8008 public:
SetPath()8009 virtual void SetPath()
8010 {
8011 stage = fragment;
8012 etype = matrix_rm;
8013 layout = std140;
8014 }
8015 };
8016
8017 class AdvancedUnsizedArrayLength_fs_std140_struct : public AdvancedUnsizedArrayLength2
8018 {
8019 public:
SetPath()8020 virtual void SetPath()
8021 {
8022 stage = fragment;
8023 etype = structure;
8024 layout = std140;
8025 }
8026 };
8027
8028 class AdvancedUnsizedArrayLength_vs_std430_vec_pad : public AdvancedUnsizedArrayLength2
8029 {
8030 public:
SetPath()8031 virtual void SetPath()
8032 {
8033 stage = vertex;
8034 etype = vector;
8035 layout = std430;
8036 other_members = true;
8037 }
8038 };
8039
8040 class AdvancedUnsizedArrayLength_vs_std140_matC : public AdvancedUnsizedArrayLength2
8041 {
8042 public:
SetPath()8043 virtual void SetPath()
8044 {
8045 stage = vertex;
8046 etype = matrix_cm;
8047 layout = std140;
8048 }
8049 };
8050
8051 class AdvancedUnsizedArrayLength_vs_packed_matR : public AdvancedUnsizedArrayLength2
8052 {
8053 public:
SetPath()8054 virtual void SetPath()
8055 {
8056 stage = vertex;
8057 etype = matrix_rm;
8058 layout = packed;
8059 }
8060 };
8061
8062 class AdvancedUnsizedArrayLength_vs_std140_struct : public AdvancedUnsizedArrayLength2
8063 {
8064 public:
SetPath()8065 virtual void SetPath()
8066 {
8067 stage = vertex;
8068 etype = structure;
8069 layout = std140;
8070 }
8071 };
8072
8073 class AdvancedUnsizedArrayLength_cs_std430_vec_pad : public AdvancedUnsizedArrayLength2
8074 {
8075 public:
SetPath()8076 virtual void SetPath()
8077 {
8078 etype = vector;
8079 other_members = true;
8080 }
8081 };
8082
8083 class AdvancedUnsizedArrayLength_cs_std430_matC_pad : public AdvancedUnsizedArrayLength2
8084 {
8085 public:
SetPath()8086 virtual void SetPath()
8087 {
8088 etype = matrix_cm;
8089 other_members = true;
8090 }
8091 };
8092
8093 class AdvancedUnsizedArrayLength_cs_std140_matR_pad : public AdvancedUnsizedArrayLength2
8094 {
8095 public:
SetPath()8096 virtual void SetPath()
8097 {
8098 etype = matrix_rm;
8099 layout = std140;
8100 other_members = true;
8101 }
8102 };
8103
8104 class AdvancedUnsizedArrayLength_cs_std430_struct_pad : public AdvancedUnsizedArrayLength2
8105 {
8106 public:
SetPath()8107 virtual void SetPath()
8108 {
8109 etype = structure;
8110 other_members = true;
8111 }
8112 };
8113
8114 //-----------------------------------------------------------------------------
8115 // 2.8 AdvancedMatrix
8116 //-----------------------------------------------------------------------------
8117 class AdvancedMatrixVSFS : public ShaderStorageBufferObjectBase
8118 {
8119 GLuint m_program;
8120 GLuint m_storage_buffer[3];
8121 GLuint m_vertex_array;
8122 GLuint m_vertex_buffer;
8123 GLuint m_fbo, m_rt;
8124
Setup()8125 virtual long Setup()
8126 {
8127 m_program = 0;
8128 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
8129 m_vertex_array = 0;
8130 m_vertex_buffer = 0;
8131 glGenFramebuffers(1, &m_fbo);
8132 glGenTextures(1, &m_rt);
8133 return NO_ERROR;
8134 }
Run()8135 virtual long Run()
8136 {
8137 if (!IsVSFSAvailable(2, 2))
8138 return NOT_SUPPORTED;
8139 const char *const glsl_vs =
8140 NL "layout(location = 0) in vec4 g_position;" NL "flat out int instance_id;" NL
8141 "layout(binding = 0, std430) coherent buffer Buffer0 {" NL " mat3x4 g_transform[4];" NL
8142 " mat4x3 g_color;" NL " mat3 g_data0;" NL "};" NL
8143 "layout(binding = 1, std430) readonly buffer Buffer1 {" NL " mat4 color;" NL "} g_buffer1;" NL
8144 "uniform int g_index1;" NL "uniform int g_index2;" NL "void main() {" NL
8145 " gl_Position = vec4(transpose(g_transform[gl_InstanceID]) * g_position, 1);" NL
8146 " g_color[gl_InstanceID] = g_buffer1.color[gl_InstanceID].rgb;" NL
8147 " if (gl_VertexID == 0 && gl_InstanceID == 0) {" NL " g_data0[1][1] = 1.0;" NL
8148 " g_data0[g_index1][g_index2] += 3.0;" NL " }" NL " memoryBarrier();" NL
8149 " instance_id = gl_InstanceID;" NL "}";
8150 const char *const glsl_fs =
8151 NL "flat in int instance_id;" NL "layout(location = 0) out vec4 g_ocolor;" NL
8152 "layout(binding = 0, std430) coherent buffer Buffer0 {" NL " mat3x4 g_transform[4];" NL
8153 " mat4x3 g_color;" NL " mat3 g_data0;" NL "};" NL "uniform int g_index1;" NL "uniform int g_index2;" NL
8154 "void main() {" NL " if (g_data0[g_index1][g_index1] != 1.0) g_ocolor = vec4(0);" NL
8155 " else if (g_data0[g_index1][g_index2] != 3.0) g_ocolor = vec4(0);" NL
8156 " else g_ocolor = vec4(g_color[instance_id], 1);" NL "}";
8157 m_program = CreateProgram(glsl_vs, glsl_fs);
8158 glLinkProgram(m_program);
8159 if (!CheckProgram(m_program))
8160 return ERROR;
8161
8162 glGenBuffers(3, m_storage_buffer);
8163
8164 /* transform buffer */
8165 {
8166 float data[48 + 16 + 12 + 16] = {
8167 1.0f, 0.0f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f,
8168 0.0f, 1.0f, 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.5f,
8169 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
8170 };
8171 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
8172 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
8173 }
8174 /* transform buffer */
8175 {
8176 float data[16] = {
8177 1.0f, 0.0f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f,
8178 };
8179 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
8180 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
8181 }
8182 /* vertex buffer */
8183 {
8184 float data[8] = {-0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.4f, 0.4f};
8185 glGenBuffers(1, &m_vertex_buffer);
8186 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
8187 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
8188 glBindBuffer(GL_ARRAY_BUFFER, 0);
8189 }
8190
8191 glBindTexture(GL_TEXTURE_2D, m_rt);
8192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8193 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8194 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
8195 glBindTexture(GL_TEXTURE_2D, 0);
8196 glViewport(0, 0, 100, 100);
8197 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
8198 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
8199
8200 glGenVertexArrays(1, &m_vertex_array);
8201 glBindVertexArray(m_vertex_array);
8202 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
8203 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
8204 glBindBuffer(GL_ARRAY_BUFFER, 0);
8205 glEnableVertexAttribArray(0);
8206 glBindVertexArray(0);
8207
8208 glClear(GL_COLOR_BUFFER_BIT);
8209 glUseProgram(m_program);
8210 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
8211 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
8212
8213 glBindVertexArray(m_vertex_array);
8214 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
8215 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1), vec3(1, 1, 0)))
8216 {
8217 return ERROR;
8218 }
8219 return NO_ERROR;
8220 }
8221
Cleanup()8222 virtual long Cleanup()
8223 {
8224 glViewport(0, 0, getWindowWidth(), getWindowHeight());
8225 glUseProgram(0);
8226 glDeleteProgram(m_program);
8227 glDeleteBuffers(3, m_storage_buffer);
8228 glDeleteBuffers(1, &m_vertex_buffer);
8229 glDeleteVertexArrays(1, &m_vertex_array);
8230 glDeleteFramebuffers(1, &m_fbo);
8231 glDeleteTextures(1, &m_rt);
8232 return NO_ERROR;
8233 }
8234 };
8235
8236 class AdvancedMatrixCS : public ShaderStorageBufferObjectBase
8237 {
8238 GLuint m_program;
8239 GLuint m_storage_buffer;
8240
Setup()8241 virtual long Setup()
8242 {
8243 m_program = 0;
8244 m_storage_buffer = 0;
8245 return NO_ERROR;
8246 }
8247
Run()8248 virtual long Run()
8249 {
8250 bool status = true;
8251 const char *const glsl_cs =
8252 NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Buffer {" NL " mat4x3 dst4x3;" NL
8253 " mat4 dst4;" NL " mat4 src4;" NL "} b;" NL "uniform int g_index1;" NL "uniform int g_index2;" NL
8254 "void main() {" NL " b.dst4x3[gl_LocalInvocationIndex] = b.src4[gl_LocalInvocationIndex].rgb;" NL
8255 " b.dst4x3[gl_LocalInvocationIndex + 1u] = b.src4[gl_LocalInvocationIndex + 1u].aar;" NL
8256 " b.dst4[g_index2][g_index1] = 17.0;" NL " b.dst4[g_index2][g_index1] += 6.0;" NL
8257 " b.dst4[3][0] = b.src4[3][0] != 44.0 ? 3.0 : 7.0;" NL " b.dst4[3][1] = b.src4[3][1];" NL "}";
8258 m_program = CreateProgramCS(glsl_cs);
8259 glLinkProgram(m_program);
8260 if (!CheckProgram(m_program))
8261 return ERROR;
8262
8263 glGenBuffers(1, &m_storage_buffer);
8264 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
8265 GLfloat data[16 + 16 + 16];
8266 for (int i = 0; i < 32; ++i)
8267 data[i] = 0.0f;
8268 for (int i = 32; i < 48; ++i)
8269 data[i] = (GLfloat)i;
8270 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data[0], GL_DYNAMIC_DRAW);
8271
8272 glUseProgram(m_program);
8273 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
8274 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
8275 glDispatchCompute(1, 1, 1);
8276 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
8277 GLfloat *out_data = (GLfloat *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), GL_MAP_READ_BIT);
8278 if (!out_data)
8279 return ERROR;
8280 GLfloat expected[32] = {
8281 32.0f, 33.0f, 34.0f, 0.0f, 39.0f, 39.0f, 36.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8282
8283 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 23.0f, 0.0f, 0.0f, 7.0f, 45.0f, 0.0f, 0.0f};
8284 for (int i = 0; i < 32; ++i)
8285 {
8286 if (out_data[i] != expected[i])
8287 {
8288 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Received: " << out_data[i]
8289 << ", but expected: " << expected[i] << tcu::TestLog::EndMessage;
8290 status = false;
8291 }
8292 }
8293 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
8294 if (status)
8295 return NO_ERROR;
8296 else
8297 return ERROR;
8298 }
Cleanup()8299 virtual long Cleanup()
8300 {
8301 glUseProgram(0);
8302 glDeleteProgram(m_program);
8303 glDeleteBuffers(1, &m_storage_buffer);
8304 return NO_ERROR;
8305 }
8306 };
8307
8308 //-----------------------------------------------------------------------------
8309 // 4.1.1 NegativeAPIBind
8310 //-----------------------------------------------------------------------------
8311 class NegativeAPIBind : public ShaderStorageBufferObjectBase
8312 {
Run()8313 virtual long Run()
8314 {
8315 GLint bindings;
8316 GLint alignment;
8317 GLuint buffer;
8318 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &bindings);
8319 m_context.getTestContext().getLog()
8320 << tcu::TestLog::Message << "Max storage buffer bindings " << bindings << tcu::TestLog::EndMessage;
8321 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
8322 m_context.getTestContext().getLog()
8323 << tcu::TestLog::Message << "Storage buffer offset alignment " << alignment << tcu::TestLog::EndMessage;
8324
8325 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, bindings, 0);
8326 if (glGetError() != GL_INVALID_VALUE)
8327 {
8328 m_context.getTestContext().getLog()
8329 << tcu::TestLog::Message
8330 << "INVALID_VALUE is generated by BindBufferBase if <target> is\n"
8331 "SHADER_STORAGE_BUFFER and <index> is greater than or equal to the value of\n"
8332 "MAX_SHADER_STORAGE_BUFFER_BINDINGS."
8333 << tcu::TestLog::EndMessage;
8334 return ERROR;
8335 }
8336
8337 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, bindings, 0, 0, 0);
8338 if (glGetError() != GL_INVALID_VALUE)
8339 {
8340 m_context.getTestContext().getLog()
8341 << tcu::TestLog::Message
8342 << "INVALID_VALUE is generated by BindBufferRange if <target> is\n"
8343 "SHADER_STORAGE_BUFFER and <index> is greater than or equal to the value of\n"
8344 "MAX_SHADER_STORAGE_BUFFER_BINDINGS."
8345 << tcu::TestLog::EndMessage;
8346 return ERROR;
8347 }
8348
8349 glGenBuffers(1, &buffer);
8350 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, alignment - 1, 0);
8351 if (glGetError() != GL_INVALID_VALUE)
8352 {
8353 m_context.getTestContext().getLog()
8354 << tcu::TestLog::Message
8355 << "INVALID_VALUE is generated by BindBufferRange if <target> is\n"
8356 "SHADER_STORAGE_BUFFER and <offset> is not a multiple of the value of\n"
8357 "SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT."
8358 << tcu::TestLog::EndMessage;
8359 return ERROR;
8360 }
8361
8362 return NO_ERROR;
8363 }
8364 };
8365
8366 //-----------------------------------------------------------------------------
8367 // 4.2.1 NegativeGLSLCompileTime
8368 //-----------------------------------------------------------------------------
8369 class NegativeGLSLCompileTime : public ShaderStorageBufferObjectBase
8370 {
Shader1(int binding)8371 static std::string Shader1(int binding)
8372 {
8373 std::stringstream ss;
8374 ss << NL "layout(binding = " << binding
8375 << ") buffer Buffer {" NL " int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}";
8376 return ss.str();
8377 }
8378
Shader2(int binding)8379 static std::string Shader2(int binding)
8380 {
8381 std::stringstream ss;
8382 ss << NL "layout(binding = " << binding
8383 << ") buffer Buffer {" NL " int x;" NL "} g_array[4];" NL "void main() {" NL " g_array[0].x = 0;" NL
8384 " g_array[1].x = 0;" NL " g_array[2].x = 0;" NL " g_array[3].x = 0;" NL "}";
8385 return ss.str();
8386 }
8387
Run()8388 virtual long Run()
8389 {
8390 GLint bindings;
8391 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &bindings);
8392
8393 // initialization of buffer block member 'x' not allowed
8394 if (!Compile(NL "buffer Buffer { int x = 10; };" NL "void main() {" NL " x = 0;" NL "}"))
8395 return ERROR;
8396
8397 // syntax error, unexpected '-', expecting integer constant or unsigned integer constant at token "-"
8398 if (!Compile(Shader1(-1)))
8399 return ERROR;
8400 // invalid value 96 for layout specifier 'binding'
8401 if (!Compile(Shader1(bindings)))
8402 return ERROR;
8403
8404 // invalid value 98 for layout specifier 'binding'
8405 if (!Compile(Shader2(bindings - 2)))
8406 return ERROR;
8407
8408 // OpenGL does not allow declaring buffer variable 'x' in the global scope. Use buffer blocks instead
8409 if (!Compile(NL "buffer int x;" NL "void main() {" NL " x = 0;" NL "}"))
8410 return ERROR;
8411
8412 // OpenGL requires buffer variables to be declared in a shader storage block in the global scope
8413 if (!Compile(NL "buffer Buffer { int y; };" NL "void main() {" NL " y = 0;" NL " buffer int x = 0;" NL "}"))
8414 return ERROR;
8415
8416 // OpenGL does not allow a parameter to be a buffer
8417 if (!Compile(NL "buffer Buffer { int y; };" NL "void Modify(buffer int a) {" NL " atomicAdd(a, 1);" NL "}" NL
8418 "void main() {" NL " Modify(y);" NL "}"))
8419 return ERROR;
8420
8421 // layout specifier 'std430', incompatible with 'uniform blocks'
8422 if (!Compile(NL "layout(std430) uniform UBO { int x; };" NL "buffer SSBO { int y; };" NL "void main() {" NL
8423 " y = x;" NL "}"))
8424 return ERROR;
8425
8426 // unknown layout specifier 'std430'
8427 if (!Compile(NL "buffer SSBO {" NL " layout(std430) int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}"))
8428 return ERROR;
8429
8430 // unknown layout specifier 'binding = 1'
8431 if (!Compile(NL "buffer SSBO {" NL " layout(binding = 1) int x;" NL "};" NL "void main() {" NL " x = 0;" NL
8432 "}"))
8433 return ERROR;
8434
8435 // OpenGL does not allow writing to readonly variable 'x'
8436 if (!Compile(NL "readonly buffer SSBO {" NL " int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}"))
8437 return ERROR;
8438
8439 // OpenGL does not allow reading writeonly variable 'y'
8440 if (!Compile(NL "buffer SSBO {" NL " int x;" NL "};" NL "writeonly buffer SSBO2 {" NL " int y;" NL "};" NL
8441 "void main() {" NL " x = y;" NL "}"))
8442 return ERROR;
8443
8444 // OpenGL does not allow writing to readonly variable 'z'
8445 if (!Compile(NL "buffer SSBO {" NL " int x;" NL "};" NL "buffer SSBO2 {" NL " writeonly int y;" NL
8446 " readonly int z;" NL "};" NL "void main() {" NL " x = y;" NL " z = 0;" NL "}"))
8447 return ERROR;
8448
8449 // OpenGL does not allow having both readonly and writeonly qualifiers on a variable
8450 if (!Compile(NL "buffer SSBO {" NL " int x;" NL "};" NL "readonly buffer SSBO2 {" NL " writeonly int y;" NL
8451 "};" NL "void main() {" NL " x = y;" NL "}"))
8452 return ERROR;
8453
8454 // ["layout(binding = 1) buffer;" should cause compile-time error
8455 if (!Compile(NL "layout(binding = 1) buffer;" //
8456 NL "buffer SSBO {" NL " int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}"))
8457 return ERROR;
8458
8459 // [" atomicAdd(y, 2);" should cause compile-time error
8460 if (!Compile(NL "buffer coherent Buffer { int x; };" NL "int y;" NL "void main() {" NL " atomicAdd(x, 1);" NL
8461 " atomicAdd(y, 2);" //
8462 NL "}"))
8463 return ERROR;
8464
8465 if (!Compile( // can't construct vector from an array
8466 NL "buffer b {" NL " vec4 x[10];" NL "};" NL "void main() {" NL " vec4 y = vec4(x);" NL "}"))
8467 return ERROR;
8468
8469 if (!Compile( // ESSL31 does not allow dynamically uniform indexing of SSBO arrays
8470 NL "layout(std430, binding = 0) buffer Input {" NL " float data0;" NL "} g_input[4];" NL
8471 "layout(std430, binding = 4) buffer Output {" NL " float data0;" NL "} g_output[4];" NL
8472 "void main() {" NL " for (int i = 0; i < 4; ++i) {" NL
8473 " g_output[i].data0 = g_input[i].data0;" NL " }" NL "}"))
8474 return ERROR;
8475
8476 if (!Compile( // ESSL31 does not allow dynamically uniform indexing of SSBO arrays
8477 NL "layout(binding = 0, std430) buffer Material {" NL " vec3 color;" NL "} g_material[4];" NL
8478 "layout(binding = 4, std430) buffer OutputBuffer {" NL " vec3 color[4];" NL "};" NL
8479 "uniform int g_material_id;" NL "void main() {" NL
8480 " color[gl_LocalInvocationIndex] = vec3(g_material[g_material_id].color);" NL "}"))
8481 return ERROR;
8482
8483 return NO_ERROR;
8484 }
8485
Compile(const std::string & source)8486 bool Compile(const std::string &source)
8487 {
8488 const char *const csVer = "#version 310 es" NL "layout(local_size_x = 1) in;";
8489 const char *const src[2] = {csVer, source.c_str()};
8490 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
8491 glShaderSource(sh, 2, src, NULL);
8492 glCompileShader(sh);
8493
8494 GLchar log[1024];
8495 glGetShaderInfoLog(sh, sizeof(log), NULL, log);
8496 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
8497 << log << tcu::TestLog::EndMessage;
8498
8499 GLint status;
8500 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
8501 glDeleteShader(sh);
8502
8503 if (status == GL_TRUE)
8504 {
8505 m_context.getTestContext().getLog()
8506 << tcu::TestLog::Message << "Compilation should fail." << tcu::TestLog::EndMessage;
8507 return false;
8508 }
8509
8510 return true;
8511 }
8512 };
8513
8514 //-----------------------------------------------------------------------------
8515 // 4.2.2 NegativeGLSLLinkTime
8516 //-----------------------------------------------------------------------------
8517 class NegativeGLSLLinkTime : public ShaderStorageBufferObjectBase
8518 {
Run()8519 virtual long Run()
8520 {
8521 if (!IsVSFSAvailable(1, 1))
8522 return NOT_SUPPORTED;
8523 if (!Link("#version 310 es" NL "buffer Buffer { int x; };" NL "void main() {" NL " x += 2;" NL "}",
8524 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { uint x; };" NL "void main() {" NL
8525 " x += 3u;" NL "}"))
8526 return ERROR;
8527
8528 if (!Link("#version 310 es" NL "buffer Buffer { int x; int y; };" NL "void main() {" NL " x += 2;" NL "}",
8529 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { int x; };" NL "void main() {" NL
8530 " x += 3;" NL "}"))
8531 return ERROR;
8532
8533 if (!Link("#version 310 es" NL "buffer Buffer { int y; };" NL "void main() {" NL " y += 2;" NL "}",
8534 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { int x; };" NL "void main() {" NL
8535 " x += 3;" NL "}"))
8536 return ERROR;
8537
8538 if (!Link("#version 310 es" NL "buffer Buffer { int x[2]; };" NL "void main() {" NL " x[1] += 2;" NL "}",
8539 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { int x[3]; };" NL "void main() {" NL
8540 " x[1] += 3;" NL "}"))
8541 return ERROR;
8542
8543 return NO_ERROR;
8544 }
8545
Link(const std::string & cs0,const std::string & cs1)8546 bool Link(const std::string &cs0, const std::string &cs1)
8547 {
8548 const GLuint p = glCreateProgram();
8549
8550 /* shader 0 */
8551 {
8552 GLuint sh = glCreateShader(GL_VERTEX_SHADER);
8553 glAttachShader(p, sh);
8554 glDeleteShader(sh);
8555 const char *const src = cs0.c_str();
8556 glShaderSource(sh, 1, &src, NULL);
8557 glCompileShader(sh);
8558
8559 GLint status;
8560 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
8561 if (status == GL_FALSE)
8562 {
8563 m_context.getTestContext().getLog()
8564 << tcu::TestLog::Message << "VS compilation should be ok." << tcu::TestLog::EndMessage;
8565 CheckProgram(p);
8566 glDeleteProgram(p);
8567 return false;
8568 }
8569 }
8570 /* shader 1 */
8571 {
8572 GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
8573 glAttachShader(p, sh);
8574 glDeleteShader(sh);
8575 const char *const src = cs1.c_str();
8576 glShaderSource(sh, 1, &src, NULL);
8577 glCompileShader(sh);
8578
8579 GLint status;
8580 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
8581 if (status == GL_FALSE)
8582 {
8583 m_context.getTestContext().getLog()
8584 << tcu::TestLog::Message << "FS compilation should be ok." << tcu::TestLog::EndMessage;
8585 CheckProgram(p);
8586 glDeleteProgram(p);
8587 return false;
8588 }
8589 }
8590
8591 glLinkProgram(p);
8592
8593 GLchar log[1024];
8594 glGetProgramInfoLog(p, sizeof(log), NULL, log);
8595 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
8596 << log << tcu::TestLog::EndMessage;
8597
8598 GLint status;
8599 glGetProgramiv(p, GL_LINK_STATUS, &status);
8600 glDeleteProgram(p);
8601
8602 if (status == GL_TRUE)
8603 {
8604 m_context.getTestContext().getLog()
8605 << tcu::TestLog::Message << "Link operation should fail." << tcu::TestLog::EndMessage;
8606 return false;
8607 }
8608
8609 return true;
8610 }
8611 };
8612
8613 } // anonymous namespace
8614
ShaderStorageBufferObjectTests(glcts::Context & context)8615 ShaderStorageBufferObjectTests::ShaderStorageBufferObjectTests(glcts::Context &context)
8616 : TestCaseGroup(context, "shader_storage_buffer_object", "")
8617 {
8618 }
8619
~ShaderStorageBufferObjectTests(void)8620 ShaderStorageBufferObjectTests::~ShaderStorageBufferObjectTests(void)
8621 {
8622 }
8623
init()8624 void ShaderStorageBufferObjectTests::init()
8625 {
8626 using namespace glcts;
8627 addChild(new TestSubcase(m_context, "basic-basic-vs", TestSubcase::Create<BasicBasicVS>));
8628 addChild(new TestSubcase(m_context, "basic-basic-cs", TestSubcase::Create<BasicBasicCS>));
8629 addChild(new TestSubcase(m_context, "basic-max", TestSubcase::Create<BasicMax>));
8630 addChild(new TestSubcase(m_context, "basic-binding", TestSubcase::Create<BasicBinding>));
8631 addChild(new TestSubcase(m_context, "basic-syntax-vs", TestSubcase::Create<BasicSyntaxVS>));
8632 addChild(new TestSubcase(m_context, "basic-syntax-cs", TestSubcase::Create<BasicSyntaxCS>));
8633 addChild(new TestSubcase(m_context, "basic-syntaxSSO", TestSubcase::Create<BasicSyntaxSSO>));
8634 addChild(new TestSubcase(m_context, "basic-std430Layout-case1-vs", TestSubcase::Create<BasicStd430LayoutCase1VS>));
8635 addChild(new TestSubcase(m_context, "basic-std430Layout-case1-cs", TestSubcase::Create<BasicStd430LayoutCase1CS>));
8636 addChild(new TestSubcase(m_context, "basic-std430Layout-case2-vs", TestSubcase::Create<BasicStd430LayoutCase2VS>));
8637 addChild(new TestSubcase(m_context, "basic-std430Layout-case2-cs", TestSubcase::Create<BasicStd430LayoutCase2CS>));
8638 addChild(new TestSubcase(m_context, "basic-std430Layout-case3-vs", TestSubcase::Create<BasicStd430LayoutCase3VS>));
8639 addChild(new TestSubcase(m_context, "basic-std430Layout-case3-cs", TestSubcase::Create<BasicStd430LayoutCase3CS>));
8640 addChild(new TestSubcase(m_context, "basic-std430Layout-case4-vs", TestSubcase::Create<BasicStd430LayoutCase4VS>));
8641 addChild(new TestSubcase(m_context, "basic-std430Layout-case4-cs", TestSubcase::Create<BasicStd430LayoutCase4CS>));
8642 addChild(new TestSubcase(m_context, "basic-std430Layout-case5-vs", TestSubcase::Create<BasicStd430LayoutCase5VS>));
8643 addChild(new TestSubcase(m_context, "basic-std430Layout-case5-cs", TestSubcase::Create<BasicStd430LayoutCase5CS>));
8644 addChild(new TestSubcase(m_context, "basic-std430Layout-case6-vs", TestSubcase::Create<BasicStd430LayoutCase6VS>));
8645 addChild(new TestSubcase(m_context, "basic-std430Layout-case6-cs", TestSubcase::Create<BasicStd430LayoutCase6CS>));
8646 addChild(new TestSubcase(m_context, "basic-std430Layout-case7-vs", TestSubcase::Create<BasicStd430LayoutCase7VS>));
8647 addChild(new TestSubcase(m_context, "basic-std430Layout-case7-cs", TestSubcase::Create<BasicStd430LayoutCase7CS>));
8648 addChild(new TestSubcase(m_context, "basic-std140Layout-case1-vs", TestSubcase::Create<BasicStd140LayoutCase1VS>));
8649 addChild(new TestSubcase(m_context, "basic-std140Layout-case1-cs", TestSubcase::Create<BasicStd140LayoutCase1CS>));
8650 addChild(new TestSubcase(m_context, "basic-std140Layout-case2-vs", TestSubcase::Create<BasicStd140LayoutCase2VS>));
8651 addChild(new TestSubcase(m_context, "basic-std140Layout-case2-cs", TestSubcase::Create<BasicStd140LayoutCase2CS>));
8652 addChild(new TestSubcase(m_context, "basic-std140Layout-case3-vs", TestSubcase::Create<BasicStd140LayoutCase3VS>));
8653 addChild(new TestSubcase(m_context, "basic-std140Layout-case3-cs", TestSubcase::Create<BasicStd140LayoutCase3CS>));
8654 addChild(new TestSubcase(m_context, "basic-std140Layout-case4-vs", TestSubcase::Create<BasicStd140LayoutCase4VS>));
8655 addChild(new TestSubcase(m_context, "basic-std140Layout-case4-cs", TestSubcase::Create<BasicStd140LayoutCase4CS>));
8656 addChild(new TestSubcase(m_context, "basic-std140Layout-case5-vs", TestSubcase::Create<BasicStd140LayoutCase5VS>));
8657 addChild(new TestSubcase(m_context, "basic-std140Layout-case5-cs", TestSubcase::Create<BasicStd140LayoutCase5CS>));
8658 addChild(new TestSubcase(m_context, "basic-std140Layout-case6-vs", TestSubcase::Create<BasicStd140LayoutCase6VS>));
8659 addChild(new TestSubcase(m_context, "basic-std140Layout-case6-cs", TestSubcase::Create<BasicStd140LayoutCase6CS>));
8660 addChild(new TestSubcase(m_context, "basic-atomic-case1-vsfs", TestSubcase::Create<BasicAtomicCase1VSFS>));
8661 addChild(new TestSubcase(m_context, "basic-atomic-case1-cs", TestSubcase::Create<BasicAtomicCase1CS>));
8662 addChild(new TestSubcase(m_context, "basic-atomic-case3-vsfs", TestSubcase::Create<BasicAtomicCase3VSFS>));
8663 addChild(new TestSubcase(m_context, "basic-atomic-case3-cs", TestSubcase::Create<BasicAtomicCase3CS>));
8664 addChild(new TestSubcase(m_context, "basic-atomic-case4-vsfs", TestSubcase::Create<BasicAtomicCase4VSFS>));
8665 addChild(new TestSubcase(m_context, "basic-atomic-case4-cs", TestSubcase::Create<BasicAtomicCase4CS>));
8666 addChild(new TestSubcase(m_context, "basic-stdLayout-case1-vs", TestSubcase::Create<BasicStdLayoutCase1VS>));
8667 addChild(new TestSubcase(m_context, "basic-stdLayout-case1-cs", TestSubcase::Create<BasicStdLayoutCase1CS>));
8668 addChild(new TestSubcase(m_context, "basic-stdLayout-case2-vs", TestSubcase::Create<BasicStdLayoutCase2VS>));
8669 addChild(new TestSubcase(m_context, "basic-stdLayout-case2-cs", TestSubcase::Create<BasicStdLayoutCase2CS>));
8670 addChild(new TestSubcase(m_context, "basic-stdLayout-case3-vs", TestSubcase::Create<BasicStdLayoutCase3VS>));
8671 addChild(new TestSubcase(m_context, "basic-stdLayout-case3-cs", TestSubcase::Create<BasicStdLayoutCase3CS>));
8672 addChild(new TestSubcase(m_context, "basic-stdLayout-case4-vs", TestSubcase::Create<BasicStdLayoutCase4VS>));
8673 addChild(new TestSubcase(m_context, "basic-stdLayout-case4-cs", TestSubcase::Create<BasicStdLayoutCase4CS>));
8674 addChild(new TestSubcase(m_context, "basic-operations-case1-vs", TestSubcase::Create<BasicOperationsCase1VS>));
8675 addChild(new TestSubcase(m_context, "basic-operations-case1-cs", TestSubcase::Create<BasicOperationsCase1CS>));
8676 addChild(new TestSubcase(m_context, "basic-operations-case2-vs", TestSubcase::Create<BasicOperationsCase2VS>));
8677 addChild(new TestSubcase(m_context, "basic-operations-case2-cs", TestSubcase::Create<BasicOperationsCase2CS>));
8678 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case1-vs",
8679 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase1VS>));
8680 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case1-cs",
8681 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase1CS>));
8682 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case2-vs",
8683 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase2VS>));
8684 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case2-cs",
8685 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase2CS>));
8686 addChild(new TestSubcase(m_context, "basic-matrixOperations-case1-vs",
8687 TestSubcase::Create<BasicMatrixOperationsCase1VS>));
8688 addChild(new TestSubcase(m_context, "basic-matrixOperations-case1-cs",
8689 TestSubcase::Create<BasicMatrixOperationsCase1CS>));
8690 addChild(new TestSubcase(m_context, "basic-matrixOperations-case2-vs",
8691 TestSubcase::Create<BasicMatrixOperationsCase2VS>));
8692 addChild(new TestSubcase(m_context, "basic-matrixOperations-case2-cs",
8693 TestSubcase::Create<BasicMatrixOperationsCase2CS>));
8694 addChild(new TestSubcase(m_context, "basic-matrixOperations-case3-vs",
8695 TestSubcase::Create<BasicMatrixOperationsCase3VS>));
8696 addChild(new TestSubcase(m_context, "basic-matrixOperations-case3-cs",
8697 TestSubcase::Create<BasicMatrixOperationsCase3CS>));
8698 addChild(new TestSubcase(m_context, "basic-matrixOperations-case4-vs",
8699 TestSubcase::Create<BasicMatrixOperationsCase4VS>));
8700 addChild(new TestSubcase(m_context, "basic-matrixOperations-case4-cs",
8701 TestSubcase::Create<BasicMatrixOperationsCase4CS>));
8702 addChild(new TestSubcase(m_context, "basic-matrixOperations-case5-vs",
8703 TestSubcase::Create<BasicMatrixOperationsCase5VS>));
8704 addChild(new TestSubcase(m_context, "basic-matrixOperations-case5-cs",
8705 TestSubcase::Create<BasicMatrixOperationsCase5CS>));
8706 addChild(new TestSubcase(m_context, "basic-matrixOperations-case6-vs",
8707 TestSubcase::Create<BasicMatrixOperationsCase6VS>));
8708 addChild(new TestSubcase(m_context, "basic-matrixOperations-case6-cs",
8709 TestSubcase::Create<BasicMatrixOperationsCase6CS>));
8710 addChild(new TestSubcase(m_context, "basic-matrixOperations-case7-vs",
8711 TestSubcase::Create<BasicMatrixOperationsCase7VS>));
8712 addChild(new TestSubcase(m_context, "basic-matrixOperations-case7-cs",
8713 TestSubcase::Create<BasicMatrixOperationsCase7CS>));
8714 addChild(new TestSubcase(m_context, "basic-readonly-writeonly", TestSubcase::Create<BasicReadonlyWriteonly>));
8715 addChild(new TestSubcase(m_context, "basic-name-match", TestSubcase::Create<BasicNameMatch>));
8716 addChild(new TestSubcase(m_context, "advanced-switchBuffers-vs", TestSubcase::Create<AdvancedSwitchBuffersVS>));
8717 addChild(new TestSubcase(m_context, "advanced-switchBuffers-cs", TestSubcase::Create<AdvancedSwitchBuffersCS>));
8718 addChild(new TestSubcase(m_context, "advanced-switchPrograms-vs", TestSubcase::Create<AdvancedSwitchProgramsVS>));
8719 addChild(new TestSubcase(m_context, "advanced-switchPrograms-cs", TestSubcase::Create<AdvancedSwitchProgramsCS>));
8720 addChild(new TestSubcase(m_context, "advanced-write-fragment-fs", TestSubcase::Create<AdvancedWriteFragmentFS>));
8721 addChild(new TestSubcase(m_context, "advanced-write-fragment-cs", TestSubcase::Create<AdvancedWriteFragmentCS>));
8722 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case1-vs",
8723 TestSubcase::Create<AdvancedIndirectAddressingCase1VS>));
8724 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case1-cs",
8725 TestSubcase::Create<AdvancedIndirectAddressingCase1CS>));
8726 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case2-vsfs",
8727 TestSubcase::Create<AdvancedIndirectAddressingCase2VSFS>));
8728 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case2-cs",
8729 TestSubcase::Create<AdvancedIndirectAddressingCase2CS>));
8730 addChild(
8731 new TestSubcase(m_context, "advanced-readWrite-case1-vsfs", TestSubcase::Create<AdvancedReadWriteCase1VSFS>));
8732 addChild(new TestSubcase(m_context, "advanced-readWrite-case1-cs", TestSubcase::Create<AdvancedReadWriteCase1CS>));
8733 addChild(new TestSubcase(m_context, "advanced-usage-case1", TestSubcase::Create<AdvancedUsageCase1>));
8734 addChild(new TestSubcase(m_context, "advanced-usage-sync-vsfs", TestSubcase::Create<AdvancedUsageSyncVSFS>));
8735 addChild(new TestSubcase(m_context, "advanced-usage-sync-cs", TestSubcase::Create<AdvancedUsageSyncCS>));
8736 addChild(new TestSubcase(m_context, "advanced-usage-operators-vs", TestSubcase::Create<AdvancedUsageOperatorsVS>));
8737 addChild(new TestSubcase(m_context, "advanced-usage-operators-cs", TestSubcase::Create<AdvancedUsageOperatorsCS>));
8738 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-int",
8739 TestSubcase::Create<AdvancedUnsizedArrayLength<compute>>));
8740 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-int",
8741 TestSubcase::Create<AdvancedUnsizedArrayLength<fragment>>));
8742 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-int",
8743 TestSubcase::Create<AdvancedUnsizedArrayLength<vertex>>));
8744 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec",
8745 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec>));
8746 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-matC",
8747 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_matC>));
8748 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-matR",
8749 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_matR>));
8750 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-struct",
8751 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_struct>));
8752 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-vec",
8753 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_vec>));
8754 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-matC",
8755 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_matC>));
8756 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-matR",
8757 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_matR>));
8758 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-struct",
8759 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_struct>));
8760 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-packed-vec",
8761 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_packed_vec>));
8762 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-packed-matC",
8763 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_packed_matC>));
8764 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-shared-matR",
8765 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_shared_matR>));
8766 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std430-vec",
8767 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std430_vec>));
8768 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std430-matC-pad",
8769 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std430_matC_pad>));
8770 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std140-matR",
8771 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std140_matR>));
8772 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std140-struct",
8773 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std140_struct>));
8774 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-std430-vec",
8775 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_std430_vec_pad>));
8776 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-std140-matC",
8777 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_std140_matC>));
8778 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-packed-matR",
8779 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_packed_matR>));
8780 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-std140-struct",
8781 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_std140_struct>));
8782 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-pad",
8783 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_pad>));
8784 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-matC-pad",
8785 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_matC_pad>));
8786 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-matR-pad",
8787 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_matR_pad>));
8788 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-struct-pad",
8789 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_struct_pad>));
8790 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-bindrangeOffset",
8791 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_offset>));
8792 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-bindrangeSize",
8793 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_size>));
8794 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-bindbaseAfter",
8795 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_after>));
8796 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-indexing",
8797 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_indexing>));
8798 addChild(new TestSubcase(m_context, "advanced-matrix-vsfs", TestSubcase::Create<AdvancedMatrixVSFS>));
8799 addChild(new TestSubcase(m_context, "advanced-matrix-cs", TestSubcase::Create<AdvancedMatrixCS>));
8800 addChild(new TestSubcase(m_context, "negative-api-bind", TestSubcase::Create<NegativeAPIBind>));
8801 addChild(new TestSubcase(m_context, "negative-glsl-compileTime", TestSubcase::Create<NegativeGLSLCompileTime>));
8802 addChild(new TestSubcase(m_context, "negative-glsl-linkTime", TestSubcase::Create<NegativeGLSLLinkTime>));
8803 }
8804
8805 } // namespace glcts
8806