From 3749b812a3d729dd0fbb1fbfb5ae466813d8e2e3 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 4 Jul 2024 21:54:19 +1000 Subject: [PATCH] GPUDevice: Add ExecuteAndWaitForGPUIdle() --- src/util/d3d11_device.cpp | 5 +++++ src/util/d3d11_device.h | 2 ++ src/util/d3d12_device.cpp | 8 ++++++++ src/util/d3d12_device.h | 2 ++ src/util/gpu_device.h | 3 +++ src/util/metal_device.h | 2 ++ src/util/metal_device.mm | 6 ++++++ src/util/opengl_device.cpp | 6 ++++++ src/util/opengl_device.h | 2 ++ src/util/vulkan_device.cpp | 8 ++++++++ src/util/vulkan_device.h | 2 ++ 11 files changed, 46 insertions(+) diff --git a/src/util/d3d11_device.cpp b/src/util/d3d11_device.cpp index 1a7f33b6f..2e604c4a0 100644 --- a/src/util/d3d11_device.cpp +++ b/src/util/d3d11_device.cpp @@ -466,6 +466,11 @@ std::string D3D11Device::GetDriverInfo() const return ret; } +void D3D11Device::ExecuteAndWaitForGPUIdle() +{ + m_context->Flush(); +} + bool D3D11Device::CreateBuffers() { if (!m_vertex_buffer.Create(D3D11_BIND_VERTEX_BUFFER, VERTEX_BUFFER_SIZE, VERTEX_BUFFER_SIZE) || diff --git a/src/util/d3d11_device.h b/src/util/d3d11_device.h index 23da3223a..b41bf4d54 100644 --- a/src/util/d3d11_device.h +++ b/src/util/d3d11_device.h @@ -47,6 +47,8 @@ public: std::string GetDriverInfo() const override; + void ExecuteAndWaitForGPUIdle() override; + std::unique_ptr CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, GPUTexture::Type type, GPUTexture::Format format, const void* data = nullptr, u32 data_stride = 0) override; diff --git a/src/util/d3d12_device.cpp b/src/util/d3d12_device.cpp index 2774ccfee..093f014a4 100644 --- a/src/util/d3d12_device.cpp +++ b/src/util/d3d12_device.cpp @@ -638,6 +638,14 @@ void D3D12Device::WaitForGPUIdle() } } +void D3D12Device::ExecuteAndWaitForGPUIdle() +{ + if (InRenderPass()) + EndRenderPass(); + + SubmitCommandList(true); +} + bool D3D12Device::CreateTimestampQuery() { constexpr u32 QUERY_COUNT = NUM_TIMESTAMP_QUERIES_PER_CMDLIST * NUM_COMMAND_LISTS; diff --git a/src/util/d3d12_device.h b/src/util/d3d12_device.h index f33c265f4..24596d904 100644 --- a/src/util/d3d12_device.h +++ b/src/util/d3d12_device.h @@ -68,6 +68,8 @@ public: std::string GetDriverInfo() const override; + void ExecuteAndWaitForGPUIdle() override; + std::unique_ptr CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, GPUTexture::Type type, GPUTexture::Format format, const void* data = nullptr, u32 data_stride = 0) override; diff --git a/src/util/gpu_device.h b/src/util/gpu_device.h index e545c820d..8f624fc37 100644 --- a/src/util/gpu_device.h +++ b/src/util/gpu_device.h @@ -612,6 +612,9 @@ public: virtual std::string GetDriverInfo() const = 0; + // Executes current command buffer, waits for its completion, and destroys all pending resources. + virtual void ExecuteAndWaitForGPUIdle() = 0; + virtual std::unique_ptr CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, GPUTexture::Type type, GPUTexture::Format format, const void* data = nullptr, u32 data_stride = 0) = 0; diff --git a/src/util/metal_device.h b/src/util/metal_device.h index 6bffc27e0..fe3b570a9 100644 --- a/src/util/metal_device.h +++ b/src/util/metal_device.h @@ -208,6 +208,8 @@ public: std::string GetDriverInfo() const override; + void ExecuteAndWaitForGPUIdle() override; + std::unique_ptr CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, GPUTexture::Type type, GPUTexture::Format format, const void* data = nullptr, u32 data_stride = 0) override; diff --git a/src/util/metal_device.mm b/src/util/metal_device.mm index 7c1ee9e1c..9d4c65eab 100644 --- a/src/util/metal_device.mm +++ b/src/util/metal_device.mm @@ -2468,6 +2468,12 @@ void MetalDevice::WaitForPreviousCommandBuffers() WaitForFenceCounter(m_current_fence_counter - 1); } +void MetalDevice::ExecuteAndWaitForGPUIdle() +{ + SubmitCommandBuffer(true); + CleanupObjects(); +} + void MetalDevice::CleanupObjects() { const u64 counter = m_completed_fence_counter.load(std::memory_order_acquire); diff --git a/src/util/opengl_device.cpp b/src/util/opengl_device.cpp index 44061a55c..d68dc8dfd 100644 --- a/src/util/opengl_device.cpp +++ b/src/util/opengl_device.cpp @@ -582,6 +582,12 @@ std::string OpenGLDevice::GetDriverInfo() const gl_shading_language_version); } +void OpenGLDevice::ExecuteAndWaitForGPUIdle() +{ + // Could be glFinish(), but I'm afraid for mobile drivers... + glFlush(); +} + void OpenGLDevice::SetSwapInterval() { if (m_window_info.type == WindowInfo::Type::Surfaceless) diff --git a/src/util/opengl_device.h b/src/util/opengl_device.h index 0532a3ffe..b7ed363b6 100644 --- a/src/util/opengl_device.h +++ b/src/util/opengl_device.h @@ -48,6 +48,8 @@ public: std::string GetDriverInfo() const override; + void ExecuteAndWaitForGPUIdle() override; + std::unique_ptr CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, GPUTexture::Type type, GPUTexture::Format format, const void* data = nullptr, u32 data_stride = 0) override; diff --git a/src/util/vulkan_device.cpp b/src/util/vulkan_device.cpp index a0ab879e2..a9792d2b7 100644 --- a/src/util/vulkan_device.cpp +++ b/src/util/vulkan_device.cpp @@ -2370,6 +2370,14 @@ std::string VulkanDevice::GetDriverInfo() const return ret; } +void VulkanDevice::ExecuteAndWaitForGPUIdle() +{ + if (InRenderPass()) + EndRenderPass(); + + SubmitCommandBuffer(true); +} + void VulkanDevice::SetVSyncMode(GPUVSyncMode mode, bool allow_present_throttle) { m_allow_present_throttle = allow_present_throttle; diff --git a/src/util/vulkan_device.h b/src/util/vulkan_device.h index 347e8177b..76518afe0 100644 --- a/src/util/vulkan_device.h +++ b/src/util/vulkan_device.h @@ -82,6 +82,8 @@ public: std::string GetDriverInfo() const override; + void ExecuteAndWaitForGPUIdle() override; + std::unique_ptr CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, GPUTexture::Type type, GPUTexture::Format format, const void* data = nullptr, u32 data_stride = 0) override;