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:
parent
5b66f1ec0b
commit
320e0de4a0
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user