diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 425efed6..f7766932 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2176,6 +2176,8 @@ namespace dxvk { m_queries.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); this->renderPassUnbindFramebuffer(); + + m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters); } } @@ -2256,6 +2258,16 @@ namespace dxvk { if (!m_flags.test(DxvkContextFlag::GpXfbActive)) { m_flags.set(DxvkContextFlag::GpXfbActive); + if (m_flags.test(DxvkContextFlag::GpDirtyXfbCounters)) { + m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters); + + this->emitMemoryBarrier( + VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, /* XXX */ + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT); + } + VkBuffer ctrBuffers[MaxNumXfbBuffers]; VkDeviceSize ctrOffsets[MaxNumXfbBuffers]; @@ -2294,6 +2306,8 @@ namespace dxvk { m_cmd->cmdEndTransformFeedback( 0, MaxNumXfbBuffers, ctrBuffers, ctrOffsets); + + m_flags.set(DxvkContextFlag::GpDirtyXfbCounters); } } @@ -2967,6 +2981,22 @@ namespace dxvk { } + void DxvkContext::emitMemoryBarrier( + VkPipelineStageFlags srcStages, + VkAccessFlags srcAccess, + VkPipelineStageFlags dstStages, + VkAccessFlags dstAccess) { + VkMemoryBarrier barrier; + barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + barrier.pNext = nullptr; + barrier.srcAccessMask = srcAccess; + barrier.dstAccessMask = dstAccess; + + m_cmd->cmdPipelineBarrier(srcStages, dstStages, + 0, 1, &barrier, 0, nullptr, 0, nullptr); + } + + void DxvkContext::trackDrawBuffer() { if (m_flags.test(DxvkContextFlag::DirtyDrawBuffer)) { m_flags.clr(DxvkContextFlag::DirtyDrawBuffer); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 388f12c7..27b41294 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -838,6 +838,12 @@ namespace dxvk { void commitComputeInitBarriers(); void commitComputePostBarriers(); + void emitMemoryBarrier( + VkPipelineStageFlags srcStages, + VkAccessFlags srcAccess, + VkPipelineStageFlags dstStages, + VkAccessFlags dstAccess); + void trackDrawBuffer(); }; diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 33136a3b..56107023 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -33,6 +33,7 @@ namespace dxvk { GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date GpDirtyIndexBuffer, ///< Index buffer binding are out of date GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date + GpDirtyXfbCounters, ///< Counter buffer values are dirty GpDirtyBlendConstants, ///< Blend constants have changed GpDirtyStencilRef, ///< Stencil reference has changed GpDirtyViewport, ///< Viewport state has changed diff --git a/src/dxvk/dxvk_renderpass.cpp b/src/dxvk/dxvk_renderpass.cpp index 58422dd7..fff1d9cb 100644 --- a/src/dxvk/dxvk_renderpass.cpp +++ b/src/dxvk/dxvk_renderpass.cpp @@ -121,7 +121,7 @@ namespace dxvk { if (m_format.depth.format == VK_FORMAT_UNDEFINED) subpass.pDepthStencilAttachment = nullptr; - const std::array subpassDeps = {{ + const std::array subpassDeps = {{ { VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, @@ -130,6 +130,11 @@ namespace dxvk { VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0 }, + { 0, 0, + VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, /* XXX */ + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, 0 }, { 0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,