diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-11-25 16:05:15 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-11-25 16:05:15 +0000 |
| commit | 96d39d3be6c2a1e94070f73c62fa85ccf86ddca8 (patch) | |
| tree | 507383f96c67adb285dd1fed28c02c6dc810eea4 /Graphics/GraphicsEngineVulkan | |
| parent | Merge branch 'master' into ray_tracing_2 (diff) | |
| download | DiligentCore-96d39d3be6c2a1e94070f73c62fa85ccf86ddca8.tar.gz DiligentCore-96d39d3be6c2a1e94070f73c62fa85ccf86ddca8.zip | |
Added support for VK_KHR_acceleration_structure and VK_KHR_ray_tracing_pipeline
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
21 files changed, 279 insertions, 905 deletions
diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index 48e0a5c3..e5cd319c 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -124,7 +124,6 @@ set(VULKAN_UTILS_SRC src/VulkanUtilities/VulkanLogicalDevice.cpp src/VulkanUtilities/VulkanMemoryManager.cpp src/VulkanUtilities/VulkanPhysicalDevice.cpp - src/VulkanUtilities/VulkanRayTracingKHRviaNV.cpp ) set(GENERATE_MIPS_SHADER shaders/GenerateMipsCS.csh) diff --git a/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp index 85665f2c..d67fe937 100644 --- a/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp @@ -72,6 +72,7 @@ public: private: VkDeviceAddress m_DeviceAddress = 0; VulkanUtilities::AccelStructWrapper m_VulkanBLAS; + VulkanUtilities::BufferWrapper m_VulkanBuffer; VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation; VkDeviceSize m_MemoryAlignedOffset = 0; }; diff --git a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp index f9e42cab..6eda1339 100644 --- a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp @@ -67,10 +67,15 @@ public: /// Implementation of ITopLevelASVk::GetVkTLAS(). virtual VkAccelerationStructureKHR DILIGENT_CALL_TYPE GetVkTLAS() const override { return m_VulkanTLAS; } + /// Implementation of ITopLevelASVk::GetVkDeviceAddress(). + virtual VkDeviceAddress DILIGENT_CALL_TYPE GetVkDeviceAddress() const override { return m_DeviceAddress; } + const VkAccelerationStructureKHR* GetVkTLASPtr() const { return &m_VulkanTLAS; } private: + VkDeviceAddress m_DeviceAddress = 0; VulkanUtilities::AccelStructWrapper m_VulkanTLAS; + VulkanUtilities::BufferWrapper m_VulkanBuffer; VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation; VkDeviceSize m_MemoryAlignedOffset = 0; }; diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp index 8a21fb17..c0d79648 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp @@ -605,9 +605,9 @@ public: dstBuffer, dstOffset, stride, flags); } - __forceinline void BuildAccelerationStructure(uint32_t infoCount, - const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, - const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos) + __forceinline void BuildAccelerationStructure(uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { #if DILIGENT_USE_VOLK VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); @@ -616,7 +616,7 @@ public: // Build AS operations must be performed outside of render pass. EndRenderPass(); } - vkCmdBuildAccelerationStructureKHR(m_VkCmdBuffer, infoCount, pInfos, ppOffsetInfos); + vkCmdBuildAccelerationStructuresKHR(m_VkCmdBuffer, infoCount, pInfos, ppBuildRangeInfos); #else UNSUPPORTED("Ray tracing is not supported when vulkan library is linked statically"); #endif @@ -652,13 +652,13 @@ public: #endif } - __forceinline void TraceRays(const VkStridedBufferRegionKHR& RaygenShaderBindingTable, - const VkStridedBufferRegionKHR& MissShaderBindingTable, - const VkStridedBufferRegionKHR& HitShaderBindingTable, - const VkStridedBufferRegionKHR& CallableShaderBindingTable, - uint32_t width, - uint32_t height, - uint32_t depth) + __forceinline void TraceRays(const VkStridedDeviceAddressRegionKHR& RaygenShaderBindingTable, + const VkStridedDeviceAddressRegionKHR& MissShaderBindingTable, + const VkStridedDeviceAddressRegionKHR& HitShaderBindingTable, + const VkStridedDeviceAddressRegionKHR& CallableShaderBindingTable, + uint32_t width, + uint32_t height, + uint32_t depth) { #if DILIGENT_USE_VOLK VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h index 4b352cd6..bb95a9e4 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h @@ -31,11 +31,7 @@ # define VK_NO_PROTOTYPES #endif -// TODO: remove when ray tracing is released -#define VK_ENABLE_BETA_EXTENSIONS - #include "vulkan/vulkan.h" -#include "vulkan/vulkan_beta.h" #define VK_FORMAT_RANGE_SIZE (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1) diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp index f68d7138..0e309eff 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp @@ -174,13 +174,10 @@ public: VkMemoryRequirements GetBufferMemoryRequirements(VkBuffer vkBuffer) const; VkMemoryRequirements GetImageMemoryRequirements (VkImage vkImage ) const; - - VkMemoryRequirements GetASMemoryRequirements(const VkAccelerationStructureMemoryRequirementsInfoKHR& Info) const; VkDeviceAddress GetAccelerationStructureDeviceAddress(VkAccelerationStructureKHR AS) const; VkResult BindBufferMemory(VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset) const; VkResult BindImageMemory (VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) const; - VkResult BindASMemory (VkAccelerationStructureKHR AS, VkDeviceMemory memory, VkDeviceSize memoryOffset) const; // clang-format on VkResult MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) const; diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp index b76648a6..404e3eee 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp @@ -39,23 +39,24 @@ class VulkanPhysicalDevice public: struct ExtensionFeatures { - VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {}; - VkPhysicalDevice16BitStorageFeaturesKHR Storage16Bit = {}; - VkPhysicalDevice8BitStorageFeaturesKHR Storage8Bit = {}; - VkPhysicalDeviceShaderFloat16Int8FeaturesKHR ShaderFloat16Int8 = {}; - VkPhysicalDeviceRayTracingFeaturesKHR RayTracing = {}; - bool RayTracingNV = false; // indicates that KHR extension is emulated by NV extension - 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 = {}; + 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 = {}; }; struct ExtensionProperties { - VkPhysicalDeviceMeshShaderPropertiesNV MeshShader = {}; - VkPhysicalDeviceRayTracingPropertiesKHR RayTracing = {}; - VkPhysicalDeviceDescriptorIndexingPropertiesEXT DescriptorIndexing = {}; + VkPhysicalDeviceMeshShaderPropertiesNV MeshShader = {}; + VkPhysicalDeviceAccelerationStructurePropertiesKHR AccelStruct = {}; + VkPhysicalDeviceRayTracingPipelinePropertiesKHR RayTracingPipeline = {}; + VkPhysicalDeviceDescriptorIndexingPropertiesEXT DescriptorIndexing = {}; }; public: diff --git a/Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h b/Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h index 161de182..c09f10c0 100644 --- a/Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h @@ -50,6 +50,9 @@ DILIGENT_BEGIN_INTERFACE(ITopLevelASVk, ITopLevelAS) { /// Returns a Vulkan TLAS object handle. VIRTUAL VkAccelerationStructureKHR METHOD(GetVkTLAS)(THIS) CONST PURE; + + /// Returns a Vulkan TLAS device address. + VIRTUAL VkDeviceAddress METHOD(GetVkDeviceAddress)(THIS) CONST PURE; }; DILIGENT_END_INTERFACE @@ -57,7 +60,8 @@ DILIGENT_END_INTERFACE #if DILIGENT_C_INTERFACE -# define ITopLevelASVk_GetVkTLAS(This) CALL_IFACE_METHOD(TopLevelASVk, GetVkTLAS, This) +# define ITopLevelASVk_GetVkTLAS(This) CALL_IFACE_METHOD(TopLevelASVk, GetVkTLAS, This) +# define ITopLevelASVk_GetVkDeviceAddress(This) CALL_IFACE_METHOD(TopLevelASVk, GetVkDeviceAddress, This) #endif diff --git a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp index 4e23a13a..ffe1eb02 100644 --- a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp @@ -37,48 +37,44 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, const BottomLevelASDesc& Desc) : TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc} { - const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); - const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice(); - const auto& Limits = PhysicalDevice.GetExtProperties().RayTracing; + const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); + const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice(); + const auto& Limits = PhysicalDevice.GetExtProperties().AccelStruct; + Uint32 AccelStructSize = m_Desc.CompactedSize; - VkAccelerationStructureCreateInfoKHR CreateInfo = {}; - std::vector<VkAccelerationStructureCreateGeometryTypeInfoKHR> vkGeometries; - - CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; - CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; - CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); - - if (m_Desc.CompactedSize > 0) + if (AccelStructSize == 0) { - CreateInfo.compactedSize = m_Desc.CompactedSize; - } - else - { - CreateInfo.maxGeometryCount = m_Desc.TriangleCount + m_Desc.BoxCount; - vkGeometries.resize(CreateInfo.maxGeometryCount); - CreateInfo.pGeometryInfos = vkGeometries.data(); + VkAccelerationStructureBuildGeometryInfoKHR vkBuildInfo = {}; + std::vector<VkAccelerationStructureGeometryKHR> vkGeometries; + std::vector<uint32_t> MaxPrimitiveCounts; + VkAccelerationStructureBuildSizesInfoKHR vkSizeInfo = {VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR}; - VERIFY_EXPR(CreateInfo.maxGeometryCount <= Limits.maxGeometryCount); + vkGeometries.resize(Desc.TriangleCount + Desc.BoxCount); + MaxPrimitiveCounts.resize(vkGeometries.size()); if (m_Desc.pTriangles != nullptr) { - Uint32 MaxPrimitiveCount = 0; for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i) { auto& src = m_Desc.pTriangles[i]; auto& dst = vkGeometries[i]; - - dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; - dst.pNext = nullptr; - dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; - dst.maxPrimitiveCount = src.MaxPrimitiveCount; - dst.indexType = TypeToVkIndexType(src.IndexType); - dst.maxVertexCount = src.MaxVertexCount; - dst.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); - dst.allowsTransforms = src.AllowsTransforms; - - MaxPrimitiveCount += dst.maxPrimitiveCount; + auto& tri = dst.geometry.triangles; + + dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + dst.pNext = nullptr; + dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; + dst.flags = VkGeometryFlagsKHR(0); + + tri.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; + tri.pNext = nullptr; + tri.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); + tri.maxVertex = src.MaxVertexCount; + tri.indexType = TypeToVkIndexType(src.IndexType); + tri.transformData.deviceAddress = src.AllowsTransforms ? 1 : 0; + MaxPrimitiveCounts[i] = src.MaxPrimitiveCount; + + MaxPrimitiveCount += src.MaxPrimitiveCount; } VERIFY_EXPR(MaxPrimitiveCount <= Limits.maxPrimitiveCount); } @@ -89,17 +85,17 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, { auto& src = m_Desc.pBoxes[i]; auto& dst = vkGeometries[i]; + auto& box = dst.geometry.aabbs; + + dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + dst.pNext = nullptr; + dst.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; - dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; - dst.pNext = nullptr; - dst.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; - dst.maxPrimitiveCount = src.MaxBoxCount; - dst.indexType = VK_INDEX_TYPE_NONE_KHR; - dst.maxVertexCount = 0; - dst.vertexFormat = VK_FORMAT_UNDEFINED; - dst.allowsTransforms = VK_FALSE; + box.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR; + box.pNext = nullptr; + MaxPrimitiveCounts[i] = src.MaxBoxCount; - MaxBoxCount += dst.maxPrimitiveCount; + MaxBoxCount += src.MaxBoxCount; } VERIFY_EXPR(MaxBoxCount <= Limits.maxPrimitiveCount); } @@ -107,46 +103,58 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, { UNEXPECTED("Either pTriangles or pBoxes must not be null"); } - } - m_VulkanBLAS = LogicalDevice.CreateAccelStruct(CreateInfo, m_Desc.Name); + vkBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; + vkBuildInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); + vkBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; + vkBuildInfo.pGeometries = vkGeometries.data(); + vkBuildInfo.geometryCount = static_cast<uint32_t>(vkGeometries.size()); - VkAccelerationStructureMemoryRequirementsInfoKHR MemInfo = {}; - VkMemoryRequirements MemReqs = {}; + VERIFY_EXPR(vkBuildInfo.geometryCount <= Limits.maxGeometryCount); - MemInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR; - MemInfo.accelerationStructure = m_VulkanBLAS; - MemInfo.buildType = VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR; - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_KHR; + vkGetAccelerationStructureBuildSizesKHR(LogicalDevice.GetVkDevice(), VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &vkBuildInfo, MaxPrimitiveCounts.data(), &vkSizeInfo); - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); + AccelStructSize = static_cast<Uint32>(vkSizeInfo.accelerationStructureSize); + m_ScratchSize.Build = static_cast<Uint32>(vkSizeInfo.buildScratchSize); + m_ScratchSize.Update = static_cast<Uint32>(vkSizeInfo.updateScratchSize); + } - uint32_t MemoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(MemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VkBufferCreateInfo vkBuffCI = {}; - if (MemoryTypeIndex == VulkanUtilities::VulkanPhysicalDevice::InvalidMemoryTypeIndex) - LOG_ERROR_AND_THROW("Failed to find suitable memory type for BLAS '", m_Desc.Name, '\''); + vkBuffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + vkBuffCI.flags = 0; + vkBuffCI.size = AccelStructSize; + vkBuffCI.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR; + vkBuffCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + vkBuffCI.queueFamilyIndexCount = 0; + vkBuffCI.pQueueFamilyIndices = nullptr; + + m_VulkanBuffer = LogicalDevice.CreateBuffer(vkBuffCI, m_Desc.Name); + + VkMemoryRequirements MemReqs = LogicalDevice.GetBufferMemoryRequirements(m_VulkanBuffer); + uint32_t MemoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(MemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VERIFY(IsPowerOfTwo(MemReqs.alignment), "Alignment is not power of 2!"); - m_MemoryAllocation = pRenderDeviceVk->AllocateMemory(MemReqs.size, MemReqs.alignment, MemoryTypeIndex); + m_MemoryAllocation = pRenderDeviceVk->AllocateMemory(MemReqs.size, MemReqs.alignment, MemoryTypeIndex, VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT); + m_MemoryAlignedOffset = Align(VkDeviceSize{m_MemoryAllocation.UnalignedOffset}, MemReqs.alignment); VERIFY(m_MemoryAllocation.Size >= MemReqs.size + (m_MemoryAlignedOffset - m_MemoryAllocation.UnalignedOffset), "Size of memory allocation is too small"); - auto Memory = m_MemoryAllocation.Page->GetVkMemory(); - auto err = LogicalDevice.BindASMemory(m_VulkanBLAS, Memory, m_MemoryAlignedOffset); - CHECK_VK_ERROR_AND_THROW(err, "Failed to bind AS memory"); + auto err = LogicalDevice.BindBufferMemory(m_VulkanBuffer, Memory, m_MemoryAlignedOffset); + CHECK_VK_ERROR_AND_THROW(err, "Failed to bind buffer memory"); - m_DeviceAddress = LogicalDevice.GetAccelerationStructureDeviceAddress(m_VulkanBLAS); + VkAccelerationStructureCreateInfoKHR vkAccelStrCI = {}; - if (m_Desc.CompactedSize == 0) - { - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size); + vkAccelStrCI.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; + vkAccelStrCI.createFlags = 0; + vkAccelStrCI.buffer = m_VulkanBuffer; + vkAccelStrCI.offset = 0; + vkAccelStrCI.size = AccelStructSize; + vkAccelStrCI.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size); - } + m_VulkanBLAS = LogicalDevice.CreateAccelStruct(vkAccelStrCI, m_Desc.Name); + + m_DeviceAddress = LogicalDevice.GetAccelerationStructureDeviceAddress(m_VulkanBLAS); SetState(RESOURCE_STATE_BUILD_AS_READ); } @@ -168,6 +176,8 @@ BottomLevelASVkImpl::~BottomLevelASVkImpl() // Vk object can only be destroyed when it is no longer used by the GPU if (m_VulkanBLAS != VK_NULL_HANDLE) m_pDevice->SafeReleaseDeviceObject(std::move(m_VulkanBLAS), m_Desc.CommandQueueMask); + if (m_VulkanBuffer != VK_NULL_HANDLE) + m_pDevice->SafeReleaseDeviceObject(std::move(m_VulkanBuffer), m_Desc.CommandQueueMask); if (m_MemoryAllocation.Page != nullptr) m_pDevice->SafeReleaseDeviceObject(std::move(m_MemoryAllocation), m_Desc.CommandQueueMask); } diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp index 605d1363..52f586b6 100644 --- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp @@ -159,7 +159,10 @@ BufferVkImpl::BufferVkImpl(IReferenceCounters* pRefCounters, } case BIND_RAY_TRACING: { - VkBuffCI.usage |= VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBuffCI.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; // for scratch buffer + VkBuffCI.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBuffCI.usage |= VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; // acceleration structure build inputs such as vertex, index, transform, aabb, and instance data + VkBuffCI.usage |= VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR; break; } default: diff --git a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp index 45045cea..56a83b85 100644 --- a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp @@ -67,7 +67,7 @@ static std::vector<VkDescriptorPoolSize> PrunePoolSizes(RenderDeviceVkImpl& Devi switch (iter->type) { case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: - if (Feats.RayTracing.rayTracing == VK_FALSE) + if (Feats.RayTracingPipeline.rayTracingPipeline == VK_FALSE) iter = PoolSizes.erase(iter); else ++iter; diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index a38ed072..3cab0ae2 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -2750,14 +2750,14 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) TransitionOrVerifyBLASState(*pBLASVk, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); TransitionOrVerifyBufferState(*pScratchVk, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, OpName); - VkAccelerationStructureBuildGeometryInfoKHR Info = {}; - std::vector<VkAccelerationStructureBuildOffsetInfoKHR> Offsets; - std::vector<VkAccelerationStructureGeometryKHR> Geometries; + VkAccelerationStructureBuildGeometryInfoKHR vkASBuildInfo = {}; + std::vector<VkAccelerationStructureBuildRangeInfoKHR> vkRanges; + std::vector<VkAccelerationStructureGeometryKHR> vkGeometries; if (Attribs.pTriangleData != nullptr) { - Geometries.resize(Attribs.TriangleDataCount); - Offsets.resize(Attribs.TriangleDataCount); + vkGeometries.resize(Attribs.TriangleDataCount); + vkRanges.resize(Attribs.TriangleDataCount); pBLASVk->SetActualGeometryCount(Attribs.TriangleDataCount); for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i) @@ -2772,9 +2772,9 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) continue; } - auto& vkGeo = Geometries[Idx]; + auto& vkGeo = vkGeometries[Idx]; auto& vkTris = vkGeo.geometry.triangles; - auto& off = Offsets[Idx]; + auto& off = vkRanges[Idx]; const auto& TriDesc = BLASDesc.pTriangles[GeoIdx]; vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; @@ -2829,8 +2829,8 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) } else if (Attribs.pBoxData != nullptr) { - Geometries.resize(Attribs.BoxDataCount); - Offsets.resize(Attribs.BoxDataCount); + vkGeometries.resize(Attribs.BoxDataCount); + vkRanges.resize(Attribs.BoxDataCount); pBLASVk->SetActualGeometryCount(Attribs.BoxDataCount); for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i) @@ -2845,9 +2845,9 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) continue; } - auto& vkGeo = Geometries[Idx]; + auto& vkGeo = vkGeometries[Idx]; auto& vkAABBs = vkGeo.geometry.aabbs; - auto& off = Offsets[Idx]; + auto& off = vkRanges[Idx]; vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; vkGeo.pNext = nullptr; @@ -2871,22 +2871,21 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) } } - VkAccelerationStructureGeometryKHR const* GeometriesPtr = Geometries.data(); - VkAccelerationStructureBuildOffsetInfoKHR const* OffsetsPtr = Offsets.data(); + VkAccelerationStructureBuildRangeInfoKHR const* VkRangePtr = vkRanges.data(); - Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; - Info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; // type must be compatible with create info - Info.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(BLASDesc.Flags); // flags must be compatible with create info - Info.update = Attribs.Update; - Info.srcAccelerationStructure = Attribs.Update ? pBLASVk->GetVkBLAS() : VK_NULL_HANDLE; - Info.dstAccelerationStructure = pBLASVk->GetVkBLAS(); - Info.geometryArrayOfPointers = VK_FALSE; - Info.geometryCount = static_cast<uint32_t>(Geometries.size()); - Info.ppGeometries = &GeometriesPtr; - Info.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset; + vkASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; + vkASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; // type must be compatible with create info + vkASBuildInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(BLASDesc.Flags); // flags must be compatible with create info + vkASBuildInfo.mode = Attribs.Update ? VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR : VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; + vkASBuildInfo.srcAccelerationStructure = Attribs.Update ? pBLASVk->GetVkBLAS() : VK_NULL_HANDLE; + vkASBuildInfo.dstAccelerationStructure = pBLASVk->GetVkBLAS(); + vkASBuildInfo.geometryCount = static_cast<uint32_t>(vkGeometries.size()); + vkASBuildInfo.pGeometries = vkGeometries.data(); + vkASBuildInfo.ppGeometries = nullptr; + vkASBuildInfo.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset; EnsureVkCmdBuffer(); - m_CommandBuffer.BuildAccelerationStructure(1, &Info, &OffsetsPtr); + m_CommandBuffer.BuildAccelerationStructure(1, &vkASBuildInfo, &VkRangePtr); ++m_State.NumCommands; #ifdef DILIGENT_DEVELOPMENT @@ -2958,13 +2957,12 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs) } TransitionOrVerifyBufferState(*pInstancesVk, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName); - VkAccelerationStructureBuildGeometryInfoKHR vkASBuildInfo = {}; - VkAccelerationStructureBuildOffsetInfoKHR vkASBuildOffset = {}; - VkAccelerationStructureBuildOffsetInfoKHR const* vkASBuildOffsetPtr = &vkASBuildOffset; - VkAccelerationStructureGeometryKHR vkASGeometry = {}; - VkAccelerationStructureGeometryKHR const* vkASGeometriesPtr = &vkASGeometry; + VkAccelerationStructureBuildGeometryInfoKHR vkASBuildInfo = {}; + VkAccelerationStructureBuildRangeInfoKHR vkRange = {}; + VkAccelerationStructureBuildRangeInfoKHR const* vkRangePtr = &vkRange; + VkAccelerationStructureGeometryKHR vkASGeometry = {}; - vkASBuildOffset.primitiveCount = Attribs.InstanceCount; + vkRange.primitiveCount = Attribs.InstanceCount; vkASGeometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; vkASGeometry.pNext = nullptr; @@ -2982,15 +2980,15 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs) vkASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; vkASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; // type must be compatible with create info vkASBuildInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(TLASDesc.Flags); // flags must be compatible with create info - vkASBuildInfo.update = Attribs.Update; + vkASBuildInfo.mode = Attribs.Update ? VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR : VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; vkASBuildInfo.srcAccelerationStructure = Attribs.Update ? pTLASVk->GetVkTLAS() : VK_NULL_HANDLE; vkASBuildInfo.dstAccelerationStructure = pTLASVk->GetVkTLAS(); - vkASBuildInfo.geometryArrayOfPointers = VK_FALSE; vkASBuildInfo.geometryCount = 1; - vkASBuildInfo.ppGeometries = &vkASGeometriesPtr; + vkASBuildInfo.pGeometries = &vkASGeometry; + vkASBuildInfo.ppGeometries = nullptr; vkASBuildInfo.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset; - m_CommandBuffer.BuildAccelerationStructure(1, &vkASBuildInfo, &vkASBuildOffsetPtr); + m_CommandBuffer.BuildAccelerationStructure(1, &vkASBuildInfo, &vkRangePtr); ++m_State.NumCommands; } @@ -3150,10 +3148,10 @@ void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs) TransitionOrVerifyBufferState(*pBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_RAY_TRACING, VK_ACCESS_SHADER_READ_BIT, OpName); // clang-format off - VkStridedBufferRegionKHR RaygenShaderBindingTable = {pBufferVk->GetVkBuffer(), RayGenShaderRecord.Offset, RayGenShaderRecord.Stride, RayGenShaderRecord.Size }; - VkStridedBufferRegionKHR MissShaderBindingTable = {pBufferVk->GetVkBuffer(), MissShaderTable.Offset, MissShaderTable.Stride, MissShaderTable.Size }; - VkStridedBufferRegionKHR HitShaderBindingTable = {pBufferVk->GetVkBuffer(), HitGroupTable.Offset, HitGroupTable.Stride, HitGroupTable.Size }; - VkStridedBufferRegionKHR CallableShaderBindingTable = {pBufferVk->GetVkBuffer(), CallableShaderTable.Offset, CallableShaderTable.Stride, CallableShaderTable.Size}; + VkStridedDeviceAddressRegionKHR RaygenShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + RayGenShaderRecord.Offset, RayGenShaderRecord.Stride, RayGenShaderRecord.Size }; + VkStridedDeviceAddressRegionKHR MissShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + MissShaderTable.Offset, MissShaderTable.Stride, MissShaderTable.Size }; + VkStridedDeviceAddressRegionKHR HitShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + HitGroupTable.Offset, HitGroupTable.Stride, HitGroupTable.Size }; + VkStridedDeviceAddressRegionKHR CallableShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + CallableShaderTable.Offset, CallableShaderTable.Stride, CallableShaderTable.Size}; // clang-format on PrepareForRayTracing(); diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 705cdede..93fb9f34 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -278,7 +278,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E ENABLE_FEATURE(Storage8BitFeats.uniformAndStorageBuffer8BitAccess != VK_FALSE, UniformBuffer8BitAccess, "8-bit uniform buffer access is"); // clang-format on - ENABLE_FEATURE((DeviceExtFeatures.RayTracing.rayTracing != VK_FALSE && DeviceExtFeatures.Spirv14) || DeviceExtFeatures.RayTracingNV, RayTracing, "Ray tracing is"); + ENABLE_FEATURE(DeviceExtFeatures.AccelStruct.accelerationStructure != VK_FALSE && DeviceExtFeatures.RayTracingPipeline.rayTracingPipeline != VK_FALSE, RayTracing, "Ray tracing is"); #undef FeatureSupport @@ -405,40 +405,36 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E // Ray tracing if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED) { - if (DeviceExtFeatures.RayTracingNV) + // this extensions added to Vulkan 1.2 core + if (!DeviceExtFeatures.Spirv15) { - EnabledExtFeats.RayTracingNV = DeviceExtFeatures.RayTracingNV; - DeviceExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - DeviceExtensions.push_back(VK_NV_RAY_TRACING_EXTENSION_NAME); - } - else if (DeviceExtFeatures.RayTracing.rayTracing != VK_FALSE) - { - DeviceExtensions.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME); // required for VK_EXT_descriptor_indexing - DeviceExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); // required for VK_KHR_ray_tracing - DeviceExtensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); // required for VK_KHR_ray_tracing - DeviceExtensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); // required for VK_KHR_ray_tracing - DeviceExtensions.push_back(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // required for VK_KHR_ray_tracing - DeviceExtensions.push_back(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); // required for VK_KHR_ray_tracing - DeviceExtensions.push_back(VK_KHR_RAY_TRACING_EXTENSION_NAME); // required for VK_KHR_ray_tracing - - EnabledExtFeats.RayTracing = DeviceExtFeatures.RayTracing; - EnabledExtFeats.BufferDeviceAddress = DeviceExtFeatures.BufferDeviceAddress; - EnabledExtFeats.DescriptorIndexing = DeviceExtFeatures.DescriptorIndexing; - - if (!DeviceExtFeatures.Spirv15) - { - DeviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); // required for VK_KHR_spirv_1_4 - DeviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); // required for ray tracing shaders - EnabledExtFeats.Spirv14 = DeviceExtFeatures.Spirv14; - } - - *NextExt = &EnabledExtFeats.RayTracing; - NextExt = &EnabledExtFeats.RayTracing.pNext; - *NextExt = &EnabledExtFeats.DescriptorIndexing; - NextExt = &EnabledExtFeats.DescriptorIndexing.pNext; - *NextExt = &EnabledExtFeats.BufferDeviceAddress; - NextExt = &EnabledExtFeats.BufferDeviceAddress.pNext; + DeviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); // required for VK_KHR_spirv_1_4 + DeviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); // required for VK_KHR_ray_tracing_pipeline + EnabledExtFeats.Spirv14 = DeviceExtFeatures.Spirv14; + VERIFY_EXPR(DeviceExtFeatures.Spirv14); } + + DeviceExtensions.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME); // required for VK_EXT_descriptor_indexing + DeviceExtensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); // required for VK_KHR_acceleration_structure + 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_PIPELINE_LIBRARY_EXTENSION_NAME); // required for VK_KHR_ray_tracing_pipeline + DeviceExtensions.push_back(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); // required for ray tracing + DeviceExtensions.push_back(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); // required for ray tracing + + EnabledExtFeats.AccelStruct = DeviceExtFeatures.AccelStruct; + EnabledExtFeats.RayTracingPipeline = DeviceExtFeatures.RayTracingPipeline; + EnabledExtFeats.BufferDeviceAddress = DeviceExtFeatures.BufferDeviceAddress; + EnabledExtFeats.DescriptorIndexing = DeviceExtFeatures.DescriptorIndexing; + + *NextExt = &EnabledExtFeats.AccelStruct; + NextExt = &EnabledExtFeats.AccelStruct.pNext; + *NextExt = &EnabledExtFeats.RayTracingPipeline; + NextExt = &EnabledExtFeats.RayTracingPipeline.pNext; + *NextExt = &EnabledExtFeats.DescriptorIndexing; + NextExt = &EnabledExtFeats.DescriptorIndexing.pNext; + *NextExt = &EnabledExtFeats.BufferDeviceAddress; + NextExt = &EnabledExtFeats.BufferDeviceAddress.pNext; } // make sure that last pNext is null diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 2949c928..00bb54d9 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -348,10 +348,10 @@ static void CreateRayTracingPipeline(RenderDeviceVkImpl* { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); - const auto& RTLimits = PhysicalDevice.GetExtProperties().RayTracing; + const auto& RTLimits = PhysicalDevice.GetExtProperties().RayTracingPipeline; - DEV_CHECK_ERR(RayTracingPipeline.MaxRecursionDepth <= RTLimits.maxRecursionDepth, - "RayTracingPipeline.MaxRecursionDepth must not exceed ", RTLimits.maxRecursionDepth); + DEV_CHECK_ERR(RayTracingPipeline.MaxRecursionDepth <= RTLimits.maxRayRecursionDepth, + "RayTracingPipeline.MaxRecursionDepth must not exceed ", RTLimits.maxRayRecursionDepth); VkRayTracingPipelineCreateInfoKHR PipelineCI = {}; @@ -361,20 +361,17 @@ static void CreateRayTracingPipeline(RenderDeviceVkImpl* PipelineCI.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; #endif - PipelineCI.stageCount = static_cast<Uint32>(Stages.size()); - PipelineCI.pStages = Stages.data(); - PipelineCI.layout = Layout.GetVkPipelineLayout(); - - PipelineCI.groupCount = static_cast<Uint32>(ShaderGroups.size()); - PipelineCI.pGroups = ShaderGroups.data(); - PipelineCI.maxRecursionDepth = RayTracingPipeline.MaxRecursionDepth; - PipelineCI.libraries.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR; - PipelineCI.libraries.pNext = nullptr; - PipelineCI.libraries.libraryCount = 0; - PipelineCI.libraries.pLibraries = nullptr; - PipelineCI.pLibraryInterface = nullptr; - PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from - PipelineCI.basePipelineIndex = -1; // an index into the pCreateInfos parameter to use as a pipeline to derive from + PipelineCI.stageCount = static_cast<Uint32>(Stages.size()); + PipelineCI.pStages = Stages.data(); + PipelineCI.groupCount = static_cast<Uint32>(ShaderGroups.size()); + PipelineCI.pGroups = ShaderGroups.data(); + PipelineCI.maxPipelineRayRecursionDepth = RayTracingPipeline.MaxRecursionDepth; + PipelineCI.pLibraryInfo = nullptr; + PipelineCI.pLibraryInterface = nullptr; + PipelineCI.pDynamicState = nullptr; + PipelineCI.layout = Layout.GetVkPipelineLayout(); + PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from + PipelineCI.basePipelineIndex = -1; // an index into the pCreateInfos parameter to use as a pipeline to derive from Pipeline = LogicalDevice.CreateRayTracingPipeline(PipelineCI, VK_NULL_HANDLE, PSODesc.Name); } diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 620d29e9..c44d5642 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -162,9 +162,9 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* m_pDxCompiler{CreateDXCompiler(DXCompilerTarget::Vulkan, EngineCI.pDxCompilerPath)}, m_Properties { - m_PhysicalDevice->GetExtProperties().RayTracing.shaderGroupHandleSize, - m_PhysicalDevice->GetExtProperties().RayTracing.maxShaderGroupStride, - m_PhysicalDevice->GetExtProperties().RayTracing.shaderGroupBaseAlignment, + m_PhysicalDevice->GetExtProperties().RayTracingPipeline.shaderGroupHandleSize, + m_PhysicalDevice->GetExtProperties().RayTracingPipeline.maxShaderGroupStride, + m_PhysicalDevice->GetExtProperties().RayTracingPipeline.shaderGroupBaseAlignment, m_PhysicalDevice->GetExtProperties().MeshShader.maxDrawMeshTasksCount } // clang-format on diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index 7fbe6265..b5f7e041 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -642,8 +642,8 @@ VkResult SwapChainVkImpl::AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk) { // Next command in the device context must wait for the next image to be acquired. // Unlike fences or events, the act of waiting for a semaphore also unsignals that semaphore (6.4.2). - // Swapchain may be used as UAV in compute or ray tracing shader, so we must wait on all stages. - pDeviceCtxVk->AddWaitSemaphore(m_ImageAcquiredSemaphores[m_SemaphoreIndex], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + // Swapchain image may be used as render target or as destination for copy command. + pDeviceCtxVk->AddWaitSemaphore(m_ImageAcquiredSemaphores[m_SemaphoreIndex], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT); if (!m_SwapChainImagesInitialized[m_BackBufferIndex]) { // Vulkan validation layers do not like uninitialized memory. diff --git a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp index bfde3aa6..d4c771ec 100644 --- a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp @@ -37,68 +37,75 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters, const TopLevelASDesc& Desc) : TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc} { - const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); - const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice(); - const auto& RTLimits = PhysicalDevice.GetExtProperties().RayTracing; + const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); + const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice(); + const auto& Limits = PhysicalDevice.GetExtProperties().AccelStruct; + Uint32 AccelStructSize = m_Desc.CompactedSize; - VkAccelerationStructureCreateInfoKHR CreateInfo = {}; - VkAccelerationStructureCreateGeometryTypeInfoKHR InstanceInfo = {}; - - CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; - CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; - CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); - - if (m_Desc.CompactedSize > 0) + if (AccelStructSize == 0) { - CreateInfo.compactedSize = m_Desc.CompactedSize; + VkAccelerationStructureBuildGeometryInfoKHR vkBuildInfo = {}; + VkAccelerationStructureBuildSizesInfoKHR vkSizeInfo = {VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR}; + VkAccelerationStructureGeometryKHR vkGeometry = {}; + VkAccelerationStructureGeometryInstancesDataKHR& vkInstances = vkGeometry.geometry.instances; + const uint32_t MaxPrimitiveCount = m_Desc.MaxInstanceCount; + + vkGeometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + vkGeometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; + vkInstances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR; + vkInstances.arrayOfPointers = VK_FALSE; + + vkBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; + vkBuildInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); + vkBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + vkBuildInfo.pGeometries = &vkGeometry; + vkBuildInfo.geometryCount = 1; + + VERIFY_EXPR(MaxPrimitiveCount <= Limits.maxInstanceCount); + + vkGetAccelerationStructureBuildSizesKHR(LogicalDevice.GetVkDevice(), VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &vkBuildInfo, &MaxPrimitiveCount, &vkSizeInfo); + + AccelStructSize = static_cast<Uint32>(vkSizeInfo.accelerationStructureSize); + m_ScratchSize.Build = static_cast<Uint32>(vkSizeInfo.buildScratchSize); + m_ScratchSize.Update = static_cast<Uint32>(vkSizeInfo.updateScratchSize); } - else if (m_Desc.MaxInstanceCount > 0) - { - InstanceInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; - InstanceInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; - InstanceInfo.maxPrimitiveCount = m_Desc.MaxInstanceCount; - - VERIFY_EXPR(m_Desc.MaxInstanceCount <= RTLimits.maxInstanceCount); - CreateInfo.pGeometryInfos = &InstanceInfo; - CreateInfo.maxGeometryCount = 1; - } - - m_VulkanTLAS = LogicalDevice.CreateAccelStruct(CreateInfo, m_Desc.Name); - - VkAccelerationStructureMemoryRequirementsInfoKHR MemInfo = {}; - VkMemoryRequirements MemReqs = {}; - MemInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR; - MemInfo.accelerationStructure = m_VulkanTLAS; - MemInfo.buildType = VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR; - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_KHR; + VkBufferCreateInfo vkBuffCI = {}; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); + vkBuffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + vkBuffCI.flags = 0; + vkBuffCI.size = AccelStructSize; + vkBuffCI.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR; + vkBuffCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + vkBuffCI.queueFamilyIndexCount = 0; + vkBuffCI.pQueueFamilyIndices = nullptr; - uint32_t MemoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(MemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + m_VulkanBuffer = LogicalDevice.CreateBuffer(vkBuffCI, m_Desc.Name); - if (MemoryTypeIndex == VulkanUtilities::VulkanPhysicalDevice::InvalidMemoryTypeIndex) - LOG_ERROR_AND_THROW("Failed to find suitable memory type for TLAS '", m_Desc.Name, '\''); + VkMemoryRequirements MemReqs = LogicalDevice.GetBufferMemoryRequirements(m_VulkanBuffer); + uint32_t MemoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(MemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VERIFY(IsPowerOfTwo(MemReqs.alignment), "Alignment is not power of 2!"); - m_MemoryAllocation = pRenderDeviceVk->AllocateMemory(MemReqs.size, MemReqs.alignment, MemoryTypeIndex); + m_MemoryAllocation = pRenderDeviceVk->AllocateMemory(MemReqs.size, MemReqs.alignment, MemoryTypeIndex, VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT); + m_MemoryAlignedOffset = Align(VkDeviceSize{m_MemoryAllocation.UnalignedOffset}, MemReqs.alignment); VERIFY(m_MemoryAllocation.Size >= MemReqs.size + (m_MemoryAlignedOffset - m_MemoryAllocation.UnalignedOffset), "Size of memory allocation is too small"); - auto Memory = m_MemoryAllocation.Page->GetVkMemory(); - auto err = LogicalDevice.BindASMemory(m_VulkanTLAS, Memory, m_MemoryAlignedOffset); - CHECK_VK_ERROR_AND_THROW(err, "Failed to bind AS memory"); + auto err = LogicalDevice.BindBufferMemory(m_VulkanBuffer, Memory, m_MemoryAlignedOffset); + CHECK_VK_ERROR_AND_THROW(err, "Failed to bind buffer memory"); - if (m_Desc.CompactedSize == 0) - { - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size); + VkAccelerationStructureCreateInfoKHR vkAccelStrCI = {}; - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size); - } + vkAccelStrCI.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; + vkAccelStrCI.createFlags = 0; + vkAccelStrCI.buffer = m_VulkanBuffer; + vkAccelStrCI.offset = 0; + vkAccelStrCI.size = AccelStructSize; + vkAccelStrCI.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + + m_VulkanTLAS = LogicalDevice.CreateAccelStruct(vkAccelStrCI, m_Desc.Name); + + m_DeviceAddress = LogicalDevice.GetAccelerationStructureDeviceAddress(m_VulkanTLAS); SetState(RESOURCE_STATE_BUILD_AS_READ); } @@ -112,6 +119,7 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters, m_VulkanTLAS{vkTLAS} { SetState(InitialState); + m_DeviceAddress = pRenderDeviceVk->GetLogicalDevice().GetAccelerationStructureDeviceAddress(m_VulkanTLAS); } TopLevelASVkImpl::~TopLevelASVkImpl() @@ -119,6 +127,8 @@ TopLevelASVkImpl::~TopLevelASVkImpl() // Vk object can only be destroyed when it is no longer used by the GPU if (m_VulkanTLAS != VK_NULL_HANDLE) m_pDevice->SafeReleaseDeviceObject(std::move(m_VulkanTLAS), m_Desc.CommandQueueMask); + if (m_VulkanBuffer != VK_NULL_HANDLE) + m_pDevice->SafeReleaseDeviceObject(std::move(m_VulkanBuffer), m_Desc.CommandQueueMask); if (m_MemoryAllocation.Page != nullptr) m_pDevice->SafeReleaseDeviceObject(std::move(m_MemoryAllocation), m_Desc.CommandQueueMask); } diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp index ae1d3f11..c1c20d79 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp @@ -574,7 +574,6 @@ const char* VkResultToString(VkResult errorCode) STR(ERROR_INVALID_EXTERNAL_HANDLE); STR(ERROR_FRAGMENTATION); STR(ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS); - STR(ERROR_INCOMPATIBLE_VERSION_KHR); STR(ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT); STR(ERROR_NOT_PERMITTED_EXT); STR(ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT); diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp index 7639c309..70bdd20a 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp @@ -63,9 +63,6 @@ VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDe // Since we only use one device at this time, load device function entries // https://github.com/zeux/volk#optimizing-device-calls volkLoadDevice(m_VkDevice); - - if (m_EnabledExtFeatures.RayTracingNV) - EnableRayTracingKHRviaNV(); #endif m_EnabledShaderStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; @@ -75,7 +72,7 @@ VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDe m_EnabledShaderStages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; if (m_EnabledExtFeatures.MeshShader.meshShader != VK_FALSE && m_EnabledExtFeatures.MeshShader.taskShader != VK_FALSE) m_EnabledShaderStages |= VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV | VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV; - if (m_EnabledExtFeatures.RayTracing.rayTracing != VK_FALSE) + if (m_EnabledExtFeatures.RayTracingPipeline.rayTracingPipeline != VK_FALSE) m_EnabledShaderStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR; } @@ -242,7 +239,7 @@ PipelineWrapper VulkanLogicalDevice::CreateRayTracingPipeline(const VkRayTracing VkPipeline vkPipeline = VK_NULL_HANDLE; - auto err = vkCreateRayTracingPipelinesKHR(m_VkDevice, cache, 1, &PipelineCI, m_VkAllocator, &vkPipeline); + auto err = vkCreateRayTracingPipelinesKHR(m_VkDevice, VK_NULL_HANDLE, cache, 1, &PipelineCI, m_VkAllocator, &vkPipeline); CHECK_VK_ERROR_AND_THROW(err, "Failed to create ray tracing pipeline '", DebugName, '\''); if (*DebugName != 0) @@ -482,18 +479,6 @@ VkMemoryRequirements VulkanLogicalDevice::GetImageMemoryRequirements(VkImage vkI return MemReqs; } -VkMemoryRequirements VulkanLogicalDevice::GetASMemoryRequirements(const VkAccelerationStructureMemoryRequirementsInfoKHR& Info) const -{ - VkMemoryRequirements2 MemReqs = {}; - MemReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; -#if DILIGENT_USE_VOLK - vkGetAccelerationStructureMemoryRequirementsKHR(m_VkDevice, &Info, &MemReqs); -#else - UNSUPPORTED("vkGetAccelerationStructureMemoryRequirementsKHR is only available through Volk"); -#endif - return MemReqs.memoryRequirements; -} - VkResult VulkanLogicalDevice::BindBufferMemory(VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset) const { return vkBindBufferMemory(m_VkDevice, buffer, memory, memoryOffset); @@ -504,25 +489,6 @@ VkResult VulkanLogicalDevice::BindImageMemory(VkImage image, VkDeviceMemory memo return vkBindImageMemory(m_VkDevice, image, memory, memoryOffset); } -VkResult VulkanLogicalDevice::BindASMemory(VkAccelerationStructureKHR AS, VkDeviceMemory memory, VkDeviceSize memoryOffset) const -{ -#if DILIGENT_USE_VOLK - VkBindAccelerationStructureMemoryInfoKHR Info = {}; - - Info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR; - Info.memory = memory; - Info.memoryOffset = memoryOffset; - Info.deviceIndexCount = 0; - Info.pDeviceIndices = nullptr; - Info.accelerationStructure = AS; - - return vkBindAccelerationStructureMemoryKHR(m_VkDevice, 1, &Info); -#else - UNSUPPORTED("vkBindAccelerationStructureMemoryKHR is only available through Volk"); - return VK_ERROR_FEATURE_NOT_PRESENT; -#endif -} - VkDeviceAddress VulkanLogicalDevice::GetAccelerationStructureDeviceAddress(VkAccelerationStructureKHR AS) const { #if DILIGENT_USE_VOLK diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp index fd81dcfb..61f9f8de 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp @@ -71,8 +71,6 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice, #if DILIGENT_USE_VOLK if (Instance.IsExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { - VkPhysicalDeviceRayTracingPropertiesNV RayTracingNV = {}; - VkPhysicalDeviceFeatures2 Feats2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; VkPhysicalDeviceProperties2 Props2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; void** NextFeat = &Feats2.pNext; @@ -120,27 +118,32 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice, m_ExtProperties.MeshShader.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV; } - // Get ray tracing features and properties. - if (IsExtensionSupported(VK_KHR_RAY_TRACING_EXTENSION_NAME)) + // Get acceleration structure features and properties. + if (IsExtensionSupported(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) { - *NextFeat = &m_ExtFeatures.RayTracing; - NextFeat = &m_ExtFeatures.RayTracing.pNext; + *NextFeat = &m_ExtFeatures.AccelStruct; + NextFeat = &m_ExtFeatures.AccelStruct.pNext; - m_ExtFeatures.RayTracing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR; + m_ExtFeatures.AccelStruct.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR; - *NextProp = &m_ExtProperties.RayTracing; - NextProp = &m_ExtProperties.RayTracing.pNext; + *NextProp = &m_ExtProperties.AccelStruct; + NextProp = &m_ExtProperties.AccelStruct.pNext; - m_ExtProperties.RayTracing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_KHR; + m_ExtProperties.AccelStruct.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR; } - else if (IsExtensionSupported(VK_NV_RAY_TRACING_EXTENSION_NAME)) + + // Get ray tracing pipeline features and properties. + if (IsExtensionSupported(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME)) { - m_ExtFeatures.RayTracingNV = true; + *NextFeat = &m_ExtFeatures.RayTracingPipeline; + NextFeat = &m_ExtFeatures.RayTracingPipeline.pNext; + + m_ExtFeatures.RayTracingPipeline.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR; - *NextProp = &RayTracingNV; - NextProp = &RayTracingNV.pNext; + *NextProp = &m_ExtProperties.RayTracingPipeline; + NextProp = &m_ExtProperties.RayTracingPipeline.pNext; - RayTracingNV.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV; + m_ExtProperties.RayTracingPipeline.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR; } // Additional extension that is required for ray tracing. @@ -185,22 +188,6 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice, // Some flags may not be supported by hardware. vkGetPhysicalDeviceFeatures2KHR(m_VkDevice, &Feats2); vkGetPhysicalDeviceProperties2KHR(m_VkDevice, &Props2); - - // Emulate KHR extension - if (m_ExtFeatures.RayTracingNV) - { - m_ExtFeatures.RayTracing.rayTracing = VK_TRUE; - - m_ExtProperties.RayTracing.shaderGroupHandleSize = RayTracingNV.shaderGroupHandleSize; - m_ExtProperties.RayTracing.maxRecursionDepth = RayTracingNV.maxRecursionDepth; - m_ExtProperties.RayTracing.maxShaderGroupStride = RayTracingNV.maxShaderGroupStride; - m_ExtProperties.RayTracing.shaderGroupBaseAlignment = RayTracingNV.shaderGroupBaseAlignment; - m_ExtProperties.RayTracing.maxGeometryCount = RayTracingNV.maxGeometryCount; - m_ExtProperties.RayTracing.maxInstanceCount = RayTracingNV.maxInstanceCount; - m_ExtProperties.RayTracing.maxPrimitiveCount = RayTracingNV.maxTriangleCount; - m_ExtProperties.RayTracing.maxDescriptorSetAccelerationStructures = RayTracingNV.maxDescriptorSetAccelerationStructures; - m_ExtProperties.RayTracing.shaderGroupHandleCaptureReplaySize = 0; - } } #endif // DILIGENT_USE_VOLK } diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanRayTracingKHRviaNV.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanRayTracingKHRviaNV.cpp deleted file mode 100644 index 8661f5fe..00000000 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanRayTracingKHRviaNV.cpp +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * 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. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - - -// KHR ray tracing emulation through NVidia extension. -// Will be deprecated after the release of KHR extension. - -#include <mutex> -#include <unordered_map> -#include <vector> - -#include "../../include/VulkanErrors.hpp" -#include "../../include/VulkanUtilities/VulkanLogicalDevice.hpp" - -namespace VulkanUtilities -{ - -#if DILIGENT_USE_VOLK -static_assert(sizeof(VkAccelerationStructureKHR) == sizeof(VkAccelerationStructureNV), "KHR is incompatible with NV extension"); -static_assert(sizeof(VkDeviceAddress) == 8, "KHR is incompatible with NV extension"); - -namespace -{ - -PFN_vkCreateBuffer Origin_vkCreateBuffer = nullptr; -PFN_vkDestroyBuffer Origin_vkDestroyBuffer = nullptr; -PFN_vkGetBufferDeviceAddressKHR Origin_vkGetBufferDeviceAddressKHR = nullptr; -PFN_vkAllocateMemory Origin_vkAllocateMemory = nullptr; - -struct DeviceAddressEmulator -{ - std::mutex Guard; - std::unordered_map<VkDeviceAddress, VkBuffer> AddrToBuffer; - std::unordered_map<VkBuffer, VkDeviceAddress> BufferToAddr; - uint32_t Counter = 0; - static constexpr VkDeviceAddress BufferMask = 0xFFFFFFFF00000000ull; - - static DeviceAddressEmulator* GetInstance() - { - static DeviceAddressEmulator inst; - return &inst; - } - - ~DeviceAddressEmulator() - { - vkGetBufferDeviceAddressKHR = Origin_vkGetBufferDeviceAddressKHR; - vkCreateBuffer = Origin_vkCreateBuffer; - vkDestroyBuffer = Origin_vkDestroyBuffer; - vkAllocateMemory = Origin_vkAllocateMemory; - } -}; - - -VKAPI_ATTR VkResult VKAPI_CALL Wrap_vkCreateBuffer(VkDevice device, - const VkBufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBuffer* pBuffer) -{ - VkBufferCreateInfo CreateInfo = *pCreateInfo; - CreateInfo.usage &= ~VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; - return Origin_vkCreateBuffer(device, &CreateInfo, pAllocator, pBuffer); -} - -VKAPI_ATTR VkResult VKAPI_PTR Wrap_vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory) -{ - VkMemoryAllocateInfo AllocInfo = *pAllocateInfo; - - for (auto** ppNext = reinterpret_cast<VkBaseOutStructure**>(const_cast<void**>(&AllocInfo.pNext)); *ppNext;) - { - // remove VkMemoryAllocateFlagsInfo because VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is removed from buffer create info. - if ((*ppNext)->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO) - *ppNext = (*ppNext)->pNext; - else - ppNext = &((*ppNext)->pNext); - } - - return Origin_vkAllocateMemory(device, &AllocInfo, pAllocator, pMemory); -} - -VKAPI_ATTR void VKAPI_CALL Wrap_vkDestroyBuffer(VkDevice device, - VkBuffer buffer, - const VkAllocationCallbacks* pAllocator) -{ - Origin_vkDestroyBuffer(device, buffer, pAllocator); - - auto* inst = DeviceAddressEmulator::GetInstance(); - - std::unique_lock<std::mutex> lock{inst->Guard}; - - auto iter = inst->BufferToAddr.find(buffer); - if (iter != inst->BufferToAddr.end()) - { - inst->AddrToBuffer.erase(iter->second); - inst->BufferToAddr.erase(iter); - } -} - -VKAPI_ATTR VkDeviceAddress VKAPI_CALL Wrap_vkGetBufferDeviceAddressKHR(VkDevice device, - const VkBufferDeviceAddressInfo* pInfo) -{ - VERIFY_EXPR(pInfo->sType == VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR); - VERIFY_EXPR(pInfo->pNext == nullptr); - - auto* inst = DeviceAddressEmulator::GetInstance(); - - std::unique_lock<std::mutex> lock{inst->Guard}; - - // find in existing buffers - auto iter = inst->BufferToAddr.find(pInfo->buffer); - if (iter != inst->BufferToAddr.end()) - return iter->second; - - // create new device address - VkDeviceAddress Addr = VkDeviceAddress{++inst->Counter} << 32; - inst->BufferToAddr[pInfo->buffer] = Addr; - inst->AddrToBuffer[Addr] = pInfo->buffer; - return Addr; -} - -struct BufferAndOffset -{ - VkBuffer Buffer; - VkDeviceSize Offset; -}; -BufferAndOffset DeviceAddressToBuffer(VkDeviceAddress Addr) -{ - if (Addr == 0) - return {VK_NULL_HANDLE, 0}; - - auto* inst = DeviceAddressEmulator::GetInstance(); - - std::unique_lock<std::mutex> lock{inst->Guard}; - - auto iter = inst->AddrToBuffer.find(Addr & DeviceAddressEmulator::BufferMask); - if (iter == inst->AddrToBuffer.end()) - { - UNEXPECTED("Failed to map device address to buffer"); - return {VK_NULL_HANDLE, 0}; - } - - return {iter->second, Addr & ~DeviceAddressEmulator::BufferMask}; -} - -BufferAndOffset DeviceAddressToBuffer(const VkDeviceOrHostAddressConstKHR& Addr) -{ - return DeviceAddressToBuffer(Addr.deviceAddress); -} - -BufferAndOffset DeviceAddressToBuffer(const VkDeviceOrHostAddressKHR& Addr) -{ - return DeviceAddressToBuffer(Addr.deviceAddress); -} - - -VKAPI_ATTR VkResult VKAPI_CALL Redirect_vkCreateAccelerationStructureKHR(VkDevice device, - const VkAccelerationStructureCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkAccelerationStructureKHR* pAccelerationStructure) -{ - VERIFY_EXPR(pCreateInfo->sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR); - VERIFY_EXPR(pCreateInfo->pNext == nullptr); - VERIFY_EXPR(pCreateInfo->deviceAddress == 0); - - VkAccelerationStructureCreateInfoNV CreateInfo = {}; - std::vector<VkGeometryNV> Geometries; - - CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; - CreateInfo.compactedSize = pCreateInfo->compactedSize; - CreateInfo.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; - CreateInfo.info.type = pCreateInfo->type; - CreateInfo.info.flags = pCreateInfo->flags; - - if (CreateInfo.info.type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) - { - VERIFY_EXPR(pCreateInfo->maxGeometryCount == 1 || pCreateInfo->compactedSize > 0); - - if (pCreateInfo->pGeometryInfos && pCreateInfo->maxGeometryCount == 1) - { - VERIFY_EXPR(pCreateInfo->pGeometryInfos->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR); - CreateInfo.info.instanceCount = pCreateInfo->pGeometryInfos->maxPrimitiveCount; - } - } - else if (CreateInfo.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) - { - Geometries.resize(pCreateInfo->maxGeometryCount); - - for (uint32_t i = 0; i < pCreateInfo->maxGeometryCount; ++i) - { - auto& src = pCreateInfo->pGeometryInfos[i]; - auto& dst = Geometries[i]; - - VERIFY_EXPR(src.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR); - VERIFY_EXPR(src.pNext == nullptr); - - dst.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV; - dst.pNext = nullptr; - dst.geometryType = src.geometryType; - dst.flags = 0; - - dst.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV; - dst.geometry.triangles.pNext = nullptr; - - dst.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV; - dst.geometry.aabbs.pNext = nullptr; - - if (dst.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) - { - dst.geometry.triangles.vertexData = VK_NULL_HANDLE; - dst.geometry.triangles.vertexOffset = 0; - dst.geometry.triangles.vertexStride = 0; - dst.geometry.triangles.vertexFormat = src.vertexFormat; - dst.geometry.triangles.indexData = VK_NULL_HANDLE; - dst.geometry.triangles.indexOffset = 0; - dst.geometry.triangles.indexCount = 0; - dst.geometry.triangles.indexType = src.indexType; - dst.geometry.triangles.transformData = VK_NULL_HANDLE; - dst.geometry.triangles.transformOffset = 0; - - if (dst.geometry.triangles.indexType == VK_INDEX_TYPE_NONE_KHR) - { - VERIFY_EXPR(src.maxVertexCount == src.maxPrimitiveCount * 3); - dst.geometry.triangles.vertexCount = src.maxPrimitiveCount * 3; - } - else - { - dst.geometry.triangles.indexCount = src.maxPrimitiveCount * 3; - dst.geometry.triangles.vertexCount = std::max(src.maxPrimitiveCount * 6, src.maxVertexCount); - } - } - else if (dst.geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) - { - dst.geometry.aabbs.aabbData = VK_NULL_HANDLE; - dst.geometry.aabbs.numAABBs = src.maxPrimitiveCount; - dst.geometry.aabbs.stride = 0; - dst.geometry.aabbs.offset = 0; - } - } - - CreateInfo.info.geometryCount = static_cast<uint32_t>(Geometries.size()); - CreateInfo.info.pGeometries = CreateInfo.info.geometryCount ? Geometries.data() : nullptr; - } - else - { - UNEXPECTED("unknown AS type"); - return VK_RESULT_MAX_ENUM; - } - - return vkCreateAccelerationStructureNV(device, &CreateInfo, pAllocator, reinterpret_cast<VkAccelerationStructureNV*>(pAccelerationStructure)); -} - -VKAPI_ATTR void VKAPI_CALL Redirect_vkGetAccelerationStructureMemoryRequirementsKHR(VkDevice device, - const VkAccelerationStructureMemoryRequirementsInfoKHR* pInfo, - VkMemoryRequirements2* pMemoryRequirements) -{ - VERIFY_EXPR(pInfo->sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR); - VERIFY_EXPR(pMemoryRequirements->sType == VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2); - VERIFY_EXPR(pInfo->pNext == nullptr); - VERIFY_EXPR(pInfo->buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR); - - VkAccelerationStructureMemoryRequirementsInfoNV Info = {}; - - Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; - Info.type = pInfo->type; - Info.accelerationStructure = pInfo->accelerationStructure; - - return vkGetAccelerationStructureMemoryRequirementsNV(device, &Info, pMemoryRequirements); -} - -VKAPI_ATTR VkResult VKAPI_CALL Redirect_vkBindAccelerationStructureMemoryKHR(VkDevice device, - uint32_t bindInfoCount, - const VkBindAccelerationStructureMemoryInfoKHR* pBindInfos) -{ - VERIFY_EXPR(pBindInfos->sType == VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV); - return vkBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos); -} - -VKAPI_ATTR VkDeviceAddress VKAPI_CALL Redirect_vkGetAccelerationStructureDeviceAddressKHR(VkDevice device, - const VkAccelerationStructureDeviceAddressInfoKHR* pInfo) -{ - VERIFY_EXPR(pInfo->sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR); - VERIFY_EXPR(pInfo->pNext == nullptr); - - VkDeviceAddress result = 0; - vkGetAccelerationStructureHandleNV(device, pInfo->accelerationStructure, sizeof(result), &result); - return result; -} - -VKAPI_ATTR void VKAPI_CALL Redirect_vkCmdBuildAccelerationStructureKHR(VkCommandBuffer commandBuffer, - uint32_t infoCount, - const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, - const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos) -{ - std::vector<VkGeometryNV> Geometries; - - for (uint32_t i = 0; i < infoCount; ++i) - { - auto& SrcInfo = pInfos[i]; - auto& SrcOffset = ppOffsetInfos[i]; - - VERIFY_EXPR(SrcInfo.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR); - VERIFY_EXPR(SrcInfo.pNext == nullptr); - - BufferAndOffset Scratch = DeviceAddressToBuffer(SrcInfo.scratchData); - - VkAccelerationStructureInfoNV Info = {}; - - Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; - Info.pNext = nullptr; - Info.type = SrcInfo.type; - Info.flags = SrcInfo.flags; - - if (Info.type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) - { - VERIFY_EXPR(SrcInfo.geometryCount == 1); - VERIFY_EXPR(SrcInfo.geometryArrayOfPointers == VK_FALSE); - VERIFY_EXPR((*SrcInfo.ppGeometries)[0].geometry.instances.arrayOfPointers == VK_FALSE); - - Info.instanceCount = SrcOffset->primitiveCount; - - BufferAndOffset Instance = DeviceAddressToBuffer((*SrcInfo.ppGeometries)[0].geometry.instances.data); - - vkCmdBuildAccelerationStructureNV(commandBuffer, &Info, - Instance.Buffer, Instance.Offset + SrcOffset[0].primitiveOffset, - SrcInfo.update, - SrcInfo.dstAccelerationStructure, SrcInfo.srcAccelerationStructure, - Scratch.Buffer, Scratch.Offset); - } - else if (Info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) - { - VERIFY_EXPR(SrcInfo.geometryArrayOfPointers == VK_FALSE); - - Geometries.resize(SrcInfo.geometryCount); - - for (uint32_t j = 0; j < SrcInfo.geometryCount; ++j) - { - auto& src = (*SrcInfo.ppGeometries)[j]; - auto& dst = Geometries[j]; - auto& off = SrcOffset[j]; - - VERIFY_EXPR(src.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR); - VERIFY_EXPR(src.pNext == nullptr); - VERIFY_EXPR(src.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR || src.geometryType == VK_GEOMETRY_TYPE_AABBS_KHR); - - dst.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV; - dst.pNext = nullptr; - dst.flags = src.flags; - dst.geometryType = src.geometryType; - - dst.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV; - dst.geometry.triangles.pNext = nullptr; - - dst.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV; - dst.geometry.aabbs.pNext = nullptr; - - if (dst.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) - { - VERIFY_EXPR(src.geometry.triangles.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR); - VERIFY_EXPR(src.geometry.triangles.pNext == nullptr); - VERIFY_EXPR(off.firstVertex == 0); - - BufferAndOffset VB = DeviceAddressToBuffer(src.geometry.triangles.vertexData); - BufferAndOffset IB = DeviceAddressToBuffer(src.geometry.triangles.indexData); - BufferAndOffset TB = DeviceAddressToBuffer(src.geometry.triangles.transformData); - - dst.geometry.triangles.vertexData = VB.Buffer; - dst.geometry.triangles.vertexOffset = VB.Offset; - dst.geometry.triangles.vertexCount = 0; - dst.geometry.triangles.vertexStride = src.geometry.triangles.vertexStride; - dst.geometry.triangles.vertexFormat = src.geometry.triangles.vertexFormat; - dst.geometry.triangles.indexData = IB.Buffer; - dst.geometry.triangles.indexOffset = IB.Offset; - dst.geometry.triangles.indexCount = 0; - dst.geometry.triangles.indexType = src.geometry.triangles.indexType; - dst.geometry.triangles.transformData = TB.Buffer; - dst.geometry.triangles.transformOffset = TB.Offset + off.transformOffset; - - if (dst.geometry.triangles.indexType == VK_INDEX_TYPE_NONE_KHR) - { - dst.geometry.triangles.vertexOffset += off.primitiveOffset; - dst.geometry.triangles.vertexCount = off.primitiveCount * 3; - } - else - { - dst.geometry.triangles.indexOffset += off.primitiveOffset; - dst.geometry.triangles.indexCount = off.primitiveCount * 3; - dst.geometry.triangles.vertexCount = off.primitiveCount * 6; - } - } - else - { - VERIFY_EXPR(src.geometry.aabbs.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR); - VERIFY_EXPR(src.geometry.aabbs.pNext == nullptr); - VERIFY_EXPR(src.geometry.aabbs.stride <= std::numeric_limits<uint32_t>::max()); - - BufferAndOffset Data = DeviceAddressToBuffer(src.geometry.aabbs.data); - - dst.geometry.aabbs.aabbData = Data.Buffer; - dst.geometry.aabbs.numAABBs = off.primitiveCount; - dst.geometry.aabbs.stride = static_cast<uint32_t>(src.geometry.aabbs.stride); - dst.geometry.aabbs.offset = Data.Offset + off.primitiveOffset; - } - } - - Info.geometryCount = static_cast<uint32_t>(Geometries.size()); - Info.pGeometries = Geometries.data(); - - vkCmdBuildAccelerationStructureNV(commandBuffer, &Info, - VK_NULL_HANDLE, 0, - SrcInfo.update, - SrcInfo.dstAccelerationStructure, SrcInfo.srcAccelerationStructure, - Scratch.Buffer, Scratch.Offset); - } - else - { - UNEXPECTED("unknown AS type"); - } - } -} - -VKAPI_ATTR void VKAPI_CALL Redirect_vkCmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer, - const VkCopyAccelerationStructureInfoKHR* pInfo) -{ - VERIFY_EXPR(pInfo->sType == VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR); - VERIFY_EXPR(pInfo->pNext == nullptr); - - vkCmdCopyAccelerationStructureNV(commandBuffer, pInfo->dst, pInfo->src, pInfo->mode); -} - -VKAPI_ATTR void VKAPI_CALL Redirect_vkCmdWriteAccelerationStructuresPropertiesKHR(VkCommandBuffer commandBuffer, - uint32_t accelerationStructureCount, - const VkAccelerationStructureKHR* pAccelerationStructures, - VkQueryType queryType, - VkQueryPool queryPool, - uint32_t firstQuery) -{ - vkCmdWriteAccelerationStructuresPropertiesNV(commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery); -} - -VKAPI_ATTR void VKAPI_CALL Redirect_vkCmdTraceRaysKHR(VkCommandBuffer commandBuffer, - const VkStridedBufferRegionKHR* pRaygenShaderBindingTable, - const VkStridedBufferRegionKHR* pMissShaderBindingTable, - const VkStridedBufferRegionKHR* pHitShaderBindingTable, - const VkStridedBufferRegionKHR* pCallableShaderBindingTable, - uint32_t width, - uint32_t height, - uint32_t depth) -{ - vkCmdTraceRaysNV(commandBuffer, - pRaygenShaderBindingTable->buffer, pRaygenShaderBindingTable->offset, - pMissShaderBindingTable->buffer, pMissShaderBindingTable->offset, pMissShaderBindingTable->stride, - pHitShaderBindingTable->buffer, pHitShaderBindingTable->offset, pHitShaderBindingTable->stride, - pCallableShaderBindingTable->buffer, pCallableShaderBindingTable->offset, pCallableShaderBindingTable->stride, - width, height, depth); -} - -VKAPI_ATTR VkResult VKAPI_CALL Redirect_vkGetRayTracingShaderGroupHandlesKHR(VkDevice device, - VkPipeline pipeline, - uint32_t firstGroup, - uint32_t groupCount, - size_t dataSize, - void* pData) -{ - return vkGetRayTracingShaderGroupHandlesNV(device, pipeline, firstGroup, groupCount, dataSize, pData); -} - -VKAPI_ATTR void VKAPI_CALL Redirect_vkDestroyAccelerationStructureKHR(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator) -{ - return vkDestroyAccelerationStructureNV(device, accelerationStructure, pAllocator); -} - - -VKAPI_ATTR VkResult VKAPI_CALL Redirect_vkCreateRayTracingPipelinesKHR(VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines) -{ - std::vector<VkRayTracingPipelineCreateInfoNV> Infos; - std::vector<VkRayTracingShaderGroupCreateInfoNV> Groups; - Infos.resize(createInfoCount); - - size_t GroupCount = 0; - for (uint32_t i = 0; i < createInfoCount; ++i) - { - GroupCount += pCreateInfos[i].groupCount; - } - Groups.resize(GroupCount); - GroupCount = 0; - - for (uint32_t i = 0; i < createInfoCount; ++i) - { - auto& src = pCreateInfos[i]; - auto& dst = Infos[i]; - - VERIFY_EXPR(src.sType == VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR); - VERIFY_EXPR(src.pNext == nullptr); - VERIFY_EXPR(src.libraries.libraryCount == 0); - VERIFY_EXPR(src.libraries.pLibraries == nullptr); - VERIFY_EXPR(src.pLibraryInterface == nullptr); - - // copy groups - for (uint32_t j = 0; j < src.groupCount; ++j) - { - auto& srcg = src.pGroups[j]; - auto& dstg = Groups[GroupCount + j]; - - VERIFY_EXPR(srcg.sType == VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR); - VERIFY_EXPR(srcg.pNext == nullptr); - - dstg.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV; - dstg.pNext = nullptr; - dstg.type = srcg.type; - dstg.generalShader = srcg.generalShader; - dstg.closestHitShader = srcg.closestHitShader; - dstg.anyHitShader = srcg.anyHitShader; - dstg.intersectionShader = srcg.intersectionShader; - - VERIFY_EXPR(srcg.pNext == nullptr); - } - - dst.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV; - dst.pNext = nullptr; - dst.flags = src.flags; - dst.stageCount = src.stageCount; - dst.pStages = src.pStages; - dst.groupCount = src.groupCount; - dst.pGroups = Groups.data() + GroupCount; - dst.maxRecursionDepth = src.maxRecursionDepth; - dst.layout = src.layout; - dst.basePipelineHandle = src.basePipelineHandle; - dst.basePipelineIndex = src.basePipelineIndex; - - GroupCount += src.groupCount; - } - - return vkCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, Infos.data(), pAllocator, pPipelines); -} - -} // namespace - -void EnableRayTracingKHRviaNV() -{ - LOG_WARNING_MESSAGE("This is fallback implementation, you should use VK_KHR_ray_tracing instead"); - - vkCreateAccelerationStructureKHR = &Redirect_vkCreateAccelerationStructureKHR; - vkGetAccelerationStructureMemoryRequirementsKHR = &Redirect_vkGetAccelerationStructureMemoryRequirementsKHR; - vkBindAccelerationStructureMemoryKHR = &Redirect_vkBindAccelerationStructureMemoryKHR; - vkGetAccelerationStructureDeviceAddressKHR = &Redirect_vkGetAccelerationStructureDeviceAddressKHR; - vkCmdBuildAccelerationStructureKHR = &Redirect_vkCmdBuildAccelerationStructureKHR; - vkCmdCopyAccelerationStructureKHR = &Redirect_vkCmdCopyAccelerationStructureKHR; - vkCmdWriteAccelerationStructuresPropertiesKHR = &Redirect_vkCmdWriteAccelerationStructuresPropertiesKHR; - vkGetRayTracingShaderGroupHandlesKHR = &Redirect_vkGetRayTracingShaderGroupHandlesKHR; - vkCreateRayTracingPipelinesKHR = &Redirect_vkCreateRayTracingPipelinesKHR; - vkCmdTraceRaysKHR = &Redirect_vkCmdTraceRaysKHR; - vkDestroyAccelerationStructureKHR = &Redirect_vkDestroyAccelerationStructureKHR; - - Origin_vkGetBufferDeviceAddressKHR = vkGetBufferDeviceAddressKHR; - Origin_vkCreateBuffer = vkCreateBuffer; - Origin_vkDestroyBuffer = vkDestroyBuffer; - Origin_vkAllocateMemory = vkAllocateMemory; - vkCreateBuffer = &Wrap_vkCreateBuffer; - vkDestroyBuffer = &Wrap_vkDestroyBuffer; - vkAllocateMemory = Wrap_vkAllocateMemory; - vkGetBufferDeviceAddressKHR = &Wrap_vkGetBufferDeviceAddressKHR; - vkGetBufferDeviceAddress = &Wrap_vkGetBufferDeviceAddressKHR; - vkGetBufferDeviceAddressEXT = &Wrap_vkGetBufferDeviceAddressKHR; -} -#endif // DILIGENT_USE_VOLK - -} // namespace VulkanUtilities |
