gpu: drop global barriers for PM4 flush events and releases, ordering buffer-writing draws like dispatches

This commit is contained in:
nmzik
2026-10-21 01:33:10 +02:00
parent ea1b032c59
commit 70668fbd98
6 changed files with 31 additions and 64 deletions
@@ -104,7 +104,6 @@ public:
uint32_t value);
void PrepareCpuFlip(uint64_t request_id);
void SynchronizeGpu();
void EmitGlobalBarrier();
void TriggerEopEventAtEndOfPipe(uint32_t interrupt_context_id);
void DispatchDirect(uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z,
uint32_t mode);
@@ -71,12 +71,6 @@ constexpr uint32_t NormalizeRegisterOffset(uint32_t raw_offset) {
return raw_offset & ~RegisterSelectorMask;
}
bool ReleaseMemGcrNeedsBarrier(uint32_t eop_event_type, uint32_t gcr_cntl) {
return eop_event_type != 0x28u ||
(gcr_cntl & (GcrGl2MetadataInvalidate | GcrGl0VectorInvalidate | GcrGl1Invalidate |
GcrGl2Invalidate | GcrGl2Writeback)) != 0;
}
uint32_t ReleaseMemCacheActionFromGcr(uint32_t gcr_cntl) {
return ((gcr_cntl & GcrGl2Writeback) != 0 ? 0x38u : 0x00u);
}
@@ -2259,30 +2253,14 @@ KYTY_CP_OP_PARSER(CpOpReleaseMem) {
}
};
if (data_sel == 0 || interrupt_selector == 4) {
if (eop_event_type != 0x28 || gcr_cntl != 0) {
cp.EmitGlobalBarrier();
}
// Cache actions only order GPU work, which the renderer's resource barriers already order.
if (data_sel == 0 || interrupt_selector == 4 ||
(release_dst == ReleaseMemDstMemory && dst_gpu_addr == nullptr)) {
trigger_interrupt();
return 7;
}
if (release_dst == ReleaseMemDstMemory && dst_gpu_addr == nullptr) {
if (eop_event_type != 0x28 || gcr_cntl != 0) {
cp.EmitGlobalBarrier();
}
trigger_interrupt();
return 7;
}
if (ReleaseMemGcrNeedsBarrier(eop_event_type, gcr_cntl)) {
cp.EmitGlobalBarrier();
}
auto cache_action = ReleaseMemCacheActionFromGcr(gcr_cntl);
cache_policy = 0;
+5 -27
View File
@@ -607,7 +607,6 @@ bool GuestGpu::Process(Submission& submission) {
case SubmissionType::SuspendPoint:
// Age caches at the frame boundary, not once per command list.
m_renderer.RunGarbageCollector();
cp.EmitGlobalBarrier();
m_renderer.GetCommandScheduler().DeferPriorityOperation(
[ready = m_suspend_point_ready] { ready->release(); });
cp.BufferFlush();
@@ -1222,22 +1221,6 @@ void CommandProcessor::WriteAtEndOfPipe64(uint32_t cache_policy, uint32_t event_
interrupt_context_id);
}
void CommandProcessor::EmitGlobalBarrier() {
Common::LockGuard lock(m_renderer.GetMutex());
vk::MemoryBarrier2 barrier {};
barrier.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands;
barrier.srcAccessMask = vk::AccessFlagBits2::eMemoryWrite;
barrier.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands;
barrier.dstAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite;
vk::DependencyInfo dependency {};
dependency.memoryBarrierCount = 1;
dependency.pMemoryBarriers = &barrier;
GetScheduler().EndRendering();
CurrentBuffer().Handle().pipelineBarrier2(dependency);
}
void CommandProcessor::TriggerEopEventAtEndOfPipe(uint32_t interrupt_context_id) {
(void)CurrentBuffer().Handle();
GetScheduler().DeferPriorityOperation(
@@ -1257,21 +1240,17 @@ void CommandProcessor::TriggerEvent(uint32_t event_type, uint32_t event_index,
}
const auto valid_cache_event_index = event_index == 0x00000000 || event_index == 0x00000007;
// Partial flushes and cache writebacks only order GPU work, which the renderer's resource
// barriers already order.
switch (event_type) {
// CsPartialFlush, GsPartialFlush, PsPartialFlush.
case 0x00000007:
case 0x0000000f:
case 0x00000010: EmitGlobalBarrier(); break;
// CbDbDataWritebackInvalidate, CbDataWritebackInvalidate.
case 0x00000010: break;
// CbDbDataWritebackInvalidate, CbDataWritebackInvalidate, DbDataWritebackInvalidate,
// DbMetadataWritebackInvalidate, CbMetadataWritebackInvalidate.
case 0x00000016:
case 0x00000031:
if (!valid_cache_event_index) {
EXIT("unknown event type: 0x%08" PRIx32 ", 0x%08" PRIx32 "\n", event_type,
event_index);
}
EmitGlobalBarrier();
break;
// DbDataWritebackInvalidate, DbMetadataWritebackInvalidate, CbMetadataWritebackInvalidate.
case 0x0000002a:
case 0x0000002c:
case 0x0000002e:
@@ -1279,7 +1258,6 @@ void CommandProcessor::TriggerEvent(uint32_t event_type, uint32_t event_index,
EXIT("unknown event type: 0x%08" PRIx32 ", 0x%08" PRIx32 "\n", event_type,
event_index);
}
EmitGlobalBarrier();
break;
case 0x0000000d:
case 0x0000000e: