summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2021-03-14 22:28:21 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:23 +0000
commite84c0e499e60adc8456a44fe28ae4d116f1da648 (patch)
tree7f38ed7415731039fb8b7d86ef9ce42ca580824a /Graphics/GraphicsEngineVulkan
parentAdded DrawMeshIndirectCount command. (diff)
downloadDiligentCore-e84c0e499e60adc8456a44fe28ae4d116f1da648.tar.gz
DiligentCore-e84c0e499e60adc8456a44fe28ae4d116f1da648.zip
Vulkan: fixed tests on Mac.
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h5
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp25
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp18
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp202
-rw-r--r--Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp12
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp11
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp17
10 files changed, 281 insertions, 23 deletions
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<ShaderResourceBindingVkImpl*, MAX_RESOURCE_SIGNATURES>;
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<Uint32>(DescriptorType::Count);
+
+ std::array<Uint32, DescCount> DescriptorCount = {};
+ std::array<std::array<Uint32, DescCount>, MAX_SHADERS_IN_PIPELINE> PerStageDescriptorCount = {};
+ std::array<bool, MAX_SHADERS_IN_PIPELINE> 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<Uint32>(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<Uint32>(DescriptorType::CombinedImageSampler)] +
+ DescriptorCount[static_cast<Uint32>(DescriptorType::SeparateImage)] +
+ DescriptorCount[static_cast<Uint32>(DescriptorType::UniformTexelBuffer)];
+ const Uint32 NumStorageImages =
+ DescriptorCount[static_cast<Uint32>(DescriptorType::StorageImage)] +
+ DescriptorCount[static_cast<Uint32>(DescriptorType::StorageTexelBuffer)] +
+ DescriptorCount[static_cast<Uint32>(DescriptorType::StorageTexelBuffer_ReadOnly)];
+ const Uint32 NumStorageBuffers =
+ DescriptorCount[static_cast<Uint32>(DescriptorType::StorageBuffer)] +
+ DescriptorCount[static_cast<Uint32>(DescriptorType::StorageBuffer_ReadOnly)];
+ const Uint32 NumDynamicStorageBuffers =
+ DescriptorCount[static_cast<Uint32>(DescriptorType::StorageBufferDynamic)] +
+ DescriptorCount[static_cast<Uint32>(DescriptorType::StorageBufferDynamic_ReadOnly)];
+ const Uint32 NumSamplers = DescriptorCount[static_cast<Uint32>(DescriptorType::Sampler)];
+ const Uint32 NumUniformBuffers = DescriptorCount[static_cast<Uint32>(DescriptorType::UniformBuffer)];
+ const Uint32 NumDynamicUniformBuffers = DescriptorCount[static_cast<Uint32>(DescriptorType::UniformBufferDynamic)];
+ const Uint32 NumInputAttachments = DescriptorCount[static_cast<Uint32>(DescriptorType::InputAttachment)];
+ const Uint32 NumAccelerationStructures = DescriptorCount[static_cast<Uint32>(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<Uint32>(DescriptorType::CombinedImageSampler)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::SeparateImage)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::UniformTexelBuffer)];
+ const Uint32 NumStorageImages =
+ NumDesc[static_cast<Uint32>(DescriptorType::StorageImage)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::StorageTexelBuffer)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::StorageTexelBuffer_ReadOnly)];
+ const Uint32 NumStorageBuffers =
+ NumDesc[static_cast<Uint32>(DescriptorType::StorageBuffer)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::StorageBuffer_ReadOnly)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::StorageBufferDynamic)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::StorageBufferDynamic_ReadOnly)];
+ const Uint32 NumUniformBuffers =
+ NumDesc[static_cast<Uint32>(DescriptorType::UniformBuffer)] +
+ NumDesc[static_cast<Uint32>(DescriptorType::UniformBufferDynamic)];
+ const Uint32 NumSamplers = NumDesc[static_cast<Uint32>(DescriptorType::Sampler)];
+ const Uint32 NumInputAttachments = NumDesc[static_cast<Uint32>(DescriptorType::InputAttachment)];
+ const Uint32 NumAccelerationStructures = NumDesc[static_cast<Uint32>(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 <Windows.h>
+# 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;