summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-11-05 00:43:05 +0000
committerazhirnov <zh1dron@gmail.com>2020-11-05 00:53:36 +0000
commit5e81b867be771dc7f2add0d7b403af4aeaa744db (patch)
tree0f1f3835149f8887d80d558203956fcdbb233f60 /Graphics/GraphicsEngineD3D12
parentfixed compilation (diff)
downloadDiligentCore-5e81b867be771dc7f2add0d7b403af4aeaa744db.tar.gz
DiligentCore-5e81b867be771dc7f2add0d7b403af4aeaa744db.zip
Added AS copy with compacting.
Added UB & SB size checks for Vulkan. Some improvements for ray tracing & tests.
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/CommandContext.hpp5
-rw-r--r--Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp3
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp3
-rw-r--r--Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp10
-rw-r--r--Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h10
-rw-r--r--Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp126
-rw-r--r--Graphics/GraphicsEngineD3D12/src/CommandContext.cpp26
-rw-r--r--Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp46
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp204
-rw-r--r--Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp97
-rw-r--r--Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp44
14 files changed, 336 insertions, 252 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp
index 511f1a03..1d1f0082 100644
--- a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp
@@ -383,11 +383,10 @@ public:
}
void EmitRaytracingAccelerationStructurePostbuildInfo(const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC& Desc,
- UINT NumSourceAccelerationStructures,
- const D3D12_GPU_VIRTUAL_ADDRESS* pSourceAccelerationStructureData)
+ D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureAddress)
{
FlushResourceBarriers();
- static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->EmitRaytracingAccelerationStructurePostbuildInfo(&Desc, NumSourceAccelerationStructures, pSourceAccelerationStructureData);
+ static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->EmitRaytracingAccelerationStructurePostbuildInfo(&Desc, 1, &SourceAccelerationStructureAddress);
}
void CopyRaytracingAccelerationStructure(D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData,
diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp
index 389b76a1..8b1818f2 100644
--- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp
@@ -83,4 +83,7 @@ DXGI_FORMAT ValueTypeToIndexType(VALUE_TYPE Type);
D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags);
D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags);
+D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS BuildASFlagsToD3D12ASBuildFlags(RAYTRACING_BUILD_AS_FLAGS Flags);
+D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE CopyASModeToD3D12ASCopyMode(COPY_AS_MODE Mode);
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
index 3ac65274..a112b90e 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
@@ -273,6 +273,12 @@ public:
/// Implementation of IDeviceContext::CopyTLAS() in Direct3D12 backend.
virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::WriteBLASCompactedSize() in Direct3D12 backend.
+ virtual void DILIGENT_CALL_TYPE WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::WriteTLASCompactedSize() in Direct3D12 backend.
+ virtual void DILIGENT_CALL_TYPE WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) override final;
+
/// Implementation of IDeviceContext::TraceRays() in Direct3D12 backend.
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
index 636175d5..619368fd 100644
--- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
@@ -180,6 +180,9 @@ public:
static Uint32 GetShaderGroupHandleSize() { return D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; }
static Uint32 GetMaxShaderRecordStride() { return D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE; }
+ static Uint32 GetShaderGroupBaseAlignment() { return D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT; }
+
+ static Uint32 GetMaxDrawMeshTasksCount() { return 64000; }
private:
template <typename PSOCreateInfoType>
diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp
index daf84d14..537f240a 100644
--- a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp
@@ -57,16 +57,6 @@ public:
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:
- RefCntAutoPtr<IBuffer> m_pBuffer;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h
index aa50251a..18ebd984 100644
--- a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h
+++ b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h
@@ -50,14 +50,6 @@ static const INTERFACE_ID IID_ShaderBindingTableD3D12 =
/// 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
@@ -65,8 +57,6 @@ DILIGENT_END_INTERFACE
#if DILIGENT_C_INTERFACE
-# define IShaderBindingTableD3D12_GetD3D12AddressRangeAndStride(This, ...) CALL_IFACE_METHOD(ShaderBindingTableD3D12, GetD3D12AddressRangeAndStride, This, __VA_ARGS__)
-
#endif
DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp
index 31f0e6a3..1fc9f876 100644
--- a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp
@@ -44,67 +44,84 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef
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;
+ auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5();
+ UINT64 ResultDataMaxSizeInBytes = 0;
- if (m_Desc.pTriangles != nullptr)
+ if (m_Desc.CompactedSize)
{
- 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);
+ ResultDataMaxSizeInBytes = m_Desc.CompactedSize;
}
- else if (m_Desc.pBoxes != nullptr)
+ else
{
- 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;
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12BottomLevelPrebuildInfo = {};
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12BottomLevelInputs = {};
+ std::vector<D3D12_RAYTRACING_GEOMETRY_DESC> Geometries;
- MaxBoxCount += src.MaxBoxCount;
+ 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.IndexType == VT_UNDEFINED ? 0 : src.MaxPrimitiveCount * 3;
+ dst.Triangles.IndexFormat = ValueTypeToIndexType(src.IndexType);
+ dst.Triangles.IndexBuffer = 0;
+ dst.Triangles.Transform3x4 = 0;
+
+ MaxPrimitiveCount += src.MaxPrimitiveCount;
+ }
+ 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);
+ }
+ else
+ {
+ UNEXPECTED("Either pTriangles or pBoxes must not be null");
}
- 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);
+ 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());
+ d3d12BottomLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
+ d3d12BottomLevelInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(m_Desc.Flags);
+ d3d12BottomLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ d3d12BottomLevelInputs.pGeometryDescs = Geometries.data();
+ d3d12BottomLevelInputs.NumDescs = static_cast<UINT>(Geometries.size());
- auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5();
+ pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12BottomLevelInputs, &d3d12BottomLevelPrebuildInfo);
+ if (d3d12BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0)
+ LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info");
- pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&BottomLevelInputs, &BottomLevelPrebuildInfo);
- if (BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0)
- LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info");
+ ResultDataMaxSizeInBytes = d3d12BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes;
+
+ m_ScratchSize.Build = static_cast<Uint32>(d3d12BottomLevelPrebuildInfo.ScratchDataSizeInBytes);
+ m_ScratchSize.Update = static_cast<Uint32>(d3d12BottomLevelPrebuildInfo.UpdateScratchDataSizeInBytes);
+ }
D3D12_HEAP_PROPERTIES HeapProps;
HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
@@ -116,7 +133,7 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef
D3D12_RESOURCE_DESC ASDesc = {};
ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
ASDesc.Alignment = 0;
- ASDesc.Width = BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes;
+ ASDesc.Width = ResultDataMaxSizeInBytes;
ASDesc.Height = 1;
ASDesc.DepthOrArraySize = 1;
ASDesc.MipLevels = 1;
@@ -136,8 +153,9 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef
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);
+ VERIFY_EXPR(GetGPUAddress() % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0);
+
+ SetState(RESOURCE_STATE_BUILD_AS_READ);
}
BottomLevelASD3D12Impl::~BottomLevelASD3D12Impl()
diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
index 4285e11a..1e301bb2 100644
--- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
@@ -224,6 +224,12 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
"RESOURCE_STATE_UNKNOWN to make the engine use current resource state");
}
+ // RESOURCE_STATE_UNORDERED_ACCESS and RESOURCE_STATE_BUILD_AS_WRITE converted to D3D12_RESOURCE_STATE_UNORDERED_ACCESS.
+ // UAV barrier must be inserted between D3D12_RESOURCE_STATE_UNORDERED_ACCESS resource usage.
+ bool RequireUAVBarrier =
+ (OldState == RESOURCE_STATE_UNORDERED_ACCESS || OldState == RESOURCE_STATE_BUILD_AS_WRITE) &&
+ (Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS || Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE);
+
// Check if required state is already set
if ((OldState & Barrier.NewState) != Barrier.NewState)
{
@@ -306,26 +312,34 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
}
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);
}
+
+ // acceleration structure is always in D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE but requires UAV barrier instead of state transition.
+ RequireUAVBarrier |= (OldState == RESOURCE_STATE_BUILD_AS_WRITE);
}
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);
}
+
+ // acceleration structure is always in D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE but requires UAV barrier instead of state transition.
+ RequireUAVBarrier |= (OldState == RESOURCE_STATE_BUILD_AS_WRITE);
+
+#ifdef DILIGENT_DEVELOPMENT
+ if (Barrier.NewState & RESOURCE_STATE_RAY_TRACING)
+ {
+ pTLASD3D12Impl->ValidateContent();
+ }
+#endif
}
}
- if ((OldState == RESOURCE_STATE_UNORDERED_ACCESS || OldState == RESOURCE_STATE_BUILD_AS_WRITE) &&
- (Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS || Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE))
+ if (RequireUAVBarrier)
{
DEV_CHECK_ERR(Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE, "UAV barriers must not be split");
InsertUAVBarrier(pd3d12Resource);
diff --git a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp
index 74e65559..63d19ce4 100644
--- a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp
@@ -94,6 +94,8 @@ Uint64 CommandQueueD3D12Impl::WaitForIdle()
Uint64 CommandQueueD3D12Impl::GetCompletedFenceValue()
{
auto CompletedFenceValue = m_d3d12Fence->GetCompletedValue();
+ VERIFY(CompletedFenceValue != UINT64_MAX, "If the device has been removed, the return value will be UINT64_MAX");
+
if (CompletedFenceValue > m_LastCompletedFenceValue)
m_LastCompletedFenceValue = CompletedFenceValue;
return m_LastCompletedFenceValue;
diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
index a6d6963e..1f1f621c 100644
--- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
@@ -367,7 +367,7 @@ public:
StateFlagBitPosToD3D12ResourceState()
{
static_assert((1 << MaxFlagBitPos) == RESOURCE_STATE_MAX_BIT, "This function must be updated to handle new resource state flag");
- for (Uint32 bit = 0; bit <= MaxFlagBitPos; ++bit)
+ for (Uint32 bit = 0; bit < FlagBitPosToResStateMap.size(); ++bit)
{
FlagBitPosToResStateMap[bit] = ResourceStateFlagToD3D12ResourceState(static_cast<RESOURCE_STATE>(1 << bit));
}
@@ -436,7 +436,7 @@ class D3D12StateFlagBitPosToResourceState
public:
D3D12StateFlagBitPosToResourceState()
{
- for (Uint32 bit = 0; bit <= MaxFlagBitPos; ++bit)
+ for (Uint32 bit = 0; bit < FlagBitPosToResStateMap.size(); ++bit)
{
FlagBitPosToResStateMap[bit] = D3D12ResourceStateToResourceStateFlags(static_cast<D3D12_RESOURCE_STATES>(1 << bit));
}
@@ -653,4 +653,46 @@ D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_I
return Result;
}
+D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS BuildASFlagsToD3D12ASBuildFlags(RAYTRACING_BUILD_AS_FLAGS Flags)
+{
+ static_assert(RAYTRACING_BUILD_AS_FLAGS_LAST == RAYTRACING_BUILD_AS_LOW_MEMORY,
+ "Please update the switch below to handle the new acceleration structure build flag");
+
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS Result = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
+ while (Flags != RAYTRACING_BUILD_AS_NONE)
+ {
+ auto FlagBit = static_cast<RAYTRACING_BUILD_AS_FLAGS>(1 << PlatformMisc::GetLSB(Uint32{Flags}));
+ switch (FlagBit)
+ {
+ // clang-format off
+ case RAYTRACING_BUILD_AS_ALLOW_UPDATE: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE; break;
+ case RAYTRACING_BUILD_AS_ALLOW_COMPACTION: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION; break;
+ case RAYTRACING_BUILD_AS_PREFER_FAST_TRACE: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE; break;
+ case RAYTRACING_BUILD_AS_PREFER_FAST_BUILD: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD; break;
+ case RAYTRACING_BUILD_AS_LOW_MEMORY: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY; break;
+ // clang-format on
+ default: UNEXPECTED("unknown build AS flag");
+ }
+ Flags &= ~FlagBit;
+ }
+ return Result;
+}
+
+D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE CopyASModeToD3D12ASCopyMode(COPY_AS_MODE Mode)
+{
+ static_assert(COPY_AS_MODE_LAST == COPY_AS_MODE_COMPACT,
+ "Please update the switch below to handle the new copy AS mode");
+
+ switch (Mode)
+ {
+ // clang-format off
+ case COPY_AS_MODE_CLONE: return D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE;
+ case COPY_AS_MODE_COMPACT: return D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT;
+ // clang-format on
+ default:
+ UNEXPECTED("unknown AS copy mode");
+ return static_cast<D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE>(~0u);
+ }
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 0adcaa59..41de3a47 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -2143,7 +2143,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyBufferState(CommandContext&
{
if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
{
- if (Buffer.IsInKnownState() && !Buffer.CheckState(RequiredState))
+ if (Buffer.IsInKnownState())
CmdCtx.TransitionResource(&Buffer, RequiredState);
}
#ifdef DILIGENT_DEVELOPMENT
@@ -2162,7 +2162,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTextureState(CommandContext&
{
if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
{
- if (Texture.IsInKnownState() && !Texture.CheckState(RequiredState))
+ if (Texture.IsInKnownState())
CmdCtx.TransitionResource(&Texture, RequiredState);
}
#ifdef DILIGENT_DEVELOPMENT
@@ -2181,7 +2181,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyBLASState(CommandContext&
{
if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
{
- if (BLAS.IsInKnownState() && !BLAS.CheckState(RequiredState))
+ if (BLAS.IsInKnownState())
CmdCtx.TransitionResource(&BLAS, RequiredState);
}
#ifdef DILIGENT_DEVELOPMENT
@@ -2200,7 +2200,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext&
{
if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
{
- if (TLAS.IsInKnownState() && !TLAS.CheckState(RequiredState))
+ if (TLAS.IsInKnownState())
CmdCtx.TransitionResource(&TLAS, RequiredState);
}
#ifdef DILIGENT_DEVELOPMENT
@@ -2208,11 +2208,6 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext&
{
DvpVerifyTLASState(TLAS, RequiredState, OperationName);
}
-
- if (RequiredState & RESOURCE_STATE_RAY_TRACING)
- {
- TLAS.CheckBLASVersion();
- }
#endif
}
@@ -2291,8 +2286,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
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;
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC d3d12BuildASDesc = {};
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& d3d12BuildASInputs = d3d12BuildASDesc.Inputs;
std::vector<D3D12_RAYTRACING_GEOMETRY_DESC> Geometries;
if (Attribs.pTriangleData != nullptr)
@@ -2301,10 +2296,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i)
{
- const auto& SrcTris = Attribs.pTriangleData[i];
- Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcTris.GeometryName);
- auto& d3d12Geo = Geometries[GeoIdx];
- auto& d3d12Tris = d3d12Geo.Triangles;
+ const auto& SrcTris = Attribs.pTriangleData[i];
+ Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcTris.GeometryName);
if (GeoIdx >= Geometries.size())
{
@@ -2312,11 +2305,17 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
continue;
}
+ auto& d3d12Geo = Geometries[GeoIdx];
+ auto& d3d12Tris = d3d12Geo.Triangles;
+ const auto& TriDesc = BLASDesc.pTriangles[GeoIdx];
+
d3d12Geo.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
d3d12Geo.Flags = GeometryFlagsToD3D12RTGeometryFlags(SrcTris.Flags);
- auto* const pVB = ValidatedCast<BufferD3D12Impl>(SrcTris.pVertexBuffer);
- d3d12Tris.VertexFormat = TypeToDXGI_Format(SrcTris.VertexValueType, SrcTris.VertexComponentCount, SrcTris.VertexValueType < VT_FLOAT16);
+ auto* const pVB = ValidatedCast<BufferD3D12Impl>(SrcTris.pVertexBuffer);
+
+ // vertex format in SrcTris may be undefined, so use vertex format from description
+ d3d12Tris.VertexFormat = TypeToDXGI_Format(TriDesc.VertexValueType, TriDesc.VertexComponentCount, TriDesc.VertexValueType < VT_FLOAT16);
d3d12Tris.VertexCount = SrcTris.VertexCount;
d3d12Tris.VertexBuffer.StartAddress = pVB->GetGPUAddress() + SrcTris.VertexOffset;
d3d12Tris.VertexBuffer.StrideInBytes = SrcTris.VertexStride;
@@ -2325,10 +2324,12 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
if (SrcTris.pIndexBuffer)
{
- auto* const pIB = ValidatedCast<BufferD3D12Impl>(SrcTris.pIndexBuffer);
+ auto* const pIB = ValidatedCast<BufferD3D12Impl>(SrcTris.pIndexBuffer);
+
+ // index type in SrcTris may be undefined, so use index type from description
+ d3d12Tris.IndexFormat = ValueTypeToIndexType(TriDesc.IndexType);
d3d12Tris.IndexBuffer = pIB->GetGPUAddress() + SrcTris.IndexOffset;
- d3d12Tris.IndexCount = SrcTris.IndexCount;
- d3d12Tris.IndexFormat = ValueTypeToIndexType(SrcTris.IndexType);
+ d3d12Tris.IndexCount = SrcTris.PrimitiveCount * 3;
TransitionOrVerifyBufferState(CmdCtx, *pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
}
@@ -2340,8 +2341,6 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
if (SrcTris.pTransformBuffer)
{
- VERIFY_EXPR(BLASDesc.pTriangles[GeoIdx].AllowsTransforms);
-
auto* const pTB = ValidatedCast<BufferD3D12Impl>(SrcTris.pTransformBuffer);
d3d12Tris.Transform3x4 = pTB->GetGPUAddress() + SrcTris.TransformBufferOffset;
@@ -2349,7 +2348,6 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
}
else
{
- VERIFY_EXPR(!BLASDesc.pTriangles[GeoIdx].AllowsTransforms);
d3d12Tris.Transform3x4 = 0;
}
}
@@ -2360,10 +2358,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i)
{
- const auto& SrcBoxes = Attribs.pBoxData[i];
- Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcBoxes.GeometryName);
- auto& d3d12Geo = Geometries[GeoIdx];
- auto& d3d12AABs = d3d12Geo.AABBs;
+ const auto& SrcBoxes = Attribs.pBoxData[i];
+ Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcBoxes.GeometryName);
if (GeoIdx >= Geometries.size())
{
@@ -2371,6 +2367,9 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
continue;
}
+ auto& d3d12Geo = Geometries[GeoIdx];
+ auto& d3d12AABs = d3d12Geo.AABBs;
+
d3d12Geo.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
d3d12Geo.Flags = GeometryFlagsToD3D12RTGeometryFlags(SrcBoxes.Flags);
@@ -2383,16 +2382,17 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
}
}
- 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();
+ d3d12BuildASInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
+ d3d12BuildASInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(BLASDesc.Flags);
+ d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ d3d12BuildASInputs.NumDescs = static_cast<UINT>(Geometries.size());
+ d3d12BuildASInputs.pGeometryDescs = Geometries.data();
- Desc.DestAccelerationStructureData = pBLASD12->GetGPUAddress();
- Desc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
- Desc.SourceAccelerationStructureData = 0;
+ d3d12BuildASDesc.DestAccelerationStructureData = pBLASD12->GetGPUAddress();
+ d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
+ d3d12BuildASDesc.SourceAccelerationStructureData = 0;
- CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr);
+ CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr);
++m_State.NumCommands;
#ifdef DILIGENT_DEVELOPMENT
@@ -2420,21 +2420,20 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs)
// 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;
+ size_t Size = Attribs.InstanceCount * sizeof(D3D12_RAYTRACING_INSTANCE_DESC);
+ auto TmpSpace = m_DynamicHeap.Allocate(Size, 16, m_ContextFrameNumber);
for (Uint32 i = 0; i < Attribs.InstanceCount; ++i)
{
const auto& Inst = Attribs.pInstances[i];
- auto& d3d12Inst = static_cast<D3D12_RAYTRACING_INSTANCE_DESC*>(pMappedInstances)[i];
+ auto& d3d12Inst = static_cast<D3D12_RAYTRACING_INSTANCE_DESC*>(TmpSpace.CPUAddress)[i];
auto* const pBLASD12 = ValidatedCast<BottomLevelASD3D12Impl>(Inst.pBLAS);
static_assert(sizeof(d3d12Inst.Transform) == sizeof(Inst.Transform), "size mismatch");
std::memcpy(&d3d12Inst.Transform, Inst.Transform.data, sizeof(d3d12Inst.Transform));
d3d12Inst.InstanceID = Inst.CustomId;
- d3d12Inst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize
+ d3d12Inst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex;
d3d12Inst.InstanceMask = Inst.Mask;
d3d12Inst.Flags = InstanceFlagsToD3D12RTInstanceFlags(Inst.Flags);
d3d12Inst.AccelerationStructure = pBLASD12->GetGPUAddress();
@@ -2449,6 +2448,7 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs)
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& d3d12BuildASInputs = d3d12BuildASDesc.Inputs;
d3d12BuildASInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
+ d3d12BuildASInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(pTLASD12->GetDesc().Flags);
d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
d3d12BuildASInputs.NumDescs = Attribs.InstanceCount;
d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress();
@@ -2469,12 +2469,17 @@ void DeviceContextD3D12Impl::CopyBLAS(const CopyBLASAttribs& Attribs)
auto* pSrcD3D12 = ValidatedCast<BottomLevelASD3D12Impl>(Attribs.pSrc);
auto* pDstD3D12 = ValidatedCast<BottomLevelASD3D12Impl>(Attribs.pDst);
auto& CmdCtx = GetCmdContext();
+ auto Mode = CopyASModeToD3D12ASCopyMode(Attribs.Mode);
+
+ // Dst BLAS description has specified CompactedSize, but doesn't have specified pTriangles and pBoxes.
+ // We should copy geometries because it required for SBT to map geometry name to hit group.
+ pDstD3D12->CopyDescription(*pSrcD3D12);
const char* OpName = "Copy BottomLevelAS (DeviceContextD3D12Impl::CopyBLAS)";
- TransitionOrVerifyBLASState(CmdCtx, *pSrcD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
- TransitionOrVerifyBLASState(CmdCtx, *pDstD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+ TransitionOrVerifyBLASState(CmdCtx, *pSrcD3D12, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyBLASState(CmdCtx, *pDstD3D12, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
- CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pSrcD3D12->GetGPUAddress(), pDstD3D12->GetGPUAddress(), D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE);
+ CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pDstD3D12->GetGPUAddress(), pSrcD3D12->GetGPUAddress(), Mode);
++m_State.NumCommands;
#ifdef DILIGENT_DEVELOPMENT
@@ -2490,14 +2495,67 @@ void DeviceContextD3D12Impl::CopyTLAS(const CopyTLASAttribs& Attribs)
auto* pSrcD3D12 = ValidatedCast<TopLevelASD3D12Impl>(Attribs.pSrc);
auto* pDstD3D12 = ValidatedCast<TopLevelASD3D12Impl>(Attribs.pDst);
auto& CmdCtx = GetCmdContext();
+ auto Mode = CopyASModeToD3D12ASCopyMode(Attribs.Mode);
+ // Instances specified in BuildTLAS command.
+ // We should copy instances because it required for SBT to map instance name to hit group.
pDstD3D12->CopyInstancceData(*pSrcD3D12);
const char* OpName = "Copy BottomLevelAS (DeviceContextD3D12Impl::CopyTLAS)";
- TransitionOrVerifyTLASState(CmdCtx, *pSrcD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
- TransitionOrVerifyTLASState(CmdCtx, *pDstD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+ TransitionOrVerifyTLASState(CmdCtx, *pSrcD3D12, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyTLASState(CmdCtx, *pDstD3D12, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
- CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pSrcD3D12->GetGPUAddress(), pDstD3D12->GetGPUAddress(), D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE);
+ CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pDstD3D12->GetGPUAddress(), pSrcD3D12->GetGPUAddress(), Mode);
+ ++m_State.NumCommands;
+}
+
+void DeviceContextD3D12Impl::WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs)
+{
+ if (!TDeviceContextBase::WriteBLASCompactedSize(Attribs, 0))
+ return;
+
+ static_assert(sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC) == sizeof(Uint64),
+ "Engine api specifies that compacted size is 64 bits");
+
+ auto* pBLASD3D12 = ValidatedCast<BottomLevelASD3D12Impl>(Attribs.pBLAS);
+ auto* pDestBuffD3D12 = ValidatedCast<BufferD3D12Impl>(Attribs.pDestBuffer);
+ auto& CmdCtx = GetCmdContext();
+
+ const char* OpName = "Write AS compacted size (DeviceContextD3D12Impl::WriteBLASCompactedSize)";
+ TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyBufferState(CmdCtx, *pDestBuffD3D12, Attribs.BufferTransitionMode, RESOURCE_STATE_UNORDERED_ACCESS, OpName);
+
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC d3d12Desc = {};
+
+ d3d12Desc.DestBuffer = pDestBuffD3D12->GetGPUAddress() + Attribs.DestBufferOffset;
+ d3d12Desc.InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE;
+
+ CmdCtx.AsGraphicsContext4().EmitRaytracingAccelerationStructurePostbuildInfo(d3d12Desc, pBLASD3D12->GetGPUAddress());
+ ++m_State.NumCommands;
+}
+
+void DeviceContextD3D12Impl::WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs)
+{
+ if (!TDeviceContextBase::WriteTLASCompactedSize(Attribs, 0))
+ return;
+
+ static_assert(sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC) == sizeof(Uint64),
+ "Engine api specifies that compacted size is 64 bits");
+
+ auto* pTLASD3D12 = ValidatedCast<TopLevelASD3D12Impl>(Attribs.pTLAS);
+ auto* pDestBuffD3D12 = ValidatedCast<BufferD3D12Impl>(Attribs.pDestBuffer);
+ auto& CmdCtx = GetCmdContext();
+
+ const char* OpName = "Write AS compacted size (DeviceContextD3D12Impl::WriteTLASCompactedSize)";
+ TransitionOrVerifyTLASState(CmdCtx, *pTLASD3D12, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyBufferState(CmdCtx, *pDestBuffD3D12, Attribs.BufferTransitionMode, RESOURCE_STATE_UNORDERED_ACCESS, OpName);
+
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC d3d12Desc = {};
+
+ d3d12Desc.DestBuffer = pDestBuffD3D12->GetGPUAddress() + Attribs.DestBufferOffset;
+ d3d12Desc.InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE;
+
+ CmdCtx.AsGraphicsContext4().EmitRaytracingAccelerationStructurePostbuildInfo(d3d12Desc, pTLASD3D12->GetGPUAddress());
++m_State.NumCommands;
}
@@ -2506,20 +2564,60 @@ void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs)
if (!TDeviceContextBase::TraceRays(Attribs, 0))
return;
+ VERIFY_EXPR((Attribs.DimensionX * Attribs.DimensionY * Attribs.DimensionZ) <= D3D12_RAYTRACING_MAX_RAY_GENERATION_SHADER_THREADS);
+
+ auto& CmdCtx = GetCmdContext().AsGraphicsContext4();
+ auto* pSBTD12 = ValidatedCast<ShaderBindingTableD3D12Impl>(Attribs.pSBT);
+ IBuffer* pBuffer = nullptr;
+
+ ShaderBindingTableD3D12Impl::BindingTable RayGenShaderRecord = {};
+ ShaderBindingTableD3D12Impl::BindingTable MissShaderTable = {};
+ ShaderBindingTableD3D12Impl::BindingTable HitGroupTable = {};
+ ShaderBindingTableD3D12Impl::BindingTable CallableShaderTable = {};
+
+ pSBTD12->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable);
+
+ auto* pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffer);
+
+ const char* OpName = "Trace rays (DeviceContextD3D12Impl::TraceRays)";
+ TransitionOrVerifyBufferState(CmdCtx, *pBufferD3D12, Attribs.SBTTransitionMode, RESOURCE_STATE_COPY_DEST, OpName);
+
+ // buffer ranges are not intersected, so we don't need to add barriers between them
+ if (RayGenShaderRecord.pData)
+ UpdateBuffer(pBufferD3D12, RayGenShaderRecord.Offset, RayGenShaderRecord.Size, RayGenShaderRecord.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (MissShaderTable.pData)
+ UpdateBuffer(pBufferD3D12, MissShaderTable.Offset, MissShaderTable.Size, MissShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (HitGroupTable.pData)
+ UpdateBuffer(pBufferD3D12, HitGroupTable.Offset, HitGroupTable.Size, HitGroupTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (CallableShaderTable.pData)
+ UpdateBuffer(pBufferD3D12, CallableShaderTable.Offset, CallableShaderTable.Size, CallableShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ TransitionOrVerifyBufferState(CmdCtx, *pBufferD3D12, Attribs.SBTTransitionMode, RESOURCE_STATE_RAY_TRACING, OpName);
+
D3D12_DISPATCH_RAYS_DESC d3d12DispatchDesc = {};
d3d12DispatchDesc.Width = Attribs.DimensionX;
d3d12DispatchDesc.Height = Attribs.DimensionY;
d3d12DispatchDesc.Depth = Attribs.DimensionZ;
- auto* pSBTD12 = ValidatedCast<ShaderBindingTableD3D12Impl>(Attribs.pSBT);
- pSBTD12->GetD3D12AddressRangeAndStride(this, Attribs.TransitionMode,
- d3d12DispatchDesc.RayGenerationShaderRecord,
- d3d12DispatchDesc.MissShaderTable,
- d3d12DispatchDesc.HitGroupTable,
- d3d12DispatchDesc.CallableShaderTable);
+ d3d12DispatchDesc.RayGenerationShaderRecord.StartAddress = pBufferD3D12->GetGPUAddress() + RayGenShaderRecord.Offset;
+ d3d12DispatchDesc.RayGenerationShaderRecord.SizeInBytes = RayGenShaderRecord.Size;
+
+ d3d12DispatchDesc.MissShaderTable.StartAddress = pBufferD3D12->GetGPUAddress() + MissShaderTable.Offset;
+ d3d12DispatchDesc.MissShaderTable.SizeInBytes = MissShaderTable.Size;
+ d3d12DispatchDesc.MissShaderTable.StrideInBytes = MissShaderTable.Stride;
+
+ d3d12DispatchDesc.HitGroupTable.StartAddress = pBufferD3D12->GetGPUAddress() + HitGroupTable.Offset;
+ d3d12DispatchDesc.HitGroupTable.SizeInBytes = HitGroupTable.Size;
+ d3d12DispatchDesc.HitGroupTable.StrideInBytes = HitGroupTable.Stride;
+
+ d3d12DispatchDesc.CallableShaderTable.StartAddress = pBufferD3D12->GetGPUAddress() + CallableShaderTable.Offset;
+ d3d12DispatchDesc.CallableShaderTable.SizeInBytes = CallableShaderTable.Size;
+ d3d12DispatchDesc.CallableShaderTable.StrideInBytes = CallableShaderTable.Stride;
- auto& CmdCtx = GetCmdContext().AsGraphicsContext4();
PrepareForDispatchRays(CmdCtx);
CmdCtx.DispatchRays(d3d12DispatchDesc);
diff --git a/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp
index a9e1c7d8..02308ca0 100644
--- a/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp
@@ -51,7 +51,9 @@ FenceD3D12Impl::~FenceD3D12Impl()
Uint64 FenceD3D12Impl::GetCompletedValue()
{
- return m_pd3d12Fence->GetCompletedValue();
+ Uint64 Result = m_pd3d12Fence->GetCompletedValue();
+ VERIFY(Result != UINT64_MAX, "If the device has been removed, the return value will be UINT64_MAX");
+ return Result;
}
void FenceD3D12Impl::Reset(Uint64 Value)
@@ -61,7 +63,7 @@ void FenceD3D12Impl::Reset(Uint64 Value)
void FenceD3D12Impl::WaitForCompletion(Uint64 Value)
{
- while (m_pd3d12Fence->GetCompletedValue() < Value)
+ while (GetCompletedValue() < Value)
std::this_thread::yield();
}
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp
index d71d98b7..ac67ba57 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp
@@ -62,101 +62,4 @@ 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), 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/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp
index 3bbf3308..2d087d08 100644
--- a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp
@@ -44,21 +44,34 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte
bool bIsDeviceInternal) :
TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal}
{
- D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12TopLevelPrebuildInfo = {};
- D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12TopLevelInputs = {};
+ auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5();
+ UINT64 ResultDataMaxSizeInBytes = 0;
- d3d12TopLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
- d3d12TopLevelInputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
- d3d12TopLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
- d3d12TopLevelInputs.NumDescs = Desc.MaxInstanceCount;
+ if (m_Desc.CompactedSize > 0)
+ {
+ ResultDataMaxSizeInBytes = m_Desc.CompactedSize;
+ }
+ else
+ {
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12TopLevelPrebuildInfo = {};
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12TopLevelInputs = {};
- VERIFY_EXPR(Desc.MaxInstanceCount <= D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE);
+ d3d12TopLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
+ d3d12TopLevelInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(m_Desc.Flags);
+ d3d12TopLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ d3d12TopLevelInputs.NumDescs = m_Desc.MaxInstanceCount;
- auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5();
+ VERIFY_EXPR(m_Desc.MaxInstanceCount <= D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE);
- pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12TopLevelInputs, &d3d12TopLevelPrebuildInfo);
- if (d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0)
- LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info");
+ pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12TopLevelInputs, &d3d12TopLevelPrebuildInfo);
+ if (d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0)
+ LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info");
+
+ ResultDataMaxSizeInBytes = d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes;
+
+ m_ScratchSize.Build = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.ScratchDataSizeInBytes);
+ m_ScratchSize.Update = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes);
+ }
D3D12_HEAP_PROPERTIES HeapProps;
HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
@@ -70,7 +83,7 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte
D3D12_RESOURCE_DESC d3d12ASDesc = {};
d3d12ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
d3d12ASDesc.Alignment = 0;
- d3d12ASDesc.Width = d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes;
+ d3d12ASDesc.Width = ResultDataMaxSizeInBytes;
d3d12ASDesc.Height = 1;
d3d12ASDesc.DepthOrArraySize = 1;
d3d12ASDesc.MipLevels = 1;
@@ -90,9 +103,6 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte
if (*m_Desc.Name != 0)
m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str());
- m_ScratchSize.Build = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.ScratchDataSizeInBytes);
- m_ScratchSize.Update = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes);
-
m_DescriptorHandle = pDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
D3D12_SHADER_RESOURCE_VIEW_DESC d3d12SRVDesc;
@@ -101,6 +111,10 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte
d3d12SRVDesc.Format = DXGI_FORMAT_UNKNOWN;
d3d12SRVDesc.RaytracingAccelerationStructure.Location = GetGPUAddress();
pd3d12Device->CreateShaderResourceView(nullptr, &d3d12SRVDesc, m_DescriptorHandle.GetCpuHandle());
+
+ VERIFY_EXPR(GetGPUAddress() % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0);
+
+ SetState(RESOURCE_STATE_BUILD_AS_READ);
}
TopLevelASD3D12Impl::~TopLevelASD3D12Impl()