diff options
| author | azhirnov <zh1dron@gmail.com> | 2021-03-15 00:24:13 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:23 +0000 |
| commit | 408db3c96481ad05b686a5105cf92c9d58cfa5ba (patch) | |
| tree | a0d4c1c99665ff3e030477adf2b1dc93315c4d5c /Graphics/GraphicsEngine | |
| parent | Added inline ray tracing & trace rays indirect command. (diff) | |
| download | DiligentCore-408db3c96481ad05b686a5105cf92c9d58cfa5ba.tar.gz DiligentCore-408db3c96481ad05b686a5105cf92c9d58cfa5ba.zip | |
Added DrawMeshIndirectCount command.
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/include/DeviceContextBase.hpp | 69 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/DeviceContext.h | 76 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/src/DeviceContextBase.cpp | 25 |
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) { |
