From 3754e64eace661e7130c95e3c6ce96220256589d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 16 Feb 2025 13:53:46 +0100 Subject: [PATCH] [dxvk,d3d11] Fix draw buffer tracking for DrawAuto Not like anybody uses this feature, but we need to both check for hazards and make sure the SO counter actually gets tracked. Use the existing draw buffer mechanism for this. --- src/d3d11/d3d11_context.cpp | 16 ++++++++++++++-- src/dxvk/dxvk_context.cpp | 16 +++++++++------- src/dxvk/dxvk_context.h | 8 ++++---- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index bdbbf25a6d10..0868ab9edc7e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1009,10 +1009,22 @@ namespace dxvk { if (!ctrBuf.defined()) return; - EmitCs([=] (DxvkContext* ctx) { - ctx->drawIndirectXfb(ctrBuf, + // We bind the SO counter as an indirect count buffer, + // so reset any tracking we may have been doing here. + m_state.id.reset(); + + EmitCs([=] (DxvkContext* ctx) mutable { + ctx->bindDrawBuffers(DxvkBufferSlice(), + Forwarder::move(ctrBuf)); + + ctx->drawIndirectXfb(0u, vtxBuf.buffer()->getXfbVertexStride(), vtxBuf.offset()); + + // Reset draw buffer right away so we don't + // keep the SO counter alive indefinitely + ctx->bindDrawBuffers(DxvkBufferSlice(), + DxvkBufferSlice()); }); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e8adc0ede3b7..67d25e0c8d6c 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1052,17 +1052,19 @@ namespace dxvk { void DxvkContext::drawIndirectXfb( - const DxvkBufferSlice& counterBuffer, + VkDeviceSize counterOffset, uint32_t counterDivisor, uint32_t counterBias) { - if (this->commitGraphicsState()) { - auto physSlice = counterBuffer.getSliceHandle(); + if (this->commitGraphicsState()) { + auto physSlice = m_state.id.cntBuffer.getSliceHandle(); m_cmd->cmdDrawIndirectVertexCount(1, 0, - physSlice.handle, - physSlice.offset, - counterBias, - counterDivisor); + physSlice.handle, physSlice.offset + counterOffset, + counterBias, counterDivisor); + + // The count will generally be written from streamout + if (likely(m_state.id.cntBuffer.buffer()->hasGfxStores())) + accessDrawCountBuffer(counterOffset); } } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index ace683ebff79..a3aba78d2890 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -832,14 +832,14 @@ namespace dxvk { uint32_t stride); /** - * \brief Transform feddback draw call - - * \param [in] counterBuffer Xfb counter buffer + * \brief Transform feedback draw call + * + * \param [in] counterOffset Draw count offset * \param [in] counterDivisor Vertex stride * \param [in] counterBias Counter bias */ void drawIndirectXfb( - const DxvkBufferSlice& counterBuffer, + VkDeviceSize counterOffset, uint32_t counterDivisor, uint32_t counterBias);