| /*------------------------------------------------------------------------- |
| * Vulkan CTS Framework |
| * -------------------- |
| * |
| * Copyright (c) 2021 The Khronos Group Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Vulkan SC utilities |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vkSafetyCriticalUtil.hpp" |
| #include <set> |
| |
| #ifdef CTS_USES_VULKANSC |
| |
| namespace vk |
| { |
| struct MemoryArea |
| { |
| MemoryArea(const void *data_, std::size_t size_) : data(data_), size(size_) |
| { |
| } |
| |
| const void *data; |
| std::size_t size; |
| }; |
| } // namespace vk |
| |
| namespace std |
| { |
| template <> |
| struct hash<vk::MemoryArea> |
| { |
| std::size_t operator()(const vk::MemoryArea &s) const noexcept |
| { |
| std::size_t seed = 0; |
| std::hash<unsigned char> hasher; |
| for (std::size_t i = 0; i < s.size; ++i) |
| { |
| unsigned char *v = (unsigned char *)s.data + i; |
| seed ^= hasher(*v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); |
| } |
| return seed; |
| } |
| }; |
| } // namespace std |
| |
| namespace vk |
| { |
| |
| VkDeviceObjectReservationCreateInfo resetDeviceObjectReservationCreateInfo() |
| { |
| VkDeviceObjectReservationCreateInfo result = { |
| VK_STRUCTURE_TYPE_DEVICE_OBJECT_RESERVATION_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // uint32_t pipelineCacheCreateInfoCount; |
| DE_NULL, // const VkPipelineCacheCreateInfo* pPipelineCacheCreateInfos; |
| 0u, // uint32_t pipelinePoolSizeCount; |
| DE_NULL, // const VkPipelinePoolSize* pPipelinePoolSizes; |
| 0u, // uint32_t semaphoreRequestCount; |
| 0u, // uint32_t commandBufferRequestCount; |
| 0u, // uint32_t fenceRequestCount; |
| 0u, // uint32_t deviceMemoryRequestCount; |
| 0u, // uint32_t bufferRequestCount; |
| 0u, // uint32_t imageRequestCount; |
| 0u, // uint32_t eventRequestCount; |
| 0u, // uint32_t queryPoolRequestCount; |
| 0u, // uint32_t bufferViewRequestCount; |
| 0u, // uint32_t imageViewRequestCount; |
| 0u, // uint32_t layeredImageViewRequestCount; |
| 0u, // uint32_t pipelineCacheRequestCount; |
| 0u, // uint32_t pipelineLayoutRequestCount; |
| 0u, // uint32_t renderPassRequestCount; |
| 0u, // uint32_t graphicsPipelineRequestCount; |
| 0u, // uint32_t computePipelineRequestCount; |
| 0u, // uint32_t descriptorSetLayoutRequestCount; |
| 0u, // uint32_t samplerRequestCount; |
| 0u, // uint32_t descriptorPoolRequestCount; |
| 0u, // uint32_t descriptorSetRequestCount; |
| 0u, // uint32_t framebufferRequestCount; |
| 0u, // uint32_t commandPoolRequestCount; |
| 0u, // uint32_t samplerYcbcrConversionRequestCount; |
| 0u, // uint32_t surfaceRequestCount; |
| 0u, // uint32_t swapchainRequestCount; |
| 0u, // uint32_t displayModeRequestCount; |
| 0u, // uint32_t subpassDescriptionRequestCount; |
| 0u, // uint32_t attachmentDescriptionRequestCount; |
| 0u, // uint32_t descriptorSetLayoutBindingRequestCount; |
| 0u, // uint32_t descriptorSetLayoutBindingLimit; |
| 0u, // uint32_t maxImageViewMipLevels; |
| 0u, // uint32_t maxImageViewArrayLayers; |
| 0u, // uint32_t maxLayeredImageViewMipLevels; |
| 0u, // uint32_t maxOcclusionQueriesPerPool; |
| 0u, // uint32_t maxPipelineStatisticsQueriesPerPool; |
| 0u, // uint32_t maxTimestampQueriesPerPool; |
| 0u, // uint32_t maxImmutableSamplersPerDescriptorSetLayout; |
| }; |
| return result; |
| } |
| |
| VkPipelineOfflineCreateInfo resetPipelineOfflineCreateInfo() |
| { |
| VkPipelineOfflineCreateInfo pipelineID = { |
| VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| {0}, // uint8_t pipelineIdentifier[VK_UUID_SIZE]; |
| VK_PIPELINE_MATCH_CONTROL_APPLICATION_UUID_EXACT_MATCH, // VkPipelineMatchControl matchControl; |
| 0u // VkDeviceSize poolEntrySize; |
| |
| }; |
| for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) |
| pipelineID.pipelineIdentifier[i] = 0U; |
| |
| return pipelineID; |
| } |
| |
| void applyPipelineIdentifier(VkPipelineOfflineCreateInfo &pipelineID, const std::string &value) |
| { |
| for (uint32_t i = 0; i < VK_UUID_SIZE && i < value.size(); ++i) |
| pipelineID.pipelineIdentifier[i] = uint8_t(value[i]); |
| } |
| |
| VkPhysicalDeviceVulkanSC10Features createDefaultSC10Features() |
| { |
| VkPhysicalDeviceVulkanSC10Features result = { |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES, // VkStructureType sType; |
| DE_NULL, // void* pNext; |
| VK_FALSE // VkBool32 shaderAtomicInstructions; |
| }; |
| return result; |
| } |
| |
| void hashPNextChain(std::size_t &seed, const void *pNext, const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| VkBaseInStructure *pBase = (VkBaseInStructure *)pNext; |
| if (pNext != DE_NULL) |
| { |
| switch (pBase->sType) |
| { |
| case VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT: |
| { |
| VkAttachmentDescriptionStencilLayout *ptr = (VkAttachmentDescriptionStencilLayout *)pNext; |
| hash_combine(seed, uint32_t(ptr->stencilInitialLayout), uint32_t(ptr->stencilFinalLayout)); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO: |
| { |
| VkDescriptorSetLayoutBindingFlagsCreateInfo *ptr = (VkDescriptorSetLayoutBindingFlagsCreateInfo *)pNext; |
| if (ptr->pBindingFlags != DE_NULL) |
| for (uint32_t i = 0; i < ptr->bindingCount; ++i) |
| hash_combine(seed, ptr->pBindingFlags[i]); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT: |
| { |
| VkPipelineColorBlendAdvancedStateCreateInfoEXT *ptr = |
| (VkPipelineColorBlendAdvancedStateCreateInfoEXT *)pNext; |
| hash_combine(seed, ptr->srcPremultiplied, ptr->dstPremultiplied, uint32_t(ptr->blendOverlap)); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT: |
| { |
| VkPipelineColorWriteCreateInfoEXT *ptr = (VkPipelineColorWriteCreateInfoEXT *)pNext; |
| if (ptr->pColorWriteEnables != DE_NULL) |
| for (uint32_t i = 0; i < ptr->attachmentCount; ++i) |
| hash_combine(seed, ptr->pColorWriteEnables[i]); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT: |
| { |
| VkPipelineDiscardRectangleStateCreateInfoEXT *ptr = (VkPipelineDiscardRectangleStateCreateInfoEXT *)pNext; |
| hash_combine(seed, ptr->flags, uint32_t(ptr->discardRectangleMode)); |
| if (ptr->pDiscardRectangles != DE_NULL) |
| for (uint32_t i = 0; i < ptr->discardRectangleCount; ++i) |
| hash_combine(seed, ptr->pDiscardRectangles[i].offset.x, ptr->pDiscardRectangles[i].offset.y, |
| ptr->pDiscardRectangles[i].extent.width, ptr->pDiscardRectangles[i].extent.height); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR: |
| { |
| VkPipelineFragmentShadingRateStateCreateInfoKHR *ptr = |
| (VkPipelineFragmentShadingRateStateCreateInfoKHR *)pNext; |
| hash_combine(seed, ptr->fragmentSize.width, ptr->fragmentSize.height, uint32_t(ptr->combinerOps[0]), |
| uint32_t(ptr->combinerOps[1])); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT: |
| { |
| VkPipelineRasterizationConservativeStateCreateInfoEXT *ptr = |
| (VkPipelineRasterizationConservativeStateCreateInfoEXT *)pNext; |
| hash_combine(seed, ptr->flags, uint32_t(ptr->conservativeRasterizationMode), |
| ptr->extraPrimitiveOverestimationSize); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: |
| { |
| VkPipelineRasterizationDepthClipStateCreateInfoEXT *ptr = |
| (VkPipelineRasterizationDepthClipStateCreateInfoEXT *)pNext; |
| hash_combine(seed, ptr->flags, ptr->depthClipEnable); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT: |
| { |
| VkPipelineRasterizationLineStateCreateInfoEXT *ptr = (VkPipelineRasterizationLineStateCreateInfoEXT *)pNext; |
| hash_combine(seed, uint32_t(ptr->lineRasterizationMode), ptr->stippledLineEnable, ptr->lineStippleFactor, |
| ptr->lineStipplePattern); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT: |
| { |
| VkPipelineSampleLocationsStateCreateInfoEXT *ptr = (VkPipelineSampleLocationsStateCreateInfoEXT *)pNext; |
| hash_combine(seed, ptr->sampleLocationsEnable, uint32_t(ptr->sampleLocationsInfo.sampleLocationsPerPixel), |
| ptr->sampleLocationsInfo.sampleLocationGridSize.width, |
| ptr->sampleLocationsInfo.sampleLocationGridSize.height); |
| if (ptr->sampleLocationsInfo.pSampleLocations != DE_NULL) |
| for (uint32_t i = 0; i < ptr->sampleLocationsInfo.sampleLocationsCount; ++i) |
| hash_combine(seed, ptr->sampleLocationsInfo.pSampleLocations[i].x, |
| ptr->sampleLocationsInfo.pSampleLocations[i].y); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT: |
| { |
| VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT *ptr = |
| (VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT *)pNext; |
| hash_combine(seed, ptr->requiredSubgroupSize); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO: |
| { |
| VkPipelineTessellationDomainOriginStateCreateInfo *ptr = |
| (VkPipelineTessellationDomainOriginStateCreateInfo *)pNext; |
| hash_combine(seed, uint32_t(ptr->domainOrigin)); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT: |
| { |
| VkPipelineVertexInputDivisorStateCreateInfoEXT *ptr = |
| (VkPipelineVertexInputDivisorStateCreateInfoEXT *)pNext; |
| if (ptr->pVertexBindingDivisors != DE_NULL) |
| for (uint32_t i = 0; i < ptr->vertexBindingDivisorCount; ++i) |
| hash_combine(seed, ptr->pVertexBindingDivisors[i].binding, ptr->pVertexBindingDivisors[i].divisor); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO: |
| { |
| VkRenderPassInputAttachmentAspectCreateInfo *ptr = (VkRenderPassInputAttachmentAspectCreateInfo *)pNext; |
| if (ptr->pAspectReferences != DE_NULL) |
| for (uint32_t i = 0; i < ptr->aspectReferenceCount; ++i) |
| hash_combine(seed, ptr->pAspectReferences[i].subpass, |
| ptr->pAspectReferences[i].inputAttachmentIndex, ptr->pAspectReferences[i].aspectMask); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: |
| { |
| VkRenderPassMultiviewCreateInfo *ptr = (VkRenderPassMultiviewCreateInfo *)pNext; |
| if (ptr->pViewMasks != DE_NULL) |
| for (uint32_t i = 0; i < ptr->subpassCount; ++i) |
| hash_combine(seed, ptr->pViewMasks[i]); |
| if (ptr->pViewOffsets != DE_NULL) |
| for (uint32_t i = 0; i < ptr->dependencyCount; ++i) |
| hash_combine(seed, ptr->pViewOffsets[i]); |
| if (ptr->pCorrelationMasks != DE_NULL) |
| for (uint32_t i = 0; i < ptr->correlationMaskCount; ++i) |
| hash_combine(seed, ptr->pCorrelationMasks[i]); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT: |
| { |
| VkSamplerCustomBorderColorCreateInfoEXT *ptr = (VkSamplerCustomBorderColorCreateInfoEXT *)pNext; |
| for (uint32_t i = 0; i < 4; ++i) |
| hash_combine(seed, ptr->customBorderColor.uint32[i]); |
| hash_combine(seed, uint32_t(ptr->format)); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO: |
| { |
| VkSamplerReductionModeCreateInfo *ptr = (VkSamplerReductionModeCreateInfo *)pNext; |
| hash_combine(seed, uint32_t(ptr->reductionMode)); |
| break; |
| } |
| case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO: |
| { |
| VkSamplerYcbcrConversionInfo *ptr = (VkSamplerYcbcrConversionInfo *)pNext; |
| { |
| auto it = objectHashes.find(ptr->conversion.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| break; |
| } |
| default: |
| break; |
| } |
| hashPNextChain(seed, pBase->pNext, objectHashes); |
| } |
| } |
| |
| bool graphicsPipelineHasDynamicState(const VkGraphicsPipelineCreateInfo &gpCI, VkDynamicState state) |
| { |
| if (gpCI.pDynamicState == DE_NULL) |
| return false; |
| |
| if (gpCI.pDynamicState->pDynamicStates == DE_NULL) |
| return false; |
| |
| for (uint32_t i = 0; i < gpCI.pDynamicState->dynamicStateCount; ++i) |
| if (gpCI.pDynamicState->pDynamicStates[i] == state) |
| return true; |
| |
| return false; |
| } |
| |
| std::size_t calculateGraphicsPipelineHash(const VkGraphicsPipelineCreateInfo &gpCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| |
| hashPNextChain(seed, gpCI.pNext, objectHashes); |
| |
| hash_combine(seed, gpCI.flags); |
| |
| bool vertexInputStateRequired = false; |
| bool inputAssemblyStateRequired = false; |
| bool tessellationStateRequired = false; |
| bool viewportStateRequired = false; |
| bool viewportStateViewportsRequired = false; |
| bool viewportStateScissorsRequired = false; |
| bool multiSampleStateRequired = false; |
| bool depthStencilStateRequired = false; |
| bool colorBlendStateRequired = false; |
| |
| if (gpCI.pStages != DE_NULL) |
| { |
| for (uint32_t i = 0; i < gpCI.stageCount; ++i) |
| { |
| hashPNextChain(seed, gpCI.pStages[i].pNext, objectHashes); |
| |
| hash_combine(seed, uint32_t(gpCI.pStages[i].flags), uint32_t(gpCI.pStages[i].stage)); |
| auto it = objectHashes.find(gpCI.pStages[i].module.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| |
| hash_combine(seed, std::string(gpCI.pStages[i].pName)); |
| |
| if (gpCI.pStages[i].pSpecializationInfo != DE_NULL) |
| { |
| if (gpCI.pStages[i].pSpecializationInfo->pMapEntries != DE_NULL) |
| { |
| for (uint32_t j = 0; j < gpCI.pStages[i].pSpecializationInfo->mapEntryCount; ++j) |
| hash_combine(seed, gpCI.pStages[i].pSpecializationInfo->pMapEntries[j].constantID, |
| gpCI.pStages[i].pSpecializationInfo->pMapEntries[j].offset, |
| gpCI.pStages[i].pSpecializationInfo->pMapEntries[j].size); |
| |
| hash_combine(seed, MemoryArea(gpCI.pStages[i].pSpecializationInfo->pData, |
| gpCI.pStages[i].pSpecializationInfo->dataSize)); |
| } |
| } |
| if (gpCI.pStages[i].stage == VK_SHADER_STAGE_VERTEX_BIT) |
| { |
| vertexInputStateRequired = true; |
| inputAssemblyStateRequired = true; |
| } |
| if (gpCI.pStages[i].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) |
| { |
| tessellationStateRequired = true; |
| } |
| } |
| } |
| if (gpCI.pDynamicState != DE_NULL) |
| { |
| if (gpCI.pDynamicState->pDynamicStates != DE_NULL) |
| for (uint32_t i = 0; i < gpCI.pDynamicState->dynamicStateCount; ++i) |
| { |
| if (gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_VIEWPORT || |
| gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT) |
| { |
| viewportStateRequired = true; |
| viewportStateViewportsRequired = true; |
| } |
| if (gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_SCISSOR || |
| gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT) |
| { |
| viewportStateRequired = true; |
| viewportStateScissorsRequired = true; |
| } |
| if (gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT) |
| viewportStateRequired = true; |
| } |
| } |
| if (gpCI.pRasterizationState != DE_NULL) |
| { |
| if (gpCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE) |
| { |
| viewportStateRequired = true; |
| viewportStateViewportsRequired = true; |
| viewportStateScissorsRequired = true; |
| multiSampleStateRequired = true; |
| depthStencilStateRequired = true; |
| colorBlendStateRequired = true; |
| } |
| } |
| |
| if (vertexInputStateRequired && gpCI.pVertexInputState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pVertexInputState->pNext, objectHashes); |
| hash_combine(seed, gpCI.pVertexInputState->flags); |
| if (gpCI.pVertexInputState->pVertexBindingDescriptions != DE_NULL) |
| for (uint32_t i = 0; i < gpCI.pVertexInputState->vertexBindingDescriptionCount; ++i) |
| hash_combine(seed, gpCI.pVertexInputState->pVertexBindingDescriptions[i].binding, |
| gpCI.pVertexInputState->pVertexBindingDescriptions[i].stride, |
| uint32_t(gpCI.pVertexInputState->pVertexBindingDescriptions[i].inputRate)); |
| if (gpCI.pVertexInputState->pVertexAttributeDescriptions != DE_NULL) |
| for (uint32_t i = 0; i < gpCI.pVertexInputState->vertexAttributeDescriptionCount; ++i) |
| hash_combine(seed, gpCI.pVertexInputState->pVertexAttributeDescriptions[i].location, |
| gpCI.pVertexInputState->pVertexAttributeDescriptions[i].binding, |
| uint32_t(gpCI.pVertexInputState->pVertexAttributeDescriptions[i].format), |
| gpCI.pVertexInputState->pVertexAttributeDescriptions[i].offset); |
| } |
| |
| if (inputAssemblyStateRequired && gpCI.pInputAssemblyState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pInputAssemblyState->pNext, objectHashes); |
| hash_combine(seed, uint32_t(gpCI.pInputAssemblyState->flags), uint32_t(gpCI.pInputAssemblyState->topology), |
| gpCI.pInputAssemblyState->primitiveRestartEnable); |
| } |
| if (tessellationStateRequired && gpCI.pTessellationState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pTessellationState->pNext, objectHashes); |
| hash_combine(seed, gpCI.pTessellationState->flags, gpCI.pTessellationState->patchControlPoints); |
| } |
| if (viewportStateRequired && gpCI.pViewportState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pViewportState->pNext, objectHashes); |
| hash_combine(seed, gpCI.pViewportState->flags); |
| |
| if (viewportStateViewportsRequired && gpCI.pViewportState->pViewports != DE_NULL) |
| for (uint32_t i = 0; i < gpCI.pViewportState->viewportCount; ++i) |
| hash_combine(seed, gpCI.pViewportState->pViewports[i].x, gpCI.pViewportState->pViewports[i].y, |
| gpCI.pViewportState->pViewports[i].width, gpCI.pViewportState->pViewports[i].height, |
| gpCI.pViewportState->pViewports[i].minDepth, gpCI.pViewportState->pViewports[i].maxDepth); |
| |
| if (viewportStateScissorsRequired && gpCI.pViewportState->pScissors != DE_NULL) |
| for (uint32_t i = 0; i < gpCI.pViewportState->scissorCount; ++i) |
| hash_combine(seed, gpCI.pViewportState->pScissors[i].offset.x, |
| gpCI.pViewportState->pScissors[i].offset.y, gpCI.pViewportState->pScissors[i].extent.width, |
| gpCI.pViewportState->pScissors[i].extent.height); |
| } |
| if (gpCI.pRasterizationState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pRasterizationState->pNext, objectHashes); |
| hash_combine(seed, uint32_t(gpCI.pRasterizationState->flags), gpCI.pRasterizationState->depthClampEnable, |
| gpCI.pRasterizationState->rasterizerDiscardEnable, uint32_t(gpCI.pRasterizationState->polygonMode), |
| uint32_t(gpCI.pRasterizationState->cullMode), uint32_t(gpCI.pRasterizationState->frontFace), |
| gpCI.pRasterizationState->depthBiasEnable, gpCI.pRasterizationState->depthBiasConstantFactor, |
| gpCI.pRasterizationState->depthBiasClamp, gpCI.pRasterizationState->depthBiasSlopeFactor, |
| gpCI.pRasterizationState->lineWidth); |
| } |
| if (multiSampleStateRequired && gpCI.pMultisampleState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pMultisampleState->pNext, objectHashes); |
| hash_combine(seed, uint32_t(gpCI.pMultisampleState->flags), |
| uint32_t(gpCI.pMultisampleState->rasterizationSamples), |
| gpCI.pMultisampleState->sampleShadingEnable, gpCI.pMultisampleState->minSampleShading); |
| if (gpCI.pMultisampleState->pSampleMask != DE_NULL) |
| for (int i = 0; i < ((gpCI.pMultisampleState->rasterizationSamples + 31) / 32); i++) |
| hash_combine(seed, gpCI.pMultisampleState->pSampleMask[i]); |
| hash_combine(seed, gpCI.pMultisampleState->alphaToCoverageEnable, gpCI.pMultisampleState->alphaToOneEnable); |
| } |
| if (depthStencilStateRequired && gpCI.pDepthStencilState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pDepthStencilState->pNext, objectHashes); |
| hash_combine(seed, uint32_t(gpCI.pDepthStencilState->flags), gpCI.pDepthStencilState->depthTestEnable, |
| gpCI.pDepthStencilState->depthWriteEnable, uint32_t(gpCI.pDepthStencilState->depthCompareOp), |
| gpCI.pDepthStencilState->depthBoundsTestEnable, gpCI.pDepthStencilState->stencilTestEnable); |
| if (gpCI.pDepthStencilState->stencilTestEnable) |
| { |
| hash_combine(seed, uint32_t(gpCI.pDepthStencilState->front.failOp), |
| uint32_t(gpCI.pDepthStencilState->front.passOp), |
| uint32_t(gpCI.pDepthStencilState->front.depthFailOp), |
| uint32_t(gpCI.pDepthStencilState->front.compareOp), gpCI.pDepthStencilState->front.compareMask, |
| gpCI.pDepthStencilState->front.writeMask, gpCI.pDepthStencilState->front.reference); |
| hash_combine(seed, uint32_t(gpCI.pDepthStencilState->back.failOp), |
| uint32_t(gpCI.pDepthStencilState->back.passOp), |
| uint32_t(gpCI.pDepthStencilState->back.depthFailOp), |
| uint32_t(gpCI.pDepthStencilState->back.compareOp), gpCI.pDepthStencilState->back.compareMask, |
| gpCI.pDepthStencilState->back.writeMask, gpCI.pDepthStencilState->back.reference); |
| } |
| hash_combine(seed, gpCI.pDepthStencilState->minDepthBounds, gpCI.pDepthStencilState->maxDepthBounds); |
| } |
| if (colorBlendStateRequired && gpCI.pColorBlendState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pColorBlendState->pNext, objectHashes); |
| hash_combine(seed, uint32_t(gpCI.pColorBlendState->flags), gpCI.pColorBlendState->logicOpEnable, |
| uint32_t(gpCI.pColorBlendState->logicOp)); |
| |
| bool hashBlendConstants = false; |
| std::set<VkBlendFactor> constFactors = { |
| VK_BLEND_FACTOR_CONSTANT_COLOR, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, VK_BLEND_FACTOR_CONSTANT_ALPHA, |
| VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA}; |
| if (gpCI.pColorBlendState->pAttachments != DE_NULL) |
| { |
| for (uint32_t i = 0; i < gpCI.pColorBlendState->attachmentCount; ++i) |
| { |
| hash_combine(seed, gpCI.pColorBlendState->pAttachments[i].blendEnable, |
| uint32_t(gpCI.pColorBlendState->pAttachments[i].srcColorBlendFactor), |
| uint32_t(gpCI.pColorBlendState->pAttachments[i].dstColorBlendFactor), |
| uint32_t(gpCI.pColorBlendState->pAttachments[i].colorBlendOp), |
| uint32_t(gpCI.pColorBlendState->pAttachments[i].srcAlphaBlendFactor), |
| uint32_t(gpCI.pColorBlendState->pAttachments[i].dstAlphaBlendFactor), |
| uint32_t(gpCI.pColorBlendState->pAttachments[i].alphaBlendOp), |
| uint32_t(gpCI.pColorBlendState->pAttachments[i].colorWriteMask)); |
| if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].srcColorBlendFactor) != end(constFactors)) |
| hashBlendConstants = true; |
| if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].dstColorBlendFactor) != end(constFactors)) |
| hashBlendConstants = true; |
| if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].srcAlphaBlendFactor) != end(constFactors)) |
| hashBlendConstants = true; |
| if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].dstAlphaBlendFactor) != end(constFactors)) |
| hashBlendConstants = true; |
| } |
| } |
| // omit blendConstants when VK_DYNAMIC_STATE_BLEND_CONSTANTS is present |
| if (hashBlendConstants && !graphicsPipelineHasDynamicState(gpCI, VK_DYNAMIC_STATE_BLEND_CONSTANTS)) |
| for (uint32_t i = 0; i < 4; ++i) |
| hash_combine(seed, gpCI.pColorBlendState->blendConstants[i]); |
| } |
| if (gpCI.pDynamicState != DE_NULL) |
| { |
| hashPNextChain(seed, gpCI.pDynamicState->pNext, objectHashes); |
| hash_combine(seed, gpCI.pDynamicState->flags); |
| if (gpCI.pDynamicState->pDynamicStates != DE_NULL) |
| for (uint32_t i = 0; i < gpCI.pDynamicState->dynamicStateCount; ++i) |
| hash_combine(seed, uint32_t(gpCI.pDynamicState->pDynamicStates[i])); |
| } |
| |
| { |
| auto it = objectHashes.find(gpCI.layout.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| |
| { |
| auto it = objectHashes.find(gpCI.renderPass.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| |
| hash_combine(seed, gpCI.subpass); |
| |
| { |
| auto it = objectHashes.find(gpCI.basePipelineHandle.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| hash_combine(seed, gpCI.basePipelineIndex); |
| |
| return seed; |
| } |
| |
| std::size_t calculateComputePipelineHash(const VkComputePipelineCreateInfo &cpCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| |
| hashPNextChain(seed, cpCI.pNext, objectHashes); |
| |
| hash_combine(seed, cpCI.flags); |
| |
| { |
| hash_combine(seed, uint32_t(cpCI.stage.flags), uint32_t(cpCI.stage.stage)); |
| auto it = objectHashes.find(cpCI.stage.module.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| |
| hash_combine(seed, std::string(cpCI.stage.pName)); |
| |
| if (cpCI.stage.pSpecializationInfo != DE_NULL) |
| { |
| if (cpCI.stage.pSpecializationInfo->pMapEntries != DE_NULL) |
| { |
| for (uint32_t j = 0; j < cpCI.stage.pSpecializationInfo->mapEntryCount; ++j) |
| hash_combine(seed, cpCI.stage.pSpecializationInfo->pMapEntries[j].constantID, |
| cpCI.stage.pSpecializationInfo->pMapEntries[j].offset, |
| cpCI.stage.pSpecializationInfo->pMapEntries[j].size); |
| |
| hash_combine( |
| seed, MemoryArea(cpCI.stage.pSpecializationInfo->pData, cpCI.stage.pSpecializationInfo->dataSize)); |
| } |
| } |
| } |
| |
| { |
| auto it = objectHashes.find(cpCI.layout.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| |
| { |
| auto it = objectHashes.find(cpCI.basePipelineHandle.getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| hash_combine(seed, cpCI.basePipelineIndex); |
| |
| return seed; |
| } |
| |
| std::size_t calculateSamplerYcbcrConversionHash(const VkSamplerYcbcrConversionCreateInfo &scCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| DE_UNREF(objectHashes); |
| std::size_t seed = 0; |
| hashPNextChain(seed, scCI.pNext, objectHashes); |
| hash_combine(seed, uint32_t(scCI.format), uint32_t(scCI.ycbcrModel), uint32_t(scCI.ycbcrRange), |
| uint32_t(scCI.components.r), uint32_t(scCI.components.g), uint32_t(scCI.components.b), |
| uint32_t(scCI.components.a), uint32_t(scCI.xChromaOffset), uint32_t(scCI.yChromaOffset), |
| uint32_t(scCI.chromaFilter), scCI.forceExplicitReconstruction); |
| return seed; |
| } |
| |
| std::size_t calculateSamplerHash(const VkSamplerCreateInfo &sCI, const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| hashPNextChain(seed, sCI.pNext, objectHashes); |
| hash_combine(seed, uint32_t(sCI.flags), uint32_t(sCI.magFilter), uint32_t(sCI.minFilter), uint32_t(sCI.mipmapMode), |
| uint32_t(sCI.addressModeU), uint32_t(sCI.addressModeV), uint32_t(sCI.addressModeW), sCI.mipLodBias, |
| sCI.anisotropyEnable, sCI.maxAnisotropy, sCI.compareEnable, uint32_t(sCI.compareOp), sCI.minLod, |
| sCI.maxLod, uint32_t(sCI.borderColor), sCI.unnormalizedCoordinates); |
| return seed; |
| } |
| |
| std::size_t calculateDescriptorSetLayoutHash(const VkDescriptorSetLayoutCreateInfo &sCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| |
| hashPNextChain(seed, sCI.pNext, objectHashes); |
| |
| hash_combine(seed, uint32_t(sCI.flags)); |
| if (sCI.pBindings != DE_NULL) |
| { |
| for (uint32_t i = 0; i < sCI.bindingCount; ++i) |
| { |
| hash_combine(seed, sCI.pBindings[i].binding, uint32_t(sCI.pBindings[i].descriptorType), |
| sCI.pBindings[i].descriptorCount, uint32_t(sCI.pBindings[i].stageFlags)); |
| if (sCI.pBindings[i].pImmutableSamplers != DE_NULL) |
| { |
| for (uint32_t j = 0; j < sCI.pBindings[i].descriptorCount; ++j) |
| { |
| auto it = objectHashes.find(sCI.pBindings[i].pImmutableSamplers[j].getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| } |
| } |
| } |
| return seed; |
| } |
| |
| std::size_t calculatePipelineLayoutHash(const VkPipelineLayoutCreateInfo &pCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| |
| hashPNextChain(seed, pCI.pNext, objectHashes); |
| |
| hash_combine(seed, uint32_t(pCI.flags)); |
| |
| if (pCI.pSetLayouts != DE_NULL) |
| { |
| for (uint32_t i = 0; i < pCI.setLayoutCount; ++i) |
| { |
| auto it = objectHashes.find(pCI.pSetLayouts[i].getInternal()); |
| if (it != end(objectHashes)) |
| hash_combine(seed, it->second); |
| } |
| } |
| if (pCI.pPushConstantRanges != DE_NULL) |
| { |
| for (uint32_t i = 0; i < pCI.pushConstantRangeCount; ++i) |
| { |
| hash_combine(seed, uint32_t(pCI.pPushConstantRanges[i].stageFlags)); |
| hash_combine(seed, pCI.pPushConstantRanges[i].offset); |
| hash_combine(seed, pCI.pPushConstantRanges[i].size); |
| } |
| } |
| |
| return seed; |
| } |
| |
| std::size_t calculateShaderModuleHash(const VkShaderModuleCreateInfo &sCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| |
| hashPNextChain(seed, sCI.pNext, objectHashes); |
| |
| hash_combine(seed, uint32_t(sCI.flags)); |
| hash_combine(seed, MemoryArea(sCI.pCode, sCI.codeSize)); |
| |
| return seed; |
| } |
| |
| std::size_t calculateRenderPassHash(const VkRenderPassCreateInfo &rCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| |
| hashPNextChain(seed, rCI.pNext, objectHashes); |
| |
| hash_combine(seed, uint32_t(rCI.flags)); |
| |
| if (rCI.pAttachments != DE_NULL) |
| for (uint32_t i = 0; i < rCI.attachmentCount; ++i) |
| hash_combine(seed, uint32_t(rCI.pAttachments[i].flags), uint32_t(rCI.pAttachments[i].format), |
| uint32_t(rCI.pAttachments[i].samples), uint32_t(rCI.pAttachments[i].loadOp), |
| uint32_t(rCI.pAttachments[i].storeOp), uint32_t(rCI.pAttachments[i].stencilLoadOp), |
| uint32_t(rCI.pAttachments[i].stencilStoreOp), uint32_t(rCI.pAttachments[i].initialLayout), |
| uint32_t(rCI.pAttachments[i].finalLayout)); |
| |
| if (rCI.pSubpasses != DE_NULL) |
| { |
| for (uint32_t i = 0; i < rCI.subpassCount; ++i) |
| { |
| hash_combine(seed, uint32_t(rCI.pSubpasses[i].flags), uint32_t(rCI.pSubpasses[i].pipelineBindPoint)); |
| if (rCI.pSubpasses[i].pInputAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].inputAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pInputAttachments[j].attachment, |
| uint32_t(rCI.pSubpasses[i].pInputAttachments[j].layout)); |
| if (rCI.pSubpasses[i].pColorAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pColorAttachments[j].attachment, |
| uint32_t(rCI.pSubpasses[i].pColorAttachments[j].layout)); |
| if (rCI.pSubpasses[i].pResolveAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pResolveAttachments[j].attachment, |
| uint32_t(rCI.pSubpasses[i].pResolveAttachments[j].layout)); |
| if (rCI.pSubpasses[i].pDepthStencilAttachment != DE_NULL) |
| hash_combine(seed, rCI.pSubpasses[i].pDepthStencilAttachment->attachment, |
| uint32_t(rCI.pSubpasses[i].pDepthStencilAttachment->layout)); |
| if (rCI.pSubpasses[i].pPreserveAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].preserveAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pPreserveAttachments[j]); |
| } |
| } |
| if (rCI.pDependencies != DE_NULL) |
| for (uint32_t i = 0; i < rCI.dependencyCount; ++i) |
| hash_combine(seed, rCI.pDependencies[i].srcSubpass, rCI.pDependencies[i].dstSubpass, |
| uint32_t(rCI.pDependencies[i].srcStageMask), uint32_t(rCI.pDependencies[i].dstStageMask), |
| uint64_t(rCI.pDependencies[i].srcAccessMask), uint64_t(rCI.pDependencies[i].dstAccessMask), |
| uint32_t(rCI.pDependencies[i].dependencyFlags)); |
| |
| return seed; |
| } |
| |
| std::size_t calculateRenderPass2Hash(const VkRenderPassCreateInfo2 &rCI, |
| const std::map<uint64_t, std::size_t> &objectHashes) |
| { |
| std::size_t seed = 0; |
| |
| hashPNextChain(seed, rCI.pNext, objectHashes); |
| |
| hash_combine(seed, rCI.flags); |
| |
| if (rCI.pAttachments != DE_NULL) |
| for (uint32_t i = 0; i < rCI.attachmentCount; ++i) |
| hash_combine(seed, uint32_t(rCI.pAttachments[i].flags), uint32_t(rCI.pAttachments[i].format), |
| uint32_t(rCI.pAttachments[i].samples), uint32_t(rCI.pAttachments[i].loadOp), |
| uint32_t(rCI.pAttachments[i].storeOp), uint32_t(rCI.pAttachments[i].stencilLoadOp), |
| uint32_t(rCI.pAttachments[i].stencilStoreOp), uint32_t(rCI.pAttachments[i].initialLayout), |
| uint32_t(rCI.pAttachments[i].finalLayout)); |
| |
| if (rCI.pSubpasses != DE_NULL) |
| { |
| for (uint32_t i = 0; i < rCI.subpassCount; ++i) |
| { |
| hash_combine(seed, uint32_t(rCI.pSubpasses[i].flags), uint32_t(rCI.pSubpasses[i].pipelineBindPoint)); |
| if (rCI.pSubpasses[i].pInputAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].inputAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pInputAttachments[j].attachment, |
| uint32_t(rCI.pSubpasses[i].pInputAttachments[j].layout)); |
| if (rCI.pSubpasses[i].pColorAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pColorAttachments[j].attachment, |
| uint32_t(rCI.pSubpasses[i].pColorAttachments[j].layout)); |
| if (rCI.pSubpasses[i].pResolveAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pResolveAttachments[j].attachment, |
| uint32_t(rCI.pSubpasses[i].pResolveAttachments[j].layout)); |
| if (rCI.pSubpasses[i].pDepthStencilAttachment != DE_NULL) |
| hash_combine(seed, rCI.pSubpasses[i].pDepthStencilAttachment->attachment, |
| uint32_t(rCI.pSubpasses[i].pDepthStencilAttachment->layout)); |
| if (rCI.pSubpasses[i].pPreserveAttachments != DE_NULL) |
| for (uint32_t j = 0; j < rCI.pSubpasses[i].preserveAttachmentCount; ++j) |
| hash_combine(seed, rCI.pSubpasses[i].pPreserveAttachments[j]); |
| } |
| } |
| if (rCI.pDependencies != DE_NULL) |
| for (uint32_t i = 0; i < rCI.dependencyCount; ++i) |
| hash_combine(seed, rCI.pDependencies[i].srcSubpass, rCI.pDependencies[i].dstSubpass, |
| uint32_t(rCI.pDependencies[i].srcStageMask), uint32_t(rCI.pDependencies[i].dstStageMask), |
| uint64_t(rCI.pDependencies[i].srcAccessMask), uint64_t(rCI.pDependencies[i].dstAccessMask), |
| uint32_t(rCI.pDependencies[i].dependencyFlags)); |
| |
| if (rCI.pCorrelatedViewMasks != DE_NULL) |
| for (uint32_t i = 0; i < rCI.correlatedViewMaskCount; ++i) |
| hash_combine(seed, rCI.pCorrelatedViewMasks[i]); |
| |
| return seed; |
| } |
| |
| VkGraphicsPipelineCreateInfo prepareSimpleGraphicsPipelineCI( |
| VkPipelineVertexInputStateCreateInfo &vertexInputStateCreateInfo, |
| std::vector<VkPipelineShaderStageCreateInfo> &shaderStageCreateInfos, |
| VkPipelineInputAssemblyStateCreateInfo &inputAssemblyStateCreateInfo, |
| VkPipelineViewportStateCreateInfo &viewPortStateCreateInfo, |
| VkPipelineRasterizationStateCreateInfo &rasterizationStateCreateInfo, |
| VkPipelineMultisampleStateCreateInfo &multisampleStateCreateInfo, |
| VkPipelineColorBlendAttachmentState &colorBlendAttachmentState, |
| VkPipelineColorBlendStateCreateInfo &colorBlendStateCreateInfo, |
| VkPipelineDynamicStateCreateInfo &dynamicStateCreateInfo, std::vector<VkDynamicState> &dynamicStates, |
| VkPipelineLayout pipelineLayout, VkRenderPass renderPass) |
| { |
| vertexInputStateCreateInfo = { |
| VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; |
| 0u, // uint32_t vertexBindingDescriptionCount; |
| DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; |
| 0u, // uint32_t vertexAttributeDescriptionCount; |
| DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; |
| }; |
| |
| inputAssemblyStateCreateInfo = { |
| VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; |
| VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology; |
| VK_FALSE // VkBool32 primitiveRestartEnable; |
| }; |
| |
| viewPortStateCreateInfo = { |
| VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; |
| 1, // uint32_t viewportCount; |
| DE_NULL, // const VkViewport* pViewports; |
| 1, // uint32_t scissorCount; |
| DE_NULL // const VkRect2D* pScissors; |
| }; |
| |
| rasterizationStateCreateInfo = { |
| VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; |
| VK_FALSE, // VkBool32 depthClampEnable; |
| VK_FALSE, // VkBool32 rasterizerDiscardEnable; |
| VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; |
| VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode; |
| VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace; |
| VK_FALSE, // VkBool32 depthBiasEnable; |
| 0.0f, // float depthBiasConstantFactor; |
| 0.0f, // float depthBiasClamp; |
| 0.0f, // float depthBiasSlopeFactor; |
| 1.0f // float lineWidth; |
| }; |
| |
| multisampleStateCreateInfo = { |
| VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; |
| VK_FALSE, // VkBool32 sampleShadingEnable; |
| 0.0f, // float minSampleShading; |
| DE_NULL, // const VkSampleMask* pSampleMask; |
| VK_FALSE, // VkBool32 alphaToCoverageEnable; |
| VK_FALSE // VkBool32 alphaToOneEnable; |
| }; |
| |
| colorBlendAttachmentState = { |
| VK_FALSE, // VkBool32 blendEnable; |
| VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor; |
| VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; |
| VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; |
| VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor; |
| VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; |
| VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; |
| (VkColorComponentFlags)0xFu // VkColorComponentFlags colorWriteMask; |
| }; |
| |
| colorBlendStateCreateInfo = { |
| VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; |
| false, // VkBool32 logicOpEnable; |
| VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; |
| 1, // uint32_t attachmentCount; |
| &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; |
| {1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4]; |
| }; |
| |
| dynamicStateCreateInfo = { |
| VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags; |
| uint32_t(dynamicStates.size()), // uint32_t dynamicStateCount; |
| dynamicStates.data() // const VkDynamicState* pDynamicStates; |
| }; |
| |
| VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = { |
| VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; |
| uint32_t(shaderStageCreateInfos.size()), // uint32_t stageCount; |
| shaderStageCreateInfos.data(), // const VkPipelineShaderStageCreateInfo* pStages; |
| &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; |
| &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; |
| DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; |
| &viewPortStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; |
| &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; |
| &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; |
| DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; |
| &colorBlendStateCreateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; |
| &dynamicStateCreateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; |
| pipelineLayout, // VkPipelineLayout layout; |
| renderPass, // VkRenderPass renderPass; |
| 0u, // uint32_t subpass; |
| DE_NULL, // VkPipeline basePipelineHandle; |
| 0 // int basePipelineIndex; |
| }; |
| |
| return graphicsPipelineCreateInfo; |
| } |
| |
| VkComputePipelineCreateInfo prepareSimpleComputePipelineCI(const VkPipelineShaderStageCreateInfo &shaderStageCreateInfo, |
| VkPipelineLayout pipelineLayout) |
| { |
| const VkComputePipelineCreateInfo pipelineCreateInfo = { |
| VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType |
| DE_NULL, // const void* pNext |
| 0u, // VkPipelineCreateFlags flags |
| shaderStageCreateInfo, // VkPipelineShaderStageCreateInfo stage |
| pipelineLayout, // VkPipelineLayout layout |
| (vk::VkPipeline)0, // VkPipeline basePipelineHandle |
| 0u, // int32_t basePipelineIndex |
| }; |
| return pipelineCreateInfo; |
| } |
| |
| VkRenderPassCreateInfo prepareSimpleRenderPassCI(VkFormat format, VkAttachmentDescription &attachmentDescription, |
| VkAttachmentReference &attachmentReference, |
| VkSubpassDescription &subpassDescription) |
| { |
| attachmentDescription = { |
| (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags; |
| format, // VkFormat format; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; |
| VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; |
| VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; |
| VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; |
| }; |
| |
| attachmentReference = { |
| 0u, // uint32_t attachment; |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; |
| }; |
| |
| subpassDescription = { |
| (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags; |
| VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint |
| 0u, // uint32_t inputAttachmentCount |
| DE_NULL, // const VkAttachmentReference* pInputAttachments |
| 1u, // uint32_t colorAttachmentCount |
| &attachmentReference, // const VkAttachmentReference* pColorAttachments |
| DE_NULL, // const VkAttachmentReference* pResolveAttachments |
| DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment |
| 0u, // uint32_t preserveAttachmentCount |
| DE_NULL // const uint32_t* pPreserveAttachments |
| }; |
| |
| const VkRenderPassCreateInfo renderPassCreateInfo = { |
| VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; |
| 1u, // uint32_t attachmentCount |
| &attachmentDescription, // const VkAttachmentDescription* pAttachments |
| 1u, // uint32_t subpassCount |
| &subpassDescription, // const VkSubpassDescription* pSubpasses |
| 0u, // uint32_t dependencyCount |
| DE_NULL // const VkSubpassDependency* pDependencies |
| }; |
| |
| return renderPassCreateInfo; |
| } |
| |
| VkFormat getRenderTargetFormat(const InstanceInterface &vk, const VkPhysicalDevice &device) |
| { |
| const VkFormatFeatureFlags featureFlags = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; |
| VkFormatProperties formatProperties; |
| vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_B8G8R8A8_UNORM, &formatProperties); |
| if ((formatProperties.linearTilingFeatures & featureFlags) || |
| (formatProperties.optimalTilingFeatures & featureFlags)) |
| return VK_FORMAT_B8G8R8A8_UNORM; |
| vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_R8G8B8A8_UNORM, &formatProperties); |
| if ((formatProperties.linearTilingFeatures & featureFlags) || |
| formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) |
| return VK_FORMAT_R8G8B8A8_UNORM; |
| TCU_THROW(NotSupportedError, "Device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM"); |
| return VK_FORMAT_UNDEFINED; |
| } |
| |
| } // namespace vk |
| |
| #else |
| DE_EMPTY_CPP_FILE |
| #endif // CTS_USES_VULKANSC |