1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxvk] Track transform feedback counter hazards properly

If we avoid needlessly pausing and resuming transform feedback with the
same counters, we can use existing barrier tracking to insert counter
barriers without requiring an invalid render pass self-dependency.
This commit is contained in:
Philip Rebohle 2021-08-23 16:36:39 +02:00
parent 04474b761b
commit 2f5c7562c2
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 12 additions and 20 deletions

View File

@ -2146,10 +2146,10 @@ namespace dxvk {
DxvkCmdBuffer cmdBuffer; DxvkCmdBuffer cmdBuffer;
if (replaceBuffer) { if (replaceBuffer) {
// Pause transform feedback so that we don't mess // Suspend render pass so that we don't mess with the
// with the currently bound counter buffers // currently bound transform feedback counter buffers
if (m_flags.test(DxvkContextFlag::GpXfbActive)) if (m_flags.test(DxvkContextFlag::GpXfbActive))
this->pauseTransformFeedback(); this->spillRenderPass(true);
// As an optimization, allocate a free slice and perform // As an optimization, allocate a free slice and perform
// the copy in the initialization command buffer instead // the copy in the initialization command buffer instead
@ -3925,8 +3925,6 @@ namespace dxvk {
m_gfxBarriers.recordCommands(m_cmd); m_gfxBarriers.recordCommands(m_cmd);
this->unbindGraphicsPipeline(); this->unbindGraphicsPipeline();
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
} else if (!suspend) { } else if (!suspend) {
// We may end a previously suspended render pass // We may end a previously suspended render pass
if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) { if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) {
@ -4023,16 +4021,6 @@ namespace dxvk {
if (!m_flags.test(DxvkContextFlag::GpXfbActive)) { if (!m_flags.test(DxvkContextFlag::GpXfbActive)) {
m_flags.set(DxvkContextFlag::GpXfbActive); m_flags.set(DxvkContextFlag::GpXfbActive);
if (m_flags.test(DxvkContextFlag::GpDirtyXfbCounters)) {
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
this->emitMemoryBarrier(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);
}
VkBuffer ctrBuffers[MaxNumXfbBuffers]; VkBuffer ctrBuffers[MaxNumXfbBuffers];
VkDeviceSize ctrOffsets[MaxNumXfbBuffers]; VkDeviceSize ctrOffsets[MaxNumXfbBuffers];
@ -4077,8 +4065,6 @@ namespace dxvk {
m_cmd->cmdEndTransformFeedback( m_cmd->cmdEndTransformFeedback(
0, MaxNumXfbBuffers, ctrBuffers, ctrOffsets); 0, MaxNumXfbBuffers, ctrBuffers, ctrOffsets);
m_flags.set(DxvkContextFlag::GpDirtyXfbCounters);
} }
} }
@ -4171,8 +4157,6 @@ namespace dxvk {
bool DxvkContext::updateGraphicsPipelineState() { bool DxvkContext::updateGraphicsPipelineState() {
this->pauseTransformFeedback();
// Set up vertex buffer strides for active bindings // Set up vertex buffer strides for active bindings
for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) { for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) {
const uint32_t binding = m_state.gp.state.ilBindings[i].binding(); const uint32_t binding = m_state.gp.state.ilBindings[i].binding();
@ -5105,11 +5089,20 @@ namespace dxvk {
&& m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasTransformFeedback)) { && m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasTransformFeedback)) {
for (uint32_t i = 0; i < MaxNumXfbBuffers && !requiresBarrier; i++) { for (uint32_t i = 0; i < MaxNumXfbBuffers && !requiresBarrier; i++) {
const auto& xfbBufferSlice = m_state.xfb.buffers[i]; const auto& xfbBufferSlice = m_state.xfb.buffers[i];
const auto& xfbCounterSlice = m_state.xfb.counters[i];
if (xfbBufferSlice.defined()) { if (xfbBufferSlice.defined()) {
requiresBarrier = this->checkGfxBufferBarrier<DoEmit>(xfbBufferSlice, requiresBarrier = this->checkGfxBufferBarrier<DoEmit>(xfbBufferSlice,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0; VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0;
if (xfbCounterSlice.defined()) {
requiresBarrier |= this->checkGfxBufferBarrier<DoEmit>(xfbCounterSlice,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT |
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT) != 0;
}
} }
} }
} }

View File

@ -32,7 +32,6 @@ namespace dxvk {
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
GpDirtyIndexBuffer, ///< Index buffer binding are out of date GpDirtyIndexBuffer, ///< Index buffer binding are out of date
GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date
GpDirtyXfbCounters, ///< Counter buffer values are dirty
GpDirtyBlendConstants, ///< Blend constants have changed GpDirtyBlendConstants, ///< Blend constants have changed
GpDirtyDepthBias, ///< Depth bias has changed GpDirtyDepthBias, ///< Depth bias has changed
GpDirtyDepthBounds, ///< Depth bounds have changed GpDirtyDepthBounds, ///< Depth bounds have changed