1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2022 The Khronos Group Inc. 6 * Copyright (c) 2022 ARM Ltd. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief VK_EXT_shader_tile_image tests. 23 *//*--------------------------------------------------------------------*/ 24 25// Draw overwrapped patches with incremental value. The last value should be the patch count. 26// Decision is made with comparing between simulated value and result value. 27// All multi sample tests run with per sample shading property except MsaaSampleMask test case. 28// There are several variants. 29// - Color 30// - Depth 31// - Stencil 32// - Msaa 33// - Formats 34// - Draw Count 35// - Patch Count per Draw 36// - Coherent Mode 37// ... 38 39#include "vktShaderTileImageTests.hpp" 40#include "deDefs.hpp" 41#include "deSharedPtr.hpp" 42#include "deUniquePtr.hpp" 43#include "draw/vktDrawBufferObjectUtil.hpp" 44#include "tcuCommandLine.hpp" 45#include "tcuImageCompare.hpp" 46#include "tcuResource.hpp" 47#include "tcuStringTemplate.hpp" 48#include "tcuTestLog.hpp" 49#include "tcuTextureUtil.hpp" 50#include "vkBuilderUtil.hpp" 51#include "vkCmdUtil.hpp" 52#include "vkDefs.hpp" 53#include "vkImageUtil.hpp" 54#include "vkMemUtil.hpp" 55#include "vkObjUtil.hpp" 56#include "vkPrograms.hpp" 57#include "vkQueryUtil.hpp" 58#include "vkRef.hpp" 59#include "vkRefUtil.hpp" 60#include "vkTypeUtil.hpp" 61#include "vktRasterizationTests.hpp" 62#include "vktTestCase.hpp" 63 64using namespace vk; 65using de::MovePtr; 66using de::SharedPtr; 67 68namespace vkt 69{ 70 71namespace rasterization 72{ 73 74namespace 75{ 76 77constexpr deUint32 kImageSize = 4; // power of 2 for helper test 78constexpr deUint32 kMultiDrawElementCount = 3; 79constexpr deUint32 kMultiPatchElementCount = 3; 80constexpr deUint32 kMRTCount = 2; 81constexpr uint32_t kDerivative0 = 1; // derivative 0 + offset 1 82constexpr uint32_t kDerivative1 = 2; // derivative 1 + offset 1 83 84enum class TestType 85{ 86 Color, 87 MultiRenderTarget, 88 MultiRenderTargetDynamicIndex, 89 MsaaSampleMask, 90 HelperClassColor, 91 HelperClassDepth, 92 HelperClassStencil, 93 Depth, 94 Stencil 95}; 96 97struct TestParam 98{ 99 bool coherent; 100 TestType testType; 101 VkFormat colorFormat; 102 VkFormat depthStencilFormat; 103 VkSampleCountFlagBits m_sampleCount; 104 bool multipleDrawCalls; 105 bool multiplePatchesPerDraw; 106 deUint32 frameBufferSize; 107}; 108 109bool isHelperClassTest(TestType testType) 110{ 111 const bool helperClass = (testType == TestType::HelperClassColor) || (testType == TestType::HelperClassDepth) || 112 (testType == TestType::HelperClassStencil); 113 return helperClass; 114} 115 116deUint32 getSampleCount(VkSampleCountFlagBits sampleCount) 117{ 118 deUint32 ret = 0; 119 switch (sampleCount) 120 { 121 case VK_SAMPLE_COUNT_1_BIT: 122 ret = 1; 123 break; 124 case VK_SAMPLE_COUNT_2_BIT: 125 ret = 2; 126 break; 127 case VK_SAMPLE_COUNT_4_BIT: 128 ret = 4; 129 break; 130 case VK_SAMPLE_COUNT_8_BIT: 131 ret = 8; 132 break; 133 case VK_SAMPLE_COUNT_16_BIT: 134 ret = 16; 135 break; 136 case VK_SAMPLE_COUNT_32_BIT: 137 ret = 32; 138 break; 139 case VK_SAMPLE_COUNT_64_BIT: 140 ret = 64; 141 break; 142 default: 143 DE_ASSERT(false); 144 }; 145 return ret; 146} 147 148deUint32 getSampleMask(TestType testType) 149{ 150 return (testType == TestType::MsaaSampleMask) ? 0xaaaaaaaa : 0; 151} 152 153deUint32 getColorAttachmentCount(TestType testType) 154{ 155 switch (testType) 156 { 157 case TestType::MultiRenderTargetDynamicIndex: 158 case TestType::MultiRenderTarget: 159 case TestType::HelperClassColor: 160 case TestType::HelperClassDepth: 161 case TestType::HelperClassStencil: 162 return kMRTCount; 163 default: 164 return 1; 165 } 166 return 1; 167} 168 169deUint32 getVertexCountPerPatch(const TestParam* testParam) 170{ 171 return (testParam->testType == TestType::MsaaSampleMask) ? 3 : 6; 172} 173 174deUint32 getPatchesPerDrawCount(bool multiplePatchesPerDraw) 175{ 176 return multiplePatchesPerDraw ? kMultiPatchElementCount : 1; 177} 178 179deUint32 getDrawCallCount(const TestParam* testParam) 180{ 181 if (isHelperClassTest(testParam->testType)) 182 { 183 // helper class use two draw calls, but it is similar to single draw call 184 DE_ASSERT(!testParam->multipleDrawCalls); 185 return 2; 186 } 187 188 return testParam->multipleDrawCalls ? kMultiDrawElementCount : 1; 189} 190 191bool isNormalizedColorFormat(VkFormat format) 192{ 193 const tcu::TextureFormat colorFormat(mapVkFormat(format)); 194 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type)); 195 const bool normalizedColorFormat = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || 196 channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT); 197 return normalizedColorFormat; 198} 199 200void addOverhead(std::stringstream& shaderStream) 201{ 202 shaderStream << "{\n" 203 << " uint overheadLoop = uint(gl_FragCoord.x) * uint(${TOTAL_PATCH_COUNT} + 1);\n" 204 << " zero = patchIndex / (${TOTAL_PATCH_COUNT} + 1);\n" 205 << " for(uint index = 0u; index < overheadLoop; index++)\n" 206 << " {\n" 207 << " zero = uint(sin(float(zero)));\n" 208 << " }\n" 209 << "}\n"; 210} 211 212void transition2DImage(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, 213 vk::VkImageAspectFlags aspectMask, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout, 214 vk::VkAccessFlags srcAccessMask, vk::VkAccessFlags dstAccessMask, 215 vk::VkPipelineStageFlags srcStageMask, vk::VkPipelineStageFlags dstStageMask) 216{ 217 vk::VkImageMemoryBarrier barrier; 218 barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 219 barrier.pNext = DE_NULL; 220 barrier.srcAccessMask = srcAccessMask; 221 barrier.dstAccessMask = dstAccessMask; 222 barrier.oldLayout = oldLayout; 223 barrier.newLayout = newLayout; 224 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 225 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 226 barrier.image = image; 227 barrier.subresourceRange.aspectMask = aspectMask; 228 barrier.subresourceRange.baseMipLevel = 0; 229 barrier.subresourceRange.levelCount = 1; 230 barrier.subresourceRange.baseArrayLayer = 0; 231 barrier.subresourceRange.layerCount = 1; 232 233 vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (vk::VkDependencyFlags)0, 0, 234 (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, 235 &barrier); 236} 237 238class ShaderTileImageTestCase : public TestCase 239{ 240public: 241 ShaderTileImageTestCase(tcu::TestContext& context, const std::string& name, const TestParam& testParam); 242 ~ShaderTileImageTestCase() override = default; 243 TestInstance* createInstance(Context& context) const override; 244 245protected: 246 void initPrograms(SourceCollections& programCollection) const override; 247 void checkSupport(Context& context) const override; 248 249 void addVS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const; 250 void addFS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const; 251 void addCS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const; 252 253 void getColorTestTypeFS(std::stringstream& fragShader) const; 254 void getHelperClassTestTypeFS(std::stringstream& fragShader) const; 255 void getSampleMaskTypeFS(std::stringstream& fragShader) const; 256 void getDepthTestTypeFS(std::stringstream& fragShader) const; 257 void getStencilTestTypeFS(std::stringstream& fragShader) const; 258 259protected: 260 const TestParam m_testParam; 261}; 262 263class ShaderTileImageTestInstance : public TestInstance 264{ 265public: 266 ShaderTileImageTestInstance(Context& context, const TestParam* testParam); 267 ~ShaderTileImageTestInstance() override = default; 268 tcu::TestStatus iterate() override; 269 270protected: 271 void initialize(); 272 void generateCmdBuffer(); 273 void generateVertexBuffer(); 274 void generateAttachments(); 275 Move<VkPipeline> generateGraphicsPipeline(bool disableColor0Write, bool disableDepthWrite, 276 bool disableStencilWrite); 277 void generateComputePipeline(); 278 void rendering(); 279 deUint32 getResultValue(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const; 280 deUint32 simulate(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const; 281 tcu::TestStatus checkResult() const; 282 283protected: 284 const TestParam* m_testParam; 285 286 const DeviceInterface& m_vk; 287 SharedPtr<Draw::Buffer> m_vertexBuffer; 288 289 Move<VkCommandPool> m_cmdPool; 290 Move<VkCommandBuffer> m_cmdBuffer; 291 Move<vk::VkDescriptorPool> m_descriptorPool; 292 Move<vk::VkDescriptorSet> m_descriptorSets[kMRTCount]; 293 Move<VkPipelineLayout> m_graphicsPipelineLayout; 294 Move<VkPipeline> m_graphicsPipeline; 295 Move<VkPipeline> m_graphicsPipelineForHelperClass; 296 Move<vk::VkDescriptorSetLayout> m_computeDescriptorSetLayout; 297 Move<VkPipelineLayout> m_computePipelineLayout; 298 Move<VkPipeline> m_computePipeline; 299 Move<VkShaderModule> m_vertexModule; 300 Move<VkShaderModule> m_fragmentModule; 301 Move<VkImage> m_imageColor[kMRTCount]; 302 MovePtr<Allocation> m_imageColorAlloc[kMRTCount]; 303 deUint32* m_imageColorBufferHostPtr; 304 Move<VkImageView> m_imageColorView[kMRTCount]; 305 SharedPtr<Draw::Buffer> m_imageBuffer[kMRTCount]; 306 Move<VkImage> m_imageDepthStencil; 307 MovePtr<Allocation> m_imageDepthStencilAlloc; 308 Move<VkImageView> m_imageDepthStencilView; 309}; 310 311ShaderTileImageTestCase::ShaderTileImageTestCase(tcu::TestContext& context, const std::string& name, const TestParam& testParam) 312 : TestCase(context, name), m_testParam(testParam) 313{ 314} 315 316void ShaderTileImageTestCase::addVS(SourceCollections& programCollection, 317 const std::map<std::string, std::string>& params) const 318{ 319 std::stringstream vertShader; 320 vertShader << "#version 450 core\n" 321 << "precision highp float;\n" 322 << "precision highp int;\n" 323 << "layout(location = 0) in highp vec2 v_position;\n" 324 << "layout(location = 0) flat out uint patchIndex;" 325 << "layout( push_constant ) uniform ConstBlock\n" 326 << "{\n" 327 << " highp uint drawIndex;\n" 328 << "};\n" 329 << "void main ()\n" 330 << "{\n" 331 << " uint localPatchIndex = uint(gl_VertexIndex) / ${VERTEX_COUNT_PER_PATCH} + 1;\n" // index from 1 332 << " uint patchCountPerDraw = ${PATCH_COUNT_PER_DRAW};\n" 333 << " uint globalPatchIndex = drawIndex * patchCountPerDraw + localPatchIndex;\n" 334 << " patchIndex = globalPatchIndex;\n" 335 << " gl_Position = vec4(v_position, ${INV_TOTAL_PATCH_COUNT} * globalPatchIndex, 1);\n" 336 << "}\n"; 337 338 tcu::StringTemplate vertShaderTpl(vertShader.str()); 339 programCollection.glslSources.add("vert") << glu::VertexSource(vertShaderTpl.specialize(params)); 340} 341 342void ShaderTileImageTestCase::getColorTestTypeFS(std::stringstream& fragShader) const 343{ 344 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam.testType); 345 const bool mrtDynamicIndexTestType = (m_testParam.testType == TestType::MultiRenderTargetDynamicIndex); 346 const bool multiSampleTest = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT); 347 348 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat)); 349 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type)); 350 const bool normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat); 351 const tcu::IVec4 channelBitDepth = tcu::getTextureFormatBitDepth(colorFormat); 352 353 fragShader << "#version 450 core\n" 354 << "#extension GL_EXT_shader_tile_image : require\n" 355 << "precision highp float;\n" 356 << "precision highp int;\n" 357 << "layout( push_constant ) uniform ConstBlock\n" 358 << "{\n" 359 << " highp uint drawIndex;\n" 360 << "};\n" 361 << "layout( location = 0 ) flat in uint patchIndex;\n"; 362 363 if (!m_testParam.coherent) 364 { 365 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n"; 366 } 367 368 if (mrtDynamicIndexTestType) 369 { 370 // layout( location = 0 ) tileImageEXT highp attachmentEXT colorIn[0] 371 fragShader << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn[${ATTACHMENT_COUNT}];\n"; 372 } 373 else 374 { 375 for (deUint32 i = 0; i < attachmentCount; i++) 376 { 377 // layout( location = 0 ) tileImageEXT highp attachmentEXT colorIn0 378 fragShader << "layout( location = " << i << ") tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn" << i << ";\n"; 379 } 380 } 381 382 for (deUint32 i = 0; i < attachmentCount; i++) 383 { 384 // layout( location = 0 ) out highp vec4 out0 385 fragShader << "layout( location = " << i << " ) out highp ${OUTPUT_VECTOR_NAME} out" << i << ";\n"; 386 } 387 388 fragShader << "void main()\n" 389 << "{\n" 390 << " uint zero = 0;\n" 391 << " uvec2 previous[${ATTACHMENT_COUNT}];\n"; 392 393 float amplifier = 1.0f; 394 if (normalizedColorFormat) 395 { 396 amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ? 397 static_cast<float>(1 << (channelBitDepth.y() - 1)) : // signed 398 static_cast<float>((1 << channelBitDepth.y()) - 1); // unsigned 399 400 // color output precision is less than test case; 401 DE_ASSERT(amplifier > static_cast<float>(kMultiPatchElementCount * kMultiDrawElementCount * attachmentCount + 402 getSampleCount(m_testParam.m_sampleCount))); 403 } 404 405 for (deUint32 i = 0; i < attachmentCount; i++) 406 { 407 // in0 or colorIn[0] 408 const std::string inputImage = 409 mrtDynamicIndexTestType ? "colorIn[" + std::to_string(i) + "]" : "colorIn" + std::to_string(i); 410 411 // (in0) or (colorIn0, gl_SampleID) 412 const std::string funcParams = multiSampleTest ? "(" + inputImage + ", gl_SampleID)" : "(" + inputImage + ")"; 413 414 if (normalizedColorFormat) 415 { 416 // previous[0] = round(colorAttachmentRead(in0) * amplifier).xy;\n"; 417 fragShader << " previous[" << i << "] = uvec2(round((colorAttachmentReadEXT" << funcParams << " * " 418 << amplifier << ").xy));\n"; 419 } 420 else 421 { 422 // previous[0] *= uvec2(round(colorAttachmentRead(in0).xy));\n"; 423 fragShader << " previous[" << i << "] = uvec2(round((colorAttachmentReadEXT" << funcParams << ").xy));\n"; 424 } 425 } 426 427 // add overhead after fetching data 428 addOverhead(fragShader); 429 430 // used only for normalized color format 431 const float invAmplifier = 1.0f / static_cast<float>(amplifier); 432 433 // write output 434 for (deUint32 i = 0; i < attachmentCount; i++) 435 { 436 // if (previous[0].x == 0 && patchIndex == 1)", initial write 437 // out0.y = float(patchIndex + zero + gl_SampleID + 0);" 438 // else if (previous[0].x == 0 && (previous[0].y + 1) == (patchIndex + gl_SampleID + 0))" 439 // out0.y = float(previous[0].y + 1);" 440 // else 441 // out0.y = float(previous[0].y);" 442 // out0.x = 1;" // error 443 fragShader << " if (previous[" << i << "].x == 0 && patchIndex == 1)\n" 444 << " {\n" 445 << " out" << i << ".y = ${OUTPUT_BASIC_TYPE}(patchIndex + zero + gl_SampleID + " << i << ");\n" 446 << " }\n" 447 << " else if (previous[" << i << "].x == 0 && (previous[" << i 448 << "].y + 1) == (patchIndex + gl_SampleID + " << i << "))\n" 449 << " {\n" 450 << " out" << i << ".y = ${OUTPUT_BASIC_TYPE}(previous[" << i << "].y + 1 + zero);\n" 451 << " }\n" 452 << " else\n" 453 << " {\n" 454 << " out" << i << ".y = ${OUTPUT_BASIC_TYPE}(previous[" << i << "].y);\n" // for debug purpose 455 << " out" << i << ".x = 1;\n" // error 456 << " }\n"; 457 458 if (normalizedColorFormat) 459 { 460 // out0.y *= invAmplifier; 461 fragShader << " out" << i << ".y *= " << invAmplifier << ";\n"; 462 } 463 } 464 fragShader << "}\n"; 465} 466 467void ShaderTileImageTestCase::getHelperClassTestTypeFS(std::stringstream& fragShader) const 468{ 469 const bool depthHelperClassTest = (m_testParam.testType == TestType::HelperClassDepth); 470 const bool stencilHelperClassTest = (m_testParam.testType == TestType::HelperClassStencil); 471 472 DE_ASSERT(getPatchesPerDrawCount(!m_testParam.multiplePatchesPerDraw)); 473 DE_ASSERT(getDrawCallCount(&m_testParam) == 2); 474 DE_ASSERT(getColorAttachmentCount(m_testParam.testType) == 2); 475 DE_ASSERT((m_testParam.m_sampleCount == VK_SAMPLE_COUNT_1_BIT)); 476 DE_ASSERT(!isNormalizedColorFormat(m_testParam.colorFormat)); 477 478 fragShader << "#version 450 core\n" 479 << "#extension GL_EXT_shader_tile_image : require\n" 480 << "precision highp float;\n" 481 << "precision highp int;\n" 482 << "layout( push_constant ) uniform ConstBlock\n" 483 << "{\n" 484 << " highp uint drawIndex;\n" 485 << "};\n" 486 << "layout( location = 0 ) flat in uint patchIndex;\n"; 487 488 if (!m_testParam.coherent) 489 { 490 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n"; 491 if (depthHelperClassTest) 492 { 493 fragShader << "layout( non_coherent_depth_attachment_readEXT ) in;\n"; 494 } 495 496 if (stencilHelperClassTest) 497 { 498 fragShader << "layout( non_coherent_stencil_attachment_readEXT ) in;\n"; 499 } 500 } 501 502 fragShader << "layout(location = 0) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n"; 503 fragShader << "layout(location = 1) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn1;\n"; 504 505 fragShader << "layout(location = 0) out highp ${OUTPUT_VECTOR_NAME} out0;\n"; 506 fragShader << "layout(location = 1) out highp ${OUTPUT_VECTOR_NAME} out1;\n"; 507 508 fragShader << "void main()\n" 509 << "{\n" 510 << " uint zero = 0;\n" 511 << " uvec2 previous;\n"; 512 513 if (depthHelperClassTest) 514 { 515 fragShader << " uint scalingFactor = ${TOTAL_PATCH_COUNT};\n"; 516 fragShader << " previous.x = uint(round(colorAttachmentReadEXT(colorIn0).x));\n"; // read error status 517 fragShader << " previous.y = uint(round(depthAttachmentReadEXT() * scalingFactor));\n"; // read depth value 518 } 519 else if (stencilHelperClassTest) 520 { 521 fragShader << " previous.x = uint(round(colorAttachmentReadEXT(colorIn0).x));\n"; // read error status 522 fragShader << " previous.y = uint(stencilAttachmentReadEXT());\n"; // read stencil value 523 } 524 else 525 { 526 fragShader << " previous = uvec2(round((colorAttachmentReadEXT(colorIn0)).xy));\n"; 527 } 528 529 { 530 // draw only one triangle for helperClassTestType, dx or dy should be 0 inside of triangle. 531 // And they should be patchIndex in the diagonal edge of triangle. 532 fragShader << " uint err = 0;\n" 533 << " uint dx = 0;\n" 534 << " uint dy = 0;\n" 535 << " if (patchIndex != 1)" 536 << " {\n" 537 << " dx = uint(round(abs(dFdxFine(previous.y))));\n" 538 << " dy = uint(round(abs(dFdyFine(previous.y))));\n" 539 << " uint err = 0;\n" 540 << " if ((dx != 0 && dx != patchIndex - 1) || (dy != 0 && dy != patchIndex - 1))\n" 541 << " {\n" 542 << " err = 1;\n" // first draw doesn't have error check. 543 << " }\n" 544 << " }\n"; 545 } 546 547 // add overhead after fetching data 548 addOverhead(fragShader); 549 550 // first draw writes to attachment0 551 // second draw reads from attachment0(depth) writes to attachment1 552 { 553 fragShader << " if (patchIndex == 1 && err != 1)\n" 554 << " {\n" 555 << " out0.y = ${OUTPUT_BASIC_TYPE}(patchIndex);\n" 556 << " out0.x = 0;\n" // error 557 << " }\n" 558 << " else if (previous.x == 0 && err != 1 && ((previous.y + 1) == patchIndex || previous.y == 0))\n" 559 << " {\n" 560 << " out1.y = ${OUTPUT_BASIC_TYPE}(max(dx, dy) + 1);\n" // last 1 is to differentiate clear value 561 << " }\n" 562 << " else\n" 563 << " {\n" 564 << " out0.y = ${OUTPUT_BASIC_TYPE}(previous.y);\n" // for debug purpose 565 << " out0.x = 1;\n" // error 566 << " out1.y = ${OUTPUT_BASIC_TYPE}(previous.x);\n" 567 << " out1.x = 1;\n" // error 568 << " }\n"; 569 } 570 fragShader << "}\n"; 571} 572 573void ShaderTileImageTestCase::getSampleMaskTypeFS(std::stringstream& fragShader) const 574{ 575 const deUint32 sampleCount = getSampleCount(m_testParam.m_sampleCount); 576 577 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat)); 578 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type)); 579 const bool normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat); 580 const tcu::IVec4 channelBitDepth = tcu::getTextureFormatBitDepth(colorFormat); 581 582 deUint32 amplifier = 1; 583 if (normalizedColorFormat) 584 { 585 amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ? 586 (1 << (channelBitDepth.y() - 1)) : // signed 587 ((1 << channelBitDepth.y()) - 1); // unsigned 588 } 589 590 // Samples which is not covered should be 0 591 fragShader << "#version 450 core\n" 592 << "#extension GL_EXT_shader_tile_image : require\n" 593 << "precision highp float;\n" 594 << "precision highp int;\n" 595 << "layout( push_constant ) uniform ConstBlock\n" 596 << "{\n" 597 << " highp uint drawIndex;\n" 598 << "};\n"; 599 if (!m_testParam.coherent) 600 { 601 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n"; 602 } 603 fragShader << "layout( location = 0 ) flat in uint patchIndex;\n" 604 << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n" 605 << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n" 606 << "\n" 607 << "void main()\n" 608 << "{\n" 609 << " uint zero = 0;\n" 610 << " uint previous = 0;\n" 611 << " bool error = false;\n" 612 << " for (int i = 0; i < " << sampleCount << "; ++i)\n" 613 << " {\n" 614 << " if (((gl_SampleMaskIn[0] >> i) & 0x1) == 0x1)\n" 615 << " {\n" 616 << " uvec2 previousSample = uvec2(round(colorAttachmentReadEXT" 617 << "(colorIn0, i) * " << amplifier << ")).xy;\n" 618 << " if (previousSample.x != 0)\n" 619 << " {\n" 620 << " error = true;\n" 621 << " break;" 622 << " }\n" 623 << " if (previous == 0)\n" 624 << " {\n" 625 << " previous = previousSample.y;\n" // write non zero value to the covered sample 626 << " }\n" 627 << "\n" 628 << " if ((patchIndex != 1 && previousSample.y == 0) || previous != previousSample.y)\n" 629 << " {\n" 630 << " error = true;\n" 631 << " break;\n" 632 << " }\n" 633 << " }\n" 634 << " }\n" 635 << "\n"; 636 637 // add overhead after fetching data 638 addOverhead(fragShader); 639 640 // write output 641 fragShader << "if (!error && (previous + 1 == patchIndex))\n" 642 << " {\n" 643 << " out0.y = ${OUTPUT_BASIC_TYPE}(previous + 1 + zero);\n" 644 << " }\n" 645 << " else\n" 646 << " {\n" 647 << " out0.y = ${OUTPUT_BASIC_TYPE}(previous);\n" 648 << " out0.x = 1;\n" // error 649 << " }\n"; 650 651 const float invAmplifier = 1.0f / static_cast<float>(amplifier); 652 if (normalizedColorFormat) 653 { 654 fragShader << " out0.y *= " << invAmplifier << ";\n"; 655 } 656 657 fragShader << "}\n"; 658} 659 660void ShaderTileImageTestCase::getDepthTestTypeFS(std::stringstream& fragShader) const 661{ 662 const bool multiSampleTest = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT); 663 const std::string depthFuncParams = multiSampleTest ? "(gl_SampleID)" : "()"; 664 const std::string colorFuncParams = multiSampleTest ? "(colorIn0, gl_SampleID)" : "(colorIn0)"; 665 const deUint32 sampleCount = getSampleCount(m_testParam.m_sampleCount); 666 667 fragShader << "#version 450 core\n" 668 << "#extension GL_EXT_shader_tile_image : require\n" 669 << "precision highp float;\n" 670 << "precision highp int;\n" 671 << "layout( push_constant ) uniform ConstBlock\n" 672 << "{\n" 673 << " highp uint drawIndex;\n" 674 << "};\n"; 675 if (!m_testParam.coherent) 676 { 677 fragShader << "layout( non_coherent_depth_attachment_readEXT ) in;\n"; 678 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n"; 679 } 680 fragShader << "layout( location = 0 ) flat in uint patchIndex;\n" 681 << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n" 682 << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n" 683 << "\n" 684 << "void main()\n" 685 << "{\n" 686 << " uint zero = 0;\n" 687 << " uint scalingFactor = ${TOTAL_PATCH_COUNT};\n"; 688 if (multiSampleTest) 689 { 690 // scaling with (patch count + sample count) for multisample case 691 fragShader << " scalingFactor += " << sampleCount << ";\n"; 692 } 693 fragShader << " uint previousDepth = uint(round(depthAttachmentReadEXT" << depthFuncParams 694 << " * scalingFactor));\n" 695 << " ${OUTPUT_VECTOR_NAME} previous = ${OUTPUT_VECTOR_NAME}(round(colorAttachmentReadEXT" 696 << colorFuncParams << "));\n"; 697 698 // add overhead after fetching data 699 addOverhead(fragShader); 700 701 // write output 702 fragShader << " if (previous.x == 0 && patchIndex == 1)\n" 703 << " {\n" 704 << " out0.y = (1u + zero + gl_SampleID);\n" 705 << " }\n" 706 << " else if (previous.x == 0 && (previous.y + 1) == (patchIndex + gl_SampleID) && (previousDepth + 1) " 707 "== (patchIndex + gl_SampleID))\n" 708 << " {\n" 709 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousDepth + 1 + zero);\n" 710 << " }\n" 711 << " else\n" 712 << " {\n" 713 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousDepth);\n" // debug purpose 714 << " out0.x = 1;\n" // error 715 << " }\n"; 716 717 if (multiSampleTest) 718 { 719 // Depth value is written without adding SampleID. 720 // Forcely write all fragment depth 721 fragShader << " gl_FragDepth = float(out0.y) / scalingFactor;\n"; 722 } 723 724 fragShader << "}\n"; 725} 726 727void ShaderTileImageTestCase::getStencilTestTypeFS(std::stringstream& fragShader) const 728{ 729 const bool multiSampleTest = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT); 730 const std::string stencilFuncParams = multiSampleTest ? "(gl_SampleID)" : "()"; 731 const std::string colorFuncParams = multiSampleTest ? "(colorIn0, gl_SampleID)" : "(colorIn0)"; 732 733 fragShader << "#version 450 core\n" 734 << "#extension GL_EXT_shader_tile_image : require\n" 735 << "precision highp float;\n" 736 << "precision highp int;\n" 737 << "layout( push_constant ) uniform ConstBlock\n" 738 << "{\n" 739 << " highp uint drawIndex;\n" 740 << "};\n"; 741 if (!m_testParam.coherent) 742 { 743 fragShader << "layout( non_coherent_stencil_attachment_readEXT ) in;\n"; 744 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n"; 745 } 746 fragShader << "layout( location = 0 ) flat in uint patchIndex;\n" 747 << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n" 748 << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n" 749 << "\n" 750 << "void main()\n" 751 << "{\n" 752 << " uint zero = 0;\n" 753 << " uint previousStencil = uint(round(stencilAttachmentReadEXT" << stencilFuncParams << " ));\n" 754 << " ${OUTPUT_VECTOR_NAME} previous = ${OUTPUT_VECTOR_NAME}(round(colorAttachmentReadEXT" 755 << colorFuncParams << "));\n"; 756 757 // add overhead after fetching data 758 addOverhead(fragShader); 759 760 // write output 761 fragShader << " if (previous.x == 0 && (previous.y + 1) == patchIndex && (previousStencil + 1) == patchIndex)\n" 762 << " {\n" 763 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousStencil + 1 + zero);\n" 764 << " }\n" 765 << " else\n" 766 << " {\n" 767 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousStencil);\n" // debug purpose 768 << " out0.x = 1;\n" // error 769 << " }\n" 770 << "}\n"; 771} 772 773void rasterization::ShaderTileImageTestCase::addFS(SourceCollections& programCollection, 774 const std::map<std::string, std::string>& params) const 775{ 776 std::stringstream fragShader; 777 778 switch (m_testParam.testType) 779 { 780 case TestType::Color: 781 case TestType::MultiRenderTarget: 782 case TestType::MultiRenderTargetDynamicIndex: 783 getColorTestTypeFS(fragShader); 784 break; 785 case TestType::HelperClassColor: 786 case TestType::HelperClassDepth: 787 case TestType::HelperClassStencil: 788 getHelperClassTestTypeFS(fragShader); 789 break; 790 case TestType::MsaaSampleMask: 791 getSampleMaskTypeFS(fragShader); 792 break; 793 case TestType::Depth: 794 getDepthTestTypeFS(fragShader); 795 break; 796 case TestType::Stencil: 797 getStencilTestTypeFS(fragShader); 798 break; 799 default: 800 DE_ASSERT(true); 801 } 802 803 tcu::StringTemplate fragShaderTpl(fragShader.str()); 804 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params)); 805} 806 807// Copy Image to Buffer using Compute Shader for handling multi sample cases 808void ShaderTileImageTestCase::addCS(SourceCollections& programCollection, 809 const std::map<std::string, std::string>& params) const 810{ 811 std::stringstream compShader; 812 813 const deUint32 sampleCount = getSampleCount(m_testParam.m_sampleCount); 814 const std::string fsampler = sampleCount > 1 ? "texture2DMS" : "texture2D"; 815 const std::string usampler = sampleCount > 1 ? "utexture2DMS" : "utexture2D"; 816 const std::string isampler = sampleCount > 1 ? "itexture2DMS" : "itexture2D"; 817 818 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat)); 819 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type)); 820 const tcu::IVec4 channelBitDepth = tcu::getTextureFormatBitDepth(colorFormat); 821 const bool normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat); 822 823 std::string sampler; 824 switch (channelClass) 825 { 826 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 827 sampler = usampler; 828 break; 829 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 830 sampler = isampler; 831 break; 832 default: 833 sampler = fsampler; 834 } 835 836 deUint32 amplifier = 1; 837 838 if (normalizedColorFormat) 839 { 840 amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ? 841 (1 << (channelBitDepth.y() - 1)) : // signed 842 ((1 << channelBitDepth.y()) - 1); // unsigned 843 } 844 845 // Compute shader copies color to linear layout in buffer memory 846 compShader << "#version 450 core\n" 847 << "#extension GL_EXT_samplerless_texture_functions : enable\n" 848 << "precision highp float;\n" 849 << "precision highp int;\n" 850 << "layout(set = 0, binding = 0) uniform " << sampler << " colorTex;\n" 851 << "layout(set = 0, binding = 1, std430) buffer Block0 { uvec2 values[]; } colorbuf;\n" 852 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 853 << "void main()\n" 854 << "{\n" 855 << " for (uint i = 0u; i < " << sampleCount << "u; ++i) {\n" 856 << " uint idx = ((gl_GlobalInvocationID.y * " << m_testParam.frameBufferSize 857 << "u) + gl_GlobalInvocationID.x) * " << sampleCount << "u + i;\n"; 858 859 if (normalizedColorFormat) 860 { 861 compShader << " colorbuf.values[idx].y = uint(round(texelFetch(colorTex, ivec2(gl_GlobalInvocationID.xy), " 862 "int(i)).y * " 863 << amplifier << "));\n"; 864 compShader << " colorbuf.values[idx].x = uint(round(texelFetch(colorTex, ivec2(gl_GlobalInvocationID.xy), " 865 "int(i)).x));\n"; 866 } 867 else 868 { 869 compShader << " colorbuf.values[idx] = uvec2(round(vec2(texelFetch(colorTex, " 870 "ivec2(gl_GlobalInvocationID.xy), int(i)).xy)));\n"; 871 } 872 873 compShader << " }\n" 874 << "}\n"; 875 876 tcu::StringTemplate computeShaderTpl(compShader.str()); 877 programCollection.glslSources.add("comp") << glu::ComputeSource(computeShaderTpl.specialize(params)); 878} 879 880void ShaderTileImageTestCase::initPrograms(SourceCollections& programCollection) const 881{ 882 std::map<std::string, std::string> params; 883 884 const deUint32 drawCount = getDrawCallCount(&m_testParam); 885 const deUint32 patchCountPerDraw = getPatchesPerDrawCount(m_testParam.multiplePatchesPerDraw); 886 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam.testType); 887 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat)); 888 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type)); 889 890 params["VERTEX_COUNT_PER_PATCH"] = std::to_string(getVertexCountPerPatch(&m_testParam)); 891 params["PATCH_COUNT_PER_DRAW"] = std::to_string(patchCountPerDraw); 892 params["INV_TOTAL_PATCH_COUNT"] = std::to_string(1.0f / static_cast<float>(drawCount * patchCountPerDraw)); 893 params["TOTAL_PATCH_COUNT"] = std::to_string(drawCount * patchCountPerDraw); 894 params["ATTACHMENT_COUNT"] = std::to_string(attachmentCount); 895 896 std::string strVecName; 897 std::string strBasicType; 898 std::string strTileImageType; 899 900 switch (channelClass) 901 { 902 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 903 strVecName = "uvec"; 904 strTileImageType = "uattachmentEXT"; 905 strBasicType = "uint"; 906 break; 907 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 908 strVecName = "ivec"; 909 strTileImageType = "iattachmentEXT"; 910 strBasicType = "int"; 911 break; 912 default: 913 strVecName = "vec"; 914 strTileImageType = "attachmentEXT"; 915 strBasicType = "float"; 916 } 917 params["OUTPUT_VECTOR_NAME"] = strVecName + std::to_string(tcu::getNumUsedChannels(colorFormat.order)); 918 params["OUTPUT_BASIC_TYPE"] = strBasicType; 919 params["TILE_IMAGE_TYPE"] = strTileImageType; 920 921 addVS(programCollection, params); 922 addFS(programCollection, params); 923 addCS(programCollection, params); 924} 925 926TestInstance* ShaderTileImageTestCase::createInstance(Context& context) const 927{ 928 return new ShaderTileImageTestInstance(context, &m_testParam); 929} 930 931void ShaderTileImageTestCase::checkSupport(Context& context) const 932{ 933 if (!context.requireDeviceFunctionality("VK_KHR_dynamic_rendering")) 934 { 935 TCU_THROW(NotSupportedError, "VK_KHR_dynamic_rendering not supported"); 936 } 937 938 if (!context.requireDeviceFunctionality("VK_EXT_shader_tile_image")) 939 { 940 TCU_THROW(NotSupportedError, "VK_EXT_shader_tile_image not supported"); 941 } 942 /* sampleRateShading must be enabled to call fragment shader for all the samples in multisampling */ 943 VkPhysicalDeviceShaderTileImageFeaturesEXT shaderTileImageFeature = {}; 944 shaderTileImageFeature.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT; 945 946 VkPhysicalDeviceFeatures features = {}; 947 VkPhysicalDeviceFeatures2 features2 = {}; 948 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 949 features2.pNext = &shaderTileImageFeature; 950 951 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features); 952 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2); 953 954 if (!shaderTileImageFeature.shaderTileImageColorReadAccess) 955 { 956 TCU_THROW(NotSupportedError, "color read access of VK_EXT_shader_tile_image is not supported"); 957 } 958 switch (m_testParam.testType) 959 { 960 case TestType::Depth: 961 case TestType::HelperClassDepth: 962 if (!shaderTileImageFeature.shaderTileImageDepthReadAccess) 963 { 964 TCU_THROW(NotSupportedError, "depth read access of VK_EXT_shader_tile_image is not supported"); 965 } 966 break; 967 case TestType::Stencil: 968 case TestType::HelperClassStencil: 969 if (!shaderTileImageFeature.shaderTileImageStencilReadAccess) 970 { 971 TCU_THROW(NotSupportedError, "stencil read access of VK_EXT_shader_tile_image is not supported"); 972 } 973 break; 974 case TestType::Color: 975 case TestType::MultiRenderTarget: 976 case TestType::MultiRenderTargetDynamicIndex: 977 case TestType::MsaaSampleMask: 978 case TestType::HelperClassColor: 979 break; 980 default: 981 DE_ASSERT(0); 982 } 983 984 VkPhysicalDeviceVulkan12Properties vulkan12Properties = {}; 985 vulkan12Properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES; 986 987 VkPhysicalDeviceShaderTileImagePropertiesEXT shaderTileImageProperties = {}; 988 shaderTileImageProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_PROPERTIES_EXT; 989 shaderTileImageProperties.pNext = &vulkan12Properties; 990 991 VkPhysicalDeviceProperties2 properties = {}; 992 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 993 properties.pNext = &shaderTileImageProperties; 994 995 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties); 996 997 // shaderTileImageReadSampleFromPixelRateInvocation is a boolean that will be VK_TRUE if reading from samples from a 998 // pixel rate fragment invocation is supported when VkPipelineMultisampleStateCreateInfo::rasterizationSamples > 1. 999 // shaderTileImageReadFromHelperInvocation is a boolean that will be VK_TRUE if reads of tile image data from helper 1000 // fragment invocations result in valid values. 1001 if (!shaderTileImageProperties.shaderTileImageReadSampleFromPixelRateInvocation) 1002 { 1003 if (m_testParam.testType == TestType::MsaaSampleMask) 1004 { 1005 TCU_THROW(NotSupportedError, "multi-samples pixel access of VK_EXT_shader_tile_image is not supported"); 1006 } 1007 } 1008 1009 if (!shaderTileImageProperties.shaderTileImageReadFromHelperInvocation) 1010 { 1011 if (isHelperClassTest(m_testParam.testType)) 1012 { 1013 TCU_THROW(NotSupportedError, "helper class fragments access of VK_EXT_shader_tile_image is not supported"); 1014 } 1015 } 1016 1017 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat)); 1018 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type)); 1019 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER || 1020 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 1021 { 1022 if ((vulkan12Properties.framebufferIntegerColorSampleCounts & m_testParam.m_sampleCount) == 0 || 1023 (properties.properties.limits.sampledImageIntegerSampleCounts & m_testParam.m_sampleCount) == 0) 1024 { 1025 TCU_THROW(NotSupportedError, "Sample count not supported"); 1026 } 1027 } 1028 else 1029 { 1030 if ((properties.properties.limits.framebufferColorSampleCounts & m_testParam.m_sampleCount) == 0 || 1031 (properties.properties.limits.sampledImageColorSampleCounts & m_testParam.m_sampleCount) == 0) 1032 { 1033 TCU_THROW(NotSupportedError, "Sample count not supported"); 1034 } 1035 } 1036 1037 if (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT && m_testParam.testType != TestType::MsaaSampleMask && 1038 !features.sampleRateShading) 1039 { 1040 TCU_THROW(NotSupportedError, "sampleRateShading feature not supported"); 1041 } 1042 1043 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam.testType); 1044 1045 if (properties.properties.limits.maxFragmentOutputAttachments < attachmentCount || 1046 properties.properties.limits.maxPerStageDescriptorInputAttachments < attachmentCount) 1047 { 1048 TCU_THROW(NotSupportedError, "attachment number not supported"); 1049 } 1050 1051 const InstanceInterface& vki = context.getInstanceInterface(); 1052 VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1053 const VkFormatProperties colorFormatProperties( 1054 getPhysicalDeviceFormatProperties(vki, physicalDevice, m_testParam.colorFormat)); 1055 const VkFormatProperties dsFormatProperties( 1056 getPhysicalDeviceFormatProperties(vki, physicalDevice, m_testParam.depthStencilFormat)); 1057 1058 if ((colorFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) 1059 { 1060 TCU_THROW(NotSupportedError, "Format can't be used as color attachment"); 1061 } 1062 1063 if ((dsFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0) 1064 { 1065 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment"); 1066 } 1067} 1068 1069ShaderTileImageTestInstance::ShaderTileImageTestInstance(Context& context, const TestParam* testParam) 1070 : TestInstance(context), m_testParam(testParam), m_vk(m_context.getDeviceInterface()) 1071{ 1072 initialize(); 1073} 1074 1075void ShaderTileImageTestInstance::initialize() 1076{ 1077 generateCmdBuffer(); 1078 generateAttachments(); 1079 generateVertexBuffer(); 1080 m_graphicsPipeline = generateGraphicsPipeline(false, false, false); 1081 m_graphicsPipelineForHelperClass = generateGraphicsPipeline(true, true, true); 1082 generateComputePipeline(); 1083} 1084 1085void ShaderTileImageTestInstance::generateComputePipeline() 1086{ 1087 const deUint32 attachmentSize = getColorAttachmentCount(m_testParam->testType); 1088 const VkDevice device = m_context.getDevice(); 1089 1090 const Unique<VkShaderModule> cs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("comp"), 0)); 1091 1092 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0; 1093 1094 const VkDescriptorSetLayoutBinding bindings[] = { 1095 { 1096 0, // binding 1097 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType 1098 1, // descriptorCount 1099 VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags 1100 DE_NULL, // pImmutableSamplers 1101 }, 1102 { 1103 1, // binding 1104 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType 1105 1, // descriptorCount 1106 VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags 1107 DE_NULL, // pImmutableSamplers 1108 }, 1109 }; 1110 1111 // Create a layout and allocate a descriptor set for it. 1112 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo = { 1113 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType 1114 DE_NULL, // pNext 1115 layoutCreateFlags, // flags 1116 sizeof(bindings) / sizeof(bindings[0]), // bindingCount 1117 &bindings[0] // pBindings 1118 }; 1119 1120 m_computeDescriptorSetLayout = vk::createDescriptorSetLayout(m_vk, device, &setLayoutCreateInfo); 1121 1122 const VkPipelineShaderStageCreateInfo csShaderCreateInfo = { 1123 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1124 DE_NULL, 1125 (VkPipelineShaderStageCreateFlags)0, 1126 VK_SHADER_STAGE_COMPUTE_BIT, // stage 1127 *cs, // shader 1128 "main", 1129 DE_NULL, // pSpecializationInfo 1130 }; 1131 1132 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { 1133 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType 1134 DE_NULL, // pNext 1135 (VkPipelineLayoutCreateFlags)0, 1136 1, // setLayoutCount 1137 &m_computeDescriptorSetLayout.get(), // pSetLayouts 1138 0, // pushConstantRangeCount 1139 DE_NULL, // pPushConstantRanges 1140 }; 1141 1142 m_computePipelineLayout = createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo, NULL); 1143 1144 const VkComputePipelineCreateInfo pipelineCreateInfo = { 1145 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 1146 DE_NULL, 1147 0u, // flags 1148 csShaderCreateInfo, // cs 1149 *m_computePipelineLayout, // layout 1150 (vk::VkPipeline)0, // basePipelineHandle 1151 0u, // basePipelineIndex 1152 }; 1153 1154 m_computePipeline = createComputePipeline(m_vk, device, DE_NULL, &pipelineCreateInfo, NULL); 1155 1156 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 1157 1158 vk::DescriptorPoolBuilder poolBuilder; 1159 for (deUint32 i = 0; i < (deInt32)(sizeof(bindings) / sizeof(bindings[0])); ++i) 1160 { 1161 poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount * attachmentSize); 1162 } 1163 m_descriptorPool = poolBuilder.build(m_vk, device, poolCreateFlags, attachmentSize); 1164 1165 for (deUint32 i = 0; i < attachmentSize; ++i) 1166 { 1167 m_descriptorSets[i] = makeDescriptorSet(m_vk, device, *m_descriptorPool, *m_computeDescriptorSetLayout); 1168 VkDescriptorImageInfo imageInfo; 1169 VkDescriptorBufferInfo bufferInfo; 1170 1171 VkWriteDescriptorSet w = { 1172 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType 1173 DE_NULL, // pNext 1174 *m_descriptorSets[i], // dstSet 1175 (deUint32)0, // dstBinding 1176 0, // dstArrayElement 1177 1u, // descriptorCount 1178 bindings[0].descriptorType, // descriptorType 1179 &imageInfo, // pImageInfo 1180 &bufferInfo, // pBufferInfo 1181 DE_NULL, // pTexelBufferView 1182 }; 1183 1184 imageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageColorView[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 1185 w.dstBinding = 0; 1186 w.descriptorType = bindings[0].descriptorType; 1187 m_vk.updateDescriptorSets(device, 1, &w, 0, NULL); 1188 1189 bufferInfo = makeDescriptorBufferInfo(m_imageBuffer[i]->object(), 0, VK_WHOLE_SIZE); 1190 w.dstBinding = 1; 1191 w.descriptorType = bindings[1].descriptorType; 1192 m_vk.updateDescriptorSets(device, 1, &w, 0, NULL); 1193 } 1194} 1195 1196Move<VkPipeline> ShaderTileImageTestInstance::generateGraphicsPipeline(bool disableColor0Write, bool disableDepthWrite, 1197 bool disableStencilWrite) 1198{ 1199 const VkDevice device = m_context.getDevice(); 1200 1201 VkPushConstantRange pushConstant; 1202 pushConstant.offset = 0; 1203 pushConstant.size = sizeof(deUint32); 1204 pushConstant.stageFlags = (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); 1205 1206 m_graphicsPipelineLayout = makePipelineLayout(m_vk, device, 0, nullptr, 1, &pushConstant); 1207 m_vertexModule = createShaderModule(m_vk, device, m_context.getBinaryCollection().get("vert"), 0u); 1208 m_fragmentModule = createShaderModule(m_vk, device, m_context.getBinaryCollection().get("frag"), 0u); 1209 1210 const VkVertexInputBindingDescription vertexInputBindingDescription = { 1211 0, // deUint32 binding; 1212 sizeof(tcu::Vec2), // deUint32 strideInBytes; 1213 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputStepRate stepRate; 1214 }; 1215 1216 const VkVertexInputAttributeDescription vertexInputAttributeDescription = { 1217 0u, // deUint32 location; 1218 0u, // deUint32 binding; 1219 VK_FORMAT_R32G32_SFLOAT, // VkFormat format; 1220 0u, // deUint32 offsetInBytes; 1221 }; 1222 1223 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = { 1224 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1225 DE_NULL, // const void* pNext; 1226 0, // VkPipelineVertexInputStateCreateFlags flags; 1227 1u, // deUint32 bindingCount; 1228 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1229 1u, // deUint32 attributeCount; 1230 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1231 }; 1232 1233 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = { 1234 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1235 DE_NULL, // const void* pNext; 1236 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 1237 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 1238 VK_FALSE, // VkBool32 primitiveRestartEnable; 1239 }; 1240 1241 const VkViewport viewport{ 1242 0, 0, static_cast<float>(m_testParam->frameBufferSize), static_cast<float>(m_testParam->frameBufferSize), 0, 1 1243 }; 1244 const VkRect2D scissor{ { 0, 0 }, { m_testParam->frameBufferSize, m_testParam->frameBufferSize } }; 1245 1246 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = { 1247 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1248 DE_NULL, // const void* pNext; 1249 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 1250 1u, // uint32_t viewportCount; 1251 &viewport, // const VkViewport* pViewports; 1252 1u, // uint32_t scissorCount; 1253 &scissor, // const VkRect2D* pScissors; 1254 }; 1255 1256 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = { 1257 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1258 DE_NULL, // const void* pNext; 1259 0u, // VkPipelineRasterizationStateCreateFlags flags; 1260 VK_FALSE, // VkBool32 depthClampEnable; 1261 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 1262 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 1263 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 1264 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1265 VK_FALSE, // VkBool32 depthBiasEnable; 1266 0.0f, // float depthBiasConstantFactor; 1267 0.0f, // float depthBiasClamp; 1268 0.0f, // float depthBiasSlopeFactor; 1269 1.0f, // float lineWidth; 1270 }; 1271 1272 const VkSampleMask sampleMask = getSampleMask(m_testParam->testType); 1273 const VkSampleMask* pSampleMask = (m_testParam->testType == TestType::MsaaSampleMask) ? &sampleMask : DE_NULL; 1274 const bool sampleShadingEnable = (m_testParam->testType != TestType::MsaaSampleMask); 1275 1276 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = { 1277 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1278 DE_NULL, // const void* pNext; 1279 0u, // VkPipelineMultisampleStateCreateFlags flags; 1280 m_testParam->m_sampleCount, // VkSampleCountFlagBits rasterizationSamples; 1281 sampleShadingEnable, // VkBool32 sampleShadingEnable; 1282 1.0f, // float minSampleShading; 1283 pSampleMask, // const VkSampleMask* pSampleMask; 1284 VK_FALSE, // VkBool32 alphaToCoverageEnable; 1285 VK_FALSE // VkBool32 alphaToOneEnable; 1286 }; 1287 1288 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState( 1289 getColorAttachmentCount(m_testParam->testType), 1290 { 1291 false, // VkBool32 blendEnable; 1292 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 1293 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor; 1294 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 1295 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 1296 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha; 1297 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 1298 (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT) // VkChannelFlags channelWriteMask; 1299 }); 1300 1301 if (disableColor0Write) 1302 { 1303 colorBlendAttachmentState[0].colorWriteMask = 0; 1304 } 1305 1306 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = { 1307 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1308 DE_NULL, // const void* pNext; 1309 /* always needed */ 1310 0, // VkPipelineColorBlendStateCreateFlags flags; 1311 false, // VkBool32 logicOpEnable; 1312 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1313 (deUint32)colorBlendAttachmentState.size(), // deUint32 attachmentCount; 1314 colorBlendAttachmentState.data(), // const VkPipelineColorBlendAttachmentState* pAttachments; 1315 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 1316 }; 1317 1318 VkStencilOpState stencilOpState = { 1319 VK_STENCIL_OP_ZERO, // VkStencilOp failOp; 1320 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp passOp; 1321 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp depthFailOp; 1322 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; 1323 0xff, // uint32_t compareMask; 1324 0xff, // uint32_t writeMask; 1325 0, // uint32_t reference; 1326 }; 1327 1328 if (disableStencilWrite) 1329 { 1330 stencilOpState.failOp = VK_STENCIL_OP_KEEP; 1331 stencilOpState.passOp = VK_STENCIL_OP_KEEP; 1332 stencilOpState.depthFailOp = VK_STENCIL_OP_KEEP; 1333 } 1334 1335 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = { 1336 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 1337 // VkStructureType sType; 1338 DE_NULL, // const void* pNext; 1339 0, 1340 // VkPipelineDepthStencilStateCreateFlags flags; 1341 VK_TRUE, // VkBool32 depthTestEnable; 1342 VK_TRUE, // VkBool32 depthWriteEnable; 1343 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp; 1344 VK_FALSE, // VkBool32 depthBoundsTestEnable; 1345 VK_TRUE, // VkBool32 stencilTestEnable; 1346 stencilOpState, // VkStencilOpState front; 1347 stencilOpState, // VkStencilOpState back; 1348 0.0f, // float minDepthBounds; 1349 1.0f, // float maxDepthBounds; 1350 }; 1351 1352 if (disableDepthWrite) 1353 { 1354 pipelineDepthStencilStateInfo.depthWriteEnable = VK_FALSE; 1355 } 1356 1357 std::vector<VkFormat> colorsAttachmentFormats(getColorAttachmentCount(m_testParam->testType), 1358 m_testParam->colorFormat); 1359 const tcu::TextureFormat depthStencilTexFormat = mapVkFormat(m_testParam->depthStencilFormat); 1360 VkFormat depthFormat = tcu::hasDepthComponent(depthStencilTexFormat.order) ? m_testParam->depthStencilFormat : VK_FORMAT_UNDEFINED; 1361 VkFormat stencilFormat = tcu::hasStencilComponent(depthStencilTexFormat.order) ? m_testParam->depthStencilFormat : VK_FORMAT_UNDEFINED; 1362 const VkPipelineRenderingCreateInfoKHR renderingCreateInfo{ 1363 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, // VkStructureType sType; 1364 DE_NULL, // const void* pNext; 1365 0u, // deUint32 viewMask; 1366 static_cast<deUint32>(colorsAttachmentFormats.size()), // deUint32 colorAttachmentCount; 1367 colorsAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats; 1368 depthFormat, // VkFormat depthAttachmentFormat; 1369 stencilFormat, // VkFormat stencilAttachmentFormat; 1370 }; 1371 1372 const VkPipelineShaderStageCreateInfo pShaderStages[] = { 1373 { 1374 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1375 DE_NULL, // const void* pNext; 1376 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 1377 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 1378 *m_vertexModule, // VkShaderModule module; 1379 "main", // const char* pName; 1380 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 1381 }, 1382 { 1383 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1384 DE_NULL, // const void* pNext; 1385 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 1386 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 1387 *m_fragmentModule, // VkShaderModule module; 1388 "main", // const char* pName; 1389 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 1390 }, 1391 }; 1392 1393 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = { 1394 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1395 &renderingCreateInfo, // const void* pNext; 1396 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 1397 2u, // deUint32 stageCount; 1398 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages; 1399 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1400 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1401 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1402 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; 1403 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 1404 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1405 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1406 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1407 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1408 *m_graphicsPipelineLayout, // VkPipelineLayout layout; 1409 DE_NULL, // VkRenderPass renderPass; 1410 0u, // deUint32 subpass; 1411 DE_NULL, // VkPipeline basePipelineHandle; 1412 0, // deInt32 basePipelineIndex; 1413 }; 1414 1415 return createGraphicsPipeline(m_vk, device, DE_NULL, &graphicsPipelineInfo); 1416} 1417 1418void ShaderTileImageTestInstance::generateAttachments() 1419{ 1420 const VkDevice device = m_context.getDevice(); 1421 Allocator& allocator = m_context.getDefaultAllocator(); 1422 1423 auto makeImageCreateInfo = [](const VkFormat format, deUint32 imageSize, VkSampleCountFlagBits sampleCount, 1424 VkImageUsageFlags usage) -> VkImageCreateInfo 1425 { 1426 const VkImageCreateInfo imageParams = { 1427 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1428 DE_NULL, // const void* pNext; 1429 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 1430 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1431 format, // VkFormat format; 1432 makeExtent3D(imageSize, imageSize, 1), // VkExtent3D extent; 1433 1u, // deUint32 mipLevels; 1434 1u, // deUint32 arrayLayers; 1435 sampleCount, // VkSampleCountFlagBits samples; 1436 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1437 usage, // VkImageUsageFlags usage; 1438 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1439 0u, // deUint32 queueFamilyIndexCount; 1440 DE_NULL, // const deUint32* pQueueFamilyIndices; 1441 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1442 }; 1443 return imageParams; 1444 }; 1445 1446 // Color Attachment 1447 { 1448 constexpr deUint32 imageBufferPixelSize = sizeof(deUint32) * 2; // always uvec2 type 1449 const VkImageUsageFlags imageUsage = 1450 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1451 const VkDeviceSize imageBufferSize = m_testParam->frameBufferSize * m_testParam->frameBufferSize * 1452 imageBufferPixelSize * getSampleCount(m_testParam->m_sampleCount); 1453 const VkImageSubresourceRange imageSubresource = 1454 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 1455 const VkImageCreateInfo imageInfo = makeImageCreateInfo(m_testParam->colorFormat, m_testParam->frameBufferSize, 1456 m_testParam->m_sampleCount, imageUsage); 1457 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo( 1458 imageBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 1459 1460 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam->testType); 1461 for (deUint32 i = 0; i < attachmentCount; ++i) 1462 { 1463 m_imageColor[i] = makeImage(m_vk, device, imageInfo); 1464 m_imageColorAlloc[i] = bindImage(m_vk, device, allocator, *m_imageColor[i], MemoryRequirement::Any); 1465 m_imageBuffer[i] = 1466 Draw::Buffer::createAndAlloc(m_vk, device, bufferInfo, allocator, MemoryRequirement::HostVisible); 1467 m_imageColorView[i] = makeImageView(m_vk, device, *m_imageColor[i], VK_IMAGE_VIEW_TYPE_2D, 1468 m_testParam->colorFormat, imageSubresource); 1469 } 1470 1471 m_imageColorBufferHostPtr = static_cast<deUint32*>(m_imageBuffer[0]->getHostPtr()); 1472 } 1473 1474 // depth/stencil attachment. 1475 { 1476 const tcu::TextureFormat depthStencilFormat = mapVkFormat(m_testParam->depthStencilFormat); 1477 const VkImageUsageFlags imageUsage = 1478 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1479 1480 VkImageAspectFlags aspect = 0; 1481 if (tcu::hasDepthComponent(depthStencilFormat.order)) 1482 { 1483 aspect |= VK_IMAGE_ASPECT_DEPTH_BIT; 1484 } 1485 if (tcu::hasStencilComponent(depthStencilFormat.order)) 1486 { 1487 aspect |= VK_IMAGE_ASPECT_STENCIL_BIT; 1488 } 1489 1490 const VkImageCreateInfo imageInfo = makeImageCreateInfo( 1491 m_testParam->depthStencilFormat, m_testParam->frameBufferSize, m_testParam->m_sampleCount, imageUsage); 1492 1493 const VkImageSubresourceRange imageSubresource = makeImageSubresourceRange(aspect, 0u, 1u, 0u, 1u); 1494 1495 m_imageDepthStencil = makeImage(m_vk, device, imageInfo); 1496 m_imageDepthStencilAlloc = bindImage(m_vk, device, allocator, *m_imageDepthStencil, MemoryRequirement::Any); 1497 m_imageDepthStencilView = makeImageView(m_vk, device, *m_imageDepthStencil, VK_IMAGE_VIEW_TYPE_2D, 1498 m_testParam->depthStencilFormat, imageSubresource); 1499 } 1500} 1501 1502void ShaderTileImageTestInstance::generateVertexBuffer() 1503{ 1504 const deUint32 drawCount = getDrawCallCount(m_testParam); 1505 const deUint32 patchCountPerDraw = getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw); 1506 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1507 const VkDevice device = m_context.getDevice(); 1508 Allocator& allocator = m_context.getDefaultAllocator(); 1509 std::vector<tcu::Vec2> vbo; 1510 for (deUint32 patchIndex = 0; patchIndex < (patchCountPerDraw * drawCount); patchIndex++) 1511 { 1512 // _____ 1513 // | / 1514 // | / 1515 // |/ 1516 vbo.emplace_back(tcu::Vec2(-1, -1)); 1517 vbo.emplace_back(tcu::Vec2(1, 1)); 1518 vbo.emplace_back(tcu::Vec2(-1, 1)); 1519 1520 if (getVertexCountPerPatch(m_testParam) == 6) 1521 { 1522 if (isHelperClassTest(m_testParam->testType) && patchIndex == 0) 1523 { 1524 // helper class cases render the first patch like follow. 1525 // _____ 1526 // | / 1527 // | / 1528 // |/ 1529 // So, 3 of second triangle is dummy. 1530 vbo.emplace_back(tcu::Vec2(-1, -1)); 1531 vbo.emplace_back(tcu::Vec2(-1, -1)); 1532 vbo.emplace_back(tcu::Vec2(-1, -1)); 1533 } 1534 else 1535 { 1536 // Other 6 vertices cases render like follow 1537 // _____ 1538 // | /| 1539 // | / | 1540 // |/__| 1541 vbo.emplace_back(tcu::Vec2(-1, -1)); 1542 vbo.emplace_back(tcu::Vec2(1, -1)); 1543 vbo.emplace_back(tcu::Vec2(1, 1)); 1544 } 1545 } 1546 } 1547 1548 const size_t dataSize = vbo.size() * sizeof(tcu::Vec2); 1549 { 1550 const VkBufferCreateInfo bufferInfo = { 1551 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1552 DE_NULL, // const void* pNext; 1553 0u, // VkBufferCreateFlags flags; 1554 dataSize, // VkDeviceSize size; 1555 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1556 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1557 1u, // deUint32 queueFamilyCount; 1558 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1559 }; 1560 m_vertexBuffer = 1561 Draw::Buffer::createAndAlloc(m_vk, device, bufferInfo, allocator, MemoryRequirement::HostVisible); 1562 } 1563 1564 /* Load vertices into vertex buffer */ 1565 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), vbo.data(), dataSize); 1566 flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory()); 1567} 1568void ShaderTileImageTestInstance::generateCmdBuffer() 1569{ 1570 const VkDevice device = m_context.getDevice(); 1571 1572 m_cmdPool = createCommandPool(m_vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, 1573 m_context.getUniversalQueueFamilyIndex()); 1574 m_cmdBuffer = allocateCommandBuffer(m_vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1575} 1576 1577tcu::TestStatus ShaderTileImageTestInstance::iterate() 1578{ 1579 rendering(); 1580 return checkResult(); 1581} 1582 1583deUint32 ShaderTileImageTestInstance::getResultValue(deUint32 fx, deUint32 fy, deUint32 fs, 1584 deUint32 renderTargetID) const 1585{ 1586 const deUint32* resultData = 1587 static_cast<const deUint32*>(m_imageBuffer[renderTargetID]->getBoundMemory().getHostPtr()); 1588 const deUint32 sampleCount = getSampleCount(m_testParam->m_sampleCount); 1589 const deUint32 index = (((fy * m_testParam->frameBufferSize) + fx) * sampleCount + fs) * 2; // 2 is for xy 1590 if (resultData[index] != 0) // error 1591 { 1592 return 0xFFFFFFFF; 1593 } 1594 1595 return resultData[index + 1]; // y value 1596} 1597 1598deUint32 ShaderTileImageTestInstance::simulate(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const 1599{ 1600 const deUint32 totalLayerCount = 1601 getDrawCallCount(m_testParam) * getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw); 1602 1603 if (m_testParam->testType == TestType::MsaaSampleMask) 1604 { 1605 deUint32 expectedValue = 0; 1606 1607 if (((getSampleMask(m_testParam->testType) >> fs) & 0x1) == 0x1) 1608 { 1609 expectedValue = totalLayerCount + renderTargetID; 1610 } 1611 return expectedValue; 1612 } 1613 if (m_testParam->testType == TestType::Stencil) 1614 { 1615 // stencil test doesn't add fragment sample ID to the output; 1616 const deUint32 expectedValue = totalLayerCount + renderTargetID; 1617 return expectedValue; 1618 } 1619 if (isHelperClassTest(m_testParam->testType)) 1620 { 1621 // ________ ________ ________ 1622 // 1|1|1|0| 0|0|*|1| 1|1|#|2| 1623 // 1|1|0|0| 0|0|1|*| 1|1|2|#| 1624 // 1|0|0|0| => *|1|0|0| => #|2|1|1| 1625 // 0|0|0|0| 1|*|0|0| 2|#|1|1| 1626 // ________ ________ ________ 1627 // raster max(dx,dy) result(+1) 1628 // *(#): max(dx, dy) could be 0(1) or 1(2). 1629 if ((fx) == (fy)) 1630 { 1631 return kDerivative1; // derivative is 1 because of coverage. (+1) for differentiate clear value 1632 } 1633 else 1634 { 1635 return kDerivative0; // 0, fill all or fill none for quad. (+1) for differentiate clear value 1636 } 1637 } 1638 else 1639 { 1640 const deUint32 expectedValue = totalLayerCount + renderTargetID + fs; 1641 return expectedValue; 1642 } 1643} 1644 1645tcu::TestStatus ShaderTileImageTestInstance::checkResult() const 1646{ 1647 const VkDevice device = m_context.getDevice(); 1648 1649 qpTestResult res = QP_TEST_RESULT_PASS; 1650 const deUint32 sampleCount = getSampleCount(m_testParam->m_sampleCount); 1651 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam->testType); 1652 const deUint32 vertexCountPerPatch = getVertexCountPerPatch(m_testParam); 1653 // Loop over all samples in the same fragment 1654 1655 for (deUint32 rt = 0; (res == QP_TEST_RESULT_PASS) && rt < attachmentCount; rt++) 1656 { 1657 // Result of Helper Class test valid only for the rt 1 1658 invalidateAlloc(m_vk, device, m_imageBuffer[rt]->getBoundMemory()); 1659 1660 if (rt != 1 && isHelperClassTest(m_testParam->testType)) 1661 { 1662 continue; 1663 } 1664 1665 for (deUint32 fy = 0; (res == QP_TEST_RESULT_PASS) && fy < m_testParam->frameBufferSize; ++fy) 1666 { 1667 for (deUint32 fx = 0; (res == QP_TEST_RESULT_PASS) && fx < m_testParam->frameBufferSize; ++fx) 1668 { 1669 for (deUint32 fs = 0; (res == QP_TEST_RESULT_PASS) && fs < sampleCount; ++fs) 1670 { 1671 const deUint32 expectedValue = simulate(fx, fy, fs, rt); 1672 const deUint32 resultValue = getResultValue(fx, fy, fs, rt); 1673 1674 if (isHelperClassTest(m_testParam->testType)) 1675 { 1676 // ________ ________ ________ 1677 // 1|1|1|0| 0|0|*|1| 1|1|#|2| 1678 // 1|1|0|0| 0|0|1|*| 1|1|2|#| 1679 // 1|0|0|0| => *|1|0|0| => #|2|1|1| 1680 // 0|0|0|0| 1|*|0|0| 2|#|1|1| 1681 // ________ ________ ________ 1682 // raster max(dx,dy) result(+1) 1683 // *(#): max(dx, dy) could be 0(1) or 1(2). 1684 if (expectedValue != resultValue) 1685 { 1686 if (std::abs(static_cast<deInt32>(fx - fy)) != 1 || resultValue != kDerivative1) 1687 { 1688 res = QP_TEST_RESULT_FAIL; 1689 break; 1690 } 1691 } 1692 } 1693 else if (vertexCountPerPatch == 6) // Fill full quad to the framebuffer 1694 { 1695 if (expectedValue != resultValue) 1696 { 1697 res = QP_TEST_RESULT_FAIL; 1698 break; 1699 } 1700 } 1701 else // Fill a triangle to the framebuffer, check half of framebuffer 1702 { 1703 if (fy > fx) // inside of triangle 1704 { 1705 if (expectedValue != resultValue) // not expected value 1706 { 1707 res = QP_TEST_RESULT_FAIL; 1708 break; 1709 } 1710 } 1711 else // outside of filling triangle or triangle edge 1712 { 1713 if (resultValue != 0 && resultValue != expectedValue) // can be not filling 1714 { 1715 res = QP_TEST_RESULT_FAIL; 1716 break; 1717 } 1718 } 1719 } 1720 } 1721 } 1722 } 1723 } 1724 1725 return tcu::TestStatus(res, qpGetTestResultName(res)); 1726} 1727 1728void ShaderTileImageTestInstance::rendering() 1729{ 1730 const VkDevice device = m_context.getDevice(); 1731 const VkQueue queue = m_context.getUniversalQueue(); 1732 1733 beginCommandBuffer(m_vk, *m_cmdBuffer); 1734 1735 // begin render pass 1736 const VkClearValue clearValue = {}; // { 0, 0, 0, 0 } 1737 const VkClearValue dsClearValue = {}; // .depth = 0.0f, .stencil = 0 1738 const VkRect2D renderArea = { { 0, 0 }, { m_testParam->frameBufferSize, m_testParam->frameBufferSize } }; 1739 1740 const deUint32 colorAttachmentCount = getColorAttachmentCount(m_testParam->testType); 1741 1742 std::vector<VkRenderingAttachmentInfoKHR> colorAttachments; 1743 for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++) 1744 { 1745 const VkRenderingAttachmentInfoKHR renderingAtachInfo = { 1746 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; 1747 DE_NULL, // const void* pNext; 1748 *m_imageColorView[colorIndex], // VkImageView imageView; 1749 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout; 1750 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; 1751 DE_NULL, // VkImageView resolveImageView; 1752 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; 1753 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1754 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1755 clearValue, // VkClearValue clearValue; 1756 }; 1757 1758 colorAttachments.push_back(renderingAtachInfo); 1759 } 1760 1761 const tcu::TextureFormat depthStencilFormat = mapVkFormat(m_testParam->depthStencilFormat); 1762 const bool hasDepth = tcu::hasDepthComponent(depthStencilFormat.order); 1763 const bool hasStencil = tcu::hasStencilComponent(depthStencilFormat.order); 1764 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_UNDEFINED; 1765 VkImageAspectFlags depthStencilAspect = 0; 1766 if (hasDepth && hasStencil) 1767 { 1768 depthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1769 depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 1770 } 1771 else if (hasDepth) 1772 { 1773 depthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; 1774 depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT; 1775 } 1776 else if (hasStencil) 1777 { 1778 depthStencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL; 1779 depthStencilAspect = VK_IMAGE_ASPECT_STENCIL_BIT; 1780 } 1781 1782 const VkRenderingAttachmentInfoKHR depthStencilAttachment = { 1783 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; 1784 DE_NULL, // const void* pNext; 1785 *m_imageDepthStencilView, // VkImageView imageView; 1786 depthStencilLayout, // VkImageLayout imageLayout; 1787 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; 1788 DE_NULL, // VkImageView resolveImageView; 1789 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; 1790 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1791 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1792 dsClearValue, // VkClearValue clearValue; 1793 }; 1794 1795 const VkRenderingInfoKHR renderingInfo = { 1796 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, // VkStructureType sType; 1797 DE_NULL, // const void* pNext; 1798 0, // VkRenderingFlagsKHR flags; 1799 renderArea, // VkRect2D renderArea; 1800 1u, // deUint32 layerCount; 1801 0u, // deUint32 viewMask; 1802 static_cast<deUint32>(colorAttachments.size()), // deUint32 colorAttachmentCount; 1803 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments; 1804 hasDepth ? &depthStencilAttachment : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment; 1805 hasStencil ? &depthStencilAttachment : DE_NULL // const VkRenderingAttachmentInfoKHR* pStencilAttachment; 1806 }; 1807 1808 for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++) 1809 { 1810 transition2DImage(m_vk, *m_cmdBuffer, *m_imageColor[colorIndex], VK_IMAGE_ASPECT_COLOR_BIT, 1811 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, 1812 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 1813 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); 1814 } 1815 1816 transition2DImage(m_vk, *m_cmdBuffer, *m_imageDepthStencil, depthStencilAspect, VK_IMAGE_LAYOUT_UNDEFINED, 1817 depthStencilLayout, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 1818 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 1819 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); 1820 1821 m_vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo); 1822 1823 // vertex input setup 1824 const VkBuffer vertexBuffer = m_vertexBuffer->object(); 1825 1826 for (deUint32 drawIndex = 0; drawIndex < getDrawCallCount(m_testParam); drawIndex++) 1827 { 1828 // pipeline setup 1829 if (drawIndex == 1 && isHelperClassTest(m_testParam->testType)) 1830 { 1831 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineForHelperClass); 1832 } 1833 else 1834 { 1835 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline); 1836 } 1837 1838 const deUint32 vertexCountPerPatch = getVertexCountPerPatch(m_testParam); 1839 const deUint32 vertexCount = vertexCountPerPatch * getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw); 1840 m_vk.cmdPushConstants(*m_cmdBuffer, *m_graphicsPipelineLayout, 1841 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), 0, sizeof(deUint32), 1842 &drawIndex); 1843 1844 const VkDeviceSize vertexBufferOffset = (vertexCount * drawIndex) * sizeof(tcu::Vec2); 1845 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 1846 1847 if (!m_testParam->coherent) 1848 { 1849 VkMemoryBarrier2KHR memoryBarrierForColor = { 1850 VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR, // sType 1851 DE_NULL, // pNext 1852 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,// srcStageMask 1853 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // srcAccessMask 1854 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,// dstStageMask 1855 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR // dstAccessMask 1856 }; 1857 1858 VkMemoryBarrier2KHR memoryBarrierForDepthStencil = { 1859 VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR, // sType 1860 DE_NULL, // pNext 1861 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | 1862 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, // srcStageMask 1863 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR, // srcAccessMask 1864 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | 1865 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT , // dstStageMask 1866 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR // dstAccessMask 1867 }; 1868 1869 VkMemoryBarrier2KHR* memoryBarrier = 1870 (m_testParam->testType == TestType::Depth) || (m_testParam->testType == TestType::Stencil) ? 1871 &memoryBarrierForDepthStencil : 1872 &memoryBarrierForColor; 1873 1874 VkDependencyInfoKHR dependencyInfo{ 1875 VK_STRUCTURE_TYPE_DEPENDENCY_INFO, // sType 1876 DE_NULL, // pNext 1877 VK_DEPENDENCY_BY_REGION_BIT, //dependency flags 1878 1, //memory barrier count 1879 memoryBarrier, //memory barrier 1880 0, // bufferMemoryBarrierCount 1881 DE_NULL, // pBufferMemoryBarriers 1882 0, // imageMemoryBarrierCount 1883 DE_NULL, // pImageMemoryBarriers 1884 }; 1885 m_vk.cmdPipelineBarrier2(*m_cmdBuffer, &dependencyInfo); 1886 } 1887 1888 m_vk.cmdDraw(*m_cmdBuffer, vertexCount, 1, 0, 0u); 1889 } 1890 m_vk.cmdEndRendering(*m_cmdBuffer); 1891 1892 for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++) 1893 { 1894 1895 transition2DImage(m_vk, *m_cmdBuffer, *m_imageColor[colorIndex], VK_IMAGE_ASPECT_COLOR_BIT, 1896 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1897 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, 1898 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 1899 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); 1900 } 1901 1902 VkMemoryBarrier memBarrier = { 1903 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType 1904 DE_NULL, // pNext 1905 0u, // srcAccessMask 1906 0u, // dstAccessMask 1907 }; 1908 memBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 1909 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; 1910 m_vk.cmdPipelineBarrier(*m_cmdBuffer, 1911 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 1912 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL); 1913 1914 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline); 1915 1916 // Copy color images to buffer memory 1917 for (deUint32 attachmentIndex = 0; attachmentIndex < colorAttachmentCount; attachmentIndex++) 1918 { 1919 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelineLayout, 0u, 1, 1920 &*m_descriptorSets[attachmentIndex], 0u, DE_NULL); 1921 1922 m_vk.cmdDispatch(*m_cmdBuffer, m_testParam->frameBufferSize, m_testParam->frameBufferSize, 1); 1923 } 1924 memBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; 1925 memBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; 1926 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 1, 1927 &memBarrier, 0, DE_NULL, 0, DE_NULL); 1928 1929 VK_CHECK(m_vk.endCommandBuffer(*m_cmdBuffer)); 1930 1931 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get()); 1932} 1933 1934std::string formatToName(VkFormat format) 1935{ 1936 const std::string formatStr = de::toString(format); 1937 const std::string prefix = "VK_FORMAT_"; 1938 1939 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix); 1940 1941 return de::toLower(formatStr.substr(prefix.length())); 1942} 1943 1944void createShaderTileImageTestVariations(tcu::TestContext& testCtx, tcu::TestCaseGroup* gr) 1945{ 1946 struct TestTypeParam 1947 { 1948 TestType value; 1949 const char* name; 1950 }; 1951 1952 struct BoolParam 1953 { 1954 bool value; 1955 const char* name; 1956 }; 1957 1958 struct VkSampleCountFlagParam 1959 { 1960 VkSampleCountFlagBits value; 1961 const char* name; 1962 }; 1963 1964 const std::vector<BoolParam> coherentParams = { { true, "coherent" }, { false, "non_coherent" } }; 1965 1966 const std::vector<TestTypeParam> testTypeParams = { 1967 { TestType::Color, "color" }, 1968 { TestType::MultiRenderTarget, "mrt" }, 1969 { TestType::MultiRenderTargetDynamicIndex, "mrt_dynamic_index" }, 1970 { TestType::MsaaSampleMask, "msaa_sample_mask" }, 1971 { TestType::HelperClassColor, "helper_class_color" }, 1972 { TestType::HelperClassDepth, "helper_class_depth" }, 1973 { TestType::HelperClassStencil, "helper_class_stencil" }, 1974 { TestType::Depth, "depth" }, 1975 { TestType::Stencil, "stencil" }, 1976 }; 1977 1978 const std::vector<VkSampleCountFlagParam> sampleCountParams = { 1979 { VK_SAMPLE_COUNT_1_BIT, "samples_1" }, { VK_SAMPLE_COUNT_2_BIT, "samples_2" }, 1980 { VK_SAMPLE_COUNT_4_BIT, "samples_4" }, { VK_SAMPLE_COUNT_8_BIT, "samples_8" }, 1981 { VK_SAMPLE_COUNT_16_BIT, "samples_16" }, { VK_SAMPLE_COUNT_32_BIT, "samples_32" }, 1982 }; 1983 1984 const std::vector<BoolParam> multiDrawsParams = { { false, "single_draw" }, { true, "multi_draws" } }; 1985 1986 const std::vector<BoolParam> multiPatchParams = { { false, "single_patch" }, { true, "multi_patches" } }; 1987 1988 const std::vector<VkFormat> formats = { VK_FORMAT_R5G6B5_UNORM_PACK16, 1989 VK_FORMAT_R8G8_UNORM, 1990 VK_FORMAT_R8G8_SNORM, 1991 VK_FORMAT_R8G8_UINT, 1992 VK_FORMAT_R8G8_SINT, 1993 VK_FORMAT_R8G8B8A8_UNORM, 1994 VK_FORMAT_R8G8B8A8_SNORM, 1995 VK_FORMAT_R8G8B8A8_UINT, 1996 VK_FORMAT_R8G8B8A8_SINT, 1997 VK_FORMAT_R8G8B8A8_SRGB, 1998 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 1999 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 2000 VK_FORMAT_A8B8G8R8_UINT_PACK32, 2001 VK_FORMAT_A8B8G8R8_SINT_PACK32, 2002 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 2003 VK_FORMAT_B8G8R8A8_UNORM, 2004 VK_FORMAT_B8G8R8A8_SRGB, 2005 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 2006 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 2007 VK_FORMAT_A2B10G10R10_UINT_PACK32, 2008 VK_FORMAT_R16G16_UNORM, 2009 VK_FORMAT_R16G16_SNORM, 2010 VK_FORMAT_R16G16_UINT, 2011 VK_FORMAT_R16G16_SINT, 2012 VK_FORMAT_R16G16_SFLOAT, 2013 VK_FORMAT_R16G16B16A16_UNORM, 2014 VK_FORMAT_R16G16B16A16_SNORM, 2015 VK_FORMAT_R16G16B16A16_UINT, 2016 VK_FORMAT_R16G16B16A16_SINT, 2017 VK_FORMAT_R16G16B16A16_SFLOAT, 2018 VK_FORMAT_R32G32_UINT, 2019 VK_FORMAT_R32G32_SINT, 2020 VK_FORMAT_R32G32_SFLOAT, 2021 VK_FORMAT_R32G32B32A32_UINT, 2022 VK_FORMAT_R32G32B32A32_SINT, 2023 VK_FORMAT_R32G32B32A32_SFLOAT, 2024 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, 2025 2026 VK_FORMAT_D16_UNORM, 2027 VK_FORMAT_X8_D24_UNORM_PACK32, 2028 VK_FORMAT_D32_SFLOAT, 2029 VK_FORMAT_S8_UINT, 2030 VK_FORMAT_D16_UNORM_S8_UINT, 2031 VK_FORMAT_D24_UNORM_S8_UINT, 2032 VK_FORMAT_D32_SFLOAT_S8_UINT }; 2033 2034 tcu::TestCaseGroup* subGroup = nullptr; 2035 std::vector<tcu::TestCaseGroup*> testGroupStack; 2036 testGroupStack.push_back(gr); 2037 2038 for (const BoolParam& coherentParam : coherentParams) 2039 { 2040 subGroup = (new tcu::TestCaseGroup(testCtx, coherentParam.name)); 2041 testGroupStack.back()->addChild(subGroup); 2042 testGroupStack.push_back(subGroup); 2043 for (const TestTypeParam& testTypeParam : testTypeParams) 2044 { 2045 subGroup = new tcu::TestCaseGroup(testCtx, testTypeParam.name); 2046 testGroupStack.back()->addChild(subGroup); 2047 testGroupStack.push_back(subGroup); 2048 2049 for (const VkSampleCountFlagParam& sampleCountParam : sampleCountParams) 2050 { 2051 if (testTypeParam.value == TestType::MsaaSampleMask && sampleCountParam.value == VK_SAMPLE_COUNT_1_BIT) 2052 { 2053 // SampleMask test requires MSAA 2054 continue; 2055 } 2056 if (isHelperClassTest(testTypeParam.value) && sampleCountParam.value != VK_SAMPLE_COUNT_1_BIT) 2057 { 2058 // HelperClass test designed for non msaa case 2059 continue; 2060 } 2061 subGroup = new tcu::TestCaseGroup(testCtx, sampleCountParam.name); 2062 testGroupStack.back()->addChild(subGroup); 2063 testGroupStack.push_back(subGroup); 2064 2065 for (const BoolParam& multiDrawsParam : multiDrawsParams) 2066 { 2067 if (isHelperClassTest(testTypeParam.value) && multiDrawsParam.value) 2068 { 2069 // helper class 2 draws but works like single draw call 2070 continue; 2071 } 2072 2073 subGroup = new tcu::TestCaseGroup(testCtx, multiDrawsParam.name); 2074 testGroupStack.back()->addChild(subGroup); 2075 testGroupStack.push_back(subGroup); 2076 2077 for (const BoolParam& multiPatchParam : multiPatchParams) 2078 { 2079 if (!coherentParam.value && multiPatchParam.value) // cannot guarantee 2080 { 2081 continue; 2082 } 2083 if (isHelperClassTest(testTypeParam.value) && multiPatchParam.value) 2084 { 2085 // helper class works on single patch cases 2086 continue; 2087 } 2088 2089 subGroup = new tcu::TestCaseGroup(testCtx, multiPatchParam.name); 2090 testGroupStack.back()->addChild(subGroup); 2091 testGroupStack.push_back(subGroup); 2092 2093 for (VkFormat format : formats) 2094 { 2095 tcu::TestCaseGroup* curGroup = testGroupStack.back(); 2096 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(format).order); 2097 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(format).order); 2098 std::string name = formatToName(format); 2099 2100 TestParam testParam = {}; 2101 testParam.coherent = coherentParam.value; 2102 testParam.testType = testTypeParam.value; 2103 testParam.colorFormat = VK_FORMAT_R32G32B32A32_UINT; 2104 testParam.depthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT; 2105 testParam.m_sampleCount = sampleCountParam.value; 2106 testParam.multipleDrawCalls = multiDrawsParam.value; 2107 testParam.multiplePatchesPerDraw = multiPatchParam.value; 2108 testParam.frameBufferSize = kImageSize; 2109 if (testTypeParam.value == TestType::Depth || 2110 testTypeParam.value == TestType::HelperClassDepth) 2111 { 2112 if (hasDepth) 2113 { 2114 testParam.depthStencilFormat = format; 2115 curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam)); 2116 } 2117 } 2118 else if (testTypeParam.value == TestType::Stencil || 2119 testTypeParam.value == TestType::HelperClassStencil) 2120 { 2121 if (hasStencil) 2122 { 2123 testParam.depthStencilFormat = format; 2124 curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam)); 2125 } 2126 } 2127 else 2128 { 2129 if (!hasStencil && !hasDepth) 2130 { 2131 if (isHelperClassTest(testTypeParam.value) && isNormalizedColorFormat(format)) 2132 { 2133 // reduce helper class test cases and complexities 2134 continue; 2135 } 2136 2137 const deUint32 maxResultValue = 2138 (getDrawCallCount(&testParam) * 2139 getPatchesPerDrawCount(testParam.multiplePatchesPerDraw) * 2140 getColorAttachmentCount(testParam.testType) + 2141 getSampleCount(testParam.m_sampleCount)); 2142 const tcu::IVec4 channelBitDepth = 2143 tcu::getTextureFormatBitDepth(mapVkFormat(format)); 2144 2145 // color output precision is less than test case. 2146 // ban the overflow problem. 2147 if (static_cast<deUint32>(1 << (channelBitDepth.y() - 1)) > maxResultValue) 2148 { 2149 testParam.colorFormat = format; 2150 curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam)); 2151 } 2152 } 2153 } 2154 } // formats 2155 testGroupStack.pop_back(); 2156 } // multiPatchParams 2157 testGroupStack.pop_back(); 2158 } // multiDrawsParams 2159 testGroupStack.pop_back(); 2160 } // sampleCountParams 2161 testGroupStack.pop_back(); 2162 } // testTypeParams 2163 testGroupStack.pop_back(); 2164 } // coherentParams 2165} 2166} // namespace 2167// anonymous namespace 2168 2169tcu::TestCaseGroup* createShaderTileImageTests(tcu::TestContext& testCtx) 2170{ 2171 /* Add the color tests */ 2172 tcu::TestCaseGroup* gr = new tcu::TestCaseGroup(testCtx, "shader_tile_image"); 2173 createShaderTileImageTestVariations(testCtx, gr); 2174 2175 return gr; 2176} 2177 2178} // namespace rasterization 2179} // namespace vkt 2180