From 084ceb925acad470b69467d64e4dfbb3bd7ef3f1 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 18 Feb 2020 16:51:42 -0400 Subject: UI: Replasce accurate GPU option for GPU Accuracy Level --- src/video_core/engines/maxwell_dma.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index c2610f992..32b04e31e 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -136,7 +136,7 @@ void MaxwellDMA::HandleCopy() { write_buffer.resize(dst_size); } - if (Settings::values.use_accurate_gpu_emulation) { + if (Settings::IsGPULevelExtreme()) { memory_manager.ReadBlock(source, read_buffer.data(), src_size); memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); } else { -- cgit v1.2.3 From da8f17715dbdc7eec92f5f0c11c968a51b86cab4 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 16 Feb 2020 09:51:37 -0400 Subject: GPU: Refactor synchronization on Async GPU --- src/video_core/dma_pusher.cpp | 1 + src/video_core/engines/maxwell_3d.cpp | 8 ++++++-- src/video_core/gpu.cpp | 3 +++ src/video_core/gpu.h | 1 + src/video_core/gpu_thread.cpp | 6 +++--- src/video_core/rasterizer_interface.h | 6 ++++++ src/video_core/renderer_opengl/gl_rasterizer.cpp | 16 ++++++++++++++++ src/video_core/renderer_opengl/gl_rasterizer.h | 2 ++ src/video_core/renderer_vulkan/vk_rasterizer.cpp | 14 ++++++++++++++ src/video_core/renderer_vulkan/vk_rasterizer.h | 2 ++ src/video_core/texture_cache/texture_cache.h | 4 ++-- 11 files changed, 56 insertions(+), 7 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 0b77afc71..2516ea993 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -32,6 +32,7 @@ void DmaPusher::DispatchCalls() { } } gpu.FlushCommands(); + gpu.SyncGuestHost(); } bool DmaPusher::Step() { diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index baa74ad4c..2298a6273 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -403,9 +403,13 @@ void Maxwell3D::ProcessQueryGet() { "Units other than CROP are unimplemented"); switch (regs.query.query_get.operation) { - case Regs::QueryOperation::Release: - StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); + case Regs::QueryOperation::Release: { + rasterizer.FlushCommands(); + rasterizer.SyncGuestHost(); + const u64 result = regs.query.query_sequence; + StampQueryResult(result, regs.query.query_get.short_query == 0); break; + } case Regs::QueryOperation::Acquire: // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that // matches the current payload. diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index a606f4abd..13bca5a78 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -142,6 +142,9 @@ void GPU::FlushCommands() { renderer->Rasterizer().FlushCommands(); } +void GPU::SyncGuestHost() { + renderer->Rasterizer().SyncGuestHost(); +} // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. // So the values you see in docs might be multiplied by 4. diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 1a2d747be..99ed190bc 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -156,6 +156,7 @@ public: void CallMethod(const MethodCall& method_call); void FlushCommands(); + void SyncGuestHost(); /// Returns a reference to the Maxwell3D GPU engine. Engines::Maxwell3D& Maxwell3D(); diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 10cda686b..1994d3bb4 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -40,7 +40,7 @@ static void RunThread(VideoCore::RendererBase& renderer, Core::Frontend::Graphic } else if (const auto data = std::get_if(&next.data)) { renderer.Rasterizer().FlushRegion(data->addr, data->size); } else if (const auto data = std::get_if(&next.data)) { - renderer.Rasterizer().InvalidateRegion(data->addr, data->size); + renderer.Rasterizer().OnCPUWrite(data->addr, data->size); } else if (std::holds_alternative(next.data)) { return; } else { @@ -82,12 +82,12 @@ void ThreadManager::FlushRegion(VAddr addr, u64 size) { } void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { - system.Renderer().Rasterizer().InvalidateRegion(addr, size); + system.Renderer().Rasterizer().OnCPUWrite(addr, size); } void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) { // Skip flush on asynch mode, as FlushAndInvalidateRegion is not used for anything too important - InvalidateRegion(addr, size); + system.Renderer().Rasterizer().OnCPUWrite(addr, size); } void ThreadManager::WaitIdle() const { diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 8ae5b9c4e..0d05a3fc7 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -58,6 +58,12 @@ public: /// Notify rasterizer that any caches of the specified region should be invalidated virtual void InvalidateRegion(VAddr addr, u64 size) = 0; + /// Notify rasterizer that any caches of the specified region are desync with guest + virtual void OnCPUWrite(VAddr addr, u64 size) = 0; + + /// Sync memory between guest and host. + virtual void SyncGuestHost() = 0; + /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory /// and invalidated virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index ac4485a18..537912745 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -660,6 +660,22 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { query_cache.InvalidateRegion(addr, size); } +void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { + MICROPROFILE_SCOPE(OpenGL_CacheManagement); + if (!addr || !size) { + return; + } + texture_cache.OnCPUWrite(addr, size); + shader_cache.InvalidateRegion(addr, size); + buffer_cache.InvalidateRegion(addr, size); +} + +void RasterizerOpenGL::SyncGuestHost() { + MICROPROFILE_SCOPE(OpenGL_CacheManagement); + texture_cache.SyncGuestHost(); + // buffer_cache.SyncGuestHost(); +} + void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { if (Settings::IsGPULevelExtreme()) { FlushRegion(addr, size); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index caea174d2..a870024c6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -67,6 +67,8 @@ public: void FlushAll() override; void FlushRegion(VAddr addr, u64 size) override; void InvalidateRegion(VAddr addr, u64 size) override; + void OnCPUWrite(VAddr addr, u64 size) override; + void SyncGuestHost() override; void FlushAndInvalidateRegion(VAddr addr, u64 size) override; void FlushCommands() override; void TickFrame() override; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 71007bbe8..ad59f558d 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -524,6 +524,20 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { query_cache.InvalidateRegion(addr, size); } +void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { + if (!addr || !size) { + return; + } + texture_cache.OnCPUWrite(addr, size); + pipeline_cache.InvalidateRegion(addr, size); + buffer_cache.InvalidateRegion(addr, size); +} + +void RasterizerVulkan::SyncGuestHost() { + texture_cache.SyncGuestHost(); + // buffer_cache.SyncGuestHost(); +} + void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { FlushRegion(addr, size); InvalidateRegion(addr, size); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index d9108f862..285f731bc 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -119,6 +119,8 @@ public: void FlushAll() override; void FlushRegion(VAddr addr, u64 size) override; void InvalidateRegion(VAddr addr, u64 size) override; + void OnCPUWrite(VAddr addr, u64 size) override; + void SyncGuestHost() override; void FlushAndInvalidateRegion(VAddr addr, u64 size) override; void FlushCommands() override; void TickFrame() override; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 441fda53d..c23b9f9b9 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -63,7 +63,7 @@ public: } } - void OnCPUWrite(CacheAddr addr, std::size_t size) { + void OnCPUWrite(VAddr addr, std::size_t size) { std::lock_guard lock{mutex}; for (const auto& surface : GetSurfacesInRegion(addr, size)) { @@ -549,7 +549,7 @@ private: } const auto& final_params = new_surface->GetSurfaceParams(); if (cr_params.type != final_params.type) { - if (Settings::values.use_accurate_gpu_emulation) { + if (Settings::IsGPULevelExtreme()) { BufferCopy(current_surface, new_surface); } } else { -- cgit v1.2.3 From 339d0d9d6c02cf79d6025dae7c60d8635fa4ea3b Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 16 Feb 2020 16:24:37 -0400 Subject: GPU: Delay Fences. --- src/video_core/dma_pusher.cpp | 1 + src/video_core/engines/maxwell_3d.cpp | 10 +++++++++- src/video_core/engines/maxwell_3d.h | 4 ++++ src/video_core/gpu.cpp | 4 ++++ src/video_core/gpu.h | 1 + src/video_core/gpu_thread.cpp | 2 +- 6 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 31627b812..324dafdcd 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -34,6 +34,7 @@ void DmaPusher::DispatchCalls() { } gpu.FlushCommands(); gpu.SyncGuestHost(); + gpu.OnCommandListEnd(); } bool DmaPusher::Step() { diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2298a6273..2605c3b42 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -397,6 +397,14 @@ void Maxwell3D::StampQueryResult(u64 payload, bool long_query) { } } +void Maxwell3D::ReleaseFences() { + for (const auto pair : delay_fences) { + const auto [addr, payload] = pair; + memory_manager.Write(addr, static_cast(payload)); + } + delay_fences.clear(); +} + void Maxwell3D::ProcessQueryGet() { // TODO(Subv): Support the other query units. ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, @@ -407,7 +415,7 @@ void Maxwell3D::ProcessQueryGet() { rasterizer.FlushCommands(); rasterizer.SyncGuestHost(); const u64 result = regs.query.query_sequence; - StampQueryResult(result, regs.query.query_get.short_query == 0); + delay_fences.emplace_back(regs.query.QueryAddress(), result); break; } case Regs::QueryOperation::Acquire: diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 59d5752d2..0a93827ec 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1427,6 +1427,8 @@ public: Tables tables{}; } dirty; + void ReleaseFences(); + private: void InitializeRegisterDefaults(); @@ -1467,6 +1469,8 @@ private: std::array dirty_pointers{}; + std::vector> delay_fences; + /// Retrieves information about a specific TIC entry from the TIC buffer. Texture::TICEntry GetTICEntry(u32 tic_index) const; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 13bca5a78..71ddfbd26 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -145,6 +145,10 @@ void GPU::FlushCommands() { void GPU::SyncGuestHost() { renderer->Rasterizer().SyncGuestHost(); } + +void GPU::OnCommandListEnd() { + maxwell_3d->ReleaseFences(); +} // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. // So the values you see in docs might be multiplied by 4. diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 99ed190bc..b88445634 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -157,6 +157,7 @@ public: void FlushCommands(); void SyncGuestHost(); + void OnCommandListEnd(); /// Returns a reference to the Maxwell3D GPU engine. Engines::Maxwell3D& Maxwell3D(); diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 0a8123cfe..1994d3bb4 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -78,7 +78,7 @@ void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { } void ThreadManager::FlushRegion(VAddr addr, u64 size) { - system.Renderer().Rasterizer().FlushRegion(addr, size); + PushCommand(FlushRegionCommand(addr, size)); } void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { -- cgit v1.2.3 From 487379c593bcaf3787ede187c5d44f7923b54dc9 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 17 Feb 2020 18:10:23 -0400 Subject: OpenGL: Implement Fencing backend. --- src/video_core/engines/maxwell_3d.cpp | 16 ++++-------- src/video_core/engines/maxwell_3d.h | 4 --- src/video_core/gpu.cpp | 2 +- src/video_core/gpu.h | 2 +- src/video_core/gpu_asynch.cpp | 4 +++ src/video_core/gpu_asynch.h | 2 ++ src/video_core/gpu_thread.cpp | 6 +++++ src/video_core/gpu_thread.h | 7 +++++- src/video_core/rasterizer_interface.h | 8 ++++++ src/video_core/renderer_opengl/gl_rasterizer.cpp | 28 +++++++++++++++++++++ src/video_core/renderer_opengl/gl_rasterizer.h | 2 ++ src/video_core/texture_cache/texture_cache.h | 32 +++++++++++++++++++++++- 12 files changed, 94 insertions(+), 19 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2605c3b42..c297bc31b 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -397,14 +397,6 @@ void Maxwell3D::StampQueryResult(u64 payload, bool long_query) { } } -void Maxwell3D::ReleaseFences() { - for (const auto pair : delay_fences) { - const auto [addr, payload] = pair; - memory_manager.Write(addr, static_cast(payload)); - } - delay_fences.clear(); -} - void Maxwell3D::ProcessQueryGet() { // TODO(Subv): Support the other query units. ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, @@ -412,10 +404,12 @@ void Maxwell3D::ProcessQueryGet() { switch (regs.query.query_get.operation) { case Regs::QueryOperation::Release: { - rasterizer.FlushCommands(); - rasterizer.SyncGuestHost(); const u64 result = regs.query.query_sequence; - delay_fences.emplace_back(regs.query.QueryAddress(), result); + if (regs.query.query_get.fence == 1) { + rasterizer.SignalFence(regs.query.QueryAddress(), static_cast(result)); + } else { + StampQueryResult(result, regs.query.query_get.short_query == 0); + } break; } case Regs::QueryOperation::Acquire: diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 0a93827ec..59d5752d2 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1427,8 +1427,6 @@ public: Tables tables{}; } dirty; - void ReleaseFences(); - private: void InitializeRegisterDefaults(); @@ -1469,8 +1467,6 @@ private: std::array dirty_pointers{}; - std::vector> delay_fences; - /// Retrieves information about a specific TIC entry from the TIC buffer. Texture::TICEntry GetTICEntry(u32 tic_index) const; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 71ddfbd26..d05b6a9d2 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -147,7 +147,7 @@ void GPU::SyncGuestHost() { } void GPU::OnCommandListEnd() { - maxwell_3d->ReleaseFences(); + renderer.Rasterizer().ReleaseFences(); } // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index b88445634..fa9991c87 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -157,7 +157,7 @@ public: void FlushCommands(); void SyncGuestHost(); - void OnCommandListEnd(); + virtual void OnCommandListEnd(); /// Returns a reference to the Maxwell3D GPU engine. Engines::Maxwell3D& Maxwell3D(); diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp index 20e73a37e..53305ab43 100644 --- a/src/video_core/gpu_asynch.cpp +++ b/src/video_core/gpu_asynch.cpp @@ -52,4 +52,8 @@ void GPUAsynch::WaitIdle() const { gpu_thread.WaitIdle(); } +void GPUAsynch::OnCommandListEnd() { + gpu_thread.OnCommandListEnd(); +} + } // namespace VideoCommon diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h index 03fd0eef0..517658612 100644 --- a/src/video_core/gpu_asynch.h +++ b/src/video_core/gpu_asynch.h @@ -32,6 +32,8 @@ public: void FlushAndInvalidateRegion(VAddr addr, u64 size) override; void WaitIdle() const override; + void OnCommandListEnd() override; + protected: void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override; diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 1994d3bb4..251a9d911 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -37,6 +37,8 @@ static void RunThread(VideoCore::RendererBase& renderer, Core::Frontend::Graphic dma_pusher.DispatchCalls(); } else if (const auto data = std::get_if(&next.data)) { renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); + } else if (const auto data = std::get_if(&next.data)) { + renderer.Rasterizer().ReleaseFences(); } else if (const auto data = std::get_if(&next.data)) { renderer.Rasterizer().FlushRegion(data->addr, data->size); } else if (const auto data = std::get_if(&next.data)) { @@ -95,6 +97,10 @@ void ThreadManager::WaitIdle() const { } } +void ThreadManager::OnCommandListEnd() { + PushCommand(OnCommandListEndCommand()); +} + u64 ThreadManager::PushCommand(CommandData&& command_data) { const u64 fence{++state.last_fence}; state.queue.Push(CommandDataContainer(std::move(command_data), fence)); diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index cd74ad330..9d0877921 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h @@ -70,9 +70,12 @@ struct FlushAndInvalidateRegionCommand final { u64 size; }; +/// Command to signal to the GPU thread that processing has ended +struct OnCommandListEndCommand final {}; + using CommandData = std::variant; + InvalidateRegionCommand, FlushAndInvalidateRegionCommand, OnCommandListEndCommand>; struct CommandDataContainer { CommandDataContainer() = default; @@ -122,6 +125,8 @@ public: // Wait until the gpu thread is idle. void WaitIdle() const; + void OnCommandListEnd(); + private: /// Pushes a command to be executed by the GPU thread u64 PushCommand(CommandData&& command_data); diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 0d05a3fc7..72f65b166 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -49,6 +49,14 @@ public: /// Records a GPU query and caches it virtual void Query(GPUVAddr gpu_addr, QueryType type, std::optional timestamp) = 0; + virtual void SignalFence(GPUVAddr addr, u32 value) { + + } + + virtual void ReleaseFences() { + + } + /// Notify rasterizer that all caches should be flushed to Switch memory virtual void FlushAll() = 0; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 988eaeaa5..93bb33e8c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -676,6 +676,34 @@ void RasterizerOpenGL::SyncGuestHost() { buffer_cache.SyncGuestHost(); } +void RasterizerOpenGL::SignalFence(GPUVAddr addr, u32 value) { + if (!fences.empty()) { + const std::pair& current_fence = fences.front(); + const auto [address, payload] = current_fence; + texture_cache.PopAsyncFlushes(); + auto& gpu{system.GPU()}; + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write(address, payload); + fences.pop_front(); + } + fences.emplace_back(addr, value); + texture_cache.CommitAsyncFlushes(); + FlushCommands(); + SyncGuestHost(); +} + +void RasterizerOpenGL::ReleaseFences() { + while (!fences.empty()) { + const std::pair& current_fence = fences.front(); + const auto [address, payload] = current_fence; + texture_cache.PopAsyncFlushes(); + auto& gpu{system.GPU()}; + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write(address, payload); + fences.pop_front(); + } +} + void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { if (Settings::IsGPULevelExtreme()) { FlushRegion(addr, size); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index a870024c6..486a154ad 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -69,6 +69,8 @@ public: void InvalidateRegion(VAddr addr, u64 size) override; void OnCPUWrite(VAddr addr, u64 size) override; void SyncGuestHost() override; + void SignalFence(GPUVAddr addr, u32 value) override; + void ReleaseFences() override; void FlushAndInvalidateRegion(VAddr addr, u64 size) override; void FlushCommands() override; void TickFrame() override; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index d8c8390bb..6629c59ed 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -238,7 +238,7 @@ public: surface->MarkAsRenderTarget(false, NO_RT); const auto& cr_params = surface->GetSurfaceParams(); if (!cr_params.is_tiled) { - FlushSurface(surface); + AsyncFlushSurface(surface); } } render_targets[index].target = surface_view.first; @@ -317,6 +317,26 @@ public: return ++ticks; } + void CommitAsyncFlushes() { + commited_flushes.push_back(uncommited_flushes); + uncommited_flushes.reset(); + } + + void PopAsyncFlushes() { + if (commited_flushes.empty()) { + return; + } + auto& flush_list = commited_flushes.front(); + if (!flush_list) { + commited_flushes.pop_front(); + return; + } + for (TSurface& surface : *flush_list) { + FlushSurface(surface); + } + commited_flushes.pop_front(); + } + protected: explicit TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, bool is_astc_supported) @@ -1152,6 +1172,13 @@ private: TView view; }; + void AsyncFlushSurface(TSurface& surface) { + if (!uncommited_flushes) { + uncommited_flushes = std::make_shared>(); + } + uncommited_flushes->push_back(surface); + } + VideoCore::RasterizerInterface& rasterizer; FormatLookupTable format_lookup_table; @@ -1198,6 +1225,9 @@ private: std::list marked_for_unregister; + std::shared_ptr> uncommited_flushes{}; + std::list>> commited_flushes; + StagingCache staging_cache; std::recursive_mutex mutex; }; -- cgit v1.2.3 From a081a7c8558500249f4871f3a1b8c9046cb1b6f1 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 18 Feb 2020 13:19:24 -0400 Subject: GPU: Fix rebase errors. --- src/video_core/engines/maxwell_3d.cpp | 7 +++---- src/video_core/renderer_opengl/gl_rasterizer.cpp | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index c297bc31b..cff90bc1d 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -403,12 +403,11 @@ void Maxwell3D::ProcessQueryGet() { "Units other than CROP are unimplemented"); switch (regs.query.query_get.operation) { - case Regs::QueryOperation::Release: { - const u64 result = regs.query.query_sequence; + case Regs::QueryOperation::Release: if (regs.query.query_get.fence == 1) { - rasterizer.SignalFence(regs.query.QueryAddress(), static_cast(result)); + rasterizer.SignalFence(regs.query.QueryAddress(), regs.query.query_sequence); } else { - StampQueryResult(result, regs.query.query_get.short_query == 0); + StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); } break; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index ffa0a0429..db7eae065 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -673,6 +673,7 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { texture_cache.OnCPUWrite(addr, size); shader_cache.InvalidateRegion(addr, size); buffer_cache.OnCPUWrite(addr, size); + query_cache.InvalidateRegion(addr, size); } void RasterizerOpenGL::SyncGuestHost() { -- cgit v1.2.3 From 4adfc9bb0870296b372dc96296436538d6aa6c32 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 18 Feb 2020 13:24:38 -0400 Subject: Rasterizer: Document SignalFence & ReleaseFences and setup skeletons on Vulkan. --- src/video_core/engines/maxwell_3d.cpp | 1 - src/video_core/gpu_thread.cpp | 5 ++++- src/video_core/rasterizer_interface.h | 6 ++++-- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 25 ++++++++++++++++++++++++ src/video_core/renderer_vulkan/vk_rasterizer.h | 2 ++ 5 files changed, 35 insertions(+), 4 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index cff90bc1d..a7e951433 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -410,7 +410,6 @@ void Maxwell3D::ProcessQueryGet() { StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); } break; - } case Regs::QueryOperation::Acquire: // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that // matches the current payload. diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 672f8d2fa..1c3ab2145 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -81,9 +81,12 @@ void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { } void ThreadManager::FlushRegion(VAddr addr, u64 size) { + if (!Settings::IsGPULevelExtreme()) { + return; + } if (system.Renderer().Rasterizer().MustFlushRegion(addr, size)) { u64 fence = PushCommand(FlushRegionCommand(addr, size)); - while (fence < state.signaled_fence.load(std::memory_order_relaxed)) { + while (fence > state.signaled_fence.load(std::memory_order_relaxed)) { } } } diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 228752131..b49f15df2 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -49,9 +49,11 @@ public: /// Records a GPU query and caches it virtual void Query(GPUVAddr gpu_addr, QueryType type, std::optional timestamp) = 0; - virtual void SignalFence(GPUVAddr addr, u32 value) {} + /// Signal a GPU based fence + virtual void SignalFence(GPUVAddr addr, u32 value) = 0; - virtual void ReleaseFences() {} + /// Release all pending fences. + virtual void ReleaseFences() = 0; /// Notify rasterizer that all caches should be flushed to Switch memory virtual void FlushAll() = 0; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 9437a4aa1..1d75a4766 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -535,6 +535,7 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { texture_cache.OnCPUWrite(addr, size); pipeline_cache.InvalidateRegion(addr, size); buffer_cache.OnCPUWrite(addr, size); + query_cache.InvalidateRegion(addr, size); } void RasterizerVulkan::SyncGuestHost() { @@ -542,6 +543,30 @@ void RasterizerVulkan::SyncGuestHost() { buffer_cache.SyncGuestHost(); } +void RasterizerVulkan::SignalFence(GPUVAddr addr, u32 value) { + auto& gpu{system.GPU()}; + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write(addr, value); + /* + if (!gpu.IsAsync()) { + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write(addr, value); + return; + } + fence_manager.SignalFence(addr, value); + */ +} + +void RasterizerVulkan::ReleaseFences() { + /* + auto& gpu{system.GPU()}; + if (!gpu.IsAsync()) { + return; + } + fence_manager.WaitPendingFences(); + */ +} + void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { FlushRegion(addr, size); InvalidateRegion(addr, size); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 7002a4fa3..08a9af401 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -122,6 +122,8 @@ public: void InvalidateRegion(VAddr addr, u64 size) override; void OnCPUWrite(VAddr addr, u64 size) override; void SyncGuestHost() override; + void SignalFence(GPUVAddr addr, u32 value) override; + void ReleaseFences() override; void FlushAndInvalidateRegion(VAddr addr, u64 size) override; void FlushCommands() override; void TickFrame() override; -- cgit v1.2.3 From b7bc3c25496849661846f2fe42f591f2a81fbc87 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 19 Feb 2020 13:40:37 -0400 Subject: FenceManager: Manage syncpoints and rename fences to semaphores. --- src/video_core/buffer_cache/buffer_cache.h | 7 +++ src/video_core/engines/maxwell_3d.cpp | 4 +- src/video_core/fence_manager.h | 58 ++++++++++++++++++---- src/video_core/rasterizer_interface.h | 7 ++- .../renderer_opengl/gl_fence_manager.cpp | 24 +++++++-- src/video_core/renderer_opengl/gl_fence_manager.h | 6 ++- src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 ++++- src/video_core/renderer_opengl/gl_rasterizer.h | 3 +- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 16 +++++- src/video_core/renderer_vulkan/vk_rasterizer.h | 3 +- src/video_core/texture_cache/texture_cache.h | 7 +++ 11 files changed, 123 insertions(+), 25 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 06fb931d7..54c75ca4e 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -229,6 +229,13 @@ public: return true; } + bool HasUncommitedFlushes() { + if (uncommited_flushes) { + return true; + } + return false; + } + void PopAsyncFlushes() { if (commited_flushes.empty()) { return; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index a7e951433..2824ed707 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -405,7 +405,7 @@ void Maxwell3D::ProcessQueryGet() { switch (regs.query.query_get.operation) { case Regs::QueryOperation::Release: if (regs.query.query_get.fence == 1) { - rasterizer.SignalFence(regs.query.QueryAddress(), regs.query.query_sequence); + rasterizer.SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence); } else { StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); } @@ -487,7 +487,7 @@ void Maxwell3D::ProcessSyncPoint() { const u32 increment = regs.sync_info.increment.Value(); [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); if (increment) { - system.GPU().IncrementSyncPoint(sync_point); + rasterizer.SignalSyncPoint(sync_point); } } diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index 72ee50955..417cb113f 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h @@ -22,7 +22,11 @@ namespace VideoCommon { class FenceBase { public: - FenceBase(GPUVAddr address, u32 payload) : address{address}, payload{payload} {} + FenceBase(u32 payload, bool is_stubbed) + : address{}, payload{payload}, is_semaphore{false}, is_stubbed{is_stubbed} {} + + FenceBase(GPUVAddr address, u32 payload, bool is_stubbed) + : address{address}, payload{payload}, is_semaphore{true}, is_stubbed{is_stubbed} {} constexpr GPUVAddr GetAddress() const { return address; @@ -32,22 +36,49 @@ public: return payload; } + constexpr bool IsSemaphore() const { + return is_semaphore; + } + private: GPUVAddr address; u32 payload; + bool is_semaphore; + +protected: + bool is_stubbed; }; template class FenceManager { public: - void SignalFence(GPUVAddr addr, u32 value) { + void SignalSemaphore(GPUVAddr addr, u32 value) { TryReleasePendingFences(); + bool should_flush = texture_cache.HasUncommitedFlushes(); + should_flush |= buffer_cache.HasUncommitedFlushes(); texture_cache.CommitAsyncFlushes(); buffer_cache.CommitAsyncFlushes(); - TFence new_fence = CreateFence(addr, value); + TFence new_fence = CreateFence(addr, value, !should_flush); fences.push(new_fence); QueueFence(new_fence); - rasterizer.FlushCommands(); + if (should_flush) { + rasterizer.FlushCommands(); + } + rasterizer.SyncGuestHost(); + } + + void SignalSyncPoint(u32 value) { + TryReleasePendingFences(); + bool should_flush = texture_cache.HasUncommitedFlushes(); + should_flush |= buffer_cache.HasUncommitedFlushes(); + texture_cache.CommitAsyncFlushes(); + buffer_cache.CommitAsyncFlushes(); + TFence new_fence = CreateFence(value, !should_flush); + fences.push(new_fence); + QueueFence(new_fence); + if (should_flush) { + rasterizer.FlushCommands(); + } rasterizer.SyncGuestHost(); } @@ -62,8 +93,12 @@ public: texture_cache.PopAsyncFlushes(); buffer_cache.PopAsyncFlushes(); auto& gpu{system.GPU()}; - auto& memory_manager{gpu.MemoryManager()}; - memory_manager.Write(current_fence->GetAddress(), current_fence->GetPayload()); + if (current_fence->IsSemaphore()) { + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write(current_fence->GetAddress(), current_fence->GetPayload()); + } else { + gpu.IncrementSyncPoint(current_fence->GetPayload()); + } fences.pop(); } } @@ -74,7 +109,8 @@ protected: : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, buffer_cache{ buffer_cache} {} - virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0; + virtual TFence CreateFence(u32 value, bool is_stubbed) = 0; + virtual TFence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) = 0; virtual void QueueFence(TFence& fence) = 0; virtual bool IsFenceSignaled(TFence& fence) = 0; virtual void WaitFence(TFence& fence) = 0; @@ -96,8 +132,12 @@ private: texture_cache.PopAsyncFlushes(); buffer_cache.PopAsyncFlushes(); auto& gpu{system.GPU()}; - auto& memory_manager{gpu.MemoryManager()}; - memory_manager.Write(current_fence->GetAddress(), current_fence->GetPayload()); + if (current_fence->IsSemaphore()) { + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write(current_fence->GetAddress(), current_fence->GetPayload()); + } else { + gpu.IncrementSyncPoint(current_fence->GetPayload()); + } fences.pop(); } } diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index b49f15df2..4e9c8fb59 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -49,8 +49,11 @@ public: /// Records a GPU query and caches it virtual void Query(GPUVAddr gpu_addr, QueryType type, std::optional timestamp) = 0; - /// Signal a GPU based fence - virtual void SignalFence(GPUVAddr addr, u32 value) = 0; + /// Signal a GPU based semaphore as a fence + virtual void SignalSemaphore(GPUVAddr addr, u32 value) = 0; + + /// Signal a GPU based syncpoint as a fence + virtual void SignalSyncPoint(u32 value) = 0; /// Release all pending fences. virtual void ReleaseFences() = 0; diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp index 69dd3211b..579c03a1e 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.cpp +++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp @@ -8,17 +8,26 @@ namespace OpenGL { -GLInnerFence::GLInnerFence(GPUVAddr address, u32 payload) - : VideoCommon::FenceBase(address, payload), sync_object{} {} +GLInnerFence::GLInnerFence(u32 payload, bool is_stubbed) + : VideoCommon::FenceBase(payload, is_stubbed), sync_object{} {} + +GLInnerFence::GLInnerFence(GPUVAddr address, u32 payload, bool is_stubbed) + : VideoCommon::FenceBase(address, payload, is_stubbed), sync_object{} {} GLInnerFence::~GLInnerFence() = default; void GLInnerFence::Queue() { + if (is_stubbed) { + return; + } ASSERT(sync_object.handle == 0); sync_object.Create(); } bool GLInnerFence::IsSignaled() const { + if (is_stubbed) { + return true; + } ASSERT(sync_object.handle != 0); GLsizei length; GLint sync_status; @@ -27,6 +36,9 @@ bool GLInnerFence::IsSignaled() const { } void GLInnerFence::Wait() { + if (is_stubbed) { + return; + } ASSERT(sync_object.handle != 0); while (glClientWaitSync(sync_object.handle, 0, 1000) == GL_TIMEOUT_EXPIRED) ; @@ -36,8 +48,12 @@ FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::Rasteriz TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache) : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache) {} -Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) { - return std::make_shared(addr, value); +Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) { + return std::make_shared(value, is_stubbed); +} + +Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) { + return std::make_shared(addr, value, is_stubbed); } void FenceManagerOpenGL::QueueFence(Fence& fence) { diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h index b48d5eaa0..ba48d2f84 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.h +++ b/src/video_core/renderer_opengl/gl_fence_manager.h @@ -17,7 +17,8 @@ namespace OpenGL { class GLInnerFence : public VideoCommon::FenceBase { public: - GLInnerFence(GPUVAddr address, u32 payload); + GLInnerFence(u32 payload, bool is_stubbed); + GLInnerFence(GPUVAddr address, u32 payload, bool is_stubbed); ~GLInnerFence(); void Queue(); @@ -39,7 +40,8 @@ public: TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache); protected: - Fence CreateFence(GPUVAddr addr, u32 value) override; + Fence CreateFence(u32 value, bool is_stubbed) override; + Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override; void QueueFence(Fence& fence) override; bool IsFenceSignaled(Fence& fence) override; void WaitFence(Fence& fence) override; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 88914828c..e52e5961f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -683,14 +683,23 @@ void RasterizerOpenGL::SyncGuestHost() { buffer_cache.SyncGuestHost(); } -void RasterizerOpenGL::SignalFence(GPUVAddr addr, u32 value) { +void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { auto& gpu{system.GPU()}; if (!gpu.IsAsync()) { auto& memory_manager{gpu.MemoryManager()}; memory_manager.Write(addr, value); return; } - fence_manager.SignalFence(addr, value); + fence_manager.SignalSemaphore(addr, value); +} + +void RasterizerOpenGL::SignalSyncPoint(u32 value) { + auto& gpu{system.GPU()}; + if (!gpu.IsAsync()) { + gpu.IncrementSyncPoint(value); + return; + } + fence_manager.SignalSyncPoint(value); } void RasterizerOpenGL::ReleaseFences() { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 5c0f88e6f..15e9ff7d7 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -71,7 +71,8 @@ public: void InvalidateRegion(VAddr addr, u64 size) override; void OnCPUWrite(VAddr addr, u64 size) override; void SyncGuestHost() override; - void SignalFence(GPUVAddr addr, u32 value) override; + void SignalSemaphore(GPUVAddr addr, u32 value) override; + void SignalSyncPoint(u32 value) override; void ReleaseFences() override; void FlushAndInvalidateRegion(VAddr addr, u64 size) override; void FlushCommands() override; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 1d75a4766..507262c8f 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -543,7 +543,7 @@ void RasterizerVulkan::SyncGuestHost() { buffer_cache.SyncGuestHost(); } -void RasterizerVulkan::SignalFence(GPUVAddr addr, u32 value) { +void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { auto& gpu{system.GPU()}; auto& memory_manager{gpu.MemoryManager()}; memory_manager.Write(addr, value); @@ -553,7 +553,19 @@ void RasterizerVulkan::SignalFence(GPUVAddr addr, u32 value) { memory_manager.Write(addr, value); return; } - fence_manager.SignalFence(addr, value); + fence_manager.SignalSemaphore(addr, value); + */ +} + +void RasterizerVulkan::SignalSyncPoint(u32 value) { + auto& gpu{system.GPU()}; + gpu.IncrementSyncPoint(value); + /* + if (!gpu.IsAsync()) { + gpu.IncrementSyncPoint(value); + return; + } + fence_manager.SignalSyncPoint(value); */ } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 08a9af401..145bdf899 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -122,7 +122,8 @@ public: void InvalidateRegion(VAddr addr, u64 size) override; void OnCPUWrite(VAddr addr, u64 size) override; void SyncGuestHost() override; - void SignalFence(GPUVAddr addr, u32 value) override; + void SignalSemaphore(GPUVAddr addr, u32 value) override; + void SignalSyncPoint(u32 value) override; void ReleaseFences() override; void FlushAndInvalidateRegion(VAddr addr, u64 size) override; void FlushCommands() override; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index e1a1edbd2..f3ca1ffd1 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -337,6 +337,13 @@ public: uncommited_flushes.reset(); } + bool HasUncommitedFlushes() { + if (uncommited_flushes) { + return true; + } + return false; + } + bool ShouldWaitAsyncFlushes() { if (commited_flushes.empty()) { return false; -- cgit v1.2.3 From 1b3be8a8f86f0315004a4c60ef1828ba09f48b32 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 19 Apr 2020 13:27:56 -0400 Subject: MaxwellDMA: Correct copying on accuracy level. --- src/video_core/engines/maxwell_dma.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/video_core/engines') diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 32b04e31e..3bfed6ab8 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -104,8 +104,13 @@ void MaxwellDMA::HandleCopy() { write_buffer.resize(dst_size); } - memory_manager.ReadBlock(source, read_buffer.data(), src_size); - memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); + if (Settings::IsGPULevelExtreme()) { + memory_manager.ReadBlock(source, read_buffer.data(), src_size); + memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); + } else { + memory_manager.ReadBlockUnsafe(source, read_buffer.data(), src_size); + memory_manager.ReadBlockUnsafe(dest, write_buffer.data(), dst_size); + } Texture::UnswizzleSubrect( regs.x_count, regs.y_count, regs.dst_pitch, regs.src_params.size_x, bytes_per_pixel, -- cgit v1.2.3