1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19:24:10 +01:00

[dxvk] Handle xfb barriers in commitGraphicsBarriers

Avoids spilling the render pass when switching xfb buffers.
This commit is contained in:
Philip Rebohle 2019-10-26 16:26:21 +02:00
parent 5b66f1ec0b
commit 320e0de4a0
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99

View File

@ -253,8 +253,6 @@ namespace dxvk {
const DxvkBufferSlice& counter) { const DxvkBufferSlice& counter) {
if (!m_state.xfb.buffers [binding].matches(buffer) if (!m_state.xfb.buffers [binding].matches(buffer)
|| !m_state.xfb.counters[binding].matches(counter)) { || !m_state.xfb.counters[binding].matches(counter)) {
this->spillRenderPass();
m_state.xfb.buffers [binding] = buffer; m_state.xfb.buffers [binding] = buffer;
m_state.xfb.counters[binding] = counter; m_state.xfb.counters[binding] = counter;
@ -3785,6 +3783,7 @@ namespace dxvk {
// Force-update vertex/index buffers for hazard checks // Force-update vertex/index buffers for hazard checks
m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer, m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer,
DxvkContextFlag::GpDirtyVertexBuffers, DxvkContextFlag::GpDirtyVertexBuffers,
DxvkContextFlag::GpDirtyXfbBuffers,
DxvkContextFlag::DirtyDrawBuffer); DxvkContextFlag::DirtyDrawBuffer);
// This is necessary because we'll only do hazard // This is necessary because we'll only do hazard
@ -4352,7 +4351,8 @@ namespace dxvk {
return false; return false;
} }
if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasStorageDescriptors)) if (m_state.gp.flags.any(DxvkGraphicsPipelineFlag::HasStorageDescriptors,
DxvkGraphicsPipelineFlag::HasTransformFeedback))
this->commitGraphicsBarriers<Indexed, Indirect>(); this->commitGraphicsBarriers<Indexed, Indirect>();
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer))
@ -4543,7 +4543,8 @@ namespace dxvk {
auto layout = m_state.gp.pipeline->layout(); auto layout = m_state.gp.pipeline->layout();
constexpr auto storageBufferUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT 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; constexpr auto storageImageUsage = VK_IMAGE_USAGE_STORAGE_BIT;
bool requiresBarrier = false; 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 // Check shader resources on every draw to handle WAW hazards
for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) { for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) {
const DxvkDescriptorSlot binding = layout->binding(i); const DxvkDescriptorSlot binding = layout->binding(i);