From fd52022fff343f66a79ec9045985c720245dae04 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 29 Oct 2018 10:52:04 +0100 Subject: [PATCH] [dxvk] Spill render pass after draws with storage resources --- src/dxvk/dxvk_context.cpp | 28 ++++++++++++++++++++++------ src/dxvk/dxvk_context.h | 2 ++ src/dxvk/dxvk_context_state.h | 1 + src/dxvk/dxvk_graphics.h | 6 +++--- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 4b4dc9c6..e9d777a1 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -953,6 +953,8 @@ namespace dxvk { m_cmd->cmdDraw( vertexCount, instanceCount, firstVertex, firstInstance); + + this->commitGraphicsPostBarriers(); } m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); @@ -973,6 +975,7 @@ namespace dxvk { descriptor.buffer.offset + offset, count, stride); + this->commitGraphicsPostBarriers(); this->trackDrawBuffer(); } @@ -993,6 +996,8 @@ namespace dxvk { indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); + + this->commitGraphicsPostBarriers(); } m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); @@ -1013,6 +1018,7 @@ namespace dxvk { descriptor.buffer.offset + offset, count, stride); + this->commitGraphicsPostBarriers(); this->trackDrawBuffer(); } @@ -1033,6 +1039,8 @@ namespace dxvk { physicalSlice.handle(), physicalSlice.offset(), counterBias, counterDivisor); + + this->commitGraphicsPostBarriers(); } m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); @@ -2403,9 +2411,12 @@ namespace dxvk { m_state.gp.vs.shader, m_state.gp.tcs.shader, m_state.gp.tes.shader, m_state.gp.gs.shader, m_state.gp.fs.shader); + m_state.gp.flags = DxvkGraphicsPipelineFlags(); - if (m_state.gp.pipeline != nullptr) + if (m_state.gp.pipeline != nullptr) { + m_state.gp.flags = m_state.gp.pipeline->flags(); m_cmd->trackResource(m_state.gp.pipeline); + } } } @@ -2820,11 +2831,7 @@ namespace dxvk { void DxvkContext::updateTransformFeedbackState() { - bool hasTransformFeedback = - m_state.gp.pipeline != nullptr - && m_state.gp.pipeline->flags().test(DxvkGraphicsPipelineFlag::HasTransformFeedback); - - if (!hasTransformFeedback) + if (!m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasTransformFeedback)) return; if (m_flags.test(DxvkContextFlag::GpDirtyXfbBuffers)) { @@ -3022,6 +3029,15 @@ namespace dxvk { } } } + + + void DxvkContext::commitGraphicsPostBarriers() { + // Render pass dependencies always act as a full memory barrier. We + // have to do this because writes from the vertex shader in one draw + // need to be visible to the fragment shader in the next draw, etc. + if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasStorageDescriptors)) + this->spillRenderPass(); + } void DxvkContext::emitMemoryBarrier( diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 374eec3c..6943a70c 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -849,6 +849,8 @@ namespace dxvk { void commitComputeInitBarriers(); void commitComputePostBarriers(); + + void commitGraphicsPostBarriers(); void emitMemoryBarrier( VkPipelineStageFlags srcStages, diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 56107023..3e5512c2 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -110,6 +110,7 @@ namespace dxvk { DxvkShaderStage fs; DxvkGraphicsPipelineStateInfo state; + DxvkGraphicsPipelineFlags flags; Rc pipeline; }; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 999ffce0..445c942d 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -24,7 +24,7 @@ namespace dxvk { HasStorageDescriptors, }; - using DxvkGraphicsCommonPipelineFlags = Flags; + using DxvkGraphicsPipelineFlags = Flags; /** @@ -171,7 +171,7 @@ namespace dxvk { * \brief Returns graphics pipeline flags * \returns Graphics pipeline property flags */ - DxvkGraphicsCommonPipelineFlags flags() const { + DxvkGraphicsPipelineFlags flags() const { return m_flags; } @@ -232,7 +232,7 @@ namespace dxvk { uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; - DxvkGraphicsCommonPipelineFlags m_flags; + DxvkGraphicsPipelineFlags m_flags; DxvkGraphicsCommonPipelineStateInfo m_common; // List of pipeline instances, shared between threads