diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 5da06668de..8aed499bb7 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -75,6 +75,8 @@ public: void Finish(); + void FlushDeferredClear() {} + StagingBufferMap UploadStagingBuffer(size_t size, bool deferred = false); StagingBufferMap DownloadStagingBuffer(size_t size, bool deferred = false); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 68852a0e82..792377d242 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -192,6 +192,14 @@ bool Scheduler::DeferDepthStencilClear(const Framebuffer* framebuffer, const VkC return true; } +void Scheduler::FlushDeferredClear() { + if (deferred_clear.framebuffer == nullptr) { + return; + } + RealizeDeferredClear(); + EndRenderPass(); +} + void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) { if (deferred_clear.framebuffer == framebuffer) { RealizeDeferredClear(); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index c2aa3fb996..d4bc8d0ec5 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -65,6 +65,9 @@ public: /// Defers a full depth/stencil clear so it becomes the next render pass. bool DeferDepthStencilClear(const Framebuffer* framebuffer, const VkClearValue& value); + /// Realizes any pending deferred clear before its framebuffer can be moved or freed. + void FlushDeferredClear(); + /// Requests the current execution context to be able to execute operations only allowed outside /// of a renderpass. void RequestOutsideRenderPassOperationContext(); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 35a04bd808..47d285f297 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1796,6 +1796,10 @@ bool TextureCacheRuntime::CanReportMemoryUsage() const { return device.CanReportMemoryUsage(); } +void TextureCacheRuntime::FlushDeferredClear() { + scheduler.FlushDeferredClear(); +} + void TextureCacheRuntime::TickFrame() { std::erase_if(pending_msaa_images, [this](const auto& pending) { return scheduler.IsFree(pending.first); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 681866d7e3..fd11dd2ef6 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -60,6 +60,8 @@ public: void TickFrame(); + void FlushDeferredClear(); + u64 GetDeviceLocalMemory() const; u64 GetDeviceMemoryUsage() const; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index de56ba52ed..e3e9e213a8 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -577,6 +577,7 @@ FramebufferId TextureCache
::GetFramebufferId(const RenderTargets& key) { return id ? &slot_image_views[id] : nullptr; }); ImageView* const depth_buffer = key.depth_buffer_id ? &slot_image_views[key.depth_buffer_id] : nullptr; + runtime.FlushDeferredClear(); framebuffer_id = slot_framebuffers.insert(runtime, color_buffers, depth_buffer, key); return framebuffer_id; } @@ -2419,6 +2420,7 @@ void TextureCache
::RemoveImageViewReferences(std::span ::RemoveFramebuffers(std::span