1 /*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 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 /** 25 */ /*! 26 * \file gl4cSparseTexture2Tests.cpp 27 * \brief Conformance tests for the GL_ARB_sparse_texture2 functionality. 28 */ /*-------------------------------------------------------------------*/ 29 30 #include "gl4cSparseTexture2Tests.hpp" 31 #include "deStringUtil.hpp" 32 #include "gl4cSparseTextureTests.hpp" 33 #include "gluContextInfo.hpp" 34 #include "gluDefs.hpp" 35 #include "glwEnums.hpp" 36 #include "glwFunctions.hpp" 37 #include "tcuTestLog.hpp" 38 39 #include <cmath> 40 #include <stdio.h> 41 #include <string.h> 42 #include <vector> 43 44 using namespace glw; 45 using namespace glu; 46 47 namespace gl4cts 48 { 49 50 const char* st2_compute_textureFill = "#version 430 core\n" 51 "\n" 52 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 53 "\n" 54 "layout (location = 1) writeonly uniform highp <INPUT_TYPE> uni_image;\n" 55 "\n" 56 "void main()\n" 57 "{\n" 58 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n" 59 " memoryBarrier();\n" 60 " <RETURN_TYPE> color = <RETURN_TYPE><RESULT_EXPECTED>;\n" 61 " imageStore(uni_image, point<SAMPLE_DEF>, color);\n" 62 "}\n"; 63 64 const char* st2_compute_textureVerify = "#version 430 core\n" 65 "\n" 66 "#extension GL_ARB_sparse_texture2 : enable\n" 67 "\n" 68 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 69 "\n" 70 "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out_image;\n" 71 "layout (location = 2, <FORMAT>) readonly uniform <INPUT_TYPE> uni_in_image;\n" 72 "\n" 73 "void main()\n" 74 "{\n" 75 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n" 76 " memoryBarrier();\n" 77 " highp <RETURN_TYPE> color,\n" 78 " expected,\n" 79 " epsilon;\n" 80 " color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n" 81 " expected = <RETURN_TYPE><RESULT_EXPECTED>;\n" 82 " epsilon = <RETURN_TYPE>(<EPSILON>);\n" 83 "\n" 84 " if (all(lessThanEqual(color, expected + epsilon)) &&\n" 85 " all(greaterThanEqual(color, expected - epsilon)))\n" 86 " {\n" 87 " imageStore(uni_out_image, point, uvec4(255));\n" 88 " }\n" 89 " else {\n" 90 " imageStore(uni_out_image, point, uvec4(0));\n" 91 " }\n" 92 "}\n"; 93 94 const char* st2_compute_atomicVerify = "#version 430 core\n" 95 "\n" 96 "#extension GL_ARB_sparse_texture2 : enable\n" 97 "\n" 98 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 99 "\n" 100 "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out_image;\n" 101 "layout (location = 2, <FORMAT>) uniform <INPUT_TYPE> uni_in_image;\n" 102 "\n" 103 "layout (location = 3) uniform int widthCommitted;\n" 104 "\n" 105 "void main()\n" 106 "{\n" 107 " <POINT_TYPE> point,\n" 108 " offset;\n" 109 " point = <POINT_TYPE>(<POINT_DEF>);\n" 110 " offset = <POINT_TYPE>(0);\n" 111 " offset.x = widthCommitted;\n" 112 " memoryBarrier();\n" 113 " if (point.x >= widthCommitted) {\n" 114 " uint index = ((point.x - widthCommitted) + point.y * 8) % 8;\n" 115 " <DATA_TYPE> value = 127;\n" 116 " if (index == 0)\n" 117 " value = imageAtomicExchange(uni_in_image, point<SAMPLE_DEF>,\n" 118 " <DATA_TYPE>(0x0F));\n" 119 " else if (index == 1)\n" 120 " value = imageAtomicCompSwap(uni_in_image, point<SAMPLE_DEF>,\n" 121 " <DATA_TYPE>(0), <DATA_TYPE>(0x0F));\n" 122 " else if (index == 2)\n" 123 " value = imageAtomicAdd(uni_in_image, point<SAMPLE_DEF>,\n" 124 " <DATA_TYPE>(0x0F));\n" 125 " else if (index == 3)\n" 126 " value = imageAtomicAnd(uni_in_image, point<SAMPLE_DEF>,\n" 127 " <DATA_TYPE>(0x0F));\n" 128 " else if (index == 4)\n" 129 " value = imageAtomicOr(uni_in_image, point<SAMPLE_DEF>,\n" 130 " <DATA_TYPE>(0x0F));\n" 131 " else if (index == 5)\n" 132 " value = imageAtomicXor(uni_in_image, point<SAMPLE_DEF>,\n" 133 " <DATA_TYPE>(0x0F));\n" 134 " else if (index == 6)\n" 135 " value = imageAtomicMin(uni_in_image, point<SAMPLE_DEF>,\n" 136 " <DATA_TYPE>(0x0F));\n" 137 " else if (index == 7)\n" 138 " value = imageAtomicMax(uni_in_image, point<SAMPLE_DEF>,\n" 139 " <DATA_TYPE>(0x0F));\n" 140 "\n" 141 " <RETURN_TYPE> color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n" 142 "\n" 143 " if (value == 0)\n" 144 " imageStore(uni_out_image, point - offset, uvec4(0));\n" 145 " else\n" 146 " imageStore(uni_out_image, point - offset, uvec4(value));\n" 147 "\n" 148 " if (color.r == 0)\n" 149 " imageStore(uni_out_image, point, uvec4(0));\n" 150 " else\n" 151 " imageStore(uni_out_image, point, uvec4(1));\n" 152 " }\n" 153 "}\n"; 154 155 const char* st2_vertex_drawBuffer = "#version 430 core\n" 156 "\n" 157 "#extension GL_ARB_sparse_texture2 : enable\n" 158 "\n" 159 "in vec3 vertex;\n" 160 "in vec2 inTexCoord;\n" 161 "out vec2 texCoord;\n" 162 "\n" 163 "void main()\n" 164 "{\n" 165 " texCoord = inTexCoord;\n" 166 " gl_Position = vec4(vertex, 1);\n" 167 "}\n"; 168 169 const char* st2_fragment_drawBuffer = "#version 430 core\n" 170 "\n" 171 "#extension GL_ARB_sparse_texture2 : enable\n" 172 "\n" 173 "layout (location = 1) uniform sampler2D uni_sampler;\n" 174 "\n" 175 "in vec2 texCoord;\n" 176 "out vec4 fragColor;\n" 177 "\n" 178 "void main()\n" 179 "{\n" 180 " fragColor = texture(uni_sampler, texCoord);\n" 181 "}\n"; 182 183 const char* st2_compute_extensionCheck = "#version 450 core\n" 184 "\n" 185 "#extension <EXTENSION> : require\n" 186 "\n" 187 "#ifndef <EXTENSION>\n" 188 " #error <EXTENSION> not defined\n" 189 "#else\n" 190 " #if (<EXTENSION> != 1)\n" 191 " #error <EXTENSION> wrong value\n" 192 " #endif\n" 193 "#endif // <EXTENSION>\n" 194 "\n" 195 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 196 "\n" 197 "void main()\n" 198 "{\n" 199 "}\n"; 200 201 const char* st2_compute_lookupVerify = "#version 450 core\n" 202 "\n" 203 "#extension GL_ARB_sparse_texture2 : enable\n" 204 "#extension GL_ARB_sparse_texture_clamp : enable\n" 205 "\n" 206 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 207 "\n" 208 "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out;\n" 209 "layout (location = 2<FORMAT_DEF>) uniform <INPUT_TYPE> uni_in;\n" 210 "layout (location = 3) uniform int widthCommitted;\n" 211 "\n" 212 "void main()\n" 213 "{\n" 214 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n" 215 " <ICOORD_TYPE> texSize = <ICOORD_TYPE>(<SIZE_DEF>);\n" 216 " <ICOORD_TYPE> icoord = <ICOORD_TYPE>(<COORD_DEF>);\n" 217 " <COORD_TYPE> coord = <COORD_TYPE>(<COORD_DEF>) / <COORD_TYPE>(texSize);\n" 218 " <RETURN_TYPE> retValue,\n" 219 " expValue,\n" 220 " epsilon;\n" 221 " retValue = <RETURN_TYPE>(0);\n" 222 " expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n" 223 " epsilon = <RETURN_TYPE>(<EPSILON>);\n" 224 "\n" 225 "<CUBE_MAP_COORD_DEF>\n" 226 "<OFFSET_ARRAY_DEF>\n" 227 "\n" 228 " ivec2 corner1 = ivec2(1, 1);\n" 229 " ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n" 230 "\n" 231 " int code = <FUNCTION>(uni_in,\n" 232 " <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n" 233 " retValue<COMPONENT_DEF>);\n" 234 " memoryBarrier();\n" 235 "\n" 236 " imageStore(uni_out, point, uvec4(255));\n" 237 "\n" 238 " if (point.x > corner1.x && point.y > corner1.y &&\n" 239 " point.x < corner2.x && point.y < corner2.y &&\n" 240 " point.x < widthCommitted - 1)\n" 241 " {\n" 242 " if (!sparseTexelsResidentARB(code) ||\n" 243 " any(greaterThan(retValue, expValue + epsilon)) ||\n" 244 " any(lessThan(retValue, expValue - epsilon)))\n" 245 " {\n" 246 " imageStore(uni_out, point, uvec4(0));\n" 247 " }\n" 248 " }\n" 249 "\n" 250 " if (point.x > corner1.x && point.y > corner1.y &&\n" 251 " point.x < corner2.x && point.y < corner2.y &&\n" 252 " point.x >= widthCommitted + 1)\n" 253 " {\n" 254 " if (sparseTexelsResidentARB(code))\n" 255 " {\n" 256 " imageStore(uni_out, point, uvec4(0));\n" 257 " }\n" 258 " }\n" 259 "}\n"; 260 261 /** Replace all occurance of <token> with <text> in <string> 262 * 263 * @param token Token string 264 * @param text String that will be used as replacement for <token> 265 * @param string String to work on 266 **/ 267 void replaceToken(const GLchar* token, const GLchar* text, std::string& string) 268 { 269 const size_t text_length = strlen(text); 270 const size_t token_length = strlen(token); 271 272 size_t token_position; 273 while ((token_position = string.find(token, 0)) != std::string::npos) 274 { 275 string.replace(token_position, token_length, text, text_length); 276 } 277 } 278 279 /** Constructor. 280 * 281 * @param context Rendering context 282 */ 283 ShaderExtensionTestCase::ShaderExtensionTestCase(deqp::Context& context, const std::string extension) 284 : TestCase(context, "ShaderExtension", "Verifies if extension is available for GLSL"), mExtension(extension) 285 { 286 /* Left blank intentionally */ 287 } 288 289 /** Executes test iteration. 290 * 291 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 292 */ 293 tcu::TestNode::IterateResult ShaderExtensionTestCase::iterate() 294 { 295 if (!m_context.getContextInfo().isExtensionSupported(mExtension.c_str())) 296 { 297 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 298 return STOP; 299 } 300 301 const Functions& gl = m_context.getRenderContext().getFunctions(); 302 303 std::string shader = st2_compute_extensionCheck; 304 replaceToken("<EXTENSION>", mExtension.c_str(), shader); 305 306 ProgramSources sources; 307 sources << ComputeSource(shader); 308 ShaderProgram program(gl, sources); 309 310 if (!program.isOk()) 311 { 312 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 313 m_testCtx.getLog() << tcu::TestLog::Message << "Checking shader preprocessor directives failed. Source:\n" 314 << shader.c_str() << "InfoLog:\n" 315 << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n" 316 << tcu::TestLog::EndMessage; 317 return STOP; 318 } 319 320 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 321 return STOP; 322 } 323 324 /** Constructor. 325 * 326 * @param context Rendering context 327 */ 328 StandardPageSizesTestCase::StandardPageSizesTestCase(deqp::Context& context) 329 : TestCase(context, "StandardPageSizesTestCase", 330 "Verifies if values returned by GetInternalFormativ query matches Standard Virtual Page Sizes") 331 { 332 /* Left blank intentionally */ 333 } 334 335 /** Stub init method */ 336 void StandardPageSizesTestCase::init() 337 { 338 mSupportedTargets.push_back(GL_TEXTURE_1D); 339 mSupportedTargets.push_back(GL_TEXTURE_1D_ARRAY); 340 mSupportedTargets.push_back(GL_TEXTURE_2D); 341 mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY); 342 mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP); 343 mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY); 344 mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE); 345 mSupportedTargets.push_back(GL_TEXTURE_BUFFER); 346 mSupportedTargets.push_back(GL_RENDERBUFFER); 347 348 mStandardVirtualPageSizesTable[GL_R8] = PageSizeStruct(256, 256, 1); 349 mStandardVirtualPageSizesTable[GL_R8_SNORM] = PageSizeStruct(256, 256, 1); 350 mStandardVirtualPageSizesTable[GL_R8I] = PageSizeStruct(256, 256, 1); 351 mStandardVirtualPageSizesTable[GL_R8UI] = PageSizeStruct(256, 256, 1); 352 mStandardVirtualPageSizesTable[GL_R16] = PageSizeStruct(256, 128, 1); 353 mStandardVirtualPageSizesTable[GL_R16_SNORM] = PageSizeStruct(256, 128, 1); 354 mStandardVirtualPageSizesTable[GL_RG8] = PageSizeStruct(256, 128, 1); 355 mStandardVirtualPageSizesTable[GL_RG8_SNORM] = PageSizeStruct(256, 128, 1); 356 mStandardVirtualPageSizesTable[GL_RGB565] = PageSizeStruct(256, 128, 1); 357 mStandardVirtualPageSizesTable[GL_R16F] = PageSizeStruct(256, 128, 1); 358 mStandardVirtualPageSizesTable[GL_R16I] = PageSizeStruct(256, 128, 1); 359 mStandardVirtualPageSizesTable[GL_R16UI] = PageSizeStruct(256, 128, 1); 360 mStandardVirtualPageSizesTable[GL_RG8I] = PageSizeStruct(256, 128, 1); 361 mStandardVirtualPageSizesTable[GL_RG8UI] = PageSizeStruct(256, 128, 1); 362 mStandardVirtualPageSizesTable[GL_RG16] = PageSizeStruct(128, 128, 1); 363 mStandardVirtualPageSizesTable[GL_RG16_SNORM] = PageSizeStruct(128, 128, 1); 364 mStandardVirtualPageSizesTable[GL_RGBA8] = PageSizeStruct(128, 128, 1); 365 mStandardVirtualPageSizesTable[GL_RGBA8_SNORM] = PageSizeStruct(128, 128, 1); 366 mStandardVirtualPageSizesTable[GL_RGB10_A2] = PageSizeStruct(128, 128, 1); 367 mStandardVirtualPageSizesTable[GL_RGB10_A2UI] = PageSizeStruct(128, 128, 1); 368 mStandardVirtualPageSizesTable[GL_RG16F] = PageSizeStruct(128, 128, 1); 369 mStandardVirtualPageSizesTable[GL_R32F] = PageSizeStruct(128, 128, 1); 370 mStandardVirtualPageSizesTable[GL_R11F_G11F_B10F] = PageSizeStruct(128, 128, 1); 371 mStandardVirtualPageSizesTable[GL_RGB9_E5] = PageSizeStruct(128, 128, 1); 372 mStandardVirtualPageSizesTable[GL_R32I] = PageSizeStruct(128, 128, 1); 373 mStandardVirtualPageSizesTable[GL_R32UI] = PageSizeStruct(128, 128, 1); 374 mStandardVirtualPageSizesTable[GL_RG16I] = PageSizeStruct(128, 128, 1); 375 mStandardVirtualPageSizesTable[GL_RG16UI] = PageSizeStruct(128, 128, 1); 376 mStandardVirtualPageSizesTable[GL_RGBA8I] = PageSizeStruct(128, 128, 1); 377 mStandardVirtualPageSizesTable[GL_RGBA8UI] = PageSizeStruct(128, 128, 1); 378 mStandardVirtualPageSizesTable[GL_RGBA16] = PageSizeStruct(128, 64, 1); 379 mStandardVirtualPageSizesTable[GL_RGBA16_SNORM] = PageSizeStruct(128, 64, 1); 380 mStandardVirtualPageSizesTable[GL_RGBA16F] = PageSizeStruct(128, 64, 1); 381 mStandardVirtualPageSizesTable[GL_RG32F] = PageSizeStruct(128, 64, 1); 382 mStandardVirtualPageSizesTable[GL_RG32I] = PageSizeStruct(128, 64, 1); 383 mStandardVirtualPageSizesTable[GL_RG32UI] = PageSizeStruct(128, 64, 1); 384 mStandardVirtualPageSizesTable[GL_RGBA16I] = PageSizeStruct(128, 64, 1); 385 mStandardVirtualPageSizesTable[GL_RGBA16UI] = PageSizeStruct(128, 64, 1); 386 mStandardVirtualPageSizesTable[GL_RGBA32F] = PageSizeStruct(64, 64, 1); 387 mStandardVirtualPageSizesTable[GL_RGBA32I] = PageSizeStruct(64, 64, 1); 388 mStandardVirtualPageSizesTable[GL_RGBA32UI] = PageSizeStruct(64, 64, 1); 389 } 390 391 /** Executes test iteration. 392 * 393 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 394 */ 395 tcu::TestNode::IterateResult StandardPageSizesTestCase::iterate() 396 { 397 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2")) 398 { 399 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 400 return STOP; 401 } 402 403 const Functions& gl = m_context.getRenderContext().getFunctions(); 404 405 m_testCtx.getLog() << tcu::TestLog::Message << "Testing getInternalformativ" << tcu::TestLog::EndMessage; 406 407 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end(); 408 ++iter) 409 { 410 const GLint& target = *iter; 411 412 for (std::map<glw::GLint, PageSizeStruct>::const_iterator formIter = mStandardVirtualPageSizesTable.begin(); 413 formIter != mStandardVirtualPageSizesTable.end(); ++formIter) 414 { 415 const PageSizePair& format = *formIter; 416 const PageSizeStruct& page = format.second; 417 418 GLint pageSizeX; 419 GLint pageSizeY; 420 GLint pageSizeZ; 421 SparseTextureUtils::getTexturePageSizes(gl, target, format.first, pageSizeX, pageSizeY, pageSizeZ); 422 423 if (pageSizeX != page.xSize || pageSizeY != page.ySize || pageSizeZ != page.zSize) 424 { 425 m_testCtx.getLog() << tcu::TestLog::Message << "Standard Virtual Page Size mismatch, target: " << target 426 << ", format: " << format.first << ", returned: " << pageSizeX << "/" << pageSizeY 427 << "/" << pageSizeZ << ", expected: " << page.xSize << "/" << page.ySize << "/" 428 << page.zSize << tcu::TestLog::EndMessage; 429 430 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 431 return STOP; 432 } 433 } 434 } 435 436 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 437 438 return STOP; 439 } 440 441 /** Constructor. 442 * 443 * @param context Rendering context 444 */ 445 SparseTexture2AllocationTestCase::SparseTexture2AllocationTestCase(deqp::Context& context) 446 : SparseTextureAllocationTestCase(context, "SparseTexture2Allocation", 447 "Verifies TexStorage* functionality added in CTS_ARB_sparse_texture2") 448 { 449 /* Left blank intentionally */ 450 } 451 452 /** Initializes the test group contents. */ 453 void SparseTexture2AllocationTestCase::init() 454 { 455 SparseTextureAllocationTestCase::init(); 456 457 mSupportedTargets.clear(); 458 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE); 459 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 460 461 mFullArrayTargets.clear(); 462 mFullArrayTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 463 } 464 465 /** Executes test iteration. 466 * 467 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 468 */ 469 tcu::TestNode::IterateResult SparseTexture2AllocationTestCase::iterate() 470 { 471 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2")) 472 { 473 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 474 return STOP; 475 } 476 477 return SparseTextureAllocationTestCase::iterate(); 478 } 479 480 /** Constructor. 481 * 482 * @param context Rendering context 483 * @param name Test name 484 * @param description Test description 485 */ 486 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context, const char* name, 487 const char* description) 488 : SparseTextureCommitmentTestCase(context, name, description) 489 { 490 /* Left blank intentionally */ 491 } 492 493 /** Constructor. 494 * 495 * @param context Rendering context 496 */ 497 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context) 498 : SparseTextureCommitmentTestCase( 499 context, "SparseTexture2Commitment", 500 "Verifies glTexPageCommitmentARB functionality added by ARB_sparse_texture2 extension") 501 { 502 /* Left blank intentionally */ 503 } 504 505 /** Initializes the test group contents. */ 506 void SparseTexture2CommitmentTestCase::init() 507 { 508 SparseTextureCommitmentTestCase::init(); 509 510 //Verify all targets once again and multisample targets as it was added in ARB_sparse_texture2 extension 511 mSupportedTargets.clear(); 512 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE); 513 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 514 } 515 516 /** Executes test iteration. 517 * 518 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 519 */ 520 tcu::TestNode::IterateResult SparseTexture2CommitmentTestCase::iterate() 521 { 522 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2")) 523 { 524 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 525 return STOP; 526 } 527 528 return SparseTextureCommitmentTestCase::iterate(); 529 } 530 531 /** Create set of token strings fit to texture verifying shader 532 * 533 * @param target Target for which texture is binded 534 * @param format Texture internal format 535 * @param sample Texture sample number 536 537 * @return target Structure of token strings 538 */ 539 SparseTexture2CommitmentTestCase::TokenStrings SparseTexture2CommitmentTestCase::createShaderTokens( 540 GLint target, GLint format, GLint sample, const std::string outputBase, const std::string inputBase) 541 { 542 TokenStrings s; 543 std::string prefix; 544 545 if (format == GL_R8) 546 { 547 s.format = "r8"; 548 s.resultExpected = "(1, 0, 0, 1)"; 549 s.resultDefault = "(0, 0, 0, 1)"; 550 } 551 else if (format == GL_R8_SNORM) 552 { 553 s.format = "r8_snorm"; 554 s.resultExpected = "(1, 0, 0, 1)"; 555 s.resultDefault = "(0, 0, 0, 1)"; 556 } 557 else if (format == GL_R16) 558 { 559 s.format = "r16"; 560 s.resultExpected = "(1, 0, 0, 1)"; 561 s.resultDefault = "(0, 0, 0, 1)"; 562 } 563 else if (format == GL_R16_SNORM) 564 { 565 s.format = "r16_snorm"; 566 s.resultExpected = "(1, 0, 0, 1)"; 567 s.resultDefault = "(0, 0, 0, 1)"; 568 } 569 else if (format == GL_RG8) 570 { 571 s.format = "rg8"; 572 s.resultExpected = "(1, 1, 0, 1)"; 573 s.resultDefault = "(0, 0, 0, 1)"; 574 } 575 else if (format == GL_RG8_SNORM) 576 { 577 s.format = "rg8_snorm"; 578 s.resultExpected = "(1, 1, 0, 1)"; 579 s.resultDefault = "(0, 0, 0, 1)"; 580 } 581 else if (format == GL_RG16) 582 { 583 s.format = "rg16"; 584 s.resultExpected = "(1, 1, 0, 1)"; 585 s.resultDefault = "(0, 0, 0, 1)"; 586 } 587 else if (format == GL_RG16_SNORM) 588 { 589 s.format = "rg16_snorm"; 590 s.resultExpected = "(1, 1, 0, 1)"; 591 s.resultDefault = "(0, 0, 0, 1)"; 592 } 593 else if (format == GL_RGBA8) 594 { 595 s.format = "rgba8"; 596 s.resultExpected = "(1, 1, 1, 1)"; 597 s.resultDefault = "(0, 0, 0, 0)"; 598 } 599 else if (format == GL_RGBA8_SNORM) 600 { 601 s.format = "rgba8_snorm"; 602 s.resultExpected = "(1, 1, 1, 1)"; 603 s.resultDefault = "(0, 0, 0, 0)"; 604 } 605 else if (format == GL_RGB10_A2) 606 { 607 s.format = "rgb10_a2"; 608 s.resultExpected = "(1, 1, 1, 1)"; 609 s.resultDefault = "(0, 0, 0, 0)"; 610 } 611 else if (format == GL_RGB10_A2UI) 612 { 613 s.format = "rgb10_a2ui"; 614 s.resultExpected = "(1, 1, 1, 1)"; 615 s.resultDefault = "(0, 0, 0, 0)"; 616 prefix = "u"; 617 } 618 else if (format == GL_RGBA16) 619 { 620 s.format = "rgba16"; 621 s.resultExpected = "(1, 1, 1, 1)"; 622 s.resultDefault = "(0, 0, 0, 0)"; 623 } 624 else if (format == GL_RGBA16_SNORM) 625 { 626 s.format = "rgba16_snorm"; 627 s.resultExpected = "(1, 1, 1, 1)"; 628 s.resultDefault = "(0, 0, 0, 0)"; 629 } 630 else if (format == GL_R16F) 631 { 632 s.format = "r16f"; 633 s.resultExpected = "(1, 0, 0, 1)"; 634 s.resultDefault = "(0, 0, 0, 1)"; 635 } 636 else if (format == GL_RG16F) 637 { 638 s.format = "rg16f"; 639 s.resultExpected = "(1, 1, 0, 1)"; 640 s.resultDefault = "(0, 0, 0, 1)"; 641 } 642 else if (format == GL_RGBA16F) 643 { 644 s.format = "rgba16f"; 645 s.resultExpected = "(1, 1, 1, 1)"; 646 s.resultDefault = "(0, 0, 0, 0)"; 647 } 648 else if (format == GL_R32F) 649 { 650 s.format = "r32f"; 651 s.resultExpected = "(1, 0, 0, 1)"; 652 s.resultDefault = "(0, 0, 0, 1)"; 653 } 654 else if (format == GL_RG32F) 655 { 656 s.format = "rg32f"; 657 s.resultExpected = "(1, 1, 0, 1)"; 658 s.resultDefault = "(0, 0, 0, 1)"; 659 } 660 else if (format == GL_RGBA32F) 661 { 662 s.format = "rgba32f"; 663 s.resultExpected = "(1, 1, 1, 1)"; 664 s.resultDefault = "(0, 0, 0, 0)"; 665 } 666 else if (format == GL_R11F_G11F_B10F) 667 { 668 s.format = "r11f_g11f_b10f"; 669 s.resultExpected = "(1, 1, 1, 1)"; 670 s.resultDefault = "(0, 0, 0, 1)"; 671 } 672 else if (format == GL_R8I) 673 { 674 s.format = "r8i"; 675 s.resultExpected = "(1, 0, 0, 1)"; 676 s.resultDefault = "(0, 0, 0, 1)"; 677 prefix = "i"; 678 } 679 else if (format == GL_R8UI) 680 { 681 s.format = "r8ui"; 682 s.resultExpected = "(1, 0, 0, 1)"; 683 s.resultDefault = "(0, 0, 0, 1)"; 684 prefix = "u"; 685 } 686 else if (format == GL_R16I) 687 { 688 s.format = "r16i"; 689 s.resultExpected = "(1, 0, 0, 1)"; 690 s.resultDefault = "(0, 0, 0, 1)"; 691 prefix = "i"; 692 } 693 else if (format == GL_R16UI) 694 { 695 s.format = "r16ui"; 696 s.resultExpected = "(1, 0, 0, 1)"; 697 s.resultDefault = "(0, 0, 0, 1)"; 698 prefix = "u"; 699 } 700 else if (format == GL_R32I) 701 { 702 s.format = "r32i"; 703 s.resultExpected = "(1, 0, 0, 1)"; 704 s.resultDefault = "(0, 0, 0, 1)"; 705 prefix = "i"; 706 } 707 else if (format == GL_R32UI) 708 { 709 s.format = "r32ui"; 710 s.resultExpected = "(1, 0, 0, 1)"; 711 s.resultDefault = "(0, 0, 0, 1)"; 712 prefix = "u"; 713 } 714 else if (format == GL_RG8I) 715 { 716 s.format = "rg8i"; 717 s.resultExpected = "(1, 1, 0, 1)"; 718 s.resultDefault = "(0, 0, 0, 1)"; 719 prefix = "i"; 720 } 721 else if (format == GL_RG8UI) 722 { 723 s.format = "rg8ui"; 724 s.resultExpected = "(1, 1, 0, 1)"; 725 s.resultDefault = "(0, 0, 0, 1)"; 726 prefix = "u"; 727 } 728 else if (format == GL_RG16I) 729 { 730 s.format = "rg16i"; 731 s.resultExpected = "(1, 1, 0, 1)"; 732 s.resultDefault = "(0, 0, 0, 1)"; 733 prefix = "i"; 734 } 735 else if (format == GL_RG16UI) 736 { 737 s.format = "rg16ui"; 738 s.resultExpected = "(1, 1, 0, 1)"; 739 s.resultDefault = "(0, 0, 0, 1)"; 740 prefix = "u"; 741 } 742 else if (format == GL_RG32I) 743 { 744 s.format = "rg32i"; 745 s.resultExpected = "(1, 1, 0, 1)"; 746 s.resultDefault = "(0, 0, 0, 1)"; 747 prefix = "i"; 748 } 749 else if (format == GL_RG32UI) 750 { 751 s.format = "rg32ui"; 752 s.resultExpected = "(1, 1, 0, 1)"; 753 s.resultDefault = "(0, 0, 0, 1)"; 754 prefix = "u"; 755 } 756 else if (format == GL_RGBA8I) 757 { 758 s.format = "rgba8i"; 759 s.resultExpected = "(1, 1, 1, 1)"; 760 s.resultDefault = "(0, 0, 0, 0)"; 761 prefix = "i"; 762 } 763 else if (format == GL_RGBA8UI) 764 { 765 s.format = "rgba8ui"; 766 s.resultExpected = "(1, 1, 1, 1)"; 767 s.resultDefault = "(0, 0, 0, 0)"; 768 prefix = "u"; 769 } 770 else if (format == GL_RGBA16I) 771 { 772 s.format = "rgba16i"; 773 s.resultExpected = "(1, 1, 1, 1)"; 774 s.resultDefault = "(0, 0, 0, 0)"; 775 prefix = "i"; 776 } 777 else if (format == GL_RGBA16UI) 778 { 779 s.format = "rgba16ui"; 780 s.resultExpected = "(1, 1, 1, 1)"; 781 s.resultDefault = "(0, 0, 0, 0)"; 782 prefix = "u"; 783 } 784 else if (format == GL_RGBA32I) 785 { 786 s.format = "rgba32i"; 787 s.resultExpected = "(1, 1, 1, 1)"; 788 s.resultDefault = "(0, 0, 0, 0)"; 789 prefix = "i"; 790 } 791 else if (format == GL_DEPTH_COMPONENT16) 792 { 793 s.format = "r16"; 794 s.resultExpected = "(1, 0, 0, 0)"; 795 s.resultDefault = "(0, 0, 0, 0)"; 796 } 797 798 s.returnType = prefix + "vec4"; 799 s.outputType = "u" + outputBase + "2D"; 800 s.inputType = prefix + inputBase + "2D"; 801 s.pointType = "ivec2"; 802 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y"; 803 804 if (s.returnType == "vec4") 805 s.epsilon = "0.008"; 806 else 807 s.epsilon = "0"; 808 809 if (target == GL_TEXTURE_1D) 810 { 811 s.outputType = "u" + outputBase + "2D"; 812 s.inputType = prefix + inputBase + "1D"; 813 s.pointType = "int"; 814 s.pointDef = "gl_WorkGroupID.x"; 815 } 816 else if (target == GL_TEXTURE_1D_ARRAY) 817 { 818 s.outputType = "u" + outputBase + "2D_ARRAY"; 819 s.inputType = prefix + inputBase + "1DArray"; 820 s.pointType = "ivec2"; 821 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.z"; 822 } 823 else if (target == GL_TEXTURE_2D_ARRAY) 824 { 825 s.outputType = "u" + outputBase + "2DArray"; 826 s.inputType = prefix + inputBase + "2DArray"; 827 s.pointType = "ivec3"; 828 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; 829 } 830 else if (target == GL_TEXTURE_3D) 831 { 832 s.outputType = "u" + outputBase + "2DArray"; 833 s.inputType = prefix + inputBase + "3D"; 834 s.pointType = "ivec3"; 835 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; 836 } 837 else if (target == GL_TEXTURE_CUBE_MAP) 838 { 839 s.outputType = "u" + outputBase + "2DArray"; 840 s.inputType = prefix + inputBase + "Cube"; 841 s.pointType = "ivec3"; 842 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6"; 843 } 844 else if (target == GL_TEXTURE_CUBE_MAP_ARRAY) 845 { 846 s.outputType = "u" + outputBase + "2DArray"; 847 s.inputType = prefix + inputBase + "CubeArray"; 848 s.pointType = "ivec3"; 849 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; 850 } 851 else if (target == GL_TEXTURE_RECTANGLE) 852 { 853 s.inputType = prefix + inputBase + "2DRect"; 854 } 855 else if (target == GL_TEXTURE_2D_MULTISAMPLE) 856 { 857 s.inputType = prefix + inputBase + "2DMS"; 858 s.sampleDef = ", " + de::toString(sample); 859 } 860 else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 861 { 862 s.outputType = "u" + outputBase + "2DArray"; 863 s.inputType = prefix + inputBase + "2DMSArray"; 864 s.pointType = "ivec3"; 865 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; 866 s.sampleDef = ", " + de::toString(sample); 867 } 868 869 return s; 870 } 871 872 /** Check if specific combination of target and format is allowed 873 * 874 * @param target Target for which texture is binded 875 * @param format Texture internal format 876 * 877 * @return Returns true if target/format combination is allowed, false otherwise. 878 */ 879 bool SparseTexture2CommitmentTestCase::caseAllowed(GLint target, GLint format) 880 { 881 // Multisample textures are filling with data and verifying using compute shader. 882 // As shaders do not support some texture formats it is necessary to exclude them. 883 if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && 884 (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5)) 885 { 886 return false; 887 } 888 889 return true; 890 } 891 892 /** Allocating sparse texture memory using texStorage* function 893 * 894 * @param gl GL API functions 895 * @param target Target for which texture is binded 896 * @param format Texture internal format 897 * @param texture Texture object 898 * @param levels Texture mipmaps level 899 * 900 * @return Returns true if no error occurred, otherwise throws an exception. 901 */ 902 bool SparseTexture2CommitmentTestCase::sparseAllocateTexture(const Functions& gl, GLint target, GLint format, 903 GLuint& texture, GLint levels) 904 { 905 mLog << "Sparse Allocate [levels: " << levels << "] - "; 906 907 prepareTexture(gl, target, format, texture); 908 909 GLint maxLevels; 910 gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE); 911 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB"); 912 gl.getTexParameteriv(target, GL_NUM_SPARSE_LEVELS_ARB, &maxLevels); 913 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv"); 914 if (levels > maxLevels) 915 levels = maxLevels; 916 917 //GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level 918 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE && 919 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 920 { 921 mState.levels = levels; 922 } 923 else 924 mState.levels = 1; 925 926 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 927 { 928 mState.samples = 1; 929 } 930 else 931 mState.samples = 2; 932 933 Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height, 934 mState.depth); 935 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage"); 936 937 return true; 938 } 939 940 /** Allocating texture memory using texStorage* function 941 * 942 * @param gl GL API functions 943 * @param target Target for which texture is binded 944 * @param format Texture internal format 945 * @param texture Texture object 946 * @param levels Texture mipmaps level 947 * 948 * @return Returns true if no error occurred, otherwise throws an exception. 949 */ 950 bool SparseTexture2CommitmentTestCase::allocateTexture(const Functions& gl, GLint target, GLint format, GLuint& texture, 951 GLint levels) 952 { 953 mLog << "Allocate [levels: " << levels << "] - "; 954 955 prepareTexture(gl, target, format, texture); 956 957 // GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level 958 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE && 959 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 960 { 961 mState.levels = levels; 962 } 963 else 964 mState.levels = 1; 965 966 // GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can use multiple samples 967 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 968 { 969 mState.samples = 1; 970 } 971 else 972 mState.samples = 2; 973 974 Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height, 975 mState.depth); 976 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage"); 977 978 return true; 979 } 980 981 /** Writing data to generated texture 982 * 983 * @param gl GL API functions 984 * @param target Target for which texture is binded 985 * @param format Texture internal format 986 * @param texture Texture object 987 * 988 * @return Returns true if no error occurred, otherwise throws an exception. 989 */ 990 bool SparseTexture2CommitmentTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format, 991 GLuint& texture, GLint level) 992 { 993 mLog << "Fill Texture [level: " << level << "] - "; 994 995 if (level > mState.levels - 1) 996 TCU_FAIL("Invalid level"); 997 998 TransferFormat transferFormat = glu::getTransferFormat(mState.format); 999 1000 GLint width; 1001 GLint height; 1002 GLint depth; 1003 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); 1004 1005 if (width > 0 && height > 0 && depth >= mState.minDepth) 1006 { 1007 if (target == GL_TEXTURE_CUBE_MAP) 1008 depth = depth * 6; 1009 1010 GLint texSize = width * height * depth * mState.format.getPixelSize(); 1011 1012 std::vector<GLubyte> vecData; 1013 vecData.resize(texSize); 1014 GLubyte* data = vecData.data(); 1015 1016 deMemset(data, 255, texSize); 1017 1018 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 1019 { 1020 Texture::SubImage(gl, target, level, 0, 0, 0, width, height, depth, transferFormat.format, 1021 transferFormat.dataType, (GLvoid*)data); 1022 GLU_EXPECT_NO_ERROR(gl.getError(), "SubImage"); 1023 } 1024 // For multisample texture use compute shader to store image data 1025 else 1026 { 1027 for (GLint sample = 0; sample < mState.samples; ++sample) 1028 { 1029 std::string shader = st2_compute_textureFill; 1030 1031 // Adjust shader source to texture format 1032 TokenStrings s = createShaderTokens(target, format, sample); 1033 1034 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader); 1035 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader); 1036 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader); 1037 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader); 1038 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader); 1039 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader); 1040 1041 ProgramSources sources; 1042 sources << ComputeSource(shader); 1043 1044 // Build and run shader 1045 ShaderProgram program(m_context.getRenderContext(), sources); 1046 if (program.isOk()) 1047 { 1048 gl.useProgram(program.getProgram()); 1049 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1050 gl.bindImageTexture(0 /* unit */, texture, level /* level */, GL_FALSE /* layered */, 0 /* layer */, 1051 GL_WRITE_ONLY, format); 1052 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 1053 gl.uniform1i(1, 0 /* image_unit */); 1054 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1055 gl.dispatchCompute(width, height, depth); 1056 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); 1057 gl.memoryBarrier(GL_ALL_BARRIER_BITS); 1058 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); 1059 } 1060 else 1061 { 1062 mLog << "Compute shader compilation failed (writing) for target: " << target 1063 << ", format: " << format << ", sample: " << sample 1064 << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog 1065 << ", shaderSource: " << shader.c_str() << " - "; 1066 } 1067 } 1068 } 1069 } 1070 1071 return true; 1072 } 1073 1074 /** Verify if data stored in texture is as expected 1075 * 1076 * @param gl GL API functions 1077 * @param target Target for which texture is binded 1078 * @param format Texture internal format 1079 * @param texture Texture object 1080 * @param level Texture mipmap level 1081 * 1082 * @return Returns true if data is as expected, false if not, throws an exception if error occurred. 1083 */ 1084 bool SparseTexture2CommitmentTestCase::verifyTextureData(const Functions& gl, GLint target, GLint format, 1085 GLuint& texture, GLint level) 1086 { 1087 mLog << "Verify Texture [level: " << level << "] - "; 1088 1089 if (level > mState.levels - 1) 1090 TCU_FAIL("Invalid level"); 1091 1092 TransferFormat transferFormat = glu::getTransferFormat(mState.format); 1093 1094 GLint width; 1095 GLint height; 1096 GLint depth; 1097 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); 1098 1099 //Committed region is limited to 1/2 of width 1100 GLint widthCommitted = width / 2; 1101 1102 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth) 1103 return true; 1104 1105 bool result = true; 1106 1107 if (target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE && 1108 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 1109 { 1110 GLint texSize = width * height * depth * mState.format.getPixelSize(); 1111 1112 std::vector<GLubyte> vecExpData; 1113 std::vector<GLubyte> vecOutData; 1114 vecExpData.resize(texSize); 1115 vecOutData.resize(texSize); 1116 GLubyte* exp_data = vecExpData.data(); 1117 GLubyte* out_data = vecOutData.data(); 1118 1119 deMemset(exp_data, 255, texSize); 1120 deMemset(out_data, 127, texSize); 1121 1122 Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data); 1123 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 1124 1125 //Verify only committed region 1126 for (GLint x = 0; x < widthCommitted; ++x) 1127 for (GLint y = 0; y < height; ++y) 1128 for (GLint z = 0; z < depth; ++z) 1129 { 1130 int pixelSize = mState.format.getPixelSize(); 1131 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize); 1132 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize); 1133 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0) 1134 result = false; 1135 } 1136 } 1137 else if (target == GL_TEXTURE_CUBE_MAP) 1138 { 1139 std::vector<GLint> subTargets; 1140 1141 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X); 1142 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X); 1143 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y); 1144 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y); 1145 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z); 1146 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); 1147 1148 GLint texSize = width * height * mState.format.getPixelSize(); 1149 1150 std::vector<GLubyte> vecExpData; 1151 std::vector<GLubyte> vecOutData; 1152 vecExpData.resize(texSize); 1153 vecOutData.resize(texSize); 1154 GLubyte* exp_data = vecExpData.data(); 1155 GLubyte* out_data = vecOutData.data(); 1156 1157 deMemset(exp_data, 255, texSize); 1158 1159 for (size_t i = 0; i < subTargets.size(); ++i) 1160 { 1161 GLint subTarget = subTargets[i]; 1162 1163 mLog << "Verify Subtarget [subtarget: " << subTarget << "] - "; 1164 1165 deMemset(out_data, 127, texSize); 1166 1167 Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data); 1168 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 1169 1170 //Verify only committed region 1171 for (GLint x = 0; x < widthCommitted; ++x) 1172 for (GLint y = 0; y < height; ++y) 1173 for (GLint z = 0; z < depth; ++z) 1174 { 1175 int pixelSize = mState.format.getPixelSize(); 1176 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize); 1177 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize); 1178 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0) 1179 result = false; 1180 } 1181 1182 if (!result) 1183 break; 1184 } 1185 } 1186 // For multisample texture use compute shader to verify image data 1187 else if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 1188 { 1189 GLint texSize = width * height * depth; 1190 1191 std::vector<GLubyte> vecExpData; 1192 std::vector<GLubyte> vecOutData; 1193 vecExpData.resize(texSize); 1194 vecOutData.resize(texSize); 1195 GLubyte* exp_data = vecExpData.data(); 1196 GLubyte* out_data = vecOutData.data(); 1197 1198 deMemset(exp_data, 255, texSize); 1199 1200 // Create verifying texture 1201 GLint verifyTarget; 1202 if (target == GL_TEXTURE_2D_MULTISAMPLE) 1203 verifyTarget = GL_TEXTURE_2D; 1204 else 1205 verifyTarget = GL_TEXTURE_2D_ARRAY; 1206 1207 GLuint verifyTexture; 1208 Texture::Generate(gl, verifyTexture); 1209 Texture::Bind(gl, verifyTexture, verifyTarget); 1210 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth); 1211 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage"); 1212 1213 for (int sample = 0; sample < mState.samples; ++sample) 1214 { 1215 deMemset(out_data, 0, texSize); 1216 1217 Texture::Bind(gl, verifyTexture, verifyTarget); 1218 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE, 1219 (GLvoid*)out_data); 1220 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage"); 1221 1222 std::string shader = st2_compute_textureVerify; 1223 1224 // Adjust shader source to texture format 1225 TokenStrings s = createShaderTokens(target, format, sample); 1226 1227 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader); 1228 replaceToken("<FORMAT>", s.format.c_str(), shader); 1229 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader); 1230 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader); 1231 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader); 1232 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader); 1233 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader); 1234 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader); 1235 replaceToken("<EPSILON>", s.epsilon.c_str(), shader); 1236 1237 ProgramSources sources; 1238 sources << ComputeSource(shader); 1239 1240 // Build and run shader 1241 ShaderProgram program(m_context.getRenderContext(), sources); 1242 if (program.isOk()) 1243 { 1244 gl.useProgram(program.getProgram()); 1245 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1246 gl.bindImageTexture(0, //unit 1247 verifyTexture, 1248 0, //level 1249 GL_FALSE, //layered 1250 0, //layer 1251 GL_WRITE_ONLY, GL_R8UI); 1252 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 1253 gl.bindImageTexture(1, //unit 1254 texture, 1255 level, //level 1256 GL_FALSE, //layered 1257 0, //layer 1258 GL_READ_ONLY, format); 1259 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 1260 gl.uniform1i(1, 0 /* image_unit */); 1261 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1262 gl.uniform1i(2, 1 /* image_unit */); 1263 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1264 gl.dispatchCompute(width, height, depth); 1265 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); 1266 gl.memoryBarrier(GL_ALL_BARRIER_BITS); 1267 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); 1268 1269 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data); 1270 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 1271 1272 //Verify only committed region 1273 for (GLint x = 0; x < widthCommitted; ++x) 1274 for (GLint y = 0; y < height; ++y) 1275 for (GLint z = 0; z < depth; ++z) 1276 { 1277 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height); 1278 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height); 1279 if (dataRegion[0] != outDataRegion[0]) 1280 result = false; 1281 } 1282 } 1283 else 1284 { 1285 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format 1286 << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog 1287 << ", shaderSource: " << shader.c_str() << " - "; 1288 1289 result = false; 1290 } 1291 } 1292 1293 Texture::Delete(gl, verifyTexture); 1294 } 1295 1296 return result; 1297 } 1298 1299 const GLfloat texCoord[] = { 1300 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1301 }; 1302 1303 const GLfloat vertices[] = { 1304 -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1305 }; 1306 1307 const GLuint indices[] = { 0, 1, 2, 1, 2, 3 }; 1308 1309 /** Constructor. 1310 * 1311 * @param context Rendering context 1312 */ 1313 UncommittedRegionsAccessTestCase::UncommittedRegionsAccessTestCase(deqp::Context& context) 1314 : SparseTexture2CommitmentTestCase(context, "UncommittedRegionsAccess", 1315 "Verifies if access to uncommitted regions of sparse texture works as expected") 1316 { 1317 /* Left blank intentionally */ 1318 } 1319 1320 /** Stub init method */ 1321 void UncommittedRegionsAccessTestCase::init() 1322 { 1323 SparseTextureCommitmentTestCase::init(); 1324 1325 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE); 1326 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 1327 } 1328 1329 /** Executes test iteration. 1330 * 1331 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1332 */ 1333 tcu::TestNode::IterateResult UncommittedRegionsAccessTestCase::iterate() 1334 { 1335 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2")) 1336 { 1337 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 1338 return STOP; 1339 } 1340 1341 const Functions& gl = m_context.getRenderContext().getFunctions(); 1342 1343 bool result = true; 1344 1345 GLuint texture; 1346 1347 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end(); 1348 ++iter) 1349 { 1350 const GLint& target = *iter; 1351 1352 for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin(); 1353 formIter != mSupportedInternalFormats.end(); ++formIter) 1354 { 1355 const GLint& format = *formIter; 1356 1357 if (!caseAllowed(target, format)) 1358 continue; 1359 1360 mLog.str(""); 1361 mLog << "Testing uncommitted regions access for target: " << target << ", format: " << format << " - "; 1362 1363 sparseAllocateTexture(gl, target, format, texture, 3); 1364 for (int l = 0; l < mState.levels; ++l) 1365 { 1366 if (commitTexturePage(gl, target, format, texture, l)) 1367 { 1368 writeDataToTexture(gl, target, format, texture, l); 1369 result = result && UncommittedReads(gl, target, format, texture, l); 1370 result = result && UncommittedAtomicOperations(gl, target, format, texture, l); 1371 } 1372 1373 if (!result) 1374 break; 1375 } 1376 1377 Texture::Delete(gl, texture); 1378 1379 if (!result) 1380 { 1381 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage; 1382 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1383 return STOP; 1384 } 1385 } 1386 } 1387 1388 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1389 return STOP; 1390 } 1391 1392 /** Check if reads from uncommitted regions are allowed 1393 * 1394 * @param target Target for which texture is binded 1395 * @param format Texture internal format 1396 * 1397 * @return Returns true if allowed, false otherwise. 1398 */ 1399 bool UncommittedRegionsAccessTestCase::readsAllowed(GLint target, GLint format, bool shaderOnly) 1400 { 1401 DE_UNREF(target); 1402 1403 if (shaderOnly && (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5)) 1404 { 1405 return false; 1406 } 1407 1408 return true; 1409 } 1410 1411 /** Check if atomic operations on uncommitted regions are allowed 1412 * 1413 * @param target Target for which texture is binded 1414 * @param format Texture internal format 1415 * 1416 * @return Returns true if allowed, false otherwise. 1417 */ 1418 bool UncommittedRegionsAccessTestCase::atomicAllowed(GLint target, GLint format) 1419 { 1420 DE_UNREF(target); 1421 1422 if (format == GL_R32I || format == GL_R32UI) 1423 { 1424 return true; 1425 } 1426 1427 return false; 1428 } 1429 1430 /** Check if depth and stencil test on uncommitted regions are allowed 1431 * 1432 * @param target Target for which texture is binded 1433 * @param format Texture internal format 1434 * 1435 * @return Returns true if allowed, false otherwise. 1436 */ 1437 bool UncommittedRegionsAccessTestCase::depthStencilAllowed(GLint target, GLint format) 1438 { 1439 if (target == GL_TEXTURE_2D && format == GL_RGBA8) 1440 { 1441 return true; 1442 } 1443 1444 return false; 1445 } 1446 1447 /** Verify reads from uncommitted texture regions works as expected 1448 * 1449 * @param gl GL API functions 1450 * @param target Target for which texture is binded 1451 * @param format Texture internal format 1452 * @param texture Texture object 1453 * @param level Texture mipmap level 1454 * 1455 * @return Returns true if data is as expected, false otherwise. 1456 */ 1457 bool UncommittedRegionsAccessTestCase::UncommittedReads(const Functions& gl, GLint target, GLint format, 1458 GLuint& texture, GLint level) 1459 { 1460 bool result = true; 1461 1462 // Verify using API glGetTexImage* 1463 if (readsAllowed(target, format, false)) 1464 { 1465 mLog << "API Reads - "; 1466 result = result && verifyTextureDataExtended(gl, target, format, texture, level, false); 1467 } 1468 1469 // Verify using shader imageLoad function 1470 if (result && readsAllowed(target, format, true)) 1471 { 1472 mLog << "Shader Reads - "; 1473 result = result && verifyTextureDataExtended(gl, target, format, texture, level, true); 1474 } 1475 1476 // Verify mipmap generating 1477 if (result && level == 0 && target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE && 1478 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 1479 { 1480 mLog << "Mipmap Generate - "; 1481 Texture::Bind(gl, texture, target); 1482 gl.generateMipmap(target); 1483 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap"); 1484 1485 for (int l = 1; l < mState.levels; ++l) 1486 result = result && verifyTextureDataExtended(gl, target, format, texture, level, false); 1487 } 1488 1489 return result; 1490 } 1491 1492 /** Verify atomic operations on uncommitted texture pixels works as expected 1493 * 1494 * @param gl GL API functions 1495 * @param target Target for which texture is binded 1496 * @param format Texture internal format 1497 * @param texture Texture object 1498 * @param level Texture mipmap level 1499 * 1500 * @return Returns true if data is as expected, false otherwise. 1501 */ 1502 bool UncommittedRegionsAccessTestCase::UncommittedAtomicOperations(const Functions& gl, GLint target, GLint format, 1503 GLuint& texture, GLint level) 1504 { 1505 bool result = true; 1506 1507 if (atomicAllowed(target, format)) 1508 { 1509 mLog << "Atomic Operations - "; 1510 result = result && verifyAtomicOperations(gl, target, format, texture, level); 1511 } 1512 1513 return result; 1514 } 1515 1516 /** Verify depth and stencil tests on uncommitted texture pixels works as expected 1517 * 1518 * @param gl GL API functions 1519 * @param target Target for which texture is binded 1520 * @param format Texture internal format 1521 * @param texture Texture object 1522 * @param level Texture mipmap level 1523 * 1524 * @return Returns true if data is as expected, false otherwise. 1525 */ 1526 bool UncommittedRegionsAccessTestCase::UncommittedDepthStencil(const Functions& gl, GLint target, GLint format, 1527 GLuint& texture, GLint level) 1528 { 1529 if (!depthStencilAllowed(target, format)) 1530 return true; 1531 1532 mLog << "Depth Stencil - "; 1533 1534 bool result = true; 1535 1536 GLint width; 1537 GLint height; 1538 GLint depth; 1539 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); 1540 1541 //Committed region is limited to 1/2 of width 1542 GLuint widthCommitted = width / 2; 1543 1544 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth) 1545 return true; 1546 1547 //Prepare shaders 1548 std::string vertexSource = st2_vertex_drawBuffer; 1549 std::string fragmentSource = st2_fragment_drawBuffer; 1550 1551 ShaderProgram program(gl, glu::makeVtxFragSources(vertexSource, fragmentSource)); 1552 if (!program.isOk()) 1553 { 1554 mLog << "Shader compilation failed (depth_stencil) for target: " << target << ", format: " << format 1555 << ", vertex_infoLog: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog 1556 << ", fragment_infoLog: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog 1557 << ", vertexSource: " << vertexSource.c_str() << "\n" 1558 << ", fragmentSource: " << fragmentSource.c_str() << " - "; 1559 1560 return false; 1561 } 1562 1563 prepareDepthStencilFramebuffer(gl, width, height); 1564 1565 gl.useProgram(program.getProgram()); 1566 1567 gl.activeTexture(GL_TEXTURE0); 1568 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture"); 1569 Texture::Bind(gl, texture, target); 1570 gl.uniform1i(1, 0); 1571 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1572 1573 // Stencil test 1574 result = result && verifyStencilTest(gl, program, width, height, widthCommitted); 1575 1576 // Depth test 1577 result = result && verifyDepthTest(gl, program, width, height, widthCommitted); 1578 1579 // Depth bounds test 1580 if (m_context.getContextInfo().isExtensionSupported("GL_EXT_depth_bounds_test")) 1581 result = result && verifyDepthBoundsTest(gl, program, width, height, widthCommitted); 1582 1583 // Resources cleaning 1584 cleanupDepthStencilFramebuffer(gl); 1585 1586 return result; 1587 } 1588 1589 /** Prepare gl depth and stencil test resources 1590 * 1591 * @param gl GL API functions 1592 * @param width Framebuffer width 1593 * @param height Framebuffer height 1594 */ 1595 void UncommittedRegionsAccessTestCase::prepareDepthStencilFramebuffer(const Functions& gl, GLint width, GLint height) 1596 { 1597 gl.genRenderbuffers(1, &mRenderbuffer); 1598 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers"); 1599 gl.bindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); 1600 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer"); 1601 if (mState.samples == 1) 1602 { 1603 gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); 1604 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage"); 1605 } 1606 else 1607 { 1608 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, mState.samples, GL_DEPTH_STENCIL, width, height); 1609 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample"); 1610 } 1611 1612 gl.genFramebuffers(1, &mFramebuffer); 1613 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers"); 1614 gl.bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1615 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer"); 1616 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mRenderbuffer); 1617 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer"); 1618 gl.viewport(0, 0, width, height); 1619 } 1620 1621 /** Cleanup gl depth and stencil test resources 1622 * 1623 * @param gl GL API functions 1624 */ 1625 void UncommittedRegionsAccessTestCase::cleanupDepthStencilFramebuffer(const Functions& gl) 1626 { 1627 gl.deleteFramebuffers(1, &mFramebuffer); 1628 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers"); 1629 gl.deleteRenderbuffers(1, &mRenderbuffer); 1630 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers"); 1631 1632 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1633 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer"); 1634 } 1635 1636 /** Verify if data stored in texture in uncommitted regions is as expected 1637 * 1638 * @param gl GL API functions 1639 * @param target Target for which texture is binded 1640 * @param format Texture internal format 1641 * @param texture Texture object 1642 * @param level Texture mipmap level 1643 * @param shaderOnly Shader texture filling flag, default false 1644 * 1645 * @return Returns true if data is as expected, false if not, throws an exception if error occurred. 1646 */ 1647 bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions& gl, GLint target, GLint format, 1648 GLuint& texture, GLint level, bool shaderOnly) 1649 { 1650 mLog << "Verify Texture [level: " << level << "] - "; 1651 1652 if (level > mState.levels - 1) 1653 TCU_FAIL("Invalid level"); 1654 1655 TransferFormat transferFormat = glu::getTransferFormat(mState.format); 1656 1657 GLint width; 1658 GLint height; 1659 GLint depth; 1660 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); 1661 1662 //Committed region is limited to 1/2 of width 1663 GLint widthCommitted = width / 2; 1664 1665 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth) 1666 return true; 1667 1668 bool result = true; 1669 1670 // Verify texture using API glGetTexImage* (Skip multisample textures as it can not be verified using API) 1671 if (!shaderOnly && target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE && 1672 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 1673 { 1674 GLint texSize = width * height * depth * mState.format.getPixelSize(); 1675 1676 std::vector<GLubyte> vecExpData; 1677 std::vector<GLubyte> vecOutData; 1678 vecExpData.resize(texSize); 1679 vecOutData.resize(texSize); 1680 GLubyte* exp_data = vecExpData.data(); 1681 GLubyte* out_data = vecOutData.data(); 1682 1683 // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros 1684 deMemset(exp_data, 0, texSize); 1685 deMemset(out_data, 255, texSize); 1686 1687 Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data); 1688 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 1689 1690 //Verify only uncommitted region 1691 for (GLint x = widthCommitted; x < width; ++x) 1692 for (GLint y = 0; y < height; ++y) 1693 for (GLint z = 0; z < depth; ++z) 1694 { 1695 int pixelSize = mState.format.getPixelSize(); 1696 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize); 1697 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize); 1698 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0) 1699 result = false; 1700 } 1701 } 1702 // Verify texture using API glGetTexImage* (Only cube map as it has to be verified for subtargets) 1703 else if (!shaderOnly && target == GL_TEXTURE_CUBE_MAP) 1704 { 1705 std::vector<GLint> subTargets; 1706 1707 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X); 1708 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X); 1709 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y); 1710 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y); 1711 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z); 1712 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); 1713 1714 GLint texSize = width * height * mState.format.getPixelSize(); 1715 1716 std::vector<GLubyte> vecExpData; 1717 std::vector<GLubyte> vecOutData; 1718 vecExpData.resize(texSize); 1719 vecOutData.resize(texSize); 1720 GLubyte* exp_data = vecExpData.data(); 1721 GLubyte* out_data = vecOutData.data(); 1722 1723 deMemset(exp_data, 0, texSize); 1724 1725 for (size_t i = 0; i < subTargets.size(); ++i) 1726 { 1727 GLint subTarget = subTargets[i]; 1728 1729 mLog << "Verify Subtarget [subtarget: " << subTarget << "] - "; 1730 1731 deMemset(out_data, 255, texSize); 1732 1733 Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data); 1734 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 1735 1736 //Verify only uncommitted region 1737 for (GLint x = widthCommitted; x < width; ++x) 1738 for (GLint y = 0; y < height; ++y) 1739 for (GLint z = 0; z < depth; ++z) 1740 { 1741 int pixelSize = mState.format.getPixelSize(); 1742 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize); 1743 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize); 1744 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0) 1745 result = false; 1746 } 1747 1748 if (!result) 1749 break; 1750 } 1751 } 1752 // Verify texture using shader imageLoad function 1753 else if (shaderOnly) 1754 { 1755 // Create verifying texture 1756 GLint verifyTarget; 1757 if (target == GL_TEXTURE_2D_MULTISAMPLE) 1758 verifyTarget = GL_TEXTURE_2D; 1759 else 1760 verifyTarget = GL_TEXTURE_2D_ARRAY; 1761 1762 if (target == GL_TEXTURE_CUBE_MAP) 1763 depth = depth * 6; 1764 1765 GLint texSize = width * height * depth; 1766 1767 std::vector<GLubyte> vecExpData; 1768 std::vector<GLubyte> vecOutData; 1769 vecExpData.resize(texSize); 1770 vecOutData.resize(texSize); 1771 GLubyte* exp_data = vecExpData.data(); 1772 GLubyte* out_data = vecOutData.data(); 1773 1774 // Expected value in this case is 255 because shader fills output texture with 255 if in texture is filled with zeros 1775 deMemset(exp_data, 255, texSize); 1776 1777 GLuint verifyTexture; 1778 Texture::Generate(gl, verifyTexture); 1779 Texture::Bind(gl, verifyTexture, verifyTarget); 1780 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth); 1781 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage"); 1782 1783 for (GLint sample = 0; sample < mState.samples; ++sample) 1784 { 1785 deMemset(out_data, 0, texSize); 1786 1787 Texture::Bind(gl, verifyTexture, verifyTarget); 1788 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE, 1789 (GLvoid*)out_data); 1790 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage"); 1791 1792 std::string shader = st2_compute_textureVerify; 1793 1794 // Adjust shader source to texture format 1795 TokenStrings s = createShaderTokens(target, format, sample); 1796 1797 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader); 1798 replaceToken("<FORMAT>", s.format.c_str(), shader); 1799 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader); 1800 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader); 1801 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader); 1802 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader); 1803 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader); 1804 replaceToken("<RESULT_EXPECTED>", s.resultDefault.c_str(), shader); 1805 replaceToken("<EPSILON>", s.epsilon.c_str(), shader); 1806 1807 ProgramSources sources; 1808 sources << ComputeSource(shader); 1809 1810 // Build and run shader 1811 ShaderProgram program(m_context.getRenderContext(), sources); 1812 if (program.isOk()) 1813 { 1814 gl.useProgram(program.getProgram()); 1815 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1816 gl.bindImageTexture(0, //unit 1817 verifyTexture, 1818 0, //level 1819 GL_FALSE, //layered 1820 0, //layer 1821 GL_WRITE_ONLY, GL_R8UI); 1822 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 1823 gl.bindImageTexture(1, //unit 1824 texture, 1825 level, //level 1826 GL_FALSE, //layered 1827 0, //layer 1828 GL_READ_ONLY, format); 1829 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 1830 gl.uniform1i(1, 0 /* image_unit */); 1831 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1832 gl.uniform1i(2, 1 /* image_unit */); 1833 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1834 gl.dispatchCompute(width, height, depth); 1835 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); 1836 gl.memoryBarrier(GL_ALL_BARRIER_BITS); 1837 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); 1838 1839 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data); 1840 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 1841 1842 //Verify only committed region 1843 for (GLint x = widthCommitted; x < width; ++x) 1844 for (GLint y = 0; y < height; ++y) 1845 for (GLint z = 0; z < depth; ++z) 1846 { 1847 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height); 1848 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height); 1849 if (dataRegion[0] != outDataRegion[0]) 1850 result = false; 1851 } 1852 } 1853 else 1854 { 1855 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format 1856 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog 1857 << ", shaderSource: " << shader.c_str() << " - "; 1858 1859 result = false; 1860 } 1861 } 1862 1863 Texture::Delete(gl, verifyTexture); 1864 } 1865 1866 return result; 1867 } 1868 1869 /** Verify if atomic operations on uncommitted regions returns zeros and has no effect on texture 1870 * 1871 * @param gl GL API functions 1872 * @param target Target for which texture is binded 1873 * @param format Texture internal format 1874 * @param texture Texture object 1875 * @param level Texture mipmap level 1876 * 1877 * @return Returns true if data is as expected, false if not, throws an exception if error occurred. 1878 */ 1879 bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions& gl, GLint target, GLint format, 1880 GLuint& texture, GLint level) 1881 { 1882 mLog << "Verify Atomic Operations [level: " << level << "] - "; 1883 1884 if (level > mState.levels - 1) 1885 TCU_FAIL("Invalid level"); 1886 1887 GLint width; 1888 GLint height; 1889 GLint depth; 1890 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); 1891 1892 //Committed region is limited to 1/2 of width 1893 GLint widthCommitted = width / 2; 1894 1895 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth) 1896 return true; 1897 1898 bool result = true; 1899 1900 // Create verifying texture 1901 GLint verifyTarget; 1902 if (target == GL_TEXTURE_2D_MULTISAMPLE) 1903 verifyTarget = GL_TEXTURE_2D; 1904 else 1905 verifyTarget = GL_TEXTURE_2D_ARRAY; 1906 1907 GLint texSize = width * height * depth; 1908 1909 std::vector<GLubyte> vecExpData; 1910 std::vector<GLubyte> vecOutData; 1911 vecExpData.resize(texSize); 1912 vecOutData.resize(texSize); 1913 GLubyte* exp_data = vecExpData.data(); 1914 GLubyte* out_data = vecOutData.data(); 1915 1916 // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros 1917 deMemset(exp_data, 0, texSize); 1918 1919 GLuint verifyTexture; 1920 Texture::Generate(gl, verifyTexture); 1921 Texture::Bind(gl, verifyTexture, verifyTarget); 1922 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth); 1923 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage"); 1924 1925 for (GLint sample = 0; sample < mState.samples; ++sample) 1926 { 1927 deMemset(out_data, 255, texSize); 1928 1929 Texture::Bind(gl, verifyTexture, verifyTarget); 1930 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE, 1931 (GLvoid*)out_data); 1932 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage"); 1933 1934 std::string shader = st2_compute_atomicVerify; 1935 1936 // Adjust shader source to texture format 1937 TokenStrings s = createShaderTokens(target, format, sample); 1938 std::string dataType = (s.returnType == "ivec4" ? "int" : "uint"); 1939 1940 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader); 1941 replaceToken("<FORMAT>", s.format.c_str(), shader); 1942 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader); 1943 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader); 1944 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader); 1945 replaceToken("<DATA_TYPE>", dataType.c_str(), shader); 1946 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader); 1947 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader); 1948 1949 ProgramSources sources; 1950 sources << ComputeSource(shader); 1951 1952 // Build and run shader 1953 ShaderProgram program(m_context.getRenderContext(), sources); 1954 if (program.isOk()) 1955 { 1956 gl.useProgram(program.getProgram()); 1957 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1958 gl.bindImageTexture(0, //unit 1959 verifyTexture, 1960 0, //level 1961 GL_FALSE, //layered 1962 0, //layer 1963 GL_WRITE_ONLY, GL_R8UI); 1964 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 1965 gl.bindImageTexture(1, //unit 1966 texture, 1967 level, //level 1968 GL_FALSE, //layered 1969 0, //layer 1970 GL_READ_ONLY, format); 1971 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 1972 gl.uniform1i(1, 0 /* image_unit */); 1973 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1974 gl.uniform1i(2, 1 /* image_unit */); 1975 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1976 gl.uniform1i(3, widthCommitted /* committed width */); 1977 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 1978 gl.dispatchCompute(width, height, depth); 1979 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); 1980 gl.memoryBarrier(GL_ALL_BARRIER_BITS); 1981 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); 1982 1983 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data); 1984 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 1985 1986 //Verify only committed region 1987 for (GLint x = 0; x < width; ++x) 1988 for (GLint y = 0; y < height; ++y) 1989 for (GLint z = 0; z < depth; ++z) 1990 { 1991 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height); 1992 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height); 1993 if (dataRegion[0] != outDataRegion[0]) 1994 { 1995 printf("%d:%d ", dataRegion[0], outDataRegion[0]); 1996 result = false; 1997 } 1998 } 1999 } 2000 else 2001 { 2002 mLog << "Compute shader compilation failed (atomic) for target: " << target << ", format: " << format 2003 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog 2004 << ", shaderSource: " << shader.c_str() << " - "; 2005 2006 result = false; 2007 } 2008 } 2009 2010 Texture::Delete(gl, verifyTexture); 2011 2012 return result; 2013 } 2014 2015 /** Verify if stencil test on uncommitted texture region works as expected texture 2016 * 2017 * @param gl GL API functions 2018 * @param program Shader program 2019 * @param width Texture width 2020 * @param height Texture height 2021 * @param widthCommitted Committed region width 2022 * 2023 * @return Returns true if stencil data is as expected, false otherwise. 2024 */ 2025 bool UncommittedRegionsAccessTestCase::verifyStencilTest(const Functions& gl, ShaderProgram& program, GLint width, 2026 GLint height, GLint widthCommitted) 2027 { 2028 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices), 2029 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) }; 2030 2031 mLog << "Perform Stencil Test - "; 2032 2033 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 2034 gl.enable(GL_STENCIL_TEST); 2035 gl.stencilFunc(GL_GREATER, 1, 0xFF); 2036 gl.stencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 2037 2038 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, 2039 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices)); 2040 2041 std::vector<GLubyte> dataStencil; 2042 dataStencil.resize(width * height); 2043 GLubyte* dataStencilPtr = dataStencil.data(); 2044 2045 gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, (GLvoid*)dataStencilPtr); 2046 for (int x = widthCommitted; x < width; ++x) 2047 for (int y = 0; y < height; ++y) 2048 { 2049 if (dataStencilPtr[x + y * width] != 0x00) 2050 { 2051 gl.disable(GL_STENCIL_TEST); 2052 return false; 2053 } 2054 } 2055 2056 gl.disable(GL_STENCIL_TEST); 2057 return true; 2058 } 2059 2060 /** Verify if depth test on uncommitted texture region works as expected texture 2061 * 2062 * @param gl GL API functions 2063 * @param program Shader program 2064 * @param width Texture width 2065 * @param height Texture height 2066 * @param widthCommitted Committed region width 2067 * 2068 * @return Returns true if depth data is as expected, false otherwise. 2069 */ 2070 bool UncommittedRegionsAccessTestCase::verifyDepthTest(const Functions& gl, ShaderProgram& program, GLint width, 2071 GLint height, GLint widthCommitted) 2072 { 2073 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices), 2074 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) }; 2075 2076 mLog << "Perform Depth Test - "; 2077 2078 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 2079 gl.enable(GL_DEPTH_TEST); 2080 gl.depthFunc(GL_LESS); 2081 2082 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, 2083 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices)); 2084 2085 std::vector<GLuint> dataDepth; 2086 dataDepth.resize(width * height); 2087 GLuint* dataDepthPtr = dataDepth.data(); 2088 2089 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid*)dataDepthPtr); 2090 for (int x = widthCommitted; x < width; ++x) 2091 for (int y = 0; y < height; ++y) 2092 { 2093 if (dataDepthPtr[x + y * width] != 0xFFFFFFFF) 2094 { 2095 gl.disable(GL_DEPTH_TEST); 2096 return false; 2097 } 2098 } 2099 2100 gl.disable(GL_DEPTH_TEST); 2101 return true; 2102 } 2103 2104 /** Verify if depth bounds test on uncommitted texture region works as expected texture 2105 * 2106 * @param gl GL API functions 2107 * @param program Shader program 2108 * @param width Texture width 2109 * @param height Texture height 2110 * @param widthCommitted Committed region width 2111 * 2112 * @return Returns true if depth data is as expected, false otherwise. 2113 */ 2114 bool UncommittedRegionsAccessTestCase::verifyDepthBoundsTest(const Functions& gl, ShaderProgram& program, GLint width, 2115 GLint height, GLint widthCommitted) 2116 { 2117 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices), 2118 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) }; 2119 2120 mLog << "Perform Depth Bounds Test - "; 2121 2122 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 2123 gl.enable(GL_DEPTH_BOUNDS_TEST_EXT); 2124 gl.depthFunc(GL_LESS); 2125 2126 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, 2127 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices)); 2128 2129 std::vector<GLuint> dataDepth; 2130 dataDepth.resize(width * height); 2131 GLuint* dataDepthPtr = dataDepth.data(); 2132 2133 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid*)dataDepthPtr); 2134 for (int x = widthCommitted; x < width; ++x) 2135 for (int y = 0; y < height; ++y) 2136 { 2137 if (dataDepthPtr[x + y * width] != 0xFFFFFFFF) 2138 { 2139 gl.disable(GL_DEPTH_BOUNDS_TEST_EXT); 2140 return false; 2141 } 2142 } 2143 2144 gl.disable(GL_DEPTH_BOUNDS_TEST_EXT); 2145 return true; 2146 } 2147 2148 /** Constructor. 2149 * 2150 * @param context Rendering context 2151 */ 2152 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context) 2153 : SparseTexture2CommitmentTestCase(context, "SparseTexture2Lookup", 2154 "Verifies if sparse texture lookup functions for GLSL works as expected") 2155 { 2156 /* Left blank intentionally */ 2157 } 2158 2159 /** Constructor. 2160 * 2161 * @param context Rendering context 2162 */ 2163 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context, const char* name, 2164 const char* description) 2165 : SparseTexture2CommitmentTestCase(context, name, description) 2166 { 2167 /* Left blank intentionally */ 2168 } 2169 2170 /** Initializes the test group contents. */ 2171 void SparseTexture2LookupTestCase::init() 2172 { 2173 SparseTextureCommitmentTestCase::init(); 2174 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE); 2175 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 2176 2177 mSupportedInternalFormats.push_back(GL_DEPTH_COMPONENT16); 2178 2179 FunctionToken f; 2180 f = FunctionToken("sparseTextureARB", "<CUBE_REFZ_DEF>"); 2181 f.allowedTargets.insert(GL_TEXTURE_2D); 2182 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2183 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); 2184 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); 2185 f.allowedTargets.insert(GL_TEXTURE_3D); 2186 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2187 mFunctions.push_back(f); 2188 2189 f = FunctionToken("sparseTextureLodARB", ", <LOD>"); 2190 f.allowedTargets.insert(GL_TEXTURE_2D); 2191 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2192 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); 2193 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); 2194 f.allowedTargets.insert(GL_TEXTURE_3D); 2195 mFunctions.push_back(f); 2196 2197 f = FunctionToken("sparseTextureOffsetARB", ", <OFFSET_TYPE><OFFSET_DIM>(0)"); 2198 f.allowedTargets.insert(GL_TEXTURE_2D); 2199 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2200 f.allowedTargets.insert(GL_TEXTURE_3D); 2201 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2202 mFunctions.push_back(f); 2203 2204 f = FunctionToken("sparseTexelFetchARB", "<LOD_DEF>"); 2205 f.allowedTargets.insert(GL_TEXTURE_2D); 2206 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2207 f.allowedTargets.insert(GL_TEXTURE_3D); 2208 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2209 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE); 2210 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 2211 mFunctions.push_back(f); 2212 2213 f = FunctionToken("sparseTexelFetchOffsetARB", "<LOD_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)"); 2214 f.allowedTargets.insert(GL_TEXTURE_2D); 2215 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2216 f.allowedTargets.insert(GL_TEXTURE_3D); 2217 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2218 mFunctions.push_back(f); 2219 2220 f = FunctionToken("sparseTextureLodOffsetARB", ", <LOD>, <OFFSET_TYPE><OFFSET_DIM>(0)"); 2221 f.allowedTargets.insert(GL_TEXTURE_2D); 2222 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2223 f.allowedTargets.insert(GL_TEXTURE_3D); 2224 mFunctions.push_back(f); 2225 2226 f = FunctionToken("sparseTextureGradARB", ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0)"); 2227 f.allowedTargets.insert(GL_TEXTURE_2D); 2228 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2229 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); 2230 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); 2231 f.allowedTargets.insert(GL_TEXTURE_3D); 2232 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2233 mFunctions.push_back(f); 2234 2235 f = FunctionToken("sparseTextureGradOffsetARB", 2236 ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0)"); 2237 f.allowedTargets.insert(GL_TEXTURE_2D); 2238 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2239 f.allowedTargets.insert(GL_TEXTURE_3D); 2240 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2241 mFunctions.push_back(f); 2242 2243 f = FunctionToken("sparseTextureGatherARB", "<REFZ_DEF>"); 2244 f.allowedTargets.insert(GL_TEXTURE_2D); 2245 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2246 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); 2247 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); 2248 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2249 mFunctions.push_back(f); 2250 2251 f = FunctionToken("sparseTextureGatherOffsetARB", "<REFZ_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)"); 2252 f.allowedTargets.insert(GL_TEXTURE_2D); 2253 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2254 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2255 mFunctions.push_back(f); 2256 2257 f = FunctionToken("sparseTextureGatherOffsetsARB", "<REFZ_DEF>, offsetsArray"); 2258 f.allowedTargets.insert(GL_TEXTURE_2D); 2259 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2260 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2261 mFunctions.push_back(f); 2262 2263 f = FunctionToken("sparseImageLoadARB", ""); 2264 f.allowedTargets.insert(GL_TEXTURE_2D); 2265 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); 2266 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); 2267 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); 2268 f.allowedTargets.insert(GL_TEXTURE_3D); 2269 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); 2270 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE); 2271 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 2272 //mFunctions.push_back(f); 2273 } 2274 2275 /** Executes test iteration. 2276 * 2277 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2278 */ 2279 tcu::TestNode::IterateResult SparseTexture2LookupTestCase::iterate() 2280 { 2281 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2")) 2282 { 2283 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 2284 return STOP; 2285 } 2286 2287 const Functions& gl = m_context.getRenderContext().getFunctions(); 2288 2289 bool result = true; 2290 2291 GLuint texture; 2292 2293 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end(); 2294 ++iter) 2295 { 2296 const GLint& target = *iter; 2297 2298 for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin(); 2299 formIter != mSupportedInternalFormats.end(); ++formIter) 2300 { 2301 const GLint& format = *formIter; 2302 2303 if (!caseAllowed(target, format)) 2304 continue; 2305 2306 for (std::vector<FunctionToken>::const_iterator tokIter = mFunctions.begin(); tokIter != mFunctions.end(); 2307 ++tokIter) 2308 { 2309 // Check if target is allowed for current lookup function 2310 FunctionToken funcToken = *tokIter; 2311 if (!funcAllowed(target, format, funcToken)) 2312 continue; 2313 2314 mLog.str(""); 2315 mLog << "Testing sparse texture lookup functions for target: " << target << ", format: " << format 2316 << " - "; 2317 2318 sparseAllocateTexture(gl, target, format, texture, 3); 2319 if (format == GL_DEPTH_COMPONENT16) 2320 setupDepthMode(gl, target, texture); 2321 2322 for (int l = 0; l < mState.levels; ++l) 2323 { 2324 if (commitTexturePage(gl, target, format, texture, l)) 2325 { 2326 writeDataToTexture(gl, target, format, texture, l); 2327 result = result && verifyLookupTextureData(gl, target, format, texture, l, funcToken); 2328 } 2329 2330 if (!result) 2331 break; 2332 } 2333 2334 Texture::Delete(gl, texture); 2335 2336 if (!result) 2337 { 2338 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage; 2339 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2340 return STOP; 2341 } 2342 } 2343 } 2344 } 2345 2346 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2347 return STOP; 2348 } 2349 2350 /** Create set of token strings fit to lookup functions verifying shader 2351 * 2352 * @param target Target for which texture is binded 2353 * @param format Texture internal format 2354 * @param level Texture mipmap level 2355 * @param sample Texture sample number 2356 * @param funcToken Texture lookup function structure 2357 * 2358 * @return Returns extended token strings structure. 2359 */ 2360 SparseTexture2LookupTestCase::TokenStringsExt SparseTexture2LookupTestCase::createLookupShaderTokens( 2361 GLint target, GLint format, GLint level, GLint sample, FunctionToken& funcToken) 2362 { 2363 std::string funcName = funcToken.name; 2364 2365 TokenStringsExt s; 2366 2367 std::string inputType; 2368 std::string samplerSufix; 2369 2370 if (funcName == "sparseImageLoadARB") 2371 inputType = "image"; 2372 else 2373 inputType = "sampler"; 2374 2375 // Copy data from TokenStrings to TokenStringsExt 2376 TokenStrings ss = createShaderTokens(target, format, sample, "image", inputType); 2377 s.epsilon = ss.epsilon; 2378 s.format = ss.format; 2379 s.inputType = ss.inputType; 2380 s.outputType = ss.outputType; 2381 s.pointDef = ss.pointDef; 2382 s.pointType = ss.pointType; 2383 s.resultDefault = ss.resultDefault; 2384 s.resultExpected = ss.resultExpected; 2385 s.returnType = ss.returnType; 2386 s.sampleDef = ss.sampleDef; 2387 2388 // Set format definition for image input types 2389 if (inputType == "image") 2390 s.formatDef = ", " + s.format; 2391 2392 // Set tokens for depth texture format 2393 if (format == GL_DEPTH_COMPONENT16) 2394 { 2395 s.refZDef = ", 0.5"; 2396 2397 if (inputType == "sampler" && target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_MULTISAMPLE && 2398 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 2399 { 2400 s.inputType = s.inputType + "Shadow"; 2401 } 2402 } 2403 2404 // Set coord type, coord definition and offset vector dimensions 2405 s.coordType = "vec2"; 2406 s.offsetType = "ivec"; 2407 s.nOffsetType = "vec"; 2408 s.offsetDim = "2"; 2409 if (target == GL_TEXTURE_1D) 2410 { 2411 s.coordType = "float"; 2412 s.offsetType = "int"; 2413 s.nOffsetType = "float"; 2414 s.offsetDim = ""; 2415 } 2416 else if (target == GL_TEXTURE_1D_ARRAY) 2417 { 2418 s.coordType = "vec2"; 2419 s.offsetType = "int"; 2420 s.nOffsetType = "float"; 2421 s.offsetDim = ""; 2422 } 2423 else if (target == GL_TEXTURE_2D_ARRAY) 2424 { 2425 s.coordType = "vec3"; 2426 } 2427 else if (target == GL_TEXTURE_3D) 2428 { 2429 s.coordType = "vec3"; 2430 s.offsetDim = "3"; 2431 } 2432 else if (target == GL_TEXTURE_CUBE_MAP) 2433 { 2434 s.coordType = "vec3"; 2435 s.offsetDim = "3"; 2436 } 2437 else if (target == GL_TEXTURE_CUBE_MAP_ARRAY) 2438 { 2439 s.coordType = "vec4"; 2440 s.coordDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6, floor(gl_WorkGroupID.z / 6)"; 2441 s.offsetDim = "3"; 2442 } 2443 else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 2444 { 2445 s.coordType = "vec3"; 2446 } 2447 2448 if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) && 2449 funcName.find("Fetch", 0) == std::string::npos) 2450 { 2451 s.cubeMapCoordDef = " int face = point.z % 6;\n" 2452 " if (face == 0) coord.xyz = vec3(1, coord.y * 2 - 1, -coord.x * 2 + 1);\n" 2453 " if (face == 1) coord.xyz = vec3(-1, coord.y * 2 - 1, coord.x * 2 - 1);\n" 2454 " if (face == 2) coord.xyz = vec3(coord.x * 2 - 1, 1, coord.y * 2 - 1);\n" 2455 " if (face == 3) coord.xyz = vec3(coord.x * 2 - 1, -1, -coord.y * 2 + 1);\n" 2456 " if (face == 4) coord.xyz = vec3(coord.x * 2 - 1, coord.y * 2 - 1, 1);\n" 2457 " if (face == 5) coord.xyz = vec3(-coord.x * 2 + 1, coord.y * 2 - 1, -1);\n"; 2458 } 2459 2460 if (s.coordDef.empty()) 2461 s.coordDef = s.pointDef; 2462 2463 // Set expected result vector, component definition and offset array definition for gather functions 2464 if (funcName.find("Gather", 0) != std::string::npos) 2465 { 2466 if (funcName.find("GatherOffsets", 0) != std::string::npos) 2467 { 2468 s.offsetArrayDef = " <OFFSET_TYPE><OFFSET_DIM> offsetsArray[4];\n" 2469 " offsetsArray[0] = <OFFSET_TYPE><OFFSET_DIM>(0);\n" 2470 " offsetsArray[1] = <OFFSET_TYPE><OFFSET_DIM>(0);\n" 2471 " offsetsArray[2] = <OFFSET_TYPE><OFFSET_DIM>(0);\n" 2472 " offsetsArray[3] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"; 2473 } 2474 2475 if (format != GL_DEPTH_COMPONENT16) 2476 s.componentDef = ", 0"; 2477 s.resultExpected = "(1, 1, 1, 1)"; 2478 } 2479 // Extend coord type dimension and coord vector definition if shadow sampler and non-cube map array target selected 2480 // Set component definition to red component 2481 else if (format == GL_DEPTH_COMPONENT16) 2482 { 2483 if (target != GL_TEXTURE_CUBE_MAP_ARRAY) 2484 { 2485 if (s.coordType == "float") 2486 s.coordType = "vec3"; 2487 else if (s.coordType == "vec2") 2488 s.coordType = "vec3"; 2489 else if (s.coordType == "vec3") 2490 s.coordType = "vec4"; 2491 s.coordDef += s.refZDef; 2492 } 2493 else 2494 s.cubeMapArrayRefZDef = s.refZDef; 2495 2496 s.componentDef = ".r"; 2497 } 2498 2499 // Set level of details definition 2500 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE && 2501 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 2502 { 2503 s.lod = de::toString(level); 2504 s.lodDef = ", " + de::toString(level); 2505 } 2506 2507 // Set proper coord vector 2508 if (target == GL_TEXTURE_RECTANGLE || funcName.find("Fetch") != std::string::npos || 2509 funcName.find("ImageLoad") != std::string::npos) 2510 { 2511 s.pointCoord = "icoord"; 2512 } 2513 else 2514 s.pointCoord = "coord"; 2515 2516 // Set size vector definition 2517 if (format != GL_DEPTH_COMPONENT16 || funcName.find("Gather", 0) != std::string::npos) 2518 { 2519 if (s.coordType == "float") 2520 s.sizeDef = "<TEX_WIDTH>"; 2521 else if (s.coordType == "vec2" && target == GL_TEXTURE_1D_ARRAY) 2522 s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>"; 2523 else if (s.coordType == "vec2") 2524 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>"; 2525 else if (s.coordType == "vec3") 2526 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>"; 2527 else if (s.coordType == "vec4") 2528 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, floor(<TEX_DEPTH> / 6), 6"; 2529 } 2530 // Set size vector for shadow samplers and non-gether functions selected 2531 else 2532 { 2533 if (s.coordType == "vec3" && target == GL_TEXTURE_1D) 2534 s.sizeDef = "<TEX_WIDTH>, 1 , 1"; 2535 else if (s.coordType == "vec3" && target == GL_TEXTURE_1D_ARRAY) 2536 s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>, 1"; 2537 else if (s.coordType == "vec3") 2538 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, 1"; 2539 else if (s.coordType == "vec4") 2540 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>, 1"; 2541 } 2542 2543 if (s.coordType != "float") 2544 s.iCoordType = "i" + s.coordType; 2545 else 2546 s.iCoordType = "int"; 2547 2548 return s; 2549 } 2550 2551 /** Check if specific combination of target and format is 2552 2553 * 2554 * @param target Target for which texture is binded 2555 * @param format Texture internal format 2556 * 2557 * @return Returns true if target/format combination is allowed, false otherwise. 2558 */ 2559 bool SparseTexture2LookupTestCase::caseAllowed(GLint target, GLint format) 2560 { 2561 DE_UNREF(target); 2562 2563 // As shaders do not support some texture formats it is necessary to exclude them. 2564 if (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5) 2565 { 2566 return false; 2567 } 2568 2569 if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_3D) && 2570 (format == GL_DEPTH_COMPONENT16)) 2571 { 2572 return false; 2573 } 2574 2575 return true; 2576 } 2577 2578 /** Check if specific lookup function is allowed for specific target and format 2579 * 2580 * @param target Target for which texture is binded 2581 * @param format Texture internal format 2582 * @param funcToken Texture lookup function structure 2583 * 2584 * @return Returns true if target/format combination is allowed, false otherwise. 2585 */ 2586 bool SparseTexture2LookupTestCase::funcAllowed(GLint target, GLint format, FunctionToken& funcToken) 2587 { 2588 if (funcToken.allowedTargets.find(target) == funcToken.allowedTargets.end()) 2589 return false; 2590 2591 if (format == GL_DEPTH_COMPONENT16) 2592 { 2593 if (funcToken.name == "sparseTextureLodARB" || funcToken.name == "sparseTextureLodOffsetARB") 2594 { 2595 if (target != GL_TEXTURE_2D) 2596 return false; 2597 } 2598 else if (funcToken.name == "sparseTextureOffsetARB" || funcToken.name == "sparseTextureGradOffsetARB" || 2599 funcToken.name == "sparseTextureGatherOffsetARB" || funcToken.name == "sparseTextureGatherOffsetsARB") 2600 { 2601 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_ARRAY && target != GL_TEXTURE_RECTANGLE) 2602 { 2603 return false; 2604 } 2605 } 2606 else if (funcToken.name == "sparseTexelFetchARB" || funcToken.name == "sparseTexelFetchOffsetARB") 2607 { 2608 return false; 2609 } 2610 else if (funcToken.name == "sparseTextureGradARB") 2611 { 2612 if (target == GL_TEXTURE_CUBE_MAP_ARRAY) 2613 return false; 2614 } 2615 else if (funcToken.name == "sparseImageLoadARB") 2616 { 2617 return false; 2618 } 2619 } 2620 2621 return true; 2622 } 2623 2624 /** Writing data to generated texture using compute shader 2625 * 2626 * @param gl GL API functions 2627 * @param target Target for which texture is binded 2628 * @param format Texture internal format 2629 * @param texture Texture object 2630 * 2631 * @return Returns true if no error occurred, otherwise throws an exception. 2632 */ 2633 bool SparseTexture2LookupTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format, GLuint& texture, 2634 GLint level) 2635 { 2636 mLog << "Fill Texture with shader [level: " << level << "] - "; 2637 2638 if (level > mState.levels - 1) 2639 TCU_FAIL("Invalid level"); 2640 2641 GLint width; 2642 GLint height; 2643 GLint depth; 2644 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); 2645 2646 if (width > 0 && height > 0 && depth >= mState.minDepth) 2647 { 2648 if (target == GL_TEXTURE_CUBE_MAP) 2649 depth = depth * 6; 2650 2651 GLint texSize = width * height * depth * mState.format.getPixelSize(); 2652 2653 std::vector<GLubyte> vecData; 2654 vecData.resize(texSize); 2655 GLubyte* data = vecData.data(); 2656 2657 deMemset(data, 255, texSize); 2658 2659 for (GLint sample = 0; sample < mState.samples; ++sample) 2660 { 2661 std::string shader = st2_compute_textureFill; 2662 2663 // Adjust shader source to texture format 2664 TokenStrings s = createShaderTokens(target, format, sample); 2665 2666 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader); 2667 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader); 2668 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader); 2669 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader); 2670 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader); 2671 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader); 2672 2673 ProgramSources sources; 2674 sources << ComputeSource(shader); 2675 2676 GLint convFormat = format; 2677 if (format == GL_DEPTH_COMPONENT16) 2678 convFormat = GL_R16; 2679 2680 // Build and run shader 2681 ShaderProgram program(m_context.getRenderContext(), sources); 2682 if (program.isOk()) 2683 { 2684 gl.useProgram(program.getProgram()); 2685 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 2686 gl.bindImageTexture(0 /* unit */, texture, level /* level */, GL_FALSE /* layered */, 0 /* layer */, 2687 GL_WRITE_ONLY, convFormat); 2688 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 2689 gl.uniform1i(1, 0 /* image_unit */); 2690 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 2691 gl.dispatchCompute(width, height, depth); 2692 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); 2693 gl.memoryBarrier(GL_ALL_BARRIER_BITS); 2694 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); 2695 } 2696 else 2697 { 2698 mLog << "Compute shader compilation failed (writing) for target: " << target << ", format: " << format 2699 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog 2700 << ", shaderSource: " << shader.c_str() << " - "; 2701 } 2702 } 2703 } 2704 2705 return true; 2706 } 2707 2708 /** Setup depth compare mode and compare function for depth texture 2709 * 2710 * @param gl GL API functions 2711 * @param target Target for which texture is binded 2712 * @param texture Texture object 2713 */ 2714 void SparseTexture2LookupTestCase::setupDepthMode(const Functions& gl, GLint target, GLuint& texture) 2715 { 2716 Texture::Bind(gl, texture, target); 2717 gl.texParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 2718 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); 2719 gl.texParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS); 2720 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); 2721 } 2722 2723 /** Verify if data stored in texture is as expected 2724 * 2725 * @param gl GL API functions 2726 * @param target Target for which texture is binded 2727 * @param format Texture internal format 2728 * @param texture Texture object 2729 * @param level Texture mipmap level 2730 * @param funcToken Lookup function tokenize structure 2731 * 2732 * @return Returns true if data is as expected, false if not, throws an exception if error occurred. 2733 */ 2734 bool SparseTexture2LookupTestCase::verifyLookupTextureData(const Functions& gl, GLint target, GLint format, 2735 GLuint& texture, GLint level, FunctionToken& funcToken) 2736 { 2737 mLog << "Verify Lookup Texture Data [function: " << funcToken.name << ", level: " << level << "] - "; 2738 2739 if (level > mState.levels - 1) 2740 TCU_FAIL("Invalid level"); 2741 2742 GLint width; 2743 GLint height; 2744 GLint depth; 2745 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); 2746 2747 //Committed region is limited to 1/2 of width 2748 GLint widthCommitted = width / 2; 2749 2750 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth) 2751 return true; 2752 2753 bool result = true; 2754 2755 if (target == GL_TEXTURE_CUBE_MAP) 2756 depth = depth * 6; 2757 2758 GLint texSize = width * height * depth; 2759 2760 std::vector<GLubyte> vecExpData; 2761 std::vector<GLubyte> vecOutData; 2762 vecExpData.resize(texSize); 2763 vecOutData.resize(texSize); 2764 GLubyte* exp_data = vecExpData.data(); 2765 GLubyte* out_data = vecOutData.data(); 2766 2767 // Expected data is 255 because 2768 deMemset(exp_data, 255, texSize); 2769 2770 // Make token copy to work on 2771 FunctionToken f = funcToken; 2772 2773 // Create verifying texture 2774 GLint verifyTarget; 2775 if (target == GL_TEXTURE_2D_MULTISAMPLE) 2776 verifyTarget = GL_TEXTURE_2D; 2777 else 2778 verifyTarget = GL_TEXTURE_2D_ARRAY; 2779 2780 GLuint verifyTexture; 2781 Texture::Generate(gl, verifyTexture); 2782 Texture::Bind(gl, verifyTexture, verifyTarget); 2783 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth); 2784 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage"); 2785 2786 for (int sample = 0; sample < mState.samples; ++sample) 2787 { 2788 deMemset(out_data, 0, texSize); 2789 2790 Texture::Bind(gl, verifyTexture, verifyTarget); 2791 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE, 2792 (GLvoid*)out_data); 2793 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage"); 2794 2795 std::string shader = st2_compute_lookupVerify; 2796 2797 // Adjust shader source to texture format 2798 TokenStringsExt s = createLookupShaderTokens(target, format, level, sample, f); 2799 2800 replaceToken("<FUNCTION>", f.name.c_str(), shader); 2801 replaceToken("<ARGUMENTS>", f.arguments.c_str(), shader); 2802 2803 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader); 2804 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader); 2805 replaceToken("<SIZE_DEF>", s.sizeDef.c_str(), shader); 2806 replaceToken("<LOD>", s.lod.c_str(), shader); 2807 replaceToken("<LOD_DEF>", s.lodDef.c_str(), shader); 2808 replaceToken("<COORD_TYPE>", s.coordType.c_str(), shader); 2809 replaceToken("<ICOORD_TYPE>", s.iCoordType.c_str(), shader); 2810 replaceToken("<COORD_DEF>", s.coordDef.c_str(), shader); 2811 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader); 2812 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader); 2813 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader); 2814 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader); 2815 replaceToken("<EPSILON>", s.epsilon.c_str(), shader); 2816 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader); 2817 replaceToken("<REFZ_DEF>", s.refZDef.c_str(), shader); 2818 replaceToken("<CUBE_REFZ_DEF>", s.cubeMapArrayRefZDef.c_str(), shader); 2819 replaceToken("<POINT_COORD>", s.pointCoord.c_str(), shader); 2820 replaceToken("<COMPONENT_DEF>", s.componentDef.c_str(), shader); 2821 replaceToken("<CUBE_MAP_COORD_DEF>", s.cubeMapCoordDef.c_str(), shader); 2822 replaceToken("<OFFSET_ARRAY_DEF>", s.offsetArrayDef.c_str(), shader); 2823 replaceToken("<FORMAT_DEF>", s.formatDef.c_str(), shader); 2824 replaceToken("<OFFSET_TYPE>", s.offsetType.c_str(), shader); 2825 replaceToken("<NOFFSET_TYPE>", s.nOffsetType.c_str(), shader); 2826 replaceToken("<OFFSET_DIM>", s.offsetDim.c_str(), shader); 2827 2828 replaceToken("<TEX_WIDTH>", de::toString(width).c_str(), shader); 2829 replaceToken("<TEX_HEIGHT>", de::toString(height).c_str(), shader); 2830 replaceToken("<TEX_DEPTH>", de::toString(depth).c_str(), shader); 2831 2832 ProgramSources sources; 2833 sources << ComputeSource(shader); 2834 2835 // Build and run shader 2836 ShaderProgram program(m_context.getRenderContext(), sources); 2837 if (program.isOk()) 2838 { 2839 gl.useProgram(program.getProgram()); 2840 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 2841 2842 // Pass output image to shader 2843 gl.bindImageTexture(1, //unit 2844 verifyTexture, 2845 0, //level 2846 GL_TRUE, //layered 2847 0, //layer 2848 GL_WRITE_ONLY, GL_R8UI); 2849 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 2850 gl.uniform1i(1, 1 /* image_unit */); 2851 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 2852 2853 // Pass input sampler/image to shader 2854 if (f.name != "sparseImageLoadARB") 2855 { 2856 gl.activeTexture(GL_TEXTURE0); 2857 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture"); 2858 gl.bindTexture(target, texture); 2859 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture"); 2860 gl.uniform1i(2, 0 /* sampler_unit */); 2861 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 2862 } 2863 else 2864 { 2865 gl.bindImageTexture(0, //unit 2866 texture, 2867 level, //level 2868 GL_FALSE, //layered 2869 0, //layer 2870 GL_READ_ONLY, format); 2871 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); 2872 gl.uniform1i(2, 0 /* image_unit */); 2873 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 2874 } 2875 2876 // Pass committed region width to shader 2877 gl.uniform1i(3, widthCommitted /* committed region width */); 2878 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 2879 gl.dispatchCompute(width, height, depth); 2880 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); 2881 gl.memoryBarrier(GL_ALL_BARRIER_BITS); 2882 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); 2883 2884 Texture::Bind(gl, verifyTexture, verifyTarget); 2885 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data); 2886 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); 2887 2888 //Verify only committed region 2889 for (GLint z = 0; z < depth; ++z) 2890 for (GLint y = 0; y < height; ++y) 2891 for (GLint x = 0; x < width; ++x) 2892 { 2893 GLubyte* dataRegion = exp_data + x + y * width + z * width * height; 2894 GLubyte* outDataRegion = out_data + x + y * width + z * width * height; 2895 if (dataRegion[0] != outDataRegion[0]) 2896 result = false; 2897 } 2898 } 2899 else 2900 { 2901 mLog << "Compute shader compilation failed (lookup) for target: " << target << ", format: " << format 2902 << ", shaderInfoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog 2903 << ", programInfoLog: " << program.getProgramInfo().infoLog << ", shaderSource: " << shader.c_str() 2904 << " - "; 2905 2906 result = false; 2907 } 2908 } 2909 2910 Texture::Delete(gl, verifyTexture); 2911 2912 return result; 2913 } 2914 2915 /** Constructor. 2916 * 2917 * @param context Rendering context. 2918 */ 2919 SparseTexture2Tests::SparseTexture2Tests(deqp::Context& context) 2920 : TestCaseGroup(context, "sparse_texture2_tests", "Verify conformance of CTS_ARB_sparse_texture2 implementation") 2921 { 2922 } 2923 2924 /** Initializes the test group contents. */ 2925 void SparseTexture2Tests::init() 2926 { 2927 addChild(new ShaderExtensionTestCase(m_context, "GL_ARB_sparse_texture2")); 2928 addChild(new StandardPageSizesTestCase(m_context)); 2929 addChild(new SparseTexture2AllocationTestCase(m_context)); 2930 addChild(new SparseTexture2CommitmentTestCase(m_context)); 2931 addChild(new UncommittedRegionsAccessTestCase(m_context)); 2932 addChild(new SparseTexture2LookupTestCase(m_context)); 2933 } 2934 2935 } /* gl4cts namespace */ 2936