1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * Copyright (c) 2014 The Android Open Source Project 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 Geometry shader layered rendering tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktGeometryLayeredRenderingTests.hpp" 26 #include "vktTestCase.hpp" 27 #include "vktTestCaseUtil.hpp" 28 #include "vktGeometryTestsUtil.hpp" 29 30 #include "vkPrograms.hpp" 31 #include "vkStrUtil.hpp" 32 #include "vkQueryUtil.hpp" 33 #include "vkMemUtil.hpp" 34 #include "vkRefUtil.hpp" 35 #include "vkBarrierUtil.hpp" 36 #include "vkTypeUtil.hpp" 37 #include "vkImageUtil.hpp" 38 #include "vkBuilderUtil.hpp" 39 #include "vkCmdUtil.hpp" 40 #include "vkObjUtil.hpp" 41 42 #include "deStringUtil.hpp" 43 #include "deUniquePtr.hpp" 44 45 #include "tcuTextureUtil.hpp" 46 #include "tcuVectorUtil.hpp" 47 #include "tcuTestLog.hpp" 48 49 namespace vkt 50 { 51 namespace geometry 52 { 53 namespace 54 { 55 using namespace vk; 56 using de::MovePtr; 57 using de::UniquePtr; 58 using tcu::Vec4; 59 using tcu::IVec3; 60 61 enum TestType 62 { 63 TEST_TYPE_DEFAULT_LAYER, // !< draw to default layer 64 TEST_TYPE_SINGLE_LAYER, // !< draw to single layer 65 TEST_TYPE_ALL_LAYERS, // !< draw all layers 66 TEST_TYPE_DIFFERENT_CONTENT, // !< draw different content to different layers 67 TEST_TYPE_LAYER_ID, // !< draw to all layers, verify gl_Layer fragment input 68 TEST_TYPE_INVOCATION_PER_LAYER, // !< draw to all layers, one invocation per layer 69 TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, // !< draw to all layers, multiple invocations write to multiple layers 70 TEST_TYPE_LAYERED_READBACK, // !< draw to two layers multiple times 71 }; 72 73 struct ImageParams 74 { 75 VkImageViewType viewType; 76 VkExtent3D size; 77 deUint32 numLayers; 78 }; 79 80 struct TestParams 81 { 82 TestType testType; 83 ImageParams image; 84 }; 85 86 static const float s_colors[][4] = 87 { 88 { 1.0f, 1.0f, 1.0f, 1.0f }, // white 89 { 1.0f, 0.0f, 0.0f, 1.0f }, // red 90 { 0.0f, 1.0f, 0.0f, 1.0f }, // green 91 { 0.0f, 0.0f, 1.0f, 1.0f }, // blue 92 { 1.0f, 1.0f, 0.0f, 1.0f }, // yellow 93 { 1.0f, 0.0f, 1.0f, 1.0f }, // magenta 94 }; 95 96 tcu::Vec4 scaleColor(const tcu::Vec4& color, float factor) 97 { 98 return tcu::Vec4(color[0] * factor, 99 color[1] * factor, 100 color[2] * factor, 101 color[3]); 102 } 103 104 deUint32 getTargetLayer (const ImageParams& imageParams) 105 { 106 if (imageParams.viewType == VK_IMAGE_VIEW_TYPE_3D) 107 return imageParams.size.depth / 2; 108 else 109 return imageParams.numLayers / 2; 110 } 111 112 std::string getShortImageViewTypeName (const VkImageViewType imageViewType) 113 { 114 std::string s(getImageViewTypeName(imageViewType)); 115 return de::toLower(s.substr(19)); 116 } 117 118 VkImageType getImageType (const VkImageViewType viewType) 119 { 120 switch (viewType) 121 { 122 case VK_IMAGE_VIEW_TYPE_1D: 123 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 124 return VK_IMAGE_TYPE_1D; 125 126 case VK_IMAGE_VIEW_TYPE_2D: 127 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 128 case VK_IMAGE_VIEW_TYPE_CUBE: 129 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 130 return VK_IMAGE_TYPE_2D; 131 132 case VK_IMAGE_VIEW_TYPE_3D: 133 return VK_IMAGE_TYPE_3D; 134 135 default: 136 DE_ASSERT(0); 137 return VK_IMAGE_TYPE_LAST; 138 } 139 } 140 141 VkFormat getStencilBufferFormat(VkFormat depthStencilImageFormat) 142 { 143 const tcu::TextureFormat tcuFormat = mapVkFormat(depthStencilImageFormat); 144 const VkFormat result = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS) ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED; 145 146 DE_ASSERT(result != VK_FORMAT_UNDEFINED); 147 148 return result; 149 } 150 151 inline bool isCubeImageViewType (const VkImageViewType viewType) 152 { 153 return viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 154 } 155 156 void checkImageFormatProperties (const InstanceInterface& vki, 157 const VkPhysicalDevice& physDevice, 158 const VkImageType& imageType, 159 const VkImageTiling& imageTiling, 160 const VkImageUsageFlags imageUsageFlags, 161 const VkImageCreateFlags imageCreateFlags, 162 const VkFormat format, 163 const VkExtent3D& requiredSize, 164 const deUint32 requiredLayers) 165 { 166 VkImageFormatProperties imageFormatProperties; 167 VkResult result; 168 169 deMemset(&imageFormatProperties, 0, sizeof(imageFormatProperties)); 170 171 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties); 172 173 if (result != VK_SUCCESS || 174 imageFormatProperties.maxArrayLayers < requiredLayers || 175 imageFormatProperties.maxExtent.height < requiredSize.height || 176 imageFormatProperties.maxExtent.width < requiredSize.width || 177 imageFormatProperties.maxExtent.depth < requiredSize.depth) 178 { 179 TCU_THROW(NotSupportedError, "Depth/stencil format is not supported"); 180 } 181 } 182 183 VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const VkImageUsageFlags usage) 184 { 185 const VkImageCreateInfo imageParams = 186 { 187 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 188 DE_NULL, // const void* pNext; 189 flags, // VkImageCreateFlags flags; 190 type, // VkImageType imageType; 191 format, // VkFormat format; 192 size, // VkExtent3D extent; 193 1u, // deUint32 mipLevels; 194 numLayers, // deUint32 arrayLayers; 195 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 196 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 197 usage, // VkImageUsageFlags usage; 198 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 199 0u, // deUint32 queueFamilyIndexCount; 200 DE_NULL, // const deUint32* pQueueFamilyIndices; 201 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 202 }; 203 return imageParams; 204 } 205 206 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, 207 const VkDevice device, 208 const VkFormat colorFormat, 209 const VkFormat dsFormat, 210 const bool useDepthStencil) 211 { 212 return vk::makeRenderPass(vk, device, colorFormat, useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD); 213 } 214 215 216 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk, 217 const VkDevice device, 218 const VkPipelineLayout pipelineLayout, 219 const VkRenderPass renderPass, 220 const VkShaderModule vertexModule, 221 const VkShaderModule geometryModule, 222 const VkShaderModule fragmentModule, 223 const VkExtent2D renderSize, 224 const bool useDepthStencil = false) 225 { 226 const std::vector<VkViewport> viewports (1, makeViewport(renderSize)); 227 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize)); 228 229 const VkStencilOpState stencilOpState = makeStencilOpState( 230 VK_STENCIL_OP_KEEP, // stencil fail 231 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // depth & stencil pass 232 VK_STENCIL_OP_KEEP, // depth only fail 233 VK_COMPARE_OP_ALWAYS, // compare op 234 ~0u, // compare mask 235 ~0u, // write mask 236 0u); // reference 237 238 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 239 { 240 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 241 DE_NULL, // const void* pNext; 242 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 243 useDepthStencil ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable; 244 useDepthStencil ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable; 245 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 246 VK_FALSE, // VkBool32 depthBoundsTestEnable; 247 useDepthStencil ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable; 248 stencilOpState, // VkStencilOpState front; 249 stencilOpState, // VkStencilOpState back; 250 0.0f, // float minDepthBounds; 251 1.0f // float maxDepthBounds; 252 }; 253 254 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk 255 device, // const VkDevice device 256 pipelineLayout, // const VkPipelineLayout pipelineLayout 257 vertexModule, // const VkShaderModule vertexShaderModule 258 DE_NULL, // const VkShaderModule tessellationControlModule 259 DE_NULL, // const VkShaderModule tessellationEvalModule 260 geometryModule, // const VkShaderModule geometryShaderModule 261 fragmentModule, // const VkShaderModule fragmentShaderModule 262 renderPass, // const VkRenderPass renderPass 263 viewports, // const std::vector<VkViewport>& viewports 264 scissors, // const std::vector<VkRect2D>& scissors 265 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology topology 266 0u, // const deUint32 subpass 267 0u, // const deUint32 patchControlPoints 268 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo 269 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo 270 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo 271 &pipelineDepthStencilStateInfo); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo 272 } 273 274 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 275 const VkDevice device, 276 const VkRenderPass renderPass, 277 const VkImageView* pAttachments, 278 const deUint32 attachmentsCount, 279 const deUint32 width, 280 const deUint32 height, 281 const deUint32 layers) 282 { 283 const VkFramebufferCreateInfo framebufferInfo = { 284 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 285 DE_NULL, // const void* pNext; 286 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 287 renderPass, // VkRenderPass renderPass; 288 attachmentsCount, // uint32_t attachmentCount; 289 pAttachments, // const VkImageView* pAttachments; 290 width, // uint32_t width; 291 height, // uint32_t height; 292 layers, // uint32_t layers; 293 }; 294 295 return createFramebuffer(vk, device, &framebufferInfo); 296 } 297 298 //! Convenience wrapper to access 1D, 2D, and 3D image layers/slices in a uniform way. 299 class LayeredImageAccess 300 { 301 public: 302 static LayeredImageAccess create (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData) 303 { 304 if (type == VK_IMAGE_TYPE_1D) 305 return LayeredImageAccess(format, size.width, numLayers, pData); 306 else 307 return LayeredImageAccess(type, format, size, numLayers, pData); 308 } 309 310 inline tcu::ConstPixelBufferAccess getLayer (const int layer) const 311 { 312 return tcu::getSubregion(m_wholeImage, 0, (m_1dModifier * layer), ((~m_1dModifier & 1) * layer), m_width, m_height, 1); 313 } 314 315 inline int getNumLayersOrSlices (void) const 316 { 317 return m_layers; 318 } 319 320 private: 321 // Specialized for 1D images. 322 LayeredImageAccess (const VkFormat format, const deUint32 width, const deUint32 numLayers, const void* pData) 323 : m_width (static_cast<int>(width)) 324 , m_height (1) 325 , m_1dModifier (1) 326 , m_layers (numLayers) 327 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_layers, 1, pData)) 328 { 329 } 330 331 LayeredImageAccess (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData) 332 : m_width (static_cast<int>(size.width)) 333 , m_height (static_cast<int>(size.height)) 334 , m_1dModifier (0) 335 , m_layers (static_cast<int>(type == VK_IMAGE_TYPE_3D ? size.depth : numLayers)) 336 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_height, m_layers, pData)) 337 { 338 } 339 340 const int m_width; 341 const int m_height; 342 const int m_1dModifier; 343 const int m_layers; 344 const tcu::ConstPixelBufferAccess m_wholeImage; 345 }; 346 347 inline bool compareColors (const Vec4& colorA, const Vec4& colorB, const Vec4& threshold) 348 { 349 return tcu::allEqual( 350 tcu::lessThan(tcu::abs(colorA - colorB), threshold), 351 tcu::BVec4(true, true, true, true)); 352 } 353 354 bool verifyImageSingleColoredRow (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image, const float rowWidthRatio, const tcu::Vec4& barColor) 355 { 356 DE_ASSERT(rowWidthRatio > 0.0f); 357 358 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f); 359 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f); 360 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); 361 const Vec4 threshold (0.02f); 362 const int barLength = static_cast<int>(rowWidthRatio * static_cast<float>(image.getWidth())); 363 const int barLengthThreshold = 1; 364 tcu::TextureLevel errorMask (image.getFormat(), image.getWidth(), image.getHeight()); 365 tcu::PixelBufferAccess errorMaskAccess = errorMask.getAccess(); 366 367 tcu::clear(errorMask.getAccess(), green); 368 369 log << tcu::TestLog::Message 370 << "Expecting all pixels with distance less or equal to (about) " << barLength 371 << " pixels from left border to be of color " << barColor.swizzle(0, 1, 2) << "." 372 << tcu::TestLog::EndMessage; 373 374 bool allPixelsOk = true; 375 376 for (int y = 0; y < image.getHeight(); ++y) 377 for (int x = 0; x < image.getWidth(); ++x) 378 { 379 const Vec4 color = image.getPixel(x, y); 380 const bool isBlack = compareColors(color, black, threshold); 381 const bool isColor = compareColors(color, barColor, threshold); 382 383 bool isOk; 384 385 if (x <= barLength - barLengthThreshold) 386 isOk = isColor; 387 else if (x >= barLength + barLengthThreshold) 388 isOk = isBlack; 389 else 390 isOk = isColor || isBlack; 391 392 allPixelsOk &= isOk; 393 394 if (!isOk) 395 errorMaskAccess.setPixel(red, x, y); 396 } 397 398 if (allPixelsOk) 399 { 400 log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage 401 << tcu::TestLog::ImageSet("LayerContent", "Layer content") 402 << tcu::TestLog::Image("Layer", "Layer", image) 403 << tcu::TestLog::EndImageSet; 404 return true; 405 } 406 else 407 { 408 log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage 409 << tcu::TestLog::ImageSet("LayerContent", "Layer content") 410 << tcu::TestLog::Image("Layer", "Layer", image) 411 << tcu::TestLog::Image("ErrorMask", "Errors", errorMask) 412 << tcu::TestLog::EndImageSet; 413 return false; 414 } 415 416 log << tcu::TestLog::Image("LayerContent", "Layer content", image); 417 418 return allPixelsOk; 419 } 420 421 static bool verifyImageMultipleBars (tcu::TestLog& log, 422 const tcu::ConstPixelBufferAccess image, 423 const float* barWidthRatios, 424 const tcu::Vec4* barValues, 425 const int barsCount, 426 const int numUsedChannels, 427 const std::string& imageTypeName) 428 { 429 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f); 430 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); 431 const Vec4 threshold (0.02f); 432 const tcu::TextureFormat errorMaskFormat (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)); 433 tcu::TextureLevel errorMask (errorMaskFormat, image.getWidth(), image.getHeight()); 434 tcu::PixelBufferAccess errorMaskAccess = errorMask.getAccess(); 435 bool allPixelsOk = true; 436 437 DE_ASSERT(barsCount > 0); 438 439 tcu::clear(errorMask.getAccess(), green); 440 441 // Format information message 442 { 443 int leftBorder = 0; 444 int rightBorder = 0; 445 std::ostringstream str; 446 447 for (int barNdx = 0; barNdx < barsCount; ++barNdx) 448 { 449 leftBorder = rightBorder; 450 rightBorder = static_cast<int>(barWidthRatios[barNdx] * static_cast<float>(image.getWidth())); 451 452 DE_ASSERT(leftBorder < rightBorder); 453 454 str << std::endl << " [" << leftBorder << "," <<rightBorder << "): "; 455 456 switch (numUsedChannels) 457 { 458 case 1: str << barValues[barNdx][0]; break; 459 case 4: str << barValues[barNdx]; break; 460 default: DE_ASSERT(false); break; 461 } 462 } 463 464 log << tcu::TestLog::Message 465 << "Expecting " + imageTypeName + " values depending x-axis position to be of following values: " 466 << str.str() 467 << tcu::TestLog::EndMessage; 468 } 469 470 for (int x = 0; x < image.getWidth(); ++x) 471 { 472 tcu::Vec4 expectedValue = barValues[0]; 473 474 for (int barNdx = 0; barNdx < barsCount; ++barNdx) 475 { 476 const int rightBorder = static_cast<int>(barWidthRatios[barNdx] * static_cast<float>(image.getWidth())); 477 478 if (x < rightBorder) 479 { 480 expectedValue = barValues[barNdx]; 481 482 break; 483 } 484 } 485 486 for (int y = 0; y < image.getHeight(); ++y) 487 { 488 const tcu::Vec4 realValue = image.getPixel(x, y); 489 bool isOk = false; 490 491 switch (numUsedChannels) 492 { 493 case 1: isOk = fabs(realValue[0] - expectedValue[0]) < threshold[0]; break; 494 case 4: isOk = compareColors(realValue, expectedValue, threshold); break; 495 default: DE_ASSERT(false); break; 496 } 497 498 if (!isOk) 499 errorMaskAccess.setPixel(red, x, y); 500 501 allPixelsOk = allPixelsOk && isOk; 502 } 503 } 504 505 if (allPixelsOk) 506 { 507 log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage 508 << tcu::TestLog::ImageSet(imageTypeName + "LayerContent", imageTypeName + " Layer Content") 509 << tcu::TestLog::Image("Layer", "Layer", image) 510 << tcu::TestLog::EndImageSet; 511 } 512 else 513 { 514 log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage 515 << tcu::TestLog::ImageSet(imageTypeName + "LayerContent", imageTypeName + " Layer Content") 516 << tcu::TestLog::Image("Layer", "Layer", image) 517 << tcu::TestLog::Image("ErrorMask", "Errors", errorMask) 518 << tcu::TestLog::EndImageSet; 519 } 520 521 return allPixelsOk; 522 } 523 524 static void convertDepthToColorBufferAccess (const tcu::ConstPixelBufferAccess& inputImage, tcu::PixelBufferAccess& outputImage) 525 { 526 for (int y = 0; y < inputImage.getHeight(); y++) 527 for (int x = 0; x < inputImage.getWidth(); x++) 528 { 529 const float depth = inputImage.getPixDepth(x, y); 530 const tcu::Vec4 color = tcu::Vec4(depth, depth, depth, 1.0f); 531 532 outputImage.setPixel(color, x, y); 533 } 534 } 535 536 static void convertStencilToColorBufferAccess (const tcu::ConstPixelBufferAccess& inputImage, tcu::PixelBufferAccess& outputImage, int maxValue) 537 { 538 for (int y = 0; y < inputImage.getHeight(); y++) 539 for (int x = 0; x < inputImage.getWidth(); x++) 540 { 541 const int stencilInt = inputImage.getPixStencil(x, y); 542 const float stencil = (stencilInt < maxValue) ? float(stencilInt) / float(maxValue) : 1.0f; 543 const tcu::Vec4 color = tcu::Vec4(stencil, stencil, stencil, 1.0f); 544 545 outputImage.setPixel(color, x, y); 546 } 547 } 548 549 bool verifyEmptyImage (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image) 550 { 551 log << tcu::TestLog::Message << "Expecting empty image" << tcu::TestLog::EndMessage; 552 553 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f); 554 const Vec4 threshold (0.02f); 555 556 for (int y = 0; y < image.getHeight(); ++y) 557 for (int x = 0; x < image.getWidth(); ++x) 558 { 559 const Vec4 color = image.getPixel(x, y); 560 561 if (!compareColors(color, black, threshold)) 562 { 563 log << tcu::TestLog::Message 564 << "Found (at least) one bad pixel at " << x << "," << y << ". Pixel color is not background color." 565 << tcu::TestLog::EndMessage 566 << tcu::TestLog::ImageSet("LayerContent", "Layer content") 567 << tcu::TestLog::Image("Layer", "Layer", image) 568 << tcu::TestLog::EndImageSet; 569 return false; 570 } 571 } 572 573 log << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage; 574 575 return true; 576 } 577 578 bool verifyLayerContent (tcu::TestLog& log, const TestType testType, const tcu::ConstPixelBufferAccess image, const int layerNdx, const int numLayers, const bool depthCheck, const bool stencilCheck) 579 { 580 const Vec4 white (1.0f, 1.0f, 1.0f, 1.0f); 581 const int targetLayer = numLayers / 2; 582 const float variableBarRatio = static_cast<float>(layerNdx) / static_cast<float>(numLayers); 583 584 switch (testType) 585 { 586 case TEST_TYPE_DEFAULT_LAYER: 587 if (layerNdx == 0) 588 return verifyImageSingleColoredRow(log, image, 0.5f, white); 589 else 590 return verifyEmptyImage(log, image); 591 592 case TEST_TYPE_SINGLE_LAYER: 593 if (layerNdx == targetLayer) 594 return verifyImageSingleColoredRow(log, image, 0.5f, white); 595 else 596 return verifyEmptyImage(log, image); 597 598 case TEST_TYPE_ALL_LAYERS: 599 case TEST_TYPE_INVOCATION_PER_LAYER: 600 return verifyImageSingleColoredRow(log, image, 0.5f, s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]); 601 602 case TEST_TYPE_DIFFERENT_CONTENT: 603 case TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION: 604 if (layerNdx == 0) 605 return verifyEmptyImage(log, image); 606 else 607 return verifyImageSingleColoredRow(log, image, variableBarRatio, white); 608 609 case TEST_TYPE_LAYER_ID: 610 { 611 // This code must be in sync with the fragment shader. 612 const tcu::Vec4 layerColor( (layerNdx % 2) == 1 ? 1.0f : 0.5f, 613 ((layerNdx/2) % 2) == 1 ? 1.0f : 0.5f, 614 layerNdx == 0 ? 1.0f : 0.0f, 615 1.0f); 616 return verifyImageSingleColoredRow(log, image, 0.5f, layerColor); 617 } 618 619 case TEST_TYPE_LAYERED_READBACK: 620 { 621 const float barWidthRatios[] = { 0.25f, 0.5f, 1.0f }; 622 const int barsCount = DE_LENGTH_OF_ARRAY(barWidthRatios); 623 bool result = false; 624 625 if (depthCheck) 626 { 627 const std::string checkType = "Depth"; 628 const float pass0depth = static_cast<float>(layerNdx + 1) / static_cast<float>(2 * numLayers); 629 const float pass1depth = static_cast<float>(layerNdx + 0) / static_cast<float>(2 * numLayers); 630 const tcu::Vec4 barDepths[barsCount] = { tcu::Vec4(pass1depth), tcu::Vec4(pass0depth), tcu::Vec4(1.0f) }; 631 tcu::TextureLevel depthAsColorBuffer (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), image.getWidth(), image.getHeight()); 632 tcu::PixelBufferAccess depthAsColor (depthAsColorBuffer); 633 const int numUsedChannels (tcu::getNumUsedChannels(depthAsColor.getFormat().order)); 634 635 convertDepthToColorBufferAccess(image, depthAsColor); 636 637 result = verifyImageMultipleBars(log, depthAsColor, barWidthRatios, barDepths, barsCount, numUsedChannels, checkType); 638 } 639 else if (stencilCheck) 640 { 641 const std::string checkType = "Stencil"; 642 const int maxStencilValue = 4; 643 const float pass0stencil = static_cast<float>(1.0f / maxStencilValue); 644 const float pass1stencil = static_cast<float>(2.0f / maxStencilValue); 645 const tcu::Vec4 barStencils[barsCount] = { tcu::Vec4(pass1stencil), tcu::Vec4(pass0stencil), tcu::Vec4(0.0f) }; 646 tcu::TextureLevel stencilAsColorBuffer (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), image.getWidth(), image.getHeight()); 647 tcu::PixelBufferAccess stencilAsColor (stencilAsColorBuffer); 648 const int numUsedChannels (tcu::getNumUsedChannels(stencilAsColor.getFormat().order)); 649 650 convertStencilToColorBufferAccess(image, stencilAsColor, maxStencilValue); 651 652 result = verifyImageMultipleBars(log, stencilAsColor, barWidthRatios, barStencils, barsCount, numUsedChannels, checkType); 653 } 654 else 655 { 656 const std::string checkType = "Color"; 657 const tcu::Vec4 baseColor (s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]); 658 const tcu::Vec4 barColors[barsCount] = { scaleColor(baseColor, 1.00f), scaleColor(baseColor, 0.50f), scaleColor(baseColor, 0.25f) }; 659 const int numUsedChannels (tcu::getNumUsedChannels(image.getFormat().order)); 660 661 result = verifyImageMultipleBars(log, image, barWidthRatios, barColors, barsCount, numUsedChannels, checkType); 662 } 663 664 return result; 665 } 666 667 default: 668 DE_ASSERT(0); 669 return false; 670 }; 671 } 672 673 std::string getLayerDescription (const VkImageViewType viewType, const int layer) 674 { 675 std::ostringstream str; 676 const int numCubeFaces = 6; 677 678 if (isCubeImageViewType(viewType)) 679 str << "cube " << (layer / numCubeFaces) << ", face " << (layer % numCubeFaces); 680 else if (viewType == VK_IMAGE_VIEW_TYPE_3D) 681 str << "slice z = " << layer; 682 else 683 str << "layer " << layer; 684 685 return str.str(); 686 } 687 688 bool verifyResults (tcu::TestLog& log, const TestParams& params, const VkFormat imageFormat, const void* resultData, const bool depthCheck = false, const bool stencilCheck = false) 689 { 690 const LayeredImageAccess image = LayeredImageAccess::create(getImageType(params.image.viewType), imageFormat, params.image.size, params.image.numLayers, resultData); 691 692 int numGoodLayers = 0; 693 694 for (int layerNdx = 0; layerNdx < image.getNumLayersOrSlices(); ++layerNdx) 695 { 696 const tcu::ConstPixelBufferAccess layerImage = image.getLayer(layerNdx); 697 698 log << tcu::TestLog::Message << "Verifying " << getLayerDescription(params.image.viewType, layerNdx) << tcu::TestLog::EndMessage; 699 700 if (verifyLayerContent(log, params.testType, layerImage, layerNdx, image.getNumLayersOrSlices(), depthCheck, stencilCheck)) 701 ++numGoodLayers; 702 } 703 704 return numGoodLayers == image.getNumLayersOrSlices(); 705 } 706 707 std::string toGlsl (const Vec4& v) 708 { 709 std::ostringstream str; 710 str << "vec4("; 711 for (int i = 0; i < 4; ++i) 712 str << (i != 0 ? ", " : "") << de::floatToString(v[i], 1); 713 str << ")"; 714 return str.str(); 715 } 716 717 void initPrograms (SourceCollections& programCollection, const TestParams params) 718 { 719 const bool geomOutputColor = (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_LAYERED_READBACK); 720 721 // Vertex shader 722 { 723 std::ostringstream src; 724 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 725 << "\n" 726 << "void main(void)\n" 727 << "{\n" 728 << "}\n"; 729 730 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 731 } 732 733 // Geometry shader 734 { 735 const int numLayers = static_cast<int>(params.image.viewType == VK_IMAGE_VIEW_TYPE_3D ? params.image.size.depth : params.image.numLayers); 736 737 const int maxVertices = (params.testType == TEST_TYPE_DIFFERENT_CONTENT) ? (numLayers + 1) * numLayers : 738 (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_LAYER_ID || params.testType == TEST_TYPE_LAYERED_READBACK) ? numLayers * 4 : 739 (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) ? 6 : 4; 740 741 std::ostringstream src; 742 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 743 << "\n"; 744 745 if (params.testType == TEST_TYPE_LAYERED_READBACK) 746 src << "layout(binding = 0) readonly uniform Input {\n" 747 << " int pass;\n" 748 << "} uInput;\n\n"; 749 750 if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) 751 src << "layout(points, invocations = " << numLayers << ") in;\n"; 752 else 753 src << "layout(points) in;\n"; 754 755 src << "layout(triangle_strip, max_vertices = " << maxVertices << ") out;\n" 756 << "\n" 757 << (geomOutputColor ? "layout(location = 0) out vec4 vert_color;\n\n" : "") 758 << "out gl_PerVertex {\n" 759 << " vec4 gl_Position;\n" 760 << "};\n" 761 << "\n" 762 << "void main(void)\n" 763 << "{\n"; 764 765 std::ostringstream colorTable; 766 { 767 const int numColors = DE_LENGTH_OF_ARRAY(s_colors); 768 769 colorTable << " const vec4 colors[" << numColors << "] = vec4[" << numColors << "]("; 770 771 const std::string padding(colorTable.str().length(), ' '); 772 773 for (int i = 0; i < numColors; ++i) 774 colorTable << (i != 0 ? ",\n" + padding : "") << toGlsl(s_colors[i]); 775 776 colorTable << ");\n"; 777 } 778 779 if (params.testType == TEST_TYPE_DEFAULT_LAYER) 780 { 781 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 782 << " EmitVertex();\n" 783 << "\n" 784 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 785 << " EmitVertex();\n" 786 << "\n" 787 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 788 << " EmitVertex();\n" 789 << "\n" 790 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 791 << " EmitVertex();\n"; 792 } 793 else if (params.testType == TEST_TYPE_SINGLE_LAYER) 794 { 795 const deUint32 targetLayer = getTargetLayer(params.image); 796 797 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 798 << " gl_Layer = " << targetLayer << ";\n" 799 << " EmitVertex();\n" 800 << "\n" 801 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 802 << " gl_Layer = " << targetLayer << ";\n" 803 << " EmitVertex();\n" 804 << "\n" 805 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 806 << " gl_Layer = " << targetLayer << ";\n" 807 << " EmitVertex();\n" 808 << "\n" 809 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 810 << " gl_Layer = " << targetLayer << ";\n" 811 << " EmitVertex();\n"; 812 } 813 else if (params.testType == TEST_TYPE_ALL_LAYERS) 814 { 815 src << colorTable.str() 816 << "\n" 817 << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n" 818 << " const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n" 819 << "\n" 820 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 821 << " gl_Layer = layerNdx;\n" 822 << " vert_color = colors[colorNdx];\n" 823 << " EmitVertex();\n" 824 << "\n" 825 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 826 << " gl_Layer = layerNdx;\n" 827 << " vert_color = colors[colorNdx];\n" 828 << " EmitVertex();\n" 829 << "\n" 830 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 831 << " gl_Layer = layerNdx;\n" 832 << " vert_color = colors[colorNdx];\n" 833 << " EmitVertex();\n" 834 << "\n" 835 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 836 << " gl_Layer = layerNdx;\n" 837 << " vert_color = colors[colorNdx];\n" 838 << " EmitVertex();\n" 839 << " EndPrimitive();\n" 840 << " };\n"; 841 } 842 else if (params.testType == TEST_TYPE_LAYER_ID) 843 { 844 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n" 845 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 846 << " gl_Layer = layerNdx;\n" 847 << " EmitVertex();\n" 848 << "\n" 849 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 850 << " gl_Layer = layerNdx;\n" 851 << " EmitVertex();\n" 852 << "\n" 853 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 854 << " gl_Layer = layerNdx;\n" 855 << " EmitVertex();\n" 856 << "\n" 857 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 858 << " gl_Layer = layerNdx;\n" 859 << " EmitVertex();\n" 860 << " EndPrimitive();\n" 861 << " };\n"; 862 } 863 else if (params.testType == TEST_TYPE_DIFFERENT_CONTENT) 864 { 865 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n" 866 << " for (int colNdx = 0; colNdx <= layerNdx; ++colNdx) {\n" 867 << " const float posX = float(colNdx) / float(" << numLayers << ") * 2.0 - 1.0;\n" 868 << "\n" 869 << " gl_Position = vec4(posX, 1.0, 0.0, 1.0);\n" 870 << " gl_Layer = layerNdx;\n" 871 << " EmitVertex();\n" 872 << "\n" 873 << " gl_Position = vec4(posX, -1.0, 0.0, 1.0);\n" 874 << " gl_Layer = layerNdx;\n" 875 << " EmitVertex();\n" 876 << " }\n" 877 << " EndPrimitive();\n" 878 << " }\n"; 879 } 880 else if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER) 881 { 882 src << colorTable.str() 883 << " const int colorNdx = gl_InvocationID % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n" 884 << "\n" 885 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 886 << " gl_Layer = gl_InvocationID;\n" 887 << " vert_color = colors[colorNdx];\n" 888 << " EmitVertex();\n" 889 << "\n" 890 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 891 << " gl_Layer = gl_InvocationID;\n" 892 << " vert_color = colors[colorNdx];\n" 893 << " EmitVertex();\n" 894 << "\n" 895 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 896 << " gl_Layer = gl_InvocationID;\n" 897 << " vert_color = colors[colorNdx];\n" 898 << " EmitVertex();\n" 899 << "\n" 900 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 901 << " gl_Layer = gl_InvocationID;\n" 902 << " vert_color = colors[colorNdx];\n" 903 << " EmitVertex();\n" 904 << " EndPrimitive();\n"; 905 } 906 else if (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) 907 { 908 src << " const int layerA = gl_InvocationID;\n" 909 << " const int layerB = (gl_InvocationID + 1) % " << numLayers << ";\n" 910 << " const float aEnd = float(layerA) / float(" << numLayers << ") * 2.0 - 1.0;\n" 911 << " const float bEnd = float(layerB) / float(" << numLayers << ") * 2.0 - 1.0;\n" 912 << "\n" 913 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 914 << " gl_Layer = layerA;\n" 915 << " EmitVertex();\n" 916 << "\n" 917 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 918 << " gl_Layer = layerA;\n" 919 << " EmitVertex();\n" 920 << "\n" 921 << " gl_Position = vec4(aEnd, -1.0, 0.0, 1.0);\n" 922 << " gl_Layer = layerA;\n" 923 << " EmitVertex();\n" 924 << " EndPrimitive();\n" 925 << "\n" 926 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 927 << " gl_Layer = layerB;\n" 928 << " EmitVertex();\n" 929 << "\n" 930 << " gl_Position = vec4(bEnd, 1.0, 0.0, 1.0);\n" 931 << " gl_Layer = layerB;\n" 932 << " EmitVertex();\n" 933 << "\n" 934 << " gl_Position = vec4(bEnd, -1.0, 0.0, 1.0);\n" 935 << " gl_Layer = layerB;\n" 936 << " EmitVertex();\n" 937 << " EndPrimitive();\n"; 938 } 939 else if (params.testType == TEST_TYPE_LAYERED_READBACK) 940 { 941 src << colorTable.str() 942 << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n" 943 << " const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n" 944 << " const vec3 passColor0 = (uInput.pass == 0 ? 0.5 : 1.0) * vec3(colors[colorNdx]);\n" 945 << " const vec4 passColor = vec4(passColor0, 1.0);\n" 946 << " const float posX = (uInput.pass == 0 ? 0.0 : -0.5);\n" 947 << " const float posZ = float(layerNdx + 1 - uInput.pass) / float(" << 2*numLayers << ");\n" 948 << "\n" 949 << " gl_Position = vec4(-1.0, -1.0, posZ, 1.0);\n" 950 << " gl_Layer = layerNdx;\n" 951 << " vert_color = passColor;\n" 952 << " EmitVertex();\n" 953 << "\n" 954 << " gl_Position = vec4(-1.0, 1.0, posZ, 1.0);\n" 955 << " gl_Layer = layerNdx;\n" 956 << " vert_color = passColor;\n" 957 << " EmitVertex();\n" 958 << "\n" 959 << " gl_Position = vec4(posX, -1.0, posZ, 1.0);\n" 960 << " gl_Layer = layerNdx;\n" 961 << " vert_color = passColor;\n" 962 << " EmitVertex();\n" 963 << "\n" 964 << " gl_Position = vec4(posX, 1.0, posZ, 1.0);\n" 965 << " gl_Layer = layerNdx;\n" 966 << " vert_color = passColor;\n" 967 << " EmitVertex();\n" 968 << "\n" 969 << " EndPrimitive();\n" 970 << " }\n"; 971 } 972 else 973 DE_ASSERT(0); 974 975 src << "}\n"; // end main 976 977 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str()); 978 } 979 980 // Fragment shader 981 { 982 std::ostringstream src; 983 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 984 << "\n" 985 << "layout(location = 0) out vec4 o_color;\n" 986 << (geomOutputColor ? "layout(location = 0) in vec4 vert_color;\n" : "") 987 << "\n" 988 << "void main(void)\n" 989 << "{\n"; 990 991 if (params.testType == TEST_TYPE_LAYER_ID) 992 { 993 // This code must be in sync with verifyLayerContent() 994 src << " o_color = vec4( (gl_Layer % 2) == 1 ? 1.0 : 0.5,\n" 995 << " ((gl_Layer/2) % 2) == 1 ? 1.0 : 0.5,\n" 996 << " gl_Layer == 0 ? 1.0 : 0.0,\n" 997 << " 1.0);\n"; 998 } 999 else if (geomOutputColor) 1000 src << " o_color = vert_color;\n"; 1001 else 1002 src << " o_color = vec4(1.0);\n"; 1003 1004 src << "}\n"; 1005 1006 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); 1007 } 1008 } 1009 1010 tcu::TestStatus test (Context& context, const TestParams params) 1011 { 1012 if (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType && 1013 (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1"))) 1014 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported"); 1015 1016 const DeviceInterface& vk = context.getDeviceInterface(); 1017 const InstanceInterface& vki = context.getInstanceInterface(); 1018 const VkDevice device = context.getDevice(); 1019 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 1020 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1021 const VkQueue queue = context.getUniversalQueue(); 1022 Allocator& allocator = context.getDefaultAllocator(); 1023 1024 checkGeometryShaderSupport(vki, physDevice); 1025 1026 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 1027 const deUint32 numLayers = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers); 1028 const Vec4 clearColor = Vec4(0.0f, 0.0f, 0.0f, 1.0f); 1029 const VkDeviceSize colorBufferSize = params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * tcu::getPixelSize(mapVkFormat(colorFormat)); 1030 const VkImageCreateFlags imageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) | 1031 (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageCreateFlagBits)0); 1032 const VkImageViewType viewType = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType); 1033 1034 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size, 1035 params.image.numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT))); 1036 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any)); 1037 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers))); 1038 1039 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); 1040 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible)); 1041 1042 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u)); 1043 const Unique<VkShaderModule> geometryModule (createShaderModule (vk, device, context.getBinaryCollection().get("geom"), 0u)); 1044 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u)); 1045 1046 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat)); 1047 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, &*colorAttachment, 1u, params.image.size.width, params.image.size.height, numLayers)); 1048 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device)); 1049 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule, 1050 makeExtent2D(params.image.size.width, params.image.size.height))); 1051 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 1052 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 1053 1054 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize); 1055 1056 beginCommandBuffer(vk, *cmdBuffer); 1057 1058 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, params.image.size.width, params.image.size.height), clearColor); 1059 1060 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 1061 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u); 1062 endRenderPass(vk, *cmdBuffer); 1063 1064 // Prepare color image for copy 1065 { 1066 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers); 1067 const VkImageMemoryBarrier barriers[] = 1068 { 1069 { 1070 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1071 DE_NULL, // const void* pNext; 1072 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask; 1073 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask; 1074 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 1075 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 1076 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1077 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1078 *colorImage, // VkImage image; 1079 colorSubresourceRange, // VkImageSubresourceRange subresourceRange; 1080 }, 1081 }; 1082 1083 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1084 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers); 1085 } 1086 // Color image -> host buffer 1087 { 1088 const VkBufferImageCopy region = 1089 { 1090 0ull, // VkDeviceSize bufferOffset; 1091 0u, // uint32_t bufferRowLength; 1092 0u, // uint32_t bufferImageHeight; 1093 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, params.image.numLayers), // VkImageSubresourceLayers imageSubresource; 1094 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 1095 params.image.size, // VkExtent3D imageExtent; 1096 }; 1097 1098 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion); 1099 } 1100 // Buffer write barrier 1101 { 1102 const VkBufferMemoryBarrier barriers[] = 1103 { 1104 { 1105 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1106 DE_NULL, // const void* pNext; 1107 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1108 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 1109 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 1110 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 1111 *colorBuffer, // VkBuffer buffer; 1112 0ull, // VkDeviceSize offset; 1113 VK_WHOLE_SIZE, // VkDeviceSize size; 1114 }, 1115 }; 1116 1117 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1118 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u); 1119 } 1120 1121 endCommandBuffer(vk, *cmdBuffer); 1122 submitCommandsAndWait(vk, device, queue, *cmdBuffer); 1123 1124 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSize); 1125 1126 if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr())) 1127 return tcu::TestStatus::fail("Rendered images are incorrect"); 1128 else 1129 return tcu::TestStatus::pass("OK"); 1130 } 1131 1132 tcu::TestStatus testLayeredReadBack (Context& context, const TestParams params) 1133 { 1134 if (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType && 1135 (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1"))) 1136 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported"); 1137 1138 const DeviceInterface& vk = context.getDeviceInterface(); 1139 const InstanceInterface& vki = context.getInstanceInterface(); 1140 const VkDevice device = context.getDevice(); 1141 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 1142 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1143 const VkQueue queue = context.getUniversalQueue(); 1144 Allocator& allocator = context.getDefaultAllocator(); 1145 1146 checkGeometryShaderSupport(vki, physDevice); 1147 1148 const size_t passCount = 2; 1149 const deUint32 numLayers = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers); 1150 const VkImageCreateFlags imageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) | 1151 (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageCreateFlagBits)0); 1152 const VkImageViewType viewType = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType); 1153 const VkImageType imageType = getImageType(params.image.viewType); 1154 const VkExtent2D imageExtent2D = makeExtent2D(params.image.size.width, params.image.size.height); 1155 1156 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 1157 const deUint32 colorImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(colorFormat))); 1158 const VkDeviceSize colorBufferSize = params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * colorImagePixelSize; 1159 const VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; 1160 1161 const bool dsUsed = (VK_IMAGE_VIEW_TYPE_3D != params.image.viewType); 1162 const VkFormat dsFormat = VK_FORMAT_D24_UNORM_S8_UINT; 1163 const deUint32 dsImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat))); 1164 const VkImageUsageFlags dsImageUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; 1165 const VkImageAspectFlags dsAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 1166 const VkDeviceSize depthBufferSize = params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * dsImagePixelSize; 1167 1168 const VkFormat stencilBufferFormat = getStencilBufferFormat(dsFormat); 1169 const deUint32 stencilPixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat))); 1170 const VkDeviceSize stencilBufferSize = params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * stencilPixelSize; 1171 1172 checkImageFormatProperties(vki, physDevice, imageType, VK_IMAGE_TILING_OPTIMAL, dsImageUsage, imageCreateFlags, dsFormat, params.image.size, params.image.numLayers); 1173 1174 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(imageCreateFlags, imageType, colorFormat, params.image.size, params.image.numLayers, colorImageUsage))); 1175 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any)); 1176 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers))); 1177 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))); 1178 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible)); 1179 1180 const Unique<VkImage> dsImage (makeImage (vk, device, makeImageCreateInfo(imageCreateFlags, imageType, dsFormat, params.image.size, params.image.numLayers, dsImageUsage))); 1181 const UniquePtr<Allocation> dsImageAlloc (bindImage (vk, device, allocator, *dsImage, MemoryRequirement::Any)); 1182 const Unique<VkImageView> dsAttachment (makeImageView (vk, device, *dsImage, viewType, dsFormat, makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, numLayers))); 1183 const Unique<VkBuffer> depthBuffer (makeBuffer (vk, device, makeBufferCreateInfo(depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))); 1184 const UniquePtr<Allocation> depthBufferAlloc (bindBuffer (vk, device, allocator, *depthBuffer, MemoryRequirement::HostVisible)); 1185 const Unique<VkBuffer> stencilBuffer (makeBuffer (vk, device, makeBufferCreateInfo(stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))); 1186 const UniquePtr<Allocation> stencilBufferAlloc (bindBuffer (vk, device, allocator, *stencilBuffer, MemoryRequirement::HostVisible)); 1187 1188 const VkImageView attachments[] = {*colorAttachment, *dsAttachment}; 1189 const deUint32 attachmentsCount = dsUsed ? DE_LENGTH_OF_ARRAY(attachments) : 1u; 1190 1191 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u)); 1192 const Unique<VkShaderModule> geometryModule (createShaderModule (vk, device, context.getBinaryCollection().get("geom"), 0u)); 1193 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u)); 1194 1195 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat, dsFormat, dsUsed)); 1196 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, attachments, attachmentsCount, params.image.size.width, params.image.size.height, numLayers)); 1197 1198 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder() 1199 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, passCount) 1200 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, passCount); 1201 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder() 1202 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT) 1203 .build(vk, device); 1204 const Move<VkDescriptorSet> descriptorSet[] = 1205 { 1206 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout), 1207 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout), 1208 }; 1209 1210 const size_t uniformBufSize = sizeof(deUint32); 1211 const VkBufferCreateInfo uniformBufCI = makeBufferCreateInfo(uniformBufSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 1212 const Move<VkBuffer> uniformBuf[] = { createBuffer(vk, device, &uniformBufCI), createBuffer(vk, device, &uniformBufCI) }; 1213 const MovePtr<Allocation> uniformBufAlloc[] = 1214 { 1215 allocator.allocate(getBufferMemoryRequirements(vk, device, *uniformBuf[0]), MemoryRequirement::HostVisible), 1216 allocator.allocate(getBufferMemoryRequirements(vk, device, *uniformBuf[1]), MemoryRequirement::HostVisible), 1217 }; 1218 const VkDescriptorBufferInfo uniformBufDesc[] = 1219 { 1220 makeDescriptorBufferInfo(*uniformBuf[0], 0ull, uniformBufSize), 1221 makeDescriptorBufferInfo(*uniformBuf[1], 0ull, uniformBufSize), 1222 }; 1223 1224 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device, *descriptorSetLayout)); 1225 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule, imageExtent2D, dsUsed)); 1226 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 1227 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 1228 const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers); 1229 const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, params.image.numLayers); 1230 const VkImageMemoryBarrier colorPassBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 1231 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, *colorImage, colorSubresRange); 1232 const VkImageMemoryBarrier dsPassBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 1233 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, *dsImage, dsSubresRange); 1234 std::string result; 1235 1236 beginCommandBuffer(vk, *cmdBuffer); 1237 { 1238 const VkImageMemoryBarrier colorBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 1239 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, *colorImage, colorSubresRange); 1240 const VkImageMemoryBarrier dsBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 1241 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, *dsImage, dsSubresRange); 1242 1243 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &colorBarrier); 1244 1245 if (dsUsed) 1246 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &dsBarrier); 1247 1248 for (deUint32 layerNdx = 0; layerNdx < numLayers; ++layerNdx) 1249 { 1250 const deUint32 imageDepth = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType) ? layerNdx : 0u; 1251 const deUint32 layer = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType) ? 0u : layerNdx; 1252 const VkOffset3D imageOffset = makeOffset3D(0u, 0u, imageDepth); 1253 const VkExtent3D imageExtent = makeExtent3D(params.image.size.width, params.image.size.height, 1u); 1254 1255 // Clear color image with initial value 1256 { 1257 const tcu::Vec4 clearColor = scaleColor(s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)], 0.25f); 1258 const deUint32 bufferSliceSize = params.image.size.width * params.image.size.height * colorImagePixelSize; 1259 const VkDeviceSize bufferOffset = layerNdx * bufferSliceSize; 1260 const VkImageSubresourceLayers imageSubresource = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, layer, 1u); 1261 const VkBufferImageCopy bufferImageCopyRegion = makeBufferImageCopy(bufferOffset, imageSubresource, imageOffset, imageExtent); 1262 1263 fillBuffer(vk, device, *colorBufferAlloc, bufferOffset, bufferSliceSize, colorFormat, clearColor); 1264 vk.cmdCopyBufferToImage(*cmdBuffer, *colorBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion); 1265 } 1266 1267 // Clear depth image with initial value 1268 if (dsUsed) 1269 { 1270 const float depthValue = 1.0f; 1271 const deUint32 bufferSliceSize = params.image.size.width * params.image.size.height * dsImagePixelSize; 1272 const VkDeviceSize bufferOffset = layerNdx * bufferSliceSize; 1273 const VkImageSubresourceLayers imageSubresource = makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, layer, 1u); 1274 const VkBufferImageCopy bufferImageCopyRegion = makeBufferImageCopy(bufferOffset, imageSubresource, imageOffset, imageExtent); 1275 1276 fillBuffer(vk, device, *depthBufferAlloc, bufferOffset, bufferSliceSize, dsFormat, depthValue); 1277 vk.cmdCopyBufferToImage(*cmdBuffer, *depthBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion); 1278 } 1279 1280 // Clear stencil image with initial value 1281 if (dsUsed) 1282 { 1283 const deUint8 stencilValue = 0; 1284 const deUint32 bufferSliceSize = params.image.size.width * params.image.size.height * stencilPixelSize; 1285 const VkDeviceSize bufferOffset = layerNdx * bufferSliceSize; 1286 const VkImageSubresourceLayers imageSubresource = makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, layer, 1u); 1287 const VkBufferImageCopy bufferImageCopyRegion = makeBufferImageCopy(bufferOffset, imageSubresource, imageOffset, imageExtent); 1288 deUint8* bufferStart = static_cast<deUint8*>((*stencilBufferAlloc).getHostPtr()); 1289 deUint8* bufferLayerStart = &bufferStart[bufferOffset]; 1290 1291 deMemset(bufferLayerStart, stencilValue, bufferSliceSize); 1292 flushMappedMemoryRange(vk, device, stencilBufferAlloc->getMemory(), stencilBufferAlloc->getOffset() + bufferOffset, bufferSliceSize); 1293 vk.cmdCopyBufferToImage(*cmdBuffer, *stencilBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion); 1294 } 1295 } 1296 } 1297 // Change images layouts 1298 { 1299 const VkImageMemoryBarrier colorBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 1300 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, *colorImage, colorSubresRange); 1301 const VkImageMemoryBarrier dsBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 1302 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, *dsImage, dsSubresRange); 1303 1304 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &colorBarrier); 1305 1306 if (dsUsed) 1307 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &dsBarrier); 1308 } 1309 1310 for (deUint32 pass = 0; pass < passCount; ++pass) 1311 { 1312 DE_ASSERT(sizeof(pass) == uniformBufSize); 1313 1314 VK_CHECK(vk.bindBufferMemory(device, *uniformBuf[pass], uniformBufAlloc[pass]->getMemory(), uniformBufAlloc[pass]->getOffset())); 1315 deMemcpy(uniformBufAlloc[pass]->getHostPtr(), &pass, uniformBufSize); 1316 flushMappedMemoryRange(vk, device, uniformBufAlloc[pass]->getMemory(), uniformBufAlloc[pass]->getOffset(), uniformBufSize); 1317 1318 DescriptorSetUpdateBuilder() 1319 .writeSingle(*descriptorSet[pass], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufDesc[pass]) 1320 .update(vk, device); 1321 1322 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet[pass], 0u, DE_NULL); 1323 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(imageExtent2D)); 1324 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 1325 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u); 1326 endRenderPass(vk, *cmdBuffer); 1327 1328 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &colorPassBarrier); 1329 1330 if (dsUsed) 1331 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &dsPassBarrier); 1332 } 1333 endCommandBuffer(vk, *cmdBuffer); 1334 submitCommandsAndWait(vk, device, queue, *cmdBuffer); 1335 1336 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize); 1337 zeroBuffer(vk, device, *depthBufferAlloc, depthBufferSize); 1338 zeroBuffer(vk, device, *stencilBufferAlloc, stencilBufferSize); 1339 1340 beginCommandBuffer(vk, *cmdBuffer); 1341 { 1342 // Copy color image 1343 { 1344 const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 1345 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorImage, colorSubresRange); 1346 const VkBufferImageCopy region = makeBufferImageCopy(params.image.size, makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, params.image.numLayers)); 1347 const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE); 1348 1349 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); 1350 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion); 1351 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); 1352 } 1353 1354 // Depth/Stencil image copy 1355 if (dsUsed) 1356 { 1357 const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 1358 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsImage, dsSubresRange); 1359 const VkBufferImageCopy depthCopyRegion = makeBufferImageCopy(params.image.size, makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, params.image.numLayers)); 1360 const VkBufferImageCopy stencilCopyRegion = makeBufferImageCopy(params.image.size, makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, params.image.numLayers)); 1361 const VkBufferMemoryBarrier postCopyBarriers[] = 1362 { 1363 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthBuffer, 0ull, VK_WHOLE_SIZE), 1364 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilBuffer, 0ull, VK_WHOLE_SIZE), 1365 }; 1366 1367 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); 1368 vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthBuffer, 1u, &depthCopyRegion); 1369 vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilBuffer, 1u, &stencilCopyRegion); 1370 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u); 1371 } 1372 } 1373 endCommandBuffer(vk, *cmdBuffer); 1374 submitCommandsAndWait(vk, device, queue, *cmdBuffer); 1375 1376 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSize); 1377 invalidateMappedMemoryRange(vk, device, depthBufferAlloc->getMemory(), depthBufferAlloc->getOffset(), depthBufferSize); 1378 invalidateMappedMemoryRange(vk, device, stencilBufferAlloc->getMemory(), stencilBufferAlloc->getOffset(), stencilBufferSize); 1379 1380 if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr())) 1381 result += " Color"; 1382 1383 if (dsUsed) 1384 { 1385 if (!verifyResults(context.getTestContext().getLog(), params, dsFormat, depthBufferAlloc->getHostPtr(), true, false)) 1386 result += " Depth"; 1387 1388 if (!verifyResults(context.getTestContext().getLog(), params, stencilBufferFormat, stencilBufferAlloc->getHostPtr(), false, true)) 1389 result += " Stencil"; 1390 } 1391 1392 if (result.empty()) 1393 return tcu::TestStatus::pass("OK"); 1394 else 1395 return tcu::TestStatus::fail("Following parts of image are incorrect:" + result); 1396 } 1397 1398 } // anonymous 1399 1400 tcu::TestCaseGroup* createLayeredRenderingTests (tcu::TestContext& testCtx) 1401 { 1402 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "layered", "Layered rendering tests.")); 1403 1404 const struct 1405 { 1406 TestType test; 1407 const char* name; 1408 const char* description; 1409 } testTypes[] = 1410 { 1411 { TEST_TYPE_DEFAULT_LAYER, "render_to_default_layer", "Render to the default layer" }, 1412 { TEST_TYPE_SINGLE_LAYER, "render_to_one", "Render to one layer" }, 1413 { TEST_TYPE_ALL_LAYERS, "render_to_all", "Render to all layers" }, 1414 { TEST_TYPE_DIFFERENT_CONTENT, "render_different_content", "Render different data to different layers" }, 1415 { TEST_TYPE_LAYER_ID, "fragment_layer", "Read gl_Layer in fragment shader" }, 1416 { TEST_TYPE_INVOCATION_PER_LAYER, "invocation_per_layer", "Render to multiple layers with multiple invocations, one invocation per layer" }, 1417 { TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, "multiple_layers_per_invocation", "Render to multiple layers with multiple invocations, multiple layers per invocation", }, 1418 { TEST_TYPE_LAYERED_READBACK, "readback", "Render to multiple layers with two passes to check LOAD_OP_LOAD capability" }, 1419 }; 1420 1421 const ImageParams imageParams[] = 1422 { 1423 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, { 64, 1, 1 }, 4 }, 1424 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, { 64, 64, 1 }, 4 }, 1425 { VK_IMAGE_VIEW_TYPE_CUBE, { 64, 64, 1 }, 6 }, 1426 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, { 64, 64, 1 }, 2*6 }, 1427 { VK_IMAGE_VIEW_TYPE_3D, { 64, 64, 8 }, 1 } 1428 }; 1429 1430 for (int imageParamNdx = 0; imageParamNdx < DE_LENGTH_OF_ARRAY(imageParams); ++imageParamNdx) 1431 { 1432 MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, getShortImageViewTypeName(imageParams[imageParamNdx].viewType).c_str(), "")); 1433 1434 for (int testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx) 1435 { 1436 const TestParams params = 1437 { 1438 testTypes[testTypeNdx].test, 1439 imageParams[imageParamNdx], 1440 }; 1441 1442 if (testTypes[testTypeNdx].test == TEST_TYPE_LAYERED_READBACK) 1443 addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, initPrograms, testLayeredReadBack, params); 1444 else 1445 addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, initPrograms, test, params); 1446 } 1447 1448 group->addChild(viewTypeGroup.release()); 1449 } 1450 1451 return group.release(); 1452 } 1453 1454 } // geometry 1455 } // vkt 1456