mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-27 04:54:15 +01:00
[dxvk] Fix global render pass barrier
Only need to deal with common write-after-read scenarios, we can ignore writes since those will add extra barriers anyway. Also move this work out of the somewhat hot pipeline bind function.
This commit is contained in:
parent
dd1ca4ce59
commit
6f7a468174
@ -21,32 +21,17 @@ namespace dxvk {
|
||||
m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets);
|
||||
m_descriptorManager = new DxvkDescriptorManager(device.ptr());
|
||||
|
||||
// Default destination barriers for graphics pipelines
|
||||
m_globalRoGraphicsBarrier.stages = m_device->getShaderPipelineStages()
|
||||
// Global barrier for graphics pipelines. This is only used to
|
||||
// avoid write-after-read hazards after a render pass, so the
|
||||
// access mask here can be zero.
|
||||
m_renderPassBarrierDst.stages = m_device->getShaderPipelineStages()
|
||||
| VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
m_globalRoGraphicsBarrier.access = 0;
|
||||
|
||||
if (m_device->features().extTransformFeedback.transformFeedback)
|
||||
m_globalRoGraphicsBarrier.stages |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
|
||||
|
||||
m_globalRwGraphicsBarrier = m_globalRoGraphicsBarrier;
|
||||
m_globalRwGraphicsBarrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
|
||||
| VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||
|
||||
m_globalRwGraphicsBarrier.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT
|
||||
| VK_ACCESS_INDEX_READ_BIT
|
||||
| VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
|
||||
| VK_ACCESS_UNIFORM_READ_BIT
|
||||
| VK_ACCESS_SHADER_READ_BIT
|
||||
| VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
||||
| VK_ACCESS_TRANSFER_READ_BIT;
|
||||
|
||||
if (m_device->features().extTransformFeedback.transformFeedback)
|
||||
m_globalRwGraphicsBarrier.access |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT;
|
||||
m_renderPassBarrierDst.stages |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
|
||||
|
||||
// Store the lifetime tracking bit as a context feature so
|
||||
// that we don't have to scan device features at draw time
|
||||
@ -5230,6 +5215,14 @@ namespace dxvk {
|
||||
else
|
||||
this->transitionRenderTargetLayouts(false);
|
||||
|
||||
if (m_renderPassBarrierSrc.stages) {
|
||||
accessMemory(DxvkCmdBuffer::ExecBuffer,
|
||||
m_renderPassBarrierSrc.stages, m_renderPassBarrierSrc.access,
|
||||
m_renderPassBarrierDst.stages, m_renderPassBarrierDst.access);
|
||||
|
||||
m_renderPassBarrierSrc = DxvkGlobalPipelineBarrier();
|
||||
}
|
||||
|
||||
flushBarriers();
|
||||
flushResolves();
|
||||
|
||||
@ -5733,7 +5726,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
bool DxvkContext::updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier) {
|
||||
bool DxvkContext::updateGraphicsPipelineState() {
|
||||
bool oldIndependentSets = m_flags.test(DxvkContextFlag::GpIndependentSets);
|
||||
|
||||
// Check which dynamic states need to be active. States that
|
||||
@ -5808,19 +5801,9 @@ namespace dxvk {
|
||||
|
||||
// Emit barrier based on pipeline properties, in order to avoid
|
||||
// accidental write-after-read hazards after the render pass.
|
||||
DxvkGlobalPipelineBarrier pipelineBarrier = m_state.gp.pipeline->getGlobalBarrier(m_state.gp.state);
|
||||
srcBarrier.stages |= pipelineBarrier.stages;
|
||||
srcBarrier.access |= pipelineBarrier.access;
|
||||
|
||||
if (srcBarrier.stages) {
|
||||
DxvkGlobalPipelineBarrier dstBarrier = (srcBarrier.access & vk::AccessWriteMask)
|
||||
? m_globalRwGraphicsBarrier
|
||||
: m_globalRoGraphicsBarrier;
|
||||
|
||||
accessMemory(DxvkCmdBuffer::ExecBuffer,
|
||||
srcBarrier.stages, srcBarrier.access,
|
||||
dstBarrier.stages, dstBarrier.access);
|
||||
}
|
||||
DxvkGlobalPipelineBarrier srcBarrier = m_state.gp.pipeline->getGlobalBarrier(m_state.gp.state);
|
||||
m_renderPassBarrierSrc.stages |= srcBarrier.stages;
|
||||
m_renderPassBarrierSrc.access |= srcBarrier.access;
|
||||
|
||||
if (unlikely(m_features.test(DxvkContextFeature::DebugUtils))) {
|
||||
uint32_t color = getGraphicsPipelineDebugColor();
|
||||
@ -6392,6 +6375,9 @@ namespace dxvk {
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_INDEX_READ_BIT, DxvkAccessOp::None);
|
||||
}
|
||||
|
||||
m_renderPassBarrierSrc.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||
m_renderPassBarrierSrc.access |= VK_ACCESS_INDEX_READ_BIT;
|
||||
|
||||
m_cmd->track(m_state.vi.indexBuffer.buffer(), DxvkAccess::Read);
|
||||
return true;
|
||||
}
|
||||
@ -6758,19 +6744,7 @@ namespace dxvk {
|
||||
this->updateSpecConstants<VK_PIPELINE_BIND_POINT_GRAPHICS>();
|
||||
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) {
|
||||
DxvkGlobalPipelineBarrier barrier = { };
|
||||
|
||||
if (Indexed) {
|
||||
barrier.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||
barrier.access |= VK_ACCESS_INDEX_READ_BIT;
|
||||
}
|
||||
|
||||
if (Indirect) {
|
||||
barrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
|
||||
barrier.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
}
|
||||
|
||||
if (unlikely(!this->updateGraphicsPipelineState(barrier)))
|
||||
if (unlikely(!this->updateGraphicsPipelineState()))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7031,6 +7005,9 @@ namespace dxvk {
|
||||
if (m_flags.test(DxvkContextFlag::DirtyDrawBuffer)) {
|
||||
m_flags.clr(DxvkContextFlag::DirtyDrawBuffer);
|
||||
|
||||
m_renderPassBarrierSrc.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
|
||||
m_renderPassBarrierSrc.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
|
||||
if (m_state.id.argBuffer.length())
|
||||
m_cmd->track(m_state.id.argBuffer.buffer(), DxvkAccess::Read);
|
||||
|
||||
|
@ -1435,8 +1435,8 @@ namespace dxvk {
|
||||
|
||||
DxvkGpuQueryManager m_queryManager;
|
||||
|
||||
DxvkGlobalPipelineBarrier m_globalRoGraphicsBarrier;
|
||||
DxvkGlobalPipelineBarrier m_globalRwGraphicsBarrier;
|
||||
DxvkGlobalPipelineBarrier m_renderPassBarrierSrc = { };
|
||||
DxvkGlobalPipelineBarrier m_renderPassBarrierDst = { };
|
||||
|
||||
DxvkRenderTargetLayouts m_rtLayouts = { };
|
||||
|
||||
@ -1690,7 +1690,7 @@ namespace dxvk {
|
||||
|
||||
void unbindGraphicsPipeline();
|
||||
bool updateGraphicsPipeline();
|
||||
bool updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier);
|
||||
bool updateGraphicsPipelineState();
|
||||
|
||||
uint32_t getGraphicsPipelineDebugColor() const;
|
||||
|
||||
|
@ -955,8 +955,7 @@ namespace dxvk {
|
||||
if (m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) {
|
||||
m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback);
|
||||
|
||||
m_barrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
|
||||
| VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
|
||||
m_barrier.stages |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
|
||||
m_barrier.access |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
|
||||
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT
|
||||
| VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
|
||||
|
Loading…
x
Reference in New Issue
Block a user