From 3a4809263089384c98a835bf7969cce6d72b22e0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 4 Sep 2018 02:17:05 +0200 Subject: [PATCH] [dxvk] Implement transform feedback draw call --- src/dxvk/dxvk_buffer.h | 25 ++++++++++++++++++++++++- src/dxvk/dxvk_context.cpp | 27 ++++++++++++++++++++++++++- src/dxvk/dxvk_context.h | 12 ++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index e0a3ff77..77887178 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -146,6 +146,28 @@ namespace dxvk { return prevSlice; } + /** + * \brief Transform feedback vertex stride + * + * Used when drawing after transform feedback, + * \returns The current xfb vertex stride + */ + uint32_t getXfbVertexStride() const { + return m_vertexStride; + } + + /** + * \brief Set transform feedback vertex stride + * + * When the buffer is used as a transform feedback + * buffer, this will be set to the vertex stride + * defined by the geometry shader. + * \param [in] stride Vertex stride + */ + void setXfbVertexStride(uint32_t stride) { + m_vertexStride = stride; + } + /** * \brief Allocates new physical resource * \returns The new backing buffer slice @@ -170,7 +192,8 @@ namespace dxvk { VkMemoryPropertyFlags m_memFlags; DxvkPhysicalBufferSlice m_physSlice; - uint32_t m_revision = 0; + uint32_t m_revision = 0; + uint32_t m_vertexStride = 0; sync::Spinlock m_freeMutex; sync::Spinlock m_swapMutex; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 79e95440..1e6bfc47 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1020,6 +1020,25 @@ namespace dxvk { } + void DxvkContext::drawIndirectXfb( + const DxvkBufferSlice& counterBuffer, + uint32_t counterDivisor, + uint32_t counterBias) { + this->commitGraphicsState(); + + if (this->validateGraphicsState()) { + auto physicalSlice = counterBuffer.physicalSlice(); + + m_cmd->cmdDrawIndirectVertexCount(1, 0, + physicalSlice.handle(), + physicalSlice.offset(), + counterBias, counterDivisor); + } + + m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); + } + + void DxvkContext::initImage( const Rc& image, const VkImageSubresourceRange& subresources) { @@ -2758,6 +2777,8 @@ namespace dxvk { void DxvkContext::updateTransformFeedbackBuffers() { + auto gsOptions = m_state.gp.gs.shader->shaderOptions(); + VkBuffer xfbBuffers[MaxNumXfbBuffers]; VkDeviceSize xfbOffsets[MaxNumXfbBuffers]; VkDeviceSize xfbLengths[MaxNumXfbBuffers]; @@ -2772,8 +2793,12 @@ namespace dxvk { if (physSlice.handle() == VK_NULL_HANDLE) xfbBuffers[i] = m_device->dummyBufferHandle(); - if (physSlice.handle() != VK_NULL_HANDLE) + if (physSlice.handle() != VK_NULL_HANDLE) { + auto buffer = m_state.xfb.buffers[i].buffer(); + buffer->setXfbVertexStride(gsOptions.xfbStrides[i]); + m_cmd->trackResource(physSlice.resource()); + } } m_cmd->cmdBindTransformFeedbackBuffers( diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 27b41294..374eec3c 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -486,6 +486,18 @@ namespace dxvk { uint32_t count, uint32_t stride); + /** + * \brief Transform feddback draw call + + * \param [in] counterBuffer Xfb counter buffer + * \param [in] counterDivisor Vertex stride + * \param [in] counterBias Counter bias + */ + void drawIndirectXfb( + const DxvkBufferSlice& counterBuffer, + uint32_t counterDivisor, + uint32_t counterBias); + /** * \brief Generates mip maps *