Просмотр исходного кода

Merge pull request #5919 from ReinUsesLisp/stream-buffer-tragic

gl_stream_buffer/vk_staging_buffer_pool: Fix size check
Morph 5 лет назад
Родитель
Сommit
83227ad981

+ 1 - 1
src/video_core/renderer_opengl/gl_stream_buffer.cpp

@@ -40,7 +40,7 @@ std::pair<std::span<u8>, size_t> StreamBuffer::Request(size_t size) noexcept {
         glClientWaitSync(fences[region].handle, 0, GL_TIMEOUT_IGNORED);
         fences[region].Release();
     }
-    if (iterator + size > free_iterator) {
+    if (iterator + size >= free_iterator) {
         free_iterator = iterator + size;
     }
     if (iterator + size > STREAM_BUFFER_SIZE) {

+ 8 - 3
src/video_core/renderer_vulkan/vk_master_semaphore.h

@@ -21,7 +21,12 @@ public:
 
     /// Returns the current logical tick.
     [[nodiscard]] u64 CurrentTick() const noexcept {
-        return current_tick;
+        return current_tick.load(std::memory_order_relaxed);
+    }
+
+    /// Returns the last known GPU tick.
+    [[nodiscard]] u64 KnownGpuTick() const noexcept {
+        return gpu_tick.load(std::memory_order_relaxed);
     }
 
     /// Returns the timeline semaphore handle.
@@ -31,7 +36,7 @@ public:
 
     /// Returns true when a tick has been hit by the GPU.
     [[nodiscard]] bool IsFree(u64 tick) {
-        return gpu_tick >= tick;
+        return gpu_tick.load(std::memory_order_relaxed) >= tick;
     }
 
     /// Advance to the logical tick.
@@ -41,7 +46,7 @@ public:
 
     /// Refresh the known GPU tick
     void Refresh() {
-        gpu_tick = semaphore.GetCounter();
+        gpu_tick.store(semaphore.GetCounter(), std::memory_order_relaxed);
     }
 
     /// Waits for a tick to be hit on the GPU

+ 3 - 2
src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp

@@ -153,7 +153,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
     used_iterator = iterator;
     free_iterator = std::max(free_iterator, iterator + size);
 
-    if (iterator + size > STREAM_BUFFER_SIZE) {
+    if (iterator + size >= STREAM_BUFFER_SIZE) {
         std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS,
                   current_tick);
         used_iterator = 0;
@@ -175,8 +175,9 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
 }
 
 bool StagingBufferPool::AreRegionsActive(size_t region_begin, size_t region_end) const {
+    const u64 gpu_tick = scheduler.GetMasterSemaphore().KnownGpuTick();
     return std::any_of(sync_ticks.begin() + region_begin, sync_ticks.begin() + region_end,
-                       [this](u64 sync_tick) { return !scheduler.IsFree(sync_tick); });
+                       [gpu_tick](u64 sync_tick) { return gpu_tick < sync_tick; });
 };
 
 StagingBufferRef StagingBufferPool::GetStagingBuffer(size_t size, MemoryUsage usage) {