From f6cd6128fff6b42a504ac5a1376041720c3ba5af Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sat, 26 Sep 2026 18:28:32 -0400 Subject: [PATCH] Experiment on tfb draws again --- src/video_core/buffer_cache/buffer_base.h | 13 +++++++++---- src/video_core/buffer_cache/buffer_cache.h | 17 ++++++++++------- src/video_core/buffer_cache/buffer_cache_base.h | 7 +++++-- .../renderer_vulkan/vk_graphics_pipeline.cpp | 4 ---- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_base.h b/src/video_core/buffer_cache/buffer_base.h index b8d0d1896f..cdfb235ef0 100644 --- a/src/video_core/buffer_cache/buffer_base.h +++ b/src/video_core/buffer_cache/buffer_base.h @@ -137,18 +137,22 @@ public: content_serial = ++next_content_serial; } - [[nodiscard]] bool HasDrawHazard(u64 pass, u64 wfi, DAddr addr, u64 size) const noexcept { - return draw_write_pass == pass && draw_write_wfi < wfi && addr < draw_write_end && - addr + size > draw_write_begin; + [[nodiscard]] bool HasDrawHazard(u64 pass, u64 wfi, DAddr addr, u64 size, + bool check_feedback) const noexcept { + return draw_write_pass == pass && + (draw_write_wfi < wfi || (check_feedback && draw_write_feedback)) && + addr < draw_write_end && addr + size > draw_write_begin; } - void MarkDrawWrite(u64 pass, u64 wfi, DAddr addr, u64 size) noexcept { + void MarkDrawWrite(u64 pass, u64 wfi, DAddr addr, u64 size, bool feedback) noexcept { if (draw_write_pass != pass) { draw_write_pass = pass; draw_write_begin = addr; draw_write_end = addr + size; + draw_write_feedback = false; } draw_write_wfi = wfi; + draw_write_feedback |= feedback; draw_write_begin = (std::min)(draw_write_begin, addr); draw_write_end = (std::max)(draw_write_end, addr + size); } @@ -167,6 +171,7 @@ private: u64 draw_write_wfi = 0; DAddr draw_write_begin = 0; DAddr draw_write_end = 0; + bool draw_write_feedback = false; }; } // namespace VideoCommon diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 95610c7c14..087d7ac1f8 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -395,7 +395,7 @@ void BufferCache

::CommitDrawWrites() { const u64 pass = runtime.RenderPassSerial(); for (const DrawWrite& write : draw_writes) { slot_buffers[write.buffer_id].MarkDrawWrite(pass, draw_wfi, write.device_addr, - write.size); + write.size, write.feedback); } runtime.MarkRenderPassWrites(); } @@ -1202,8 +1202,8 @@ void BufferCache

::BindHostTransformFeedbackBuffers() { Buffer& buffer = slot_buffers[binding.buffer_id]; TouchBuffer(buffer, binding.buffer_id); size = binding.size; - SynchronizeBuffer(buffer, binding.device_addr, size); - MarkWrittenBuffer(binding.buffer_id, binding.device_addr, size); + SynchronizeBuffer(buffer, binding.device_addr, size, false); + MarkWrittenBuffer(binding.buffer_id, binding.device_addr, size, true); offset = buffer.Offset(binding.device_addr); buffer.MarkUsage(offset, size); host_buffer = &buffer; @@ -1573,13 +1573,14 @@ void BufferCache

::UpdateComputeTextureBuffers() { } template -void BufferCache

::MarkWrittenBuffer(BufferId buffer_id, DAddr device_addr, u32 size) { +void BufferCache

::MarkWrittenBuffer(BufferId buffer_id, DAddr device_addr, u32 size, + bool feedback) { if constexpr (!IS_OPENGL) { Buffer& buffer = slot_buffers[buffer_id]; buffer.setWriteTick(runtime.CurrentTick()); buffer.MarkContentModified(); if (recording_draw) { - draw_writes.push_back({buffer_id, device_addr, size}); + draw_writes.push_back({buffer_id, device_addr, size, feedback}); } } memory_tracker.MarkRegionAsGpuModified(device_addr, size); @@ -1800,9 +1801,11 @@ void BufferCache

::TouchBuffer(Buffer& buffer, BufferId buffer_id) noexcept { } template -bool BufferCache

::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size) { +bool BufferCache

::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size, + bool check_feedback) { if constexpr (!IS_OPENGL) { - draw_hazard |= buffer.HasDrawHazard(draw_pass, draw_wfi, device_addr, size); + draw_hazard |= + buffer.HasDrawHazard(draw_pass, draw_wfi, device_addr, size, check_feedback); } upload_copies.clear(); u64 total_size_bytes = 0; diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 6730291831..d1f9ff5f97 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -443,7 +443,8 @@ private: void UpdateComputeTextureBuffers(); - void MarkWrittenBuffer(BufferId buffer_id, DAddr device_addr, u32 size); + void MarkWrittenBuffer(BufferId buffer_id, DAddr device_addr, u32 size, + bool feedback = false); [[nodiscard]] BufferId FindBuffer(DAddr device_addr, u32 size, bool sparse_compatible); @@ -465,7 +466,8 @@ private: void TouchBuffer(Buffer& buffer, BufferId buffer_id) noexcept; - bool SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size); + bool SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size, + bool check_feedback = true); void UploadMemory(Buffer& buffer, u64 total_size_bytes, u64 largest_copy, std::span copies); @@ -528,6 +530,7 @@ private: BufferId buffer_id; DAddr device_addr; u32 size; + bool feedback; }; boost::container::small_vector draw_writes; u64 draw_pass = 0; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 792e7d2e7c..d0be8fbded 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -532,10 +532,6 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) { bind_stage_info(4); } - if (regs.transform_feedback_enabled != 0) { - scheduler.RequestOutsideRenderPassOperationContext(); - } - buffer_cache.UpdateGraphicsBuffers(is_indexed); buffer_cache.BindHostGeometryBuffers(is_indexed);