1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2015 The Android Open Source Project 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 Negative Shader Image Load Store Tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fNegativeShaderImageLoadStoreTests.hpp" 25 26 #include "deUniquePtr.hpp" 27 28 #include "glwEnums.hpp" 29 30 #include "gluShaderProgram.hpp" 31 32 #include "glsTextureTestUtil.hpp" 33 34 #include "tcuStringTemplate.hpp" 35 #include "tcuTexture.hpp" 36 #include "tcuTestLog.hpp" 37 38 namespace deqp 39 { 40 namespace gles31 41 { 42 namespace Functional 43 { 44 namespace NegativeTestShared 45 { 46 namespace 47 { 48 49 enum MemoryQualifier 50 { 51 MEMORY_NONE = 0, 52 MEMORY_READONLY, 53 MEMORY_WRITEONLY, 54 MEMORY_BOTH, 55 56 MEMORY_LAST 57 }; 58 59 enum ImageOperation 60 { 61 IMAGE_OPERATION_STORE = 0, 62 IMAGE_OPERATION_LOAD, 63 IMAGE_OPERATION_ATOMIC_ADD, 64 IMAGE_OPERATION_ATOMIC_MIN, 65 IMAGE_OPERATION_ATOMIC_MAX, 66 IMAGE_OPERATION_ATOMIC_AND, 67 IMAGE_OPERATION_ATOMIC_OR, 68 IMAGE_OPERATION_ATOMIC_XOR, 69 IMAGE_OPERATION_ATOMIC_EXCHANGE, 70 IMAGE_OPERATION_ATOMIC_COMP_SWAP, 71 72 IMAGE_OPERATION_LAST 73 }; 74 75 static const glu::ShaderType s_shaders[] = 76 { 77 glu::SHADERTYPE_VERTEX, 78 glu::SHADERTYPE_FRAGMENT, 79 glu::SHADERTYPE_GEOMETRY, 80 glu::SHADERTYPE_TESSELLATION_CONTROL, 81 glu::SHADERTYPE_TESSELLATION_EVALUATION, 82 glu::SHADERTYPE_COMPUTE 83 }; 84 85 std::string getShaderImageLayoutQualifier (const tcu::TextureFormat& format) 86 { 87 std::ostringstream qualifier; 88 89 switch (format.order) 90 { 91 case tcu::TextureFormat::RGBA: qualifier << "rgba"; break; 92 case tcu::TextureFormat::R: qualifier << "r"; break; 93 default: 94 DE_ASSERT(false); 95 return std::string(""); 96 } 97 98 switch (format.type) 99 { 100 case tcu::TextureFormat::FLOAT: qualifier << "32f"; break; 101 case tcu::TextureFormat::HALF_FLOAT: qualifier << "16f"; break; 102 case tcu::TextureFormat::UNORM_INT8: qualifier << "8"; break; 103 case tcu::TextureFormat::SNORM_INT8: qualifier << "8_snorm"; break; 104 case tcu::TextureFormat::SIGNED_INT32: qualifier << "32i"; break; 105 case tcu::TextureFormat::SIGNED_INT16: qualifier << "16i"; break; 106 case tcu::TextureFormat::SIGNED_INT8: qualifier << "8i"; break; 107 case tcu::TextureFormat::UNSIGNED_INT32: qualifier << "32ui"; break; 108 case tcu::TextureFormat::UNSIGNED_INT16: qualifier << "16ui"; break; 109 case tcu::TextureFormat::UNSIGNED_INT8: qualifier << "8ui"; break; 110 default: 111 DE_ASSERT(false); 112 return std::string(""); 113 } 114 115 return qualifier.str(); 116 } 117 118 std::string getShaderImageTypeDeclaration (const tcu::TextureFormat& format, glu::TextureTestUtil::TextureType imageType) 119 { 120 std::ostringstream declaration; 121 122 switch (format.type) 123 { 124 case tcu::TextureFormat::FLOAT: 125 case tcu::TextureFormat::HALF_FLOAT: 126 case tcu::TextureFormat::UNORM_INT8: 127 case tcu::TextureFormat::SNORM_INT8: declaration << ""; break; 128 129 case tcu::TextureFormat::SIGNED_INT32: 130 case tcu::TextureFormat::SIGNED_INT16: 131 case tcu::TextureFormat::SIGNED_INT8: declaration << "i"; break; 132 133 case tcu::TextureFormat::UNSIGNED_INT32: 134 case tcu::TextureFormat::UNSIGNED_INT16: 135 case tcu::TextureFormat::UNSIGNED_INT8: declaration << "u"; break; 136 137 default: 138 DE_ASSERT(false); 139 return std::string(""); 140 } 141 142 declaration << "image"; 143 144 switch(imageType) 145 { 146 case glu::TextureTestUtil::TEXTURETYPE_2D: declaration << "2D"; break; 147 case glu::TextureTestUtil::TEXTURETYPE_3D: declaration << "3D"; break; 148 case glu::TextureTestUtil::TEXTURETYPE_CUBE: declaration << "Cube"; break; 149 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY: declaration << "2DArray"; break; 150 case glu::TextureTestUtil::TEXTURETYPE_BUFFER: declaration << "Buffer"; break; 151 case glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY: declaration << "CubeArray"; break; 152 default: 153 DE_ASSERT(false); 154 return std::string(""); 155 } 156 157 return declaration.str(); 158 } 159 160 std::string getShaderImageTypeExtensionString (glu::TextureTestUtil::TextureType imageType) 161 { 162 std::string extension; 163 164 switch(imageType) 165 { 166 case glu::TextureTestUtil::TEXTURETYPE_2D: 167 case glu::TextureTestUtil::TEXTURETYPE_3D: 168 case glu::TextureTestUtil::TEXTURETYPE_CUBE: 169 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY: 170 extension = ""; 171 break; 172 173 case glu::TextureTestUtil::TEXTURETYPE_BUFFER: 174 extension = "#extension GL_EXT_texture_buffer : enable"; 175 break; 176 177 case glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY: 178 extension = "#extension GL_EXT_texture_cube_map_array : enable"; 179 break; 180 181 default: 182 DE_ASSERT(false); 183 return std::string(""); 184 } 185 186 return extension; 187 } 188 189 std::string getShaderImageParamP (glu::TextureTestUtil::TextureType imageType) 190 { 191 switch(imageType) 192 { 193 case glu::TextureTestUtil::TEXTURETYPE_2D: 194 return "ivec2(1, 1)"; 195 196 case glu::TextureTestUtil::TEXTURETYPE_3D: 197 case glu::TextureTestUtil::TEXTURETYPE_CUBE: 198 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY: 199 case glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY: 200 return "ivec3(1, 1, 1)"; 201 202 case glu::TextureTestUtil::TEXTURETYPE_BUFFER: 203 return "1"; 204 205 default: 206 DE_ASSERT(false); 207 return std::string(""); 208 } 209 } 210 211 std::string getOtherFunctionArguments (const tcu::TextureFormat& format, ImageOperation function) 212 { 213 std::ostringstream data; 214 data << ", "; 215 216 bool isFloat = false; 217 218 switch(format.type) 219 { 220 case tcu::TextureFormat::FLOAT: 221 case tcu::TextureFormat::HALF_FLOAT: 222 case tcu::TextureFormat::UNORM_INT8: 223 case tcu::TextureFormat::SNORM_INT8: 224 data << ""; 225 isFloat = true; 226 break; 227 228 case tcu::TextureFormat::SIGNED_INT32: 229 case tcu::TextureFormat::SIGNED_INT16: 230 case tcu::TextureFormat::SIGNED_INT8: 231 data << "i"; 232 break; 233 234 case tcu::TextureFormat::UNSIGNED_INT32: 235 case tcu::TextureFormat::UNSIGNED_INT16: 236 case tcu::TextureFormat::UNSIGNED_INT8: 237 data << "u"; 238 break; 239 240 default: 241 DE_ASSERT(false); 242 return std::string(""); 243 } 244 245 switch (function) 246 { 247 case IMAGE_OPERATION_LOAD: 248 return ""; 249 250 case IMAGE_OPERATION_STORE: 251 data << "vec4(1, 1, 1, 1)"; 252 break; 253 254 case IMAGE_OPERATION_ATOMIC_ADD: 255 case IMAGE_OPERATION_ATOMIC_MIN: 256 case IMAGE_OPERATION_ATOMIC_MAX: 257 case IMAGE_OPERATION_ATOMIC_AND: 258 case IMAGE_OPERATION_ATOMIC_OR: 259 case IMAGE_OPERATION_ATOMIC_XOR: 260 return ", 1"; 261 262 case IMAGE_OPERATION_ATOMIC_EXCHANGE: 263 return isFloat ? ", 1.0" : ", 1"; 264 265 case IMAGE_OPERATION_ATOMIC_COMP_SWAP: 266 return ", 1, 1"; 267 268 default: 269 DE_ASSERT(false); 270 return std::string(""); 271 } 272 return data.str(); 273 } 274 275 std::string getMemoryQualifier (MemoryQualifier memory) 276 { 277 switch (memory) 278 { 279 case MEMORY_NONE: 280 return std::string(""); 281 282 case MEMORY_WRITEONLY: 283 return std::string("writeonly"); 284 285 case MEMORY_READONLY: 286 return std::string("readonly"); 287 288 case MEMORY_BOTH: 289 return std::string("writeonly readonly"); 290 291 default: 292 DE_ASSERT(DE_FALSE); 293 } 294 295 return std::string(""); 296 } 297 298 std::string getShaderImageFunctionExtensionString (ImageOperation function) 299 { 300 switch (function) 301 { 302 case IMAGE_OPERATION_STORE: 303 case IMAGE_OPERATION_LOAD: 304 return std::string(""); 305 306 case IMAGE_OPERATION_ATOMIC_ADD: 307 case IMAGE_OPERATION_ATOMIC_MIN: 308 case IMAGE_OPERATION_ATOMIC_MAX: 309 case IMAGE_OPERATION_ATOMIC_AND: 310 case IMAGE_OPERATION_ATOMIC_OR: 311 case IMAGE_OPERATION_ATOMIC_XOR: 312 case IMAGE_OPERATION_ATOMIC_EXCHANGE: 313 case IMAGE_OPERATION_ATOMIC_COMP_SWAP: 314 return std::string("#extension GL_OES_shader_image_atomic : enable"); 315 316 default: 317 DE_ASSERT(DE_FALSE); 318 } 319 return std::string(""); 320 } 321 322 std::string getFunctionName (ImageOperation function) 323 { 324 switch (function) 325 { 326 case IMAGE_OPERATION_STORE: return std::string("imageStore"); 327 case IMAGE_OPERATION_LOAD: return std::string("imageLoad"); 328 case IMAGE_OPERATION_ATOMIC_ADD: return std::string("imageAtomicAdd"); 329 case IMAGE_OPERATION_ATOMIC_MIN: return std::string("imageAtomicMin"); 330 case IMAGE_OPERATION_ATOMIC_MAX: return std::string("imageAtomicMax"); 331 case IMAGE_OPERATION_ATOMIC_AND: return std::string("imageAtomicAnd"); 332 case IMAGE_OPERATION_ATOMIC_OR: return std::string("imageAtomicOr"); 333 case IMAGE_OPERATION_ATOMIC_XOR: return std::string("imageAtomicXor"); 334 case IMAGE_OPERATION_ATOMIC_EXCHANGE: return std::string("imageAtomicExchange"); 335 case IMAGE_OPERATION_ATOMIC_COMP_SWAP: return std::string("imageAtomicCompSwap"); 336 default: 337 DE_ASSERT(DE_FALSE); 338 } 339 return std::string(""); 340 } 341 342 std::string generateShaderSource (ImageOperation function, MemoryQualifier memory, glu::TextureTestUtil::TextureType imageType, const tcu::TextureFormat& format, glu::ShaderType shaderType) 343 { 344 const char* shaderTemplate = "${GLSL_VERSION_DECL}\n" 345 "${GLSL_TYPE_EXTENSION}\n" 346 "${GLSL_FUNCTION_EXTENSION}\n" 347 "${GEOMETRY_SHADER_LAYOUT}\n" 348 "layout(${LAYOUT_FORMAT}, binding = 0) highp uniform ${MEMORY_QUALIFIER} ${IMAGE_TYPE} u_img0;\n" 349 "void main(void)\n" 350 "{\n" 351 " ${FUNCTION_NAME}(u_img0, ${IMAGE_PARAM_P}${FUNCTION_ARGUMENTS});\n" 352 "}\n"; 353 354 std::map<std::string, std::string> params; 355 356 params["GLSL_VERSION_DECL"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES); 357 params["GLSL_TYPE_EXTENSION"] = getShaderImageTypeExtensionString(imageType); 358 params["GLSL_FUNCTION_EXTENSION"] = getShaderImageFunctionExtensionString(function); 359 params["GEOMETRY_SHADER_LAYOUT"] = getGLShaderType(shaderType) == GL_GEOMETRY_SHADER ? "layout(max_vertices = 3) out;" : ""; 360 params["LAYOUT_FORMAT"] = getShaderImageLayoutQualifier(format); 361 params["MEMORY_QUALIFIER"] = getMemoryQualifier(memory); 362 params["IMAGE_TYPE"] = getShaderImageTypeDeclaration(format, imageType); 363 params["FUNCTION_NAME"] = getFunctionName(function); 364 params["IMAGE_PARAM_P"] = getShaderImageParamP(imageType); 365 params["FUNCTION_ARGUMENTS"] = getOtherFunctionArguments(format, function); 366 367 return tcu::StringTemplate(shaderTemplate).specialize(params); 368 } 369 370 void testShader (NegativeTestContext& ctx, ImageOperation function, MemoryQualifier memory, glu::TextureTestUtil::TextureType imageType, const tcu::TextureFormat& format) 371 { 372 tcu::TestLog& log = ctx.getLog(); 373 ctx.beginSection(getFunctionName(function) + " " + getMemoryQualifier(memory) + " " + getShaderImageLayoutQualifier(format)); 374 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaders); ndx++) 375 { 376 if (ctx.isShaderSupported(s_shaders[ndx])) 377 { 378 ctx.beginSection(std::string("Verify shader: ") + glu::getShaderTypeName(s_shaders[ndx])); 379 std::string shaderSource(generateShaderSource(function, memory, imageType, format, s_shaders[ndx])); 380 const glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources() << glu::ShaderSource(s_shaders[ndx], shaderSource)); 381 if (program.getShaderInfo(s_shaders[ndx]).compileOk) 382 { 383 log << program; 384 log << tcu::TestLog::Message << "Expected program to fail, but compilation passed." << tcu::TestLog::EndMessage; 385 ctx.fail("Shader was not expected to compile."); 386 } 387 ctx.endSection(); 388 } 389 } 390 ctx.endSection(); 391 } 392 393 void image_store (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType) 394 { 395 const tcu::TextureFormat formats[] = 396 { 397 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), 398 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::HALF_FLOAT), 399 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), 400 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 401 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SNORM_INT8), 402 403 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32), 404 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT16), 405 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8), 406 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT32), 407 408 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32), 409 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16), 410 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8), 411 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT32) 412 }; 413 414 const MemoryQualifier memoryOptions[] = 415 { 416 MEMORY_READONLY, 417 MEMORY_BOTH 418 }; 419 420 ctx.beginSection("It is an error to pass a readonly image to imageStore."); 421 for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx) 422 { 423 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx) 424 { 425 testShader(ctx, IMAGE_OPERATION_STORE, memoryOptions[memoryNdx], imageType, formats[fmtNdx]); 426 } 427 } 428 ctx.endSection(); 429 } 430 431 void image_load (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType) 432 { 433 const tcu::TextureFormat formats[] = 434 { 435 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), 436 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::HALF_FLOAT), 437 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), 438 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 439 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SNORM_INT8), 440 441 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32), 442 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT16), 443 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8), 444 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT32), 445 446 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32), 447 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16), 448 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8), 449 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT32) 450 }; 451 452 const MemoryQualifier memoryOptions[] = 453 { 454 MEMORY_WRITEONLY, 455 MEMORY_BOTH 456 }; 457 458 ctx.beginSection("It is an error to pass a writeonly image to imageLoad."); 459 for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx) 460 { 461 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx) 462 { 463 testShader(ctx, IMAGE_OPERATION_LOAD, memoryOptions[memoryNdx], imageType, formats[fmtNdx]); 464 } 465 } 466 ctx.endSection(); 467 } 468 469 void image_atomic (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType) 470 { 471 const tcu::TextureFormat formats[] = 472 { 473 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32), 474 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT16), 475 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8), 476 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT32), 477 478 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32), 479 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16), 480 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8), 481 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT32) 482 }; 483 484 const MemoryQualifier memoryOptions[] = 485 { 486 MEMORY_READONLY, 487 MEMORY_WRITEONLY, 488 MEMORY_BOTH 489 }; 490 491 const ImageOperation imageOperations[] = 492 { 493 IMAGE_OPERATION_ATOMIC_ADD, 494 IMAGE_OPERATION_ATOMIC_MIN, 495 IMAGE_OPERATION_ATOMIC_MAX, 496 IMAGE_OPERATION_ATOMIC_AND, 497 IMAGE_OPERATION_ATOMIC_OR, 498 IMAGE_OPERATION_ATOMIC_XOR, 499 IMAGE_OPERATION_ATOMIC_COMP_SWAP 500 }; 501 502 ctx.beginSection("It is an error to pass a writeonly and/or readonly image to imageAtomic*."); 503 for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx) 504 { 505 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx) 506 { 507 for (int functionNdx = 0; functionNdx < DE_LENGTH_OF_ARRAY(imageOperations); ++functionNdx) 508 { 509 testShader(ctx, imageOperations[functionNdx], memoryOptions[memoryNdx], imageType, formats[fmtNdx]); 510 } 511 } 512 } 513 ctx.endSection(); 514 } 515 516 void image_atomic_exchange (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType) 517 { 518 const tcu::TextureFormat formats[] = 519 { 520 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), 521 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::HALF_FLOAT), 522 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), 523 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 524 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SNORM_INT8), 525 526 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32), 527 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT16), 528 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8), 529 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT32), 530 531 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32), 532 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16), 533 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8), 534 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT32) 535 }; 536 537 const MemoryQualifier memoryOptions[] = 538 { 539 MEMORY_READONLY, 540 MEMORY_WRITEONLY, 541 MEMORY_BOTH 542 }; 543 544 ctx.beginSection("It is an error to pass a writeonly and/or readonly image to imageAtomic*."); 545 for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx) 546 { 547 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx) 548 { 549 testShader(ctx, IMAGE_OPERATION_ATOMIC_EXCHANGE, memoryOptions[memoryNdx], imageType, formats[fmtNdx]); 550 } 551 } 552 ctx.endSection(); 553 } 554 555 // Re-routing function template for generating the standard negative 556 // test function signature with texture type added. 557 558 template <int Type> 559 void loadFuncWrapper (NegativeTestContext& ctx) 560 { 561 image_load(ctx, (glu::TextureTestUtil::TextureType)Type); 562 } 563 564 template <int Type> 565 void storeFuncWrapper (NegativeTestContext& ctx) 566 { 567 image_store(ctx, (glu::TextureTestUtil::TextureType)Type); 568 } 569 570 template <int Type> 571 void atomicFuncWrapper (NegativeTestContext& ctx) 572 { 573 image_atomic(ctx, (glu::TextureTestUtil::TextureType)Type); 574 } 575 576 template <int Type> 577 void atomicExchangeFuncWrapper (NegativeTestContext& ctx) 578 { 579 image_atomic_exchange(ctx, (glu::TextureTestUtil::TextureType)Type); 580 } 581 582 } // anonymous 583 584 // Set of texture types to create tests for. 585 #define CREATE_TEST_FUNC_PER_TEXTURE_TYPE(NAME, FUNC) const FunctionContainer NAME[] = \ 586 { \ 587 {FUNC<glu::TextureTestUtil::TEXTURETYPE_2D>, "texture_2d", "Texture2D negative tests."}, \ 588 {FUNC<glu::TextureTestUtil::TEXTURETYPE_3D>, "texture_3d", "Texture3D negative tests."}, \ 589 {FUNC<glu::TextureTestUtil::TEXTURETYPE_CUBE>, "cube", "Cube texture negative tests."}, \ 590 {FUNC<glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY>, "2d_array", "2D array texture negative tests."}, \ 591 {FUNC<glu::TextureTestUtil::TEXTURETYPE_BUFFER>, "buffer", "Buffer negative tests."}, \ 592 {FUNC<glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY>, "cube_array", "Cube array texture negative tests."} \ 593 } 594 595 std::vector<FunctionContainer> getNegativeShaderImageLoadTestFunctions (void) 596 { 597 CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, loadFuncWrapper); 598 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); 599 } 600 601 std::vector<FunctionContainer> getNegativeShaderImageStoreTestFunctions (void) 602 { 603 CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, storeFuncWrapper); 604 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); 605 } 606 607 std::vector<FunctionContainer> getNegativeShaderImageAtomicTestFunctions (void) 608 { 609 CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, atomicFuncWrapper); 610 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); 611 } 612 613 std::vector<FunctionContainer> getNegativeShaderImageAtomicExchangeTestFunctions (void) 614 { 615 CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, atomicExchangeFuncWrapper); 616 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); 617 } 618 619 } // NegativeTestShared 620 } // Functional 621 } // gles31 622 } // deqp 623