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& lt, 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 =
2644 NL "layout(location = 0) in vec4 g_in_position;" NL
2645 "layout(std430, binding = 0) coherent buffer Counters {" NL " uint g_uint_counter;" NL
2646 " int g_int_counter;" NL "};" NL
2647 "layout(std430, binding = 1) buffer OutputU {" NL " uint udata[8];" NL "} g_outputU;" NL
2648 "layout(std430, binding = 2) buffer OutputI {" NL " int idata[8];" NL "} g_outputI;" NL
2649 "void main() {" NL " gl_Position = g_in_position;" NL
2650 "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL
2651 " uint uidx = atomicAdd(g_uint_counter, 1u);" NL " int iidx = atomicAdd(g_int_counter, -1);" NL
2652 " g_outputU.udata[uidx] = uidx;" NL " g_outputI.idata[iidx] = iidx;" NL "}";
2653 const char* const glsl_fs =
2654 NL "layout(location = 0) out vec4 g_fs_out;" NL "layout(std430, binding = 0) coherent buffer Counters {" NL
2655 " uint g_uint_counter;" NL " int g_int_counter;" NL "};" NL
2656 "layout(std430, binding = 1) buffer OutputU {" NL " uint udata[8];" NL "} g_outputU;" NL
2657 "layout(std430, binding = 2) buffer OutputI {" NL " int idata[8];" NL "} g_outputI;" NL
2658 "void main() {" NL " g_fs_out = vec4(0, 1, 0, 1);" NL
2659 " uint uidx = atomicAdd(g_uint_counter, 1u);" NL " int iidx = atomicAdd(g_int_counter, -1);" NL
2660 " g_outputU.udata[uidx] = uidx;" NL " g_outputI.idata[iidx] = iidx;" NL "}";
2661 m_program = CreateProgram(glsl_vs, glsl_fs);
2662 glLinkProgram(m_program);
2663 if (!CheckProgram(m_program))
2664 return ERROR;
2665
2666 glGenBuffers(3, m_storage_buffer);
2667 /* counter buffer */
2668 {
2669 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
2670 glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2671 int* ptr = reinterpret_cast<int*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_WRITE_BIT));
2672 if (!ptr)
2673 return ERROR;
2674 *ptr++ = 0;
2675 *ptr++ = 7;
2676 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2677 }
2678 /* output buffers */
2679 {
2680 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
2681 glBufferData(GL_SHADER_STORAGE_BUFFER, 8 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2682 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
2683 glBufferData(GL_SHADER_STORAGE_BUFFER, 8 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2684 }
2685 /* vertex buffer */
2686 {
2687 const float data[] = { -0.8f, -0.8f, 0.8f, -0.8f, -0.8f, 0.8f, 0.8f, 0.8f };
2688 glGenBuffers(1, &m_vertex_buffer);
2689 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2690 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
2691 glBindBuffer(GL_ARRAY_BUFFER, 0);
2692 }
2693
2694 glGenVertexArrays(1, &m_vertex_array);
2695 glBindVertexArray(m_vertex_array);
2696 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
2697 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
2698 glBindBuffer(GL_ARRAY_BUFFER, 0);
2699 glEnableVertexAttribArray(0);
2700 glBindVertexArray(0);
2701
2702 glClear(GL_COLOR_BUFFER_BIT);
2703 glUseProgram(m_program);
2704 glBindVertexArray(m_vertex_array);
2705 glDrawArrays(GL_POINTS, 0, 4);
2706 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2707
2708 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
2709 GLuint* udata = (GLuint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_READ_BIT);
2710 if (!udata)
2711 return ERROR;
2712 for (GLuint i = 0; i < 8; ++i)
2713 {
2714 if (udata[i] != i)
2715 {
2716 m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is "
2717 << udata[i] << " should be " << i << tcu::TestLog::EndMessage;
2718 return ERROR;
2719 }
2720 }
2721 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2722
2723 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
2724 GLint* idata = (GLint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_READ_BIT);
2725 if (!idata)
2726 return ERROR;
2727 for (GLint i = 0; i < 8; ++i)
2728 {
2729 if (idata[i] != i)
2730 {
2731 m_context.getTestContext().getLog() << tcu::TestLog::Message << "iData at index " << i << " is "
2732 << idata[i] << " should be " << i << tcu::TestLog::EndMessage;
2733 return ERROR;
2734 }
2735 }
2736 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2737 return NO_ERROR;
2738 }
Cleanup()2739 virtual long Cleanup()
2740 {
2741 glUseProgram(0);
2742 glDeleteProgram(m_program);
2743 glDeleteBuffers(3, m_storage_buffer);
2744 glDeleteBuffers(1, &m_vertex_buffer);
2745 glDeleteVertexArrays(1, &m_vertex_array);
2746 return NO_ERROR;
2747 }
2748 };
2749
2750 class BasicAtomicCase4CS : public ShaderStorageBufferObjectBase
2751 {
2752 GLuint m_program;
2753 GLuint m_storage_buffer[2];
2754
Setup()2755 virtual long Setup()
2756 {
2757 m_program = 0;
2758 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
2759 return NO_ERROR;
2760 }
Run()2761 virtual long Run()
2762 {
2763 const char* const glsl_cs =
2764 NL "layout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;" NL
2765 "layout(std430, binding = 0) coherent buffer Counters {" NL " uint g_uint_counter;" NL
2766 " int g_int_counter;" NL "};" NL "layout(std430, binding = 1) buffer Output {" NL " uint udata[8];" NL
2767 " int idata[8];" NL "} g_output;" NL "void main() {" NL
2768 " uint uidx = atomicAdd(g_uint_counter, 1u);" NL " int iidx = atomicAdd(g_int_counter, -1);" NL
2769 " g_output.udata[uidx] = uidx;" NL " g_output.idata[iidx] = iidx;" NL "}";
2770 m_program = CreateProgramCS(glsl_cs);
2771 glLinkProgram(m_program);
2772 if (!CheckProgram(m_program))
2773 return ERROR;
2774
2775 glGenBuffers(2, m_storage_buffer);
2776 /* counter buffer */
2777 {
2778 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
2779 glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2780 int* ptr = reinterpret_cast<int*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_WRITE_BIT));
2781 if (!ptr)
2782 return ERROR;
2783 *ptr++ = 0;
2784 *ptr++ = 7;
2785 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2786 }
2787 /* output buffer */
2788 {
2789 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
2790 glBufferData(GL_SHADER_STORAGE_BUFFER, 16 * sizeof(int), NULL, GL_DYNAMIC_DRAW);
2791 }
2792 glUseProgram(m_program);
2793 glDispatchCompute(1, 1, 1);
2794 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2795
2796 GLuint* udata = (GLuint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_READ_BIT);
2797 if (!udata)
2798 return ERROR;
2799 for (GLuint i = 0; i < 8; ++i)
2800 {
2801 if (udata[i] != i)
2802 {
2803 m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is "
2804 << udata[i] << " should be " << i << tcu::TestLog::EndMessage;
2805 return ERROR;
2806 }
2807 }
2808 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2809 GLint* idata = (GLint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 32, 32, GL_MAP_READ_BIT);
2810 if (!idata)
2811 return ERROR;
2812 for (GLint i = 0; i < 8; ++i)
2813 {
2814 if (idata[i] != i)
2815 {
2816 m_context.getTestContext().getLog() << tcu::TestLog::Message << "iData at index " << i << " is "
2817 << idata[i] << " should be " << i << tcu::TestLog::EndMessage;
2818 return ERROR;
2819 }
2820 }
2821 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2822 return NO_ERROR;
2823 }
Cleanup()2824 virtual long Cleanup()
2825 {
2826 glUseProgram(0);
2827 glDeleteProgram(m_program);
2828 glDeleteBuffers(2, m_storage_buffer);
2829 return NO_ERROR;
2830 }
2831 };
2832
2833 //-----------------------------------------------------------------------------
2834 // 1.9.x BasicStdLayoutBase2
2835 //-----------------------------------------------------------------------------
2836 class BasicStdLayoutBase2VS : public ShaderStorageBufferObjectBase
2837 {
2838 GLuint m_program;
2839 GLuint m_buffer[8];
2840 GLuint m_vertex_array;
2841
2842 virtual const char* GetInput(std::vector<GLubyte> in_data[4]) = 0;
2843
Setup()2844 virtual long Setup()
2845 {
2846 m_program = 0;
2847 memset(m_buffer, 0, sizeof(m_buffer));
2848 m_vertex_array = 0;
2849 return NO_ERROR;
2850 }
Run()2851 virtual long Run()
2852 {
2853 if (!IsVSFSAvailable(8, 0))
2854 return NOT_SUPPORTED;
2855 std::vector<GLubyte> in_data[4];
2856 const char* glsl_vs = GetInput(in_data);
2857 const char* const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
2858 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
2859
2860 m_program = CreateProgram(glsl_vs, glsl_fs);
2861 glLinkProgram(m_program);
2862 if (!CheckProgram(m_program))
2863 return ERROR;
2864
2865 glGenBuffers(8, m_buffer);
2866
2867 for (GLuint i = 0; i < 4; ++i)
2868 {
2869 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_buffer[i]);
2870 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &in_data[i][0], GL_STATIC_DRAW);
2871
2872 std::vector<GLubyte> out_data(in_data[i].size());
2873 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i + 4, m_buffer[i + 4]);
2874 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &out_data[0], GL_STATIC_DRAW);
2875 }
2876
2877 glGenVertexArrays(1, &m_vertex_array);
2878 glEnable(GL_RASTERIZER_DISCARD);
2879
2880 glUseProgram(m_program);
2881 glBindVertexArray(m_vertex_array);
2882 glDrawArrays(GL_POINTS, 0, 1);
2883
2884 bool status = true;
2885 for (int j = 0; j < 4; ++j)
2886 {
2887 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 4]);
2888 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2889 GLubyte* out_data =
2890 (GLubyte*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(), GL_MAP_READ_BIT);
2891 if (!out_data)
2892 return ERROR;
2893
2894 for (size_t i = 0; i < in_data[j].size(); ++i)
2895 {
2896 if (in_data[j][i] != out_data[i])
2897 {
2898 m_context.getTestContext().getLog()
2899 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
2900 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
2901 << tcu::TestLog::EndMessage;
2902 status = false;
2903 }
2904 }
2905 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2906 }
2907 if (!status)
2908 return ERROR;
2909 return NO_ERROR;
2910 }
Cleanup()2911 virtual long Cleanup()
2912 {
2913 glDisable(GL_RASTERIZER_DISCARD);
2914 glUseProgram(0);
2915 glDeleteProgram(m_program);
2916 glDeleteBuffers(8, m_buffer);
2917 glDeleteVertexArrays(1, &m_vertex_array);
2918 return NO_ERROR;
2919 }
2920 };
2921
2922 class BasicStdLayoutBase2CS : public ShaderStorageBufferObjectBase
2923 {
2924 GLuint m_program;
2925 GLuint m_buffer[8];
2926
2927 virtual const char* GetInput(std::vector<GLubyte> in_data[4]) = 0;
2928
Setup()2929 virtual long Setup()
2930 {
2931 m_program = 0;
2932 memset(m_buffer, 0, sizeof(m_buffer));
2933 return NO_ERROR;
2934 }
2935
Run()2936 virtual long Run()
2937 {
2938 std::vector<GLubyte> in_data[4];
2939 std::stringstream ss;
2940 GLint blocksCS;
2941 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &blocksCS);
2942 if (blocksCS < 8)
2943 return NO_ERROR;
2944 ss << "layout(local_size_x = 1) in;\n" << GetInput(in_data);
2945 m_program = CreateProgramCS(ss.str());
2946 glLinkProgram(m_program);
2947 if (!CheckProgram(m_program))
2948 return ERROR;
2949
2950 glGenBuffers(8, m_buffer);
2951
2952 for (GLuint i = 0; i < 4; ++i)
2953 {
2954 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_buffer[i]);
2955 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &in_data[i][0], GL_STATIC_DRAW);
2956
2957 std::vector<GLubyte> out_data(in_data[i].size());
2958 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i + 4, m_buffer[i + 4]);
2959 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[i].size(), &out_data[0], GL_STATIC_DRAW);
2960 }
2961
2962 glUseProgram(m_program);
2963 glDispatchCompute(1, 1, 1);
2964 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
2965
2966 bool status = true;
2967 for (int j = 0; j < 4; ++j)
2968 {
2969 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 4]);
2970 GLubyte* out_data =
2971 (GLubyte*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(), GL_MAP_READ_BIT);
2972 if (!out_data)
2973 return ERROR;
2974
2975 for (size_t i = 0; i < in_data[j].size(); ++i)
2976 {
2977 if (in_data[j][i] != out_data[i])
2978 {
2979 m_context.getTestContext().getLog()
2980 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
2981 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
2982 << tcu::TestLog::EndMessage;
2983 status = false;
2984 }
2985 }
2986 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
2987 }
2988 if (!status)
2989 return ERROR;
2990 return NO_ERROR;
2991 }
2992
Cleanup()2993 virtual long Cleanup()
2994 {
2995 glUseProgram(0);
2996 glDeleteProgram(m_program);
2997 glDeleteBuffers(8, m_buffer);
2998 return NO_ERROR;
2999 }
3000 };
3001 //-----------------------------------------------------------------------------
3002 // 1.9.1 BasicStdLayoutCase1
3003 //-----------------------------------------------------------------------------
GetInputC1(std::vector<GLubyte> in_data[4])3004 const char* GetInputC1(std::vector<GLubyte> in_data[4])
3005 {
3006 for (int i = 0; i < 4; ++i)
3007 {
3008 in_data[i].resize(1 * 4);
3009 float* fp = reinterpret_cast<float*>(&in_data[i][0]);
3010 fp[0] = static_cast<float>(i + 1) * 1.0f;
3011 }
3012 return NL "layout(std430, binding = 0) buffer Input {" NL " float data0;" NL "} g_input[4];" NL
3013 "layout(std430, binding = 4) buffer Output {" NL " float data0;" NL "} g_output[4];" NL
3014 "void main() {" NL " g_output[0].data0 = g_input[0].data0;" NL
3015 " g_output[1].data0 = g_input[1].data0;" NL " g_output[2].data0 = g_input[2].data0;" NL
3016 " g_output[3].data0 = g_input[3].data0;" NL "}";
3017 }
3018
3019 class BasicStdLayoutCase1VS : public BasicStdLayoutBase2VS
3020 {
GetInput(std::vector<GLubyte> in_data[4])3021 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3022 {
3023 return GetInputC1(in_data);
3024 }
3025 };
3026
3027 class BasicStdLayoutCase1CS : public BasicStdLayoutBase2CS
3028 {
GetInput(std::vector<GLubyte> in_data[4])3029 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3030 {
3031 return GetInputC1(in_data);
3032 }
3033 };
3034
3035 //-----------------------------------------------------------------------------
3036 // 1.9.2 BasicStdLayoutCase2
3037 //-----------------------------------------------------------------------------
GetInputC2(std::vector<GLubyte> in_data[4])3038 const char* GetInputC2(std::vector<GLubyte> in_data[4])
3039 {
3040 /* input 0, std140 */
3041 {
3042 in_data[0].resize(12 * 4);
3043 float* fp = reinterpret_cast<float*>(&in_data[0][0]);
3044 fp[0] = 1.0f;
3045 fp[1] = 0.0f;
3046 fp[2] = 0.0f;
3047 fp[3] = 0.0f;
3048 fp[4] = 2.0f;
3049 fp[5] = 0.0f;
3050 fp[6] = 0.0f;
3051 fp[7] = 0.0f;
3052 fp[8] = 3.0f;
3053 fp[9] = 0.0f;
3054 fp[10] = 0.0f;
3055 fp[11] = 0.0f;
3056 }
3057 /* input 1, std430 */
3058 {
3059 in_data[1].resize(3 * 4);
3060 float* fp = reinterpret_cast<float*>(&in_data[1][0]);
3061 fp[0] = 4.0f;
3062 fp[1] = 5.0f;
3063 fp[2] = 6.0f;
3064 }
3065 /* input 2, std140 */
3066 {
3067 in_data[2].resize(12 * 4);
3068 float* fp = reinterpret_cast<float*>(&in_data[2][0]);
3069 fp[0] = 7.0f;
3070 fp[1] = 0.0f;
3071 fp[2] = 0.0f;
3072 fp[3] = 0.0f;
3073 fp[4] = 8.0f;
3074 fp[5] = 0.0f;
3075 fp[6] = 0.0f;
3076 fp[7] = 0.0f;
3077 fp[8] = 9.0f;
3078 fp[9] = 0.0f;
3079 fp[10] = 0.0f;
3080 fp[11] = 0.0f;
3081 }
3082 /* input 3, std430 */
3083 {
3084 in_data[3].resize(3 * 4);
3085 float* fp = reinterpret_cast<float*>(&in_data[3][0]);
3086 fp[0] = 10.0f;
3087 fp[1] = 11.0f;
3088 fp[2] = 12.0f;
3089 }
3090 return NL "layout(std140, binding = 0) buffer Input0 {" NL " float data0[3];" NL "} g_input0;" NL
3091 "layout(std430, binding = 1) buffer Input1 {" NL " float data0[3];" NL "} g_input1;" NL
3092 "layout(std140, binding = 2) buffer Input2 {" NL " float data0[3];" NL "} g_input2;" NL
3093 "layout(std430, binding = 3) buffer Input3 {" NL " float data0[3];" NL "} g_input3;" NL
3094 "layout(std140, binding = 4) buffer Output0 {" NL " float data0[3];" NL "} g_output0;" NL
3095 "layout(std430, binding = 5) buffer Output1 {" NL " float data0[3];" NL "} g_output1;" NL
3096 "layout(std140, binding = 6) buffer Output2 {" NL " float data0[3];" NL "} g_output2;" NL
3097 "layout(std430, binding = 7) buffer Output3 {" NL " float data0[3];" NL "} g_output3;" NL
3098 "void main() {" NL
3099 " for (int i = 0; i < g_input0.data0.length(); ++i) g_output0.data0[i] = g_input0.data0[i];" NL
3100 " for (int i = 0; i < g_input1.data0.length(); ++i) g_output1.data0[i] = g_input1.data0[i];" NL
3101 " for (int i = 0; i < g_input2.data0.length(); ++i) g_output2.data0[i] = g_input2.data0[i];" NL
3102 " for (int i = 0; i < g_input3.data0.length(); ++i) g_output3.data0[i] = g_input3.data0[i];" NL "}";
3103 }
3104
3105 class BasicStdLayoutCase2VS : public BasicStdLayoutBase2VS
3106 {
GetInput(std::vector<GLubyte> in_data[4])3107 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3108 {
3109 return GetInputC2(in_data);
3110 }
3111 };
3112
3113 class BasicStdLayoutCase2CS : public BasicStdLayoutBase2CS
3114 {
GetInput(std::vector<GLubyte> in_data[4])3115 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3116 {
3117 return GetInputC2(in_data);
3118 }
3119 };
3120
3121 //-----------------------------------------------------------------------------
3122 // 1.9.3 BasicStdLayoutCase3
3123 //-----------------------------------------------------------------------------
GetInputC3(std::vector<GLubyte> in_data[4])3124 const char* GetInputC3(std::vector<GLubyte> in_data[4])
3125 {
3126 /* input 0, std140 */
3127 {
3128 in_data[0].resize(62 * 4);
3129 float* fp = reinterpret_cast<float*>(&in_data[0][0]);
3130 int* ip = reinterpret_cast<int*>(&in_data[0][0]);
3131 ip[0] = 1;
3132 ip[1] = 0;
3133 ip[2] = 0;
3134 ip[3] = 0;
3135 fp[4] = 2.0f;
3136 fp[5] = 0.0f;
3137 fp[6] = 0.0f;
3138 fp[7] = 0.0f;
3139 fp[8] = 3.0f;
3140 fp[9] = 0.0f;
3141 fp[10] = 0.0f;
3142 fp[11] = 0.0f;
3143 fp[12] = 4.0f;
3144 fp[13] = 0.0f;
3145 fp[14] = 0.0f;
3146 fp[15] = 0.0f;
3147 fp[16] = 5.0f;
3148 fp[17] = 0.0f;
3149 fp[18] = 0.0f;
3150 fp[19] = 0.0f;
3151 fp[20] = 6.0f;
3152 fp[21] = 0.0f;
3153 fp[22] = 0.0f;
3154 fp[23] = 0.0f;
3155 fp[24] = 7.0f;
3156 fp[25] = 8.0f;
3157 fp[26] = 0.0f;
3158 fp[27] = 0.0f;
3159 fp[28] = 9.0f;
3160 fp[29] = 10.0f;
3161 fp[30] = 0.0f;
3162 fp[31] = 0.0f;
3163 fp[32] = 11.0f;
3164 fp[33] = 12.0f;
3165 fp[34] = 0.0f;
3166 fp[35] = 0.0f;
3167 fp[36] = 13.0f;
3168 fp[37] = 0.0f;
3169 fp[38] = 0.0f;
3170 fp[39] = 0.0f;
3171 fp[40] = 14.0f;
3172 fp[41] = 0.0f;
3173 fp[42] = 0.0f;
3174 fp[43] = 0.0f;
3175 fp[44] = 15.0f;
3176 fp[45] = 0.0f;
3177 fp[46] = 0.0f;
3178 fp[47] = 0.0f;
3179 ip[48] = 16;
3180 ip[49] = 0;
3181 ip[50] = 0;
3182 ip[51] = 0;
3183 ip[52] = 17;
3184 ip[53] = 18;
3185 ip[54] = 19;
3186 ip[55] = 0;
3187 }
3188 /* input 1, std430 */
3189 {
3190 in_data[1].resize(30 * 4);
3191 float* fp = reinterpret_cast<float*>(&in_data[1][0]);
3192 int* ip = reinterpret_cast<int*>(&in_data[1][0]);
3193 ip[0] = 1;
3194 fp[1] = 2.0f;
3195 fp[2] = 3.0f;
3196 fp[3] = 4.0f;
3197 fp[4] = 5.0f;
3198 fp[5] = 6.0f;
3199 fp[6] = 7.0f;
3200 fp[7] = 8.0f;
3201 fp[8] = 9.0f;
3202 fp[9] = 10.0f;
3203 fp[10] = 11.0f;
3204 fp[11] = 12.0f;
3205 fp[12] = 13.0f;
3206 fp[13] = 14.0f;
3207 fp[14] = 15.0f;
3208 ip[15] = 16;
3209 ip[16] = 17;
3210 ip[17] = 18;
3211 ip[18] = 19;
3212 }
3213 /* input 2, std140 */
3214 {
3215 in_data[2].resize(5 * 4);
3216 int* ip = reinterpret_cast<int*>(&in_data[2][0]);
3217 ip[0] = 1;
3218 ip[1] = 0;
3219 ip[2] = 0;
3220 ip[3] = 0;
3221 ip[4] = 2;
3222 }
3223 /* input 3, std430 */
3224 {
3225 in_data[3].resize(2 * 4);
3226 int* ip = reinterpret_cast<int*>(&in_data[3][0]);
3227 ip[0] = 1;
3228 ip[1] = 2;
3229 }
3230 return NL "layout(std140, binding = 0) buffer Input0 {" NL " int data0;" //BA=4, OF=[0]0, next=4
3231 NL " float data1[5];" //BA=16, OF=[4]16, next=96
3232 NL " mat3x2 data2;" //BA=16, OF=[24]96, next=144
3233 NL " float data3;" //BA=4, OF=[36]144,next=148
3234 NL " float data4[2];" //BA=16, OF=[40]160,next=192
3235 NL " int data5;" //BA=4, OF=[48]192,next=196
3236 NL " ivec3 data6;" //BA=16, OF=[52]208
3237 NL "} g_input0;" NL "layout(std430, binding = 1) buffer Input1 {" NL " int data0;" //BA=4, OF=[0], next=[1]
3238 NL " float data1[5];" //BA=4, OF=[1], next=[6]
3239 NL " mat3x2 data2;" //BA=8, OF=[6], next=[12]
3240 NL " float data3;" //BA=4, OF=[12], next=[13]
3241 NL " float data4[2];" //BA=4, OF=[13], next=[15]
3242 NL " int data5;" //BA=4, OF=[15], next=[16]
3243 NL " ivec3 data6;" //BA=16,OF=[16]
3244 NL "} g_input1;" NL "struct Struct0 {" NL " int data0;" NL "};" NL
3245 "layout(std140, binding = 2) buffer Input2 {" NL " int data0;" // offset 0
3246 NL " Struct0 data1;" // offset 16, struct should be aligned to a multiple of 16 bytes
3247 NL "} g_input2;" NL "layout(std430, binding = 3) buffer Input3 {" NL " int data0;" // offset 0
3248 NL " Struct0 data1;" // offset 4
3249 NL "} g_input3;"
3250
3251 NL "layout(std140, binding = 4) buffer Output0 {" NL " int data0;" NL " float data1[5];" NL
3252 " mat3x2 data2;" NL " float data3;" NL " float data4[2];" NL " int data5;" NL " ivec3 data6;" NL
3253 "} g_output0;" NL "layout(std430, binding = 5) buffer Output1 {" NL " int data0;" NL
3254 " float data1[5];" NL " mat3x2 data2;" NL " float data3;" NL " float data4[2];" NL " int data5;" NL
3255 " ivec3 data6;" NL "} g_output1;" NL "layout(std140, binding = 6) buffer Output2 {" NL " int data0;" NL
3256 " Struct0 data1;" NL "} g_output2;" NL "layout(std430, binding = 7) buffer Output3 {" NL
3257 " int data0;" NL " Struct0 data1;" NL "} g_output3;" NL "void main() {" NL
3258 " g_output0.data0 = g_input0.data0;" NL
3259 " for (int i = 0; i < g_input0.data1.length(); ++i) g_output0.data1[i] = g_input0.data1[i];" NL
3260 " g_output0.data2 = g_input0.data2;" NL " g_output0.data3 = g_input0.data3;" NL
3261 " for (int i = 0; i < g_input0.data4.length(); ++i) g_output0.data4[i] = g_input0.data4[i];" NL
3262 " g_output0.data5 = g_input0.data5;" NL " g_output0.data6 = g_input0.data6;"
3263
3264 NL " g_output1.data0 = g_input1.data0;" NL
3265 " for (int i = 0; i < g_input1.data1.length(); ++i) g_output1.data1[i] = g_input1.data1[i];" NL
3266 " g_output1.data2 = g_input1.data2;" NL " g_output1.data3 = g_input1.data3;" NL
3267 " for (int i = 0; i < g_input1.data4.length(); ++i) g_output1.data4[i] = g_input1.data4[i];" NL
3268 " g_output1.data5 = g_input1.data5;" NL " g_output1.data6 = g_input1.data6;"
3269
3270 NL " g_output2.data0 = g_input2.data0;" NL " g_output2.data1 = g_input2.data1;"
3271
3272 NL " g_output3.data0 = g_input3.data0;" NL " g_output3.data1 = g_input3.data1;" NL "}";
3273 }
3274
3275 class BasicStdLayoutCase3VS : public BasicStdLayoutBase2VS
3276 {
GetInput(std::vector<GLubyte> in_data[4])3277 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3278 {
3279 return GetInputC3(in_data);
3280 }
3281 };
3282
3283 class BasicStdLayoutCase3CS : public BasicStdLayoutBase2CS
3284 {
GetInput(std::vector<GLubyte> in_data[4])3285 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3286 {
3287 return GetInputC3(in_data);
3288 }
3289 };
3290
3291 //-----------------------------------------------------------------------------
3292 // 1.9.4 BasicStdLayoutCase4
3293 //-----------------------------------------------------------------------------
GetInputC4(std::vector<GLubyte> in_data[4])3294 const char* GetInputC4(std::vector<GLubyte> in_data[4])
3295 {
3296 /* input 0, std140 */
3297 {
3298 in_data[0].resize(57 * 4);
3299 float* fp = reinterpret_cast<float*>(&in_data[0][0]);
3300 int* ip = reinterpret_cast<int*>(&in_data[0][0]);
3301 ip[0] = 1;
3302 ip[1] = 0;
3303 ip[2] = 0;
3304 ip[3] = 0;
3305 ip[4] = 2;
3306 ip[5] = 3;
3307 ip[6] = 0;
3308 ip[7] = 0;
3309 ip[8] = 4;
3310 ip[9] = 5;
3311 ip[10] = 0;
3312 ip[11] = 0;
3313 fp[12] = 6.0f;
3314 fp[13] = 0.0f;
3315 fp[14] = 0.0f;
3316 fp[15] = 0.0f;
3317 fp[16] = 7.0f;
3318 fp[17] = 8.0f;
3319 fp[18] = 0.0f;
3320 fp[19] = 0.0f;
3321 ip[20] = 9;
3322 ip[21] = 10;
3323 ip[22] = 11;
3324 ip[23] = 0;
3325 fp[24] = 12.0f;
3326 fp[25] = 13.0f;
3327 fp[26] = 0.0f;
3328 fp[27] = 0.0f;
3329 ip[28] = 14;
3330 ip[29] = 15;
3331 ip[30] = 16;
3332 ip[31] = 0;
3333 fp[32] = 17.0f;
3334 fp[33] = 0.0f;
3335 fp[34] = 0.0f;
3336 fp[35] = 0.0f;
3337 ip[36] = 18;
3338 ip[37] = 0;
3339 ip[38] = 0;
3340 ip[39] = 0;
3341 ip[40] = 19;
3342 ip[41] = 20;
3343 ip[42] = 0;
3344 ip[43] = 0;
3345 ip[44] = 21;
3346 ip[45] = 0;
3347 ip[45] = 0;
3348 ip[45] = 0;
3349 fp[48] = 22.0f;
3350 fp[49] = 23.0f;
3351 fp[50] = 0.0f;
3352 fp[51] = 0.0f;
3353 ip[52] = 24;
3354 ip[53] = 25;
3355 ip[54] = 26;
3356 ip[55] = 0;
3357 fp[56] = 27.0f;
3358 }
3359 /* input 1, std140 */
3360 {
3361 in_data[1].resize(57 * 4);
3362 float* fp = reinterpret_cast<float*>(&in_data[1][0]);
3363 int* ip = reinterpret_cast<int*>(&in_data[1][0]);
3364 ip[0] = 101;
3365 ip[1] = 0;
3366 ip[2] = 0;
3367 ip[3] = 0;
3368 ip[4] = 102;
3369 ip[5] = 103;
3370 ip[6] = 0;
3371 ip[7] = 0;
3372 ip[8] = 104;
3373 ip[9] = 105;
3374 ip[10] = 0;
3375 ip[11] = 0;
3376 fp[12] = 106.0f;
3377 fp[13] = 0.0f;
3378 fp[14] = 0.0f;
3379 fp[15] = 0.0f;
3380 fp[16] = 107.0f;
3381 fp[17] = 108.0f;
3382 fp[18] = 0.0f;
3383 fp[19] = 0.0f;
3384 ip[20] = 109;
3385 ip[21] = 110;
3386 ip[22] = 111;
3387 ip[23] = 0;
3388 fp[24] = 112.0f;
3389 fp[25] = 113.0f;
3390 fp[26] = 0.0f;
3391 fp[27] = 0.0f;
3392 ip[28] = 114;
3393 ip[29] = 115;
3394 ip[30] = 116;
3395 ip[31] = 0;
3396 fp[32] = 117.0f;
3397 fp[33] = 0.0f;
3398 fp[34] = 0.0f;
3399 fp[35] = 0.0f;
3400 ip[36] = 118;
3401 ip[37] = 0;
3402 ip[38] = 0;
3403 ip[39] = 0;
3404 ip[40] = 119;
3405 ip[41] = 120;
3406 ip[42] = 0;
3407 ip[43] = 0;
3408 ip[44] = 121;
3409 ip[45] = 0;
3410 ip[45] = 0;
3411 ip[45] = 0;
3412 fp[48] = 122.0f;
3413 fp[49] = 123.0f;
3414 fp[50] = 0.0f;
3415 fp[51] = 0.0f;
3416 ip[52] = 124;
3417 ip[53] = 125;
3418 ip[54] = 126;
3419 ip[55] = 0;
3420 fp[56] = 127.0f;
3421 }
3422 /* input 2, std430 */
3423 {
3424 in_data[2].resize(45 * 4);
3425 float* fp = reinterpret_cast<float*>(&in_data[2][0]);
3426 int* ip = reinterpret_cast<int*>(&in_data[2][0]);
3427 ip[0] = 1000;
3428 ip[1] = 0;
3429 ip[2] = 1001;
3430 ip[3] = 1002;
3431 ip[4] = 1003;
3432 ip[5] = 1004;
3433 fp[6] = 1005.0f;
3434 fp[7] = 0.0f;
3435 fp[8] = 1006.0f;
3436 fp[9] = 1007.0f;
3437 fp[10] = 0.0f;
3438 fp[11] = 0.0f;
3439 ip[12] = 1008;
3440 ip[13] = 1009;
3441 ip[14] = 1010;
3442 ip[15] = 0;
3443 fp[16] = 1011.0f;
3444 fp[17] = 1012.0f;
3445 fp[18] = 0.0f;
3446 fp[19] = 0.0f;
3447 ip[20] = 1013;
3448 ip[21] = 1014;
3449 ip[22] = 1015;
3450 ip[23] = 0;
3451 fp[24] = 1016.0f;
3452 fp[25] = 0.0f;
3453 fp[26] = 0.0f;
3454 fp[27] = 0.0f;
3455 ip[28] = 1017;
3456 ip[29] = 0;
3457 ip[30] = 1018;
3458 ip[31] = 1019;
3459 ip[32] = 1020;
3460 ip[33] = 0;
3461 ip[34] = 0;
3462 ip[35] = 0;
3463 fp[36] = 1021.0f;
3464 fp[37] = 1022.0f;
3465 fp[38] = 0.0f;
3466 fp[39] = 0.0f;
3467 ip[40] = 1023;
3468 ip[41] = 1024;
3469 ip[42] = 1025;
3470 ip[43] = 0;
3471 fp[44] = 1026.0f;
3472 }
3473 /* input 3, std430 */
3474 {
3475 in_data[3].resize(45 * 4);
3476 float* fp = reinterpret_cast<float*>(&in_data[3][0]);
3477 int* ip = reinterpret_cast<int*>(&in_data[3][0]);
3478 ip[0] = 10000;
3479 ip[1] = 0;
3480 ip[2] = 10001;
3481 ip[3] = 10002;
3482 ip[4] = 10003;
3483 ip[5] = 10004;
3484 fp[6] = 10005.0f;
3485 fp[7] = 0.0f;
3486 fp[8] = 10006.0f;
3487 fp[9] = 10007.0f;
3488 fp[10] = 0.0f;
3489 fp[11] = 0.0f;
3490 ip[12] = 10008;
3491 ip[13] = 10009;
3492 ip[14] = 10010;
3493 ip[15] = 0;
3494 fp[16] = 10011.0f;
3495 fp[17] = 10012.0f;
3496 fp[18] = 0.0f;
3497 fp[19] = 0.0f;
3498 ip[20] = 10013;
3499 ip[21] = 10014;
3500 ip[22] = 10015;
3501 ip[23] = 0;
3502 fp[24] = 10016.0f;
3503 fp[25] = 0.0f;
3504 fp[26] = 0.0f;
3505 fp[27] = 0.0f;
3506 ip[28] = 10017;
3507 ip[29] = 0;
3508 ip[30] = 10018;
3509 ip[31] = 10019;
3510 ip[32] = 10020;
3511 ip[33] = 0;
3512 ip[34] = 0;
3513 ip[35] = 0;
3514 fp[36] = 10021.0f;
3515 fp[37] = 10022.0f;
3516 fp[38] = 0.0f;
3517 fp[39] = 0.0f;
3518 ip[40] = 10023;
3519 ip[41] = 10024;
3520 ip[42] = 10025;
3521 ip[43] = 0;
3522 fp[44] = 10026.0f;
3523 }
3524 return NL
3525 "struct Struct0 {" NL " ivec2 data0;" NL "};" NL "struct Struct1 {" NL " vec2 data0;" // offset 0
3526 NL " ivec3 data1;" // offset 16
3527 NL "};" NL "struct Struct2 {" NL " int data0;" // offset 0
3528 NL " Struct0 data1;" // offset std430 8, std140 16
3529 NL " int data2;" // offset std430 16, std140 32
3530 NL " Struct1 data3;" // offset std430 32, std140 48
3531 NL " float data4;" // offset std430 64, std140 80
3532 NL "};" NL "layout(std140, binding = 0) buffer Input01 {" NL " int data0;" // offset 0
3533 NL " Struct0 data1[2];" // offset 16
3534 NL " float data2;" // offset 48
3535 NL " Struct1 data3[2];" // offset 64
3536 NL " float data4;" // offset 128
3537 NL " Struct2 data5;" // offset 144
3538 NL "} g_input01[2];" NL "layout(std430, binding = 2) buffer Input23 {" NL " int data0;" // offset 0
3539 NL " Struct0 data1[2];" // offset 8
3540 NL " float data2;" // offset 24
3541 NL " Struct1 data3[2];" // offset 32
3542 NL " float data4;" // offset 96
3543 NL " Struct2 data5;" // offset 112
3544 NL "} g_input23[2];"
3545
3546 NL "layout(std140, binding = 4) buffer Output01 {" NL " int data0;" NL " Struct0 data1[2];" NL
3547 " float data2;" NL " Struct1 data3[2];" NL " float data4;" NL " Struct2 data5;" NL "} g_output01[2];" NL
3548 "layout(std430, binding = 6) buffer Output23 {" NL " int data0;" NL " Struct0 data1[2];" NL
3549 " float data2;" NL " Struct1 data3[2];" NL " float data4;" NL " Struct2 data5;" NL "} g_output23[2];" NL NL
3550 "void main() {" NL " g_output01[0].data0 = g_input01[0].data0;" NL
3551 " for (int i = 0; i < g_input01[0].data1.length(); ++i) g_output01[0].data1[i] = g_input01[0].data1[i];" NL
3552 " g_output01[0].data2 = g_input01[0].data2;" NL " g_output01[0].data3[0] = g_input01[0].data3[0];" NL
3553 " g_output01[0].data3[1] = g_input01[0].data3[1];" NL " g_output01[0].data4 = g_input01[0].data4;" NL
3554 " g_output01[1].data0 = g_input01[1].data0;" NL
3555 " for (int i = 0; i < g_input01[1].data1.length(); ++i) g_output01[1].data1[i] = g_input01[1].data1[i];" NL
3556 " g_output01[1].data2 = g_input01[1].data2;" NL " g_output01[1].data3[0] = g_input01[1].data3[0];" NL
3557 " g_output01[1].data3[1] = g_input01[1].data3[1];" NL " g_output01[1].data4 = g_input01[1].data4;" NL
3558 " g_output01[0].data5 = g_input01[0].data5;" NL " g_output01[1].data5 = g_input01[1].data5;" NL NL
3559 " g_output23[0].data0 = g_input23[0].data0;" NL
3560 " for (int i = 0; i < g_input23[0].data1.length(); ++i) g_output23[0].data1[i] = g_input23[0].data1[i];" NL
3561 " g_output23[0].data2 = g_input23[0].data2;" NL " g_output23[0].data3[0] = g_input23[0].data3[0];" NL
3562 " g_output23[0].data3[1] = g_input23[0].data3[1];" NL " g_output23[0].data4 = g_input23[0].data4;" NL
3563 " g_output23[1].data0 = g_input23[1].data0;" NL
3564 " for (int i = 0; i < g_input23[1].data1.length(); ++i) g_output23[1].data1[i] = g_input23[1].data1[i];" NL
3565 " g_output23[1].data2 = g_input23[1].data2;" NL " g_output23[1].data3[0] = g_input23[1].data3[0];" NL
3566 " g_output23[1].data3[1] = g_input23[1].data3[1];" NL " g_output23[1].data4 = g_input23[1].data4;" NL
3567 " g_output23[0].data5 = g_input23[0].data5;" NL " g_output23[1].data5 = g_input23[1].data5;" NL "}";
3568 }
3569
3570 class BasicStdLayoutCase4VS : public BasicStdLayoutBase2VS
3571 {
GetInput(std::vector<GLubyte> in_data[4])3572 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3573 {
3574 return GetInputC4(in_data);
3575 }
3576 };
3577
3578 class BasicStdLayoutCase4CS : public BasicStdLayoutBase2CS
3579 {
GetInput(std::vector<GLubyte> in_data[4])3580 virtual const char* GetInput(std::vector<GLubyte> in_data[4])
3581 {
3582 return GetInputC4(in_data);
3583 }
3584 };
3585
3586 //-----------------------------------------------------------------------------
3587 // 1.10.x BasicOperationsBase
3588 //-----------------------------------------------------------------------------
3589 class BasicOperationsBaseVS : public ShaderStorageBufferObjectBase
3590 {
3591 GLuint m_program;
3592 GLuint m_buffer[2];
3593 GLuint m_vertex_array;
3594
3595 virtual const char* GetInput(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data) = 0;
3596
Setup()3597 virtual long Setup()
3598 {
3599 m_program = 0;
3600 memset(m_buffer, 0, sizeof(m_buffer));
3601 m_vertex_array = 0;
3602 return NO_ERROR;
3603 }
3604
Run()3605 virtual long Run()
3606 {
3607 if (!IsVSFSAvailable(2, 0))
3608 return NOT_SUPPORTED;
3609 std::vector<GLubyte> in_data;
3610 std::vector<GLubyte> expected_data;
3611 const char* glsl_vs = GetInput(in_data, expected_data);
3612 const char* const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
3613 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
3614
3615 m_program = CreateProgram(glsl_vs, glsl_fs);
3616 glLinkProgram(m_program);
3617 if (!CheckProgram(m_program))
3618 return ERROR;
3619
3620 glGenBuffers(2, m_buffer);
3621
3622 /* output buffer */
3623 {
3624 std::vector<GLubyte> zero(expected_data.size());
3625 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
3626 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)expected_data.size(), &zero[0], GL_STATIC_DRAW);
3627 }
3628 // input buffer
3629 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
3630 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data.size(), &in_data[0], GL_STATIC_DRAW);
3631
3632 glGenVertexArrays(1, &m_vertex_array);
3633 glEnable(GL_RASTERIZER_DISCARD);
3634
3635 glUseProgram(m_program);
3636 glBindVertexArray(m_vertex_array);
3637
3638 glUniform3f(glGetUniformLocation(m_program, "g_value0"), 10.0, 20.0, 30.0);
3639 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
3640 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
3641
3642 glDrawArrays(GL_POINTS, 0, 1);
3643
3644 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
3645 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3646 GLubyte* out_data =
3647 (GLubyte*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)expected_data.size(), GL_MAP_READ_BIT);
3648 if (!out_data)
3649 return ERROR;
3650
3651 bool status = true;
3652 for (size_t i = 0; i < expected_data.size(); ++i)
3653 {
3654 if (expected_data[i] != out_data[i])
3655 {
3656 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i)
3657 << " is " << tcu::toHex(out_data[i]) << " should be "
3658 << tcu::toHex(expected_data[i]) << tcu::TestLog::EndMessage;
3659 status = false;
3660 }
3661 }
3662 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3663 if (!status)
3664 return ERROR;
3665 return NO_ERROR;
3666 }
3667
Cleanup()3668 virtual long Cleanup()
3669 {
3670 glDisable(GL_RASTERIZER_DISCARD);
3671 glUseProgram(0);
3672 glDeleteProgram(m_program);
3673 glDeleteBuffers(2, m_buffer);
3674 glDeleteVertexArrays(1, &m_vertex_array);
3675 return NO_ERROR;
3676 }
3677 };
3678
3679 class BasicOperationsBaseCS : public ShaderStorageBufferObjectBase
3680 {
3681 GLuint m_program;
3682 GLuint m_buffer[2];
3683
3684 virtual const char* GetInput(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data) = 0;
3685
Setup()3686 virtual long Setup()
3687 {
3688 m_program = 0;
3689 memset(m_buffer, 0, sizeof(m_buffer));
3690 return NO_ERROR;
3691 }
3692
Run()3693 virtual long Run()
3694 {
3695 std::vector<GLubyte> in_data;
3696 std::vector<GLubyte> expected_data;
3697
3698 std::stringstream ss;
3699 ss << "layout(local_size_x = 1) in;\n" << GetInput(in_data, expected_data);
3700 m_program = CreateProgramCS(ss.str());
3701 glLinkProgram(m_program);
3702 if (!CheckProgram(m_program))
3703 return ERROR;
3704
3705 glGenBuffers(2, m_buffer);
3706
3707 /* output buffer */
3708 {
3709 std::vector<GLubyte> zero(expected_data.size());
3710 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
3711 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)expected_data.size(), &zero[0], GL_STATIC_DRAW);
3712 }
3713 // input buffer
3714 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
3715 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data.size(), &in_data[0], GL_STATIC_DRAW);
3716
3717 glUseProgram(m_program);
3718 glUniform3f(glGetUniformLocation(m_program, "g_value0"), 10.0, 20.0, 30.0);
3719 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
3720 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
3721 glDispatchCompute(1, 1, 1);
3722
3723 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
3724 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
3725 GLubyte* out_data =
3726 (GLubyte*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)expected_data.size(), GL_MAP_READ_BIT);
3727 if (!out_data)
3728 return ERROR;
3729
3730 bool status = true;
3731 for (size_t i = 0; i < expected_data.size(); ++i)
3732 {
3733 if (expected_data[i] != out_data[i])
3734 {
3735 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i)
3736 << " is " << tcu::toHex(out_data[i]) << " should be "
3737 << tcu::toHex(expected_data[i]) << tcu::TestLog::EndMessage;
3738 status = false;
3739 }
3740 }
3741 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3742 if (!status)
3743 return ERROR;
3744 return NO_ERROR;
3745 }
3746
Cleanup()3747 virtual long Cleanup()
3748 {
3749 glUseProgram(0);
3750 glDeleteProgram(m_program);
3751 glDeleteBuffers(2, m_buffer);
3752 return NO_ERROR;
3753 }
3754 };
3755
3756 //-----------------------------------------------------------------------------
3757 // 1.10.1 BasicOperationsCase1
3758 //-----------------------------------------------------------------------------
GetInputOp1(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3759 const char* GetInputOp1(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data)
3760 {
3761 /* input */
3762 {
3763 in_data.resize(16 * 9);
3764 int* ip = reinterpret_cast<int*>(&in_data[0]);
3765 float* fp = reinterpret_cast<float*>(&in_data[0]);
3766 ip[0] = 1;
3767 ip[1] = 2;
3768 ip[2] = 3;
3769 ip[3] = 4; // data0
3770 fp[4] = 1.0f;
3771 fp[5] = 2.0f;
3772 fp[6] = 3.0f;
3773 fp[7] = 0.0f; // data1
3774 ip[8] = 1;
3775 ip[9] = 2;
3776 ip[10] = 3;
3777 ip[11] = 4; // data2
3778 ip[12] = 1;
3779 ip[13] = -2;
3780 ip[14] = 3;
3781 ip[15] = 4; // data3
3782 fp[16] = 1.0f;
3783 fp[17] = 2.0f;
3784 fp[18] = 3.0f;
3785 fp[19] = 4.0f; // data4
3786 fp[20] = 1.0f;
3787 fp[21] = 2.0f;
3788 fp[22] = 3.0f;
3789 fp[23] = 4.0f; // data5
3790 fp[24] = 1.0f;
3791 fp[25] = 2.0f;
3792 fp[26] = 3.0f;
3793 fp[27] = 4.0f; // data5
3794 fp[28] = 1.0f;
3795 fp[29] = 2.0f;
3796 fp[30] = 3.0f;
3797 fp[31] = 4.0f; // data5
3798 fp[32] = 1.0f;
3799 fp[33] = 0.0f;
3800 fp[34] = 0.0f;
3801 fp[35] = 4.0f; // data5
3802 }
3803 /* expected output */
3804 {
3805 out_data.resize(16 * 9);
3806 int* ip = reinterpret_cast<int*>(&out_data[0]);
3807 float* fp = reinterpret_cast<float*>(&out_data[0]);
3808 ip[0] = 4;
3809 ip[1] = 3;
3810 ip[2] = 2;
3811 ip[3] = 1;
3812 fp[4] = 3.0f;
3813 fp[5] = 2.0f;
3814 fp[6] = 1.0f;
3815 fp[7] = 0.0f;
3816 ip[8] = 4;
3817 ip[9] = 1;
3818 ip[10] = 0;
3819 ip[11] = 3;
3820 ip[12] = 10;
3821 ip[13] = 4;
3822 ip[14] = -2;
3823 ip[15] = 20;
3824 fp[16] = 50.0f;
3825 fp[17] = 5.0f;
3826 fp[18] = 2.0f;
3827 fp[19] = 30.0f;
3828 fp[20] = 4.0f;
3829 fp[21] = 2.0f;
3830 fp[22] = 3.0f;
3831 fp[23] = 1.0f; // data5
3832 fp[24] = 4.0f;
3833 fp[25] = 3.0f;
3834 fp[26] = 2.0f;
3835 fp[27] = 1.0f; // data5
3836 fp[28] = 2.0f;
3837 fp[29] = 2.0f;
3838 fp[30] = 2.0f;
3839 fp[31] = 2.0f; // data5
3840 fp[32] = 4.0f;
3841 fp[33] = 0.0f;
3842 fp[34] = 0.0f;
3843 fp[35] = 1.0f; // data5
3844 }
3845 return NL "layout(std430, binding = 0) buffer Input {" NL " ivec4 data0;" NL " vec3 data1;" NL " uvec4 data2;" NL
3846 " ivec4 data3;" NL " vec4 data4;" NL " mat4 data5;" NL "} g_input;" NL
3847 "layout(std430, binding = 1) buffer Output {" NL " ivec4 data0;" NL " vec3 data1;" NL
3848 " uvec4 data2;" NL " ivec4 data3;" NL " vec4 data4;" NL " mat4 data5;" NL "} g_output;" NL
3849 "uniform vec3 g_value0;" NL "uniform int g_index1;" NL "void main() {" NL " int index0 = 0;" NL
3850 " g_output.data0.wzyx = g_input.data0;" NL " g_output.data1 = g_input.data1.zyx;" NL
3851 " g_output.data2.xwy = g_input.data2.wzx;" NL " g_output.data3.xw = ivec2(10, 20);" NL
3852 " g_output.data3.zy = g_input.data3.yw;" NL " g_output.data4.wx = g_value0.xz;" // w == 10.0, x == 30.0
3853 NL " g_output.data4.wx += g_value0.yy;" // w == 30.0, x == 50.0
3854 NL " g_output.data4.yz = g_input.data4.xx + g_input.data4.wx;" // y == 5.0, z == 2.0
3855 NL " g_output.data5[g_index1 - 1].wyzx = vec4(1, 2, 3, 4);" NL
3856 " g_output.data5[g_index1 + index0] = g_input.data5[g_index1].wzyx;" NL
3857 " g_output.data5[1 + g_index1] = g_input.data5[g_index1 + 1].yyyy;" NL
3858 " g_output.data5[5 - g_index1 - 1].wx = g_input.data5[4 - g_index1].xw;" NL "}";
3859 }
3860
3861 class BasicOperationsCase1VS : public BasicOperationsBaseVS
3862 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3863 virtual const char* GetInput(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data)
3864 {
3865 return GetInputOp1(in_data, out_data);
3866 }
3867 };
3868
3869 class BasicOperationsCase1CS : public BasicOperationsBaseCS
3870 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3871 virtual const char* GetInput(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data)
3872 {
3873 return GetInputOp1(in_data, out_data);
3874 }
3875 };
3876
3877 //-----------------------------------------------------------------------------
3878 // 1.10.2 BasicOperationsCase2
3879 //-----------------------------------------------------------------------------
GetInputOp2(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3880 const char* GetInputOp2(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data)
3881 {
3882 /* input */
3883 {
3884 in_data.resize(16 * 8);
3885 float* fp = reinterpret_cast<float*>(&in_data[0]);
3886 fp[0] = 1.0f;
3887 fp[1] = 0.0f;
3888 fp[2] = 0.0f;
3889 fp[3] = 0.0f;
3890 fp[4] = 0.0f;
3891 fp[5] = 1.0f;
3892 fp[6] = 0.0f;
3893 fp[7] = 0.0f;
3894 fp[8] = 0.0f;
3895 fp[9] = 0.0f;
3896 fp[10] = 1.0f;
3897 fp[11] = 0.0f;
3898 fp[12] = 0.0f;
3899 fp[13] = 0.0f;
3900 fp[14] = 0.0f;
3901 fp[15] = 1.0f;
3902
3903 fp[16] = 2.0f;
3904 fp[17] = 0.0f;
3905 fp[18] = 0.0f;
3906 fp[19] = 0.0f;
3907 fp[20] = 0.0f;
3908 fp[21] = 3.0f;
3909 fp[22] = 0.0f;
3910 fp[23] = 0.0f;
3911 fp[24] = 0.0f;
3912 fp[25] = 0.0f;
3913 fp[26] = 4.0f;
3914 fp[27] = 0.0f;
3915 fp[28] = 0.0f;
3916 fp[29] = 0.0f;
3917 fp[30] = 0.0f;
3918 fp[31] = 5.0f;
3919 }
3920 /* expected output */
3921 {
3922 out_data.resize(16 * 5);
3923 float* fp = reinterpret_cast<float*>(&out_data[0]);
3924 fp[0] = 2.0f;
3925 fp[1] = 0.0f;
3926 fp[2] = 0.0f;
3927 fp[3] = 0.0f;
3928 fp[4] = 0.0f;
3929 fp[5] = 3.0f;
3930 fp[6] = 0.0f;
3931 fp[7] = 0.0f;
3932 fp[8] = 0.0f;
3933 fp[9] = 0.0f;
3934 fp[10] = 4.0f;
3935 fp[11] = 0.0f;
3936 fp[12] = 0.0f;
3937 fp[13] = 0.0f;
3938 fp[14] = 0.0f;
3939 fp[15] = 5.0f;
3940
3941 fp[16] = 0.0f;
3942 fp[17] = 1.0f;
3943 fp[18] = 4.0f;
3944 fp[19] = 0.0f;
3945 }
3946 return NL "layout(std430, binding = 0) buffer Input {" NL " mat4 data0;" NL " mat4 data1;" NL "} g_input;" NL
3947 "layout(std430, binding = 1) buffer Output {" NL " mat4 data0;" NL " vec4 data1;" NL "} g_output;" NL
3948 "uniform int g_index2;" NL "void main() {" NL
3949 " g_output.data0 = matrixCompMult(g_input.data0, g_input.data1);" NL
3950 " g_output.data1 = g_input.data0[1] + g_input.data1[g_index2];" NL "}";
3951 }
3952
3953 class BasicOperationsCase2VS : public BasicOperationsBaseVS
3954 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3955 virtual const char* GetInput(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data)
3956 {
3957 return GetInputOp2(in_data, out_data);
3958 }
3959 };
3960
3961 class BasicOperationsCase2CS : public BasicOperationsBaseCS
3962 {
GetInput(std::vector<GLubyte> & in_data,std::vector<GLubyte> & out_data)3963 virtual const char* GetInput(std::vector<GLubyte>& in_data, std::vector<GLubyte>& out_data)
3964 {
3965 return GetInputOp2(in_data, out_data);
3966 }
3967 };
3968
3969 //-----------------------------------------------------------------------------
3970 // 1.11.x BasicStdLayoutBase3
3971 //-----------------------------------------------------------------------------
3972 class BasicStdLayoutBase3VS : public ShaderStorageBufferObjectBase
3973 {
3974 GLuint m_program;
3975 GLuint m_buffer[4];
3976 GLuint m_vertex_array;
3977
3978 virtual const char* GetInput(std::vector<GLubyte> in_data[2]) = 0;
3979
Setup()3980 virtual long Setup()
3981 {
3982 m_program = 0;
3983 memset(m_buffer, 0, sizeof(m_buffer));
3984 m_vertex_array = 0;
3985 return NO_ERROR;
3986 }
3987
Run()3988 virtual long Run()
3989 {
3990 if (!IsVSFSAvailable(4, 0))
3991 return NOT_SUPPORTED;
3992 std::vector<GLubyte> in_data[2];
3993 const char* glsl_vs = GetInput(in_data);
3994 const char* const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
3995 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
3996
3997 m_program = CreateProgram(glsl_vs, glsl_fs);
3998 glLinkProgram(m_program);
3999 if (!CheckProgram(m_program))
4000 return ERROR;
4001
4002 glGenBuffers(4, m_buffer);
4003
4004 // input buffers
4005 glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_buffer[0]);
4006 glBufferData(GL_UNIFORM_BUFFER, (GLsizeiptr)in_data[0].size(), &in_data[0][0], GL_STATIC_DRAW);
4007
4008 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]);
4009 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &in_data[1][0], GL_STATIC_DRAW);
4010
4011 /* output buffer 0 */
4012 {
4013 std::vector<GLubyte> out_data(in_data[0].size());
4014 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[2]);
4015 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[0].size(), &out_data[0], GL_STATIC_DRAW);
4016 }
4017 /* output buffer 1 */
4018 {
4019 std::vector<GLubyte> out_data(in_data[1].size());
4020 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]);
4021 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &out_data[0], GL_STATIC_DRAW);
4022 }
4023
4024 glGenVertexArrays(1, &m_vertex_array);
4025 glEnable(GL_RASTERIZER_DISCARD);
4026
4027 glUseProgram(m_program);
4028 glBindVertexArray(m_vertex_array);
4029
4030 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
4031
4032 glDrawArrays(GL_POINTS, 0, 1);
4033
4034 bool status = true;
4035 for (int j = 0; j < 2; ++j)
4036 {
4037 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 2]);
4038 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4039 GLubyte* out_data =
4040 (GLubyte*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(), GL_MAP_READ_BIT);
4041 if (!out_data)
4042 return ERROR;
4043
4044 for (size_t i = 0; i < in_data[j].size(); ++i)
4045 {
4046 if (in_data[j][i] != out_data[i])
4047 {
4048 m_context.getTestContext().getLog()
4049 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
4050 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
4051 << tcu::TestLog::EndMessage;
4052 status = false;
4053 }
4054 }
4055 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4056 }
4057 if (!status)
4058 return ERROR;
4059 return NO_ERROR;
4060 }
Cleanup()4061 virtual long Cleanup()
4062 {
4063 glDisable(GL_RASTERIZER_DISCARD);
4064 glUseProgram(0);
4065 glDeleteProgram(m_program);
4066 glDeleteBuffers(4, m_buffer);
4067 glDeleteVertexArrays(1, &m_vertex_array);
4068 return NO_ERROR;
4069 }
4070 };
4071
4072 class BasicStdLayoutBase3CS : public ShaderStorageBufferObjectBase
4073 {
4074 GLuint m_program;
4075 GLuint m_buffer[4];
4076
4077 virtual const char* GetInput(std::vector<GLubyte> in_data[2]) = 0;
4078
Setup()4079 virtual long Setup()
4080 {
4081 m_program = 0;
4082 memset(m_buffer, 0, sizeof(m_buffer));
4083 return NO_ERROR;
4084 }
Run()4085 virtual long Run()
4086 {
4087 std::vector<GLubyte> in_data[2];
4088
4089 std::stringstream ss;
4090 ss << "layout(local_size_x = 1) in;\n" << GetInput(in_data);
4091 m_program = CreateProgramCS(ss.str());
4092 glLinkProgram(m_program);
4093 if (!CheckProgram(m_program))
4094 return ERROR;
4095
4096 glGenBuffers(4, m_buffer);
4097
4098 // input buffers
4099 glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_buffer[0]);
4100 glBufferData(GL_UNIFORM_BUFFER, (GLsizeiptr)in_data[0].size(), &in_data[0][0], GL_STATIC_DRAW);
4101
4102 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]);
4103 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &in_data[1][0], GL_STATIC_DRAW);
4104
4105 /* output buffer 0 */
4106 {
4107 std::vector<GLubyte> out_data(in_data[0].size());
4108 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[2]);
4109 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[0].size(), &out_data[0], GL_STATIC_DRAW);
4110 }
4111 /* output buffer 1 */
4112 {
4113 std::vector<GLubyte> out_data(in_data[1].size());
4114 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]);
4115 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)in_data[1].size(), &out_data[0], GL_STATIC_DRAW);
4116 }
4117
4118 glUseProgram(m_program);
4119 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
4120 glDispatchCompute(1, 1, 1);
4121
4122 bool status = true;
4123 for (int j = 0; j < 2; ++j)
4124 {
4125 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[j + 2]);
4126 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4127 GLubyte* out_data =
4128 (GLubyte*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)in_data[j].size(), GL_MAP_READ_BIT);
4129 if (!out_data)
4130 return ERROR;
4131
4132 for (size_t i = 0; i < in_data[j].size(); ++i)
4133 {
4134 if (in_data[j][i] != out_data[i])
4135 {
4136 m_context.getTestContext().getLog()
4137 << tcu::TestLog::Message << "Byte at index " << static_cast<int>(i) << " is "
4138 << tcu::toHex(out_data[i]) << " should be " << tcu::toHex(in_data[j][i])
4139 << tcu::TestLog::EndMessage;
4140 status = false;
4141 }
4142 }
4143 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4144 }
4145 if (!status)
4146 return ERROR;
4147 return NO_ERROR;
4148 }
Cleanup()4149 virtual long Cleanup()
4150 {
4151 glUseProgram(0);
4152 glDeleteProgram(m_program);
4153 glDeleteBuffers(4, m_buffer);
4154 return NO_ERROR;
4155 }
4156 };
4157
4158 //-----------------------------------------------------------------------------
4159 // 1.11.1 Basic_UBO_SSBO_LayoutCase1
4160 //-----------------------------------------------------------------------------
GetInputUBO1(std::vector<GLubyte> in_data[2])4161 const char* GetInputUBO1(std::vector<GLubyte> in_data[2])
4162 {
4163 /* UBO */
4164 {
4165 in_data[0].resize(12 * 4);
4166 float* fp = reinterpret_cast<float*>(&in_data[0][0]);
4167 fp[0] = 1.0f;
4168 fp[1] = 0.0f;
4169 fp[2] = 0.0f;
4170 fp[3] = 0.0f;
4171 fp[4] = 2.0f;
4172 fp[5] = 0.0f;
4173 fp[6] = 0.0f;
4174 fp[7] = 0.0f;
4175 fp[8] = 3.0f;
4176 fp[9] = 0.0f;
4177 fp[10] = 0.0f;
4178 fp[11] = 0.0f;
4179 }
4180 /* SSBO */
4181 {
4182 in_data[1].resize(3 * 4);
4183 float* fp = reinterpret_cast<float*>(&in_data[1][0]);
4184 fp[0] = 1.0f;
4185 fp[1] = 2.0f;
4186 fp[2] = 3.0f;
4187 }
4188 return NL
4189 "layout(std140, binding = 0) uniform InputUBO {" NL " float data0;" NL " float data1[2];" NL
4190 "} g_input_ubo;" NL "layout(std430, binding = 0) buffer InputSSBO {" NL " float data0;" NL
4191 " float data1[2];" NL "} g_input_ssbo;" NL "layout(std140, binding = 1) buffer OutputUBO {" NL
4192 " float data0;" NL " float data1[2];" NL "} g_output_ubo;" NL
4193 "layout(std430, binding = 2) buffer OutputSSBO {" NL " float data0;" NL " float data1[2];" NL
4194 "} g_output_ssbo;" NL "void main() {" NL " g_output_ubo.data0 = g_input_ubo.data0;" NL
4195 " for (int i = 0; i < g_input_ubo.data1.length(); ++i) g_output_ubo.data1[i] = g_input_ubo.data1[i];" NL
4196 " g_output_ssbo.data0 = g_input_ssbo.data0;" NL
4197 " for (int i = 0; i < g_input_ssbo.data1.length(); ++i) g_output_ssbo.data1[i] = g_input_ssbo.data1[i];" NL
4198 "}";
4199 }
4200
4201 class Basic_UBO_SSBO_LayoutCase1VS : public BasicStdLayoutBase3VS
4202 {
GetInput(std::vector<GLubyte> in_data[2])4203 virtual const char* GetInput(std::vector<GLubyte> in_data[2])
4204 {
4205 return GetInputUBO1(in_data);
4206 }
4207 };
4208
4209 class Basic_UBO_SSBO_LayoutCase1CS : public BasicStdLayoutBase3CS
4210 {
GetInput(std::vector<GLubyte> in_data[2])4211 virtual const char* GetInput(std::vector<GLubyte> in_data[2])
4212 {
4213 return GetInputUBO1(in_data);
4214 }
4215 };
4216
4217 //-----------------------------------------------------------------------------
4218 // 1.11.2 Basic_UBO_SSBO_LayoutCase2
4219 //-----------------------------------------------------------------------------
GetInputUBO2(std::vector<GLubyte> in_data[2])4220 const char* GetInputUBO2(std::vector<GLubyte> in_data[2])
4221 {
4222 /* UBO */
4223 {
4224 in_data[0].resize(280 * 4);
4225 float* fp = reinterpret_cast<float*>(&in_data[0][0]);
4226 int* ip = reinterpret_cast<int*>(&in_data[0][0]);
4227 fp[0] = 1.0f;
4228 fp[1] = 2.0f;
4229 fp[2] = 3.0f;
4230 fp[3] = 4.0f;
4231 fp[4] = 5.0f;
4232 fp[5] = 6.0f;
4233 fp[6] = 7.0f;
4234 fp[8] = 9.0f;
4235 fp[12] = 10.0f;
4236 fp[16] = 11.0f;
4237 fp[20] = 12.0f;
4238 fp[24] = 13.0f;
4239
4240 ip[28] = 14;
4241 for (int i = 0; i < 20; ++i)
4242 {
4243 fp[32 + i * 4] = static_cast<float>(15 + i);
4244 }
4245 ip[112] = 140;
4246 for (int i = 0; i < 20; ++i)
4247 {
4248 fp[116 + i * 4] = static_cast<float>(150 + i);
4249 }
4250 ip[196] = 1400;
4251 for (int i = 0; i < 20; ++i)
4252 {
4253 fp[200 + i * 4] = static_cast<float>(1500 + i);
4254 }
4255 }
4256 /* SSBO */
4257 {
4258 in_data[1].resize(76 * 4);
4259 float* fp = reinterpret_cast<float*>(&in_data[1][0]);
4260 int* ip = reinterpret_cast<int*>(&in_data[1][0]);
4261 fp[0] = 1.0f;
4262 fp[1] = 2.0f;
4263 fp[2] = 3.0f;
4264 fp[3] = 4.0f;
4265 fp[4] = 5.0f;
4266 fp[5] = 6.0f;
4267 fp[6] = 7.0f;
4268 fp[7] = 8.0f;
4269 fp[8] = 9.0f;
4270 fp[9] = 10.0f;
4271 fp[10] = 11.0f;
4272 fp[11] = 12.0f;
4273 fp[12] = 13.0f;
4274 ip[13] = 14;
4275 fp[14] = 15.0f;
4276 fp[15] = 16.0f;
4277 fp[16] = 17.0f;
4278 fp[17] = 18.0f;
4279 fp[18] = 19.0f;
4280 fp[19] = 20.0f;
4281 fp[20] = 21.0f;
4282 fp[21] = 22.0f;
4283 fp[22] = 23.0f;
4284 fp[23] = 24.0f;
4285 fp[24] = 25.0f;
4286 fp[25] = 26.0f;
4287 fp[26] = 27.0f;
4288 fp[27] = 28.0f;
4289 fp[28] = 29.0f;
4290 fp[29] = 30.0f;
4291 fp[30] = 31.0f;
4292 fp[31] = 32.0f;
4293 fp[32] = 33.0f;
4294 fp[33] = 34.0f;
4295 ip[34] = 35;
4296 fp[35] = 36.0f;
4297 fp[36] = 37.0f;
4298 fp[37] = 38.0f;
4299 fp[38] = 39.0f;
4300 fp[39] = 40.0f;
4301 fp[40] = 41.0f;
4302 fp[41] = 42.0f;
4303 fp[42] = 43.0f;
4304 fp[43] = 44.0f;
4305 fp[44] = 45.0f;
4306 fp[45] = 46.0f;
4307 fp[46] = 47.0f;
4308 fp[47] = 48.0f;
4309 fp[48] = 49.0f;
4310 fp[49] = 50.0f;
4311 fp[50] = 51.0f;
4312 fp[51] = 52.0f;
4313 fp[52] = 53.0f;
4314 fp[53] = 54.0f;
4315 fp[54] = 55.0f;
4316 ip[55] = 56;
4317 fp[56] = 57.0f;
4318 fp[57] = 58.0f;
4319 fp[58] = 59.0f;
4320 fp[59] = 60.0f;
4321 fp[60] = 61.0f;
4322 fp[61] = 62.0f;
4323 fp[62] = 63.0f;
4324 fp[63] = 64.0f;
4325 fp[64] = 65.0f;
4326 fp[65] = 66.0f;
4327 fp[66] = 67.0f;
4328 fp[67] = 68.0f;
4329 fp[68] = 69.0f;
4330 fp[69] = 70.0f;
4331 fp[70] = 71.0f;
4332 fp[71] = 72.0f;
4333 fp[72] = 73.0f;
4334 fp[73] = 74.0f;
4335 fp[74] = 75.0f;
4336 fp[75] = 76.0f;
4337 }
4338 return NL
4339 "struct MM {" NL " float mm_a[5];" NL "};" NL "struct TT {" NL " int tt_a;" NL " MM tt_b[4];" NL "};" NL
4340 "layout(std140, binding = 0) uniform InputUBO {" NL " vec4 a;" NL " vec4 b;" NL " float c;" NL
4341 " float d[4];" NL " TT e[3];" NL "} g_input_ubo;" NL "layout(std430, binding = 0) buffer InputSSBO {" NL
4342 " vec4 a;" NL " vec4 b;" NL " float c;" NL " float d[4];" NL " TT e[3];" NL "} g_input_ssbo;" NL
4343 "layout(std140, binding = 1) buffer OutputUBO {" NL " vec4 a;" NL " vec4 b;" NL " float c;" NL
4344 " float d[4];" NL " TT e[3];" NL "} g_output_ubo;" NL "layout(std430, binding = 2) buffer OutputSSBO {" NL
4345 " vec4 a;" NL " vec4 b;" NL " float c;" NL " float d[4];" NL " TT e[3];" NL "} g_output_ssbo;" NL
4346 "uniform int g_index1;" NL "void main() {" NL " int index0 = 0;" NL NL " g_output_ubo.a = g_input_ubo.a;" NL
4347 " g_output_ubo.b = g_input_ubo.b;" NL " g_output_ubo.c = g_input_ubo.c;" NL
4348 " for (int i = 0; i < g_input_ubo.d.length(); ++i) g_output_ubo.d[i] = g_input_ubo.d[i];" NL
4349 " for (int j = 0; j < g_input_ubo.e.length(); ++j) {" NL
4350 " g_output_ubo.e[j].tt_a = g_input_ubo.e[j].tt_a;" NL
4351 " for (int i = 0; i < g_input_ubo.e[j].tt_b.length(); ++i) {" NL
4352 " g_output_ubo.e[j].tt_b[i].mm_a[0] = g_input_ubo.e[j].tt_b[i].mm_a[0];" NL
4353 " g_output_ubo.e[j].tt_b[index0 + i].mm_a[1] = g_input_ubo.e[j].tt_b[i].mm_a[1];" NL
4354 " g_output_ubo.e[j].tt_b[i].mm_a[2] = g_input_ubo.e[j].tt_b[i].mm_a[2 + index0];" NL
4355 " 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 + "
4356 "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
4357 " }" NL " }" NL NL " g_output_ssbo.a = g_input_ssbo.a;" NL " g_output_ssbo.b = g_input_ssbo.b;" NL
4358 " g_output_ssbo.c = g_input_ssbo.c;" NL
4359 " for (int i = 0; i < g_input_ssbo.d.length(); ++i) g_output_ssbo.d[i] = g_input_ssbo.d[i];" NL
4360 " for (int j = 0; j < g_input_ssbo.e.length(); ++j) {" NL
4361 " g_output_ssbo.e[j].tt_a = g_input_ssbo.e[j].tt_a;" NL
4362 " for (int i = 0; i < g_input_ssbo.e[j].tt_b.length(); ++i) {" NL
4363 " g_output_ssbo.e[j + index0].tt_b[i].mm_a[0] = g_input_ssbo.e[j].tt_b[i].mm_a[index0];" NL
4364 " 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
4365 " 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
4366 " 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 - "
4367 "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
4368 " }" NL "}";
4369 }
4370
4371 class Basic_UBO_SSBO_LayoutCase2VS : public BasicStdLayoutBase3VS
4372 {
GetInput(std::vector<GLubyte> in_data[2])4373 virtual const char* GetInput(std::vector<GLubyte> in_data[2])
4374 {
4375 return GetInputUBO2(in_data);
4376 }
4377 };
4378
4379 class Basic_UBO_SSBO_LayoutCase2CS : public BasicStdLayoutBase3CS
4380 {
GetInput(std::vector<GLubyte> in_data[2])4381 virtual const char* GetInput(std::vector<GLubyte> in_data[2])
4382 {
4383 return GetInputUBO2(in_data);
4384 }
4385 };
4386
4387 //-----------------------------------------------------------------------------
4388 // 1.12.x BasicMatrixOperationsBase
4389 //-----------------------------------------------------------------------------
4390 class BasicMatrixOperationsBaseVS : public ShaderStorageBufferObjectBase
4391 {
4392 GLuint m_program;
4393 GLuint m_buffer[2];
4394 GLuint m_vertex_array;
4395
4396 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected) = 0;
4397
Equal(float a,float b)4398 static bool Equal(float a, float b)
4399 {
4400 return fabsf(a - b) < 0.001f;
4401 }
Setup()4402 virtual long Setup()
4403 {
4404 m_program = 0;
4405 memset(m_buffer, 0, sizeof(m_buffer));
4406 m_vertex_array = 0;
4407 return NO_ERROR;
4408 }
Run()4409 virtual long Run()
4410 {
4411 if (!IsVSFSAvailable(2, 0))
4412 return NOT_SUPPORTED;
4413 std::vector<float> in;
4414 std::vector<float> expected;
4415 const char* glsl_vs = GetInput(in, expected);
4416 const char* const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
4417 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
4418
4419 m_program = CreateProgram(glsl_vs, glsl_fs);
4420 glLinkProgram(m_program);
4421 if (!CheckProgram(m_program))
4422 return ERROR;
4423
4424 glGenBuffers(2, m_buffer);
4425
4426 /* output buffer */
4427 {
4428 std::vector<float> zero(expected.size());
4429 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
4430 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(expected.size() * sizeof(float)), &zero[0],
4431 GL_STATIC_DRAW);
4432 }
4433 // input buffer
4434 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
4435 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(in.size() * sizeof(float)), &in[0], GL_STATIC_DRAW);
4436
4437 glGenVertexArrays(1, &m_vertex_array);
4438 glEnable(GL_RASTERIZER_DISCARD);
4439
4440 glUseProgram(m_program);
4441 glBindVertexArray(m_vertex_array);
4442 glDrawArrays(GL_POINTS, 0, 1);
4443
4444 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
4445 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4446 float* out_data = (float*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
4447 (GLsizeiptr)(expected.size() * sizeof(float)), GL_MAP_READ_BIT);
4448 if (!out_data)
4449 return ERROR;
4450
4451 bool status = true;
4452 for (size_t i = 0; i < expected.size(); ++i)
4453 {
4454 if (!Equal(expected[i], out_data[i]))
4455 {
4456 m_context.getTestContext().getLog()
4457 << tcu::TestLog::Message << "Float at index " << static_cast<int>(i) << " is " << out_data[i]
4458 << " should be " << expected[i] << tcu::TestLog::EndMessage;
4459 status = false;
4460 }
4461 }
4462 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4463 if (!status)
4464 return ERROR;
4465 return NO_ERROR;
4466 }
Cleanup()4467 virtual long Cleanup()
4468 {
4469 glDisable(GL_RASTERIZER_DISCARD);
4470 glUseProgram(0);
4471 glDeleteProgram(m_program);
4472 glDeleteBuffers(2, m_buffer);
4473 glDeleteVertexArrays(1, &m_vertex_array);
4474 return NO_ERROR;
4475 }
4476 };
4477
4478 class BasicMatrixOperationsBaseCS : public ShaderStorageBufferObjectBase
4479 {
4480 GLuint m_program;
4481 GLuint m_buffer[2];
4482
4483 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected) = 0;
4484
Equal(float a,float b)4485 static bool Equal(float a, float b)
4486 {
4487 return fabsf(a - b) < 0.001f;
4488 }
4489
Setup()4490 virtual long Setup()
4491 {
4492 m_program = 0;
4493 memset(m_buffer, 0, sizeof(m_buffer));
4494 return NO_ERROR;
4495 }
4496
Run()4497 virtual long Run()
4498 {
4499 std::vector<float> in;
4500 std::vector<float> expected;
4501 std::stringstream ss;
4502 ss << "layout(local_size_x = 1) in;\n" << GetInput(in, expected);
4503 m_program = CreateProgramCS(ss.str());
4504 glLinkProgram(m_program);
4505 if (!CheckProgram(m_program))
4506 return ERROR;
4507
4508 glGenBuffers(2, m_buffer);
4509
4510 /* output buffer */
4511 {
4512 std::vector<float> zero(expected.size());
4513 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
4514 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(expected.size() * sizeof(float)), &zero[0],
4515 GL_STATIC_DRAW);
4516 }
4517 // input buffer
4518 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
4519 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(in.size() * sizeof(float)), &in[0], GL_STATIC_DRAW);
4520
4521 glUseProgram(m_program);
4522 glDispatchCompute(1, 1, 1);
4523
4524 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[1]);
4525 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4526 float* out_data = (float*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
4527 (GLsizeiptr)(expected.size() * sizeof(float)), GL_MAP_READ_BIT);
4528 if (!out_data)
4529 return ERROR;
4530
4531 bool status = true;
4532 for (size_t i = 0; i < expected.size(); ++i)
4533 {
4534 if (!Equal(expected[i], out_data[i]))
4535 {
4536 m_context.getTestContext().getLog()
4537 << tcu::TestLog::Message << "Float at index " << static_cast<int>(i) << " is " << out_data[i]
4538 << " should be " << expected[i] << tcu::TestLog::EndMessage;
4539 status = false;
4540 }
4541 }
4542 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4543 if (!status)
4544 return ERROR;
4545 return NO_ERROR;
4546 }
4547
Cleanup()4548 virtual long Cleanup()
4549 {
4550 glUseProgram(0);
4551 glDeleteProgram(m_program);
4552 glDeleteBuffers(2, m_buffer);
4553 return NO_ERROR;
4554 }
4555 };
4556
4557 //-----------------------------------------------------------------------------
4558 // 1.12.1 BasicMatrixOperationsCase1
4559 //-----------------------------------------------------------------------------
GetInputM1(std::vector<float> & in,std::vector<float> & expected)4560 const char* GetInputM1(std::vector<float>& in, std::vector<float>& expected)
4561 {
4562 in.resize(8);
4563 in[0] = 1.0f;
4564 in[2] = 3.0f;
4565 in[1] = 2.0f;
4566 in[3] = 4.0f;
4567 in[4] = 1.0f;
4568 in[6] = 3.0f;
4569 in[5] = 2.0f;
4570 in[7] = 4.0f;
4571 expected.resize(4);
4572 expected[0] = 7.0f;
4573 expected[2] = 15.0f;
4574 expected[1] = 10.0f;
4575 expected[3] = 22.0f;
4576 return NL "layout(std430, binding = 0) buffer Input {" NL " mat2 m0;" NL " mat2 m1;" NL "} g_input;" NL
4577 "layout(std430, binding = 1) buffer Output {" NL " mat2 m;" NL "} g_output;" NL
4578 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4579 }
4580
4581 class BasicMatrixOperationsCase1VS : public BasicMatrixOperationsBaseVS
4582 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4583 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4584 {
4585 return GetInputM1(in, expected);
4586 }
4587 };
4588
4589 class BasicMatrixOperationsCase1CS : public BasicMatrixOperationsBaseCS
4590 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4591 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4592 {
4593 return GetInputM1(in, expected);
4594 }
4595 };
4596
4597 //-----------------------------------------------------------------------------
4598 // 1.12.2 BasicMatrixOperationsCase2
4599 //-----------------------------------------------------------------------------
GetInputM2(std::vector<float> & in,std::vector<float> & expected)4600 const char* GetInputM2(std::vector<float>& in, std::vector<float>& expected)
4601 {
4602 in.resize(15);
4603 expected.resize(4);
4604 // mat3x2
4605 in[0] = 1.0f;
4606 in[2] = 3.0f;
4607 in[4] = 5.0f;
4608 in[1] = 2.0f;
4609 in[3] = 4.0f;
4610 in[5] = 6.0f;
4611 // mat2x3
4612 in[8] = 1.0f;
4613 in[12] = 4.0f;
4614 in[9] = 2.0f;
4615 in[13] = 5.0f;
4616 in[10] = 3.0f;
4617 in[14] = 6.0f;
4618 // mat2
4619 expected[0] = 22.0f;
4620 expected[2] = 49.0f;
4621 expected[1] = 28.0f;
4622 expected[3] = 64.0f;
4623 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(column_major) mat3x2 m0;" NL
4624 " layout(column_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4625 " layout(column_major) mat2 m;" NL "} g_output;" NL
4626 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4627 }
4628
4629 class BasicMatrixOperationsCase2VS : public BasicMatrixOperationsBaseVS
4630 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4631 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4632 {
4633 return GetInputM2(in, expected);
4634 }
4635 };
4636
4637 class BasicMatrixOperationsCase2CS : public BasicMatrixOperationsBaseCS
4638 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4639 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4640 {
4641 return GetInputM2(in, expected);
4642 }
4643 };
4644
4645 //-----------------------------------------------------------------------------
4646 // 1.12.3 BasicMatrixOperationsCase3
4647 //-----------------------------------------------------------------------------
GetInputM3(std::vector<float> & in,std::vector<float> & expected)4648 const char* GetInputM3(std::vector<float>& in, std::vector<float>& expected)
4649 {
4650 in.resize(15);
4651 expected.resize(4);
4652 // row major mat3x2
4653 in[0] = 1.0f;
4654 in[1] = 3.0f;
4655 in[2] = 5.0f;
4656 in[4] = 2.0f;
4657 in[5] = 4.0f;
4658 in[6] = 6.0f;
4659 // row major mat2x3
4660 in[8] = 1.0f;
4661 in[9] = 4.0f;
4662 in[10] = 2.0f;
4663 in[11] = 5.0f;
4664 in[12] = 3.0f;
4665 in[13] = 6.0f;
4666 // row major mat2
4667 expected[0] = 22.0f;
4668 expected[1] = 49.0f;
4669 expected[2] = 28.0f;
4670 expected[3] = 64.0f;
4671 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(row_major) mat3x2 m0;" NL
4672 " layout(row_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4673 " layout(row_major) mat2 m;" NL "} g_output;" NL "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4674 }
4675
4676 class BasicMatrixOperationsCase3VS : public BasicMatrixOperationsBaseVS
4677 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4678 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4679 {
4680 return GetInputM3(in, expected);
4681 }
4682 };
4683
4684 class BasicMatrixOperationsCase3CS : public BasicMatrixOperationsBaseCS
4685 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4686 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4687 {
4688 return GetInputM3(in, expected);
4689 }
4690 };
4691
4692 //-----------------------------------------------------------------------------
4693 // 1.12.4 BasicMatrixOperationsCase4
4694 //-----------------------------------------------------------------------------
GetInputM4(std::vector<float> & in,std::vector<float> & expected)4695 const char* GetInputM4(std::vector<float>& in, std::vector<float>& expected)
4696 {
4697 in.resize(15);
4698 expected.resize(4);
4699 // column major mat3x2
4700 in[0] = 1.0f;
4701 in[2] = 3.0f;
4702 in[4] = 5.0f;
4703 in[1] = 2.0f;
4704 in[3] = 4.0f;
4705 in[5] = 6.0f;
4706 // row major mat2x3
4707 in[8] = 1.0f;
4708 in[9] = 4.0f;
4709 in[10] = 2.0f;
4710 in[11] = 5.0f;
4711 in[12] = 3.0f;
4712 in[13] = 6.0f;
4713 // column major mat2
4714 expected[0] = 13.0f;
4715 expected[1] = 16.0f;
4716 expected[2] = 37.0f;
4717 expected[3] = 46.0f;
4718 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(column_major) mat3x2 m0;" NL
4719 " layout(row_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4720 " layout(column_major) mat2 m;" NL "} g_output;" NL
4721 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4722 }
4723
4724 class BasicMatrixOperationsCase4VS : public BasicMatrixOperationsBaseVS
4725 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4726 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4727 {
4728 return GetInputM4(in, expected);
4729 }
4730 };
4731
4732 class BasicMatrixOperationsCase4CS : public BasicMatrixOperationsBaseCS
4733 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4734 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4735 {
4736 return GetInputM4(in, expected);
4737 }
4738 };
4739
4740 //-----------------------------------------------------------------------------
4741 // 1.12.5 BasicMatrixOperationsCase5
4742 //-----------------------------------------------------------------------------
GetInputM5(std::vector<float> & in,std::vector<float> & expected)4743 const char* GetInputM5(std::vector<float>& in, std::vector<float>& expected)
4744 {
4745 in.resize(15);
4746 expected.resize(4);
4747 // column major mat3x2
4748 in[0] = 1.0f;
4749 in[2] = 3.0f;
4750 in[4] = 5.0f;
4751 in[1] = 2.0f;
4752 in[3] = 4.0f;
4753 in[5] = 6.0f;
4754 // row major mat2x3
4755 in[8] = 1.0f;
4756 in[9] = 4.0f;
4757 in[10] = 2.0f;
4758 in[11] = 5.0f;
4759 in[12] = 3.0f;
4760 in[13] = 6.0f;
4761 // row major mat2
4762 expected[0] = 13.0f;
4763 expected[1] = 37.0f;
4764 expected[2] = 16.0f;
4765 expected[3] = 46.0f;
4766 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(column_major) mat3x2 m0;" NL
4767 " layout(row_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4768 " layout(row_major) mat2 m;" NL "} g_output;" NL "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4769 }
4770
4771 class BasicMatrixOperationsCase5VS : public BasicMatrixOperationsBaseVS
4772 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4773 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4774 {
4775 return GetInputM5(in, expected);
4776 }
4777 };
4778
4779 class BasicMatrixOperationsCase5CS : public BasicMatrixOperationsBaseCS
4780 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4781 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4782 {
4783 return GetInputM5(in, expected);
4784 }
4785 };
4786 //-----------------------------------------------------------------------------
4787 // 1.12.6 BasicMatrixOperationsCase6
4788 //-----------------------------------------------------------------------------
GetInputM6(std::vector<float> & in,std::vector<float> & expected)4789 const char* GetInputM6(std::vector<float>& in, std::vector<float>& expected)
4790 {
4791 in.resize(20);
4792 expected.resize(4);
4793 // row major mat3x2
4794 in[0] = 1.0f;
4795 in[1] = 3.0f;
4796 in[2] = 5.0f;
4797 in[4] = 2.0f;
4798 in[5] = 4.0f;
4799 in[6] = 6.0f;
4800 // column major mat2x3
4801 in[8] = 1.0f;
4802 in[12] = 4.0f;
4803 in[9] = 2.0f;
4804 in[13] = 5.0f;
4805 in[10] = 3.0f;
4806 in[14] = 6.0f;
4807 // column major mat2
4808 expected[0] = 22.0f;
4809 expected[1] = 28.0f;
4810 expected[2] = 49.0f;
4811 expected[3] = 64.0f;
4812 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(row_major) mat3x2 m0;" NL
4813 " layout(column_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4814 " layout(column_major) mat2 m;" NL "} g_output;" NL
4815 "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4816 }
4817
4818 class BasicMatrixOperationsCase6VS : public BasicMatrixOperationsBaseVS
4819 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4820 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4821 {
4822 return GetInputM6(in, expected);
4823 }
4824 };
4825
4826 class BasicMatrixOperationsCase6CS : public BasicMatrixOperationsBaseCS
4827 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4828 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4829 {
4830 return GetInputM6(in, expected);
4831 }
4832 };
4833
4834 //-----------------------------------------------------------------------------
4835 // 1.12.7 BasicMatrixOperationsCase7
4836 //-----------------------------------------------------------------------------
GetInputM7(std::vector<float> & in,std::vector<float> & expected)4837 const char* GetInputM7(std::vector<float>& in, std::vector<float>& expected)
4838 {
4839 in.resize(20);
4840 expected.resize(4);
4841 // row major mat3x2
4842 in[0] = 1.0f;
4843 in[1] = 3.0f;
4844 in[2] = 5.0f;
4845 in[4] = 2.0f;
4846 in[5] = 4.0f;
4847 in[6] = 6.0f;
4848 // column major mat2x3
4849 in[8] = 1.0f;
4850 in[12] = 4.0f;
4851 in[9] = 2.0f;
4852 in[13] = 5.0f;
4853 in[10] = 3.0f;
4854 in[14] = 6.0f;
4855 // row major mat2
4856 expected[0] = 22.0f;
4857 expected[1] = 49.0f;
4858 expected[2] = 28.0f;
4859 expected[3] = 64.0f;
4860 return NL "layout(std430, binding = 0) buffer Input {" NL " layout(row_major) mat3x2 m0;" NL
4861 " layout(column_major) mat2x3 m1;" NL "} g_input;" NL "layout(std430, binding = 1) buffer Output {" NL
4862 " layout(row_major) mat2 m;" NL "} g_output;" NL "void main() { g_output.m = g_input.m0 * g_input.m1; }";
4863 }
4864
4865 class BasicMatrixOperationsCase7VS : public BasicMatrixOperationsBaseVS
4866 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4867 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4868 {
4869 return GetInputM7(in, expected);
4870 }
4871 };
4872
4873 class BasicMatrixOperationsCase7CS : public BasicMatrixOperationsBaseCS
4874 {
GetInput(std::vector<float> & in,std::vector<float> & expected)4875 virtual const char* GetInput(std::vector<float>& in, std::vector<float>& expected)
4876 {
4877 return GetInputM7(in, expected);
4878 }
4879 };
4880
4881 //----------------------------------------------------------------------------
4882 // 1.13 BasicReadonlyWriteonly
4883 //-----------------------------------------------------------------------------
4884 class BasicReadonlyWriteonly : public ShaderStorageBufferObjectBase
4885 {
4886 GLuint m_program;
4887 GLuint m_storage_buffer[2];
4888
Setup()4889 virtual long Setup()
4890 {
4891 m_program = 0;
4892 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
4893 return NO_ERROR;
4894 }
4895
Run()4896 virtual long Run()
4897 {
4898 const char* const glsl_cs =
4899 NL "layout(local_size_x = 1) in;" NL "layout(std430, binding = 0) buffer Input {" NL
4900 " readonly writeonly int g_in[];" NL "};" NL "layout(std430, binding = 1) buffer Output {" NL
4901 " int count;" NL "} g_output;" NL "void main() {" NL " g_output.count = g_in.length();" NL "}";
4902
4903 m_program = CreateProgramCS(glsl_cs);
4904 glLinkProgram(m_program);
4905 if (!CheckProgram(m_program))
4906 return ERROR;
4907
4908 glGenBuffers(2, m_storage_buffer);
4909
4910 /* Input */
4911 int input_data[] = { 1, 2, 3 };
4912 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
4913 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(input_data), input_data, GL_STATIC_DRAW);
4914
4915 /* Output */
4916 int output_data[] = { 0 };
4917 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
4918 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(output_data), output_data, GL_DYNAMIC_COPY);
4919
4920 glUseProgram(m_program);
4921 glDispatchCompute(1, 1, 1);
4922 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4923
4924 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
4925 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
4926 if (!data)
4927 return ERROR;
4928 if (*data != DE_LENGTH_OF_ARRAY(input_data))
4929 {
4930 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer data is " << *data << " should be "
4931 << sizeof(input_data) << tcu::TestLog::EndMessage;
4932 return ERROR;
4933 }
4934 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4935 return NO_ERROR;
4936 }
4937
Cleanup()4938 virtual long Cleanup()
4939 {
4940 glUseProgram(0);
4941 glDeleteProgram(m_program);
4942 glDeleteBuffers(2, m_storage_buffer);
4943 return NO_ERROR;
4944 }
4945 };
4946
4947 //----------------------------------------------------------------------------
4948 // 1.15 BasicNameMatch
4949 //-----------------------------------------------------------------------------
4950 class BasicNameMatch : public ShaderStorageBufferObjectBase
4951 {
Run()4952 virtual long Run()
4953 {
4954 GLint blocksVS, blocksFS;
4955 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &blocksVS);
4956 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &blocksFS);
4957 if ((blocksVS == 0) || (blocksFS == 0))
4958 return NOT_SUPPORTED;
4959
4960 // check if link error is generated when one of matched blocks has instance name and other doesn't
4961 std::string vs1("buffer Buf { float x; };\n"
4962 "void main() {\n"
4963 " gl_Position = vec4(x);\n"
4964 "}");
4965 std::string fs1("buffer Buf { float x; } b;\n"
4966 "out vec4 color;\n"
4967 "void main() {\n"
4968 " color = vec4(b.x);\n"
4969 "}");
4970 if (Link(vs1, fs1))
4971 {
4972 m_context.getTestContext().getLog()
4973 << tcu::TestLog::Message << "Linking should fail." << tcu::TestLog::EndMessage;
4974 return ERROR;
4975 }
4976
4977 // check if linking succeeds when both matched blocks are lacking an instance name
4978 std::string vs2("buffer Buf { float x; };\n"
4979 "void main() {\n"
4980 " gl_Position = vec4(x);\n"
4981 "}");
4982 std::string fs2("buffer Buf { float x; };\n"
4983 "out vec4 color;\n"
4984 "void main() {\n"
4985 " color = vec4(x);\n"
4986 "}");
4987 if (!Link(vs2, fs2))
4988 {
4989 m_context.getTestContext().getLog()
4990 << tcu::TestLog::Message << "Linking should succeed." << tcu::TestLog::EndMessage;
4991 return ERROR;
4992 }
4993
4994 // check if linking succeeds when both matched blocks have different instance names
4995 std::string vs3("buffer Buf { float x; } a;\n"
4996 "void main() {\n"
4997 " gl_Position = vec4(a.x);\n"
4998 "}");
4999 std::string fs3("buffer Buf { float x; } b;\n"
5000 "out vec4 color;\n"
5001 "void main() {\n"
5002 " color = vec4(b.x);\n"
5003 "}");
5004 if (!Link(vs3, fs3))
5005 {
5006 m_context.getTestContext().getLog()
5007 << tcu::TestLog::Message << "Linking should succeed." << tcu::TestLog::EndMessage;
5008 return ERROR;
5009 }
5010
5011 return NO_ERROR;
5012 }
5013
Link(const std::string & vs,const std::string & fs)5014 bool Link(const std::string& vs, const std::string& fs)
5015 {
5016 GLuint program = CreateProgram(vs, fs);
5017 glLinkProgram(program);
5018 GLint status;
5019 glGetProgramiv(program, GL_LINK_STATUS, &status);
5020 glDeleteProgram(program);
5021 return (status == GL_TRUE);
5022 }
5023 };
5024
5025 //-----------------------------------------------------------------------------
5026 // 2.1 AdvancedSwitchBuffers
5027 //-----------------------------------------------------------------------------
5028 class AdvancedSwitchBuffersVS : public ShaderStorageBufferObjectBase
5029 {
PassCriteria()5030 virtual std::string PassCriteria()
5031 {
5032 return NL "Everything works as expected.";
5033 }
5034
5035 GLuint m_program;
5036 GLuint m_storage_buffer[5];
5037 GLuint m_vertex_array;
5038 GLuint m_fbo, m_rt;
5039
Setup()5040 virtual long Setup()
5041 {
5042 m_program = 0;
5043 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5044 m_vertex_array = 0;
5045 glGenFramebuffers(1, &m_fbo);
5046 glGenTextures(1, &m_rt);
5047 return NO_ERROR;
5048 }
Run()5049 virtual long Run()
5050 {
5051 if (!IsVSFSAvailable(1, 0))
5052 return NOT_SUPPORTED;
5053 const char* const glsl_vs = NL "struct VertexData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL
5054 "layout(binding = 0, std430) buffer Input {" NL " VertexData vertex[4];" NL
5055 "} g_vs_in;" NL "out vec3 StageData_color;" NL "void main() {" NL
5056 " gl_Position = vec4(g_vs_in.vertex[gl_VertexID].position, 0, 1);" NL
5057 " StageData_color = g_vs_in.vertex[gl_VertexID].color;" NL "}";
5058 const char* const glsl_fs = NL "in vec3 StageData_color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5059 "void main() {" NL " g_fs_out = vec4(StageData_color, 1);" NL "}";
5060 m_program = CreateProgram(glsl_vs, glsl_fs);
5061 glLinkProgram(m_program);
5062 if (!CheckProgram(m_program))
5063 return ERROR;
5064
5065 glGenBuffers(5, m_storage_buffer);
5066
5067 /* left, bottom, red quad */
5068 {
5069 const float data[] = { -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 -0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5072 0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f };
5073 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
5074 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5075 }
5076 /* right, bottom, green quad */
5077 {
5078 const float data[] = { -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 -0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5081 0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };
5082 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
5083 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5084 }
5085 /* left, top, blue quad */
5086 {
5087 const float data[] = { -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 -0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5090 0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f };
5091 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
5092 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5093 }
5094 /* right, top, yellow quad */
5095 {
5096 const float data[] = { -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 -0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5099 0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f };
5100 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
5101 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5102 }
5103
5104 GLint alignment;
5105 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
5106 GLint offset = deRoundUp32(sizeof(float) * 32, alignment);
5107
5108 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
5109 glBufferData(GL_SHADER_STORAGE_BUFFER, offset * 4, NULL, GL_STATIC_DRAW);
5110
5111 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[0]);
5112 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(float) * 32);
5113 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[1]);
5114 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, offset, sizeof(float) * 32);
5115 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[2]);
5116 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 2 * offset,
5117 sizeof(float) * 32);
5118 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[3]);
5119 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 3 * offset,
5120 sizeof(float) * 32);
5121
5122 glBindTexture(GL_TEXTURE_2D, m_rt);
5123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5125 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5126 glBindTexture(GL_TEXTURE_2D, 0);
5127 glViewport(0, 0, 100, 100);
5128 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5129 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5130
5131 glGenVertexArrays(1, &m_vertex_array);
5132
5133 glUseProgram(m_program);
5134 glBindVertexArray(m_vertex_array);
5135
5136 glClear(GL_COLOR_BUFFER_BIT);
5137 for (int i = 0; i < 4; ++i)
5138 {
5139 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[i]);
5140 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5141 }
5142 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5143 {
5144 return ERROR;
5145 }
5146
5147 glClear(GL_COLOR_BUFFER_BIT);
5148 for (int i = 0; i < 4; ++i)
5149 {
5150 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[4], i * offset,
5151 sizeof(float) * 32);
5152 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
5153 }
5154 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5155 {
5156 return ERROR;
5157 }
5158
5159 return NO_ERROR;
5160 }
Cleanup()5161 virtual long Cleanup()
5162 {
5163 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5164 glUseProgram(0);
5165 glDeleteProgram(m_program);
5166 glDeleteBuffers(5, m_storage_buffer);
5167 glDeleteVertexArrays(1, &m_vertex_array);
5168 glDeleteFramebuffers(1, &m_fbo);
5169 glDeleteTextures(1, &m_rt);
5170 return NO_ERROR;
5171 }
5172 };
5173
5174 class AdvancedSwitchBuffersCS : public ShaderStorageBufferObjectBase
5175 {
5176 GLuint m_program;
5177 GLuint m_storage_buffer[6];
5178
Setup()5179 virtual long Setup()
5180 {
5181 m_program = 0;
5182 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5183 return NO_ERROR;
5184 }
Run()5185 virtual long Run()
5186 {
5187 const char* const glsl_cs =
5188 NL "layout(local_size_x = 1) in;" NL "layout(binding = 0, std430) buffer Input {" NL " uint cookie[4];" NL
5189 "} g_in;" NL "layout(binding = 1, std430) buffer Output {" NL " uvec4 digest;" NL "} ;" NL
5190 "void main() {" NL " switch (g_in.cookie[0]+g_in.cookie[1]+g_in.cookie[2]+g_in.cookie[3]) {" NL
5191 " case 0x000000ffu: digest.x = 0xff000000u; break;" NL
5192 " case 0x0000ff00u: digest.y = 0x00ff0000u; break;" NL
5193 " case 0x00ff0000u: digest.z = 0x0000ff00u; break;" NL
5194 " case 0xff000000u: digest.w = 0x000000ffu; break;" NL " }" NL "}";
5195 m_program = CreateProgramCS(glsl_cs);
5196 glLinkProgram(m_program);
5197 if (!CheckProgram(m_program))
5198 return ERROR;
5199
5200 glGenBuffers(6, m_storage_buffer);
5201
5202 const GLubyte data0[] = { 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x88, 0, 0, 0, 0x22 };
5203 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
5204 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data0), data0, GL_STATIC_DRAW);
5205 const GLubyte data1[] = { 0, 0, 0x44, 0, 0, 0, 0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0 };
5206 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
5207 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data1), data1, GL_STATIC_DRAW);
5208 const GLubyte data2[] = { 0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x22, 0, 0 };
5209 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
5210 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW);
5211 const GLubyte data3[] = { 0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0 };
5212 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
5213 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data3), data3, GL_STATIC_DRAW);
5214
5215 GLint alignment;
5216 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
5217 GLint offset = deRoundUp32(sizeof(data0), alignment);
5218 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
5219 glBufferData(GL_SHADER_STORAGE_BUFFER, offset * 4, NULL, GL_STATIC_DRAW);
5220
5221 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[0]);
5222 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(data0));
5223 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[1]);
5224 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, offset, sizeof(data0));
5225 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[2]);
5226 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 2 * offset, sizeof(data0));
5227 glBindBuffer(GL_COPY_READ_BUFFER, m_storage_buffer[3]);
5228 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 3 * offset, sizeof(data0));
5229
5230 const GLubyte data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
5231 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[5]);
5232 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5233
5234 glUseProgram(m_program);
5235 for (int i = 0; i < 4; ++i)
5236 {
5237 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[i]);
5238 glDispatchCompute(1, 1, 1);
5239 }
5240 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
5241 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5242 GLuint* out_data = (GLuint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data0), GL_MAP_READ_BIT);
5243 if (!out_data)
5244 return ERROR;
5245 GLuint expected[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
5246 if (out_data[0] != expected[0] || out_data[1] != expected[1] || out_data[2] != expected[2] ||
5247 out_data[3] != expected[3])
5248 {
5249 m_context.getTestContext().getLog()
5250 << tcu::TestLog::Message << "Received: " << out_data[0] << ", " << out_data[1] << ", " << out_data[2]
5251 << ", " << out_data[3] << ", but expected: " << expected[0] << ", " << expected[1] << ", "
5252 << expected[2] << ", " << expected[3] << tcu::TestLog::EndMessage;
5253 return ERROR;
5254 }
5255 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5256 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5257
5258 for (int i = 0; i < 4; ++i)
5259 {
5260 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[4], i * offset, sizeof(data0));
5261 glDispatchCompute(1, 1, 1);
5262 }
5263 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
5264 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5265 out_data = (GLuint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data0), GL_MAP_READ_BIT);
5266 if (!out_data)
5267 return ERROR;
5268 if (out_data[0] != expected[0] || out_data[1] != expected[1] || out_data[2] != expected[2] ||
5269 out_data[3] != expected[3])
5270 {
5271 m_context.getTestContext().getLog()
5272 << tcu::TestLog::Message << "Received: " << tcu::toHex(out_data[0]) << ", " << tcu::toHex(out_data[1])
5273 << ", " << tcu::toHex(out_data[2]) << ", " << tcu::toHex(out_data[3])
5274 << ", but expected: " << tcu::toHex(expected[0]) << ", " << tcu::toHex(expected[1]) << ", "
5275 << tcu::toHex(expected[2]) << ", " << tcu::toHex(expected[3]) << tcu::TestLog::EndMessage;
5276 return ERROR;
5277 }
5278
5279 return NO_ERROR;
5280 }
Cleanup()5281 virtual long Cleanup()
5282 {
5283 glUseProgram(0);
5284 glDeleteProgram(m_program);
5285 glDeleteBuffers(6, m_storage_buffer);
5286 return NO_ERROR;
5287 }
5288 };
5289
5290 //-----------------------------------------------------------------------------
5291 // 2.2 AdvancedSwitchPrograms
5292 //-----------------------------------------------------------------------------
5293 class AdvancedSwitchProgramsVS : public ShaderStorageBufferObjectBase
5294 {
5295 GLuint m_program[4];
5296 GLuint m_storage_buffer[4];
5297 GLuint m_vertex_array;
5298 GLuint m_fbo, m_rt;
5299
GenSource(int binding)5300 std::string GenSource(int binding)
5301 {
5302 std::stringstream ss;
5303 ss << NL "struct VertexData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL "layout(binding = "
5304 << binding
5305 << ", std430) buffer Input {" NL " VertexData vertex[4];" NL "} g_vs_in;" NL "out vec3 StageData_color;" NL
5306 "void main() {" NL " gl_Position = vec4(g_vs_in.vertex[gl_VertexID].position, 0, 1);" NL
5307 " StageData_color = g_vs_in.vertex[gl_VertexID].color;" NL "}";
5308 return ss.str();
5309 }
5310
Setup()5311 virtual long Setup()
5312 {
5313 memset(m_program, 0, sizeof(m_program));
5314 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5315 m_vertex_array = 0;
5316 glGenFramebuffers(1, &m_fbo);
5317 glGenTextures(1, &m_rt);
5318 return NO_ERROR;
5319 }
5320
Run()5321 virtual long Run()
5322 {
5323 if (!IsVSFSAvailable(1, 0))
5324 return NOT_SUPPORTED;
5325 const char* const glsl_fs = NL "in vec3 StageData_color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5326 "void main() {" NL " g_fs_out = vec4(StageData_color, 1);" NL "}";
5327 for (int i = 0; i < 4; ++i)
5328 {
5329 m_program[i] = CreateProgram(GenSource(i), glsl_fs);
5330 glLinkProgram(m_program[i]);
5331 if (!CheckProgram(m_program[i]))
5332 return ERROR;
5333 }
5334
5335 glGenBuffers(4, m_storage_buffer);
5336
5337 /* left, bottom, red quad */
5338 {
5339 const float data[] = { -0.4f - 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5340 0.4f - 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5341 -0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
5342 0.4f - 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f };
5343 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5344 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5345 }
5346 /* right, bottom, green quad */
5347 {
5348 const float data[] = { -0.4f + 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5349 0.4f + 0.5f, -0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5350 -0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
5351 0.4f + 0.5f, 0.4f - 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };
5352 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5353 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5354 }
5355 /* left, top, blue quad */
5356 {
5357 const float data[] = { -0.4f - 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5358 0.4f - 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5359 -0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
5360 0.4f - 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f };
5361 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5362 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5363 }
5364 /* right, top, yellow quad */
5365 {
5366 const float data[] = { -0.4f + 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5367 0.4f + 0.5f, -0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5368 -0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
5369 0.4f + 0.5f, 0.4f + 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f };
5370 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5371 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5372 }
5373
5374 glBindTexture(GL_TEXTURE_2D, m_rt);
5375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5377 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5378 glBindTexture(GL_TEXTURE_2D, 0);
5379 glViewport(0, 0, 100, 100);
5380 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5381 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5382
5383 glGenVertexArrays(1, &m_vertex_array);
5384 glBindVertexArray(m_vertex_array);
5385
5386 glClear(GL_COLOR_BUFFER_BIT);
5387 for (int i = 0; i < 4; ++i)
5388 {
5389 glUseProgram(m_program[i]);
5390 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5391 }
5392 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5393 {
5394 return ERROR;
5395 }
5396
5397 return NO_ERROR;
5398 }
5399
Cleanup()5400 virtual long Cleanup()
5401 {
5402 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5403 glUseProgram(0);
5404 for (int i = 0; i < 4; ++i)
5405 glDeleteProgram(m_program[i]);
5406 glDeleteBuffers(4, m_storage_buffer);
5407 glDeleteVertexArrays(1, &m_vertex_array);
5408 glDeleteFramebuffers(1, &m_fbo);
5409 glDeleteTextures(1, &m_rt);
5410 return NO_ERROR;
5411 }
5412 };
5413
5414 class AdvancedSwitchProgramsCS : public ShaderStorageBufferObjectBase
5415 {
5416 GLuint m_program[4];
5417 GLuint m_storage_buffer[5];
5418
Setup()5419 virtual long Setup()
5420 {
5421 memset(m_program, 0, sizeof(m_program));
5422 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5423 return NO_ERROR;
5424 }
5425
GenSource(int binding)5426 std::string GenSource(int binding)
5427 {
5428 std::stringstream ss;
5429 ss << NL "layout(local_size_x = 1) in;" NL "layout(binding = " << binding
5430 << ", std430) buffer Input {" NL " uint cookie[4];" NL "} g_in;" NL
5431 "layout(binding = 0, std430) buffer Output {" NL " uvec4 digest;" NL "} ;" NL "void main() {" NL
5432 " switch (g_in.cookie[0]+g_in.cookie[1]+g_in.cookie[2]+g_in.cookie[3]) {" NL
5433 " case 0x000000ffu: digest.x = 0xff000000u; break;" NL
5434 " case 0x0000ff00u: digest.y = 0x00ff0000u; break;" NL
5435 " case 0x00ff0000u: digest.z = 0x0000ff00u; break;" NL
5436 " case 0xff000000u: digest.w = 0x000000ffu; break;" NL " }" NL "}";
5437 return ss.str();
5438 }
5439
Run()5440 virtual long Run()
5441 {
5442 for (int i = 0; i < 4; ++i)
5443 {
5444 m_program[i] = CreateProgramCS(GenSource(i + 1));
5445 glLinkProgram(m_program[i]);
5446 if (!CheckProgram(m_program[i]))
5447 return ERROR;
5448 }
5449
5450 glGenBuffers(5, m_storage_buffer);
5451
5452 const GLubyte data0[] = { 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x88, 0, 0, 0, 0x22 };
5453 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5454 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data0), data0, GL_STATIC_DRAW);
5455 const GLubyte data1[] = { 0, 0, 0x44, 0, 0, 0, 0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0 };
5456 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5457 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data1), data1, GL_STATIC_DRAW);
5458 const GLubyte data2[] = { 0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0, 0x22, 0, 0 };
5459 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5460 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW);
5461 const GLubyte data3[] = { 0x22, 0, 0, 0, 0x88, 0, 0, 0, 0x11, 0, 0, 0, 0x44, 0, 0, 0 };
5462 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
5463 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data3), data3, GL_STATIC_DRAW);
5464
5465 const GLubyte data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
5466 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5467 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5468
5469 for (int i = 0; i < 4; ++i)
5470 {
5471 glUseProgram(m_program[i]);
5472 glDispatchCompute(1, 1, 1);
5473 }
5474 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
5475 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5476 GLuint* out_data = (GLuint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data0), GL_MAP_READ_BIT);
5477 if (!out_data)
5478 return ERROR;
5479 GLuint expected[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
5480 if (out_data[0] != expected[0] || out_data[1] != expected[1] || out_data[2] != expected[2] ||
5481 out_data[3] != expected[3])
5482 {
5483 m_context.getTestContext().getLog()
5484 << tcu::TestLog::Message << "Received: " << tcu::toHex(out_data[0]) << ", " << tcu::toHex(out_data[1])
5485 << ", " << tcu::toHex(out_data[2]) << ", " << tcu::toHex(out_data[3])
5486 << ", but expected: " << tcu::toHex(expected[0]) << ", " << tcu::toHex(expected[1]) << ", "
5487 << tcu::toHex(expected[2]) << ", " << tcu::toHex(expected[3]) << tcu::TestLog::EndMessage;
5488 return ERROR;
5489 }
5490 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5491
5492 return NO_ERROR;
5493 }
Cleanup()5494 virtual long Cleanup()
5495 {
5496 glUseProgram(0);
5497 for (int i = 0; i < 4; ++i)
5498 glDeleteProgram(m_program[i]);
5499 glDeleteBuffers(5, m_storage_buffer);
5500 return NO_ERROR;
5501 }
5502 };
5503 //-----------------------------------------------------------------------------
5504 // 2.3.1 AdvancedWriteFragment
5505 //-----------------------------------------------------------------------------
5506 class AdvancedWriteFragmentFS : public ShaderStorageBufferObjectBase
5507 {
5508 GLuint m_program[2];
5509 GLuint m_storage_buffer;
5510 GLuint m_counter_buffer;
5511 GLuint m_attribless_vertex_array;
5512 GLuint m_draw_vertex_array;
5513 GLuint m_fbo, m_rt;
5514
Setup()5515 virtual long Setup()
5516 {
5517 memset(m_program, 0, sizeof(m_program));
5518 m_storage_buffer = 0;
5519 m_counter_buffer = 0;
5520 m_attribless_vertex_array = 0;
5521 m_draw_vertex_array = 0;
5522 glGenFramebuffers(1, &m_fbo);
5523 glGenTextures(1, &m_rt);
5524 return NO_ERROR;
5525 }
5526
Run()5527 virtual long Run()
5528 {
5529 if (!IsVSFSAvailable(0, 1))
5530 return NOT_SUPPORTED;
5531 const char* const glsl_vs0 =
5532 NL "out vec2 position;" NL "out vec3 color;" NL
5533 "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
5534 "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
5535 "vec3 g_color[4] = vec3[4](vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1), vec3(1, 1, 0));" NL
5536 "void main() {" NL " vec2 pos = g_quad[gl_VertexID] + g_offset[gl_InstanceID];" NL
5537 " gl_Position = vec4(pos, 0, 1);" NL " position = pos;" NL " color = g_color[gl_InstanceID];" NL "}";
5538 const char* const glsl_fs0 =
5539 NL "in vec2 position;" NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5540 "struct FragmentData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL
5541 "layout(std430, binding = 3) buffer Output {" NL " FragmentData g_fragment[6400];" NL "};" NL
5542 "uniform uint g_max_fragment_count;" NL
5543 "layout(binding = 2, offset = 0) uniform atomic_uint g_fragment_counter;" NL "void main() {" NL
5544 " uint fragment_number = atomicCounterIncrement(g_fragment_counter);" NL
5545 " if (fragment_number < g_max_fragment_count) {" NL
5546 " g_fragment[fragment_number].position = position;" NL
5547 " g_fragment[fragment_number].color = color;" NL " }" NL " g_fs_out = vec4(color, 1);" NL "}";
5548 m_program[0] = CreateProgram(glsl_vs0, glsl_fs0);
5549 glLinkProgram(m_program[0]);
5550 if (!CheckProgram(m_program[0]))
5551 return ERROR;
5552
5553 const char* const glsl_vs1 =
5554 NL "layout(location = 0) in vec4 g_in_position;" NL "layout(location = 1) in vec4 g_in_color;" NL
5555 "out vec3 color;" NL "void main() {" NL " gl_Position = vec4(g_in_position.xy, 0, 1);" NL
5556 "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL " color = g_in_color.rgb;" NL "}";
5557 const char* const glsl_fs1 = NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5558 "void main() {" NL " g_fs_out = vec4(color, 1);" NL "}";
5559 m_program[1] = CreateProgram(glsl_vs1, glsl_fs1);
5560 glLinkProgram(m_program[1]);
5561 if (!CheckProgram(m_program[1]))
5562 return ERROR;
5563
5564 // The first pass renders four squares on-screen, and writes a
5565 // record to the SSBO for each fragment processed. The rectangles
5566 // will be 40x40 when using a 100x100 viewport, so we expect 1600
5567 // pixels per rectangle or 6400 pixels total. Size the SSBO
5568 // accordingly, and render the second pass (sourcing the SSBO as a
5569 // vertex buffer) with an identical number of points. If we have
5570 // a larger buffer and draw more points on the second pass, those
5571 // may overwrite "real" points using garbage position/color.
5572 int expectedPixels = 6400;
5573
5574 glGenBuffers(1, &m_storage_buffer);
5575 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer);
5576 glBufferData(GL_SHADER_STORAGE_BUFFER, expectedPixels * 32, NULL, GL_DYNAMIC_DRAW);
5577
5578 glGenBuffers(1, &m_counter_buffer);
5579 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 2, m_counter_buffer);
5580 glBufferData(GL_ATOMIC_COUNTER_BUFFER, 4, NULL, GL_DYNAMIC_DRAW);
5581 uvec4 zero(0);
5582 glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, 4, &zero);
5583
5584 glBindTexture(GL_TEXTURE_2D, m_rt);
5585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5586 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5587 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5588 glBindTexture(GL_TEXTURE_2D, 0);
5589 glViewport(0, 0, 100, 100);
5590 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5591 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5592
5593 glGenVertexArrays(1, &m_attribless_vertex_array);
5594
5595 glGenVertexArrays(1, &m_draw_vertex_array);
5596 glBindVertexArray(m_draw_vertex_array);
5597 glBindBuffer(GL_ARRAY_BUFFER, m_storage_buffer);
5598 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 32, 0);
5599 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 32, reinterpret_cast<void*>(16));
5600 glBindBuffer(GL_ARRAY_BUFFER, 0);
5601 glEnableVertexAttribArray(0);
5602 glEnableVertexAttribArray(1);
5603 glBindVertexArray(0);
5604
5605 glClear(GL_COLOR_BUFFER_BIT);
5606 glUseProgram(m_program[0]);
5607 glUniform1ui(glGetUniformLocation(m_program[0], "g_max_fragment_count"), expectedPixels);
5608 glBindVertexArray(m_attribless_vertex_array);
5609 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
5610 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5611 {
5612 return ERROR;
5613 }
5614
5615 glClear(GL_COLOR_BUFFER_BIT);
5616 glUseProgram(m_program[1]);
5617 glBindVertexArray(m_draw_vertex_array);
5618 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
5619 glDrawArrays(GL_POINTS, 0, expectedPixels);
5620 int bad_pixels;
5621 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1), &bad_pixels) &&
5622 bad_pixels > 2)
5623 {
5624 return ERROR;
5625 }
5626
5627 return NO_ERROR;
5628 }
5629
Cleanup()5630 virtual long Cleanup()
5631 {
5632 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5633 glUseProgram(0);
5634 for (int i = 0; i < 2; ++i)
5635 glDeleteProgram(m_program[i]);
5636 glDeleteBuffers(1, &m_storage_buffer);
5637 glDeleteBuffers(1, &m_counter_buffer);
5638 glDeleteVertexArrays(1, &m_attribless_vertex_array);
5639 glDeleteVertexArrays(1, &m_draw_vertex_array);
5640 glDeleteFramebuffers(1, &m_fbo);
5641 glDeleteTextures(1, &m_rt);
5642 return NO_ERROR;
5643 }
5644 };
5645
5646 class AdvancedWriteFragmentCS : public ShaderStorageBufferObjectBase
5647 {
5648 GLuint m_program[2];
5649 GLuint m_storage_buffer;
5650 GLuint m_counter_buffer;
5651 GLuint m_draw_vertex_array;
5652 GLuint m_fbo, m_rt;
5653
Setup()5654 virtual long Setup()
5655 {
5656 memset(m_program, 0, sizeof(m_program));
5657 m_storage_buffer = 0;
5658 m_counter_buffer = 0;
5659 m_draw_vertex_array = 0;
5660 glGenFramebuffers(1, &m_fbo);
5661 glGenTextures(1, &m_rt);
5662 return NO_ERROR;
5663 }
5664
Run()5665 virtual long Run()
5666 {
5667 const char* const glsl_cs = NL
5668 "layout(local_size_x = 10, local_size_y = 10) in;" NL "uniform uint g_max_point_count;" NL
5669 "uniform uint g_brick;" NL
5670 "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
5671 "struct PointData {" NL " vec2 position;" NL " vec3 color;" NL "};" NL
5672 "layout(std430, binding = 3) buffer Output {" NL " PointData g_point[];" NL "};" NL
5673 "layout(binding = 0, offset = 0) uniform atomic_uint g_point_counter;" NL "void main() {" NL
5674 " uint g_offset[4] = uint[4](g_brick, 9u*g_brick, 11u*g_brick, 19u*g_brick);" NL
5675 " uint point_number = atomicCounterIncrement(g_point_counter);" NL
5676 " uint giidx = gl_GlobalInvocationID.x;" NL " uint giidy = gl_GlobalInvocationID.y;" NL
5677 " g_point[point_number].position = vec2(gl_GlobalInvocationID.xy * 2u) / 100.0 - 1.0;" NL
5678 " g_point[point_number].color = g_color[4];" NL " if (point_number < g_max_point_count) {" NL
5679 " if (giidx > g_offset[0] && giidx < g_offset[1] && giidy > g_offset[0] && giidy < g_offset[1]) {" NL
5680 " g_point[point_number].color = g_color[0];" NL " }" NL
5681 " if (giidx > g_offset[2] && giidx < g_offset[3] && giidy > g_offset[0] && giidy < g_offset[1]) {" NL
5682 " g_point[point_number].color = g_color[1];" NL " }" NL
5683 " if (giidx > g_offset[2] && giidx < g_offset[3] && giidy > g_offset[2] && giidy < g_offset[3]) {" NL
5684 " g_point[point_number].color = g_color[2];" NL " }" NL
5685 " if (giidx > g_offset[0] && giidx < g_offset[1] && giidy > g_offset[2] && giidy < g_offset[3]) {" NL
5686 " g_point[point_number].color = g_color[3];" NL " }" NL " }" NL "}";
5687
5688 m_program[0] = CreateProgramCS(glsl_cs);
5689 glLinkProgram(m_program[0]);
5690 if (!CheckProgram(m_program[0]))
5691 return ERROR;
5692
5693 const char* const glsl_vs1 =
5694 NL "layout(location = 0) in vec4 g_in_position;" NL "layout(location = 1) in vec4 g_in_color;" NL
5695 "out vec3 color;" NL "void main() {" NL " gl_Position = vec4(g_in_position.xy, 0, 1);" NL
5696 "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL " color = g_in_color.rgb;" NL "}";
5697
5698 const char* const glsl_fs1 = NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5699 "void main() {" NL " g_fs_out = vec4(color, 1);" NL "}";
5700
5701 m_program[1] = CreateProgram(glsl_vs1, glsl_fs1);
5702 glLinkProgram(m_program[1]);
5703 if (!CheckProgram(m_program[1]))
5704 return ERROR;
5705
5706 glGenBuffers(1, &m_storage_buffer);
5707 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer);
5708 glBufferData(GL_SHADER_STORAGE_BUFFER, 100 * 100 * 32, NULL, GL_DYNAMIC_DRAW);
5709
5710 glGenBuffers(1, &m_counter_buffer);
5711 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_counter_buffer);
5712 glBufferData(GL_ATOMIC_COUNTER_BUFFER, 4, NULL, GL_DYNAMIC_DRAW);
5713 uvec4 zero(0);
5714 glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, 4, &zero);
5715
5716 glGenVertexArrays(1, &m_draw_vertex_array);
5717 glBindVertexArray(m_draw_vertex_array);
5718 glBindBuffer(GL_ARRAY_BUFFER, m_storage_buffer);
5719 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 32, 0);
5720 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 32, reinterpret_cast<void*>(16));
5721 glBindBuffer(GL_ARRAY_BUFFER, 0);
5722 glEnableVertexAttribArray(0);
5723 glEnableVertexAttribArray(1);
5724 glBindVertexArray(0);
5725
5726 glUseProgram(m_program[0]);
5727 glUniform1ui(glGetUniformLocation(m_program[0], "g_max_point_count"), 100 * 100);
5728 glUniform1ui(glGetUniformLocation(m_program[0], "g_brick"), 5);
5729 glDispatchCompute(10, 10, 1);
5730
5731 glBindTexture(GL_TEXTURE_2D, m_rt);
5732 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5733 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5734 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5735 glBindTexture(GL_TEXTURE_2D, 0);
5736 glViewport(0, 0, 100, 100);
5737 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5738 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5739
5740 glClear(GL_COLOR_BUFFER_BIT);
5741 glUseProgram(m_program[1]);
5742 glBindVertexArray(m_draw_vertex_array);
5743 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
5744 glDrawArrays(GL_POINTS, 0, 100 * 100);
5745 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
5746 {
5747 return ERROR;
5748 }
5749
5750 return NO_ERROR;
5751 }
Cleanup()5752 virtual long Cleanup()
5753 {
5754 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5755 glUseProgram(0);
5756 for (int i = 0; i < 2; ++i)
5757 glDeleteProgram(m_program[i]);
5758 glDeleteBuffers(1, &m_storage_buffer);
5759 glDeleteBuffers(1, &m_counter_buffer);
5760 glDeleteVertexArrays(1, &m_draw_vertex_array);
5761 glDeleteFramebuffers(1, &m_fbo);
5762 glDeleteTextures(1, &m_rt);
5763 return NO_ERROR;
5764 }
5765 };
5766 //-----------------------------------------------------------------------------
5767 // 2.4.1 AdvancedIndirectAddressingCase1
5768 //-----------------------------------------------------------------------------
5769 class AdvancedIndirectAddressingCase1VS : public ShaderStorageBufferObjectBase
5770 {
5771 GLuint m_program;
5772 GLuint m_storage_buffer[4];
5773 GLuint m_vertex_array;
5774 GLuint m_vertex_buffer;
5775 GLuint m_fbo, m_rt;
5776
Setup()5777 virtual long Setup()
5778 {
5779 m_program = 0;
5780 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5781 m_vertex_array = 0;
5782 m_vertex_buffer = 0;
5783 glGenFramebuffers(1, &m_fbo);
5784 glGenTextures(1, &m_rt);
5785 return NO_ERROR;
5786 }
5787
Run()5788 virtual long Run()
5789 {
5790 if (!IsVSFSAvailable(4, 0))
5791 return NOT_SUPPORTED;
5792 const char* const glsl_vs =
5793 NL "layout(location = 0) in vec2 g_in_position;" NL "struct Material {" NL " vec3 color;" NL "};" NL
5794 "layout(binding = 0, std430) buffer MaterialBuffer {" NL " Material g_material[4];" NL "};" NL
5795 "layout(binding = 1, std430) buffer MaterialIDBuffer {" NL " uint g_material_id[4];" NL "};" NL
5796 "layout(binding = 2, std430) buffer TransformBuffer {" NL " vec2 translation[4];" NL "} g_transform;" NL
5797 "layout(binding = 3, std430) buffer TransformIDBuffer {" NL " uint g_transform_id[4];" NL "};" NL
5798 "out vec3 color;" NL "void main() {" NL " uint mid = g_material_id[gl_InstanceID];" NL
5799 " Material m = g_material[mid];" NL " uint tid = g_transform_id[gl_InstanceID];" NL
5800 " vec2 t = g_transform.translation[tid];" NL " gl_Position = vec4(g_in_position + t, 0, 1);" NL
5801 " color = m.color;" NL "}";
5802 const char* const glsl_fs = NL "in vec3 color;" NL "layout(location = 0) out vec4 g_fs_out;" NL
5803 "void main() {" NL " g_fs_out = vec4(color, 1);" NL "}";
5804 m_program = CreateProgram(glsl_vs, glsl_fs);
5805 glLinkProgram(m_program);
5806 if (!CheckProgram(m_program))
5807 return ERROR;
5808
5809 glGenBuffers(4, m_storage_buffer);
5810
5811 /* material buffer */
5812 {
5813 const float data[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
5814 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };
5815 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5816 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5817 }
5818 /* material id buffer */
5819 {
5820 const unsigned int data[] = { 2, 3, 0, 2 };
5821 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5822 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5823 }
5824 /* transform buffer */
5825 {
5826 const float data[] = { -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f };
5827 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5828 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5829 }
5830 /* transform id buffer */
5831 {
5832 const unsigned int data[] = { 3, 1, 0, 2 };
5833 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5834 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5835 }
5836
5837 /* vertex buffer */
5838 {
5839 const float data[] = { -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.4f, 0.4f };
5840 glGenBuffers(1, &m_vertex_buffer);
5841 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
5842 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
5843 glBindBuffer(GL_ARRAY_BUFFER, 0);
5844 }
5845
5846 glBindTexture(GL_TEXTURE_2D, m_rt);
5847 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5848 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5849 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
5850 glBindTexture(GL_TEXTURE_2D, 0);
5851 glViewport(0, 0, 100, 100);
5852 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5853 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
5854
5855 glGenVertexArrays(1, &m_vertex_array);
5856 glBindVertexArray(m_vertex_array);
5857 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
5858 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
5859 glBindBuffer(GL_ARRAY_BUFFER, 0);
5860 glEnableVertexAttribArray(0);
5861 glBindVertexArray(0);
5862
5863 glClear(GL_COLOR_BUFFER_BIT);
5864 glUseProgram(m_program);
5865 glBindVertexArray(m_vertex_array);
5866 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
5867 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(1, 1, 0), vec3(0, 0, 1), vec3(0, 0, 1)))
5868 {
5869 return ERROR;
5870 }
5871
5872 /* update material id buffer with BufferSubData */
5873 {
5874 const unsigned int data[] = { 3, 2, 1, 0 };
5875 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
5876 glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), data);
5877 }
5878
5879 /* update transform id buffer with BufferData */
5880 {
5881 const unsigned int data[] = { 0, 1, 2, 3 };
5882 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
5883 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5884 }
5885
5886 glClear(GL_COLOR_BUFFER_BIT);
5887 glUseProgram(m_program);
5888 glBindVertexArray(m_vertex_array);
5889 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
5890 if (!ValidateWindow4Quads(vec3(1, 1, 0), vec3(0, 0, 1), vec3(1, 0, 0), vec3(0, 1, 0)))
5891 {
5892 return ERROR;
5893 }
5894
5895 return NO_ERROR;
5896 }
5897
Cleanup()5898 virtual long Cleanup()
5899 {
5900 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5901 glUseProgram(0);
5902 glDeleteProgram(m_program);
5903 glDeleteBuffers(4, m_storage_buffer);
5904 glDeleteBuffers(1, &m_vertex_buffer);
5905 glDeleteVertexArrays(1, &m_vertex_array);
5906 glDeleteFramebuffers(1, &m_fbo);
5907 glDeleteTextures(1, &m_rt);
5908 return NO_ERROR;
5909 }
5910 };
5911
5912 class AdvancedIndirectAddressingCase1CS : public ShaderStorageBufferObjectBase
5913 {
5914 GLuint m_program;
5915 GLuint m_storage_buffer[5];
5916
Setup()5917 virtual long Setup()
5918 {
5919 m_program = 0;
5920 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
5921 return NO_ERROR;
5922 }
5923
Run()5924 virtual long Run()
5925 {
5926 bool status = true;
5927 const char* const glsl_cs =
5928 NL "layout(local_size_x = 2, local_size_y = 2) in;" NL "struct Material {" NL " vec3 color;" NL "};" NL
5929 "layout(binding = 0, std430) buffer MaterialBuffer {" NL " Material g_material[4];" NL "};" NL
5930 "layout(binding = 1, std430) buffer MaterialIDBuffer {" NL " uint g_material_id[4];" NL "};" NL
5931 "layout(binding = 2, std430) buffer TransformBuffer {" NL " vec2 translation[4];" NL "} g_transform;" NL
5932 "layout(binding = 3, std430) buffer TransformIDBuffer {" NL " uint g_transform_id[4];" NL "};" NL
5933 "layout(binding = 4, std430) buffer OutputBuffer {" NL " vec3 color[16];" NL " vec2 pos[16];" NL
5934 "};" NL "vec2 g_in_position[4] = vec2[4](vec2(-0.4f, -0.4f), vec2(0.4f, -0.4f), vec2(-0.4f, 0.4f), "
5935 "vec2(0.4f, 0.4f));" NL "void main() {" NL " uint mid = g_material_id[gl_WorkGroupID.x];" NL
5936 " Material m = g_material[mid];" NL " uint tid = g_transform_id[gl_WorkGroupID.x];" NL
5937 " vec2 t = g_transform.translation[tid];" NL
5938 " pos[gl_LocalInvocationIndex + gl_WorkGroupID.x * gl_WorkGroupSize.x * gl_WorkGroupSize.y] " NL
5939 " = g_in_position[gl_LocalInvocationIndex] + t;" NL " color[gl_LocalInvocationIndex + "
5940 "gl_WorkGroupID.x * gl_WorkGroupSize.x * "
5941 "gl_WorkGroupSize.y] = m.color;" NL "}";
5942
5943 m_program = CreateProgramCS(glsl_cs);
5944 glLinkProgram(m_program);
5945 if (!CheckProgram(m_program))
5946 return ERROR;
5947
5948 glGenBuffers(5, m_storage_buffer);
5949
5950 /* material buffer */
5951 {
5952 const float data[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
5953 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };
5954 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
5955 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5956 }
5957 /* material id buffer */
5958 {
5959 const unsigned int data[] = { 2, 3, 0, 2 };
5960 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
5961 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5962 }
5963 /* transform buffer */
5964 {
5965 const float data[] = { -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f };
5966 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
5967 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5968 }
5969 /* transform id buffer */
5970 {
5971 const unsigned int data[] = { 3, 1, 0, 2 };
5972 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
5973 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
5974 }
5975
5976 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
5977 glBufferData(GL_SHADER_STORAGE_BUFFER, 16 * 4 * 4 + 16 * 2 * 4, 0, GL_STATIC_DRAW);
5978
5979 glUseProgram(m_program);
5980 glDispatchCompute(4, 1, 1);
5981 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5982 GLfloat* out_data =
5983 (GLfloat*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16 * 4 * 4 + 16 * 2 * 4, GL_MAP_READ_BIT);
5984 if (!out_data)
5985 return ERROR;
5986
5987 GLfloat expected[16 * 4 + 16 * 2] = {
5988 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,
5989 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,
5990 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,
5991 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,
5992 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,
5993 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,
5994 -0.9f, -0.1f, -0.1f, -0.1f, -0.9f, 0.1f, -0.1f, 0.1f, -0.9f, 0.9f, -0.1f, 0.9f
5995 };
5996
5997 for (int i = 0; i < 16; ++i)
5998 {
5999 if (out_data[i * 4 + 0] != expected[i * 4 + 0] || out_data[i * 4 + 1] != expected[i * 4 + 1] ||
6000 out_data[i * 4 + 2] != expected[i * 4 + 2])
6001 {
6002 m_context.getTestContext().getLog()
6003 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 0] << ", " << out_data[i * 4 + 1]
6004 << ", " << out_data[i * 4 + 2] << ", but expected: " << expected[i * 4 + 0] << ", "
6005 << expected[i * 4 + 1] << ", " << expected[i * 4 + 2] << tcu::TestLog::EndMessage;
6006 status = false;
6007 }
6008 }
6009 for (int i = 32; i < 32 + 16; ++i)
6010 {
6011 if (fabs(out_data[i * 2 + 0] - expected[i * 2 + 0]) > 1e-6 ||
6012 fabs(out_data[i * 2 + 1] - expected[i * 2 + 1]) > 1e-6)
6013 {
6014 m_context.getTestContext().getLog()
6015 << tcu::TestLog::Message << "Received: " << out_data[i * 2 + 0] << ", " << out_data[i * 2 + 1]
6016 << ", but expected: " << expected[i * 2 + 0] << ", " << expected[i * 2 + 1]
6017 << tcu::TestLog::EndMessage;
6018 status = false;
6019 }
6020 }
6021 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6022
6023 /* update material id buffer with BufferSubData */
6024 {
6025 const unsigned int data[] = { 3, 2, 1, 0 };
6026 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
6027 glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), data);
6028 }
6029
6030 /* update transform id buffer with BufferData */
6031 {
6032 const unsigned int data[] = { 0, 1, 2, 3 };
6033 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
6034 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW);
6035 }
6036
6037 glUseProgram(m_program);
6038 glDispatchCompute(4, 1, 1);
6039 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
6040 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6041 GLfloat* out_data2 =
6042 (GLfloat*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16 * 4 * 4 + 16 * 2 * 4, GL_MAP_READ_BIT);
6043 if (!out_data2)
6044 return ERROR;
6045
6046 GLfloat expected2[16 * 4 + 16 * 2] = {
6047 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,
6048 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,
6049 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,
6050 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,
6051 -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,
6052 -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
6053 };
6054 for (int i = 0; i < 16; ++i)
6055 {
6056 if (out_data2[i * 4 + 0] != expected2[i * 4 + 0] || out_data2[i * 4 + 1] != expected2[i * 4 + 1] ||
6057 out_data2[i * 4 + 2] != expected2[i * 4 + 2])
6058 {
6059 m_context.getTestContext().getLog()
6060 << tcu::TestLog::Message << "Received: " << out_data2[i * 4 + 0] << ", " << out_data2[i * 4 + 1]
6061 << ", " << out_data2[i * 4 + 2] << ", but expected: " << expected2[i * 4 + 0] << ", "
6062 << expected2[i * 4 + 1] << ", " << expected2[i * 4 + 2] << tcu::TestLog::EndMessage;
6063 status = false;
6064 }
6065 }
6066 for (int i = 32; i < 32 + 16; ++i)
6067 {
6068 if (fabs(out_data2[i * 2 + 0] - expected2[i * 2 + 0]) > 1e-6 ||
6069 fabs(out_data2[i * 2 + 1] - expected2[i * 2 + 1]) > 1e-6)
6070 {
6071 m_context.getTestContext().getLog()
6072 << tcu::TestLog::Message << "Received: " << out_data2[i * 2 + 0] << ", " << out_data2[i * 2 + 1]
6073 << ", but expected: " << expected2[i * 2 + 0] << ", " << expected2[i * 2 + 1]
6074 << tcu::TestLog::EndMessage;
6075 status = false;
6076 }
6077 }
6078
6079 if (status)
6080 return NO_ERROR;
6081 else
6082 return ERROR;
6083 }
6084
Cleanup()6085 virtual long Cleanup()
6086 {
6087 glUseProgram(0);
6088 glDeleteProgram(m_program);
6089 glDeleteBuffers(5, m_storage_buffer);
6090 return NO_ERROR;
6091 }
6092 };
6093
6094 //-----------------------------------------------------------------------------
6095 // 2.4.2 AdvancedIndirectAddressingCase2
6096 //-----------------------------------------------------------------------------
6097 class AdvancedIndirectAddressingCase2VSFS : public ShaderStorageBufferObjectBase
6098 {
6099 GLuint m_program;
6100 GLuint m_storage_buffer[8];
6101 GLuint m_vertex_array;
6102 GLuint m_vertex_buffer;
6103 GLuint m_fbo, m_rt;
6104
Setup()6105 virtual long Setup()
6106 {
6107 m_program = 0;
6108 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6109 m_vertex_array = 0;
6110 m_vertex_buffer = 0;
6111 glGenFramebuffers(1, &m_fbo);
6112 glGenTextures(1, &m_rt);
6113 return NO_ERROR;
6114 }
6115
Run()6116 virtual long Run()
6117 {
6118 if (!IsVSFSAvailable(4, 4))
6119 return NOT_SUPPORTED;
6120 GLint blocksC;
6121 glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &blocksC);
6122 if (blocksC < 8)
6123 return NOT_SUPPORTED;
6124 const char* const glsl_vs =
6125 NL "layout(location = 1) in vec2 g_in_position;" NL "layout(binding = 0, std430) buffer Transform {" NL
6126 " vec2 translation;" NL "} g_transform[4];" NL "uniform uint g_transform_id;" NL "void main() {" NL
6127 " vec2 translation = vec2(0);" NL " switch (g_transform_id) {" NL " case 0u:" NL
6128 " translation = g_transform[0].translation;" NL " break;" NL " case 1u:" NL
6129 " translation = g_transform[1].translation;" NL " break;" NL " case 2u:" NL
6130 " translation = g_transform[2].translation;" NL " break;" NL " case 3u:" NL
6131 " translation = g_transform[3].translation;" NL " break;" NL " }" NL
6132 " gl_Position = vec4(g_in_position + translation, 0, 1);" NL "}";
6133 const char* const glsl_fs = NL
6134 "layout(location = 0) out vec4 g_fs_out;" NL "layout(binding = 4, std430) buffer Material {" NL
6135 " vec3 color;" NL "} g_material[4];" NL "uniform int g_material_id;" NL "void main() {" NL
6136 " vec3 color = vec3(0);" NL " switch (g_material_id) {" NL " case 0:" NL
6137 " color = g_material[0].color;" NL " break;" NL " case 1:" NL " color = g_material[1].color;" NL
6138 " break;" NL " case 2:" NL " color = g_material[2].color;" NL " break;" NL " case 3:" NL
6139 " color = g_material[3].color;" NL " break;" NL " }" NL " g_fs_out = vec4(color, 1);" NL "}";
6140 m_program = CreateProgram(glsl_vs, glsl_fs);
6141 glLinkProgram(m_program);
6142 if (!CheckProgram(m_program))
6143 return ERROR;
6144
6145 glGenBuffers(8, m_storage_buffer);
6146
6147 /* transform buffers */
6148 {
6149 const float data[4][2] = { { -0.5f, -0.5f }, { 0.5f, -0.5f }, { -0.5f, 0.5f }, { 0.5f, 0.5f } };
6150 for (GLuint i = 0; i < 4; ++i)
6151 {
6152 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
6153 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data[i]), data[i], GL_DYNAMIC_DRAW);
6154 }
6155 }
6156 /* material buffers */
6157 {
6158 const float data[4][3] = {
6159 { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }
6160 };
6161 for (GLuint i = 0; i < 4; ++i)
6162 {
6163 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i + 4, m_storage_buffer[i + 4]);
6164 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data[i]), data[i], GL_DYNAMIC_DRAW);
6165 }
6166 }
6167
6168 /* vertex buffer */
6169 {
6170 const float data[] = { -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.4f, 0.4f };
6171 glGenBuffers(1, &m_vertex_buffer);
6172 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6173 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6174 glBindBuffer(GL_ARRAY_BUFFER, 0);
6175 }
6176
6177 glBindTexture(GL_TEXTURE_2D, m_rt);
6178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6180 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
6181 glBindTexture(GL_TEXTURE_2D, 0);
6182 glViewport(0, 0, 100, 100);
6183 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
6184 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
6185
6186 glGenVertexArrays(1, &m_vertex_array);
6187 glBindVertexArray(m_vertex_array);
6188 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6189 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
6190 glBindBuffer(GL_ARRAY_BUFFER, 0);
6191 glEnableVertexAttribArray(1);
6192 glBindVertexArray(0);
6193
6194 glUseProgram(m_program);
6195 glBindVertexArray(m_vertex_array);
6196
6197 glClear(GL_COLOR_BUFFER_BIT);
6198 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 2);
6199 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 1);
6200 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6201 if (!ValidateWindow4Quads(vec3(0), vec3(0), vec3(0), vec3(0, 1, 0)))
6202 {
6203 return ERROR;
6204 }
6205
6206 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 0);
6207 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 2);
6208 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6209 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(0), vec3(0), vec3(0, 1, 0)))
6210 {
6211 return ERROR;
6212 }
6213
6214 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 1);
6215 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 3);
6216 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
6217 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(1, 1, 0), vec3(0), vec3(0, 1, 0)))
6218 {
6219 return ERROR;
6220 }
6221
6222 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 3);
6223 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 0);
6224 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6225 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(1, 1, 0), vec3(1, 0, 0), vec3(0, 1, 0)))
6226 {
6227 return ERROR;
6228 }
6229
6230 // once again with only one validation at the end
6231 glClear(GL_COLOR_BUFFER_BIT);
6232 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 2);
6233 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 1);
6234 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6235
6236 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 0);
6237 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 2);
6238 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6239
6240 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 1);
6241 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 3);
6242 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6243
6244 glUniform1ui(glGetUniformLocation(m_program, "g_transform_id"), 3);
6245 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 0);
6246 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[7]);
6247 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6248
6249 if (!ValidateWindow4Quads(vec3(0, 0, 1), vec3(1, 1, 0), vec3(1, 1, 0), vec3(0, 1, 0)))
6250 {
6251 return ERROR;
6252 }
6253 return NO_ERROR;
6254 }
Cleanup()6255 virtual long Cleanup()
6256 {
6257 glViewport(0, 0, getWindowWidth(), getWindowHeight());
6258 glUseProgram(0);
6259 glDeleteProgram(m_program);
6260 glDeleteBuffers(8, m_storage_buffer);
6261 glDeleteBuffers(1, &m_vertex_buffer);
6262 glDeleteVertexArrays(1, &m_vertex_array);
6263 glDeleteFramebuffers(1, &m_fbo);
6264 glDeleteTextures(1, &m_rt);
6265 return NO_ERROR;
6266 }
6267 };
6268 class AdvancedIndirectAddressingCase2CS : public ShaderStorageBufferObjectBase
6269 {
6270 GLuint m_program;
6271 GLuint m_storage_buffer[5];
6272
Setup()6273 virtual long Setup()
6274 {
6275 m_program = 0;
6276 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6277 return NO_ERROR;
6278 }
6279
Run()6280 virtual long Run()
6281 {
6282 GLint blocksC;
6283 glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &blocksC);
6284 if (blocksC < 8)
6285 return NOT_SUPPORTED;
6286 bool status = true;
6287 const char* const glsl_cs =
6288 NL "layout(local_size_x = 4) in;" NL "layout(binding = 0, std430) buffer Material {" NL " vec3 color;" NL
6289 "} g_material[4];" NL "layout(binding = 4, std430) buffer OutputBuffer {" NL " vec3 color[4];" NL
6290 "};" NL "uniform int g_material_id;" NL "void main() {" NL
6291 " if (g_material_id == 0) color[gl_LocalInvocationIndex] = g_material[0].color;" NL
6292 " else if (g_material_id == 1) color[gl_LocalInvocationIndex] = g_material[1].color;" NL
6293 " else if (g_material_id == 2) color[gl_LocalInvocationIndex] = g_material[2].color;" NL
6294 " else if (g_material_id == 3) color[gl_LocalInvocationIndex] = g_material[3].color;" NL "}";
6295 m_program = CreateProgramCS(glsl_cs);
6296 glLinkProgram(m_program);
6297 if (!CheckProgram(m_program))
6298 return ERROR;
6299
6300 glGenBuffers(5, m_storage_buffer);
6301
6302 /* material buffers */
6303 const float data[4][3] = {
6304 { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }
6305 };
6306 for (GLuint i = 0; i < 4; ++i)
6307 {
6308 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
6309 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data[i]), data[i], GL_DYNAMIC_DRAW);
6310 }
6311
6312 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
6313 glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW);
6314
6315 glUseProgram(m_program);
6316 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 1);
6317 glDispatchCompute(1, 1, 1);
6318 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
6319 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6320 GLfloat* out_data = (GLfloat*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4 * 4, GL_MAP_READ_BIT);
6321 if (!out_data)
6322 return ERROR;
6323 const float* expected = &data[1][0];
6324 for (int i = 0; i < 4; ++i)
6325 {
6326 if (out_data[i * 4 + 0] != expected[0] || out_data[i * 4 + 1] != expected[1] ||
6327 out_data[i * 4 + 2] != expected[2])
6328 {
6329 m_context.getTestContext().getLog()
6330 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 0] << ", " << out_data[i * 4 + 1]
6331 << ", " << out_data[i * 4 + 2] << ", but expected: " << expected[0] << ", " << expected[1] << ", "
6332 << expected[2] << tcu::TestLog::EndMessage;
6333 status = false;
6334 }
6335 }
6336 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6337 glUniform1i(glGetUniformLocation(m_program, "g_material_id"), 3);
6338 glDispatchCompute(1, 1, 1);
6339 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6340 out_data = (GLfloat*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4 * 4, GL_MAP_READ_BIT);
6341 if (!out_data)
6342 return ERROR;
6343 expected = &data[3][0];
6344 for (int i = 0; i < 4; ++i)
6345 {
6346 if (out_data[i * 4 + 0] != expected[0] || out_data[i * 4 + 1] != expected[1] ||
6347 out_data[i * 4 + 2] != expected[2])
6348 {
6349 m_context.getTestContext().getLog()
6350 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 0] << ", " << out_data[i * 4 + 1]
6351 << ", " << out_data[i * 4 + 2] << ", but expected: " << expected[0] << ", " << expected[1] << ", "
6352 << expected[2] << tcu::TestLog::EndMessage;
6353 status = false;
6354 }
6355 }
6356
6357 if (!status)
6358 {
6359 return ERROR;
6360 }
6361 return NO_ERROR;
6362 }
6363
Cleanup()6364 virtual long Cleanup()
6365 {
6366 glUseProgram(0);
6367 glDeleteProgram(m_program);
6368 glDeleteBuffers(5, m_storage_buffer);
6369 return NO_ERROR;
6370 }
6371 };
6372 //-----------------------------------------------------------------------------
6373 // 2.5.1 AdvancedReadWriteCase1
6374 //-----------------------------------------------------------------------------
6375 class AdvancedReadWriteCase1VSFS : public ShaderStorageBufferObjectBase
6376 {
6377 GLuint m_program;
6378 GLuint m_storage_buffer;
6379 GLuint m_vertex_array;
6380 GLuint m_vertex_buffer;
6381
Setup()6382 virtual long Setup()
6383 {
6384 m_program = 0;
6385 m_storage_buffer = 0;
6386 m_vertex_array = 0;
6387 m_vertex_buffer = 0;
6388 return NO_ERROR;
6389 }
6390
Run()6391 virtual long Run()
6392 {
6393 if (!IsVSFSAvailable(1, 1))
6394 return NOT_SUPPORTED;
6395 const char* const glsl_vs = NL "layout(location = 0) in vec4 g_in_position;" NL "coherent buffer Buffer {" NL
6396 " vec4 in_color;" NL " vec4 out_color;" NL "} g_buffer;" NL "void main() {" NL
6397 " if (gl_VertexID == 0) {" NL " g_buffer.out_color = g_buffer.in_color;" NL
6398 " memoryBarrier();" NL " }" NL " gl_Position = g_in_position;" NL "}";
6399 const char* const glsl_fs =
6400 NL "layout(location = 0) out vec4 g_fs_out;" NL "coherent buffer Buffer {" NL " vec4 in_color;" NL
6401 " vec4 out_color;" NL "} g_buffer;" NL "void main() {" NL " g_fs_out = g_buffer.out_color;" NL "}";
6402 m_program = CreateProgram(glsl_vs, glsl_fs);
6403 glLinkProgram(m_program);
6404 if (!CheckProgram(m_program))
6405 return ERROR;
6406
6407 glGenBuffers(1, &m_storage_buffer);
6408 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
6409 glBufferData(GL_SHADER_STORAGE_BUFFER, 2 * sizeof(float) * 4, NULL, GL_DYNAMIC_DRAW);
6410 float* ptr = reinterpret_cast<float*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 32, GL_MAP_WRITE_BIT));
6411 if (!ptr)
6412 return ERROR;
6413 *ptr++ = 0.0f;
6414 *ptr++ = 1.0f;
6415 *ptr++ = 0.0f;
6416 *ptr++ = 1.0f;
6417 *ptr++ = 0.0f;
6418 *ptr++ = 0.0f;
6419 *ptr++ = 0.0f;
6420 *ptr++ = 0.0f;
6421 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6422
6423 /* vertex buffer */
6424 {
6425 const float data[] = { -1, -1, 1, -1, -1, 1, 1, 1 };
6426 glGenBuffers(1, &m_vertex_buffer);
6427 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6428 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6429 glBindBuffer(GL_ARRAY_BUFFER, 0);
6430 }
6431
6432 glGenVertexArrays(1, &m_vertex_array);
6433 glBindVertexArray(m_vertex_array);
6434 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6435 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
6436 glBindBuffer(GL_ARRAY_BUFFER, 0);
6437 glEnableVertexAttribArray(0);
6438 glBindVertexArray(0);
6439
6440 glClear(GL_COLOR_BUFFER_BIT);
6441 glUseProgram(m_program);
6442 glBindVertexArray(m_vertex_array);
6443 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6444 if (!CheckFB(vec3(0, 1, 0)))
6445 {
6446 return ERROR;
6447 }
6448
6449 ptr = reinterpret_cast<float*>(
6450 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(float) * 4, GL_MAP_WRITE_BIT));
6451 if (!ptr)
6452 return ERROR;
6453 *ptr++ = 1.0f;
6454 *ptr++ = 0.0f;
6455 *ptr++ = 1.0f;
6456 *ptr++ = 1.0f;
6457 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6458
6459 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6460 if (!CheckFB(vec3(1, 0, 1)))
6461 {
6462 return ERROR;
6463 }
6464
6465 return NO_ERROR;
6466 }
Cleanup()6467 virtual long Cleanup()
6468 {
6469 glUseProgram(0);
6470 glDeleteProgram(m_program);
6471 glDeleteBuffers(1, &m_storage_buffer);
6472 glDeleteBuffers(1, &m_vertex_buffer);
6473 glDeleteVertexArrays(1, &m_vertex_array);
6474 return NO_ERROR;
6475 }
6476 };
6477
6478 class AdvancedReadWriteCase1CS : public ShaderStorageBufferObjectBase
6479 {
6480 GLuint m_program;
6481 GLuint m_storage_buffer;
6482
Setup()6483 virtual long Setup()
6484 {
6485 m_program = 0;
6486 m_storage_buffer = 0;
6487 return NO_ERROR;
6488 }
Run()6489 virtual long Run()
6490 {
6491 bool status = true;
6492 const char* const glsl_cs = NL
6493 "layout(local_size_x = 128) in;" NL "struct s {" NL " int ene;" NL " int due;" NL " int like;" NL
6494 " int fake;" NL "};" NL "layout(std430) coherent buffer Buffer {" NL " s a[128];" NL "} g_buffer;" NL
6495 "void main() {" NL " g_buffer.a[gl_LocalInvocationIndex].due = g_buffer.a[gl_LocalInvocationIndex].ene;" NL
6496 " groupMemoryBarrier();" NL " barrier();" NL " g_buffer.a[(gl_LocalInvocationIndex + 1u) % 128u].like = "
6497 "g_buffer.a[(gl_LocalInvocationIndex + 1u) % 128u].due;" NL " groupMemoryBarrier();" NL " barrier();" NL
6498 " g_buffer.a[(gl_LocalInvocationIndex + 17u) % 128u].fake "
6499 "= g_buffer.a[(gl_LocalInvocationIndex + 17u) % "
6500 "128u].like;" NL "}";
6501 m_program = CreateProgramCS(glsl_cs);
6502 glLinkProgram(m_program);
6503 if (!CheckProgram(m_program))
6504 return ERROR;
6505
6506 glGenBuffers(1, &m_storage_buffer);
6507 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
6508 GLint data[128 * 4];
6509 for (int i = 0; i < 128; ++i)
6510 {
6511 data[i * 4] = i + 256;
6512 data[i * 4 + 1] = 0;
6513 data[i * 4 + 2] = 0;
6514 data[i * 4 + 3] = 0;
6515 }
6516 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data[0], GL_DYNAMIC_DRAW);
6517
6518 glUseProgram(m_program);
6519 glDispatchCompute(1, 1, 1);
6520 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6521 GLint* out_data = (GLint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), GL_MAP_READ_BIT);
6522 if (!out_data)
6523 return ERROR;
6524 for (int i = 0; i < 128; ++i)
6525 {
6526 if (out_data[i * 4 + 3] != data[i * 4])
6527 {
6528 m_context.getTestContext().getLog()
6529 << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 3] << ", but expected: " << data[i * 4]
6530 << " -> " << out_data[i * 4 + 1] << " -> " << out_data[i * 4 + 2] << tcu::TestLog::EndMessage;
6531 status = false;
6532 }
6533 }
6534 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6535 for (int i = 0; i < 128; ++i)
6536 {
6537 data[i * 4] = i + 512;
6538 data[i * 4 + 1] = 0;
6539 data[i * 4 + 2] = 0;
6540 data[i * 4 + 3] = 0;
6541 }
6542 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data[0], GL_DYNAMIC_DRAW);
6543
6544 glDispatchCompute(1, 1, 1);
6545 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6546 out_data = (GLint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), GL_MAP_READ_BIT);
6547 if (!out_data)
6548 return ERROR;
6549 for (int i = 0; i < 128; ++i)
6550 {
6551 if (out_data[i * 4 + 3] != data[i * 4])
6552 {
6553 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Received: " << out_data[i * 4 + 3]
6554 << ", but expected: " << data[i * 4] << tcu::TestLog::EndMessage;
6555 status = false;
6556 }
6557 }
6558 if (status)
6559 return NO_ERROR;
6560 else
6561 return ERROR;
6562 }
6563
Cleanup()6564 virtual long Cleanup()
6565 {
6566 glUseProgram(0);
6567 glDeleteProgram(m_program);
6568 glDeleteBuffers(1, &m_storage_buffer);
6569 return NO_ERROR;
6570 }
6571 };
6572 //-----------------------------------------------------------------------------
6573 // 2.6.1 AdvancedUsageCase1
6574 //-----------------------------------------------------------------------------
6575 class AdvancedUsageCase1 : public ShaderStorageBufferObjectBase
6576 {
6577 GLuint m_program;
6578 GLuint m_storage_buffer[3];
6579 GLuint m_vertex_array;
6580 GLuint m_vertex_buffer;
6581 GLuint m_fbo, m_rt;
6582
Setup()6583 virtual long Setup()
6584 {
6585 m_program = 0;
6586 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6587 m_vertex_array = 0;
6588 m_vertex_buffer = 0;
6589 glGenFramebuffers(1, &m_fbo);
6590 glGenTextures(1, &m_rt);
6591 return NO_ERROR;
6592 }
Run()6593 virtual long Run()
6594 {
6595 using namespace tcu;
6596
6597 if (!IsVSFSAvailable(2, 2))
6598 return NOT_SUPPORTED;
6599 const char* const glsl_vs =
6600 NL "layout(location = 0) in vec4 g_position;" NL "layout(location = 1) in int g_object_id;" NL
6601 "flat out int object_id;" NL "layout(binding = 0) buffer TransformBuffer {" NL
6602 " mat4 g_transform[4];" NL "};" NL "void main() {" NL " mat4 mvp = g_transform[g_object_id];" NL
6603 " gl_Position = mvp * g_position;" NL " object_id = g_object_id;" NL "}";
6604 const char* const glsl_fs =
6605 NL "flat in int object_id;" NL "layout(location = 0) out vec4 g_fs_out;" NL "struct Material {" NL
6606 " vec3 color;" NL "};" NL "layout(binding = 1, std430) buffer MaterialBuffer {" NL
6607 " Material g_material[4];" NL "};" NL "layout(binding = 2, std430) buffer MaterialIDBuffer {" NL
6608 " int g_material_id[4];" NL "};" NL "void main() {" NL " int mid = g_material_id[object_id];" NL
6609 " Material m = g_material[mid];" NL " g_fs_out = vec4(m.color, 1);" NL "}";
6610 m_program = CreateProgram(glsl_vs, glsl_fs);
6611 glLinkProgram(m_program);
6612 if (!CheckProgram(m_program))
6613 return ERROR;
6614
6615 glGenBuffers(3, m_storage_buffer);
6616
6617 /* transform buffer */
6618 {
6619 mat4 data[] = { transpose(Translation(-0.5f, -0.5f, 0.0f)), transpose(Translation(0.5f, -0.5f, 0.0f)),
6620 transpose(Translation(-0.5f, 0.5f, 0.0f)), transpose(Translation(0.5f, 0.5f, 0.0f)) };
6621 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
6622 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6623 }
6624 /* material buffer */
6625 {
6626 vec4 data[] = { vec4(1, 0, 0, 1), vec4(0, 1, 0, 1), vec4(0, 0, 1, 0), vec4(1, 1, 0, 1) };
6627 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
6628 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6629 }
6630 /* material id buffer */
6631 {
6632 int data[] = { 0, 1, 2, 3 };
6633 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
6634 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6635 }
6636 /* vertex buffer */
6637 {
6638 struct
6639 {
6640 vec2 position;
6641 int object_id;
6642 } data[] = { { vec2(-0.4f, -0.4f), 0 }, { vec2(0.4f, -0.4f), 0 }, { vec2(-0.4f, 0.4f), 0 },
6643 { vec2(0.4f, 0.4f), 0 }, { vec2(-0.4f, -0.4f), 1 }, { vec2(0.4f, -0.4f), 1 },
6644 { vec2(-0.4f, 0.4f), 1 }, { vec2(0.4f, 0.4f), 1 }, { vec2(-0.4f, -0.4f), 2 },
6645 { vec2(0.4f, -0.4f), 2 }, { vec2(-0.4f, 0.4f), 2 }, { vec2(0.4f, 0.4f), 2 },
6646 { vec2(-0.4f, -0.4f), 3 }, { vec2(0.4f, -0.4f), 3 }, { vec2(-0.4f, 0.4f), 3 },
6647 { vec2(0.4f, 0.4f), 3 } };
6648 glGenBuffers(1, &m_vertex_buffer);
6649 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6650 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
6651 glBindBuffer(GL_ARRAY_BUFFER, 0);
6652 }
6653
6654 glBindTexture(GL_TEXTURE_2D, m_rt);
6655 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6656 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6657 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
6658 glBindTexture(GL_TEXTURE_2D, 0);
6659 glViewport(0, 0, 100, 100);
6660 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
6661 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
6662
6663 glGenVertexArrays(1, &m_vertex_array);
6664 glBindVertexArray(m_vertex_array);
6665 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
6666 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vec2) + sizeof(int), 0);
6667 glVertexAttribIPointer(1, 1, GL_INT, sizeof(vec2) + sizeof(int), reinterpret_cast<void*>(sizeof(vec2)));
6668 glBindBuffer(GL_ARRAY_BUFFER, 0);
6669 glEnableVertexAttribArray(0);
6670 glEnableVertexAttribArray(1);
6671 glBindVertexArray(0);
6672
6673 glClear(GL_COLOR_BUFFER_BIT);
6674 glUseProgram(m_program);
6675 glBindVertexArray(m_vertex_array);
6676 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
6677 glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
6678 glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
6679 glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
6680 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1)))
6681 {
6682 return ERROR;
6683 }
6684 return NO_ERROR;
6685 }
6686
Cleanup()6687 virtual long Cleanup()
6688 {
6689 glViewport(0, 0, getWindowWidth(), getWindowHeight());
6690 glUseProgram(0);
6691 glDeleteProgram(m_program);
6692 glDeleteBuffers(3, m_storage_buffer);
6693 glDeleteBuffers(1, &m_vertex_buffer);
6694 glDeleteVertexArrays(1, &m_vertex_array);
6695 glDeleteFramebuffers(1, &m_fbo);
6696 glDeleteTextures(1, &m_rt);
6697 return NO_ERROR;
6698 }
6699 };
6700 //-----------------------------------------------------------------------------
6701 // 2.6.2 AdvancedUsageSync
6702 //-----------------------------------------------------------------------------
6703 class AdvancedUsageSyncVSFS : public ShaderStorageBufferObjectBase
6704 {
6705 GLuint m_program;
6706 GLuint m_storage_buffer[7];
6707 GLuint m_vertex_array;
6708
Setup()6709 virtual long Setup()
6710 {
6711 m_program = 0;
6712 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6713 m_vertex_array = 0;
6714 return NO_ERROR;
6715 }
Run()6716 virtual long Run()
6717 {
6718 if (!IsVSFSAvailable(3, 4))
6719 return NOT_SUPPORTED;
6720 const char* const glsl_vs = NL
6721 "layout(std430, binding = 0) coherent buffer Buffer0 {" NL " int g_data0, g_inc0;" NL
6722 " int g_data1, g_inc1;" NL "};" NL "layout(std430, binding = 1) buffer Buffer12 {" NL " int inc, data;" NL
6723 "} g_buffer12[2];" NL "flat out int primitive_id;" NL NL "void Modify(int path) {" NL
6724 " if (path == 0) {" NL " atomicAdd(g_data0, g_inc0);" NL " atomicAdd(g_data1, g_inc0);" NL
6725 " } else if (path == 1) {" NL " atomicAdd(g_data0, - g_inc0);" NL " atomicAdd(g_data1, - g_inc0);" NL
6726 " } else if (path == 2) {" NL " atomicAdd(g_data0, g_inc1);" NL " atomicAdd(g_data1, g_inc1);" NL
6727 " }" NL NL " if (path == 0) {" NL " g_buffer12[0].data += g_buffer12[1].inc;" NL
6728 " } else if (path == 1) {" NL " g_buffer12[1].data += g_buffer12[0].inc;" NL " }" NL "}" NL NL
6729 "void main() {" NL " Modify(gl_VertexID);" NL " primitive_id = gl_VertexID;" NL
6730 " gl_Position = vec4(0, 0, 0, 1);" NL "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL "}";
6731 const char* glsl_fs =
6732 NL "layout(binding = 3, std430) coherent buffer Buffer3 {" NL " int data;" NL "} g_buffer3;" NL
6733 "layout(std430, binding = 4) coherent buffer Buffer4 {" NL " int data0, inc0;" NL
6734 " int data1, inc1;" NL "} g_buffer4;" NL "layout(std430, binding = 5) buffer Buffer56 {" NL
6735 " int inc, data;" NL "} g_buffer56[2];" NL "flat in int primitive_id;" NL NL
6736 "void ModifyFS(int path) {" NL " if (path == 0) {" NL
6737 " atomicAdd(g_buffer4.data0, g_buffer4.inc0);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc0);" NL
6738 " } else if (path == 1) {" NL " atomicAdd(g_buffer4.data0, - g_buffer4.inc0);" NL
6739 " atomicAdd(g_buffer4.data1, - g_buffer4.inc0);" NL " } else if (path == 2) {" NL
6740 " atomicAdd(g_buffer4.data0, g_buffer4.inc1);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc1);" NL
6741 " }" NL NL " if (path == 0) {" NL " g_buffer56[0].data += g_buffer56[1].inc;" NL
6742 " } else if (path == 1) {" NL " g_buffer56[1].data += g_buffer56[0].inc;" NL " }" NL "}" NL
6743 "void main() {" NL " atomicAdd(g_buffer3.data, 1);" NL " ModifyFS(primitive_id);" NL "}";
6744 m_program = CreateProgram(glsl_vs, glsl_fs);
6745 glLinkProgram(m_program);
6746 if (!CheckProgram(m_program))
6747 return ERROR;
6748
6749 glGenVertexArrays(1, &m_vertex_array);
6750 glGenBuffers(7, m_storage_buffer);
6751
6752 /* Buffer0 */
6753 {
6754 int data[4] = { 0, 1, 0, 2 };
6755 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
6756 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6757 }
6758 /* Buffer1 */
6759 {
6760 int data[2] = { 3, 1 };
6761 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
6762 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6763 }
6764 /* Buffer2 */
6765 {
6766 int data[2] = { 2, 4 };
6767 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
6768 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6769 }
6770 /* Buffer3 */
6771 {
6772 int data[1] = { 0 };
6773 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
6774 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6775 }
6776 /* Buffer4 */
6777 {
6778 int data[4] = { 0, 1, 0, 2 };
6779 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
6780 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6781 }
6782 /* Buffer5 */
6783 {
6784 int data[2] = { 3, 1 };
6785 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, m_storage_buffer[5]);
6786 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6787 }
6788 /* Buffer6 */
6789 {
6790 int data[2] = { 2, 4 };
6791 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, m_storage_buffer[6]);
6792 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6793 }
6794
6795 glUseProgram(m_program);
6796 glBindVertexArray(m_vertex_array);
6797
6798 glDrawArrays(GL_POINTS, 0, 3);
6799 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
6800 glDrawArrays(GL_POINTS, 0, 3);
6801 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
6802
6803 /* Buffer0 */
6804 {
6805 const int ref_data[4] = { 4, 1, 4, 2 };
6806 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
6807 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
6808 if (!data)
6809 return ERROR;
6810 for (int i = 0; i < 4; ++i)
6811 {
6812 if (data[i] != ref_data[i])
6813 {
6814 m_context.getTestContext().getLog()
6815 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
6816 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6817 return ERROR;
6818 }
6819 }
6820 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6821 }
6822 /* Buffer1 */
6823 {
6824 const int ref_data[2] = { 3, 5 };
6825 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
6826 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6827 if (!data)
6828 return ERROR;
6829 for (int i = 0; i < 2; ++i)
6830 {
6831 if (data[i] != ref_data[i])
6832 {
6833 m_context.getTestContext().getLog()
6834 << tcu::TestLog::Message << "[Buffer1] Data at index " << i << " is " << data[i]
6835 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6836 return ERROR;
6837 }
6838 }
6839 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6840 }
6841 /* Buffer2 */
6842 {
6843 const int ref_data[2] = { 2, 10 };
6844 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
6845 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6846 if (!data)
6847 return ERROR;
6848 for (int i = 0; i < 2; ++i)
6849 {
6850 if (data[i] != ref_data[i])
6851 {
6852 m_context.getTestContext().getLog()
6853 << tcu::TestLog::Message << "[Buffer2] Data at index " << i << " is " << data[i]
6854 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6855 return ERROR;
6856 }
6857 }
6858 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6859 }
6860 /* Buffer3 */
6861 {
6862 const int ref_data[1] = { 6 };
6863 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
6864 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
6865 if (!data)
6866 return ERROR;
6867 for (int i = 0; i < 1; ++i)
6868 {
6869 if (data[i] != ref_data[i])
6870 {
6871 m_context.getTestContext().getLog()
6872 << tcu::TestLog::Message << "[Buffer3] Data at index " << i << " is " << data[i]
6873 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6874 return ERROR;
6875 }
6876 }
6877 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6878 }
6879 /* Buffer4 */
6880 {
6881 const int ref_data[4] = { 4, 1, 4, 2 };
6882 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
6883 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
6884 if (!data)
6885 return ERROR;
6886 for (int i = 0; i < 4; ++i)
6887 {
6888 if (data[i] != ref_data[i])
6889 {
6890 m_context.getTestContext().getLog()
6891 << tcu::TestLog::Message << "[Buffer4] Data at index " << i << " is " << data[i]
6892 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6893 return ERROR;
6894 }
6895 }
6896 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6897 }
6898 /* Buffer5 */
6899 {
6900 const int ref_data[2] = { 3, 5 };
6901 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
6902 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6903 if (!data)
6904 return ERROR;
6905 for (int i = 0; i < 2; ++i)
6906 {
6907 if (data[i] != ref_data[i])
6908 {
6909 m_context.getTestContext().getLog()
6910 << tcu::TestLog::Message << "[Buffer5] Data at index " << i << " is " << data[i]
6911 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6912 return ERROR;
6913 }
6914 }
6915 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6916 }
6917 /* Buffer6 */
6918 {
6919 const int ref_data[2] = { 2, 10 };
6920 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[6]);
6921 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
6922 if (!data)
6923 return ERROR;
6924 for (int i = 0; i < 2; ++i)
6925 {
6926 if (data[i] != ref_data[i])
6927 {
6928 m_context.getTestContext().getLog()
6929 << tcu::TestLog::Message << "[Buffer6] Data at index " << i << " is " << data[i]
6930 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
6931 return ERROR;
6932 }
6933 }
6934 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
6935 }
6936
6937 return NO_ERROR;
6938 }
6939
Cleanup()6940 virtual long Cleanup()
6941 {
6942 glUseProgram(0);
6943 glDeleteProgram(m_program);
6944 glDeleteBuffers(7, m_storage_buffer);
6945 glDeleteVertexArrays(1, &m_vertex_array);
6946 return NO_ERROR;
6947 }
6948 };
6949
6950 class AdvancedUsageSyncCS : public ShaderStorageBufferObjectBase
6951 {
6952 GLuint m_program;
6953 GLuint m_storage_buffer[7];
6954
Setup()6955 virtual long Setup()
6956 {
6957 m_program = 0;
6958 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
6959 return NO_ERROR;
6960 }
6961
Run()6962 virtual long Run()
6963 {
6964 const char* const glsl_cs =
6965 NL "layout(local_size_x = 1) in;" NL "layout(std430, binding = 0) coherent buffer Buffer0 {" NL
6966 " int g_data0, g_inc0;" NL " int g_data1, g_inc1;" NL "};" NL
6967 "layout(std430, binding = 1) buffer Buffer12 {" NL " int inc, data;" NL "} g_buffer12[2];" NL
6968 "layout(binding = 3, std430) coherent buffer Buffer3 {" NL " int data;" NL "} g_buffer3;" NL
6969 "layout(std430, binding = 4) coherent buffer Buffer4 {" NL " int data0, inc0;" NL
6970 " int data1, inc1;" NL "} g_buffer4;" NL "layout(std430, binding = 5) buffer Buffer56 {" NL
6971 " int inc, data;" NL "} g_buffer56[2];" NL NL "void Modify1(int path) {" NL " if (path == 0) {" NL
6972 " atomicAdd(g_data0, g_inc0);" NL " atomicAdd(g_data1, g_inc0);" NL " } else if (path == 1) {" NL
6973 " atomicAdd(g_data0, - g_inc0);" NL " atomicAdd(g_data1, - g_inc0);" NL
6974 " } else if (path == 2) {" NL " atomicAdd(g_data0, g_inc1);" NL " atomicAdd(g_data1, g_inc1);" NL
6975 " }" NL " if (path == 0) {" NL " g_buffer12[0].data += g_buffer12[1].inc;" NL
6976 " } else if (path == 1) {" NL " g_buffer12[1].data += g_buffer12[0].inc;" NL " }" NL "}" NL NL
6977 "void Modify2(int path) {" NL " if (path == 0) {" NL
6978 " atomicAdd(g_buffer4.data0, g_buffer4.inc0);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc0);" NL
6979 " } else if (path == 1) {" NL " atomicAdd(g_buffer4.data0, - g_buffer4.inc0);" NL
6980 " atomicAdd(g_buffer4.data1, - g_buffer4.inc0);" NL " } else if (path == 2) {" NL
6981 " atomicAdd(g_buffer4.data0, g_buffer4.inc1);" NL " atomicAdd(g_buffer4.data1, g_buffer4.inc1);" NL
6982 " }" NL " if (path == 0) {" NL " g_buffer56[0].data += g_buffer56[1].inc;" NL
6983 " } else if (path == 1) {" NL " g_buffer56[1].data += g_buffer56[0].inc;" NL " }" NL "}" NL NL
6984 "void main() {" NL " Modify1(int(gl_WorkGroupID.z));" NL " atomicAdd(g_buffer3.data, 1);" NL
6985 " Modify2(int(gl_WorkGroupID.z));" NL "}";
6986 m_program = CreateProgramCS(glsl_cs);
6987 glLinkProgram(m_program);
6988 if (!CheckProgram(m_program))
6989 return ERROR;
6990
6991 glGenBuffers(7, m_storage_buffer);
6992
6993 /* Buffer0 */
6994 {
6995 int data[4] = { 0, 1, 0, 2 };
6996 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
6997 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
6998 }
6999 /* Buffer1 */
7000 {
7001 int data[2] = { 3, 1 };
7002 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
7003 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7004 }
7005 /* Buffer2 */
7006 {
7007 int data[2] = { 2, 4 };
7008 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2]);
7009 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7010 }
7011 /* Buffer3 */
7012 {
7013 int data[1] = { 0 };
7014 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[3]);
7015 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7016 }
7017 /* Buffer4 */
7018 {
7019 int data[4] = { 0, 1, 0, 2 };
7020 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[4]);
7021 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7022 }
7023 /* Buffer5 */
7024 {
7025 int data[2] = { 3, 1 };
7026 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, m_storage_buffer[5]);
7027 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7028 }
7029 /* Buffer6 */
7030 {
7031 int data[2] = { 2, 4 };
7032 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, m_storage_buffer[6]);
7033 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7034 }
7035
7036 glUseProgram(m_program);
7037
7038 glDispatchCompute(1, 1, 3);
7039 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
7040 glDispatchCompute(1, 1, 3);
7041
7042 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7043
7044 /* Buffer0 */
7045 {
7046 const int ref_data[4] = { 4, 1, 4, 2 };
7047 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
7048 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7049 if (!data)
7050 return ERROR;
7051 for (int i = 0; i < 2; ++i)
7052 {
7053 /* g_data incremented in VS which can be invoked multiple times per vertex */
7054 if (data[2*i] < ref_data[2*i])
7055 {
7056 m_context.getTestContext().getLog()
7057 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7058 << " should be at least" << ref_data[i] << tcu::TestLog::EndMessage;
7059 return ERROR;
7060 }
7061 /* g_inc */
7062 if (data[2*i + 1] != ref_data[2*i + 1])
7063 {
7064 m_context.getTestContext().getLog()
7065 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7066 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7067 return ERROR;
7068 }
7069 }
7070 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7071 }
7072 /* Buffer1 */
7073 {
7074 const int ref_data[2] = { 3, 5 };
7075 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
7076 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7077 if (!data)
7078 return ERROR;
7079 /* inc */
7080 if (data[0] != ref_data[0])
7081 {
7082 m_context.getTestContext().getLog()
7083 << tcu::TestLog::Message << "[Buffer1] Data at index 0 is " << data[0]
7084 << " should be " << ref_data[0] << tcu::TestLog::EndMessage;
7085 return ERROR;
7086 }
7087 /* data incremented in VS which can be invoked multiple times per vertex */
7088 if (data[1] < ref_data[1])
7089 {
7090 m_context.getTestContext().getLog()
7091 << tcu::TestLog::Message << "[Buffer1] Data at index 1 is " << data[1]
7092 << " should be at least" << ref_data[1] << tcu::TestLog::EndMessage;
7093 return ERROR;
7094 }
7095 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7096 }
7097 /* Buffer2 */
7098 {
7099 const int ref_data[2] = { 2, 10 };
7100 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]);
7101 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7102 if (!data)
7103 return ERROR;
7104 /* inc */
7105 if (data[0] != ref_data[0])
7106 {
7107 m_context.getTestContext().getLog()
7108 << tcu::TestLog::Message << "[Buffer2] Data at index 0 is " << data[0]
7109 << " should be " << ref_data[0] << tcu::TestLog::EndMessage;
7110 return ERROR;
7111 }
7112 /* data incremented in VS which can be invoked multiple times per vertex */
7113 if (data[1] < ref_data[1])
7114 {
7115 m_context.getTestContext().getLog()
7116 << tcu::TestLog::Message << "[Buffer2] Data at index 1 is " << data[1]
7117 << " should be at least" << ref_data[1] << tcu::TestLog::EndMessage;
7118 return ERROR;
7119 }
7120 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7121 }
7122 /* Buffer3 */
7123 {
7124 const int ref_data[1] = { 6 };
7125 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
7126 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
7127 if (!data)
7128 return ERROR;
7129 for (int i = 0; i < 1; ++i)
7130 {
7131 if (data[i] != ref_data[i])
7132 {
7133 m_context.getTestContext().getLog()
7134 << tcu::TestLog::Message << "[Buffer3] Data at index " << i << " is " << data[i]
7135 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7136 return ERROR;
7137 }
7138 }
7139 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7140 }
7141 /* Buffer4 */
7142 {
7143 const int ref_data[4] = { 4, 1, 4, 2 };
7144 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
7145 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7146 if (!data)
7147 return ERROR;
7148 for (int i = 0; i < 4; ++i)
7149 {
7150 if (data[i] != ref_data[i])
7151 {
7152 m_context.getTestContext().getLog()
7153 << tcu::TestLog::Message << "[Buffer4] Data at index " << i << " is " << data[i]
7154 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7155 return ERROR;
7156 }
7157 }
7158 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7159 }
7160 /* Buffer5 */
7161 {
7162 const int ref_data[2] = { 3, 5 };
7163 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[5]);
7164 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7165 if (!data)
7166 return ERROR;
7167 for (int i = 0; i < 2; ++i)
7168 {
7169 if (data[i] != ref_data[i])
7170 {
7171 m_context.getTestContext().getLog()
7172 << tcu::TestLog::Message << "[Buffer5] Data at index " << i << " is " << data[i]
7173 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7174 return ERROR;
7175 }
7176 }
7177 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7178 }
7179 /* Buffer6 */
7180 {
7181 const int ref_data[2] = { 2, 10 };
7182 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[6]);
7183 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 8, GL_MAP_READ_BIT);
7184 if (!data)
7185 return ERROR;
7186 for (int i = 0; i < 2; ++i)
7187 {
7188 if (data[i] != ref_data[i])
7189 {
7190 m_context.getTestContext().getLog()
7191 << tcu::TestLog::Message << "[Buffer6] Data at index " << i << " is " << data[i]
7192 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7193 return ERROR;
7194 }
7195 }
7196 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7197 }
7198
7199 return NO_ERROR;
7200 }
7201
Cleanup()7202 virtual long Cleanup()
7203 {
7204 glUseProgram(0);
7205 glDeleteProgram(m_program);
7206 glDeleteBuffers(7, m_storage_buffer);
7207 return NO_ERROR;
7208 }
7209 };
7210 //-----------------------------------------------------------------------------
7211 // 2.6.3 AdvancedUsageOperators
7212 //-----------------------------------------------------------------------------
7213 class AdvancedUsageOperatorsVS : public ShaderStorageBufferObjectBase
7214 {
7215 GLuint m_program;
7216 GLuint m_storage_buffer[2];
7217 GLuint m_vertex_array;
7218
Setup()7219 virtual long Setup()
7220 {
7221 m_program = 0;
7222 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7223 m_vertex_array = 0;
7224 return NO_ERROR;
7225 }
7226
Run()7227 virtual long Run()
7228 {
7229 if (!IsVSFSAvailable(2, 0))
7230 return NOT_SUPPORTED;
7231 const char* const glsl_vs =
7232 NL "layout(std430, binding = 0) buffer Buffer0 {" NL " readonly int g_i0;" NL " int g_o0;" NL "};" NL
7233 "layout(std430, binding = 1) buffer Buffer1 {" NL " int i0;" NL "} g_buffer1;" NL
7234 "const int g_values[6] = int[](1, 2, 3, 4, 5, 6);" NL "void main() {" NL " g_o0 += g_i0;" NL
7235 " g_o0 <<= 1;" NL " g_o0 = g_i0 > g_o0 ? g_i0 : g_o0;" NL " g_o0 *= g_i0;" NL
7236 " g_o0 = --g_o0 + g_values[g_i0];" NL " g_o0++;" NL " ++g_o0;" NL " g_buffer1.i0 = 0xff2f;" NL
7237 " g_o0 &= g_buffer1.i0;" NL "}";
7238 const char* const glsl_fs = NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
7239 " o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
7240
7241 m_program = CreateProgram(glsl_vs, glsl_fs);
7242 glLinkProgram(m_program);
7243 if (!CheckProgram(m_program))
7244 return ERROR;
7245
7246 glGenVertexArrays(1, &m_vertex_array);
7247 glGenBuffers(2, m_storage_buffer);
7248
7249 /* Buffer0 */
7250 {
7251 int data[4] = { 3, 5 };
7252 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
7253 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7254 }
7255 /* Buffer1 */
7256 {
7257 int data[1] = { 0 };
7258 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
7259 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7260 }
7261
7262 glEnable(GL_RASTERIZER_DISCARD);
7263 glUseProgram(m_program);
7264 glBindVertexArray(m_vertex_array);
7265 glDrawArrays(GL_POINTS, 0, 1);
7266 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7267
7268 /* Buffer0 */
7269 {
7270 const int ref_data[2] = { 3, 37 };
7271 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
7272 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7273 if (!data)
7274 return ERROR;
7275 for (int i = 0; i < 2; ++i)
7276 {
7277 if (data[i] != ref_data[i])
7278 {
7279 m_context.getTestContext().getLog()
7280 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7281 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7282 return ERROR;
7283 }
7284 }
7285 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7286 }
7287 /* Buffer0 */
7288 {
7289 const int ref_data[1] = { 0xff2f };
7290 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]);
7291 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_READ_BIT);
7292 if (!data)
7293 return ERROR;
7294 for (int i = 0; i < 1; ++i)
7295 {
7296 if (data[i] != ref_data[i])
7297 {
7298 m_context.getTestContext().getLog()
7299 << tcu::TestLog::Message << "[Buffer1] Data at index " << i << " is " << data[i]
7300 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7301 return ERROR;
7302 }
7303 }
7304 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7305 }
7306
7307 return NO_ERROR;
7308 }
7309
Cleanup()7310 virtual long Cleanup()
7311 {
7312 glDisable(GL_RASTERIZER_DISCARD);
7313 glUseProgram(0);
7314 glDeleteProgram(m_program);
7315 glDeleteBuffers(2, m_storage_buffer);
7316 glDeleteVertexArrays(1, &m_vertex_array);
7317 return NO_ERROR;
7318 }
7319 };
7320
7321 class AdvancedUsageOperatorsCS : public ShaderStorageBufferObjectBase
7322 {
7323 GLuint m_program;
7324 GLuint m_storage_buffer[2];
7325
Setup()7326 virtual long Setup()
7327 {
7328 m_program = 0;
7329 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7330 return NO_ERROR;
7331 }
Run()7332 virtual long Run()
7333 {
7334 const char* const glsl_cs =
7335 NL "layout(local_size_x = 1) in;" NL "layout(std430, binding = 0) buffer Buffer0 {" NL
7336 " readonly int g_i0;" NL " int g_o0;" NL "};" NL "layout(std430, binding = 1) buffer Buffer1 {" NL
7337 " int i0;" NL "} g_buffer1;" NL "const int g_values[6] = int[](1, 2, 3, 4, 5, 6);" NL "void main() {" NL
7338 " 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
7339 " g_o0 = --g_o0 + g_values[g_i0];" NL " g_o0++;" NL " ++g_o0;" NL " g_buffer1.i0 = 0xff2f;" NL
7340 " g_o0 &= g_buffer1.i0;" NL "}";
7341
7342 m_program = CreateProgramCS(glsl_cs);
7343 glLinkProgram(m_program);
7344 if (!CheckProgram(m_program))
7345 return ERROR;
7346
7347 glGenBuffers(2, m_storage_buffer);
7348
7349 /* Buffer0 */
7350 {
7351 int data[4] = { 3, 5 };
7352 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
7353 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7354 }
7355 /* Buffer1 */
7356 {
7357 int data[1] = { 0 };
7358 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
7359 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
7360 }
7361
7362 glUseProgram(m_program);
7363 glDispatchCompute(1, 1, 1);
7364 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7365
7366 /* Buffer0 */
7367 {
7368 const int ref_data[2] = { 3, 37 };
7369 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]);
7370 int* data = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT);
7371 if (!data)
7372 return ERROR;
7373 for (int i = 0; i < 2; ++i)
7374 {
7375 if (data[i] != ref_data[i])
7376 {
7377 m_context.getTestContext().getLog()
7378 << tcu::TestLog::Message << "[Buffer0] Data at index " << i << " is " << data[i]
7379 << " should be " << ref_data[i] << tcu::TestLog::EndMessage;
7380 return ERROR;
7381 }
7382 }
7383 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7384 }
7385
7386 return NO_ERROR;
7387 }
7388
Cleanup()7389 virtual long Cleanup()
7390 {
7391 glUseProgram(0);
7392 glDeleteProgram(m_program);
7393 glDeleteBuffers(2, m_storage_buffer);
7394 return NO_ERROR;
7395 }
7396 };
7397
7398 //-----------------------------------------------------------------------------
7399 // 2.7 AdvancedUnsizedArrayLength
7400 //-----------------------------------------------------------------------------
7401 template <int stage>
7402 class AdvancedUnsizedArrayLength : public ShaderStorageBufferObjectBase
7403 {
7404 GLuint m_program;
7405 GLuint m_storage_buffer[4];
7406 GLuint m_vertex_array;
7407
Setup()7408 virtual long Setup()
7409 {
7410 m_program = 0;
7411 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7412 m_vertex_array = 0;
7413 return NO_ERROR;
7414 }
Cleanup()7415 virtual long Cleanup()
7416 {
7417 glUseProgram(0);
7418 glDeleteProgram(m_program);
7419 glDeleteBuffers(4, m_storage_buffer);
7420 if (stage != compute)
7421 glDeleteVertexArrays(1, &m_vertex_array);
7422 return NO_ERROR;
7423 }
BuildShaderPT(int st)7424 std::string BuildShaderPT(int st)
7425 {
7426 std::ostringstream os;
7427 if (st == vertex)
7428 {
7429 os << NL "void main() {" NL " gl_Position = vec4(0,0,0,1);" NL "#ifdef GL_ES" NL
7430 " gl_PointSize = 1.0f;" NL "#endif";
7431 }
7432 if (st == fragment)
7433 {
7434 os << NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
7435 " o_color = vec4(0.0, 1.0, 0.0, 1.0);";
7436 }
7437 os << NL "}";
7438 return os.str();
7439 }
BuildShader()7440 std::string BuildShader()
7441 {
7442 std::ostringstream os;
7443 std::string decl =
7444 NL "layout(std430, binding = 0) readonly buffer Input0 {" NL " uint g_input0[];" NL "};" NL
7445 "layout(std430, binding = 1) readonly buffer Input23 {" NL " float data[];" NL "} g_input23[2];" NL
7446 "layout(std430, binding = 3) buffer Output {" NL " int g_length2;" NL " int g_length[];" NL "};";
7447 std::string expr = NL " g_length[0] = g_input0.length();" NL " g_length[1] = g_input23[0].data.length();" NL
7448 " g_length[2] = g_input23[1].data.length();" NL " g_length2 = g_length.length();";
7449 if (stage == vertex)
7450 {
7451 os << decl << NL "void main() {" NL "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL
7452 " gl_Position = vec4(0,0,0,1);"
7453 << expr;
7454 }
7455 if (stage == fragment)
7456 {
7457 os << NL "layout(location = 0) out vec4 o_color;" << decl
7458 << NL "void main() {" NL " o_color = vec4(0.0, 1.0, 0.0, 1.0);" << expr;
7459 }
7460 if (stage == compute)
7461 {
7462 os << NL "layout(local_size_x = 1) in;" << decl << NL "void main() {" << expr;
7463 }
7464 os << NL "}";
7465 return os.str();
7466 }
7467
Run()7468 virtual long Run()
7469 {
7470 const int kSize = 10000;
7471 const int kBufs = 4;
7472 if ((stage == vertex && !IsVSFSAvailable(kBufs, 0)) || (stage == fragment && !IsVSFSAvailable(0, kBufs)))
7473 return NOT_SUPPORTED;
7474 if (stage == vertex)
7475 {
7476 std::string glsl_vs = BuildShader();
7477 std::string glsl_fs = BuildShaderPT(fragment);
7478 m_program = CreateProgram(glsl_vs, glsl_fs);
7479 }
7480 else if (stage == fragment)
7481 {
7482 std::string glsl_vs = BuildShaderPT(vertex);
7483 std::string glsl_fs = BuildShader();
7484 m_program = CreateProgram(glsl_vs, glsl_fs);
7485 }
7486 else
7487 { // compute
7488 std::string glsl_cs = BuildShader();
7489 m_program = CreateProgramCS(glsl_cs);
7490 }
7491 glLinkProgram(m_program);
7492 if (!CheckProgram(m_program))
7493 return ERROR;
7494 glUseProgram(m_program);
7495
7496 glGenBuffers(kBufs, m_storage_buffer);
7497 int sizes[kBufs] = { 7, 3, 4, 5 };
7498 std::vector<int> data(kSize, 41);
7499 for (int i = 0; i < kBufs; ++i)
7500 {
7501 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
7502 glBufferData(GL_SHADER_STORAGE_BUFFER, sizes[i] * 4, &data[0], GL_DYNAMIC_COPY);
7503 }
7504
7505 if (stage != compute)
7506 {
7507 glGenVertexArrays(1, &m_vertex_array);
7508 glBindVertexArray(m_vertex_array);
7509 glDrawArrays(GL_POINTS, 0, 1);
7510 }
7511 else
7512 {
7513 glDispatchCompute(1, 1, 1);
7514 }
7515 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7516
7517 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]);
7518 int* dataout = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizes[kBufs - 1], GL_MAP_READ_BIT);
7519 if (!dataout)
7520 return ERROR;
7521 bool status = true;
7522 for (int i = 0; i < kBufs - 1; ++i)
7523 if (dataout[i + 1] != sizes[i])
7524 {
7525 m_context.getTestContext().getLog()
7526 << tcu::TestLog::Message << "Array " << i << " length is " << dataout[i + 1] << " should be "
7527 << sizes[i] << tcu::TestLog::EndMessage;
7528 status = false;
7529 }
7530 if (dataout[0] != sizes[kBufs - 1] - 1)
7531 {
7532 m_context.getTestContext().getLog()
7533 << tcu::TestLog::Message << "Array " << (kBufs - 1) << " length is " << dataout[0] << " should be "
7534 << (sizes[kBufs - 1] - 1) << tcu::TestLog::EndMessage;
7535 status = false;
7536 }
7537 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7538
7539 if (!status)
7540 return ERROR;
7541
7542 return NO_ERROR;
7543 }
7544 };
7545
7546 class AdvancedUnsizedArrayLength2 : public ShaderStorageBufferObjectBase
7547 {
7548 GLuint m_program;
7549 GLuint m_storage_buffer[8];
7550 GLuint m_vertex_array;
7551 virtual void SetPath() = 0;
7552
Setup()7553 virtual long Setup()
7554 {
7555 m_program = 0;
7556 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
7557 m_vertex_array = 0;
7558 return NO_ERROR;
7559 }
Cleanup()7560 virtual long Cleanup()
7561 {
7562 glUseProgram(0);
7563 glDeleteProgram(m_program);
7564 glDeleteBuffers(8, m_storage_buffer);
7565 if (stage != compute)
7566 glDeleteVertexArrays(1, &m_vertex_array);
7567 return NO_ERROR;
7568 }
BuildShaderPT(int stagept)7569 std::string BuildShaderPT(int stagept)
7570 {
7571 std::ostringstream os;
7572 if (stagept == vertex)
7573 {
7574 os << NL "void main() {" NL " gl_Position = vec4(0,0,0,1);" NL "#ifdef GL_ES" NL
7575 " gl_PointSize = 1.0f;" NL "#endif";
7576 }
7577 if (stagept == fragment)
7578 {
7579 os << NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
7580 " o_color = vec4(0.0, 1.0, 0.0, 1.0);";
7581 }
7582 os << NL "}";
7583 return os.str();
7584 }
BuildShader()7585 std::string BuildShader()
7586 {
7587 std::ostringstream os;
7588 std::string e[4][7] = { { "bvec3", "vec4", "ivec3", "ivec3", "uvec2", "vec2", "uvec4" },
7589 { "mat2", "mat3", "mat4", "mat4", "mat2x3", "mat3x2", "mat4x2" },
7590 { "mat2", "mat3", "mat4", "mat4", "mat2x3", "mat3x2", "mat4x2" },
7591 { "S0", "S1", "S2", "S2", "S4", "S5", "S6" } };
7592 std::string sd =
7593 NL "struct S0 {" NL " float f;" NL " int i;" NL " uint ui;" NL " bool b;" NL "};" NL "struct S1 {" NL
7594 " ivec3 iv;" NL " bvec2 bv;" NL " vec4 v;" NL " uvec2 uv;" NL "};" NL "struct S2 {" NL
7595 " mat2x2 m22;" NL " mat4x4 m44;" NL " mat2x3 m23;" NL " mat4x2 m42;" NL " mat3x4 m34;" NL "};" NL
7596 "struct S4 {" NL " float f[1];" NL " int i[2];" NL " uint ui[3];" NL " bool b[4];" NL
7597 " ivec3 iv[5];" NL " bvec2 bv[6];" NL " vec4 v[7];" NL " uvec2 uv[8];" NL "};" NL "struct S5 {" NL
7598 " S0 s0;" NL " S1 s1;" NL " S2 s2;" NL "};" NL "struct S6 {" NL " S4 s4[3];" NL "};";
7599
7600 std::string lo = "";
7601 std::string l[4] = { "std140", "std430", "shared", "packed" };
7602 lo += l[layout];
7603 if (etype == matrix_rm)
7604 lo += ", row_major";
7605
7606 std::string decl = sd + NL "layout(" + lo + ") buffer;" NL "layout(binding = 0) readonly buffer Input0 {" +
7607 ((other_members) ? ("\n " + e[etype][0] + " pad0;") : "") + NL " " + e[etype][0] +
7608 " g_input0[];" NL "};" NL "layout(binding = 1) readonly buffer Input1 {" +
7609 ((other_members) ? ("\n " + e[etype][1] + " pad1;") : "") + NL " " + e[etype][1] +
7610 " data[];" NL "} g_input1;" NL "layout(binding = 2) readonly buffer Input23 {" +
7611 ((other_members) ? ("\n " + e[etype][2] + " pad2;") : "") + NL " " + e[etype][2] +
7612 " data[];" NL "} g_input23[2];" NL "layout(binding = 4) buffer Output0 {" +
7613 ((other_members) ? ("\n " + e[etype][4] + " pad4;") : "") + NL " " + e[etype][4] +
7614 " data[];" NL "} g_output0;" NL "layout(binding = 5) readonly buffer Input4 {" +
7615 ((other_members) ? ("\n " + e[etype][5] + " pad5;") : "") + NL " " + e[etype][5] +
7616 " data[];" NL "} g_input4;" NL "layout(binding = 6) buffer Output1 {" +
7617 ((other_members) ? ("\n " + e[etype][6] + " pad6;") : "") + NL " " + e[etype][6] +
7618 " data[];" NL "} g_output1;" NL "layout(std430, binding = 7) buffer Output {" NL
7619 " int g_length[];" NL "};";
7620 std::string expr =
7621 NL " g_length[0] = g_input0.length();" NL " g_length[1] = g_input1.data.length();" NL
7622 " g_length[2] = g_input23[0].data.length();" NL " g_length[3] = g_input23[1].data.length();" NL
7623 " g_length[4] = g_output0.data.length();" NL " g_length[5] = g_input4.data.length();" NL
7624 " g_length[6] = g_output1.data.length();";
7625 std::string lastelemexpr =
7626 NL " g_output0.data[g_output0.data.length()-2] += g_output0.data[g_output0.data.length()-1];" NL
7627 " g_output1.data[g_output1.data.length()-2] += g_output1.data[g_output1.data.length()-1];";
7628 if (length_as_index)
7629 expr += lastelemexpr;
7630 if (stage == vertex)
7631 {
7632 os << decl << NL "void main() {" NL "#ifdef GL_ES" NL " gl_PointSize = 1.0f;" NL "#endif" NL
7633 " gl_Position = vec4(0,0,0,1);"
7634 << expr;
7635 }
7636 if (stage == fragment)
7637 {
7638 os << NL "layout(location = 0) out vec4 o_color;" << decl
7639 << NL "void main() {" NL " o_color = vec4(0.0, 1.0, 0.0, 1.0);" << expr;
7640 }
7641 if (stage == compute)
7642 {
7643 os << NL "layout(local_size_x = 1) in;" << decl << NL "void main() {" << expr;
7644 }
7645 os << NL "}";
7646 return os.str();
7647 }
7648
Run()7649 virtual long Run()
7650 {
7651 const int kSize = 100000;
7652 const int kBufs = 8;
7653 SetPath();
7654 if ((stage == vertex && !IsVSFSAvailable(kBufs, 0)) || (stage == fragment && !IsVSFSAvailable(0, kBufs)))
7655 return NOT_SUPPORTED;
7656 GLint blocksC;
7657 glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &blocksC);
7658 GLint minA;
7659 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &minA);
7660 if (blocksC < kBufs)
7661 return NOT_SUPPORTED;
7662 if (stage == vertex)
7663 {
7664 std::string glsl_vs = BuildShader();
7665 std::string glsl_fs = BuildShaderPT(fragment);
7666 m_program = CreateProgram(glsl_vs, glsl_fs);
7667 }
7668 else if (stage == fragment)
7669 {
7670 std::string glsl_vs = BuildShaderPT(vertex);
7671 std::string glsl_fs = BuildShader();
7672 m_program = CreateProgram(glsl_vs, glsl_fs);
7673 }
7674 else
7675 { // compute
7676 std::string glsl_cs = BuildShader();
7677 m_program = CreateProgramCS(glsl_cs);
7678 }
7679 glLinkProgram(m_program);
7680 if (!CheckProgram(m_program))
7681 return ERROR;
7682 glUseProgram(m_program);
7683
7684 glGenBuffers(kBufs, m_storage_buffer);
7685 int sizes[kBufs] = { 7, 5, 3, 4, 23, 123, 419, 8 };
7686 int columns[4][kBufs] = {
7687 { 1, 1, 1, 1, 1, 1, 1, 1 }, // vector: 1 col
7688 { 2, 3, 4, 4, 2, 3, 4, 1 }, // mat: # of cols
7689 { 2, 3, 4, 4, 3, 2, 2, 1 }, // RM mat: # of rows
7690 { 1, 1, 1, 1, 1, 1, 1, 1 } // structure: not used
7691 };
7692
7693 int scalars[4][kBufs] = {
7694 { 4, 4, 4, 4, 2, 2, 4, 1 }, //vector: size
7695 { 2, 4, 4, 4, 4, 2, 2, 1 }, //matrix column_major: rows
7696 { 2, 4, 4, 4, 2, 4, 4, 1 }, //matrix row_major: columns
7697 { 1, 1, 1, 1, 1, 1, 1, 1 } //structure: not used
7698 };
7699 int mindw[4][kBufs] = { { 3, 4, 3, 3, 2, 2, 4, 1 }, // # of real 32bit items
7700 { 4, 9, 16, 16, 6, 6, 8, 1 },
7701 { 4, 9, 16, 16, 6, 6, 8, 1 },
7702 { 4, 11, 35, 35, 81, 127, 381, 1 } };
7703 int std430struct[kBufs] = { 4, 16, 48, 48, 88, 68, 264, 1 };
7704 int std140struct[kBufs] = { 4, 16, 60, 60, 144, 80, 432, 1 };
7705 int bufsize[kBufs][2] = { { 0 }, { 0 } };
7706
7707 std::vector<ivec4> data(kSize, ivec4(41));
7708 for (int i = 0; i < kBufs; ++i)
7709 {
7710 if (layout == std430)
7711 {
7712 bufsize[i][1] = 4 * columns[etype][i] * scalars[etype][i];
7713 if (etype == structure)
7714 {
7715 bufsize[i][1] = 4 * std430struct[i];
7716 }
7717 }
7718 else if (layout == std140)
7719 {
7720 bufsize[i][1] = 4 * columns[etype][i] * 4;
7721 if (etype == structure)
7722 {
7723 bufsize[i][1] = 4 * std140struct[i];
7724 }
7725 }
7726 else
7727 {
7728 bufsize[i][1] = 4 * mindw[etype][i];
7729 }
7730 bufsize[i][0] = sizes[i] * bufsize[i][1];
7731 if (i == kBufs - 1 || bind_seq == bindbasebefore)
7732 { // never trim feedback storage
7733 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
7734 glBufferData(GL_SHADER_STORAGE_BUFFER, bufsize[i][0], &data[0], GL_DYNAMIC_COPY);
7735 }
7736 else
7737 {
7738 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[i]);
7739 glBufferData(GL_SHADER_STORAGE_BUFFER, bufsize[i][0], &data[0], GL_DYNAMIC_COPY);
7740 if (bind_seq == bindbaseafter)
7741 {
7742 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]);
7743 }
7744 else if (bind_seq == bindrangeoffset && 2 * bufsize[i][1] >= minA)
7745 {
7746 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i], 2 * bufsize[i][1],
7747 bufsize[i][0] - 2 * bufsize[i][1]); // without 2 elements
7748 }
7749 else
7750 { // bind_seq == bindrangesize || 2*bufsize[i][1] < minA
7751 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i], 0,
7752 bufsize[i][0] - 2 * bufsize[i][1]); // without 2 elements
7753 }
7754 }
7755 }
7756
7757 if (stage != compute)
7758 {
7759 glGenVertexArrays(1, &m_vertex_array);
7760 glBindVertexArray(m_vertex_array);
7761 glDrawArrays(GL_POINTS, 0, 1);
7762 }
7763 else
7764 {
7765 glDispatchCompute(1, 1, 1);
7766 }
7767 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
7768
7769 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[kBufs - 1]);
7770 int* dataout = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizes[kBufs - 1], GL_MAP_READ_BIT);
7771 if (!dataout)
7772 return ERROR;
7773 bool status = true;
7774 for (int i = 0; i < kBufs - 1; ++i)
7775 {
7776 if (other_members)
7777 sizes[i] -= 1; // space consumed by a pad
7778 if (bind_seq == bindrangesize || bind_seq == bindrangeoffset)
7779 sizes[i] -= 2; // space constrained by offset of range size
7780 if ((layout == std140 || layout == std430) && dataout[i] != sizes[i])
7781 {
7782 m_context.getTestContext().getLog()
7783 << tcu::TestLog::Message << "Array " << i << " length is " << dataout[i] << " should be "
7784 << sizes[i] << tcu::TestLog::EndMessage;
7785 status = false;
7786 }
7787 if ((layout == packed || layout == shared) && (dataout[i] > sizes[i]))
7788 {
7789 m_context.getTestContext().getLog()
7790 << tcu::TestLog::Message << "Array " << i << " length is " << dataout[i]
7791 << " should be not greater that " << sizes[i] << tcu::TestLog::EndMessage;
7792 status = false;
7793 }
7794 }
7795 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7796
7797 if (length_as_index)
7798 {
7799 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[4]);
7800 dataout = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bufsize[4][0], GL_MAP_READ_BIT);
7801 if (!dataout)
7802 return ERROR;
7803 int i = (sizes[4] - 2) * columns[etype][4] * scalars[etype][4];
7804 if (dataout[i] != 82)
7805 {
7806 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Array 4 index " << i << " is "
7807 << dataout[i] << " should be 82" << tcu::TestLog::EndMessage;
7808 status = false;
7809 }
7810 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7811 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[6]);
7812 dataout = (int*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bufsize[6][0], GL_MAP_READ_BIT);
7813 if (!dataout)
7814 return ERROR;
7815 i = (sizes[6] - 2) * columns[etype][6] * scalars[etype][6];
7816 if (dataout[i] != 82)
7817 {
7818 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Array 6 index " << i << " is "
7819 << dataout[i] << " should be 82" << tcu::TestLog::EndMessage;
7820 status = false;
7821 }
7822 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
7823 }
7824
7825 if (!status)
7826 return ERROR;
7827
7828 return NO_ERROR;
7829 }
7830
7831 public:
7832 int stage;
7833 int etype;
7834 int layout;
7835 bool other_members;
7836 int bind_seq;
7837 bool length_as_index;
7838
AdvancedUnsizedArrayLength2()7839 AdvancedUnsizedArrayLength2()
7840 : m_program(0)
7841 , m_vertex_array(0)
7842 , stage(compute)
7843 , etype(vector)
7844 , layout(std430)
7845 , other_members(false)
7846 , bind_seq(bindbasebefore)
7847 , length_as_index(false)
7848 {
7849 }
7850 };
7851
7852 class AdvancedUnsizedArrayLength_cs_std430_vec_indexing : public AdvancedUnsizedArrayLength2
7853 {
7854 public:
SetPath()7855 virtual void SetPath()
7856 {
7857 length_as_index = true;
7858 }
7859 };
7860
7861 class AdvancedUnsizedArrayLength_cs_std430_vec_after : public AdvancedUnsizedArrayLength2
7862 {
7863 public:
SetPath()7864 virtual void SetPath()
7865 {
7866 bind_seq = bindbaseafter;
7867 }
7868 };
7869
7870 class AdvancedUnsizedArrayLength_cs_std430_vec_offset : public AdvancedUnsizedArrayLength2
7871 {
7872 public:
SetPath()7873 virtual void SetPath()
7874 {
7875 bind_seq = bindrangeoffset;
7876 }
7877 };
7878
7879 class AdvancedUnsizedArrayLength_cs_std430_vec_size : public AdvancedUnsizedArrayLength2
7880 {
7881 public:
SetPath()7882 virtual void SetPath()
7883 {
7884 bind_seq = bindrangesize;
7885 }
7886 };
7887
7888 class AdvancedUnsizedArrayLength_cs_std430_vec : public AdvancedUnsizedArrayLength2
7889 {
7890 public:
SetPath()7891 virtual void SetPath()
7892 {
7893 etype = vector;
7894 }
7895 };
7896
7897 class AdvancedUnsizedArrayLength_cs_std430_matC : public AdvancedUnsizedArrayLength2
7898 {
7899 public:
SetPath()7900 virtual void SetPath()
7901 {
7902 etype = matrix_cm;
7903 }
7904 };
7905
7906 class AdvancedUnsizedArrayLength_cs_std430_matR : public AdvancedUnsizedArrayLength2
7907 {
7908 public:
SetPath()7909 virtual void SetPath()
7910 {
7911 etype = matrix_rm;
7912 }
7913 };
7914
7915 class AdvancedUnsizedArrayLength_cs_std430_struct : public AdvancedUnsizedArrayLength2
7916 {
7917 public:
SetPath()7918 virtual void SetPath()
7919 {
7920 etype = structure;
7921 }
7922 };
7923
7924 class AdvancedUnsizedArrayLength_cs_std140_vec : public AdvancedUnsizedArrayLength2
7925 {
7926 public:
SetPath()7927 virtual void SetPath()
7928 {
7929 stage = compute;
7930 layout = std140;
7931 }
7932 };
7933
7934 class AdvancedUnsizedArrayLength_cs_std140_matC : public AdvancedUnsizedArrayLength2
7935 {
7936 public:
SetPath()7937 virtual void SetPath()
7938 {
7939 etype = matrix_cm;
7940 layout = std140;
7941 }
7942 };
7943
7944 class AdvancedUnsizedArrayLength_cs_std140_matR : public AdvancedUnsizedArrayLength2
7945 {
7946 public:
SetPath()7947 virtual void SetPath()
7948 {
7949 etype = matrix_rm;
7950 layout = std140;
7951 }
7952 };
7953
7954 class AdvancedUnsizedArrayLength_cs_std140_struct : public AdvancedUnsizedArrayLength2
7955 {
7956 public:
SetPath()7957 virtual void SetPath()
7958 {
7959 etype = structure;
7960 layout = std140;
7961 }
7962 };
7963
7964 class AdvancedUnsizedArrayLength_cs_packed_vec : public AdvancedUnsizedArrayLength2
7965 {
7966 public:
SetPath()7967 virtual void SetPath()
7968 {
7969 etype = vector;
7970 layout = packed;
7971 }
7972 };
7973
7974 class AdvancedUnsizedArrayLength_cs_packed_matC : public AdvancedUnsizedArrayLength2
7975 {
7976 public:
SetPath()7977 virtual void SetPath()
7978 {
7979 etype = matrix_cm;
7980 layout = packed;
7981 }
7982 };
7983
7984 class AdvancedUnsizedArrayLength_cs_shared_matR : public AdvancedUnsizedArrayLength2
7985 {
7986 public:
SetPath()7987 virtual void SetPath()
7988 {
7989 etype = matrix_rm;
7990 layout = shared;
7991 }
7992 };
7993
7994 class AdvancedUnsizedArrayLength_fs_std430_vec : public AdvancedUnsizedArrayLength2
7995 {
7996 public:
SetPath()7997 virtual void SetPath()
7998 {
7999 stage = fragment;
8000 etype = vector;
8001 layout = std430;
8002 }
8003 };
8004
8005 class AdvancedUnsizedArrayLength_fs_std430_matC_pad : public AdvancedUnsizedArrayLength2
8006 {
8007 public:
SetPath()8008 virtual void SetPath()
8009 {
8010 stage = fragment;
8011 etype = matrix_cm;
8012 layout = std430;
8013 other_members = true;
8014 }
8015 };
8016
8017 class AdvancedUnsizedArrayLength_fs_std140_matR : public AdvancedUnsizedArrayLength2
8018 {
8019 public:
SetPath()8020 virtual void SetPath()
8021 {
8022 stage = fragment;
8023 etype = matrix_rm;
8024 layout = std140;
8025 }
8026 };
8027
8028 class AdvancedUnsizedArrayLength_fs_std140_struct : public AdvancedUnsizedArrayLength2
8029 {
8030 public:
SetPath()8031 virtual void SetPath()
8032 {
8033 stage = fragment;
8034 etype = structure;
8035 layout = std140;
8036 }
8037 };
8038
8039 class AdvancedUnsizedArrayLength_vs_std430_vec_pad : public AdvancedUnsizedArrayLength2
8040 {
8041 public:
SetPath()8042 virtual void SetPath()
8043 {
8044 stage = vertex;
8045 etype = vector;
8046 layout = std430;
8047 other_members = true;
8048 }
8049 };
8050
8051 class AdvancedUnsizedArrayLength_vs_std140_matC : public AdvancedUnsizedArrayLength2
8052 {
8053 public:
SetPath()8054 virtual void SetPath()
8055 {
8056 stage = vertex;
8057 etype = matrix_cm;
8058 layout = std140;
8059 }
8060 };
8061
8062 class AdvancedUnsizedArrayLength_vs_packed_matR : public AdvancedUnsizedArrayLength2
8063 {
8064 public:
SetPath()8065 virtual void SetPath()
8066 {
8067 stage = vertex;
8068 etype = matrix_rm;
8069 layout = packed;
8070 }
8071 };
8072
8073 class AdvancedUnsizedArrayLength_vs_std140_struct : public AdvancedUnsizedArrayLength2
8074 {
8075 public:
SetPath()8076 virtual void SetPath()
8077 {
8078 stage = vertex;
8079 etype = structure;
8080 layout = std140;
8081 }
8082 };
8083
8084 class AdvancedUnsizedArrayLength_cs_std430_vec_pad : public AdvancedUnsizedArrayLength2
8085 {
8086 public:
SetPath()8087 virtual void SetPath()
8088 {
8089 etype = vector;
8090 other_members = true;
8091 }
8092 };
8093
8094 class AdvancedUnsizedArrayLength_cs_std430_matC_pad : public AdvancedUnsizedArrayLength2
8095 {
8096 public:
SetPath()8097 virtual void SetPath()
8098 {
8099 etype = matrix_cm;
8100 other_members = true;
8101 }
8102 };
8103
8104 class AdvancedUnsizedArrayLength_cs_std140_matR_pad : public AdvancedUnsizedArrayLength2
8105 {
8106 public:
SetPath()8107 virtual void SetPath()
8108 {
8109 etype = matrix_rm;
8110 layout = std140;
8111 other_members = true;
8112 }
8113 };
8114
8115 class AdvancedUnsizedArrayLength_cs_std430_struct_pad : public AdvancedUnsizedArrayLength2
8116 {
8117 public:
SetPath()8118 virtual void SetPath()
8119 {
8120 etype = structure;
8121 other_members = true;
8122 }
8123 };
8124
8125 //-----------------------------------------------------------------------------
8126 // 2.8 AdvancedMatrix
8127 //-----------------------------------------------------------------------------
8128 class AdvancedMatrixVSFS : public ShaderStorageBufferObjectBase
8129 {
8130 GLuint m_program;
8131 GLuint m_storage_buffer[3];
8132 GLuint m_vertex_array;
8133 GLuint m_vertex_buffer;
8134 GLuint m_fbo, m_rt;
8135
Setup()8136 virtual long Setup()
8137 {
8138 m_program = 0;
8139 memset(m_storage_buffer, 0, sizeof(m_storage_buffer));
8140 m_vertex_array = 0;
8141 m_vertex_buffer = 0;
8142 glGenFramebuffers(1, &m_fbo);
8143 glGenTextures(1, &m_rt);
8144 return NO_ERROR;
8145 }
Run()8146 virtual long Run()
8147 {
8148 if (!IsVSFSAvailable(2, 2))
8149 return NOT_SUPPORTED;
8150 const char* const glsl_vs =
8151 NL "layout(location = 0) in vec4 g_position;" NL "flat out int instance_id;" 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
8154 "layout(binding = 1, std430) readonly buffer Buffer1 {" NL " mat4 color;" NL "} g_buffer1;" NL
8155 "uniform int g_index1;" NL "uniform int g_index2;" NL "void main() {" NL
8156 " gl_Position = vec4(transpose(g_transform[gl_InstanceID]) * g_position, 1);" NL
8157 " g_color[gl_InstanceID] = g_buffer1.color[gl_InstanceID].rgb;" NL
8158 " if (gl_VertexID == 0 && gl_InstanceID == 0) {" NL " g_data0[1][1] = 1.0;" NL
8159 " g_data0[g_index1][g_index2] += 3.0;" NL " }" NL " memoryBarrier();" NL
8160 " instance_id = gl_InstanceID;" NL "}";
8161 const char* const glsl_fs =
8162 NL "flat in int instance_id;" NL "layout(location = 0) out vec4 g_ocolor;" NL
8163 "layout(binding = 0, std430) coherent buffer Buffer0 {" NL " mat3x4 g_transform[4];" NL
8164 " mat4x3 g_color;" NL " mat3 g_data0;" NL "};" NL "uniform int g_index1;" NL "uniform int g_index2;" NL
8165 "void main() {" NL " if (g_data0[g_index1][g_index1] != 1.0) g_ocolor = vec4(0);" NL
8166 " else if (g_data0[g_index1][g_index2] != 3.0) g_ocolor = vec4(0);" NL
8167 " else g_ocolor = vec4(g_color[instance_id], 1);" NL "}";
8168 m_program = CreateProgram(glsl_vs, glsl_fs);
8169 glLinkProgram(m_program);
8170 if (!CheckProgram(m_program))
8171 return ERROR;
8172
8173 glGenBuffers(3, m_storage_buffer);
8174
8175 /* transform buffer */
8176 {
8177 float data[48 + 16 + 12 + 16] = {
8178 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,
8179 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,
8180 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,
8181 };
8182 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]);
8183 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
8184 }
8185 /* transform buffer */
8186 {
8187 float data[16] = {
8188 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,
8189 };
8190 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]);
8191 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
8192 }
8193 /* vertex buffer */
8194 {
8195 float data[8] = { -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.4f, 0.4f };
8196 glGenBuffers(1, &m_vertex_buffer);
8197 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
8198 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
8199 glBindBuffer(GL_ARRAY_BUFFER, 0);
8200 }
8201
8202 glBindTexture(GL_TEXTURE_2D, m_rt);
8203 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8205 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 100, 100);
8206 glBindTexture(GL_TEXTURE_2D, 0);
8207 glViewport(0, 0, 100, 100);
8208 glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
8209 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt, 0);
8210
8211 glGenVertexArrays(1, &m_vertex_array);
8212 glBindVertexArray(m_vertex_array);
8213 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
8214 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
8215 glBindBuffer(GL_ARRAY_BUFFER, 0);
8216 glEnableVertexAttribArray(0);
8217 glBindVertexArray(0);
8218
8219 glClear(GL_COLOR_BUFFER_BIT);
8220 glUseProgram(m_program);
8221 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
8222 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
8223
8224 glBindVertexArray(m_vertex_array);
8225 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);
8226 if (!ValidateWindow4Quads(vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1), vec3(1, 1, 0)))
8227 {
8228 return ERROR;
8229 }
8230 return NO_ERROR;
8231 }
8232
Cleanup()8233 virtual long Cleanup()
8234 {
8235 glViewport(0, 0, getWindowWidth(), getWindowHeight());
8236 glUseProgram(0);
8237 glDeleteProgram(m_program);
8238 glDeleteBuffers(3, m_storage_buffer);
8239 glDeleteBuffers(1, &m_vertex_buffer);
8240 glDeleteVertexArrays(1, &m_vertex_array);
8241 glDeleteFramebuffers(1, &m_fbo);
8242 glDeleteTextures(1, &m_rt);
8243 return NO_ERROR;
8244 }
8245 };
8246
8247 class AdvancedMatrixCS : public ShaderStorageBufferObjectBase
8248 {
8249 GLuint m_program;
8250 GLuint m_storage_buffer;
8251
Setup()8252 virtual long Setup()
8253 {
8254 m_program = 0;
8255 m_storage_buffer = 0;
8256 return NO_ERROR;
8257 }
8258
Run()8259 virtual long Run()
8260 {
8261 bool status = true;
8262 const char* const glsl_cs =
8263 NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Buffer {" NL " mat4x3 dst4x3;" NL
8264 " mat4 dst4;" NL " mat4 src4;" NL "} b;" NL "uniform int g_index1;" NL "uniform int g_index2;" NL
8265 "void main() {" NL " b.dst4x3[gl_LocalInvocationIndex] = b.src4[gl_LocalInvocationIndex].rgb;" NL
8266 " b.dst4x3[gl_LocalInvocationIndex + 1u] = b.src4[gl_LocalInvocationIndex + 1u].aar;" NL
8267 " b.dst4[g_index2][g_index1] = 17.0;" NL " b.dst4[g_index2][g_index1] += 6.0;" NL
8268 " b.dst4[3][0] = b.src4[3][0] != 44.0 ? 3.0 : 7.0;" NL " b.dst4[3][1] = b.src4[3][1];" NL "}";
8269 m_program = CreateProgramCS(glsl_cs);
8270 glLinkProgram(m_program);
8271 if (!CheckProgram(m_program))
8272 return ERROR;
8273
8274 glGenBuffers(1, &m_storage_buffer);
8275 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer);
8276 GLfloat data[16 + 16 + 16];
8277 for (int i = 0; i < 32; ++i)
8278 data[i] = 0.0f;
8279 for (int i = 32; i < 48; ++i)
8280 data[i] = (GLfloat)i;
8281 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data[0], GL_DYNAMIC_DRAW);
8282
8283 glUseProgram(m_program);
8284 glUniform1i(glGetUniformLocation(m_program, "g_index1"), 1);
8285 glUniform1i(glGetUniformLocation(m_program, "g_index2"), 2);
8286 glDispatchCompute(1, 1, 1);
8287 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
8288 GLfloat* out_data = (GLfloat*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), GL_MAP_READ_BIT);
8289 if (!out_data)
8290 return ERROR;
8291 GLfloat expected[32] = { 32.0f, 33.0f, 34.0f, 0.0f, 39.0f, 39.0f, 36.0f, 0.0f,
8292 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8293
8294 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8295 0.0f, 23.0f, 0.0f, 0.0f, 7.0f, 45.0f, 0.0f, 0.0f };
8296 for (int i = 0; i < 32; ++i)
8297 {
8298 if (out_data[i] != expected[i])
8299 {
8300 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Received: " << out_data[i]
8301 << ", but expected: " << expected[i] << tcu::TestLog::EndMessage;
8302 status = false;
8303 }
8304 }
8305 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
8306 if (status)
8307 return NO_ERROR;
8308 else
8309 return ERROR;
8310 }
Cleanup()8311 virtual long Cleanup()
8312 {
8313 glUseProgram(0);
8314 glDeleteProgram(m_program);
8315 glDeleteBuffers(1, &m_storage_buffer);
8316 return NO_ERROR;
8317 }
8318 };
8319
8320 //-----------------------------------------------------------------------------
8321 // 4.1.1 NegativeAPIBind
8322 //-----------------------------------------------------------------------------
8323 class NegativeAPIBind : public ShaderStorageBufferObjectBase
8324 {
Run()8325 virtual long Run()
8326 {
8327 GLint bindings;
8328 GLint alignment;
8329 GLuint buffer;
8330 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &bindings);
8331 m_context.getTestContext().getLog()
8332 << tcu::TestLog::Message << "Max storage buffer bindings " << bindings << tcu::TestLog::EndMessage;
8333 glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
8334 m_context.getTestContext().getLog()
8335 << tcu::TestLog::Message << "Storage buffer offset alignment " << alignment << tcu::TestLog::EndMessage;
8336
8337 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, bindings, 0);
8338 if (glGetError() != GL_INVALID_VALUE)
8339 {
8340 m_context.getTestContext().getLog()
8341 << tcu::TestLog::Message
8342 << "INVALID_VALUE is generated by BindBufferBase 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 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, bindings, 0, 0, 0);
8350 if (glGetError() != GL_INVALID_VALUE)
8351 {
8352 m_context.getTestContext().getLog()
8353 << tcu::TestLog::Message
8354 << "INVALID_VALUE is generated by BindBufferRange if <target> is\n"
8355 "SHADER_STORAGE_BUFFER and <index> is greater than or equal to the value of\n"
8356 "MAX_SHADER_STORAGE_BUFFER_BINDINGS."
8357 << tcu::TestLog::EndMessage;
8358 return ERROR;
8359 }
8360
8361 glGenBuffers(1, &buffer);
8362 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, alignment - 1, 0);
8363 if (glGetError() != GL_INVALID_VALUE)
8364 {
8365 m_context.getTestContext().getLog()
8366 << tcu::TestLog::Message << "INVALID_VALUE is generated by BindBufferRange if <target> is\n"
8367 "SHADER_STORAGE_BUFFER and <offset> is not a multiple of the value of\n"
8368 "SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT."
8369 << tcu::TestLog::EndMessage;
8370 return ERROR;
8371 }
8372
8373 return NO_ERROR;
8374 }
8375 };
8376
8377 //-----------------------------------------------------------------------------
8378 // 4.2.1 NegativeGLSLCompileTime
8379 //-----------------------------------------------------------------------------
8380 class NegativeGLSLCompileTime : public ShaderStorageBufferObjectBase
8381 {
Shader1(int binding)8382 static std::string Shader1(int binding)
8383 {
8384 std::stringstream ss;
8385 ss << NL "layout(binding = " << binding
8386 << ") buffer Buffer {" NL " int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}";
8387 return ss.str();
8388 }
8389
Shader2(int binding)8390 static std::string Shader2(int binding)
8391 {
8392 std::stringstream ss;
8393 ss << NL "layout(binding = " << binding
8394 << ") buffer Buffer {" NL " int x;" NL "} g_array[4];" NL "void main() {" NL " g_array[0].x = 0;" NL
8395 " g_array[1].x = 0;" NL " g_array[2].x = 0;" NL " g_array[3].x = 0;" NL "}";
8396 return ss.str();
8397 }
8398
Run()8399 virtual long Run()
8400 {
8401 GLint bindings;
8402 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &bindings);
8403
8404 // initialization of buffer block member 'x' not allowed
8405 if (!Compile(NL "buffer Buffer { int x = 10; };" NL "void main() {" NL " x = 0;" NL "}"))
8406 return ERROR;
8407
8408 // syntax error, unexpected '-', expecting integer constant or unsigned integer constant at token "-"
8409 if (!Compile(Shader1(-1)))
8410 return ERROR;
8411 // invalid value 96 for layout specifier 'binding'
8412 if (!Compile(Shader1(bindings)))
8413 return ERROR;
8414
8415 // invalid value 98 for layout specifier 'binding'
8416 if (!Compile(Shader2(bindings - 2)))
8417 return ERROR;
8418
8419 // OpenGL does not allow declaring buffer variable 'x' in the global scope. Use buffer blocks instead
8420 if (!Compile(NL "buffer int x;" NL "void main() {" NL " x = 0;" NL "}"))
8421 return ERROR;
8422
8423 // OpenGL requires buffer variables to be declared in a shader storage block in the global scope
8424 if (!Compile(NL "buffer Buffer { int y; };" NL "void main() {" NL " y = 0;" NL " buffer int x = 0;" NL "}"))
8425 return ERROR;
8426
8427 // OpenGL does not allow a parameter to be a buffer
8428 if (!Compile(NL "buffer Buffer { int y; };" NL "void Modify(buffer int a) {" NL " atomicAdd(a, 1);" NL "}" NL
8429 "void main() {" NL " Modify(y);" NL "}"))
8430 return ERROR;
8431
8432 // layout specifier 'std430', incompatible with 'uniform blocks'
8433 if (!Compile(NL "layout(std430) uniform UBO { int x; };" NL "buffer SSBO { int y; };" NL "void main() {" NL
8434 " y = x;" NL "}"))
8435 return ERROR;
8436
8437 // unknown layout specifier 'std430'
8438 if (!Compile(NL "buffer SSBO {" NL " layout(std430) int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}"))
8439 return ERROR;
8440
8441 // unknown layout specifier 'binding = 1'
8442 if (!Compile(NL "buffer SSBO {" NL " layout(binding = 1) int x;" NL "};" NL "void main() {" NL " x = 0;" NL
8443 "}"))
8444 return ERROR;
8445
8446 // OpenGL does not allow writing to readonly variable 'x'
8447 if (!Compile(NL "readonly buffer SSBO {" NL " int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}"))
8448 return ERROR;
8449
8450 // OpenGL does not allow reading writeonly variable 'y'
8451 if (!Compile(NL "buffer SSBO {" NL " int x;" NL "};" NL "writeonly buffer SSBO2 {" NL " int y;" NL "};" NL
8452 "void main() {" NL " x = y;" NL "}"))
8453 return ERROR;
8454
8455 // OpenGL does not allow writing to readonly variable 'z'
8456 if (!Compile(NL "buffer SSBO {" NL " int x;" NL "};" NL "buffer SSBO2 {" NL " writeonly int y;" NL
8457 " readonly int z;" NL "};" NL "void main() {" NL " x = y;" NL " z = 0;" NL "}"))
8458 return ERROR;
8459
8460 // OpenGL does not allow having both readonly and writeonly qualifiers on a variable
8461 if (!Compile(NL "buffer SSBO {" NL " int x;" NL "};" NL "readonly buffer SSBO2 {" NL " writeonly int y;" NL
8462 "};" NL "void main() {" NL " x = y;" NL "}"))
8463 return ERROR;
8464
8465 // ["layout(binding = 1) buffer;" should cause compile-time error
8466 if (!Compile(NL "layout(binding = 1) buffer;" //
8467 NL "buffer SSBO {" NL " int x;" NL "};" NL "void main() {" NL " x = 0;" NL "}"))
8468 return ERROR;
8469
8470 // [" atomicAdd(y, 2);" should cause compile-time error
8471 if (!Compile(NL "buffer coherent Buffer { int x; };" NL "int y;" NL "void main() {" NL " atomicAdd(x, 1);" NL
8472 " atomicAdd(y, 2);" //
8473 NL "}"))
8474 return ERROR;
8475
8476 if (!Compile( // can't construct vector from an array
8477 NL "buffer b {" NL " vec4 x[10];" NL "};" NL "void main() {" NL " vec4 y = vec4(x);" NL "}"))
8478 return ERROR;
8479
8480 if (!Compile( // ESSL31 does not allow dynamically uniform indexing of SSBO arrays
8481 NL "layout(std430, binding = 0) buffer Input {" NL " float data0;" NL "} g_input[4];" NL
8482 "layout(std430, binding = 4) buffer Output {" NL " float data0;" NL "} g_output[4];" NL
8483 "void main() {" NL " for (int i = 0; i < 4; ++i) {" NL
8484 " g_output[i].data0 = g_input[i].data0;" NL " }" NL "}"))
8485 return ERROR;
8486
8487 if (!Compile( // ESSL31 does not allow dynamically uniform indexing of SSBO arrays
8488 NL "layout(binding = 0, std430) buffer Material {" NL " vec3 color;" NL "} g_material[4];" NL
8489 "layout(binding = 4, std430) buffer OutputBuffer {" NL " vec3 color[4];" NL "};" NL
8490 "uniform int g_material_id;" NL "void main() {" NL
8491 " color[gl_LocalInvocationIndex] = vec3(g_material[g_material_id].color);" NL "}"))
8492 return ERROR;
8493
8494 return NO_ERROR;
8495 }
8496
Compile(const std::string & source)8497 bool Compile(const std::string& source)
8498 {
8499 const char* const csVer = "#version 310 es" NL "layout(local_size_x = 1) in;";
8500 const char* const src[2] = { csVer, source.c_str() };
8501 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
8502 glShaderSource(sh, 2, src, NULL);
8503 glCompileShader(sh);
8504
8505 GLchar log[1024];
8506 glGetShaderInfoLog(sh, sizeof(log), NULL, log);
8507 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
8508 << log << tcu::TestLog::EndMessage;
8509
8510 GLint status;
8511 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
8512 glDeleteShader(sh);
8513
8514 if (status == GL_TRUE)
8515 {
8516 m_context.getTestContext().getLog()
8517 << tcu::TestLog::Message << "Compilation should fail." << tcu::TestLog::EndMessage;
8518 return false;
8519 }
8520
8521 return true;
8522 }
8523 };
8524
8525 //-----------------------------------------------------------------------------
8526 // 4.2.2 NegativeGLSLLinkTime
8527 //-----------------------------------------------------------------------------
8528 class NegativeGLSLLinkTime : public ShaderStorageBufferObjectBase
8529 {
Run()8530 virtual long Run()
8531 {
8532 if (!IsVSFSAvailable(1, 1))
8533 return NOT_SUPPORTED;
8534 if (!Link("#version 310 es" NL "buffer Buffer { int x; };" NL "void main() {" NL " x += 2;" NL "}",
8535 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { uint x; };" NL "void main() {" NL
8536 " x += 3u;" NL "}"))
8537 return ERROR;
8538
8539 if (!Link("#version 310 es" NL "buffer Buffer { int x; int y; };" NL "void main() {" NL " x += 2;" NL "}",
8540 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { int x; };" NL "void main() {" NL
8541 " x += 3;" NL "}"))
8542 return ERROR;
8543
8544 if (!Link("#version 310 es" NL "buffer Buffer { int y; };" NL "void main() {" NL " y += 2;" NL "}",
8545 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { int x; };" NL "void main() {" NL
8546 " x += 3;" NL "}"))
8547 return ERROR;
8548
8549 if (!Link("#version 310 es" NL "buffer Buffer { int x[2]; };" NL "void main() {" NL " x[1] += 2;" NL "}",
8550 "#version 310 es" NL "precision highp float;" NL "buffer Buffer { int x[3]; };" NL "void main() {" NL
8551 " x[1] += 3;" NL "}"))
8552 return ERROR;
8553
8554 return NO_ERROR;
8555 }
8556
Link(const std::string & cs0,const std::string & cs1)8557 bool Link(const std::string& cs0, const std::string& cs1)
8558 {
8559 const GLuint p = glCreateProgram();
8560
8561 /* shader 0 */
8562 {
8563 GLuint sh = glCreateShader(GL_VERTEX_SHADER);
8564 glAttachShader(p, sh);
8565 glDeleteShader(sh);
8566 const char* const src = cs0.c_str();
8567 glShaderSource(sh, 1, &src, NULL);
8568 glCompileShader(sh);
8569
8570 GLint status;
8571 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
8572 if (status == GL_FALSE)
8573 {
8574 m_context.getTestContext().getLog()
8575 << tcu::TestLog::Message << "VS compilation should be ok." << tcu::TestLog::EndMessage;
8576 CheckProgram(p);
8577 glDeleteProgram(p);
8578 return false;
8579 }
8580 }
8581 /* shader 1 */
8582 {
8583 GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
8584 glAttachShader(p, sh);
8585 glDeleteShader(sh);
8586 const char* const src = cs1.c_str();
8587 glShaderSource(sh, 1, &src, NULL);
8588 glCompileShader(sh);
8589
8590 GLint status;
8591 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
8592 if (status == GL_FALSE)
8593 {
8594 m_context.getTestContext().getLog()
8595 << tcu::TestLog::Message << "FS compilation should be ok." << tcu::TestLog::EndMessage;
8596 CheckProgram(p);
8597 glDeleteProgram(p);
8598 return false;
8599 }
8600 }
8601
8602 glLinkProgram(p);
8603
8604 GLchar log[1024];
8605 glGetProgramInfoLog(p, sizeof(log), NULL, log);
8606 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
8607 << log << tcu::TestLog::EndMessage;
8608
8609 GLint status;
8610 glGetProgramiv(p, GL_LINK_STATUS, &status);
8611 glDeleteProgram(p);
8612
8613 if (status == GL_TRUE)
8614 {
8615 m_context.getTestContext().getLog()
8616 << tcu::TestLog::Message << "Link operation should fail." << tcu::TestLog::EndMessage;
8617 return false;
8618 }
8619
8620 return true;
8621 }
8622 };
8623
8624 } // anonymous namespace
8625
ShaderStorageBufferObjectTests(glcts::Context & context)8626 ShaderStorageBufferObjectTests::ShaderStorageBufferObjectTests(glcts::Context& context)
8627 : TestCaseGroup(context, "shader_storage_buffer_object", "")
8628 {
8629 }
8630
~ShaderStorageBufferObjectTests(void)8631 ShaderStorageBufferObjectTests::~ShaderStorageBufferObjectTests(void)
8632 {
8633 }
8634
init()8635 void ShaderStorageBufferObjectTests::init()
8636 {
8637 using namespace glcts;
8638 addChild(new TestSubcase(m_context, "basic-basic-vs", TestSubcase::Create<BasicBasicVS>));
8639 addChild(new TestSubcase(m_context, "basic-basic-cs", TestSubcase::Create<BasicBasicCS>));
8640 addChild(new TestSubcase(m_context, "basic-max", TestSubcase::Create<BasicMax>));
8641 addChild(new TestSubcase(m_context, "basic-binding", TestSubcase::Create<BasicBinding>));
8642 addChild(new TestSubcase(m_context, "basic-syntax-vs", TestSubcase::Create<BasicSyntaxVS>));
8643 addChild(new TestSubcase(m_context, "basic-syntax-cs", TestSubcase::Create<BasicSyntaxCS>));
8644 addChild(new TestSubcase(m_context, "basic-syntaxSSO", TestSubcase::Create<BasicSyntaxSSO>));
8645 addChild(new TestSubcase(m_context, "basic-std430Layout-case1-vs", TestSubcase::Create<BasicStd430LayoutCase1VS>));
8646 addChild(new TestSubcase(m_context, "basic-std430Layout-case1-cs", TestSubcase::Create<BasicStd430LayoutCase1CS>));
8647 addChild(new TestSubcase(m_context, "basic-std430Layout-case2-vs", TestSubcase::Create<BasicStd430LayoutCase2VS>));
8648 addChild(new TestSubcase(m_context, "basic-std430Layout-case2-cs", TestSubcase::Create<BasicStd430LayoutCase2CS>));
8649 addChild(new TestSubcase(m_context, "basic-std430Layout-case3-vs", TestSubcase::Create<BasicStd430LayoutCase3VS>));
8650 addChild(new TestSubcase(m_context, "basic-std430Layout-case3-cs", TestSubcase::Create<BasicStd430LayoutCase3CS>));
8651 addChild(new TestSubcase(m_context, "basic-std430Layout-case4-vs", TestSubcase::Create<BasicStd430LayoutCase4VS>));
8652 addChild(new TestSubcase(m_context, "basic-std430Layout-case4-cs", TestSubcase::Create<BasicStd430LayoutCase4CS>));
8653 addChild(new TestSubcase(m_context, "basic-std430Layout-case5-vs", TestSubcase::Create<BasicStd430LayoutCase5VS>));
8654 addChild(new TestSubcase(m_context, "basic-std430Layout-case5-cs", TestSubcase::Create<BasicStd430LayoutCase5CS>));
8655 addChild(new TestSubcase(m_context, "basic-std430Layout-case6-vs", TestSubcase::Create<BasicStd430LayoutCase6VS>));
8656 addChild(new TestSubcase(m_context, "basic-std430Layout-case6-cs", TestSubcase::Create<BasicStd430LayoutCase6CS>));
8657 addChild(new TestSubcase(m_context, "basic-std430Layout-case7-vs", TestSubcase::Create<BasicStd430LayoutCase7VS>));
8658 addChild(new TestSubcase(m_context, "basic-std430Layout-case7-cs", TestSubcase::Create<BasicStd430LayoutCase7CS>));
8659 addChild(new TestSubcase(m_context, "basic-std140Layout-case1-vs", TestSubcase::Create<BasicStd140LayoutCase1VS>));
8660 addChild(new TestSubcase(m_context, "basic-std140Layout-case1-cs", TestSubcase::Create<BasicStd140LayoutCase1CS>));
8661 addChild(new TestSubcase(m_context, "basic-std140Layout-case2-vs", TestSubcase::Create<BasicStd140LayoutCase2VS>));
8662 addChild(new TestSubcase(m_context, "basic-std140Layout-case2-cs", TestSubcase::Create<BasicStd140LayoutCase2CS>));
8663 addChild(new TestSubcase(m_context, "basic-std140Layout-case3-vs", TestSubcase::Create<BasicStd140LayoutCase3VS>));
8664 addChild(new TestSubcase(m_context, "basic-std140Layout-case3-cs", TestSubcase::Create<BasicStd140LayoutCase3CS>));
8665 addChild(new TestSubcase(m_context, "basic-std140Layout-case4-vs", TestSubcase::Create<BasicStd140LayoutCase4VS>));
8666 addChild(new TestSubcase(m_context, "basic-std140Layout-case4-cs", TestSubcase::Create<BasicStd140LayoutCase4CS>));
8667 addChild(new TestSubcase(m_context, "basic-std140Layout-case5-vs", TestSubcase::Create<BasicStd140LayoutCase5VS>));
8668 addChild(new TestSubcase(m_context, "basic-std140Layout-case5-cs", TestSubcase::Create<BasicStd140LayoutCase5CS>));
8669 addChild(new TestSubcase(m_context, "basic-std140Layout-case6-vs", TestSubcase::Create<BasicStd140LayoutCase6VS>));
8670 addChild(new TestSubcase(m_context, "basic-std140Layout-case6-cs", TestSubcase::Create<BasicStd140LayoutCase6CS>));
8671 addChild(new TestSubcase(m_context, "basic-atomic-case1-vsfs", TestSubcase::Create<BasicAtomicCase1VSFS>));
8672 addChild(new TestSubcase(m_context, "basic-atomic-case1-cs", TestSubcase::Create<BasicAtomicCase1CS>));
8673 addChild(new TestSubcase(m_context, "basic-atomic-case3-vsfs", TestSubcase::Create<BasicAtomicCase3VSFS>));
8674 addChild(new TestSubcase(m_context, "basic-atomic-case3-cs", TestSubcase::Create<BasicAtomicCase3CS>));
8675 addChild(new TestSubcase(m_context, "basic-atomic-case4-vsfs", TestSubcase::Create<BasicAtomicCase4VSFS>));
8676 addChild(new TestSubcase(m_context, "basic-atomic-case4-cs", TestSubcase::Create<BasicAtomicCase4CS>));
8677 addChild(new TestSubcase(m_context, "basic-stdLayout-case1-vs", TestSubcase::Create<BasicStdLayoutCase1VS>));
8678 addChild(new TestSubcase(m_context, "basic-stdLayout-case1-cs", TestSubcase::Create<BasicStdLayoutCase1CS>));
8679 addChild(new TestSubcase(m_context, "basic-stdLayout-case2-vs", TestSubcase::Create<BasicStdLayoutCase2VS>));
8680 addChild(new TestSubcase(m_context, "basic-stdLayout-case2-cs", TestSubcase::Create<BasicStdLayoutCase2CS>));
8681 addChild(new TestSubcase(m_context, "basic-stdLayout-case3-vs", TestSubcase::Create<BasicStdLayoutCase3VS>));
8682 addChild(new TestSubcase(m_context, "basic-stdLayout-case3-cs", TestSubcase::Create<BasicStdLayoutCase3CS>));
8683 addChild(new TestSubcase(m_context, "basic-stdLayout-case4-vs", TestSubcase::Create<BasicStdLayoutCase4VS>));
8684 addChild(new TestSubcase(m_context, "basic-stdLayout-case4-cs", TestSubcase::Create<BasicStdLayoutCase4CS>));
8685 addChild(new TestSubcase(m_context, "basic-operations-case1-vs", TestSubcase::Create<BasicOperationsCase1VS>));
8686 addChild(new TestSubcase(m_context, "basic-operations-case1-cs", TestSubcase::Create<BasicOperationsCase1CS>));
8687 addChild(new TestSubcase(m_context, "basic-operations-case2-vs", TestSubcase::Create<BasicOperationsCase2VS>));
8688 addChild(new TestSubcase(m_context, "basic-operations-case2-cs", TestSubcase::Create<BasicOperationsCase2CS>));
8689 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case1-vs",
8690 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase1VS>));
8691 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case1-cs",
8692 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase1CS>));
8693 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case2-vs",
8694 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase2VS>));
8695 addChild(new TestSubcase(m_context, "basic-stdLayout_UBO_SSBO-case2-cs",
8696 TestSubcase::Create<Basic_UBO_SSBO_LayoutCase2CS>));
8697 addChild(new TestSubcase(m_context, "basic-matrixOperations-case1-vs",
8698 TestSubcase::Create<BasicMatrixOperationsCase1VS>));
8699 addChild(new TestSubcase(m_context, "basic-matrixOperations-case1-cs",
8700 TestSubcase::Create<BasicMatrixOperationsCase1CS>));
8701 addChild(new TestSubcase(m_context, "basic-matrixOperations-case2-vs",
8702 TestSubcase::Create<BasicMatrixOperationsCase2VS>));
8703 addChild(new TestSubcase(m_context, "basic-matrixOperations-case2-cs",
8704 TestSubcase::Create<BasicMatrixOperationsCase2CS>));
8705 addChild(new TestSubcase(m_context, "basic-matrixOperations-case3-vs",
8706 TestSubcase::Create<BasicMatrixOperationsCase3VS>));
8707 addChild(new TestSubcase(m_context, "basic-matrixOperations-case3-cs",
8708 TestSubcase::Create<BasicMatrixOperationsCase3CS>));
8709 addChild(new TestSubcase(m_context, "basic-matrixOperations-case4-vs",
8710 TestSubcase::Create<BasicMatrixOperationsCase4VS>));
8711 addChild(new TestSubcase(m_context, "basic-matrixOperations-case4-cs",
8712 TestSubcase::Create<BasicMatrixOperationsCase4CS>));
8713 addChild(new TestSubcase(m_context, "basic-matrixOperations-case5-vs",
8714 TestSubcase::Create<BasicMatrixOperationsCase5VS>));
8715 addChild(new TestSubcase(m_context, "basic-matrixOperations-case5-cs",
8716 TestSubcase::Create<BasicMatrixOperationsCase5CS>));
8717 addChild(new TestSubcase(m_context, "basic-matrixOperations-case6-vs",
8718 TestSubcase::Create<BasicMatrixOperationsCase6VS>));
8719 addChild(new TestSubcase(m_context, "basic-matrixOperations-case6-cs",
8720 TestSubcase::Create<BasicMatrixOperationsCase6CS>));
8721 addChild(new TestSubcase(m_context, "basic-matrixOperations-case7-vs",
8722 TestSubcase::Create<BasicMatrixOperationsCase7VS>));
8723 addChild(new TestSubcase(m_context, "basic-matrixOperations-case7-cs",
8724 TestSubcase::Create<BasicMatrixOperationsCase7CS>));
8725 addChild(new TestSubcase(m_context, "basic-readonly-writeonly", TestSubcase::Create<BasicReadonlyWriteonly>));
8726 addChild(new TestSubcase(m_context, "basic-name-match", TestSubcase::Create<BasicNameMatch>));
8727 addChild(new TestSubcase(m_context, "advanced-switchBuffers-vs", TestSubcase::Create<AdvancedSwitchBuffersVS>));
8728 addChild(new TestSubcase(m_context, "advanced-switchBuffers-cs", TestSubcase::Create<AdvancedSwitchBuffersCS>));
8729 addChild(new TestSubcase(m_context, "advanced-switchPrograms-vs", TestSubcase::Create<AdvancedSwitchProgramsVS>));
8730 addChild(new TestSubcase(m_context, "advanced-switchPrograms-cs", TestSubcase::Create<AdvancedSwitchProgramsCS>));
8731 addChild(new TestSubcase(m_context, "advanced-write-fragment-fs", TestSubcase::Create<AdvancedWriteFragmentFS>));
8732 addChild(new TestSubcase(m_context, "advanced-write-fragment-cs", TestSubcase::Create<AdvancedWriteFragmentCS>));
8733 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case1-vs",
8734 TestSubcase::Create<AdvancedIndirectAddressingCase1VS>));
8735 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case1-cs",
8736 TestSubcase::Create<AdvancedIndirectAddressingCase1CS>));
8737 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case2-vsfs",
8738 TestSubcase::Create<AdvancedIndirectAddressingCase2VSFS>));
8739 addChild(new TestSubcase(m_context, "advanced-indirectAddressing-case2-cs",
8740 TestSubcase::Create<AdvancedIndirectAddressingCase2CS>));
8741 addChild(
8742 new TestSubcase(m_context, "advanced-readWrite-case1-vsfs", TestSubcase::Create<AdvancedReadWriteCase1VSFS>));
8743 addChild(new TestSubcase(m_context, "advanced-readWrite-case1-cs", TestSubcase::Create<AdvancedReadWriteCase1CS>));
8744 addChild(new TestSubcase(m_context, "advanced-usage-case1", TestSubcase::Create<AdvancedUsageCase1>));
8745 addChild(new TestSubcase(m_context, "advanced-usage-sync-vsfs", TestSubcase::Create<AdvancedUsageSyncVSFS>));
8746 addChild(new TestSubcase(m_context, "advanced-usage-sync-cs", TestSubcase::Create<AdvancedUsageSyncCS>));
8747 addChild(new TestSubcase(m_context, "advanced-usage-operators-vs", TestSubcase::Create<AdvancedUsageOperatorsVS>));
8748 addChild(new TestSubcase(m_context, "advanced-usage-operators-cs", TestSubcase::Create<AdvancedUsageOperatorsCS>));
8749 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-int",
8750 TestSubcase::Create<AdvancedUnsizedArrayLength<compute> >));
8751 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-int",
8752 TestSubcase::Create<AdvancedUnsizedArrayLength<fragment> >));
8753 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-int",
8754 TestSubcase::Create<AdvancedUnsizedArrayLength<vertex> >));
8755 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec",
8756 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec>));
8757 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-matC",
8758 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_matC>));
8759 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-matR",
8760 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_matR>));
8761 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-struct",
8762 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_struct>));
8763 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-vec",
8764 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_vec>));
8765 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-matC",
8766 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_matC>));
8767 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-matR",
8768 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_matR>));
8769 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-struct",
8770 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_struct>));
8771 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-packed-vec",
8772 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_packed_vec>));
8773 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-packed-matC",
8774 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_packed_matC>));
8775 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-shared-matR",
8776 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_shared_matR>));
8777 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std430-vec",
8778 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std430_vec>));
8779 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std430-matC-pad",
8780 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std430_matC_pad>));
8781 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std140-matR",
8782 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std140_matR>));
8783 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-fs-std140-struct",
8784 TestSubcase::Create<AdvancedUnsizedArrayLength_fs_std140_struct>));
8785 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-std430-vec",
8786 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_std430_vec_pad>));
8787 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-std140-matC",
8788 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_std140_matC>));
8789 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-packed-matR",
8790 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_packed_matR>));
8791 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-vs-std140-struct",
8792 TestSubcase::Create<AdvancedUnsizedArrayLength_vs_std140_struct>));
8793 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-pad",
8794 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_pad>));
8795 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-matC-pad",
8796 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_matC_pad>));
8797 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std140-matR-pad",
8798 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std140_matR_pad>));
8799 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-struct-pad",
8800 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_struct_pad>));
8801 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-bindrangeOffset",
8802 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_offset>));
8803 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-bindrangeSize",
8804 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_size>));
8805 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-bindbaseAfter",
8806 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_after>));
8807 addChild(new TestSubcase(m_context, "advanced-unsizedArrayLength-cs-std430-vec-indexing",
8808 TestSubcase::Create<AdvancedUnsizedArrayLength_cs_std430_vec_indexing>));
8809 addChild(new TestSubcase(m_context, "advanced-matrix-vsfs", TestSubcase::Create<AdvancedMatrixVSFS>));
8810 addChild(new TestSubcase(m_context, "advanced-matrix-cs", TestSubcase::Create<AdvancedMatrixCS>));
8811 addChild(new TestSubcase(m_context, "negative-api-bind", TestSubcase::Create<NegativeAPIBind>));
8812 addChild(new TestSubcase(m_context, "negative-glsl-compileTime", TestSubcase::Create<NegativeGLSLCompileTime>));
8813 addChild(new TestSubcase(m_context, "negative-glsl-linkTime", TestSubcase::Create<NegativeGLSLLinkTime>));
8814 }
8815
8816 } // namespace glcts
8817