diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 129aeae5..ab4a68d6 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -723,20 +723,20 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexedInstancedIndirect( ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { - static bool errorShown = false; + D3D11Buffer* buffer = static_cast(pBufferForArgs); + DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); - if (!std::exchange(errorShown, true)) - Logger::err("D3D11DeviceContext::DrawIndexedInstancedIndirect: Not implemented"); + m_context->drawIndexedIndirect(bufferSlice, 1, 0); } void STDMETHODCALLTYPE D3D11DeviceContext::DrawInstancedIndirect( ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { - static bool errorShown = false; + D3D11Buffer* buffer = static_cast(pBufferForArgs); + DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); - if (!std::exchange(errorShown, true)) - Logger::err("D3D11DeviceContext::DrawInstancedIndirect: Not implemented"); + m_context->drawIndirect(bufferSlice, 1, 0); } @@ -754,10 +754,10 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DispatchIndirect( ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { - static bool errorShown = false; + D3D11Buffer* buffer = static_cast(pBufferForArgs); + DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); - if (!std::exchange(errorShown, true)) - Logger::err("D3D11DeviceContext::DispatchIndirect: Not implemented"); + m_context->dispatchIndirect(bufferSlice); } diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index cc87b50a..4e3ca3b9 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -239,6 +239,14 @@ namespace dxvk { } + void DxvkCommandList::cmdDispatchIndirect( + VkBuffer buffer, + VkDeviceSize offset) { + m_vkd->vkCmdDispatchIndirect( + m_buffer, buffer, offset); + } + + void DxvkCommandList::cmdDraw( uint32_t vertexCount, uint32_t instanceCount, @@ -250,6 +258,16 @@ namespace dxvk { } + void DxvkCommandList::cmdDrawIndirect( + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride) { + m_vkd->vkCmdDrawIndirect(m_buffer, + buffer, offset, drawCount, stride); + } + + void DxvkCommandList::cmdDrawIndexed( uint32_t indexCount, uint32_t instanceCount, @@ -263,6 +281,16 @@ namespace dxvk { } + void DxvkCommandList::cmdDrawIndexedIndirect( + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride) { + m_vkd->vkCmdDrawIndexedIndirect(m_buffer, + buffer, offset, drawCount, stride); + } + + void DxvkCommandList::cmdEndRenderPass() { m_vkd->vkCmdEndRenderPass(m_buffer); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index b74167de..1ea886eb 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -146,12 +146,22 @@ namespace dxvk { uint32_t y, uint32_t z); + void cmdDispatchIndirect( + VkBuffer buffer, + VkDeviceSize offset); + void cmdDraw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); + void cmdDrawIndirect( + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + void cmdDrawIndexed( uint32_t indexCount, uint32_t instanceCount, @@ -159,6 +169,12 @@ namespace dxvk { uint32_t vertexOffset, uint32_t firstInstance); + void cmdDrawIndexedIndirect( + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + void cmdEndRenderPass(); void cmdPipelineBarrier( diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d63df1d0..0209e929 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -381,6 +381,18 @@ namespace dxvk { } + void DxvkContext::dispatchIndirect( + const DxvkBufferSlice& buffer) { + this->commitComputeState(); + + m_cmd->cmdDispatchIndirect( + buffer.handle(), + buffer.offset()); + + this->commitComputeBarriers(); + } + + void DxvkContext::draw( uint32_t vertexCount, uint32_t instanceCount, @@ -394,6 +406,19 @@ namespace dxvk { } + void DxvkContext::drawIndirect( + const DxvkBufferSlice& buffer, + uint32_t count, + uint32_t stride) { + this->commitGraphicsState(); + + m_cmd->cmdDrawIndirect( + buffer.handle(), + buffer.offset(), + count, stride); + } + + void DxvkContext::drawIndexed( uint32_t indexCount, uint32_t instanceCount, @@ -409,6 +434,19 @@ namespace dxvk { } + void DxvkContext::drawIndexedIndirect( + const DxvkBufferSlice& buffer, + uint32_t count, + uint32_t stride) { + this->commitGraphicsState(); + + m_cmd->cmdDrawIndexedIndirect( + buffer.handle(), + buffer.offset(), + count, stride); + } + + void DxvkContext::initImage( const Rc& image, const VkImageSubresourceRange& subresources) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 7c1fa879..6e8c2470 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -217,6 +217,16 @@ namespace dxvk { uint32_t y, uint32_t z); + /** + * \brief Indirect dispatch call + * + * Takes arguments from a buffer. The buffer must contain + * a structure of the type \c VkDispatchIndirectCommand. + * \param [in] buffer The buffer slice + */ + void dispatchIndirect( + const DxvkBufferSlice& buffer); + /** * \brief Draws primitive without using an index buffer * @@ -231,6 +241,20 @@ namespace dxvk { uint32_t firstVertex, uint32_t firstInstance); + /** + * \brief Indirect indexed draw call + * + * Takes arguments from a buffer. The structure stored + * in the buffer must be of type \c VkDrawIndirectCommand. + * \param [in] buffer The buffer slice + * \param [in] count Number of dispatch calls + * \param [in] stride Stride between dispatch calls + */ + void drawIndirect( + const DxvkBufferSlice& buffer, + uint32_t count, + uint32_t stride); + /** * \brief Draws primitives using an index buffer * @@ -247,6 +271,20 @@ namespace dxvk { uint32_t vertexOffset, uint32_t firstInstance); + /** + * \brief Indirect indexed draw call + * + * Takes arguments from a buffer. The structure type for + * the draw buffer is \c VkDrawIndexedIndirectCommand. + * \param [in] buffer The buffer slice + * \param [in] count Number of dispatch calls + * \param [in] stride Stride between dispatch calls + */ + void drawIndexedIndirect( + const DxvkBufferSlice& buffer, + uint32_t count, + uint32_t stride); + /** * \brief Initializes or invalidates an image *