summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2021-03-15 00:24:13 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:23 +0000
commit408db3c96481ad05b686a5105cf92c9d58cfa5ba (patch)
treea0d4c1c99665ff3e030477adf2b1dc93315c4d5c /Graphics/GraphicsEngine
parentAdded inline ray tracing & trace rays indirect command. (diff)
downloadDiligentCore-408db3c96481ad05b686a5105cf92c9d58cfa5ba.tar.gz
DiligentCore-408db3c96481ad05b686a5105cf92c9d58cfa5ba.zip
Added DrawMeshIndirectCount command.
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.hpp69
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h76
-rw-r--r--Graphics/GraphicsEngine/src/DeviceContextBase.cpp25
3 files changed, 154 insertions, 16 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
index 87433ea5..769f8f01 100644
--- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
+++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
@@ -57,6 +57,7 @@ bool VerifyDispatchComputeIndirectAttribs(const DispatchComputeIndirectAttribs&
bool VerifyDrawMeshAttribs(Uint32 MaxDrawMeshTasksCount, const DrawMeshAttribs& Attribs);
bool VerifyDrawMeshIndirectAttribs(const DrawMeshIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer);
+bool VerifyDrawMeshIndirectCountAttribs(const DrawMeshIndirectCountAttribs& Attribs, const IBuffer* pAttribsBuffer, const IBuffer* pCountBuff, Uint32 IndirectCmdStride);
bool VerifyResolveTextureSubresourceAttribs(const ResolveTextureSubresourceAttribs& ResolveAttribs,
const TextureDesc& SrcTexDesc,
@@ -72,7 +73,10 @@ 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);
+bool VerifyTraceRaysIndirectAttribs(const IRenderDevice* pDevice,
+ const TraceRaysIndirectAttribs& Attribs,
+ const IBuffer* pAttribsBuffer,
+ Uint32 SBTSize);
@@ -290,12 +294,13 @@ protected:
#ifdef DILIGENT_DEVELOPMENT
// clang-format off
- bool DvpVerifyDrawArguments (const DrawAttribs& Attribs) const;
- bool DvpVerifyDrawIndexedArguments (const DrawIndexedAttribs& Attribs) const;
- bool DvpVerifyDrawMeshArguments (const DrawMeshAttribs& Attribs) const;
- bool DvpVerifyDrawIndirectArguments (const DrawIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer) const;
- bool DvpVerifyDrawIndexedIndirectArguments(const DrawIndexedIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer) const;
- bool DvpVerifyDrawMeshIndirectArguments (const DrawMeshIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer) const;
+ bool DvpVerifyDrawArguments (const DrawAttribs& Attribs) const;
+ bool DvpVerifyDrawIndexedArguments (const DrawIndexedAttribs& Attribs) const;
+ bool DvpVerifyDrawMeshArguments (const DrawMeshAttribs& Attribs) const;
+ bool DvpVerifyDrawIndirectArguments (const DrawIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer) const;
+ bool DvpVerifyDrawIndexedIndirectArguments (const DrawIndexedIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer) const;
+ bool DvpVerifyDrawMeshIndirectArguments (const DrawMeshIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer) const;
+ bool DvpVerifyDrawMeshIndirectCountArguments(const DrawMeshIndirectCountAttribs& Attribs, const IBuffer* pAttribsBuffer, const IBuffer* pCountBuff) const;
bool DvpVerifyDispatchArguments (const DispatchComputeAttribs& Attribs) const;
bool DvpVerifyDispatchIndirectArguments(const DispatchComputeIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer) const;
@@ -307,12 +312,13 @@ protected:
bool DvpVerifyBLASState (const BottomLevelASType& BLAS, RESOURCE_STATE RequiredState, const char* OperationName) const;
bool DvpVerifyTLASState (const TopLevelASType& TLAS, RESOURCE_STATE RequiredState, const char* OperationName) const;
#else
- bool DvpVerifyDrawArguments (const DrawAttribs& Attribs)const {return true;}
- bool DvpVerifyDrawIndexedArguments (const DrawIndexedAttribs& Attribs)const {return true;}
- bool DvpVerifyDrawMeshArguments (const DrawMeshAttribs& Attribs)const {return true;}
- bool DvpVerifyDrawIndirectArguments (const DrawIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer)const {return true;}
- bool DvpVerifyDrawIndexedIndirectArguments(const DrawIndexedIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer)const {return true;}
- bool DvpVerifyDrawMeshIndirectArguments (const DrawMeshIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer)const {return true;}
+ bool DvpVerifyDrawArguments (const DrawAttribs& Attribs)const {return true;}
+ bool DvpVerifyDrawIndexedArguments (const DrawIndexedAttribs& Attribs)const {return true;}
+ bool DvpVerifyDrawMeshArguments (const DrawMeshAttribs& Attribs)const {return true;}
+ bool DvpVerifyDrawIndirectArguments (const DrawIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer)const {return true;}
+ bool DvpVerifyDrawIndexedIndirectArguments (const DrawIndexedIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer)const {return true;}
+ bool DvpVerifyDrawMeshIndirectArguments (const DrawMeshIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer)const {return true;}
+ bool DvpVerifyDrawMeshIndirectCountArguments(const DrawMeshIndirectCountAttribs& Attribs, const IBuffer* pAttribsBuffer, const IBuffer* pCountBuff) const {return true;}
bool DvpVerifyDispatchArguments (const DispatchComputeAttribs& Attribs)const {return true;}
bool DvpVerifyDispatchIndirectArguments(const DispatchComputeIndirectAttribs& Attribs, const IBuffer* pAttribsBuffer)const {return true;}
@@ -335,8 +341,10 @@ protected:
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
+ static constexpr Uint32 DrawMeshIndirectCommandStride = sizeof(uint) * 3; // D3D12: 12 bytes (x, y, z dimension)
+ // Vulkan: 8 bytes (task count, first task)
+ 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;
@@ -1895,6 +1903,37 @@ inline bool DeviceContextBase<ImplementationTraits>::DvpVerifyDrawMeshIndirectAr
}
template <typename ImplementationTraits>
+inline bool DeviceContextBase<ImplementationTraits>::DvpVerifyDrawMeshIndirectCountArguments(
+ const DrawMeshIndirectCountAttribs& Attribs,
+ const IBuffer* pAttribsBuffer,
+ const IBuffer* pCountBuff) const
+{
+ if ((Attribs.Flags & DRAW_FLAG_VERIFY_DRAW_ATTRIBS) == 0)
+ return true;
+
+ if (m_pDevice->GetDeviceCaps().Features.MeshShaders != DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_MESSAGE("DrawMeshIndirectCount: mesh shaders are not supported by this device");
+ return false;
+ }
+
+ if (!m_pPipelineState)
+ {
+ LOG_ERROR_MESSAGE("DrawMeshIndirectCount command arguments are invalid: no pipeline state is bound.");
+ return false;
+ }
+
+ if (m_pPipelineState->GetDesc().PipelineType != PIPELINE_TYPE_MESH)
+ {
+ LOG_ERROR_MESSAGE("DrawMeshIndirectCount command arguments are invalid: pipeline state '",
+ m_pPipelineState->GetDesc().Name, "' is not a mesh pipeline.");
+ return false;
+ }
+
+ return VerifyDrawMeshIndirectCountAttribs(Attribs, pAttribsBuffer, pCountBuff, DrawMeshIndirectCommandStride);
+}
+
+template <typename ImplementationTraits>
inline bool DeviceContextBase<ImplementationTraits>::DvpVerifyRenderTargets() const
{
if (!m_pPipelineState)
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index 5800ad76..b5909451 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -434,6 +434,49 @@ struct DrawMeshIndirectAttribs
typedef struct DrawMeshIndirectAttribs DrawMeshIndirectAttribs;
+/// Defines the mesh indirect draw count command attributes.
+
+/// This structure is used by IDeviceContext::DrawMeshIndirectCount().
+struct DrawMeshIndirectCountAttribs
+{
+ /// Additional flags, see Diligent::DRAW_FLAGS.
+ DRAW_FLAGS Flags DEFAULT_INITIALIZER(DRAW_FLAG_NONE);
+
+ /// The maximum number of commands that will be read from the count buffer.
+ Uint32 MaxCommandCount DEFAULT_INITIALIZER(1);
+
+ /// State transition mode for indirect draw arguments buffer.
+ RESOURCE_STATE_TRANSITION_MODE IndirectAttribsBufferStateTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+ /// Offset from the beginning of the buffer to the location of draw command attributes.
+ Uint32 IndirectDrawArgsOffset DEFAULT_INITIALIZER(0);
+
+ /// State transition mode for the count buffer.
+ RESOURCE_STATE_TRANSITION_MODE CountBufferStateTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
+
+ /// Offset from the beginning of the buffer to the location of the command counter.
+ Uint32 CountBufferOffset DEFAULT_INITIALIZER(0);
+
+#if DILIGENT_CPP_INTERFACE
+ DrawMeshIndirectCountAttribs()noexcept{}
+
+ /// Initializes the structure members with user-specified values.
+ DrawMeshIndirectCountAttribs(DRAW_FLAGS _Flags,
+ RESOURCE_STATE_TRANSITION_MODE _IndirectAttribsBufferStateTransitionMode,
+ Uint32 _IndirectDrawArgsOffset,
+ RESOURCE_STATE_TRANSITION_MODE _CountBufferStateTransitionMode,
+ Uint32 _CountBufferOffset)noexcept :
+ Flags {_Flags },
+ IndirectAttribsBufferStateTransitionMode{_IndirectAttribsBufferStateTransitionMode},
+ IndirectDrawArgsOffset {_IndirectDrawArgsOffset },
+ CountBufferStateTransitionMode {_CountBufferStateTransitionMode },
+ CountBufferOffset {_CountBufferOffset }
+ {}
+#endif
+};
+typedef struct DrawMeshIndirectCountAttribs DrawMeshIndirectCountAttribs;
+
+
/// Defines which parts of the depth-stencil buffer to clear.
/// These flags are used by IDeviceContext::ClearDepthStencil().
@@ -1765,8 +1808,38 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject)
IBuffer* pAttribsBuffer) PURE;
+ /// Executes an mesh indirect draw command with indirect command count buffer.
+
+ /// \param [in] Attribs - Structure describing the command attributes, see Diligent::DrawMeshIndirectCountAttribs for details.
+ /// \param [in] pAttribsBuffer - Pointer to the buffer, from which indirect draw attributes will be read.
+ /// The buffer must contain the following arguments at the specified offset:
+ /// Direct3D12:
+ /// Uint32 ThreadGroupCountX;
+ /// Uint32 ThreadGroupCountY;
+ /// Uint32 ThreadGroupCountZ;
+ /// Vulkan:
+ /// Uint32 TaskCount;
+ /// Uint32 FirstTask;
+ /// Size of the buffer must be sizeof(Uint32[3]) * Attribs.MaxDrawCommands.
+ /// \param [in] pCountBuffer - Pointer to the buffer, from which Uint32 value with draw count will be read.
+ ///
+ /// \remarks For compatibility between Direct3D12 and Vulkan and with direct call (DrawMesh) use the first element in the structure,
+ /// for example: Direct3D12 {TaskCount, 1, 1}, Vulkan {TaskCount, 0}.
+ ///
+ /// \remarks If IndirectAttribsBufferStateTransitionMode member is Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION,
+ /// the method may transition the state of the indirect draw arguments buffer. This is not a thread safe operation,
+ /// so no other thread is allowed to read or write the state of the buffer.
+ ///
+ /// If the application intends to use the same resources in other threads simultaneously, it needs to
+ /// explicitly manage the states using IDeviceContext::TransitionResourceStates() method.
+ VIRTUAL void METHOD(DrawMeshIndirectCount)(THIS_
+ const DrawMeshIndirectCountAttribs REF Attribs,
+ IBuffer* pAttribsBuffer,
+ IBuffer* pCountBuffer) PURE;
+
+
/// Executes a dispatch compute command.
-
+
/// \param [in] Attribs - Dispatch command attributes, see Diligent::DispatchComputeAttribs for details.
VIRTUAL void METHOD(DispatchCompute)(THIS_
const DispatchComputeAttribs REF Attribs) PURE;
@@ -2264,6 +2337,7 @@ DILIGENT_END_INTERFACE
# define IDeviceContext_DrawIndexedIndirect(This, ...) CALL_IFACE_METHOD(DeviceContext, DrawIndexedIndirect, This, __VA_ARGS__)
# define IDeviceContext_DrawMesh(This, ...) CALL_IFACE_METHOD(DeviceContext, DrawMesh, This, __VA_ARGS__)
# define IDeviceContext_DrawMeshIndirect(This, ...) CALL_IFACE_METHOD(DeviceContext, DrawMeshIndirect, This, __VA_ARGS__)
+# define IDeviceContext_DrawMeshIndirectCount(This, ...) CALL_IFACE_METHOD(DeviceContext, DrawMeshIndirectCount, This, __VA_ARGS__)
# define IDeviceContext_DispatchCompute(This, ...) CALL_IFACE_METHOD(DeviceContext, DispatchCompute, This, __VA_ARGS__)
# define IDeviceContext_DispatchComputeIndirect(This, ...) CALL_IFACE_METHOD(DeviceContext, DispatchComputeIndirect, This, __VA_ARGS__)
# define IDeviceContext_ClearDepthStencil(This, ...) CALL_IFACE_METHOD(DeviceContext, ClearDepthStencil, This, __VA_ARGS__)
diff --git a/Graphics/GraphicsEngine/src/DeviceContextBase.cpp b/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
index 1e0a3b11..2561db62 100644
--- a/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
+++ b/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
@@ -136,6 +136,31 @@ bool VerifyDrawMeshIndirectAttribs(const DrawMeshIndirectAttribs& Attribs, const
return true;
}
+bool VerifyDrawMeshIndirectCountAttribs(const DrawMeshIndirectCountAttribs& Attribs, const IBuffer* pAttribsBuffer, const IBuffer* pCountBuff, Uint32 IndirectCmdStride)
+{
+#define CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS(Expr, ...) CHECK_PARAMETER(Expr, "Draw mesh indirect count attribs are invalid: ", __VA_ARGS__)
+
+ CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS(pAttribsBuffer != nullptr, "indirect draw arguments buffer must not be null.");
+
+ const auto& IDesc = pAttribsBuffer->GetDesc();
+ CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS((IDesc.BindFlags & BIND_INDIRECT_DRAW_ARGS) != 0,
+ "indirect draw arguments buffer '", IDesc.Name, "' was not created with BIND_INDIRECT_DRAW_ARGS flag.");
+ CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS(Attribs.IndirectDrawArgsOffset + IndirectCmdStride * Attribs.MaxCommandCount <= IDesc.uiSizeInBytes,
+ "invalid IndirectDrawArgsOffset or indirect draw arguments buffer '", IDesc.Name, "' is too small.");
+
+ CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS(pCountBuff != nullptr, "count buffer must not be null.");
+
+ const auto& CDesc = pAttribsBuffer->GetDesc();
+ CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS((CDesc.BindFlags & BIND_INDIRECT_DRAW_ARGS) != 0,
+ "count buffer '", CDesc.Name, "' was not created with BIND_INDIRECT_DRAW_ARGS flag.");
+ CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS(Attribs.CountBufferOffset + 4 <= CDesc.uiSizeInBytes,
+ "invalid CountBufferOffset or count buffer '", CDesc.Name, "' is too small.");
+
+#undef CHECK_DRAW_MESH_INDIRECT_COUNT_ATTRIBS
+
+ return true;
+}
+
bool VerifyDispatchComputeAttribs(const DispatchComputeAttribs& Attribs)
{