diff --git a/core/rend/vulkan/oit/oit_drawer.h b/core/rend/vulkan/oit/oit_drawer.h index 1c29ee2a3..383ef6a8c 100644 --- a/core/rend/vulkan/oit/oit_drawer.h +++ b/core/rend/vulkan/oit/oit_drawer.h @@ -165,12 +165,16 @@ public: screenPipelineManager = std::make_unique(); screenPipelineManager->Init(shaderManager, oitBuffers); OITDrawer::Init(samplerManager, screenPipelineManager.get(), oitBuffers); + if (GetContext()->GetVendorID() == VulkanContext::VENDOR_ARM) + // Use an event to synchronize command buffers with Mali GPUs + event = GetContext()->GetDevice().createEventUnique(vk::EventCreateInfo()); MakeFramebuffers(viewport); GetContext()->PresentFrame(vk::Image(), vk::ImageView(), viewport, 0); } void Term() { + event.reset(); screenPipelineManager.reset(); framebuffers.clear(); finalColorAttachments.clear(); @@ -188,6 +192,10 @@ public: } else { + if (event) { + GetContext()->GetDevice().resetEvent(*event); + currentCommandBuffer.setEvent(*event, vk::PipelineStageFlagBits::eBottomOfPipe); + } currentCommandBuffer.end(); commandPool->EndFrame(); aspectRatio = getOutputFramebufferAspectRatio(); @@ -203,7 +211,7 @@ public: return false; frameRendered = false; GetContext()->PresentFrame(finalColorAttachments[GetCurrentImage()]->GetImage(), - finalColorAttachments[GetCurrentImage()]->GetImageView(), viewport.extent, aspectRatio); + finalColorAttachments[GetCurrentImage()]->GetImageView(), viewport.extent, aspectRatio, *event); return true; } @@ -222,6 +230,7 @@ private: std::vector transitionNeeded; bool frameRendered = false; float aspectRatio = 0.f; + vk::UniqueEvent event; }; class OITTextureDrawer : public OITDrawer diff --git a/core/rend/vulkan/vk_context_lr.cpp b/core/rend/vulkan/vk_context_lr.cpp index 8daa7aaa7..5265c95b1 100644 --- a/core/rend/vulkan/vk_context_lr.cpp +++ b/core/rend/vulkan/vk_context_lr.cpp @@ -321,7 +321,7 @@ bool VulkanContext::init(retro_hw_render_interface_vulkan *retro_render_if) return true; } -void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio) +void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio, vk::Event event) { if (image == vk::Image()) return; diff --git a/core/rend/vulkan/vk_context_lr.h b/core/rend/vulkan/vk_context_lr.h index 16edba20b..76039336d 100644 --- a/core/rend/vulkan/vk_context_lr.h +++ b/core/rend/vulkan/vk_context_lr.h @@ -43,7 +43,7 @@ public: void term() override; u32 GetGraphicsQueueFamilyIndex() const { return retro_render_if->queue_index; } - void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio); + void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio, vk::Event event = nullptr); vk::PhysicalDevice GetPhysicalDevice() const { return physicalDevice; } vk::Device GetDevice() const { return device; } diff --git a/core/rend/vulkan/vulkan_context.cpp b/core/rend/vulkan/vulkan_context.cpp index 18a194213..1677709e5 100644 --- a/core/rend/vulkan/vulkan_context.cpp +++ b/core/rend/vulkan/vulkan_context.cpp @@ -952,7 +952,7 @@ vk::CommandBuffer VulkanContext::PrepareOverlay(bool vmu, bool crosshair) extern Renderer *renderer; -void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio) noexcept +void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio, vk::Event event) noexcept { lastFrameView = imageView; lastFrameExtent = extent; @@ -967,7 +967,12 @@ void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const BeginRenderPass(); if (lastFrameView) // Might have been nullified if swap chain recreated + { + if (event) + GetCurrentCommandBuffer().waitEvents(event, vk::PipelineStageFlagBits::eBottomOfPipe, vk::PipelineStageFlagBits::eTopOfPipe, + nullptr, nullptr, nullptr); DrawFrame(imageView, extent, aspectRatio); + } DrawOverlay(settings.display.uiScale, config::FloatVMUs, true); renderer->DrawOSD(false); diff --git a/core/rend/vulkan/vulkan_context.h b/core/rend/vulkan/vulkan_context.h index cdff7e2cb..cbc109bfa 100644 --- a/core/rend/vulkan/vulkan_context.h +++ b/core/rend/vulkan/vulkan_context.h @@ -59,7 +59,7 @@ public: void BeginRenderPass(); void EndFrame(vk::CommandBuffer cmdBuffer = vk::CommandBuffer()); void Present() noexcept; - void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio) noexcept; + void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio, vk::Event event = nullptr) noexcept; void PresentLastFrame(); void initVideoRouting() override;