summaryrefslogtreecommitdiffstats
path: root/Graphics
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
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')
-rw-r--r--Graphics/GraphicsEngine/include/BottomLevelASBase.hpp247
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.hpp341
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.hpp8
-rw-r--r--Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp126
-rw-r--r--Graphics/GraphicsEngine/include/TopLevelASBase.hpp142
-rw-r--r--Graphics/GraphicsEngine/interface/BottomLevelAS.h67
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h410
-rw-r--r--Graphics/GraphicsEngine/interface/GraphicsTypes.h7
-rw-r--r--Graphics/GraphicsEngine/interface/PipelineState.h86
-rw-r--r--Graphics/GraphicsEngine/interface/Shader.h2
-rw-r--r--Graphics/GraphicsEngine/interface/ShaderBindingTable.h10
-rw-r--r--Graphics/GraphicsEngine/interface/TopLevelAS.h40
-rw-r--r--Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp6
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp10
-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
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp10
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp10
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp9
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp10
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp19
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp15
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h10
-rw-r--r--Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp123
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp203
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp104
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp23
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp49
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp11
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp4
-rw-r--r--Graphics/ShaderTools/include/SPIRVShaderResources.hpp11
-rw-r--r--Graphics/ShaderTools/src/SPIRVShaderResources.cpp30
47 files changed, 1772 insertions, 971 deletions
diff --git a/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp b/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
index 2bdd51dc..5a6db4bd 100644
--- a/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
+++ b/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
@@ -36,7 +36,7 @@
#include "BottomLevelAS.h"
#include "DeviceObjectBase.hpp"
#include "RenderDeviceBase.hpp"
-#include "StringPool.hpp"
+#include "LinearAllocator.hpp"
#include "HashUtils.hpp"
namespace Diligent
@@ -67,84 +67,21 @@ public:
{
ValidateBottomLevelASDesc(Desc);
- // Memory must be released if an exception is thrown.
- auto RawMemDeleter = [](void* ptr) {
- if (ptr != nullptr)
- GetRawAllocator().Free(ptr);
- };
-
- if (Desc.pTriangles != nullptr)
+ if (Desc.CompactedSize > 0)
+ {}
+ else
{
- size_t StringPoolSize = 0;
- for (Uint32 i = 0; i < Desc.TriangleCount; ++i)
- {
- if (Desc.pTriangles[i].GeometryName == nullptr)
- LOG_ERROR_AND_THROW("Geometry name can not be null!");
-
- StringPoolSize += strlen(Desc.pTriangles[i].GeometryName) + 1;
- }
-
- m_StringPool.Reserve(StringPoolSize, GetRawAllocator());
-
- std::unique_ptr<BLASTriangleDesc[], decltype(RawMemDeleter)> pTriangles{
- ALLOCATE(GetRawAllocator(), "Memory for BLASTriangleDesc array", BLASTriangleDesc, Desc.TriangleCount),
- RawMemDeleter};
-
- std::memcpy(pTriangles.get(), Desc.pTriangles, sizeof(*Desc.pTriangles) * Desc.TriangleCount);
- this->m_Desc.pBoxes = nullptr;
-
- // copy strings
- for (Uint32 i = 0; i < Desc.TriangleCount; ++i)
- {
- pTriangles[i].GeometryName = m_StringPool.CopyString(pTriangles[i].GeometryName);
- bool IsUniqueName = m_NameToIndex.emplace(pTriangles[i].GeometryName, i).second;
- if (!IsUniqueName)
- LOG_ERROR_AND_THROW("Geometry name must be unique!");
- }
- this->m_Desc.pTriangles = pTriangles.release();
+ LinearAllocator MemPool{GetRawAllocator()};
+ CopyDescription(Desc, this->m_Desc, MemPool, m_NameToIndex);
+ this->m_pRawPtr = MemPool.ReleaseOwnership();
}
- else if (Desc.pBoxes != nullptr)
- {
- size_t StringPoolSize = 0;
- for (Uint32 i = 0; i < Desc.BoxCount; ++i)
- {
- if (Desc.pBoxes[i].GeometryName == nullptr)
- LOG_ERROR_AND_THROW("Geometry name can not be null!");
-
- StringPoolSize += strlen(Desc.pBoxes[i].GeometryName) + 1;
- }
-
- m_StringPool.Reserve(StringPoolSize, GetRawAllocator());
-
- std::unique_ptr<BLASBoundingBoxDesc[], decltype(RawMemDeleter)> pBoxes{
- ALLOCATE(GetRawAllocator(), "Memory for BLASBoundingBoxDesc array", BLASBoundingBoxDesc, Desc.BoxCount),
- RawMemDeleter};
-
- std::memcpy(pBoxes.get(), Desc.pBoxes, sizeof(*Desc.pBoxes) * Desc.BoxCount);
- this->m_Desc.pTriangles = nullptr;
-
- // copy strings
- for (Uint32 i = 0; i < Desc.BoxCount; ++i)
- {
- pBoxes[i].GeometryName = m_StringPool.CopyString(pBoxes[i].GeometryName);
- bool IsUniqueName = m_NameToIndex.emplace(pBoxes[i].GeometryName, i).second;
- if (!IsUniqueName)
- LOG_ERROR_AND_THROW("Geometry name must be unique!");
- }
- this->m_Desc.pBoxes = pBoxes.release();
- }
- VERIFY_EXPR(m_StringPool.GetRemainingSize() == 0);
}
~BottomLevelASBase()
{
- if (this->m_Desc.pTriangles != nullptr)
+ if (this->m_pRawPtr)
{
- GetRawAllocator().Free(const_cast<BLASTriangleDesc*>(this->m_Desc.pTriangles));
- }
- if (this->m_Desc.pBoxes != nullptr)
- {
- GetRawAllocator().Free(const_cast<BLASBoundingBoxDesc*>(this->m_Desc.pBoxes));
+ GetRawAllocator().Free(this->m_pRawPtr);
}
}
@@ -164,6 +101,8 @@ public:
virtual void DILIGENT_CALL_TYPE SetState(RESOURCE_STATE State) override final
{
+ VERIFY(State == RESOURCE_STATE_BUILD_AS_READ || State == RESOURCE_STATE_BUILD_AS_WRITE,
+ "Unsupported state for bottom-level acceleration structure");
this->m_State = State;
}
@@ -184,6 +123,36 @@ public:
return (this->m_State & State) == State;
}
+ void CopyDescription(const BottomLevelASBase& Src)
+ {
+ const auto& SrcDesc = Src.GetDesc();
+ auto& DstDesc = this->m_Desc;
+
+ try
+ {
+ if (this->m_pRawPtr)
+ {
+ GetRawAllocator().Free(this->m_pRawPtr);
+ this->m_pRawPtr = nullptr;
+ }
+ m_NameToIndex.clear();
+
+ DstDesc.TriangleCount = SrcDesc.TriangleCount;
+ DstDesc.BoxCount = SrcDesc.BoxCount;
+
+ LinearAllocator MemPool{GetRawAllocator()};
+ CopyDescription(SrcDesc, DstDesc, MemPool, m_NameToIndex);
+ this->m_pRawPtr = MemPool.ReleaseOwnership();
+ }
+ catch (...)
+ {
+ // memory for arrays is not allocated or have been freed
+ DstDesc.pTriangles = nullptr;
+ DstDesc.pBoxes = nullptr;
+ m_NameToIndex.clear();
+ }
+ }
+
#ifdef DILIGENT_DEVELOPMENT
void UpdateVersion()
{
@@ -194,29 +163,143 @@ public:
{
return m_Version.load();
}
-#endif
+
+ bool ValidateContent() const
+ {
+ return true;
+ }
+#endif // DILIGENT_DEVELOPMENT
protected:
static void ValidateBottomLevelASDesc(const BottomLevelASDesc& Desc)
{
#define LOG_BLAS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of Bottom-level AS '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__)
- if (!((Desc.pBoxes != nullptr) ^ (Desc.pTriangles != nullptr)))
+ if (Desc.CompactedSize > 0)
{
- LOG_BLAS_ERROR_AND_THROW("Exactly one of pTriangles and pBoxes must be defined");
- }
+ if (Desc.pTriangles != nullptr || Desc.pBoxes != nullptr)
+ LOG_BLAS_ERROR_AND_THROW("If CompactedSize is specified then pTriangles and pBoxes must be null");
- if (Desc.pBoxes == nullptr && Desc.BoxCount > 0)
+ if (Desc.Flags != RAYTRACING_BUILD_AS_NONE)
+ LOG_BLAS_ERROR_AND_THROW("If CompactedSize is specified then Flags must be RAYTRACING_BUILD_AS_NONE");
+ }
+ else
{
- LOG_BLAS_ERROR_AND_THROW("pBoxes is null but BoxCount is not 0");
+ if (!((Desc.pBoxes != nullptr) ^ (Desc.pTriangles != nullptr)))
+ LOG_BLAS_ERROR_AND_THROW("Exactly one of pTriangles and pBoxes must be defined");
+
+ if (Desc.pBoxes == nullptr && Desc.BoxCount > 0)
+ LOG_BLAS_ERROR_AND_THROW("pBoxes is null but BoxCount is not 0");
+
+ if (Desc.pTriangles == nullptr && Desc.TriangleCount > 0)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles is null but TriangleCount is not 0");
+
+ if ((Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_TRACE) && (Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_BUILD))
+ LOG_BLAS_ERROR_AND_THROW("can not set both flags RAYTRACING_BUILD_AS_PREFER_FAST_TRACE and RAYTRACING_BUILD_AS_PREFER_FAST_BUILD");
+
+#ifdef DILIGENT_DEVELOPMENT
+ for (Uint32 i = 0; i < Desc.TriangleCount; ++i)
+ {
+ const auto& tri = Desc.pTriangles[i];
+
+ if (tri.GeometryName == nullptr)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].GeometryName must not be null");
+
+ if (tri.VertexValueType >= VT_NUM_TYPES)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].VertexValueType must be valid type");
+
+ if (tri.VertexComponentCount != 2 && tri.VertexComponentCount != 3)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].VertexComponentCount must be 2 or 3");
+
+ if (tri.MaxVertexCount == 0)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxVertexCount must be greater then 0");
+
+ if (tri.MaxPrimitiveCount == 0)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxPrimitiveCount must be greater then 0");
+
+ if (tri.IndexType == VT_UNDEFINED)
+ {
+ if (tri.MaxVertexCount != tri.MaxPrimitiveCount * 3)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxVertexCount must equal to (MaxPrimitiveCount * 3)");
+ }
+ else
+ {
+ if (tri.IndexType != VT_UINT32 && tri.IndexType != VT_UINT16)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].IndexType must be VT_UINT16 or VT_UINT32");
+ }
+ }
+
+ for (Uint32 i = 0; i < Desc.BoxCount; ++i)
+ {
+ const auto& box = Desc.pBoxes[i];
+
+ if (box.GeometryName == nullptr)
+ LOG_BLAS_ERROR_AND_THROW("pBoxes[", i, "].GeometryName must not be null");
+
+ if (box.MaxBoxCount == 0)
+ LOG_BLAS_ERROR_AND_THROW("pBoxes[", i, "].MaxBoxCount must be greater then 0");
+ }
+#endif // DILIGENT_DEVELOPMENT
}
- if (Desc.pTriangles == nullptr && Desc.TriangleCount > 0)
+#undef LOG_BLAS_ERROR_AND_THROW
+ }
+
+ static void CopyDescription(const BottomLevelASDesc& SrcDesc,
+ BottomLevelASDesc& DstDesc,
+ LinearAllocator& MemPool,
+ std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>& NameToIndex)
+ {
+ if (SrcDesc.pTriangles != nullptr)
{
- LOG_BLAS_ERROR_AND_THROW("pTriangles is null but TriangleCount is not 0");
+ MemPool.AddSpace<decltype(*SrcDesc.pTriangles)>(SrcDesc.TriangleCount);
+
+ for (Uint32 i = 0; i < SrcDesc.TriangleCount; ++i)
+ MemPool.AddSpaceForString(SrcDesc.pTriangles[i].GeometryName);
+
+ MemPool.Reserve();
+
+ auto* pTriangles = MemPool.CopyArray(SrcDesc.pTriangles, SrcDesc.TriangleCount);
+
+ // copy strings
+ for (Uint32 i = 0; i < SrcDesc.TriangleCount; ++i)
+ {
+ pTriangles[i].GeometryName = MemPool.CopyString(SrcDesc.pTriangles[i].GeometryName);
+ bool IsUniqueName = NameToIndex.emplace(SrcDesc.pTriangles[i].GeometryName, i).second;
+ if (!IsUniqueName)
+ LOG_ERROR_AND_THROW("Geometry name must be unique!");
+ }
+ DstDesc.pTriangles = pTriangles;
+ DstDesc.pBoxes = nullptr;
+ DstDesc.BoxCount = 0;
}
+ else if (SrcDesc.pBoxes != nullptr)
+ {
+ MemPool.AddSpace<decltype(*SrcDesc.pBoxes)>(SrcDesc.BoxCount);
-#undef LOG_BLAS_ERROR_AND_THROW
+ for (Uint32 i = 0; i < SrcDesc.BoxCount; ++i)
+ MemPool.AddSpaceForString(SrcDesc.pBoxes[i].GeometryName);
+
+ MemPool.Reserve();
+
+ auto* pBoxes = MemPool.CopyArray(SrcDesc.pBoxes, SrcDesc.BoxCount);
+
+ // copy strings
+ for (Uint32 i = 0; i < SrcDesc.BoxCount; ++i)
+ {
+ pBoxes[i].GeometryName = MemPool.CopyString(SrcDesc.pBoxes[i].GeometryName);
+ bool IsUniqueName = NameToIndex.emplace(SrcDesc.pBoxes[i].GeometryName, i).second;
+ if (!IsUniqueName)
+ LOG_ERROR_AND_THROW("Geometry name must be unique!");
+ }
+ DstDesc.pBoxes = pBoxes;
+ DstDesc.pTriangles = nullptr;
+ DstDesc.TriangleCount = 0;
+ }
+ else
+ {
+ LOG_ERROR_AND_THROW("Either pTriangles or pBoxes must not be null");
+ }
}
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_BottomLevelAS, TDeviceObjectBase)
@@ -226,7 +309,7 @@ protected:
std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher> m_NameToIndex;
- StringPool m_StringPool;
+ void* m_pRawPtr = nullptr;
#ifdef DILIGENT_DEVELOPMENT
std::atomic<Uint32> m_Version{0};
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
index ba586f4b..f7abedb8 100644
--- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
+++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
@@ -279,11 +279,13 @@ protected:
// clang-format on
#endif
- bool BuildBLAS(const BLASBuildAttribs& Attribs, int);
- bool BuildTLAS(const TLASBuildAttribs& Attribs, int);
- bool CopyBLAS(const CopyBLASAttribs& Attribs, int);
- bool CopyTLAS(const CopyTLASAttribs& Attribs, int);
- bool TraceRays(const TraceRaysAttribs& Attribs, int);
+ bool BuildBLAS(const BLASBuildAttribs& Attribs, int) const;
+ bool BuildTLAS(const TLASBuildAttribs& Attribs, int) const;
+ bool CopyBLAS(const CopyBLASAttribs& Attribs, int) const;
+ bool CopyTLAS(const CopyTLASAttribs& Attribs, int) const;
+ bool WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs, int) const;
+ bool WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs, int) const;
+ bool TraceRays(const TraceRaysAttribs& Attribs, int) const;
/// Strong reference to the device.
RefCntAutoPtr<DeviceImplType> m_pDevice;
@@ -1503,6 +1505,12 @@ inline bool DeviceContextBase<BaseInterface, ImplementationTraits>::
if ((Attribs.Flags & DRAW_FLAG_VERIFY_DRAW_ATTRIBS) == 0)
return true;
+ if (m_pDevice->GetDeviceCaps().Features.MeshShaders != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("DrawMesh: mesh shaders are not supported by this device");
+ return false;
+ }
+
if (!m_pPipelineState)
{
LOG_ERROR_MESSAGE("DrawMesh command arguments are invalid: no pipeline state is bound.");
@@ -1521,6 +1529,11 @@ inline bool DeviceContextBase<BaseInterface, ImplementationTraits>::
LOG_WARNING_MESSAGE("DrawMesh command arguments are invalid: number of groups to dispatch is zero.");
}
+ if (Attribs.ThreadGroupCount > m_pDevice->GetMaxDrawMeshTasksCount())
+ {
+ LOG_WARNING_MESSAGE("DrawMesh command arguments are invalid: number of groups to dispatch must be less then ", m_pDevice->GetMaxDrawMeshTasksCount());
+ }
+
return true;
}
@@ -1635,6 +1648,12 @@ inline bool DeviceContextBase<BaseInterface, ImplementationTraits>::
if ((Attribs.Flags & DRAW_FLAG_VERIFY_DRAW_ATTRIBS) == 0)
return true;
+ if (m_pDevice->GetDeviceCaps().Features.MeshShaders != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("DrawMeshIndirect: mesh shaders are not supported by this device");
+ return false;
+ }
+
if (!m_pPipelineState)
{
LOG_ERROR_MESSAGE("DrawMeshIndirect command arguments are invalid: no pipeline state is bound.");
@@ -1860,7 +1879,7 @@ void DeviceContextBase<BaseInterface, ImplementationTraits>::
const auto& BLASDesc = pBottomLevelAS->GetDesc();
OldState = Barrier.OldState != RESOURCE_STATE_UNKNOWN ? Barrier.OldState : pBottomLevelAS->GetState();
DEV_CHECK_ERR(OldState != RESOURCE_STATE_UNKNOWN, "The state of BLAS '", BLASDesc.Name, "' is unknown to the engine and is not explicitly specified in the barrier");
- DEV_CHECK_ERR(Barrier.NewState == RESOURCE_STATE_BUILD_AS_READ || Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE || Barrier.NewState == RESOURCE_STATE_RAY_TRACING,
+ DEV_CHECK_ERR(Barrier.NewState == RESOURCE_STATE_BUILD_AS_READ || Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE,
"Invlaid new state specified for BLAS '", BLASDesc.Name, "'");
DEV_CHECK_ERR(Barrier.TransitionType != STATE_TRANSITION_TYPE_IMMEDIATE, "Split barriers are not supported for BLAS");
}
@@ -1951,11 +1970,17 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::
#endif // DILIGENT_DEVELOPMENT
template <typename BaseInterface, typename ImplementationTraits>
-bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLASBuildAttribs& Attribs, int)
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLASBuildAttribs& Attribs, int) const
{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: ray tracing is not supported by this device");
+ return false;
+ }
+
if (m_pActiveRenderPass != nullptr)
{
- LOG_ERROR_MESSAGE("BuildBLAS command must be performed outside of render pass");
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS command must be performed outside of render pass");
return false;
}
@@ -1989,22 +2014,51 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLA
return false;
}
+ const auto& BLASDesc = Attribs.pBLAS->GetDesc();
+
+ if (Attribs.BoxDataCount > BLASDesc.BoxCount)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: BoxDataCount must be less than or equal to pBLAS->GetDesc().BoxCount");
+ return false;
+ }
+
+ if (Attribs.TriangleDataCount > BLASDesc.TriangleCount)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: TriangleDataCount must be less than or equal to pBLAS->GetDesc().TriangleCount");
+ return false;
+ }
+
#ifdef DILIGENT_DEVELOPMENT
for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i)
{
const auto& tri = Attribs.pTriangleData[i];
const Uint32 VertexSize = GetValueSize(tri.VertexValueType) * tri.VertexComponentCount;
const Uint32 VertexDataSize = tri.VertexStride * tri.VertexCount;
+ const Uint32 GeomIndex = Attribs.pBLAS->GetGeometryIndex(tri.GeometryName);
+
+ if (GeomIndex == BottomLevelASType::InvalidGeometryIndex)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].GeometryName not found in BLAS description");
+ return false;
+ }
+
+ const auto& TriDesc = BLASDesc.pTriangles[GeomIndex];
+
+ if (tri.VertexValueType != VT_UNDEFINED && tri.VertexValueType != TriDesc.VertexValueType)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].VertexValueType must be undefined or match the VertexValueType in geometry description");
+ return false;
+ }
- if (tri.VertexValueType >= VT_NUM_TYPES)
+ if (tri.VertexComponentCount != 0 && tri.VertexComponentCount != TriDesc.VertexComponentCount)
{
- LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].VertexValueType must be valid type");
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].VertexComponentCount must be 0 or match the VertexComponentCount in geometry description");
return false;
}
- if (tri.VertexComponentCount != 2 && tri.VertexComponentCount != 3)
+ if (tri.VertexCount > TriDesc.MaxVertexCount)
{
- LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].VertexComponentCount must be 2 or 3");
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].VertexCount must not be greater then MaxVertexCount(", TriDesc.MaxVertexCount, ")");
return false;
}
@@ -2032,20 +2086,20 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLA
return false;
}
- if (tri.IndexType != VT_UNDEFINED)
+ if (tri.IndexType != VT_UNDEFINED && tri.IndexType != TriDesc.IndexType)
{
- if (tri.IndexType != VT_UINT16 && tri.IndexType != VT_UINT32)
- {
- LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].IndexType must not be VT_UNDEFINED, VT_UINT16 or VT_UINT32");
- return false;
- }
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].IndexType must match the IndexType in geometry description");
+ return false;
+ }
- if (tri.IndexCount == 0 || (tri.IndexCount % 3 != 0))
- {
- LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].IndexCount must be valid");
- return false;
- }
+ if (tri.PrimitiveCount > TriDesc.MaxPrimitiveCount)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].PrimitiveCount must not be greater then MaxPrimitiveCount(", TriDesc.MaxPrimitiveCount, ")");
+ return false;
+ }
+ if (TriDesc.IndexType != VT_UNDEFINED)
+ {
if (tri.pIndexBuffer == nullptr)
{
LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].pIndexBuffer must not be null");
@@ -2058,7 +2112,7 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLA
return false;
}
- const Uint32 IndexDataSize = tri.IndexCount * GetValueSize(tri.IndexType);
+ const Uint32 IndexDataSize = tri.PrimitiveCount * 3 * GetValueSize(tri.IndexType);
if (tri.IndexOffset + IndexDataSize > tri.pIndexBuffer->GetDesc().uiSizeInBytes)
{
LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].pIndexBuffer is too small for specified IndexType and IndexCount");
@@ -2067,10 +2121,14 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLA
}
else
{
+ if (tri.VertexCount != tri.PrimitiveCount * 3)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].VertexCount must equal to (PrimitiveCount * 3)");
+ return false;
+ }
+
VERIFY(tri.pIndexBuffer == nullptr,
"IDeviceContext::BuildBLAS: pTriangleData[", i, "].pIndexBuffer must be null if IndexType is VT_UNDEFINED");
- VERIFY(tri.IndexCount == 0,
- "IDeviceContext::BuildBLAS: pTriangleData[", i, "].IndexCount must be zero if IndexType is VT_UNDEFINED");
}
if (tri.pTransformBuffer != nullptr)
@@ -2080,13 +2138,34 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLA
LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "].pTransformBuffer must be created with BIND_RAY_TRACING flag");
return false;
}
+
+ if (!TriDesc.AllowsTransforms)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pTriangleData[", i, "] use transform buffer but AllowsTransforms is false");
+ return false;
+ }
}
}
for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i)
{
- const auto& box = Attribs.pBoxData[i];
- const Uint32 BoxSize = sizeof(float) * 6;
+ const auto& box = Attribs.pBoxData[i];
+ const Uint32 BoxSize = sizeof(float) * 6;
+ const Uint32 GeomIndex = Attribs.pBLAS->GetGeometryIndex(box.GeometryName);
+
+ if (GeomIndex == BottomLevelASType::InvalidGeometryIndex)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pBoxData[", i, "].GeometryName not found in BLAS description");
+ return false;
+ }
+
+ const auto& BoxDesc = BLASDesc.pBoxes[GeomIndex];
+
+ if (box.BoxCount > BoxDesc.MaxBoxCount)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: pBoxData[", i, "].BoxCount must not be greated then MaxBoxCount (", BoxDesc.MaxBoxCount, ")");
+ return false;
+ }
if (box.BoxStride < BoxSize)
{
@@ -2108,20 +2187,6 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLA
}
#endif // DILIGENT_DEVELOPMENT
- const auto& BLASDesc = Attribs.pBLAS->GetDesc();
-
- if (Attribs.BoxDataCount > BLASDesc.BoxCount)
- {
- LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: BoxDataCount must be less than or equal to Attribs.pBLAS->GetDesc().BoxCount");
- return false;
- }
-
- if (Attribs.TriangleDataCount > BLASDesc.TriangleCount)
- {
- LOG_ERROR_MESSAGE("IDeviceContext::BuildBLAS: TriangleDataCount must be less than or equal to Attribs.pBLAS->GetDesc().TriangleCount");
- return false;
- }
-
const auto& ScratchDesc = Attribs.pScratchBuffer->GetDesc();
if (Attribs.ScratchBufferOffset > ScratchDesc.uiSizeInBytes)
@@ -2146,11 +2211,17 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLA
}
template <typename BaseInterface, typename ImplementationTraits>
-bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const TLASBuildAttribs& Attribs, int)
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const TLASBuildAttribs& Attribs, int) const
{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildTLAS: ray tracing is not supported by this device");
+ return false;
+ }
+
if (m_pActiveRenderPass != nullptr)
{
- LOG_ERROR_MESSAGE("BuildTLAS command must be performed outside of render pass");
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildTLAS command must be performed outside of render pass");
return false;
}
@@ -2201,9 +2272,11 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const TLA
// calculate instance data size
for (Uint32 i = 0; i < Attribs.InstanceCount; ++i)
{
- VERIFY_EXPR((Attribs.pInstances[i].CustomId & ~0x00FFFFFF) == 0);
- VERIFY_EXPR(Attribs.pInstances[i].ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO ||
- (Attribs.pInstances[i].ContributionToHitGroupIndex & ~0x00FFFFFF) == 0);
+ VERIFY((Attribs.pInstances[i].CustomId & ~0x00FFFFFF) == 0, "Only first 24 bits are used");
+
+ VERIFY(Attribs.pInstances[i].ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO ||
+ (Attribs.pInstances[i].ContributionToHitGroupIndex & ~0x00FFFFFF) == 0,
+ "Only first 24 bits are used");
if (Attribs.pInstances[i].InstanceName == nullptr)
{
@@ -2219,6 +2292,14 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const TLA
if (Attribs.pInstances[i].ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO)
++AutoOffsetCounter;
+
+
+ if (TLASDesc.BindingMode != SHADER_BINDING_USER_DEFINED && Attribs.pInstances[i].ContributionToHitGroupIndex != TLAS_INSTANCE_OFFSET_AUTO)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::BuildTLAS: pInstances[", i, "].ContributionToHitGroupIndex must be TLAS_INSTANCE_OFFSET_AUTO "
+ "if TLAS created with BindingMode that is not SHADER_BINDING_USER_DEFINED");
+ return false;
+ }
}
if (AutoOffsetCounter != 0 && AutoOffsetCounter != Attribs.InstanceCount)
@@ -2270,8 +2351,14 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const TLA
}
template <typename BaseInterface, typename ImplementationTraits>
-bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyBLAS(const CopyBLASAttribs& Attribs, int)
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyBLAS(const CopyBLASAttribs& Attribs, int) const
{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyBLAS: ray tracing is not supported by this device");
+ return false;
+ }
+
if (Attribs.pSrc == nullptr)
{
LOG_ERROR_MESSAGE("IDeviceContext::CopyBLAS: pSrc must not be null");
@@ -2286,11 +2373,17 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyBLAS(const Copy
if (m_pActiveRenderPass != nullptr)
{
- LOG_ERROR_MESSAGE("CopyBLAS command must be performed outside of render pass");
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyBLAS command must be performed outside of render pass");
return false;
}
#ifdef DILIGENT_DEVELOPMENT
+ if (!ValidatedCast<BottomLevelASType>(Attribs.pSrc)->ValidateContent())
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyBLAS: pSrc acceleration structure is not valid");
+ return false;
+ }
+
if (Attribs.Mode == COPY_AS_MODE_CLONE)
{
auto& SrcDesc = Attribs.pSrc->GetDesc();
@@ -2323,7 +2416,7 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyBLAS(const Copy
if (SrcTri.MaxVertexCount != DstTri.MaxVertexCount ||
SrcTri.VertexValueType != DstTri.VertexValueType ||
SrcTri.VertexComponentCount != DstTri.VertexComponentCount ||
- SrcTri.MaxIndexCount != DstTri.MaxIndexCount ||
+ SrcTri.MaxPrimitiveCount != DstTri.MaxPrimitiveCount ||
SrcTri.IndexType != DstTri.IndexType ||
SrcTri.AllowsTransforms != DstTri.AllowsTransforms)
// clang-format on
@@ -2342,6 +2435,23 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyBLAS(const Copy
}
}
}
+ else if (Attribs.Mode == COPY_AS_MODE_COMPACT)
+ {
+ auto& SrcDesc = Attribs.pSrc->GetDesc();
+ auto& DstDesc = Attribs.pDst->GetDesc();
+
+ if (!(SrcDesc.Flags & RAYTRACING_BUILD_AS_ALLOW_COMPACTION))
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyBLAS: pSrc must be create with RAYTRACING_BUILD_AS_ALLOW_COMPACTION flag");
+ return false;
+ }
+
+ if (DstDesc.CompactedSize == 0)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyBLAS: pDst must be create with defined CompactedSize");
+ return false;
+ }
+ }
else
{
LOG_ERROR_MESSAGE("IDeviceContext::CopyBLAS: unknown Mode");
@@ -2353,8 +2463,14 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyBLAS(const Copy
}
template <typename BaseInterface, typename ImplementationTraits>
-bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyTLAS(const CopyTLASAttribs& Attribs, int)
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyTLAS(const CopyTLASAttribs& Attribs, int) const
{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS: ray tracing is not supported by this device");
+ return false;
+ }
+
if (Attribs.pSrc == nullptr)
{
LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS: pSrc must not be null");
@@ -2369,14 +2485,14 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyTLAS(const Copy
if (m_pActiveRenderPass != nullptr)
{
- LOG_ERROR_MESSAGE("CopyTLAS command must be performed outside of render pass");
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS command must be performed outside of render pass");
return false;
}
#ifdef DILIGENT_DEVELOPMENT
- if (!ValidatedCast<TopLevelASType>(Attribs.pSrc)->CheckBLASVersion())
+ if (!ValidatedCast<TopLevelASType>(Attribs.pSrc)->ValidateContent())
{
- LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS: pSrc must be rebuilded to apply BLAS changes before being copied to another TLAS");
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS: pSrc acceleration structure is not valid");
return false;
}
@@ -2392,6 +2508,23 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyTLAS(const Copy
return false;
}
}
+ else if (Attribs.Mode == COPY_AS_MODE_COMPACT)
+ {
+ auto& SrcDesc = Attribs.pSrc->GetDesc();
+ auto& DstDesc = Attribs.pDst->GetDesc();
+
+ if (!(SrcDesc.Flags & RAYTRACING_BUILD_AS_ALLOW_COMPACTION))
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS: pSrc must be create with RAYTRACING_BUILD_AS_ALLOW_COMPACTION flag");
+ return false;
+ }
+
+ if (DstDesc.CompactedSize == 0)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS: pDst must be create with defined CompactedSize");
+ return false;
+ }
+ }
else
{
LOG_ERROR_MESSAGE("IDeviceContext::CopyTLAS: unknown Mode");
@@ -2403,8 +2536,104 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::CopyTLAS(const Copy
}
template <typename BaseInterface, typename ImplementationTraits>
-bool DeviceContextBase<BaseInterface, ImplementationTraits>::TraceRays(const TraceRaysAttribs& Attribs, int)
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs, int) const
{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteBLASCompactedSize: ray tracing is not supported by this device");
+ return false;
+ }
+
+ if (Attribs.pBLAS == nullptr)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteBLASCompactedSize: pBLAS must not be null");
+ return false;
+ }
+ if (!(Attribs.pBLAS->GetDesc().Flags & RAYTRACING_BUILD_AS_ALLOW_COMPACTION))
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteBLASCompactedSize: pBLAS must be created with RAYTRACING_BUILD_AS_ALLOW_COMPACTION flag");
+ return false;
+ }
+
+ if (Attribs.pDestBuffer == nullptr)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteBLASCompactedSize: pDestBuffer must not be null");
+ return false;
+ }
+ if (Attribs.DestBufferOffset + sizeof(Uint64) > Attribs.pDestBuffer->GetDesc().uiSizeInBytes)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteBLASCompactedSize: pDestBuffer is too small");
+ return false;
+ }
+ if (m_pDevice->GetDeviceCaps().DevType == RENDER_DEVICE_TYPE_D3D12 &&
+ !(Attribs.pDestBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS))
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteBLASCompactedSize: pDestBuffer must be created with BIND_UNORDERED_ACCESS flag");
+ return false;
+ }
+
+ if (m_pActiveRenderPass != nullptr)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteBLASCompactedSize: command must be performed outside of render pass");
+ return false;
+ }
+ return true;
+}
+
+template <typename BaseInterface, typename ImplementationTraits>
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs, int) const
+{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteTLASCompactedSize: ray tracing is not supported by this device");
+ return false;
+ }
+
+ if (Attribs.pTLAS == nullptr)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteTLASCompactedSize: pTLAS must not be null");
+ return false;
+ }
+ if (!(Attribs.pTLAS->GetDesc().Flags & RAYTRACING_BUILD_AS_ALLOW_COMPACTION))
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteTLASCompactedSize: pTLAS must be created with RAYTRACING_BUILD_AS_ALLOW_COMPACTION flag");
+ return false;
+ }
+
+ if (Attribs.pDestBuffer == nullptr)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteTLASCompactedSize: pDestBuffer must not be null");
+ return false;
+ }
+ if (Attribs.DestBufferOffset + sizeof(Uint64) > Attribs.pDestBuffer->GetDesc().uiSizeInBytes)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteTLASCompactedSize: pDestBuffer is too small");
+ return false;
+ }
+ if (m_pDevice->GetDeviceCaps().DevType == RENDER_DEVICE_TYPE_D3D12 &&
+ !(Attribs.pDestBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS))
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteTLASCompactedSize: pDestBuffer must be created with BIND_UNORDERED_ACCESS flag");
+ return false;
+ }
+
+ if (m_pActiveRenderPass != nullptr)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::WriteTLASCompactedSize: command must be performed outside of render pass");
+ return false;
+ }
+ return true;
+}
+
+template <typename BaseInterface, typename ImplementationTraits>
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::TraceRays(const TraceRaysAttribs& Attribs, int) const
+{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::TraceRays: ray tracing is not supported by this device");
+ return false;
+ }
+
if (Attribs.pSBT == nullptr)
{
LOG_ERROR_MESSAGE("IDeviceContext::TraceRays: pSBT must not be null");
@@ -2431,7 +2660,7 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::TraceRays(const Tra
return false;
}
- if (Attribs.pSBT->GetDesc().pPSO != m_pPipelineState)
+ if (Attribs.pSBT->GetDesc().pPSO != m_pPipelineState.RawPtr())
{
LOG_ERROR_MESSAGE("IDeviceContext::TraceRays command arguments are invalid: currently bound pipeline ", m_pPipelineState->GetDesc().Name,
"doesn't match the pipeline ", Attribs.pSBT->GetDesc().pPSO->GetDesc().Name, " that was used in ShaderBindingTable");
diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
index 6ce6280b..5a2db2f8 100644
--- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
+++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
@@ -228,13 +228,19 @@ public:
inline void CopyShaderHandle(const char* Name, void* pData, Uint32 DataSize) const
{
- VERIFY_EXPR(Name != nullptr && Name[0] != '\0');
VERIFY_EXPR(this->m_Desc.IsRayTracingPipeline());
VERIFY_EXPR(m_pRayTracingPipelineData != nullptr);
const auto ShaderHandleSize = m_pRayTracingPipelineData->ShaderHandleSize;
VERIFY_EXPR(ShaderHandleSize <= DataSize);
+ if (Name == nullptr || Name[0] == '\0')
+ {
+ // set shader binding to zero to skip shader execution
+ std::memset(pData, 0, ShaderHandleSize);
+ return;
+ }
+
auto iter = m_pRayTracingPipelineData->NameToGroupIndex.find(Name);
if (iter != m_pRayTracingPipelineData->NameToGroupIndex.end())
{
diff --git a/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp b/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp
index b5642a75..04870876 100644
--- a/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp
+++ b/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp
@@ -225,10 +225,133 @@ public:
Bool DILIGENT_CALL_TYPE Verify() const override final
{
- // AZ TODO
+ Uint32 ShCounter = 0;
+ Uint32 RecCounter = 0;
+ const auto Stride = this->m_ShaderRecordStride;
+ const auto ShSize = this->m_pDevice->GetShaderGroupHandleSize();
+ const auto FindPattern = [&ShCounter, &RecCounter, Stride, ShSize](const std::vector<Uint8>& Data, const char* Name) -> bool //
+ {
+ for (size_t i = 0; i < Data.size(); i += Stride)
+ {
+ Uint32 Count = 0;
+ for (size_t j = 0; j < ShSize; ++j)
+ Count += (Data[i + j] == EmptyElem);
+
+ if (Count == ShSize)
+ {
+ LOG_ERROR_MESSAGE("Shader binding table is not valid: shader in '", Name, "'(", i / Stride, ") is not bound");
+ return false;
+ }
+
+ Count = 0;
+ for (size_t j = ShSize; j < Stride; ++j)
+ Count += (Data[i + j] == EmptyElem);
+
+ if (Count > Stride - ShSize)
+ LOG_WARNING_MESSAGE("Shader binding table is not valid: shader record data in '", Name, "'(", i / Stride, ") is not initialized");
+ }
+ return true;
+ };
+
+ if (m_RayGenShaderRecord.empty())
+ {
+ LOG_ERROR_MESSAGE("Shader binding table is not valid: ray generation shader is not bound");
+ return false;
+ }
+
+ if (!FindPattern(m_RayGenShaderRecord, "ray generation") ||
+ !FindPattern(m_MissShadersRecord, "miss") ||
+ !FindPattern(m_CallableShadersRecord, "callable") ||
+ !FindPattern(m_HitGroupsRecord, "hit groups"))
+ return false;
+
return true;
}
+ struct BindingTable
+ {
+ const void* pData = nullptr;
+ Uint32 Size = 0;
+ Uint32 Offset = 0;
+ Uint32 Stride = 0;
+ };
+ void GetData(IBuffer*& pSBTBuffer,
+ BindingTable& RaygenShaderBindingTable,
+ BindingTable& MissShaderBindingTable,
+ BindingTable& HitShaderBindingTable,
+ BindingTable& CallableShaderBindingTable)
+ {
+ const auto ShaderGroupBaseAlignment = GetDevice()->GetShaderGroupBaseAlignment();
+
+ const auto AlignToLarger = [ShaderGroupBaseAlignment](size_t offset) -> Uint32 {
+ return Align(static_cast<Uint32>(offset), ShaderGroupBaseAlignment);
+ };
+
+ 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 (this->m_pBuffer == nullptr || this->m_pBuffer->GetDesc().uiSizeInBytes < BufSize)
+ {
+ this->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, &this->m_pBuffer);
+ VERIFY_EXPR(this->m_pBuffer != nullptr);
+ }
+
+ if (this->m_pBuffer == nullptr)
+ return; // something goes wrong
+
+ pSBTBuffer = this->m_pBuffer;
+
+ if (m_RayGenShaderRecord.size())
+ {
+ RaygenShaderBindingTable.pData = this->m_Changed ? m_RayGenShaderRecord.data() : nullptr;
+ RaygenShaderBindingTable.Offset = RayGenOffset;
+ RaygenShaderBindingTable.Size = static_cast<Uint32>(m_RayGenShaderRecord.size());
+ RaygenShaderBindingTable.Stride = this->m_ShaderRecordStride;
+ }
+
+ if (m_MissShadersRecord.size())
+ {
+ MissShaderBindingTable.pData = this->m_Changed ? m_MissShadersRecord.data() : nullptr;
+ MissShaderBindingTable.Offset = MissShaderOffset;
+ MissShaderBindingTable.Size = static_cast<Uint32>(m_MissShadersRecord.size());
+ MissShaderBindingTable.Stride = this->m_ShaderRecordStride;
+ }
+
+ if (m_HitGroupsRecord.size())
+ {
+ HitShaderBindingTable.pData = this->m_Changed ? m_HitGroupsRecord.data() : nullptr;
+ HitShaderBindingTable.Offset = HitGroupOffset;
+ HitShaderBindingTable.Size = static_cast<Uint32>(m_HitGroupsRecord.size());
+ HitShaderBindingTable.Stride = this->m_ShaderRecordStride;
+ }
+
+ if (m_CallableShadersRecord.size())
+ {
+ CallableShaderBindingTable.pData = this->m_Changed ? m_CallableShadersRecord.data() : nullptr;
+ CallableShaderBindingTable.Offset = CallableShadersOffset;
+ CallableShaderBindingTable.Size = static_cast<Uint32>(m_CallableShadersRecord.size());
+ CallableShaderBindingTable.Stride = this->m_ShaderRecordStride;
+ }
+
+ if (!this->m_Changed)
+ return;
+
+ this->m_Changed = false;
+ }
+
protected:
void ValidateShaderBindingTableDesc(const ShaderBindingTableDesc& Desc) const
{
@@ -270,6 +393,7 @@ protected:
std::vector<Uint8> m_HitGroupsRecord;
RefCntAutoPtr<PipelineStateImplType> m_pPSO;
+ RefCntAutoPtr<IBuffer> m_pBuffer;
Uint32 m_ShaderRecordSize = 0;
Uint32 m_ShaderRecordStride = 0;
diff --git a/Graphics/GraphicsEngine/include/TopLevelASBase.hpp b/Graphics/GraphicsEngine/include/TopLevelASBase.hpp
index b03d9e5c..a8896abb 100644
--- a/Graphics/GraphicsEngine/include/TopLevelASBase.hpp
+++ b/Graphics/GraphicsEngine/include/TopLevelASBase.hpp
@@ -33,6 +33,7 @@
#include <unordered_map>
#include "TopLevelAS.h"
+#include "BottomLevelAS.h"
#include "DeviceObjectBase.hpp"
#include "RenderDeviceBase.hpp"
#include "StringPool.hpp"
@@ -71,59 +72,66 @@ public:
{
}
- void SetInstanceData(const TLASBuildInstanceData* pInstances, Uint32 InstanceCount, Uint32 HitShadersPerInstance)
+ void SetInstanceData(const TLASBuildInstanceData* pInstances, Uint32 InstanceCount, Uint32 HitShadersPerInstance) noexcept
{
- this->m_Instances.clear();
- this->m_StringPool.Release();
- this->m_HitShadersPerInstance = HitShadersPerInstance;
-
- size_t StringPoolSize = 0;
- for (Uint32 i = 0; i < InstanceCount; ++i)
+ try
{
- StringPoolSize += strlen(pInstances[i].InstanceName) + 1;
- }
+ this->m_Instances.clear();
+ this->m_StringPool.Release();
+ this->m_HitShadersPerInstance = HitShadersPerInstance;
+
+ size_t StringPoolSize = 0;
+ for (Uint32 i = 0; i < InstanceCount; ++i)
+ {
+ StringPoolSize += strlen(pInstances[i].InstanceName) + 1;
+ }
- this->m_StringPool.Reserve(StringPoolSize, GetRawAllocator());
+ this->m_StringPool.Reserve(StringPoolSize, GetRawAllocator());
- Uint32 InstanceOffset = 0;
+ Uint32 InstanceOffset = 0;
- for (Uint32 i = 0; i < InstanceCount; ++i)
- {
- auto& inst = pInstances[i];
- const char* NameCopy = this->m_StringPool.CopyString(inst.InstanceName);
- InstanceDesc Desc = {};
+ for (Uint32 i = 0; i < InstanceCount; ++i)
+ {
+ auto& inst = pInstances[i];
+ const char* NameCopy = this->m_StringPool.CopyString(inst.InstanceName);
+ InstanceDesc Desc = {};
- Desc.ContributionToHitGroupIndex = inst.ContributionToHitGroupIndex;
- Desc.pBLAS = ValidatedCast<BottomLevelASType>(inst.pBLAS);
+ Desc.ContributionToHitGroupIndex = inst.ContributionToHitGroupIndex;
+ Desc.pBLAS = ValidatedCast<BottomLevelASType>(inst.pBLAS);
#ifdef DILIGENT_DEVELOPMENT
- Desc.Version = Desc.pBLAS->GetVersion();
+ Desc.Version = Desc.pBLAS->GetVersion();
#endif
- if (Desc.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO)
- {
- Desc.ContributionToHitGroupIndex = InstanceOffset;
- auto& BLASDesc = Desc.pBLAS->GetDesc();
- switch (this->m_Desc.BindingMode)
+ if (Desc.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO)
{
- // clang-format off
- case SHADER_BINDING_MODE_PER_GEOMETRY: InstanceOffset += (BLASDesc.TriangleCount + BLASDesc.BoxCount) * HitShadersPerInstance; break;
- case SHADER_BINDING_MODE_PER_INSTANCE: InstanceOffset += HitShadersPerInstance; break;
- case SHADER_BINDING_USER_DEFINED: UNEXPECTED("TLAS_INSTANCE_OFFSET_AUTO is not compatible with SHADER_BINDING_USER_DEFINED"); break;
- default: UNEXPECTED("unknown ray tracing shader binding mode");
- // clang-format on
+ Desc.ContributionToHitGroupIndex = InstanceOffset;
+ auto& BLASDesc = Desc.pBLAS->GetDesc();
+ switch (this->m_Desc.BindingMode)
+ {
+ // clang-format off
+ case SHADER_BINDING_MODE_PER_GEOMETRY: InstanceOffset += (BLASDesc.TriangleCount + BLASDesc.BoxCount) * HitShadersPerInstance; break;
+ case SHADER_BINDING_MODE_PER_INSTANCE: InstanceOffset += HitShadersPerInstance; break;
+ case SHADER_BINDING_USER_DEFINED: UNEXPECTED("TLAS_INSTANCE_OFFSET_AUTO is not compatible with SHADER_BINDING_USER_DEFINED"); break;
+ default: UNEXPECTED("unknown ray tracing shader binding mode");
+ // clang-format on
+ }
}
+
+ bool IsUniqueName = this->m_Instances.emplace(NameCopy, Desc).second;
+ if (!IsUniqueName)
+ LOG_ERROR_AND_THROW("Instance name must be unique!");
}
- bool IsUniqueName = this->m_Instances.emplace(NameCopy, Desc).second;
- if (!IsUniqueName)
- LOG_ERROR_AND_THROW("Instance name must be unique!");
+ VERIFY_EXPR(this->m_StringPool.GetRemainingSize() == 0);
+ }
+ catch (...)
+ {
+ this->m_Instances.clear();
}
-
- VERIFY_EXPR(this->m_StringPool.GetRemainingSize() == 0);
}
- void CopyInstancceData(const TopLevelASBase& Src)
+ void CopyInstancceData(const TopLevelASBase& Src) noexcept
{
this->m_Instances.clear();
this->m_StringPool.Release();
@@ -162,6 +170,8 @@ public:
virtual void DILIGENT_CALL_TYPE SetState(RESOURCE_STATE State) override final
{
+ VERIFY(State == RESOURCE_STATE_BUILD_AS_READ || State == RESOURCE_STATE_BUILD_AS_WRITE || State == RESOURCE_STATE_RAY_TRACING,
+ "Unsupported state for top-level acceleration structure");
this->m_State = State;
}
@@ -183,18 +193,42 @@ public:
}
#ifdef DILIGENT_DEVELOPMENT
- bool CheckBLASVersion() const
+ bool ValidateContent() const
{
+ bool result = true;
+
+ if (m_Instances.empty())
+ {
+ LOG_ERROR_MESSAGE("TLAS with name ('", GetDesc().Name, "') doesn't have instances, use IDeviceContext::BuildTLAS() or IDeviceContext::CopyTLAS() to initialize TLAS content");
+ result = false;
+ }
+
+ // validate instances
for (auto& NameAndInst : m_Instances)
{
- auto& Inst = NameAndInst.second;
+ const InstanceDesc& Inst = NameAndInst.second;
+ const BottomLevelASDesc& Desc = Inst.pBLAS->GetDesc();
+
if (Inst.Version != Inst.pBLAS->GetVersion())
{
- LOG_ERROR_MESSAGE("Instance with name ('", NameAndInst.first.GetStr(), "') has BLAS that was changed after TLAS build, you must rebuild TLAS.");
- return false;
+ LOG_ERROR_MESSAGE("Instance with name ('", NameAndInst.first.GetStr(), "') has BLAS with name ('", Desc.Name, "') that was changed after TLAS build, you must rebuild TLAS");
+ result = false;
+ }
+
+ if (Inst.pBLAS->GetState() != RESOURCE_STATE_BUILD_AS_READ)
+ {
+ LOG_ERROR_MESSAGE("Instance with name ('", NameAndInst.first.GetStr(), "') has BLAS with name ('", Desc.Name, "') that must be in BUILD_AS_READ state, but current state is ",
+ GetResourceStateFlagString(Inst.pBLAS->GetState()));
+ result = false;
+ }
+
+ if (!Inst.pBLAS->ValidateContent())
+ {
+ LOG_ERROR_MESSAGE("Instance with name ('", NameAndInst.first.GetStr(), "') has BLAS with name ('", Desc.Name, "') that is not valid");
+ result = false;
}
}
- return true;
+ return result;
}
#endif
@@ -203,15 +237,29 @@ protected:
{
#define LOG_TLAS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of Top-level AS '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__)
- if (Desc.MaxInstanceCount == 0)
+ if (Desc.CompactedSize > 0)
{
- LOG_TLAS_ERROR_AND_THROW("MaxInstanceCount must not be zero");
- }
+ if (Desc.MaxInstanceCount != 0)
+ {
+ LOG_TLAS_ERROR_AND_THROW("If CompactedSize is specified then MaxInstanceCount must be zero");
+ }
- if ((Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_TRACE) != 0 ||
- (Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_BUILD) != 0)
+ if (Desc.Flags != RAYTRACING_BUILD_AS_NONE)
+ {
+ LOG_TLAS_ERROR_AND_THROW("If CompactedSize is specified then Flags must be RAYTRACING_BUILD_AS_NONE");
+ }
+ }
+ else
{
- LOG_TLAS_ERROR_AND_THROW("RAYTRACING_BUILD_AS_PREFER_FAST_TRACE and RAYTRACING_BUILD_AS_PREFER_FAST_BUILD are invalid");
+ if (Desc.MaxInstanceCount == 0)
+ {
+ LOG_TLAS_ERROR_AND_THROW("MaxInstanceCount must not be zero");
+ }
+
+ if ((Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_TRACE) && (Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_BUILD))
+ {
+ LOG_TLAS_ERROR_AND_THROW("can not set both flags RAYTRACING_BUILD_AS_PREFER_FAST_TRACE and RAYTRACING_BUILD_AS_PREFER_FAST_BUILD");
+ }
}
#undef LOG_TLAS_ERROR_AND_THROW
diff --git a/Graphics/GraphicsEngine/interface/BottomLevelAS.h b/Graphics/GraphicsEngine/interface/BottomLevelAS.h
index d2f1ed0f..ac521756 100644
--- a/Graphics/GraphicsEngine/interface/BottomLevelAS.h
+++ b/Graphics/GraphicsEngine/interface/BottomLevelAS.h
@@ -46,39 +46,37 @@ static const INTERFACE_ID IID_BottomLevelAS =
/// Defines bottom level acceleration structure triangles description.
-/// AZ TODO
+/// Triangle geometry description.
struct BLASTriangleDesc
{
/// Geometry name.
- /// The name is used to map BLASBuildTriangleData to this geometry.
+ /// The name is used to map triangles data (BLASBuildTriangleData) to this geometry.
const char* GeometryName DEFAULT_INITIALIZER(nullptr);
/// The maximum vertex count for this geometry.
/// Current number of vertices is defined in BLASBuildTriangleData::VertexCount.
Uint32 MaxVertexCount DEFAULT_INITIALIZER(0);
- /// The type of vertices in this geometry.
- /// Float, Int16 are supported.
+ /// The type of vertices in this geometry, see Diligent::VALUE_TYPE.
VALUE_TYPE VertexValueType DEFAULT_INITIALIZER(VT_UNDEFINED);
/// The number of components in vertex.
/// 2 and 3 are supported.
Uint8 VertexComponentCount DEFAULT_INITIALIZER(0);
- /// The maximum index count for this geometry.
- /// The current number of indices is defined in BLASBuildTriangleData::IndexCount.
- /// It must be 0 if IndexType is VT_UNDEFINED and greater than zero otherwise.
- Uint32 MaxIndexCount DEFAULT_INITIALIZER(0);
+ /// The maximum primitive count of this geometry.
+ /// The current number of primitives is defined in BLASBuildTriangleData::PrimitiveCount.
+ Uint32 MaxPrimitiveCount DEFAULT_INITIALIZER(0);
- /// Index type of this geometry.
+ /// Index type of this geometry, see Diligent::VALUE_TYPE.
/// Must be VT_UINT16, VT_UINT32 or VT_UNDEFINED.
+ /// If not defined then used vertex array instead of indexed vertices.
VALUE_TYPE IndexType DEFAULT_INITIALIZER(VT_UNDEFINED);
- /// AZ TODO
+ /// Vulkan only, allows to use transformations in BLASBuildTriangleData.
Bool AllowsTransforms DEFAULT_INITIALIZER(False);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
BLASTriangleDesc() noexcept {}
#endif
};
@@ -87,11 +85,11 @@ typedef struct BLASTriangleDesc BLASTriangleDesc;
/// Defines bottom level acceleration structure axis aligned bounding boxes description.
-/// AZ TODO
+/// AABB geometry description.
struct BLASBoundingBoxDesc
{
/// Geometry name.
- /// The name is used to map BLASBuildBoundingBoxData to this geometry.
+ /// The name is used to map AABB data (BLASBuildBoundingBoxData) to this geometry.
const char* GeometryName DEFAULT_INITIALIZER(nullptr);
/// The maximum AABBs count.
@@ -99,25 +97,22 @@ struct BLASBoundingBoxDesc
Uint32 MaxBoxCount DEFAULT_INITIALIZER(0);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
BLASBoundingBoxDesc() noexcept {}
#endif
};
typedef struct BLASBoundingBoxDesc BLASBoundingBoxDesc;
-/// AZ TODO
-
-/// AZ TODO
+/// Defines acceleration structures build flags.
DILIGENT_TYPED_ENUM(RAYTRACING_BUILD_AS_FLAGS, Uint8)
{
- /// AZ TODO
RAYTRACING_BUILD_AS_NONE = 0,
- /// AZ TODO
+ /// AZ TODO: not supported yet
RAYTRACING_BUILD_AS_ALLOW_UPDATE = 0x01,
- /// Indicates that the specified acceleration structure can act as the source for a copy acceleration structure command
+ /// Indicates that the specified acceleration structure can act as the source for
+ /// a copy acceleration structure command IDeviceContext::CopyBLAS() or IDeviceContext::CopyTLAS()
/// with mode of COPY_AS_MODE_COMPACT to produce a compacted acceleration structure.
RAYTRACING_BUILD_AS_ALLOW_COMPACTION = 0x02,
@@ -131,15 +126,12 @@ DILIGENT_TYPED_ENUM(RAYTRACING_BUILD_AS_FLAGS, Uint8)
/// result build, potentially at the expense of build time or trace performance.
RAYTRACING_BUILD_AS_LOW_MEMORY = 0x10,
- RAYTRACING_BUILD_AS_FLAGS_LAST = 0x10
+ RAYTRACING_BUILD_AS_FLAGS_LAST = RAYTRACING_BUILD_AS_LOW_MEMORY
};
DEFINE_FLAG_ENUM_OPERATORS(RAYTRACING_BUILD_AS_FLAGS)
-/// AZ TODO
-
-// Here we allocate space for geometry data.
-// Geometry can be dynamically updated.
+/// Bottom-level AS description.
struct BottomLevelASDesc DILIGENT_DERIVE(DeviceObjectAttribs)
/// Array of triangle geometry descriptions.
@@ -156,29 +148,37 @@ struct BottomLevelASDesc DILIGENT_DERIVE(DeviceObjectAttribs)
/// Ray tracing build flags, see Diligent::RAYTRACING_BUILD_AS_FLAGS.
RAYTRACING_BUILD_AS_FLAGS Flags DEFAULT_INITIALIZER(RAYTRACING_BUILD_AS_NONE);
+
+ /// Size from the result of IDeviceContext::WriteBLASCompactedSize() if this acceleration structure
+ /// is going to be the target of a compacting copy (IDeviceContext::CopyBLAS() with COPY_AS_MODE_COMPACT).
+ Uint32 CompactedSize DEFAULT_INITIALIZER(0);
/// Defines which command queues this BLAS can be used with
Uint64 CommandQueueMask DEFAULT_INITIALIZER(1);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
BottomLevelASDesc() noexcept {}
#endif
};
typedef struct BottomLevelASDesc BottomLevelASDesc;
+
+/// Defines scratch buffer info for acceleration structure.
struct ScratchBufferSizes
{
+ /// Scratch buffer size for acceleration structure building.
Uint32 Build DEFAULT_INITIALIZER(0);
+
+ /// AZ TODO: not supported yet
Uint32 Update DEFAULT_INITIALIZER(0);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
ScratchBufferSizes() noexcept {}
#endif
};
typedef struct ScratchBufferSizes ScratchBufferSizes;
+
#define DILIGENT_INTERFACE_NAME IBottomLevelAS
#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
@@ -186,7 +186,9 @@ typedef struct ScratchBufferSizes ScratchBufferSizes;
IDeviceObjectInclusiveMethods; \
IBottomLevelASMethods BottomLevelAS
-/// AZ TODO
+/// Bottom-level AS interface
+
+/// Defines the methods to manipulate a BLAS object
DILIGENT_BEGIN_INTERFACE(IBottomLevelAS, IDeviceObject)
{
#if DILIGENT_CPP_INTERFACE
@@ -194,11 +196,16 @@ DILIGENT_BEGIN_INTERFACE(IBottomLevelAS, IDeviceObject)
virtual const BottomLevelASDesc& DILIGENT_CALL_TYPE GetDesc() const override = 0;
#endif
- /// AZ TODO
+ /// Returns geometry index that can be used in shader binding table.
+
+ /// \param [in] Name - Geometry name that specified in BLASTriangleDesc or BLASBoundingBoxDesc.
+ /// \return Geometry index.
VIRTUAL Uint32 METHOD(GetGeometryIndex)(THIS_
const char* Name) CONST PURE;
- /// AZ TODO
+ /// Returns scratch buffer info for current acceleration structure.
+
+ /// \return structure object.
VIRTUAL ScratchBufferSizes METHOD(GetScratchBufferSizes)(THIS) CONST PURE;
/// Returns native acceleration structure handle specific to the underlying graphics API
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index 0cb7fe7d..6c035ded 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -719,10 +719,10 @@ struct BeginRenderPassAttribs
};
typedef struct BeginRenderPassAttribs BeginRenderPassAttribs;
-/// AZ TODO
+
+/// TLAS instance flags that used in IDeviceContext::BuildTLAS().
DILIGENT_TYPED_ENUM(RAYTRACING_INSTANCE_FLAGS, Uint8)
{
- /// AZ TODO
RAYTRACING_INSTANCE_NONE = 0,
/// Disables face culling for this instance.
@@ -734,38 +734,40 @@ DILIGENT_TYPED_ENUM(RAYTRACING_INSTANCE_FLAGS, Uint8)
RAYTRACING_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x02,
/// Causes this instance to act as though RAYTRACING_GEOMETRY_FLAGS_OPAQUE were specified on all
- /// geometries referenced by this instance. This behavior can be overridden by the SPIR-V NoOpaqueKHR ray flag.
+ /// geometries referenced by this instance. This behavior can be overridden in shader by ray flags.
RAYTRACING_INSTANCE_FORCE_OPAQUE = 0x04,
- /// causes this instance to act as though RAYTRACING_GEOMETRY_FLAGS_OPAQUE were not specified on all
- /// geometries referenced by this instance. This behavior can be overridden by the SPIR-V OpaqueKHR ray flag.
+ /// Causes this instance to act as though RAYTRACING_GEOMETRY_FLAGS_OPAQUE were not specified on all
+ /// geometries referenced by this instance. This behavior can be overridden shader by ray flags.
RAYTRACING_INSTANCE_FORCE_NO_OPAQUE = 0x08,
RAYTRACING_INSTANCE_FLAGS_LAST = RAYTRACING_INSTANCE_FORCE_NO_OPAQUE
};
DEFINE_FLAG_ENUM_OPERATORS(RAYTRACING_INSTANCE_FLAGS)
-/// AZ TODO
+
+/// Defines acceleration structure copy mode.
+
+/// These flags are used by IDeviceContext::CopyBLAS() and IDeviceContext::CopyTLAS().
DILIGENT_TYPED_ENUM(COPY_AS_MODE, Uint8)
{
- /// Creates a direct copy of the acceleration structure specified in src into the one specified by dst.
- /// The dst acceleration structure must have been created with the same parameters as src.
+ /// Creates a direct copy of the acceleration structure specified in pSrc into the one specified by pDst.
+ /// The pDst acceleration structure must have been created with the same parameters as pSrc.
COPY_AS_MODE_CLONE = 0,
- // creates a more compact version of an acceleration structure src into dst.
- // The acceleration structure dst must have been created with a compactedSize corresponding to the one returned by vkCmdWriteAccelerationStructuresPropertiesKHR
- // after the build of the acceleration structure specified by src.
- //COPY_AS_MODE_COMPACT,
+ /// Creates a more compact version of an acceleration structure pSrc into pDst.
+ /// The acceleration structure pDst must have been created with a CompactedSize corresponding
+ /// to the one returned by IDeviceContext::WriteBLASCompactedSize() or IDeviceContext::WriteTLASCompactedSize()
+ /// after the build of the acceleration structure specified by pSrc.
+ COPY_AS_MODE_COMPACT,
- COPY_AS_MODE_LAST = COPY_AS_MODE_CLONE,
+ COPY_AS_MODE_LAST = COPY_AS_MODE_COMPACT,
};
-/// Defines geometry flags for ray tracing.
-/// AZ TODO
+/// Defines geometry flags for ray tracing.
DILIGENT_TYPED_ENUM(RAYTRACING_GEOMETRY_FLAGS, Uint8)
{
- /// AZ TODO
RAYTRACING_GEOMETRY_NONE = 0,
/// Indicates that this geometry does not invoke the any-hit shaders even if present in a hit group.
@@ -779,148 +781,168 @@ DILIGENT_TYPED_ENUM(RAYTRACING_GEOMETRY_FLAGS, Uint8)
};
DEFINE_FLAG_ENUM_OPERATORS(RAYTRACING_GEOMETRY_FLAGS)
-/// AZ TODO
+
+/// Triangle geometry data description.
struct BLASBuildTriangleData
{
- // put geometry data to geometry that allocated by BLASTriangleDesc
+ /// Geometry name used to map geometry to hit group in shader binding table.
+ /// Put geometry data to geometry that allocated by BLASTriangleDesc with the same name.
const char* GeometryName DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- IBuffer* pVertexBuffer DEFAULT_INITIALIZER(nullptr); // specs: Triangles are considered "inactive" (but legal input to acceleration structure build) if the x component of each vertex is NaN
+ /// Triangle vertices data source.
+ /// Triangles are considered "inactive" if the x component of each vertex is NaN.
+ /// Buffer must be created with BIND_RAY_TRACING flag.
+ IBuffer* pVertexBuffer DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Data offset in bytes in pVertexBuffer.
Uint32 VertexOffset DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Stride in bytes between each vertex.
Uint32 VertexStride DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Number of triangle vertices.
+ /// Must be less than or equal to BLASTriangleDesc::MaxVertexCount.
Uint32 VertexCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
- VALUE_TYPE VertexValueType DEFAULT_INITIALIZER(VT_UNDEFINED); // optional, value may be taken from declaration
- Uint8 VertexComponentCount DEFAULT_INITIALIZER(0); // optional, value may be taken from declaration
-
- // optional
+ /// The type of vertex and number of components.
+ /// This is optional values. Must be undefined or same as in BLASTriangleDesc.
+ VALUE_TYPE VertexValueType DEFAULT_INITIALIZER(VT_UNDEFINED);
+ Uint8 VertexComponentCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Number of triangles.
+ /// Must equal to VertexCount / 3 if pIndexBuffer is null or must equal to index count / 3.
+ Uint32 PrimitiveCount DEFAULT_INITIALIZER(0);
+
+ /// Triangle indices data source.
+ /// Must be null if BLASTriangleDesc::IndexType is undefined.
+ /// Buffer must be created with BIND_RAY_TRACING flag.
IBuffer* pIndexBuffer DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Data offset in bytes in pIndexBuffer.
Uint32 IndexOffset DEFAULT_INITIALIZER(0);
- /// AZ TODO
- Uint32 IndexCount DEFAULT_INITIALIZER(0); // AZ TODO: use PrimitveCount ?
+ /// Type of triangle indices, see Diligent::VALUE_TYPE.
+ /// This is optional value. Must be undefined or same as in BLASTriangleDesc.
+ VALUE_TYPE IndexType DEFAULT_INITIALIZER(VT_UNDEFINED);
- /// AZ TODO
- VALUE_TYPE IndexType DEFAULT_INITIALIZER(VT_UNDEFINED); // optional, value may be taken from declaration
-
- // optional, buffer that contains 3x4 matrix with local transformation for this triangles/mesh
-
- /// AZ TODO
+ /// Geometry transformation data source.
+ /// Buffer must be created with BIND_RAY_TRACING flag.
IBuffer* pTransformBuffer DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Data offset in bytes in pTransformBuffer.
Uint32 TransformBufferOffset DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Geometry flags.
RAYTRACING_GEOMETRY_FLAGS Flags DEFAULT_INITIALIZER(RAYTRACING_GEOMETRY_NONE);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
BLASBuildTriangleData() noexcept {}
#endif
};
typedef struct BLASBuildTriangleData BLASBuildTriangleData;
-/// AZ TODO
+
+/// AABB geometry data description.
struct BLASBuildBoundingBoxData
{
- /// AZ TODO
- // put geometry data to geometry that allocated by BLASBoundingBoxDesc
+ /// Geometry name used to map geometry to hit group in shader binding table.
+ /// Put geometry data to geometry that allocated by BLASBoundingBoxDesc with the same name.
const char* GeometryName DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- IBuffer* pBoxBuffer DEFAULT_INITIALIZER(nullptr); // specs: AABBs are considered inactive if AABB.MinX is NaN
+ /// AABB data source.
+ /// Each AABB defined as { float3 Min; float3 Max } structure.
+ /// AABB are considered inactive if AABB.Min.x is NaN.
+ /// Buffer must be created with BIND_RAY_TRACING flag.
+ IBuffer* pBoxBuffer DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Data offset in bytes in pBoxBuffer.
Uint32 BoxOffset DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Stride in bytes between each AABB.
Uint32 BoxStride DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Number of AABBs.
+ /// Must be less than or equal to BLASBoundingBoxDesc::MaxBoxCount.
Uint32 BoxCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Geometry flags, see Diligent::RAYTRACING_GEOMETRY_FLAGS.
RAYTRACING_GEOMETRY_FLAGS Flags DEFAULT_INITIALIZER(RAYTRACING_GEOMETRY_NONE);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
BLASBuildBoundingBoxData() noexcept {}
#endif
};
typedef struct BLASBuildBoundingBoxData BLASBuildBoundingBoxData;
-/// AZ TODO
+/// This structure is used by IDeviceContext::BuildBLAS().
struct BLASBuildAttribs
{
- /// AZ TODO
+ /// Target bottom-level AS.
IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr);
-
- /// AZ TODO
+
+ /// Bottom-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
RESOURCE_STATE_TRANSITION_MODE BLASTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
- /// AZ TODO
+ /// Geometry data source buffers state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
RESOURCE_STATE_TRANSITION_MODE GeometryTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
- /// AZ TODO
+ /// A pointer to an array of TriangleDataCount BLASBuildTriangleData structures that contains triangle geometry data.
BLASBuildTriangleData const* pTriangleData DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Number of triangle grometries.
+ /// Must be less than or equal to BottomLevelASDesc::TriangleCount.
Uint32 TriangleDataCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// A pointer to an array of BoxDataCount BLASBuildBoundingBoxData structures that contains AABB geometry data.
BLASBuildBoundingBoxData const* pBoxData DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Number of AABB geometries.
+ /// Must be less than or equal to BottomLevelASDesc::BoxCount.
Uint32 BoxDataCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Buffer that used for acceleration structure building.
+ /// Must be created with BIND_RAY_TRACING.
+ /// Call IBottomLevelAS::GetScratchBufferSizes().Build to get minimal size for scratch buffer.
IBuffer* pScratchBuffer DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Offset from the beginning of the buffer.
Uint32 ScratchBufferOffset DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Scratch buffer state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
RESOURCE_STATE_TRANSITION_MODE ScratchBufferTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
BLASBuildAttribs() noexcept {}
#endif
};
typedef struct BLASBuildAttribs BLASBuildAttribs;
-/// AZ TODO
+/// Can be used in TLASBuildInstanceData::ContributionToHitGroupIndex to calculate index
+/// depending on geometry count in TLASBuildInstanceData::pBLAS and shader binding mode in TopLevelASDesc::BindingMode.
+///
+/// Example:
+/// For each instance in TLAS
+/// if (Instance.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO)
+/// Instance.ContributionToHitGroupIndex = InstanceOffset;
+/// if (BindingMode == SHADER_BINDING_MODE_PER_GEOMETRY) InstanceOffset += Instance.pBLAS->GeometryCount() * HitShadersPerInstance;
+/// if (BindingMode == SHADER_BINDING_MODE_PER_INSTANCE) InstanceOffset += HitShadersPerInstance;
static const Uint32 TLAS_INSTANCE_OFFSET_AUTO = ~0u;
-/// AZ TODO
-static const Uint32 TLAS_INSTANCE_DATA_SIZE = 64;
-/// AZ TODO
+/// Row-major matrix
struct InstanceMatrix
{
- /// rotation translation
- /// (0 1 2) [ 3]
- /// (4 5 6) [ 7]
- /// (8 9 10) [11]
+ /// (0.0 1.0 2.0)
+ /// (0.1 1.1 2.1) - rotation
+ /// (0.2 1.2 2.2)
+ ///
+ /// [0.3 1.3 2.3] - translation
float data [3][4];
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
+ /// Construct identity matrix.
InstanceMatrix() noexcept :
data{{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
@@ -928,7 +950,8 @@ struct InstanceMatrix
{}
InstanceMatrix(const InstanceMatrix&) noexcept = default;
-
+
+ /// Set matrix translation.
InstanceMatrix& SetTranslation(float x, float y, float z) noexcept
{
data[0][3] = x;
@@ -936,151 +959,229 @@ struct InstanceMatrix
data[2][3] = z;
return *this;
}
+
+ /// Set matrix rotation basis.
+ InstanceMatrix& SetRotation(const float* pMatrix3x3) noexcept
+ {
+ data[0][0] = pMatrix3x3[0]; data[1][0] = pMatrix3x3[1]; data[2][0] = pMatrix3x3[2];
+ data[0][1] = pMatrix3x3[3]; data[1][1] = pMatrix3x3[4]; data[2][1] = pMatrix3x3[5];
+ data[0][2] = pMatrix3x3[6]; data[1][2] = pMatrix3x3[7]; data[2][2] = pMatrix3x3[8];
+ return *this;
+ }
#endif
};
typedef struct InstanceMatrix InstanceMatrix;
-/// AZ TODO
+
+/// This structure is used by TLASBuildAttribs.
struct TLASBuildInstanceData
{
- /// AZ TODO
+ /// Instance name that used to map instance to hit group in shader binding table.
const char* InstanceName DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr); // can be null to deactive instance
+ /// Bottom-level AS that represents instance geometry.
+ IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Instace to world transformation.
InstanceMatrix Transform;
- /// AZ TODO
- Uint32 CustomId DEFAULT_INITIALIZER(0); // 24 bits, in shader: gl_InstanceCustomIndexNV for GLSL, InstanceID() for HLSL
+ /// User-defined value that can be accessed in shader via InstanceID() in HLSL and gl_InstanceCustomIndex in GLSL.
+ /// Used only first 24 bits.
+ Uint32 CustomId DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Instance flags, see Diligent::RAYTRACING_INSTANCE_FLAGS.
RAYTRACING_INSTANCE_FLAGS Flags DEFAULT_INITIALIZER(RAYTRACING_INSTANCE_NONE);
- /// AZ TODO
- Uint8 Mask DEFAULT_INITIALIZER(0xFF); // visibility mask for the geometry, the instance may only be hit if rayMask & instance.mask != 0
+ /// Visibility mask for the geometry, the instance may only be hit if rayMask & instance.Mask != 0.
+ /// (rayMask in GLSL is a cullMask argument of traceRayEXT(), rayMask in HLSL is a InstanceInclusionMask argument of TraceRay()).
+ Uint8 Mask DEFAULT_INITIALIZER(0xFF);
- /// AZ TODO
- Uint32 ContributionToHitGroupIndex DEFAULT_INITIALIZER(TLAS_INSTANCE_OFFSET_AUTO); // used when TLAS created with SHADER_BINDING_USER_DEFINED, see IShaderBindingTangle::BindAll()
+ /// Index used to calculate hit group location in shader binding table.
+ /// Must be TLAS_INSTANCE_OFFSET_AUTO is TLAS created with BindingMode SHADER_BINDING_MODE_PER_GEOMETRY or SHADER_BINDING_MODE_PER_INSTANCE.
+ /// Used only first 24 bits.
+ Uint32 ContributionToHitGroupIndex DEFAULT_INITIALIZER(TLAS_INSTANCE_OFFSET_AUTO);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
TLASBuildInstanceData() noexcept {}
#endif
};
typedef struct TLASBuildInstanceData TLASBuildInstanceData;
-/// AZ TODO
+/// Instance size in GPU side.
+/// Used to calculate size of TLASBuildAttribs::pInstanceBuffer.
+static const Uint32 TLAS_INSTANCE_DATA_SIZE = 64;
+
+
+/// This structure is used by IDeviceContext::BuildTLAS().
struct TLASBuildAttribs
{
- /// AZ TODO
+ /// Target top-level AS.
ITopLevelAS* pTLAS DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Top-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
RESOURCE_STATE_TRANSITION_MODE TLASTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
- /// AZ TODO
+ /// Bottom-level AS (in TLASBuildInstanceData::pBLAS) state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
RESOURCE_STATE_TRANSITION_MODE BLASTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
-
- /// AZ TODO
+
+ /// A pointer to an array of InstanceCount TLASBuildInstanceData structures that contains instance data.
TLASBuildInstanceData const* pInstances DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Number of instances.
+ /// Must be less than or equal to TopLevelASDesc::MaxInstanceCount.
Uint32 InstanceCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Buffer that will be used to store instance data during AS building.
+ /// Buffer size must be at least TLAS_INSTANCE_DATA_SIZE * InstanceCount.
+ /// Buffer must be created with BIND_RAY_TRACING flag.
IBuffer* pInstanceBuffer DEFAULT_INITIALIZER(nullptr);
-
- /// AZ TODO
+
+ /// Offset from the beginning of the buffer to location of instance data.
Uint32 InstanceBufferOffset DEFAULT_INITIALIZER(0);
-
- /// AZ TODO
+
+ /// Instance buffer state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
RESOURCE_STATE_TRANSITION_MODE InstanceBufferTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
/// AZ TODO
Uint32 HitShadersPerInstance DEFAULT_INITIALIZER(1);
-
- /// AZ TODO
+
+ /// Buffer that used for acceleration structure building.
+ /// Must be created with BIND_RAY_TRACING.
+ /// Call ITopLevelAS::GetScratchBufferSizes().Build to get minimal size for scratch buffer.
IBuffer* pScratchBuffer DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Offset from the beginning of the buffer.
Uint32 ScratchBufferOffset DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Scratch buffer state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
RESOURCE_STATE_TRANSITION_MODE ScratchBufferTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
TLASBuildAttribs() noexcept {}
#endif
};
typedef struct TLASBuildAttribs TLASBuildAttribs;
-/// AZ TODO
+/// This structure is used by IDeviceContext::CopyBLAS().
struct CopyBLASAttribs
{
- /// AZ TODO
- IBottomLevelAS* pSrc DEFAULT_INITIALIZER(nullptr);
+ /// Source bottom-level AS.
+ IBottomLevelAS* pSrc DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- IBottomLevelAS* pDst DEFAULT_INITIALIZER(nullptr);
+ /// Destination bottom-level AS.
+ /// If Mode is COPY_AS_MODE_COMPACT then pDst must be created with CompactedSize
+ /// that is greater or equal to size that returned by IDeviceContext::WriteBLASCompactedSize.
+ IBottomLevelAS* pDst DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- COPY_AS_MODE Mode DEFAULT_INITIALIZER(COPY_AS_MODE_CLONE);
+ /// Acceleration structure copy mode, see Diligent::COPY_AS_MODE.
+ COPY_AS_MODE Mode DEFAULT_INITIALIZER(COPY_AS_MODE_CLONE);
- /// AZ TODO
- RESOURCE_STATE_TRANSITION_MODE TransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+ /// Source bottom-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE SrcTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+ /// Destination bottom-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE DstTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
CopyBLASAttribs() noexcept {}
#endif
};
typedef struct CopyBLASAttribs CopyBLASAttribs;
-/// AZ TODO
+/// This structure is used by IDeviceContext::CopyTLAS().
struct CopyTLASAttribs
{
- /// AZ TODO
- ITopLevelAS* pSrc DEFAULT_INITIALIZER(nullptr);
+ /// Source top-level AS.
+ ITopLevelAS* pSrc DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- ITopLevelAS* pDst DEFAULT_INITIALIZER(nullptr);
+ /// Destination top-level AS.
+ /// If Mode is COPY_AS_MODE_COMPACT then pDst must be created with CompactedSize
+ /// that is greater or equal to size that returned by IDeviceContext::WriteTLASCompactedSize.
+ ITopLevelAS* pDst DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- COPY_AS_MODE Mode DEFAULT_INITIALIZER(COPY_AS_MODE_CLONE);
+ /// Acceleration structure copy mode, see Diligent::COPY_AS_MODE.
+ COPY_AS_MODE Mode DEFAULT_INITIALIZER(COPY_AS_MODE_CLONE);
- /// AZ TODO
- RESOURCE_STATE_TRANSITION_MODE TransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+ /// Source top-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE SrcTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+ /// Destination top-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE DstTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
CopyTLASAttribs() noexcept {}
#endif
};
typedef struct CopyTLASAttribs CopyTLASAttribs;
-/// AZ TODO
+/// This structure is used by IDeviceContext::WriteBLASCompactedSize().
+struct WriteBLASCompactedSizeAttribs
+{
+ /// Bottom-level AS.
+ IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr);
+
+ /// Command will writes 64 bit value with acceleration structure compacted size into buffer.
+ IBuffer* pDestBuffer DEFAULT_INITIALIZER(nullptr);
+
+ /// Offset from the beginning of the buffer to location of AS compacted size.
+ Uint32 DestBufferOffset DEFAULT_INITIALIZER(0);
+
+ /// Bottom-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE BLASTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+ /// Destination buffer state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE BufferTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+#if DILIGENT_CPP_INTERFACE
+ WriteBLASCompactedSizeAttribs() noexcept {}
+#endif
+};
+typedef struct WriteBLASCompactedSizeAttribs WriteBLASCompactedSizeAttribs;
+
+
+/// This structure is used by IDeviceContext::WriteTLASCompactedSize().
+struct WriteTLASCompactedSizeAttribs
+{
+ /// Top-level AS.
+ ITopLevelAS* pTLAS DEFAULT_INITIALIZER(nullptr);
+
+ /// Command will writes 64 bit value with acceleration structure compacted size into buffer.
+ IBuffer* pDestBuffer DEFAULT_INITIALIZER(nullptr);
+
+ /// Offset from the beginning of the buffer to location of AS compacted size.
+ Uint32 DestBufferOffset DEFAULT_INITIALIZER(0);
+
+ /// Top-level AS state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE TLASTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+ /// Destination buffer state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE BufferTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+#if DILIGENT_CPP_INTERFACE
+ WriteTLASCompactedSizeAttribs() noexcept {}
+#endif
+};
+typedef struct WriteTLASCompactedSizeAttribs WriteTLASCompactedSizeAttribs;
+
+
+/// This structure is used by IDeviceContext::TraceRays().
struct TraceRaysAttribs
{
- /// AZ TODO
- IShaderBindingTable* pSBT DEFAULT_INITIALIZER(nullptr);
+ /// Shader binding table.
+ IShaderBindingTable* pSBT DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- Uint32 DimensionX DEFAULT_INITIALIZER(1);
- Uint32 DimensionY DEFAULT_INITIALIZER(1);
- Uint32 DimensionZ DEFAULT_INITIALIZER(1);
+ Uint32 DimensionX DEFAULT_INITIALIZER(1); ///< Number of rays dispatched in X direction.
+ Uint32 DimensionY DEFAULT_INITIALIZER(1); ///< Number of rays dispatched in Y direction.
+ Uint32 DimensionZ DEFAULT_INITIALIZER(1); ///< Number of rays dispatched in Z direction.
- /// AZ TODO
- RESOURCE_STATE_TRANSITION_MODE TransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+ /// Shader binding table buffer state transition mode (see Diligent::RESOURCE_STATE_TRANSITION_MODE).
+ RESOURCE_STATE_TRANSITION_MODE SBTTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
TraceRaysAttribs() noexcept {}
#endif
};
@@ -1981,23 +2082,52 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject)
ITexture* pDstTexture,
const ResolveTextureSubresourceAttribs REF ResolveAttribs) PURE;
- /// AZ TODO
+
+ /// Build Bottom-level acceleration structure with the specified geometries.
+
+ /// \param [in] Attribs - Structure describing build BLAS command attributes, see Diligent::BLASBuildAttribs for details.
VIRTUAL void METHOD(BuildBLAS)(THIS_
const BLASBuildAttribs REF Attribs) PURE;
- /// AZ TODO
+
+ /// Build Top-level acceleration structure with the specified instances.
+
+ /// \param [in] Attribs - Structure describing build TLAS command attributes, see Diligent::TLASBuildAttribs for details.
VIRTUAL void METHOD(BuildTLAS)(THIS_
const TLASBuildAttribs REF Attribs) PURE;
- /// AZ TODO
+
+ /// Copies data from one acceleration structure to another.
+
+ /// \param [in] Attribs - Structure describing copy BLAS command attributes, see Diligent::CopyBLASAttribs for details.
VIRTUAL void METHOD(CopyBLAS)(THIS_
const CopyBLASAttribs REF Attribs) PURE;
- /// AZ TODO
+
+ /// Copies data from one acceleration structure to another.
+
+ /// \param [in] Attribs - Structure describing copy TLAS command attributes, see Diligent::CopyTLASAttribs for details.
VIRTUAL void METHOD(CopyTLAS)(THIS_
const CopyTLASAttribs REF Attribs) PURE;
- /// AZ TODO
+
+ /// Writes acceleration structure memory size to the buffer for compacting operation.
+
+ /// \param [in] Attribs - Structure describing write BLAS compacted size command attributes, see Diligent::WriteBLASCompactedSizeAttribs for details.
+ VIRTUAL void METHOD(WriteBLASCompactedSize)(THIS_
+ const WriteBLASCompactedSizeAttribs REF Attribs) PURE;
+
+
+ /// Writes acceleration structure memory size to the buffer for compacting operation.
+
+ /// \param [in] Attribs - Structure describing write TLAS compacted size command attributes, see Diligent::WriteTLASCompactedSizeAttribs for details.
+ VIRTUAL void METHOD(WriteTLASCompactedSize)(THIS_
+ const WriteTLASCompactedSizeAttribs REF Attribs) PURE;
+
+
+ /// Executes a trace rays command.
+
+ /// \param [in] Attribs - Trace rays command attributes, see Diligent::TraceRaysAttribs for details.
VIRTUAL void METHOD(TraceRays)(THIS_
const TraceRaysAttribs REF Attribs) PURE;
};
@@ -2054,6 +2184,8 @@ DILIGENT_END_INTERFACE
# define IDeviceContext_BuildTLAS(This, ...) CALL_IFACE_METHOD(DeviceContext, BuildTLAS, This, __VA_ARGS__)
# define IDeviceContext_CopyBLAS(This, ...) CALL_IFACE_METHOD(DeviceContext, CopyBLAS, This, __VA_ARGS__)
# define IDeviceContext_CopyTLAS(This, ...) CALL_IFACE_METHOD(DeviceContext, CopyTLAS, This, __VA_ARGS__)
+# define IDeviceContext_WriteBLASCompactedSize(This, ...) CALL_IFACE_METHOD(DeviceContext, WriteBLASCompactedSize, This, __VA_ARGS__)
+# define IDeviceContext_WriteTLASCompactedSize(This, ...) CALL_IFACE_METHOD(DeviceContext, WriteTLASCompactedSize, This, __VA_ARGS__)
# define IDeviceContext_TraceRays(This, ...) CALL_IFACE_METHOD(DeviceContext, TraceRays, This, __VA_ARGS__)
// clang-format on
diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
index 76f8dcd6..cd32efc4 100644
--- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h
+++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
@@ -2731,9 +2731,14 @@ DILIGENT_TYPED_ENUM(RESOURCE_STATE, Uint32)
/// The resource is used for present
RESOURCE_STATE_PRESENT = 0x10000,
- /// AZ TODO
+ /// The resource is used as vertex/index/instance buffer in a AS building operation
+ /// or as acceleration structure source in a AS copy operation.
RESOURCE_STATE_BUILD_AS_READ = 0x20000,
+
+ /// The resource is used as target in a AS building or AS copy operations.
RESOURCE_STATE_BUILD_AS_WRITE = 0x40000,
+
+ /// The resource is used as top-level AS shader resource in a trace rays operation.
RESOURCE_STATE_RAY_TRACING = 0x80000,
RESOURCE_STATE_MAX_BIT = RESOURCE_STATE_RAY_TRACING,
diff --git a/Graphics/GraphicsEngine/interface/PipelineState.h b/Graphics/GraphicsEngine/interface/PipelineState.h
index ebec8344..a630b1f1 100644
--- a/Graphics/GraphicsEngine/interface/PipelineState.h
+++ b/Graphics/GraphicsEngine/interface/PipelineState.h
@@ -152,7 +152,7 @@ typedef struct PipelineResourceLayoutDesc PipelineResourceLayoutDesc;
/// Graphics pipeline state description
-/// This structure describes the graphics pipeline state and is part of the PipelineStateDesc structure.
+/// This structure describes the graphics pipeline state and is part of the GraphicsPipelineStateCreateInfo structure.
struct GraphicsPipelineDesc
{
/// Blend state description.
@@ -215,13 +215,13 @@ struct GraphicsPipelineDesc
typedef struct GraphicsPipelineDesc GraphicsPipelineDesc;
-/// AZ TODO
+/// Ray tracing general shader group description
struct RayTracingGeneralShaderGroup
{
- /// AZ TODO
+ /// Unique group name.
const char* Name DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Shader type must be SHADER_TYPE_RAY_GEN or SHADER_TYPE_RAY_MISS or SHADER_TYPE_CALLABLE.
IShader* pShader DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
@@ -237,16 +237,18 @@ struct RayTracingGeneralShaderGroup
};
typedef struct RayTracingGeneralShaderGroup RayTracingGeneralShaderGroup;
-/// AZ TODO
+/// Ray tracing triangle hit shader group description.
struct RayTracingTriangleHitShaderGroup
{
- /// AZ TODO
+ /// Unique group name.
const char* Name DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Closest hit shader.
+ /// Shader type must be SHADER_TYPE_RAY_CLOSEST_HIT.
IShader* pClosestHitShader DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Any-hit shader. Can be null.
+ /// Shader type must be SHADER_TYPE_RAY_ANY_HIT.
IShader* pAnyHitShader DEFAULT_INITIALIZER(nullptr); // can be null
#if DILIGENT_CPP_INTERFACE
@@ -264,20 +266,23 @@ struct RayTracingTriangleHitShaderGroup
};
typedef struct RayTracingTriangleHitShaderGroup RayTracingTriangleHitShaderGroup;
-/// AZ TODO
+/// Ray tracing procedural hit shader group description.
struct RayTracingProceduralHitShaderGroup
{
- /// AZ TODO
+ /// Unique group name.
const char* Name DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
+ /// Intersection shader.
+ /// Shader type must be SHADER_TYPE_RAY_INTERSECTION.
IShader* pIntersectionShader DEFAULT_INITIALIZER(nullptr);
-
- /// AZ TODO
- IShader* pClosestHitShader DEFAULT_INITIALIZER(nullptr); // can be null
-
- /// AZ TODO
- IShader* pAnyHitShader DEFAULT_INITIALIZER(nullptr); // can be null
+
+ /// Closest hit shader. Can be null.
+ /// Shader type must be SHADER_TYPE_RAY_CLOSEST_HIT.
+ IShader* pClosestHitShader DEFAULT_INITIALIZER(nullptr);
+
+ /// Any-hit shader. Can be null.
+ /// Shader type must be SHADER_TYPE_RAY_ANY_HIT.
+ IShader* pAnyHitShader DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
RayTracingProceduralHitShaderGroup() noexcept
@@ -296,14 +301,16 @@ struct RayTracingProceduralHitShaderGroup
};
typedef struct RayTracingProceduralHitShaderGroup RayTracingProceduralHitShaderGroup;
-/// AZ TODO
+/// This structure describes the ray tracing pipeline state and is part of the RayTracingPipelineStateCreateInfo structure.
struct RayTracingPipelineDesc
{
- // Size of the additional data passed to the shader.
- Uint16 ShaderRecordSize DEFAULT_INITIALIZER(0);
+ /// Size of the additional data passed to the shader.
+ /// Shader record size plus shader group size (32 bytes) must be aligned to 32 bytes.
+ /// Shader record size plus shader group size (32 bytes) must not exceed 4096 bytes.
+ Uint16 ShaderRecordSize DEFAULT_INITIALIZER(0);
- /// AZ TODO
- Uint8 MaxRecursionDepth DEFAULT_INITIALIZER(0); // must be 0..31 (check current device limits)
+ /// Number of recursive call of TraceRay() in HLSL or traceRay() in GLSL.
+ Uint8 MaxRecursionDepth DEFAULT_INITIALIZER(0); // must be 0..31 (check current device limits)
};
typedef struct RayTracingPipelineDesc RayTracingPipelineDesc;
@@ -440,26 +447,28 @@ typedef struct ComputePipelineStateCreateInfo ComputePipelineStateCreateInfo;
/// Ray tracing pipeline state description.
struct RayTracingPipelineStateCreateInfo DILIGENT_DERIVE(PipelineStateCreateInfo)
- /// AZ TODO
+ /// Ray tracing pipeline description.
RayTracingPipelineDesc RayTracingPipeline;
- /// AZ TODO
+ /// A pointer to an array of GeneralShaderCount RayTracingGeneralShaderGroup structures that contains shader group description.
const RayTracingGeneralShaderGroup* pGeneralShaders DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- const RayTracingTriangleHitShaderGroup* pTriangleHitShaders DEFAULT_INITIALIZER(nullptr); // can be null
+ /// Number of general shader groups.
+ Uint32 GeneralShaderCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
- const RayTracingProceduralHitShaderGroup* pProceduralHitShaders DEFAULT_INITIALIZER(nullptr); // can be null
+ /// A pointer to an array of TriangleHitShaderCount RayTracingTriangleHitShaderGroup structures that contains shader group description.
+ /// Can be null.
+ const RayTracingTriangleHitShaderGroup* pTriangleHitShaders DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- Uint16 GeneralShaderCount DEFAULT_INITIALIZER(0);
+ /// Number of triangle hit shader groups.
+ Uint32 TriangleHitShaderCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
- Uint16 TriangleHitShaderCount DEFAULT_INITIALIZER(0);
+ /// A pointer to an array of ProceduralHitShaderCount RayTracingProceduralHitShaderGroup structures that contains shader group description.
+ /// Can be null.
+ const RayTracingProceduralHitShaderGroup* pProceduralHitShaders DEFAULT_INITIALIZER(nullptr);
- /// AZ TODO
- Uint16 ProceduralHitShaderCount DEFAULT_INITIALIZER(0);
+ /// Number of procedural shader groups.
+ Uint32 ProceduralHitShaderCount DEFAULT_INITIALIZER(0);
/// Direct3D12 only: set name of constant buffer that will be used by local root signature.
/// Ignored if RayTracingPipelineDesc::ShaderRecordSize is zero.
@@ -575,11 +584,16 @@ DILIGENT_BEGIN_INTERFACE(IPipelineState, IDeviceObject)
VIRTUAL bool METHOD(IsCompatibleWith)(THIS_
const struct IPipelineState* pPSO) CONST PURE;
- /// AZ TODO
+
+ /// Returns index of shader group that is used by shader binding table.
+ /// This method must only be called for a ray tracing pipeline.
+
+ /// \param [in] Name - Shader group name.
VIRTUAL Uint32 METHOD(GetShaderGroupIndex)(THIS_
const char* Name) CONST PURE;
- /// AZ TODO
+
+ /// AZ TODO: remove ?
VIRTUAL Uint32 METHOD(GetShaderGroupCount)(THIS) CONST PURE;
};
DILIGENT_END_INTERFACE
diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h
index 28e0bb17..fddffeba 100644
--- a/Graphics/GraphicsEngine/interface/Shader.h
+++ b/Graphics/GraphicsEngine/interface/Shader.h
@@ -356,7 +356,7 @@ DILIGENT_TYPED_ENUM(SHADER_RESOURCE_TYPE, Uint8)
/// Input attachment in a render pass
SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT,
- /// AZ TODO
+ /// Acceleration structure
SHADER_RESOURCE_TYPE_ACCEL_STRUCT,
SHADER_RESOURCE_TYPE_LAST = SHADER_RESOURCE_TYPE_ACCEL_STRUCT
diff --git a/Graphics/GraphicsEngine/interface/ShaderBindingTable.h b/Graphics/GraphicsEngine/interface/ShaderBindingTable.h
index d6f0740f..da650349 100644
--- a/Graphics/GraphicsEngine/interface/ShaderBindingTable.h
+++ b/Graphics/GraphicsEngine/interface/ShaderBindingTable.h
@@ -46,17 +46,16 @@ static const INTERFACE_ID IID_ShaderBindingTable =
// clang-format off
-/// AZ TODO
+/// Shader binding table description.
struct ShaderBindingTableDesc DILIGENT_DERIVE(DeviceObjectAttribs)
- /// AZ TODO
+ /// Ray tracing pipeline state object from which shaders will be taken.
IPipelineState* pPSO DEFAULT_INITIALIZER(nullptr);
/// AZ TODO
Uint32 HitShadersPerInstance DEFAULT_INITIALIZER(1);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
ShaderBindingTableDesc() noexcept {}
#endif
};
@@ -89,7 +88,6 @@ struct BindAllAttribs
Uint32 HitSRDataSize DEFAULT_INITIALIZER(0); // stride will be calculated as (HitSRDataSize / HitGroupCount)
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
BindAllAttribs() noexcept {}
#endif
};
@@ -102,7 +100,9 @@ typedef struct BindAllAttribs BindAllAttribs;
IDeviceObjectInclusiveMethods; \
IShaderBindingTableMethods ShaderBindingTable
-/// AZ TODO
+/// Shader binding table interface
+
+/// Defines the methods to manipulate a SBT object
DILIGENT_BEGIN_INTERFACE(IShaderBindingTable, IDeviceObject)
{
#if DILIGENT_CPP_INTERFACE
diff --git a/Graphics/GraphicsEngine/interface/TopLevelAS.h b/Graphics/GraphicsEngine/interface/TopLevelAS.h
index 630f8ddd..2efd8518 100644
--- a/Graphics/GraphicsEngine/interface/TopLevelAS.h
+++ b/Graphics/GraphicsEngine/interface/TopLevelAS.h
@@ -45,7 +45,7 @@ static const INTERFACE_ID IID_TopLevelAS =
// clang-format off
-/// AZ TODO
+/// Defines shader binding mode.
DILIGENT_TYPED_ENUM(SHADER_BINDING_MODE, Uint8)
{
/// Each geometry in each instance can have a unique shader.
@@ -58,41 +58,44 @@ DILIGENT_TYPED_ENUM(SHADER_BINDING_MODE, Uint8)
SHADER_BINDING_USER_DEFINED,
};
-/// AZ TODO
+
+/// Top-level AS description.
struct TopLevelASDesc DILIGENT_DERIVE(DeviceObjectAttribs)
- /// Here we allocate space for instances.
- /// Instances can be dynamicaly updated.
+ /// Allocate space for specified number of instances.
Uint32 MaxInstanceCount DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Ray tracing build flags, see Diligent::RAYTRACING_BUILD_AS_FLAGS.
RAYTRACING_BUILD_AS_FLAGS Flags DEFAULT_INITIALIZER(RAYTRACING_BUILD_AS_NONE);
+
+ /// Size from the result of IDeviceContext::WriteTLASCompactedSize() if this acceleration structure
+ /// is going to be the target of a compacting copy (IDeviceContext::CopyTLAS() with COPY_AS_MODE_COMPACT).
+ Uint32 CompactedSize DEFAULT_INITIALIZER(0);
- // binding mode used for instanceOffset calculation.
+ /// Binding mode that used for TLASBuildInstanceData::ContributionToHitGroupIndex calculation,
+ /// see Diligent::SHADER_BINDING_MODE.
SHADER_BINDING_MODE BindingMode DEFAULT_INITIALIZER(SHADER_BINDING_MODE_PER_GEOMETRY);
- /// Defines which command queues this BLAS can be used with
+ /// Defines which command queues this BLAS can be used with.
Uint64 CommandQueueMask DEFAULT_INITIALIZER(1);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
TopLevelASDesc() noexcept {}
#endif
};
typedef struct TopLevelASDesc TopLevelASDesc;
-/// AZ TODO
+/// Top-level AS instance description.
struct TLASInstanceDesc
{
- /// AZ TODO
+ /// Index that specified in TLASBuildInstanceData::ContributionToHitGroupIndex.
Uint32 ContributionToHitGroupIndex DEFAULT_INITIALIZER(0);
- /// AZ TODO
+ /// Bottom-level AS that specified in TLASBuildInstanceData::pBLAS.
IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
- /// AZ TODO
TLASInstanceDesc() noexcept {}
#endif
};
@@ -106,7 +109,9 @@ typedef struct TLASInstanceDesc TLASInstanceDesc;
IDeviceObjectInclusiveMethods; \
ITopLevelASMethods TopLevelAS
-/// AZ TODO
+/// Top-level AS interface
+
+/// Defines the methods to manipulate a TLAS object
DILIGENT_BEGIN_INTERFACE(ITopLevelAS, IDeviceObject)
{
#if DILIGENT_CPP_INTERFACE
@@ -114,11 +119,16 @@ DILIGENT_BEGIN_INTERFACE(ITopLevelAS, IDeviceObject)
virtual const TopLevelASDesc& DILIGENT_CALL_TYPE GetDesc() const override = 0;
#endif
- /// AZ TODO
+ /// Returns instance description that can be used in shader binding table.
+
+ /// \param [in] Name - Instance name that specified in TLASBuildInstanceData::InstanceName.
+ /// \return structure object.
VIRTUAL TLASInstanceDesc METHOD(GetInstanceDesc)(THIS_
const char* Name) CONST PURE;
- /// AZ TODO
+ /// Returns scratch buffer info for current acceleration structure.
+
+ /// \return structure object.
VIRTUAL ScratchBufferSizes METHOD(GetScratchBufferSizes)(THIS) CONST PURE;
/// Returns native acceleration structure handle specific to the underlying graphics API
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
index 5be505a1..0eea2efe 100644
--- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
@@ -262,6 +262,12 @@ public:
/// Implementation of IDeviceContext::CopyTLAS().
virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::WriteBLASCompactedSize().
+ virtual void DILIGENT_CALL_TYPE WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::WriteTLASCompactedSize().
+ virtual void DILIGENT_CALL_TYPE WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) override final;
+
/// Implementation of IDeviceContext::TraceRays().
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
index 54c9b3c4..c59f7165 100755
--- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
@@ -2319,6 +2319,16 @@ void DeviceContextD3D11Impl::CopyTLAS(const CopyTLASAttribs& Attribs)
UNSUPPORTED("CopyTLAS is not supported in DirectX 11");
}
+void DeviceContextD3D11Impl::WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs)
+{
+ UNSUPPORTED("CopyTLAS is not supported in DirectX 11");
+}
+
+void DeviceContextD3D11Impl::WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs)
+{
+ UNSUPPORTED("CopyTLAS is not supported in DirectX 11");
+}
+
void DeviceContextD3D11Impl::TraceRays(const TraceRaysAttribs& Attribs)
{
UNSUPPORTED("TraceRays is not supported in DirectX 11");
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()
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
index 32055367..b851a017 100644
--- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
@@ -259,6 +259,12 @@ public:
/// Implementation of IDeviceContext::CopyTLAS() in OpenGL backend.
virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::WriteBLASCompactedSize() in OpenGL backend.
+ virtual void DILIGENT_CALL_TYPE WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::WriteTLASCompactedSize() in OpenGL backend.
+ virtual void DILIGENT_CALL_TYPE WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) override final;
+
/// Implementation of IDeviceContext::TraceRays() in OpenGL backend.
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index 7b09f9ce..8fdb05b6 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -1740,6 +1740,16 @@ void DeviceContextGLImpl::CopyTLAS(const CopyTLASAttribs& Attribs)
UNSUPPORTED("CopyTLAS is not supported in OpenGL");
}
+void DeviceContextGLImpl::WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs)
+{
+ UNSUPPORTED("WriteBLASCompactedSize is not supported in OpenGL");
+}
+
+void DeviceContextGLImpl::WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs)
+{
+ UNSUPPORTED("WriteTLASCompactedSize is not supported in OpenGL");
+}
+
void DeviceContextGLImpl::TraceRays(const TraceRaysAttribs& Attribs)
{
UNSUPPORTED("TraceRays is not supported in OpenGL");
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
index 40e19d80..39dca08d 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
@@ -266,6 +266,12 @@ public:
/// Implementation of IDeviceContext::CopyTLAS() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::WriteBLASCompactedSize() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) override final;
+
+ /// Implementation of IDeviceContext::WriteTLASCompactedSize() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) override final;
+
/// Implementation of IDeviceContext::TraceRays() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
@@ -470,6 +476,8 @@ private:
void DvpLogRenderPass_PSOMismatch();
+ void CreateASCompactedSizeQueryPool();
+
VulkanUtilities::VulkanCommandBuffer m_CommandBuffer;
const Uint32 m_NumCommandsToFlush = 192;
@@ -551,6 +559,8 @@ private:
Int32 m_ActiveQueriesCounter = 0;
std::vector<VkClearValue> m_vkClearValues;
+
+ VulkanUtilities::QueryPoolWrapper m_ASQueryPool;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
index 5440a6c8..556e3aa5 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
@@ -205,6 +205,15 @@ public:
{
return GetPhysicalDevice().GetExtProperties().RayTracing.maxShaderGroupStride;
}
+ Uint32 GetShaderGroupBaseAlignment() const
+ {
+ return GetPhysicalDevice().GetExtProperties().RayTracing.shaderGroupBaseAlignment;
+ }
+
+ Uint32 GetMaxDrawMeshTasksCount() const
+ {
+ return GetPhysicalDevice().GetExtProperties().MeshShader.maxDrawMeshTasksCount;
+ }
private:
template <typename PSOCreateInfoType>
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
index cef50a4e..ab43ab80 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
@@ -54,17 +54,7 @@ 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 GetVkStridedBufferRegions(IDeviceContextVk* pContext,
- RESOURCE_STATE_TRANSITION_MODE TransitionMode,
- VkStridedBufferRegionKHR& RaygenShaderBindingTable,
- VkStridedBufferRegionKHR& MissShaderBindingTable,
- VkStridedBufferRegionKHR& HitShaderBindingTable,
- VkStridedBufferRegionKHR& CallableShaderBindingTable) override;
-
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderBindingTableVk, TShaderBindingTableBase);
-
-private:
- RefCntAutoPtr<IBuffer> m_pBuffer;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
index 44b75187..bee3de1f 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
@@ -197,6 +197,11 @@ public:
/* 16 */ const char* const Name;
/* 24 */ const ShaderResourceLayoutVk& ParentResLayout;
+
+#ifdef DILIGENT_DEBUG
+/* 32 */ const Uint32 BufferStaticSize;
+/* 36 */ const Uint32 BufferStride;
+#endif
// clang-format on
VkResource(const ShaderResourceLayoutVk& _ParentLayout,
@@ -210,7 +215,9 @@ public:
uint32_t _DescriptorSet,
Uint32 _CacheOffset,
Uint32 _SamplerInd,
- bool _ImmutableSamplerAssigned = false) noexcept :
+ bool _ImmutableSamplerAssigned,
+ Uint32 _BufferStaticSize,
+ Uint32 _BufferStride) noexcept :
// clang-format off
Binding {static_cast<decltype(Binding)>(_Binding) },
DescriptorSet {static_cast<decltype(DescriptorSet)>(_DescriptorSet)},
@@ -222,11 +229,15 @@ public:
Type {_Type },
ResourceDim {_ResourceDim },
IsMS {_IsMS ? Uint8{1} : Uint8{0}},
- Name {_Name },
- ParentResLayout {_ParentLayout }
+#ifdef DILIGENT_DEBUG
+ BufferStaticSize {_BufferStaticSize},
+ BufferStride {_BufferStride },
+#endif
+ Name {_Name },
+ ParentResLayout {_ParentLayout }
// clang-format on
{
-#if defined(_MSC_VER) && defined(_WIN64)
+#if defined(_MSC_VER) && defined(_WIN64) && !defined(DILIGENT_DEBUG)
static_assert(sizeof(*this) == 32, "Unexpected sizeof(VkResource)");
#endif
// clang-format off
diff --git a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
index 0f8a94c8..8f2b42ab 100644
--- a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
@@ -58,7 +58,7 @@ public:
virtual void* DILIGENT_CALL_TYPE GetNativeHandle() override final
{
auto Handle = GetVkTLAS();
- return reinterpret_cast<void*>(Handle);
+ return reinterpret_cast<void*>(Handle); // AZ TODO: fix for 32 bit platform
}
/// Implementation of ITopLevelASVk::GetVkTLAS().
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
index 50a4c99f..8a21fb17 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
@@ -637,6 +637,21 @@ public:
#endif
}
+ __forceinline void WriteAccelerationStructuresProperties(VkAccelerationStructureKHR accelerationStructure, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery)
+ {
+#if DILIGENT_USE_VOLK
+ VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
+ if (m_State.RenderPass != VK_NULL_HANDLE)
+ {
+ // Write AS properties operations must be performed outside of render pass.
+ EndRenderPass();
+ }
+ vkCmdWriteAccelerationStructuresPropertiesKHR(m_VkCmdBuffer, 1, &accelerationStructure, queryType, queryPool, firstQuery);
+#else
+ UNSUPPORTED("Ray tracing is not supported when vulkan library is linked statically");
+#endif
+ }
+
__forceinline void TraceRays(const VkStridedBufferRegionKHR& RaygenShaderBindingTable,
const VkStridedBufferRegionKHR& MissShaderBindingTable,
const VkStridedBufferRegionKHR& HitShaderBindingTable,
diff --git a/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h b/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h
index d879faac..ee4ea3c8 100644
--- a/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h
@@ -50,14 +50,6 @@ static const INTERFACE_ID IID_ShaderBindingTableVk =
/// Exposes Vulkan-specific functionality of a Shader binding table object.
DILIGENT_BEGIN_INTERFACE(IShaderBindingTableVk, IShaderBindingTable)
{
- /// AZ TODO
- VIRTUAL void METHOD(GetVkStridedBufferRegions)(THIS_
- IDeviceContextVk* pContext,
- RESOURCE_STATE_TRANSITION_MODE TransitionMode,
- VkStridedBufferRegionKHR REF RaygenShaderBindingTable,
- VkStridedBufferRegionKHR REF MissShaderBindingTable,
- VkStridedBufferRegionKHR REF HitShaderBindingTable,
- VkStridedBufferRegionKHR REF CallableShaderBindingTable) PURE;
};
DILIGENT_END_INTERFACE
// clang-format on
@@ -66,8 +58,6 @@ DILIGENT_END_INTERFACE
#if DILIGENT_C_INTERFACE
-# define IShaderBindingTableVk_GetVkStridedBufferRegions(This, ...) CALL_IFACE_METHOD(ShaderBindingTableVk, GetVkStridedBufferRegions, This, __VA_ARGS__)
-
#endif
DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
index a1172130..cc16c9e4 100644
--- a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
@@ -45,63 +45,69 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
VkAccelerationStructureCreateInfoKHR CreateInfo = {};
std::vector<VkAccelerationStructureCreateGeometryTypeInfoKHR> Geometries;
- CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
- CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
- CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags);
- CreateInfo.maxGeometryCount = std::max(m_Desc.BoxCount, m_Desc.TriangleCount);
- CreateInfo.compactedSize = 0; // AZ TODO
+ CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
+ CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
+ CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags);
- VERIFY_EXPR(CreateInfo.maxGeometryCount <= Limits.maxGeometryCount);
+ if (m_Desc.CompactedSize > 0)
+ {
+ CreateInfo.compactedSize = m_Desc.CompactedSize;
+ }
+ else
+ {
+ CreateInfo.maxGeometryCount = m_Desc.TriangleCount + m_Desc.BoxCount;
+ Geometries.resize(CreateInfo.maxGeometryCount);
+ CreateInfo.pGeometryInfos = Geometries.data();
- Geometries.resize(CreateInfo.maxGeometryCount);
- CreateInfo.pGeometryInfos = Geometries.data();
+ VERIFY_EXPR(CreateInfo.maxGeometryCount <= Limits.maxGeometryCount);
- // Specs says: the geometryType member of each geometry in pGeometries must be the same.
- if (m_Desc.pTriangles != nullptr)
- {
- Uint32 MaxPrimitiveCount = 0;
- for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i)
+ if (m_Desc.pTriangles != nullptr)
{
- auto& src = m_Desc.pTriangles[i];
- auto& dst = Geometries[i];
-
- dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
- dst.pNext = nullptr;
- dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
- dst.maxPrimitiveCount = (src.IndexType == VT_UNDEFINED ? src.MaxVertexCount : src.MaxIndexCount) / 3;
- dst.indexType = TypeToVkIndexType(src.IndexType);
- dst.maxVertexCount = src.MaxVertexCount;
- dst.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16);
- dst.allowsTransforms = src.AllowsTransforms;
-
- MaxPrimitiveCount += dst.maxPrimitiveCount;
+
+ Uint32 MaxPrimitiveCount = 0;
+ for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i)
+ {
+ auto& src = m_Desc.pTriangles[i];
+ auto& dst = Geometries[i];
+
+ dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
+ dst.pNext = nullptr;
+ dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
+ dst.maxPrimitiveCount = src.MaxPrimitiveCount;
+ dst.indexType = TypeToVkIndexType(src.IndexType);
+ dst.maxVertexCount = src.MaxVertexCount;
+ dst.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16);
+ dst.allowsTransforms = src.AllowsTransforms;
+
+ MaxPrimitiveCount += dst.maxPrimitiveCount;
+ }
+ VERIFY_EXPR(MaxPrimitiveCount <= Limits.maxPrimitiveCount);
}
- VERIFY_EXPR(MaxPrimitiveCount <= Limits.maxPrimitiveCount);
- }
- else if (m_Desc.pBoxes != nullptr)
- {
- Uint32 MaxBoxCount = 0;
- for (uint32_t i = 0; i < m_Desc.BoxCount; ++i)
+ else if (m_Desc.pBoxes != nullptr)
{
- auto& src = m_Desc.pBoxes[i];
- auto& dst = Geometries[i];
-
- dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
- dst.pNext = nullptr;
- dst.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR;
- dst.maxPrimitiveCount = src.MaxBoxCount;
- dst.indexType = VK_INDEX_TYPE_NONE_KHR;
- dst.maxVertexCount = 0;
- dst.vertexFormat = VK_FORMAT_UNDEFINED;
- dst.allowsTransforms = VK_FALSE;
-
- MaxBoxCount += dst.maxPrimitiveCount;
+ Uint32 MaxBoxCount = 0;
+ for (uint32_t i = 0; i < m_Desc.BoxCount; ++i)
+ {
+ auto& src = m_Desc.pBoxes[i];
+ auto& dst = Geometries[i];
+
+ dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
+ dst.pNext = nullptr;
+ dst.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR;
+ dst.maxPrimitiveCount = src.MaxBoxCount;
+ dst.indexType = VK_INDEX_TYPE_NONE_KHR;
+ dst.maxVertexCount = 0;
+ dst.vertexFormat = VK_FORMAT_UNDEFINED;
+ dst.allowsTransforms = VK_FALSE;
+
+ MaxBoxCount += dst.maxPrimitiveCount;
+ }
+ VERIFY_EXPR(MaxBoxCount <= Limits.maxPrimitiveCount);
+ }
+ else
+ {
+ UNEXPECTED("Either pTriangles or pBoxes must not be null");
}
- VERIFY_EXPR(MaxBoxCount <= Limits.maxPrimitiveCount);
- }
- else
- {
- UNEXPECTED("Either pTriangles or pBoxes must not be null");
}
m_VulkanBLAS = LogicalDevice.CreateAccelStruct(CreateInfo, m_Desc.Name);
@@ -132,13 +138,18 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
m_DeviceAddress = LogicalDevice.GetAccelerationStructureDeviceAddress(m_VulkanBLAS);
- MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR;
- MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
- m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size);
+ if (m_Desc.CompactedSize == 0)
+ {
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size);
+
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size);
+ }
- MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
- MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
- m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size);
+ SetState(RESOURCE_STATE_BUILD_AS_READ);
}
BottomLevelASVkImpl::~BottomLevelASVkImpl()
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index a77fb96d..a76a901e 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -117,6 +117,8 @@ DeviceContextVkImpl::DeviceContextVkImpl(IReferenceCounters* p
m_DummyVB = pDummyVB.RawPtr<BufferVkImpl>();
m_vkClearValues.reserve(16);
+
+ CreateASCompactedSizeQueryPool();
}
DeviceContextVkImpl::~DeviceContextVkImpl()
@@ -592,16 +594,6 @@ void DeviceContextVkImpl::DrawMesh(const DrawMeshAttribs& Attribs)
if (!DvpVerifyDrawMeshArguments(Attribs))
return;
-#ifdef DILIGENT_DEBUG
- {
- const auto& PhysicalDevice = m_pDevice->GetPhysicalDevice();
- const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
- const auto& MeshShaderFeats = LogicalDevice.GetEnabledExtFeatures().MeshShader;
- VERIFY_EXPR(MeshShaderFeats.meshShader != VK_FALSE && MeshShaderFeats.taskShader != VK_FALSE);
- VERIFY_EXPR(Attribs.ThreadGroupCount <= PhysicalDevice.GetExtProperties().MeshShader.maxDrawMeshTasksCount);
- }
-#endif
-
PrepareForDraw(Attribs.Flags);
m_CommandBuffer.DrawMesh(Attribs.ThreadGroupCount, 0);
@@ -613,13 +605,6 @@ void DeviceContextVkImpl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Attrib
if (!DvpVerifyDrawMeshIndirectArguments(Attribs, pAttribsBuffer))
return;
-#ifdef DILIGENT_DEBUG
- {
- const auto& MeshShaderFeats = m_pDevice->GetLogicalDevice().GetEnabledExtFeatures().MeshShader;
- VERIFY_EXPR(MeshShaderFeats.meshShader != VK_FALSE && MeshShaderFeats.taskShader != VK_FALSE);
- }
-#endif
-
// We must prepare indirect draw attribs buffer first because state transitions must
// be performed outside of render pass, and PrepareForDraw commits render pass
BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectDrawAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode);
@@ -2684,9 +2669,9 @@ void DeviceContextVkImpl::TransitionOrVerifyTLASState(TopLevelASVkImpl&
DvpVerifyTLASState(TLAS, RequiredState, OperationName);
}
- if (RequiredState & RESOURCE_STATE_RAY_TRACING)
+ if (RequiredState & (RESOURCE_STATE_RAY_TRACING | RESOURCE_STATE_BUILD_AS_READ))
{
- TLAS.CheckBLASVersion();
+ TLAS.ValidateContent();
}
#endif
}
@@ -2812,13 +2797,6 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
if (!TDeviceContextBase::BuildBLAS(Attribs, 0))
return;
-#ifdef DILIGENT_DEBUG
- {
- const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
- VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE);
- }
-#endif
-
auto* pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pBLAS);
auto* pScratchVk = ValidatedCast<BufferVkImpl>(Attribs.pScratchBuffer);
auto& BLASDesc = pBLASVk->GetDesc();
@@ -2842,9 +2820,6 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
{
const auto& SrcTris = Attribs.pTriangleData[i];
Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcTris.GeometryName);
- auto& vkGeo = Geometries[GeoIdx];
- auto& vkTris = vkGeo.geometry.triangles;
- auto& off = Offsets[GeoIdx];
if (GeoIdx >= Geometries.size())
{
@@ -2852,6 +2827,11 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
continue;
}
+ auto& vkGeo = Geometries[GeoIdx];
+ auto& vkTris = vkGeo.geometry.triangles;
+ auto& off = Offsets[GeoIdx];
+ const auto& TriDesc = BLASDesc.pTriangles[GeoIdx];
+
vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
vkGeo.pNext = nullptr;
vkGeo.flags = GeometryFlagsToVkGeometryFlags(SrcTris.Flags);
@@ -2859,8 +2839,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
vkTris.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
vkTris.pNext = nullptr;
- auto* const pVB = ValidatedCast<BufferVkImpl>(SrcTris.pVertexBuffer);
- vkTris.vertexFormat = TypeToVkFormat(SrcTris.VertexValueType, SrcTris.VertexComponentCount, SrcTris.VertexValueType < VT_FLOAT16);
+ auto* const pVB = ValidatedCast<BufferVkImpl>(SrcTris.pVertexBuffer);
+
+ // vertex format in SrcTris may be undefined, so use vertex format from description
+ vkTris.vertexFormat = TypeToVkFormat(TriDesc.VertexValueType, TriDesc.VertexComponentCount, TriDesc.VertexValueType < VT_FLOAT16);
vkTris.vertexStride = SrcTris.VertexStride;
vkTris.vertexData.deviceAddress = pVB->GetVkDeviceAddress() + SrcTris.VertexOffset;
@@ -2868,10 +2850,11 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
if (SrcTris.pIndexBuffer)
{
- auto* const pIB = ValidatedCast<BufferVkImpl>(SrcTris.pIndexBuffer);
- vkTris.indexType = TypeToVkIndexType(SrcTris.IndexType);
+ auto* const pIB = ValidatedCast<BufferVkImpl>(SrcTris.pIndexBuffer);
+
+ // index type in SrcTris may be undefined, so use index type from description
+ vkTris.indexType = TypeToVkIndexType(TriDesc.IndexType);
vkTris.indexData.deviceAddress = pIB->GetVkDeviceAddress() + SrcTris.IndexOffset;
- off.primitiveCount = SrcTris.IndexCount / 3;
TransitionOrVerifyBufferState(*pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName);
}
@@ -2879,13 +2862,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
{
vkTris.indexType = VK_INDEX_TYPE_NONE_KHR;
vkTris.indexData.deviceAddress = 0;
- off.primitiveCount = SrcTris.VertexCount / 3;
}
if (SrcTris.pTransformBuffer)
{
- VERIFY_EXPR(BLASDesc.pTriangles[GeoIdx].AllowsTransforms);
-
auto* const pTB = ValidatedCast<BufferVkImpl>(SrcTris.pTransformBuffer);
vkTris.transformData.deviceAddress = pTB->GetVkDeviceAddress() + SrcTris.TransformBufferOffset;
@@ -2893,10 +2873,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
}
else
{
- VERIFY_EXPR(!BLASDesc.pTriangles[GeoIdx].AllowsTransforms);
vkTris.transformData.deviceAddress = 0;
}
+ off.primitiveCount = SrcTris.PrimitiveCount;
off.firstVertex = 0;
off.primitiveOffset = 0;
off.transformOffset = 0;
@@ -2911,9 +2891,6 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
{
const auto& SrcBoxes = Attribs.pBoxData[i];
Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcBoxes.GeometryName);
- auto& vkGeo = Geometries[GeoIdx];
- auto& vkAABBs = vkGeo.geometry.aabbs;
- auto& off = Offsets[GeoIdx];
if (GeoIdx >= Geometries.size())
{
@@ -2921,6 +2898,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
continue;
}
+ auto& vkGeo = Geometries[GeoIdx];
+ auto& vkAABBs = vkGeo.geometry.aabbs;
+ auto& off = Offsets[GeoIdx];
+
vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
vkGeo.pNext = nullptr;
vkGeo.flags = GeometryFlagsToVkGeometryFlags(SrcBoxes.Flags);
@@ -2971,13 +2952,6 @@ void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs)
static_assert(TLAS_INSTANCE_DATA_SIZE == sizeof(VkAccelerationStructureInstanceKHR), "Value in TLAS_INSTANCE_DATA_SIZE doesn't match the actual instance description size");
-#ifdef DILIGENT_DEBUG
- {
- const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
- VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE);
- }
-#endif
-
auto* pTLASVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pTLAS);
auto* pScratchVk = ValidatedCast<BufferVkImpl>(Attribs.pScratchBuffer);
auto* pInstancesVk = ValidatedCast<BufferVkImpl>(Attribs.pInstanceBuffer);
@@ -3007,7 +2981,7 @@ void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs)
std::memcpy(&vkASInst.transform, Inst.Transform.data, sizeof(vkASInst.transform));
vkASInst.instanceCustomIndex = Inst.CustomId;
- vkASInst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize
+ vkASInst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex;
vkASInst.mask = Inst.Mask;
vkASInst.flags = InstanceFlagsToVkGeometryInstanceFlags(Inst.Flags);
vkASInst.accelerationStructureReference = pBLASVk->GetVkDeviceAddress();
@@ -3058,16 +3032,13 @@ void DeviceContextVkImpl::CopyBLAS(const CopyBLASAttribs& Attribs)
if (!TDeviceContextBase::CopyBLAS(Attribs, 0))
return;
-#ifdef DILIGENT_DEBUG
- {
- const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
- VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE);
- }
-#endif
-
auto* pSrcVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pSrc);
auto* pDstVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pDst);
+ // 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.
+ pDstVk->CopyDescription(*pSrcVk);
+
VkCopyAccelerationStructureInfoKHR Info = {};
Info.sType = VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR;
@@ -3078,8 +3049,8 @@ void DeviceContextVkImpl::CopyBLAS(const CopyBLASAttribs& Attribs)
EnsureVkCmdBuffer();
const char* OpName = "Copy BottomLevelAS (DeviceContextVkImpl::CopyBLAS)";
- TransitionOrVerifyBLASState(*pSrcVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
- TransitionOrVerifyBLASState(*pDstVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+ TransitionOrVerifyBLASState(*pSrcVk, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyBLASState(*pDstVk, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
m_CommandBuffer.CopyAccelerationStructure(Info);
++m_State.NumCommands;
@@ -3094,16 +3065,11 @@ void DeviceContextVkImpl::CopyTLAS(const CopyTLASAttribs& Attribs)
if (!TDeviceContextBase::CopyTLAS(Attribs, 0))
return;
-#ifdef DILIGENT_DEBUG
- {
- const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
- VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE);
- }
-#endif
-
auto* pSrcVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pSrc);
auto* pDstVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pDst);
+ // Instances specified in BuildTLAS command.
+ // We should copy instances because it required for SBT to map instance name to hit group.
pDstVk->CopyInstancceData(*pSrcVk);
VkCopyAccelerationStructureInfoKHR Info = {};
@@ -3116,32 +3082,111 @@ void DeviceContextVkImpl::CopyTLAS(const CopyTLASAttribs& Attribs)
EnsureVkCmdBuffer();
const char* OpName = "Copy TopLevelAS (DeviceContextVkImpl::CopyTLAS)";
- TransitionOrVerifyTLASState(*pSrcVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
- TransitionOrVerifyTLASState(*pDstVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
+ TransitionOrVerifyTLASState(*pSrcVk, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyTLASState(*pDstVk, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
m_CommandBuffer.CopyAccelerationStructure(Info);
++m_State.NumCommands;
}
-void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs)
+void DeviceContextVkImpl::WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs)
{
- if (!TDeviceContextBase::TraceRays(Attribs, 0))
+ if (!TDeviceContextBase::WriteBLASCompactedSize(Attribs, 0))
return;
-#ifdef DILIGENT_DEBUG
+ const Uint32 QueryIndex = 0;
+ auto* pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pBLAS);
+ auto* pDestBuffVk = ValidatedCast<BufferVkImpl>(Attribs.pDestBuffer);
+
+ EnsureVkCmdBuffer();
+
+ const char* OpName = "Write AS compacted size (DeviceContextVkImpl::WriteBLASCompactedSize)";
+ TransitionOrVerifyBLASState(*pBLASVk, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyBufferState(*pDestBuffVk, Attribs.BufferTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName);
+
+ m_CommandBuffer.WriteAccelerationStructuresProperties(pBLASVk->GetVkBLAS(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, m_ASQueryPool, QueryIndex);
+ m_CommandBuffer.CopyQueryPoolResults(m_ASQueryPool, QueryIndex, 1, pDestBuffVk->GetVkBuffer(), Attribs.DestBufferOffset, sizeof(Uint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
+ m_CommandBuffer.ResetQueryPool(m_ASQueryPool, QueryIndex, 1);
+ ++m_State.NumCommands;
+}
+
+void DeviceContextVkImpl::WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs)
+{
+ if (!TDeviceContextBase::WriteTLASCompactedSize(Attribs, 0))
+ return;
+
+ const Uint32 QueryIndex = 0;
+ auto* pTLASVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pTLAS);
+ auto* pDestBuffVk = ValidatedCast<BufferVkImpl>(Attribs.pDestBuffer);
+
+ EnsureVkCmdBuffer();
+
+ const char* OpName = "Write AS compacted size (DeviceContextVkImpl::WriteTLASCompactedSize)";
+ TransitionOrVerifyTLASState(*pTLASVk, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
+ TransitionOrVerifyBufferState(*pDestBuffVk, Attribs.BufferTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName);
+
+ m_CommandBuffer.WriteAccelerationStructuresProperties(pTLASVk->GetVkTLAS(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, m_ASQueryPool, QueryIndex);
+ m_CommandBuffer.CopyQueryPoolResults(m_ASQueryPool, QueryIndex, 1, pDestBuffVk->GetVkBuffer(), Attribs.DestBufferOffset, sizeof(Uint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
+ m_CommandBuffer.ResetQueryPool(m_ASQueryPool, QueryIndex, 1);
+ ++m_State.NumCommands;
+}
+
+void DeviceContextVkImpl::CreateASCompactedSizeQueryPool()
+{
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing == DEVICE_FEATURE_STATE_ENABLED)
{
- const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
- VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE);
+ const auto& LogicalDevice = m_pDevice->GetLogicalDevice();
+ VkQueryPoolCreateInfo Info = {};
+
+ Info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+ Info.queryCount = 1;
+ Info.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR;
+
+ m_ASQueryPool = LogicalDevice.CreateQueryPool(Info);
}
-#endif
+}
+
+void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs)
+{
+ if (!TDeviceContextBase::TraceRays(Attribs, 0))
+ return;
+
+ auto* pSBTVk = ValidatedCast<ShaderBindingTableVkImpl>(Attribs.pSBT);
+ IBuffer* pBuffer = nullptr;
- VkStridedBufferRegionKHR RaygenShaderBindingTable = {};
- VkStridedBufferRegionKHR MissShaderBindingTable = {};
- VkStridedBufferRegionKHR HitShaderBindingTable = {};
- VkStridedBufferRegionKHR CallableShaderBindingTable = {};
+ ShaderBindingTableVkImpl::BindingTable RayGenShaderRecord = {};
+ ShaderBindingTableVkImpl::BindingTable MissShaderTable = {};
+ ShaderBindingTableVkImpl::BindingTable HitGroupTable = {};
+ ShaderBindingTableVkImpl::BindingTable CallableShaderTable = {};
- auto* pSBTVk = ValidatedCast<ShaderBindingTableVkImpl>(Attribs.pSBT);
- pSBTVk->GetVkStridedBufferRegions(this, Attribs.TransitionMode, RaygenShaderBindingTable, MissShaderBindingTable, HitShaderBindingTable, CallableShaderBindingTable);
+ pSBTVk->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable);
+
+ auto* pBufferVk = ValidatedCast<BufferVkImpl>(pBuffer);
+
+ const char* OpName = "Trace rays (DeviceContextVkImpl::TraceRays)";
+ TransitionOrVerifyBufferState(*pBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName);
+
+ // buffer ranges are not intersected, so we don't need to add barriers between them
+ if (RayGenShaderRecord.pData)
+ UpdateBuffer(pBuffer, RayGenShaderRecord.Offset, RayGenShaderRecord.Size, RayGenShaderRecord.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (MissShaderTable.pData)
+ UpdateBuffer(pBuffer, MissShaderTable.Offset, MissShaderTable.Size, MissShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (HitGroupTable.pData)
+ UpdateBuffer(pBuffer, HitGroupTable.Offset, HitGroupTable.Size, HitGroupTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (CallableShaderTable.pData)
+ UpdateBuffer(pBuffer, CallableShaderTable.Offset, CallableShaderTable.Size, CallableShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ TransitionOrVerifyBufferState(*pBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_RAY_TRACING, VK_ACCESS_SHADER_READ_BIT, OpName);
+
+ // clang-format off
+ VkStridedBufferRegionKHR RaygenShaderBindingTable = {pBufferVk->GetVkBuffer(), RayGenShaderRecord.Offset, RayGenShaderRecord.Stride, RayGenShaderRecord.Size };
+ VkStridedBufferRegionKHR MissShaderBindingTable = {pBufferVk->GetVkBuffer(), MissShaderTable.Offset, MissShaderTable.Stride, MissShaderTable.Size };
+ VkStridedBufferRegionKHR HitShaderBindingTable = {pBufferVk->GetVkBuffer(), HitGroupTable.Offset, HitGroupTable.Stride, HitGroupTable.Size };
+ VkStridedBufferRegionKHR CallableShaderBindingTable = {pBufferVk->GetVkBuffer(), CallableShaderTable.Offset, CallableShaderTable.Stride, CallableShaderTable.Size};
+ // clang-format on
PrepareForRayTracing();
m_CommandBuffer.TraceRays(RaygenShaderBindingTable, MissShaderBindingTable, HitShaderBindingTable, CallableShaderBindingTable,
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
index 3940769f..c0228146 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
@@ -57,108 +57,4 @@ void ShaderBindingTableVkImpl::BindAll(const BindAllAttribs& Attribs)
// AZ TODO
}
-void ShaderBindingTableVkImpl::GetVkStridedBufferRegions(IDeviceContextVk* pContext,
- RESOURCE_STATE_TRANSITION_MODE TransitionMode,
- VkStridedBufferRegionKHR& RaygenShaderBindingTable,
- VkStridedBufferRegionKHR& MissShaderBindingTable,
- VkStridedBufferRegionKHR& HitShaderBindingTable,
- VkStridedBufferRegionKHR& CallableShaderBindingTable)
-{
- const auto ShaderGroupBaseAlignment = GetDevice()->GetPhysicalDevice().GetExtProperties().RayTracing.shaderGroupBaseAlignment;
-
- const auto AlignToLarger = [ShaderGroupBaseAlignment](size_t offset) -> Uint32 {
- return Align(static_cast<Uint32>(offset), ShaderGroupBaseAlignment);
- };
-
- 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
-
- VkBuffer BuffHandle = m_pBuffer.RawPtr<BufferVkImpl>()->GetVkBuffer();
-
- if (m_RayGenShaderRecord.size())
- {
- RaygenShaderBindingTable.buffer = BuffHandle;
- RaygenShaderBindingTable.offset = RayGenOffset;
- RaygenShaderBindingTable.size = m_RayGenShaderRecord.size();
- RaygenShaderBindingTable.stride = m_ShaderRecordStride;
- }
-
- if (m_MissShadersRecord.size())
- {
- MissShaderBindingTable.buffer = BuffHandle;
- MissShaderBindingTable.offset = MissShaderOffset;
- MissShaderBindingTable.size = m_MissShadersRecord.size();
- MissShaderBindingTable.stride = m_ShaderRecordStride;
- }
-
- if (m_HitGroupsRecord.size())
- {
- HitShaderBindingTable.buffer = BuffHandle;
- HitShaderBindingTable.offset = HitGroupOffset;
- HitShaderBindingTable.size = m_HitGroupsRecord.size();
- HitShaderBindingTable.stride = m_ShaderRecordStride;
- }
-
- if (m_CallableShadersRecord.size())
- {
- CallableShaderBindingTable.buffer = BuffHandle;
- CallableShaderBindingTable.offset = CallableShadersOffset;
- CallableShaderBindingTable.size = m_CallableShadersRecord.size();
- CallableShaderBindingTable.stride = 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/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp
index 27e5ee72..0054315f 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp
@@ -324,7 +324,9 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
"with IDeviceContext::TransitionResourceStates().");
}
- pTLASVk->CheckBLASVersion();
+#ifdef DILIGENT_DEVELOPMENT
+ pTLASVk->ValidateContent();
+#endif
}
else
{
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
index f1e8b726..cab26f83 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
@@ -328,7 +328,9 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const std::vector<co
DescriptorSet,
CacheOffset,
SamplerInd,
- SrcImmutableSamplerInd >= 0 //
+ SrcImmutableSamplerInd >= 0,
+ Attribs.BufferStaticSize,
+ Attribs.BufferStride //
};
}
else
@@ -618,7 +620,9 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende
DescriptorSet,
CacheOffset,
SamplerInd,
- vkImmutableSampler != VK_NULL_HANDLE //
+ vkImmutableSampler != VK_NULL_HANDLE,
+ Attribs.BufferStaticSize,
+ Attribs.BufferStride //
};
}
else
@@ -822,6 +826,14 @@ void ShaderResourceLayoutVk::VkResource::CacheUniformBuffer(IDeviceObject*
RefCntAutoPtr<BufferVkImpl> pBufferVk{pBuffer, IID_BufferVk};
#ifdef DILIGENT_DEVELOPMENT
VerifyConstantBufferBinding(*this, GetVariableType(), ArrayInd, pBuffer, pBufferVk.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName());
+
+ if (pBufferVk->GetDesc().uiSizeInBytes != BufferStaticSize)
+ {
+ std::stringstream ss;
+ ss << "binding buffer '" << pBufferVk->GetDesc().Name << "' size (" << pBufferVk->GetDesc().uiSizeInBytes
+ << ") doesn't match buffer size in shader (" << BufferStaticSize << ")";
+ LOG_INFO_MESSAGE(ss.str());
+ }
#endif
auto UpdateDynamicBuffersCounter = [&DynamicBuffersCounter](const BufferVkImpl* pOldBuffer, const BufferVkImpl* pNewBuffer) {
@@ -875,6 +887,13 @@ void ShaderResourceLayoutVk::VkResource::CacheStorageBuffer(IDeviceObject*
LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
Name, "' in shader '", ParentResLayout.GetShaderName(), "': structured buffer view is expected.");
}
+
+ if (ViewDesc.ByteWidth < BufferStaticSize || (ViewDesc.ByteWidth - BufferStaticSize) % BufferStride != 0)
+ {
+ LOG_INFO_MESSAGE("binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
+ Name, "' in shader '", ParentResLayout.GetShaderName(), "': size mismatch, in shader buffer has static size (",
+ BufferStaticSize, ") and array stride (", BufferStride, "), but actual size is (", ViewDesc.ByteWidth, ").");
+ }
}
}
#endif
diff --git a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
index ae10b74b..fbef736c 100644
--- a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
@@ -40,23 +40,29 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters,
{
const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice();
const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice();
- const auto& Limits = PhysicalDevice.GetExtProperties().RayTracing;
-
- VERIFY_EXPR(m_Desc.MaxInstanceCount <= Limits.maxInstanceCount);
+ const auto& RTLimits = PhysicalDevice.GetExtProperties().RayTracing;
VkAccelerationStructureCreateInfoKHR CreateInfo = {};
VkAccelerationStructureCreateGeometryTypeInfoKHR InstanceInfo = {};
- CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
- CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
- CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags);
- CreateInfo.maxGeometryCount = 1;
- CreateInfo.pGeometryInfos = &InstanceInfo;
- CreateInfo.compactedSize = 0; // AZ TODO
-
- InstanceInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
- InstanceInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
- InstanceInfo.maxPrimitiveCount = m_Desc.MaxInstanceCount;
+ CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
+ CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
+ CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags);
+
+ if (m_Desc.CompactedSize > 0)
+ {
+ CreateInfo.compactedSize = m_Desc.CompactedSize;
+ }
+ else if (m_Desc.MaxInstanceCount > 0)
+ {
+ InstanceInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
+ InstanceInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
+ InstanceInfo.maxPrimitiveCount = m_Desc.MaxInstanceCount;
+
+ VERIFY_EXPR(m_Desc.MaxInstanceCount <= RTLimits.maxInstanceCount);
+ CreateInfo.pGeometryInfos = &InstanceInfo;
+ CreateInfo.maxGeometryCount = 1;
+ }
m_VulkanTLAS = LogicalDevice.CreateAccelStruct(CreateInfo, m_Desc.Name);
@@ -84,13 +90,18 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters,
auto err = LogicalDevice.BindASMemory(m_VulkanTLAS, Memory, m_MemoryAlignedOffset);
CHECK_VK_ERROR_AND_THROW(err, "Failed to bind AS memory");
- MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR;
- MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
- m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size);
+ if (m_Desc.CompactedSize == 0)
+ {
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size);
+
+ MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
+ MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
+ m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size);
+ }
- MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
- MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo);
- m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size);
+ SetState(RESOURCE_STATE_BUILD_AS_READ);
}
TopLevelASVkImpl::~TopLevelASVkImpl()
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
index e039311b..53719439 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
@@ -1241,7 +1241,7 @@ static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag)
case RESOURCE_STATE_PRESENT: return 0;
case RESOURCE_STATE_BUILD_AS_READ: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
case RESOURCE_STATE_BUILD_AS_WRITE: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
- case RESOURCE_STATE_RAY_TRACING: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
+ case RESOURCE_STATE_RAY_TRACING: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_SHADER_READ_BIT; // for TLAS & SBT
// clang-format on
default:
@@ -1256,7 +1256,7 @@ public:
StateFlagBitPosToVkAccessFlags()
{
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 < FlagBitPosToVkAccessFlagsMap.size(); ++bit)
{
FlagBitPosToVkAccessFlagsMap[bit] = ResourceStateFlagToVkAccessFlags(static_cast<RESOURCE_STATE>(1 << bit));
}
@@ -1335,7 +1335,7 @@ class VkAccessFlagBitPosToResourceState
public:
VkAccessFlagBitPosToResourceState()
{
- for (Uint32 bit = 0; bit < MaxFlagBitPos; ++bit)
+ for (Uint32 bit = 0; bit < FlagBitPosToResourceState.size(); ++bit)
{
FlagBitPosToResourceState[bit] = VkAccessFlagToResourceStates(static_cast<VkAccessFlagBits>(1 << bit));
}
@@ -1680,13 +1680,14 @@ VkGeometryInstanceFlagsKHR InstanceFlagsToVkGeometryInstanceFlags(RAYTRACING_INS
VkCopyAccelerationStructureModeKHR CopyASModeToVkCopyAccelerationStructureMode(COPY_AS_MODE Mode)
{
- static_assert(COPY_AS_MODE_LAST == COPY_AS_MODE_CLONE,
+ 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 VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR;
+ case COPY_AS_MODE_CLONE: return VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR;
+ case COPY_AS_MODE_COMPACT: return VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR;
// clang-format on
default:
UNEXPECTED("unknown AS copy mode");
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
index 4d47ca3e..1f81c872 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
@@ -134,12 +134,12 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags
case VK_ACCESS_MEMORY_WRITE_BIT:
break;
- // AZ TODO: comment
+ // Read access to acceleration structure or vertex/index/instance buffer in a build AS or trace rays operations.
case VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR:
Stages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
break;
- // AZ TODO: comment
+ // Write access to acceleration structure or scratch buffer in a build AS operations.
case VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR:
Stages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
break;
diff --git a/Graphics/ShaderTools/include/SPIRVShaderResources.hpp b/Graphics/ShaderTools/include/SPIRVShaderResources.hpp
index 7e75fb07..9385ff3f 100644
--- a/Graphics/ShaderTools/include/SPIRVShaderResources.hpp
+++ b/Graphics/ShaderTools/include/SPIRVShaderResources.hpp
@@ -55,7 +55,7 @@ struct Resource;
namespace Diligent
{
-// sizeof(SPIRVShaderResourceAttribs) == 24, msvc x64
+// sizeof(SPIRVShaderResourceAttribs) == 32, msvc x64
struct SPIRVShaderResourceAttribs
{
enum ResourceType : Uint8
@@ -94,7 +94,10 @@ public:
// Offset in SPIRV words (uint32_t) of binding & descriptor set decorations in SPIRV binary
/* 16 */const uint32_t BindingDecorationOffset;
/* 20 */const uint32_t DescriptorSetDecorationOffset;
-/* 24 */ // End of structure
+
+/* 24 */const Uint32 BufferStaticSize;
+/* 28 */const Uint32 BufferStride;
+/* 32 */ // End of structure
// clang-format on
@@ -102,7 +105,9 @@ public:
const diligent_spirv_cross::Resource& Res,
const char* _Name,
ResourceType _Type,
- Uint32 _SamplerOrSepImgInd = InvalidSepSmplrOrImgInd) noexcept;
+ Uint32 _SamplerOrSepImgInd = InvalidSepSmplrOrImgInd,
+ Uint32 _BufferStaticSize = 0,
+ Uint32 _BufferStride = 0) noexcept;
bool IsValidSepSamplerAssigned() const
{
diff --git a/Graphics/ShaderTools/src/SPIRVShaderResources.cpp b/Graphics/ShaderTools/src/SPIRVShaderResources.cpp
index bb15cc06..6c4ce16e 100644
--- a/Graphics/ShaderTools/src/SPIRVShaderResources.cpp
+++ b/Graphics/ShaderTools/src/SPIRVShaderResources.cpp
@@ -109,7 +109,9 @@ SPIRVShaderResourceAttribs::SPIRVShaderResourceAttribs(const diligent_spirv_cros
const diligent_spirv_cross::Resource& Res,
const char* _Name,
ResourceType _Type,
- Uint32 _SepSmplrOrImgInd) noexcept :
+ Uint32 _SepSmplrOrImgInd,
+ Uint32 _BufferStaticSize,
+ Uint32 _BufferStride) noexcept :
// clang-format off
Name {_Name},
ArraySize {GetResourceArraySize<decltype(ArraySize)>(Compiler, Res)},
@@ -118,7 +120,9 @@ SPIRVShaderResourceAttribs::SPIRVShaderResourceAttribs(const diligent_spirv_cros
IsMS {Diligent::IsMultisample(Compiler, Res) ? Uint8{1} : Uint8{0}},
SepSmplrOrImgInd {_SepSmplrOrImgInd},
BindingDecorationOffset {GetDecorationOffset(Compiler, Res, spv::Decoration::DecorationBinding)},
- DescriptorSetDecorationOffset {GetDecorationOffset(Compiler, Res, spv::Decoration::DecorationDescriptorSet)}
+ DescriptorSetDecorationOffset {GetDecorationOffset(Compiler, Res, spv::Decoration::DecorationDescriptorSet)},
+ BufferStaticSize {_BufferStaticSize},
+ BufferStride {_BufferStride}
// clang-format on
{
VERIFY(_SepSmplrOrImgInd == SPIRVShaderResourceAttribs::InvalidSepSmplrOrImgInd ||
@@ -297,10 +301,8 @@ SPIRVShaderResources::SPIRVShaderResources(IMemoryAllocator& Allocator,
&resources.separate_images,
&resources.separate_samplers,
&resources.subpass_inputs,
- &resources.acceleration_structures
- // clang-format off
- })
- // clang-format on
+ &resources.acceleration_structures //
+ }) //
{
for (const auto& res : *pResType)
ResourceNamesPoolSize += res.name.length() + 1;
@@ -379,12 +381,16 @@ SPIRVShaderResources::SPIRVShaderResources(IMemoryAllocator& Allocator,
Uint32 CurrUB = 0;
for (const auto& UB : resources.uniform_buffers)
{
- const auto& name = GetUBName(Compiler, UB, ParsedIRSource);
+ const auto& name = GetUBName(Compiler, UB, ParsedIRSource);
+ const auto& Type = Compiler.get_type(UB.type_id);
+ const size_t Size = Compiler.get_declared_struct_size(Type);
new (&GetUB(CurrUB++))
SPIRVShaderResourceAttribs(Compiler,
UB,
ResourceNamesPool.CopyString(name),
- SPIRVShaderResourceAttribs::ResourceType::UniformBuffer);
+ SPIRVShaderResourceAttribs::ResourceType::UniformBuffer,
+ SPIRVShaderResourceAttribs::InvalidSepSmplrOrImgInd,
+ Uint32(Size));
}
VERIFY_EXPR(CurrUB == GetNumUBs());
}
@@ -398,11 +404,17 @@ SPIRVShaderResources::SPIRVShaderResources(IMemoryAllocator& Allocator,
auto ResType = IsReadOnly ?
SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer :
SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer;
+ const auto& Type = Compiler.get_type(SB.type_id);
+ const size_t Size = Compiler.get_declared_struct_size(Type);
+ const size_t Stride = Compiler.get_declared_struct_size_runtime_array(Type, 1);
new (&GetSB(CurrSB++))
SPIRVShaderResourceAttribs(Compiler,
SB,
ResourceNamesPool.CopyString(SB.name),
- ResType);
+ ResType,
+ SPIRVShaderResourceAttribs::InvalidSepSmplrOrImgInd,
+ Uint32(Size),
+ Uint32(Stride));
}
VERIFY_EXPR(CurrSB == GetNumSBs());
}