summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
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/GraphicsEngineVulkan
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/GraphicsEngineVulkan')
-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
15 files changed, 303 insertions, 293 deletions
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;