mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-09-30 21:11:43 -05:00
Vulkan: Experimental barrier skip when the game does not request it
This commit is contained in:
@@ -214,6 +214,10 @@ LatteCMDPtr LatteCP_itSurfaceSync(LatteCMDPtr cmd)
|
||||
MPTR addressPhys = LatteReadCMD() << 8;
|
||||
uint32 pollInterval = LatteReadCMD();
|
||||
|
||||
// let the renderer know about colorbuffer invalidation
|
||||
if (static_cast<uint32>(invalidationFlags & (Latte::E_COHER_CNTL::CB_ACTION_ENA | Latte::E_COHER_CNTL::CB_ALL_DEST_BASE_ENA)) != 0)
|
||||
g_renderer->SurfaceSync(invalidationFlags, addressPhys, size);
|
||||
|
||||
if (addressPhys == MPTR_NULL || size == 0xFFFFFFFF)
|
||||
return cmd; // block global invalidations because they are too expensive
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ namespace Latte
|
||||
SO1_DEST_BASE_ENA = (1<<3),
|
||||
SO2_DEST_BASE_ENA = (1<<4),
|
||||
SO3_DEST_BASE_ENA = (1<<5),
|
||||
CB0_DEST_BASE_ENA = (1<<6),
|
||||
CB0_DEST_BASE_ENA = (1<<6), // flush color buffer 0
|
||||
CB1_DEST_BASE_ENA = (1<<7),
|
||||
CB2_DEST_BASE_ENA = (1<<8),
|
||||
CB3_DEST_BASE_ENA = (1<<9),
|
||||
@@ -367,6 +367,8 @@ namespace Latte
|
||||
CB5_DEST_BASE_ENA = (1<<11),
|
||||
CB6_DEST_BASE_ENA = (1<<12),
|
||||
CB7_DEST_BASE_ENA = (1<<13),
|
||||
CB_ALL_DEST_BASE_ENA = (0xFF<<6), // CB0-CB7 combined
|
||||
|
||||
DB_DEST_BASE_ENA = (1<<14),
|
||||
|
||||
FULL_CACHE_ENA = (1<<20),
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
// flush control
|
||||
virtual void Flush(bool waitIdle = false) = 0; // called when explicit flush is required (e.g. by imgui)
|
||||
virtual void NotifyLatteCommandProcessorIdle() = 0; // called when command processor has no more commands available or when stalled
|
||||
virtual void SurfaceSync(Latte::E_COHER_CNTL coher, MPTR address, uint32 size) {} // triggered by game via GX2Invalidate, can be utilized by the render backend as an optimization hint
|
||||
|
||||
// imgui
|
||||
virtual bool ImguiBegin(bool mainWindow);
|
||||
|
||||
@@ -240,6 +240,7 @@ public:
|
||||
|
||||
void Flush(bool waitIdle = false) override;
|
||||
void NotifyLatteCommandProcessorIdle() override;
|
||||
void SurfaceSync(Latte::E_COHER_CNTL coher, MPTR address, uint32 size) override;
|
||||
|
||||
uint64 GenUniqueId(); // return unique id (uses incrementing counter)
|
||||
|
||||
@@ -419,6 +420,7 @@ private:
|
||||
|
||||
// invalidation / flushing
|
||||
uint64 currentFlushIndex{0};
|
||||
bool colorBufferSyncPending{false}; // guest color-buffer sync since the previous draw; survives command-buffer resets
|
||||
bool requestFlush{ false }; // flush after every draw operation. The renderpass dependencies dont handle dependencies across multiple drawcalls inside a single renderpass
|
||||
|
||||
// draw sequence
|
||||
|
||||
@@ -995,6 +995,12 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
|
||||
return dsInfo;
|
||||
}
|
||||
|
||||
void VulkanRenderer::SurfaceSync(Latte::E_COHER_CNTL coher, MPTR address, uint32 size)
|
||||
{
|
||||
if (static_cast<uint32>(coher & Latte::E_COHER_CNTL::CB_ALL_DEST_BASE_ENA) != 0)
|
||||
m_state.colorBufferSyncPending = true;
|
||||
}
|
||||
|
||||
void VulkanRenderer::sync_inputTexturesChanged(bool withinFeedbackLoopRenderPass)
|
||||
{
|
||||
bool writeFlushRequired = withinFeedbackLoopRenderPass; // feedback loop still requires us to emit a barrier
|
||||
@@ -1029,6 +1035,12 @@ void VulkanRenderer::sync_inputTexturesChanged(bool withinFeedbackLoopRenderPass
|
||||
// barrier here
|
||||
if (writeFlushRequired)
|
||||
{
|
||||
// Continued draws with unchanged descriptors in the same renderpass only introduce feedback hazards.
|
||||
// Relax color feedback without a guest sync, but keep the read indices above updated for later passes.
|
||||
if (withinFeedbackLoopRenderPass && !m_state.descriptorSetsChanged && !m_state.colorBufferSyncPending
|
||||
&& m_state.m_curRenderpassSelfDependencyInfo.GetAspectMask() == VK_IMAGE_ASPECT_COLOR_BIT)
|
||||
return;
|
||||
|
||||
VkMemoryBarrier memoryBarrier{};
|
||||
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||
memoryBarrier.srcAccessMask = 0;
|
||||
@@ -1740,6 +1752,7 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
||||
draw_execute_first(baseVertex, baseInstance, instanceCount, count, indexDataMPTR, indexType, drawcallContext);
|
||||
else
|
||||
draw_execute_continued(baseVertex, baseInstance, instanceCount, count, indexDataMPTR, indexType, drawcallContext);
|
||||
m_state.colorBufferSyncPending = false;
|
||||
LatteGPUState.drawCallCounter++;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,11 +286,7 @@ namespace GX2
|
||||
|
||||
if (HAS_FLAG(invalidationFlags, GX2InvalidationFlag::GPU_COLOR_BUFFER))
|
||||
{
|
||||
coherCntl |= Latte::E_COHER_CNTL::CB_ACTION_ENA
|
||||
| Latte::E_COHER_CNTL::CB0_DEST_BASE_ENA | Latte::E_COHER_CNTL::CB1_DEST_BASE_ENA
|
||||
| Latte::E_COHER_CNTL::CB2_DEST_BASE_ENA | Latte::E_COHER_CNTL::CB3_DEST_BASE_ENA
|
||||
| Latte::E_COHER_CNTL::CB4_DEST_BASE_ENA | Latte::E_COHER_CNTL::CB5_DEST_BASE_ENA
|
||||
| Latte::E_COHER_CNTL::CB6_DEST_BASE_ENA | Latte::E_COHER_CNTL::CB7_DEST_BASE_ENA;
|
||||
coherCntl |= Latte::E_COHER_CNTL::CB_ACTION_ENA | Latte::E_COHER_CNTL::CB_ALL_DEST_BASE_ENA;
|
||||
}
|
||||
|
||||
if (HAS_FLAG(invalidationFlags, GX2InvalidationFlag::GPU_DEPTH_BUFFER))
|
||||
|
||||
Reference in New Issue
Block a user