summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-10-28 16:33:03 +0000
committerazhirnov <zh1dron@gmail.com>2020-10-28 18:04:08 +0000
commit135d5dc6743fc89d7a19c539fa06eca33506f51b (patch)
tree9c8ed6e0d40a010f20657e62acbe955fba0757da /Graphics/GraphicsEngineD3D12
parentFixed vexing gcc/clang liker error (diff)
downloadDiligentCore-135d5dc6743fc89d7a19c539fa06eca33506f51b.tar.gz
DiligentCore-135d5dc6743fc89d7a19c539fa06eca33506f51b.zip
added ray tracing implementation for dx12 and vulkan
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/CMakeLists.txt9
-rw-r--r--Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp74
-rw-r--r--Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/include/CommandContext.hpp157
-rw-r--r--Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp21
-rw-r--r--Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp79
-rw-r--r--Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp83
-rw-r--r--Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h70
-rw-r--r--Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h71
-rw-r--r--Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h77
-rw-r--r--Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp152
-rw-r--r--Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp4
-rw-r--r--Graphics/GraphicsEngineD3D12/src/CommandContext.cpp99
-rw-r--r--Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp70
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp274
-rw-r--r--Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp8
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp33
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RootSignature.cpp15
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp202
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp30
-rw-r--r--Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp115
26 files changed, 1512 insertions, 149 deletions
diff --git a/Graphics/GraphicsEngineD3D12/CMakeLists.txt b/Graphics/GraphicsEngineD3D12/CMakeLists.txt
index 9941b62b..611bcbda 100644
--- a/Graphics/GraphicsEngineD3D12/CMakeLists.txt
+++ b/Graphics/GraphicsEngineD3D12/CMakeLists.txt
@@ -37,6 +37,9 @@ set(INCLUDE
include/SwapChainD3D12Impl.hpp
include/TextureD3D12Impl.hpp
include/TextureViewD3D12Impl.hpp
+ include/BottomLevelASD3D12Impl.hpp
+ include/TopLevelASD3D12Impl.hpp
+ include/ShaderBindingTableD3D12Impl.hpp
)
set(INTERFACE
@@ -55,6 +58,9 @@ set(INTERFACE
interface/SwapChainD3D12.h
interface/TextureD3D12.h
interface/TextureViewD3D12.h
+ interface/BottomLevelASD3D12.h
+ interface/TopLevelASD3D12.h
+ interface/ShaderBindingTableD3D12.h
)
@@ -89,6 +95,9 @@ set(SRC
src/SwapChainD3D12Impl.cpp
src/TextureD3D12Impl.cpp
src/TextureViewD3D12Impl.cpp
+ src/BottomLevelASD3D12Impl.cpp
+ src/TopLevelASD3D12Impl.cpp
+ src/ShaderBindingTableD3D12Impl.cpp
)
if(PLATFORM_WIN32)
diff --git a/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp
new file mode 100644
index 00000000..b631bdcc
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp
@@ -0,0 +1,74 @@
+/*
+ * 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
+/// Declaration of Diligent::BottomLevelASD3D12Impl class
+
+#include "BottomLevelASD3D12.h"
+#include "RenderDeviceD3D12.h"
+#include "BottomLevelASBase.hpp"
+#include "D3D12ResourceBase.hpp"
+#include "RenderDeviceD3D12Impl.hpp"
+
+namespace Diligent
+{
+
+/// Bottom-level acceleration structure object implementation in Direct3D12 backend.
+class BottomLevelASD3D12Impl final : public BottomLevelASBase<IBottomLevelASD3D12, RenderDeviceD3D12Impl>, public D3D12ResourceBase
+{
+public:
+ using TBottomLevelASBase = BottomLevelASBase<IBottomLevelASD3D12, RenderDeviceD3D12Impl>;
+
+ BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters,
+ class RenderDeviceD3D12Impl* pDeviceD3D12,
+ const BottomLevelASDesc& Desc,
+ bool bIsDeviceInternal = false);
+ ~BottomLevelASD3D12Impl();
+
+ virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
+
+ /// Implementation of IBottomLevelAS::GetScratchBufferSizes() in DirectX 12 backend.
+ virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; }
+
+ /// Implementation of IBottomLevelASD3D12::GetD3D12BLAS().
+ virtual ID3D12Resource* DILIGENT_CALL_TYPE GetD3D12BLAS() override final { return GetD3D12Resource(); }
+
+ /// Implementation of IBottomLevelAS::GetNativeHandle() in Direct3D12 backend.
+ virtual void* DILIGENT_CALL_TYPE GetNativeHandle() override final { return GetD3D12BLAS(); }
+
+ D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress()
+ {
+ return GetD3D12Resource()->GetGPUVirtualAddress();
+ }
+
+private:
+ ScratchBufferSizes m_ScratchSize;
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp
index ab90dfe7..ad3027a8 100644
--- a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp
@@ -103,6 +103,12 @@ public:
}
}
+ __forceinline D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress()
+ {
+ VERIFY_EXPR(m_Desc.Usage != USAGE_DYNAMIC);
+ return GetD3D12Resource()->GetGPUVirtualAddress();
+ }
+
D3D12_CPU_DESCRIPTOR_HANDLE GetCBVHandle() { return m_CBVDescriptorAllocation.GetCpuHandle(); }
private:
diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp
index 94f74933..511f1a03 100644
--- a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp
@@ -34,6 +34,8 @@
#include "TextureViewD3D12.h"
#include "TextureD3D12.h"
#include "BufferD3D12.h"
+#include "BottomLevelASD3D12.h"
+#include "TopLevelASD3D12.h"
#include "DescriptorHeap.hpp"
namespace Diligent
@@ -114,6 +116,8 @@ public:
void TransitionResource(ITextureD3D12* pTexture, RESOURCE_STATE NewState);
void TransitionResource(IBufferD3D12* pBuffer, RESOURCE_STATE NewState);
+ void TransitionResource(IBottomLevelASD3D12* pBLAS, RESOURCE_STATE NewState);
+ void TransitionResource(ITopLevelASD3D12* pTLAS, RESOURCE_STATE NewState);
void TransitionResource(const StateTransitionDesc& Barrier);
//void BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false);
@@ -238,8 +242,25 @@ protected:
Uint32 m_MaxInterfaceVer = 0;
};
+class ComputeContext : public CommandContext
+{
+public:
+ void SetComputeRootSignature(ID3D12RootSignature* pRootSig)
+ {
+ if (pRootSig != m_pCurComputeRootSignature)
+ {
+ m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig);
+ }
+ }
-class GraphicsContext : public CommandContext
+ void Dispatch(size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1)
+ {
+ FlushResourceBarriers();
+ m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ);
+ }
+};
+
+class GraphicsContext : public ComputeContext
{
public:
void ClearRenderTarget(D3D12_CPU_DESCRIPTOR_HANDLE RTV, const float* Color)
@@ -254,7 +275,7 @@ public:
m_pCommandList->ClearDepthStencilView(DSV, ClearFlags, Depth, Stencil, 0, nullptr);
}
- void SetRootSignature(ID3D12RootSignature* pRootSig)
+ void SetGraphicsRootSignature(ID3D12RootSignature* pRootSig)
{
if (pRootSig != m_pCurGraphicsRootSignature)
{
@@ -291,47 +312,6 @@ public:
}
}
- void SetConstants(UINT RootIndex, UINT NumConstants, const void* pConstants)
- {
- m_pCommandList->SetGraphicsRoot32BitConstants(RootIndex, NumConstants, pConstants, 0);
- }
-
- void SetConstants(UINT RootIndex, DWParam X)
- {
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0);
- }
-
- void SetConstants(UINT RootIndex, DWParam X, DWParam Y)
- {
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0);
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Y.Uint, 1);
- }
-
- void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z)
- {
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0);
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Y.Uint, 1);
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Z.Uint, 2);
- }
-
- void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W)
- {
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0);
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Y.Uint, 1);
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Z.Uint, 2);
- m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, W.Uint, 3);
- }
-
- void SetConstantBuffer(UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV)
- {
- m_pCommandList->SetGraphicsRootConstantBufferView(RootIndex, CBV);
- }
-
- void SetDescriptorTable(UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle)
- {
- m_pCommandList->SetGraphicsRootDescriptorTable(RootIndex, FirstHandle);
- }
-
void SetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW& IBView)
{
m_pCommandList->IASetIndexBuffer(&IBView);
@@ -384,83 +364,62 @@ public:
{
static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->EndRenderPass();
}
-};
-class GraphicsContext5 : public GraphicsContext4
-{
-};
-
-class GraphicsContext6 : public GraphicsContext5
-{
-public:
- void DrawMesh(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ)
+ void SetRayTracingPipelineState(ID3D12StateObject* pPSO)
{
-#ifdef D3D12_H_HAS_MESH_SHADER
- FlushResourceBarriers();
- static_cast<ID3D12GraphicsCommandList6*>(m_pCommandList.p)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
-#else
- UNSUPPORTED("DrawMesh is not supported in current D3D12 header");
-#endif
- }
-};
-
-class ComputeContext : public CommandContext
-{
-public:
- void SetRootSignature(ID3D12RootSignature* pRootSig)
- {
- if (pRootSig != m_pCurComputeRootSignature)
+ if (pPSO != m_pCurPipelineState)
{
- m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig);
+ static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->SetPipelineState1(pPSO);
+ m_pCurPipelineState = pPSO;
}
}
- void SetConstants(UINT RootIndex, UINT NumConstants, const void* pConstants)
- {
- m_pCommandList->SetComputeRoot32BitConstants(RootIndex, NumConstants, pConstants, 0);
- }
-
- void SetConstants(UINT RootIndex, DWParam X)
- {
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0);
- }
-
- void SetConstants(UINT RootIndex, DWParam X, DWParam Y)
+ void BuildRaytracingAccelerationStructure(const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC& Desc,
+ UINT NumPostbuildInfoDescs,
+ const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC* pPostbuildInfoDescs)
{
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0);
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1);
+ FlushResourceBarriers();
+ static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->BuildRaytracingAccelerationStructure(&Desc, NumPostbuildInfoDescs, pPostbuildInfoDescs);
}
- void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z)
+ void EmitRaytracingAccelerationStructurePostbuildInfo(const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC& Desc,
+ UINT NumSourceAccelerationStructures,
+ const D3D12_GPU_VIRTUAL_ADDRESS* pSourceAccelerationStructureData)
{
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0);
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1);
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Z.Uint, 2);
+ FlushResourceBarriers();
+ static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->EmitRaytracingAccelerationStructurePostbuildInfo(&Desc, NumSourceAccelerationStructures, pSourceAccelerationStructureData);
}
- void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W)
+ void CopyRaytracingAccelerationStructure(D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData,
+ D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureData,
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE Mode)
{
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0);
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1);
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Z.Uint, 2);
- m_pCommandList->SetComputeRoot32BitConstant(RootIndex, W.Uint, 3);
+ FlushResourceBarriers();
+ static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->CopyRaytracingAccelerationStructure(DestAccelerationStructureData, SourceAccelerationStructureData, Mode);
}
-
- void SetConstantBuffer(UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV)
+ void DispatchRays(const D3D12_DISPATCH_RAYS_DESC& Desc)
{
- m_pCommandList->SetComputeRootConstantBufferView(RootIndex, CBV);
+ FlushResourceBarriers();
+ static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->DispatchRays(&Desc);
}
+};
- void SetDescriptorTable(UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle)
- {
- m_pCommandList->SetComputeRootDescriptorTable(RootIndex, FirstHandle);
- }
+class GraphicsContext5 : public GraphicsContext4
+{
+};
- void Dispatch(size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1)
+class GraphicsContext6 : public GraphicsContext5
+{
+public:
+ void DrawMesh(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ)
{
+#ifdef D3D12_H_HAS_MESH_SHADER
FlushResourceBarriers();
- m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ);
+ static_cast<ID3D12GraphicsCommandList6*>(m_pCommandList.p)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
+#else
+ UNSUPPORTED("DrawMesh is not supported in current D3D12 header");
+#endif
}
};
diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp
index 240ea165..e3a78c6c 100644
--- a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp
@@ -43,7 +43,7 @@ public:
ID3D12Resource* GetD3D12Resource() { return m_pd3d12Resource; }
protected:
- CComPtr<ID3D12Resource> m_pd3d12Resource; ///< D3D12 buffer object
+ CComPtr<ID3D12Resource> m_pd3d12Resource; ///< D3D12 resource object
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp
index c6678ddd..389b76a1 100644
--- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp
@@ -78,5 +78,9 @@ D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType
D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType);
SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility);
+DXGI_FORMAT ValueTypeToIndexType(VALUE_TYPE Type);
+
+D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags);
+D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags);
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
index 39a354dd..3ac65274 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
@@ -42,6 +42,8 @@
#include "RenderPassD3D12Impl.hpp"
#include "PipelineStateD3D12Impl.hpp"
#include "D3D12DynamicHeap.hpp"
+#include "BottomLevelASD3D12Impl.hpp"
+#include "TopLevelASD3D12Impl.hpp"
namespace Diligent
{
@@ -56,6 +58,8 @@ struct DeviceContextD3D12ImplTraits
using QueryType = QueryD3D12Impl;
using FramebufferType = FramebufferD3D12Impl;
using RenderPassType = RenderPassD3D12Impl;
+ using BottomLevelASType = BottomLevelASD3D12Impl;
+ using TopLevelASType = TopLevelASD3D12Impl;
};
/// Device context implementation in Direct3D12 backend.
@@ -125,13 +129,13 @@ public:
ITextureView* pDepthStencil,
RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final;
- /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D11 backend.
+ /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D12 backend.
virtual void DILIGENT_CALL_TYPE BeginRenderPass(const BeginRenderPassAttribs& Attribs) override final;
- /// Implementation of IDeviceContext::NextSubpass() in Direct3D11 backend.
+ /// Implementation of IDeviceContext::NextSubpass() in Direct3D12 backend.
virtual void DILIGENT_CALL_TYPE NextSubpass() override final;
- /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend.
+ /// Implementation of IDeviceContext::EndRenderPass() in Direct3D12 backend.
virtual void DILIGENT_CALL_TYPE EndRenderPass() override final;
// clang-format off
@@ -351,12 +355,23 @@ private:
RESOURCE_STATE_TRANSITION_MODE TransitionMode,
RESOURCE_STATE RequiredState,
const char* OperationName);
+ __forceinline void TransitionOrVerifyBLASState(CommandContext& CmdCtx,
+ BottomLevelASD3D12Impl& BLAS,
+ RESOURCE_STATE_TRANSITION_MODE TransitionMode,
+ RESOURCE_STATE RequiredState,
+ const char* OperationName);
+ __forceinline void TransitionOrVerifyTLASState(CommandContext& CmdCtx,
+ TopLevelASD3D12Impl& TLAS,
+ RESOURCE_STATE_TRANSITION_MODE TransitionMode,
+ RESOURCE_STATE RequiredState,
+ const char* OperationName);
__forceinline void PrepareForDraw(GraphicsContext& GraphCtx, DRAW_FLAGS Flags);
__forceinline void PrepareForIndexedDraw(GraphicsContext& GraphCtx, DRAW_FLAGS Flags, VALUE_TYPE IndexType);
__forceinline void PrepareForDispatchCompute(ComputeContext& GraphCtx);
+ __forceinline void PrepareForDispatchRays(GraphicsContext& GraphCtx);
__forceinline void PrepareDrawIndirectBuffer(GraphicsContext& GraphCtx,
IBuffer* pAttribsBuffer,
diff --git a/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp
index 59642660..31b65866 100644
--- a/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp
@@ -39,7 +39,7 @@ namespace Diligent
class FixedBlockMemoryAllocator;
-/// Render pass implementation in Direct3D11 backend.
+/// Render pass implementation in Direct3D12 backend.
class FramebufferD3D12Impl final : public FramebufferBase<IFramebuffer, RenderDeviceD3D12Impl>
{
public:
diff --git a/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp
index 501e62df..00984731 100644
--- a/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp
@@ -39,7 +39,7 @@ namespace Diligent
class FixedBlockMemoryAllocator;
-/// Render pass implementation in Direct3D11 backend.
+/// Render pass implementation in Direct3D12 backend.
class RenderPassD3D12Impl final : public RenderPassBase<IRenderPass, RenderDeviceD3D12Impl>
{
public:
diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp
new file mode 100644
index 00000000..e866c6f2
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp
@@ -0,0 +1,79 @@
+/*
+ * 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
+/// Declaration of Diligent::ShaderBindingTableD3D12Impl class
+
+#include "ShaderBindingTableD3D12.h"
+#include "RenderDeviceD3D12.h"
+#include "ShaderBindingTableBase.hpp"
+#include "D3D12ResourceBase.hpp"
+#include "RenderDeviceD3D12Impl.hpp"
+#include "PipelineStateD3D12Impl.hpp"
+
+namespace Diligent
+{
+
+/// Shader binding table object implementation in Direct3D12 backend.
+class ShaderBindingTableD3D12Impl final : public ShaderBindingTableBase<IShaderBindingTableD3D12, PipelineStateD3D12Impl, RenderDeviceD3D12Impl>, public D3D12ResourceBase
+{
+public:
+ using TShaderBindingTableBase = ShaderBindingTableBase<IShaderBindingTableD3D12, PipelineStateD3D12Impl, RenderDeviceD3D12Impl>;
+
+ ShaderBindingTableD3D12Impl(IReferenceCounters* pRefCounters,
+ class RenderDeviceD3D12Impl* pDeviceD3D12,
+ const ShaderBindingTableDesc& Desc,
+ bool bIsDeviceInternal = false);
+ ~ShaderBindingTableD3D12Impl();
+
+ virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
+
+ 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 BindAll(const BindAllAttribs& Attribs) override;
+
+ virtual void DILIGENT_CALL_TYPE GetD3D12AddressRangeAndStride(IDeviceContextD3D12* pContext,
+ RESOURCE_STATE_TRANSITION_MODE TransitionMode,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE& RaygenShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& MissShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& HitShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& CallableShaderBindingTable) override;
+
+private:
+ void ValidateDesc(const ShaderBindingTableDesc& Desc) const;
+
+private:
+ RefCntAutoPtr<IBuffer> m_pBuffer;
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp
new file mode 100644
index 00000000..8eccf530
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp
@@ -0,0 +1,83 @@
+/*
+ * 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
+/// Declaration of Diligent::TopLevelASD3D12Impl class
+
+#include "TopLevelASD3D12.h"
+#include "RenderDeviceD3D12.h"
+#include "TopLevelASBase.hpp"
+#include "D3D12ResourceBase.hpp"
+#include "RenderDeviceD3D12Impl.hpp"
+
+namespace Diligent
+{
+
+/// Top-level acceleration structure object implementation in Direct3D12 backend.
+class TopLevelASD3D12Impl final : public TopLevelASBase<ITopLevelASD3D12, RenderDeviceD3D12Impl>, public D3D12ResourceBase
+{
+public:
+ using TTopLevelASBase = TopLevelASBase<ITopLevelASD3D12, RenderDeviceD3D12Impl>;
+
+ TopLevelASD3D12Impl(IReferenceCounters* pRefCounters,
+ class RenderDeviceD3D12Impl* pDeviceD3D12,
+ const TopLevelASDesc& Desc,
+ bool bIsDeviceInternal = false);
+ ~TopLevelASD3D12Impl();
+
+ virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
+
+ /// Implementation of ITopLevelASD3D12::GetScratchBufferSizes() in DirectX 12 backend.
+ virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; }
+
+ /// Implementation of ITopLevelASD3D12D3D12::GetD3D12TLAS().
+ virtual ID3D12Resource* DILIGENT_CALL_TYPE GetD3D12TLAS() override final { return GetD3D12Resource(); }
+
+ /// Implementation of ITopLevelASD3D12::GetNativeHandle() in Direct3D12 backend.
+ virtual void* DILIGENT_CALL_TYPE GetNativeHandle() override final { return GetD3D12TLAS(); }
+
+ D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress()
+ {
+ return GetD3D12Resource()->GetGPUVirtualAddress();
+ }
+
+ /// Implementation of ITopLevelASD3D12::GetCPUDescriptorHandle() in Direct3D12 backend.
+ virtual D3D12_CPU_DESCRIPTOR_HANDLE DILIGENT_CALL_TYPE GetCPUDescriptorHandle() override final
+ {
+ return m_DescriptorHandle.GetCpuHandle();
+ }
+
+private:
+ ScratchBufferSizes m_ScratchSize;
+
+ // Allocation in a CPU-only descriptor heap
+ DescriptorHeapAllocation m_DescriptorHandle;
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h b/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h
new file mode 100644
index 00000000..2b64da57
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h
@@ -0,0 +1,70 @@
+/*
+ * 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::IBottomLevelASD3D12 interface
+
+#include "../../GraphicsEngine/interface/BottomLevelAS.h"
+#include "../../GraphicsEngine/interface/DeviceContext.h"
+
+DILIGENT_BEGIN_NAMESPACE(Diligent)
+
+// {610228AF-F161-4B12-A00E-71E6E3BB97FE}
+static const INTERFACE_ID IID_BottomLevelASD3D12 =
+ {0x610228af, 0xf161, 0x4b12, {0xa0, 0xe, 0x71, 0xe6, 0xe3, 0xbb, 0x97, 0xfe}};
+
+#define DILIGENT_INTERFACE_NAME IBottomLevelASD3D12
+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
+
+#define IBottomLevelASD3D12InclusiveMethods \
+ IBottomLevelASInclusiveMethods; \
+ IBottomLevelASD3D12Methods BottomLevelASD3D12
+
+// clang-format off
+
+/// Exposes Direct3D12-specific functionality of a bottom-level acceleration structure object.
+DILIGENT_BEGIN_INTERFACE(IBottomLevelASD3D12, IBottomLevelAS)
+{
+ /// Returns ID3D12Resource interface of the internal D3D12 acceleration structure object.
+
+ /// The method does *NOT* call AddRef() on the returned interface,
+ /// so Release() must not be called.
+ VIRTUAL ID3D12Resource* METHOD(GetD3D12BLAS)(THIS) PURE;
+};
+DILIGENT_END_INTERFACE
+
+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
+
+#if DILIGENT_C_INTERFACE
+
+# define IBottomLevelASD3D12_GetD3D12BLAS(This) CALL_IFACE_METHOD(IBottomLevelASD3D12, GetD3D12BLAS, This)
+
+#endif
+
+DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h
new file mode 100644
index 00000000..f33bac1b
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h
@@ -0,0 +1,71 @@
+/*
+ * 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::IShaderBindingTableD3D12 interface
+
+#include "../../GraphicsEngine/interface/ShaderBindingTable.h"
+#include "DeviceContextD3D12.h"
+
+DILIGENT_BEGIN_NAMESPACE(Diligent)
+
+// {DCA2FAD9-2C41-4419-9D16-79731C0ED9D8}
+static const INTERFACE_ID IID_ShaderBindingTableD3D12 =
+ {0xdca2fad9, 0x2c41, 0x4419, {0x9d, 0x16, 0x79, 0x73, 0x1c, 0xe, 0xd9, 0xd8}};
+
+#define DILIGENT_INTERFACE_NAME IShaderBindingTableD3D12
+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
+
+#define IShaderBindingTableD3D12InclusiveMethods \
+ IShaderBindingTableInclusiveMethods; \
+ IShaderBindingTableD3D12Methods ShaderBindingTable
+// clang-format off
+
+/// Exposes Direct3D12-specific functionality of a shader binding table object.
+DILIGENT_BEGIN_INTERFACE(IShaderBindingTableD3D12, IShaderBindingTable)
+{
+ /// AZ TODO
+ VIRTUAL void METHOD(GetD3D12AddressRangeAndStride)(THIS_
+ IDeviceContextD3D12* pContext,
+ RESOURCE_STATE_TRANSITION_MODE TransitionMode,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE REF RaygenShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE REF MissShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE REF HitShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE REF CallableShaderBindingTable) PURE;
+};
+DILIGENT_END_INTERFACE
+
+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
+
+#if DILIGENT_C_INTERFACE
+
+
+#endif
+
+DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h b/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h
new file mode 100644
index 00000000..5b2bd512
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h
@@ -0,0 +1,77 @@
+/*
+ * 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::ITopLevelASD3D12 interface
+
+#include "../../GraphicsEngine/interface/TopLevelAS.h"
+#include "../../GraphicsEngine/interface/DeviceContext.h"
+
+DILIGENT_BEGIN_NAMESPACE(Diligent)
+
+// {46334F12-64CB-4F7C-BB71-31515B6F386D}
+static const INTERFACE_ID IID_TopLevelASD3D12 =
+ {0x46334f12, 0x64cb, 0x4f7c, {0xbb, 0x71, 0x31, 0x51, 0x5b, 0x6f, 0x38, 0x6d}};
+
+#define DILIGENT_INTERFACE_NAME ITopLevelASD3D12
+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
+
+#define ITopLevelASD3D12InclusiveMethods \
+ ITopLevelASInclusiveMethods; \
+ ITopLevelASD3D12Methods TopLevelASD3D12
+
+// clang-format off
+
+/// Exposes Direct3D12-specific functionality of a top-level acceleration structure object.
+DILIGENT_BEGIN_INTERFACE(ITopLevelASD3D12, ITopLevelAS)
+{
+ /// Returns ID3D12Resource interface of the internal D3D12 acceleration structure object.
+
+ /// The method does *NOT* call AddRef() on the returned interface,
+ /// so Release() must not be called.
+ VIRTUAL ID3D12Resource* METHOD(GetD3D12TLAS)(THIS) PURE;
+
+ /// Returns a CPU descriptor handle of the D3D12 acceleration structure
+
+ /// The method does *NOT* call AddRef() on the returned interface,
+ /// so Release() must not be called.
+ VIRTUAL D3D12_CPU_DESCRIPTOR_HANDLE METHOD(GetCPUDescriptorHandle)(THIS) PURE;
+};
+DILIGENT_END_INTERFACE
+
+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
+
+#if DILIGENT_C_INTERFACE
+
+# define ITopLevelASD3D12_GetD3D12TLAS(This) CALL_IFACE_METHOD(ITopLevelASD3D12, GetD3D12TLAS, This)
+# define ITopLevelASD3D12_GetCPUDescriptorHandle(This) CALL_IFACE_METHOD(ITopLevelASD3D12, GetCPUDescriptorHandle, This)
+
+#endif
+
+DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp
new file mode 100644
index 00000000..31f0e6a3
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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 "BottomLevelASD3D12Impl.hpp"
+#include "RenderDeviceD3D12Impl.hpp"
+#include "DeviceContextD3D12Impl.hpp"
+#include "D3D12TypeConversions.hpp"
+#include "GraphicsAccessories.hpp"
+#include "DXGITypeConversions.hpp"
+#include "EngineMemory.h"
+#include "StringTools.hpp"
+
+namespace Diligent
+{
+
+BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters,
+ class RenderDeviceD3D12Impl* pDeviceD3D12,
+ const BottomLevelASDesc& Desc,
+ bool bIsDeviceInternal) :
+ TBottomLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal}
+{
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO BottomLevelPrebuildInfo = {};
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS BottomLevelInputs = {};
+ std::vector<D3D12_RAYTRACING_GEOMETRY_DESC> Geometries;
+
+ if (m_Desc.pTriangles != nullptr)
+ {
+ Geometries.resize(m_Desc.TriangleCount);
+ Uint32 MaxPrimitiveCount = 0;
+ for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i)
+ {
+ auto& src = m_Desc.pTriangles[i];
+ auto& dst = Geometries[i];
+
+ dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
+ dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
+ dst.Triangles.VertexBuffer.StartAddress = 0;
+ dst.Triangles.VertexBuffer.StrideInBytes = 0;
+ dst.Triangles.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16);
+ dst.Triangles.VertexCount = src.MaxVertexCount;
+ dst.Triangles.IndexCount = src.MaxIndexCount;
+ dst.Triangles.IndexFormat = ValueTypeToIndexType(src.IndexType);
+ dst.Triangles.IndexBuffer = 0;
+ dst.Triangles.Transform3x4 = 0;
+
+ MaxPrimitiveCount += src.MaxIndexCount ? src.MaxIndexCount / 3 : src.MaxVertexCount / 3;
+ }
+ VERIFY_EXPR(MaxPrimitiveCount <= D3D12_RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE);
+ }
+ else if (m_Desc.pBoxes != nullptr)
+ {
+ Geometries.resize(m_Desc.BoxCount);
+ Uint32 MaxBoxCount = 0;
+ for (uint32_t i = 0; i < m_Desc.BoxCount; ++i)
+ {
+ auto& src = m_Desc.pBoxes[i];
+ auto& dst = Geometries[i];
+
+ dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
+ dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
+ dst.AABBs.AABBCount = src.MaxBoxCount;
+ dst.AABBs.AABBs.StartAddress = 0;
+ dst.AABBs.AABBs.StrideInBytes = 0;
+
+ MaxBoxCount += src.MaxBoxCount;
+ }
+ VERIFY_EXPR(MaxBoxCount <= D3D12_RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE);
+ }
+
+ VERIFY_EXPR(Geometries.size() <= D3D12_RAYTRACING_MAX_GEOMETRIES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE);
+
+ BottomLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
+ BottomLevelInputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
+ BottomLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ BottomLevelInputs.pGeometryDescs = Geometries.data();
+ BottomLevelInputs.NumDescs = static_cast<UINT>(Geometries.size());
+
+ auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5();
+
+ pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&BottomLevelInputs, &BottomLevelPrebuildInfo);
+ if (BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0)
+ LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info");
+
+ D3D12_HEAP_PROPERTIES HeapProps;
+ HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ HeapProps.CreationNodeMask = 1;
+ HeapProps.VisibleNodeMask = 1;
+
+ D3D12_RESOURCE_DESC ASDesc = {};
+ ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ ASDesc.Alignment = 0;
+ ASDesc.Width = BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes;
+ ASDesc.Height = 1;
+ ASDesc.DepthOrArraySize = 1;
+ ASDesc.MipLevels = 1;
+ ASDesc.Format = DXGI_FORMAT_UNKNOWN;
+ ASDesc.SampleDesc.Count = 1;
+ ASDesc.SampleDesc.Quality = 0;
+ ASDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ ASDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
+
+ auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE,
+ &ASDesc, D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE, nullptr,
+ __uuidof(m_pd3d12Resource),
+ reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)));
+ if (FAILED(hr))
+ LOG_ERROR_AND_THROW("Failed to create D3D12 Bottom-level acceleration structure");
+
+ if (*m_Desc.Name != 0)
+ m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str());
+
+ m_ScratchSize.Build = static_cast<Uint32>(BottomLevelPrebuildInfo.ScratchDataSizeInBytes);
+ m_ScratchSize.Update = static_cast<Uint32>(BottomLevelPrebuildInfo.UpdateScratchDataSizeInBytes);
+}
+
+BottomLevelASD3D12Impl::~BottomLevelASD3D12Impl()
+{
+ // D3D12 object can only be destroyed when it is no longer used by the GPU
+ auto* pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice());
+ pDeviceD3D12Impl->SafeReleaseDeviceObject(std::move(m_pd3d12Resource), m_Desc.CommandQueueMask);
+}
+
+IMPLEMENT_QUERY_INTERFACE(BottomLevelASD3D12Impl, IID_BottomLevelASD3D12, TBottomLevelASBase)
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
index d7cd54b6..8e84b844 100644
--- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp
@@ -118,9 +118,9 @@ BufferD3D12Impl::BufferD3D12Impl(IReferenceCounters* pRefCounters,
// understood by applications and row-major texture data is commonly marshaled through buffers.
D3D12BuffDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
D3D12BuffDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
- if (m_Desc.BindFlags & BIND_UNORDERED_ACCESS)
+ if ((m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || (m_Desc.BindFlags & BIND_RAY_TRACING))
D3D12BuffDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
- if (!(m_Desc.BindFlags & BIND_SHADER_RESOURCE))
+ if (!(m_Desc.BindFlags & BIND_SHADER_RESOURCE) && !(m_Desc.BindFlags & BIND_RAY_TRACING))
D3D12BuffDesc.Flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
auto* pd3d12Device = pRenderDeviceD3D12->GetD3D12Device();
diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
index 389bf3eb..6bc55ac3 100644
--- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
@@ -30,6 +30,8 @@
#include "CommandContext.hpp"
#include "TextureD3D12Impl.hpp"
#include "BufferD3D12Impl.hpp"
+#include "BottomLevelASD3D12Impl.hpp"
+#include "TopLevelASD3D12Impl.hpp"
#include "CommandListManager.hpp"
#include "D3D12TypeConversions.hpp"
@@ -39,9 +41,9 @@ namespace Diligent
CommandContext::CommandContext(CommandListManager& CmdListManager) :
// clang-format off
- m_pCurGraphicsRootSignature {nullptr},
- m_pCurPipelineState {nullptr},
- m_pCurComputeRootSignature {nullptr},
+ m_pCurGraphicsRootSignature {nullptr},
+ m_pCurPipelineState {nullptr},
+ m_pCurComputeRootSignature {nullptr},
m_PendingResourceBarriers (STD_ALLOCATOR_RAW_MEM(D3D12_RESOURCE_BARRIER, GetRawAllocator(), "Allocator for vector<D3D12_RESOURCE_BARRIER>"))
// clang-format on
{
@@ -78,7 +80,7 @@ void CommandContext::Reset(CommandListManager& CmdListManager)
m_PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
#if 0
- BindDescriptorHeaps();
+ BindDescriptorHeaps();
#endif
}
@@ -115,6 +117,24 @@ void CommandContext::TransitionResource(IBufferD3D12* pBuffer, RESOURCE_STATE Ne
TransitionResource(BufferBarrier);
}
+void CommandContext::TransitionResource(IBottomLevelASD3D12* pBLAS, RESOURCE_STATE NewState)
+{
+ VERIFY_EXPR(pBLAS != nullptr);
+ auto* pBLASfD3D12 = ValidatedCast<BottomLevelASD3D12Impl>(pBLAS);
+ VERIFY(pBLASfD3D12->IsInKnownState(), "BLAS state can't be unknown");
+ StateTransitionDesc ASBarrier(pBLAS, RESOURCE_STATE_UNKNOWN, NewState, true);
+ TransitionResource(ASBarrier);
+}
+
+void CommandContext::TransitionResource(ITopLevelASD3D12* pTLAS, RESOURCE_STATE NewState)
+{
+ VERIFY_EXPR(pTLAS != nullptr);
+ auto* pTLASfD3D12 = ValidatedCast<TopLevelASD3D12Impl>(pTLAS);
+ VERIFY(pTLASfD3D12->IsInKnownState(), "TLAS state can't be unknown");
+ StateTransitionDesc ASBarrier(pTLAS, RESOURCE_STATE_UNKNOWN, NewState, true);
+ TransitionResource(ASBarrier);
+}
+
void CommandContext::InsertUAVBarrier(ID3D12Resource* pd3d12Resource)
{
m_PendingResourceBarriers.emplace_back();
@@ -147,25 +167,23 @@ static D3D12_RESOURCE_BARRIER_FLAGS TransitionTypeToD3D12ResourceBarrierFlag(STA
void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
{
- DEV_CHECK_ERR((Barrier.pTexture != nullptr) ^ (Barrier.pBuffer != nullptr), "Exactly one of pTexture or pBuffer must not be null");
-
DEV_CHECK_ERR(Barrier.NewState != RESOURCE_STATE_UNKNOWN, "New resource state can't be unknown");
- RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN;
- ID3D12Resource* pd3d12Resource = nullptr;
- TextureD3D12Impl* pTextureD3D12Impl = nullptr;
- BufferD3D12Impl* pBufferD3D12Impl = nullptr;
- if (Barrier.pTexture)
+ RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN;
+ ID3D12Resource* pd3d12Resource = nullptr;
+ RefCntAutoPtr<TextureD3D12Impl> pTextureD3D12Impl{Barrier.pResource, IID_TextureD3D12};
+ RefCntAutoPtr<BufferD3D12Impl> pBufferD3D12Impl{Barrier.pResource, IID_BufferD3D12};
+ RefCntAutoPtr<BottomLevelASD3D12Impl> pBLASD3D12Impl{Barrier.pResource, IID_BottomLevelASD3D12};
+ RefCntAutoPtr<TopLevelASD3D12Impl> pTLASD3D12Impl{Barrier.pResource, IID_TopLevelASD3D12};
+
+ if (pTextureD3D12Impl)
{
- pTextureD3D12Impl = ValidatedCast<TextureD3D12Impl>(Barrier.pTexture);
- pd3d12Resource = pTextureD3D12Impl->GetD3D12Resource();
- OldState = pTextureD3D12Impl->GetState();
+ pd3d12Resource = pTextureD3D12Impl->GetD3D12Resource();
+ OldState = pTextureD3D12Impl->GetState();
}
- else
+ else if (pBufferD3D12Impl)
{
- VERIFY_EXPR(Barrier.pBuffer != nullptr);
- pBufferD3D12Impl = ValidatedCast<BufferD3D12Impl>(Barrier.pBuffer);
- pd3d12Resource = pBufferD3D12Impl->GetD3D12Resource();
- OldState = pBufferD3D12Impl->GetState();
+ pd3d12Resource = pBufferD3D12Impl->GetD3D12Resource();
+ OldState = pBufferD3D12Impl->GetState();
#ifdef DILIGENT_DEVELOPMENT
// Dynamic buffers wtih no SRV/UAV bind flags are suballocated in
@@ -178,6 +196,20 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
}
#endif
}
+ else if (pBLASD3D12Impl)
+ {
+ pd3d12Resource = pBLASD3D12Impl->GetD3D12Resource();
+ OldState = pBLASD3D12Impl->GetState();
+ }
+ else if (pTLASD3D12Impl)
+ {
+ pd3d12Resource = pTLASD3D12Impl->GetD3D12Resource();
+ OldState = pTLASD3D12Impl->GetState();
+ }
+ else
+ {
+ UNEXPECTED("unsupported resource type");
+ }
if (OldState == RESOURCE_STATE_UNKNOWN)
{
@@ -243,9 +275,8 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
}
}
}
- else
+ else if (pBufferD3D12Impl)
{
- VERIFY_EXPR(pBufferD3D12Impl);
m_PendingResourceBarriers.emplace_back(BarrierDesc);
}
}
@@ -259,10 +290,8 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
pTextureD3D12Impl->SetState(NewState);
}
}
- else
+ else if (pBufferD3D12Impl)
{
- VERIFY_EXPR(pBufferD3D12Impl);
-
VERIFY(!Barrier.UpdateResourceState || (Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE || Barrier.TransitionType == STATE_TRANSITION_TYPE_END),
"Buffer state can't be updated in begin-split barrier");
if (Barrier.UpdateResourceState)
@@ -275,9 +304,29 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
"Dynamic buffers without SRV/UAV bind flag are expected to never "
"transition from RESOURCE_STATE_GENERIC_READ state");
}
+ else if (pBLASD3D12Impl)
+ {
+ VERIFY(!Barrier.UpdateResourceState || (Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE || Barrier.TransitionType == STATE_TRANSITION_TYPE_END),
+ "Bottom-level acceleration structure state can't be updated in begin-split barrier");
+ if (Barrier.UpdateResourceState)
+ {
+ pBLASD3D12Impl->SetState(NewState);
+ }
+ }
+ else if (pTLASD3D12Impl)
+ {
+ VERIFY(!Barrier.UpdateResourceState || (Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE || Barrier.TransitionType == STATE_TRANSITION_TYPE_END),
+ "Top-level acceleration structure state can't be updated in begin-split barrier");
+ if (Barrier.UpdateResourceState)
+ {
+ pTLASD3D12Impl->SetState(NewState);
+ }
+ }
}
- if (OldState == RESOURCE_STATE_UNORDERED_ACCESS && Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS)
+ if ((OldState == RESOURCE_STATE_UNORDERED_ACCESS && Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS) ||
+ (OldState == RESOURCE_STATE_BUILD_AS_WRITE && Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE) ||
+ (OldState == RESOURCE_STATE_RAY_TRACING && Barrier.NewState == RESOURCE_STATE_RAY_TRACING))
{
DEV_CHECK_ERR(Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE, "UAV barriers must not be split");
InsertUAVBarrier(pd3d12Resource);
diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
index 3ea4bad0..ddab5096 100644
--- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
@@ -351,8 +351,9 @@ static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STAT
case RESOURCE_STATE_RESOLVE_SOURCE: return D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
case RESOURCE_STATE_INPUT_ATTACHMENT: return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
case RESOURCE_STATE_PRESENT: return D3D12_RESOURCE_STATE_PRESENT;
- case RESOURCE_STATE_BUILD_AS: return D3D12_RESOURCE_STATES(0);
- case RESOURCE_STATE_RAY_TRACING: return D3D12_RESOURCE_STATES(0); // AZ TODO
+ case RESOURCE_STATE_BUILD_AS_READ: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
+ case RESOURCE_STATE_BUILD_AS_WRITE: return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
+ case RESOURCE_STATE_RAY_TRACING: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
// clang-format on
default:
UNEXPECTED("Unexpected resource state flag");
@@ -379,7 +380,7 @@ public:
}
private:
- static constexpr Uint32 MaxFlagBitPos = 18;
+ static constexpr Uint32 MaxFlagBitPos = 19;
std::array<D3D12_RESOURCE_STATES, MaxFlagBitPos + 1> FlagBitPosToResStateMap;
};
@@ -422,7 +423,6 @@ static RESOURCE_STATE D3D12ResourceStateToResourceStateFlags(D3D12_RESOURCE_STAT
case D3D12_RESOURCE_STATE_COPY_SOURCE: return RESOURCE_STATE_COPY_SOURCE;
case D3D12_RESOURCE_STATE_RESOLVE_DEST: return RESOURCE_STATE_RESOLVE_DEST;
case D3D12_RESOURCE_STATE_RESOLVE_SOURCE: return RESOURCE_STATE_RESOLVE_SOURCE;
- // AZ TODO
// clang-format on
default:
UNEXPECTED("Unexpected D3D12 resource state");
@@ -592,5 +592,67 @@ SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisi
}
}
+DXGI_FORMAT ValueTypeToIndexType(VALUE_TYPE IndexType)
+{
+ switch (IndexType)
+ {
+ // clang-format off
+ case VT_UNDEFINED: return DXGI_FORMAT_UNKNOWN; // only for ray tracing
+ case VT_UINT16: return DXGI_FORMAT_R16_UINT;
+ case VT_UINT32: return DXGI_FORMAT_R32_UINT;
+ // clang-format on
+ default:
+ UNEXPECTED("Unexpected index type");
+ return DXGI_FORMAT_R32_UINT;
+ }
+}
+
+D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags)
+{
+ static_assert(RAYTRACING_GEOMETRY_FLAGS_LAST == RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION,
+ "Please update the switch below to handle the new ray tracing geometry flag");
+
+ Uint32 Result = 0;
+ for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1)
+ {
+ if ((Flags & Bit) != Bit)
+ continue;
+
+ switch (static_cast<RAYTRACING_GEOMETRY_FLAGS>(Bit))
+ {
+ // clang-format off
+ case RAYTRACING_GEOMETRY_OPAQUE: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; break;
+ case RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION; break;
+ // clang-format on
+ default: UNEXPECTED("unknown geometry flag");
+ }
+ }
+ return static_cast<D3D12_RAYTRACING_GEOMETRY_FLAGS>(Result);
+}
+
+D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags)
+{
+ static_assert(RAYTRACING_INSTANCE_FLAGS_LAST == RAYTRACING_INSTANCE_FORCE_NO_OPAQUE,
+ "Please update the switch below to handle the new ray tracing instance flag");
+
+ Uint32 Result = 0;
+ for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1)
+ {
+ if ((Flags & Bit) != Bit)
+ continue;
+
+ switch (static_cast<RAYTRACING_INSTANCE_FLAGS>(Bit))
+ {
+ // clang-format off
+ case RAYTRACING_INSTANCE_TRIANGLE_FACING_CULL_DISABLE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE ; break;
+ case RAYTRACING_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE ; break;
+ case RAYTRACING_INSTANCE_FORCE_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE ; break;
+ case RAYTRACING_INSTANCE_FORCE_NO_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE ; break;
+ // clang-format on
+ default: UNEXPECTED("unknown instance flag");
+ }
+ }
+ return static_cast<D3D12_RAYTRACING_INSTANCE_FLAGS>(Result);
+}
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 6ca74c27..95025c4c 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -39,6 +39,7 @@
#include "D3D12DynamicHeap.hpp"
#include "CommandListD3D12Impl.hpp"
#include "DXGITypeConversions.hpp"
+#include "ShaderBindingTableD3D12Impl.hpp"
namespace Diligent
{
@@ -262,6 +263,8 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState)
}
case PIPELINE_TYPE_RAY_TRACING:
{
+ auto* pd3d12SO = pPipelineStateD3D12->GetD3D12StateObject();
+ CmdCtx.AsGraphicsContext4().SetRayTracingPipelineState(pd3d12SO);
break;
}
default:
@@ -449,7 +452,7 @@ void DeviceContextD3D12Impl::PrepareForDraw(GraphicsContext& GraphCtx, DRAW_FLAG
}
#endif
- GraphCtx.SetRootSignature(m_pPipelineState->GetD3D12RootSignature());
+ GraphCtx.SetGraphicsRootSignature(m_pPipelineState->GetD3D12RootSignature());
if (m_State.pCommittedResourceCache != nullptr)
{
@@ -605,7 +608,7 @@ void DeviceContextD3D12Impl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Att
void DeviceContextD3D12Impl::PrepareForDispatchCompute(ComputeContext& ComputeCtx)
{
- ComputeCtx.SetRootSignature(m_pPipelineState->GetD3D12RootSignature());
+ ComputeCtx.SetComputeRootSignature(m_pPipelineState->GetD3D12RootSignature());
if (m_State.pCommittedResourceCache != nullptr)
{
if (m_State.pCommittedResourceCache->GetNumDynamicCBsBound() > 0)
@@ -634,6 +637,37 @@ void DeviceContextD3D12Impl::PrepareForDispatchCompute(ComputeContext& ComputeCt
#endif
}
+void DeviceContextD3D12Impl::PrepareForDispatchRays(GraphicsContext& GraphCtx)
+{
+ GraphCtx.SetComputeRootSignature(m_pPipelineState->GetD3D12RootSignature());
+ if (m_State.pCommittedResourceCache != nullptr)
+ {
+ if (m_State.pCommittedResourceCache->GetNumDynamicCBsBound() > 0)
+ {
+ // Only process dynamic buffers. Non-dynamic buffers are committed by CommitShaderResources
+ m_pPipelineState->GetRootSignature()
+ .CommitRootViews(*m_State.pCommittedResourceCache,
+ GraphCtx,
+ true, // IsCompute
+ m_ContextId,
+ this,
+ true, // CommitViews
+ true, // ProcessDynamicBuffers
+ false, // ProcessNonDynamicBuffers
+ false, // TransitionStates
+ false // ValidateStates
+ );
+ }
+ }
+#ifdef DILIGENT_DEVELOPMENT
+ else
+ {
+ if (m_pPipelineState->ContainsShaderResources())
+ LOG_ERROR_MESSAGE("Pipeline state '", m_pPipelineState->GetDesc().Name, "' contains shader resources, but IDeviceContext::CommitShaderResources() was not called with non-null SRB");
+ }
+#endif
+}
+
void DeviceContextD3D12Impl::DispatchCompute(const DispatchComputeAttribs& Attribs)
{
if (!DvpVerifyDispatchArguments(Attribs))
@@ -2139,6 +2173,46 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTextureState(CommandContext&
#endif
}
+void DeviceContextD3D12Impl::TransitionOrVerifyBLASState(CommandContext& CmdCtx,
+ BottomLevelASD3D12Impl& BLAS,
+ RESOURCE_STATE_TRANSITION_MODE TransitionMode,
+ RESOURCE_STATE RequiredState,
+ const char* OperationName)
+{
+ if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
+ {
+ if (BLAS.IsInKnownState() && !BLAS.CheckState(RequiredState))
+ CmdCtx.TransitionResource(&BLAS, RequiredState);
+ }
+#ifdef DILIGENT_DEVELOPMENT
+ else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY)
+ {
+ DvpVerifyBLASState(BLAS, RequiredState, OperationName);
+ }
+#endif
+}
+
+void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext& CmdCtx,
+ TopLevelASD3D12Impl& TLAS,
+ RESOURCE_STATE_TRANSITION_MODE TransitionMode,
+ RESOURCE_STATE RequiredState,
+ const char* OperationName)
+{
+ // AZ TODO: transit BLAS state too?
+
+ if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
+ {
+ if (TLAS.IsInKnownState() && !TLAS.CheckState(RequiredState))
+ CmdCtx.TransitionResource(&TLAS, RequiredState);
+ }
+#ifdef DILIGENT_DEVELOPMENT
+ else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY)
+ {
+ DvpVerifyTLASState(TLAS, RequiredState, OperationName);
+ }
+#endif
+}
+
void DeviceContextD3D12Impl::TransitionTextureState(ITexture* pTexture, D3D12_RESOURCE_STATES State)
{
VERIFY_EXPR(pTexture != nullptr);
@@ -2202,22 +2276,218 @@ void DeviceContextD3D12Impl::ResolveTextureSubresource(ITexture*
void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
{
+ if (!TDeviceContextBase::BuildBLAS(Attribs, 0))
+ return;
+
+ auto* pBLASD12 = ValidatedCast<BottomLevelASD3D12Impl>(Attribs.pBLAS);
+ auto* pScratchD12 = ValidatedCast<BufferD3D12Impl>(Attribs.pScratchBuffer);
+ auto& BLASDesc = pBLASD12->GetDesc();
+
+ auto& CmdCtx = GetCmdContext();
+ const char* OpName = "Build BottomLevelAS (DeviceContextD3D12Impl::BuildBLAS)";
+ TransitionOrVerifyBLASState(CmdCtx, *pBLASD12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+ TransitionOrVerifyBufferState(CmdCtx, *pScratchD12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC Desc = {};
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& Inputs = Desc.Inputs;
+ std::vector<D3D12_RAYTRACING_GEOMETRY_DESC> Geometries;
+
+ if (Attribs.pTriangleData != nullptr)
+ {
+ Geometries.resize(Attribs.TriangleDataCount);
+
+ for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i)
+ {
+ auto& src = Attribs.pTriangleData[i];
+ Uint32 j = pBLASD12->GetGeometryIndex(src.GeometryName);
+ auto& dst = Geometries.data()[j];
+ auto& tri = dst.Triangles;
+
+ if (j >= Geometries.size())
+ {
+ UNEXPECTED("Failed to find geometry by name");
+ continue;
+ }
+
+ dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
+ dst.Flags = GeometryFlagsToD3D12RTGeometryFlags(src.Flags);
+
+ auto* pVB = ValidatedCast<BufferD3D12Impl>(src.pVertexBuffer);
+ tri.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16);
+ tri.VertexCount = src.VertexCount;
+ tri.VertexBuffer.StartAddress = pVB->GetGPUAddress() + src.VertexOffset;
+ tri.VertexBuffer.StrideInBytes = src.VertexStride;
+
+ if (src.pIndexBuffer)
+ {
+ auto* pIB = ValidatedCast<BufferD3D12Impl>(src.pIndexBuffer);
+ tri.IndexBuffer = pIB->GetGPUAddress() + src.IndexOffset;
+ tri.IndexCount = src.IndexCount;
+ tri.IndexFormat = ValueTypeToIndexType(src.IndexType);
+
+ TransitionOrVerifyBufferState(CmdCtx, *pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ }
+ else
+ {
+ tri.IndexFormat = DXGI_FORMAT_UNKNOWN;
+ tri.IndexBuffer = 0;
+ }
+
+ if (src.pTransformBuffer)
+ {
+ VERIFY_EXPR(BLASDesc.pTriangles[j].AllowsTransforms);
+
+ auto* pTB = ValidatedCast<BufferD3D12Impl>(src.pTransformBuffer);
+ tri.Transform3x4 = pTB->GetGPUAddress() + src.TransformBufferOffset;
+
+ TransitionOrVerifyBufferState(CmdCtx, *pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ }
+ else
+ {
+ VERIFY_EXPR(!BLASDesc.pTriangles[j].AllowsTransforms);
+ tri.Transform3x4 = 0;
+ }
+ }
+ }
+ else if (Attribs.pBoxData != nullptr)
+ {
+ Geometries.resize(Attribs.BoxDataCount);
+
+ for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i)
+ {
+ auto& src = Attribs.pBoxData[i];
+ Uint32 j = pBLASD12->GetGeometryIndex(src.GeometryName);
+ auto& dst = Geometries.data()[j];
+ auto& box = dst.AABBs;
+
+ if (j >= Geometries.size())
+ {
+ UNEXPECTED("Failed to find geometry by name");
+ continue;
+ }
+
+ dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
+ dst.Flags = GeometryFlagsToD3D12RTGeometryFlags(src.Flags);
+
+ auto* pBB = ValidatedCast<BufferD3D12Impl>(src.pBoxBuffer);
+ box.AABBCount = src.BoxCount;
+ box.AABBs.StartAddress = pBB->GetGPUAddress() + src.BoxOffset;
+ box.AABBs.StrideInBytes = src.BoxStride;
+
+ TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ }
+ }
+
+ Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
+ Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ Inputs.NumDescs = static_cast<UINT>(Geometries.size());
+ Inputs.pGeometryDescs = Geometries.data();
+
+ Desc.DestAccelerationStructureData = pBLASD12->GetGPUAddress();
+ Desc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
+ Desc.SourceAccelerationStructureData = 0;
+
+ CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr);
+ ++m_State.NumCommands;
}
void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs)
{
+ if (!TDeviceContextBase::BuildTLAS(Attribs, 0))
+ return;
+
+ static_assert(TLAS_INSTANCE_DATA_SIZE == sizeof(D3D12_RAYTRACING_INSTANCE_DESC), "Value in TLAS_INSTANCE_DATA_SIZE doesn't match the actual instance description size");
+
+ auto* pTLASD12 = ValidatedCast<TopLevelASD3D12Impl>(Attribs.pTLAS);
+ auto* pScratchD12 = ValidatedCast<BufferD3D12Impl>(Attribs.pScratchBuffer);
+ auto* pInstancesD12 = ValidatedCast<BufferD3D12Impl>(Attribs.pInstanceBuffer);
+ //auto& TLASDesc = pTLASD12->GetDesc();
+
+ auto& CmdCtx = GetCmdContext();
+ const char* OpName = "Build TopLevelAS (DeviceContextD3D12Impl::BuildTLAS)";
+ TransitionOrVerifyTLASState(CmdCtx, *pTLASD12, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+ TransitionOrVerifyBufferState(CmdCtx, *pScratchD12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+
+ pTLASD12->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.HitShadersPerInstance);
+
+ // copy instance data into instance buffer
+ {
+ size_t Size = Attribs.InstanceCount * sizeof(D3D12_RAYTRACING_INSTANCE_DESC);
+ auto TmpSpace = m_DynamicHeap.Allocate(Size, 16, m_ContextFrameNumber);
+ void* pMappedInstances = TmpSpace.CPUAddress;
+
+ for (Uint32 i = 0; i < Attribs.InstanceCount; ++i)
+ {
+ auto& src = Attribs.pInstances[i];
+ auto& dst = static_cast<D3D12_RAYTRACING_INSTANCE_DESC*>(pMappedInstances)[i];
+ auto* pBLASD12 = ValidatedCast<BottomLevelASD3D12Impl>(src.pBLAS);
+
+ static_assert(sizeof(dst.Transform) == sizeof(src.Transform), "size mismatch");
+ std::memcpy(&dst.Transform, src.Transform, sizeof(dst.Transform));
+
+ dst.InstanceID = src.CustomId;
+ dst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(src.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize
+ dst.InstanceMask = src.Mask;
+ dst.Flags = InstanceFlagsToD3D12RTInstanceFlags(src.Flags);
+ dst.AccelerationStructure = pBLASD12->GetGPUAddress();
+
+ TransitionOrVerifyBLASState(CmdCtx, *pBLASD12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ }
+ UpdateBufferRegion(pInstancesD12, TmpSpace, Attribs.InstanceBufferOffset, Size, Attribs.InstanceBufferTransitionMode);
+ }
+ TransitionOrVerifyBufferState(CmdCtx, *pInstancesD12, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC Desc = {};
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& Inputs = Desc.Inputs;
+
+ Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
+ Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ Inputs.NumDescs = Attribs.InstanceCount;
+ Inputs.InstanceDescs = pInstancesD12->GetGPUAddress();
+
+ Desc.DestAccelerationStructureData = pTLASD12->GetGPUAddress();
+ Desc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
+ Desc.SourceAccelerationStructureData = 0;
+
+ CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr);
+ ++m_State.NumCommands;
}
void DeviceContextD3D12Impl::CopyBLAS(const CopyBLASAttribs& Attribs)
{
+ if (!TDeviceContextBase::CopyBLAS(Attribs, 0))
+ return;
+
+ // AZ TODO
}
void DeviceContextD3D12Impl::CopyTLAS(const CopyTLASAttribs& Attribs)
{
+ if (!TDeviceContextBase::CopyTLAS(Attribs, 0))
+ return;
+
+ // AZ TODO
}
void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs)
{
+ if (!TDeviceContextBase::TraceRays(Attribs, 0))
+ return;
+
+ D3D12_DISPATCH_RAYS_DESC Desc = {};
+
+ Desc.Width = Attribs.DimensionX;
+ Desc.Height = Attribs.DimensionY;
+ Desc.Depth = Attribs.DimensionZ;
+
+ auto* pSBTD12 = ValidatedCast<ShaderBindingTableD3D12Impl>(Attribs.pSBT);
+ pSBTD12->GetD3D12AddressRangeAndStride(this, Attribs.TransitionMode, Desc.RayGenerationShaderRecord, Desc.MissShaderTable, Desc.HitGroupTable, Desc.CallableShaderTable);
+
+ auto& CmdCtx = GetCmdContext().AsGraphicsContext4();
+ PrepareForDispatchRays(CmdCtx);
+
+ CmdCtx.DispatchRays(Desc);
+ ++m_State.NumCommands;
}
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp
index be5c68eb..0da4470b 100644
--- a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp
@@ -113,7 +113,7 @@ GenerateMipsHelper::GenerateMipsHelper(ID3D12Device* pd3d12Device)
void GenerateMipsHelper::GenerateMips(ID3D12Device* pd3d12Device, TextureViewD3D12Impl* pTexView, CommandContext& Ctx) const
{
auto& ComputeCtx = Ctx.AsComputeContext();
- ComputeCtx.SetRootSignature(m_pGenerateMipsRS);
+ ComputeCtx.SetComputeRootSignature(m_pGenerateMipsRS);
auto* pTexD3D12 = pTexView->GetTexture<TextureD3D12Impl>();
const auto& TexDesc = pTexD3D12->GetDesc();
const auto& ViewDesc = pTexView->GetDesc();
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
index efae7b37..9cc7faa5 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
@@ -877,9 +877,9 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou
if (Attrib.CommitResources)
{
if (m_Desc.IsAnyGraphicsPipeline())
- CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature());
+ CmdCtx.AsGraphicsContext().SetGraphicsRootSignature(GetD3D12RootSignature());
else
- CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature());
+ CmdCtx.AsComputeContext().SetComputeRootSignature(GetD3D12RootSignature());
}
return nullptr;
}
@@ -906,9 +906,9 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou
if (Attrib.CommitResources)
{
if (m_Desc.IsAnyGraphicsPipeline())
- CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature());
+ CmdCtx.AsGraphicsContext().SetGraphicsRootSignature(GetD3D12RootSignature());
else
- CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature());
+ CmdCtx.AsComputeContext().SetComputeRootSignature(GetD3D12RootSignature());
if (Attrib.TransitionResources)
{
diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
index 9feabb6a..f8f545e7 100644
--- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
@@ -40,6 +40,9 @@
#include "QueryD3D12Impl.hpp"
#include "RenderPassD3D12Impl.hpp"
#include "FramebufferD3D12Impl.hpp"
+#include "BottomLevelASD3D12Impl.hpp"
+#include "TopLevelASD3D12Impl.hpp"
+#include "ShaderBindingTableD3D12Impl.hpp"
#include "EngineMemory.h"
namespace Diligent
@@ -137,9 +140,9 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
sizeof(QueryD3D12Impl),
sizeof(RenderPassD3D12Impl),
sizeof(FramebufferD3D12Impl),
- 0,
- 0,
- 0
+ sizeof(BottomLevelASD3D12Impl),
+ sizeof(TopLevelASD3D12Impl),
+ sizeof(ShaderBindingTableD3D12Impl)
}
},
m_pd3d12Device {pd3d12Device},
@@ -725,19 +728,37 @@ void RenderDeviceD3D12Impl::CreateFramebuffer(const FramebufferDesc& Desc, IFram
void RenderDeviceD3D12Impl::CreateBLAS(const BottomLevelASDesc& Desc,
IBottomLevelAS** ppBLAS)
{
- // AZ TODO
+ CreateDeviceObject("BottomLevelAS", Desc, ppBLAS,
+ [&]() //
+ {
+ BottomLevelASD3D12Impl* pBottomLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASD3D12Impl instance", BottomLevelASD3D12Impl)(this, Desc));
+ pBottomLevelASVk->QueryInterface(IID_BottomLevelAS, reinterpret_cast<IObject**>(ppBLAS));
+ OnCreateDeviceObject(pBottomLevelASVk);
+ });
}
void RenderDeviceD3D12Impl::CreateTLAS(const TopLevelASDesc& Desc,
ITopLevelAS** ppTLAS)
{
- // AZ TODO
+ CreateDeviceObject("TopLevelAS", Desc, ppTLAS,
+ [&]() //
+ {
+ TopLevelASD3D12Impl* pTopLevelASVk(NEW_RC_OBJ(m_TLASAllocator, "TopLevelASD3D12Impl instance", TopLevelASD3D12Impl)(this, Desc));
+ pTopLevelASVk->QueryInterface(IID_TopLevelAS, reinterpret_cast<IObject**>(ppTLAS));
+ OnCreateDeviceObject(pTopLevelASVk);
+ });
}
void RenderDeviceD3D12Impl::CreateSBT(const ShaderBindingTableDesc& Desc,
IShaderBindingTable** ppSBT)
{
- // AZ TODO
+ CreateDeviceObject("ShaderBindingTable", Desc, ppSBT,
+ [&]() //
+ {
+ ShaderBindingTableD3D12Impl* pSBTVk(NEW_RC_OBJ(m_SBTAllocator, "ShaderBindingTableD3D12Impl instance", ShaderBindingTableD3D12Impl)(this, Desc));
+ pSBTVk->QueryInterface(IID_ShaderBindingTable, reinterpret_cast<IObject**>(ppSBT));
+ OnCreateDeviceObject(pSBTVk);
+ });
}
DescriptorHeapAllocation RenderDeviceD3D12Impl::AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count /*= 1*/)
diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
index 35274af3..d0db2201 100644
--- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
@@ -33,6 +33,7 @@
#include "CommandContext.hpp"
#include "RenderDeviceD3D12Impl.hpp"
#include "TextureD3D12Impl.hpp"
+#include "TopLevelASD3D12Impl.hpp"
#include "D3D12TypeConversions.hpp"
#include "HashUtils.hpp"
@@ -702,6 +703,10 @@ __forceinline void TransitionResource(CommandContext& Ctx,
case CachedResourceType::AccelStruct:
{
+ VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type");
+ auto* pTLASD3D12 = Res.pObject.RawPtr<TopLevelASD3D12Impl>();
+ if (pTLASD3D12->IsInKnownState() && !pTLASD3D12->CheckState(RESOURCE_STATE_RAY_TRACING))
+ Ctx.TransitionResource(pTLASD3D12, RESOURCE_STATE_RAY_TRACING);
}
break;
@@ -806,6 +811,16 @@ void RootSignature::DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resou
case CachedResourceType::AccelStruct:
{
+ VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type");
+ const auto* pTLASD3D12 = Res.pObject.RawPtr<const TopLevelASD3D12Impl>();
+ if (pTLASD3D12->IsInKnownState() && !pTLASD3D12->CheckState(RESOURCE_STATE_RAY_TRACING))
+ {
+ LOG_ERROR_MESSAGE("TLAS '", pTLASD3D12->GetDesc().Name, "' must be in RESOURCE_STATE_RAY_TRACING state. Actual state: ",
+ GetResourceStateString(pTLASD3D12->GetState()),
+ ". Call IDeviceContext::TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION "
+ "when calling IDeviceContext::CommitShaderResources() or explicitly transition the TLAS state "
+ "with IDeviceContext::TransitionResourceStates().");
+ }
}
break;
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp
new file mode 100644
index 00000000..3727913f
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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 "ShaderBindingTableD3D12Impl.hpp"
+#include "RenderDeviceD3D12Impl.hpp"
+#include "DeviceContextD3D12Impl.hpp"
+#include "D3D12TypeConversions.hpp"
+#include "GraphicsAccessories.hpp"
+#include "DXGITypeConversions.hpp"
+#include "EngineMemory.h"
+#include "StringTools.hpp"
+
+namespace Diligent
+{
+
+ShaderBindingTableD3D12Impl::ShaderBindingTableD3D12Impl(IReferenceCounters* pRefCounters,
+ class RenderDeviceD3D12Impl* pDeviceD3D12,
+ const ShaderBindingTableDesc& Desc,
+ bool bIsDeviceInternal) :
+ TShaderBindingTableBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal}
+{
+ ValidateDesc(Desc);
+
+ m_ShaderRecordStride = m_Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
+}
+
+ShaderBindingTableD3D12Impl::~ShaderBindingTableD3D12Impl()
+{
+}
+
+IMPLEMENT_QUERY_INTERFACE(ShaderBindingTableD3D12Impl, IID_ShaderBindingTableD3D12, TShaderBindingTableBase)
+
+void ShaderBindingTableD3D12Impl::ValidateDesc(const ShaderBindingTableDesc& Desc) const
+{
+ if (Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES > D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE)
+ {
+ LOG_ERROR_AND_THROW("Description of Shader binding table '", (Desc.Name ? Desc.Name : ""),
+ "' is invalid: ShaderRecordSize is too big, max size is: ", D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE - D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
+ }
+}
+
+void ShaderBindingTableD3D12Impl::Verify() const
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableD3D12Impl::Reset(const ShaderBindingTableDesc& Desc)
+{
+ m_RayGenShaderRecord.clear();
+ m_MissShadersRecord.clear();
+ m_CallableShadersRecord.clear();
+ m_HitGroupsRecord.clear();
+ m_Changed = true;
+
+ try
+ {
+ ValidateShaderBindingTableDesc(Desc);
+ ValidateDesc(Desc);
+ }
+ catch (const std::runtime_error&)
+ {
+ // AZ TODO
+ return;
+ }
+
+ m_Desc = Desc;
+ m_ShaderRecordStride = m_Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
+}
+
+void ShaderBindingTableD3D12Impl::ResetHitGroups(Uint32 HitShadersPerInstance)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableD3D12Impl::BindAll(const BindAllAttribs& Attribs)
+{
+ // AZ TODO
+}
+
+void ShaderBindingTableD3D12Impl::GetD3D12AddressRangeAndStride(IDeviceContextD3D12* pContext,
+ RESOURCE_STATE_TRANSITION_MODE TransitionMode,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE& RaygenShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& MissShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& HitShaderBindingTable,
+ D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& CallableShaderBindingTable)
+{
+ const auto AlignToLarger = [](size_t offset) -> Uint32 {
+ return Align(static_cast<Uint32>(offset), static_cast<Uint32>(D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT));
+ };
+
+ const Uint32 RayGenOffset = 0;
+ const Uint32 MissShaderOffset = AlignToLarger(m_RayGenShaderRecord.size());
+ const Uint32 HitGroupOffset = AlignToLarger(MissShaderOffset + m_MissShadersRecord.size());
+ const Uint32 CallableShadersOffset = AlignToLarger(HitGroupOffset + m_HitGroupsRecord.size());
+ const Uint32 BufSize = AlignToLarger(CallableShadersOffset + m_CallableShadersRecord.size());
+
+ // recreate buffer
+ if (m_pBuffer == nullptr || m_pBuffer->GetDesc().uiSizeInBytes < BufSize)
+ {
+ m_pBuffer = nullptr;
+
+ String BuffName = String{GetDesc().Name} + " - internal buffer";
+ BufferDesc BuffDesc;
+ BuffDesc.Name = BuffName.c_str();
+ BuffDesc.Usage = USAGE_DEFAULT;
+ BuffDesc.BindFlags = BIND_RAY_TRACING;
+ BuffDesc.uiSizeInBytes = BufSize;
+
+ GetDevice()->CreateBuffer(BuffDesc, nullptr, &m_pBuffer);
+ VERIFY_EXPR(m_pBuffer != nullptr);
+ }
+
+ if (m_pBuffer == nullptr)
+ return; // something goes wrong
+
+ const D3D12_GPU_VIRTUAL_ADDRESS BuffHandle = m_pBuffer.RawPtr<BufferD3D12Impl>()->GetGPUAddress(0, ValidatedCast<DeviceContextD3D12Impl>(pContext));
+
+ if (m_RayGenShaderRecord.size())
+ {
+ RaygenShaderBindingTable.StartAddress = BuffHandle + RayGenOffset;
+ RaygenShaderBindingTable.SizeInBytes = m_RayGenShaderRecord.size();
+ }
+
+ if (m_MissShadersRecord.size())
+ {
+ MissShaderBindingTable.StartAddress = BuffHandle + MissShaderOffset;
+ MissShaderBindingTable.SizeInBytes = m_MissShadersRecord.size();
+ MissShaderBindingTable.StrideInBytes = m_ShaderRecordStride;
+ }
+
+ if (m_HitGroupsRecord.size())
+ {
+ HitShaderBindingTable.StartAddress = BuffHandle + HitGroupOffset;
+ HitShaderBindingTable.SizeInBytes = m_HitGroupsRecord.size();
+ HitShaderBindingTable.StrideInBytes = m_ShaderRecordStride;
+ }
+
+ if (m_CallableShadersRecord.size())
+ {
+ CallableShaderBindingTable.StartAddress = BuffHandle + CallableShadersOffset;
+ CallableShaderBindingTable.SizeInBytes = m_CallableShadersRecord.size();
+ CallableShaderBindingTable.StrideInBytes = m_ShaderRecordStride;
+ }
+
+ if (!m_Changed)
+ return;
+
+ m_Changed = false;
+
+ // update buffer data
+ if (m_RayGenShaderRecord.size())
+ pContext->UpdateBuffer(m_pBuffer, RayGenOffset, static_cast<Uint32>(m_RayGenShaderRecord.size()), m_RayGenShaderRecord.data(), TransitionMode);
+
+ if (m_MissShadersRecord.size())
+ pContext->UpdateBuffer(m_pBuffer, MissShaderOffset, static_cast<Uint32>(m_MissShadersRecord.size()), m_MissShadersRecord.data(), TransitionMode);
+
+ if (m_HitGroupsRecord.size())
+ pContext->UpdateBuffer(m_pBuffer, HitGroupOffset, static_cast<Uint32>(m_HitGroupsRecord.size()), m_HitGroupsRecord.data(), TransitionMode);
+
+ if (m_CallableShadersRecord.size())
+ pContext->UpdateBuffer(m_pBuffer, CallableShadersOffset, static_cast<Uint32>(m_CallableShadersRecord.size()), m_CallableShadersRecord.data(), TransitionMode);
+
+ if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
+ {
+ StateTransitionDesc Barrier;
+ Barrier.pResource = m_pBuffer;
+ Barrier.NewState = RESOURCE_STATE_RAY_TRACING;
+ Barrier.UpdateResourceState = true;
+ pContext->TransitionResourceStates(1, &Barrier);
+ }
+ else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY)
+ {
+ VERIFY_EXPR(m_pBuffer->GetState() == RESOURCE_STATE_RAY_TRACING);
+ }
+}
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
index b4bb1f72..6dbdb97f 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
@@ -40,6 +40,7 @@
#include "ShaderResourceVariableBase.hpp"
#include "ShaderVariableD3DBase.hpp"
#include "LinearAllocator.hpp"
+#include "TopLevelASD3D12.h"
namespace Diligent
{
@@ -622,6 +623,35 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheAccelStruct(IDeviceObject*
Uint32 ArrayIndex,
D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const
{
+ VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point");
+ VERIFY_EXPR(ArrayIndex < Attribs.BindCount);
+
+ RefCntAutoPtr<ITopLevelASD3D12> pTLASD3D12(pTLAS, IID_TopLevelASD3D12);
+ if (pTLASD3D12)
+ {
+ if (GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr)
+ {
+ // Do not update resource if one is already bound unless it is dynamic. This may be
+ // dangerous as CopyDescriptorsSimple() may interfere with GPU reading the same descriptor.
+ return;
+ }
+
+ DstRes.Type = GetResType();
+ DstRes.CPUDescriptorHandle = pTLASD3D12->GetCPUDescriptorHandle();
+ VERIFY(DstRes.CPUDescriptorHandle.ptr != 0, "No relevant D3D12 resource");
+
+ if (ShdrVisibleHeapCPUDescriptorHandle.ptr != 0)
+ {
+ // Dynamic resources are assigned descriptor in the GPU-visible heap at every draw call, and
+ // the descriptor is copied by the RootSignature when resources are committed
+ VERIFY(DstRes.pObject == nullptr, "Static and mutable resource descriptors must be copied only once");
+
+ ID3D12Device* pd3d12Device = ParentResLayout.m_pd3d12Device;
+ pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, DstRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+ }
+
+ DstRes.pObject = std::move(pTLASD3D12);
+ }
}
const ShaderResourceLayoutD3D12::D3D12Resource& ShaderResourceLayoutD3D12::GetAssignedSampler(const D3D12Resource& TexSrv) const
diff --git a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp
new file mode 100644
index 00000000..5f411640
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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 "TopLevelASD3D12Impl.hpp"
+#include "RenderDeviceD3D12Impl.hpp"
+#include "DeviceContextD3D12Impl.hpp"
+#include "D3D12TypeConversions.hpp"
+#include "GraphicsAccessories.hpp"
+#include "DXGITypeConversions.hpp"
+#include "EngineMemory.h"
+#include "StringTools.hpp"
+
+namespace Diligent
+{
+
+TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounters,
+ class RenderDeviceD3D12Impl* pDeviceD3D12,
+ const TopLevelASDesc& Desc,
+ bool bIsDeviceInternal) :
+ TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal}
+{
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO TopLevelPrebuildInfo = {};
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS TopLevelInputs = {};
+
+ TopLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
+ TopLevelInputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
+ TopLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ TopLevelInputs.NumDescs = Desc.MaxInstanceCount;
+
+ VERIFY_EXPR(Desc.MaxInstanceCount <= D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE);
+
+ auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5();
+
+ pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&TopLevelInputs, &TopLevelPrebuildInfo);
+ if (TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0)
+ LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info");
+
+ D3D12_HEAP_PROPERTIES HeapProps;
+ HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ HeapProps.CreationNodeMask = 1;
+ HeapProps.VisibleNodeMask = 1;
+
+ D3D12_RESOURCE_DESC ASDesc = {};
+ ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ ASDesc.Alignment = 0;
+ ASDesc.Width = TopLevelPrebuildInfo.ResultDataMaxSizeInBytes;
+ ASDesc.Height = 1;
+ ASDesc.DepthOrArraySize = 1;
+ ASDesc.MipLevels = 1;
+ ASDesc.Format = DXGI_FORMAT_UNKNOWN;
+ ASDesc.SampleDesc.Count = 1;
+ ASDesc.SampleDesc.Quality = 0;
+ ASDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ ASDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
+
+ auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE,
+ &ASDesc, D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE, nullptr,
+ __uuidof(m_pd3d12Resource),
+ reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)));
+ if (FAILED(hr))
+ LOG_ERROR_AND_THROW("Failed to create D3D12 Top-level acceleration structure");
+
+ if (*m_Desc.Name != 0)
+ m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str());
+
+ m_ScratchSize.Build = static_cast<Uint32>(TopLevelPrebuildInfo.ScratchDataSizeInBytes);
+ m_ScratchSize.Update = static_cast<Uint32>(TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes);
+
+ m_DescriptorHandle = pDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+
+ D3D12_SHADER_RESOURCE_VIEW_DESC SRVDesc;
+ SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
+ SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ SRVDesc.Format = DXGI_FORMAT_UNKNOWN;
+ SRVDesc.RaytracingAccelerationStructure.Location = GetGPUAddress();
+ pd3d12Device->CreateShaderResourceView(nullptr, &SRVDesc, m_DescriptorHandle.GetCpuHandle());
+}
+
+TopLevelASD3D12Impl::~TopLevelASD3D12Impl()
+{
+ // D3D12 object can only be destroyed when it is no longer used by the GPU
+ auto* pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice());
+ pDeviceD3D12Impl->SafeReleaseDeviceObject(std::move(m_pd3d12Resource), m_Desc.CommandQueueMask);
+}
+
+IMPLEMENT_QUERY_INTERFACE(TopLevelASD3D12Impl, IID_TopLevelASD3D12, TTopLevelASBase)
+
+} // namespace Diligent