From 07e900baf66074fe486ddf190294c79d3e355424 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 23 Jun 2023 09:27:51 -0700 Subject: [PATCH] [Impeller] re-enable buffer to texture blit Vulkan. (flutter/engine#43129) I was missing the VMA flush. Because skia is writing directly to the exposed ptr, we don't go through the OnSetContents which makes a flush call. Add a flush API and implement it for Vk DeviceBuffers. --- engine/src/flutter/impeller/core/device_buffer.cc | 2 ++ engine/src/flutter/impeller/core/device_buffer.h | 2 ++ .../impeller/renderer/backend/vulkan/capabilities_vk.cc | 2 +- .../impeller/renderer/backend/vulkan/device_buffer_vk.cc | 4 ++++ .../impeller/renderer/backend/vulkan/device_buffer_vk.h | 5 +++++ engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc | 3 +++ 6 files changed, 17 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/impeller/core/device_buffer.cc b/engine/src/flutter/impeller/core/device_buffer.cc index 741a4d7ee2..0498ee3e89 100644 --- a/engine/src/flutter/impeller/core/device_buffer.cc +++ b/engine/src/flutter/impeller/core/device_buffer.cc @@ -39,6 +39,8 @@ std::shared_ptr DeviceBuffer::AsTexture( return texture; } +void DeviceBuffer::Flush() {} + const DeviceBufferDescriptor& DeviceBuffer::GetDeviceBufferDescriptor() const { return desc_; } diff --git a/engine/src/flutter/impeller/core/device_buffer.h b/engine/src/flutter/impeller/core/device_buffer.h index 507a4157d5..739d46ca22 100644 --- a/engine/src/flutter/impeller/core/device_buffer.h +++ b/engine/src/flutter/impeller/core/device_buffer.h @@ -32,6 +32,8 @@ class DeviceBuffer : public Buffer, BufferView AsBufferView() const; + virtual void Flush(); + virtual std::shared_ptr AsTexture( Allocator& allocator, const TextureDescriptor& descriptor, diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc index ddbbdb9160..c9cb8722cb 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc @@ -327,7 +327,7 @@ bool CapabilitiesVK::SupportsSSBO() const { // |Capabilities| bool CapabilitiesVK::SupportsBufferToTextureBlits() const { - return false; + return true; } // |Capabilities| diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.cc index cb84dcd5ef..e88a2cbc13 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.cc @@ -53,6 +53,10 @@ bool DeviceBufferVK::OnCopyHostBuffer(const uint8_t* source, return true; } +void DeviceBufferVK::Flush() { + ::vmaFlushAllocation(allocator_, allocation_, 0, VK_WHOLE_SIZE); +} + bool DeviceBufferVK::SetLabel(const std::string& label) { auto context = context_.lock(); if (!context || !buffer_) { diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.h index 229a1b6b04..25d910beff 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/device_buffer_vk.h @@ -28,6 +28,11 @@ class DeviceBufferVK final : public DeviceBuffer, vk::Buffer GetBuffer() const; + // If the contents of this buffer have been written to with + // `OnGetContents`, then calling flush may be necessary if the memory is + // non-coherent. + void Flush() override; + private: friend class AllocatorVK; diff --git a/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc b/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc index ecb455c1bd..c0776b0caa 100644 --- a/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc +++ b/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc @@ -510,6 +510,9 @@ ImpellerAllocator::ImpellerAllocator( std::optional> ImpellerAllocator::GetDeviceBuffer() const { + if (buffer_.has_value()) { + buffer_.value()->Flush(); + } return buffer_; }