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 "gluContextInfo.hpp" 26 #include "glwEnums.hpp" 27 #include "tcuMatrix.hpp" 28 #include "tcuRenderTarget.hpp" 29 #include "tcuVectorUtil.hpp" 30 #include <assert.h> 31 #include <cstdarg> 32 #include <map> 33 34 namespace gl4cts 35 { 36 namespace es31compatibility 37 { 38 using namespace glw; 39 namespace 40 { 41 typedef tcu::Vec2 vec2; 42 typedef tcu::Vec4 vec4; 43 typedef tcu::IVec4 ivec4; 44 typedef tcu::UVec4 uvec4; 45 typedef tcu::Mat4 mat4; 46 47 enum Target 48 { 49 T2D = 0, 50 T3D, 51 TCM, 52 T2DA 53 }; 54 55 const char* const kGLSLVer = "#version 310 es"; 56 const char* const kGLSLSIA = NL "#extension GL_OES_shader_image_atomic : require"; 57 const char* const kGLSLPrec = 58 NL "precision highp float;" NL "precision highp int;" NL "precision highp sampler2D;" NL 59 "precision highp sampler3D;" NL "precision highp samplerCube;" NL "precision highp sampler2DArray;" NL 60 "precision highp isampler2D;" NL "precision highp isampler3D;" NL "precision highp isamplerCube;" NL 61 "precision highp isampler2DArray;" NL "precision highp usampler2D;" NL "precision highp usampler3D;" NL 62 "precision highp usamplerCube;" NL "precision highp usampler2DArray;" NL "precision highp image2D;" NL 63 "precision highp image3D;" NL "precision highp imageCube;" NL "precision highp image2DArray;" NL 64 "precision highp iimage2D;" NL "precision highp iimage3D;" NL "precision highp iimageCube;" NL 65 "precision highp iimage2DArray;" NL "precision highp uimage2D;" NL "precision highp uimage3D;" NL 66 "precision highp uimageCube;" NL "precision highp uimage2DArray;"; 67 68 class ShaderImageLoadStoreBase : public deqp::SubcaseBase 69 { 70 public: 71 virtual std::string Title() 72 { 73 return ""; 74 } 75 76 virtual std::string Purpose() 77 { 78 return ""; 79 } 80 81 virtual std::string Method() 82 { 83 return ""; 84 } 85 86 virtual std::string PassCriteria() 87 { 88 return ""; 89 } 90 91 bool IsVSFSAvailable(int requiredVS, int requiredFS) 92 { 93 GLint imagesVS, imagesFS; 94 glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &imagesVS); 95 glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &imagesFS); 96 if (imagesVS >= requiredVS && imagesFS >= requiredFS) 97 return true; 98 else 99 { 100 std::ostringstream reason; 101 reason << "Required " << requiredVS << " VS image uniforms but only " << imagesVS << " available." 102 << std::endl 103 << "Required " << requiredFS << " FS image uniforms but only " << imagesFS << " available." 104 << std::endl; 105 OutputNotSupported(reason.str()); 106 return false; 107 } 108 } 109 bool IsSSBInVSFSAvailable(int required) 110 { 111 GLint blocksVS, blocksFS; 112 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &blocksVS); 113 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &blocksFS); 114 if (blocksVS >= required && blocksFS >= required) 115 return true; 116 else 117 { 118 std::ostringstream reason; 119 reason << "Required " << required << " VS storage blocks but only " << blocksVS << " available." 120 << std::endl 121 << "Required " << required << " FS storage blocks but only " << blocksFS << " available." 122 << std::endl; 123 OutputNotSupported(reason.str()); 124 return false; 125 } 126 } 127 128 bool IsImageAtomicSupported() 129 { 130 bool is_at_least_gl_45 = 131 (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 132 bool is_arb_es31_compatibility = m_context.getContextInfo().isExtensionSupported("GL_ARB_ES3_1_compatibility"); 133 if (!(is_at_least_gl_45 || is_arb_es31_compatibility)) 134 { 135 std::ostringstream reason; 136 reason << "Required GL_OES_shader_image_atomic is not available." << std::endl; 137 OutputNotSupported(reason.str()); 138 return false; 139 } 140 return true; 141 } 142 143 bool AreOutputsAvailable(int required) 144 { 145 GLint outputs; 146 glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &outputs); 147 if (outputs < required) 148 { 149 std::ostringstream reason; 150 reason << "Required " << required << " shader output resources but only " << outputs << " available." 151 << std::endl; 152 OutputNotSupported(reason.str()); 153 return false; 154 } 155 return true; 156 } 157 158 int getWindowWidth() 159 { 160 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 161 return renderTarget.getWidth(); 162 } 163 164 int getWindowHeight() 165 { 166 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 167 return renderTarget.getHeight(); 168 } 169 170 inline bool ColorEqual(const vec4& c0, const vec4& c1, const vec4& epsilon) 171 { 172 if (fabs(c0[0] - c1[0]) > epsilon[0]) 173 return false; 174 if (fabs(c0[1] - c1[1]) > epsilon[1]) 175 return false; 176 if (fabs(c0[2] - c1[2]) > epsilon[2]) 177 return false; 178 if (fabs(c0[3] - c1[3]) > epsilon[3]) 179 return false; 180 return true; 181 } 182 183 bool Equal(const vec4& v0, const vec4& v1, GLenum internalformat) 184 { 185 if (internalformat == GL_RGBA8_SNORM || internalformat == GL_RGBA8) 186 { 187 return ColorEqual(v0, v1, vec4(0.01f)); 188 } 189 return (v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[2]) && (v0[3] == v1[3]); 190 } 191 bool Equal(const ivec4& a, const ivec4& b, GLenum) 192 { 193 return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]); 194 } 195 bool Equal(const uvec4& a, const uvec4& b, GLenum) 196 { 197 return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]); 198 } 199 200 template <class T> 201 std::string ToString(T v) 202 { 203 std::ostringstream s; 204 s << "["; 205 for (int i = 0; i < 4; ++i) 206 s << v[i] << (i == 3 ? "" : ","); 207 s << "]"; 208 return s.str(); 209 } 210 211 template <typename T> 212 bool CompareValues(T* map_data, int kSize, const T& expected_value, GLenum internalformat = 0, int layers = 1) 213 { 214 for (int i = 0; i < kSize * kSize * layers; ++i) 215 { 216 if (!Equal(map_data[i], expected_value, internalformat)) 217 { 218 m_context.getTestContext().getLog() 219 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str() 220 << ". Value should be: " << ToString(expected_value).c_str() << "." << tcu::TestLog::EndMessage; 221 return false; 222 } 223 } 224 return true; 225 } 226 template <typename T> 227 bool CompareValues(bool always, T* map_data, int kSize, const T& expected_value, GLenum internalformat = 0, 228 int layers = 1) 229 { 230 (void)internalformat; 231 for (int i = 0; i < kSize * kSize * layers; ++i) 232 { 233 if (always) 234 { 235 m_context.getTestContext().getLog() 236 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str() 237 << ". Value should be: " << ToString(expected_value).c_str() << "." << tcu::TestLog::EndMessage; 238 } 239 } 240 return true; 241 } 242 243 bool CheckFB(vec4 expected) 244 { 245 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 246 const tcu::PixelFormat& pixelFormat = renderTarget.getPixelFormat(); 247 vec4 g_color_eps = vec4(1.f / (float)(1 << pixelFormat.redBits), 1.f / (float)(1 << pixelFormat.greenBits), 248 1.f / (float)(1 << pixelFormat.blueBits), 1.f); 249 vec4 g_color_max = vec4(255); 250 std::vector<GLubyte> fb(getWindowWidth() * getWindowHeight() * 4); 251 int fb_w = getWindowWidth(); 252 int fb_h = getWindowHeight(); 253 glReadPixels(0, 0, fb_w, fb_h, GL_RGBA, GL_UNSIGNED_BYTE, &fb[0]); 254 for (GLint i = 0, y = 0; y < fb_h; ++y) 255 for (GLint x = 0; x < fb_w; ++x, i += 4) 256 { 257 if (fabs(fb[i + 0] / g_color_max[0] - expected[0]) > g_color_eps[0] || 258 fabs(fb[i + 1] / g_color_max[1] - expected[1]) > g_color_eps[1] || 259 fabs(fb[i + 2] / g_color_max[2] - expected[2]) > g_color_eps[2]) 260 { 261 m_context.getTestContext().getLog() 262 << tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << ", " << y 263 << "). Color is (" << fb[i + 0] / g_color_max[0] << ", " << fb[i + 1] / g_color_max[1] << ", " 264 << fb[i + 2] / g_color_max[2] << "). Color should be (" << expected[0] << ", " << expected[1] 265 << ", " << expected[2] << ")." << tcu::TestLog::EndMessage; 266 return false; 267 } 268 } 269 return true; 270 } 271 272 bool CompileShader(GLuint shader) 273 { 274 glCompileShader(shader); 275 276 GLint status; 277 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 278 if (status == GL_FALSE) 279 { 280 GLsizei length; 281 GLchar log[1024]; 282 glGetShaderInfoLog(shader, sizeof(log), &length, log); 283 if (length > 1) 284 { 285 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n" 286 << log << tcu::TestLog::EndMessage; 287 } 288 return false; 289 } 290 return true; 291 } 292 293 bool LinkProgram(GLuint program) 294 { 295 glLinkProgram(program); 296 297 GLint status; 298 glGetProgramiv(program, GL_LINK_STATUS, &status); 299 if (status == GL_FALSE) 300 { 301 GLsizei length; 302 GLchar log[1024]; 303 glGetProgramInfoLog(program, sizeof(log), &length, log); 304 if (length > 1) 305 { 306 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n" 307 << log << tcu::TestLog::EndMessage; 308 } 309 return false; 310 } 311 return true; 312 } 313 314 GLuint BuildProgram(const char* src_vs, const char* src_fs, bool SIAvs = false, bool SIAfs = false) 315 { 316 std::ostringstream osvs, osfs; 317 osvs << kGLSLVer << (SIAvs ? kGLSLSIA : "\n") << kGLSLPrec; 318 osfs << kGLSLVer << (SIAfs ? kGLSLSIA : "\n") << kGLSLPrec; 319 std::string hvs = osvs.str(); 320 std::string hfs = osfs.str(); 321 322 const GLuint p = glCreateProgram(); 323 324 if (src_vs) 325 { 326 GLuint sh = glCreateShader(GL_VERTEX_SHADER); 327 glAttachShader(p, sh); 328 glDeleteShader(sh); 329 const char* const src[2] = { hvs.c_str(), src_vs }; 330 glShaderSource(sh, 2, src, NULL); 331 if (!CompileShader(sh)) 332 { 333 m_context.getTestContext().getLog() 334 << tcu::TestLog::Message << src[0] << src[1] << tcu::TestLog::EndMessage; 335 return p; 336 } 337 } 338 if (src_fs) 339 { 340 GLuint sh = glCreateShader(GL_FRAGMENT_SHADER); 341 glAttachShader(p, sh); 342 glDeleteShader(sh); 343 const char* const src[2] = { hfs.c_str(), src_fs }; 344 glShaderSource(sh, 2, src, NULL); 345 if (!CompileShader(sh)) 346 { 347 m_context.getTestContext().getLog() 348 << tcu::TestLog::Message << src[0] << src[1] << tcu::TestLog::EndMessage; 349 return p; 350 } 351 } 352 if (!LinkProgram(p)) 353 { 354 if (src_vs) 355 m_context.getTestContext().getLog() 356 << tcu::TestLog::Message << hvs.c_str() << src_vs << tcu::TestLog::EndMessage; 357 if (src_fs) 358 m_context.getTestContext().getLog() 359 << tcu::TestLog::Message << hfs.c_str() << src_fs << tcu::TestLog::EndMessage; 360 return p; 361 } 362 363 return p; 364 } 365 366 GLuint CreateComputeProgram(const std::string& cs, bool SIA = false) 367 { 368 std::ostringstream oscs; 369 oscs << kGLSLVer << (SIA ? kGLSLSIA : "\n") << kGLSLPrec; 370 std::string hcs = oscs.str(); 371 const GLuint p = glCreateProgram(); 372 373 if (!cs.empty()) 374 { 375 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 376 glAttachShader(p, sh); 377 glDeleteShader(sh); 378 const char* const src[2] = { hcs.c_str(), cs.c_str() }; 379 glShaderSource(sh, 2, src, NULL); 380 if (!CompileShader(sh)) 381 { 382 m_context.getTestContext().getLog() 383 << tcu::TestLog::Message << src[0] << src[1] << tcu::TestLog::EndMessage; 384 return p; 385 } 386 } 387 if (!LinkProgram(p)) 388 { 389 if (!cs.empty()) 390 m_context.getTestContext().getLog() 391 << tcu::TestLog::Message << hcs.c_str() << cs.c_str() << tcu::TestLog::EndMessage; 392 return p; 393 } 394 395 return p; 396 } 397 398 GLuint BuildShaderProgram(GLenum type, const char* src) 399 { 400 const char* const src3[3] = { kGLSLVer, kGLSLPrec, src }; 401 const GLuint p = glCreateShaderProgramv(type, 3, src3); 402 GLint status; 403 glGetProgramiv(p, GL_LINK_STATUS, &status); 404 if (status == GL_FALSE) 405 { 406 GLchar log[1024]; 407 glGetProgramInfoLog(p, sizeof(log), NULL, log); 408 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n" 409 << log << "\n" 410 << src3[0] << "\n" 411 << src3[1] << "\n" 412 << src3[2] << tcu::TestLog::EndMessage; 413 } 414 return p; 415 } 416 417 void CreateFullViewportQuad(GLuint* vao, GLuint* vbo, GLuint* ebo) 418 { 419 assert(vao && vbo); 420 421 // interleaved data (vertex, color0 (green), color1 (blue), color2 (red)) 422 const float v[] = { 423 -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 424 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 425 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 426 }; 427 glGenBuffers(1, vbo); 428 glBindBuffer(GL_ARRAY_BUFFER, *vbo); 429 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW); 430 glBindBuffer(GL_ARRAY_BUFFER, 0); 431 432 if (ebo) 433 { 434 std::vector<GLushort> index_data(4); 435 for (int i = 0; i < 4; ++i) 436 { 437 index_data[i] = static_cast<GLushort>(i); 438 } 439 glGenBuffers(1, ebo); 440 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *ebo); 441 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 4, &index_data[0], GL_STATIC_DRAW); 442 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 443 } 444 445 glGenVertexArrays(1, vao); 446 glBindVertexArray(*vao); 447 glBindBuffer(GL_ARRAY_BUFFER, *vbo); 448 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 11, 0); 449 450 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, reinterpret_cast<void*>(sizeof(float) * 2)); 451 452 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, 453 454 reinterpret_cast<void*>(sizeof(float) * 5)); 455 456 glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, reinterpret_cast<void*>(sizeof(float) * 8)); 457 458 glBindBuffer(GL_ARRAY_BUFFER, 0); 459 glEnableVertexAttribArray(0); 460 glEnableVertexAttribArray(1); 461 glEnableVertexAttribArray(2); 462 glEnableVertexAttribArray(3); 463 if (ebo) 464 { 465 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *ebo); 466 } 467 glBindVertexArray(0); 468 } 469 470 std::string FormatEnumToString(GLenum e) 471 { 472 switch (e) 473 { 474 case GL_RGBA32F: 475 return "rgba32f"; 476 case GL_RGBA16F: 477 return "rgba16f"; 478 case GL_R32F: 479 return "r32f"; 480 481 case GL_RGBA32UI: 482 return "rgba32ui"; 483 case GL_RGBA16UI: 484 return "rgba16ui"; 485 case GL_RGBA8UI: 486 return "rgba8ui"; 487 case GL_R32UI: 488 return "r32ui"; 489 490 case GL_RGBA32I: 491 return "rgba32i"; 492 case GL_RGBA16I: 493 return "rgba16i"; 494 case GL_RGBA8I: 495 return "rgba8i"; 496 case GL_R32I: 497 return "r32i"; 498 499 case GL_RGBA8: 500 return "rgba8"; 501 502 case GL_RGBA8_SNORM: 503 return "rgba8_snorm"; 504 } 505 506 assert(0); 507 return ""; 508 } 509 510 template <typename T> 511 GLenum Format(); 512 513 template <typename T> 514 GLenum Type(); 515 516 template <typename T> 517 std::string TypePrefix(); 518 519 template <typename T> 520 GLenum ImageType(GLenum target); 521 522 void ClearBuffer(GLenum buffer, GLint drawbuffer, const vec4& color) 523 { 524 glClearBufferfv(buffer, drawbuffer, &color[0]); 525 } 526 527 void ClearBuffer(GLenum buffer, GLint drawbuffer, const ivec4& color) 528 { 529 glClearBufferiv(buffer, drawbuffer, &color[0]); 530 } 531 532 void ClearBuffer(GLenum buffer, GLint drawbuffer, const uvec4& color) 533 { 534 glClearBufferuiv(buffer, drawbuffer, &color[0]); 535 } 536 537 bool CheckMax(GLenum pname, GLint min_value) 538 { 539 GLboolean b; 540 GLint i; 541 GLfloat f; 542 GLint64 i64; 543 544 glGetIntegerv(pname, &i); 545 if (i < min_value) 546 return false; 547 548 glGetBooleanv(pname, &b); 549 if (b != (i ? GL_TRUE : GL_FALSE)) 550 return false; 551 552 glGetFloatv(pname, &f); 553 if (static_cast<GLint>(f) < min_value) 554 return false; 555 556 glGetInteger64v(pname, &i64); 557 if (static_cast<GLint>(i64) < min_value) 558 return false; 559 560 return true; 561 } 562 563 bool CheckBinding(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, 564 GLenum format) 565 { 566 GLint i; 567 GLboolean b; 568 569 glGetIntegeri_v(GL_IMAGE_BINDING_NAME, unit, &i); 570 if (static_cast<GLuint>(i) != texture) 571 { 572 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_NAME is " << i 573 << " should be " << texture << "." << tcu::TestLog::EndMessage; 574 return false; 575 } 576 577 glGetIntegeri_v(GL_IMAGE_BINDING_LEVEL, unit, &i); 578 if (i != level) 579 { 580 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LEVEL is " << i 581 << " should be " << level << "." << tcu::TestLog::EndMessage; 582 return false; 583 } 584 585 glGetIntegeri_v(GL_IMAGE_BINDING_LAYERED, unit, &i); 586 glGetBooleani_v(GL_IMAGE_BINDING_LAYERED, unit, &b); 587 if (i != layered || b != layered) 588 { 589 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYERED is " << i 590 << " should be " << layered << "." << tcu::TestLog::EndMessage; 591 return false; 592 } 593 594 glGetIntegeri_v(GL_IMAGE_BINDING_LAYER, unit, &i); 595 if (i != layer) 596 { 597 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYER is " << i 598 << " should be " << layer << "." << tcu::TestLog::EndMessage; 599 return false; 600 } 601 602 glGetIntegeri_v(GL_IMAGE_BINDING_ACCESS, unit, &i); 603 if (static_cast<GLenum>(i) != access) 604 { 605 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_ACCESS is " << i 606 << " should be " << access << "." << tcu::TestLog::EndMessage; 607 return false; 608 } 609 610 glGetIntegeri_v(GL_IMAGE_BINDING_FORMAT, unit, &i); 611 if (static_cast<GLenum>(i) != format) 612 { 613 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_FORMAT is " << i 614 << " should be " << format << "." << tcu::TestLog::EndMessage; 615 return false; 616 } 617 618 return true; 619 } 620 const char* EnumToString(GLenum e) 621 { 622 switch (e) 623 { 624 case GL_TEXTURE_2D: 625 return "GL_TEXTURE_2D"; 626 case GL_TEXTURE_3D: 627 return "GL_TEXTURE_3D"; 628 case GL_TEXTURE_CUBE_MAP: 629 return "GL_TEXTURE_CUBE_MAP"; 630 case GL_TEXTURE_2D_ARRAY: 631 return "GL_TEXTURE_2D_ARRAY"; 632 633 default: 634 assert(0); 635 break; 636 } 637 return NULL; 638 } 639 }; 640 641 template <> 642 GLenum ShaderImageLoadStoreBase::Format<vec4>() 643 { 644 return GL_RGBA; 645 } 646 647 template <> 648 GLenum ShaderImageLoadStoreBase::Format<ivec4>() 649 { 650 return GL_RGBA_INTEGER; 651 } 652 653 template <> 654 GLenum ShaderImageLoadStoreBase::Format<uvec4>() 655 { 656 return GL_RGBA_INTEGER; 657 } 658 659 template <> 660 GLenum ShaderImageLoadStoreBase::Format<GLint>() 661 { 662 return GL_RED_INTEGER; 663 } 664 665 template <> 666 GLenum ShaderImageLoadStoreBase::Format<GLuint>() 667 { 668 return GL_RED_INTEGER; 669 } 670 671 template <> 672 GLenum ShaderImageLoadStoreBase::Type<vec4>() 673 { 674 return GL_FLOAT; 675 } 676 677 template <> 678 GLenum ShaderImageLoadStoreBase::Type<ivec4>() 679 { 680 return GL_INT; 681 } 682 683 template <> 684 GLenum ShaderImageLoadStoreBase::Type<uvec4>() 685 { 686 return GL_UNSIGNED_INT; 687 } 688 689 template <> 690 GLenum ShaderImageLoadStoreBase::Type<GLint>() 691 { 692 return GL_INT; 693 } 694 695 template <> 696 GLenum ShaderImageLoadStoreBase::Type<GLuint>() 697 { 698 return GL_UNSIGNED_INT; 699 } 700 701 template <> 702 std::string ShaderImageLoadStoreBase::TypePrefix<vec4>() 703 { 704 return ""; 705 } 706 707 template <> 708 709 std::string ShaderImageLoadStoreBase::TypePrefix<ivec4>() 710 { 711 return "i"; 712 } 713 714 template <> 715 std::string ShaderImageLoadStoreBase::TypePrefix<uvec4>() 716 { 717 return "u"; 718 } 719 720 template <> 721 722 std::string ShaderImageLoadStoreBase::TypePrefix<GLint>() 723 { 724 return "i"; 725 } 726 727 template <> 728 std::string ShaderImageLoadStoreBase::TypePrefix<GLuint>() 729 { 730 return "u"; 731 } 732 733 template <> 734 GLenum ShaderImageLoadStoreBase::ImageType<vec4>(GLenum target) 735 { 736 switch (target) 737 { 738 case GL_TEXTURE_2D: 739 return GL_IMAGE_2D; 740 case GL_TEXTURE_3D: 741 return GL_IMAGE_3D; 742 case GL_TEXTURE_CUBE_MAP: 743 return GL_IMAGE_CUBE; 744 case GL_TEXTURE_2D_ARRAY: 745 return GL_IMAGE_2D_ARRAY; 746 } 747 assert(0); 748 return 0; 749 } 750 751 template <> 752 GLenum ShaderImageLoadStoreBase::ImageType<ivec4>(GLenum target) 753 { 754 switch (target) 755 { 756 case GL_TEXTURE_2D: 757 return GL_INT_IMAGE_2D; 758 case GL_TEXTURE_3D: 759 return GL_INT_IMAGE_3D; 760 case GL_TEXTURE_CUBE_MAP: 761 return GL_INT_IMAGE_CUBE; 762 case GL_TEXTURE_2D_ARRAY: 763 return GL_INT_IMAGE_2D_ARRAY; 764 } 765 assert(0); 766 return 0; 767 } 768 769 template <> 770 GLenum ShaderImageLoadStoreBase::ImageType<uvec4>(GLenum target) 771 { 772 switch (target) 773 { 774 case GL_TEXTURE_2D: 775 return GL_UNSIGNED_INT_IMAGE_2D; 776 case GL_TEXTURE_3D: 777 return GL_UNSIGNED_INT_IMAGE_3D; 778 case GL_TEXTURE_CUBE_MAP: 779 return GL_UNSIGNED_INT_IMAGE_CUBE; 780 case GL_TEXTURE_2D_ARRAY: 781 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY; 782 } 783 assert(0); 784 return 0; 785 } 786 787 int Components(GLenum e) 788 { 789 return (e == GL_RED || e == GL_RED_INTEGER) ? 1 : 4; 790 } 791 792 bool Shorts(GLenum e) 793 { 794 return (e == GL_RGBA16I || e == GL_RGBA16UI); 795 } 796 797 bool Bytes(GLenum e) 798 { 799 return (e == GL_RGBA8I || e == GL_RGBA8UI || e == GL_RGBA8 || e == GL_RGBA8_SNORM); 800 } 801 802 template <typename T> 803 class ShortByteData 804 { 805 public: 806 std::vector<T> data; 807 std::vector<GLshort> datas; 808 std::vector<GLbyte> datab; 809 810 ShortByteData(int size, const T& value, GLenum internalformat, GLenum format) 811 : data(size * size, value), datas(size * size * 4), datab(size * size * 4) 812 { 813 if (Components(format) == 1) 814 for (unsigned i = 0; i < data.size() / 4; ++i) 815 { 816 data[i][0] = data[i * 4][0]; 817 data[i][1] = data[i * 4 + 1][0]; 818 data[i][2] = data[i * 4 + 2][0]; 819 data[i][3] = data[i * 4 + 3][0]; 820 } 821 if (Shorts(internalformat)) 822 { 823 for (unsigned i = 0; i < datas.size(); i += 4) 824 { 825 datas[i] = static_cast<GLshort>(data[i / 4][0]); 826 datas[i + 1] = static_cast<GLshort>(data[i / 4][1]); 827 datas[i + 2] = static_cast<GLshort>(data[i / 4][2]); 828 datas[i + 3] = static_cast<GLshort>(data[i / 4][3]); 829 } 830 } 831 if (Bytes(internalformat)) 832 { 833 for (unsigned i = 0; i < datas.size(); i += 4) 834 { 835 if (internalformat == GL_RGBA8I || internalformat == GL_RGBA8UI) 836 { 837 datab[i] = static_cast<GLbyte>(data[i / 4][0]); 838 datab[i + 1] = static_cast<GLbyte>(data[i / 4][1]); 839 datab[i + 2] = static_cast<GLbyte>(data[i / 4][2]); 840 datab[i + 3] = static_cast<GLbyte>(data[i / 4][3]); 841 } 842 else if (internalformat == GL_RGBA8) 843 { 844 datab[i] = static_cast<GLbyte>(data[i / 4][0] * 255); 845 datab[i + 1] = static_cast<GLbyte>(data[i / 4][1] * 255); 846 datab[i + 2] = static_cast<GLbyte>(data[i / 4][2] * 255); 847 datab[i + 3] = static_cast<GLbyte>(data[i / 4][3] * 255); 848 } 849 else 850 { // GL_RGBA8_SNORM 851 datab[i] = static_cast<GLbyte>(data[i / 4][0] * 127); 852 datab[i + 1] = static_cast<GLbyte>(data[i / 4][1] * 127); 853 datab[i + 2] = static_cast<GLbyte>(data[i / 4][2] * 127); 854 datab[i + 3] = static_cast<GLbyte>(data[i / 4][3] * 127); 855 } 856 } 857 } 858 } 859 }; 860 861 //----------------------------------------------------------------------------- 862 // 1.1.1 BasicAPIGet 863 //----------------------------------------------------------------------------- 864 class BasicAPIGet : public ShaderImageLoadStoreBase 865 { 866 virtual long Run() 867 { 868 if (!CheckMax(GL_MAX_IMAGE_UNITS, 4)) 869 { 870 m_context.getTestContext().getLog() 871 << tcu::TestLog::Message << "GL_MAX_IMAGE_UNITS value is invalid." << tcu::TestLog::EndMessage; 872 return ERROR; 873 } 874 if (!CheckMax(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, 4)) 875 { 876 m_context.getTestContext().getLog() 877 << tcu::TestLog::Message << "GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES value is invalid." 878 << tcu::TestLog::EndMessage; 879 return ERROR; 880 } 881 if (!CheckMax(GL_MAX_VERTEX_IMAGE_UNIFORMS, 0)) 882 { 883 m_context.getTestContext().getLog() 884 << tcu::TestLog::Message << "GL_MAX_VERTEX_IMAGE_UNIFORMS value is invalid." 885 << tcu::TestLog::EndMessage; 886 return ERROR; 887 } 888 if (!CheckMax(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, 0)) 889 { 890 m_context.getTestContext().getLog() 891 << tcu::TestLog::Message << "GL_MAX_FRAGMENT_IMAGE_UNIFORMS value is invalid." 892 << tcu::TestLog::EndMessage; 893 return ERROR; 894 } 895 if (!CheckMax(GL_MAX_COMBINED_IMAGE_UNIFORMS, 4)) 896 { 897 m_context.getTestContext().getLog() 898 << tcu::TestLog::Message << "GL_MAX_COMBINED_IMAGE_UNIFORMS value is invalid." 899 << tcu::TestLog::EndMessage; 900 return ERROR; 901 } 902 if (!CheckMax(GL_MAX_COMPUTE_IMAGE_UNIFORMS, 4)) 903 { 904 m_context.getTestContext().getLog() 905 << tcu::TestLog::Message << "GL_MAX_COMPUTE_IMAGE_UNIFORMS value is invalid." 906 << tcu::TestLog::EndMessage; 907 return ERROR; 908 } 909 return NO_ERROR; 910 } 911 }; 912 913 //----------------------------------------------------------------------------- 914 // 1.1.2 BasicAPIBind 915 //----------------------------------------------------------------------------- 916 class BasicAPIBind : public ShaderImageLoadStoreBase 917 { 918 GLuint m_texture; 919 920 virtual long Setup() 921 { 922 m_texture = 0; 923 return NO_ERROR; 924 } 925 926 virtual long Run() 927 { 928 bool status = true; 929 for (GLuint index = 0; index < 4; ++index) 930 { 931 if (!CheckBinding(index, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI)) 932 { 933 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Binding point " << index 934 << " has invalid default state." << tcu::TestLog::EndMessage; 935 status = false; 936 } 937 } 938 939 glGenTextures(1, &m_texture); 940 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture); 941 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RG32F, 16, 16, 4); 942 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 943 944 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); 945 if (!CheckBinding(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F)) 946 status = false; 947 948 glBindImageTexture(3, m_texture, 1, GL_TRUE, 1, GL_WRITE_ONLY, GL_RGBA8); 949 if (!CheckBinding(3, m_texture, 1, GL_TRUE, 1, GL_WRITE_ONLY, GL_RGBA8)) 950 status = false; 951 952 glBindImageTexture(1, m_texture, 3, GL_FALSE, 2, GL_READ_WRITE, GL_RGBA8UI); 953 if (!CheckBinding(1, m_texture, 3, GL_FALSE, 2, GL_READ_WRITE, GL_RGBA8UI)) 954 status = false; 955 956 glBindImageTexture(2, m_texture, 4, GL_FALSE, 3, GL_READ_ONLY, GL_R32I); 957 if (!CheckBinding(2, m_texture, 4, GL_FALSE, 3, GL_READ_ONLY, GL_R32I)) 958 status = false; 959 960 glDeleteTextures(1, &m_texture); 961 m_texture = 0; 962 963 for (GLuint index = 0; index < 4; ++index) 964 { 965 GLint name; 966 glGetIntegeri_v(GL_IMAGE_BINDING_NAME, index, &name); 967 if (name != 0) 968 { 969 m_context.getTestContext().getLog() 970 << tcu::TestLog::Message << "Binding point " << index 971 << " should be set to 0 after texture deletion." << tcu::TestLog::EndMessage; 972 status = false; 973 } 974 if (!CheckBinding(index, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI)) 975 status = false; 976 } 977 978 return status ? NO_ERROR : ERROR; 979 } 980 981 virtual long Cleanup() 982 { 983 glDeleteTextures(1, &m_texture); 984 return NO_ERROR; 985 } 986 }; 987 //----------------------------------------------------------------------------- 988 // 1.1.3 BasicAPIBarrier 989 //----------------------------------------------------------------------------- 990 class BasicAPIBarrier : public ShaderImageLoadStoreBase 991 { 992 virtual long Run() 993 { 994 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT); 995 glMemoryBarrier(GL_ELEMENT_ARRAY_BARRIER_BIT); 996 glMemoryBarrier(GL_UNIFORM_BARRIER_BIT); 997 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 998 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 999 glMemoryBarrier(GL_COMMAND_BARRIER_BIT); 1000 glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); 1001 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 1002 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1003 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT); 1004 glMemoryBarrier(GL_TRANSFORM_FEEDBACK_BARRIER_BIT); 1005 glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT); 1006 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 1007 1008 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT | 1009 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT | 1010 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT | 1011 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT | 1012 GL_SHADER_STORAGE_BARRIER_BIT); 1013 1014 glMemoryBarrier(GL_ALL_BARRIER_BITS); 1015 1016 return NO_ERROR; 1017 } 1018 }; 1019 1020 class BasicAPIBarrierByRegion : public ShaderImageLoadStoreBase 1021 { 1022 virtual long Run() 1023 { 1024 glMemoryBarrierByRegion(GL_UNIFORM_BARRIER_BIT); 1025 glMemoryBarrierByRegion(GL_TEXTURE_FETCH_BARRIER_BIT); 1026 glMemoryBarrierByRegion(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 1027 glMemoryBarrierByRegion(GL_FRAMEBUFFER_BARRIER_BIT); 1028 glMemoryBarrierByRegion(GL_ATOMIC_COUNTER_BARRIER_BIT); 1029 glMemoryBarrierByRegion(GL_SHADER_STORAGE_BARRIER_BIT); 1030 1031 glMemoryBarrierByRegion(GL_UNIFORM_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT | 1032 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT | 1033 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT); 1034 1035 glMemoryBarrierByRegion(GL_ALL_BARRIER_BITS); 1036 return NO_ERROR; 1037 } 1038 }; 1039 //----------------------------------------------------------------------------- 1040 // 1.1.4 BasicAPITexParam 1041 //----------------------------------------------------------------------------- 1042 class BasicAPITexParam : public ShaderImageLoadStoreBase 1043 { 1044 GLuint m_texture; 1045 1046 virtual long Setup() 1047 { 1048 m_texture = 0; 1049 return NO_ERROR; 1050 } 1051 1052 virtual long Run() 1053 { 1054 glGenTextures(1, &m_texture); 1055 glBindTexture(GL_TEXTURE_2D, m_texture); 1056 glTexStorage2D(GL_TEXTURE_2D, 5, GL_RG32F, 16, 16); 1057 1058 GLint i; 1059 GLfloat f; 1060 1061 glGetTexParameteriv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &i); 1062 if (i != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE) 1063 { 1064 m_context.getTestContext().getLog() 1065 << tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to " 1066 << "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL." 1067 << tcu::TestLog::EndMessage; 1068 return ERROR; 1069 } 1070 glGetTexParameterfv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &f); 1071 if (static_cast<GLenum>(f) != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE) 1072 { 1073 m_context.getTestContext().getLog() 1074 << tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to " 1075 << "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL." 1076 << tcu::TestLog::EndMessage; 1077 return ERROR; 1078 } 1079 1080 return NO_ERROR; 1081 } 1082 1083 virtual long Cleanup() 1084 { 1085 glDeleteTextures(1, &m_texture); 1086 return NO_ERROR; 1087 } 1088 }; 1089 //----------------------------------------------------------------------------- 1090 // 1.2.1 BasicAllFormatsStore 1091 //----------------------------------------------------------------------------- 1092 class BasicAllFormatsStoreFS : public ShaderImageLoadStoreBase 1093 { 1094 GLuint m_vao, m_vbo; 1095 1096 virtual long Setup() 1097 { 1098 m_vao = 0; 1099 m_vbo = 0; 1100 return NO_ERROR; 1101 } 1102 1103 virtual long Run() 1104 { 1105 if (!IsVSFSAvailable(0, 1)) 1106 return NOT_SUPPORTED; 1107 1108 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 1109 1110 if (!Write(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f))) 1111 return ERROR; 1112 if (!Write(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f))) 1113 return ERROR; 1114 if (!Write(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f))) 1115 return ERROR; 1116 1117 if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1118 return ERROR; 1119 if (!Write(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1))) 1120 return ERROR; 1121 if (!Write(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1122 return ERROR; 1123 if (!Write(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1124 return ERROR; 1125 1126 if (!Write(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 1127 return ERROR; 1128 if (!Write(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1))) 1129 return ERROR; 1130 if (!Write(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 1131 return ERROR; 1132 if (!Write(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 1133 return ERROR; 1134 1135 if (!Write(GL_RGBA8, vec4(1.0f), vec4(1.0f))) 1136 return ERROR; 1137 1138 if (!Write(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f))) 1139 return ERROR; 1140 1141 return NO_ERROR; 1142 } 1143 1144 template <typename T> 1145 bool Write(GLenum internalformat, const T& write_value, const T& expected_value) 1146 { 1147 const char* src_vs = 1148 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 1149 GLuint program = BuildProgram(src_vs, GenFS(internalformat, write_value).c_str()); 1150 const int kSize = 11; 1151 std::vector<T> data(kSize * kSize); 1152 GLuint texture; 1153 glGenTextures(1, &texture); 1154 glUseProgram(program); 1155 1156 GLuint unit = 2; 1157 glBindTexture(GL_TEXTURE_2D, texture); 1158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1160 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 1161 glBindTexture(GL_TEXTURE_2D, 0); 1162 1163 glViewport(0, 0, kSize, kSize); 1164 glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); 1165 glBindVertexArray(m_vao); 1166 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 1167 1168 glBindTexture(GL_TEXTURE_2D, texture); 1169 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 1170 1171 GLuint c_program = CreateComputeProgram(GenC(write_value)); 1172 std::vector<T> out_data(kSize * kSize); 1173 GLuint m_buffer; 1174 glGenBuffers(1, &m_buffer); 1175 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 1176 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW); 1177 1178 glUseProgram(c_program); 1179 glDispatchCompute(1, 1, 1); 1180 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1181 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 1182 for (int i = 0; i < kSize * kSize; ++i) 1183 { 1184 if (!Equal(map_data[i], expected_value, internalformat)) 1185 { 1186 m_context.getTestContext().getLog() 1187 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str() 1188 << ". Value should be: " << ToString(expected_value).c_str() 1189 << ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "." 1190 << tcu::TestLog::EndMessage; 1191 glDeleteTextures(1, &texture); 1192 glUseProgram(0); 1193 glDeleteProgram(program); 1194 glDeleteProgram(c_program); 1195 glDeleteBuffers(1, &m_buffer); 1196 return false; 1197 } 1198 } 1199 glDeleteTextures(1, &texture); 1200 glUseProgram(0); 1201 glDeleteProgram(program); 1202 glDeleteProgram(c_program); 1203 glDeleteBuffers(1, &m_buffer); 1204 return true; 1205 } 1206 1207 virtual long Cleanup() 1208 { 1209 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 1210 glDeleteVertexArrays(1, &m_vao); 1211 glDeleteBuffers(1, &m_vbo); 1212 return NO_ERROR; 1213 } 1214 1215 template <typename T> 1216 std::string GenFS(GLenum internalformat, const T& value) 1217 { 1218 std::ostringstream os; 1219 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) writeonly uniform " 1220 << TypePrefix<T>() << "image2D g_image;" NL "void main() {" NL " ivec2 coord = ivec2(gl_FragCoord.xy);" NL 1221 " imageStore(g_image, coord, " 1222 << TypePrefix<T>() << "vec4" << value << ");" NL " discard;" NL "}"; 1223 return os.str(); 1224 } 1225 1226 template <typename T> 1227 std::string GenC(const T& value) 1228 { 1229 std::ostringstream os; 1230 os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform " 1231 << TypePrefix<T>() << "sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL " " 1232 << TypePrefix<T>() 1233 << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL 1234 " data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL 1235 " //data[gl_LocalInvocationIndex] = " 1236 << value << ";" NL "}"; 1237 return os.str(); 1238 } 1239 }; 1240 1241 class BasicAllFormatsStoreCS : public ShaderImageLoadStoreBase 1242 { 1243 virtual long Setup() 1244 { 1245 return NO_ERROR; 1246 } 1247 1248 template <typename T> 1249 std::string GenCS(GLenum internalformat, const T& value) 1250 { 1251 std::ostringstream os; 1252 os << NL "#define KSIZE 4" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform " 1253 << TypePrefix<T>() 1254 << "image2D g_image;" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "void main() {" NL 1255 " ivec2 thread_xy = ivec2(gl_LocalInvocationID);" NL " imageStore(g_image, thread_xy, " 1256 << TypePrefix<T>() << "vec4" << value << ");" NL "}"; 1257 return os.str(); 1258 } 1259 1260 template <typename T> 1261 std::string GenC(const T& value) 1262 { 1263 std::ostringstream os; 1264 os << NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform " 1265 << TypePrefix<T>() << "sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL " " 1266 << TypePrefix<T>() 1267 << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL 1268 " data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL 1269 " //data[gl_LocalInvocationIndex] = " 1270 << TypePrefix<T>() << "vec4" << value << ";" NL "}"; 1271 return os.str(); 1272 } 1273 1274 template <typename T> 1275 bool WriteCS(GLenum internalformat, const T& write_value, const T& expected_value) 1276 { 1277 const int kSize = 4; 1278 GLuint program = CreateComputeProgram(GenCS(internalformat, write_value)); 1279 1280 std::vector<T> data(kSize * kSize); 1281 GLuint texture; 1282 glGenTextures(1, &texture); 1283 1284 GLuint unit = 0; 1285 glBindTexture(GL_TEXTURE_2D, texture); 1286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1288 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 1289 glBindTexture(GL_TEXTURE_2D, 0); 1290 glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); 1291 glUseProgram(program); 1292 glDispatchCompute(1, 1, 1); 1293 1294 glBindTexture(GL_TEXTURE_2D, texture); 1295 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 1296 1297 GLuint c_program = CreateComputeProgram(GenC(expected_value)); 1298 std::vector<T> out_data(kSize * kSize); 1299 GLuint m_buffer; 1300 glGenBuffers(1, &m_buffer); 1301 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 1302 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW); 1303 1304 glUseProgram(c_program); 1305 glDispatchCompute(1, 1, 1); 1306 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1307 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 1308 for (int i = 0; i < kSize * kSize; ++i) 1309 { 1310 if (!Equal(map_data[i], expected_value, internalformat)) 1311 { 1312 m_context.getTestContext().getLog() 1313 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str() 1314 << ". Value should be: " << ToString(expected_value).c_str() 1315 << ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "." 1316 << tcu::TestLog::EndMessage; 1317 glDeleteTextures(1, &texture); 1318 glUseProgram(0); 1319 glDeleteProgram(program); 1320 glDeleteProgram(c_program); 1321 glDeleteBuffers(1, &m_buffer); 1322 return false; 1323 } 1324 } 1325 glDeleteTextures(1, &texture); 1326 glUseProgram(0); 1327 glDeleteProgram(program); 1328 glDeleteProgram(c_program); 1329 glDeleteBuffers(1, &m_buffer); 1330 1331 return true; 1332 } 1333 1334 virtual long Run() 1335 { 1336 1337 if (!WriteCS(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f))) 1338 return ERROR; 1339 if (!WriteCS(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f))) 1340 return ERROR; 1341 if (!WriteCS(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f))) 1342 return ERROR; 1343 1344 if (!WriteCS(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1345 return ERROR; 1346 if (!WriteCS(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1))) 1347 return ERROR; 1348 if (!WriteCS(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1349 return ERROR; 1350 if (!WriteCS(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1351 return ERROR; 1352 1353 if (!WriteCS(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 1354 return ERROR; 1355 if (!WriteCS(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1))) 1356 return ERROR; 1357 if (!WriteCS(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 1358 return ERROR; 1359 if (!WriteCS(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 1360 return ERROR; 1361 1362 if (!WriteCS(GL_RGBA8, vec4(1.0f), vec4(1.0f))) 1363 return ERROR; 1364 1365 if (!WriteCS(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f))) 1366 return ERROR; 1367 1368 return NO_ERROR; 1369 } 1370 1371 virtual long Cleanup() 1372 { 1373 return NO_ERROR; 1374 } 1375 }; 1376 //----------------------------------------------------------------------------- 1377 // 1.2.2 BasicAllFormatsLoad 1378 //----------------------------------------------------------------------------- 1379 class BasicAllFormatsLoadFS : public ShaderImageLoadStoreBase 1380 { 1381 GLuint m_vao, m_vbo; 1382 1383 virtual long Setup() 1384 { 1385 m_vao = 0; 1386 m_vbo = 0; 1387 return NO_ERROR; 1388 } 1389 1390 virtual long Run() 1391 { 1392 if (!IsVSFSAvailable(0, 1) || !IsSSBInVSFSAvailable(1)) 1393 return NOT_SUPPORTED; 1394 1395 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 1396 1397 if (!Read(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT)) 1398 return ERROR; 1399 if (!Read(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f), GL_RED, GL_FLOAT)) 1400 return ERROR; 1401 if (!Read(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT)) 1402 return ERROR; 1403 1404 if (!Read(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_INT)) 1405 return ERROR; 1406 if (!Read(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1), GL_RED_INTEGER, GL_INT)) 1407 return ERROR; 1408 if (!Read(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_SHORT)) 1409 return ERROR; 1410 if (!Read(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_BYTE)) 1411 return ERROR; 1412 1413 if (!Read(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 1414 return ERROR; 1415 if (!Read(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1), GL_RED_INTEGER, GL_UNSIGNED_INT)) 1416 return ERROR; 1417 if (!Read(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_SHORT)) 1418 return ERROR; 1419 if (!Read(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_BYTE)) 1420 return ERROR; 1421 1422 if (!Read(GL_RGBA8, vec4(1.0f), vec4(1.0f), GL_RGBA, GL_UNSIGNED_BYTE)) 1423 return ERROR; 1424 1425 if (!Read(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f), GL_RGBA, GL_BYTE)) 1426 return ERROR; 1427 1428 return NO_ERROR; 1429 } 1430 1431 template <typename T> 1432 bool Read(GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type) 1433 { 1434 const char* src_vs = 1435 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 1436 GLuint program = BuildProgram(src_vs, GenFS(internalformat, expected_value).c_str()); 1437 const int kSize = 11; 1438 ShortByteData<T> d(kSize, value, internalformat, format); 1439 GLuint texture; 1440 glGenTextures(1, &texture); 1441 GLuint unit = 1; 1442 glBindTexture(GL_TEXTURE_2D, texture); 1443 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1444 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1445 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 1446 if (Shorts(internalformat)) 1447 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datas[0]); 1448 else if (Bytes(internalformat)) 1449 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datab[0]); 1450 else 1451 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.data[0]); 1452 glBindTexture(GL_TEXTURE_2D, 0); 1453 1454 glViewport(0, 0, kSize, kSize); 1455 glClear(GL_COLOR_BUFFER_BIT); 1456 glUseProgram(program); 1457 glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); 1458 glBindVertexArray(m_vao); 1459 1460 std::vector<T> out_data(kSize * kSize); 1461 GLuint m_buffer; 1462 glGenBuffers(1, &m_buffer); 1463 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 1464 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW); 1465 1466 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 1467 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1468 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 1469 for (int i = 0; i < kSize * kSize; ++i) 1470 { 1471 if (!Equal(map_data[i], expected_value, internalformat)) 1472 { 1473 m_context.getTestContext().getLog() 1474 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str() 1475 << ". Value should be: " << ToString(expected_value).c_str() 1476 << ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "." 1477 << tcu::TestLog::EndMessage; 1478 glUseProgram(0); 1479 glDeleteProgram(program); 1480 glDeleteTextures(1, &texture); 1481 glDeleteBuffers(1, &m_buffer); 1482 return false; 1483 } 1484 } 1485 glUseProgram(0); 1486 glDeleteProgram(program); 1487 glDeleteTextures(1, &texture); 1488 glDeleteBuffers(1, &m_buffer); 1489 return true; 1490 } 1491 1492 virtual long Cleanup() 1493 { 1494 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 1495 glDeleteVertexArrays(1, &m_vao); 1496 glDeleteBuffers(1, &m_vbo); 1497 return NO_ERROR; 1498 } 1499 1500 template <typename T> 1501 std::string GenFS(GLenum internalformat, const T& expected_value) 1502 { 1503 std::ostringstream os; 1504 os << NL "#define KSIZE 11" NL "layout(" << FormatEnumToString(internalformat) 1505 << ", binding = 1) readonly uniform " << TypePrefix<T>() 1506 << "image2D g_image;" NL "layout(std430) buffer OutputBuffer {" NL " " << TypePrefix<T>() 1507 << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_FragCoord.xy);" NL " " 1508 << TypePrefix<T>() << "vec4 v = imageLoad(g_image, coord);" NL " data[coord.y * KSIZE + coord.x] = v;" NL 1509 " //data[coord.y * KSIZE + coord.x] = " 1510 << TypePrefix<T>() << "vec4" << expected_value << ";" NL " discard;" NL "}"; 1511 return os.str(); 1512 } 1513 }; 1514 1515 class BasicAllFormatsLoadCS : public ShaderImageLoadStoreBase 1516 { 1517 virtual long Setup() 1518 { 1519 return NO_ERROR; 1520 } 1521 1522 template <typename T> 1523 std::string GenCS(GLenum internalformat, const T& expected_value) 1524 { 1525 std::ostringstream os; 1526 os << NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "layout(" 1527 << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform " << TypePrefix<T>() 1528 << "image2D g_image;" NL "layout(std430) buffer OutputBuffer {" NL " " << TypePrefix<T>() 1529 << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 1530 " " 1531 << TypePrefix<T>() << "vec4 v = imageLoad(g_image, coord);" NL " data[gl_LocalInvocationIndex] = v;" NL 1532 " //data[gl_LocalInvocationIndex] = " 1533 << TypePrefix<T>() << "vec4" << expected_value << ";" NL "}"; 1534 return os.str(); 1535 } 1536 1537 virtual long Run() 1538 { 1539 if (!ReadCS(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT)) 1540 return ERROR; 1541 if (!ReadCS(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f), GL_RED, GL_FLOAT)) 1542 return ERROR; 1543 if (!ReadCS(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT)) 1544 return ERROR; 1545 1546 if (!ReadCS(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_INT)) 1547 return ERROR; 1548 if (!ReadCS(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1), GL_RED_INTEGER, GL_INT)) 1549 return ERROR; 1550 if (!ReadCS(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_SHORT)) 1551 return ERROR; 1552 if (!ReadCS(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_BYTE)) 1553 return ERROR; 1554 1555 if (!ReadCS(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 1556 return ERROR; 1557 if (!ReadCS(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1), GL_RED_INTEGER, GL_UNSIGNED_INT)) 1558 return ERROR; 1559 if (!ReadCS(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_SHORT)) 1560 return ERROR; 1561 if (!ReadCS(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_BYTE)) 1562 return ERROR; 1563 1564 if (!ReadCS(GL_RGBA8, vec4(1.0f), vec4(1.0f), GL_RGBA, GL_UNSIGNED_BYTE)) 1565 return ERROR; 1566 1567 if (!ReadCS(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f), GL_RGBA, GL_BYTE)) 1568 return ERROR; 1569 1570 return NO_ERROR; 1571 } 1572 1573 template <typename T> 1574 bool ReadCS(GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type) 1575 { 1576 GLuint program = CreateComputeProgram(GenCS(internalformat, expected_value)); 1577 const int kSize = 4; 1578 ShortByteData<T> d(kSize, value, internalformat, format); 1579 GLuint texture; 1580 glGenTextures(1, &texture); 1581 1582 GLuint unit = 1; 1583 glBindTexture(GL_TEXTURE_2D, texture); 1584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1586 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 1587 if (Shorts(internalformat)) 1588 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datas[0]); 1589 else if (Bytes(internalformat)) 1590 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datab[0]); 1591 else 1592 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.data[0]); 1593 glBindTexture(GL_TEXTURE_2D, 0); 1594 1595 glUseProgram(program); 1596 glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); 1597 1598 std::vector<T> out_data(kSize * kSize); 1599 GLuint m_buffer; 1600 glGenBuffers(1, &m_buffer); 1601 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 1602 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW); 1603 1604 glDispatchCompute(1, 1, 1); 1605 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1606 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 1607 for (int i = 0; i < kSize * kSize; ++i) 1608 { 1609 if (!Equal(map_data[i], expected_value, internalformat)) 1610 { 1611 m_context.getTestContext().getLog() 1612 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str() 1613 << ". Value should be: " << ToString(expected_value).c_str() 1614 << ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "." 1615 << tcu::TestLog::EndMessage; 1616 glUseProgram(0); 1617 glDeleteProgram(program); 1618 glDeleteTextures(1, &texture); 1619 glDeleteBuffers(1, &m_buffer); 1620 return false; 1621 } 1622 } 1623 glUseProgram(0); 1624 glDeleteProgram(program); 1625 glDeleteTextures(1, &texture); 1626 glDeleteBuffers(1, &m_buffer); 1627 return true; 1628 } 1629 1630 virtual long Cleanup() 1631 { 1632 return NO_ERROR; 1633 } 1634 }; 1635 1636 class BasicAllFormatsLoadStoreComputeStage : public ShaderImageLoadStoreBase 1637 { 1638 virtual long Run() 1639 { 1640 1641 if (!Read(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(2.0f, 4.0f, 6.0f, 8.0f), GL_RGBA, GL_FLOAT)) 1642 return ERROR; 1643 if (!Read(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(2.0f, 0.0f, 0.0f, 1.0f), GL_RED, GL_FLOAT)) 1644 return ERROR; 1645 if (!Read(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(2.0f, 4.0f, 6.0f, 8.0f), GL_RGBA, GL_FLOAT)) 1646 return ERROR; 1647 1648 if (!Read(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(2, -4, 6, -8), GL_RGBA_INTEGER, GL_INT)) 1649 return ERROR; 1650 if (!Read(GL_R32I, ivec4(1, -2, 3, -4), ivec4(2, 0, 0, 1), GL_RED_INTEGER, GL_INT)) 1651 return ERROR; 1652 if (!Read(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(2, -4, 6, -8), GL_RGBA_INTEGER, GL_SHORT)) 1653 return ERROR; 1654 if (!Read(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(2, -4, 6, -8), GL_RGBA_INTEGER, GL_BYTE)) 1655 return ERROR; 1656 1657 if (!Read(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 2, 4, 6), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 1658 return ERROR; 1659 if (!Read(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(14, 0, 0, 1), GL_RED_INTEGER, GL_UNSIGNED_INT)) 1660 return ERROR; 1661 if (!Read(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 2, 4, 6), GL_RGBA_INTEGER, GL_UNSIGNED_SHORT)) 1662 return ERROR; 1663 if (!Read(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 2, 4, 6), GL_RGBA_INTEGER, GL_UNSIGNED_BYTE)) 1664 return ERROR; 1665 1666 if (!Read(GL_RGBA8, vec4(0.5f), vec4(1.0f), GL_RGBA, GL_UNSIGNED_BYTE)) 1667 return ERROR; 1668 if (!Read(GL_RGBA8_SNORM, vec4(0.5f, 0.0f, 0.5f, -0.5f), vec4(1.0f, 0.0f, 1.0f, -1.0f), GL_RGBA, GL_BYTE)) 1669 return ERROR; 1670 1671 return NO_ERROR; 1672 } 1673 1674 template <typename T> 1675 bool Read(GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type) 1676 { 1677 GLuint program = CreateComputeProgram(GenCS(internalformat, expected_value)); 1678 1679 const int kSize = 8; 1680 ShortByteData<T> d(kSize, value, internalformat, format); 1681 GLuint texture[2]; 1682 glGenTextures(2, texture); 1683 1684 /* read texture */ 1685 { 1686 glBindTexture(GL_TEXTURE_2D, texture[0]); 1687 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1688 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1689 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 1690 if (Shorts(internalformat)) 1691 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datas[0]); 1692 else if (Bytes(internalformat)) 1693 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datab[0]); 1694 else 1695 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.data[0]); 1696 } 1697 /* write texture */ 1698 { 1699 glBindTexture(GL_TEXTURE_2D, texture[1]); 1700 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1701 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1702 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 1703 } 1704 glBindTexture(GL_TEXTURE_2D, 0); 1705 1706 glUseProgram(program); 1707 1708 glBindImageTexture(2, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); 1709 glBindImageTexture(3, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); 1710 1711 glDispatchCompute(1, 1, 1); 1712 1713 glBindTexture(GL_TEXTURE_2D, texture[1]); 1714 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 1715 1716 GLuint c_program = CreateComputeProgram(GenC(expected_value)); 1717 std::vector<T> out_data(kSize * kSize); 1718 GLuint m_buffer; 1719 glGenBuffers(1, &m_buffer); 1720 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 1721 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW); 1722 1723 glUseProgram(c_program); 1724 glDispatchCompute(1, 1, 1); 1725 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1726 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 1727 for (int i = 0; i < kSize * kSize; ++i) 1728 { 1729 if (!Equal(map_data[i], expected_value, internalformat)) 1730 { 1731 m_context.getTestContext().getLog() 1732 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str() 1733 << ". Value should be: " << ToString(expected_value).c_str() 1734 << ". Format is: " << FormatEnumToString(internalformat).c_str() << "." << tcu::TestLog::EndMessage; 1735 glDeleteTextures(2, texture); 1736 glUseProgram(0); 1737 glDeleteProgram(program); 1738 glDeleteProgram(c_program); 1739 glDeleteBuffers(1, &m_buffer); 1740 return false; 1741 } 1742 } 1743 glDeleteTextures(2, texture); 1744 glUseProgram(0); 1745 glDeleteProgram(program); 1746 glDeleteProgram(c_program); 1747 glDeleteBuffers(1, &m_buffer); 1748 1749 return true; 1750 } 1751 1752 template <typename T> 1753 std::string GenCS(GLenum internalformat, const T& expected_value) 1754 { 1755 std::ostringstream os; 1756 os << NL "#define KSIZE 8" NL "layout(local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "layout(" 1757 << FormatEnumToString(internalformat) << ", binding = 2) readonly uniform " << TypePrefix<T>() 1758 << "image2D g_image_read;" NL "layout(" << FormatEnumToString(internalformat) 1759 << ", binding = 3) writeonly uniform " << TypePrefix<T>() 1760 << "image2D g_image_write;" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL " " 1761 << TypePrefix<T>() << "vec4 v = imageLoad(g_image_read, coord);" NL 1762 " imageStore(g_image_write, coord, v+v);" NL " //imageStore(g_image_write, coord, " 1763 << TypePrefix<T>() << "vec4" << expected_value << ");" NL "}"; 1764 return os.str(); 1765 } 1766 1767 template <typename T> 1768 std::string GenC(const T& value) 1769 { 1770 std::ostringstream os; 1771 os << NL "#define KSIZE 8" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform " 1772 << TypePrefix<T>() << "sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL " " 1773 << TypePrefix<T>() 1774 << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL 1775 " data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL 1776 " //data[gl_LocalInvocationIndex] = " 1777 << TypePrefix<T>() << "vec4" << value << ";" NL "}"; 1778 return os.str(); 1779 } 1780 }; 1781 //----------------------------------------------------------------------------- 1782 // 1.3.1 BasicAllTargetsStore 1783 //----------------------------------------------------------------------------- 1784 class BasicAllTargetsStoreFS : public ShaderImageLoadStoreBase 1785 { 1786 GLuint m_vao; 1787 GLuint m_vbo; 1788 1789 virtual long Setup() 1790 { 1791 m_vao = 0; 1792 m_vbo = 0; 1793 return NO_ERROR; 1794 } 1795 1796 virtual long Run() 1797 { 1798 if (!IsVSFSAvailable(0, 4)) 1799 return NOT_SUPPORTED; 1800 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 1801 1802 if (!Write(T2D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 1803 return ERROR; 1804 if (!Write(T2D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1805 return ERROR; 1806 if (!Write(T2D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 1807 return ERROR; 1808 if (!Write(T3D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 1809 return ERROR; 1810 if (!Write(T3D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1811 return ERROR; 1812 if (!Write(T3D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 1813 return ERROR; 1814 if (!Write(TCM, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 1815 return ERROR; 1816 if (!Write(TCM, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1817 return ERROR; 1818 if (!Write(TCM, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 1819 return ERROR; 1820 if (!Write(T2DA, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 1821 return ERROR; 1822 if (!Write(T2DA, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 1823 return ERROR; 1824 if (!Write(T2DA, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 1825 return ERROR; 1826 1827 return NO_ERROR; 1828 } 1829 1830 virtual long Cleanup() 1831 { 1832 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 1833 glDeleteVertexArrays(1, &m_vao); 1834 glDeleteBuffers(1, &m_vbo); 1835 glActiveTexture(GL_TEXTURE0); 1836 return NO_ERROR; 1837 } 1838 1839 template <typename T> 1840 bool Write(int target, GLenum internalformat, const T& write_value, const T& expected_value) 1841 { 1842 const char* src_vs = 1843 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 1844 const GLuint program = BuildProgram(src_vs, GenFS(target, internalformat, write_value).c_str()); 1845 GLuint textures[8]; 1846 glGenTextures(8, textures); 1847 1848 const int kSize = 11; 1849 std::vector<T> data(kSize * kSize * 2); 1850 1851 glBindTexture(GL_TEXTURE_2D, textures[1]); 1852 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1854 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 1855 glBindTexture(GL_TEXTURE_2D, 0); 1856 1857 glBindTexture(GL_TEXTURE_3D, textures[2]); 1858 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1859 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1860 glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2); 1861 glBindTexture(GL_TEXTURE_3D, 0); 1862 1863 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]); 1864 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1865 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1866 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize); 1867 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 1868 1869 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]); 1870 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1871 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1872 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2); 1873 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 1874 1875 glBindImageTexture(0, textures[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); // 2D 1876 glBindImageTexture(1, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // 3D 1877 glBindImageTexture(2, textures[4], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // Cube 1878 glBindImageTexture(3, textures[7], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // 2DArray 1879 1880 glUseProgram(program); 1881 glBindVertexArray(m_vao); 1882 glViewport(0, 0, kSize, kSize); 1883 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 1884 1885 glActiveTexture(GL_TEXTURE1); 1886 glBindTexture(GL_TEXTURE_2D, textures[1]); 1887 glActiveTexture(GL_TEXTURE2); 1888 glBindTexture(GL_TEXTURE_3D, textures[2]); 1889 glActiveTexture(GL_TEXTURE3); 1890 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]); 1891 glActiveTexture(GL_TEXTURE4); 1892 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]); 1893 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 1894 1895 GLuint c_program = CreateComputeProgram(GenC(write_value)); 1896 std::vector<T> out_data2D(kSize * kSize * 6); 1897 std::vector<T> out_data3D(kSize * kSize * 6); 1898 std::vector<T> out_dataCube(kSize * kSize * 6); 1899 std::vector<T> out_data2DArray(kSize * kSize * 6); 1900 GLuint m_buffer[4]; 1901 glGenBuffers(4, m_buffer); 1902 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[0]); 1903 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 1904 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]); 1905 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 1906 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[2]); 1907 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 1908 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]); 1909 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 1910 1911 glUseProgram(c_program); 1912 glUniform1i(glGetUniformLocation(c_program, "g_sampler_2d"), 1); 1913 glUniform1i(glGetUniformLocation(c_program, "g_sampler_3d"), 2); 1914 glUniform1i(glGetUniformLocation(c_program, "g_sampler_cube"), 3); 1915 glUniform1i(glGetUniformLocation(c_program, "g_sampler_2darray"), 4); 1916 glDispatchCompute(1, 1, 1); 1917 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1918 1919 bool status = true; 1920 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]); 1921 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 1922 int layers = 2; 1923 if (target == T2D) 1924 layers = 1; 1925 if (target == TCM) 1926 layers = 6; 1927 status = CompareValues(map_data, kSize, expected_value, internalformat, layers); 1928 if (!status) 1929 m_context.getTestContext().getLog() 1930 << tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str() 1931 << " format failed." << tcu::TestLog::EndMessage; 1932 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 1933 1934 glDeleteTextures(8, textures); 1935 glUseProgram(0); 1936 glDeleteProgram(program); 1937 glDeleteProgram(c_program); 1938 glDeleteBuffers(4, m_buffer); 1939 1940 return status; 1941 } 1942 1943 template <typename T> 1944 std::string GenFS(int target, GLenum internalformat, const T& write_value) 1945 { 1946 std::ostringstream os; 1947 switch (target) 1948 { 1949 case T2D: 1950 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) writeonly uniform " 1951 << TypePrefix<T>() << "image2D g_image_2d;"; 1952 break; 1953 case T3D: 1954 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) writeonly uniform " 1955 << TypePrefix<T>() << "image3D g_image_3d;"; 1956 break; 1957 case TCM: 1958 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) writeonly uniform " 1959 << TypePrefix<T>() << "imageCube g_image_cube;"; 1960 break; 1961 case T2DA: 1962 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) writeonly uniform " 1963 << TypePrefix<T>() << "image2DArray g_image_2darray;"; 1964 break; 1965 } 1966 os << NL "void main() {" NL " ivec2 coord = ivec2(gl_FragCoord.xy);"; 1967 1968 switch (target) 1969 { 1970 case T2D: 1971 os << NL " imageStore(g_image_2d, coord, " << TypePrefix<T>() << "vec4" << write_value << ");"; 1972 break; 1973 case T3D: 1974 os << NL " imageStore(g_image_3d, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value 1975 << ");" NL " imageStore(g_image_3d, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value 1976 << ");"; 1977 break; 1978 case TCM: 1979 os << NL " imageStore(g_image_cube, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value 1980 << ");" NL " imageStore(g_image_cube, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value 1981 << ");" NL " imageStore(g_image_cube, ivec3(coord, 2), " << TypePrefix<T>() << "vec4" << write_value 1982 << ");" NL " imageStore(g_image_cube, ivec3(coord, 3), " << TypePrefix<T>() << "vec4" << write_value 1983 << ");" NL " imageStore(g_image_cube, ivec3(coord, 4), " << TypePrefix<T>() << "vec4" << write_value 1984 << ");" NL " imageStore(g_image_cube, ivec3(coord, 5), " << TypePrefix<T>() << "vec4" << write_value 1985 << ");"; 1986 break; 1987 case T2DA: 1988 os << NL " imageStore(g_image_2darray, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value 1989 << ");" NL " imageStore(g_image_2darray, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value 1990 << ");"; 1991 break; 1992 } 1993 os << NL " discard;" NL "}"; 1994 return os.str(); 1995 } 1996 1997 template <typename T> 1998 std::string GenC(const T& write_value) 1999 { 2000 std::ostringstream os; 2001 os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform " 2002 << TypePrefix<T>() << "sampler2D g_sampler_2d;" NL "uniform " << TypePrefix<T>() 2003 << "sampler3D g_sampler_3d;" NL "uniform " << TypePrefix<T>() << "samplerCube g_sampler_cube;" NL "uniform " 2004 << TypePrefix<T>() 2005 << "sampler2DArray g_sampler_2darray;" NL "layout(std430, binding = 1) buffer OutputBuffer2D {" NL " " 2006 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;" NL 2007 "layout(std430, binding = 0) buffer OutputBuffer3D {" NL " " 2008 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;" NL 2009 "layout(std430, binding = 3) buffer OutputBufferCube {" NL " " 2010 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;" NL 2011 "layout(std430, binding = 2) buffer OutputBuffer2DArray {" NL " " 2012 << TypePrefix<T>() 2013 << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;" NL "void main() {" NL 2014 " int cubemap_i = 2 * int(gl_LocalInvocationID.x) - KSIZE + 1;" NL 2015 " int cubemap_j = 2 * int(gl_LocalInvocationID.y) - KSIZE + 1;" NL 2016 " uint layer = uint(KSIZE * KSIZE);" NL 2017 " g_buff_2d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_2d, ivec2(gl_LocalInvocationID), 0);" NL 2018 " g_buff_3d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_3d, ivec3(gl_LocalInvocationID.xy, 0), " 2019 "0);" NL " g_buff_3d.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_3d, " 2020 "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL " g_buff_2darray.data[gl_LocalInvocationIndex] = " 2021 "texelFetch(g_sampler_2darray, " 2022 "ivec3(gl_LocalInvocationID.xy, 0), 0);" NL 2023 " g_buff_2darray.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_2darray, " 2024 "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL " g_buff_cube.data[gl_LocalInvocationIndex] = " 2025 "texture(g_sampler_cube, vec3(KSIZE,cubemap_i,cubemap_j));" NL 2026 " g_buff_cube.data[gl_LocalInvocationIndex + layer] = texture(g_sampler_cube, " 2027 "vec3(KSIZE,cubemap_i,cubemap_j));" NL " g_buff_cube.data[gl_LocalInvocationIndex + 2u * layer] = " 2028 "texture(g_sampler_cube, vec3(cubemap_i,KSIZE,cubemap_j));" NL 2029 " g_buff_cube.data[gl_LocalInvocationIndex + 3u * layer] = texture(g_sampler_cube, " 2030 "vec3(cubemap_i,KSIZE,cubemap_j));" NL " g_buff_cube.data[gl_LocalInvocationIndex + 4u * layer] = " 2031 "texture(g_sampler_cube, vec3(cubemap_i,cubemap_j,KSIZE));" NL 2032 " g_buff_cube.data[gl_LocalInvocationIndex + 5u * layer] = texture(g_sampler_cube, " 2033 "vec3(cubemap_i,cubemap_j,KSIZE));" NL " //g_buff_2d.data[gl_LocalInvocationIndex] = " 2034 << write_value << ";" NL "}"; 2035 return os.str(); 2036 } 2037 }; 2038 2039 class BasicAllTargetsStoreCS : public ShaderImageLoadStoreBase 2040 { 2041 virtual long Setup() 2042 { 2043 return NO_ERROR; 2044 } 2045 2046 virtual long Run() 2047 { 2048 2049 if (!Write(T2D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 2050 return ERROR; 2051 if (!Write(T2D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 2052 return ERROR; 2053 if (!Write(T2D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 2054 return ERROR; 2055 if (!Write(T3D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 2056 return ERROR; 2057 if (!Write(T3D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 2058 return ERROR; 2059 if (!Write(T3D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 2060 return ERROR; 2061 if (!Write(TCM, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 2062 return ERROR; 2063 if (!Write(TCM, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 2064 return ERROR; 2065 if (!Write(TCM, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 2066 return ERROR; 2067 if (!Write(T2DA, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f))) 2068 return ERROR; 2069 if (!Write(T2DA, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 2070 return ERROR; 2071 if (!Write(T2DA, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4))) 2072 return ERROR; 2073 2074 return NO_ERROR; 2075 } 2076 2077 virtual long Cleanup() 2078 { 2079 glActiveTexture(GL_TEXTURE0); 2080 return NO_ERROR; 2081 } 2082 2083 template <typename T> 2084 bool Write(int target, GLenum internalformat, const T& write_value, const T& expected_value) 2085 { 2086 const GLuint program = CreateComputeProgram(GenCS(target, internalformat, write_value)); 2087 GLuint textures[8]; 2088 glGenTextures(8, textures); 2089 2090 const int kSize = 11; 2091 std::vector<T> data(kSize * kSize * 2); 2092 2093 glBindTexture(GL_TEXTURE_2D, textures[1]); 2094 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2096 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 2097 glBindTexture(GL_TEXTURE_2D, 0); 2098 2099 glBindTexture(GL_TEXTURE_3D, textures[2]); 2100 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2101 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2102 glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2); 2103 glBindTexture(GL_TEXTURE_3D, 0); 2104 2105 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]); 2106 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2107 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2108 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize); 2109 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 2110 2111 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]); 2112 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2113 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2114 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2); 2115 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 2116 2117 glBindImageTexture(0, textures[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); // 2D 2118 glBindImageTexture(1, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // 3D 2119 glBindImageTexture(2, textures[4], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // Cube 2120 glBindImageTexture(3, textures[7], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // 2DArray 2121 2122 glUseProgram(program); 2123 glDispatchCompute(1, 1, 1); 2124 2125 glActiveTexture(GL_TEXTURE1); 2126 glBindTexture(GL_TEXTURE_2D, textures[1]); 2127 glActiveTexture(GL_TEXTURE2); 2128 glBindTexture(GL_TEXTURE_3D, textures[2]); 2129 glActiveTexture(GL_TEXTURE3); 2130 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]); 2131 glActiveTexture(GL_TEXTURE4); 2132 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]); 2133 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 2134 2135 GLuint c_program = CreateComputeProgram(GenC(write_value)); 2136 std::vector<T> out_data2D(kSize * kSize * 6); 2137 std::vector<T> out_data3D(kSize * kSize * 6); 2138 std::vector<T> out_dataCube(kSize * kSize * 6); 2139 std::vector<T> out_data2DArray(kSize * kSize * 6); 2140 GLuint m_buffer[4]; 2141 glGenBuffers(4, m_buffer); 2142 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]); 2143 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2144 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]); 2145 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2146 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[2]); 2147 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2148 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[3]); 2149 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2150 2151 glUseProgram(c_program); 2152 glUniform1i(glGetUniformLocation(c_program, "g_sampler_2d"), 1); 2153 glUniform1i(glGetUniformLocation(c_program, "g_sampler_3d"), 2); 2154 glUniform1i(glGetUniformLocation(c_program, "g_sampler_cube"), 3); 2155 glUniform1i(glGetUniformLocation(c_program, "g_sampler_2darray"), 4); 2156 2157 glDispatchCompute(1, 1, 1); 2158 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 2159 2160 bool status = true; 2161 2162 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]); 2163 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 2164 int layers = 2; 2165 if (target == T2D) 2166 layers = 1; 2167 if (target == TCM) 2168 layers = 6; 2169 status = CompareValues(map_data, kSize, expected_value, internalformat, layers); 2170 if (!status) 2171 m_context.getTestContext().getLog() 2172 << tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str() 2173 << " format failed." << tcu::TestLog::EndMessage; 2174 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 2175 2176 glDeleteTextures(8, textures); 2177 glUseProgram(0); 2178 glDeleteProgram(program); 2179 glDeleteProgram(c_program); 2180 glDeleteBuffers(4, m_buffer); 2181 2182 return status; 2183 } 2184 2185 template <typename T> 2186 std::string GenCS(int target, GLenum internalformat, const T& write_value) 2187 { 2188 std::ostringstream os; 2189 os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;"; 2190 switch (target) 2191 { 2192 case T2D: 2193 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) writeonly uniform " 2194 << TypePrefix<T>() << "image2D g_image_2d;"; 2195 break; 2196 case T3D: 2197 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) writeonly uniform " 2198 << TypePrefix<T>() << "image3D g_image_3d;"; 2199 break; 2200 case TCM: 2201 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) writeonly uniform " 2202 << TypePrefix<T>() << "imageCube g_image_cube;"; 2203 break; 2204 case T2DA: 2205 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) writeonly uniform " 2206 << TypePrefix<T>() << "image2DArray g_image_2darray;"; 2207 break; 2208 } 2209 os << NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);"; 2210 switch (target) 2211 { 2212 case T2D: 2213 os << NL " imageStore(g_image_2d, coord, " << TypePrefix<T>() << "vec4" << write_value << ");"; 2214 break; 2215 case T3D: 2216 os << NL " imageStore(g_image_3d, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value 2217 << ");" NL " imageStore(g_image_3d, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value 2218 << ");"; 2219 break; 2220 case TCM: 2221 os << NL " imageStore(g_image_cube, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value 2222 << ");" NL " imageStore(g_image_cube, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value 2223 << ");" NL " imageStore(g_image_cube, ivec3(coord, 2), " << TypePrefix<T>() << "vec4" << write_value 2224 << ");" NL " imageStore(g_image_cube, ivec3(coord, 3), " << TypePrefix<T>() << "vec4" << write_value 2225 << ");" NL " imageStore(g_image_cube, ivec3(coord, 4), " << TypePrefix<T>() << "vec4" << write_value 2226 << ");" NL " imageStore(g_image_cube, ivec3(coord, 5), " << TypePrefix<T>() << "vec4" << write_value 2227 << ");"; 2228 break; 2229 case T2DA: 2230 os << NL " imageStore(g_image_2darray, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value 2231 << ");" NL " imageStore(g_image_2darray, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value 2232 << ");"; 2233 break; 2234 } 2235 os << NL "}"; 2236 return os.str(); 2237 } 2238 2239 template <typename T> 2240 std::string GenC(const T& write_value) 2241 { 2242 std::ostringstream os; 2243 os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform " 2244 << TypePrefix<T>() << "sampler2D g_sampler_2d;" NL "uniform " << TypePrefix<T>() 2245 << "sampler3D g_sampler_3d;" NL "uniform " << TypePrefix<T>() << "samplerCube g_sampler_cube;" NL "uniform " 2246 << TypePrefix<T>() 2247 << "sampler2DArray g_sampler_2darray;" NL "layout(std430, binding = 0) buffer OutputBuffer2D {" NL " " 2248 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;" NL 2249 "layout(std430, binding = 1) buffer OutputBuffer3D {" NL " " 2250 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;" NL 2251 "layout(std430, binding = 2) buffer OutputBufferCube {" NL " " 2252 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;" NL 2253 "layout(std430, binding = 3) buffer OutputBuffer2DArray {" NL " " 2254 << TypePrefix<T>() 2255 << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;" NL "void main() {" NL 2256 " int cubemap_i = 2 * int(gl_LocalInvocationID.x) - KSIZE + 1;" NL 2257 " int cubemap_j = 2 * int(gl_LocalInvocationID.y) - KSIZE + 1;" NL 2258 " uint layer = uint(KSIZE * KSIZE);" NL 2259 " g_buff_2d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_2d, ivec2(gl_LocalInvocationID), 0);" NL 2260 " g_buff_3d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_3d, ivec3(gl_LocalInvocationID.xy, 0), " 2261 "0);" NL " g_buff_3d.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_3d, " 2262 "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL " g_buff_2darray.data[gl_LocalInvocationIndex] = " 2263 "texelFetch(g_sampler_2darray, " 2264 "ivec3(gl_LocalInvocationID.xy, 0), 0);" NL 2265 " g_buff_2darray.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_2darray, " 2266 "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL " g_buff_cube.data[gl_LocalInvocationIndex] = " 2267 "texture(g_sampler_cube, vec3(KSIZE,cubemap_i,cubemap_j));" NL 2268 " g_buff_cube.data[gl_LocalInvocationIndex + layer] = texture(g_sampler_cube, " 2269 "vec3(KSIZE,cubemap_i,cubemap_j));" NL " g_buff_cube.data[gl_LocalInvocationIndex + 2u * layer] = " 2270 "texture(g_sampler_cube, vec3(cubemap_i,KSIZE,cubemap_j));" NL 2271 " g_buff_cube.data[gl_LocalInvocationIndex + 3u * layer] = texture(g_sampler_cube, " 2272 "vec3(cubemap_i,KSIZE,cubemap_j));" NL " g_buff_cube.data[gl_LocalInvocationIndex + 4u * layer] = " 2273 "texture(g_sampler_cube, vec3(cubemap_i,cubemap_j,KSIZE));" NL 2274 " g_buff_cube.data[gl_LocalInvocationIndex + 5u * layer] = texture(g_sampler_cube, " 2275 "vec3(cubemap_i,cubemap_j,KSIZE));" NL " //g_buff_2d.data[gl_LocalInvocationIndex] = " 2276 << write_value << ";" NL "}"; 2277 return os.str(); 2278 } 2279 }; 2280 //----------------------------------------------------------------------------- 2281 // 1.3.2.1 BasicAllTargetsLoad 2282 //----------------------------------------------------------------------------- 2283 class BasicAllTargetsLoadFS : public ShaderImageLoadStoreBase 2284 { 2285 GLuint m_vao; 2286 GLuint m_vbo; 2287 2288 virtual long Setup() 2289 { 2290 m_vao = 0; 2291 m_vbo = 0; 2292 return NO_ERROR; 2293 } 2294 2295 virtual long Run() 2296 { 2297 if (!IsVSFSAvailable(0, 4) || !IsSSBInVSFSAvailable(4)) 2298 return NOT_SUPPORTED; 2299 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 2300 2301 if (!Read(T2D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2302 GL_FLOAT)) 2303 return ERROR; 2304 if (!Read(T2D, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2305 return ERROR; 2306 if (!Read(T2D, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 2307 return ERROR; 2308 if (!Read(T3D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2309 GL_FLOAT)) 2310 return ERROR; 2311 if (!Read(T3D, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2312 return ERROR; 2313 if (!Read(T3D, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 2314 return ERROR; 2315 if (!Read(TCM, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2316 GL_FLOAT)) 2317 return ERROR; 2318 if (!Read(TCM, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2319 return ERROR; 2320 if (!Read(TCM, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 2321 return ERROR; 2322 if (!Read(T2DA, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2323 GL_FLOAT)) 2324 return ERROR; 2325 if (!Read(T2DA, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2326 return ERROR; 2327 if (!Read(T2DA, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER, 2328 GL_UNSIGNED_INT)) 2329 return ERROR; 2330 2331 return NO_ERROR; 2332 } 2333 2334 virtual long Cleanup() 2335 { 2336 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 2337 glDeleteVertexArrays(1, &m_vao); 2338 glDeleteBuffers(1, &m_vbo); 2339 return NO_ERROR; 2340 } 2341 2342 template <typename T> 2343 bool Read(int target, GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type) 2344 { 2345 const char* src_vs = 2346 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 2347 const GLuint program = BuildProgram(src_vs, GenFS(target, internalformat, expected_value).c_str()); 2348 GLuint textures[8]; 2349 glGenTextures(8, textures); 2350 2351 const int kSize = 11; 2352 std::vector<T> data(kSize * kSize * 2, value); 2353 2354 glBindTexture(GL_TEXTURE_2D, textures[1]); 2355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2356 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2357 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 2358 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2359 glBindTexture(GL_TEXTURE_2D, 0); 2360 2361 glBindTexture(GL_TEXTURE_3D, textures[2]); 2362 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2363 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2364 glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2); 2365 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]); 2366 glBindTexture(GL_TEXTURE_3D, 0); 2367 2368 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]); 2369 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2370 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2371 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize); 2372 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2373 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2374 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2375 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2376 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2377 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2378 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 2379 2380 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]); 2381 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2382 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2383 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2); 2384 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]); 2385 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 2386 2387 glBindImageTexture(2, textures[1], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); // 2D 2388 glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // 3D 2389 glBindImageTexture(3, textures[4], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // Cube 2390 glBindImageTexture(1, textures[7], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // 2DArray 2391 2392 std::vector<T> out_data2D(kSize * kSize * 6); 2393 std::vector<T> out_data3D(kSize * kSize * 6); 2394 std::vector<T> out_dataCube(kSize * kSize * 6); 2395 std::vector<T> out_data2DArray(kSize * kSize * 6); 2396 GLuint m_buffer[4]; 2397 glGenBuffers(4, m_buffer); 2398 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[0]); 2399 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2400 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]); 2401 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2402 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[2]); 2403 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2404 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]); 2405 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2406 2407 glUseProgram(program); 2408 glClear(GL_COLOR_BUFFER_BIT); 2409 glBindVertexArray(m_vao); 2410 glViewport(0, 0, kSize, kSize); 2411 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 2412 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 2413 2414 bool status = true; 2415 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]); 2416 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 2417 int layers = 2; 2418 if (target == T2D) 2419 layers = 1; 2420 if (target == TCM) 2421 layers = 6; 2422 status = CompareValues(map_data, kSize, expected_value, internalformat, layers); 2423 if (!status) 2424 m_context.getTestContext().getLog() 2425 << tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str() 2426 << " format failed." << tcu::TestLog::EndMessage; 2427 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 2428 2429 glUseProgram(0); 2430 glDeleteProgram(program); 2431 glDeleteTextures(8, textures); 2432 glDeleteBuffers(4, m_buffer); 2433 2434 return status; 2435 } 2436 2437 template <typename T> 2438 std::string GenFS(int target, GLenum internalformat, const T& expected_value) 2439 { 2440 std::ostringstream os; 2441 os << NL "#define KSIZE 11"; 2442 switch (target) 2443 { 2444 case T2D: 2445 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) readonly uniform " 2446 << TypePrefix<T>() 2447 << "image2D g_image_2d;" NL "layout(std430, binding = 1) buffer OutputBuffer2D {" NL " " 2448 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;"; 2449 break; 2450 case T3D: 2451 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) readonly uniform " 2452 << TypePrefix<T>() 2453 << "image3D g_image_3d;" NL "layout(std430, binding = 0) buffer OutputBuffer3D {" NL " " 2454 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;"; 2455 break; 2456 case TCM: 2457 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) readonly uniform " 2458 << TypePrefix<T>() 2459 << "imageCube g_image_cube;" NL "layout(std430, binding = 3) buffer OutputBufferCube {" NL " " 2460 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;"; 2461 break; 2462 case T2DA: 2463 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform " 2464 << TypePrefix<T>() 2465 << "image2DArray g_image_2darray;" NL "layout(std430, binding = 2) buffer OutputBuffer2DArray {" NL " " 2466 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;"; 2467 break; 2468 } 2469 os << NL "void main() {" NL " ivec2 coord = ivec2(gl_FragCoord.xy);" NL 2470 " int coordIndex = coord.x + KSIZE * coord.y;" NL " int layer = int(KSIZE * KSIZE);" NL " " 2471 << TypePrefix<T>() << "vec4 v;"; 2472 2473 switch (target) 2474 { 2475 case T2D: 2476 os << NL " v = imageLoad(g_image_2d, coord);" NL " g_buff_2d.data[coordIndex] = v;"; 2477 break; 2478 case T3D: 2479 os << NL " v = imageLoad(g_image_3d, ivec3(coord.xy, 0));" NL " g_buff_3d.data[coordIndex] = v;" NL 2480 " v = imageLoad(g_image_3d, ivec3(coord.xy, 1));" NL " g_buff_3d.data[coordIndex + layer] = v;"; 2481 break; 2482 case TCM: 2483 os << NL 2484 " v = imageLoad(g_image_cube, ivec3(coord, 0));" NL " g_buff_cube.data[coordIndex] = v;" NL 2485 " v = imageLoad(g_image_cube, ivec3(coord, 1));" NL " g_buff_cube.data[coordIndex + layer] = v;" NL 2486 " v = imageLoad(g_image_cube, ivec3(coord, 2));" NL 2487 " g_buff_cube.data[coordIndex + 2 * layer] = v;" NL 2488 " v = imageLoad(g_image_cube, ivec3(coord, 3));" NL 2489 " g_buff_cube.data[coordIndex + 3 * layer] = v;" NL 2490 " v = imageLoad(g_image_cube, ivec3(coord, 4));" NL 2491 " g_buff_cube.data[coordIndex + 4 * layer] = v;" NL 2492 " v = imageLoad(g_image_cube, ivec3(coord, 5));" NL " g_buff_cube.data[coordIndex + 5 * layer] = v;"; 2493 break; 2494 case T2DA: 2495 os << NL " v = imageLoad(g_image_2darray, ivec3(coord, 0));" NL " g_buff_2darray.data[coordIndex] = v;" NL 2496 " v = imageLoad(g_image_2darray, ivec3(coord, 1));" NL 2497 " g_buff_2darray.data[coordIndex + layer] = v;"; 2498 break; 2499 } 2500 os << NL " //g_buff_2d.data[coordIndex] = " << expected_value << ";" NL "}"; 2501 return os.str(); 2502 } 2503 }; 2504 2505 class BasicAllTargetsLoadCS : public ShaderImageLoadStoreBase 2506 { 2507 virtual long Setup() 2508 { 2509 return NO_ERROR; 2510 } 2511 2512 virtual long Run() 2513 { 2514 if (!Read(T2D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2515 GL_FLOAT)) 2516 return ERROR; 2517 if (!Read(T2D, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), 2518 ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2519 return ERROR; 2520 if (!Read(T2D, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), 2521 uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 2522 return ERROR; 2523 if (!Read(T3D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2524 GL_FLOAT)) 2525 return ERROR; 2526 if (!Read(T3D, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), 2527 ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2528 return ERROR; 2529 if (!Read(T3D, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), 2530 uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 2531 return ERROR; 2532 if (!Read(TCM, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2533 GL_FLOAT)) 2534 return ERROR; 2535 if (!Read(TCM, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), 2536 ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2537 return ERROR; 2538 if (!Read(TCM, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), 2539 uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 2540 return ERROR; 2541 if (!Read(T2DA, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA, 2542 GL_FLOAT)) 2543 return ERROR; 2544 if (!Read(T2DA, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), 2545 ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT)) 2546 return ERROR; 2547 if (!Read(T2DA, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), 2548 uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT)) 2549 return ERROR; 2550 2551 return NO_ERROR; 2552 } 2553 2554 virtual long Cleanup() 2555 { 2556 return NO_ERROR; 2557 } 2558 2559 template <typename T> 2560 bool Read(int target, GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type) 2561 { 2562 const GLuint program = CreateComputeProgram(GenCS(target, internalformat, expected_value)); 2563 GLuint textures[8]; 2564 glGenTextures(8, textures); 2565 2566 const int kSize = 11; 2567 std::vector<T> data(kSize * kSize * 2, value); 2568 2569 glBindTexture(GL_TEXTURE_2D, textures[1]); 2570 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2572 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 2573 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2574 glBindTexture(GL_TEXTURE_2D, 0); 2575 2576 glBindTexture(GL_TEXTURE_3D, textures[2]); 2577 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2578 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2579 glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2); 2580 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]); 2581 glBindTexture(GL_TEXTURE_3D, 0); 2582 2583 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]); 2584 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2585 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2586 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize); 2587 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2588 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2589 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2590 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2591 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2592 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]); 2593 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 2594 2595 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]); 2596 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2597 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2598 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2); 2599 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]); 2600 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 2601 2602 glBindImageTexture(2, textures[1], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); // 2D 2603 glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // 3D 2604 glBindImageTexture(3, textures[4], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // Cube 2605 glBindImageTexture(1, textures[7], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // 2DArray 2606 2607 std::vector<T> out_data2D(kSize * kSize * 6); 2608 std::vector<T> out_data3D(kSize * kSize * 6); 2609 std::vector<T> out_dataCube(kSize * kSize * 6); 2610 std::vector<T> out_data2DArray(kSize * kSize * 6); 2611 GLuint m_buffer[4]; 2612 glGenBuffers(4, m_buffer); 2613 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]); 2614 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2615 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]); 2616 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2617 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[2]); 2618 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2619 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[3]); 2620 glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW); 2621 2622 glUseProgram(program); 2623 glDispatchCompute(1, 1, 1); 2624 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 2625 2626 bool status = true; 2627 2628 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]); 2629 T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 2630 int layers = 2; 2631 if (target == T2D) 2632 layers = 1; 2633 if (target == TCM) 2634 layers = 6; 2635 status = CompareValues(map_data, kSize, expected_value, internalformat, layers); 2636 if (!status) 2637 m_context.getTestContext().getLog() 2638 << tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str() 2639 << " format failed." << tcu::TestLog::EndMessage; 2640 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 2641 2642 glUseProgram(0); 2643 glDeleteProgram(program); 2644 glDeleteTextures(8, textures); 2645 glDeleteBuffers(4, m_buffer); 2646 2647 return status; 2648 } 2649 2650 template <typename T> 2651 std::string GenCS(int target, GLenum internalformat, const T& expected_value) 2652 { 2653 std::ostringstream os; 2654 os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;"; 2655 switch (target) 2656 { 2657 case T2D: 2658 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) readonly uniform " 2659 << TypePrefix<T>() 2660 << "image2D g_image_2d;" NL "layout(std430, binding = 0) buffer OutputBuffer2D {" NL " " 2661 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;"; 2662 break; 2663 case T3D: 2664 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) readonly uniform " 2665 << TypePrefix<T>() 2666 << "image3D g_image_3d;" NL "layout(std430, binding = 1) buffer OutputBuffer3D {" NL " " 2667 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;"; 2668 break; 2669 case TCM: 2670 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) readonly uniform " 2671 << TypePrefix<T>() 2672 << "imageCube g_image_cube;" NL "layout(std430, binding = 2) buffer OutputBufferCube {" NL " " 2673 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;"; 2674 break; 2675 case T2DA: 2676 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform " 2677 << TypePrefix<T>() 2678 << "image2DArray g_image_2darray;" NL "layout(std430, binding = 3) buffer OutputBuffer2DArray {" NL " " 2679 << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;"; 2680 break; 2681 } 2682 os << NL "void main() {" NL " ivec3 coord = ivec3(gl_LocalInvocationID.xy, 0);" NL 2683 " uint layer = uint(KSIZE * KSIZE);" NL " " 2684 << TypePrefix<T>() << "vec4 v;"; 2685 switch (target) 2686 { 2687 case T2D: 2688 os << NL " v = imageLoad(g_image_2d, coord.xy);" NL " g_buff_2d.data[gl_LocalInvocationIndex] = v;"; 2689 break; 2690 case T3D: 2691 os << NL " v = imageLoad(g_image_3d, coord);" NL " g_buff_3d.data[gl_LocalInvocationIndex] = v;" NL 2692 " v = imageLoad(g_image_3d, ivec3(coord.xy, 1));" NL 2693 " g_buff_3d.data[gl_LocalInvocationIndex + layer] = v;"; 2694 break; 2695 case TCM: 2696 os << NL " v = imageLoad(g_image_cube, coord);" NL " g_buff_cube.data[gl_LocalInvocationIndex] = v;" NL 2697 " v = imageLoad(g_image_cube, ivec3(coord.xy, 1));" NL 2698 " g_buff_cube.data[gl_LocalInvocationIndex + layer] = v;" NL 2699 " v = imageLoad(g_image_cube, ivec3(coord.xy, 2));" NL 2700 " g_buff_cube.data[gl_LocalInvocationIndex + 2u * layer] = v;" NL 2701 " v = imageLoad(g_image_cube, ivec3(coord.xy, 3));" NL 2702 " g_buff_cube.data[gl_LocalInvocationIndex + 3u * layer] = v;" NL 2703 " v = imageLoad(g_image_cube, ivec3(coord.xy, 4));" NL 2704 " g_buff_cube.data[gl_LocalInvocationIndex + 4u * layer] = v;" NL 2705 " v = imageLoad(g_image_cube, ivec3(coord.xy, 5));" NL 2706 " g_buff_cube.data[gl_LocalInvocationIndex + 5u * layer] = v;"; 2707 break; 2708 case T2DA: 2709 os << NL " v = imageLoad(g_image_2darray, coord);" NL 2710 " g_buff_2darray.data[gl_LocalInvocationIndex] = v;" NL 2711 " v = imageLoad(g_image_2darray, ivec3(coord.xy, 1));" NL 2712 " g_buff_2darray.data[gl_LocalInvocationIndex + layer] = v;"; 2713 break; 2714 } 2715 os << NL " //g_buff_2d.data[gl_LocalInvocationIndex] = " << expected_value << ";" NL "}"; 2716 return os.str(); 2717 } 2718 }; 2719 //----------------------------------------------------------------------------- 2720 // 1.3.3 BasicAllTargetsAtomic 2721 //----------------------------------------------------------------------------- 2722 class BasicAllTargetsAtomicFS : public ShaderImageLoadStoreBase 2723 { 2724 GLuint m_vao; 2725 GLuint m_vbo; 2726 2727 virtual long Setup() 2728 { 2729 m_vao = 0; 2730 m_vbo = 0; 2731 return NO_ERROR; 2732 } 2733 2734 virtual long Run() 2735 { 2736 if (!IsImageAtomicSupported()) 2737 return NOT_SUPPORTED; 2738 if (!IsVSFSAvailable(0, 4)) 2739 return NOT_SUPPORTED; 2740 if (!AreOutputsAvailable(5)) 2741 return NOT_SUPPORTED; 2742 if (!IsSSBInVSFSAvailable(1)) 2743 return NOT_SUPPORTED; 2744 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 2745 2746 if (!Atomic<GLint>(GL_R32I)) 2747 return ERROR; 2748 if (!Atomic<GLuint>(GL_R32UI)) 2749 return ERROR; 2750 2751 return NO_ERROR; 2752 } 2753 2754 virtual long Cleanup() 2755 { 2756 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 2757 glDeleteVertexArrays(1, &m_vao); 2758 glDeleteBuffers(1, &m_vbo); 2759 return NO_ERROR; 2760 } 2761 2762 template <typename T> 2763 bool Atomic(GLenum internalformat) 2764 { 2765 const char* src_vs = 2766 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 2767 const GLuint program = BuildProgram(src_vs, GenFS<T>(internalformat).c_str(), false, true); 2768 GLuint textures[8]; 2769 GLuint buffer; 2770 glGenTextures(8, textures); 2771 glGenBuffers(1, &buffer); 2772 2773 const int kSize = 11; 2774 std::vector<T> data(kSize * kSize * 3); 2775 2776 glBindTexture(GL_TEXTURE_2D, textures[1]); 2777 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2778 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2779 glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize); 2780 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]); 2781 glBindTexture(GL_TEXTURE_2D, 0); 2782 2783 glBindTexture(GL_TEXTURE_3D, textures[2]); 2784 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2785 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2786 glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 3); 2787 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kSize, kSize, 3, Format<T>(), Type<T>(), &data[0]); 2788 glBindTexture(GL_TEXTURE_3D, 0); 2789 2790 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]); 2791 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2792 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2793 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize); 2794 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]); 2795 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]); 2796 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]); 2797 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]); 2798 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]); 2799 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]); 2800 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 2801 2802 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]); 2803 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2804 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2805 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 3); 2806 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 3, Format<T>(), Type<T>(), &data[0]); 2807 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 2808 2809 glBindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat); // 2D 2810 glBindImageTexture(2, textures[2], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat); // 3D 2811 glBindImageTexture(0, textures[4], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat); // Cube 2812 glBindImageTexture(3, textures[7], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat); // 2DArray 2813 2814 std::vector<ivec4> o_data(kSize * kSize); 2815 GLuint m_buffer; 2816 glGenBuffers(1, &m_buffer); 2817 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 2818 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &o_data[0], GL_STATIC_DRAW); 2819 2820 glUseProgram(program); 2821 glClear(GL_COLOR_BUFFER_BIT); 2822 glBindVertexArray(m_vao); 2823 glViewport(0, 0, kSize, kSize); 2824 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 2825 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 2826 2827 bool status = true; 2828 2829 ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 2830 for (int i = 0; i < kSize * kSize; ++i) 2831 { 2832 if (!Equal(out_data[i], ivec4(10, 10, 10, 10), 0)) 2833 { 2834 status = false; 2835 m_context.getTestContext().getLog() 2836 << tcu::TestLog::Message << "[" << i 2837 << "] Atomic operation check failed. (operation/target coded: " << ToString(out_data[i]).c_str() 2838 << ")" << tcu::TestLog::EndMessage; 2839 } 2840 } 2841 2842 glUseProgram(0); 2843 glDeleteProgram(program); 2844 glDeleteTextures(8, textures); 2845 glDeleteBuffers(1, &buffer); 2846 glDeleteBuffers(1, &m_buffer); 2847 2848 return status; 2849 } 2850 2851 template <typename T> 2852 std::string GenFS(GLenum internalformat) 2853 { 2854 std::ostringstream os; 2855 os << NL "#define KSIZE 11" NL "layout(" << FormatEnumToString(internalformat) 2856 << ", binding = 1) coherent uniform " << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" 2857 << FormatEnumToString(internalformat) << ", binding = 2) coherent uniform " << TypePrefix<T>() 2858 << "image3D g_image_3d;" NL "layout(" << FormatEnumToString(internalformat) 2859 << ", binding = 0) coherent uniform " << TypePrefix<T>() << "imageCube g_image_cube;" NL "layout(" 2860 << FormatEnumToString(internalformat) << ", binding = 3) coherent uniform " << TypePrefix<T>() 2861 << "image2DArray g_image_2darray;" NL "layout(std430) buffer out_data {" NL 2862 " ivec4 o_color[KSIZE*KSIZE];" NL "};" NL 2863 << TypePrefix<T>() << "vec2 t(int i) {" NL " return " << TypePrefix<T>() 2864 << "vec2(i);" NL "}" NL "void main() {" NL " ivec2 coord = ivec2(gl_FragCoord.xy);" NL 2865 " int coordIndex = coord.x + KSIZE * coord.y;" NL " o_color[coordIndex] = ivec4(coordIndex);" NL 2866 " if (imageAtomicAdd(g_image_2d, coord, t(2).x) != t(0).x) o_color[coordIndex].x = 1;" NL 2867 " else if (imageAtomicMin(g_image_2d, coord, t(3).x) != t(2).x) o_color[coordIndex].x = 2;" NL 2868 " else if (imageAtomicMax(g_image_2d, coord, t(4).x) != t(2).x) o_color[coordIndex].x = 3;" NL 2869 " else if (imageAtomicAnd(g_image_2d, coord, t(0).x) != t(4).x) o_color[coordIndex].x = 4;" NL 2870 " else if (imageAtomicOr(g_image_2d, coord, t(7).x) != t(0).x) o_color[coordIndex].x = 5;" NL 2871 " else if (imageAtomicXor(g_image_2d, coord, t(4).x) != t(7).x) o_color[coordIndex].x = 6;" NL 2872 " else if (imageAtomicExchange(g_image_2d, coord, t(1).x) != t(3).x) o_color[coordIndex].x = 7;" NL 2873 " else if (imageAtomicCompSwap(g_image_2d, coord, t(1).x, t(6).x) != t(1).x) o_color[coordIndex].x = " 2874 "8;" NL " else o_color[coordIndex].x = 10;" NL 2875 " if (imageAtomicAdd(g_image_3d, ivec3(coord, 2), t(2).x) != t(0).x) o_color[coordIndex].y = 1;" NL 2876 " else if (imageAtomicMin(g_image_3d, ivec3(coord, 2), t(3).x) != t(2).x) o_color[coordIndex].y = 2;" NL 2877 " else if (imageAtomicMax(g_image_3d, ivec3(coord, 2), t(4).x) != t(2).x) o_color[coordIndex].y = 3;" NL 2878 " else if (imageAtomicAnd(g_image_3d, ivec3(coord, 2), t(0).x) != t(4).x) o_color[coordIndex].y = 4;" NL 2879 " else if (imageAtomicOr(g_image_3d, ivec3(coord, 2), t(7).x) != t(0).x) o_color[coordIndex].y = 5;" NL 2880 " else if (imageAtomicXor(g_image_3d, ivec3(coord, 2), t(4).x) != t(7).x) o_color[coordIndex].y = 6;" NL 2881 " else if (imageAtomicExchange(g_image_3d, ivec3(coord, 2), t(1).x) != t(3).x) o_color[coordIndex].y = " 2882 "7;" NL " else if (imageAtomicCompSwap(g_image_3d, ivec3(coord, 2), t(1).x, t(6).x) != t(1).x) " 2883 "o_color[coordIndex].y = 8;" NL " else o_color[coordIndex].y = 10;" NL 2884 " if (imageAtomicAdd(g_image_cube, ivec3(coord, 3), t(2).x) != t(0).x) o_color[coordIndex].z = 1;" NL 2885 " else if (imageAtomicMin(g_image_cube, ivec3(coord, 3), t(3).x) != t(2).x) o_color[coordIndex].z = " 2886 "2;" NL " else if (imageAtomicMax(g_image_cube, ivec3(coord, 3), t(4).x) != t(2).x) " 2887 "o_color[coordIndex].z = 3;" NL " else if (imageAtomicAnd(g_image_cube, ivec3(coord, 3), " 2888 "t(0).x) != t(4).x) o_color[coordIndex].z = 4;" NL 2889 " else if (imageAtomicOr(g_image_cube, ivec3(coord, 3), t(7).x) != t(0).x) o_color[coordIndex].z = 5;" NL 2890 " else if (imageAtomicXor(g_image_cube, ivec3(coord, 3), t(4).x) != t(7).x) o_color[coordIndex].z = " 2891 "6;" NL " else if (imageAtomicExchange(g_image_cube, ivec3(coord, 3), t(1).x) != t(3).x) " 2892 "o_color[coordIndex].z = 7;" NL " else if (imageAtomicCompSwap(g_image_cube, ivec3(coord, 3), " 2893 "t(1).x, t(6).x) != t(1).x) o_color[coordIndex].z = 8;" NL " else o_color[coordIndex].z = 10;" NL 2894 " if (imageAtomicAdd(g_image_2darray, ivec3(coord, 2), t(2).x) != t(0).x) o_color[coordIndex].w = 1;" NL 2895 " else if (imageAtomicMin(g_image_2darray, ivec3(coord, 2), t(3).x) != t(2).x) o_color[coordIndex].w = " 2896 "2;" NL " else if (imageAtomicMax(g_image_2darray, ivec3(coord, 2), t(4).x) != t(2).x) " 2897 "o_color[coordIndex].w = 3;" NL " else if (imageAtomicAnd(g_image_2darray, ivec3(coord, 2), " 2898 "t(0).x) != t(4).x) o_color[coordIndex].w = 4;" NL 2899 " else if (imageAtomicOr(g_image_2darray, ivec3(coord, 2), t(7).x) != t(0).x) o_color[coordIndex].w = " 2900 "5;" NL " else if (imageAtomicXor(g_image_2darray, ivec3(coord, 2), t(4).x) != t(7).x) " 2901 "o_color[coordIndex].w = 6;" NL " else if (imageAtomicExchange(g_image_2darray, ivec3(coord, " 2902 "2), t(1).x) != t(3).x) o_color[coordIndex].w = 7;" NL 2903 " else if (imageAtomicCompSwap(g_image_2darray, ivec3(coord, 2), t(1).x, t(6).x) != t(1).x) " 2904 "o_color[coordIndex].w = 8;" NL " else o_color[coordIndex].w = 10;" NL " discard;" NL "}"; 2905 return os.str(); 2906 } 2907 }; 2908 //----------------------------------------------------------------------------- 2909 // LoadStoreMachine 2910 //----------------------------------------------------------------------------- 2911 class LoadStoreMachine : public ShaderImageLoadStoreBase 2912 { 2913 GLuint m_vao; 2914 GLuint m_buffer; 2915 int m_stage; 2916 2917 virtual long Setup() 2918 { 2919 glEnable(GL_RASTERIZER_DISCARD); 2920 glGenVertexArrays(1, &m_vao); 2921 glGenBuffers(1, &m_buffer); 2922 return NO_ERROR; 2923 } 2924 2925 virtual long Cleanup() 2926 { 2927 glDisable(GL_RASTERIZER_DISCARD); 2928 glDeleteVertexArrays(1, &m_vao); 2929 glDeleteBuffers(1, &m_buffer); 2930 return NO_ERROR; 2931 } 2932 2933 template <typename T> 2934 bool Write(GLenum internalformat, const T& write_value, const T& expected_value) 2935 { 2936 const GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY }; 2937 const int kTargets = sizeof(targets) / sizeof(targets[0]); 2938 const int kSize = 100; 2939 GLuint program_store = 0; 2940 GLuint program_load = 0; 2941 if (m_stage == 0) 2942 { // VS 2943 const char* src_fs = NL "void main() {" NL " discard;" NL "}"; 2944 program_store = BuildProgram(GenStoreShader(m_stage, internalformat, write_value).c_str(), src_fs); 2945 program_load = BuildProgram(GenLoadShader(m_stage, internalformat, expected_value).c_str(), src_fs); 2946 } 2947 else if (m_stage == 4) 2948 { // CS 2949 program_store = CreateComputeProgram(GenStoreShader(m_stage, internalformat, write_value)); 2950 program_load = CreateComputeProgram(GenLoadShader(m_stage, internalformat, expected_value)); 2951 } 2952 GLuint textures[kTargets]; 2953 glGenTextures(kTargets, textures); 2954 2955 for (int i = 0; i < kTargets; ++i) 2956 { 2957 glBindTexture(targets[i], textures[i]); 2958 glTexParameteri(targets[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2959 glTexParameteri(targets[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2960 2961 if (targets[i] == GL_TEXTURE_2D) 2962 { 2963 glTexStorage2D(targets[i], 1, internalformat, kSize, 1); 2964 } 2965 else if (targets[i] == GL_TEXTURE_3D || targets[i] == GL_TEXTURE_2D_ARRAY) 2966 { 2967 glTexStorage3D(targets[i], 1, internalformat, kSize, 1, 2); 2968 } 2969 else if (targets[i] == GL_TEXTURE_CUBE_MAP) 2970 { 2971 glTexStorage2D(targets[i], 1, internalformat, kSize, kSize); 2972 } 2973 } 2974 glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); // 2D 2975 glBindImageTexture(2, textures[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // 3D 2976 glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // Cube 2977 glBindImageTexture(3, textures[3], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat); // 2DArray 2978 2979 std::vector<ivec4> b_data(kSize); 2980 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 2981 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * 4 * 4, &b_data[0], GL_STATIC_DRAW); 2982 2983 glUseProgram(program_store); 2984 glBindVertexArray(m_vao); 2985 if (m_stage == 4) 2986 { // CS 2987 glDispatchCompute(1, 1, 1); 2988 } 2989 else if (m_stage == 0) 2990 { // VS 2991 glDrawArrays(GL_POINTS, 0, kSize); 2992 } 2993 bool status = true; 2994 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 2995 2996 glBindImageTexture(3, textures[0], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); // 2D 2997 glBindImageTexture(2, textures[1], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // 3D 2998 glBindImageTexture(1, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // Cube 2999 glBindImageTexture(0, textures[3], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat); // 2DArray 3000 3001 glUseProgram(program_load); 3002 if (m_stage == 0) 3003 { // VS 3004 glDrawArrays(GL_POINTS, 0, kSize); 3005 } 3006 else if (m_stage == 4) 3007 { // CS 3008 glDispatchCompute(1, 1, 1); 3009 } 3010 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3011 3012 ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * 4 * 4, GL_MAP_READ_BIT); 3013 for (int i = 0; i < kSize; ++i) 3014 { 3015 if (!Equal(out_data[i], ivec4(0, 1, 0, 1), 0)) 3016 { 3017 status = false; 3018 m_context.getTestContext().getLog() 3019 << tcu::TestLog::Message << "[" << i << "] load/store operation check failed. (" 3020 << ToString(out_data[i]).c_str() << ")" << tcu::TestLog::EndMessage; 3021 } 3022 } 3023 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 3024 glUseProgram(0); 3025 glDeleteProgram(program_store); 3026 glDeleteProgram(program_load); 3027 glDeleteTextures(kTargets, textures); 3028 return status; 3029 } 3030 3031 template <typename T> 3032 std::string GenStoreShader(int stage, GLenum internalformat, const T& write_value) 3033 { 3034 std::ostringstream os; 3035 if (stage == 4) 3036 { // CS 3037 os << NL "#define KSIZE 100" NL "layout(local_size_x = KSIZE) in;"; 3038 } 3039 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) writeonly uniform " 3040 << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat) 3041 << ", binding = 2) writeonly uniform " << TypePrefix<T>() << "image3D g_image_3d;" NL "layout(" 3042 << FormatEnumToString(internalformat) << ", binding = 0) writeonly uniform " << TypePrefix<T>() 3043 << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat) 3044 << ", binding = 3) writeonly uniform " << TypePrefix<T>() 3045 << "image2DArray g_image_2darray;" NL "layout(std430) buffer out_data {" NL " ivec4 o_color;" NL "};" NL 3046 "void main() {" NL " " 3047 << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>() << "vec4(o_color) + " << TypePrefix<T>() << "vec4" 3048 << write_value 3049 << ";" NL " int g_index[6] = int[](o_color.x, o_color.y, o_color.z, o_color.w, o_color.r, o_color.g);"; 3050 if (stage == 0) 3051 { // VS 3052 os << NL " ivec2 coord = ivec2(gl_VertexID, g_index[0]);"; 3053 } 3054 else if (stage == 4) 3055 { // CS 3056 os << NL " ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_index[0]);"; 3057 } 3058 os << NL " imageStore(g_image_2d, coord, g_value);" NL 3059 " imageStore(g_image_3d, ivec3(coord.xy, g_index[0]), g_value);" NL 3060 " imageStore(g_image_3d, ivec3(coord.xy, g_index[1]), g_value);" NL 3061 " for (int i = 0; i < 6; ++i) {" NL 3062 " imageStore(g_image_cube, ivec3(coord, g_index[i]), g_value);" NL " }" NL 3063 " imageStore(g_image_2darray, ivec3(coord, g_index[0]), g_value);" NL 3064 " imageStore(g_image_2darray, ivec3(coord, g_index[1]), g_value);" NL "}"; 3065 return os.str(); 3066 } 3067 3068 template <typename T> 3069 std::string GenLoadShader(int stage, GLenum internalformat, const T& expected_value) 3070 { 3071 std::ostringstream os; 3072 os << NL "#define KSIZE 100"; 3073 if (stage == 4) 3074 { // CS 3075 os << NL "layout(local_size_x = KSIZE) in;"; 3076 } 3077 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) readonly uniform " 3078 << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat) 3079 << ", binding = 2) readonly uniform " << TypePrefix<T>() << "image3D g_image_3d;" NL "layout(" 3080 << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform " << TypePrefix<T>() 3081 << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat) 3082 << ", binding = 0) readonly uniform " << TypePrefix<T>() 3083 << "image2DArray g_image_2darray;" NL "layout(std430) buffer out_data {" NL " ivec4 o_color[KSIZE];" NL 3084 "};" NL "void main() {"; 3085 3086 if (stage == 0) 3087 { // VS 3088 os << NL " " << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>() << "vec4(o_color[gl_VertexID]) + " 3089 << TypePrefix<T>() << "vec4" << expected_value << ";"; 3090 } 3091 else if (stage == 4) 3092 { // CS 3093 os << NL " " << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>() 3094 << "vec4(o_color[gl_GlobalInvocationID.x]) + " << TypePrefix<T>() << "vec4" << expected_value << ";"; 3095 } 3096 3097 os << NL " int g_index[6] = int[](o_color[0].x, o_color[0].y, o_color[0].z, o_color[0].w, o_color[1].r, " 3098 "o_color[1].g);"; 3099 if (stage == 0) 3100 { // VS 3101 os << NL " ivec2 coord = ivec2(gl_VertexID, g_index[0]);"; 3102 } 3103 else if (stage == 4) 3104 { // CS 3105 os << NL " ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_index[0]);"; 3106 } 3107 os << NL " vec4 r = vec4(0.0, 1.0, 0.0, 1.0);" NL " " << TypePrefix<T>() 3108 << "vec4 v;" NL " v = imageLoad(g_image_2d, coord);" NL 3109 " if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 2.0);" NL 3110 " v = imageLoad(g_image_3d, ivec3(coord, g_index[0]));" NL 3111 " if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 3.0);" NL 3112 " v = imageLoad(g_image_cube, ivec3(coord, g_index[0]));" NL 3113 " if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 6.0);" NL 3114 " v = imageLoad(g_image_2darray, ivec3(coord, g_index[0]));" NL 3115 " if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 23.0);" NL " o_color[coord.x] = ivec4(r);" NL 3116 "}"; 3117 return os.str(); 3118 } 3119 3120 protected: 3121 long RunStage(int stage) 3122 { 3123 m_stage = stage; 3124 if (!AreOutputsAvailable(5)) 3125 return NOT_SUPPORTED; 3126 3127 if (!Write(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f))) 3128 return ERROR; 3129 if (!Write(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f))) 3130 return ERROR; 3131 if (!Write(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f))) 3132 return ERROR; 3133 3134 if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 3135 return ERROR; 3136 if (!Write(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1))) 3137 return ERROR; 3138 if (!Write(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 3139 return ERROR; 3140 if (!Write(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4))) 3141 return ERROR; 3142 3143 if (!Write(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 3144 return ERROR; 3145 if (!Write(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1))) 3146 return ERROR; 3147 if (!Write(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 3148 return ERROR; 3149 if (!Write(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3))) 3150 return ERROR; 3151 3152 if (!Write(GL_RGBA8, vec4(1.0f), vec4(1.0f))) 3153 return ERROR; 3154 3155 if (!Write(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f))) 3156 return ERROR; 3157 3158 return NO_ERROR; 3159 } 3160 }; 3161 3162 //----------------------------------------------------------------------------- 3163 // AtomicMachine 3164 //----------------------------------------------------------------------------- 3165 class AtomicMachine : public ShaderImageLoadStoreBase 3166 { 3167 GLuint m_vao; 3168 GLuint m_buffer; 3169 3170 virtual long Setup() 3171 { 3172 glEnable(GL_RASTERIZER_DISCARD); 3173 glGenVertexArrays(1, &m_vao); 3174 glGenBuffers(1, &m_buffer); 3175 return NO_ERROR; 3176 } 3177 3178 virtual long Cleanup() 3179 { 3180 glDisable(GL_RASTERIZER_DISCARD); 3181 glDeleteVertexArrays(1, &m_vao); 3182 glDeleteBuffers(1, &m_buffer); 3183 return NO_ERROR; 3184 } 3185 3186 template <typename T> 3187 bool Atomic(int target, int stage, GLenum internalformat) 3188 { 3189 GLuint program = 0; 3190 if (stage == 0) 3191 { // VS 3192 const char* src_fs = NL "void main() {" NL " discard;" NL "}"; 3193 program = BuildProgram(GenShader<T>(target, stage, internalformat).c_str(), src_fs, true, false); 3194 } 3195 else if (stage == 4) 3196 { // CS 3197 program = CreateComputeProgram(GenShader<T>(target, stage, internalformat), true); 3198 } 3199 3200 const GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY }; 3201 const int kTargets = sizeof(targets) / sizeof(targets[0]); 3202 const int kSize = 100; 3203 3204 GLuint textures[kTargets]; 3205 glGenTextures(kTargets, textures); 3206 3207 for (int i = 0; i < kTargets; ++i) 3208 { 3209 glBindTexture(targets[i], textures[i]); 3210 glTexParameteri(targets[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3211 glTexParameteri(targets[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3212 if (targets[i] == GL_TEXTURE_2D) 3213 { 3214 glTexStorage2D(targets[i], 1, internalformat, kSize, 1); 3215 } 3216 else if (targets[i] == GL_TEXTURE_3D || targets[i] == GL_TEXTURE_2D_ARRAY) 3217 { 3218 glTexStorage3D(targets[i], 1, internalformat, kSize, 1, 2); 3219 } 3220 else if (targets[i] == GL_TEXTURE_CUBE_MAP) 3221 { 3222 glTexStorage2D(targets[i], 1, internalformat, kSize, kSize); 3223 } 3224 } 3225 glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat); // 2D 3226 glBindImageTexture(2, textures[1], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat); // 3D 3227 glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat); // Cube 3228 glBindImageTexture(3, textures[3], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat); // 2DArray 3229 3230 std::vector<ivec4> b_data(kSize); 3231 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 3232 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * 4 * 4, &b_data[0], GL_STATIC_DRAW); 3233 3234 glUseProgram(program); 3235 glBindVertexArray(m_vao); 3236 if (stage == 0) 3237 { // VS 3238 glDrawArrays(GL_POINTS, 0, kSize); 3239 } 3240 else if (stage == 4) 3241 { // CS 3242 glDispatchCompute(1, 1, 1); 3243 } 3244 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3245 3246 bool status = true; 3247 ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * 4 * 4, GL_MAP_READ_BIT); 3248 for (int i = 0; i < kSize; ++i) 3249 { 3250 if (!Equal(out_data[i], ivec4(0, 1, 0, 1), 0)) 3251 { 3252 status = false; 3253 m_context.getTestContext().getLog() 3254 << tcu::TestLog::Message << "[" << i << "] Atomic operation check failed. (" 3255 << ToString(out_data[i]).c_str() << ")" << tcu::TestLog::EndMessage; 3256 } 3257 } 3258 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 3259 glUseProgram(0); 3260 glDeleteProgram(program); 3261 glDeleteTextures(kTargets, textures); 3262 return status; 3263 } 3264 3265 template <typename T> 3266 std::string GenShader(int target, int stage, GLenum internalformat) 3267 { 3268 std::ostringstream os; 3269 os << NL "#define KSIZE 100"; 3270 if (stage == 4) 3271 { // CS 3272 os << NL "layout(local_size_x = KSIZE) in;"; 3273 } 3274 switch (target) 3275 { 3276 case T2D: 3277 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) coherent uniform " 3278 << TypePrefix<T>() << "image2D g_image_2d;"; 3279 break; 3280 case T3D: 3281 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) coherent uniform " 3282 << TypePrefix<T>() << "image3D g_image_3d;"; 3283 break; 3284 case TCM: 3285 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) coherent uniform " 3286 << TypePrefix<T>() << "imageCube g_image_cube;"; 3287 break; 3288 case T2DA: 3289 os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) coherent uniform " 3290 << TypePrefix<T>() << "image2DArray g_image_2darray;"; 3291 break; 3292 } 3293 os << NL "layout(std430) buffer out_data {" NL " ivec4 o_color[KSIZE];" NL "} r;" NL << TypePrefix<T>() 3294 << "vec2 t(int i) {" NL " return " << TypePrefix<T>() 3295 << "vec2(i);" NL "}" NL "void main() {" NL " int g_value[6] = int[](r.o_color[0].x, r.o_color[0].y+1, " 3296 "r.o_color[0].z+2, r.o_color[0].w+3, r.o_color[1].r+4, " 3297 "r.o_color[1].g+5);"; 3298 if (stage == 0) 3299 { // VS 3300 os << NL " ivec2 coord = ivec2(gl_VertexID, g_value[0]);"; 3301 } 3302 else if (stage == 4) 3303 { // CS 3304 os << NL " ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_value[0]);"; 3305 } 3306 os << NL " ivec4 o_color = ivec4(0, 1, 0, 1);"; 3307 3308 switch (target) 3309 { 3310 case T2D: 3311 os << NL " ivec4 i = ivec4(1, 0, 0, 2);" NL " imageAtomicExchange(g_image_2d, coord, t(0).x);" NL 3312 " if (imageAtomicAdd(g_image_2d, coord, t(2).x) != t(0).x) o_color = i;" NL 3313 " if (imageAtomicMin(g_image_2d, coord, t(3).x) != t(2).x) o_color = i;" NL 3314 " if (imageAtomicMax(g_image_2d, coord, t(4).x) != t(2).x) o_color = i;" NL 3315 " if (imageAtomicAnd(g_image_2d, coord, t(0).x) != t(4).x) o_color = i;" NL 3316 " if (imageAtomicOr(g_image_2d, coord, t(7).x) != t(0).x) o_color = i;" NL 3317 " if (imageAtomicXor(g_image_2d, coord, t(4).x) != t(7).x) o_color = i;" NL 3318 " if (imageAtomicExchange(g_image_2d, coord, t(1).x) != t(3).x) o_color = i;" NL 3319 " if (imageAtomicCompSwap(g_image_2d, coord, t(1).x, t(6).x) != t(1).x) o_color = i;" NL 3320 " if (imageAtomicExchange(g_image_2d, coord, t(0).x) != t(6).x) o_color = i;"; 3321 break; 3322 case T3D: 3323 os << NL " ivec4 i = ivec4(1, 0, 0, 3);" NL 3324 " imageAtomicExchange(g_image_3d, ivec3(coord, 0), t(0).x);" NL 3325 " if (imageAtomicAdd(g_image_3d, ivec3(coord, 0), t(2).x) != t(0).x) o_color = i;" NL 3326 " if (imageAtomicMin(g_image_3d, ivec3(coord, 0), t(3).x) != t(2).x) o_color = i;" NL 3327 " if (imageAtomicMax(g_image_3d, ivec3(coord, g_value[0]), t(4).x) != t(2).x) o_color = i;" NL 3328 " if (imageAtomicAnd(g_image_3d, ivec3(coord, 0), t(0).x) != t(4).x) o_color = i;" NL 3329 " if (imageAtomicOr(g_image_3d, ivec3(coord, 0), t(7).x) != t(0).x) o_color = i;" NL 3330 " if (imageAtomicXor(g_image_3d, ivec3(coord, 0), t(4).x) != t(7).x) o_color = i;" NL 3331 " if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), t(1).x) != t(3).x) o_color = i;" NL 3332 " if (imageAtomicCompSwap(g_image_3d, ivec3(coord, 0), t(1).x, t(6).x) != t(1).x) o_color = i;" NL 3333 " if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), t(0).x) != t(6).x) o_color = i;"; 3334 break; 3335 case TCM: 3336 os << NL 3337 " ivec4 i = ivec4(1, 0, 0, 6);" NL " imageAtomicExchange(g_image_cube, ivec3(coord, 0), t(0).x);" NL 3338 " if (imageAtomicAdd(g_image_cube, ivec3(coord, 0), t(g_value[2]).x) != t(0).x) o_color = i;" NL 3339 " if (imageAtomicMin(g_image_cube, ivec3(coord, 0), t(3).x) != t(2).x) o_color = i;" NL 3340 " if (imageAtomicMax(g_image_cube, ivec3(coord, 0), t(4).x) != t(2).x) o_color = i;" NL 3341 " if (imageAtomicAnd(g_image_cube, ivec3(coord, 0), t(0).x) != t(4).x) o_color = i;" NL 3342 " if (imageAtomicOr(g_image_cube, ivec3(coord, 0), t(7).x) != t(0).x) o_color = i;" NL 3343 " if (imageAtomicXor(g_image_cube, ivec3(coord, 0), t(4).x) != t(7).x) o_color = i;" NL 3344 " if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), t(1).x) != t(3).x) o_color = i;" NL 3345 " if (imageAtomicCompSwap(g_image_cube, ivec3(coord, g_value[0]), t(1).x, t(6).x) != t(1).x) o_color " 3346 "= i;" NL " if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), t(0).x) != t(6).x) o_color = i;"; 3347 break; 3348 case T2DA: 3349 os << NL 3350 " ivec4 i = ivec4(1, 0, 0, 23);" NL 3351 " imageAtomicExchange(g_image_2darray, ivec3(coord, 0), t(0).x);" NL 3352 " if (imageAtomicAdd(g_image_2darray, ivec3(coord, 0), t(2).x) != t(0).x) o_color = i;" NL 3353 " if (imageAtomicMin(g_image_2darray, ivec3(coord, 0), t(3).x) != t(2).x) o_color = i;" NL 3354 " if (imageAtomicMax(g_image_2darray, ivec3(coord, 0), t(4).x) != t(2).x) o_color = i;" NL 3355 " if (imageAtomicAnd(g_image_2darray, ivec3(coord, 0), t(0).x) != t(4).x) o_color = i;" NL 3356 " if (imageAtomicOr(g_image_2darray, ivec3(coord, 0), t(7).x) != t(0).x) o_color = i;" NL 3357 " if (imageAtomicXor(g_image_2darray, ivec3(coord, 0), t(g_value[4]).x) != t(7).x) o_color = i;" NL 3358 " if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), t(1).x) != t(3).x) o_color = i;" NL 3359 " if (imageAtomicCompSwap(g_image_2darray, ivec3(coord, 0), t(1).x, t(6).x) != t(1).x) o_color = i;" NL 3360 " if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), t(0).x) != t(6).x) o_color = i;"; 3361 break; 3362 } 3363 os << NL " r.o_color[coord.x] = o_color;" NL "}"; 3364 return os.str(); 3365 } 3366 3367 protected: 3368 long RunStage(int stage) 3369 { 3370 if (!IsImageAtomicSupported()) 3371 return NOT_SUPPORTED; 3372 if (!Atomic<GLint>(T2D, stage, GL_R32I)) 3373 return ERROR; 3374 if (!Atomic<GLuint>(T2D, stage, GL_R32UI)) 3375 return ERROR; 3376 if (!Atomic<GLint>(T3D, stage, GL_R32I)) 3377 return ERROR; 3378 if (!Atomic<GLuint>(T3D, stage, GL_R32UI)) 3379 return ERROR; 3380 if (!Atomic<GLint>(TCM, stage, GL_R32I)) 3381 return ERROR; 3382 if (!Atomic<GLuint>(TCM, stage, GL_R32UI)) 3383 return ERROR; 3384 if (!Atomic<GLint>(T2DA, stage, GL_R32I)) 3385 return ERROR; 3386 if (!Atomic<GLuint>(T2DA, stage, GL_R32UI)) 3387 return ERROR; 3388 return NO_ERROR; 3389 } 3390 }; 3391 3392 //----------------------------------------------------------------------------- 3393 // 1.3.4 BasicAllTargetsLoadStoreVS 3394 //----------------------------------------------------------------------------- 3395 class BasicAllTargetsLoadStoreVS : public LoadStoreMachine 3396 { 3397 virtual long Run() 3398 { 3399 if (!IsVSFSAvailable(4, 0) || !IsSSBInVSFSAvailable(1)) 3400 return NOT_SUPPORTED; 3401 return RunStage(0); 3402 } 3403 }; 3404 3405 //----------------------------------------------------------------------------- 3406 // 1.3.8 BasicAllTargetsLoadStoreCS 3407 //----------------------------------------------------------------------------- 3408 class BasicAllTargetsLoadStoreCS : public LoadStoreMachine 3409 { 3410 virtual long Run() 3411 { 3412 return RunStage(4); 3413 } 3414 }; 3415 3416 //----------------------------------------------------------------------------- 3417 // 1.3.9 BasicAllTargetsAtomicVS 3418 //----------------------------------------------------------------------------- 3419 class BasicAllTargetsAtomicVS : public AtomicMachine 3420 { 3421 virtual long Run() 3422 { 3423 if (!IsVSFSAvailable(4, 0) || !IsSSBInVSFSAvailable(1)) 3424 return NOT_SUPPORTED; 3425 return RunStage(0); 3426 } 3427 }; 3428 3429 //----------------------------------------------------------------------------- 3430 // 1.3.13 BasicAllTargetsAtomicCS 3431 //----------------------------------------------------------------------------- 3432 class BasicAllTargetsAtomicCS : public AtomicMachine 3433 { 3434 virtual long Run() 3435 { 3436 return RunStage(4); 3437 } 3438 }; 3439 3440 //----------------------------------------------------------------------------- 3441 // 1.4.1 BasicGLSLMisc 3442 //----------------------------------------------------------------------------- 3443 class BasicGLSLMiscFS : public ShaderImageLoadStoreBase 3444 { 3445 GLuint m_texture; 3446 GLuint m_program; 3447 GLuint m_vao, m_vbo; 3448 GLuint m_buffer; 3449 3450 virtual long Setup() 3451 { 3452 m_texture = 0; 3453 m_program = 0; 3454 m_vao = m_vbo = 0; 3455 m_buffer = 0; 3456 return NO_ERROR; 3457 } 3458 3459 virtual long Run() 3460 { 3461 if (!IsVSFSAvailable(0, 2) || !IsSSBInVSFSAvailable(1)) 3462 return NOT_SUPPORTED; 3463 3464 const int kSize = 32; 3465 std::vector<float> data(kSize * kSize * 4); 3466 3467 glGenTextures(1, &m_texture); 3468 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture); 3469 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3470 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3471 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, kSize, kSize, 4); 3472 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 4, GL_RED, GL_FLOAT, &data[0]); 3473 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 3474 3475 const char* src_vs = 3476 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 3477 3478 const char* src_fs = 3479 NL "#define KSIZE 32" NL "layout(std430) buffer out_data {" NL " ivec4 o_color[KSIZE*KSIZE];" NL "};" NL 3480 "layout(r32f, binding = 0) coherent restrict uniform image2D g_image_layer0;" NL 3481 "layout(r32f, binding = 1) volatile uniform image2D g_image_layer1;" NL "void main() {" NL 3482 " ivec2 coord = ivec2(gl_FragCoord.xy);" NL " imageStore(g_image_layer0, coord, vec4(1.0));" NL 3483 " memoryBarrier();" NL " imageStore(g_image_layer1, coord, vec4(2.0));" NL " memoryBarrier();" NL 3484 " imageStore(g_image_layer0, coord, vec4(3.0));" NL " memoryBarrier();" NL 3485 " int coordIndex = coord.x + KSIZE * coord.y;" NL 3486 " o_color[coordIndex] = ivec4(imageLoad(g_image_layer0, coord) + imageLoad(g_image_layer1, coord));" NL 3487 "}"; 3488 m_program = BuildProgram(src_vs, src_fs); 3489 3490 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 3491 3492 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); 3493 glBindImageTexture(1, m_texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F); 3494 3495 glClear(GL_COLOR_BUFFER_BIT); 3496 glViewport(0, 0, kSize, kSize); 3497 3498 std::vector<ivec4> o_data(kSize * kSize); 3499 glGenBuffers(1, &m_buffer); 3500 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 3501 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &o_data[0], GL_STATIC_DRAW); 3502 3503 glUseProgram(m_program); 3504 glBindVertexArray(m_vao); 3505 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 3506 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3507 3508 bool status = true; 3509 3510 ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 3511 for (int i = 0; i < kSize * kSize; ++i) 3512 { 3513 if (!Equal(out_data[i], ivec4(5, 0, 0, 2), 0)) 3514 { 3515 status = false; 3516 m_context.getTestContext().getLog() 3517 << tcu::TestLog::Message << "[" << i 3518 << "] Check failed. Received: " << ToString(out_data[i]).c_str() 3519 << " instead of: " << ToString(ivec4(5, 0, 0, 2)).c_str() << tcu::TestLog::EndMessage; 3520 } 3521 } 3522 3523 if (status) 3524 return NO_ERROR; 3525 else 3526 return ERROR; 3527 } 3528 3529 virtual long Cleanup() 3530 { 3531 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 3532 glDeleteTextures(1, &m_texture); 3533 glDeleteVertexArrays(1, &m_vao); 3534 glDeleteBuffers(1, &m_vbo); 3535 glDeleteBuffers(1, &m_buffer); 3536 glUseProgram(0); 3537 glDeleteProgram(m_program); 3538 return NO_ERROR; 3539 } 3540 }; 3541 3542 class BasicGLSLMiscCS : public ShaderImageLoadStoreBase 3543 { 3544 GLuint m_texture; 3545 GLuint m_program; 3546 GLuint m_buffer; 3547 3548 virtual long Setup() 3549 { 3550 m_texture = 0; 3551 m_program = 0; 3552 m_buffer = 0; 3553 return NO_ERROR; 3554 } 3555 3556 virtual long Run() 3557 { 3558 const int kSize = 10; 3559 std::vector<float> data(kSize * kSize * 4); 3560 3561 glGenTextures(1, &m_texture); 3562 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture); 3563 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3564 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3565 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, kSize, kSize, 4); 3566 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 4, GL_RED, GL_FLOAT, &data[0]); 3567 glBindTexture(GL_TEXTURE_2D_ARRAY, 0); 3568 3569 const char* src_cs = 3570 NL "#define KSIZE 10" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 3571 "layout(std430) buffer out_data {" NL " ivec4 o_color[KSIZE*KSIZE];" NL "};" NL 3572 "layout(r32f, binding = 0) coherent restrict uniform image2D g_image_layer0;" NL 3573 "layout(r32f, binding = 1) volatile uniform image2D g_image_layer1;" NL "void main() {" NL 3574 " ivec2 coord = ivec2(gl_LocalInvocationID.xy);" NL " imageStore(g_image_layer0, coord, vec4(1.0));" NL 3575 " memoryBarrier();" NL " imageStore(g_image_layer1, coord, vec4(2.0));" NL " memoryBarrier();" NL 3576 " imageStore(g_image_layer0, coord, vec4(3.0));" NL " memoryBarrier();" NL 3577 " o_color[gl_LocalInvocationIndex] = ivec4(imageLoad(g_image_layer0, coord) + " 3578 "imageLoad(g_image_layer1, coord));" NL "}"; 3579 m_program = CreateComputeProgram(src_cs); 3580 3581 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); 3582 glBindImageTexture(1, m_texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F); 3583 3584 std::vector<ivec4> o_data(kSize * kSize); 3585 glGenBuffers(1, &m_buffer); 3586 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 3587 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &o_data[0], GL_STATIC_DRAW); 3588 3589 glUseProgram(m_program); 3590 glDispatchCompute(1, 1, 1); 3591 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3592 3593 bool status = true; 3594 3595 ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 3596 for (int i = 0; i < kSize * kSize; ++i) 3597 { 3598 if (!Equal(out_data[i], ivec4(5, 0, 0, 2), 0)) 3599 { 3600 status = false; 3601 m_context.getTestContext().getLog() 3602 << tcu::TestLog::Message << "[" << i 3603 << "] Check failed. Received: " << ToString(out_data[i]).c_str() 3604 << " instead of: " << ToString(ivec4(5, 0, 0, 2)).c_str() << tcu::TestLog::EndMessage; 3605 } 3606 } 3607 3608 if (status) 3609 return NO_ERROR; 3610 else 3611 return ERROR; 3612 } 3613 3614 virtual long Cleanup() 3615 { 3616 glDeleteTextures(1, &m_texture); 3617 glUseProgram(0); 3618 glDeleteProgram(m_program); 3619 glDeleteBuffers(1, &m_buffer); 3620 return NO_ERROR; 3621 } 3622 }; 3623 3624 //----------------------------------------------------------------------------- 3625 // 1.4.2 BasicGLSLEarlyFragTests 3626 //----------------------------------------------------------------------------- 3627 class BasicGLSLEarlyFragTests : public ShaderImageLoadStoreBase 3628 { 3629 GLuint m_texture[2]; 3630 GLuint m_program[2]; 3631 GLuint m_vao, m_vbo; 3632 GLuint c_program; 3633 GLuint m_buffer; 3634 3635 virtual long Setup() 3636 { 3637 m_texture[0] = m_texture[1] = 0; 3638 m_program[0] = m_program[1] = 0; 3639 m_vao = m_vbo = 0; 3640 m_buffer = 0; 3641 c_program = 0; 3642 return NO_ERROR; 3643 } 3644 3645 virtual long Run() 3646 { 3647 if (!IsVSFSAvailable(0, 1)) 3648 return NOT_SUPPORTED; 3649 3650 const int kSize = 8; 3651 std::vector<vec4> data(kSize * kSize); 3652 3653 glGenTextures(2, m_texture); 3654 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 3655 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3656 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3657 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize); 3658 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]); 3659 glBindTexture(GL_TEXTURE_2D, 0); 3660 3661 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 3662 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3663 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3664 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize); 3665 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]); 3666 glBindTexture(GL_TEXTURE_2D, 0); 3667 3668 const char* glsl_vs = 3669 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 3670 const char* glsl_early_frag_tests_fs = 3671 NL "layout(early_fragment_tests) in;" NL "layout(location = 0) out vec4 o_color;" NL 3672 "layout(rgba32f, binding = 0) writeonly coherent uniform image2D g_image;" NL "void main() {" NL 3673 " ivec2 coord = ivec2(gl_FragCoord.xy);" NL " imageStore(g_image, coord, vec4(17.0));" NL 3674 " o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}"; 3675 const char* glsl_fs = 3676 NL "layout(location = 0) out vec4 o_color;" NL 3677 "layout(rgba32f, binding = 1) writeonly coherent uniform image2D g_image;" NL "void main() {" NL 3678 " ivec2 coord = ivec2(gl_FragCoord.xy);" NL " imageStore(g_image, coord, vec4(13.0));" NL 3679 " o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}"; 3680 m_program[0] = BuildProgram(glsl_vs, glsl_early_frag_tests_fs); 3681 m_program[1] = BuildProgram(glsl_vs, glsl_fs); 3682 3683 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 3684 3685 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 3686 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 3687 3688 glViewport(0, 0, kSize, kSize); 3689 glBindVertexArray(m_vao); 3690 3691 glEnable(GL_DEPTH_TEST); 3692 glClearColor(0.0, 1.0f, 0.0, 1.0f); 3693 glClearDepthf(0.0f); 3694 3695 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3696 glUseProgram(m_program[0]); 3697 3698 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 3699 3700 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3701 glUseProgram(m_program[1]); 3702 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 3703 3704 const char* check_cs = 3705 NL "#define KSIZE 8" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 3706 "uniform sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL 3707 " vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL 3708 " data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL "}"; 3709 3710 c_program = CreateComputeProgram(check_cs); 3711 std::vector<vec4> out_data(kSize * kSize); 3712 glGenBuffers(1, &m_buffer); 3713 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 3714 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW); 3715 3716 glActiveTexture(GL_TEXTURE5); 3717 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 3718 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 3719 3720 glUseProgram(c_program); 3721 glUniform1i(glGetUniformLocation(c_program, "g_sampler"), 5); 3722 glDispatchCompute(1, 1, 1); 3723 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3724 vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 3725 3726 float expectedVal = 0.0f; 3727 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 3728 if (renderTarget.getDepthBits() == 0) 3729 { 3730 expectedVal = 17.0f; 3731 } 3732 3733 if (!CompareValues(map_data, kSize, vec4(expectedVal))) 3734 return ERROR; 3735 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 3736 3737 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 3738 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 3739 3740 glDispatchCompute(1, 1, 1); 3741 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3742 map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 3743 3744 if (!CompareValues(map_data, kSize, vec4(13.0f))) 3745 return ERROR; 3746 3747 return NO_ERROR; 3748 } 3749 3750 virtual long Cleanup() 3751 { 3752 glDisable(GL_DEPTH_TEST); 3753 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 3754 glClearDepthf(1.0f); 3755 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 3756 glDeleteTextures(2, m_texture); 3757 glDeleteVertexArrays(1, &m_vao); 3758 glDeleteBuffers(1, &m_vbo); 3759 glUseProgram(0); 3760 glDeleteProgram(m_program[0]); 3761 glDeleteProgram(m_program[1]); 3762 glDeleteProgram(c_program); 3763 glDeleteBuffers(1, &m_buffer); 3764 glActiveTexture(GL_TEXTURE0); 3765 return NO_ERROR; 3766 } 3767 }; 3768 3769 //----------------------------------------------------------------------------- 3770 // 1.4.3 BasicGLSLConst 3771 //----------------------------------------------------------------------------- 3772 class BasicGLSLConst : public ShaderImageLoadStoreBase 3773 { 3774 GLuint m_program; 3775 GLuint m_buffer; 3776 3777 virtual long Setup() 3778 { 3779 m_program = 0; 3780 m_buffer = 0; 3781 return NO_ERROR; 3782 } 3783 3784 virtual long Run() 3785 { 3786 const char* src_cs = 3787 NL "layout (local_size_x = 1) in;" NL "layout(std430) buffer out_data {" NL " ivec4 o_color;" NL "};" NL 3788 "uniform int MaxImageUnits;" NL "uniform int MaxCombinedShaderOutputResources;" NL 3789 "uniform int MaxVertexImageUniforms;" NL "uniform int MaxFragmentImageUniforms;" NL 3790 "uniform int MaxComputeImageUniforms;" NL "uniform int MaxCombinedImageUniforms;" NL "void main() {" NL 3791 " o_color = ivec4(0, 1, 0, 1);" NL 3792 " if (gl_MaxImageUnits != MaxImageUnits) o_color = ivec4(1, 0, 0, 1);" NL 3793 " if (gl_MaxCombinedShaderOutputResources != MaxCombinedShaderOutputResources) o_color = ivec4(1, 0, " 3794 "0, 2);" NL " if (gl_MaxVertexImageUniforms != MaxVertexImageUniforms) o_color = ivec4(1, 0, 0, 4);" NL 3795 " if (gl_MaxFragmentImageUniforms != MaxFragmentImageUniforms) o_color = ivec4(1, 0, 0, 5);" NL 3796 " if (gl_MaxComputeImageUniforms != MaxComputeImageUniforms) o_color = ivec4(1, 0, 0, 6);" NL 3797 " if (gl_MaxCombinedImageUniforms != MaxCombinedImageUniforms) o_color = ivec4(1, 0, 0, 9);" NL "}"; 3798 m_program = CreateComputeProgram(src_cs); 3799 glUseProgram(m_program); 3800 3801 GLint i; 3802 glGetIntegerv(GL_MAX_IMAGE_UNITS, &i); 3803 glUniform1i(glGetUniformLocation(m_program, "MaxImageUnits"), i); 3804 3805 glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &i); 3806 glUniform1i(glGetUniformLocation(m_program, "MaxCombinedShaderOutputResources"), i); 3807 3808 glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &i); 3809 glUniform1i(glGetUniformLocation(m_program, "MaxVertexImageUniforms"), i); 3810 3811 glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &i); 3812 glUniform1i(glGetUniformLocation(m_program, "MaxFragmentImageUniforms"), i); 3813 3814 glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &i); 3815 glUniform1i(glGetUniformLocation(m_program, "MaxComputeImageUniforms"), i); 3816 3817 glGetIntegerv(GL_MAX_COMBINED_IMAGE_UNIFORMS, &i); 3818 glUniform1i(glGetUniformLocation(m_program, "MaxCombinedImageUniforms"), i); 3819 3820 std::vector<ivec4> out_data(1); 3821 glGenBuffers(1, &m_buffer); 3822 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 3823 glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 4, &out_data[0], GL_STATIC_DRAW); 3824 3825 glDispatchCompute(1, 1, 1); 3826 3827 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3828 ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4, GL_MAP_READ_BIT); 3829 3830 if (!Equal(map_data[0], ivec4(0, 1, 0, 1), 0)) 3831 { 3832 m_context.getTestContext().getLog() 3833 << tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[0]).c_str() 3834 << ". Value should be: " << ToString(ivec4(0, 1, 0, 1)).c_str() << tcu::TestLog::EndMessage; 3835 return ERROR; 3836 } 3837 return NO_ERROR; 3838 } 3839 3840 virtual long Cleanup() 3841 { 3842 glUseProgram(0); 3843 glDeleteProgram(m_program); 3844 glDeleteBuffers(1, &m_buffer); 3845 return NO_ERROR; 3846 } 3847 }; 3848 3849 //----------------------------------------------------------------------------- 3850 // 2.1.1 AdvancedSyncImageAccess 3851 //----------------------------------------------------------------------------- 3852 class AdvancedSyncImageAccess : public ShaderImageLoadStoreBase 3853 { 3854 GLuint m_buffer; 3855 GLuint m_texture; 3856 GLuint m_store_program; 3857 GLuint m_draw_program; 3858 GLuint m_attribless_vao; 3859 3860 virtual long Setup() 3861 { 3862 m_buffer = 0; 3863 m_texture = 0; 3864 m_store_program = 0; 3865 m_draw_program = 0; 3866 m_attribless_vao = 0; 3867 return NO_ERROR; 3868 } 3869 3870 virtual long Run() 3871 { 3872 if (!IsVSFSAvailable(1, 0) || !IsSSBInVSFSAvailable(1)) 3873 return NOT_SUPPORTED; 3874 3875 const int kSize = 44; 3876 const char* const glsl_store_vs = 3877 NL "layout(rgba32f) writeonly uniform image2D g_output_data;" NL "void main() {" NL 3878 " vec2[4] data = vec2[4](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));" NL 3879 " imageStore(g_output_data, ivec2(gl_VertexID,0), vec4(data[gl_VertexID], 0.0, 1.0));" NL 3880 " gl_PointSize = 1.0;" NL "}"; 3881 const char* const glsl_store_fs = NL "void main() {" NL " discard;" NL "}"; 3882 const char* const glsl_draw_vs = 3883 NL "out vec4 vs_color;" NL "layout(rgba32f) readonly uniform image2D g_image;" NL 3884 "uniform sampler2D g_sampler;" NL "void main() {" NL 3885 " vec4 pi = imageLoad(g_image, ivec2(gl_VertexID, 0));" NL 3886 " vec4 ps = texelFetch(g_sampler, ivec2(gl_VertexID, 0), 0);" NL 3887 " if (pi != ps) vs_color = vec4(1.0, 0.0, 0.0, 1.0);" NL 3888 " else vs_color = vec4(0.0, 1.0, 0.0, 1.0);" NL " gl_Position = pi;" NL "}"; 3889 const char* const glsl_draw_fs = 3890 NL "#define KSIZE 44" NL "in vec4 vs_color;" NL "layout(std430) buffer OutputBuffer {" NL 3891 " vec4 o_color[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_FragCoord.xy);" NL 3892 " int coordIndex = coord.x + KSIZE * coord.y;" NL " o_color[coordIndex] = vs_color;" NL "}"; 3893 m_store_program = BuildProgram(glsl_store_vs, glsl_store_fs); 3894 m_draw_program = BuildProgram(glsl_draw_vs, glsl_draw_fs); 3895 3896 glGenVertexArrays(1, &m_attribless_vao); 3897 glBindVertexArray(m_attribless_vao); 3898 3899 glGenTextures(1, &m_texture); 3900 glBindTexture(GL_TEXTURE_2D, m_texture); 3901 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3902 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3903 std::vector<ivec4> data(4); 3904 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 4, 1); 3905 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 1, GL_RGBA, GL_FLOAT, &data[0]); 3906 3907 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 3908 3909 glUseProgram(m_store_program); 3910 glDrawArrays(GL_POINTS, 0, 4); 3911 3912 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT); 3913 3914 glViewport(0, 0, kSize, kSize); 3915 glClear(GL_COLOR_BUFFER_BIT); 3916 glUseProgram(m_draw_program); 3917 3918 std::vector<vec4> out_data(kSize * kSize); 3919 glGenBuffers(1, &m_buffer); 3920 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 3921 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW); 3922 3923 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 3924 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 3925 vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 3926 3927 if (!CompareValues(map_data, kSize, vec4(0, 1, 0, 1))) 3928 return ERROR; 3929 3930 return NO_ERROR; 3931 } 3932 3933 virtual long Cleanup() 3934 { 3935 glUseProgram(0); 3936 glDeleteBuffers(1, &m_buffer); 3937 glDeleteTextures(1, &m_texture); 3938 glDeleteProgram(m_store_program); 3939 glDeleteProgram(m_draw_program); 3940 glDeleteVertexArrays(1, &m_attribless_vao); 3941 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 3942 return NO_ERROR; 3943 } 3944 }; 3945 3946 //----------------------------------------------------------------------------- 3947 // 2.1.2 AdvancedSyncVertexArray 3948 //----------------------------------------------------------------------------- 3949 class AdvancedSyncVertexArray : public ShaderImageLoadStoreBase 3950 { 3951 GLuint m_position_buffer; 3952 GLuint m_color_buffer; 3953 GLuint m_element_buffer; 3954 GLuint m_texture[3]; 3955 GLuint m_store_program; 3956 GLuint m_copy_program; 3957 GLuint m_draw_program; 3958 GLuint m_attribless_vao; 3959 GLuint m_draw_vao; 3960 3961 virtual long Setup() 3962 { 3963 m_position_buffer = 0; 3964 m_color_buffer = 0; 3965 m_element_buffer = 0; 3966 m_store_program = 0; 3967 m_draw_program = 0; 3968 m_copy_program = 0; 3969 m_attribless_vao = 0; 3970 m_draw_vao = 0; 3971 return NO_ERROR; 3972 } 3973 3974 virtual long Run() 3975 { 3976 if (!IsVSFSAvailable(3, 0)) 3977 return NOT_SUPPORTED; 3978 const char* const glsl_store_vs = 3979 NL "layout(rgba32f, binding = 0) writeonly uniform image2D g_position_buffer;" NL 3980 "layout(rgba32f, binding = 1) writeonly uniform image2D g_color_buffer;" NL 3981 "layout(r32ui, binding = 2) writeonly uniform uimage2D g_element_buffer;" NL "uniform vec4 g_color;" NL 3982 "void main() {" NL " vec2[4] data = vec2[4](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));" NL 3983 " imageStore(g_position_buffer, ivec2(gl_VertexID,0), vec4(data[gl_VertexID], 0.0, 1.0));" NL 3984 " imageStore(g_color_buffer, ivec2(gl_VertexID,0), g_color);" NL 3985 " imageStore(g_element_buffer, ivec2(gl_VertexID,0), uvec4(gl_VertexID));" NL "}"; 3986 const char* const glsl_store_fs = NL "void main() {" NL " discard;" NL "}"; 3987 const char* glsl_copy_cs = 3988 NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE) in;" NL 3989 "layout(rgba32f, binding = 0) readonly uniform image2D g_position_img;" NL 3990 "layout(rgba32f, binding = 1) readonly uniform image2D g_color_img;" NL 3991 "layout(r32ui, binding = 2) readonly uniform uimage2D g_element_img;" NL 3992 "layout(std430, binding = 1) buffer g_position_buf {" NL " vec2 g_pos[KSIZE];" NL "};" NL 3993 "layout(std430, binding = 2) buffer g_color_buf {" NL " vec4 g_col[KSIZE];" NL "};" NL 3994 "layout(std430, binding = 3) buffer g_element_buf {" NL " uint g_elem[KSIZE];" NL "};" NL 3995 "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID.x, 0);" NL 3996 " g_pos[coord.x] = (imageLoad(g_position_img, coord)).xy;" NL 3997 " g_col[coord.x] = imageLoad(g_color_img, coord);" NL 3998 " g_elem[coord.x] = uint((imageLoad(g_element_img, coord)).x);" NL "}"; 3999 const char* const glsl_draw_vs = NL 4000 "layout(location = 0) in vec4 i_position;" NL "layout(location = 1) in vec4 i_color;" NL 4001 "out vec4 vs_color;" NL "void main() {" NL " gl_Position = i_position;" NL " vs_color = i_color;" NL "}"; 4002 const char* const glsl_draw_fs = NL "in vec4 vs_color;" NL "layout(location = 0) out vec4 o_color;" NL 4003 "void main() {" NL " o_color = vs_color;" NL "}"; 4004 m_store_program = BuildProgram(glsl_store_vs, glsl_store_fs); 4005 m_copy_program = CreateComputeProgram(glsl_copy_cs); 4006 m_draw_program = BuildProgram(glsl_draw_vs, glsl_draw_fs); 4007 4008 glGenTextures(3, m_texture); 4009 std::vector<ivec4> data(4); 4010 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 4011 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 4, 1); 4012 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4013 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4014 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 4015 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 4, 1); 4016 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4017 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4018 glBindTexture(GL_TEXTURE_2D, m_texture[2]); 4019 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 4, 1); 4020 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4021 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4022 4023 glGenVertexArrays(1, &m_attribless_vao); 4024 glGenVertexArrays(1, &m_draw_vao); 4025 glBindVertexArray(m_draw_vao); 4026 glGenBuffers(1, &m_position_buffer); 4027 glBindBuffer(GL_ARRAY_BUFFER, m_position_buffer); 4028 glBufferData(GL_ARRAY_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW); 4029 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); 4030 glGenBuffers(1, &m_color_buffer); 4031 glBindBuffer(GL_ARRAY_BUFFER, m_color_buffer); 4032 glBufferData(GL_ARRAY_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW); 4033 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); 4034 glBindBuffer(GL_ARRAY_BUFFER, 0); 4035 glEnableVertexAttribArray(0); 4036 glEnableVertexAttribArray(1); 4037 glGenBuffers(1, &m_element_buffer); 4038 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_element_buffer); 4039 glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW); 4040 glBindVertexArray(0); 4041 4042 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4043 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4044 glBindImageTexture(2, m_texture[2], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); 4045 glUseProgram(m_store_program); 4046 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 1.0f, 0.0f, 1.0f); 4047 glBindVertexArray(m_attribless_vao); 4048 glDrawArrays(GL_POINTS, 0, 4); 4049 4050 glUseProgram(m_copy_program); 4051 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_position_buffer); 4052 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_color_buffer); 4053 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_element_buffer); 4054 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4055 glDispatchCompute(1, 1, 1); 4056 4057 glClear(GL_COLOR_BUFFER_BIT); 4058 glUseProgram(m_draw_program); 4059 glBindVertexArray(m_draw_vao); 4060 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT); 4061 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0); 4062 4063 if (!CheckFB(vec4(0, 1, 0, 1))) 4064 { 4065 return ERROR; 4066 } 4067 4068 glUseProgram(m_store_program); 4069 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 0.0f, 1.0f, 1.0f); 4070 glBindVertexArray(m_attribless_vao); 4071 glDrawArrays(GL_POINTS, 0, 4); 4072 glUseProgram(m_copy_program); 4073 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4074 glDispatchCompute(1, 1, 1); 4075 glClear(GL_COLOR_BUFFER_BIT); 4076 glUseProgram(m_draw_program); 4077 glBindVertexArray(m_draw_vao); 4078 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT); 4079 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0); 4080 4081 if (!CheckFB(vec4(0, 0, 1, 1))) 4082 { 4083 return ERROR; 4084 } 4085 return NO_ERROR; 4086 } 4087 4088 virtual long Cleanup() 4089 { 4090 glDisable(GL_RASTERIZER_DISCARD); 4091 glUseProgram(0); 4092 glDeleteTextures(3, m_texture); 4093 glDeleteBuffers(1, &m_position_buffer); 4094 glDeleteBuffers(1, &m_color_buffer); 4095 glDeleteBuffers(1, &m_element_buffer); 4096 glDeleteProgram(m_store_program); 4097 glDeleteProgram(m_copy_program); 4098 glDeleteProgram(m_draw_program); 4099 glDeleteVertexArrays(1, &m_attribless_vao); 4100 glDeleteVertexArrays(1, &m_draw_vao); 4101 return NO_ERROR; 4102 } 4103 }; 4104 4105 //----------------------------------------------------------------------------- 4106 // 2.1.6 AdvancedSyncImageAccess2 4107 //----------------------------------------------------------------------------- 4108 class AdvancedSyncImageAccess2 : public ShaderImageLoadStoreBase 4109 { 4110 GLuint m_texture; 4111 GLuint m_store_program; 4112 GLuint m_draw_program; 4113 GLuint m_vao; 4114 GLuint m_vbo; 4115 GLuint m_buffer; 4116 4117 virtual long Setup() 4118 { 4119 m_texture = 0; 4120 m_store_program = 0; 4121 m_draw_program = 0; 4122 m_vao = 0; 4123 m_vbo = 0; 4124 m_buffer = 0; 4125 return NO_ERROR; 4126 } 4127 4128 virtual long Run() 4129 { 4130 const int kSize = 32; 4131 if (!IsVSFSAvailable(0, 1) || !IsSSBInVSFSAvailable(1)) 4132 return NOT_SUPPORTED; 4133 const char* const glsl_vs = 4134 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 4135 const char* const glsl_store_fs = 4136 NL "layout(rgba32f) writeonly uniform image2D g_image;" NL "uniform vec4 g_color;" NL "void main() {" NL 4137 " imageStore(g_image, ivec2(gl_FragCoord.xy), g_color);" NL " discard;" NL "}"; 4138 const char* const glsl_draw_fs = 4139 NL "layout(location = 0) out vec4 o_color;" NL "uniform sampler2D g_sampler;" NL 4140 "layout(std430) buffer OutputBuffer {" NL " uvec4 counter;" NL " vec4 data[];" NL "};" NL 4141 "void main() {" NL " uint idx = atomicAdd(counter[0], 1u);" NL 4142 " data[idx] = texelFetch(g_sampler, ivec2(gl_FragCoord.xy), 0);" NL "}"; 4143 m_store_program = BuildProgram(glsl_vs, glsl_store_fs); 4144 m_draw_program = BuildProgram(glsl_vs, glsl_draw_fs); 4145 4146 glGenTextures(1, &m_texture); 4147 glBindTexture(GL_TEXTURE_2D, m_texture); 4148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4150 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, getWindowWidth(), getWindowHeight()); 4151 glBindTexture(GL_TEXTURE_2D, 0); 4152 4153 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 4154 4155 glViewport(0, 0, kSize, kSize); 4156 std::vector<vec4> data_b(kSize * kSize + 1); 4157 glGenBuffers(1, &m_buffer); 4158 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4159 glBufferData(GL_SHADER_STORAGE_BUFFER, (kSize * kSize + 1) * 4 * 4, &data_b[0], GL_STATIC_DRAW); 4160 4161 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); 4162 glUseProgram(m_store_program); 4163 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 1.0f, 0.0f, 0.0f, 1.0f); 4164 glBindVertexArray(m_vao); 4165 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 4166 4167 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4168 4169 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 1.0f, 0.0f, 1.0f); 4170 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 4171 4172 glBindTexture(GL_TEXTURE_2D, m_texture); 4173 glUseProgram(m_draw_program); 4174 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 4175 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 4176 4177 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4178 vec4* map_data = 4179 (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 4 * 4, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 4180 4181 if (!CompareValues(map_data, kSize, vec4(0, 1, 0, 1))) 4182 return ERROR; 4183 return NO_ERROR; 4184 } 4185 4186 virtual long Cleanup() 4187 { 4188 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 4189 glUseProgram(0); 4190 glDeleteBuffers(1, &m_vbo); 4191 glDeleteTextures(1, &m_texture); 4192 glDeleteProgram(m_store_program); 4193 glDeleteProgram(m_draw_program); 4194 glDeleteVertexArrays(1, &m_vao); 4195 glDeleteBuffers(1, &m_buffer); 4196 return NO_ERROR; 4197 } 4198 }; 4199 4200 //----------------------------------------------------------------------------- 4201 // 2.2.1 AdvancedAllStagesOneImage 4202 //----------------------------------------------------------------------------- 4203 class AdvancedAllStagesOneImage : public ShaderImageLoadStoreBase 4204 { 4205 GLuint m_program; 4206 GLuint c_program; 4207 GLuint m_vao; 4208 GLuint m_vbo; 4209 GLuint m_buffer; 4210 GLuint m_texture; 4211 4212 virtual long Setup() 4213 { 4214 m_program = 0; 4215 c_program = 0; 4216 m_vao = 0; 4217 m_vbo = 0; 4218 m_buffer = 0; 4219 m_texture = 0; 4220 return NO_ERROR; 4221 } 4222 4223 virtual long Run() 4224 { 4225 const int kSize = 64; 4226 if (!IsVSFSAvailable(1, 1) || !IsImageAtomicSupported()) 4227 return NOT_SUPPORTED; 4228 const char* const glsl_vs = 4229 NL "layout(location = 0) in vec4 i_position;" NL 4230 "layout(r32ui, binding = 3) coherent uniform uimage2D g_image;" NL "void main() {" NL 4231 " gl_Position = i_position;" NL " imageAtomicAdd(g_image, ivec2(0, gl_VertexID), 100u);" NL "}"; 4232 const char* const glsl_fs = 4233 NL "#define KSIZE 64" NL "layout(r32ui, binding = 3) coherent uniform uimage2D g_image;" NL 4234 "void main() {" NL " imageAtomicAdd(g_image, ivec2(0, int(gl_FragCoord.x) & 0x03), 0x1u);" NL "}"; 4235 m_program = BuildProgram(glsl_vs, glsl_fs, true, true); 4236 const char* const glsl_cs = 4237 NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE) in;" NL 4238 "layout(r32ui, binding = 3) uniform uimage2D g_image;" NL "layout(std430) buffer out_data {" NL 4239 " uvec4 data[KSIZE];" NL "};" NL "void main() {" NL 4240 " uvec4 v = imageLoad(g_image, ivec2(0, gl_LocalInvocationID.x));" NL 4241 " data[gl_LocalInvocationIndex] = v;" NL "}"; 4242 c_program = CreateComputeProgram(glsl_cs, true); 4243 glUseProgram(m_program); 4244 4245 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 4246 4247 std::vector<uvec4> ui32(16); 4248 glGenTextures(1, &m_texture); 4249 glBindTexture(GL_TEXTURE_2D, m_texture); 4250 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 4, 4); 4251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4253 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RED_INTEGER, GL_UNSIGNED_INT, &ui32[0]); 4254 glBindTexture(GL_TEXTURE_2D, 0); 4255 4256 glBindImageTexture(3, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); 4257 4258 glViewport(0, 0, kSize, kSize); 4259 glBindVertexArray(m_vao); 4260 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1); 4261 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4262 4263 std::vector<vec4> data_b(4); 4264 glGenBuffers(1, &m_buffer); 4265 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4266 glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 4 * 4, &data_b[0], GL_STATIC_DRAW); 4267 glUseProgram(c_program); 4268 glDispatchCompute(1, 1, 1); 4269 4270 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4271 uvec4* map_data = (uvec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4 * 4, GL_MAP_READ_BIT); 4272 4273 if (!CompareValues(map_data, 2, uvec4(1024 + 100, 0, 0, 1))) 4274 return ERROR; 4275 return NO_ERROR; 4276 } 4277 4278 virtual long Cleanup() 4279 { 4280 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 4281 glUseProgram(0); 4282 glDeleteBuffers(1, &m_buffer); 4283 glDeleteBuffers(1, &m_vbo); 4284 glDeleteTextures(1, &m_texture); 4285 glDeleteProgram(m_program); 4286 glDeleteProgram(c_program); 4287 glDeleteVertexArrays(1, &m_vao); 4288 return NO_ERROR; 4289 } 4290 }; 4291 4292 //----------------------------------------------------------------------------- 4293 // 2.3.2 AdvancedMemoryOrder 4294 //----------------------------------------------------------------------------- 4295 class AdvancedMemoryOrderVSFS : public ShaderImageLoadStoreBase 4296 { 4297 GLuint m_buffer; 4298 GLuint m_texture[2]; 4299 GLuint m_program; 4300 GLuint m_vao; 4301 GLuint m_vbo; 4302 4303 virtual long Setup() 4304 { 4305 m_buffer = 0; 4306 m_program = 0; 4307 m_vao = 0; 4308 m_vbo = 0; 4309 return NO_ERROR; 4310 } 4311 4312 virtual long Run() 4313 { 4314 const int kSize = 11; 4315 if (!IsVSFSAvailable(1, 1) || !IsSSBInVSFSAvailable(1)) 4316 return NOT_SUPPORTED; 4317 const char* const glsl_vs = NL 4318 "layout(location = 0) in vec4 i_position;" NL "out vec4 vs_color;" NL 4319 "layout(r32f, binding = 0) uniform image2D g_image_vs;" NL "void main() {" NL 4320 " gl_Position = i_position;" NL " vs_color = vec4(41, 42, 43, 44);" NL 4321 " imageStore(g_image_vs, ivec2(gl_VertexID), vec4(1.0));" NL 4322 " imageStore(g_image_vs, ivec2(gl_VertexID), vec4(2.0));" NL 4323 " imageStore(g_image_vs, ivec2(gl_VertexID), vec4(3.0));" NL 4324 " if (imageLoad(g_image_vs, ivec2(gl_VertexID)) != vec4(3,0,0,1)) vs_color = vec4(21, 22, 23, 24);" NL "}"; 4325 const char* const glsl_fs = 4326 NL "#define KSIZE 11" NL "in vec4 vs_color;" NL "layout(r32f, binding = 1) uniform image2D g_image;" NL 4327 "layout(std430) buffer out_data {" NL " vec4 data[KSIZE*KSIZE*4];" NL "};" NL "void main() {" NL 4328 " ivec2 coord = ivec2(gl_FragCoord);" NL " int coordIndex = coord.x + KSIZE * coord.y;" NL 4329 " for (int i = 0; i < 4; ++i) {" NL " data[coordIndex + i * KSIZE*KSIZE] = vs_color;" NL " }" NL 4330 " for (int i = 0; i < 4; ++i) {" NL " imageStore(g_image, coord, vec4(i+50));" NL 4331 " vec4 v = imageLoad(g_image, coord);" NL " if (v.x != float(i+50)) {" NL 4332 " data[coordIndex + i * KSIZE*KSIZE] = vec4(v.xyz, i+10);" NL " break;" NL " }" NL " }" NL 4333 "}"; 4334 m_program = BuildProgram(glsl_vs, glsl_fs); 4335 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 4336 4337 std::vector<float> data(kSize * kSize); 4338 glGenTextures(2, m_texture); 4339 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 4340 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, kSize, kSize); 4341 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4342 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4343 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RED, GL_FLOAT, &data[0]); 4344 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 4345 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, kSize, kSize); 4346 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4347 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4348 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RED, GL_FLOAT, &data[0]); 4349 glBindTexture(GL_TEXTURE_2D, 0); 4350 4351 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); 4352 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); 4353 4354 std::vector<vec4> data_b(kSize * kSize * 4); 4355 glGenBuffers(1, &m_buffer); 4356 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4357 glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * kSize * kSize * 4 * 4, &data_b[0], GL_STATIC_DRAW); 4358 4359 glUseProgram(m_program); 4360 glViewport(0, 0, kSize, kSize); 4361 glBindVertexArray(m_vao); 4362 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1); 4363 4364 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4365 vec4* map_data = 4366 (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 4367 4368 if (!CompareValues(map_data, kSize * 2, vec4(41, 42, 43, 44))) 4369 return ERROR; 4370 return NO_ERROR; 4371 } 4372 4373 virtual long Cleanup() 4374 { 4375 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 4376 glUseProgram(0); 4377 glDeleteBuffers(1, &m_vbo); 4378 glDeleteBuffers(1, &m_buffer); 4379 glDeleteTextures(2, m_texture); 4380 glDeleteProgram(m_program); 4381 glDeleteVertexArrays(1, &m_vao); 4382 return NO_ERROR; 4383 } 4384 }; 4385 4386 //----------------------------------------------------------------------------- 4387 // 2.4.1 AdvancedSSOSimple 4388 //----------------------------------------------------------------------------- 4389 class AdvancedSSOSimple : public ShaderImageLoadStoreBase 4390 { 4391 bool pipeline; 4392 GLuint m_texture; 4393 GLuint m_pipeline[2]; 4394 GLuint m_vsp, m_fsp0, m_fsp1; 4395 GLuint m_vao, m_vbo; 4396 GLuint m_program[2]; 4397 GLuint c_program; 4398 GLuint m_buffer; 4399 4400 virtual long Setup() 4401 { 4402 c_program = 0; 4403 m_buffer = 0; 4404 CreateFullViewportQuad(&m_vao, &m_vbo, NULL); 4405 glGenTextures(1, &m_texture); 4406 const char* const glsl_vs = 4407 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 4408 const char* const glsl_fs0 = 4409 NL "layout(rgba32f, binding = 2) writeonly uniform image2D g_image[2];" NL "void main() {" NL 4410 " int i = g_image.length();" NL " imageStore(g_image[0], ivec2(gl_FragCoord), vec4(i+98));" NL 4411 " imageStore(g_image[1], ivec2(gl_FragCoord), vec4(i+99));" NL " discard;" NL "}"; 4412 const char* const glsl_fs1 = 4413 NL "layout(rgba32f, binding = 0) writeonly uniform image2D g_image[2];" NL "void main() {" NL 4414 " int i = g_image.length();" NL " imageStore(g_image[0], ivec2(gl_FragCoord), vec4(i+8));" NL 4415 " imageStore(g_image[1], ivec2(gl_FragCoord), vec4(i+9));" NL " discard;" NL "}"; 4416 if (pipeline) 4417 { 4418 glGenProgramPipelines(2, m_pipeline); 4419 m_vsp = BuildShaderProgram(GL_VERTEX_SHADER, glsl_vs); 4420 m_fsp0 = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs0); 4421 m_fsp1 = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs1); 4422 } 4423 else 4424 { 4425 m_program[0] = BuildProgram(glsl_vs, glsl_fs0); 4426 m_program[1] = BuildProgram(glsl_vs, glsl_fs1); 4427 } 4428 return NO_ERROR; 4429 } 4430 4431 virtual long Run() 4432 { 4433 if (!IsVSFSAvailable(0, 2)) 4434 return NOT_SUPPORTED; 4435 const int kSize = 4; 4436 4437 if (pipeline) 4438 { 4439 glUseProgramStages(m_pipeline[0], GL_VERTEX_SHADER_BIT, m_vsp); 4440 glUseProgramStages(m_pipeline[0], GL_FRAGMENT_SHADER_BIT, m_fsp0); 4441 glUseProgramStages(m_pipeline[1], GL_VERTEX_SHADER_BIT, m_vsp); 4442 glUseProgramStages(m_pipeline[1], GL_FRAGMENT_SHADER_BIT, m_fsp1); 4443 } 4444 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture); 4445 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4446 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4447 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 8); 4448 4449 glBindImageTexture(0, m_texture, 0, GL_FALSE, 6, GL_READ_WRITE, GL_RGBA32F); 4450 glBindImageTexture(1, m_texture, 0, GL_FALSE, 4, GL_READ_WRITE, GL_RGBA32F); 4451 glBindImageTexture(2, m_texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_RGBA32F); 4452 glBindImageTexture(3, m_texture, 0, GL_FALSE, 3, GL_READ_WRITE, GL_RGBA32F); 4453 4454 glBindVertexArray(m_vao); 4455 if (pipeline) 4456 glBindProgramPipeline(m_pipeline[0]); 4457 else 4458 glUseProgram(m_program[0]); 4459 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1); 4460 4461 if (pipeline) 4462 glBindProgramPipeline(m_pipeline[1]); 4463 else 4464 glUseProgram(m_program[1]); 4465 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 4466 4467 const char* const glsl_cs = 4468 NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4469 "layout(rgba32f, binding = 0) readonly uniform image2D g_image[4];" NL 4470 "layout(std430) buffer OutputBuffer {" NL " uvec4 counter;" NL " vec4 data[];" NL "};" NL 4471 "void main() {" NL " uint idx = atomicAdd(counter[0], 1u);" NL 4472 " data[idx][0] = (imageLoad(g_image[0], ivec2(gl_GlobalInvocationID))).z;" NL 4473 " data[idx][1] = (imageLoad(g_image[1], ivec2(gl_GlobalInvocationID))).z;" NL 4474 " data[idx][2] = (imageLoad(g_image[2], ivec2(gl_GlobalInvocationID))).z;" NL 4475 " data[idx][3] = (imageLoad(g_image[3], ivec2(gl_GlobalInvocationID))).z;" NL "}"; 4476 c_program = CreateComputeProgram(glsl_cs); 4477 glUseProgram(c_program); 4478 int wsx = (getWindowWidth() / kSize) * kSize; 4479 int wsy = (getWindowHeight() / kSize) * kSize; 4480 int minor = wsx > wsy ? wsy : wsx; 4481 4482 std::vector<vec4> data_b(wsx * wsy + 1); 4483 glGenBuffers(1, &m_buffer); 4484 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4485 glBufferData(GL_SHADER_STORAGE_BUFFER, (wsx * wsy + 1) * 4 * 4, &data_b[0], GL_STATIC_DRAW); 4486 4487 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4488 glDispatchCompute(wsx / kSize, wsy / kSize, 1); 4489 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4490 vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 4 * 4, wsx * wsy * 4 * 4, GL_MAP_READ_BIT); 4491 4492 if (!CompareValues(map_data, minor, vec4(10, 11, 100, 101))) 4493 return ERROR; 4494 return NO_ERROR; 4495 } 4496 4497 virtual long Cleanup() 4498 { 4499 glUseProgram(0); 4500 glDeleteBuffers(1, &m_vbo); 4501 glDeleteTextures(1, &m_texture); 4502 if (pipeline) 4503 { 4504 glDeleteProgram(m_vsp); 4505 glDeleteProgram(m_fsp0); 4506 glDeleteProgram(m_fsp1); 4507 glDeleteProgramPipelines(2, m_pipeline); 4508 } 4509 else 4510 { 4511 glDeleteProgram(m_program[0]); 4512 glDeleteProgram(m_program[1]); 4513 } 4514 glDeleteProgram(c_program); 4515 glDeleteVertexArrays(1, &m_vao); 4516 glDeleteBuffers(1, &m_buffer); 4517 return NO_ERROR; 4518 } 4519 4520 public: 4521 AdvancedSSOSimple() : pipeline(true) 4522 { 4523 } 4524 }; 4525 4526 //----------------------------------------------------------------------------- 4527 // 2.5 AdvancedCopyImage 4528 //----------------------------------------------------------------------------- 4529 class AdvancedCopyImageFS : public ShaderImageLoadStoreBase 4530 { 4531 GLuint m_texture[2]; 4532 GLuint m_program; 4533 GLuint c_program; 4534 GLuint m_vao, m_vbo, m_ebo; 4535 GLuint m_buffer; 4536 4537 virtual long Setup() 4538 { 4539 glGenTextures(2, m_texture); 4540 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo); 4541 glGenBuffers(1, &m_buffer); 4542 4543 const char* const glsl_vs = 4544 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 4545 const char* const glsl_fs = 4546 NL "layout(rgba32f, binding = 3) readonly uniform image2D g_input_image;" NL 4547 "layout(rgba32f, binding = 1) writeonly uniform image2D g_output_image;" NL "void main() {" NL 4548 " ivec2 coord = ivec2(gl_FragCoord);" NL 4549 " imageStore(g_output_image, coord, imageLoad(g_input_image, coord));" NL " discard;" NL "}"; 4550 m_program = BuildProgram(glsl_vs, glsl_fs); 4551 const char* const glsl_cs = NL 4552 "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4553 "layout(rgba32f, binding = 2) readonly uniform image2D g_image;" NL "layout(std430) buffer out_data {" NL 4554 " vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 4555 " data[gl_LocalInvocationIndex] = imageLoad(g_image, coord);" NL "}"; 4556 c_program = CreateComputeProgram(glsl_cs); 4557 4558 return NO_ERROR; 4559 } 4560 4561 virtual long Run() 4562 { 4563 const int kSize = 11; 4564 if (!IsVSFSAvailable(0, 2)) 4565 return NOT_SUPPORTED; 4566 4567 std::vector<vec4> data(kSize * kSize, vec4(7.0f)); 4568 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 4569 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize); 4570 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4572 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]); 4573 4574 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 4575 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize); 4576 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4577 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4578 4579 glBindTexture(GL_TEXTURE_2D, 0); 4580 4581 glBindImageTexture(3, m_texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 4582 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); 4583 glBindImageTexture(2, m_texture[1], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 4584 4585 std::vector<vec4> data_b(kSize * kSize); 4586 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4587 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data_b[0], GL_STATIC_DRAW); 4588 4589 glUseProgram(m_program); 4590 glBindVertexArray(m_vao); 4591 glViewport(0, 0, kSize, kSize); 4592 glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1); 4593 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4594 4595 glUseProgram(c_program); 4596 glDispatchCompute(1, 1, 1); 4597 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4598 vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 4599 4600 if (!CompareValues(map_data, kSize, vec4(7.f))) 4601 return ERROR; 4602 return NO_ERROR; 4603 } 4604 4605 virtual long Cleanup() 4606 { 4607 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 4608 glUseProgram(0); 4609 glDeleteBuffers(1, &m_vbo); 4610 glDeleteBuffers(1, &m_ebo); 4611 glDeleteBuffers(1, &m_buffer); 4612 glDeleteTextures(2, m_texture); 4613 glDeleteProgram(m_program); 4614 glDeleteProgram(c_program); 4615 glDeleteVertexArrays(1, &m_vao); 4616 return NO_ERROR; 4617 } 4618 }; 4619 4620 class AdvancedCopyImageCS : public ShaderImageLoadStoreBase 4621 { 4622 GLuint m_texture[2]; 4623 GLuint m_program; 4624 GLuint c_program; 4625 GLuint m_buffer; 4626 4627 virtual long Setup() 4628 { 4629 glGenTextures(2, m_texture); 4630 glGenBuffers(1, &m_buffer); 4631 4632 const char* const glsl_cs = 4633 NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4634 "layout(rgba32f, binding = 3) readonly uniform image2D g_input_image;" NL 4635 "layout(rgba32f, binding = 1) writeonly uniform image2D g_output_image;" NL "void main() {" NL 4636 " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 4637 " imageStore(g_output_image, coord, imageLoad(g_input_image, coord));" NL "}"; 4638 m_program = CreateComputeProgram(glsl_cs); 4639 const char* const glsl_cs_c = NL 4640 "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4641 "layout(rgba32f, binding = 2) readonly uniform image2D g_image;" NL "layout(std430) buffer out_data {" NL 4642 " vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 4643 " data[gl_LocalInvocationIndex] = imageLoad(g_image, coord);" NL "}"; 4644 c_program = CreateComputeProgram(glsl_cs_c); 4645 4646 return NO_ERROR; 4647 } 4648 4649 virtual long Run() 4650 { 4651 const int kSize = 11; 4652 4653 std::vector<vec4> data(kSize * kSize, vec4(7.0f)); 4654 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 4655 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize); 4656 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4658 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]); 4659 4660 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 4661 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize); 4662 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4663 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4664 4665 glBindTexture(GL_TEXTURE_2D, 0); 4666 4667 glBindImageTexture(3, m_texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 4668 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); 4669 glBindImageTexture(2, m_texture[1], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 4670 4671 std::vector<vec4> data_b(kSize * kSize); 4672 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4673 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data_b[0], GL_STATIC_DRAW); 4674 4675 glUseProgram(m_program); 4676 glDispatchCompute(1, 1, 1); 4677 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4678 4679 glUseProgram(c_program); 4680 glDispatchCompute(1, 1, 1); 4681 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4682 vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 4683 4684 if (!CompareValues(map_data, kSize, vec4(7.f))) 4685 return ERROR; 4686 return NO_ERROR; 4687 } 4688 4689 virtual long Cleanup() 4690 { 4691 glUseProgram(0); 4692 glDeleteBuffers(1, &m_buffer); 4693 glDeleteTextures(2, m_texture); 4694 glDeleteProgram(m_program); 4695 glDeleteProgram(c_program); 4696 return NO_ERROR; 4697 } 4698 }; 4699 4700 //----------------------------------------------------------------------------- 4701 // 2.6 AdvancedAllMips 4702 //----------------------------------------------------------------------------- 4703 class AdvancedAllMipsFS : public ShaderImageLoadStoreBase 4704 { 4705 GLuint m_texture; 4706 GLuint m_store_program, m_load_program; 4707 GLuint m_vao, m_vbo, m_ebo; 4708 GLuint m_buffer; 4709 4710 virtual long Setup() 4711 { 4712 glGenTextures(1, &m_texture); 4713 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo); 4714 glGenBuffers(1, &m_buffer); 4715 4716 const char* const glsl_vs = 4717 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 4718 const char* const glsl_store_fs = 4719 NL "layout(rgba32f, binding = 0) writeonly uniform image2D g_image[4];" NL "void main() {" NL 4720 " imageStore(g_image[0], ivec2(gl_FragCoord), vec4(23));" NL 4721 " imageStore(g_image[1], ivec2(gl_FragCoord), vec4(24));" NL 4722 " imageStore(g_image[2], ivec2(gl_FragCoord), vec4(25));" NL 4723 " imageStore(g_image[3], ivec2(gl_FragCoord), vec4(26));" NL " discard;" NL "}"; 4724 const char* const glsl_load_cs = NL 4725 "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4726 "layout(rgba32f, binding = 0) readonly uniform image2D g_image[4];" NL "layout(std430) buffer out_data {" NL 4727 " ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 4728 " data[gl_LocalInvocationIndex] = ivec4(2, 3, 4, 5);" NL " vec4 c0 = imageLoad(g_image[0], coord);" NL 4729 " vec4 c1 = imageLoad(g_image[1], coord);" NL " vec4 c2 = imageLoad(g_image[2], coord);" NL 4730 " vec4 c3 = imageLoad(g_image[3], coord);" NL 4731 " if ((all(lessThan(coord, ivec2(2))) && c0 != vec4(23)) || (any(greaterThanEqual(coord, ivec2(2))) && " 4732 "c0.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][0] = int(c0.x);" NL 4733 " if ((all(lessThan(coord, ivec2(4))) && c1 != vec4(24)) || (any(greaterThanEqual(coord, ivec2(4))) && " 4734 "c1.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][1] = int(c1.x);" NL 4735 " if ((all(lessThan(coord, ivec2(8))) && c2 != vec4(25)) || (any(greaterThanEqual(coord, ivec2(8))) && " 4736 "c2.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][2] = int(c2.x);" NL 4737 " if ((all(lessThan(coord, ivec2(16))) && c3 != vec4(26)) || (any(greaterThanEqual(coord, ivec2(16))) && " 4738 "c3.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][3] = int(c3.x);" NL "}"; 4739 m_store_program = BuildProgram(glsl_vs, glsl_store_fs); 4740 m_load_program = CreateComputeProgram(glsl_load_cs); 4741 4742 return NO_ERROR; 4743 } 4744 4745 virtual long Run() 4746 { 4747 const int kSize = 11; 4748 if (!IsVSFSAvailable(0, 4)) 4749 return NOT_SUPPORTED; 4750 glBindTexture(GL_TEXTURE_2D, m_texture); 4751 glTexStorage2D(GL_TEXTURE_2D, 8, GL_RGBA32F, 128, 128); 4752 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4753 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4754 glBindTexture(GL_TEXTURE_2D, 0); 4755 4756 glBindImageTexture(0, m_texture, 6, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4757 glBindImageTexture(1, m_texture, 5, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4758 glBindImageTexture(2, m_texture, 4, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4759 glBindImageTexture(3, m_texture, 3, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4760 4761 std::vector<GLubyte> data(kSize * kSize * 4 * 4); 4762 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4763 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW); 4764 4765 glViewport(0, 0, kSize, kSize); 4766 glBindVertexArray(m_vao); 4767 4768 glUseProgram(m_store_program); 4769 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); 4770 4771 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4772 4773 glUseProgram(m_load_program); 4774 glDispatchCompute(1, 1, 1); 4775 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4776 ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 4777 4778 if (!CompareValues(map_data, kSize, ivec4(2, 3, 4, 5))) 4779 return ERROR; 4780 return NO_ERROR; 4781 } 4782 4783 virtual long Cleanup() 4784 { 4785 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 4786 glUseProgram(0); 4787 glDeleteBuffers(1, &m_vbo); 4788 glDeleteBuffers(1, &m_ebo); 4789 glDeleteTextures(1, &m_texture); 4790 glDeleteProgram(m_store_program); 4791 glDeleteProgram(m_load_program); 4792 glDeleteVertexArrays(1, &m_vao); 4793 glDeleteBuffers(1, &m_buffer); 4794 return NO_ERROR; 4795 } 4796 }; 4797 4798 class AdvancedAllMipsCS : public ShaderImageLoadStoreBase 4799 { 4800 GLuint m_texture; 4801 GLuint m_store_program, m_load_program; 4802 GLuint m_buffer; 4803 4804 virtual long Setup() 4805 { 4806 glGenTextures(1, &m_texture); 4807 glGenBuffers(1, &m_buffer); 4808 4809 const char* const glsl_store_cs = 4810 NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4811 "layout(rgba32f, binding = 0) writeonly uniform image2D g_image[4];" NL "void main() {" NL 4812 " ivec2 coord = ivec2(gl_LocalInvocationID);" NL " imageStore(g_image[0], coord, vec4(23));" NL 4813 " imageStore(g_image[1], coord, vec4(24));" NL " imageStore(g_image[2], coord, vec4(25));" NL 4814 " imageStore(g_image[3], coord, vec4(26));" NL "}"; 4815 const char* const glsl_load_cs = NL 4816 "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4817 "layout(rgba32f, binding = 0) readonly uniform image2D g_image[4];" NL "layout(std430) buffer out_data {" NL 4818 " ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 4819 " data[gl_LocalInvocationIndex] = ivec4(2, 3, 4, 5);" NL " vec4 c0 = imageLoad(g_image[0], coord);" NL 4820 " vec4 c1 = imageLoad(g_image[1], coord);" NL " vec4 c2 = imageLoad(g_image[2], coord);" NL 4821 " vec4 c3 = imageLoad(g_image[3], coord);" NL 4822 " if ((all(lessThan(coord, ivec2(2))) && c0 != vec4(23)) || (any(greaterThanEqual(coord, ivec2(2))) && " 4823 "c0.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][0] = int(c0.x);" NL 4824 " if ((all(lessThan(coord, ivec2(4))) && c1 != vec4(24)) || (any(greaterThanEqual(coord, ivec2(4))) && " 4825 "c1.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][1] = int(c1.x);" NL 4826 " if ((all(lessThan(coord, ivec2(8))) && c2 != vec4(25)) || (any(greaterThanEqual(coord, ivec2(8))) && " 4827 "c2.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][2] = int(c2.x);" NL 4828 " if ((all(lessThan(coord, ivec2(16))) && c3 != vec4(26)) || (any(greaterThanEqual(coord, ivec2(16))) && " 4829 "c3.xyz != vec3(0.0)))" NL " data[gl_LocalInvocationIndex][3] = int(c3.x);" NL "}"; 4830 m_store_program = CreateComputeProgram(glsl_store_cs); 4831 m_load_program = CreateComputeProgram(glsl_load_cs); 4832 4833 return NO_ERROR; 4834 } 4835 4836 virtual long Run() 4837 { 4838 const int kSize = 11; 4839 glBindTexture(GL_TEXTURE_2D, m_texture); 4840 glTexStorage2D(GL_TEXTURE_2D, 8, GL_RGBA32F, 128, 128); 4841 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4842 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4843 glBindTexture(GL_TEXTURE_2D, 0); 4844 4845 glBindImageTexture(0, m_texture, 6, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4846 glBindImageTexture(1, m_texture, 5, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4847 glBindImageTexture(2, m_texture, 4, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4848 glBindImageTexture(3, m_texture, 3, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 4849 4850 std::vector<GLubyte> data(kSize * kSize * 4 * 4); 4851 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4852 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW); 4853 4854 glUseProgram(m_store_program); 4855 glDispatchCompute(1, 1, 1); 4856 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4857 4858 glUseProgram(m_load_program); 4859 glDispatchCompute(1, 1, 1); 4860 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4861 ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 4862 4863 if (!CompareValues(map_data, kSize, ivec4(2, 3, 4, 5))) 4864 return ERROR; 4865 return NO_ERROR; 4866 } 4867 4868 virtual long Cleanup() 4869 { 4870 glUseProgram(0); 4871 glDeleteTextures(1, &m_texture); 4872 glDeleteProgram(m_store_program); 4873 glDeleteProgram(m_load_program); 4874 glDeleteBuffers(1, &m_buffer); 4875 return NO_ERROR; 4876 } 4877 }; 4878 4879 //----------------------------------------------------------------------------- 4880 // 2.7 AdvancedCast 4881 //----------------------------------------------------------------------------- 4882 class AdvancedCastFS : public ShaderImageLoadStoreBase 4883 { 4884 GLuint m_texture[2]; 4885 GLuint m_program; 4886 GLuint c_program; 4887 GLuint m_vao, m_vbo, m_ebo; 4888 GLuint m_buffer; 4889 4890 virtual long Setup() 4891 { 4892 glGenTextures(2, m_texture); 4893 glGenBuffers(1, &m_buffer); 4894 m_program = 0; 4895 c_program = 0; 4896 return NO_ERROR; 4897 } 4898 4899 virtual long Run() 4900 { 4901 if (!IsVSFSAvailable(0, 2) || !IsImageAtomicSupported()) 4902 return NOT_SUPPORTED; 4903 const int kSize = 11; 4904 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo); 4905 4906 const char* const glsl_vs = 4907 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 4908 const char* const glsl_fs = 4909 NL "#define KSIZE 11" NL "layout(r32i, binding = 0) coherent uniform iimage2D g_image0;" NL 4910 "layout(r32ui, binding = 1) coherent uniform uimage2D g_image1;" NL "void main() {" NL 4911 " ivec2 coord = ivec2(gl_FragCoord.xy);" NL " imageAtomicAdd(g_image0, coord, 2);" NL 4912 " imageAtomicAdd(g_image0, coord, -1);" NL " imageAtomicAdd(g_image1, coord, 1u);" NL 4913 " imageAtomicAdd(g_image1, coord, 2u);" NL "}"; 4914 m_program = BuildProgram(glsl_vs, glsl_fs, false, true); 4915 4916 const char* const glsl_cs = NL 4917 "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 4918 "layout(r32i, binding = 0) uniform iimage2D gi_image;" NL 4919 "layout(r32ui, binding = 1) uniform uimage2D gu_image;" NL "layout(std430) buffer out_data {" NL 4920 " ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 4921 " data[gl_LocalInvocationIndex].yx = imageLoad(gi_image, coord).xy;" NL 4922 " data[gl_LocalInvocationIndex].wz = ivec2(imageLoad(gu_image, coord).xz);" NL "}"; 4923 c_program = CreateComputeProgram(glsl_cs); 4924 4925 std::vector<GLubyte> data(kSize * kSize * 4 * 4); 4926 glActiveTexture(GL_TEXTURE11); 4927 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 4928 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize); 4929 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 4930 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4931 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4932 glActiveTexture(GL_TEXTURE15); 4933 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 4934 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize); 4935 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 4936 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4937 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4938 4939 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I); 4940 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); 4941 4942 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 4943 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW); 4944 4945 glUseProgram(m_program); 4946 glBindVertexArray(m_vao); 4947 glViewport(0, 0, kSize, kSize); 4948 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); 4949 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4950 4951 glUseProgram(c_program); 4952 glDispatchCompute(1, 1, 1); 4953 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 4954 ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 4955 4956 if (!CompareValues(map_data, kSize, ivec4(0, 1, 0, 3))) 4957 return ERROR; 4958 return NO_ERROR; 4959 } 4960 4961 virtual long Cleanup() 4962 { 4963 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 4964 glUseProgram(0); 4965 glDeleteBuffers(1, &m_vbo); 4966 glDeleteBuffers(1, &m_ebo); 4967 glDeleteBuffers(1, &m_buffer); 4968 glDeleteTextures(2, m_texture); 4969 glDeleteProgram(m_program); 4970 glDeleteProgram(c_program); 4971 glDeleteVertexArrays(1, &m_vao); 4972 glActiveTexture(GL_TEXTURE0); 4973 return NO_ERROR; 4974 } 4975 }; 4976 4977 class AdvancedCastCS : public ShaderImageLoadStoreBase 4978 { 4979 GLuint m_texture[2]; 4980 GLuint m_program; 4981 GLuint c_program; 4982 GLuint m_buffer; 4983 4984 virtual long Setup() 4985 { 4986 glGenTextures(2, m_texture); 4987 glGenBuffers(1, &m_buffer); 4988 m_program = 0; 4989 c_program = 0; 4990 return NO_ERROR; 4991 } 4992 4993 virtual long Run() 4994 { 4995 const int kSize = 11; 4996 if (!IsImageAtomicSupported()) 4997 return NO_ERROR; 4998 4999 const char* const glsl_cs = 5000 NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 5001 "layout(r32i, binding = 0) coherent uniform iimage2D g_image0;" NL 5002 "layout(r32ui, binding = 1) coherent uniform uimage2D g_image1;" NL "void main() {" NL 5003 " ivec2 coord = ivec2(gl_LocalInvocationID);" NL " imageAtomicAdd(g_image0, coord, 222);" NL 5004 " imageAtomicAdd(g_image0, coord, -11);" NL " imageAtomicAdd(g_image1, coord, 1u);" NL 5005 " imageAtomicAdd(g_image1, coord, 2u);" NL "}"; 5006 m_program = CreateComputeProgram(glsl_cs, true); 5007 5008 const char* const glsl_cs_c = NL 5009 "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL 5010 "layout(r32i, binding = 0) uniform iimage2D gi_image;" NL 5011 "layout(r32ui, binding = 1) uniform uimage2D gu_image;" NL "layout(std430) buffer out_data {" NL 5012 " ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL " ivec2 coord = ivec2(gl_LocalInvocationID);" NL 5013 " data[gl_LocalInvocationIndex].yz = imageLoad(gi_image, coord).xw;" NL 5014 " data[gl_LocalInvocationIndex].wx = ivec2(imageLoad(gu_image, coord).xy);" NL "}"; 5015 c_program = CreateComputeProgram(glsl_cs_c); 5016 5017 std::vector<GLubyte> data(kSize * kSize * 4 * 4); 5018 glActiveTexture(GL_TEXTURE11); 5019 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 5020 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize); 5021 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 5022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 5023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 5024 glActiveTexture(GL_TEXTURE15); 5025 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 5026 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize); 5027 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 5028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 5029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 5030 5031 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I); 5032 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); 5033 5034 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 5035 glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW); 5036 5037 glUseProgram(m_program); 5038 glDispatchCompute(1, 1, 1); 5039 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 5040 5041 glUseProgram(c_program); 5042 glDispatchCompute(1, 1, 1); 5043 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 5044 ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT); 5045 5046 if (!CompareValues(map_data, kSize, ivec4(0, 211, 1, 3))) 5047 return ERROR; 5048 return NO_ERROR; 5049 } 5050 5051 virtual long Cleanup() 5052 { 5053 glUseProgram(0); 5054 glDeleteBuffers(1, &m_buffer); 5055 glDeleteTextures(2, m_texture); 5056 glDeleteProgram(m_program); 5057 glDeleteProgram(c_program); 5058 glActiveTexture(GL_TEXTURE0); 5059 return NO_ERROR; 5060 } 5061 }; 5062 //----------------------------------------------------------------------------- 5063 // 4.1 NegativeUniform 5064 //----------------------------------------------------------------------------- 5065 class NegativeUniform : public ShaderImageLoadStoreBase 5066 { 5067 GLuint m_program; 5068 5069 virtual long Setup() 5070 { 5071 m_program = 0; 5072 return NO_ERROR; 5073 } 5074 5075 virtual long Run() 5076 { 5077 const char* glsl_vs = 5078 NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL " gl_Position = i_position;" NL "}"; 5079 const char* glsl_fs = NL "layout(rgba32f) writeonly uniform image2D g_image;" NL "void main() {" NL 5080 " ivec2 coord = ivec2(gl_FragCoord.xy);" NL 5081 " imageStore(g_image, coord, vec4(0.0));" NL " discard;" NL "}"; 5082 m_program = BuildProgram(glsl_vs, glsl_fs); 5083 5084 GLint max_image_units; 5085 glGetIntegerv(GL_MAX_IMAGE_UNITS, &max_image_units); 5086 glUseProgram(m_program); 5087 bool status = true; 5088 GLint i = 1; 5089 glUniform1i(glGetUniformLocation(m_program, "g_image"), 1); 5090 if (glGetError() != GL_INVALID_OPERATION) 5091 status = false; 5092 glUniform1iv(glGetUniformLocation(m_program, "g_image"), 1, &i); 5093 if (glGetError() != GL_INVALID_OPERATION) 5094 status = false; 5095 glUniform1ui(glGetUniformLocation(m_program, "g_image"), 0); 5096 if (glGetError() != GL_INVALID_OPERATION) 5097 status = false; 5098 glUniform2i(glGetUniformLocation(m_program, "g_image"), 0, 0); 5099 if (glGetError() != GL_INVALID_OPERATION) 5100 status = false; 5101 5102 if (!status) 5103 { 5104 m_context.getTestContext().getLog() 5105 << tcu::TestLog::Message << "glUniform* should generate INVALID_OPERATION " 5106 << "if the location refers to an image variable." << tcu::TestLog::EndMessage; 5107 return ERROR; 5108 } 5109 5110 glUseProgram(0); 5111 glProgramUniform1i(m_program, glGetUniformLocation(m_program, "g_image"), 1); 5112 if (glGetError() != GL_INVALID_OPERATION) 5113 status = false; 5114 glProgramUniform1iv(m_program, glGetUniformLocation(m_program, "g_image"), 1, &i); 5115 if (glGetError() != GL_INVALID_OPERATION) 5116 status = false; 5117 glProgramUniform1ui(m_program, glGetUniformLocation(m_program, "g_image"), 0); 5118 if (glGetError() != GL_INVALID_OPERATION) 5119 status = false; 5120 glProgramUniform2i(m_program, glGetUniformLocation(m_program, "g_image"), 0, 0); 5121 if (glGetError() != GL_INVALID_OPERATION) 5122 status = false; 5123 5124 if (!status) 5125 { 5126 m_context.getTestContext().getLog() 5127 << tcu::TestLog::Message << "glProgramUniform* should generate INVALID_OPERATION " 5128 << "if the location refers to an image variable." << tcu::TestLog::EndMessage; 5129 return ERROR; 5130 } 5131 5132 return NO_ERROR; 5133 } 5134 5135 virtual long Cleanup() 5136 { 5137 glUseProgram(0); 5138 glDeleteProgram(m_program); 5139 return NO_ERROR; 5140 } 5141 }; 5142 5143 //----------------------------------------------------------------------------- 5144 // 4.2 NegativeBind 5145 //----------------------------------------------------------------------------- 5146 class NegativeBind : public ShaderImageLoadStoreBase 5147 { 5148 GLuint m_texture, m_texture2; 5149 5150 virtual long Setup() 5151 { 5152 m_texture = 0; 5153 m_texture2 = 0; 5154 return NO_ERROR; 5155 } 5156 5157 virtual long Run() 5158 { 5159 GLint max_image_units; 5160 glGetIntegerv(GL_MAX_IMAGE_UNITS, &max_image_units); 5161 glGenTextures(1, &m_texture); 5162 glBindTexture(GL_TEXTURE_2D, m_texture); 5163 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 64, 64); 5164 5165 glBindImageTexture(max_image_units, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 5166 if (glGetError() != GL_INVALID_VALUE) 5167 { 5168 m_context.getTestContext().getLog() 5169 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <unit> " 5170 << "is greater than or equal to the value of MAX_IMAGE_UNITS." << tcu::TestLog::EndMessage; 5171 return ERROR; 5172 } 5173 5174 glBindImageTexture(0, 123, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 5175 if (glGetError() != GL_INVALID_VALUE) 5176 { 5177 m_context.getTestContext().getLog() 5178 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <texture> " 5179 << "is not the name of an existing texture object." << tcu::TestLog::EndMessage; 5180 return ERROR; 5181 } 5182 5183 glBindImageTexture(1, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA); 5184 if (glGetError() != GL_INVALID_VALUE) 5185 { 5186 m_context.getTestContext().getLog() 5187 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <format> " 5188 << "is not a legal format." << tcu::TestLog::EndMessage; 5189 return ERROR; 5190 } 5191 5192 glBindImageTexture(1, m_texture, -1, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 5193 if (glGetError() != GL_INVALID_VALUE) 5194 { 5195 m_context.getTestContext().getLog() 5196 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <level> " 5197 << "is less than zero." << tcu::TestLog::EndMessage; 5198 return ERROR; 5199 } 5200 5201 glBindImageTexture(1, m_texture, 0, GL_FALSE, -1, GL_READ_ONLY, GL_RGBA32F); 5202 if (glGetError() != GL_INVALID_VALUE) 5203 { 5204 m_context.getTestContext().getLog() 5205 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <layer> " 5206 << "is less than zero." << tcu::TestLog::EndMessage; 5207 return ERROR; 5208 } 5209 5210 glGenTextures(1, &m_texture2); 5211 glBindTexture(GL_TEXTURE_2D, m_texture2); 5212 glBindImageTexture(1, m_texture2, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); 5213 if (glGetError() != GL_INVALID_OPERATION) 5214 { 5215 m_context.getTestContext().getLog() 5216 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <texture> " 5217 << "is a mutable texture object." << tcu::TestLog::EndMessage; 5218 return ERROR; 5219 } 5220 5221 return NO_ERROR; 5222 } 5223 5224 virtual long Cleanup() 5225 { 5226 glDeleteTextures(1, &m_texture); 5227 glDeleteTextures(1, &m_texture2); 5228 return NO_ERROR; 5229 } 5230 }; 5231 5232 //----------------------------------------------------------------------------- 5233 // 4.3 NegativeCompileErrors 5234 //----------------------------------------------------------------------------- 5235 class NegativeCompileErrors : public ShaderImageLoadStoreBase 5236 { 5237 virtual long Run() 5238 { 5239 if (!Compile( // writeonly & readonly qualifiers 5240 NL "layout(rgba32f) writeonly readonly uniform image2D g_image;" NL "void main() {" NL 5241 " vec4 o_color;" NL " o_color = imageLoad(g_image, ivec2(0));" NL "}")) 5242 return ERROR; 5243 5244 if (!Compile( // writeonly && reading 5245 NL "layout(rgba32f) writeonly uniform image2D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5246 " o_color = imageLoad(g_image, ivec2(0));" NL "}")) 5247 return ERROR; 5248 5249 if (!Compile( //readonly && writing 5250 NL "uniform vec4 i_color;" NL "layout(rgba32f) readonly uniform image2D g_image;" NL "void main() {" NL 5251 " vec4 o_color;" NL " imageStore(g_image, ivec2(0), i_color);" NL " o_color = i_color;" NL "}")) 5252 return ERROR; 5253 5254 if (!Compile( // no format layout && load 5255 NL "uniform image2D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5256 " o_color = imageLoad(g_image, ivec2(0));" NL "}")) 5257 return ERROR; 5258 5259 if (!Compile( // no fromat layout && readonly && load 5260 NL "readonly uniform image2D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5261 " o_color = imageLoad(g_image, ivec2(0));" NL "}")) 5262 return ERROR; 5263 5264 if (!Compile( // target type image1D not supported 5265 NL "layout(r32i) uniform image1D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5266 " o_color = vec4(1.0);" NL "}")) 5267 return ERROR; 5268 5269 if (!Compile( // format layout not compatible with type 5270 NL "layout(rgba16) writeonly uniform iimage2D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5271 " o_color = vec4(1.0);" NL "}")) 5272 return ERROR; 5273 5274 if (!Compile( // imageAtomicAdd doesn't support r32f 5275 NL "#extension GL_OES_shader_image_atomic : require" NL 5276 "layout(r32f) coherent uniform image2D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5277 " imageAtomicAdd(g_image, ivec2(1), 10);" NL " o_color = vec4(1.0);" NL "}")) 5278 return ERROR; 5279 5280 if (!Compile( // imageAtomicAdd doesn't support rgba8i 5281 NL "#extension GL_OES_shader_image_atomic : require" NL 5282 "layout(rgba8i) coherent uniform iimage2D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5283 " imageAtomicAdd(g_image, ivec2(1), 1);" NL " o_color = vec4(1.0);" NL "}")) 5284 return ERROR; 5285 5286 if (!Compile( // format layout not compatible with type 5287 NL "layout(r32ui) uniform iimage3D g_image;" NL "void main() {" NL " vec4 o_color;" NL 5288 " imageStore(g_image, ivec3(1), ivec4(1));" NL " o_color = vec4(1.0);" NL "}")) 5289 return ERROR; 5290 5291 if (!Compile( // format layout not compatible with type 5292 NL "layout(r32f) uniform uimage2DArray g_image;" NL "void main() {" NL " vec4 o_color;" NL 5293 " imageStore(g_image, ivec3(0), uvec4(1));" NL " o_color = vec4(1.0);" NL "}")) 5294 return ERROR; 5295 5296 if (!Compile( // wrong function argument type 5297 NL "layout(r32f) coherent uniform image2D g_image;" NL "vec4 Load(iimage2D image) {" NL 5298 " return imageLoad(image, vec2(0));" NL "}" NL "void main() {" NL " vec4 o_color;" NL 5299 " o_color = Load(g_image);" NL "}")) 5300 return ERROR; 5301 5302 return NO_ERROR; 5303 } 5304 5305 bool Compile(const std::string& source) 5306 { 5307 const char* const csVer = "#version 310 es" NL "layout(local_size_x = 1) in;"; 5308 const char* const src[3] = { csVer, kGLSLPrec, source.c_str() }; 5309 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 5310 glShaderSource(sh, 3, src, NULL); 5311 glCompileShader(sh); 5312 5313 GLchar log[1024]; 5314 glGetShaderInfoLog(sh, sizeof(log), NULL, log); 5315 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n" 5316 << log << tcu::TestLog::EndMessage; 5317 5318 GLint status; 5319 glGetShaderiv(sh, GL_COMPILE_STATUS, &status); 5320 glDeleteShader(sh); 5321 5322 if (status == GL_TRUE) 5323 { 5324 m_context.getTestContext().getLog() 5325 << tcu::TestLog::Message << "Compilation should fail [compute shader]." << tcu::TestLog::EndMessage; 5326 return false; 5327 } 5328 const char* const fsVer = "#version 310 es" NL "precision highp float;"; 5329 const char* const fsrc[3] = { fsVer, kGLSLPrec, source.c_str() }; 5330 const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER); 5331 glShaderSource(fsh, 3, fsrc, NULL); 5332 glCompileShader(fsh); 5333 5334 glGetShaderInfoLog(fsh, sizeof(log), NULL, log); 5335 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n" 5336 << log << tcu::TestLog::EndMessage; 5337 glGetShaderiv(fsh, GL_COMPILE_STATUS, &status); 5338 glDeleteShader(fsh); 5339 5340 if (status == GL_TRUE) 5341 { 5342 m_context.getTestContext().getLog() 5343 << tcu::TestLog::Message << "Compilation should fail [fragment shader]." << tcu::TestLog::EndMessage; 5344 return false; 5345 } 5346 5347 return true; 5348 } 5349 }; 5350 5351 //----------------------------------------------------------------------------- 5352 // 4.4 NegativeLinkErrors 5353 //----------------------------------------------------------------------------- 5354 class NegativeLinkErrors : public ShaderImageLoadStoreBase 5355 { 5356 virtual long Run() 5357 { 5358 if (!IsVSFSAvailable(1, 1)) 5359 return NOT_SUPPORTED; 5360 if (!Link(NL "layout(location = 0) in vec4 i_position;" NL 5361 "layout(rgba32f) writeonly uniform highp image3D g_image;" NL "void main() {" NL 5362 " imageStore(g_image, ivec3(gl_VertexID), vec4(0));" NL " gl_Position = i_position;" NL "}", 5363 5364 NL "precision highp float;" NL "layout(location = 0) out vec4 o_color;" NL 5365 "layout(rgba32f) writeonly uniform highp image2D g_image;" NL "void main() {" NL 5366 " imageStore(g_image, ivec2(gl_FragCoord), vec4(1.0));" NL " o_color = vec4(1.0);" NL "}")) 5367 return ERROR; 5368 5369 if (!Link(NL "layout(location = 0) in vec4 i_position;" NL 5370 "layout(rgba32f) writeonly uniform highp image2D g_image;" NL "void main() {" NL 5371 " imageStore(g_image, ivec2(gl_VertexID), vec4(0));" NL " gl_Position = i_position;" NL "}", 5372 5373 NL "precision highp float;" NL "layout(location = 0) out vec4 o_color;" NL 5374 "layout(r32f) writeonly uniform highp image2D g_image;" NL "void main() {" NL 5375 " imageStore(g_image, ivec2(gl_FragCoord), vec4(1.0));" NL " o_color = vec4(1.0);" NL "}")) 5376 return ERROR; 5377 5378 return NO_ERROR; 5379 } 5380 5381 bool Link(const std::string& vs, const std::string& fs) 5382 { 5383 const char* const sVer = "#version 310 es"; 5384 const GLuint p = glCreateProgram(); 5385 5386 const GLuint vsh = glCreateShader(GL_VERTEX_SHADER); 5387 glAttachShader(p, vsh); 5388 glDeleteShader(vsh); 5389 const char* const vssrc[2] = { sVer, vs.c_str() }; 5390 glShaderSource(vsh, 2, vssrc, NULL); 5391 glCompileShader(vsh); 5392 5393 const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER); 5394 glAttachShader(p, fsh); 5395 glDeleteShader(fsh); 5396 const char* const fssrc[2] = { sVer, fs.c_str() }; 5397 glShaderSource(fsh, 2, fssrc, NULL); 5398 glCompileShader(fsh); 5399 5400 GLint status; 5401 glGetShaderiv(vsh, GL_COMPILE_STATUS, &status); 5402 if (status == GL_FALSE) 5403 { 5404 glDeleteProgram(p); 5405 m_context.getTestContext().getLog() 5406 << tcu::TestLog::Message << "VS compilation should be ok." << tcu::TestLog::EndMessage; 5407 return false; 5408 } 5409 glGetShaderiv(fsh, GL_COMPILE_STATUS, &status); 5410 if (status == GL_FALSE) 5411 { 5412 glDeleteProgram(p); 5413 m_context.getTestContext().getLog() 5414 << tcu::TestLog::Message << "FS compilation should be ok." << tcu::TestLog::EndMessage; 5415 return false; 5416 } 5417 5418 glLinkProgram(p); 5419 5420 GLchar log[1024]; 5421 glGetProgramInfoLog(p, sizeof(log), NULL, log); 5422 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n" 5423 << log << tcu::TestLog::EndMessage; 5424 5425 glGetProgramiv(p, GL_LINK_STATUS, &status); 5426 glDeleteProgram(p); 5427 5428 if (status == GL_TRUE) 5429 { 5430 m_context.getTestContext().getLog() 5431 << tcu::TestLog::Message << "Link operation should fail." << tcu::TestLog::EndMessage; 5432 return false; 5433 } 5434 5435 return true; 5436 } 5437 }; 5438 5439 } // anonymous namespace 5440 5441 ShaderImageLoadStoreTests::ShaderImageLoadStoreTests(deqp::Context& context) 5442 : TestCaseGroup(context, "shader_image_load_store", "") 5443 { 5444 } 5445 5446 ShaderImageLoadStoreTests::~ShaderImageLoadStoreTests(void) 5447 { 5448 } 5449 5450 void ShaderImageLoadStoreTests::init() 5451 { 5452 using namespace deqp; 5453 addChild(new TestSubcase(m_context, "basic-api-get", TestSubcase::Create<BasicAPIGet>)); 5454 addChild(new TestSubcase(m_context, "basic-api-bind", TestSubcase::Create<BasicAPIBind>)); 5455 addChild(new TestSubcase(m_context, "basic-api-barrier", TestSubcase::Create<BasicAPIBarrier>)); 5456 addChild(new TestSubcase(m_context, "basic-api-barrier-byRegion", TestSubcase::Create<BasicAPIBarrierByRegion>)); 5457 addChild(new TestSubcase(m_context, "basic-api-texParam", TestSubcase::Create<BasicAPITexParam>)); 5458 addChild(new TestSubcase(m_context, "basic-allFormats-store-fs", TestSubcase::Create<BasicAllFormatsStoreFS>)); 5459 addChild(new TestSubcase(m_context, "basic-allFormats-store-cs", TestSubcase::Create<BasicAllFormatsStoreCS>)); 5460 addChild(new TestSubcase(m_context, "basic-allFormats-load-fs", TestSubcase::Create<BasicAllFormatsLoadFS>)); 5461 addChild(new TestSubcase(m_context, "basic-allFormats-load-cs", TestSubcase::Create<BasicAllFormatsLoadCS>)); 5462 addChild(new TestSubcase(m_context, "basic-allFormats-loadStoreComputeStage", 5463 TestSubcase::Create<BasicAllFormatsLoadStoreComputeStage>)); 5464 addChild(new TestSubcase(m_context, "basic-allTargets-store-fs", TestSubcase::Create<BasicAllTargetsStoreFS>)); 5465 addChild(new TestSubcase(m_context, "basic-allTargets-store-cs", TestSubcase::Create<BasicAllTargetsStoreCS>)); 5466 addChild(new TestSubcase(m_context, "basic-allTargets-load-fs", TestSubcase::Create<BasicAllTargetsLoadFS>)); 5467 addChild(new TestSubcase(m_context, "basic-allTargets-load-cs", TestSubcase::Create<BasicAllTargetsLoadCS>)); 5468 addChild(new TestSubcase(m_context, "basic-allTargets-atomicFS", TestSubcase::Create<BasicAllTargetsAtomicFS>)); 5469 addChild( 5470 new TestSubcase(m_context, "basic-allTargets-loadStoreVS", TestSubcase::Create<BasicAllTargetsLoadStoreVS>)); 5471 addChild( 5472 new TestSubcase(m_context, "basic-allTargets-loadStoreCS", TestSubcase::Create<BasicAllTargetsLoadStoreCS>)); 5473 addChild(new TestSubcase(m_context, "basic-allTargets-atomicVS", TestSubcase::Create<BasicAllTargetsAtomicVS>)); 5474 addChild(new TestSubcase(m_context, "basic-allTargets-atomicCS", TestSubcase::Create<BasicAllTargetsAtomicCS>)); 5475 addChild(new TestSubcase(m_context, "basic-glsl-misc-fs", TestSubcase::Create<BasicGLSLMiscFS>)); 5476 addChild(new TestSubcase(m_context, "basic-glsl-misc-cs", TestSubcase::Create<BasicGLSLMiscCS>)); 5477 addChild(new TestSubcase(m_context, "basic-glsl-earlyFragTests", TestSubcase::Create<BasicGLSLEarlyFragTests>)); 5478 addChild(new TestSubcase(m_context, "basic-glsl-const", TestSubcase::Create<BasicGLSLConst>)); 5479 addChild(new TestSubcase(m_context, "advanced-sync-imageAccess", TestSubcase::Create<AdvancedSyncImageAccess>)); 5480 addChild(new TestSubcase(m_context, "advanced-sync-vertexArray", TestSubcase::Create<AdvancedSyncVertexArray>)); 5481 addChild(new TestSubcase(m_context, "advanced-sync-imageAccess2", TestSubcase::Create<AdvancedSyncImageAccess2>)); 5482 addChild(new TestSubcase(m_context, "advanced-allStages-oneImage", TestSubcase::Create<AdvancedAllStagesOneImage>)); 5483 addChild(new TestSubcase(m_context, "advanced-memory-order-vsfs", TestSubcase::Create<AdvancedMemoryOrderVSFS>)); 5484 addChild(new TestSubcase(m_context, "advanced-sso-simple", TestSubcase::Create<AdvancedSSOSimple>)); 5485 addChild(new TestSubcase(m_context, "advanced-copyImage-fs", TestSubcase::Create<AdvancedCopyImageFS>)); 5486 addChild(new TestSubcase(m_context, "advanced-copyImage-cs", TestSubcase::Create<AdvancedCopyImageCS>)); 5487 addChild(new TestSubcase(m_context, "advanced-allMips-fs", TestSubcase::Create<AdvancedAllMipsFS>)); 5488 addChild(new TestSubcase(m_context, "advanced-allMips-cs", TestSubcase::Create<AdvancedAllMipsCS>)); 5489 addChild(new TestSubcase(m_context, "advanced-cast-fs", TestSubcase::Create<AdvancedCastFS>)); 5490 addChild(new TestSubcase(m_context, "advanced-cast-cs", TestSubcase::Create<AdvancedCastCS>)); 5491 addChild(new TestSubcase(m_context, "negative-uniform", TestSubcase::Create<NegativeUniform>)); 5492 addChild(new TestSubcase(m_context, "negative-bind", TestSubcase::Create<NegativeBind>)); 5493 addChild(new TestSubcase(m_context, "negative-compileErrors", TestSubcase::Create<NegativeCompileErrors>)); 5494 addChild(new TestSubcase(m_context, "negative-linkErrors", TestSubcase::Create<NegativeLinkErrors>)); 5495 } 5496 5497 } // namespace es31compatibility 5498 } // namespace gl4cts 5499