diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp index 04f2465e78..6a29c398d8 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp @@ -66,30 +66,7 @@ namespace AZ RawStringList requiredLayers = GetRequiredLayers(); RawStringList requiredExtensions = GetRequiredExtensions(); - StringList deviceExtensions = physicalDevice.GetDeviceExtensionNames(); - RawStringList optionalDeviceExtensions = { { - VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, - VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, - VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, - VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, - VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, - VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME, - VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME, - VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, - VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, - VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, - - // ray tracing extensions - VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, - VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, - VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, - VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, - VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, - VK_KHR_SPIRV_1_4_EXTENSION_NAME, - VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME - } }; - - RawStringList optionalExtensions = FilterList(optionalDeviceExtensions, deviceExtensions); + RawStringList optionalExtensions = physicalDevice.FilterSupportedOptionalExtensions(); requiredExtensions.insert(requiredExtensions.end(), optionalExtensions.begin(), optionalExtensions.end()); //We now need to find the queues that the physical device has available and make sure @@ -164,7 +141,7 @@ namespace AZ // unbounded array functionality VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptorIndexingFeatures = {}; - descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; + descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& physicalDeviceDescriptorIndexingFeatures = physicalDevice.GetPhysicalDeviceDescriptorIndexingFeatures(); descriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing = physicalDeviceDescriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing; @@ -181,6 +158,15 @@ namespace AZ descriptorIndexingFeatures.descriptorBindingVariableDescriptorCount = physicalDeviceDescriptorIndexingFeatures.descriptorBindingVariableDescriptorCount; descriptorIndexingFeatures.runtimeDescriptorArray = physicalDeviceDescriptorIndexingFeatures.runtimeDescriptorArray; + VkPhysicalDeviceBufferDeviceAddressFeaturesEXT bufferDeviceAddressFeatures = {}; + bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT; + const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT& physicalDeviceBufferDeviceAddressFeatures = + physicalDevice.GetPhysicalDeviceBufferDeviceAddressFeatures(); + bufferDeviceAddressFeatures.bufferDeviceAddress = physicalDeviceBufferDeviceAddressFeatures.bufferDeviceAddress; + bufferDeviceAddressFeatures.bufferDeviceAddressCaptureReplay = physicalDeviceBufferDeviceAddressFeatures.bufferDeviceAddressCaptureReplay; + bufferDeviceAddressFeatures.bufferDeviceAddressMultiDevice = physicalDeviceBufferDeviceAddressFeatures.bufferDeviceAddressMultiDevice; + descriptorIndexingFeatures.pNext = &bufferDeviceAddressFeatures; + VkPhysicalDeviceDepthClipEnableFeaturesEXT depthClipEnabled = {}; depthClipEnabled.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT; depthClipEnabled.depthClipEnable = physicalDevice.GetPhysicalDeviceDepthClipEnableFeatures().depthClipEnable; @@ -189,7 +175,7 @@ namespace AZ VkPhysicalDeviceRobustness2FeaturesEXT robustness2 = {}; robustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; robustness2.nullDescriptor = physicalDevice.GetPhysicalDeviceRobutness2Features().nullDescriptor; - depthClipEnabled.pNext = &robustness2; + bufferDeviceAddressFeatures.pNext = &robustness2; VkPhysicalDeviceVulkan12Features vulkan12Features = {}; VkPhysicalDeviceShaderFloat16Int8FeaturesKHR float16Int8 = {}; @@ -200,6 +186,7 @@ namespace AZ if (majorVersion >= 1 && minorVersion >= 2) { vulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features = physicalDevice.GetPhysicalDeviceVulkan12Features(); vulkan12Features.drawIndirectCount = physicalDevice.GetPhysicalDeviceVulkan12Features().drawIndirectCount; vulkan12Features.shaderFloat16 = physicalDevice.GetPhysicalDeviceVulkan12Features().shaderFloat16; vulkan12Features.shaderInt8 = physicalDevice.GetPhysicalDeviceVulkan12Features().shaderInt8; @@ -800,6 +787,23 @@ namespace AZ return *m_nullDescriptorManager; } + VkBufferUsageFlags Device::ValidateBufferUsageFlagsByFeatures(const VkBufferUsageFlags& bufferUsageFlags) const + { + const auto& physicalDevice = static_cast(GetPhysicalDevice()); + + VkBufferUsageFlags result = bufferUsageFlags; + if (!physicalDevice.GetPhysicalDeviceBufferDeviceAddressFeatures().bufferDeviceAddress) + { + result &= ~VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + } + if (!physicalDevice.IsOptionalDeviceExtensionSupported(OptionalDeviceExtension::AccelerationStructure)) + { + result &= ~VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; + } + + return result; + } + VkBuffer Device::CreateBufferResouce(const RHI::BufferDescriptor& descriptor) const { AZ_Assert(descriptor.m_sharedQueueMask != RHI::HardwareQueueClassMask::None, "Invalid shared queue mask"); @@ -811,9 +815,9 @@ namespace AZ createInfo.flags = 0; createInfo.size = descriptor.m_byteCount; createInfo.usage = GetBufferUsageFlagBits(descriptor.m_bindFlags); + createInfo.usage = ValidateBufferUsageFlagsByFeatures(createInfo.usage); // Trying to guess here if the buffers are going to be used as attachments. Maybe it would be better to add an explicit flag in the descriptor. - createInfo.sharingMode = RHI::CheckBitsAny(descriptor.m_bindFlags, RHI::BufferBindFlags::ShaderWrite | RHI::BufferBindFlags::Predication | RHI::BufferBindFlags::Indirect) ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT; - createInfo.queueFamilyIndexCount = static_cast(queueFamilies.size()); + createInfo.sharingMode = RHI::CheckBitsAny(descriptor.m_bindFlags, RHI::BufferBindFlags::ShaderWrite | RHI::BufferBindFlags::Predication | RHI::BufferBindFlags::Indirect) ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = static_cast(queueFamilies.size()); createInfo.pQueueFamilyIndices = queueFamilies.empty() ? nullptr : queueFamilies.data(); VkBuffer vkBuffer = VK_NULL_HANDLE; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h index d79b937d17..94e78afc0c 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.h @@ -149,6 +149,8 @@ namespace AZ template RHI::Ptr AcquireObjectFromCache(ObjectCache& cache, const size_t hash, Args... args); + VkBufferUsageFlags ValidateBufferUsageFlagsByFeatures(const VkBufferUsageFlags& bufferUsageFlags) const; + VkDevice m_nativeDevice = VK_NULL_HANDLE; VkPhysicalDeviceFeatures m_enabledDeviceFeatures{}; VkPipelineStageFlags m_supportedPipelineStageFlagsMask = ~0; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp index 9fd38aab93..e597ef30b8 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp @@ -133,6 +133,11 @@ namespace AZ return m_descriptorIndexingFeatures; } + const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT& PhysicalDevice::GetPhysicalDeviceBufferDeviceAddressFeatures() const + { + return m_bufferDeviceAddressFeatures; + } + const VkPhysicalDeviceVulkan12Features& PhysicalDevice::GetPhysicalDeviceVulkan12Features() const { return m_vulkan12Features; @@ -234,6 +239,48 @@ namespace AZ (m_separateDepthStencilFeatures.separateDepthStencilLayouts && VK_DEVICE_EXTENSION_SUPPORTED(KHR_separate_depth_stencil_layouts)) || (m_vulkan12Features.separateDepthStencilLayouts)); m_features.set(static_cast(DeviceFeature::DescriptorIndexing), VK_DEVICE_EXTENSION_SUPPORTED(EXT_descriptor_indexing)); + m_features.set(static_cast(DeviceFeature::BufferDeviceAddress), VK_DEVICE_EXTENSION_SUPPORTED(EXT_buffer_device_address)); + } + + RawStringList PhysicalDevice::FilterSupportedOptionalExtensions() + { + // The order must match the enum OptionalDeviceExtensions + RawStringList optionalExtensions = { { + VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, + VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, + VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, + VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, + VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, + VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME, + VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME, + VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, + VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, + + // ray tracing extensions + VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, + VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, + VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, + VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, + VK_KHR_SPIRV_1_4_EXTENSION_NAME, + VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME + } }; + + StringList deviceExtensions = GetDeviceExtensionNames(); + RawStringList filteredOptionalExtensions = FilterList(optionalExtensions, deviceExtensions); + + uint32_t originalIndex = 0; + for (const auto& extension : filteredOptionalExtensions) + { + while (strcmp(extension, optionalExtensions[originalIndex]) != 0) + { + ++originalIndex; + } + m_optionalExtensions.set(originalIndex); + ++originalIndex; + } + + return filteredOptionalExtensions; } void PhysicalDevice::CompileMemoryStatistics(RHI::MemoryStatisticsBuilder& builder) const @@ -271,10 +318,15 @@ namespace AZ descriptorIndexingFeatures = {}; descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; + VkPhysicalDeviceBufferDeviceAddressFeaturesEXT& bufferDeviceAddressFeatures = m_bufferDeviceAddressFeatures; + bufferDeviceAddressFeatures = {}; + bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT; + descriptorIndexingFeatures.pNext = &bufferDeviceAddressFeatures; + VkPhysicalDeviceDepthClipEnableFeaturesEXT& dephClipEnableFeatures = m_dephClipEnableFeatures; dephClipEnableFeatures = {}; dephClipEnableFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT; - descriptorIndexingFeatures.pNext = &dephClipEnableFeatures; + bufferDeviceAddressFeatures.pNext = &dephClipEnableFeatures; VkPhysicalDeviceRobustness2FeaturesEXT& robustness2Feature = m_robutness2Features; robustness2Feature = {}; @@ -402,5 +454,11 @@ namespace AZ return m_features.test(index); } + bool PhysicalDevice::IsOptionalDeviceExtensionSupported(OptionalDeviceExtension optionalDeviceExtension) const + { + uint32_t index = static_cast(optionalDeviceExtension); + AZ_Assert(index < m_optionalExtensions.size(), "Invalid feature %d", index); + return m_optionalExtensions.test(index); + } } } diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.h index 9667e03d3b..0b84f42e0d 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.h @@ -35,9 +35,31 @@ namespace AZ NullDescriptor, SeparateDepthStencil, DescriptorIndexing, + BufferDeviceAddress, Count // Must be last }; + enum class OptionalDeviceExtension : uint32_t + { + SampleLocation = 0, + ConditionalRendering, + MemoryBudget, + DepthClipEnable, + ConservativeRasterization, + DrawIndirectCount, + RelaxedBlockLayout, + Robustness2, + ShaderFloat16Int8, + AccelerationStructure, + RayTracingPipeline, + BufferDeviceAddress, + DeferredHostOperations, + DescriptorIndexing, + Spirv14, + ShaderFloatControls, + Count + }; + class PhysicalDevice final : public RHI::PhysicalDevice { @@ -51,6 +73,7 @@ namespace AZ const VkPhysicalDevice& GetNativePhysicalDevice() const; const VkPhysicalDeviceMemoryProperties& GetMemoryProperties() const; bool IsFeatureSupported(DeviceFeature feature) const; + bool IsOptionalDeviceExtensionSupported(OptionalDeviceExtension optionalDeviceExtension) const; const VkPhysicalDeviceLimits& GetDeviceLimits() const; const VkPhysicalDeviceFeatures& GetPhysicalDeviceFeatures() const; const VkPhysicalDeviceProperties& GetPhysicalDeviceProperties() const; @@ -59,6 +82,7 @@ namespace AZ const VkPhysicalDeviceRobustness2FeaturesEXT& GetPhysicalDeviceRobutness2Features() const; const VkPhysicalDeviceShaderFloat16Int8FeaturesKHR& GetPhysicalDeviceFloat16Int8Features() const; const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& GetPhysicalDeviceDescriptorIndexingFeatures() const; + const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT& GetPhysicalDeviceBufferDeviceAddressFeatures() const; const VkPhysicalDeviceVulkan12Features& GetPhysicalDeviceVulkan12Features() const; const VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR& GetPhysicalDeviceSeparateDepthStencilFeatures() const; const VkPhysicalDeviceAccelerationStructurePropertiesKHR& GetPhysicalDeviceAccelerationStructureProperties() const; @@ -68,6 +92,7 @@ namespace AZ StringList GetDeviceExtensionNames(const char* layerName = nullptr) const; bool IsFormatSupported(RHI::Format format, VkImageTiling tiling, VkFormatFeatureFlags features) const; void LoadSupportedFeatures(); + RawStringList FilterSupportedOptionalExtensions(); void CompileMemoryStatistics(RHI::MemoryStatisticsBuilder& builder) const; private: @@ -82,6 +107,7 @@ namespace AZ VkPhysicalDevice m_vkPhysicalDevice = VK_NULL_HANDLE; VkPhysicalDeviceMemoryProperties m_memoryProperty{}; + AZStd::bitset(OptionalDeviceExtension::Count)> m_optionalExtensions; AZStd::bitset(DeviceFeature::Count)> m_features; VkPhysicalDeviceFeatures m_deviceFeatures{}; VkPhysicalDeviceProperties m_deviceProperties{}; @@ -90,6 +116,7 @@ namespace AZ VkPhysicalDeviceRobustness2FeaturesEXT m_robutness2Features{}; VkPhysicalDeviceShaderFloat16Int8FeaturesKHR m_float16Int8Features{}; VkPhysicalDeviceDescriptorIndexingFeaturesEXT m_descriptorIndexingFeatures{}; + VkPhysicalDeviceBufferDeviceAddressFeaturesEXT m_bufferDeviceAddressFeatures{}; VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR m_separateDepthStencilFeatures{}; VkPhysicalDeviceAccelerationStructurePropertiesKHR m_accelerationStructureProperties{}; VkPhysicalDeviceRayTracingPipelinePropertiesKHR m_rayTracingPipelineProperties{};