summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
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/GraphicsEngine
parentRefactored D3D11 resource cache (diff)
downloadDiligentCore-3efd89673b48bedffcf36b6b8c66d587512854a1.tar.gz
DiligentCore-3efd89673b48bedffcf36b6b8c66d587512854a1.zip
Added inline ray tracing & trace rays indirect command.
Diffstat (limited to 'Graphics/GraphicsEngine')
-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
5 files changed, 133 insertions, 4 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