1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2014 The Android Open Source Project 6 * Copyright (c) 2016 The Khronos Group Inc. 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 Utilities 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktGeometryTestsUtil.hpp" 26 #include "vkTypeUtil.hpp" 27 #include "vkDefs.hpp" 28 #include "tcuImageCompare.hpp" 29 30 #include "tcuImageIO.hpp" 31 32 #include "deMath.h" 33 34 using namespace vk; 35 36 namespace vkt 37 { 38 namespace geometry 39 { 40 41 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk, 42 const VkDevice device, 43 const VkShaderStageFlagBits stage, 44 const ProgramBinary& binary, 45 const VkSpecializationInfo* specInfo) 46 { 47 VkShaderModule module; 48 switch (stage) 49 { 50 case (VK_SHADER_STAGE_VERTEX_BIT): 51 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL); 52 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 53 module = *m_vertexShaderModule; 54 break; 55 56 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT): 57 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL); 58 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 59 module = *m_tessControlShaderModule; 60 break; 61 62 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT): 63 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL); 64 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 65 module = *m_tessEvaluationShaderModule; 66 break; 67 68 case (VK_SHADER_STAGE_GEOMETRY_BIT): 69 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL); 70 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 71 module = *m_geometryShaderModule; 72 break; 73 74 case (VK_SHADER_STAGE_FRAGMENT_BIT): 75 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL); 76 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 77 module = *m_fragmentShaderModule; 78 break; 79 80 default: 81 DE_FATAL("Invalid shader stage"); 82 return *this; 83 } 84 85 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo = 86 { 87 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 88 DE_NULL, // const void* pNext; 89 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 90 stage, // VkShaderStageFlagBits stage; 91 module, // VkShaderModule module; 92 "main", // const char* pName; 93 specInfo, // const VkSpecializationInfo* pSpecializationInfo; 94 }; 95 96 m_shaderStageFlags |= stage; 97 m_shaderStages.push_back(pipelineShaderStageInfo); 98 99 return *this; 100 } 101 102 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride) 103 { 104 const VkVertexInputBindingDescription bindingDesc = 105 { 106 0u, // uint32_t binding; 107 stride, // uint32_t stride; 108 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 109 }; 110 const VkVertexInputAttributeDescription attributeDesc = 111 { 112 0u, // uint32_t location; 113 0u, // uint32_t binding; 114 vertexFormat, // VkFormat format; 115 0u, // uint32_t offset; 116 }; 117 118 m_vertexInputBindings.clear(); 119 m_vertexInputBindings.push_back(bindingDesc); 120 121 m_vertexInputAttributes.clear(); 122 m_vertexInputAttributes.push_back(attributeDesc); 123 124 return *this; 125 } 126 127 template<typename T> 128 inline const T* dataPointer (const std::vector<T>& vec) 129 { 130 return (vec.size() != 0 ? &vec[0] : DE_NULL); 131 } 132 133 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk, 134 const VkDevice device, 135 const VkPipelineLayout pipelineLayout, 136 const VkRenderPass renderPass) 137 { 138 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 139 { 140 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 141 DE_NULL, // const void* pNext; 142 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 143 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount; 144 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 145 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount; 146 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 147 }; 148 149 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST 150 : m_primitiveTopology; 151 152 VkBool32 primitiveRestartEnable = VK_TRUE; 153 switch(m_primitiveTopology) 154 { 155 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 156 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 157 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 158 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 159 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 160 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: 161 primitiveRestartEnable = VK_FALSE; 162 break; 163 default: 164 break; 165 }; 166 167 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 168 { 169 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 170 DE_NULL, // const void* pNext; 171 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 172 topology, // VkPrimitiveTopology topology; 173 primitiveRestartEnable, // VkBool32 primitiveRestartEnable; 174 }; 175 176 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo = 177 { 178 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 179 DE_NULL, // const void* pNext; 180 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; 181 m_patchControlPoints, // uint32_t patchControlPoints; 182 }; 183 184 const VkViewport viewport = makeViewport( 185 0.0f, 0.0f, 186 static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()), 187 0.0f, 1.0f); 188 189 const VkRect2D scissor = { 190 makeOffset2D(0, 0), 191 makeExtent2D(m_renderSize.x(), m_renderSize.y()), 192 }; 193 194 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = 195 { 196 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 197 DE_NULL, // const void* pNext; 198 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 199 1u, // uint32_t viewportCount; 200 &viewport, // const VkViewport* pViewports; 201 1u, // uint32_t scissorCount; 202 &scissor, // const VkRect2D* pScissors; 203 }; 204 205 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0); 206 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 207 { 208 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 209 DE_NULL, // const void* pNext; 210 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 211 VK_FALSE, // VkBool32 depthClampEnable; 212 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable; 213 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 214 m_cullModeFlags, // VkCullModeFlags cullMode; 215 m_frontFace, // VkFrontFace frontFace; 216 VK_FALSE, // VkBool32 depthBiasEnable; 217 0.0f, // float depthBiasConstantFactor; 218 0.0f, // float depthBiasClamp; 219 0.0f, // float depthBiasSlopeFactor; 220 1.0f, // float lineWidth; 221 }; 222 223 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 224 { 225 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 226 DE_NULL, // const void* pNext; 227 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 228 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 229 VK_FALSE, // VkBool32 sampleShadingEnable; 230 0.0f, // float minSampleShading; 231 DE_NULL, // const VkSampleMask* pSampleMask; 232 VK_FALSE, // VkBool32 alphaToCoverageEnable; 233 VK_FALSE // VkBool32 alphaToOneEnable; 234 }; 235 236 const VkStencilOpState stencilOpState = makeStencilOpState( 237 VK_STENCIL_OP_KEEP, // stencil fail 238 VK_STENCIL_OP_KEEP, // depth & stencil pass 239 VK_STENCIL_OP_KEEP, // depth only fail 240 VK_COMPARE_OP_NEVER, // compare op 241 0u, // compare mask 242 0u, // write mask 243 0u); // reference 244 245 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 246 { 247 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 248 DE_NULL, // const void* pNext; 249 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 250 VK_FALSE, // VkBool32 depthTestEnable; 251 VK_FALSE, // VkBool32 depthWriteEnable; 252 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 253 VK_FALSE, // VkBool32 depthBoundsTestEnable; 254 VK_FALSE, // VkBool32 stencilTestEnable; 255 stencilOpState, // VkStencilOpState front; 256 stencilOpState, // VkStencilOpState back; 257 0.0f, // float minDepthBounds; 258 1.0f, // float maxDepthBounds; 259 }; 260 261 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 262 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 263 { 264 m_blendEnable, // VkBool32 blendEnable; 265 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 266 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor; 267 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 268 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; 269 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 270 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 271 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 272 }; 273 274 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 275 { 276 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 277 DE_NULL, // const void* pNext; 278 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 279 VK_FALSE, // VkBool32 logicOpEnable; 280 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 281 1u, // deUint32 attachmentCount; 282 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 283 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 284 }; 285 286 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = 287 { 288 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 289 DE_NULL, // const void* pNext; 290 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 291 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount; 292 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages; 293 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 294 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 295 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState; 296 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState; 297 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 298 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 299 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 300 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 301 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 302 pipelineLayout, // VkPipelineLayout layout; 303 renderPass, // VkRenderPass renderPass; 304 0u, // deUint32 subpass; 305 DE_NULL, // VkPipeline basePipelineHandle; 306 0, // deInt32 basePipelineIndex; 307 }; 308 309 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo); 310 } 311 312 std::string inputTypeToGLString (const VkPrimitiveTopology& inputType) 313 { 314 switch (inputType) 315 { 316 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 317 return "points"; 318 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 319 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 320 return "lines"; 321 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 322 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: 323 return "lines_adjacency"; 324 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 325 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 326 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: 327 return "triangles"; 328 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 329 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: 330 return "triangles_adjacency"; 331 default: 332 DE_ASSERT(DE_FALSE); 333 return "error"; 334 } 335 } 336 337 std::string outputTypeToGLString (const VkPrimitiveTopology& outputType) 338 { 339 switch (outputType) 340 { 341 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 342 return "points"; 343 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 344 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 345 return "line_strip"; 346 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 347 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 348 return "triangle_strip"; 349 default: 350 DE_ASSERT(DE_FALSE); 351 return "error"; 352 } 353 } 354 355 size_t calcOutputVertices (const VkPrimitiveTopology& inputType) 356 { 357 switch (inputType) 358 { 359 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 360 return 1 * 3; 361 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 362 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 363 return 2 * 3; 364 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 365 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: 366 return 4 * 3; 367 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 368 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 369 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: 370 return 3 * 3; 371 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 372 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: 373 return 6 * 3; 374 default: 375 DE_ASSERT(DE_FALSE); 376 return 0; 377 } 378 } 379 380 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, 381 const VkBufferUsageFlags usage) 382 { 383 const VkBufferCreateInfo bufferCreateInfo = 384 { 385 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 386 DE_NULL, // const void* pNext; 387 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags; 388 bufferSize, // VkDeviceSize size; 389 usage, // VkBufferUsageFlags usage; 390 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 391 0u, // deUint32 queueFamilyIndexCount; 392 DE_NULL, // const deUint32* pQueueFamilyIndices; 393 }; 394 return bufferCreateInfo; 395 } 396 397 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage, const deUint32 numArrayLayers) 398 { 399 const VkImageCreateInfo imageInfo = 400 { 401 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 402 DE_NULL, // const void* pNext; 403 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 404 VK_IMAGE_TYPE_2D, // VkImageType imageType; 405 format, // VkFormat format; 406 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent; 407 1u, // uint32_t mipLevels; 408 numArrayLayers, // uint32_t arrayLayers; 409 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 410 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 411 usage, // VkImageUsageFlags usage; 412 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 413 0u, // uint32_t queueFamilyIndexCount; 414 DE_NULL, // const uint32_t* pQueueFamilyIndices; 415 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 416 }; 417 return imageInfo; 418 } 419 420 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 421 const VkDevice device, 422 const VkDescriptorPool descriptorPool, 423 const VkDescriptorSetLayout setLayout) 424 { 425 const VkDescriptorSetAllocateInfo info = 426 { 427 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 428 DE_NULL, // const void* pNext; 429 descriptorPool, // VkDescriptorPool descriptorPool; 430 1u, // deUint32 descriptorSetCount; 431 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 432 }; 433 return allocateDescriptorSet(vk, device, &info); 434 } 435 436 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, const VkDevice device, const VkFormat colorFormat) 437 { 438 const VkAttachmentDescription colorAttachmentDescription = 439 { 440 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 441 colorFormat, // VkFormat format; 442 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 443 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 444 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 445 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 446 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 447 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 448 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 449 }; 450 451 const VkAttachmentReference colorAttachmentReference = 452 { 453 0u, // deUint32 attachment; 454 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 455 }; 456 457 const VkAttachmentReference depthAttachmentReference = 458 { 459 VK_ATTACHMENT_UNUSED, // deUint32 attachment; 460 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; 461 }; 462 463 const VkSubpassDescription subpassDescription = 464 { 465 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 466 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 467 0u, // deUint32 inputAttachmentCount; 468 DE_NULL, // const VkAttachmentReference* pInputAttachments; 469 1u, // deUint32 colorAttachmentCount; 470 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 471 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 472 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 473 0u, // deUint32 preserveAttachmentCount; 474 DE_NULL // const deUint32* pPreserveAttachments; 475 }; 476 477 const VkRenderPassCreateInfo renderPassInfo = 478 { 479 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 480 DE_NULL, // const void* pNext; 481 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 482 1u, // deUint32 attachmentCount; 483 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; 484 1u, // deUint32 subpassCount; 485 &subpassDescription, // const VkSubpassDescription* pSubpasses; 486 0u, // deUint32 dependencyCount; 487 DE_NULL // const VkSubpassDependency* pDependencies; 488 }; 489 490 return createRenderPass(vk, device, &renderPassInfo); 491 } 492 493 Move<VkImageView> makeImageView (const DeviceInterface& vk, 494 const VkDevice vkDevice, 495 const VkImage image, 496 const VkImageViewType viewType, 497 const VkFormat format, 498 const VkImageSubresourceRange subresourceRange) 499 { 500 const VkImageViewCreateInfo imageViewParams = 501 { 502 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 503 DE_NULL, // const void* pNext; 504 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags; 505 image, // VkImage image; 506 viewType, // VkImageViewType viewType; 507 format, // VkFormat format; 508 makeComponentMappingRGBA(), // VkComponentMapping components; 509 subresourceRange, // VkImageSubresourceRange subresourceRange; 510 }; 511 return createImageView(vk, vkDevice, &imageViewParams); 512 } 513 514 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent, 515 const VkImageSubresourceLayers subresourceLayers) 516 { 517 const VkBufferImageCopy copyParams = 518 { 519 0ull, // VkDeviceSize bufferOffset; 520 0u, // deUint32 bufferRowLength; 521 0u, // deUint32 bufferImageHeight; 522 subresourceLayers, // VkImageSubresourceLayers imageSubresource; 523 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 524 extent, // VkExtent3D imageExtent; 525 }; 526 return copyParams; 527 } 528 529 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 530 const VkDevice device, 531 const VkDescriptorSetLayout descriptorSetLayout) 532 { 533 const VkPipelineLayoutCreateInfo info = 534 { 535 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 536 DE_NULL, // const void* pNext; 537 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 538 (descriptorSetLayout != DE_NULL ? 1u : 0u), // deUint32 setLayoutCount; 539 (descriptorSetLayout != DE_NULL ? &descriptorSetLayout : DE_NULL), // const VkDescriptorSetLayout* pSetLayouts; 540 0u, // deUint32 pushConstantRangeCount; 541 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 542 }; 543 return createPipelineLayout(vk, device, &info); 544 } 545 546 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 547 const VkDevice device, 548 const VkRenderPass renderPass, 549 const VkImageView colorAttachment, 550 const deUint32 width, 551 const deUint32 height, 552 const deUint32 layers) 553 { 554 const VkFramebufferCreateInfo framebufferInfo = { 555 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 556 DE_NULL, // const void* pNext; 557 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 558 renderPass, // VkRenderPass renderPass; 559 1u, // uint32_t attachmentCount; 560 &colorAttachment, // const VkImageView* pAttachments; 561 width, // uint32_t width; 562 height, // uint32_t height; 563 layers, // uint32_t layers; 564 }; 565 566 return createFramebuffer(vk, device, &framebufferInfo); 567 } 568 569 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 570 const VkAccessFlags dstAccessMask, 571 const VkImageLayout oldLayout, 572 const VkImageLayout newLayout, 573 const VkImage image, 574 const VkImageSubresourceRange subresourceRange) 575 { 576 const VkImageMemoryBarrier barrier = 577 { 578 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 579 DE_NULL, // const void* pNext; 580 srcAccessMask, // VkAccessFlags outputMask; 581 dstAccessMask, // VkAccessFlags inputMask; 582 oldLayout, // VkImageLayout oldLayout; 583 newLayout, // VkImageLayout newLayout; 584 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 585 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 586 image, // VkImage image; 587 subresourceRange, // VkImageSubresourceRange subresourceRange; 588 }; 589 return barrier; 590 } 591 592 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, 593 const VkAccessFlags dstAccessMask, 594 const VkBuffer buffer, 595 const VkDeviceSize offset, 596 const VkDeviceSize bufferSizeBytes) 597 { 598 const VkBufferMemoryBarrier barrier = 599 { 600 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 601 DE_NULL, // const void* pNext; 602 srcAccessMask, // VkAccessFlags srcAccessMask; 603 dstAccessMask, // VkAccessFlags dstAccessMask; 604 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 605 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 606 buffer, // VkBuffer buffer; 607 offset, // VkDeviceSize offset; 608 bufferSizeBytes, // VkDeviceSize size; 609 }; 610 return barrier; 611 } 612 613 void beginRenderPass (const DeviceInterface& vk, 614 const VkCommandBuffer commandBuffer, 615 const VkRenderPass renderPass, 616 const VkFramebuffer framebuffer, 617 const VkRect2D& renderArea, 618 const tcu::Vec4& clearColor) 619 { 620 const VkClearValue clearValue = makeClearValueColor(clearColor); 621 622 const VkRenderPassBeginInfo renderPassBeginInfo = { 623 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 624 DE_NULL, // const void* pNext; 625 renderPass, // VkRenderPass renderPass; 626 framebuffer, // VkFramebuffer framebuffer; 627 renderArea, // VkRect2D renderArea; 628 1u, // uint32_t clearValueCount; 629 &clearValue, // const VkClearValue* pClearValues; 630 }; 631 632 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 633 } 634 635 void endRenderPass (const DeviceInterface& vk, 636 const VkCommandBuffer commandBuffer) 637 { 638 vk.cmdEndRenderPass(commandBuffer); 639 } 640 641 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 642 { 643 const VkCommandBufferBeginInfo info = 644 { 645 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 646 DE_NULL, // const void* pNext; 647 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 648 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 649 }; 650 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info)); 651 } 652 653 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 654 { 655 VK_CHECK(vk.endCommandBuffer(commandBuffer)); 656 } 657 658 void submitCommandsAndWait (const DeviceInterface& vk, 659 const VkDevice device, 660 const VkQueue queue, 661 const VkCommandBuffer commandBuffer) 662 { 663 const Unique<VkFence> fence(createFence(vk, device)); 664 665 const VkSubmitInfo submitInfo = 666 { 667 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 668 DE_NULL, // const void* pNext; 669 0u, // uint32_t waitSemaphoreCount; 670 DE_NULL, // const VkSemaphore* pWaitSemaphores; 671 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 672 1u, // uint32_t commandBufferCount; 673 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 674 0u, // uint32_t signalSemaphoreCount; 675 DE_NULL, // const VkSemaphore* pSignalSemaphores; 676 }; 677 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 678 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 679 } 680 681 bool compareWithFileImage (Context& context, const tcu::ConstPixelBufferAccess& resultImage, std::string testName) 682 { 683 tcu::TextureLevel referenceImage; 684 std::string fileName="vulkan/data/geometry/"+testName+".png"; 685 tcu::ImageIO::loadPNG(referenceImage, context.getTestContext().getArchive(), fileName.c_str()); 686 687 if (tcu::fuzzyCompare(context.getTestContext().getLog(), "ImageComparison", "Image Comparison", 688 referenceImage.getAccess(), resultImage, 0.001f, tcu::COMPARE_LOG_RESULT)) 689 return tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(), "ImageComparison", "Image Comparison", 690 referenceImage.getAccess(), resultImage, tcu::UVec4(1u, 1u, 1u, 1u), tcu::IVec3(2,2,2), false, tcu::COMPARE_LOG_RESULT); 691 else 692 return false; 693 } 694 695 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement) 696 { 697 de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement); 698 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset())); 699 return alloc; 700 } 701 702 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement) 703 { 704 de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement)); 705 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset())); 706 return alloc; 707 } 708 709 void zeroBuffer (const DeviceInterface& vk, const VkDevice device, const Allocation& alloc, const VkDeviceSize size) 710 { 711 deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(size)); 712 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), size); 713 } 714 715 VkBool32 checkPointSize (const InstanceInterface& vki, const VkPhysicalDevice physDevice) 716 { 717 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures (vki, physDevice); 718 return features.shaderTessellationAndGeometryPointSize; 719 } 720 721 void checkGeometryShaderSupport (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const int numGeometryShaderInvocations) 722 { 723 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures (vki, physDevice); 724 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits; 725 726 if (!features.geometryShader) 727 TCU_THROW(NotSupportedError, "Missing feature: geometryShader"); 728 729 if (numGeometryShaderInvocations != 0 && limits.maxGeometryShaderInvocations < static_cast<deUint32>(numGeometryShaderInvocations)) 730 TCU_THROW(NotSupportedError, ("Unsupported limit: maxGeometryShaderInvocations < " + de::toString(numGeometryShaderInvocations)).c_str()); 731 } 732 733 } //geometry 734 } //vkt 735