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 "vkTypeUtil.hpp" 36#include "vkImageUtil.hpp" 37 38#include "deStringUtil.hpp" 39#include "deUniquePtr.hpp" 40 41#include "tcuTextureUtil.hpp" 42#include "tcuVectorUtil.hpp" 43#include "tcuTestLog.hpp" 44 45namespace vkt 46{ 47namespace geometry 48{ 49namespace 50{ 51using namespace vk; 52using de::MovePtr; 53using de::UniquePtr; 54using tcu::Vec4; 55using tcu::IVec3; 56 57enum TestType 58{ 59 TEST_TYPE_DEFAULT_LAYER, // !< draw to default layer 60 TEST_TYPE_SINGLE_LAYER, // !< draw to single layer 61 TEST_TYPE_ALL_LAYERS, // !< draw all layers 62 TEST_TYPE_DIFFERENT_CONTENT, // !< draw different content to different layers 63 TEST_TYPE_LAYER_ID, // !< draw to all layers, verify gl_Layer fragment input 64 TEST_TYPE_INVOCATION_PER_LAYER, // !< draw to all layers, one invocation per layer 65 TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, // !< draw to all layers, multiple invocations write to multiple layers 66}; 67 68struct ImageParams 69{ 70 VkImageViewType viewType; 71 VkExtent3D size; 72 deUint32 numLayers; 73}; 74 75struct TestParams 76{ 77 TestType testType; 78 ImageParams image; 79}; 80 81static const float s_colors[][4] = 82{ 83 { 1.0f, 1.0f, 1.0f, 1.0f }, // white 84 { 1.0f, 0.0f, 0.0f, 1.0f }, // red 85 { 0.0f, 1.0f, 0.0f, 1.0f }, // green 86 { 0.0f, 0.0f, 1.0f, 1.0f }, // blue 87 { 1.0f, 1.0f, 0.0f, 1.0f }, // yellow 88 { 1.0f, 0.0f, 1.0f, 1.0f }, // magenta 89}; 90 91deUint32 getTargetLayer (const ImageParams& imageParams) 92{ 93 if (imageParams.viewType == VK_IMAGE_VIEW_TYPE_3D) 94 return imageParams.size.depth / 2; 95 else 96 return imageParams.numLayers / 2; 97} 98 99std::string getShortImageViewTypeName (const VkImageViewType imageViewType) 100{ 101 std::string s(getImageViewTypeName(imageViewType)); 102 return de::toLower(s.substr(19)); 103} 104 105VkImageType getImageType (const VkImageViewType viewType) 106{ 107 switch (viewType) 108 { 109 case VK_IMAGE_VIEW_TYPE_1D: 110 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 111 return VK_IMAGE_TYPE_1D; 112 113 case VK_IMAGE_VIEW_TYPE_2D: 114 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 115 case VK_IMAGE_VIEW_TYPE_CUBE: 116 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 117 return VK_IMAGE_TYPE_2D; 118 119 case VK_IMAGE_VIEW_TYPE_3D: 120 return VK_IMAGE_TYPE_3D; 121 122 default: 123 DE_ASSERT(0); 124 return VK_IMAGE_TYPE_LAST; 125 } 126} 127 128inline bool isCubeImageViewType (const VkImageViewType viewType) 129{ 130 return viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 131} 132 133VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const VkImageUsageFlags usage) 134{ 135 const VkImageCreateInfo imageParams = 136 { 137 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 138 DE_NULL, // const void* pNext; 139 flags, // VkImageCreateFlags flags; 140 type, // VkImageType imageType; 141 format, // VkFormat format; 142 size, // VkExtent3D extent; 143 1u, // deUint32 mipLevels; 144 numLayers, // deUint32 arrayLayers; 145 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 146 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 147 usage, // VkImageUsageFlags usage; 148 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 149 0u, // deUint32 queueFamilyIndexCount; 150 DE_NULL, // const deUint32* pQueueFamilyIndices; 151 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 152 }; 153 return imageParams; 154} 155 156Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, 157 const VkDevice device, 158 const VkFormat colorFormat) 159{ 160 const VkAttachmentDescription colorAttachmentDescription = 161 { 162 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 163 colorFormat, // VkFormat format; 164 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 165 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 166 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 167 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 168 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 169 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 170 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 171 }; 172 173 const VkAttachmentReference colorAttachmentRef = 174 { 175 0u, // deUint32 attachment; 176 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 177 }; 178 179 const VkSubpassDescription subpassDescription = 180 { 181 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 182 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 183 0u, // deUint32 inputAttachmentCount; 184 DE_NULL, // const VkAttachmentReference* pInputAttachments; 185 1u, // deUint32 colorAttachmentCount; 186 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments; 187 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 188 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 189 0u, // deUint32 preserveAttachmentCount; 190 DE_NULL // const deUint32* pPreserveAttachments; 191 }; 192 193 const VkRenderPassCreateInfo renderPassInfo = 194 { 195 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 196 DE_NULL, // const void* pNext; 197 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 198 1u, // deUint32 attachmentCount; 199 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; 200 1u, // deUint32 subpassCount; 201 &subpassDescription, // const VkSubpassDescription* pSubpasses; 202 0u, // deUint32 dependencyCount; 203 DE_NULL // const VkSubpassDependency* pDependencies; 204 }; 205 206 return createRenderPass(vk, device, &renderPassInfo); 207} 208 209Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk, 210 const VkDevice device, 211 const VkPipelineLayout pipelineLayout, 212 const VkRenderPass renderPass, 213 const VkShaderModule vertexModule, 214 const VkShaderModule geometryModule, 215 const VkShaderModule fragmentModule, 216 const VkExtent2D renderSize) 217{ 218 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 219 { 220 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 221 DE_NULL, // const void* pNext; 222 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 223 0u, // uint32_t vertexBindingDescriptionCount; 224 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 225 0u, // uint32_t vertexAttributeDescriptionCount; 226 DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 227 }; 228 229 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 230 { 231 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 232 DE_NULL, // const void* pNext; 233 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 234 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology; 235 VK_FALSE, // VkBool32 primitiveRestartEnable; 236 }; 237 238 const VkViewport viewport = makeViewport( 239 0.0f, 0.0f, 240 static_cast<float>(renderSize.width), static_cast<float>(renderSize.height), 241 0.0f, 1.0f); 242 const VkRect2D scissor = 243 { 244 makeOffset2D(0, 0), 245 makeExtent2D(renderSize.width, renderSize.height), 246 }; 247 248 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = 249 { 250 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 251 DE_NULL, // const void* pNext; 252 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 253 1u, // uint32_t viewportCount; 254 &viewport, // const VkViewport* pViewports; 255 1u, // uint32_t scissorCount; 256 &scissor, // const VkRect2D* pScissors; 257 }; 258 259 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 260 { 261 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 262 DE_NULL, // const void* pNext; 263 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 264 VK_FALSE, // VkBool32 depthClampEnable; 265 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 266 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 267 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 268 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 269 VK_FALSE, // VkBool32 depthBiasEnable; 270 0.0f, // float depthBiasConstantFactor; 271 0.0f, // float depthBiasClamp; 272 0.0f, // float depthBiasSlopeFactor; 273 1.0f, // float lineWidth; 274 }; 275 276 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 277 { 278 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 279 DE_NULL, // const void* pNext; 280 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 281 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 282 VK_FALSE, // VkBool32 sampleShadingEnable; 283 0.0f, // float minSampleShading; 284 DE_NULL, // const VkSampleMask* pSampleMask; 285 VK_FALSE, // VkBool32 alphaToCoverageEnable; 286 VK_FALSE // VkBool32 alphaToOneEnable; 287 }; 288 289 const VkStencilOpState stencilOpState = makeStencilOpState( 290 VK_STENCIL_OP_KEEP, // stencil fail 291 VK_STENCIL_OP_KEEP, // depth & stencil pass 292 VK_STENCIL_OP_KEEP, // depth only fail 293 VK_COMPARE_OP_ALWAYS, // compare op 294 0u, // compare mask 295 0u, // write mask 296 0u); // reference 297 298 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 299 { 300 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 301 DE_NULL, // const void* pNext; 302 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 303 VK_FALSE, // VkBool32 depthTestEnable; 304 VK_FALSE, // VkBool32 depthWriteEnable; 305 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 306 VK_FALSE, // VkBool32 depthBoundsTestEnable; 307 VK_FALSE, // VkBool32 stencilTestEnable; 308 stencilOpState, // VkStencilOpState front; 309 stencilOpState, // VkStencilOpState back; 310 0.0f, // float minDepthBounds; 311 1.0f, // float maxDepthBounds; 312 }; 313 314 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 315 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 316 { 317 VK_FALSE, // VkBool32 blendEnable; 318 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 319 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 320 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 321 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 322 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 323 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 324 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 325 }; 326 327 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 328 { 329 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 330 DE_NULL, // const void* pNext; 331 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 332 VK_FALSE, // VkBool32 logicOpEnable; 333 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 334 1u, // deUint32 attachmentCount; 335 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 336 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 337 }; 338 339 const VkPipelineShaderStageCreateInfo pShaderStages[] = 340 { 341 { 342 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 343 DE_NULL, // const void* pNext; 344 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 345 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 346 vertexModule, // VkShaderModule module; 347 "main", // const char* pName; 348 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 349 }, 350 { 351 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 352 DE_NULL, // const void* pNext; 353 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 354 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage; 355 geometryModule, // VkShaderModule module; 356 "main", // const char* pName; 357 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 358 }, 359 { 360 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 361 DE_NULL, // const void* pNext; 362 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 363 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 364 fragmentModule, // VkShaderModule module; 365 "main", // const char* pName; 366 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 367 }, 368 }; 369 370 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = 371 { 372 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 373 DE_NULL, // const void* pNext; 374 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 375 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount; 376 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages; 377 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 378 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 379 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 380 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; 381 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 382 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 383 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 384 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 385 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 386 pipelineLayout, // VkPipelineLayout layout; 387 renderPass, // VkRenderPass renderPass; 388 0u, // deUint32 subpass; 389 DE_NULL, // VkPipeline basePipelineHandle; 390 0, // deInt32 basePipelineIndex; 391 }; 392 393 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo); 394} 395 396//! Convenience wrapper to access 1D, 2D, and 3D image layers/slices in a uniform way. 397class LayeredImageAccess 398{ 399public: 400 static LayeredImageAccess create (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData) 401 { 402 if (type == VK_IMAGE_TYPE_1D) 403 return LayeredImageAccess(format, size.width, numLayers, pData); 404 else 405 return LayeredImageAccess(type, format, size, numLayers, pData); 406 } 407 408 inline tcu::ConstPixelBufferAccess getLayer (const int layer) const 409 { 410 return tcu::getSubregion(m_wholeImage, 0, (m_1dModifier * layer), ((~m_1dModifier & 1) * layer), m_width, m_height, 1); 411 } 412 413 inline int getNumLayersOrSlices (void) const 414 { 415 return m_layers; 416 } 417 418private: 419 // Specialized for 1D images. 420 LayeredImageAccess (const VkFormat format, const deUint32 width, const deUint32 numLayers, const void* pData) 421 : m_width (static_cast<int>(width)) 422 , m_height (1) 423 , m_1dModifier (1) 424 , m_layers (numLayers) 425 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_layers, 1, pData)) 426 { 427 } 428 429 LayeredImageAccess (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData) 430 : m_width (static_cast<int>(size.width)) 431 , m_height (static_cast<int>(size.height)) 432 , m_1dModifier (0) 433 , m_layers (static_cast<int>(type == VK_IMAGE_TYPE_3D ? size.depth : numLayers)) 434 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_height, m_layers, pData)) 435 { 436 } 437 438 const int m_width; 439 const int m_height; 440 const int m_1dModifier; 441 const int m_layers; 442 const tcu::ConstPixelBufferAccess m_wholeImage; 443}; 444 445inline bool compareColors (const Vec4& colorA, const Vec4& colorB, const Vec4& threshold) 446{ 447 return tcu::allEqual( 448 tcu::lessThan(tcu::abs(colorA - colorB), threshold), 449 tcu::BVec4(true, true, true, true)); 450} 451 452bool verifyImageSingleColoredRow (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image, const float rowWidthRatio, const tcu::Vec4& barColor) 453{ 454 DE_ASSERT(rowWidthRatio > 0.0f); 455 456 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f); 457 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f); 458 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); 459 const Vec4 threshold (0.02f); 460 const int barLength = static_cast<int>(rowWidthRatio * static_cast<float>(image.getWidth())); 461 const int barLengthThreshold = 1; 462 tcu::TextureLevel errorMask (image.getFormat(), image.getWidth(), image.getHeight()); 463 tcu::PixelBufferAccess errorMaskAccess = errorMask.getAccess(); 464 465 tcu::clear(errorMask.getAccess(), green); 466 467 log << tcu::TestLog::Message 468 << "Expecting all pixels with distance less or equal to (about) " << barLength 469 << " pixels from left border to be of color " << barColor.swizzle(0, 1, 2) << "." 470 << tcu::TestLog::EndMessage; 471 472 bool allPixelsOk = true; 473 474 for (int y = 0; y < image.getHeight(); ++y) 475 for (int x = 0; x < image.getWidth(); ++x) 476 { 477 const Vec4 color = image.getPixel(x, y); 478 const bool isBlack = compareColors(color, black, threshold); 479 const bool isColor = compareColors(color, barColor, threshold); 480 481 bool isOk; 482 483 if (x <= barLength - barLengthThreshold) 484 isOk = isColor; 485 else if (x >= barLength + barLengthThreshold) 486 isOk = isBlack; 487 else 488 isOk = isColor || isBlack; 489 490 allPixelsOk &= isOk; 491 492 if (!isOk) 493 errorMaskAccess.setPixel(red, x, y); 494 } 495 496 if (allPixelsOk) 497 { 498 log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage 499 << tcu::TestLog::ImageSet("LayerContent", "Layer content") 500 << tcu::TestLog::Image("Layer", "Layer", image) 501 << tcu::TestLog::EndImageSet; 502 return true; 503 } 504 else 505 { 506 log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage 507 << tcu::TestLog::ImageSet("LayerContent", "Layer content") 508 << tcu::TestLog::Image("Layer", "Layer", image) 509 << tcu::TestLog::Image("ErrorMask", "Errors", errorMask) 510 << tcu::TestLog::EndImageSet; 511 return false; 512 } 513 514 log << tcu::TestLog::Image("LayerContent", "Layer content", image); 515 516 return allPixelsOk; 517} 518 519bool verifyEmptyImage (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image) 520{ 521 log << tcu::TestLog::Message << "Expecting empty image" << tcu::TestLog::EndMessage; 522 523 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f); 524 const Vec4 threshold (0.02f); 525 526 for (int y = 0; y < image.getHeight(); ++y) 527 for (int x = 0; x < image.getWidth(); ++x) 528 { 529 const Vec4 color = image.getPixel(x, y); 530 531 if (!compareColors(color, black, threshold)) 532 { 533 log << tcu::TestLog::Message 534 << "Found (at least) one bad pixel at " << x << "," << y << ". Pixel color is not background color." 535 << tcu::TestLog::EndMessage 536 << tcu::TestLog::ImageSet("LayerContent", "Layer content") 537 << tcu::TestLog::Image("Layer", "Layer", image) 538 << tcu::TestLog::EndImageSet; 539 return false; 540 } 541 } 542 543 log << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage; 544 545 return true; 546} 547 548bool verifyLayerContent (tcu::TestLog& log, const TestType testType, const tcu::ConstPixelBufferAccess image, const int layerNdx, const int numLayers) 549{ 550 const Vec4 white (1.0f, 1.0f, 1.0f, 1.0f); 551 const int targetLayer = numLayers / 2; 552 const float variableBarRatio = static_cast<float>(layerNdx) / static_cast<float>(numLayers); 553 554 switch (testType) 555 { 556 case TEST_TYPE_DEFAULT_LAYER: 557 if (layerNdx == 0) 558 return verifyImageSingleColoredRow(log, image, 0.5f, white); 559 else 560 return verifyEmptyImage(log, image); 561 562 case TEST_TYPE_SINGLE_LAYER: 563 if (layerNdx == targetLayer) 564 return verifyImageSingleColoredRow(log, image, 0.5f, white); 565 else 566 return verifyEmptyImage(log, image); 567 568 case TEST_TYPE_ALL_LAYERS: 569 case TEST_TYPE_INVOCATION_PER_LAYER: 570 return verifyImageSingleColoredRow(log, image, 0.5f, s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]); 571 572 case TEST_TYPE_DIFFERENT_CONTENT: 573 case TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION: 574 if (layerNdx == 0) 575 return verifyEmptyImage(log, image); 576 else 577 return verifyImageSingleColoredRow(log, image, variableBarRatio, white); 578 579 case TEST_TYPE_LAYER_ID: 580 { 581 // This code must be in sync with the fragment shader. 582 const tcu::Vec4 layerColor( (layerNdx % 2) == 1 ? 1.0f : 0.5f, 583 ((layerNdx/2) % 2) == 1 ? 1.0f : 0.5f, 584 layerNdx == 0 ? 1.0f : 0.0f, 585 1.0f); 586 return verifyImageSingleColoredRow(log, image, 0.5f, layerColor); 587 } 588 589 default: 590 DE_ASSERT(0); 591 return false; 592 }; 593} 594 595std::string getLayerDescription (const VkImageViewType viewType, const int layer) 596{ 597 std::ostringstream str; 598 const int numCubeFaces = 6; 599 600 if (isCubeImageViewType(viewType)) 601 str << "cube " << (layer / numCubeFaces) << ", face " << (layer % numCubeFaces); 602 else if (viewType == VK_IMAGE_VIEW_TYPE_3D) 603 str << "slice z = " << layer; 604 else 605 str << "layer " << layer; 606 607 return str.str(); 608} 609 610bool verifyResults (tcu::TestLog& log, const TestParams& params, const VkFormat colorFormat, const void* resultData) 611{ 612 const LayeredImageAccess image = LayeredImageAccess::create(getImageType(params.image.viewType), colorFormat, params.image.size, params.image.numLayers, resultData); 613 614 int numGoodLayers = 0; 615 616 for (int layerNdx = 0; layerNdx < image.getNumLayersOrSlices(); ++layerNdx) 617 { 618 const tcu::ConstPixelBufferAccess layerImage = image.getLayer(layerNdx); 619 620 log << tcu::TestLog::Message << "Verifying " << getLayerDescription(params.image.viewType, layerNdx) << tcu::TestLog::EndMessage; 621 622 if (verifyLayerContent(log, params.testType, layerImage, layerNdx, image.getNumLayersOrSlices())) 623 ++numGoodLayers; 624 } 625 626 return numGoodLayers == image.getNumLayersOrSlices(); 627} 628 629std::string toGlsl (const Vec4& v) 630{ 631 std::ostringstream str; 632 str << "vec4("; 633 for (int i = 0; i < 4; ++i) 634 str << (i != 0 ? ", " : "") << de::floatToString(v[i], 1); 635 str << ")"; 636 return str.str(); 637} 638 639void initPrograms (SourceCollections& programCollection, const TestParams params) 640{ 641 const bool geomOutputColor = (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_INVOCATION_PER_LAYER); 642 643 // Vertex shader 644 { 645 std::ostringstream src; 646 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 647 << "\n" 648 << "void main(void)\n" 649 << "{\n" 650 << "}\n"; 651 652 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 653 } 654 655 // Geometry shader 656 { 657 const int numLayers = static_cast<int>(params.image.viewType == VK_IMAGE_VIEW_TYPE_3D ? params.image.size.depth : params.image.numLayers); 658 659 const int maxVertices = (params.testType == TEST_TYPE_DIFFERENT_CONTENT) ? (numLayers + 1) * numLayers : 660 (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_LAYER_ID) ? numLayers * 4 : 661 (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) ? 6 : 4; 662 663 std::ostringstream src; 664 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 665 << "\n"; 666 667 if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) 668 src << "layout(points, invocations = " << numLayers << ") in;\n"; 669 else 670 src << "layout(points) in;\n"; 671 672 src << "layout(triangle_strip, max_vertices = " << maxVertices << ") out;\n" 673 << "\n" 674 << (geomOutputColor ? "layout(location = 0) out vec4 vert_color;\n\n" : "") 675 << "out gl_PerVertex {\n" 676 << " vec4 gl_Position;\n" 677 << "};\n" 678 << "\n" 679 << "void main(void)\n" 680 << "{\n"; 681 682 std::ostringstream colorTable; 683 { 684 const int numColors = DE_LENGTH_OF_ARRAY(s_colors); 685 686 colorTable << " const vec4 colors[" << numColors << "] = vec4[" << numColors << "]("; 687 688 const std::string padding(colorTable.str().length(), ' '); 689 690 for (int i = 0; i < numColors; ++i) 691 colorTable << (i != 0 ? ",\n" + padding : "") << toGlsl(s_colors[i]); 692 693 colorTable << ");\n"; 694 } 695 696 if (params.testType == TEST_TYPE_DEFAULT_LAYER) 697 { 698 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 699 << " EmitVertex();\n" 700 << "\n" 701 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 702 << " EmitVertex();\n" 703 << "\n" 704 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 705 << " EmitVertex();\n" 706 << "\n" 707 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 708 << " EmitVertex();\n"; 709 } 710 else if (params.testType == TEST_TYPE_SINGLE_LAYER) 711 { 712 const deUint32 targetLayer = getTargetLayer(params.image); 713 714 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 715 << " gl_Layer = " << targetLayer << ";\n" 716 << " EmitVertex();\n" 717 << "\n" 718 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 719 << " gl_Layer = " << targetLayer << ";\n" 720 << " EmitVertex();\n" 721 << "\n" 722 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 723 << " gl_Layer = " << targetLayer << ";\n" 724 << " EmitVertex();\n" 725 << "\n" 726 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 727 << " gl_Layer = " << targetLayer << ";\n" 728 << " EmitVertex();\n"; 729 } 730 else if (params.testType == TEST_TYPE_ALL_LAYERS) 731 { 732 src << colorTable.str() 733 << "\n" 734 << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n" 735 << " const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n" 736 << "\n" 737 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 738 << " gl_Layer = layerNdx;\n" 739 << " vert_color = colors[colorNdx];\n" 740 << " EmitVertex();\n" 741 << "\n" 742 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 743 << " gl_Layer = layerNdx;\n" 744 << " vert_color = colors[colorNdx];\n" 745 << " EmitVertex();\n" 746 << "\n" 747 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 748 << " gl_Layer = layerNdx;\n" 749 << " vert_color = colors[colorNdx];\n" 750 << " EmitVertex();\n" 751 << "\n" 752 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 753 << " gl_Layer = layerNdx;\n" 754 << " vert_color = colors[colorNdx];\n" 755 << " EmitVertex();\n" 756 << " EndPrimitive();\n" 757 << " };\n"; 758 } 759 else if (params.testType == TEST_TYPE_LAYER_ID) 760 { 761 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n" 762 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 763 << " gl_Layer = layerNdx;\n" 764 << " EmitVertex();\n" 765 << "\n" 766 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 767 << " gl_Layer = layerNdx;\n" 768 << " EmitVertex();\n" 769 << "\n" 770 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 771 << " gl_Layer = layerNdx;\n" 772 << " EmitVertex();\n" 773 << "\n" 774 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 775 << " gl_Layer = layerNdx;\n" 776 << " EmitVertex();\n" 777 << " EndPrimitive();\n" 778 << " };\n"; 779 } 780 else if (params.testType == TEST_TYPE_DIFFERENT_CONTENT) 781 { 782 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n" 783 << " for (int colNdx = 0; colNdx <= layerNdx; ++colNdx) {\n" 784 << " const float posX = float(colNdx) / float(" << numLayers << ") * 2.0 - 1.0;\n" 785 << "\n" 786 << " gl_Position = vec4(posX, 1.0, 0.0, 1.0);\n" 787 << " gl_Layer = layerNdx;\n" 788 << " EmitVertex();\n" 789 << "\n" 790 << " gl_Position = vec4(posX, -1.0, 0.0, 1.0);\n" 791 << " gl_Layer = layerNdx;\n" 792 << " EmitVertex();\n" 793 << " }\n" 794 << " EndPrimitive();\n" 795 << " }\n"; 796 } 797 else if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER) 798 { 799 src << colorTable.str() 800 << " const int colorNdx = gl_InvocationID % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n" 801 << "\n" 802 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 803 << " gl_Layer = gl_InvocationID;\n" 804 << " vert_color = colors[colorNdx];\n" 805 << " EmitVertex();\n" 806 << "\n" 807 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 808 << " gl_Layer = gl_InvocationID;\n" 809 << " vert_color = colors[colorNdx];\n" 810 << " EmitVertex();\n" 811 << "\n" 812 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n" 813 << " gl_Layer = gl_InvocationID;\n" 814 << " vert_color = colors[colorNdx];\n" 815 << " EmitVertex();\n" 816 << "\n" 817 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n" 818 << " gl_Layer = gl_InvocationID;\n" 819 << " vert_color = colors[colorNdx];\n" 820 << " EmitVertex();\n" 821 << " EndPrimitive();\n"; 822 } 823 else if (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) 824 { 825 src << " const int layerA = gl_InvocationID;\n" 826 << " const int layerB = (gl_InvocationID + 1) % " << numLayers << ";\n" 827 << " const float aEnd = float(layerA) / float(" << numLayers << ") * 2.0 - 1.0;\n" 828 << " const float bEnd = float(layerB) / float(" << numLayers << ") * 2.0 - 1.0;\n" 829 << "\n" 830 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 831 << " gl_Layer = layerA;\n" 832 << " EmitVertex();\n" 833 << "\n" 834 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 835 << " gl_Layer = layerA;\n" 836 << " EmitVertex();\n" 837 << "\n" 838 << " gl_Position = vec4(aEnd, -1.0, 0.0, 1.0);\n" 839 << " gl_Layer = layerA;\n" 840 << " EmitVertex();\n" 841 << " EndPrimitive();\n" 842 << "\n" 843 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 844 << " gl_Layer = layerB;\n" 845 << " EmitVertex();\n" 846 << "\n" 847 << " gl_Position = vec4(bEnd, 1.0, 0.0, 1.0);\n" 848 << " gl_Layer = layerB;\n" 849 << " EmitVertex();\n" 850 << "\n" 851 << " gl_Position = vec4(bEnd, -1.0, 0.0, 1.0);\n" 852 << " gl_Layer = layerB;\n" 853 << " EmitVertex();\n" 854 << " EndPrimitive();\n"; 855 } 856 else 857 DE_ASSERT(0); 858 859 src << "}\n"; // end main 860 861 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str()); 862 } 863 864 // Fragment shader 865 { 866 std::ostringstream src; 867 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 868 << "\n" 869 << "layout(location = 0) out vec4 o_color;\n" 870 << (geomOutputColor ? "layout(location = 0) in vec4 vert_color;\n" : "") 871 << "\n" 872 << "void main(void)\n" 873 << "{\n"; 874 875 if (params.testType == TEST_TYPE_LAYER_ID) 876 { 877 // This code must be in sync with verifyLayerContent() 878 src << " o_color = vec4( (gl_Layer % 2) == 1 ? 1.0 : 0.5,\n" 879 << " ((gl_Layer/2) % 2) == 1 ? 1.0 : 0.5,\n" 880 << " gl_Layer == 0 ? 1.0 : 0.0,\n" 881 << " 1.0);\n"; 882 } 883 else if (geomOutputColor) 884 src << " o_color = vert_color;\n"; 885 else 886 src << " o_color = vec4(1.0);\n"; 887 888 src << "}\n"; 889 890 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); 891 } 892} 893 894tcu::TestStatus test (Context& context, const TestParams params) 895{ 896 if (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType && 897 (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1"))) 898 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported"); 899 900 const DeviceInterface& vk = context.getDeviceInterface(); 901 const InstanceInterface& vki = context.getInstanceInterface(); 902 const VkDevice device = context.getDevice(); 903 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 904 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 905 const VkQueue queue = context.getUniversalQueue(); 906 Allocator& allocator = context.getDefaultAllocator(); 907 908 checkGeometryShaderSupport(vki, physDevice); 909 910 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 911 const deUint32 numLayers = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers); 912 const Vec4 clearColor = Vec4(0.0f, 0.0f, 0.0f, 1.0f); 913 const VkDeviceSize colorBufferSize = params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * tcu::getPixelSize(mapVkFormat(colorFormat)); 914 const VkImageCreateFlags imageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) | 915 (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageCreateFlagBits)0); 916 const VkImageViewType viewType = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType); 917 918 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size, 919 params.image.numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT))); 920 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any)); 921 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers))); 922 923 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); 924 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible)); 925 926 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u)); 927 const Unique<VkShaderModule> geometryModule (createShaderModule (vk, device, context.getBinaryCollection().get("geom"), 0u)); 928 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u)); 929 930 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat)); 931 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, params.image.size.width, params.image.size.height, numLayers)); 932 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device)); 933 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule, 934 makeExtent2D(params.image.size.width, params.image.size.height))); 935 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 936 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 937 938 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize); 939 940 beginCommandBuffer(vk, *cmdBuffer); 941 942 const VkClearValue clearValue = makeClearValueColor(clearColor); 943 const VkRect2D renderArea = 944 { 945 makeOffset2D(0, 0), 946 makeExtent2D(params.image.size.width, params.image.size.height), 947 }; 948 const VkRenderPassBeginInfo renderPassBeginInfo = 949 { 950 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 951 DE_NULL, // const void* pNext; 952 *renderPass, // VkRenderPass renderPass; 953 *framebuffer, // VkFramebuffer framebuffer; 954 renderArea, // VkRect2D renderArea; 955 1u, // uint32_t clearValueCount; 956 &clearValue, // const VkClearValue* pClearValues; 957 }; 958 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 959 960 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 961 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u); 962 vk.cmdEndRenderPass(*cmdBuffer); 963 964 // Prepare color image for copy 965 { 966 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers); 967 const VkImageMemoryBarrier barriers[] = 968 { 969 { 970 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 971 DE_NULL, // const void* pNext; 972 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask; 973 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask; 974 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 975 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 976 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 977 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 978 *colorImage, // VkImage image; 979 colorSubresourceRange, // VkImageSubresourceRange subresourceRange; 980 }, 981 }; 982 983 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 984 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers); 985 } 986 // Color image -> host buffer 987 { 988 const VkBufferImageCopy region = 989 { 990 0ull, // VkDeviceSize bufferOffset; 991 0u, // uint32_t bufferRowLength; 992 0u, // uint32_t bufferImageHeight; 993 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, params.image.numLayers), // VkImageSubresourceLayers imageSubresource; 994 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 995 params.image.size, // VkExtent3D imageExtent; 996 }; 997 998 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion); 999 } 1000 // Buffer write barrier 1001 { 1002 const VkBufferMemoryBarrier barriers[] = 1003 { 1004 { 1005 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1006 DE_NULL, // const void* pNext; 1007 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1008 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 1009 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 1010 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 1011 *colorBuffer, // VkBuffer buffer; 1012 0ull, // VkDeviceSize offset; 1013 VK_WHOLE_SIZE, // VkDeviceSize size; 1014 }, 1015 }; 1016 1017 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1018 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u); 1019 } 1020 1021 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1022 submitCommandsAndWait(vk, device, queue, *cmdBuffer); 1023 1024 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSize); 1025 1026 if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr())) 1027 return tcu::TestStatus::fail("Rendered images are incorrect"); 1028 else 1029 return tcu::TestStatus::pass("OK"); 1030} 1031 1032} // anonymous 1033 1034tcu::TestCaseGroup* createLayeredRenderingTests (tcu::TestContext& testCtx) 1035{ 1036 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "layered", "Layered rendering tests.")); 1037 1038 const struct 1039 { 1040 TestType test; 1041 const char* name; 1042 const char* description; 1043 } testTypes[] = 1044 { 1045 { TEST_TYPE_DEFAULT_LAYER, "render_to_default_layer", "Render to the default layer" }, 1046 { TEST_TYPE_SINGLE_LAYER, "render_to_one", "Render to one layer" }, 1047 { TEST_TYPE_ALL_LAYERS, "render_to_all", "Render to all layers" }, 1048 { TEST_TYPE_DIFFERENT_CONTENT, "render_different_content", "Render different data to different layers" }, 1049 { TEST_TYPE_LAYER_ID, "fragment_layer", "Read gl_Layer in fragment shader" }, 1050 { TEST_TYPE_INVOCATION_PER_LAYER, "invocation_per_layer", "Render to multiple layers with multiple invocations, one invocation per layer" }, 1051 { TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, "multiple_layers_per_invocation", "Render to multiple layers with multiple invocations, multiple layers per invocation", }, 1052 }; 1053 1054 const ImageParams imageParams[] = 1055 { 1056 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, { 64, 1, 1 }, 4 }, 1057 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, { 64, 64, 1 }, 4 }, 1058 { VK_IMAGE_VIEW_TYPE_CUBE, { 64, 64, 1 }, 6 }, 1059 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, { 64, 64, 1 }, 2*6 }, 1060 { VK_IMAGE_VIEW_TYPE_3D, { 64, 64, 8 }, 1 } 1061 }; 1062 1063 for (int imageParamNdx = 0; imageParamNdx < DE_LENGTH_OF_ARRAY(imageParams); ++imageParamNdx) 1064 { 1065 MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, getShortImageViewTypeName(imageParams[imageParamNdx].viewType).c_str(), "")); 1066 1067 for (int testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx) 1068 { 1069 const TestParams params = 1070 { 1071 testTypes[testTypeNdx].test, 1072 imageParams[imageParamNdx], 1073 }; 1074 addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, initPrograms, test, params); 1075 } 1076 1077 group->addChild(viewTypeGroup.release()); 1078 } 1079 1080 return group.release(); 1081} 1082 1083} // geometry 1084} // vkt 1085