summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-11-07 19:34:49 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-11-10 03:43:28 +0000
commit0f35896a60c4de02ccfc91ace18bcef4450fa4d9 (patch)
tree86a772a36c6c2258949231b756970a621b69f82b /Graphics/GraphicsEngineVulkan
parentCorrected ray rtacing vertex format handling in D3D12 (diff)
downloadDiligentCore-0f35896a60c4de02ccfc91ace18bcef4450fa4d9.tar.gz
DiligentCore-0f35896a60c4de02ccfc91ace18bcef4450fa4d9.zip
Added ability to update AS.
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp8
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp12
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp8
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp8
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h40
-rw-r--r--Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp17
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp56
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp32
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp12
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp46
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp68
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp16
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp1
16 files changed, 259 insertions, 79 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp
index 1a4eb2c1..85665f2c 100644
--- a/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp
@@ -46,8 +46,12 @@ public:
BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
RenderDeviceVkImpl* pRenderDeviceVk,
- const BottomLevelASDesc& Desc,
- bool bIsDeviceInternal = false);
+ const BottomLevelASDesc& Desc);
+ BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const BottomLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ VkAccelerationStructureKHR vkBLAS);
~BottomLevelASVkImpl();
/// Implementation of IBottomLevelAS::GetNativeHandle() in Vulkan backend.
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
index 8680b819..2aaf4c69 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
@@ -151,6 +151,18 @@ public:
RESOURCE_STATE InitialState,
IBuffer** ppBuffer) override final;
+ /// Implementation of IRenderDeviceVk::CreateBLASFromVulkanResource().
+ virtual void DILIGENT_CALL_TYPE CreateBLASFromVulkanResource(VkAccelerationStructureKHR vkBLAS,
+ const BottomLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ IBottomLevelAS** ppBLAS) override final;
+
+ /// Implementation of IRenderDeviceVk::CreateTLASFromVulkanResource().
+ virtual void DILIGENT_CALL_TYPE CreateTLASFromVulkanResource(VkAccelerationStructureKHR vkTLAS,
+ const TopLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ ITopLevelAS** ppTLAS) override final;
+
/// Implementation of IRenderDevice::IdleGPU() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE IdleGPU() override final;
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
index ab43ab80..6adc1677 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp
@@ -34,16 +34,17 @@
#include "RenderDeviceVkImpl.hpp"
#include "ShaderBindingTableVk.h"
#include "ShaderBindingTableBase.hpp"
+#include "TopLevelASVkImpl.hpp"
#include "PipelineStateVkImpl.hpp"
#include "VulkanUtilities/VulkanObjectWrappers.hpp"
namespace Diligent
{
-class ShaderBindingTableVkImpl final : public ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, RenderDeviceVkImpl>
+class ShaderBindingTableVkImpl final : public ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, TopLevelASVkImpl, RenderDeviceVkImpl>
{
public:
- using TShaderBindingTableBase = ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, RenderDeviceVkImpl>;
+ using TShaderBindingTableBase = ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, TopLevelASVkImpl, RenderDeviceVkImpl>;
ShaderBindingTableVkImpl(IReferenceCounters* pRefCounters,
RenderDeviceVkImpl* pRenderDeviceVk,
@@ -51,9 +52,6 @@ public:
bool bIsDeviceInternal = false);
~ShaderBindingTableVkImpl();
- virtual void DILIGENT_CALL_TYPE ResetHitGroups(Uint32 HitShadersPerInstance) override;
- virtual void DILIGENT_CALL_TYPE BindAll(const BindAllAttribs& Attribs) override;
-
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderBindingTableVk, TShaderBindingTableBase);
};
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
index 44a377fd..97e3dead 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
@@ -396,6 +396,8 @@ public:
bool IsUsingSeparateSamplers() const { return m_IsUsingSeparateSamplers; }
+ bool IsCompatibleWith(const ShaderResourceLayoutVk& ResLayout) const;
+
private:
Uint32 GetResourceOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const
{
diff --git a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
index b55223df..a318085e 100644
--- a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp
@@ -47,8 +47,12 @@ public:
TopLevelASVkImpl(IReferenceCounters* pRefCounters,
RenderDeviceVkImpl* pRenderDeviceVk,
- const TopLevelASDesc& Desc,
- bool bIsDeviceInternal = false);
+ const TopLevelASDesc& Desc);
+ TopLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const TopLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ VkAccelerationStructureKHR vkTLAS);
~TopLevelASVkImpl();
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_TopLevelASVk, TTopLevelASBase);
diff --git a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h b/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h
index dfded94f..0d566e70 100644
--- a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h
@@ -112,6 +112,44 @@ DILIGENT_BEGIN_INTERFACE(IRenderDeviceVk, IRenderDevice)
const BufferDesc REF BuffDesc,
RESOURCE_STATE InitialState,
IBuffer** ppBuffer) PURE;
+
+ /// Creates a bottom-level AS object from native Vulkan resource
+
+ /// \param [in] vkBLAS - Vulkan acceleration structure handle.
+ /// \param [in] Desc - Bottom-level AS description.
+ /// \param [in] InitialState - Initial BLAS state. Can be RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_BUILD_AS_READ, RESOURCE_STATE_BUILD_AS_WRITE.
+ /// See Diligent::RESOURCE_STATE.
+ /// \param [out] ppBLAS - Address of the memory location where the pointer to the
+ /// bottom-level AS interface will be stored.
+ /// The function calls AddRef(), so that the new object will contain
+ /// one reference.
+ /// \note Created bottom-level AS object does not take ownership of the Vulkan acceleration structure and will not
+ /// destroy it once released. The application must not destroy Vulkan acceleration structure while it is
+ /// in use by the engine.
+ VIRTUAL void METHOD(CreateBLASFromVulkanResource)(THIS_
+ VkAccelerationStructureKHR vkBLAS,
+ const BottomLevelASDesc REF Desc,
+ RESOURCE_STATE InitialState,
+ IBottomLevelAS** ppBLAS) PURE;
+
+ /// Creates a top-level AS object from native Vulkan resource
+
+ /// \param [in] vkTLAS - Vulkan acceleration structure handle.
+ /// \param [in] Desc - Bottom-level AS description.
+ /// \param [in] InitialState - Initial TLAS state. Can be RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_BUILD_AS_READ, RESOURCE_STATE_BUILD_AS_WRITE, RESOURCE_STATE_RAY_TRACING.
+ /// See Diligent::RESOURCE_STATE.
+ /// \param [out] ppTLAS - Address of the memory location where the pointer to the
+ /// top-level AS interface will be stored.
+ /// The function calls AddRef(), so that the new object will contain
+ /// one reference.
+ /// \note Created top-level AS object does not take ownership of the Vulkan acceleration structure and will not
+ /// destroy it once released. The application must not destroy Vulkan acceleration structure while it is
+ /// in use by the engine.
+ VIRTUAL void METHOD(CreateTLASFromVulkanResource)(THIS_
+ VkAccelerationStructureKHR vkTLAS,
+ const TopLevelASDesc REF Desc,
+ RESOURCE_STATE InitialState,
+ ITopLevelAS** ppTLAS) PURE;
};
DILIGENT_END_INTERFACE
@@ -129,6 +167,8 @@ DILIGENT_END_INTERFACE
# define IRenderDeviceVk_IsFenceSignaled(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, IsFenceSignaled, This, __VA_ARGS__)
# define IRenderDeviceVk_CreateTextureFromVulkanImage(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateTextureFromVulkanImage, This, __VA_ARGS__)
# define IRenderDeviceVk_CreateBufferFromVulkanResource(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateBufferFromVulkanResource, This, __VA_ARGS__)
+# define IRenderDeviceVk_CreateBLASFromVulkanResource(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateBLASFromVulkanResource, This, __VA_ARGS__)
+# define IRenderDeviceVk_CreateTLASFromVulkanResource(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateTLASFromVulkanResource, This, __VA_ARGS__)
// clang-format on
diff --git a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
index 092da523..4e23a13a 100644
--- a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp
@@ -34,9 +34,8 @@ namespace Diligent
BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
RenderDeviceVkImpl* pRenderDeviceVk,
- const BottomLevelASDesc& Desc,
- bool bIsDeviceInternal) :
- TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc, bIsDeviceInternal}
+ const BottomLevelASDesc& Desc) :
+ TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc}
{
const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice();
const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice();
@@ -152,6 +151,18 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
SetState(RESOURCE_STATE_BUILD_AS_READ);
}
+BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const BottomLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ VkAccelerationStructureKHR vkBLAS) :
+ TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc},
+ m_VulkanBLAS{vkBLAS}
+{
+ SetState(InitialState);
+ m_DeviceAddress = pRenderDeviceVk->GetLogicalDevice().GetAccelerationStructureDeviceAddress(m_VulkanBLAS);
+}
+
BottomLevelASVkImpl::~BottomLevelASVkImpl()
{
// Vk object can only be destroyed when it is no longer used by the GPU
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index ce9c639c..1b8b3e83 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -2815,21 +2815,23 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs)
{
Geometries.resize(Attribs.TriangleDataCount);
Offsets.resize(Attribs.TriangleDataCount);
+ pBLASVk->SetActualGeometryCount(Attribs.TriangleDataCount);
for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i)
{
const auto& SrcTris = Attribs.pTriangleData[i];
- Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcTris.GeometryName);
+ Uint32 Idx = i;
+ Uint32 GeoIdx = pBLASVk->UpdateGeometryIndex(SrcTris.GeometryName, Idx, Attribs.Update);
- if (GeoIdx >= Geometries.size())
+ if (GeoIdx == INVALID_INDEX || Idx == INVALID_INDEX)
{
UNEXPECTED("Failed to find geometry by name");
continue;
}
- auto& vkGeo = Geometries[GeoIdx];
+ auto& vkGeo = Geometries[Idx];
auto& vkTris = vkGeo.geometry.triangles;
- auto& off = Offsets[GeoIdx];
+ auto& off = Offsets[Idx];
const auto& TriDesc = BLASDesc.pTriangles[GeoIdx];
vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
@@ -2886,21 +2888,23 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs)
{
Geometries.resize(Attribs.BoxDataCount);
Offsets.resize(Attribs.BoxDataCount);
+ pBLASVk->SetActualGeometryCount(Attribs.BoxDataCount);
for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i)
{
const auto& SrcBoxes = Attribs.pBoxData[i];
- Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcBoxes.GeometryName);
+ Uint32 Idx = i;
+ Uint32 GeoIdx = pBLASVk->UpdateGeometryIndex(SrcBoxes.GeometryName, Idx, Attribs.Update);
- if (GeoIdx >= Geometries.size())
+ if (GeoIdx == INVALID_INDEX || Idx == INVALID_INDEX)
{
UNEXPECTED("Failed to find geometry by name");
continue;
}
- auto& vkGeo = Geometries[GeoIdx];
+ auto& vkGeo = Geometries[Idx];
auto& vkAABBs = vkGeo.geometry.aabbs;
- auto& off = Offsets[GeoIdx];
+ auto& off = Offsets[Idx];
vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
vkGeo.pNext = nullptr;
@@ -2928,8 +2932,8 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs)
Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
Info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; // type must be compatible with create info
Info.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(BLASDesc.Flags); // flags must be compatible with create info
- Info.update = VK_FALSE;
- Info.srcAccelerationStructure = VK_NULL_HANDLE;
+ Info.update = Attribs.Update;
+ Info.srcAccelerationStructure = Attribs.Update ? pBLASVk->GetVkBLAS() : VK_NULL_HANDLE;
Info.dstAccelerationStructure = pBLASVk->GetVkBLAS();
Info.geometryArrayOfPointers = VK_FALSE;
Info.geometryCount = static_cast<uint32_t>(Geometries.size());
@@ -2963,7 +2967,16 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs)
TransitionOrVerifyTLASState(*pTLASVk, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName);
TransitionOrVerifyBufferState(*pScratchVk, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, OpName);
- pTLASVk->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.HitShadersPerInstance);
+ if (Attribs.Update)
+ {
+ if (!pTLASVk->UpdateInstances(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode))
+ return;
+ }
+ else
+ {
+ if (!pTLASVk->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode))
+ return;
+ }
// copy instance data into instance buffer
{
@@ -2973,14 +2986,22 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs)
for (Uint32 i = 0; i < Attribs.InstanceCount; ++i)
{
const auto& Inst = Attribs.pInstances[i];
- auto& vkASInst = static_cast<VkAccelerationStructureInstanceKHR*>(TmpSpace.CPUAddress)[i];
- auto* const pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Inst.pBLAS);
+ const auto InstDesc = pTLASVk->GetInstanceDesc(Inst.InstanceName);
+
+ if (InstDesc.InstanceIndex >= Attribs.InstanceCount)
+ {
+ UNEXPECTED("Failed to find instance by name");
+ return;
+ }
+
+ auto& vkASInst = static_cast<VkAccelerationStructureInstanceKHR*>(TmpSpace.CPUAddress)[InstDesc.InstanceIndex];
+ auto* pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Inst.pBLAS);
static_assert(sizeof(vkASInst.transform) == sizeof(Inst.Transform), "size mismatch");
std::memcpy(&vkASInst.transform, Inst.Transform.data, sizeof(vkASInst.transform));
vkASInst.instanceCustomIndex = Inst.CustomId;
- vkASInst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex;
+ vkASInst.instanceShaderBindingTableRecordOffset = InstDesc.ContributionToHitGroupIndex;
vkASInst.mask = Inst.Mask;
vkASInst.flags = InstanceFlagsToVkGeometryInstanceFlags(Inst.Flags);
vkASInst.accelerationStructureReference = pBLASVk->GetVkDeviceAddress();
@@ -3014,8 +3035,8 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs)
vkASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
vkASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; // type must be compatible with create info
vkASBuildInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(TLASDesc.Flags); // flags must be compatible with create info
- vkASBuildInfo.update = VK_FALSE;
- vkASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
+ vkASBuildInfo.update = Attribs.Update;
+ vkASBuildInfo.srcAccelerationStructure = Attribs.Update ? pTLASVk->GetVkTLAS() : VK_NULL_HANDLE;
vkASBuildInfo.dstAccelerationStructure = pTLASVk->GetVkTLAS();
vkASBuildInfo.geometryArrayOfPointers = VK_FALSE;
vkASBuildInfo.geometryCount = 1;
@@ -3036,7 +3057,8 @@ void DeviceContextVkImpl::CopyBLAS(const CopyBLASAttribs& Attribs)
// 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);
+ pDstVk->CopyGeometryDescription(*pSrcVk);
+ pDstVk->SetActualGeometryCount(pSrcVk->GetActualGeometryCount());
VkCopyAccelerationStructureInfoKHR Info = {};
diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
index 189b1073..44cf52e3 100644
--- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
@@ -137,8 +137,12 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
try
{
+ Uint32 Version = VK_API_VERSION_1_0;
+ if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED)
+ Version = VK_API_VERSION_1_2;
+
auto Instance = VulkanUtilities::VulkanInstance::Create(
- VK_API_VERSION_1_2, // AZ TODO: use 1.2 only for ray tracing, wave ops extensions
+ Version,
EngineCI.EnableValidation,
EngineCI.GlobalExtensionCount,
EngineCI.ppGlobalExtensionNames,
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index 6bfd4eeb..cfde6479 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -851,7 +851,7 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const
return false;
auto IsSamePipelineLayout = m_PipelineLayout.IsSameAs(pPSOVk->m_PipelineLayout);
-#if 0 //def DILIGENT_DEBUG // AZ TODO
+#ifdef DILIGENT_DEBUG
{
bool IsCompatibleShaders = true;
if (GetNumShaderStages() != pPSOVk->GetNumShaderStages())
@@ -867,8 +867,8 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const
break;
}
- const auto& Res0 = GetShaderResLayout(s).GetResources();
- const auto& Res1 = pPSOVk->GetShaderResLayout(s).GetResources();
+ const auto& Res0 = GetShaderResLayout(s);
+ const auto& Res1 = pPSOVk->GetShaderResLayout(s);
if (!Res0.IsCompatibleWith(Res1))
{
IsCompatibleShaders = false;
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index addf3440..620d29e9 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -754,6 +754,22 @@ void RenderDeviceVkImpl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebu
});
}
+void RenderDeviceVkImpl::CreateBLASFromVulkanResource(VkAccelerationStructureKHR vkBLAS,
+ const BottomLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ IBottomLevelAS** ppBLAS)
+{
+ CreateDeviceObject(
+ "BottomLevelAS", Desc, ppBLAS,
+ [&]() //
+ {
+ BottomLevelASVkImpl* pBottomLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASVkImpl instance", BottomLevelASVkImpl)(this, Desc, InitialState, vkBLAS));
+ pBottomLevelASVk->QueryInterface(IID_BottomLevelAS, reinterpret_cast<IObject**>(ppBLAS));
+ OnCreateDeviceObject(pBottomLevelASVk);
+ } //
+ );
+}
+
void RenderDeviceVkImpl::CreateBLAS(const BottomLevelASDesc& Desc,
IBottomLevelAS** ppBLAS)
{
@@ -766,6 +782,22 @@ void RenderDeviceVkImpl::CreateBLAS(const BottomLevelASDesc& Desc,
});
}
+void RenderDeviceVkImpl::CreateTLASFromVulkanResource(VkAccelerationStructureKHR vkTLAS,
+ const TopLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ ITopLevelAS** ppTLAS)
+{
+ CreateDeviceObject(
+ "TopLevelAS", Desc, ppTLAS,
+ [&]() //
+ {
+ TopLevelASVkImpl* pTopLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "TopLevelASVkImpl instance", TopLevelASVkImpl)(this, Desc, InitialState, vkTLAS));
+ pTopLevelASVk->QueryInterface(IID_TopLevelAS, reinterpret_cast<IObject**>(ppTLAS));
+ OnCreateDeviceObject(pTopLevelASVk);
+ } //
+ );
+}
+
void RenderDeviceVkImpl::CreateTLAS(const TopLevelASDesc& Desc,
ITopLevelAS** ppTLAS)
{
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
index c0228146..194d15f4 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp
@@ -45,16 +45,4 @@ ShaderBindingTableVkImpl::~ShaderBindingTableVkImpl()
{
}
-void ShaderBindingTableVkImpl::ResetHitGroups(Uint32 HitShadersPerInstance)
-{
- // AZ TODO
-
- m_Changed = true;
-}
-
-void ShaderBindingTableVkImpl::BindAll(const BindAllAttribs& Attribs)
-{
- // AZ TODO
-}
-
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp
index 2e1039ba..26516695 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp
@@ -166,9 +166,10 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
{
constexpr RESOURCE_STATE RequiredState = RESOURCE_STATE_CONSTANT_BUFFER;
VERIFY_EXPR((ResourceStateFlagsToVkAccessFlags(RequiredState) & VK_ACCESS_UNIFORM_READ_BIT) == VK_ACCESS_UNIFORM_READ_BIT);
+ const bool IsInRequiredState = pBufferVk->CheckState(RequiredState);
if (VerifyOnly)
{
- if (!pBufferVk->CheckState(RequiredState))
+ if (!IsInRequiredState)
{
LOG_ERROR_MESSAGE("State of buffer '", pBufferVk->GetDesc().Name, "' is incorrect. Required state: ",
GetResourceStateString(RequiredState), ". Actual state: ",
@@ -180,7 +181,10 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
}
else
{
- pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ if (!IsInRequiredState)
+ {
+ pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ }
VERIFY_EXPR(pBufferVk->CheckAccessFlags(VK_ACCESS_UNIFORM_READ_BIT));
}
}
@@ -207,10 +211,11 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
VERIFY_EXPR((ResourceStateFlagsToVkAccessFlags(RequiredState) & RequiredAccessFlags) == RequiredAccessFlags);
#endif
+ const bool IsInRequiredState = pBufferVk->CheckState(RequiredState);
if (VerifyOnly)
{
- if (!pBufferVk->CheckState(RequiredState))
+ if (!IsInRequiredState)
{
LOG_ERROR_MESSAGE("State of buffer '", pBufferVk->GetDesc().Name, "' is incorrect. Required state: ",
GetResourceStateString(RequiredState), ". Actual state: ",
@@ -222,7 +227,12 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
}
else
{
- pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ // When both old and new states are RESOURCE_STATE_UNORDERED_ACCESS, we need to execute UAV barrier
+ // to make sure that all UAV writes are complete and visible.
+ if (!IsInRequiredState || RequiredState == RESOURCE_STATE_UNORDERED_ACCESS)
+ {
+ pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ }
VERIFY_EXPR(pBufferVk->CheckAccessFlags(RequiredAccessFlags));
}
}
@@ -265,10 +275,11 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
VERIFY_EXPR(ResourceStateToVkImageLayout(RequiredState) == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
}
+ const bool IsInRequiredState = pTextureVk->CheckState(RequiredState);
if (VerifyOnly)
{
- if (!pTextureVk->CheckState(RequiredState))
+ if (!IsInRequiredState)
{
LOG_ERROR_MESSAGE("State of texture '", pTextureVk->GetDesc().Name, "' is incorrect. Required state: ",
GetResourceStateString(RequiredState), ". Actual state: ",
@@ -280,7 +291,12 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
}
else
{
- pCtxVkImpl->TransitionTextureState(*pTextureVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ // When both old and new states are RESOURCE_STATE_UNORDERED_ACCESS, we need to execute UAV barrier
+ // to make sure that all UAV writes are complete and visible.
+ if (!IsInRequiredState || RequiredState == RESOURCE_STATE_UNORDERED_ACCESS)
+ {
+ pCtxVkImpl->TransitionTextureState(*pTextureVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ }
}
}
}
@@ -311,10 +327,11 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
auto* pTLASVk = Res.pObject.RawPtr<TopLevelASVkImpl>();
if (pTLASVk != nullptr && pTLASVk->IsInKnownState())
{
- constexpr RESOURCE_STATE RequiredState = RESOURCE_STATE_RAY_TRACING;
+ constexpr RESOURCE_STATE RequiredState = RESOURCE_STATE_RAY_TRACING;
+ const bool IsInRequiredState = pTLASVk->CheckState(RequiredState);
if (VerifyOnly)
{
- if (!pTLASVk->CheckState(RequiredState))
+ if (!IsInRequiredState)
{
LOG_ERROR_MESSAGE("State of TLAS '", pTLASVk->GetDesc().Name, "' is incorrect. Required state: ",
GetResourceStateString(RequiredState), ". Actual state: ",
@@ -323,15 +340,18 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl)
"when calling IDeviceContext::CommitShaderResources() or explicitly transition the TLAS state "
"with IDeviceContext::TransitionResourceStates().");
}
-
-#ifdef DILIGENT_DEVELOPMENT
- pTLASVk->ValidateContent();
-#endif
}
else
{
- pCtxVkImpl->TransitionTLASState(*pTLASVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ if (!IsInRequiredState)
+ {
+ pCtxVkImpl->TransitionTLASState(*pTLASVk, RESOURCE_STATE_UNKNOWN, RequiredState, true);
+ }
}
+
+#ifdef DILIGENT_DEVELOPMENT
+ pTLASVk->ValidateContent();
+#endif
}
}
break;
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
index ba8d567a..f45749e2 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
@@ -374,27 +374,26 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages&
std::string ShadersStr;
while (Stages != SHADER_TYPE_UNKNOWN)
{
- const auto ShaderType = Stages & static_cast<SHADER_TYPE>(~(static_cast<Uint32>(Stages) - 1));
- const char* ShaderName = nullptr;
+ const auto ShaderType = Stages & static_cast<SHADER_TYPE>(~(static_cast<Uint32>(Stages) - 1));
+ String ShaderName;
- // AZ TODO
- /*for (const auto& StageInfo : ShaderStages)
+ for (const auto& StageInfo : ShaderStages)
{
if ((Stages & StageInfo.Type) != 0)
{
- ShaderName = StageInfo.pShader->GetDesc().Name;
+ ShaderName = GetShaderGroupName(StageInfo.Shaders);
break;
}
- }*/
+ }
if (!ShadersStr.empty())
ShadersStr.append(", ");
ShadersStr.append(GetShaderTypeLiteralName(ShaderType));
ShadersStr.append(" (");
- if (ShaderName)
+ if (ShaderName.size())
{
ShadersStr.push_back('\'');
- ShadersStr.append(ShaderName ? ShaderName : "<Not enabled in PSO>");
+ ShadersStr.append(ShaderName);
ShadersStr.push_back('\'');
}
else
@@ -829,10 +828,10 @@ void ShaderResourceLayoutVk::VkResource::CacheUniformBuffer(IDeviceObject*
if (pBufferVk->GetDesc().uiSizeInBytes < BufferStaticSize)
{
- std::stringstream ss;
- ss << "The size of buffer '" << pBufferVk->GetDesc().Name << "' (" << pBufferVk->GetDesc().uiSizeInBytes
- << ") is not large enough for what the shader expects (" << BufferStaticSize << ")";
- LOG_ERROR_MESSAGE(ss.str());
+ // It is OK if enabled robustBufferAccess feature, otherwise access outside of buffer range may lead to crash or undefined behavior.
+ LOG_WARNING_MESSAGE("Error binding uniform buffer '", pBufferVk->GetDesc().Name, "' to shader variable '",
+ Name, "' in shader '", ParentResLayout.GetShaderName(), "': buffer size in the shader (",
+ BufferStaticSize, ") is incompatible with the actual buffer size (", pBufferVk->GetDesc().uiSizeInBytes, ").");
}
#endif
@@ -888,11 +887,22 @@ void ShaderResourceLayoutVk::VkResource::CacheStorageBuffer(IDeviceObject*
Name, "' in shader '", ParentResLayout.GetShaderName(), "': structured buffer view is expected.");
}
- if (ViewDesc.ByteWidth < BufferStaticSize || (ViewDesc.ByteWidth - BufferStaticSize) % BufferStride != 0)
+ if (BufferStride == 0 && ViewDesc.ByteWidth < BufferStaticSize)
{
- LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
- Name, "' in shader '", ParentResLayout.GetShaderName(), "': static buffer size in the shader (",
- BufferStaticSize, ") and array element stride (", BufferStride, ") are incompatible with the actual buffer size (", ViewDesc.ByteWidth, ").");
+ // It is OK if enabled robustBufferAccess feature, otherwise access outside of buffer range may lead to crash or undefined behavior.
+ LOG_WARNING_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
+ Name, "' in shader '", ParentResLayout.GetShaderName(), "': buffer size in the shader (",
+ BufferStaticSize, ") is incompatible with the actual buffer view size (", ViewDesc.ByteWidth, ").");
+ }
+
+ if (BufferStride > 0 && (ViewDesc.ByteWidth < BufferStaticSize || (ViewDesc.ByteWidth - BufferStaticSize) % BufferStride != 0))
+ {
+ // For buffers with dynamic arrays we know only static part size and array element stride.
+ // Element stride in shader may be differ than in code. Here we check that buffer size is exactly match to the array with N elements.
+ LOG_WARNING_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
+ Name, "' in shader '", ParentResLayout.GetShaderName(), "': static buffer size in the shader (",
+ BufferStaticSize, ") and array element stride (", BufferStride, ") are incompatible with the actual buffer view size (", ViewDesc.ByteWidth, "),",
+ " this may be result of array element size mismatch.");
}
}
}
@@ -1117,7 +1127,7 @@ void ShaderResourceLayoutVk::VkResource::CacheAccelerationStructure(IDeviceObjec
VERIFY(Type == SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure, "Acceleration Structure resource is expected");
RefCntAutoPtr<TopLevelASVkImpl> pTLASVk{pTLAS, IID_TopLevelASVk};
#ifdef DILIGENT_DEVELOPMENT
- // AZ TODO
+ VerifyTLASResourceBinding(*this, GetVariableType(), ArrayInd, pTLASVk.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName());
#endif
if (UpdateCachedResource(DstRes, std::move(pTLASVk), [](const TopLevelASVkImpl*, const TopLevelASVkImpl*) {}))
{
@@ -1536,4 +1546,28 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk&
}
}
+bool ShaderResourceLayoutVk::IsCompatibleWith(const ShaderResourceLayoutVk& ResLayout) const
+{
+ if (m_NumResources != ResLayout.m_NumResources)
+ return false;
+
+ bool IsCompatible = true;
+ for (Uint32 i = 0, Cnt = GetTotalResourceCount(); i < Cnt; ++i)
+ {
+ const auto& lhs = this->GetResource(i);
+ const auto& rhs = ResLayout.GetResource(i);
+
+ // clang-format off
+ if (lhs.ArraySize != rhs.ArraySize ||
+ lhs.Type != rhs.Type ||
+ lhs.SamplerInd != rhs.SamplerInd)
+ // clang-format on
+ {
+ IsCompatible = false;
+ }
+ }
+
+ return IsCompatible;
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
index fbef736c..bfde3aa6 100644
--- a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp
@@ -34,9 +34,8 @@ namespace Diligent
TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters,
RenderDeviceVkImpl* pRenderDeviceVk,
- const TopLevelASDesc& Desc,
- bool bIsDeviceInternal) :
- TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc, bIsDeviceInternal}
+ const TopLevelASDesc& Desc) :
+ TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc}
{
const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice();
const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice();
@@ -104,6 +103,17 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters,
SetState(RESOURCE_STATE_BUILD_AS_READ);
}
+TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters,
+ RenderDeviceVkImpl* pRenderDeviceVk,
+ const TopLevelASDesc& Desc,
+ RESOURCE_STATE InitialState,
+ VkAccelerationStructureKHR vkTLAS) :
+ TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc},
+ m_VulkanTLAS{vkTLAS}
+{
+ SetState(InitialState);
+}
+
TopLevelASVkImpl::~TopLevelASVkImpl()
{
// Vk object can only be destroyed when it is no longer used by the GPU
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
index a80d7f73..fd81dcfb 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
@@ -189,7 +189,6 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice,
// Emulate KHR extension
if (m_ExtFeatures.RayTracingNV)
{
- //m_ExtFeatures.RayTracing.rayTracingPrimitiveCulling = true; // AZ TODO
m_ExtFeatures.RayTracing.rayTracing = VK_TRUE;
m_ExtProperties.RayTracing.shaderGroupHandleSize = RayTracingNV.shaderGroupHandleSize;