summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-10-04 20:23:28 +0000
committerazhirnov <zh1dron@gmail.com>2020-10-04 20:32:25 +0000
commit7838459ef71fe5f0979f30df8348a6981363d6c8 (patch)
tree0fea27225f76476cd5e19f0b11e4c574040f7bfb /Graphics/GraphicsEngineVulkan
parentAdded dummy implementation for D3D11, D3D12, OpenGL (diff)
downloadDiligentCore-7838459ef71fe5f0979f30df8348a6981363d6c8.tar.gz
DiligentCore-7838459ef71fe5f0979f30df8348a6981363d6c8.zip
Added Vulkan implementation
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/CMakeLists.txt9
-rw-r--r--Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp68
-rw-r--r--Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp3
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp21
-rw-r--r--Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp12
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp112
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp68
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp8
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp43
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h10
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp18
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp20
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/BottomLevelASVk.h68
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/BufferVk.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h67
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h67
-rw-r--r--Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp148
-rw-r--r--Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp143
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp298
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp44
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp24
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp46
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp196
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp106
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp125
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp27
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp51
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp52
30 files changed, 1757 insertions, 105 deletions
diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt
index 323b4ccf..761653a4 100644
--- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt
+++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt
@@ -36,6 +36,9 @@ set(INCLUDE
include/VulkanErrors.hpp
include/VulkanTypeConversions.hpp
include/VulkanUploadHeap.hpp
+ include/BottomLevelASVkImpl.hpp
+ include/TopLevelASVkImpl.hpp
+ include/ShaderBindingTableVkImpl.hpp
)
set(VULKAN_UTILS_INCLUDE
@@ -70,6 +73,9 @@ set(INTERFACE
interface/SwapChainVk.h
interface/TextureVk.h
interface/TextureViewVk.h
+ interface/BottomLevelASVk.h
+ interface/TopLevelASVk.h
+ interface/ShaderBindingTableVk.h
)
@@ -104,6 +110,9 @@ set(SRC
src/TextureViewVkImpl.cpp
src/VulkanTypeConversions.cpp
src/VulkanUploadHeap.cpp
+ src/BottomLevelASVkImpl.cpp
+ src/TopLevelASVkImpl.cpp
+ src/ShaderBindingTableVkImpl.cpp
)
set(VULKAN_UTILS_SRC
diff --git a/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp
new file mode 100644
index 00000000..ccf8f574
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/// \file
+/// Definition of the Diligent::BottomLevelASVkImpl class
+
+#include "RenderDeviceVk.h"
+#include "RenderDeviceVkImpl.hpp"
+#include "BottomLevelASVk.h"
+#include "BottomLevelASBase.hpp"
+#include "VulkanUtilities/VulkanObjectWrappers.hpp"
+
+namespace Diligent
+{
+
+class BottomLevelASVkImpl final : public BottomLevelASBase<IBottomLevelASVk, RenderDeviceVkImpl>
+{
+public:
+ using TBottomLevelASBase = BottomLevelASBase<IBottomLevelASVk, RenderDeviceVkImpl>;
+
+ BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const BottomLevelASDesc& Desc,
+ bool bIsDeviceInternal = false);
+ ~BottomLevelASVkImpl();
+
+ virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; }
+
+ virtual VkAccelerationStructureKHR DILIGENT_CALL_TYPE GetVkBLAS() const override { return m_VulkanBLAS; }
+
+ virtual VkDeviceAddress DILIGENT_CALL_TYPE GetVkDeviceAddress() const override { return m_DeviceAddress; }
+
+ IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_BottomLevelASVk, TBottomLevelASBase);
+
+private:
+ VkDeviceAddress m_DeviceAddress;
+ VulkanUtilities::AccelStructWrapper m_VulkanBLAS;
+ VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation;
+ ScratchBufferSizes m_ScratchSize;
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp
index 8d1c187d..a3e3d438 100644
--- a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp
@@ -106,6 +106,9 @@ public:
/// Implementation of IBufferVk::GetAccessFlags().
virtual VkAccessFlags DILIGENT_CALL_TYPE GetAccessFlags() const override final;
+ /// Implementation of IBufferVk::GetVkDeviceAddress().
+ virtual VkDeviceAddress DILIGENT_CALL_TYPE GetVkDeviceAddress() const override final;
+
bool CheckAccessFlags(VkAccessFlags AccessFlags) const
{
return (GetAccessFlags() & AccessFlags) == AccessFlags;
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
index e01178a5..26142ba0 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
@@ -135,13 +135,13 @@ public:
ITextureView* pDepthStencil,
RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final;
- /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D11 backend.
+ /// Implementation of IDeviceContext::BeginRenderPass() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE BeginRenderPass(const BeginRenderPassAttribs& Attribs) override final;
- /// Implementation of IDeviceContext::NextSubpass() in Direct3D11 backend.
+ /// Implementation of IDeviceContext::NextSubpass() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE NextSubpass() override final;
- /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend.
+ /// Implementation of IDeviceContext::EndRenderPass() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE EndRenderPass() override final;
// clang-format off
@@ -249,6 +249,21 @@ public:
/// Implementation of IDeviceContext::Flush() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE Flush() override final;
+ /// Implementation of IDeviceContext::BuildBLAS() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::BuildTLAS() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::CopyBLAS() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::CopyTLAS() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::TraceRays() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
+
// Transitions texture subresources from OldState to NewState, and optionally updates
// internal texture state.
// If OldState == RESOURCE_STATE_UNKNOWN, internal texture state is used as old state.
diff --git a/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp
index f449d416..23097d22 100644
--- a/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp
@@ -40,7 +40,7 @@ namespace Diligent
class FixedBlockMemoryAllocator;
-/// Render pass implementation in Direct3D11 backend.
+/// Framebuffer implementation in Vulkan backend.
class FramebufferVkImpl final : public FramebufferBase<IFramebufferVk, RenderDeviceVkImpl>
{
public:
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
index 25a9f44b..94b91cae 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
@@ -112,6 +112,18 @@ public:
virtual void DILIGENT_CALL_TYPE CreateFramebuffer(const FramebufferDesc& Desc,
IFramebuffer** ppFramebuffer) override final;
+ /// Implementation of IRenderDevice::CreateBLAS() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE CreateBLAS(const BottomLevelASDesc& Desc,
+ IBottomLevelAS** ppBLAS) override final;
+
+ /// Implementation of IRenderDevice::CreateTLAS() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE CreateTLAS(const TopLevelASDesc& Desc,
+ ITopLevelAS** ppTLAS) override final;
+
+ /// Implementation of IRenderDevice::CreateSBT() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE CreateSBT(const ShaderBindingTableDesc& Desc,
+ IShaderBindingTable** ppSBT) override final;
+
/// Implementation of IRenderDeviceVk::GetVkDevice().
virtual VkDevice DILIGENT_CALL_TYPE GetVkDevice() override final { return m_LogicalVkDevice->GetVkDevice(); }
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp
index 5c77784f..05962047 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp
@@ -41,7 +41,7 @@ namespace Diligent
class FixedBlockMemoryAllocator;
-/// Render pass implementation in Direct3D11 backend.
+/// Render pass implementation in Vulkan backend.
class RenderPassVkImpl final : public RenderPassBase<IRenderPassVk, RenderDeviceVkImpl>
{
public:
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
new file mode 100644
index 00000000..bba64381
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/// \file
+/// Definition of the Diligent::ShaderBindingTableVkImpl class
+
+#include "BufferVkImpl.hpp"
+#include "RenderDeviceVk.h"
+#include "RenderDeviceVkImpl.hpp"
+#include "ShaderBindingTableVk.h"
+#include "ShaderBindingTableBase.hpp"
+#include "VulkanUtilities/VulkanObjectWrappers.hpp"
+
+namespace Diligent
+{
+
+class ShaderBindingTableVkImpl final : public ShaderBindingTableBase<IShaderBindingTableVk, RenderDeviceVkImpl>
+{
+public:
+ using TShaderBindingTableBase = ShaderBindingTableBase<IShaderBindingTableVk, RenderDeviceVkImpl>;
+
+ ShaderBindingTableVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const ShaderBindingTableDesc& Desc,
+ bool bIsDeviceInternal = false);
+ ~ShaderBindingTableVkImpl();
+
+ virtual void DILIGENT_CALL_TYPE Verify() const override;
+
+ virtual void DILIGENT_CALL_TYPE Reset(const ShaderBindingTableDesc& Desc) override;
+
+ virtual void DILIGENT_CALL_TYPE ResetHitGroups(Uint32 HitShadersPerInstance) override;
+
+ virtual void DILIGENT_CALL_TYPE BindRayGenShader(const char* ShaderGroupName, const void* Data, Uint32 DataSize) override;
+
+ virtual void DILIGENT_CALL_TYPE BindMissShader(const char* ShaderGroupName, Uint32 MissIndex, const void* Data, Uint32 DataSize) override;
+
+ virtual void DILIGENT_CALL_TYPE BindHitGroup(ITopLevelAS* pTLAS,
+ const char* InstanceName,
+ const char* GeometryName,
+ Uint32 RayOffsetInHitGroupIndex,
+ const char* ShaderGroupName,
+ const void* Data,
+ Uint32 DataSize) override;
+
+ virtual void DILIGENT_CALL_TYPE BindHitGroups(ITopLevelAS* pTLAS,
+ const char* InstanceName,
+ Uint32 RayOffsetInHitGroupIndex,
+ const char* ShaderGroupName,
+ const void* Data,
+ Uint32 DataSize) override;
+
+ virtual void DILIGENT_CALL_TYPE BindCallableShader(Uint32 Index,
+ const char* ShaderName,
+ const void* Data,
+ Uint32 DataSize) override;
+
+ virtual void DILIGENT_CALL_TYPE BindAll(const BindAllAttribs& Attribs) override;
+
+ virtual void DILIGENT_CALL_TYPE GetVkStridedBufferRegions(VkStridedBufferRegionKHR& RaygenShaderBindingTable,
+ VkStridedBufferRegionKHR& MissShaderBindingTable,
+ VkStridedBufferRegionKHR& HitShaderBindingTable,
+ VkStridedBufferRegionKHR& CallableShaderBindingTable) override;
+
+ IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderBindingTableVk, TShaderBindingTableBase);
+
+private:
+ void ValidateDesc(const ShaderBindingTableDesc& Desc) const;
+
+private:
+ RefCntAutoPtr<BufferVkImpl> m_pBuffer;
+ std::vector<Uint32> m_ShaderRecords;
+ Uint32 m_MissShadersOffset;
+ Uint32 m_HitGroupsOffset;
+ Uint32 m_CallbaleShadersOffset;
+ Uint32 m_MissShaderCount;
+ Uint32 m_HitGroupCount;
+ Uint32 m_CallableShaderCount;
+ Uint32 m_ShaderGroupHandleSize;
+ Uint32 m_ShaderGroupBaseAlignment;
+
+#ifdef DILIGENT_DEBUG
+#endif
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
new file mode 100644
index 00000000..311266e7
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/// \file
+/// Definition of the Diligent::TopLevelASVkImpl class
+
+#include "RenderDeviceVk.h"
+#include "RenderDeviceVkImpl.hpp"
+#include "TopLevelASVk.h"
+#include "TopLevelASBase.hpp"
+#include "VulkanUtilities/VulkanObjectWrappers.hpp"
+
+namespace Diligent
+{
+
+class TopLevelASVkImpl final : public TopLevelASBase<ITopLevelASVk, RenderDeviceVkImpl>
+{
+public:
+ using TTopLevelASBase = TopLevelASBase<ITopLevelASVk, RenderDeviceVkImpl>;
+
+ TopLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const TopLevelASDesc& Desc,
+ bool bIsDeviceInternal = false);
+ ~TopLevelASVkImpl();
+
+ virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; }
+
+ virtual VkAccelerationStructureKHR DILIGENT_CALL_TYPE GetVkTLAS() const override { return m_VulkanTLAS; }
+
+ virtual VkDeviceAddress DILIGENT_CALL_TYPE GetVkDeviceAddress() const override { return m_DeviceAddress; }
+
+ IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_TopLevelASVk, TTopLevelASBase);
+
+private:
+ VkDeviceAddress m_DeviceAddress;
+ VulkanUtilities::AccelStructWrapper m_VulkanTLAS;
+ VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation;
+ ScratchBufferSizes m_ScratchSize;
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp
index dbba5b7e..51083968 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp
@@ -40,7 +40,8 @@ namespace Diligent
VkFormat TexFormatToVkFormat(TEXTURE_FORMAT TexFmt);
TEXTURE_FORMAT VkFormatToTexFormat(VkFormat VkFmt);
-VkFormat TypeToVkFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized);
+VkFormat TypeToVkFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized);
+VkIndexType TypeToVkIndexType(VALUE_TYPE IndexType);
VkPipelineRasterizationStateCreateInfo RasterizerStateDesc_To_VkRasterizationStateCI(const struct RasterizerStateDesc& RasterizerDesc);
VkPipelineDepthStencilStateCreateInfo DepthStencilStateDesc_To_VkDepthStencilStateCI(const struct DepthStencilStateDesc& DepthStencilDesc);
@@ -82,4 +83,9 @@ ATTACHMENT_STORE_OP VkAttachmentStoreOpToAttachmentStoreOp(VkAttachmentStoreOp V
VkPipelineStageFlags PipelineStageFlagsToVkPipelineStageFlags(PIPELINE_STAGE_FLAGS PipelineStageFlags);
VkAccessFlags AccessFlagsToVkAccessFlags(ACCESS_FLAGS AccessFlags);
+VkBuildAccelerationStructureFlagsKHR BuildASFlagsToVkBuildAccelerationStructureFlags(RAYTRACING_BUILD_AS_FLAGS Flags);
+VkGeometryFlagsKHR GeometryFlagsToVkGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags);
+VkGeometryInstanceFlagsKHR InstanceFlagsToVkGeometryInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags);
+VkCopyAccelerationStructureModeKHR CopyASModeToVkCopyAccelerationStructureMode(COPY_AS_MODE Mode);
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
index 7d66600d..04189820 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
@@ -140,27 +140,27 @@ public:
__forceinline void DrawMesh(uint32_t TaskCount, uint32_t FirstTask)
{
-#ifdef VK_NV_mesh_shader
+#if DILIGENT_USE_VOLK
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass");
VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
vkCmdDrawMeshTasksNV(m_VkCmdBuffer, TaskCount, FirstTask);
#else
- UNSUPPORTED("DrawMesh is not supported in current Vulkan headers");
+ UNSUPPORTED("DrawMesh is not supported when vulkan library linked statically");
#endif
}
__forceinline void DrawMeshIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride)
{
-#ifdef VK_NV_mesh_shader
+#if DILIGENT_USE_VOLK
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass");
VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
vkCmdDrawMeshTasksIndirectNV(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride);
#else
- UNSUPPORTED("DrawMeshIndirect is not supported in current Vulkan headers");
+ UNSUPPORTED("DrawMeshIndirect is not supported when vulkan library linked statically");
#endif
}
@@ -570,6 +570,41 @@ public:
dstBuffer, dstOffset, stride, flags);
}
+ __forceinline void BuildAccelerationStructure(uint32_t infoCount,
+ const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
+ const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos)
+ {
+#if DILIGENT_USE_VOLK
+ vkCmdBuildAccelerationStructureKHR(m_VkCmdBuffer, infoCount, pInfos, ppOffsetInfos);
+#else
+ UNSUPPORTED("Ray tracing is not supported when vulkan library linked statically");
+#endif
+ }
+
+ __forceinline void CopyAccelerationStructure(const VkCopyAccelerationStructureInfoKHR& Info)
+ {
+#if DILIGENT_USE_VOLK
+ vkCmdCopyAccelerationStructureKHR(m_VkCmdBuffer, &Info);
+#else
+ UNSUPPORTED("Ray tracing is not supported when vulkan library linked statically");
+#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)
+ {
+#if DILIGENT_USE_VOLK
+ vkCmdTraceRaysKHR(m_VkCmdBuffer, &RaygenShaderBindingTable, &MissShaderBindingTable, &HitShaderBindingTable, &CallableShaderBindingTable, width, height, depth);
+#else
+ UNSUPPORTED("Ray tracing is not supported when vulkan library linked statically");
+#endif
+ }
+
void FlushBarriers();
__forceinline void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer)
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h
index ee6461fd..769391cf 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanHeaders.h
@@ -30,15 +30,17 @@
#if DILIGENT_USE_VOLK
# define VK_NO_PROTOTYPES
#endif
+
+// TODO: remove it when ray tracing will be 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)
#if DILIGENT_USE_VOLK
# include "volk/volk.h"
-#else
-// Don't use extensions when statically linked with Vulkan
-# undef VK_KHR_get_physical_device_properties2
-# undef VK_NV_mesh_shader
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(_X11_XLIB_H_)
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp
index 3f06cb0e..c2fba2a4 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp
@@ -28,7 +28,7 @@
#pragma once
#include <memory>
-#include "VulkanHeaders.h"
+#include "VulkanPhysicalDevice.hpp"
namespace VulkanUtilities
{
@@ -57,7 +57,8 @@ enum class VulkanHandleTypeId : uint32_t
Semaphore,
Queue,
Event,
- QueryPool
+ QueryPool,
+ AccelerationStructureKHR
};
template <typename VulkanObjectType, VulkanHandleTypeId>
@@ -81,12 +82,13 @@ using DescriptorPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DescriptorPool);
using DescriptorSetLayoutWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DescriptorSetLayout);
using SemaphoreWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Semaphore);
using QueryPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(QueryPool);
+using AccelStructWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(AccelerationStructureKHR);
#undef DEFINE_VULKAN_OBJECT_WRAPPER
class VulkanLogicalDevice : public std::enable_shared_from_this<VulkanLogicalDevice>
{
public:
- static std::shared_ptr<VulkanLogicalDevice> Create(VkPhysicalDevice vkPhysicalDevice,
+ static std::shared_ptr<VulkanLogicalDevice> Create(const VulkanPhysicalDevice& PhysicalDevice,
const VkDeviceCreateInfo& DeviceCI,
const VkAllocationCallbacks* vkAllocator);
@@ -140,6 +142,7 @@ public:
SemaphoreWrapper CreateSemaphore(const VkSemaphoreCreateInfo& SemaphoreCI, const char* DebugName = "") const;
QueryPoolWrapper CreateQueryPool(const VkQueryPoolCreateInfo& QueryPoolCI, const char* DebugName = "") const;
+ AccelStructWrapper CreateAccelStruct(const VkAccelerationStructureCreateInfoKHR& CI, const char* DebugName = "") const;
VkCommandBuffer AllocateVkCommandBuffer(const VkCommandBufferAllocateInfo& AllocInfo, const char* DebugName = "") const;
VkDescriptorSet AllocateVkDescriptorSet(const VkDescriptorSetAllocateInfo& AllocInfo, const char* DebugName = "") const;
@@ -161,14 +164,19 @@ public:
void ReleaseVulkanObject(DescriptorSetLayoutWrapper&& DescriptorSetLayout) const;
void ReleaseVulkanObject(SemaphoreWrapper&& Semaphore) const;
void ReleaseVulkanObject(QueryPoolWrapper&& QueryPool) const;
+ void ReleaseVulkanObject(AccelStructWrapper&& AccelStruct) const;
void FreeDescriptorSet(VkDescriptorPool Pool, VkDescriptorSet Set) const;
VkMemoryRequirements GetBufferMemoryRequirements(VkBuffer vkBuffer) const;
- VkMemoryRequirements GetImageMemoryRequirements (VkImage vkImage ) 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;
@@ -212,7 +220,7 @@ public:
const VkPhysicalDeviceFeatures& GetEnabledFeatures() const { return m_EnabledFeatures; }
private:
- VulkanLogicalDevice(VkPhysicalDevice vkPhysicalDevice,
+ VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice,
const VkDeviceCreateInfo& DeviceCI,
const VkAllocationCallbacks* vkAllocator);
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
index b4e734c7..1e9a6edf 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
@@ -39,10 +39,20 @@ class VulkanPhysicalDevice
public:
struct ExtensionFeatures
{
- VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {};
- VkPhysicalDevice16BitStorageFeaturesKHR Storage16Bit = {};
- VkPhysicalDevice8BitStorageFeaturesKHR Storage8Bit = {};
- VkPhysicalDeviceShaderFloat16Int8FeaturesKHR ShaderFloat16Int8 = {};
+ VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {};
+ VkPhysicalDevice16BitStorageFeaturesKHR Storage16Bit = {};
+ VkPhysicalDevice8BitStorageFeaturesKHR Storage8Bit = {};
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR ShaderFloat16Int8 = {};
+ VkPhysicalDeviceRayTracingFeaturesKHR RayTracing = {};
+ VkPhysicalDeviceBufferDeviceAddressFeaturesKHR BufferDeviceAddress = {};
+ VkPhysicalDeviceDescriptorIndexingFeaturesEXT DescriptorIndexing = {};
+ };
+
+ struct ExtensionProperties
+ {
+ VkPhysicalDeviceMeshShaderPropertiesNV MeshShader = {};
+ VkPhysicalDeviceRayTracingPropertiesKHR RayTracing = {};
+ VkPhysicalDeviceDescriptorIndexingPropertiesEXT DescriptorIndexing = {};
};
public:
@@ -70,6 +80,7 @@ public:
const VkPhysicalDeviceProperties& GetProperties() const { return m_Properties; }
const VkPhysicalDeviceFeatures& GetFeatures() const { return m_Features; }
const ExtensionFeatures& GetExtFeatures() const { return m_ExtFeatures; }
+ const ExtensionProperties& GetExtProperties() const { return m_ExtProperties; }
const VkPhysicalDeviceMemoryProperties& GetMemoryProperties() const { return m_MemoryProperties; }
VkFormatProperties GetPhysicalDeviceFormatProperties(VkFormat imageFormat) const;
@@ -82,6 +93,7 @@ private:
VkPhysicalDeviceFeatures m_Features = {};
VkPhysicalDeviceMemoryProperties m_MemoryProperties = {};
ExtensionFeatures m_ExtFeatures = {};
+ ExtensionProperties m_ExtProperties = {};
std::vector<VkQueueFamilyProperties> m_QueueFamilyProperties;
std::vector<VkExtensionProperties> m_SupportedExtensions;
};
diff --git a/Graphics/GraphicsEngineVulkan/interface/BottomLevelASVk.h b/Graphics/GraphicsEngineVulkan/interface/BottomLevelASVk.h
new file mode 100644
index 00000000..eb0c2da5
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/interface/BottomLevelASVk.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/// \file
+/// Definition of the Diligent::IBottomLevelASVk interface
+
+#include "../../GraphicsEngine/interface/BottomLevelAS.h"
+
+DILIGENT_BEGIN_NAMESPACE(Diligent)
+
+
+// {7212AFC9-02E2-4D7F-81A8-1CE5353CEA2D}
+static const INTERFACE_ID IID_BottomLevelASVk =
+ {0x7212afc9, 0x2e2, 0x4d7f, {0x81, 0xa8, 0x1c, 0xe5, 0x35, 0x3c, 0xea, 0x2d}};
+
+#define DILIGENT_INTERFACE_NAME IBottomLevelASVk
+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
+
+#define IBottomLevelASVkInclusiveMethods \
+ IBottomLevelASInclusiveMethods; \
+ IBottomLevelASVkMethods BottomLevelASVk
+
+/// Exposes Vulkan-specific functionality of a Bottom-level acceleration structure object.
+DILIGENT_BEGIN_INTERFACE(IBottomLevelASVk, IBottomLevelAS)
+{
+ /// Returns a Vulkan BLAS object handle
+ VIRTUAL VkAccelerationStructureKHR METHOD(GetVkBLAS)(THIS) CONST PURE;
+
+ /// Returns a Vulkan BLAS device address
+ VIRTUAL VkDeviceAddress METHOD(GetVkDeviceAddress)(THIS) CONST PURE;
+};
+DILIGENT_END_INTERFACE
+
+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
+
+#if DILIGENT_C_INTERFACE
+
+# define IBottomLevelASVk_GetVkBLAS(This) CALL_IFACE_METHOD(BottomLevelASVk, GetVkBLAS, This)
+
+#endif
+
+DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/interface/BufferVk.h b/Graphics/GraphicsEngineVulkan/interface/BufferVk.h
index ea889795..0c95af96 100644
--- a/Graphics/GraphicsEngineVulkan/interface/BufferVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/BufferVk.h
@@ -62,6 +62,9 @@ DILIGENT_BEGIN_INTERFACE(IBufferVk, IBuffer)
/// If the buffer state is known to the engine (i.e. not Diligent::RESOURCE_STATE_UNKNOWN),
/// returns Vulkan access flags corresponding to the state. If the state is unknown, returns 0.
VIRTUAL VkAccessFlags METHOD(GetAccessFlags)(THIS) CONST PURE;
+
+ /// Returns a vulkan device address
+ VIRTUAL VkDeviceAddress METHOD(GetVkDeviceAddress)(THIS) CONST PURE;
};
DILIGENT_END_INTERFACE
@@ -72,6 +75,7 @@ DILIGENT_END_INTERFACE
# define IBufferVk_GetVkBuffer(This) CALL_IFACE_METHOD(BufferVk, GetVkBuffer, This)
# define IBufferVk_SetAccessFlags(This, ...) CALL_IFACE_METHOD(BufferVk, SetAccessFlags, This, __VA_ARGS__)
# define IBufferVk_GetAccessFlags(This) CALL_IFACE_METHOD(BufferVk, GetAccessFlags, This)
+# define IBufferVk_GetVkDeviceAddress(This) CALL_IFACE_METHOD(BufferVk, GetVkDeviceAddress, This)
#endif
diff --git a/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h b/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h
new file mode 100644
index 00000000..e3222728
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/// \file
+/// Definition of the Diligent::IShaderBindingTableVk interface
+
+#include "../../GraphicsEngine/interface/ShaderBindingTable.h"
+
+DILIGENT_BEGIN_NAMESPACE(Diligent)
+
+// {31ED9B4B-4FF4-44D8-AE71-12B5D8AF7F93}
+static const INTERFACE_ID IID_ShaderBindingTableVk =
+ {0x31ed9b4b, 0x4ff4, 0x44d8, {0xae, 0x71, 0x12, 0xb5, 0xd8, 0xaf, 0x7f, 0x93}};
+
+#define DILIGENT_INTERFACE_NAME IShaderBindingTableVk
+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
+
+#define IShaderBindingTableVkInclusiveMethods \
+ IShaderBindingTableInclusiveMethods; \
+ IShaderBindingTableVkMethods ShaderBindingTableVk
+
+/// Exposes Vulkan-specific functionality of a Shader binding table object.
+DILIGENT_BEGIN_INTERFACE(IShaderBindingTableVk, IShaderBindingTable)
+{
+ /// AZ TODO
+ VIRTUAL void METHOD(GetVkStridedBufferRegions)(VkStridedBufferRegionKHR & RaygenShaderBindingTable,
+ VkStridedBufferRegionKHR & MissShaderBindingTable,
+ VkStridedBufferRegionKHR & HitShaderBindingTable,
+ VkStridedBufferRegionKHR & CallableShaderBindingTable) PURE;
+};
+DILIGENT_END_INTERFACE
+
+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
+
+#if DILIGENT_C_INTERFACE
+
+# define IShaderBindingTableVk_GetVkStridedBufferRegions(This, ...) CALL_IFACE_METHOD(ShaderBindingTableVk, GetVkStridedBufferRegions, This, __VA_ARGS__)
+
+#endif
+
+DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h b/Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h
new file mode 100644
index 00000000..3d0b8b09
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/interface/TopLevelASVk.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/// \file
+/// Definition of the Diligent::ITopLevelASVk interface
+
+#include "../../GraphicsEngine/interface/TopLevelAS.h"
+
+DILIGENT_BEGIN_NAMESPACE(Diligent)
+
+// {356FFFFA-9E57-49F7-8FF4-7017B61BE6A8}
+static const INTERFACE_ID IID_TopLevelASVk =
+ {0x356ffffa, 0x9e57, 0x49f7, {0x8f, 0xf4, 0x70, 0x17, 0xb6, 0x1b, 0xe6, 0xa8}};
+
+#define DILIGENT_INTERFACE_NAME ITopLevelASVk
+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
+
+#define ITopLevelASVkInclusiveMethods \
+ ITopLevelASInclusiveMethods; \
+ ITopLevelASVkMethods TopLevelASVk
+
+/// Exposes Vulkan-specific functionality of a Top-level acceleration structure object.
+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
+
+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
+
+#if DILIGENT_C_INTERFACE
+
+# define ITopLevelASVk_GetVkTLAS(This) CALL_IFACE_METHOD(TopLevelASVk, GetVkTLAS, This)
+
+#endif
+
+DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
new file mode 100644
index 00000000..85c74834
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+#include "pch.h"
+#include "BottomLevelASVkImpl.hpp"
+#include "VulkanTypeConversions.hpp"
+
+namespace Diligent
+{
+
+BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const BottomLevelASDesc& Desc,
+ bool bIsDeviceInternal) :
+ TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc, bIsDeviceInternal},
+ m_DeviceAddress{0}
+{
+ const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice();
+ const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice();
+ const auto& Limits = PhysicalDevice.GetExtProperties().RayTracing;
+
+ VkAccelerationStructureCreateInfoKHR CreateInfo = {};
+ std::vector<VkAccelerationStructureCreateGeometryTypeInfoKHR> Geometries;
+
+ 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);
+ CreateInfo.maxGeometryCount = std::max(m_Desc.BoxCount, m_Desc.TriangleCount);
+ CreateInfo.compactedSize = 0; // AZ TODO
+
+ VERIFY_EXPR(CreateInfo.maxGeometryCount <= Limits.maxGeometryCount);
+
+ Geometries.resize(CreateInfo.maxGeometryCount);
+ CreateInfo.pGeometryInfos = Geometries.data();
+
+ // Specs says: the geometryType member of each geometry in pGeometries must be the same.
+ if (m_Desc.pTriangles != nullptr)
+ {
+ Uint32 MaxPrimitiveCount = 0;
+ for (uint32_t i = 0; i < CreateInfo.maxGeometryCount; ++i)
+ {
+ auto& src = m_Desc.pTriangles[i];
+ auto& dst = Geometries[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.IndexType == VT_UNDEFINED ? src.MaxVertexCount : src.MaxIndexCount) / 3;
+ 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;
+ }
+ VERIFY_EXPR(MaxPrimitiveCount <= Limits.maxPrimitiveCount);
+ }
+ else if (m_Desc.pBoxes != nullptr)
+ {
+ Uint32 MaxBoxCount = 0;
+ for (uint32_t i = 0; i < CreateInfo.maxGeometryCount; ++i)
+ {
+ auto& src = m_Desc.pBoxes[i];
+ auto& dst = Geometries[i];
+
+ 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;
+
+ MaxBoxCount += dst.maxPrimitiveCount;
+ }
+ VERIFY_EXPR(MaxBoxCount <= Limits.maxPrimitiveCount);
+ }
+
+ m_VulkanBLAS = LogicalDevice.CreateAccelStruct(CreateInfo, m_Desc.Name);
+
+ VkAccelerationStructureMemoryRequirementsInfoKHR MemInfo = {};
+ VkMemoryRequirements MemReqs = {};
+
+ 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;
+
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+
+ uint32_t MemoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(MemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+ if (MemoryTypeIndex == VulkanUtilities::VulkanPhysicalDevice::InvalidMemoryTypeIndex)
+ LOG_ERROR_AND_THROW("Failed to find suitable memory type for BLAS '", m_Desc.Name, '\'');
+
+ VERIFY(IsPowerOfTwo(MemReqs.alignment), "Alignment is not power of 2!");
+ m_MemoryAllocation = pRenderDeviceVk->AllocateMemory(MemReqs.size, MemReqs.alignment, MemoryTypeIndex);
+
+ auto Memory = m_MemoryAllocation.Page->GetVkMemory();
+ auto err = LogicalDevice.BindASMemory(m_VulkanBLAS, Memory, 0);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to bind AS memory");
+
+ m_DeviceAddress = LogicalDevice.GetAccelerationStructureDeviceAddress(m_VulkanBLAS);
+
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size);
+
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size);
+}
+
+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_MemoryAllocation.Page != nullptr)
+ m_pDevice->SafeReleaseDeviceObject(std::move(m_MemoryAllocation), m_Desc.CommandQueueMask);
+}
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
index 8edb3472..80130696 100644
--- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
@@ -86,54 +86,86 @@ BufferVkImpl::BufferVkImpl(IReferenceCounters* pRefCounters,
VkBuffCI.usage =
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | // The buffer can be used as the source of a transfer command
VK_BUFFER_USAGE_TRANSFER_DST_BIT; // The buffer can be used as the destination of a transfer command
- if (m_Desc.BindFlags & BIND_UNORDERED_ACCESS)
- {
- // VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
- // HLSL formatted buffers are mapped to GLSL storage buffers:
- //
- // RWBuffer<uint4> RWBuff
- //
- // |
- // V
- //
- // layout(std140, binding = 3) buffer RWBuff
- // {
- // uvec4 data[];
- // }g_RWBuff;
- //
- // So we have to set both VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT and VK_BUFFER_USAGE_STORAGE_BUFFER_BIT bits
- VkBuffCI.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
-
- // Each element of pDynamicOffsets of vkCmdBindDescriptorSets function which corresponds to a descriptor
- // binding with type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC must be a multiple of
- // VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment (13.2.5)
- m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minTexelBufferOffsetAlignment));
- m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minStorageBufferOffsetAlignment));
- }
- if (m_Desc.BindFlags & BIND_SHADER_RESOURCE)
- {
- // VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
- // HLSL buffer SRVs are mapped to storge buffers in GLSL, so we need to set both
- // VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT and VK_BUFFER_USAGE_STORAGE_BUFFER_BIT flags
- VkBuffCI.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
- m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minTexelBufferOffsetAlignment));
- m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minStorageBufferOffsetAlignment));
- }
- if (m_Desc.BindFlags & BIND_VERTEX_BUFFER)
- VkBuffCI.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
- if (m_Desc.BindFlags & BIND_INDEX_BUFFER)
- VkBuffCI.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
- if (m_Desc.BindFlags & BIND_INDIRECT_DRAW_ARGS)
- VkBuffCI.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
- if (m_Desc.BindFlags & BIND_UNIFORM_BUFFER)
+ static_assert(BIND_FLAGS_LAST == 0x400, "AZ TODO");
+
+ for (Uint32 BindFlag = 1; BindFlag <= m_Desc.BindFlags; BindFlag <<= 1)
{
- VkBuffCI.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+ if ((m_Desc.BindFlags & BindFlag) != BindFlag)
+ continue;
+
+ switch (BindFlag)
+ {
+ case BIND_UNORDERED_ACCESS:
+ {
+ // VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+ // HLSL formatted buffers are mapped to GLSL storage buffers:
+ //
+ // RWBuffer<uint4> RWBuff
+ //
+ // |
+ // V
+ //
+ // layout(std140, binding = 3) buffer RWBuff
+ // {
+ // uvec4 data[];
+ // }g_RWBuff;
+ //
+ // So we have to set both VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT and VK_BUFFER_USAGE_STORAGE_BUFFER_BIT bits
+ VkBuffCI.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+
+ // Each element of pDynamicOffsets of vkCmdBindDescriptorSets function which corresponds to a descriptor
+ // binding with type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC must be a multiple of
+ // VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment (13.2.5)
+ m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minTexelBufferOffsetAlignment));
+ m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minStorageBufferOffsetAlignment));
+ break;
+ }
+ case BIND_SHADER_RESOURCE:
+ {
+ // VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+ // HLSL buffer SRVs are mapped to storge buffers in GLSL, so we need to set both
+ // VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT and VK_BUFFER_USAGE_STORAGE_BUFFER_BIT flags
+ VkBuffCI.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+
+ m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minTexelBufferOffsetAlignment));
+ m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minStorageBufferOffsetAlignment));
+ break;
+ }
+ case BIND_VERTEX_BUFFER:
+ {
+ VkBuffCI.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ break;
+ }
+ case BIND_INDEX_BUFFER:
+ {
+ VkBuffCI.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
+ break;
+ }
+ case BIND_INDIRECT_DRAW_ARGS:
+ {
+ VkBuffCI.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
+ break;
+ }
+ case BIND_UNIFORM_BUFFER:
+ {
+ VkBuffCI.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
- // Each element of pDynamicOffsets parameter of vkCmdBindDescriptorSets function which corresponds to a descriptor
- // binding with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC must be a multiple of
- // VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment (13.2.5)
- m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minUniformBufferOffsetAlignment));
+ // Each element of pDynamicOffsets parameter of vkCmdBindDescriptorSets function which corresponds to a descriptor
+ // binding with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC must be a multiple of
+ // VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment (13.2.5)
+ m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minUniformBufferOffsetAlignment));
+ break;
+ }
+ case BIND_RAY_TRACING:
+ {
+ VkBuffCI.usage |= VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
+ break;
+ }
+ default:
+ UNEXPECTED("unsupported buffer binding type");
+ break;
+ }
}
if (m_Desc.Usage == USAGE_DYNAMIC)
@@ -457,6 +489,27 @@ VkAccessFlags BufferVkImpl::GetAccessFlags() const
return ResourceStateFlagsToVkAccessFlags(GetState());
}
+VkDeviceAddress BufferVkImpl::GetVkDeviceAddress() const
+{
+ constexpr auto DeviceAddressFlags = BIND_RAY_TRACING;
+
+ if (m_VulkanBuffer != VK_NULL_HANDLE && !!(m_Desc.BindFlags & DeviceAddressFlags))
+ {
+ VkBufferDeviceAddressInfoKHR BufferInfo = {};
+
+ BufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR;
+ BufferInfo.buffer = m_VulkanBuffer;
+ VkDeviceAddress Result = vkGetBufferDeviceAddressKHR(m_pDevice->GetLogicalDevice().GetVkDevice(), &BufferInfo);
+ VERIFY_EXPR(Result > 0);
+ return Result;
+ }
+ else
+ {
+ UNEXPECTED("Can't get device address for buffer");
+ return 0;
+ }
+}
+
#ifdef DILIGENT_DEVELOPMENT
void BufferVkImpl::DvpVerifyDynamicAllocation(DeviceContextVkImpl* pCtx) const
{
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 2d7b9591..d3f87287 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -36,6 +36,9 @@
#include "VulkanTypeConversions.hpp"
#include "CommandListVkImpl.hpp"
#include "FenceVkImpl.hpp"
+#include "BottomLevelASVkImpl.hpp"
+#include "TopLevelASVkImpl.hpp"
+#include "ShaderBindingTableVkImpl.hpp"
#include "GraphicsAccessories.hpp"
namespace Diligent
@@ -514,7 +517,7 @@ void DeviceContextVkImpl::PrepareForIndexedDraw(DRAW_FLAGS Flags, VALUE_TYPE Ind
}
#endif
DEV_CHECK_ERR(IndexType == VT_UINT16 || IndexType == VT_UINT32, "Unsupported index format. Only R16_UINT and R32_UINT are allowed.");
- VkIndexType vkIndexType = IndexType == VT_UINT16 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
+ VkIndexType vkIndexType = TypeToVkIndexType(IndexType);
m_CommandBuffer.BindIndexBuffer(m_pIndexBuffer->GetVkBuffer(), m_IndexDataStartOffset + m_pIndexBuffer->GetDynamicOffset(m_ContextId, this), vkIndexType);
}
@@ -575,6 +578,12 @@ void DeviceContextVkImpl::DrawMesh(const DrawMeshAttribs& Attribs)
if (!DvpVerifyDrawMeshArguments(Attribs))
return;
+#ifdef DILIGENT_DEBUG
+ auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
+ VERIFY_EXPR(PhysicalDevice.GetExtFeatures().MeshShader.meshShader == VK_TRUE && PhysicalDevice.GetExtFeatures().MeshShader.taskShader == VK_TRUE);
+ VERIFY_EXPR(Attribs.ThreadGroupCount <= PhysicalDevice.GetExtProperties().MeshShader.maxDrawMeshTasksCount);
+#endif
+
PrepareForDraw(Attribs.Flags);
m_CommandBuffer.DrawMesh(Attribs.ThreadGroupCount, 0);
@@ -586,6 +595,11 @@ void DeviceContextVkImpl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Attrib
if (!DvpVerifyDrawMeshIndirectArguments(Attribs, pAttribsBuffer))
return;
+#ifdef DILIGENT_DEBUG
+ auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
+ VERIFY_EXPR(PhysicalDevice.GetExtFeatures().MeshShader.meshShader == VK_TRUE && PhysicalDevice.GetExtFeatures().MeshShader.taskShader == VK_TRUE);
+#endif
+
// We must prepare indirect draw attribs buffer first because state transitions must
// be performed outside of render pass, and PrepareForDraw commits render pass
BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectDrawAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode);
@@ -2597,4 +2611,286 @@ void DeviceContextVkImpl::ResolveTextureSubresource(ITexture*
1, &ResolveRegion);
}
+void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
+{
+ if (!TDeviceContextBase::BuildBLAS(Attribs, 0))
+ return;
+
+
+ // AZ TODO: transitions
+
+#ifdef DILIGENT_DEBUG
+ auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
+ VERIFY_EXPR(PhysicalDevice.GetExtFeatures().RayTracing.rayTracing == VK_TRUE);
+#endif
+
+ auto* pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pBLAS);
+ auto* pScratchVk = ValidatedCast<BufferVkImpl>(Attribs.pScratchBuffer);
+ auto& BLASDesc = pBLASVk->GetDesc();
+
+ VkAccelerationStructureBuildGeometryInfoKHR Info = {};
+ std::vector<VkAccelerationStructureBuildOffsetInfoKHR> Offsets;
+ std::vector<VkAccelerationStructureGeometryKHR> Geometries;
+
+ if (Attribs.pTriangleData != nullptr)
+ {
+ Geometries.resize(Attribs.TriangleDataCount);
+ Offsets.resize(Attribs.TriangleDataCount);
+
+ for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i)
+ {
+ auto& src = Attribs.pTriangleData[i];
+ Uint32 j = pBLASVk->GetGeometryIndex(src.GeometryName);
+ auto& dst = Geometries.data()[j];
+ auto& tri = dst.geometry.triangles;
+ auto& off = Offsets.data()[j];
+
+ if (j >= Geometries.size())
+ {
+ UNEXPECTED("Failed to find geometry by name");
+ continue;
+ }
+
+ dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
+ dst.pNext = nullptr;
+ dst.flags = GeometryFlagsToVkGeometryFlags(src.Flags);
+ dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
+ tri.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
+ tri.pNext = nullptr;
+
+ auto* pVB = ValidatedCast<IBufferVk>(src.pVertexBuffer);
+ tri.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16);
+ tri.vertexStride = src.VertexStride;
+ tri.vertexData.deviceAddress = pVB->GetVkDeviceAddress() + src.VertexOffset;
+
+ if (src.pIndexBuffer)
+ {
+ auto* pIB = ValidatedCast<IBufferVk>(src.pIndexBuffer);
+ tri.indexType = TypeToVkIndexType(src.IndexType);
+ tri.indexData.deviceAddress = pIB->GetVkDeviceAddress() + src.IndexOffset;
+ off.primitiveCount = src.IndexCount / 3;
+ }
+ else
+ {
+ tri.indexType = VK_INDEX_TYPE_NONE_KHR;
+ tri.indexData.deviceAddress = 0;
+ off.primitiveCount = src.VertexCount / 3;
+ }
+
+ if (src.pTransformBuffer)
+ {
+ auto* pTB = ValidatedCast<IBufferVk>(src.pTransformBuffer);
+ tri.transformData.deviceAddress = pTB->GetVkDeviceAddress() + src.TransformBufferOffset;
+ }
+ else
+ tri.transformData.deviceAddress = 0;
+
+ off.firstVertex = 0;
+ off.primitiveOffset = 0;
+ off.transformOffset = 0;
+ }
+ }
+ else if (Attribs.pBoxData != nullptr)
+ {
+ Geometries.resize(Attribs.BoxDataCount);
+ Offsets.resize(Attribs.BoxDataCount);
+
+ for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i)
+ {
+ auto& src = Attribs.pBoxData[i];
+ Uint32 j = pBLASVk->GetGeometryIndex(src.GeometryName);
+ auto& dst = Geometries.data()[j];
+ auto& box = dst.geometry.aabbs;
+ auto& off = Offsets.data()[j];
+
+ if (j >= Geometries.size())
+ {
+ UNEXPECTED("Failed to find geometry by name");
+ continue;
+ }
+
+ auto* pBB = ValidatedCast<IBufferVk>(src.pBoxBuffer);
+ box.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR;
+ box.pNext = nullptr;
+ box.stride = src.BoxStride;
+ box.data.deviceAddress = pBB->GetVkDeviceAddress() + src.BoxOffset;
+
+ off.firstVertex = 0;
+ off.transformOffset = 0;
+ off.primitiveOffset = 0;
+ off.primitiveCount = src.BoxCount;
+ }
+ }
+
+ VkAccelerationStructureGeometryKHR const* GeometriesPtr = Geometries.data();
+ VkAccelerationStructureBuildOffsetInfoKHR const* OffsetsPtr = Offsets.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 = VK_FALSE;
+ Info.srcAccelerationStructure = 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;
+
+ EnsureVkCmdBuffer();
+ m_CommandBuffer.BuildAccelerationStructure(1, &Info, &OffsetsPtr);
+}
+
+void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs)
+{
+ if (!TDeviceContextBase::BuildTLAS(Attribs, 0))
+ return;
+
+ static_assert(TLASInstanceDataSize == sizeof(VkAccelerationStructureInstanceKHR), "AZ TODO");
+
+ // AZ TODO: transitions
+
+#ifdef DILIGENT_DEBUG
+ auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
+ VERIFY_EXPR(PhysicalDevice.GetExtFeatures().RayTracing.rayTracing == VK_TRUE);
+#endif
+
+ auto* pTLASVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pTLAS);
+ auto* pScratchVk = ValidatedCast<BufferVkImpl>(Attribs.pScratchBuffer);
+ auto* pInstancesVk = ValidatedCast<BufferVkImpl>(Attribs.pInstancesBuffer);
+ auto& TLASDesc = pTLASVk->GetDesc();
+
+ pTLASVk->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount);
+
+ // copy instance data into instance buffer
+ {
+ size_t Size = Attribs.InstanceCount * sizeof(VkAccelerationStructureInstanceKHR);
+ auto TmpSpace = m_UploadHeap.Allocate(Size, 16);
+ void* pMappedInstances = TmpSpace.CPUAddress;
+
+ for (Uint32 i = 0; i < Attribs.InstanceCount; ++i)
+ {
+ auto& src = Attribs.pInstances[i];
+ auto& dst = static_cast<VkAccelerationStructureInstanceKHR*>(pMappedInstances)[i];
+ auto* pBLASVk = ValidatedCast<IBottomLevelASVk>(src.pBLAS);
+
+ static_assert(sizeof(dst.transform) == sizeof(src.Transform), "size mismatch");
+ std::memcpy(&dst.transform, src.Transform, sizeof(dst.transform));
+
+ dst.instanceCustomIndex = src.customId;
+ dst.instanceShaderBindingTableRecordOffset = src.contributionToHitGroupIndex;
+ dst.mask = src.Mask;
+ dst.flags = InstanceFlagsToVkGeometryInstanceFlags(src.Flags);
+ dst.accelerationStructureReference = pBLASVk->GetVkDeviceAddress();
+ }
+
+ UpdateBufferRegion(pInstancesVk, Attribs.InstancesBufferOffset, Size, TmpSpace.vkBuffer, TmpSpace.AlignedOffset, Attribs.InstanceBufferTransitionMode);
+ }
+
+ VkAccelerationStructureBuildGeometryInfoKHR Info = {};
+ VkAccelerationStructureBuildOffsetInfoKHR Offset = {};
+ VkAccelerationStructureBuildOffsetInfoKHR const* OffsetsPtr = &Offset;
+ VkAccelerationStructureGeometryKHR Geometry = {VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR};
+ VkAccelerationStructureGeometryKHR const* GeometriesPtr = &Geometry;
+
+ Offset.primitiveCount = Attribs.InstanceCount;
+
+ Geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
+ auto& inst = Geometry.geometry.instances;
+ inst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
+ inst.arrayOfPointers = VK_FALSE;
+ inst.data.deviceAddress = pInstancesVk->GetVkDeviceAddress() + Attribs.InstancesBufferOffset;
+
+ Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
+ Info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; // type must be compatible with create info
+ Info.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(TLASDesc.Flags); // flags must be compatible with create info
+ Info.update = VK_FALSE;
+ Info.srcAccelerationStructure = VK_NULL_HANDLE;
+ Info.dstAccelerationStructure = pTLASVk->GetVkTLAS();
+ Info.geometryArrayOfPointers = VK_FALSE;
+ Info.geometryCount = 1;
+ Info.ppGeometries = &GeometriesPtr;
+ Info.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset;
+
+ EnsureVkCmdBuffer();
+ m_CommandBuffer.BuildAccelerationStructure(1, &Info, &OffsetsPtr);
+}
+
+void DeviceContextVkImpl::CopyBLAS(const CopyBLASAttribs& Attribs)
+{
+ if (!TDeviceContextBase::CopyBLAS(Attribs, 0))
+ return;
+
+ // AZ TODO: transitions
+
+#ifdef DILIGENT_DEBUG
+ auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
+ VERIFY_EXPR(PhysicalDevice.GetExtFeatures().RayTracing.rayTracing == VK_TRUE);
+#endif
+
+ auto* pSrcVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pSrc);
+ auto* pDstVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pDst);
+
+ VkCopyAccelerationStructureInfoKHR Info = {};
+
+ Info.sType = VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR;
+ Info.src = pSrcVk->GetVkBLAS();
+ Info.dst = pDstVk->GetVkBLAS();
+ Info.mode = CopyASModeToVkCopyAccelerationStructureMode(Attribs.Mode);
+
+ EnsureVkCmdBuffer();
+ m_CommandBuffer.CopyAccelerationStructure(Info);
+}
+
+void DeviceContextVkImpl::CopyTLAS(const CopyTLASAttribs& Attribs)
+{
+ if (!TDeviceContextBase::CopyTLAS(Attribs, 0))
+ return;
+
+ // AZ TODO: transitions
+
+#ifdef DILIGENT_DEBUG
+ auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
+ VERIFY_EXPR(PhysicalDevice.GetExtFeatures().RayTracing.rayTracing == VK_TRUE);
+#endif
+
+ auto* pSrcVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pSrc);
+ auto* pDstVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pDst);
+
+ VkCopyAccelerationStructureInfoKHR Info = {};
+
+ Info.sType = VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR;
+ Info.src = pSrcVk->GetVkTLAS();
+ Info.dst = pDstVk->GetVkTLAS();
+ Info.mode = CopyASModeToVkCopyAccelerationStructureMode(Attribs.Mode);
+
+ EnsureVkCmdBuffer();
+ m_CommandBuffer.CopyAccelerationStructure(Info);
+}
+
+void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs)
+{
+ if (!TDeviceContextBase::TraceRays(Attribs, 0))
+ return;
+
+ // AZ TODO: transitions
+
+#ifdef DILIGENT_DEBUG
+ auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
+ VERIFY_EXPR(PhysicalDevice.GetExtFeatures().RayTracing.rayTracing == VK_TRUE);
+#endif
+
+ VkStridedBufferRegionKHR RaygenShaderBindingTable = {};
+ VkStridedBufferRegionKHR MissShaderBindingTable = {};
+ VkStridedBufferRegionKHR HitShaderBindingTable = {};
+ VkStridedBufferRegionKHR CallableShaderBindingTable = {};
+
+ auto* pSBTVk = ValidatedCast<ShaderBindingTableVkImpl>(Attribs.pSBT);
+
+ pSBTVk->GetVkStridedBufferRegions(RaygenShaderBindingTable, MissShaderBindingTable, HitShaderBindingTable, CallableShaderBindingTable);
+
+ EnsureVkCmdBuffer();
+ m_CommandBuffer.TraceRays(RaygenShaderBindingTable, MissShaderBindingTable, HitShaderBindingTable, CallableShaderBindingTable,
+ Attribs.DimensionX, Attribs.DimensionY, Attribs.DimensionZ);
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
index 6a81faba..185f1da5 100644
--- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
@@ -269,15 +269,24 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
ENABLE_FEATURE(Storage8BitFeats.storageBuffer8BitAccess != VK_FALSE, ResourceBuffer8BitAccess, "8-bit resoure buffer access is");
ENABLE_FEATURE(Storage8BitFeats.uniformAndStorageBuffer8BitAccess != VK_FALSE, UniformBuffer8BitAccess, "8-bit uniform buffer access is");
// clang-format on
+
+ auto RayTracingFeats = DeiceExtFeatures.RayTracing;
+ auto BufferDeviceAddressFeats = DeiceExtFeatures.BufferDeviceAddress;
+ auto DescriptorIndexingFeats = DeiceExtFeatures.DescriptorIndexing;
+ ENABLE_FEATURE(RayTracingFeats.rayTracing != VK_FALSE, MeshShaders, "Ray tracing are");
#undef FeatureSupport
// To enable some device extensions you must enable instance extension VK_KHR_get_physical_device_properties2
// and add feature description to DeviceCreateInfo.pNext.
- const auto SupportsFeatures2 = Instance->IsExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ bool SupportsFeatures2 = Instance->IsExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+
+ // Enable extensions
if (SupportsFeatures2)
{
void** NextExt = const_cast<void**>(&DeviceCreateInfo.pNext);
+
+ // Mesh shader
if (EngineCI.Features.MeshShaders != DEVICE_FEATURE_STATE_DISABLED)
{
VERIFY_EXPR(MeshShaderFeats.taskShader != VK_FALSE && MeshShaderFeats.meshShader != VK_FALSE);
@@ -383,21 +392,42 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
DeviceExtensions.push_back(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
}
- *NextExt = nullptr;
- }
+ // Ray tracing
+ if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED)
+ {
+ if (RayTracingFeats.rayTracing != VK_FALSE)
+ {
+ // required extensions
+ DeviceExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
+ DeviceExtensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
+ DeviceExtensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
+ DeviceExtensions.push_back(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
+ DeviceExtensions.push_back(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
+ DeviceExtensions.push_back(VK_KHR_RAY_TRACING_EXTENSION_NAME);
+
+ *NextExt = &RayTracingFeats;
+ NextExt = &RayTracingFeats.pNext;
+ *NextExt = &DescriptorIndexingFeats;
+ NextExt = &DescriptorIndexingFeats.pNext;
+ *NextExt = &BufferDeviceAddressFeats;
+ NextExt = &BufferDeviceAddressFeats.pNext;
+ }
+ }
+ // make sure that last pNext is null
+ *NextExt = nullptr;
+ }
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 30, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data();
DeviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(DeviceExtensions.size());
- auto vkAllocator = Instance->GetVkAllocator();
- auto vkPhysicalDevice = PhysicalDevice->GetVkDeviceHandle();
- auto LogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(vkPhysicalDevice, DeviceCreateInfo, vkAllocator);
+ auto vkAllocator = Instance->GetVkAllocator();
+ auto LogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(*PhysicalDevice, DeviceCreateInfo, vkAllocator);
auto& RawMemAllocator = GetRawAllocator();
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
index 2fd063c9..32c0cb29 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
@@ -43,18 +43,24 @@ namespace Diligent
static VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE ShaderType)
{
- static_assert(SHADER_TYPE_LAST == 0x080, "Please update the switch below to handle the new shader type");
+ static_assert(SHADER_TYPE_LAST == 0x2000, "Please update the switch below to handle the new shader type");
switch (ShaderType)
{
// clang-format off
- case SHADER_TYPE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
- case SHADER_TYPE_HULL: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
- case SHADER_TYPE_DOMAIN: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
- case SHADER_TYPE_GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT;
- case SHADER_TYPE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT;
- case SHADER_TYPE_COMPUTE: return VK_SHADER_STAGE_COMPUTE_BIT;
- case SHADER_TYPE_AMPLIFICATION: return VK_SHADER_STAGE_TASK_BIT_NV;
- case SHADER_TYPE_MESH: return VK_SHADER_STAGE_MESH_BIT_NV;
+ case SHADER_TYPE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
+ case SHADER_TYPE_HULL: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+ case SHADER_TYPE_DOMAIN: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+ case SHADER_TYPE_GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT;
+ case SHADER_TYPE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT;
+ case SHADER_TYPE_COMPUTE: return VK_SHADER_STAGE_COMPUTE_BIT;
+ case SHADER_TYPE_AMPLIFICATION: return VK_SHADER_STAGE_TASK_BIT_NV;
+ case SHADER_TYPE_MESH: return VK_SHADER_STAGE_MESH_BIT_NV;
+ case SHADER_TYPE_RAY_GEN: return VK_SHADER_STAGE_RAYGEN_BIT_KHR;
+ case SHADER_TYPE_RAY_MISS: return VK_SHADER_STAGE_MISS_BIT_KHR;
+ case SHADER_TYPE_RAY_CLOSEST_HIT: return VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
+ case SHADER_TYPE_RAY_ANY_HIT: return VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
+ case SHADER_TYPE_RAY_INTERSECTION: return VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
+ case SHADER_TYPE_CALLABLE: return VK_SHADER_STAGE_CALLABLE_BIT_KHR;
// clang-format on
default:
UNEXPECTED("Unknown shader type");
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index c36b98b0..6e5ec710 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -39,6 +39,9 @@
#include "QueryVkImpl.hpp"
#include "RenderPassVkImpl.hpp"
#include "FramebufferVkImpl.hpp"
+#include "BottomLevelASVkImpl.hpp"
+#include "TopLevelASVkImpl.hpp"
+#include "ShaderBindingTableVkImpl.hpp"
#include "EngineMemory.h"
namespace Diligent
@@ -75,7 +78,10 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
sizeof(FenceVkImpl),
sizeof(QueryVkImpl),
sizeof(RenderPassVkImpl),
- sizeof(FramebufferVkImpl)
+ sizeof(FramebufferVkImpl),
+ sizeof(BottomLevelASVkImpl),
+ sizeof(TopLevelASVkImpl),
+ sizeof(ShaderBindingTableVkImpl)
}
},
m_VulkanInstance {Instance },
@@ -220,7 +226,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED;
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 30, "Did you add a new feature to DeviceFeatures? Please handle its satus here (if necessary).");
+ static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here (if necessary).");
#endif
const auto& vkDeviceLimits = m_PhysicalDevice->GetProperties().limits;
@@ -717,4 +723,40 @@ void RenderDeviceVkImpl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebu
});
}
+void RenderDeviceVkImpl::CreateBLAS(const BottomLevelASDesc& Desc,
+ IBottomLevelAS** ppBLAS)
+{
+ CreateDeviceObject("BottomLevelAS", Desc, ppBLAS,
+ [&]() //
+ {
+ BottomLevelASVkImpl* pBottomLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASVkImpl instance", BottomLevelASVkImpl)(this, Desc));
+ pBottomLevelASVk->QueryInterface(IID_BottomLevelAS, reinterpret_cast<IObject**>(ppBLAS));
+ OnCreateDeviceObject(pBottomLevelASVk);
+ });
+}
+
+void RenderDeviceVkImpl::CreateTLAS(const TopLevelASDesc& Desc,
+ ITopLevelAS** ppTLAS)
+{
+ CreateDeviceObject("TopLevelAS", Desc, ppTLAS,
+ [&]() //
+ {
+ TopLevelASVkImpl* pTopLevelASVk(NEW_RC_OBJ(m_TLASAllocator, "TopLevelASVkImpl instance", TopLevelASVkImpl)(this, Desc));
+ pTopLevelASVk->QueryInterface(IID_TopLevelAS, reinterpret_cast<IObject**>(ppTLAS));
+ OnCreateDeviceObject(pTopLevelASVk);
+ });
+}
+
+void RenderDeviceVkImpl::CreateSBT(const ShaderBindingTableDesc& Desc,
+ IShaderBindingTable** ppSBT)
+{
+ CreateDeviceObject("ShaderBindingTable", Desc, ppSBT,
+ [&]() //
+ {
+ ShaderBindingTableVkImpl* pSBTVk(NEW_RC_OBJ(m_SBTAllocator, "ShaderBindingTableVkImpl instance", ShaderBindingTableVkImpl)(this, Desc));
+ pSBTVk->QueryInterface(IID_ShaderBindingTable, reinterpret_cast<IObject**>(ppSBT));
+ OnCreateDeviceObject(pSBTVk);
+ });
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
new file mode 100644
index 00000000..21b06fb3
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+#include "pch.h"
+#include "ShaderBindingTableVkImpl.hpp"
+#include "VulkanTypeConversions.hpp"
+
+namespace Diligent
+{
+
+ShaderBindingTableVkImpl::ShaderBindingTableVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const ShaderBindingTableDesc& Desc,
+ bool bIsDeviceInternal) :
+ TShaderBindingTableBase{pRefCounters, pRenderDeviceVk, Desc, bIsDeviceInternal},
+ m_MissShadersOffset{0},
+ m_HitGroupsOffset{0},
+ m_CallbaleShadersOffset{0},
+ m_MissShaderCount{0},
+ m_HitGroupCount{0},
+ m_CallableShaderCount{0}
+{
+ ValidateDesc(Desc);
+
+ auto& Props = GetDevice()->GetPhysicalDevice().GetExtProperties().RayTracing;
+
+ m_ShaderGroupHandleSize = Props.shaderGroupHandleSize;
+ m_ShaderGroupBaseAlignment = Props.shaderGroupBaseAlignment;
+}
+
+ShaderBindingTableVkImpl::~ShaderBindingTableVkImpl()
+{
+}
+
+void ShaderBindingTableVkImpl::ValidateDesc(const ShaderBindingTableDesc& Desc) const
+{
+ auto& Props = GetDevice()->GetPhysicalDevice().GetExtProperties().RayTracing;
+
+ if (Desc.ShaderRecordSize + Props.shaderGroupHandleSize > Props.maxShaderGroupStride)
+ {
+ LOG_ERROR_AND_THROW("Description of Shader binding table '", (Desc.Name ? Desc.Name : ""),
+ "' is invalid: ShaderRecordSize is too big, max size is: ", Props.maxShaderGroupStride - Props.shaderGroupHandleSize);
+ }
+}
+
+void ShaderBindingTableVkImpl::Verify() const
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::Reset(const ShaderBindingTableDesc& Desc)
+{
+ try
+ {
+ ValidateShaderBindingTableDesc(Desc);
+ ValidateDesc(Desc);
+ }
+ catch (const std::runtime_error&)
+ {
+ return;
+ }
+
+ m_Desc = Desc;
+
+ // free memory
+ decltype(m_ShaderRecords) temp;
+ std::swap(temp, m_ShaderRecords);
+
+ m_MissShadersOffset = 0;
+ m_HitGroupsOffset = 0;
+ m_CallbaleShadersOffset = 0;
+ m_MissShaderCount = 0;
+ m_HitGroupCount = 0;
+ m_CallableShaderCount = 0;
+}
+
+void ShaderBindingTableVkImpl::ResetHitGroups(Uint32 HitShadersPerInstance)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::BindRayGenShader(const char* ShaderGroupName, const void* Data, Uint32 DataSize)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::BindMissShader(const char* ShaderGroupName, Uint32 MissIndex, const void* Data, Uint32 DataSize)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::BindHitGroup(ITopLevelAS* pTLAS,
+ const char* InstanceName,
+ const char* GeometryName,
+ Uint32 RayOffsetInHitGroupIndex,
+ const char* ShaderGroupName,
+ const void* Data,
+ Uint32 DataSize)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::BindHitGroups(ITopLevelAS* pTLAS,
+ const char* InstanceName,
+ Uint32 RayOffsetInHitGroupIndex,
+ const char* ShaderGroupName,
+ const void* Data,
+ Uint32 DataSize)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::BindCallableShader(Uint32 Index,
+ const char* ShaderName,
+ const void* Data,
+ Uint32 DataSize)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::BindAll(const BindAllAttribs& Attribs)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableVkImpl::GetVkStridedBufferRegions(VkStridedBufferRegionKHR& RaygenShaderBindingTable,
+ VkStridedBufferRegionKHR& MissShaderBindingTable,
+ VkStridedBufferRegionKHR& HitShaderBindingTable,
+ VkStridedBufferRegionKHR& CallableShaderBindingTable)
+{
+ auto& Props = GetDevice()->GetPhysicalDevice().GetExtProperties().RayTracing;
+
+ const VkDeviceSize Stride = m_Desc.ShaderRecordSize + Props.shaderGroupHandleSize;
+ VERIFY_EXPR(Stride <= Props.maxShaderGroupStride);
+
+ RaygenShaderBindingTable.buffer = m_pBuffer->GetVkBuffer();
+ RaygenShaderBindingTable.offset = 0;
+ RaygenShaderBindingTable.size = Stride;
+ RaygenShaderBindingTable.stride = Stride;
+
+ if (m_MissShaderCount > 0)
+ {
+ MissShaderBindingTable.buffer = m_pBuffer->GetVkBuffer();
+ MissShaderBindingTable.offset = m_MissShadersOffset;
+ MissShaderBindingTable.size = Stride * m_MissShaderCount;
+ MissShaderBindingTable.stride = Stride;
+ }
+ else
+ MissShaderBindingTable = {};
+
+ if (m_HitGroupCount > 0)
+ {
+ HitShaderBindingTable.buffer = m_pBuffer->GetVkBuffer();
+ HitShaderBindingTable.offset = m_HitGroupsOffset;
+ HitShaderBindingTable.size = Stride * m_HitGroupCount;
+ HitShaderBindingTable.stride = Stride;
+ }
+ else
+ HitShaderBindingTable = {};
+
+ if (m_CallableShaderCount > 0)
+ {
+ CallableShaderBindingTable.buffer = m_pBuffer->GetVkBuffer();
+ CallableShaderBindingTable.offset = m_CallbaleShadersOffset;
+ CallableShaderBindingTable.size = Stride * m_CallableShaderCount;
+ CallableShaderBindingTable.stride = Stride;
+ }
+ else
+ CallableShaderBindingTable = {};
+}
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
new file mode 100644
index 00000000..0fb2f334
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#include "pch.h"
+#include "TopLevelASVkImpl.hpp"
+#include "VulkanTypeConversions.hpp"
+
+namespace Diligent
+{
+
+TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const TopLevelASDesc& Desc,
+ bool bIsDeviceInternal) :
+ TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc, bIsDeviceInternal},
+ m_DeviceAddress{0}
+{
+ const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice();
+ const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice();
+ const auto& Limits = PhysicalDevice.GetExtProperties().RayTracing;
+
+ VERIFY_EXPR(m_Desc.MaxInstanceCount <= Limits.maxInstanceCount);
+
+ 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);
+ CreateInfo.maxGeometryCount = 1;
+ CreateInfo.pGeometryInfos = &InstanceInfo;
+ CreateInfo.compactedSize = 0; // AZ TODO
+
+ InstanceInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
+ InstanceInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
+ InstanceInfo.maxPrimitiveCount = m_Desc.MaxInstanceCount;
+
+ 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;
+
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+
+ uint32_t MemoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(MemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+ if (MemoryTypeIndex == VulkanUtilities::VulkanPhysicalDevice::InvalidMemoryTypeIndex)
+ LOG_ERROR_AND_THROW("Failed to find suitable memory type for TLAS '", m_Desc.Name, '\'');
+
+ VERIFY(IsPowerOfTwo(MemReqs.alignment), "Alignment is not power of 2!");
+ m_MemoryAllocation = pRenderDeviceVk->AllocateMemory(MemReqs.size, MemReqs.alignment, MemoryTypeIndex);
+
+ auto Memory = m_MemoryAllocation.Page->GetVkMemory();
+ auto err = LogicalDevice.BindASMemory(m_VulkanTLAS, Memory, 0);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to bind AS memory");
+
+ m_DeviceAddress = LogicalDevice.GetAccelerationStructureDeviceAddress(m_VulkanTLAS);
+
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size);
+
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size);
+}
+
+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_MemoryAllocation.Page != nullptr)
+ m_pDevice->SafeReleaseDeviceObject(std::move(m_MemoryAllocation), m_Desc.CommandQueueMask);
+}
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
index fb151407..b797968c 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
@@ -444,7 +444,7 @@ public:
TEXTURE_FORMAT operator[](VkFormat VkFmt) const
{
- if (VkFmt < VK_FORMAT_RANGE_SIZE)
+ if (VkFmt < _countof(m_VkFmtToTexFmtMap))
{
return m_VkFmtToTexFmtMap[VkFmt];
}
@@ -456,7 +456,7 @@ public:
}
private:
- TEXTURE_FORMAT m_VkFmtToTexFmtMap[VK_FORMAT_RANGE_SIZE] = {};
+ TEXTURE_FORMAT m_VkFmtToTexFmtMap[VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1] = {};
std::unordered_map<VkFormat, TEXTURE_FORMAT> m_VkFmtToTexFmtMapExt;
};
@@ -632,6 +632,21 @@ VkFormat TypeToVkFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormal
}
}
+VkIndexType TypeToVkIndexType(VALUE_TYPE IndexType)
+{
+ switch (IndexType)
+ {
+ // clang-format off
+ case VT_UNDEFINED: return VK_INDEX_TYPE_NONE_KHR; // only for ray tracing
+ case VT_UINT16: return VK_INDEX_TYPE_UINT16;
+ case VT_UINT32: return VK_INDEX_TYPE_UINT32;
+ // clang-format on
+ default:
+ UNEXPECTED("Unexpected index type");
+ return VK_INDEX_TYPE_UINT32;
+ }
+}
+
VkPolygonMode FillModeToVkPolygonMode(FILL_MODE FillMode)
{
switch (FillMode)
@@ -1151,10 +1166,8 @@ static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag)
//VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX
//VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT
//VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV
- //VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NVX
- //VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX
- static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag");
+ static_assert(RESOURCE_STATE_MAX_BIT == 0x40000, "This function must be updated to handle new resource state flag");
VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set");
switch (StateFlag)
{
@@ -1176,6 +1189,8 @@ static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag)
case RESOURCE_STATE_RESOLVE_SOURCE: return VK_ACCESS_TRANSFER_READ_BIT;
case RESOURCE_STATE_INPUT_ATTACHMENT: return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
case RESOURCE_STATE_PRESENT: return 0;
+ case RESOURCE_STATE_BUILD_AS: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
+ case RESOURCE_STATE_RAY_TRACING: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
// clang-format on
default:
@@ -1203,7 +1218,7 @@ public:
}
private:
- static constexpr const Uint32 MaxFlagBitPos = 16;
+ static constexpr const Uint32 MaxFlagBitPos = 18;
std::array<VkAccessFlags, MaxFlagBitPos + 1> FlagBitPosToVkAccessFlagsMap;
};
@@ -1256,8 +1271,8 @@ RESOURCE_STATE VkAccessFlagsToResourceStates(VkAccessFlagBits AccessFlagBit)
case VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV: return RESOURCE_STATE_UNKNOWN;
case VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT: return RESOURCE_STATE_UNKNOWN;
case VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV: return RESOURCE_STATE_UNKNOWN;
- case VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV: return RESOURCE_STATE_UNKNOWN;
- case VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV: return RESOURCE_STATE_UNKNOWN;
+ case VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR: return RESOURCE_STATE_RAY_TRACING;
+ case VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR: return RESOURCE_STATE_BUILD_AS;
// clang-format on
default:
UNEXPECTED("Unknown access flag");
@@ -1317,7 +1332,7 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag, bool IsInsi
//VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
//VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
- static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag");
+ static_assert(RESOURCE_STATE_MAX_BIT == 0x40000, "This function must be updated to handle new resource state flag");
VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set");
switch (StateFlag)
{
@@ -1339,6 +1354,8 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag, bool IsInsi
case RESOURCE_STATE_RESOLVE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case RESOURCE_STATE_INPUT_ATTACHMENT: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
case RESOURCE_STATE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ case RESOURCE_STATE_BUILD_AS: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_RAY_TRACING: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED;
// clang-format on
default:
@@ -1349,7 +1366,7 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag, bool IsInsi
RESOURCE_STATE VkImageLayoutToResourceState(VkImageLayout Layout)
{
- static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag");
+ static_assert(RESOURCE_STATE_MAX_BIT == 0x40000, "This function must be updated to handle new resource state flag");
switch (Layout)
{
// clang-format off
@@ -1359,7 +1376,7 @@ RESOURCE_STATE VkImageLayoutToResourceState(VkImageLayout Layout)
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return RESOURCE_STATE_DEPTH_WRITE;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return RESOURCE_STATE_DEPTH_READ;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return RESOURCE_STATE_SHADER_RESOURCE;
- case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return RESOURCE_STATE_COPY_SOURCE;
+ case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return RESOURCE_STATE_COPY_SOURCE; // AZ TODO: check for resolve state
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return RESOURCE_STATE_COPY_DEST;
case VK_IMAGE_LAYOUT_PREINITIALIZED: UNEXPECTED("This layout is not supported"); return RESOURCE_STATE_UNDEFINED;
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: UNEXPECTED("This layout is not supported"); return RESOURCE_STATE_UNDEFINED;
@@ -1511,4 +1528,90 @@ VkAccessFlags AccessFlagsToVkAccessFlags(ACCESS_FLAGS AccessFlags)
}
#undef ASSERT_SAME
+VkBuildAccelerationStructureFlagsKHR BuildASFlagsToVkBuildAccelerationStructureFlags(RAYTRACING_BUILD_AS_FLAGS Flags)
+{
+ static_assert(RAYTRACING_BUILD_AS_FLAGS_LAST == 0x10, "AZ TODO");
+
+ VkBuildAccelerationStructureFlagsKHR Result = 0;
+ for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1)
+ {
+ if ((Flags & Bit) != Bit)
+ continue;
+
+ switch (RAYTRACING_BUILD_AS_FLAGS(Bit))
+ {
+ // clang-format off
+ case RAYTRACING_BUILD_AS_ALLOW_UPDATE: Result |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR; break;
+ case RAYTRACING_BUILD_AS_ALLOW_COMPACTION: Result |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR; break;
+ case RAYTRACING_BUILD_AS_PREFER_FAST_TRACE: Result |= VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; break;
+ case RAYTRACING_BUILD_AS_PREFER_FAST_BUILD: Result |= VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR; break;
+ case RAYTRACING_BUILD_AS_LOW_MEMORY: Result |= VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR; break;
+ default: UNEXPECTED("unknown build AS flag");
+ // clang-format on
+ }
+ }
+ return Result;
+}
+
+VkGeometryFlagsKHR GeometryFlagsToVkGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags)
+{
+ static_assert(RAYTRACING_GEOMETRY_FLAGS_LAST == 0x02, "AZ TODO");
+
+ VkGeometryFlagsKHR Result = 0;
+ for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1)
+ {
+ if ((Flags & Bit) != Bit)
+ continue;
+
+ switch (RAYTRACING_GEOMETRY_FLAGS(Bit))
+ {
+ // clang-format off
+ case RAYTRACING_GEOMETRY_OPAQUE: Result |= VK_GEOMETRY_OPAQUE_BIT_KHR; break;
+ case RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION: Result |= VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR; break;
+ default: UNEXPECTED("unknown geometry flag");
+ // clang-format on
+ }
+ }
+ return Result;
+}
+
+VkGeometryInstanceFlagsKHR InstanceFlagsToVkGeometryInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags)
+{
+ static_assert(RAYTRACING_INSTANCE_FLAGS_LAST == 0x08, "AZ TODO");
+
+ VkGeometryInstanceFlagsKHR Result = 0;
+ for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1)
+ {
+ if ((Flags & Bit) != Bit)
+ continue;
+
+ switch (RAYTRACING_INSTANCE_FLAGS(Bit))
+ {
+ // clang-format off
+ case RAYTRACING_INSTANCE_TRIANGLE_FACING_CULL_DISABLE: return VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
+ case RAYTRACING_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE: return VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR;
+ case RAYTRACING_INSTANCE_FORCE_OPAQUE: return VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR;
+ case RAYTRACING_INSTANCE_FORCE_NO_OPAQUE: return VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR;
+ default: UNEXPECTED("unknown instance flag");
+ // clang-format on
+ }
+ }
+ return Result;
+}
+
+VkCopyAccelerationStructureModeKHR CopyASModeToVkCopyAccelerationStructureMode(COPY_AS_MODE Mode)
+{
+ static_assert(COPY_AS_MODE_LAST == 0, "AZ TODO");
+
+ switch (Mode)
+ {
+ // clang-format off
+ case COPY_AS_MODE_CLONE: return VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR;
+ // clang-format on
+ }
+
+ UNEXPECTED("unknown AS copy mode");
+ return VkCopyAccelerationStructureModeKHR(0);
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp
index 4feb8692..ae1d3f11 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp
@@ -400,6 +400,11 @@ void SetQueryPoolName(VkDevice device, VkQueryPool queryPool, const char* name)
SetObjectName(device, (uint64_t)queryPool, VK_OBJECT_TYPE_QUERY_POOL, name);
}
+void SetAccelStructName(VkDevice device, VkAccelerationStructureKHR accelStruct, const char* name)
+{
+ SetObjectName(device, (uint64_t)accelStruct, VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR, name);
+}
+
template <>
void SetVulkanObjectName<VkCommandPool, VulkanHandleTypeId::CommandPool>(VkDevice device, VkCommandPool cmdPool, const char* name)
@@ -527,6 +532,11 @@ void SetVulkanObjectName<VkQueryPool, VulkanHandleTypeId::QueryPool>(VkDevice de
SetQueryPoolName(device, queryPool, name);
}
+template <>
+void SetVulkanObjectName<VkAccelerationStructureKHR, VulkanHandleTypeId::AccelerationStructureKHR>(VkDevice device, VkAccelerationStructureKHR accelStruct, const char* name)
+{
+ SetAccelStructName(device, accelStruct, name);
+}
const char* VkResultToString(VkResult errorCode)
@@ -558,6 +568,21 @@ const char* VkResultToString(VkResult errorCode)
STR(ERROR_INCOMPATIBLE_DISPLAY_KHR);
STR(ERROR_VALIDATION_FAILED_EXT);
STR(ERROR_INVALID_SHADER_NV);
+ STR(ERROR_FRAGMENTED_POOL);
+ STR(ERROR_UNKNOWN);
+ STR(ERROR_OUT_OF_POOL_MEMORY);
+ 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);
+ STR(THREAD_IDLE_KHR);
+ STR(THREAD_DONE_KHR);
+ STR(OPERATION_DEFERRED_KHR);
+ STR(OPERATION_NOT_DEFERRED_KHR);
+ STR(PIPELINE_COMPILE_REQUIRED_EXT);
#undef STR
// clang-format on
default:
@@ -589,6 +614,8 @@ const char* VkAccessFlagBitToString(VkAccessFlagBits Bit)
ACCESS_FLAG_BIT_TO_STRING(VK_ACCESS_HOST_WRITE_BIT)
ACCESS_FLAG_BIT_TO_STRING(VK_ACCESS_MEMORY_READ_BIT)
ACCESS_FLAG_BIT_TO_STRING(VK_ACCESS_MEMORY_WRITE_BIT)
+ ACCESS_FLAG_BIT_TO_STRING(VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR)
+ ACCESS_FLAG_BIT_TO_STRING(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR)
#undef ACCESS_FLAG_BIT_TO_STRING
default: UNEXPECTED("Unexpected bit"); return "";
// clang-format on
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp
index 5b720fd7..45d9bfa5 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp
@@ -34,11 +34,11 @@
namespace VulkanUtilities
{
-std::shared_ptr<VulkanLogicalDevice> VulkanLogicalDevice::Create(VkPhysicalDevice vkPhysicalDevice,
+std::shared_ptr<VulkanLogicalDevice> VulkanLogicalDevice::Create(const VulkanPhysicalDevice& PhysicalDevice,
const VkDeviceCreateInfo& DeviceCI,
const VkAllocationCallbacks* vkAllocator)
{
- auto* LogicalDevice = new VulkanLogicalDevice{vkPhysicalDevice, DeviceCI, vkAllocator};
+ auto* LogicalDevice = new VulkanLogicalDevice{PhysicalDevice, DeviceCI, vkAllocator};
return std::shared_ptr<VulkanLogicalDevice>{LogicalDevice};
}
@@ -47,13 +47,13 @@ VulkanLogicalDevice::~VulkanLogicalDevice()
vkDestroyDevice(m_VkDevice, m_VkAllocator);
}
-VulkanLogicalDevice::VulkanLogicalDevice(VkPhysicalDevice vkPhysicalDevice,
+VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice,
const VkDeviceCreateInfo& DeviceCI,
const VkAllocationCallbacks* vkAllocator) :
m_VkAllocator{vkAllocator},
m_EnabledFeatures{*DeviceCI.pEnabledFeatures}
{
- auto res = vkCreateDevice(vkPhysicalDevice, &DeviceCI, vkAllocator, &m_VkDevice);
+ auto res = vkCreateDevice(PhysicalDevice.GetVkDeviceHandle(), &DeviceCI, vkAllocator, &m_VkDevice);
CHECK_VK_ERROR_AND_THROW(res, "Failed to create logical device");
#if DILIGENT_USE_VOLK
@@ -264,6 +264,12 @@ QueryPoolWrapper VulkanLogicalDevice::CreateQueryPool(const VkQueryPoolCreateInf
return CreateVulkanObject<VkQueryPool, VulkanHandleTypeId::QueryPool>(vkCreateQueryPool, QueryPoolCI, DebugName, "query pool");
}
+AccelStructWrapper VulkanLogicalDevice::CreateAccelStruct(const VkAccelerationStructureCreateInfoKHR& CI, const char* DebugName) const
+{
+ VERIFY_EXPR(CI.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR);
+ return CreateVulkanObject<VkAccelerationStructureKHR, VulkanHandleTypeId::AccelerationStructureKHR>(vkCreateAccelerationStructureKHR, CI, DebugName, "acceleration structure");
+}
+
VkCommandBuffer VulkanLogicalDevice::AllocateVkCommandBuffer(const VkCommandBufferAllocateInfo& AllocInfo, const char* DebugName) const
{
VERIFY_EXPR(AllocInfo.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO);
@@ -405,6 +411,12 @@ void VulkanLogicalDevice::ReleaseVulkanObject(QueryPoolWrapper&& QueryPool) cons
QueryPool.m_VkObject = VK_NULL_HANDLE;
}
+void VulkanLogicalDevice::ReleaseVulkanObject(AccelStructWrapper&& AccelStruct) const
+{
+ vkDestroyAccelerationStructureKHR(m_VkDevice, AccelStruct.m_VkObject, m_VkAllocator);
+ AccelStruct.m_VkObject = VK_NULL_HANDLE;
+}
+
void VulkanLogicalDevice::FreeDescriptorSet(VkDescriptorPool Pool, VkDescriptorSet Set) const
{
VERIFY_EXPR(Pool != VK_NULL_HANDLE && Set != VK_NULL_HANDLE);
@@ -428,6 +440,13 @@ VkMemoryRequirements VulkanLogicalDevice::GetImageMemoryRequirements(VkImage vkI
return MemReqs;
}
+VkMemoryRequirements VulkanLogicalDevice::GetASMemoryRequirements(const VkAccelerationStructureMemoryRequirementsInfoKHR& Info) const
+{
+ VkMemoryRequirements2 MemReqs = {};
+ vkGetAccelerationStructureMemoryRequirementsKHR(m_VkDevice, &Info, &MemReqs);
+ return MemReqs.memoryRequirements;
+}
+
VkResult VulkanLogicalDevice::BindBufferMemory(VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset) const
{
return vkBindBufferMemory(m_VkDevice, buffer, memory, memoryOffset);
@@ -438,6 +457,30 @@ VkResult VulkanLogicalDevice::BindImageMemory(VkImage image, VkDeviceMemory memo
return vkBindImageMemory(m_VkDevice, image, memory, memoryOffset);
}
+VkResult VulkanLogicalDevice::BindASMemory(VkAccelerationStructureKHR AS, VkDeviceMemory memory, VkDeviceSize memoryOffset) const
+{
+ 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);
+}
+
+VkDeviceAddress VulkanLogicalDevice::GetAccelerationStructureDeviceAddress(VkAccelerationStructureKHR AS) const
+{
+ VkAccelerationStructureDeviceAddressInfoKHR Info = {};
+
+ Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
+ Info.accelerationStructure = AS;
+
+ return vkGetAccelerationStructureDeviceAddressKHR(m_VkDevice, &Info);
+}
+
VkResult VulkanLogicalDevice::MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) const
{
return vkMapMemory(m_VkDevice, memory, offset, size, flags, ppData);
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
index 92a5e4d4..12567cd0 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
@@ -68,12 +68,13 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice,
VERIFY_EXPR(ExtensionCount == m_SupportedExtensions.size());
}
-#ifdef VK_KHR_get_physical_device_properties2
+#if DILIGENT_USE_VOLK
if (Instance.IsExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
{
VkPhysicalDeviceFeatures2 Feats2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
VkPhysicalDeviceProperties2 Props2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
void** NextFeat = &Feats2.pNext;
+ void** NextProp = &Props2.pNext;
if (IsExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME))
{
@@ -103,23 +104,68 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice,
}
}
- // Enable mesh shader extension.
+ // Get mesh shader features and properties.
if (IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME))
{
*NextFeat = &m_ExtFeatures.MeshShader;
NextFeat = &m_ExtFeatures.MeshShader.pNext;
m_ExtFeatures.MeshShader.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV;
+
+ *NextProp = &m_ExtProperties.MeshShader;
+ NextProp = &m_ExtProperties.MeshShader.pNext;
+
+ 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))
+ {
+ *NextFeat = &m_ExtFeatures.RayTracing;
+ NextFeat = &m_ExtFeatures.RayTracing.pNext;
+
+ m_ExtFeatures.RayTracing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR;
+
+ *NextProp = &m_ExtProperties.RayTracing;
+ NextProp = &m_ExtProperties.RayTracing.pNext;
+
+ m_ExtProperties.RayTracing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_KHR;
+ }
+
+
+ // Additional extension that required for ray tracing.
+ if (IsExtensionSupported(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME))
+ {
+ *NextFeat = &m_ExtFeatures.BufferDeviceAddress;
+ NextFeat = &m_ExtFeatures.BufferDeviceAddress.pNext;
+
+ m_ExtFeatures.BufferDeviceAddress.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
+ }
+
+ // Additional extension that required for ray tracing.
+ if (IsExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME))
+ {
+ *NextFeat = &m_ExtFeatures.DescriptorIndexing;
+ NextFeat = &m_ExtFeatures.DescriptorIndexing.pNext;
+
+ m_ExtFeatures.DescriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
+
+ *NextProp = &m_ExtProperties.DescriptorIndexing;
+ NextProp = &m_ExtProperties.DescriptorIndexing.pNext;
+
+ m_ExtProperties.DescriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT;
}
+ // make sure that last pNext is null
*NextFeat = nullptr;
+ *NextProp = nullptr;
// Initialize device extension features by current physical device features.
// Some flags may not be supported by hardware.
vkGetPhysicalDeviceFeatures2KHR(m_VkDevice, &Feats2);
vkGetPhysicalDeviceProperties2KHR(m_VkDevice, &Props2);
}
-#endif
+#endif // DILIGENT_USE_VOLK
}
uint32_t VulkanPhysicalDevice::FindQueueFamily(VkQueueFlags QueueFlags) const