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