From e84c0e499e60adc8456a44fe28ae4d116f1da648 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Mon, 15 Mar 2021 01:28:21 +0300 Subject: Vulkan: fixed tests on Mac. --- .../include/PipelineStateVkImpl.hpp | 2 + .../include/VulkanUtilities/VulkanHeaders.h | 5 +- .../VulkanUtilities/VulkanPhysicalDevice.hpp | 25 +-- .../src/DeviceContextVkImpl.cpp | 6 + .../GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 18 +- .../src/PipelineStateVkImpl.cpp | 202 ++++++++++++++++++++- .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 6 + .../GraphicsEngineVulkan/src/TextureVkImpl.cpp | 12 +- .../src/VulkanUtilities/VulkanDebug.cpp | 11 +- .../src/VulkanUtilities/VulkanPhysicalDevice.cpp | 17 ++ 10 files changed, 281 insertions(+), 23 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 18b23f91..9f336fe5 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -107,6 +107,8 @@ public: // when resource is bound. using SRBArray = std::array; void DvpVerifySRBResources(const SRBArray& SRBs) const; + + void DvpValidateResourceLimits() const; #endif private: diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h index 90cd5442..f8b6398a 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h @@ -31,12 +31,13 @@ # define VK_NO_PROTOTYPES #endif -#include "vulkan/vulkan.h" - #define VK_FORMAT_RANGE_SIZE (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1) #if DILIGENT_USE_VOLK +# define VK_ENABLE_BETA_EXTENSIONS # include "volk/volk.h" +#else +# include "vulkan/vulkan.h" #endif #if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(_X11_XLIB_H_) diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp index 5f17d666..11736bc1 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp @@ -39,17 +39,19 @@ class VulkanPhysicalDevice public: struct ExtensionFeatures { - VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {}; - VkPhysicalDevice16BitStorageFeaturesKHR Storage16Bit = {}; - VkPhysicalDevice8BitStorageFeaturesKHR Storage8Bit = {}; - VkPhysicalDeviceShaderFloat16Int8FeaturesKHR ShaderFloat16Int8 = {}; - VkPhysicalDeviceAccelerationStructureFeaturesKHR AccelStruct = {}; - VkPhysicalDeviceRayTracingPipelineFeaturesKHR RayTracingPipeline = {}; - VkPhysicalDeviceRayQueryFeaturesKHR RayQuery = {}; - bool Spirv14 = false; // Ray tracing requires Vulkan 1.2 or SPIRV 1.4 extension - bool Spirv15 = false; // DXC shaders with ray tracing requires Vulkan 1.2 with SPIRV 1.5 - VkPhysicalDeviceBufferDeviceAddressFeaturesKHR BufferDeviceAddress = {}; - VkPhysicalDeviceDescriptorIndexingFeaturesEXT DescriptorIndexing = {}; + VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {}; + VkPhysicalDevice16BitStorageFeaturesKHR Storage16Bit = {}; + VkPhysicalDevice8BitStorageFeaturesKHR Storage8Bit = {}; + VkPhysicalDeviceShaderFloat16Int8FeaturesKHR ShaderFloat16Int8 = {}; + VkPhysicalDeviceAccelerationStructureFeaturesKHR AccelStruct = {}; + VkPhysicalDeviceRayTracingPipelineFeaturesKHR RayTracingPipeline = {}; + VkPhysicalDeviceRayQueryFeaturesKHR RayQuery = {}; + bool Spirv14 = false; // Ray tracing requires Vulkan 1.2 or SPIRV 1.4 extension + bool Spirv15 = false; // DXC shaders with ray tracing requires Vulkan 1.2 with SPIRV 1.5 + VkPhysicalDeviceBufferDeviceAddressFeaturesKHR BufferDeviceAddress = {}; + VkPhysicalDeviceDescriptorIndexingFeaturesEXT DescriptorIndexing = {}; + bool HasPortabilitySubset = false; + VkPhysicalDevicePortabilitySubsetFeaturesKHR PortabilitySubset = {}; }; struct ExtensionProperties @@ -58,6 +60,7 @@ public: VkPhysicalDeviceAccelerationStructurePropertiesKHR AccelStruct = {}; VkPhysicalDeviceRayTracingPipelinePropertiesKHR RayTracingPipeline = {}; VkPhysicalDeviceDescriptorIndexingPropertiesEXT DescriptorIndexing = {}; + VkPhysicalDevicePortabilitySubsetPropertiesKHR PortabilitySubset = {}; }; public: diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 35702235..c13982d4 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -3216,6 +3216,9 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) vkASBuildInfo.ppGeometries = nullptr; vkASBuildInfo.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset; + const auto& ASLimits = m_pDevice->GetPhysicalDevice().GetExtProperties().AccelStruct; + VERIFY(vkASBuildInfo.scratchData.deviceAddress % ASLimits.minAccelerationStructureScratchOffsetAlignment == 0, "Scratch buffer start address is not properly aligned"); + EnsureVkCmdBuffer(); m_CommandBuffer.BuildAccelerationStructure(1, &vkASBuildInfo, &VkRangePtr); ++m_State.NumCommands; @@ -3320,6 +3323,9 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs) vkASBuildInfo.ppGeometries = nullptr; vkASBuildInfo.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset; + const auto& ASLimits = m_pDevice->GetPhysicalDevice().GetExtProperties().AccelStruct; + VERIFY(vkASBuildInfo.scratchData.deviceAddress % ASLimits.minAccelerationStructureScratchOffsetAlignment == 0, "Scratch buffer start address is not properly aligned"); + m_CommandBuffer.BuildAccelerationStructure(1, &vkASBuildInfo, &vkRangePtr); ++m_State.NumCommands; } diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 027fa892..f44d3677 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -246,9 +246,6 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E const VulkanUtilities::VulkanPhysicalDevice::ExtensionFeatures& DeviceExtFeatures = PhysicalDevice->GetExtFeatures(); VulkanUtilities::VulkanPhysicalDevice::ExtensionFeatures EnabledExtFeats = {}; - // SPIRV 1.5 is in Vulkan 1.2 core - EnabledExtFeats.Spirv15 = DeviceExtFeatures.Spirv15; - #define ENABLE_FEATURE(IsFeatureSupported, Feature, FeatureName) \ do \ { \ @@ -438,6 +435,9 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E VERIFY_EXPR(DeviceExtFeatures.Spirv14); } + // SPIRV 1.5 is in Vulkan 1.2 core + EnabledExtFeats.Spirv15 = DeviceExtFeatures.Spirv15; + DeviceExtensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); // required for VK_KHR_acceleration_structure DeviceExtensions.push_back(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // required for VK_KHR_acceleration_structure DeviceExtensions.push_back(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); // required for ray tracing @@ -480,6 +480,18 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E } } +#ifdef PLATFORM_MACOS + if (DeviceExtFeatures.HasPortabilitySubset) + { + EnabledExtFeats.HasPortabilitySubset = DeviceExtFeatures.HasPortabilitySubset; + EnabledExtFeats.PortabilitySubset = DeviceExtFeatures.PortabilitySubset; + DeviceExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); + + *NextExt = &EnabledExtFeats.PortabilitySubset; + NextExt = &EnabledExtFeats.PortabilitySubset.pNext; + } +#endif + // make sure that last pNext is null *NextExt = nullptr; } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 49fd6d64..8934c4aa 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -877,6 +877,10 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea VERIFY_EXPR(!m_Signatures[0] || m_Signatures[0]->GetDesc().BindingIndex == 0); } +#ifdef DILIGENT_DEVELOPMENT + DvpValidateResourceLimits(); +#endif + m_PipelineLayout.Create(GetDevice(), m_Signatures, m_SignatureCount); // Verify that pipeline layout is compatible with shader resources and @@ -1096,6 +1100,202 @@ void PipelineStateVkImpl::DvpVerifySRBResources(const SRBArray& SRBs) const } VERIFY_EXPR(res_info == m_ResourceAttibutions.end()); } -#endif + +void PipelineStateVkImpl::DvpValidateResourceLimits() const +{ + const auto& Limits = GetDevice()->GetPhysicalDevice().GetProperties().limits; + const auto& ASLimits = GetDevice()->GetPhysicalDevice().GetExtProperties().AccelStruct; + const auto& DescIndFeats = GetDevice()->GetPhysicalDevice().GetExtFeatures().DescriptorIndexing; + const auto& DescIndProps = GetDevice()->GetPhysicalDevice().GetExtProperties().DescriptorIndexing; + const auto DescCount = static_cast(DescriptorType::Count); + + std::array DescriptorCount = {}; + std::array, MAX_SHADERS_IN_PIPELINE> PerStageDescriptorCount = {}; + std::array ShaderStagePresented = {}; + + for (Uint32 s = 0; s < GetResourceSignatureCount(); ++s) + { + const auto* pSignature = GetResourceSignature(s); + if (pSignature == nullptr) + continue; + + for (Uint32 r = 0; r < pSignature->GetTotalResourceCount(); ++r) + { + const auto& ResDesc = pSignature->GetResourceDesc(r); + const auto& ResAttr = pSignature->GetResourceAttribs(r); + const auto DescIndex = static_cast(ResAttr.DescrType); + + DescriptorCount[DescIndex] += ResAttr.ArraySize; + + for (auto ShaderStages = ResDesc.ShaderStages; ShaderStages != 0;) + { + const auto ShaderInd = GetShaderTypePipelineIndex(ExtractLSB(ShaderStages), m_Desc.PipelineType); + PerStageDescriptorCount[ShaderInd][DescIndex] += ResAttr.ArraySize; + ShaderStagePresented[ShaderInd] = true; + } + + if ((ResDesc.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0) + { + bool NonUniformIndexingSupported = false; + bool NonUniformIndexingIsNative = false; + switch (ResAttr.GetDescriptorType()) + { + case DescriptorType::Sampler: + NonUniformIndexingSupported = true; + NonUniformIndexingIsNative = true; + break; + case DescriptorType::CombinedImageSampler: + case DescriptorType::SeparateImage: + NonUniformIndexingSupported = DescIndFeats.shaderSampledImageArrayNonUniformIndexing; + NonUniformIndexingIsNative = DescIndProps.shaderSampledImageArrayNonUniformIndexingNative; + break; + case DescriptorType::StorageImage: + NonUniformIndexingSupported = DescIndFeats.shaderStorageImageArrayNonUniformIndexing; + NonUniformIndexingIsNative = DescIndProps.shaderStorageImageArrayNonUniformIndexingNative; + break; + case DescriptorType::UniformTexelBuffer: + NonUniformIndexingSupported = DescIndFeats.shaderUniformTexelBufferArrayNonUniformIndexing; + NonUniformIndexingIsNative = DescIndProps.shaderSampledImageArrayNonUniformIndexingNative; + break; + case DescriptorType::StorageTexelBuffer: + case DescriptorType::StorageTexelBuffer_ReadOnly: + NonUniformIndexingSupported = DescIndFeats.shaderStorageTexelBufferArrayNonUniformIndexing; + NonUniformIndexingIsNative = DescIndProps.shaderStorageBufferArrayNonUniformIndexingNative; + break; + case DescriptorType::UniformBuffer: + case DescriptorType::UniformBufferDynamic: + NonUniformIndexingSupported = DescIndFeats.shaderUniformBufferArrayNonUniformIndexing; + NonUniformIndexingIsNative = DescIndProps.shaderUniformBufferArrayNonUniformIndexingNative; + break; + case DescriptorType::StorageBuffer: + case DescriptorType::StorageBuffer_ReadOnly: + case DescriptorType::StorageBufferDynamic: + case DescriptorType::StorageBufferDynamic_ReadOnly: + NonUniformIndexingSupported = DescIndFeats.shaderStorageBufferArrayNonUniformIndexing; + NonUniformIndexingIsNative = DescIndProps.shaderStorageBufferArrayNonUniformIndexingNative; + break; + case DescriptorType::InputAttachment: + NonUniformIndexingSupported = DescIndFeats.shaderInputAttachmentArrayNonUniformIndexing; + NonUniformIndexingIsNative = DescIndProps.shaderInputAttachmentArrayNonUniformIndexingNative; + break; + case DescriptorType::AccelerationStructure: + // There is no separate feature for acceleration structures, GLSL spec says: + // "If GL_EXT_nonuniform_qualifier is supported + // When aggregated into arrays within a shader, accelerationStructureEXT can + // be indexed with a non-uniform integral expressions, when decorated with the + // nonuniformEXT qualifier." + // Descriptor indexing is supported here, otherwise error will be generated in ValidatePipelineResourceSignatureDesc(). + NonUniformIndexingSupported = true; + NonUniformIndexingIsNative = true; + break; + } + + // TODO: We don't know if this resource is used for non-uniform indexing or not. + if (!NonUniformIndexingSupported) + { + LOG_WARNING_MESSAGE("PSO '", m_Desc.Name, "', resource signature '", pSignature->GetDesc().Name, "' contains shader resource '", + ResDesc.Name, "' that is defined with RUNTIME_ARRAY flag, but current device does not support non-uniform indexing for this resource type."); + } + else if (!NonUniformIndexingIsNative) + { + LOG_WARNING_MESSAGE("Performance warning in PSO '", m_Desc.Name, "', resource signature '", pSignature->GetDesc().Name, "': shader resource '", + ResDesc.Name, "' is defined with RUNTIME_ARRAY flag, but non-uniform indexing is emulated on this device."); + } + } + } + } + + // Check total descriptor count + { + const Uint32 NumSampledImages = + DescriptorCount[static_cast(DescriptorType::CombinedImageSampler)] + + DescriptorCount[static_cast(DescriptorType::SeparateImage)] + + DescriptorCount[static_cast(DescriptorType::UniformTexelBuffer)]; + const Uint32 NumStorageImages = + DescriptorCount[static_cast(DescriptorType::StorageImage)] + + DescriptorCount[static_cast(DescriptorType::StorageTexelBuffer)] + + DescriptorCount[static_cast(DescriptorType::StorageTexelBuffer_ReadOnly)]; + const Uint32 NumStorageBuffers = + DescriptorCount[static_cast(DescriptorType::StorageBuffer)] + + DescriptorCount[static_cast(DescriptorType::StorageBuffer_ReadOnly)]; + const Uint32 NumDynamicStorageBuffers = + DescriptorCount[static_cast(DescriptorType::StorageBufferDynamic)] + + DescriptorCount[static_cast(DescriptorType::StorageBufferDynamic_ReadOnly)]; + const Uint32 NumSamplers = DescriptorCount[static_cast(DescriptorType::Sampler)]; + const Uint32 NumUniformBuffers = DescriptorCount[static_cast(DescriptorType::UniformBuffer)]; + const Uint32 NumDynamicUniformBuffers = DescriptorCount[static_cast(DescriptorType::UniformBufferDynamic)]; + const Uint32 NumInputAttachments = DescriptorCount[static_cast(DescriptorType::InputAttachment)]; + const Uint32 NumAccelerationStructures = DescriptorCount[static_cast(DescriptorType::AccelerationStructure)]; + + DEV_CHECK_ERR(NumSamplers <= Limits.maxDescriptorSetSamplers, + "In PSO '", m_Desc.Name, "', the number of samplers (", NumSamplers, ") exceeds the limit (", Limits.maxDescriptorSetSamplers, ")."); + DEV_CHECK_ERR(NumSampledImages <= Limits.maxDescriptorSetSampledImages, + "In PSO '", m_Desc.Name, "', the number of sampled images (", NumSampledImages, ") exceeds the limit (", Limits.maxDescriptorSetSampledImages, ")."); + DEV_CHECK_ERR(NumStorageImages <= Limits.maxDescriptorSetStorageImages, + "In PSO '", m_Desc.Name, "', the number of storage images (", NumStorageImages, ") exceeds the limit (", Limits.maxDescriptorSetStorageImages, ")."); + DEV_CHECK_ERR(NumStorageBuffers <= Limits.maxDescriptorSetStorageBuffers, + "In PSO '", m_Desc.Name, "', the number of storage buffers (", NumStorageBuffers, ") exceeds the limit (", Limits.maxDescriptorSetStorageBuffers, ")."); + DEV_CHECK_ERR(NumDynamicStorageBuffers <= Limits.maxDescriptorSetStorageBuffersDynamic, + "In PSO '", m_Desc.Name, "', the number of dynamic storage buffers (", NumDynamicStorageBuffers, ") exceeds the limit (", Limits.maxDescriptorSetStorageBuffersDynamic, ")."); + DEV_CHECK_ERR(NumUniformBuffers <= Limits.maxDescriptorSetUniformBuffers, + "In PSO '", m_Desc.Name, "', the number of uniform buffers (", NumUniformBuffers, ") exceeds the limit (", Limits.maxDescriptorSetUniformBuffers, ")."); + DEV_CHECK_ERR(NumDynamicUniformBuffers <= Limits.maxDescriptorSetUniformBuffersDynamic, + "In PSO '", m_Desc.Name, "', the number of dynamic uniform buffers (", NumDynamicUniformBuffers, ") exceeds the limit (", Limits.maxDescriptorSetUniformBuffersDynamic, ")."); + DEV_CHECK_ERR(NumInputAttachments <= Limits.maxDescriptorSetInputAttachments, + "In PSO '", m_Desc.Name, "', the number of input attachments (", NumInputAttachments, ") exceeds the limit (", Limits.maxDescriptorSetInputAttachments, ")."); + DEV_CHECK_ERR(NumAccelerationStructures <= ASLimits.maxDescriptorSetAccelerationStructures, + "In PSO '", m_Desc.Name, "', the number of acceleration structures (", NumAccelerationStructures, ") exceeds the limit (", ASLimits.maxDescriptorSetAccelerationStructures, ")."); + } + + // Check per stage descriptor count + for (Uint32 ShaderInd = 0; ShaderInd < PerStageDescriptorCount.size(); ++ShaderInd) + { + if (!ShaderStagePresented[ShaderInd]) + continue; + + const auto& NumDesc = PerStageDescriptorCount[ShaderInd]; + const auto ShaderType = GetShaderTypeFromPipelineIndex(ShaderInd, m_Desc.PipelineType); + const char* StageName = GetShaderTypeLiteralName(ShaderType); + + const Uint32 NumSampledImages = + NumDesc[static_cast(DescriptorType::CombinedImageSampler)] + + NumDesc[static_cast(DescriptorType::SeparateImage)] + + NumDesc[static_cast(DescriptorType::UniformTexelBuffer)]; + const Uint32 NumStorageImages = + NumDesc[static_cast(DescriptorType::StorageImage)] + + NumDesc[static_cast(DescriptorType::StorageTexelBuffer)] + + NumDesc[static_cast(DescriptorType::StorageTexelBuffer_ReadOnly)]; + const Uint32 NumStorageBuffers = + NumDesc[static_cast(DescriptorType::StorageBuffer)] + + NumDesc[static_cast(DescriptorType::StorageBuffer_ReadOnly)] + + NumDesc[static_cast(DescriptorType::StorageBufferDynamic)] + + NumDesc[static_cast(DescriptorType::StorageBufferDynamic_ReadOnly)]; + const Uint32 NumUniformBuffers = + NumDesc[static_cast(DescriptorType::UniformBuffer)] + + NumDesc[static_cast(DescriptorType::UniformBufferDynamic)]; + const Uint32 NumSamplers = NumDesc[static_cast(DescriptorType::Sampler)]; + const Uint32 NumInputAttachments = NumDesc[static_cast(DescriptorType::InputAttachment)]; + const Uint32 NumAccelerationStructures = NumDesc[static_cast(DescriptorType::AccelerationStructure)]; + const Uint32 NumResources = NumSampledImages + NumStorageImages + NumStorageBuffers + NumUniformBuffers + NumSamplers + NumInputAttachments + NumAccelerationStructures; + + DEV_CHECK_ERR(NumResources <= Limits.maxPerStageResources, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the total number of resources (", NumResources, ") exceeds the per-stage limit (", Limits.maxPerStageResources, ")."); + DEV_CHECK_ERR(NumSamplers <= Limits.maxPerStageDescriptorSamplers, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the number of samplers (", NumSamplers, ") exceeds the per-stage limit (", Limits.maxPerStageDescriptorSamplers, ")."); + DEV_CHECK_ERR(NumSampledImages <= Limits.maxPerStageDescriptorSampledImages, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the number of sampled images (", NumSampledImages, ") exceeds the per-stage limit (", Limits.maxPerStageDescriptorSampledImages, ")."); + DEV_CHECK_ERR(NumStorageImages <= Limits.maxPerStageDescriptorStorageImages, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the number of storage images (", NumStorageImages, ") exceeds the per-stage limit (", Limits.maxPerStageDescriptorStorageImages, ")."); + DEV_CHECK_ERR(NumStorageBuffers <= Limits.maxPerStageDescriptorStorageBuffers, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the number of storage buffers (", NumStorageBuffers, ") exceeds the per-stage limit (", Limits.maxPerStageDescriptorStorageBuffers, ")."); + DEV_CHECK_ERR(NumUniformBuffers <= Limits.maxPerStageDescriptorUniformBuffers, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the number of uniform buffers (", NumUniformBuffers, ") exceeds the per-stage limit (", Limits.maxPerStageDescriptorUniformBuffers, ")."); + DEV_CHECK_ERR(NumInputAttachments <= Limits.maxPerStageDescriptorInputAttachments, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the number of input attachments (", NumInputAttachments, ") exceeds the per-stage limit (", Limits.maxPerStageDescriptorInputAttachments, ")."); + DEV_CHECK_ERR(NumAccelerationStructures <= ASLimits.maxPerStageDescriptorAccelerationStructures, + "In PSO '", m_Desc.Name, "' shader stage '", StageName, "', the number of acceleration structures (", NumAccelerationStructures, ") exceeds the per-stage limit (", ASLimits.maxPerStageDescriptorAccelerationStructures, ")."); + } +} +#endif // DILIGENT_DEVELOPMENT } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index 5135067b..1cba1686 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -33,6 +33,12 @@ #include "VulkanTypeConversions.hpp" #include "EngineMemory.h" +#ifdef VK_USE_PLATFORM_WIN32_KHR +# define WIN32_LEAN_AND_MEAN +# include +# undef CreateSemaphore +#endif + namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp index c96dedb0..22035b8d 100644 --- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp @@ -60,6 +60,11 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters, const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); const bool bInitializeTexture = (pInitData != nullptr && pInitData->pSubResources != nullptr && pInitData->NumSubresources > 0); + const bool ImageView2DSupported = + (m_Desc.Type == RESOURCE_DIM_TEX_3D && LogicalDevice.GetEnabledExtFeatures().HasPortabilitySubset) ? + LogicalDevice.GetEnabledExtFeatures().PortabilitySubset.imageView2DOn3DImage == VK_TRUE : + true; + if (m_Desc.Usage == USAGE_IMMUTABLE || m_Desc.Usage == USAGE_DEFAULT || m_Desc.Usage == USAGE_DYNAMIC) { VkImageCreateInfo ImageCI = {}; @@ -80,7 +85,8 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters, else if (m_Desc.Type == RESOURCE_DIM_TEX_3D) { ImageCI.imageType = VK_IMAGE_TYPE_3D; - ImageCI.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; + if (ImageView2DSupported) + ImageCI.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; } else { @@ -125,11 +131,13 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters, { // VK_IMAGE_USAGE_TRANSFER_DST_BIT is required for vkCmdClearColorImage() ImageCI.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + DEV_CHECK_ERR(ImageView2DSupported, "imageView2DOn3DImage in VkPhysicalDevicePortabilitySubsetFeaturesKHR is not enabled, can not create render target with 2D image view"); } if (m_Desc.BindFlags & BIND_DEPTH_STENCIL) { // VK_IMAGE_USAGE_TRANSFER_DST_BIT is required for vkCmdClearDepthStencilImage() ImageCI.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + DEV_CHECK_ERR(ImageView2DSupported, "imageView2DOn3DImage in VkPhysicalDevicePortabilitySubsetFeaturesKHR is not enabled, can not create depth-stencil target with 2D image view"); } if (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) { @@ -146,7 +154,7 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters, if (m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) { - if (CheckCSBasedMipGenerationSupport(ImageCI.format)) + if (CheckCSBasedMipGenerationSupport(ImageCI.format) && ImageView2DSupported) { ImageCI.usage |= VK_IMAGE_USAGE_STORAGE_BIT; m_bCSBasedMipGenerationSupported = true; diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp index dca46b48..e5653d60 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp @@ -55,11 +55,14 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugMessengerCallback(VkDebugUtilsMessageSeverit // Temporarily disable false warnings from validation layers (1.2.170). // TODO: check in next Vulkan SDK #if 1 - if (std::string{"VUID-vkCmdPipelineBarrier-dstAccessMask-02816"} == callbackData->pMessageIdName) + if (callbackData->pMessageIdName) { - std::string msg{callbackData->pMessage}; - if (msg.find("dstAccessMask bit VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR is not supported by stage mask (VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR)") != std::string::npos) - return VK_FALSE; + if (std::string{"VUID-vkCmdPipelineBarrier-dstAccessMask-02816"} == callbackData->pMessageIdName) + { + std::string msg{callbackData->pMessage}; + if (msg.find("dstAccessMask bit VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR is not supported by stage mask (VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR)") != std::string::npos) + return VK_FALSE; + } } #endif diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp index cf1cbd3f..4a8904b0 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp @@ -189,6 +189,23 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice, m_ExtFeatures.Spirv15 = true; } +# ifdef PLATFORM_MACOS + // Extension required for MoltenVk + if (IsExtensionSupported(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) + { + *NextFeat = &m_ExtFeatures.PortabilitySubset; + NextFeat = &m_ExtFeatures.PortabilitySubset.pNext; + + m_ExtFeatures.HasPortabilitySubset = true; + m_ExtFeatures.PortabilitySubset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR; + + *NextProp = &m_ExtProperties.PortabilitySubset; + NextProp = &m_ExtProperties.PortabilitySubset.pNext; + + m_ExtProperties.PortabilitySubset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR; + } +# endif + // make sure that last pNext is null *NextFeat = nullptr; *NextProp = nullptr; -- cgit v1.2.3