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 ::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 ::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