diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b68bd2f03..8e1b7b0d7 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -253,8 +253,6 @@ namespace dxvk { const DxvkBufferSlice& counter) { if (!m_state.xfb.buffers [binding].matches(buffer) || !m_state.xfb.counters[binding].matches(counter)) { - this->spillRenderPass(); - m_state.xfb.buffers [binding] = buffer; m_state.xfb.counters[binding] = counter; @@ -3785,6 +3783,7 @@ namespace dxvk { // Force-update vertex/index buffers for hazard checks m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer, DxvkContextFlag::GpDirtyVertexBuffers, + DxvkContextFlag::GpDirtyXfbBuffers, DxvkContextFlag::DirtyDrawBuffer); // This is necessary because we'll only do hazard @@ -4352,7 +4351,8 @@ namespace dxvk { return false; } - if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasStorageDescriptors)) + if (m_state.gp.flags.any(DxvkGraphicsPipelineFlag::HasStorageDescriptors, + DxvkGraphicsPipelineFlag::HasTransformFeedback)) this->commitGraphicsBarriers(); if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) @@ -4543,7 +4543,8 @@ namespace dxvk { auto layout = m_state.gp.pipeline->layout(); constexpr auto storageBufferUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT - | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; + | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT + | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT; constexpr auto storageImageUsage = VK_IMAGE_USAGE_STORAGE_BIT; bool requiresBarrier = false; @@ -4595,6 +4596,21 @@ namespace dxvk { } } + // Transform feedback buffer writes won't overlap, so we + // also only need to check those when they are rebound + if (m_flags.test(DxvkContextFlag::GpDirtyXfbCounters) + && m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasTransformFeedback)) { + for (uint32_t i = 0; i < MaxNumXfbBuffers && !requiresBarrier; i++) { + const auto& xfbBufferSlice = m_state.xfb.buffers[i]; + + if (xfbBufferSlice.defined()) { + requiresBarrier = this->checkGfxBufferBarrier(xfbBufferSlice, + VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0; + } + } + } + // Check shader resources on every draw to handle WAW hazards for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) { const DxvkDescriptorSlot binding = layout->binding(i);