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 "gl4cShaderImageSizeTests.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 33 namespace gl4cts 34 { 35 using namespace glw; 36 37 namespace 38 { 39 typedef tcu::Vec3 vec3; 40 typedef tcu::Vec4 vec4; 41 typedef tcu::IVec4 ivec4; 42 typedef tcu::UVec4 uvec4; 43 44 class ShaderImageSizeBase : public deqp::SubcaseBase 45 { 46 virtual std::string Title() 47 { 48 return ""; 49 } 50 51 virtual std::string Purpose() 52 { 53 return ""; 54 } 55 56 virtual std::string Method() 57 { 58 return ""; 59 } 60 61 virtual std::string PassCriteria() 62 { 63 return ""; 64 } 65 66 public: 67 bool SupportedInVS(int requiredVS) 68 { 69 GLint imagesVS; 70 glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &imagesVS); 71 if (imagesVS >= requiredVS) 72 return true; 73 else 74 { 75 std::ostringstream reason; 76 reason << "Required " << requiredVS << " VS image uniforms but only " << imagesVS << " available." 77 << std::endl; 78 OutputNotSupported(reason.str()); 79 return false; 80 } 81 } 82 83 bool SupportedInTCS(int requiredTCS) 84 { 85 GLint imagesTCS; 86 glGetIntegerv(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, &imagesTCS); 87 if (imagesTCS >= requiredTCS) 88 return true; 89 else 90 { 91 std::ostringstream reason; 92 reason << "Required " << requiredTCS << " TCS image uniforms but only " << imagesTCS << " available." 93 << std::endl; 94 OutputNotSupported(reason.str()); 95 return false; 96 } 97 } 98 99 bool SupportedInTES(int requiredTES) 100 { 101 GLint imagesTES; 102 glGetIntegerv(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, &imagesTES); 103 if (imagesTES >= requiredTES) 104 return true; 105 else 106 { 107 std::ostringstream reason; 108 reason << "Required " << requiredTES << " TES image uniforms but only " << imagesTES << " available." 109 << std::endl; 110 OutputNotSupported(reason.str()); 111 return false; 112 } 113 } 114 115 bool SupportedInGS(int requiredGS) 116 { 117 GLint imagesGS; 118 glGetIntegerv(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, &imagesGS); 119 if (imagesGS >= requiredGS) 120 return true; 121 else 122 { 123 std::ostringstream reason; 124 reason << "Required " << requiredGS << " GS image uniforms but only " << imagesGS << " available." 125 << std::endl; 126 OutputNotSupported(reason.str()); 127 return false; 128 } 129 } 130 131 bool SupportedInStage(int stage, int required) 132 { 133 switch (stage) 134 { 135 case 0: 136 return SupportedInVS(required); 137 case 1: 138 return SupportedInTCS(required); 139 case 2: 140 return SupportedInTES(required); 141 case 3: 142 return SupportedInGS(required); 143 default: 144 return true; 145 } 146 } 147 148 bool SupportedSamples(int required) 149 { 150 int i; 151 glGetIntegerv(GL_MAX_IMAGE_SAMPLES, &i); 152 if (i >= required) 153 return true; 154 else 155 { 156 std::ostringstream reason; 157 reason << "Required " << required << " image samples but only " << i << " available." << std::endl; 158 OutputNotSupported(reason.str()); 159 return false; 160 } 161 } 162 163 int getWindowWidth() 164 { 165 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 166 return renderTarget.getWidth(); 167 } 168 169 int getWindowHeight() 170 { 171 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 172 return renderTarget.getHeight(); 173 } 174 175 inline bool ColorEqual(const vec4& c0, const vec4& c1, const vec4& epsilon) 176 { 177 if (fabs(c0[0] - c1[0]) > epsilon[0]) 178 return false; 179 if (fabs(c0[1] - c1[1]) > epsilon[1]) 180 return false; 181 if (fabs(c0[2] - c1[2]) > epsilon[2]) 182 return false; 183 if (fabs(c0[3] - c1[3]) > epsilon[3]) 184 return false; 185 return true; 186 } 187 188 template <class T> 189 std::string ToString(T v) 190 { 191 std::ostringstream s; 192 s << "["; 193 for (int i = 0; i < 4; ++i) 194 s << v[i] << (i == 3 ? "" : ","); 195 s << "]"; 196 return s.str(); 197 } 198 199 bool ValidateReadBuffer(int x, int y, int w, int h, const vec4& expected) 200 { 201 bool status = true; 202 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 203 const tcu::PixelFormat& pixelFormat = renderTarget.getPixelFormat(); 204 vec4 g_color_eps = vec4( 205 1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits), 206 1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits)); 207 208 std::vector<vec4> fb(w * h); 209 glReadPixels(x, y, w, h, GL_RGBA, GL_FLOAT, &fb[0]); 210 211 for (int yy = 0; yy < h; ++yy) 212 { 213 for (int xx = 0; xx < w; ++xx) 214 { 215 const int idx = yy * w + xx; 216 if (!ColorEqual(fb[idx], expected, g_color_eps)) 217 { 218 m_context.getTestContext().getLog() 219 << tcu::TestLog::Message << "First bad color: " << ToString(fb[idx]) 220 << tcu::TestLog::EndMessage; 221 status = false; 222 return status; 223 } 224 } 225 } 226 return status; 227 } 228 229 bool CheckProgram(GLuint program) 230 { 231 if (program == 0) 232 return true; 233 GLint status; 234 glGetProgramiv(program, GL_LINK_STATUS, &status); 235 236 if (status == GL_FALSE) 237 { 238 GLint attached_shaders; 239 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); 240 241 if (attached_shaders > 0) 242 { 243 std::vector<GLuint> shaders(attached_shaders); 244 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]); 245 246 for (GLint i = 0; i < attached_shaders; ++i) 247 { 248 GLenum type; 249 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type)); 250 switch (type) 251 { 252 case GL_VERTEX_SHADER: 253 m_context.getTestContext().getLog() 254 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage; 255 break; 256 case GL_TESS_CONTROL_SHADER: 257 m_context.getTestContext().getLog() 258 << tcu::TestLog::Message << "*** Tessellation Control Shader ***" 259 << tcu::TestLog::EndMessage; 260 break; 261 case GL_TESS_EVALUATION_SHADER: 262 m_context.getTestContext().getLog() 263 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***" 264 << tcu::TestLog::EndMessage; 265 break; 266 case GL_GEOMETRY_SHADER: 267 m_context.getTestContext().getLog() 268 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage; 269 break; 270 case GL_FRAGMENT_SHADER: 271 m_context.getTestContext().getLog() 272 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage; 273 break; 274 case GL_COMPUTE_SHADER: 275 m_context.getTestContext().getLog() 276 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage; 277 break; 278 default: 279 m_context.getTestContext().getLog() 280 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage; 281 break; 282 } 283 GLint length; 284 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length); 285 if (length > 0) 286 { 287 std::vector<GLchar> source(length); 288 glGetShaderSource(shaders[i], length, NULL, &source[0]); 289 m_context.getTestContext().getLog() 290 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage; 291 } 292 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length); 293 if (length > 0) 294 { 295 std::vector<GLchar> log(length); 296 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]); 297 m_context.getTestContext().getLog() 298 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 299 } 300 } 301 } 302 GLint length; 303 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 304 if (length > 0) 305 { 306 std::vector<GLchar> log(length); 307 glGetProgramInfoLog(program, length, NULL, &log[0]); 308 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 309 } 310 } 311 return status == GL_TRUE ? true : false; 312 } 313 }; 314 315 template <typename T> 316 std::string ImageTypePrefix(); 317 318 template <> 319 std::string ImageTypePrefix<vec4>() 320 { 321 return ""; 322 } 323 324 template <> 325 std::string ImageTypePrefix<ivec4>() 326 { 327 return "i"; 328 } 329 330 template <> 331 std::string ImageTypePrefix<uvec4>() 332 { 333 return "u"; 334 } 335 336 template <typename T> 337 std::string ImageFormatPostfix(); 338 339 template <> 340 std::string ImageFormatPostfix<vec4>() 341 { 342 return "f"; 343 } 344 345 template <> 346 std::string ImageFormatPostfix<ivec4>() 347 { 348 return "i"; 349 } 350 351 template <> 352 std::string ImageFormatPostfix<uvec4>() 353 { 354 return "ui"; 355 } 356 357 template <typename T> 358 GLenum TexInternalFormat(); 359 360 template <> 361 GLenum TexInternalFormat<vec4>() 362 { 363 return GL_RGBA32F; 364 } 365 366 template <> 367 GLenum TexInternalFormat<ivec4>() 368 { 369 return GL_RGBA32I; 370 } 371 372 template <> 373 GLenum TexInternalFormat<uvec4>() 374 { 375 return GL_RGBA32UI; 376 } 377 378 template <typename T> 379 GLenum TexType(); 380 381 template <> 382 GLenum TexType<vec4>() 383 { 384 return GL_FLOAT; 385 } 386 387 template <> 388 GLenum TexType<ivec4>() 389 { 390 return GL_INT; 391 } 392 393 template <> 394 GLenum TexType<uvec4>() 395 { 396 return GL_UNSIGNED_INT; 397 } 398 399 template <typename T> 400 GLenum TexFormat(); 401 402 template <> 403 GLenum TexFormat<vec4>() 404 { 405 return GL_RGBA; 406 } 407 408 template <> 409 GLenum TexFormat<ivec4>() 410 { 411 return GL_RGBA_INTEGER; 412 } 413 414 template <> 415 GLenum TexFormat<uvec4>() 416 { 417 return GL_RGBA_INTEGER; 418 } 419 //============================================================================= 420 // ImageSizeMachine 421 //----------------------------------------------------------------------------- 422 class ImageSizeMachine : public deqp::GLWrapper 423 { 424 GLuint m_pipeline; 425 GLuint m_program[3]; 426 GLuint m_vertex_array; 427 GLuint m_texture; 428 429 template <typename T> 430 std::string GenShader(int stage, bool ms_and_1d, bool subroutine) 431 { 432 std::ostringstream os; 433 os << "#version 430 core"; 434 if (stage == 4) 435 { // CS 436 os << NL "#extension GL_ARB_compute_shader : require"; 437 } 438 os << NL "layout(binding = 0, rgba32i) writeonly uniform iimage2D g_result;"; 439 if (ms_and_1d == false) 440 { 441 os << NL "layout(binding = 1, rgba32" << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>() 442 << "image2D g_image_2d;" NL "layout(binding = 2, rgba32" << ImageFormatPostfix<T>() << ") uniform " 443 << ImageTypePrefix<T>() << "image3D g_image_3d;" NL "layout(binding = 3, rgba32" 444 << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>() 445 << "imageCube g_image_cube;" NL "layout(binding = 4, rgba32" << ImageFormatPostfix<T>() << ") uniform " 446 << ImageTypePrefix<T>() << "imageCubeArray g_image_cube_array;" NL "layout(binding = 5, rgba32" 447 << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>() 448 << "image2DRect g_image_rect;" NL "layout(binding = 6, rgba32" << ImageFormatPostfix<T>() << ") uniform " 449 << ImageTypePrefix<T>() << "image2DArray g_image_2d_array;" NL "layout(binding = 7, rgba32" 450 << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>() << "imageBuffer g_image_buffer;"; 451 } 452 else 453 { 454 os << NL "layout(binding = 1, rgba32" << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>() 455 << "image1D g_image_1d;" NL "layout(binding = 2, rgba32" << ImageFormatPostfix<T>() << ") uniform " 456 << ImageTypePrefix<T>() << "image1DArray g_image_1d_array;" NL "layout(binding = 3, rgba32" 457 << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>() 458 << "image2DMS g_image_2dms;" NL "layout(binding = 4, rgba32" << ImageFormatPostfix<T>() << ") uniform " 459 << ImageTypePrefix<T>() << "image2DMSArray g_image_2dms_array;"; 460 } 461 if (subroutine) 462 { 463 os << NL "subroutine void FuncType(int coord);" NL "subroutine uniform FuncType g_func;"; 464 } 465 if (stage == 0) 466 { // VS 467 os << NL "void main() {" NL " int coord = gl_VertexID;"; 468 } 469 else if (stage == 1) 470 { // TCS 471 os << NL "layout(vertices = 1) out;" NL "void main() {" NL " gl_TessLevelInner[0] = 1;" NL 472 " gl_TessLevelInner[1] = 1;" NL " gl_TessLevelOuter[0] = 1;" NL " gl_TessLevelOuter[1] = 1;" NL 473 " gl_TessLevelOuter[2] = 1;" NL " gl_TessLevelOuter[3] = 1;" NL " int coord = gl_PrimitiveID;"; 474 } 475 else if (stage == 2) 476 { // TES 477 os << NL "layout(quads, point_mode) in;" NL "void main() {" NL " int coord = gl_PrimitiveID;"; 478 } 479 else if (stage == 3) 480 { // GS 481 os << NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL "void main() {" NL 482 " int coord = gl_PrimitiveIDIn;"; 483 } 484 else if (stage == 4) 485 { // CS 486 os << NL "layout(local_size_x = 1) in;" NL "void main() {" NL " int coord = int(gl_GlobalInvocationID.x);"; 487 } 488 else if (stage == 5) 489 { // FS 490 os << NL "void main() {" NL " int coord = gl_PrimitiveID;"; 491 } 492 if (subroutine) 493 { 494 os << NL " g_func(coord);" NL "}" NL "subroutine(FuncType) void Func0(int coord) {"; 495 } 496 if (ms_and_1d == false) 497 { 498 os << NL " imageStore(g_result, ivec2(coord, 0), ivec4(imageSize(g_image_2d), 0, 0));" NL 499 " imageStore(g_result, ivec2(coord, 1), ivec4(imageSize(g_image_3d), 0));" NL 500 " imageStore(g_result, ivec2(coord, 2), ivec4(imageSize(g_image_cube), 0, 0));" NL 501 " imageStore(g_result, ivec2(coord, 3), ivec4(imageSize(g_image_cube_array), 0));" NL 502 " imageStore(g_result, ivec2(coord, 4), ivec4(imageSize(g_image_rect), 0, 0));" NL 503 " imageStore(g_result, ivec2(coord, 5), ivec4(imageSize(g_image_2d_array), 0));" NL 504 " imageStore(g_result, ivec2(coord, 6), ivec4(imageSize(g_image_buffer), 0, 0, 0));" NL "}"; 505 } 506 else 507 { 508 os << NL " imageStore(g_result, ivec2(coord, 0), ivec4(imageSize(g_image_1d), 0, 0, 0));" NL 509 " imageStore(g_result, ivec2(coord, 1), ivec4(imageSize(g_image_1d_array), 0, 0));" NL 510 " imageStore(g_result, ivec2(coord, 2), ivec4(imageSize(g_image_2dms), 0, 0));" NL 511 " imageStore(g_result, ivec2(coord, 3), ivec4(imageSize(g_image_2dms_array), 0));" NL 512 " imageStore(g_result, ivec2(coord, 4), ivec4(0));" NL 513 " imageStore(g_result, ivec2(coord, 5), ivec4(0));" NL 514 " imageStore(g_result, ivec2(coord, 6), ivec4(0));" NL "}"; 515 } 516 return os.str(); 517 } 518 519 bool CheckProgram(GLuint program) 520 { 521 if (program == 0) 522 return true; 523 GLint status; 524 glGetProgramiv(program, GL_LINK_STATUS, &status); 525 526 if (status == GL_FALSE) 527 { 528 GLint attached_shaders; 529 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); 530 531 if (attached_shaders > 0) 532 { 533 std::vector<GLuint> shaders(attached_shaders); 534 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]); 535 536 for (GLint i = 0; i < attached_shaders; ++i) 537 { 538 GLenum type; 539 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type)); 540 switch (type) 541 { 542 case GL_VERTEX_SHADER: 543 m_context.getTestContext().getLog() 544 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage; 545 break; 546 case GL_TESS_CONTROL_SHADER: 547 m_context.getTestContext().getLog() 548 << tcu::TestLog::Message << "*** Tessellation Control Shader ***" 549 << tcu::TestLog::EndMessage; 550 break; 551 case GL_TESS_EVALUATION_SHADER: 552 m_context.getTestContext().getLog() 553 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***" 554 << tcu::TestLog::EndMessage; 555 break; 556 case GL_GEOMETRY_SHADER: 557 m_context.getTestContext().getLog() 558 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage; 559 break; 560 case GL_FRAGMENT_SHADER: 561 m_context.getTestContext().getLog() 562 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage; 563 break; 564 case GL_COMPUTE_SHADER: 565 m_context.getTestContext().getLog() 566 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage; 567 break; 568 default: 569 m_context.getTestContext().getLog() 570 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage; 571 break; 572 } 573 GLint length; 574 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length); 575 if (length > 0) 576 { 577 std::vector<GLchar> source(length); 578 glGetShaderSource(shaders[i], length, NULL, &source[0]); 579 m_context.getTestContext().getLog() 580 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage; 581 } 582 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length); 583 if (length > 0) 584 { 585 std::vector<GLchar> log(length); 586 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]); 587 m_context.getTestContext().getLog() 588 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 589 } 590 } 591 } 592 GLint length; 593 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 594 if (length > 0) 595 { 596 std::vector<GLchar> log(length); 597 glGetProgramInfoLog(program, length, NULL, &log[0]); 598 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 599 } 600 } 601 return status == GL_TRUE ? true : false; 602 } 603 604 public: 605 ImageSizeMachine() 606 { 607 glGenProgramPipelines(1, &m_pipeline); 608 memset(m_program, 0, sizeof(m_program)); 609 glGenVertexArrays(1, &m_vertex_array); 610 glGenTextures(1, &m_texture); 611 } 612 613 ~ImageSizeMachine() 614 { 615 glDeleteProgramPipelines(1, &m_pipeline); 616 for (int i = 0; i < 3; ++i) 617 glDeleteProgram(m_program[i]); 618 glDeleteVertexArrays(1, &m_vertex_array); 619 glDeleteTextures(1, &m_texture); 620 } 621 622 template <typename T> 623 long Run(int stage, bool ms_and_1d, ivec4 expected_result[7], bool subroutine = false) 624 { 625 if (stage == 0) 626 { // VS 627 std::string vs = GenShader<T>(stage, ms_and_1d, subroutine); 628 const char* const glsl_vs = vs.c_str(); 629 m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs); 630 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]); 631 } 632 else if (stage == 1) 633 { // TCS 634 const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL 635 "void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}"; 636 const char* const glsl_tes = "#version 430 core" NL "layout(quads, point_mode) in;" NL "void main() {}"; 637 std::string tcs = GenShader<T>(stage, ms_and_1d, subroutine); 638 const char* const glsl_tcs = tcs.c_str(); 639 m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs); 640 m_program[1] = glCreateShaderProgramv(GL_TESS_CONTROL_SHADER, 1, &glsl_tcs); 641 m_program[2] = glCreateShaderProgramv(GL_TESS_EVALUATION_SHADER, 1, &glsl_tes); 642 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]); 643 glUseProgramStages(m_pipeline, GL_TESS_CONTROL_SHADER_BIT, m_program[1]); 644 glUseProgramStages(m_pipeline, GL_TESS_EVALUATION_SHADER_BIT, m_program[2]); 645 } 646 else if (stage == 2) 647 { // TES 648 const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL 649 "void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}"; 650 std::string tes = GenShader<T>(stage, ms_and_1d, subroutine); 651 const char* const glsl_tes = tes.c_str(); 652 m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs); 653 m_program[1] = glCreateShaderProgramv(GL_TESS_EVALUATION_SHADER, 1, &glsl_tes); 654 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]); 655 glUseProgramStages(m_pipeline, GL_TESS_EVALUATION_SHADER_BIT, m_program[1]); 656 } 657 else if (stage == 3) 658 { // GS 659 const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL 660 "void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}"; 661 std::string gs = GenShader<T>(stage, ms_and_1d, subroutine); 662 const char* const glsl_gs = gs.c_str(); 663 m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs); 664 m_program[1] = glCreateShaderProgramv(GL_GEOMETRY_SHADER, 1, &glsl_gs); 665 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]); 666 glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, m_program[1]); 667 } 668 else if (stage == 4) 669 { // CS 670 std::string cs = GenShader<T>(stage, ms_and_1d, subroutine); 671 const char* const glsl_cs = cs.c_str(); 672 m_program[0] = glCreateShaderProgramv(GL_COMPUTE_SHADER, 1, &glsl_cs); 673 glUseProgramStages(m_pipeline, GL_COMPUTE_SHADER_BIT, m_program[0]); 674 } 675 else if (stage == 5) 676 { // FS 677 const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL 678 "void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}"; 679 std::string fs = GenShader<T>(stage, ms_and_1d, subroutine); 680 const char* const glsl_fs = fs.c_str(); 681 m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs); 682 m_program[1] = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs); 683 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]); 684 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_program[1]); 685 } 686 for (int i = 0; i < 3; ++i) 687 { 688 if (!CheckProgram(m_program[i])) 689 return ERROR; 690 } 691 692 glBindTexture(GL_TEXTURE_2D, m_texture); 693 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 694 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 695 { 696 ivec4 data[7]; 697 for (int i = 0; i < 7; ++i) 698 data[i] = ivec4(100000); 699 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, 1, 7, 0, GL_RGBA_INTEGER, GL_INT, &data[0]); 700 } 701 glBindTexture(GL_TEXTURE_2D, 0); 702 703 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32I); 704 glBindProgramPipeline(m_pipeline); 705 glBindVertexArray(m_vertex_array); 706 if (stage != 5) 707 { 708 glEnable(GL_RASTERIZER_DISCARD); 709 } 710 if (stage == 1 || stage == 2) 711 { // TCS or TES 712 glPatchParameteri(GL_PATCH_VERTICES, 1); 713 glDrawArrays(GL_PATCHES, 0, 1); 714 glPatchParameteri(GL_PATCH_VERTICES, 3); 715 } 716 else if (stage == 4) 717 { // CS 718 glDispatchCompute(1, 1, 1); 719 } 720 else 721 { 722 glDrawArrays(GL_POINTS, 0, 1); 723 } 724 glDisable(GL_RASTERIZER_DISCARD); 725 726 glBindTexture(GL_TEXTURE_2D, m_texture); 727 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 728 { 729 ivec4 data[7]; 730 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA_INTEGER, GL_INT, &data[0]); 731 for (int i = 0; i < 7; ++i) 732 { 733 if (data[i] != expected_result[i]) 734 { 735 m_context.getTestContext().getLog() 736 << tcu::TestLog::Message << "Returned value is: (" << data[i][0] << " " << data[i][1] << " " 737 << data[i][2] << " " << data[i][3] << "). Expected value is: (" << expected_result[i][0] << " " 738 << expected_result[i][1] << " " << expected_result[i][2] << " " << expected_result[i][3] 739 << "). Image unit is: " << (i + 1) << tcu::TestLog::EndMessage; 740 return ERROR; 741 } 742 } 743 } 744 return NO_ERROR; 745 } 746 }; 747 //============================================================================= 748 // 1.1.x.y BasicNonMS 749 //----------------------------------------------------------------------------- 750 751 template <typename T, int STAGE> 752 class BasicNonMS : public ShaderImageSizeBase 753 { 754 GLuint m_texture[7]; 755 GLuint m_buffer; 756 757 virtual long Setup() 758 { 759 glGenTextures(7, m_texture); 760 glGenBuffers(1, &m_buffer); 761 return NO_ERROR; 762 } 763 764 virtual long Run() 765 { 766 if (!SupportedInStage(STAGE, 8)) 767 return NOT_SUPPORTED; 768 769 const GLenum target[7] = { GL_TEXTURE_2D, GL_TEXTURE_3D, 770 GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY, 771 GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_ARRAY, 772 GL_TEXTURE_BUFFER }; 773 for (int i = 0; i < 7; ++i) 774 { 775 glBindTexture(target[i], m_texture[i]); 776 if (target[i] != GL_TEXTURE_BUFFER) 777 { 778 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); 779 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); 780 } 781 782 if (i == 0) 783 { 784 glTexStorage2D(target[i], 10, TexInternalFormat<T>(), 512, 128); 785 glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 786 } 787 else if (i == 1) 788 { 789 glTexStorage3D(target[i], 3, TexInternalFormat<T>(), 8, 8, 4); 790 glBindImageTexture(2, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 791 } 792 else if (i == 2) 793 { 794 glTexStorage2D(target[i], 4, TexInternalFormat<T>(), 16, 16); 795 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>()); 796 } 797 else if (i == 3) 798 { 799 glTexStorage3D(target[i], 2, TexInternalFormat<T>(), 4, 4, 12); 800 glBindImageTexture(4, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 801 } 802 else if (i == 4) 803 { 804 glTexStorage2D(target[i], 1, TexInternalFormat<T>(), 16, 8); 805 glBindImageTexture(5, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 806 } 807 else if (i == 5) 808 { 809 glTexStorage3D(target[i], 3, TexInternalFormat<T>(), 127, 39, 12); 810 glBindImageTexture(6, m_texture[i], 2, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 811 } 812 else if (i == 6) 813 { 814 std::vector<GLubyte> data(256); 815 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer); 816 glBufferData(GL_TEXTURE_BUFFER, 256, &data[0], GL_STATIC_DRAW); 817 glTexBuffer(GL_TEXTURE_BUFFER, TexInternalFormat<T>(), m_buffer); 818 glBindImageTexture(7, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 819 } 820 } 821 ImageSizeMachine machine; 822 ivec4 res[7] = { ivec4(256, 64, 0, 0), ivec4(8, 8, 4, 0), ivec4(16, 16, 0, 0), ivec4(2, 2, 2, 0), 823 ivec4(16, 8, 0, 0), ivec4(31, 9, 12, 0), ivec4(16, 0, 0, 0) }; 824 return machine.Run<T>(STAGE, false, res); 825 } 826 827 virtual long Cleanup() 828 { 829 glDeleteTextures(7, m_texture); 830 glDeleteBuffers(1, &m_buffer); 831 return NO_ERROR; 832 } 833 }; 834 //============================================================================= 835 // 1.2.x.y BasicMS 836 //----------------------------------------------------------------------------- 837 838 template <typename T, int STAGE> 839 class BasicMS : public ShaderImageSizeBase 840 { 841 GLuint m_texture[4]; 842 843 virtual long Setup() 844 { 845 glGenTextures(4, m_texture); 846 return NO_ERROR; 847 } 848 849 virtual long Run() 850 { 851 if (!SupportedInStage(STAGE, 5)) 852 return NOT_SUPPORTED; 853 if (!SupportedSamples(4)) 854 return NOT_SUPPORTED; 855 856 const GLenum target[4] = { GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE, 857 GL_TEXTURE_2D_MULTISAMPLE_ARRAY }; 858 for (int i = 0; i < 4; ++i) 859 { 860 glBindTexture(target[i], m_texture[i]); 861 if (target[i] == GL_TEXTURE_1D || target[i] == GL_TEXTURE_1D_ARRAY) 862 { 863 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); 864 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); 865 } 866 867 if (i == 0) 868 { 869 glTexStorage1D(target[i], 10, TexInternalFormat<T>(), 512); 870 glBindImageTexture(1, m_texture[i], 6, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 871 } 872 else if (i == 1) 873 { 874 glTexStorage2D(target[i], 3, TexInternalFormat<T>(), 15, 7); 875 glBindImageTexture(2, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 876 } 877 else if (i == 2) 878 { 879 glTexImage2DMultisample(target[i], 4, TexInternalFormat<T>(), 17, 19, GL_FALSE); 880 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>()); 881 } 882 else if (i == 3) 883 { 884 glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 64, 32, 5, GL_FALSE); 885 glBindImageTexture(4, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 886 } 887 } 888 ImageSizeMachine machine; 889 ivec4 res[7] = { ivec4(8, 0, 0, 0), ivec4(7, 7, 0, 0), ivec4(17, 19, 0, 0), ivec4(64, 32, 5, 0), ivec4(0), 890 ivec4(0), ivec4(0) }; 891 return machine.Run<T>(STAGE, true, res); 892 } 893 894 virtual long Cleanup() 895 { 896 glDeleteTextures(4, m_texture); 897 return NO_ERROR; 898 } 899 }; 900 //============================================================================= 901 // 2.1 AdvancedChangeSize 902 //----------------------------------------------------------------------------- 903 class AdvancedChangeSize : public ShaderImageSizeBase 904 { 905 GLuint m_pipeline; 906 GLuint m_program[2]; 907 GLuint m_vertex_array; 908 GLuint m_texture[2]; 909 910 virtual long Setup() 911 { 912 glGenProgramPipelines(1, &m_pipeline); 913 memset(m_program, 0, sizeof(m_program)); 914 glGenVertexArrays(1, &m_vertex_array); 915 glGenTextures(2, m_texture); 916 return NO_ERROR; 917 } 918 919 virtual long Run() 920 { 921 const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL 922 "const vec2 g_position[3] = { vec2(-1, -1), vec2(3, -1), vec2(-1, 3) };" NL 923 "void main() { gl_Position = vec4(g_position[gl_VertexID], 0, 1); }"; 924 const char* const glsl_fs = 925 "#version 430 core" NL "layout(location = 0) out vec4 g_color;" NL 926 "layout(binding = 0, rgba8) uniform image2D g_image[2];" NL "uniform ivec2 g_expected_size[2];" NL 927 "uniform int g_0 = 0, g_1 = 1;" NL "void main() {" NL " vec4 c = vec4(0, 1, 0, 1);" NL 928 " if (imageSize(g_image[g_0]).xy != g_expected_size[g_0]) c = vec4(1, 0, 0, 1);" NL 929 " if (imageSize(g_image[g_1]).yx != g_expected_size[g_1]) c = vec4(1, 0, 0, 1);" NL " g_color = c;" NL 930 "}"; 931 m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs); 932 m_program[1] = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs); 933 for (int i = 0; i < 2; ++i) 934 if (!CheckProgram(m_program[i])) 935 return ERROR; 936 937 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]); 938 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_program[1]); 939 940 glBindVertexArray(m_vertex_array); 941 glBindProgramPipeline(m_pipeline); 942 943 int size[2] = { 32, 128 }; 944 for (int i = 0; i < 2; ++i) 945 { 946 glBindTexture(GL_TEXTURE_2D, m_texture[i]); 947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 948 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 949 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[i], size[i], 0, GL_RGBA, GL_FLOAT, NULL); 950 glBindImageTexture(i, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); 951 } 952 953 for (int i = 0; i < 3; ++i) 954 { 955 glProgramUniform2i(m_program[1], glGetUniformLocation(m_program[1], "g_expected_size[0]"), size[0], 956 size[0]); 957 glProgramUniform2i(m_program[1], glGetUniformLocation(m_program[1], "g_expected_size[1]"), size[1], 958 size[1]); 959 glClear(GL_COLOR_BUFFER_BIT); 960 glDrawArrays(GL_TRIANGLES, 0, 3); 961 962 { 963 bool status = true; 964 std::vector<vec3> fb(getWindowWidth() * getWindowHeight()); 965 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]); 966 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1))) 967 status = false; 968 if (!status) 969 return ERROR; 970 } 971 972 size[0] /= 2; 973 size[1] /= 2; 974 975 glBindTexture(GL_TEXTURE_2D, m_texture[0]); 976 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[0], size[0], 0, GL_RGBA, GL_FLOAT, NULL); 977 glBindTexture(GL_TEXTURE_2D, m_texture[1]); 978 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[1], size[1], 0, GL_RGBA, GL_FLOAT, NULL); 979 } 980 return NO_ERROR; 981 } 982 983 virtual long Cleanup() 984 { 985 glDeleteProgramPipelines(1, &m_pipeline); 986 for (int i = 0; i < 2; ++i) 987 glDeleteProgram(m_program[i]); 988 glDeleteVertexArrays(1, &m_vertex_array); 989 glDeleteTextures(2, m_texture); 990 return NO_ERROR; 991 } 992 }; 993 //============================================================================= 994 // 2.2.x.y AdvancedNonMS 995 //----------------------------------------------------------------------------- 996 997 template <typename T, int STAGE> 998 class AdvancedNonMS : public ShaderImageSizeBase 999 { 1000 GLuint m_texture[7]; 1001 GLuint m_buffer; 1002 1003 virtual long Setup() 1004 { 1005 glGenTextures(7, m_texture); 1006 glGenBuffers(1, &m_buffer); 1007 return NO_ERROR; 1008 } 1009 1010 virtual long Run() 1011 { 1012 if (!SupportedInStage(STAGE, 8)) 1013 return NOT_SUPPORTED; 1014 1015 const GLenum target[7] = { GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP_ARRAY, 1016 GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_ARRAY, 1017 GL_TEXTURE_BUFFER }; 1018 for (int i = 0; i < 7; ++i) 1019 { 1020 glBindTexture(target[i], m_texture[i]); 1021 if (target[i] != GL_TEXTURE_BUFFER) 1022 { 1023 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1024 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1025 } 1026 1027 if (i == 0) 1028 { 1029 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 2, 2, 7, 0, TexFormat<T>(), TexType<T>(), NULL); 1030 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 1, 1, 7, 0, TexFormat<T>(), TexType<T>(), NULL); 1031 glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 3, GL_READ_ONLY, TexInternalFormat<T>()); 1032 } 1033 else if (i == 1) 1034 { 1035 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 4, 4, 2, 0, TexFormat<T>(), TexType<T>(), NULL); 1036 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 2, 2, 1, 0, TexFormat<T>(), TexType<T>(), NULL); 1037 glTexImage3D(target[i], 2, TexInternalFormat<T>(), 1, 1, 1, 0, TexFormat<T>(), TexType<T>(), NULL); 1038 glBindImageTexture(2, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 1039 } 1040 else if (i == 2) 1041 { 1042 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 2, 2, 12, 0, TexFormat<T>(), TexType<T>(), NULL); 1043 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 1, 1, 12, 0, TexFormat<T>(), TexType<T>(), NULL); 1044 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 1, GL_READ_WRITE, TexInternalFormat<T>()); 1045 } 1046 else if (i == 3) 1047 { 1048 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 4, 4, 18, 0, TexFormat<T>(), TexType<T>(), NULL); 1049 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 2, 2, 18, 0, TexFormat<T>(), TexType<T>(), NULL); 1050 glTexImage3D(target[i], 2, TexInternalFormat<T>(), 1, 1, 18, 0, TexFormat<T>(), TexType<T>(), NULL); 1051 glBindImageTexture(4, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 1052 } 1053 else if (i == 4) 1054 { 1055 glTexImage2D(target[i], 0, TexInternalFormat<T>(), 123, 11, 0, TexFormat<T>(), TexType<T>(), NULL); 1056 glBindImageTexture(5, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>()); 1057 } 1058 else if (i == 5) 1059 { 1060 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 13, 7, 4, 0, TexFormat<T>(), TexType<T>(), NULL); 1061 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 6, 3, 4, 0, TexFormat<T>(), TexType<T>(), NULL); 1062 glTexImage3D(target[i], 2, TexInternalFormat<T>(), 3, 1, 4, 0, TexFormat<T>(), TexType<T>(), NULL); 1063 glTexImage3D(target[i], 3, TexInternalFormat<T>(), 1, 1, 4, 0, TexFormat<T>(), TexType<T>(), NULL); 1064 glBindImageTexture(6, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 1065 } 1066 else if (i == 6) 1067 { 1068 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer); 1069 glBufferData(GL_TEXTURE_BUFFER, 1024, NULL, GL_STATIC_DRAW); 1070 glTexBufferRange(GL_TEXTURE_BUFFER, TexInternalFormat<T>(), m_buffer, 256, 512); 1071 glBindImageTexture(7, m_texture[i], 0, GL_FALSE, 0, GL_WRITE_ONLY, TexInternalFormat<T>()); 1072 } 1073 } 1074 ImageSizeMachine machine; 1075 ivec4 res[7] = { ivec4(1, 1, 0, 0), ivec4(2, 2, 1, 0), ivec4(2, 2, 0, 0), ivec4(2, 2, 3, 0), 1076 ivec4(123, 11, 0, 0), ivec4(6, 3, 4, 0), ivec4(32, 0, 0, 0) }; 1077 return machine.Run<T>(STAGE, false, res, true); 1078 } 1079 1080 virtual long Cleanup() 1081 { 1082 glDeleteTextures(7, m_texture); 1083 glDeleteBuffers(1, &m_buffer); 1084 return NO_ERROR; 1085 } 1086 }; 1087 //============================================================================= 1088 // 2.3.x.y AdvancedMS 1089 //----------------------------------------------------------------------------- 1090 template <typename T, int STAGE> 1091 class AdvancedMS : public ShaderImageSizeBase 1092 { 1093 GLuint m_texture[4]; 1094 1095 virtual long Setup() 1096 { 1097 glGenTextures(4, m_texture); 1098 return NO_ERROR; 1099 } 1100 1101 virtual long Run() 1102 { 1103 if (!SupportedInStage(STAGE, 5)) 1104 return NOT_SUPPORTED; 1105 if (!SupportedSamples(4)) 1106 return NOT_SUPPORTED; 1107 1108 const GLenum target[4] = { GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1109 GL_TEXTURE_2D_MULTISAMPLE_ARRAY }; 1110 for (int i = 0; i < 4; ++i) 1111 { 1112 glBindTexture(target[i], m_texture[i]); 1113 if (target[i] == GL_TEXTURE_1D || target[i] == GL_TEXTURE_1D_ARRAY) 1114 { 1115 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1116 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1117 } 1118 1119 if (i == 0) 1120 { 1121 glTexImage1D(target[i], 0, TexInternalFormat<T>(), 7, 0, TexFormat<T>(), TexType<T>(), NULL); 1122 glTexImage1D(target[i], 1, TexInternalFormat<T>(), 3, 0, TexFormat<T>(), TexType<T>(), NULL); 1123 glTexImage1D(target[i], 2, TexInternalFormat<T>(), 1, 0, TexFormat<T>(), TexType<T>(), NULL); 1124 glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 1125 } 1126 else if (i == 1) 1127 { 1128 glTexImage2D(target[i], 0, TexInternalFormat<T>(), 7, 15, 0, TexFormat<T>(), TexType<T>(), NULL); 1129 glBindImageTexture(2, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 1130 } 1131 else if (i == 2) 1132 { 1133 glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 7, 9, 3, GL_FALSE); 1134 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 1, GL_READ_WRITE, TexInternalFormat<T>()); 1135 } 1136 else if (i == 3) 1137 { 1138 glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 64, 32, 5, GL_FALSE); 1139 glBindImageTexture(4, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>()); 1140 } 1141 } 1142 ImageSizeMachine machine; 1143 ivec4 res[7] = { ivec4(3, 0, 0, 0), ivec4(7, 15, 0, 0), ivec4(7, 9, 0, 0), ivec4(64, 32, 5, 0), 1144 ivec4(0), ivec4(0), ivec4(0) }; 1145 return machine.Run<T>(STAGE, true, res, true); 1146 } 1147 1148 virtual long Cleanup() 1149 { 1150 glDeleteTextures(4, m_texture); 1151 return NO_ERROR; 1152 } 1153 }; 1154 //============================================================================= 1155 // 4.1 NegativeCompileTime 1156 //----------------------------------------------------------------------------- 1157 class NegativeCompileTime : public ShaderImageSizeBase 1158 { 1159 virtual long Run() 1160 { 1161 // '#extension GL_ARB_shader_image_size : require' is missing 1162 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 g_color;" NL 1163 "layout(binding = 0, rg16f) uniform image2D g_image;" NL "uniform ivec2 g_expected_size;" NL 1164 "void main() {" NL " if (imageSize(g_image) == g_expected_size) g_color = vec4(0, 1, 0, 1);" NL 1165 " else g_color = vec4(1, 0, 0, 1);" NL "}")) 1166 return ERROR; 1167 // imageSize(sampler) 1168 if (!Compile("#version 430 core" NL "layout(location = 0) out vec4 g_color;" NL 1169 "layout(binding = 0) uniform sampler2D g_sampler;" NL "uniform ivec2 g_expected_size;" NL 1170 "void main() {" NL " if (imageSize(g_sampler) == g_expected_size) g_color = vec4(0, 1, 0, 1);" NL 1171 " else g_color = vec4(1, 0, 0, 1);" NL "}")) 1172 return ERROR; 1173 return NO_ERROR; 1174 } 1175 1176 bool Compile(const std::string& source) 1177 { 1178 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER); 1179 1180 const char* const src = source.c_str(); 1181 glShaderSource(sh, 1, &src, NULL); 1182 glCompileShader(sh); 1183 1184 GLchar log[1024]; 1185 glGetShaderInfoLog(sh, sizeof(log), NULL, log); 1186 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n" 1187 << log << tcu::TestLog::EndMessage; 1188 1189 GLint status; 1190 glGetShaderiv(sh, GL_COMPILE_STATUS, &status); 1191 glDeleteShader(sh); 1192 1193 if (status == GL_TRUE) 1194 { 1195 m_context.getTestContext().getLog() 1196 << tcu::TestLog::Message << "Compilation should fail." << tcu::TestLog::EndMessage; 1197 return false; 1198 } 1199 return true; 1200 } 1201 }; 1202 1203 } // anonymous namespace 1204 1205 ShaderImageSizeTests::ShaderImageSizeTests(deqp::Context& context) : TestCaseGroup(context, "shader_image_size", "") 1206 { 1207 } 1208 1209 ShaderImageSizeTests::~ShaderImageSizeTests(void) 1210 { 1211 } 1212 1213 void ShaderImageSizeTests::init() 1214 { 1215 using namespace deqp; 1216 addChild(new TestSubcase(m_context, "basic-nonMS-vs-float", TestSubcase::Create<BasicNonMS<vec4, 0> >)); 1217 addChild(new TestSubcase(m_context, "basic-nonMS-vs-int", TestSubcase::Create<BasicNonMS<ivec4, 0> >)); 1218 addChild(new TestSubcase(m_context, "basic-nonMS-vs-uint", TestSubcase::Create<BasicNonMS<uvec4, 0> >)); 1219 addChild(new TestSubcase(m_context, "basic-nonMS-tcs-float", TestSubcase::Create<BasicNonMS<vec4, 1> >)); 1220 addChild(new TestSubcase(m_context, "basic-nonMS-tcs-int", TestSubcase::Create<BasicNonMS<ivec4, 1> >)); 1221 addChild(new TestSubcase(m_context, "basic-nonMS-tcs-uint", TestSubcase::Create<BasicNonMS<uvec4, 1> >)); 1222 addChild(new TestSubcase(m_context, "basic-nonMS-tes-float", TestSubcase::Create<BasicNonMS<vec4, 2> >)); 1223 addChild(new TestSubcase(m_context, "basic-nonMS-tes-int", TestSubcase::Create<BasicNonMS<ivec4, 2> >)); 1224 addChild(new TestSubcase(m_context, "basic-nonMS-tes-uint", TestSubcase::Create<BasicNonMS<uvec4, 2> >)); 1225 addChild(new TestSubcase(m_context, "basic-nonMS-gs-float", TestSubcase::Create<BasicNonMS<vec4, 3> >)); 1226 addChild(new TestSubcase(m_context, "basic-nonMS-gs-int", TestSubcase::Create<BasicNonMS<ivec4, 3> >)); 1227 addChild(new TestSubcase(m_context, "basic-nonMS-gs-uint", TestSubcase::Create<BasicNonMS<uvec4, 3> >)); 1228 addChild(new TestSubcase(m_context, "basic-nonMS-fs-float", TestSubcase::Create<BasicNonMS<vec4, 5> >)); 1229 addChild(new TestSubcase(m_context, "basic-nonMS-fs-int", TestSubcase::Create<BasicNonMS<ivec4, 5> >)); 1230 addChild(new TestSubcase(m_context, "basic-nonMS-fs-uint", TestSubcase::Create<BasicNonMS<uvec4, 5> >)); 1231 addChild(new TestSubcase(m_context, "basic-nonMS-cs-float", TestSubcase::Create<BasicNonMS<vec4, 4> >)); 1232 addChild(new TestSubcase(m_context, "basic-nonMS-cs-int", TestSubcase::Create<BasicNonMS<ivec4, 4> >)); 1233 addChild(new TestSubcase(m_context, "basic-nonMS-cs-uint", TestSubcase::Create<BasicNonMS<uvec4, 4> >)); 1234 addChild(new TestSubcase(m_context, "basic-ms-vs-float", TestSubcase::Create<BasicMS<vec4, 0> >)); 1235 addChild(new TestSubcase(m_context, "basic-ms-vs-int", TestSubcase::Create<BasicMS<ivec4, 0> >)); 1236 addChild(new TestSubcase(m_context, "basic-ms-vs-uint", TestSubcase::Create<BasicMS<uvec4, 0> >)); 1237 addChild(new TestSubcase(m_context, "basic-ms-tcs-float", TestSubcase::Create<BasicMS<vec4, 1> >)); 1238 addChild(new TestSubcase(m_context, "basic-ms-tcs-int", TestSubcase::Create<BasicMS<ivec4, 1> >)); 1239 addChild(new TestSubcase(m_context, "basic-ms-tcs-uint", TestSubcase::Create<BasicMS<uvec4, 1> >)); 1240 addChild(new TestSubcase(m_context, "basic-ms-tes-float", TestSubcase::Create<BasicMS<vec4, 2> >)); 1241 addChild(new TestSubcase(m_context, "basic-ms-tes-int", TestSubcase::Create<BasicMS<ivec4, 2> >)); 1242 addChild(new TestSubcase(m_context, "basic-ms-tes-uint", TestSubcase::Create<BasicMS<uvec4, 2> >)); 1243 addChild(new TestSubcase(m_context, "basic-ms-gs-float", TestSubcase::Create<BasicMS<vec4, 3> >)); 1244 addChild(new TestSubcase(m_context, "basic-ms-gs-int", TestSubcase::Create<BasicMS<ivec4, 3> >)); 1245 addChild(new TestSubcase(m_context, "basic-ms-gs-uint", TestSubcase::Create<BasicMS<uvec4, 3> >)); 1246 addChild(new TestSubcase(m_context, "basic-ms-fs-float", TestSubcase::Create<BasicMS<vec4, 5> >)); 1247 addChild(new TestSubcase(m_context, "basic-ms-fs-int", TestSubcase::Create<BasicMS<ivec4, 5> >)); 1248 addChild(new TestSubcase(m_context, "basic-ms-fs-uint", TestSubcase::Create<BasicMS<uvec4, 5> >)); 1249 addChild(new TestSubcase(m_context, "basic-ms-cs-float", TestSubcase::Create<BasicMS<vec4, 4> >)); 1250 addChild(new TestSubcase(m_context, "basic-ms-cs-int", TestSubcase::Create<BasicMS<ivec4, 4> >)); 1251 addChild(new TestSubcase(m_context, "basic-ms-cs-uint", TestSubcase::Create<BasicMS<uvec4, 4> >)); 1252 addChild(new TestSubcase(m_context, "advanced-changeSize", TestSubcase::Create<AdvancedChangeSize>)); 1253 addChild(new TestSubcase(m_context, "advanced-nonMS-vs-float", TestSubcase::Create<AdvancedNonMS<vec4, 0> >)); 1254 addChild(new TestSubcase(m_context, "advanced-nonMS-vs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 0> >)); 1255 addChild(new TestSubcase(m_context, "advanced-nonMS-vs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 0> >)); 1256 addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-float", TestSubcase::Create<AdvancedNonMS<vec4, 1> >)); 1257 addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 1> >)); 1258 addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 1> >)); 1259 addChild(new TestSubcase(m_context, "advanced-nonMS-tes-float", TestSubcase::Create<AdvancedNonMS<vec4, 2> >)); 1260 addChild(new TestSubcase(m_context, "advanced-nonMS-tes-int", TestSubcase::Create<AdvancedNonMS<ivec4, 2> >)); 1261 addChild(new TestSubcase(m_context, "advanced-nonMS-tes-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 2> >)); 1262 addChild(new TestSubcase(m_context, "advanced-nonMS-gs-float", TestSubcase::Create<AdvancedNonMS<vec4, 3> >)); 1263 addChild(new TestSubcase(m_context, "advanced-nonMS-gs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 3> >)); 1264 addChild(new TestSubcase(m_context, "advanced-nonMS-gs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 3> >)); 1265 addChild(new TestSubcase(m_context, "advanced-nonMS-fs-float", TestSubcase::Create<AdvancedNonMS<vec4, 5> >)); 1266 addChild(new TestSubcase(m_context, "advanced-nonMS-fs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 5> >)); 1267 addChild(new TestSubcase(m_context, "advanced-nonMS-fs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 5> >)); 1268 addChild(new TestSubcase(m_context, "advanced-nonMS-cs-float", TestSubcase::Create<AdvancedNonMS<vec4, 4> >)); 1269 addChild(new TestSubcase(m_context, "advanced-nonMS-cs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 4> >)); 1270 addChild(new TestSubcase(m_context, "advanced-nonMS-cs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 4> >)); 1271 addChild(new TestSubcase(m_context, "advanced-ms-vs-float", TestSubcase::Create<AdvancedMS<vec4, 0> >)); 1272 addChild(new TestSubcase(m_context, "advanced-ms-vs-int", TestSubcase::Create<AdvancedMS<ivec4, 0> >)); 1273 addChild(new TestSubcase(m_context, "advanced-ms-vs-uint", TestSubcase::Create<AdvancedMS<uvec4, 0> >)); 1274 addChild(new TestSubcase(m_context, "advanced-ms-tcs-float", TestSubcase::Create<AdvancedMS<vec4, 1> >)); 1275 addChild(new TestSubcase(m_context, "advanced-ms-tcs-int", TestSubcase::Create<AdvancedMS<ivec4, 1> >)); 1276 addChild(new TestSubcase(m_context, "advanced-ms-tcs-uint", TestSubcase::Create<AdvancedMS<uvec4, 1> >)); 1277 addChild(new TestSubcase(m_context, "advanced-ms-tes-float", TestSubcase::Create<AdvancedMS<vec4, 2> >)); 1278 addChild(new TestSubcase(m_context, "advanced-ms-tes-int", TestSubcase::Create<AdvancedMS<ivec4, 2> >)); 1279 addChild(new TestSubcase(m_context, "advanced-ms-tes-uint", TestSubcase::Create<AdvancedMS<uvec4, 2> >)); 1280 addChild(new TestSubcase(m_context, "advanced-ms-gs-float", TestSubcase::Create<AdvancedMS<vec4, 3> >)); 1281 addChild(new TestSubcase(m_context, "advanced-ms-gs-int", TestSubcase::Create<AdvancedMS<ivec4, 3> >)); 1282 addChild(new TestSubcase(m_context, "advanced-ms-gs-uint", TestSubcase::Create<AdvancedMS<uvec4, 3> >)); 1283 addChild(new TestSubcase(m_context, "advanced-ms-fs-float", TestSubcase::Create<AdvancedMS<vec4, 5> >)); 1284 addChild(new TestSubcase(m_context, "advanced-ms-fs-int", TestSubcase::Create<AdvancedMS<ivec4, 5> >)); 1285 addChild(new TestSubcase(m_context, "advanced-ms-fs-uint", TestSubcase::Create<AdvancedMS<uvec4, 5> >)); 1286 addChild(new TestSubcase(m_context, "advanced-ms-cs-float", TestSubcase::Create<AdvancedMS<vec4, 4> >)); 1287 addChild(new TestSubcase(m_context, "advanced-ms-cs-int", TestSubcase::Create<AdvancedMS<ivec4, 4> >)); 1288 addChild(new TestSubcase(m_context, "advanced-ms-cs-uint", TestSubcase::Create<AdvancedMS<uvec4, 4> >)); 1289 addChild(new TestSubcase(m_context, "negative-compileTime", TestSubcase::Create<NegativeCompileTime>)); 1290 } 1291 1292 } // namespace gl4cts 1293