summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2021-03-15 00:14:26 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:23 +0000
commit3efd89673b48bedffcf36b6b8c66d587512854a1 (patch)
tree4b484320483b5b5d2ef2f0a90a78b3f5dadf095b /Graphics
parentRefactored D3D11 resource cache (diff)
downloadDiligentCore-3efd89673b48bedffcf36b6b8c66d587512854a1.tar.gz
DiligentCore-3efd89673b48bedffcf36b6b8c66d587512854a1.zip
Added inline ray tracing & trace rays indirect command.
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.hpp46
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h37
-rw-r--r--Graphics/GraphicsEngine/interface/GraphicsTypes.h12
-rw-r--r--Graphics/GraphicsEngine/interface/Shader.h4
-rw-r--r--Graphics/GraphicsEngine/src/DeviceContextBase.cpp38
-rw-r--r--Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp3
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp5
-rw-r--r--Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp3
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp15
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp99
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp7
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp3
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp5
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp9
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp5
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp16
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp1
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp64
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp42
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp9
-rw-r--r--Graphics/ShaderTools/src/DXCompiler.cpp12
22 files changed, 391 insertions, 46 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
index 630071f4..87433ea5 100644
--- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
+++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
@@ -72,6 +72,7 @@ bool VerifyCopyTLASAttribs(const CopyTLASAttribs& Attribs);
bool VerifyWriteBLASCompactedSizeAttribs(const IRenderDevice* pDevice, const WriteBLASCompactedSizeAttribs& Attribs);
bool VerifyWriteTLASCompactedSizeAttribs(const IRenderDevice* pDevice, const WriteTLASCompactedSizeAttribs& Attribs);
bool VerifyTraceRaysAttribs(const TraceRaysAttribs& Attribs);
+bool VerifyTraceRaysIndirectAttribs(const IRenderDevice* pDevice, const TraceRaysIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer, Uint32 SBTSize);
@@ -332,6 +333,10 @@ protected:
bool WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs, int) const;
bool WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs, int) const;
bool TraceRays(const TraceRaysAttribs& Attribs, int) const;
+ bool TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer, int) const;
+
+ static constexpr Uint32 TraceRaysIndirectCommandSBTSize = 88; // D3D12: 88 bytes, size of SBT offsets
+ // Vulkan: 0 bytes, SBT offsets placed directly into function call
/// Strong reference to the device.
RefCntAutoPtr<DeviceImplType> m_pDevice;
@@ -1667,6 +1672,47 @@ bool DeviceContextBase<ImplementationTraits>::TraceRays(const TraceRaysAttribs&
return true;
}
+template <typename ImplementationTraits>
+bool DeviceContextBase<ImplementationTraits>::TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer, int) const
+{
+#ifdef DILIGENT_DEVELOPMENT
+ if (m_pDevice->GetDeviceCaps().Features.RayTracing2 != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::TraceRaysIndirect: indirect trace rays is not supported by this device");
+ return false;
+ }
+
+ if (!m_pPipelineState)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::TraceRaysIndirect command arguments are invalid: no pipeline state is bound.");
+ return false;
+ }
+
+ if (!m_pPipelineState->GetDesc().IsRayTracingPipeline())
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::TraceRaysIndirect command arguments are invalid: pipeline state '", m_pPipelineState->GetDesc().Name, "' is not a ray tracing pipeline.");
+ return false;
+ }
+
+ if (m_pActiveRenderPass != nullptr)
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::TraceRaysIndirect must be performed outside of render pass");
+ return false;
+ }
+
+ if (!VerifyTraceRaysIndirectAttribs(m_pDevice, Attribs, pAttribsBuffer, TraceRaysIndirectCommandSBTSize))
+ return false;
+
+ if (!PipelineStateImplType::IsSameObject(m_pPipelineState, ValidatedCast<PipelineStateImplType>(Attribs.pSBT->GetDesc().pPSO)))
+ {
+ LOG_ERROR_MESSAGE("IDeviceContext::TraceRaysIndirect 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");
+ return false;
+ }
+#endif
+
+ return true;
+}
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index 411103d7..5800ad76 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -1237,6 +1237,29 @@ struct TraceRaysAttribs
typedef struct TraceRaysAttribs TraceRaysAttribs;
+/// This structure is used by IDeviceContext::TraceRaysIndirect().
+struct TraceRaysIndirectAttribs
+{
+ /// Shader binding table.
+ IShaderBindingTable* pSBT DEFAULT_INITIALIZER(nullptr);
+
+ /// State transition mode for indirect trace rays attributes buffer.
+ RESOURCE_STATE_TRANSITION_MODE IndirectAttribsBufferStateTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+ /// The offset from the beginning of the buffer to the trace rays command arguments.
+ Uint32 ArgsByteOffset DEFAULT_INITIALIZER(0);
+
+ /// For Direct3D12 backend size must be 104 bytes,
+ /// for Vulkan backend size must be 12 bytes (only uint3) or 104 bytes for D3D12 compatibility.
+ Uint32 ArgsByteSize DEFAULT_INITIALIZER(104);
+
+#if DILIGENT_CPP_INTERFACE
+ TraceRaysIndirectAttribs() noexcept {}
+#endif
+};
+typedef struct TraceRaysIndirectAttribs TraceRaysIndirectAttribs;
+
+
static const Uint32 REMAINING_MIP_LEVELS = ~0u;
static const Uint32 REMAINING_ARRAY_SLICES = ~0u;
@@ -2202,6 +2225,19 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject)
/// to the shader binding table passed as an argument to the function.
VIRTUAL void METHOD(TraceRays)(THIS_
const TraceRaysAttribs REF Attribs) PURE;
+
+
+ /// Executes an indirect trace rays command.
+ ///
+ /// \param [in] pAttribsBuffer - Pointer to the buffer containing indirect trace rays attributes.
+ /// The buffer must contain the following arguments at the specified offset:
+ /// [88 bytes reserved] - for Direct3D12 backend
+ /// Uint32 DimensionX;
+ /// Uint32 DimensionY;
+ /// Uint32 DimensionZ;
+ VIRTUAL void METHOD(TraceRaysIndirect)(THIS_
+ const TraceRaysIndirectAttribs REF Attribs,
+ IBuffer* pAttribsBuffer) PURE;
};
DILIGENT_END_INTERFACE
@@ -2260,6 +2296,7 @@ DILIGENT_END_INTERFACE
# 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__)
+# define IDeviceContext_TraceRaysIndirect(This, ...) CALL_IFACE_METHOD(DeviceContext, TraceRaysIndirect, This, __VA_ARGS__)
// clang-format on
diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
index ae11a655..456b33e4 100644
--- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h
+++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
@@ -1560,16 +1560,19 @@ struct DeviceFeatures
/// Indicates if device supports geometry shaders
DEVICE_FEATURE_STATE GeometryShaders DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
-
+
/// Indicates if device supports tessellation
DEVICE_FEATURE_STATE Tessellation DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
-
+
/// Indicates if device supports mesh and amplification shaders
DEVICE_FEATURE_STATE MeshShaders DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
-
+
/// Indicates if device supports ray tracing shaders
DEVICE_FEATURE_STATE RayTracing DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+ /// Indicates if device supports inline ray tracing and indirect commands
+ DEVICE_FEATURE_STATE RayTracing2 DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
/// Indicates if device supports bindless resources
DEVICE_FEATURE_STATE BindlessResources DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
@@ -1666,6 +1669,7 @@ struct DeviceFeatures
Tessellation {State},
MeshShaders {State},
RayTracing {State},
+ RayTracing2 {State},
BindlessResources {State},
OcclusionQueries {State},
BinaryOcclusionQueries {State},
@@ -1691,7 +1695,7 @@ struct DeviceFeatures
ShaderResourceRuntimeArray {State}
{
# if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(*this) == 33, "Did you add a new feature to DeviceFeatures? Please handle its status above.");
+ static_assert(sizeof(*this) == 34, "Did you add a new feature to DeviceFeatures? Please handle its status above.");
# endif
}
#endif
diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h
index 88c7e223..399f7b6e 100644
--- a/Graphics/GraphicsEngine/interface/Shader.h
+++ b/Graphics/GraphicsEngine/interface/Shader.h
@@ -252,6 +252,10 @@ DILIGENT_TYPED_ENUM(SHADER_COMPILE_FLAGS, Uint32)
/// Enable unbounded resource arrays (e.g. Texture2D g_Texture[]).
SHADER_COMPILE_FLAG_ENABLE_UNBOUNDED_ARRAYS = 0x01,
+ /// Enable inline ray tracing for graphics and compute shaders.
+ /// Requires RayTracing2 device feature.
+ SHADER_COMPILE_FLAG_ENABLE_INLINE_RAY_TRACING = 0x02,
+
SHADER_COMPILE_FLAG_LAST = SHADER_COMPILE_FLAG_ENABLE_UNBOUNDED_ARRAYS
};
DEFINE_FLAG_ENUM_OPERATORS(SHADER_COMPILE_FLAGS);
diff --git a/Graphics/GraphicsEngine/src/DeviceContextBase.cpp b/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
index 814d1e34..1e0a3b11 100644
--- a/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
+++ b/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
@@ -774,4 +774,42 @@ bool VerifyTraceRaysAttribs(const TraceRaysAttribs& Attribs)
return true;
}
+bool VerifyTraceRaysIndirectAttribs(const IRenderDevice* pDevice, const TraceRaysIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer, Uint32 SBTSize)
+{
+#define CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(Expr, ...) CHECK_PARAMETER(Expr, "Trace rays indirect attribs are invalid: ", __VA_ARGS__)
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(Attribs.pSBT != nullptr, "pSBT must not be null");
+
+#ifdef DILIGENT_DEVELOPMENT
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(Attribs.pSBT->Verify(VERIFY_SBT_FLAG_SHADER_ONLY | VERIFY_SBT_FLAG_TLAS),
+ "not all shaders in SBT are bound or instance to shader mapping is incorrect.");
+#endif // DILIGENT_DEVELOPMENT
+
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(pAttribsBuffer != nullptr, "indirect dispatch arguments buffer must not be null.");
+
+ const auto& Desc = pAttribsBuffer->GetDesc();
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS((Desc.BindFlags & BIND_INDIRECT_DRAW_ARGS) != 0,
+ "indirect trace rays arguments buffer '", Desc.Name, "' was not created with BIND_INDIRECT_DRAW_ARGS flag.");
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(Attribs.ArgsByteOffset + Attribs.ArgsByteSize <= Desc.uiSizeInBytes,
+ "indirect trace rays arguments buffer '", Desc.Name, "' is too small.");
+
+ constexpr Uint32 DimSize = sizeof(Uint32) * 3;
+ if (pDevice->GetDeviceCaps().IsVulkanDevice())
+ {
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS((Desc.BindFlags & BIND_RAY_TRACING) != 0,
+ "indirect trace rays arguments buffer '", Desc.Name, "' was not created with BIND_RAY_TRACING flag.");
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(Attribs.ArgsByteSize == DimSize || Attribs.ArgsByteSize == DimSize + SBTSize,
+ "ArgsByteSize must be (", DimSize, ") or (", DimSize + SBTSize, ") bytes");
+ }
+ else
+ {
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(Attribs.ArgsByteSize == DimSize + SBTSize, "ArgsByteSize must be (", DimSize + SBTSize, ") bytes");
+ CHECK_TRACE_RAYS_INDIRECT_ATTRIBS(Desc.Usage == USAGE_DEFAULT,
+ "pAttribsBuffer will be updated inside TraceRaysIndirect(), buffer must be created only with USAGE_DEFAULT");
+ }
+
+#undef CHECK_TRACE_RAYS_INDIRECT_ATTRIBS
+
+ return true;
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
index 7dcde7a0..6b217ed4 100644
--- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
@@ -260,6 +260,9 @@ public:
/// Implementation of IDeviceContext::TraceRays().
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::TraceRaysIndirect().
+ virtual void DILIGENT_CALL_TYPE TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final;
+
/// Implementation of IDeviceContextD3D11::GetD3D11DeviceContext().
virtual ID3D11DeviceContext* DILIGENT_CALL_TYPE GetD3D11DeviceContext() override final { return m_pd3d11DeviceContext; }
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
index 90a4c73b..9023d33e 100755
--- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
@@ -2292,6 +2292,11 @@ void DeviceContextD3D11Impl::TraceRays(const TraceRaysAttribs& Attribs)
UNSUPPORTED("TraceRays is not supported in DirectX 11");
}
+void DeviceContextD3D11Impl::TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+{
+ UNSUPPORTED("TraceRaysIndirect is not supported in DirectX 11");
+}
+
// clang-format off
#ifdef VERIFY_CONTEXT_BINDINGS
DEFINE_D3D11CTX_FUNC_POINTERS(GetCBMethods, GetConstantBuffers)
diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
index 4ff5502d..858ec96e 100644
--- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
@@ -145,6 +145,7 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo
UNSUPPORTED_FEATURE(VertexPipelineUAVWritesAndAtomics, "Vertex pipeline UAV writes and atomics are");
UNSUPPORTED_FEATURE(MeshShaders, "Mesh shaders are");
UNSUPPORTED_FEATURE(RayTracing, "Ray tracing is");
+ UNSUPPORTED_FEATURE(RayTracing2, "Inline ray tracing is");
UNSUPPORTED_FEATURE(ShaderResourceRuntimeArray, "Runtime-sized array is");
// clang-format on
@@ -176,7 +177,7 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo
#undef UNSUPPORTED_FEATURE
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 33, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 34, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
auto& TexCaps = m_DeviceCaps.TexCaps;
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
index 2edf7677..1f453e6e 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
@@ -276,6 +276,9 @@ public:
/// Implementation of IDeviceContext::TraceRays() in Direct3D12 backend.
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::TraceRaysIndirect() in Direct3D12 backend.
+ virtual void DILIGENT_CALL_TYPE TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final;
+
/// Implementation of IDeviceContextD3D12::ID3D12GraphicsCommandList() in Direct3D12 backend.
virtual ID3D12GraphicsCommandList* DILIGENT_CALL_TYPE GetD3D12CommandList() override final;
@@ -373,11 +376,12 @@ private:
__forceinline void PrepareForDispatchCompute(ComputeContext& GraphCtx);
__forceinline void PrepareForDispatchRays(GraphicsContext& GraphCtx);
- __forceinline void PrepareDrawIndirectBuffer(GraphicsContext& GraphCtx,
- IBuffer* pAttribsBuffer,
- RESOURCE_STATE_TRANSITION_MODE BufferStateTransitionMode,
- ID3D12Resource*& pd3d12ArgsBuff,
- Uint64& BuffDataStartByteOffset);
+ __forceinline void PrepareIndirectBuffer(GraphicsContext& GraphCtx,
+ IBuffer* pAttribsBuffer,
+ RESOURCE_STATE_TRANSITION_MODE BufferStateTransitionMode,
+ ID3D12Resource*& pd3d12ArgsBuff,
+ Uint64& BuffDataStartByteOffset,
+ const char* OpName);
struct RootTableInfo
{
@@ -458,6 +462,7 @@ private:
CComPtr<ID3D12CommandSignature> m_pDrawIndexedIndirectSignature;
CComPtr<ID3D12CommandSignature> m_pDispatchIndirectSignature;
CComPtr<ID3D12CommandSignature> m_pDrawMeshIndirectSignature;
+ CComPtr<ID3D12CommandSignature> m_pTraceRaysIndirectSignature;
D3D12DynamicHeap m_DynamicHeap;
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 78f00768..5dd64710 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -135,6 +135,14 @@ DeviceContextD3D12Impl::DeviceContextD3D12Impl(IReferenceCounters* pRef
CHECK_D3D_RESULT_THROW(hr, "Failed to create draw mesh indirect command signature");
}
#endif
+ if (pDeviceD3D12Impl->GetDeviceCaps().Features.RayTracing2 == DEVICE_FEATURE_STATE_ENABLED)
+ {
+ CmdSignatureDesc.ByteStride = sizeof(D3D12_DISPATCH_RAYS_DESC);
+ IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_RAYS;
+ hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pTraceRaysIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pTraceRaysIndirectSignature)));
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create trace rays indirect command signature");
+ static_assert(TraceRaysIndirectCommandSBTSize == offsetof(D3D12_DISPATCH_RAYS_DESC, Width), "Invalid SBT offsets size");
+ }
}
DeviceContextD3D12Impl::~DeviceContextD3D12Impl()
@@ -619,11 +627,12 @@ void DeviceContextD3D12Impl::DrawIndexed(const DrawIndexedAttribs& Attribs)
++m_State.NumCommands;
}
-void DeviceContextD3D12Impl::PrepareDrawIndirectBuffer(GraphicsContext& GraphCtx,
- IBuffer* pAttribsBuffer,
- RESOURCE_STATE_TRANSITION_MODE BufferStateTransitionMode,
- ID3D12Resource*& pd3d12ArgsBuff,
- Uint64& BuffDataStartByteOffset)
+void DeviceContextD3D12Impl::PrepareIndirectBuffer(GraphicsContext& GraphCtx,
+ IBuffer* pAttribsBuffer,
+ RESOURCE_STATE_TRANSITION_MODE BufferStateTransitionMode,
+ ID3D12Resource*& pd3d12ArgsBuff,
+ Uint64& BuffDataStartByteOffset,
+ const char* OpName)
{
DEV_CHECK_ERR(pAttribsBuffer != nullptr, "Indirect draw attribs buffer must not be null");
@@ -634,8 +643,7 @@ void DeviceContextD3D12Impl::PrepareDrawIndirectBuffer(GraphicsContext&
#endif
TransitionOrVerifyBufferState(GraphCtx, *pIndirectDrawAttribsD3D12, BufferStateTransitionMode,
- RESOURCE_STATE_INDIRECT_ARGUMENT,
- "Indirect draw (DeviceContextD3D12Impl::PrepareDrawIndirectBuffer)");
+ RESOURCE_STATE_INDIRECT_ARGUMENT, OpName);
pd3d12ArgsBuff = pIndirectDrawAttribsD3D12->GetD3D12Buffer(BuffDataStartByteOffset, this);
}
@@ -650,7 +658,8 @@ void DeviceContextD3D12Impl::DrawIndirect(const DrawIndirectAttribs& Attribs, IB
ID3D12Resource* pd3d12ArgsBuff;
Uint64 BuffDataStartByteOffset;
- PrepareDrawIndirectBuffer(GraphCtx, pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, pd3d12ArgsBuff, BuffDataStartByteOffset);
+ PrepareIndirectBuffer(GraphCtx, pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, pd3d12ArgsBuff, BuffDataStartByteOffset,
+ "Indirect draw (DeviceContextD3D12Impl::DrawIndirect)");
GraphCtx.ExecuteIndirect(m_pDrawIndirectSignature, pd3d12ArgsBuff, Attribs.IndirectDrawArgsOffset + BuffDataStartByteOffset);
++m_State.NumCommands;
@@ -666,7 +675,8 @@ void DeviceContextD3D12Impl::DrawIndexedIndirect(const DrawIndexedIndirectAttrib
ID3D12Resource* pd3d12ArgsBuff;
Uint64 BuffDataStartByteOffset;
- PrepareDrawIndirectBuffer(GraphCtx, pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, pd3d12ArgsBuff, BuffDataStartByteOffset);
+ PrepareIndirectBuffer(GraphCtx, pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, pd3d12ArgsBuff, BuffDataStartByteOffset,
+ "Indexed indirect draw (DeviceContextD3D12Impl::DrawIndexedIndirect)");
GraphCtx.ExecuteIndirect(m_pDrawIndexedIndirectSignature, pd3d12ArgsBuff, Attribs.IndirectDrawArgsOffset + BuffDataStartByteOffset);
++m_State.NumCommands;
@@ -694,7 +704,8 @@ void DeviceContextD3D12Impl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Att
ID3D12Resource* pd3d12ArgsBuff;
Uint64 BuffDataStartByteOffset;
- PrepareDrawIndirectBuffer(GraphCtx, pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, pd3d12ArgsBuff, BuffDataStartByteOffset);
+ PrepareIndirectBuffer(GraphCtx, pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, pd3d12ArgsBuff, BuffDataStartByteOffset,
+ "Indirect draw mesh (DeviceContextD3D12Impl::DrawMeshIndirect)");
GraphCtx.ExecuteIndirect(m_pDrawMeshIndirectSignature, pd3d12ArgsBuff, Attribs.IndirectDrawArgsOffset + BuffDataStartByteOffset);
++m_State.NumCommands;
@@ -2772,4 +2783,72 @@ void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs)
++m_State.NumCommands;
}
+void DeviceContextD3D12Impl::TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+{
+ if (!TDeviceContextBase::TraceRaysIndirect(Attribs, pAttribsBuffer, 0))
+ return;
+
+ auto& CmdCtx = GetCmdContext().AsGraphicsContext4();
+ auto* pSBTD3D12 = ValidatedCast<ShaderBindingTableD3D12Impl>(Attribs.pSBT);
+ IBuffer* pSBTBuffer = nullptr;
+
+ ShaderBindingTableD3D12Impl::BindingTable RayGenShaderRecord = {};
+ ShaderBindingTableD3D12Impl::BindingTable MissShaderTable = {};
+ ShaderBindingTableD3D12Impl::BindingTable HitGroupTable = {};
+ ShaderBindingTableD3D12Impl::BindingTable CallableShaderTable = {};
+
+ pSBTD3D12->GetData(pSBTBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable);
+
+ auto* pSBTBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pSBTBuffer);
+
+ const char* OpName = "Trace rays indirect (DeviceContextD3D12Impl::TraceRaysIndirect)";
+
+ if (RayGenShaderRecord.pData || MissShaderTable.pData || HitGroupTable.pData || CallableShaderTable.pData)
+ {
+ TransitionOrVerifyBufferState(CmdCtx, *pSBTBufferD3D12, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, RESOURCE_STATE_COPY_DEST, OpName);
+
+ // buffer ranges are not intersected, so we don't need to add barriers between them
+ if (RayGenShaderRecord.pData)
+ UpdateBuffer(pSBTBufferD3D12, RayGenShaderRecord.Offset, RayGenShaderRecord.Size, RayGenShaderRecord.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (MissShaderTable.pData)
+ UpdateBuffer(pSBTBufferD3D12, MissShaderTable.Offset, MissShaderTable.Size, MissShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (HitGroupTable.pData)
+ UpdateBuffer(pSBTBufferD3D12, HitGroupTable.Offset, HitGroupTable.Size, HitGroupTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+
+ if (CallableShaderTable.pData)
+ UpdateBuffer(pSBTBufferD3D12, CallableShaderTable.Offset, CallableShaderTable.Size, CallableShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+ }
+ TransitionOrVerifyBufferState(CmdCtx, *pSBTBufferD3D12, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, RESOURCE_STATE_RAY_TRACING, OpName);
+
+ D3D12_DISPATCH_RAYS_DESC d3d12DispatchDesc = {};
+
+ d3d12DispatchDesc.RayGenerationShaderRecord.StartAddress = pSBTBufferD3D12->GetGPUAddress() + RayGenShaderRecord.Offset;
+ d3d12DispatchDesc.RayGenerationShaderRecord.SizeInBytes = RayGenShaderRecord.Size;
+
+ d3d12DispatchDesc.MissShaderTable.StartAddress = pSBTBufferD3D12->GetGPUAddress() + MissShaderTable.Offset;
+ d3d12DispatchDesc.MissShaderTable.SizeInBytes = MissShaderTable.Size;
+ d3d12DispatchDesc.MissShaderTable.StrideInBytes = MissShaderTable.Stride;
+
+ d3d12DispatchDesc.HitGroupTable.StartAddress = pSBTBufferD3D12->GetGPUAddress() + HitGroupTable.Offset;
+ d3d12DispatchDesc.HitGroupTable.SizeInBytes = HitGroupTable.Size;
+ d3d12DispatchDesc.HitGroupTable.StrideInBytes = HitGroupTable.Stride;
+
+ d3d12DispatchDesc.CallableShaderTable.StartAddress = pSBTBufferD3D12->GetGPUAddress() + CallableShaderTable.Offset;
+ d3d12DispatchDesc.CallableShaderTable.SizeInBytes = CallableShaderTable.Size;
+ d3d12DispatchDesc.CallableShaderTable.StrideInBytes = CallableShaderTable.Stride;
+
+ // copy dispath description with shader table data and keep dimension
+ UpdateBuffer(pAttribsBuffer, Attribs.ArgsByteOffset, offsetof(D3D12_DISPATCH_RAYS_DESC, Width), &d3d12DispatchDesc, Attribs.IndirectAttribsBufferStateTransitionMode);
+
+ auto* pAttribsBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pAttribsBuffer);
+ TransitionOrVerifyBufferState(CmdCtx, *pAttribsBufferD3D12, Attribs.IndirectAttribsBufferStateTransitionMode, RESOURCE_STATE_INDIRECT_ARGUMENT, OpName);
+
+ PrepareForDispatchRays(CmdCtx);
+
+ CmdCtx.ExecuteIndirect(m_pTraceRaysIndirectSignature, pAttribsBufferD3D12->GetD3D12Resource(), Attribs.ArgsByteOffset);
+ ++m_State.NumCommands;
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
index 25ce0695..15042442 100644
--- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
@@ -251,6 +251,10 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
{
m_DeviceCaps.Features.RayTracing = DEVICE_FEATURE_STATE_ENABLED;
}
+ if (d3d12Features.RaytracingTier >= D3D12_RAYTRACING_TIER_1_1)
+ {
+ m_DeviceCaps.Features.RayTracing2 = DEVICE_FEATURE_STATE_ENABLED;
+ }
}
}
@@ -299,11 +303,12 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
CHECK_REQUIRED_FEATURE(UniformBuffer8BitAccess, "8-bit uniform buffer access is");
CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is");
+ CHECK_REQUIRED_FEATURE(RayTracing2, "inline ray tracing is");
// clang-format on
#undef CHECK_REQUIRED_FEATURE
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 33, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 34, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
auto& TexCaps = m_DeviceCaps.TexCaps;
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
index 867179af..f33b9d2c 100644
--- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
@@ -261,6 +261,9 @@ public:
/// Implementation of IDeviceContext::TraceRays() in OpenGL backend.
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::TraceRaysIndirect() in OpenGL backend.
+ virtual void DILIGENT_CALL_TYPE TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final;
+
/// Implementation of IDeviceContextGL::UpdateCurrentGLContext().
virtual bool DILIGENT_CALL_TYPE UpdateCurrentGLContext() override final;
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index c613ca7d..9958c238 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -1648,4 +1648,9 @@ void DeviceContextGLImpl::TraceRays(const TraceRaysAttribs& Attribs)
UNSUPPORTED("TraceRays is not supported in OpenGL");
}
+void DeviceContextGLImpl::TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+{
+ UNSUPPORTED("TraceRaysIndirect is not supported in OpenGL");
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
index 8cf07274..8950671e 100644
--- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
@@ -302,9 +302,12 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
} \
} while (false)
+ // clang-format off
SET_FEATURE_STATE(VertexPipelineUAVWritesAndAtomics, false, "Vertex pipeline UAV writes and atomics are");
- SET_FEATURE_STATE(MeshShaders, false, "Mesh shaders are");
- SET_FEATURE_STATE(RayTracing, false, "Ray tracing is");
+ SET_FEATURE_STATE(MeshShaders, false, "Mesh shaders are");
+ SET_FEATURE_STATE(RayTracing, false, "Ray tracing is");
+ SET_FEATURE_STATE(RayTracing2, false, "Inline ray tracing is");
+ // clang-format on
{
bool WireframeFillSupported = (glPolygonMode != nullptr);
@@ -457,7 +460,7 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
#undef SET_FEATURE_STATE
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 33, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 34, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
// get device limits
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
index ed2adf11..ee207091 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
@@ -269,6 +269,9 @@ public:
/// Implementation of IDeviceContext::TraceRays() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::TraceRaysIndirect() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final;
+
// Transitions texture subresources from OldState to NewState, and optionally updates
// internal texture state.
// If OldState == RESOURCE_STATE_UNKNOWN, internal texture state is used as old state.
@@ -451,7 +454,7 @@ private:
__forceinline void PrepareForDraw(DRAW_FLAGS Flags);
__forceinline void PrepareForIndexedDraw(DRAW_FLAGS Flags, VALUE_TYPE IndexType);
- __forceinline BufferVkImpl* PrepareIndirectDrawAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode);
+ __forceinline BufferVkImpl* PrepareIndirectAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode, const char* OpName);
__forceinline void PrepareForDispatchCompute();
__forceinline void PrepareForRayTracing();
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
index 7f15e642..49a37dc2 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
@@ -670,6 +670,22 @@ public:
#endif
}
+ __forceinline void TraceRaysIndirect(const VkStridedDeviceAddressRegionKHR& RaygenShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR& MissShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR& HitShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR& CallableShaderBindingTable,
+ VkDeviceAddress indirectDeviceAddress)
+ {
+#if DILIGENT_USE_VOLK
+ VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
+ VERIFY(m_State.RayTracingPipeline != VK_NULL_HANDLE, "No ray tracing pipeline bound");
+
+ vkCmdTraceRaysIndirectKHR(m_VkCmdBuffer, &RaygenShaderBindingTable, &MissShaderBindingTable, &HitShaderBindingTable, &CallableShaderBindingTable, indirectDeviceAddress);
+#else
+ UNSUPPORTED("Ray tracing is not supported when vulkan library is linked statically");
+#endif
+ }
+
void FlushBarriers();
__forceinline void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer)
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
index 38813f20..5f17d666 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
@@ -45,6 +45,7 @@ public:
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR ShaderFloat16Int8 = {};
VkPhysicalDeviceAccelerationStructureFeaturesKHR AccelStruct = {};
VkPhysicalDeviceRayTracingPipelineFeaturesKHR RayTracingPipeline = {};
+ VkPhysicalDeviceRayQueryFeaturesKHR RayQuery = {};
bool Spirv14 = false; // Ray tracing requires Vulkan 1.2 or SPIRV 1.4 extension
bool Spirv15 = false; // DXC shaders with ray tracing requires Vulkan 1.2 with SPIRV 1.5
VkPhysicalDeviceBufferDeviceAddressFeaturesKHR BufferDeviceAddress = {};
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 723e2c7c..0707a989 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -792,7 +792,9 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags)
#endif
}
-BufferVkImpl* DeviceContextVkImpl::PrepareIndirectDrawAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode)
+BufferVkImpl* DeviceContextVkImpl::PrepareIndirectAttribsBuffer(IBuffer* pAttribsBuffer,
+ RESOURCE_STATE_TRANSITION_MODE TransitonMode,
+ const char* OpName)
{
DEV_CHECK_ERR(pAttribsBuffer, "Indirect draw attribs buffer must not be null");
auto* pIndirectDrawAttribsVk = ValidatedCast<BufferVkImpl>(pAttribsBuffer);
@@ -804,7 +806,7 @@ BufferVkImpl* DeviceContextVkImpl::PrepareIndirectDrawAttribsBuffer(IBuffer* pAt
// Buffer memory barries must be executed outside of render pass
TransitionOrVerifyBufferState(*pIndirectDrawAttribsVk, TransitonMode, RESOURCE_STATE_INDIRECT_ARGUMENT,
- VK_ACCESS_INDIRECT_COMMAND_READ_BIT, "Indirect draw (DeviceContextVkImpl::Draw)");
+ VK_ACCESS_INDIRECT_COMMAND_READ_BIT, OpName);
return pIndirectDrawAttribsVk;
}
@@ -852,7 +854,7 @@ void DeviceContextVkImpl::DrawIndirect(const DrawIndirectAttribs& Attribs, IBuff
// 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);
+ BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, "Indirect draw (DeviceContextVkImpl::DrawIndirect)");
PrepareForDraw(Attribs.Flags);
@@ -867,7 +869,7 @@ void DeviceContextVkImpl::DrawIndexedIndirect(const DrawIndexedIndirectAttribs&
// 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);
+ BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, "Indirect draw (DeviceContextVkImpl::DrawIndexedIndirect)");
PrepareForIndexedDraw(Attribs.Flags, Attribs.IndexType);
@@ -893,7 +895,7 @@ void DeviceContextVkImpl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Attrib
// 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);
+ BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, "Indirect draw (DeviceContextVkImpl::DrawMeshIndirect)");
PrepareForDraw(Attribs.Flags);
@@ -3471,4 +3473,56 @@ void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs)
++m_State.NumCommands;
}
+void DeviceContextVkImpl::TraceRaysIndirect(const TraceRaysIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+{
+ if (!TDeviceContextBase::TraceRaysIndirect(Attribs, pAttribsBuffer, 0))
+ return;
+
+ auto* pSBTVk = ValidatedCast<ShaderBindingTableVkImpl>(Attribs.pSBT);
+ IBuffer* pBuffer = nullptr;
+
+ ShaderBindingTableVkImpl::BindingTable RayGenShaderRecord = {};
+ ShaderBindingTableVkImpl::BindingTable MissShaderTable = {};
+ ShaderBindingTableVkImpl::BindingTable HitGroupTable = {};
+ ShaderBindingTableVkImpl::BindingTable CallableShaderTable = {};
+
+ pSBTVk->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable);
+
+ const char* OpName = "Trace rays indirect (DeviceContextVkImpl::TraceRaysIndirect)";
+ auto* const pSBTBufferVk = ValidatedCast<BufferVkImpl>(pBuffer);
+ auto* const pIndirectAttribsVk = PrepareIndirectAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode, OpName);
+ const auto IndirectBuffOffset = Attribs.ArgsByteOffset + (Attribs.ArgsByteSize == sizeof(Uint32) * 3 ? 0 : TraceRaysIndirectCommandSBTSize);
+
+ if (RayGenShaderRecord.pData || MissShaderTable.pData || HitGroupTable.pData || CallableShaderTable.pData)
+ {
+ TransitionOrVerifyBufferState(*pSBTBufferVk, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, 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(*pSBTBufferVk, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, RESOURCE_STATE_RAY_TRACING, VK_ACCESS_SHADER_READ_BIT, OpName);
+
+ // clang-format off
+ VkStridedDeviceAddressRegionKHR RaygenShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + RayGenShaderRecord.Offset, RayGenShaderRecord.Stride, RayGenShaderRecord.Size };
+ VkStridedDeviceAddressRegionKHR MissShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + MissShaderTable.Offset, MissShaderTable.Stride, MissShaderTable.Size };
+ VkStridedDeviceAddressRegionKHR HitShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + HitGroupTable.Offset, HitGroupTable.Stride, HitGroupTable.Size };
+ VkStridedDeviceAddressRegionKHR CallableShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + CallableShaderTable.Offset, CallableShaderTable.Stride, CallableShaderTable.Size};
+ // clang-format on
+
+ PrepareForRayTracing();
+ m_CommandBuffer.TraceRaysIndirect(RaygenShaderBindingTable, MissShaderBindingTable, HitShaderBindingTable, CallableShaderBindingTable,
+ pIndirectAttribsVk->GetVkDeviceAddress() + IndirectBuffOffset);
+ ++m_State.NumCommands;
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
index 7e08a361..027fa892 100644
--- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
@@ -138,7 +138,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
try
{
Uint32 Version = VK_API_VERSION_1_0;
- if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED)
+ if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED || EngineCI.Features.RayTracing2 != DEVICE_FEATURE_STATE_DISABLED)
Version = VK_API_VERSION_1_2;
auto Instance = VulkanUtilities::VulkanInstance::Create(
@@ -280,8 +280,18 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
const auto& DescrIndexingFeats = DeviceExtFeatures.DescriptorIndexing;
ENABLE_FEATURE(DescrIndexingFeats.runtimeDescriptorArray != VK_FALSE, ShaderResourceRuntimeArray, "Shader resource runtime array is");
-
- ENABLE_FEATURE(DeviceExtFeatures.AccelStruct.accelerationStructure != VK_FALSE && DeviceExtFeatures.RayTracingPipeline.rayTracingPipeline != VK_FALSE, RayTracing, "Ray tracing is");
+ const auto& AccelStructFeats = DeviceExtFeatures.AccelStruct;
+ const auto& RayTracingFeats = DeviceExtFeatures.RayTracingPipeline;
+ const auto& RayQueryFeats = DeviceExtFeatures.RayQuery;
+ // clang-format off
+ ENABLE_FEATURE(AccelStructFeats.accelerationStructure != VK_FALSE &&
+ RayTracingFeats.rayTracingPipeline != VK_FALSE, RayTracing, "Ray tracing is");
+ ENABLE_FEATURE(AccelStructFeats.accelerationStructure != VK_FALSE &&
+ RayTracingFeats.rayTracingPipeline != VK_FALSE &&
+ RayTracingFeats.rayTracingPipelineTraceRaysIndirect != VK_FALSE &&
+ RayTracingFeats.rayTraversalPrimitiveCulling != VK_FALSE &&
+ RayQueryFeats.rayQuery != VK_FALSE, RayTracing2, "Inline ray tracing is");
+ // clang-format on
#undef FeatureSupport
@@ -417,13 +427,13 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
}
// Ray tracing
- if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED)
+ if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED || EngineCI.Features.RayTracing2 != DEVICE_FEATURE_STATE_DISABLED)
{
// this extensions added to Vulkan 1.2 core
if (!DeviceExtFeatures.Spirv15)
{
DeviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); // required for VK_KHR_spirv_1_4
- DeviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); // required for VK_KHR_ray_tracing_pipeline
+ DeviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); // required for VK_KHR_ray_tracing_pipeline or VK_KHR_ray_query
EnabledExtFeats.Spirv14 = DeviceExtFeatures.Spirv14;
VERIFY_EXPR(DeviceExtFeatures.Spirv14);
}
@@ -439,14 +449,11 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
// disable unused features
EnabledExtFeats.AccelStruct.accelerationStructureCaptureReplay = false;
- EnabledExtFeats.AccelStruct.accelerationStructureIndirectBuild = false;
EnabledExtFeats.AccelStruct.accelerationStructureHostCommands = false;
EnabledExtFeats.AccelStruct.descriptorBindingAccelerationStructureUpdateAfterBind = false;
EnabledExtFeats.RayTracingPipeline.rayTracingPipelineShaderGroupHandleCaptureReplay = false;
EnabledExtFeats.RayTracingPipeline.rayTracingPipelineShaderGroupHandleCaptureReplayMixed = false;
- EnabledExtFeats.RayTracingPipeline.rayTracingPipelineTraceRaysIndirect = false;
- EnabledExtFeats.RayTracingPipeline.rayTraversalPrimitiveCulling = false; // for GLSL_EXT_ray_flags_primitive_culling
*NextExt = &EnabledExtFeats.AccelStruct;
NextExt = &EnabledExtFeats.AccelStruct.pNext;
@@ -454,6 +461,23 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
NextExt = &EnabledExtFeats.RayTracingPipeline.pNext;
*NextExt = &EnabledExtFeats.BufferDeviceAddress;
NextExt = &EnabledExtFeats.BufferDeviceAddress.pNext;
+
+ // Inline ray tracing from any shader.
+ if (EngineCI.Features.RayTracing2 != DEVICE_FEATURE_STATE_DISABLED)
+ {
+ DeviceExtensions.push_back(VK_KHR_RAY_QUERY_EXTENSION_NAME);
+
+ EnabledExtFeats.RayQuery = RayQueryFeats;
+
+ *NextExt = &EnabledExtFeats.RayQuery;
+ NextExt = &EnabledExtFeats.RayQuery.pNext;
+ }
+ else
+ {
+ EnabledExtFeats.AccelStruct.accelerationStructureIndirectBuild = false;
+ EnabledExtFeats.RayTracingPipeline.rayTracingPipelineTraceRaysIndirect = false;
+ EnabledExtFeats.RayTracingPipeline.rayTraversalPrimitiveCulling = false; // for GLSL_EXT_ray_flags_primitive_culling
+ }
}
// make sure that last pNext is null
@@ -461,7 +485,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
}
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 33, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 34, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data();
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index 8debcd97..e1ce9efa 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -234,7 +234,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED;
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 33, "Did you add a new feature to DeviceFeatures? Please handle its satus here (if necessary).");
+ static_assert(sizeof(DeviceFeatures) == 34, "Did you add a new feature to DeviceFeatures? Please handle its satus here (if necessary).");
#endif
const auto& vkDeviceLimits = m_PhysicalDevice->GetProperties().limits;
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
index 343893e9..cf1cbd3f 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
@@ -146,6 +146,15 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice,
m_ExtProperties.RayTracingPipeline.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
}
+ // Get inline ray tracing features.
+ if (IsExtensionSupported(VK_KHR_RAY_QUERY_EXTENSION_NAME))
+ {
+ *NextFeat = &m_ExtFeatures.RayQuery;
+ NextFeat = &m_ExtFeatures.RayQuery.pNext;
+
+ m_ExtFeatures.RayQuery.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR;
+ }
+
// Additional extension that is required for ray tracing.
if (IsExtensionSupported(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME))
{
diff --git a/Graphics/ShaderTools/src/DXCompiler.cpp b/Graphics/ShaderTools/src/DXCompiler.cpp
index 549c5b48..488a1e00 100644
--- a/Graphics/ShaderTools/src/DXCompiler.cpp
+++ b/Graphics/ShaderTools/src/DXCompiler.cpp
@@ -725,13 +725,12 @@ void DXCompilerImpl::Compile(const ShaderCreateInfo& ShaderCI,
else
DxilArgs.push_back(L"-Od"); // TODO: something goes wrong if optimization is enabled
#endif
+ DEV_CHECK_ERR((ShaderCI.CompileFlags & SHADER_COMPILE_FLAG_ENABLE_INLINE_RAY_TRACING) == 0 ||
+ (ShaderModel.Major > 6 || (ShaderModel.Major == 6 && ShaderModel.Minor >= 5)),
+ "Inline ray tracing requires Shader Model 6.5 and above");
}
else if (m_Target == DXCompilerTarget::Vulkan)
{
- const Uint32 RayTracingStages =
- SHADER_TYPE_RAY_GEN | SHADER_TYPE_RAY_MISS | SHADER_TYPE_RAY_CLOSEST_HIT |
- SHADER_TYPE_RAY_ANY_HIT | SHADER_TYPE_RAY_INTERSECTION | SHADER_TYPE_CALLABLE;
-
DxilArgs.assign(
{
L"-spirv",
@@ -740,9 +739,10 @@ void DXCompilerImpl::Compile(const ShaderCreateInfo& ShaderCI,
L"-O3", // Optimization level 3
});
- if (ShaderCI.Desc.ShaderType & RayTracingStages)
+ if ((ShaderCI.Desc.ShaderType & SHADER_TYPE_ALL_RAY_TRACING) != 0 ||
+ (ShaderCI.CompileFlags & SHADER_COMPILE_FLAG_ENABLE_INLINE_RAY_TRACING) != 0)
{
- DxilArgs.push_back(L"-fspv-target-env=vulkan1.2"); // required for SPV_KHR_ray_tracing
+ DxilArgs.push_back(L"-fspv-target-env=vulkan1.2"); // required for SPV_KHR_ray_tracing and SPV_KHR_ray_query
}
}
else