diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 7f143b41e80ea..b64c8e147af36 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -831,6 +831,10 @@ FILE: ../../../flutter/flow/surface_frame.cc FILE: ../../../flutter/flow/surface_frame.h FILE: ../../../flutter/flow/surface_frame_unittests.cc FILE: ../../../flutter/flow/texture_unittests.cc +FILE: ../../../flutter/flutter_vma/flutter_skia_vma.cc +FILE: ../../../flutter/flutter_vma/flutter_skia_vma.h +FILE: ../../../flutter/flutter_vma/flutter_vma.cc +FILE: ../../../flutter/flutter_vma/flutter_vma.h FILE: ../../../flutter/fml/ascii_trie.cc FILE: ../../../flutter/fml/ascii_trie.h FILE: ../../../flutter/fml/ascii_trie_unittests.cc @@ -3256,6 +3260,12 @@ FILE: ../../../flutter/third_party/txt/src/txt/platform_fuchsia.cc FILE: ../../../flutter/third_party/txt/src/txt/platform_linux.cc FILE: ../../../flutter/third_party/txt/src/txt/platform_mac.mm FILE: ../../../flutter/third_party/txt/src/txt/platform_windows.cc +FILE: ../../../flutter/vulkan/procs/vulkan_handle.cc +FILE: ../../../flutter/vulkan/procs/vulkan_handle.h +FILE: ../../../flutter/vulkan/procs/vulkan_interface.cc +FILE: ../../../flutter/vulkan/procs/vulkan_interface.h +FILE: ../../../flutter/vulkan/procs/vulkan_proc_table.cc +FILE: ../../../flutter/vulkan/procs/vulkan_proc_table.h FILE: ../../../flutter/vulkan/vulkan_application.cc FILE: ../../../flutter/vulkan/vulkan_application.h FILE: ../../../flutter/vulkan/vulkan_backbuffer.cc @@ -3266,20 +3276,16 @@ FILE: ../../../flutter/vulkan/vulkan_debug_report.cc FILE: ../../../flutter/vulkan/vulkan_debug_report.h FILE: ../../../flutter/vulkan/vulkan_device.cc FILE: ../../../flutter/vulkan/vulkan_device.h -FILE: ../../../flutter/vulkan/vulkan_handle.cc -FILE: ../../../flutter/vulkan/vulkan_handle.h FILE: ../../../flutter/vulkan/vulkan_image.cc FILE: ../../../flutter/vulkan/vulkan_image.h -FILE: ../../../flutter/vulkan/vulkan_interface.cc -FILE: ../../../flutter/vulkan/vulkan_interface.h FILE: ../../../flutter/vulkan/vulkan_native_surface.cc FILE: ../../../flutter/vulkan/vulkan_native_surface.h FILE: ../../../flutter/vulkan/vulkan_native_surface_android.cc FILE: ../../../flutter/vulkan/vulkan_native_surface_android.h -FILE: ../../../flutter/vulkan/vulkan_proc_table.cc -FILE: ../../../flutter/vulkan/vulkan_proc_table.h FILE: ../../../flutter/vulkan/vulkan_provider.cc FILE: ../../../flutter/vulkan/vulkan_provider.h +FILE: ../../../flutter/vulkan/vulkan_skia_proc_table.cc +FILE: ../../../flutter/vulkan/vulkan_skia_proc_table.h FILE: ../../../flutter/vulkan/vulkan_surface.cc FILE: ../../../flutter/vulkan/vulkan_surface.h FILE: ../../../flutter/vulkan/vulkan_swapchain.cc diff --git a/flutter_vma/BUILD.gn b/flutter_vma/BUILD.gn new file mode 100644 index 0000000000000..26e6566a3d60c --- /dev/null +++ b/flutter_vma/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//flutter/flutter_vma/config.gni") + +source_set("flutter_vma") { + sources = [ + "flutter_vma.cc", + "flutter_vma.h", + ] + + if (disable_vma_stl_shared_mutex) { + defines = [ "VMA_USE_STL_SHARED_MUTEX=0" ] + } + + deps = [ + "//third_party/vulkan-deps/vulkan-headers/src:vulkan_headers", + "//third_party/vulkan_memory_allocator", + ] + + public_configs = [ "//flutter:config" ] +} + +source_set("flutter_skia_vma") { + sources = [ + "flutter_skia_vma.cc", + "flutter_skia_vma.h", + ] + + public_deps = [ ":flutter_vma" ] + + deps = [ + "//flutter/fml", + "//flutter/vulkan/procs", + "//third_party/skia", + "//third_party/vulkan-deps/vulkan-headers/src:vulkan_headers", + "//third_party/vulkan_memory_allocator", + ] +} diff --git a/flutter_vma/config.gni b/flutter_vma/config.gni new file mode 100644 index 0000000000000..bb3be5faa20cc --- /dev/null +++ b/flutter_vma/config.gni @@ -0,0 +1,7 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + disable_vma_stl_shared_mutex = false +} diff --git a/flutter_vma/flutter_skia_vma.cc b/flutter_vma/flutter_skia_vma.cc new file mode 100644 index 0000000000000..5b4eb89ae4a39 --- /dev/null +++ b/flutter_vma/flutter_skia_vma.cc @@ -0,0 +1,274 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/flutter_vma/flutter_skia_vma.h" + +#include "flutter/fml/memory/ref_ptr.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" + +namespace flutter { + +sk_sp FlutterSkiaVulkanMemoryAllocator::Make( + uint32_t vulkan_api_version, + VkInstance instance, + VkPhysicalDevice physicalDevice, + VkDevice device, + const fml::RefPtr& vk, + bool mustUseCoherentHostVisibleMemory) { +#define PROVIDE_PROC(tbl, proc, provider) tbl.vk##proc = provider->proc; + + VmaVulkanFunctions proc_table = {}; + proc_table.vkGetInstanceProcAddr = vk->NativeGetInstanceProcAddr(); + PROVIDE_PROC(proc_table, GetDeviceProcAddr, vk); + PROVIDE_PROC(proc_table, GetPhysicalDeviceProperties, vk); + PROVIDE_PROC(proc_table, GetPhysicalDeviceMemoryProperties, vk); + PROVIDE_PROC(proc_table, AllocateMemory, vk); + PROVIDE_PROC(proc_table, FreeMemory, vk); + PROVIDE_PROC(proc_table, MapMemory, vk); + PROVIDE_PROC(proc_table, UnmapMemory, vk); + PROVIDE_PROC(proc_table, FlushMappedMemoryRanges, vk); + PROVIDE_PROC(proc_table, InvalidateMappedMemoryRanges, vk); + PROVIDE_PROC(proc_table, BindBufferMemory, vk); + PROVIDE_PROC(proc_table, BindImageMemory, vk); + PROVIDE_PROC(proc_table, GetBufferMemoryRequirements, vk); + PROVIDE_PROC(proc_table, GetImageMemoryRequirements, vk); + PROVIDE_PROC(proc_table, CreateBuffer, vk); + PROVIDE_PROC(proc_table, DestroyBuffer, vk); + PROVIDE_PROC(proc_table, CreateImage, vk); + PROVIDE_PROC(proc_table, DestroyImage, vk); + PROVIDE_PROC(proc_table, CmdCopyBuffer, vk); + +#define PROVIDE_PROC_COALESCE(tbl, proc, provider) \ + tbl.vk##proc##KHR = provider->proc ? provider->proc : provider->proc##KHR; + // See the following link for why we have to pick either KHR version or + // promoted non-KHR version: + // https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/issues/203 + PROVIDE_PROC_COALESCE(proc_table, GetBufferMemoryRequirements2, vk); + PROVIDE_PROC_COALESCE(proc_table, GetImageMemoryRequirements2, vk); + PROVIDE_PROC_COALESCE(proc_table, BindBufferMemory2, vk); + PROVIDE_PROC_COALESCE(proc_table, BindImageMemory2, vk); + PROVIDE_PROC_COALESCE(proc_table, GetPhysicalDeviceMemoryProperties2, vk); +#undef PROVIDE_PROC_COALESCE + +#undef PROVIDE_PROC + + VmaAllocatorCreateInfo allocator_info = {}; + allocator_info.vulkanApiVersion = vulkan_api_version; + allocator_info.physicalDevice = physicalDevice; + allocator_info.device = device; + allocator_info.instance = instance; + allocator_info.pVulkanFunctions = &proc_table; + + VmaAllocator allocator; + vmaCreateAllocator(&allocator_info, &allocator); + + return sk_sp( + new FlutterSkiaVulkanMemoryAllocator(vk, allocator, + mustUseCoherentHostVisibleMemory)); +} + +FlutterSkiaVulkanMemoryAllocator::FlutterSkiaVulkanMemoryAllocator( + fml::RefPtr vk_proc_table, + VmaAllocator allocator, + bool mustUseCoherentHostVisibleMemory) + : vk_proc_table_(std::move(vk_proc_table)), + allocator_(allocator), + must_use_coherent_host_visible_memory_(mustUseCoherentHostVisibleMemory) { +} + +FlutterSkiaVulkanMemoryAllocator::~FlutterSkiaVulkanMemoryAllocator() { + vmaDestroyAllocator(allocator_); + allocator_ = VK_NULL_HANDLE; +} + +VkResult FlutterSkiaVulkanMemoryAllocator::allocateImageMemory( + VkImage image, + uint32_t allocationPropertyFlags, + skgpu::VulkanBackendMemory* backendMemory) { + VmaAllocationCreateInfo info; + info.flags = 0; + info.usage = VMA_MEMORY_USAGE_UNKNOWN; + info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + info.preferredFlags = 0; + info.memoryTypeBits = 0; + info.pool = VK_NULL_HANDLE; + info.pUserData = nullptr; + + if (kDedicatedAllocation_AllocationPropertyFlag & allocationPropertyFlags) { + info.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + } + if (kLazyAllocation_AllocationPropertyFlag & allocationPropertyFlags) { + info.requiredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT; + } + if (kProtected_AllocationPropertyFlag & allocationPropertyFlags) { + info.requiredFlags |= VK_MEMORY_PROPERTY_PROTECTED_BIT; + } + + VmaAllocation allocation; + VkResult result = + vmaAllocateMemoryForImage(allocator_, image, &info, &allocation, nullptr); + if (VK_SUCCESS == result) { + *backendMemory = reinterpret_cast(allocation); + } + return result; +} + +VkResult FlutterSkiaVulkanMemoryAllocator::allocateBufferMemory( + VkBuffer buffer, + BufferUsage usage, + uint32_t allocationPropertyFlags, + skgpu::VulkanBackendMemory* backendMemory) { + VmaAllocationCreateInfo info; + info.flags = 0; + info.usage = VMA_MEMORY_USAGE_UNKNOWN; + info.memoryTypeBits = 0; + info.pool = VK_NULL_HANDLE; + info.pUserData = nullptr; + + switch (usage) { + case BufferUsage::kGpuOnly: + info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + info.preferredFlags = 0; + break; + case BufferUsage::kCpuWritesGpuReads: + // When doing cpu writes and gpu reads the general rule of thumb is to use + // coherent memory. Though this depends on the fact that we are not doing + // any cpu reads and the cpu writes are sequential. For sparse writes we'd + // want cpu cached memory, however we don't do these types of writes in + // Skia. + // + // TODO (kaushikiska): In the future there may be times where specific + // types of memory could benefit from a coherent and cached memory. + // Typically these allow for the gpu to read cpu writes from the cache + // without needing to flush the writes throughout the cache. The reverse + // is not true and GPU writes tend to invalidate the cache regardless. + // Also these gpu cache read access are typically lower bandwidth than + // non-cached memory. For now Skia doesn't really have a need or want of + // this type of memory. But if we ever do we could pass in an + // AllocationPropertyFlag that requests the cached property. + info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + info.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + break; + case BufferUsage::kTransfersFromCpuToGpu: + info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + info.preferredFlags = 0; + break; + case BufferUsage::kTransfersFromGpuToCpu: + info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + info.preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + break; + } + + if (must_use_coherent_host_visible_memory_ && + (info.requiredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) { + info.requiredFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + } + if (kDedicatedAllocation_AllocationPropertyFlag & allocationPropertyFlags) { + info.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + } + if ((kLazyAllocation_AllocationPropertyFlag & allocationPropertyFlags) && + BufferUsage::kGpuOnly == usage) { + info.preferredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT; + } + + if (kPersistentlyMapped_AllocationPropertyFlag & allocationPropertyFlags) { + SkASSERT(BufferUsage::kGpuOnly != usage); + info.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT; + } + + VmaAllocation allocation; + VkResult result = vmaAllocateMemoryForBuffer(allocator_, buffer, &info, + &allocation, nullptr); + if (VK_SUCCESS == result) { + *backendMemory = reinterpret_cast(allocation); + } + + return result; +} + +void FlutterSkiaVulkanMemoryAllocator::freeMemory( + const skgpu::VulkanBackendMemory& memoryHandle) { + const VmaAllocation allocation = + reinterpret_cast(memoryHandle); + vmaFreeMemory(allocator_, allocation); +} + +void FlutterSkiaVulkanMemoryAllocator::getAllocInfo( + const skgpu::VulkanBackendMemory& memoryHandle, + skgpu::VulkanAlloc* alloc) const { + const VmaAllocation allocation = + reinterpret_cast(memoryHandle); + VmaAllocationInfo vmaInfo; + vmaGetAllocationInfo(allocator_, allocation, &vmaInfo); + + VkMemoryPropertyFlags memFlags; + vmaGetMemoryTypeProperties(allocator_, vmaInfo.memoryType, &memFlags); + + uint32_t flags = 0; + if (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT & memFlags) { + flags |= skgpu::VulkanAlloc::kMappable_Flag; + } + if (!SkToBool(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT & memFlags)) { + flags |= skgpu::VulkanAlloc::kNoncoherent_Flag; + } + if (VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT & memFlags) { + flags |= skgpu::VulkanAlloc::kLazilyAllocated_Flag; + } + + alloc->fMemory = vmaInfo.deviceMemory; + alloc->fOffset = vmaInfo.offset; + alloc->fSize = vmaInfo.size; + alloc->fFlags = flags; + alloc->fBackendMemory = memoryHandle; +} + +VkResult FlutterSkiaVulkanMemoryAllocator::mapMemory( + const skgpu::VulkanBackendMemory& memoryHandle, + void** data) { + const VmaAllocation allocation = + reinterpret_cast(memoryHandle); + return vmaMapMemory(allocator_, allocation, data); +} + +void FlutterSkiaVulkanMemoryAllocator::unmapMemory( + const skgpu::VulkanBackendMemory& memoryHandle) { + const VmaAllocation allocation = + reinterpret_cast(memoryHandle); + vmaUnmapMemory(allocator_, allocation); +} + +VkResult FlutterSkiaVulkanMemoryAllocator::flushMemory( + const skgpu::VulkanBackendMemory& memoryHandle, + VkDeviceSize offset, + VkDeviceSize size) { + const VmaAllocation allocation = + reinterpret_cast(memoryHandle); + return vmaFlushAllocation(allocator_, allocation, offset, size); +} + +VkResult FlutterSkiaVulkanMemoryAllocator::invalidateMemory( + const skgpu::VulkanBackendMemory& memoryHandle, + VkDeviceSize offset, + VkDeviceSize size) { + const VmaAllocation allocation = + reinterpret_cast(memoryHandle); + return vmaInvalidateAllocation(allocator_, allocation, offset, size); +} + +uint64_t FlutterSkiaVulkanMemoryAllocator::totalUsedMemory() const { + VmaTotalStatistics stats; + vmaCalculateStatistics(allocator_, &stats); + return stats.total.statistics.allocationBytes; +} + +uint64_t FlutterSkiaVulkanMemoryAllocator::totalAllocatedMemory() const { + VmaTotalStatistics stats; + vmaCalculateStatistics(allocator_, &stats); + return stats.total.statistics.blockBytes; +} + +} // namespace flutter diff --git a/flutter_vma/flutter_skia_vma.h b/flutter_vma/flutter_skia_vma.h new file mode 100644 index 0000000000000..fd6a6078d4e39 --- /dev/null +++ b/flutter_vma/flutter_skia_vma.h @@ -0,0 +1,70 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "flutter/flutter_vma/flutter_vma.h" + +#include "flutter/fml/memory/ref_ptr.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" +#include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" + +namespace flutter { + +class FlutterSkiaVulkanMemoryAllocator : public skgpu::VulkanMemoryAllocator { + public: + static sk_sp Make( + uint32_t vulkan_api_version, + VkInstance instance, + VkPhysicalDevice physicalDevice, + VkDevice device, + const fml::RefPtr& vk, + bool mustUseCoherentHostVisibleMemory); + + ~FlutterSkiaVulkanMemoryAllocator() override; + + VkResult allocateImageMemory(VkImage image, + uint32_t allocationPropertyFlags, + skgpu::VulkanBackendMemory*) override; + + VkResult allocateBufferMemory(VkBuffer buffer, + BufferUsage usage, + uint32_t allocationPropertyFlags, + skgpu::VulkanBackendMemory*) override; + + void freeMemory(const skgpu::VulkanBackendMemory&) override; + + void getAllocInfo(const skgpu::VulkanBackendMemory&, + skgpu::VulkanAlloc*) const override; + + VkResult mapMemory(const skgpu::VulkanBackendMemory&, void** data) override; + void unmapMemory(const skgpu::VulkanBackendMemory&) override; + + VkResult flushMemory(const skgpu::VulkanBackendMemory&, + VkDeviceSize offset, + VkDeviceSize size) override; + VkResult invalidateMemory(const skgpu::VulkanBackendMemory&, + VkDeviceSize offset, + VkDeviceSize size) override; + + uint64_t totalUsedMemory() const override; + uint64_t totalAllocatedMemory() const override; + + private: + FlutterSkiaVulkanMemoryAllocator( + fml::RefPtr vk_proc_table, + VmaAllocator allocator, + bool mustUseCoherentHostVisibleMemory); + + fml::RefPtr vk_proc_table_; + VmaAllocator allocator_; + + // For host visible allocations do we require they are coherent or not. All + // devices are required to support a host visible and coherent memory type. + // This is used to work around bugs for devices that don't handle non coherent + // memory correctly. + bool must_use_coherent_host_visible_memory_; +}; + +} // namespace flutter diff --git a/flutter_vma/flutter_vma.cc b/flutter_vma/flutter_vma.cc new file mode 100644 index 0000000000000..81df956c1daed --- /dev/null +++ b/flutter_vma/flutter_vma.cc @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifdef VMA_STATIC_VULKAN_FUNCTIONS +#undef VMA_STATIC_VULKAN_FUNCTIONS +#endif // VMA_STATIC_VULKAN_FUNCTIONS + +#ifdef VMA_DYNAMIC_VULKAN_FUNCTIONS +#undef VMA_DYNAMIC_VULKAN_FUNCTIONS +#endif // VMA_DYNAMIC_VULKAN_FUNCTIONS + +// We use our own functions pointers +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0 + +#define VMA_IMPLEMENTATION + +#include "flutter/flutter_vma/flutter_vma.h" diff --git a/flutter_vma/flutter_vma.h b/flutter_vma/flutter_vma.h new file mode 100644 index 0000000000000..f218c7a876121 --- /dev/null +++ b/flutter_vma/flutter_vma.h @@ -0,0 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "vk_mem_alloc.h" diff --git a/impeller/renderer/backend/vulkan/BUILD.gn b/impeller/renderer/backend/vulkan/BUILD.gn index 55af09309b5e5..6db2d4df534ea 100644 --- a/impeller/renderer/backend/vulkan/BUILD.gn +++ b/impeller/renderer/backend/vulkan/BUILD.gn @@ -56,7 +56,9 @@ impeller_component("vulkan") { public_deps = [ "../../:renderer", "../../../blobcat:blobcat_lib", + "//flutter/flutter_vma", "//flutter/fml", + "//flutter/vulkan/procs", "//third_party/vulkan-deps/vulkan-headers/src:vulkan_headers", "//third_party/vulkan_memory_allocator", ] diff --git a/impeller/renderer/backend/vulkan/allocator_vk.cc b/impeller/renderer/backend/vulkan/allocator_vk.cc index de0d3384c8720..9131f052ca8dd 100644 --- a/impeller/renderer/backend/vulkan/allocator_vk.cc +++ b/impeller/renderer/backend/vulkan/allocator_vk.cc @@ -2,20 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -_Pragma("GCC diagnostic push"); -_Pragma("GCC diagnostic ignored \"-Wnullability-completeness\""); -_Pragma("GCC diagnostic ignored \"-Wunused-variable\""); -_Pragma("GCC diagnostic ignored \"-Wthread-safety-analysis\""); - -#define VMA_IMPLEMENTATION #include "impeller/renderer/backend/vulkan/allocator_vk.h" -#include "impeller/renderer/backend/vulkan/device_buffer_vk.h" -#include "impeller/renderer/backend/vulkan/formats_vk.h" -#include "impeller/renderer/backend/vulkan/texture_vk.h" #include -_Pragma("GCC diagnostic pop"); +#include "flutter/fml/memory/ref_ptr.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" +#include "impeller/renderer/backend/vulkan/device_buffer_vk.h" +#include "impeller/renderer/backend/vulkan/formats_vk.h" +#include "impeller/renderer/backend/vulkan/texture_vk.h" namespace impeller { @@ -27,10 +23,51 @@ AllocatorVK::AllocatorVK(ContextVK& context, PFN_vkGetInstanceProcAddr get_instance_proc_address, PFN_vkGetDeviceProcAddr get_device_proc_address) : context_(context), device_(logical_device) { + vk_ = fml::MakeRefCounted(get_instance_proc_address); + + auto instance_handle = vulkan::VulkanHandle(instance); + FML_CHECK(vk_->SetupInstanceProcAddresses(instance_handle)); + + auto device_handle = vulkan::VulkanHandle(logical_device); + FML_CHECK(vk_->SetupDeviceProcAddresses(device_handle)); + VmaVulkanFunctions proc_table = {}; proc_table.vkGetInstanceProcAddr = get_instance_proc_address; proc_table.vkGetDeviceProcAddr = get_device_proc_address; +#define PROVIDE_PROC(tbl, proc, provider) tbl.vk##proc = provider->proc; + PROVIDE_PROC(proc_table, GetPhysicalDeviceProperties, vk_); + PROVIDE_PROC(proc_table, GetPhysicalDeviceMemoryProperties, vk_); + PROVIDE_PROC(proc_table, AllocateMemory, vk_); + PROVIDE_PROC(proc_table, FreeMemory, vk_); + PROVIDE_PROC(proc_table, MapMemory, vk_); + PROVIDE_PROC(proc_table, UnmapMemory, vk_); + PROVIDE_PROC(proc_table, FlushMappedMemoryRanges, vk_); + PROVIDE_PROC(proc_table, InvalidateMappedMemoryRanges, vk_); + PROVIDE_PROC(proc_table, BindBufferMemory, vk_); + PROVIDE_PROC(proc_table, BindImageMemory, vk_); + PROVIDE_PROC(proc_table, GetBufferMemoryRequirements, vk_); + PROVIDE_PROC(proc_table, GetImageMemoryRequirements, vk_); + PROVIDE_PROC(proc_table, CreateBuffer, vk_); + PROVIDE_PROC(proc_table, DestroyBuffer, vk_); + PROVIDE_PROC(proc_table, CreateImage, vk_); + PROVIDE_PROC(proc_table, DestroyImage, vk_); + PROVIDE_PROC(proc_table, CmdCopyBuffer, vk_); + +#define PROVIDE_PROC_COALESCE(tbl, proc, provider) \ + tbl.vk##proc##KHR = provider->proc ? provider->proc : provider->proc##KHR; + // See the following link for why we have to pick either KHR version or + // promoted non-KHR version: + // https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/issues/203 + PROVIDE_PROC_COALESCE(proc_table, GetBufferMemoryRequirements2, vk_); + PROVIDE_PROC_COALESCE(proc_table, GetImageMemoryRequirements2, vk_); + PROVIDE_PROC_COALESCE(proc_table, BindBufferMemory2, vk_); + PROVIDE_PROC_COALESCE(proc_table, BindImageMemory2, vk_); + PROVIDE_PROC_COALESCE(proc_table, GetPhysicalDeviceMemoryProperties2, vk_); +#undef PROVIDE_PROC_COALESCE + +#undef PROVIDE_PROC + VmaAllocatorCreateInfo allocator_info = {}; allocator_info.vulkanApiVersion = vulkan_api_version; allocator_info.physicalDevice = physical_device; diff --git a/impeller/renderer/backend/vulkan/allocator_vk.h b/impeller/renderer/backend/vulkan/allocator_vk.h index 5225845bf71c6..595a0b838ec96 100644 --- a/impeller/renderer/backend/vulkan/allocator_vk.h +++ b/impeller/renderer/backend/vulkan/allocator_vk.h @@ -5,6 +5,8 @@ #pragma once #include "flutter/fml/macros.h" +#include "flutter/fml/memory/ref_ptr.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "impeller/renderer/allocator.h" #include "impeller/renderer/backend/vulkan/context_vk.h" #include "impeller/renderer/backend/vulkan/vk.h" @@ -21,6 +23,7 @@ class AllocatorVK final : public Allocator { private: friend class ContextVK; + fml::RefPtr vk_; VmaAllocator allocator_ = {}; ContextVK& context_; vk::Device device_; diff --git a/impeller/renderer/backend/vulkan/context_vk.cc b/impeller/renderer/backend/vulkan/context_vk.cc index 7d6850a04e733..58bcd1da7ba33 100644 --- a/impeller/renderer/backend/vulkan/context_vk.cc +++ b/impeller/renderer/backend/vulkan/context_vk.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// FLUTTER_NOLINT: https://github.com/flutter/flutter/issues/68331 + #include "impeller/renderer/backend/vulkan/context_vk.h" #include diff --git a/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc b/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc index e00fcebe2d9c2..b4e44282f3b06 100644 --- a/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc +++ b/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc @@ -10,7 +10,7 @@ namespace impeller { -DescriptorPoolVK::DescriptorPoolVK(vk::Device device) { +DescriptorPoolVK::DescriptorPoolVK(vk::Device device) : device_(device) { constexpr size_t kPoolSize = 1024; std::vector pool_sizes = { @@ -34,20 +34,24 @@ DescriptorPoolVK::DescriptorPoolVK(vk::Device device) { pool_sizes.data() // pool sizes }; - auto res = device.createDescriptorPoolUnique(pool_info); + auto res = device.createDescriptorPool(pool_info); if (res.result != vk::Result::eSuccess) { VALIDATION_LOG << "Unable to create a descriptor pool"; return; } - pool_ = std::move(res.value); + pool_ = res.value; is_valid_ = true; } vk::DescriptorPool DescriptorPoolVK::GetPool() { - return *pool_; + return pool_; } -DescriptorPoolVK::~DescriptorPoolVK() = default; +DescriptorPoolVK::~DescriptorPoolVK() { + if (is_valid_) { + device_.destroyDescriptorPool(pool_); + } +} } // namespace impeller diff --git a/impeller/renderer/backend/vulkan/descriptor_pool_vk.h b/impeller/renderer/backend/vulkan/descriptor_pool_vk.h index da37ec2c2e179..c4d33d9289a05 100644 --- a/impeller/renderer/backend/vulkan/descriptor_pool_vk.h +++ b/impeller/renderer/backend/vulkan/descriptor_pool_vk.h @@ -22,7 +22,8 @@ class DescriptorPoolVK { vk::DescriptorPool GetPool(); private: - vk::UniqueDescriptorPool pool_; + vk::Device device_; + vk::DescriptorPool pool_; bool is_valid_ = false; FML_DISALLOW_COPY_AND_ASSIGN(DescriptorPoolVK); diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index 1179f2deff47e..d5d46b8c3c873 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -27,11 +27,11 @@ static uint32_t color_flash = 0; RenderPassVK::RenderPassVK(std::weak_ptr context, vk::Device device, - RenderTarget target, + const RenderTarget& target, vk::UniqueCommandBuffer command_buffer, vk::UniqueRenderPass render_pass, SurfaceProducerVK* surface_producer) - : RenderPass(context, target), + : RenderPass(std::move(context), target), device_(device), command_buffer_(std::move(command_buffer)), render_pass_(std::move(render_pass)), @@ -91,10 +91,6 @@ bool RenderPassVK::OnEncodeCommands(const Context& context) const { clear_value.color = vk::ClearColorValue(std::array{0.0f, 0.0f, 0.0, 0.0f}); - std::array fbo_attachments = { - tex_info.swapchain_image->GetImageView(), - }; - const auto& size = tex_info.swapchain_image->GetSize(); vk::Rect2D render_area = vk::Rect2D() @@ -377,7 +373,7 @@ vk::Framebuffer RenderPassVK::CreateFrameBuffer( .setLayers(1); auto res = device_.createFramebuffer(fb_create_info); FML_CHECK(res.result == vk::Result::eSuccess); - return std::move(res.value); + return res.value; } bool RenderPassVK::TransitionImageLayout(uint32_t frame_num, @@ -401,6 +397,11 @@ bool RenderPassVK::TransitionImageLayout(uint32_t frame_num, vk::CommandBufferBeginInfo begin_info; auto res = transition_cmd->begin(begin_info); + if (res != vk::Result::eSuccess) { + VALIDATION_LOG << "Failed to begin command buffer: " << vk::to_string(res); + return false; + } + vk::ImageMemoryBarrier barrier = vk::ImageMemoryBarrier() .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentRead) diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.h b/impeller/renderer/backend/vulkan/render_pass_vk.h index 3530cbb706676..79227696af038 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.h +++ b/impeller/renderer/backend/vulkan/render_pass_vk.h @@ -21,7 +21,7 @@ class RenderPassVK final : public RenderPass { public: RenderPassVK(std::weak_ptr context, vk::Device device, - RenderTarget target, + const RenderTarget& target, vk::UniqueCommandBuffer command_buffer, vk::UniqueRenderPass render_pass, SurfaceProducerVK* surface_producer); diff --git a/impeller/renderer/backend/vulkan/texture_vk.cc b/impeller/renderer/backend/vulkan/texture_vk.cc index 829cef6f9fed1..177c9d46f2dcb 100644 --- a/impeller/renderer/backend/vulkan/texture_vk.cc +++ b/impeller/renderer/backend/vulkan/texture_vk.cc @@ -46,9 +46,13 @@ bool TextureVK::OnSetContents(const uint8_t* contents, // currently we are only supporting 2d textures, no cube textures etc. auto mapping = texture_info_->allocated_texture.allocation_info.pMappedData; - memcpy(mapping, contents, length); - return true; + if (mapping) { + memcpy(mapping, contents, length); + return true; + } else { + return false; + } } bool TextureVK::OnSetContents(std::shared_ptr mapping, diff --git a/impeller/renderer/backend/vulkan/vk.h b/impeller/renderer/backend/vulkan/vk.h index 3ce2d346f493d..a62d94495c041 100644 --- a/impeller/renderer/backend/vulkan/vk.h +++ b/impeller/renderer/backend/vulkan/vk.h @@ -19,23 +19,12 @@ #define VULKAN_HPP_NAMESPACE impeller::vk #define VULKAN_HPP_ASSERT_ON_RESULT(ignored) \ { [[maybe_unused]] auto res = (ignored); } -#define VULKAN_HPP_NO_EXCEPTIONS #include "vulkan/vulkan.hpp" static_assert(VK_HEADER_VERSION >= 215, "Vulkan headers are must not be too old."); -#ifdef VMA_STATIC_VULKAN_FUNCTIONS -#undef VMA_STATIC_VULKAN_FUNCTIONS -#endif // VMA_STATIC_VULKAN_FUNCTIONS - -#ifdef VMA_DYNAMIC_VULKAN_FUNCTIONS -#undef VMA_DYNAMIC_VULKAN_FUNCTIONS -#endif // VMA_DYNAMIC_VULKAN_FUNCTIONS - -#define VMA_STATIC_VULKAN_FUNCTIONS 0 -#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 -#include "vk_mem_alloc.h" +#include "flutter/flutter_vma/flutter_vma.h" namespace impeller { diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index a01b18c176bf8..6ea32b1ae4ba6 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -17,7 +17,7 @@ declare_args() { impeller_enable_opengles = is_mac || is_linux || is_win || is_android # Whether the Vulkan backend is enabled. - impeller_enable_vulkan = false + impeller_enable_vulkan = is_linux # Whether to use a prebuilt impellerc. # If this is the empty string, impellerc will be built. @@ -452,7 +452,7 @@ template("impeller_shaders_gles") { sl_file_extension = "gles" # Metal reflectors generate a superset of information. - if (impeller_enable_metal) { + if (impeller_enable_metal || impeller_enable_vulkan) { intermediates_subdir = "gles" } if (is_mac) { @@ -489,7 +489,7 @@ template("impeller_shaders_gles") { group(target_name) { public_deps = [ ":$embed_gles_lib" ] - if (!impeller_enable_metal) { + if (!impeller_enable_metal && !impeller_enable_vulkan) { public_deps += [ ":$reflect_gles" ] } } diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 2b3f63e8b35c5..7fa0c1b23ae70 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -264,7 +264,10 @@ if (enable_unittests) { "shell_test_platform_view_vulkan.h", ] - public_deps += [ "//flutter/vulkan" ] + public_deps += [ + "//flutter/flutter_vma:flutter_skia_vma", + "//flutter/vulkan", + ] } if (test_enable_metal) { diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index eb70a26bcc6eb..fa3267ef731da 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -7,7 +7,9 @@ #include #include "flutter/common/graphics/persistent_cache.h" +#include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/shell/common/context_options.h" +#include "flutter/vulkan/vulkan_skia_proc_table.h" #include "flutter/vulkan/vulkan_utilities.h" #if OS_FUCHSIA @@ -111,6 +113,11 @@ ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( return; } + memory_allocator_ = FlutterSkiaVulkanMemoryAllocator::Make( + application_->GetAPIVersion(), application_->GetInstance(), + logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), + vk_, true); + // Create the Skia GrContext. if (!CreateSkiaGrContext()) { FML_DLOG(ERROR) << "Could not create Skia context."; @@ -148,7 +155,7 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( GrVkBackendContext* context) { - auto getProc = vk_->CreateSkiaGetProc(); + auto getProc = CreateSkiaGetProc(vk_); if (getProc == nullptr) { FML_DLOG(ERROR) << "GetProcAddress is null"; @@ -171,6 +178,8 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( context->fFeatures = skia_features; context->fGetProc = std::move(getProc); context->fOwnsInstanceAndDevice = false; + context->fMemoryAllocator = memory_allocator_; + return true; } diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 724fe455639fc..718f7fe6dec06 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -10,6 +10,7 @@ #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" #include "flutter/vulkan/vulkan_application.h" #include "flutter/vulkan/vulkan_device.h" +#include "flutter/vulkan/vulkan_skia_proc_table.h" namespace flutter { namespace testing { @@ -54,6 +55,7 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { shell_test_external_view_embedder_; std::unique_ptr application_; std::unique_ptr logical_device_; + sk_sp memory_allocator_; sk_sp context_; bool CreateSkiaGrContext(); diff --git a/shell/gpu/BUILD.gn b/shell/gpu/BUILD.gn index 7bbcbfbafa455..ef1a6a46877fc 100644 --- a/shell/gpu/BUILD.gn +++ b/shell/gpu/BUILD.gn @@ -56,6 +56,7 @@ source_set("gpu_surface_vulkan") { public_deps = gpu_common_deps + [ "//flutter/shell/platform/embedder:embedder_headers", "//flutter/vulkan", + "//flutter/vulkan/procs", ] } diff --git a/shell/gpu/gpu_surface_vulkan_delegate.h b/shell/gpu/gpu_surface_vulkan_delegate.h index 023fe9261900b..2a95f0a613b51 100644 --- a/shell/gpu/gpu_surface_vulkan_delegate.h +++ b/shell/gpu/gpu_surface_vulkan_delegate.h @@ -7,9 +7,9 @@ #include "flutter/fml/memory/ref_ptr.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_image.h" -#include "flutter/vulkan/vulkan_proc_table.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 5f74522f91d34..83d62c610d1cb 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -135,6 +135,11 @@ template("embedder_source_set") { "embedder_surface_vulkan.cc", "embedder_surface_vulkan.h", ] + + deps += [ + "//flutter/flutter_vma:flutter_skia_vma", + "//flutter/vulkan/procs", + ] } public_deps = [ ":embedder_headers" ] @@ -291,6 +296,7 @@ if (enable_unittests) { public_deps += [ "//flutter/testing:vulkan", "//flutter/vulkan", + "//flutter/vulkan/procs", ] } } diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 41f8f8227f08d..8b363eec43fb2 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -556,8 +556,13 @@ InferVulkanPlatformViewCreationCallback( return ptr(user_data, &image_desc); }; + auto vk_instance = static_cast(config->vulkan.instance); + auto proc_addr = + vulkan_get_instance_proc_address(vk_instance, "GetInstanceProcAddr"); + flutter::EmbedderSurfaceVulkan::VulkanDispatchTable vulkan_dispatch_table = { - .get_instance_proc_address = vulkan_get_instance_proc_address, + .get_instance_proc_address = + reinterpret_cast(proc_addr), .get_next_image = vulkan_get_next_image, .present_image = vulkan_present_image_callback, }; @@ -567,8 +572,7 @@ InferVulkanPlatformViewCreationCallback( std::unique_ptr embedder_surface = std::make_unique( - config->vulkan.version, - static_cast(config->vulkan.instance), + config->vulkan.version, vk_instance, config->vulkan.enabled_instance_extension_count, config->vulkan.enabled_instance_extensions, config->vulkan.enabled_device_extension_count, diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 837d15882c648..8fe32f17e6755 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -6,7 +6,9 @@ #include +#include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/shell/common/shell_io_manager.h" +#include "flutter/vulkan/vulkan_skia_proc_table.h" #include "include/gpu/GrDirectContext.h" #include "include/gpu/vk/GrVkBackendContext.h" #include "include/gpu/vk/GrVkExtensions.h" @@ -44,8 +46,18 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( return; } - vk_->SetupInstanceProcAddresses(vulkan::VulkanHandle{instance}); - vk_->SetupDeviceProcAddresses(vulkan::VulkanHandle{device}); + bool success = vk_->SetupInstanceProcAddresses( + vulkan::VulkanHandle{instance}); + if (!success) { + FML_LOG(ERROR) << "Could not setup instance proc addresses."; + return; + } + success = + vk_->SetupDeviceProcAddresses(vulkan::VulkanHandle{device}); + if (!success) { + FML_LOG(ERROR) << "Could not setup device proc addresses."; + return; + } if (!vk_->IsValid()) { FML_LOG(ERROR) << "VulkanProcTable invalid."; return; @@ -122,7 +134,7 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( return nullptr; } - auto get_proc = vk_->CreateSkiaGetProc(); + auto get_proc = CreateSkiaGetProc(vk_); if (get_proc == nullptr) { FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; return nullptr; @@ -143,6 +155,14 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( backend_context.fGetProc = get_proc; backend_context.fOwnsInstanceAndDevice = false; + uint32_t vulkan_api_version = version; + sk_sp allocator = + flutter::FlutterSkiaVulkanMemoryAllocator::Make( + vulkan_api_version, instance, device_.GetPhysicalDeviceHandle(), + device_.GetHandle(), vk_, true); + + backend_context.fMemoryAllocator = allocator; + extensions.init(backend_context.fGetProc, backend_context.fInstance, backend_context.fPhysicalDevice, instance_extension_count, instance_extensions, device_extension_count, diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h index d51ae5d8ce938..8c44e3ddd99e6 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.h +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -9,10 +9,10 @@ #include "flutter/shell/gpu/gpu_surface_vulkan.h" #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" #include "flutter/shell/platform/embedder/embedder_surface.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "shell/common/context_options.h" #include "shell/gpu/gpu_surface_vulkan_delegate.h" #include "shell/platform/embedder/embedder.h" -#include "vulkan/vulkan_proc_table.h" namespace flutter { @@ -20,8 +20,7 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, public GPUSurfaceVulkanDelegate { public: struct VulkanDispatchTable { - std::function - get_instance_proc_address; // required + PFN_vkGetInstanceProcAddr get_instance_proc_address; // required std::function get_next_image; // required std::function diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 58e48c4b594d8..92ff07a81291a 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -510,9 +510,9 @@ void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { vulkan_renderer_config_.get_instance_proc_address_callback = [](void* context, FlutterVulkanInstanceHandle instance, const char* name) -> void* { - return reinterpret_cast(context) - ->vulkan_context_->vk_->GetInstanceProcAddr( - reinterpret_cast(instance), name); + auto proc_addr = reinterpret_cast(context) + ->vulkan_context_->vk_->GetInstanceProcAddr; + return reinterpret_cast(proc_addr); }; vulkan_renderer_config_.get_next_image_callback = [](void* context, diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index 9260f19e98b70..c5f821a8088cc 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -11,8 +11,8 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" #include "flutter/testing/test_vulkan_context.h" #include "flutter/testing/test_vulkan_surface.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_device.h" -#include "flutter/vulkan/vulkan_proc_table.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { diff --git a/shell/platform/fuchsia/flutter/BUILD.gn b/shell/platform/fuchsia/flutter/BUILD.gn index 01a1f2e3ce106..13e55261d92f3 100644 --- a/shell/platform/fuchsia/flutter/BUILD.gn +++ b/shell/platform/fuchsia/flutter/BUILD.gn @@ -131,13 +131,16 @@ template("runner_sources") { "//flutter/shell/common", "//flutter/shell/platform/common/client_wrapper:client_wrapper", ] + flutter_deps = [ ":fuchsia_gpu_configuration", "//flutter/assets", "//flutter/common", + "//flutter/flutter_vma:flutter_skia_vma", "//flutter/fml", "//flutter/shell/platform/common/client_wrapper:client_wrapper_library_stubs", "//flutter/vulkan", + "//flutter/vulkan/procs", ] public_deps = [ diff --git a/shell/platform/fuchsia/flutter/vulkan_surface.h b/shell/platform/fuchsia/flutter/vulkan_surface.h index aa8c05da325e3..37db0c4fe35e5 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface.h +++ b/shell/platform/fuchsia/flutter/vulkan_surface.h @@ -14,9 +14,9 @@ #include #include "flutter/fml/macros.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_command_buffer.h" -#include "flutter/vulkan/vulkan_handle.h" -#include "flutter/vulkan/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_provider.h" #include "third_party/skia/include/core/SkColorType.h" #include "third_party/skia/include/core/SkRefCnt.h" diff --git a/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc b/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc index fe0213d68a246..55ccbda9c7ca8 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc +++ b/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc @@ -12,6 +12,8 @@ #include #include "flutter/fml/trace_event.h" +#include "flutter/vulkan/vulkan_skia_proc_table.h" +#include "flutter_vma/flutter_skia_vma.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" @@ -98,7 +100,7 @@ bool VulkanSurfaceProducer::Initialize(scenic::Session* scenic_session) { return false; } - auto getProc = vk_->CreateSkiaGetProc(); + auto getProc = CreateSkiaGetProc(vk_); if (getProc == nullptr) { FML_LOG(ERROR) << "VulkanSurfaceProducer: Failed to create skia getProc."; @@ -113,6 +115,11 @@ bool VulkanSurfaceProducer::Initialize(scenic::Session* scenic_session) { return false; } + memory_allocator_ = flutter::FlutterSkiaVulkanMemoryAllocator::Make( + application_->GetAPIVersion(), application_->GetInstance(), + logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), + vk_, true); + GrVkBackendContext backend_context; backend_context.fInstance = application_->GetInstance(); backend_context.fPhysicalDevice = logical_device_->GetPhysicalDeviceHandle(); @@ -125,6 +132,8 @@ bool VulkanSurfaceProducer::Initialize(scenic::Session* scenic_session) { backend_context.fFeatures = skia_features; backend_context.fGetProc = std::move(getProc); backend_context.fOwnsInstanceAndDevice = false; + backend_context.fMemoryAllocator = memory_allocator_; + // The memory_requirements_2 extension is required on Fuchsia as the AMD // memory allocator used by Skia benefit from it. const char* device_extensions[] = { diff --git a/shell/platform/fuchsia/flutter/vulkan_surface_producer.h b/shell/platform/fuchsia/flutter/vulkan_surface_producer.h index 3a87467d92a1e..10f025399b8b5 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface_producer.h +++ b/shell/platform/fuchsia/flutter/vulkan_surface_producer.h @@ -10,11 +10,12 @@ #include #include +#include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_application.h" #include "flutter/vulkan/vulkan_device.h" -#include "flutter/vulkan/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_provider.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -76,6 +77,7 @@ class VulkanSurfaceProducer final : public SurfaceProducer, std::unique_ptr logical_device_; sk_sp context_; std::unique_ptr surface_pool_; + sk_sp memory_allocator_; bool valid_ = false; // WeakPtrFactory must be the last member. diff --git a/testing/BUILD.gn b/testing/BUILD.gn index 3416c67d2cf7c..8ca7c4f0a74a7 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -141,9 +141,11 @@ if (enable_unittests) { deps = [ ":skia", + "//flutter/flutter_vma:flutter_skia_vma", "//flutter/fml", "//flutter/shell/common", "//flutter/vulkan", + "//flutter/vulkan/procs", ] if (!is_fuchsia) { diff --git a/testing/impeller_vulkan_test_status.csv b/testing/impeller_vulkan_test_status.csv index 34ff0db0bec99..517d67ef9f33e 100644 --- a/testing/impeller_vulkan_test_status.csv +++ b/testing/impeller_vulkan_test_status.csv @@ -83,7 +83,7 @@ ColorWheel/Vulkan,pass TransformMultipliesCorrectly/Vulkan,pass SolidStrokesRenderCorrectly/Vulkan,pass GradientStrokesRenderCorrectly/Vulkan,pass -CoverageOriginShouldBeAccountedForInSubpasses/Vulkan,pass +CoverageOriginShouldBeAccountedForInSubpasses/Vulkan,fail DrawRectStrokesRenderCorrectly/Vulkan,pass SaveLayerDrawsBehindSubsequentEntities/Vulkan,pass SiblingSaveLayerBoundsAreRespected/Vulkan,pass diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 85c857faa16d0..ea36581add8e2 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -6,9 +6,11 @@ #include #include +#include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/fml/logging.h" #include "flutter/shell/common/context_options.h" #include "flutter/testing/test_vulkan_context.h" +#include "flutter/vulkan/vulkan_skia_proc_table.h" #include "flutter/fml/memory/ref_ptr.h" #include "flutter/fml/native_library.h" @@ -81,12 +83,17 @@ TestVulkanContext::TestVulkanContext() { return; } - auto get_proc = vk_->CreateSkiaGetProc(); + auto get_proc = vulkan::CreateSkiaGetProc(vk_); if (get_proc == nullptr) { FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; return; } + sk_sp allocator = + flutter::FlutterSkiaVulkanMemoryAllocator::Make( + VK_MAKE_VERSION(1, 0, 0), application_->GetInstance(), + device_->GetPhysicalDeviceHandle(), device_->GetHandle(), vk_, true); + GrVkExtensions extensions; GrVkBackendContext backend_context = {}; @@ -101,6 +108,7 @@ TestVulkanContext::TestVulkanContext() { backend_context.fVkExtensions = &extensions; backend_context.fGetProc = get_proc; backend_context.fOwnsInstanceAndDevice = false; + backend_context.fMemoryAllocator = allocator; GrContextOptions options = MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan); diff --git a/testing/test_vulkan_context.h b/testing/test_vulkan_context.h index 25d212bf05eb1..7e61836550c92 100644 --- a/testing/test_vulkan_context.h +++ b/testing/test_vulkan_context.h @@ -8,9 +8,9 @@ #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_ptr.h" #include "flutter/testing/test_vulkan_image.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_application.h" #include "flutter/vulkan/vulkan_device.h" -#include "flutter/vulkan/vulkan_proc_table.h" #include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/gpu/GrDirectContext.h" diff --git a/testing/test_vulkan_image.h b/testing/test_vulkan_image.h index c8a6a797f385e..e0a030c8169df 100644 --- a/testing/test_vulkan_image.h +++ b/testing/test_vulkan_image.h @@ -6,9 +6,9 @@ #define FLUTTER_TESTING_TEST_VULKAN_IMAGE_H_ #include "flutter/fml/macros.h" -#include "flutter/vulkan/vulkan_handle.h" #include "flutter/fml/memory/ref_ptr.h" +#include "flutter/vulkan/procs/vulkan_handle.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { diff --git a/tools/gn b/tools/gn index 06f34e959a304..b4fcbe0b03c3e 100755 --- a/tools/gn +++ b/tools/gn @@ -436,13 +436,12 @@ def to_gn_args(args): # features can't work on these platforms. if args.target_os not in ['android', 'ios']: gn_args['skia_use_vulkan'] = True - gn_args['skia_vulkan_memory_allocator_dir' - ] = '//third_party/vulkan_memory_allocator' + gn_args['skia_use_vma'] = False gn_args['shell_enable_vulkan'] = True # Disable VMA's use of std::shared_mutex in environments where the # standard library doesn't support it. if args.target_os == 'ios' or sys.platform.startswith(('cygwin', 'win')): - gn_args['skia_disable_vma_stl_shared_mutex'] = True + gn_args['disable_vma_stl_shared_mutex'] = True # We should not need a special case for x86, but this seems to introduce text relocations # even with -fPIC everywhere. @@ -543,12 +542,6 @@ def to_gn_args(args): if args.prebuilt_impellerc is not None: gn_args['impeller_use_prebuilt_impellerc'] = args.prebuilt_impellerc - # Vulkan support is WIP, see: https://github.com/flutter/flutter/issues/107357 - if args.enable_impeller_vulkan: - gn_args['impeller_enable_opengles'] = False - gn_args['impeller_enable_vulkan'] = True - gn_args['skia_use_vma'] = False - # ANGLE is exclusively used for: # - Windows at runtime # - Non-fuchsia host unit tests (is_host_build evaluates to false). @@ -956,6 +949,8 @@ def parse_args(args): help='Absolute path to a prebuilt impellerc. ' + 'Do not use this outside of CI or with impellerc from a different engine version.' ) + + # This is currently a no-op, will be removed shortly. parser.add_argument( '--enable-impeller-vulkan', default=False, diff --git a/vulkan/BUILD.gn b/vulkan/BUILD.gn index 3992b361d3c35..015996e55d1d7 100644 --- a/vulkan/BUILD.gn +++ b/vulkan/BUILD.gn @@ -27,16 +27,12 @@ source_set("vulkan") { "vulkan_debug_report.h", "vulkan_device.cc", "vulkan_device.h", - "vulkan_handle.cc", - "vulkan_handle.h", "vulkan_image.cc", "vulkan_image.h", - "vulkan_interface.cc", - "vulkan_interface.h", "vulkan_native_surface.cc", "vulkan_native_surface.h", - "vulkan_proc_table.cc", - "vulkan_proc_table.h", + "vulkan_skia_proc_table.cc", + "vulkan_skia_proc_table.h", "vulkan_surface.cc", "vulkan_surface.h", "vulkan_swapchain.h", @@ -57,6 +53,8 @@ source_set("vulkan") { } deps = [ + "procs", + "//flutter/flutter_vma:flutter_skia_vma", "//flutter/fml", "//third_party/skia", ] diff --git a/vulkan/procs/BUILD.gn b/vulkan/procs/BUILD.gn new file mode 100644 index 0000000000000..0362e58f87d8e --- /dev/null +++ b/vulkan/procs/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("procs") { + sources = [ + "vulkan_handle.cc", + "vulkan_handle.h", + "vulkan_interface.cc", + "vulkan_interface.h", + "vulkan_proc_table.cc", + "vulkan_proc_table.h", + ] + + deps = [ "//flutter/fml" ] + + public_configs = [ + "//flutter/vulkan:vulkan_config", + "//flutter:config", + ] +} diff --git a/vulkan/vulkan_handle.cc b/vulkan/procs/vulkan_handle.cc similarity index 81% rename from vulkan/vulkan_handle.cc rename to vulkan/procs/vulkan_handle.cc index eb15d9ff13147..9582984c3d75e 100644 --- a/vulkan/vulkan_handle.cc +++ b/vulkan/procs/vulkan_handle.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_handle.h b/vulkan/procs/vulkan_handle.h similarity index 92% rename from vulkan/vulkan_handle.h rename to vulkan/procs/vulkan_handle.h index eb53a063d9cf0..cf33394b491f2 100644 --- a/vulkan/vulkan_handle.h +++ b/vulkan/procs/vulkan_handle.h @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_VULKAN_VULKAN_HANDLE_H_ -#define FLUTTER_VULKAN_VULKAN_HANDLE_H_ +#pragma once #include #include "flutter/fml/logging.h" #include "flutter/fml/macros.h" -#include "vulkan_interface.h" +#include "flutter/vulkan/procs/vulkan_interface.h" namespace vulkan { @@ -77,5 +76,3 @@ class VulkanHandle { }; } // namespace vulkan - -#endif // FLUTTER_VULKAN_VULKAN_HANDLE_H_ diff --git a/vulkan/vulkan_interface.cc b/vulkan/procs/vulkan_interface.cc similarity index 98% rename from vulkan/vulkan_interface.cc rename to vulkan/procs/vulkan_interface.cc index e10f47730da32..ab15206c0f1de 100644 --- a/vulkan/vulkan_interface.cc +++ b/vulkan/procs/vulkan_interface.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "vulkan_interface.h" +#include "flutter/vulkan/procs/vulkan_interface.h" namespace vulkan { diff --git a/vulkan/vulkan_interface.h b/vulkan/procs/vulkan_interface.h similarity index 88% rename from vulkan/vulkan_interface.h rename to vulkan/procs/vulkan_interface.h index f9d2a3e17d828..089ae829eb8f9 100644 --- a/vulkan/vulkan_interface.h +++ b/vulkan/procs/vulkan_interface.h @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_VULKAN_VULKAN_INTERFACE_H_ -#define FLUTTER_VULKAN_VULKAN_INTERFACE_H_ +#pragma once #include @@ -25,10 +24,6 @@ #endif // VK_USE_PLATFORM_FUCHSIA #endif // OS_FUCHSIA -#if !VULKAN_LINK_STATICALLY -#define VK_NO_PROTOTYPES 1 -#endif // !VULKAN_LINK_STATICALLY - // TODO(dnfield): vulkan_metal.h has some unguarded availability checks for // macOS 10.13. We can remove this if we bump to 10.14 or if that gets fixed // upstream, but fixing it upstream will take some time to flow through to @@ -55,5 +50,3 @@ namespace vulkan { std::string VulkanResultToString(VkResult result); } // namespace vulkan - -#endif // FLUTTER_VULKAN_VULKAN_INTERFACE_H_ diff --git a/vulkan/vulkan_proc_table.cc b/vulkan/procs/vulkan_proc_table.cc similarity index 76% rename from vulkan/vulkan_proc_table.cc rename to vulkan/procs/vulkan_proc_table.cc index a4c21bf2d7065..b4eb57032e33d 100644 --- a/vulkan/vulkan_proc_table.cc +++ b/vulkan/procs/vulkan_proc_table.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "vulkan_proc_table.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include @@ -14,6 +14,14 @@ return false; \ } +#define ACQUIRE_PROC_EITHER(name, name2, context) \ + if (!(name = AcquireProc("vk" #name, context)) && \ + !(name2 = AcquireProc("vk" #name2, context))) { \ + FML_DLOG(INFO) << "Could not acquire proc: vk" << #name << ", or proc: vk" \ + << #name2; \ + return false; \ + } + namespace vulkan { VulkanProcTable::VulkanProcTable() : VulkanProcTable("libvulkan.so"){}; @@ -26,9 +34,9 @@ VulkanProcTable::VulkanProcTable(const char* so_path) } VulkanProcTable::VulkanProcTable( - std::function get_instance_proc_addr) + PFN_vkGetInstanceProcAddr get_instance_proc_addr) : handle_(nullptr), acquired_mandatory_proc_addresses_(false) { - GetInstanceProcAddr = std::move(get_instance_proc_addr); + GetInstanceProcAddr = get_instance_proc_addr; acquired_mandatory_proc_addresses_ = SetupLoaderProcAddresses(); } @@ -57,13 +65,7 @@ bool VulkanProcTable::SetupGetInstanceProcAddress() { return true; } - GetInstanceProcAddr = reinterpret_cast( -#if VULKAN_LINK_STATICALLY - &vkGetInstanceProcAddr -#else // VULKAN_LINK_STATICALLY - const_cast(handle_->ResolveSymbol("vkGetInstanceProcAddr")) -#endif // VULKAN_LINK_STATICALLY - ); + GetInstanceProcAddr = NativeGetInstanceProcAddr(); if (!GetInstanceProcAddr) { FML_DLOG(WARNING) << "Could not acquire vkGetInstanceProcAddr."; return false; @@ -72,6 +74,20 @@ bool VulkanProcTable::SetupGetInstanceProcAddress() { return true; } +PFN_vkGetInstanceProcAddr VulkanProcTable::NativeGetInstanceProcAddr() const { + if (GetInstanceProcAddr) { + return GetInstanceProcAddr; + } + +#if VULKAN_LINK_STATICALLY + return &vkGetInstanceProcAddr; +#else // VULKAN_LINK_STATICALLY + auto instance_proc = + const_cast(handle_->ResolveSymbol("vkGetInstanceProcAddr")); + return reinterpret_cast(instance_proc); +#endif // VULKAN_LINK_STATICALLY +} + bool VulkanProcTable::SetupLoaderProcAddresses() { VulkanHandle null_instance(VK_NULL_HANDLE, nullptr); @@ -92,6 +108,11 @@ bool VulkanProcTable::SetupInstanceProcAddresses( ACQUIRE_PROC(GetDeviceProcAddr, handle); ACQUIRE_PROC(GetPhysicalDeviceFeatures, handle); ACQUIRE_PROC(GetPhysicalDeviceQueueFamilyProperties, handle); + ACQUIRE_PROC(GetPhysicalDeviceProperties, handle); + ACQUIRE_PROC(GetPhysicalDeviceMemoryProperties, handle); + ACQUIRE_PROC_EITHER(GetPhysicalDeviceMemoryProperties2, + GetPhysicalDeviceMemoryProperties2KHR, handle); + #if FML_OS_ANDROID ACQUIRE_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR, handle); ACQUIRE_PROC(GetPhysicalDeviceSurfaceFormatsKHR, handle); @@ -142,6 +163,23 @@ bool VulkanProcTable::SetupDeviceProcAddresses( ACQUIRE_PROC(ResetCommandBuffer, handle); ACQUIRE_PROC(ResetFences, handle); ACQUIRE_PROC(WaitForFences, handle); + ACQUIRE_PROC(MapMemory, handle); + ACQUIRE_PROC(UnmapMemory, handle); + ACQUIRE_PROC(FlushMappedMemoryRanges, handle); + ACQUIRE_PROC(InvalidateMappedMemoryRanges, handle); + ACQUIRE_PROC(BindBufferMemory, handle); + ACQUIRE_PROC(GetBufferMemoryRequirements, handle); + ACQUIRE_PROC(CreateBuffer, handle); + ACQUIRE_PROC(DestroyBuffer, handle); + ACQUIRE_PROC(CmdCopyBuffer, handle); + + ACQUIRE_PROC_EITHER(GetBufferMemoryRequirements2, + GetBufferMemoryRequirements2KHR, handle); + ACQUIRE_PROC_EITHER(GetImageMemoryRequirements2, + GetImageMemoryRequirements2KHR, handle); + ACQUIRE_PROC_EITHER(BindBufferMemory2, BindBufferMemory2KHR, handle); + ACQUIRE_PROC_EITHER(BindImageMemory2, BindImageMemory2KHR, handle); + #ifndef TEST_VULKAN_PROCS #if FML_OS_ANDROID ACQUIRE_PROC(AcquireNextImageKHR, handle); @@ -171,7 +209,7 @@ bool VulkanProcTable::OpenLibraryHandle(const char* path) { handle_ = fml::NativeLibrary::Create(path); #endif // VULKAN_LINK_STATICALLY if (!handle_) { - FML_DLOG(WARNING) << "Could not open Vulkan library handle: " << path; + FML_DLOG(ERROR) << "Could not open Vulkan library handle: " << path; return false; } return true; @@ -204,22 +242,4 @@ PFN_vkVoidFunction VulkanProcTable::AcquireProc( return GetDeviceProcAddr(device, proc_name); } -GrVkGetProc VulkanProcTable::CreateSkiaGetProc() const { - if (!IsValid()) { - return nullptr; - } - - return [this](const char* proc_name, VkInstance instance, VkDevice device) { - if (device != VK_NULL_HANDLE) { - auto result = - AcquireProc(proc_name, VulkanHandle{device, nullptr}); - if (result != nullptr) { - return result; - } - } - - return AcquireProc(proc_name, VulkanHandle{instance, nullptr}); - }; -} - } // namespace vulkan diff --git a/vulkan/vulkan_proc_table.h b/vulkan/procs/vulkan_proc_table.h similarity index 79% rename from vulkan/vulkan_proc_table.h rename to vulkan/procs/vulkan_proc_table.h index 93b4d0a3bfdd2..3092bed159a5d 100644 --- a/vulkan/vulkan_proc_table.h +++ b/vulkan/procs/vulkan_proc_table.h @@ -2,17 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_VULKAN_VULKAN_PROC_TABLE_H_ -#define FLUTTER_VULKAN_VULKAN_PROC_TABLE_H_ +#pragma once #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/memory/ref_ptr.h" #include "flutter/fml/native_library.h" -#include "third_party/skia/include/core/SkRefCnt.h" -#include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" -#include "vulkan_handle.h" -#include "vulkan_interface.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_interface.h" namespace vulkan { @@ -50,8 +47,7 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { VulkanProcTable(); explicit VulkanProcTable(const char* so_path); - explicit VulkanProcTable( - std::function get_instance_proc_addr); + explicit VulkanProcTable(PFN_vkGetInstanceProcAddr get_instance_proc_addr); ~VulkanProcTable(); bool HasAcquiredMandatoryProcAddresses() const; @@ -66,9 +62,7 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { bool SetupDeviceProcAddresses(const VulkanHandle& device); - GrVkGetProc CreateSkiaGetProc() const; - - std::function GetInstanceProcAddr = nullptr; + PFN_vkGetInstanceProcAddr GetInstanceProcAddr = nullptr; #define DEFINE_PROC(name) Proc name; @@ -113,6 +107,30 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { DEFINE_PROC(ResetCommandBuffer); DEFINE_PROC(ResetFences); DEFINE_PROC(WaitForFences); + DEFINE_PROC(GetPhysicalDeviceProperties); + DEFINE_PROC(GetPhysicalDeviceMemoryProperties); + DEFINE_PROC(MapMemory); + DEFINE_PROC(UnmapMemory); + DEFINE_PROC(FlushMappedMemoryRanges); + DEFINE_PROC(InvalidateMappedMemoryRanges); + DEFINE_PROC(BindBufferMemory); + DEFINE_PROC(GetBufferMemoryRequirements); + DEFINE_PROC(CreateBuffer); + DEFINE_PROC(DestroyBuffer); + DEFINE_PROC(CmdCopyBuffer); + + DEFINE_PROC(GetPhysicalDeviceMemoryProperties2); + DEFINE_PROC(GetPhysicalDeviceMemoryProperties2KHR); + + DEFINE_PROC(GetBufferMemoryRequirements2); + DEFINE_PROC(GetBufferMemoryRequirements2KHR); + DEFINE_PROC(GetImageMemoryRequirements2); + DEFINE_PROC(GetImageMemoryRequirements2KHR); + DEFINE_PROC(BindBufferMemory2); + DEFINE_PROC(BindBufferMemory2KHR); + DEFINE_PROC(BindImageMemory2); + DEFINE_PROC(BindImageMemory2KHR); + #ifndef TEST_VULKAN_PROCS #if FML_OS_ANDROID DEFINE_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR); @@ -136,6 +154,15 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { #undef DEFINE_PROC + PFN_vkGetInstanceProcAddr NativeGetInstanceProcAddr() const; + + PFN_vkVoidFunction AcquireProc( + const char* proc_name, + const VulkanHandle& instance) const; + + PFN_vkVoidFunction AcquireProc(const char* proc_name, + const VulkanHandle& device) const; + private: fml::RefPtr handle_; bool acquired_mandatory_proc_addresses_; @@ -146,15 +173,8 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { bool SetupGetInstanceProcAddress(); bool SetupLoaderProcAddresses(); bool CloseLibraryHandle(); - PFN_vkVoidFunction AcquireProc( - const char* proc_name, - const VulkanHandle& instance) const; - PFN_vkVoidFunction AcquireProc(const char* proc_name, - const VulkanHandle& device) const; FML_DISALLOW_COPY_AND_ASSIGN(VulkanProcTable); }; } // namespace vulkan - -#endif // FLUTTER_VULKAN_VULKAN_PROC_TABLE_H_ diff --git a/vulkan/vulkan_application.cc b/vulkan/vulkan_application.cc index c04522c54d8f6..47cbf3ec29eca 100644 --- a/vulkan/vulkan_application.cc +++ b/vulkan/vulkan_application.cc @@ -7,8 +7,8 @@ #include #include +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "vulkan_device.h" -#include "vulkan_proc_table.h" #include "vulkan_utilities.h" namespace vulkan { diff --git a/vulkan/vulkan_application.h b/vulkan/vulkan_application.h index 3abb558b512ef..06c437caffe0e 100644 --- a/vulkan/vulkan_application.h +++ b/vulkan/vulkan_application.h @@ -10,8 +10,8 @@ #include #include "flutter/fml/macros.h" +#include "flutter/vulkan/procs/vulkan_handle.h" #include "vulkan_debug_report.h" -#include "vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_backbuffer.cc b/vulkan/vulkan_backbuffer.cc index b8b62aedbeb9f..5baf465b539dc 100644 --- a/vulkan/vulkan_backbuffer.cc +++ b/vulkan/vulkan_backbuffer.cc @@ -6,9 +6,9 @@ #include +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "third_party/skia/include/gpu/vk/GrVkTypes.h" #include "vulkan/vulkan.h" -#include "vulkan_proc_table.h" namespace vulkan { diff --git a/vulkan/vulkan_backbuffer.h b/vulkan/vulkan_backbuffer.h index 095b6d1aa69ea..c485be6d2d1e5 100644 --- a/vulkan/vulkan_backbuffer.h +++ b/vulkan/vulkan_backbuffer.h @@ -9,10 +9,10 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" +#include "flutter/vulkan/procs/vulkan_handle.h" #include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSurface.h" #include "vulkan_command_buffer.h" -#include "vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_command_buffer.cc b/vulkan/vulkan_command_buffer.cc index 8b767808b7ba0..d8412d6c931e8 100644 --- a/vulkan/vulkan_command_buffer.cc +++ b/vulkan/vulkan_command_buffer.cc @@ -4,7 +4,7 @@ #include "vulkan_command_buffer.h" -#include "vulkan_proc_table.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" namespace vulkan { diff --git a/vulkan/vulkan_command_buffer.h b/vulkan/vulkan_command_buffer.h index 05b9bbd6d8801..fe037543e3051 100644 --- a/vulkan/vulkan_command_buffer.h +++ b/vulkan/vulkan_command_buffer.h @@ -7,7 +7,7 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" -#include "vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_debug_report.h b/vulkan/vulkan_debug_report.h index e3a62a986d13b..ba7e7e48d2483 100644 --- a/vulkan/vulkan_debug_report.h +++ b/vulkan/vulkan_debug_report.h @@ -6,9 +6,9 @@ #define FLUTTER_VULKAN_VULKAN_DEBUG_REPORT_H_ #include "flutter/fml/macros.h" -#include "vulkan_handle.h" -#include "vulkan_interface.h" -#include "vulkan_proc_table.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_interface.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" namespace vulkan { diff --git a/vulkan/vulkan_device.cc b/vulkan/vulkan_device.cc index 16126133bbe66..5325d6d52418c 100644 --- a/vulkan/vulkan_device.cc +++ b/vulkan/vulkan_device.cc @@ -8,8 +8,8 @@ #include #include +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" -#include "vulkan_proc_table.h" #include "vulkan_surface.h" #include "vulkan_utilities.h" diff --git a/vulkan/vulkan_device.h b/vulkan/vulkan_device.h index 767624c01ebde..559c4fab9d570 100644 --- a/vulkan/vulkan_device.h +++ b/vulkan/vulkan_device.h @@ -9,7 +9,7 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" -#include "vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_image.cc b/vulkan/vulkan_image.cc index ccd69fee9c181..c258aca56c2f3 100644 --- a/vulkan/vulkan_image.cc +++ b/vulkan/vulkan_image.cc @@ -4,8 +4,8 @@ #include "vulkan_image.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "vulkan_command_buffer.h" -#include "vulkan_proc_table.h" namespace vulkan { diff --git a/vulkan/vulkan_image.h b/vulkan/vulkan_image.h index cdab2faeaca06..21d4997018773 100644 --- a/vulkan/vulkan_image.h +++ b/vulkan/vulkan_image.h @@ -7,7 +7,7 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" -#include "vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_native_surface.h b/vulkan/vulkan_native_surface.h index 0cf3c33fa5431..33884c611207a 100644 --- a/vulkan/vulkan_native_surface.h +++ b/vulkan/vulkan_native_surface.h @@ -6,9 +6,9 @@ #define FLUTTER_VULKAN_VULKAN_NATIVE_SURFACE_H_ #include "flutter/fml/macros.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "third_party/skia/include/core/SkSize.h" -#include "vulkan_handle.h" -#include "vulkan_proc_table.h" namespace vulkan { diff --git a/vulkan/vulkan_provider.h b/vulkan/vulkan_provider.h index e32e99b917446..cfbc48fe9f61f 100644 --- a/vulkan/vulkan_provider.h +++ b/vulkan/vulkan_provider.h @@ -5,7 +5,8 @@ #ifndef FLUTTER_VULKAN_VULKAN_PROVIDER_H_ #define FLUTTER_VULKAN_VULKAN_PROVIDER_H_ -#include "vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" namespace vulkan { diff --git a/vulkan/vulkan_skia_proc_table.cc b/vulkan/vulkan_skia_proc_table.cc new file mode 100644 index 0000000000000..71977fd269d93 --- /dev/null +++ b/vulkan/vulkan_skia_proc_table.cc @@ -0,0 +1,28 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/vulkan/vulkan_skia_proc_table.h" + +namespace vulkan { + +GrVkGetProc CreateSkiaGetProc(const fml::RefPtr& vk) { + if (!vk || !vk->IsValid()) { + return nullptr; + } + + return [vk](const char* proc_name, VkInstance instance, VkDevice device) { + if (device != VK_NULL_HANDLE) { + auto result = + vk->AcquireProc(proc_name, VulkanHandle{device, nullptr}); + if (result != nullptr) { + return result; + } + } + + return vk->AcquireProc(proc_name, + VulkanHandle{instance, nullptr}); + }; +} + +} // namespace vulkan diff --git a/vulkan/vulkan_skia_proc_table.h b/vulkan/vulkan_skia_proc_table.h new file mode 100644 index 0000000000000..9ed988ea51598 --- /dev/null +++ b/vulkan/vulkan_skia_proc_table.h @@ -0,0 +1,15 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "flutter/vulkan/procs/vulkan_proc_table.h" + +#include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" + +namespace vulkan { + +GrVkGetProc CreateSkiaGetProc(const fml::RefPtr& vk); + +} // namespace vulkan diff --git a/vulkan/vulkan_surface.h b/vulkan/vulkan_surface.h index a214b8d917683..3455425c27631 100644 --- a/vulkan/vulkan_surface.h +++ b/vulkan/vulkan_surface.h @@ -6,8 +6,8 @@ #define FLUTTER_VULKAN_VULKAN_SURFACE_H_ #include "flutter/fml/macros.h" +#include "flutter/vulkan/procs/vulkan_handle.h" #include "third_party/skia/include/core/SkSize.h" -#include "vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_swapchain.cc b/vulkan/vulkan_swapchain.cc index 8735dcfd8d970..54dd70d8a6c52 100644 --- a/vulkan/vulkan_swapchain.cc +++ b/vulkan/vulkan_swapchain.cc @@ -4,13 +4,13 @@ #include "vulkan_swapchain.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/vk/GrVkTypes.h" #include "vulkan_backbuffer.h" #include "vulkan_device.h" #include "vulkan_image.h" -#include "vulkan_proc_table.h" #include "vulkan_surface.h" namespace vulkan { diff --git a/vulkan/vulkan_swapchain.h b/vulkan/vulkan_swapchain.h index b617b659d04fb..6d3c6788e5da6 100644 --- a/vulkan/vulkan_swapchain.h +++ b/vulkan/vulkan_swapchain.h @@ -11,9 +11,9 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" +#include "flutter/vulkan/procs/vulkan_handle.h" #include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSurface.h" -#include "vulkan_handle.h" namespace vulkan { diff --git a/vulkan/vulkan_utilities.h b/vulkan/vulkan_utilities.h index 666494c146647..cc43da1380a76 100644 --- a/vulkan/vulkan_utilities.h +++ b/vulkan/vulkan_utilities.h @@ -9,8 +9,8 @@ #include #include "flutter/fml/macros.h" -#include "vulkan_handle.h" -#include "vulkan_proc_table.h" +#include "flutter/vulkan/procs/vulkan_handle.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" namespace vulkan { diff --git a/vulkan/vulkan_window.cc b/vulkan/vulkan_window.cc index 53c8adb703203..a7067fff3f907 100644 --- a/vulkan/vulkan_window.cc +++ b/vulkan/vulkan_window.cc @@ -9,6 +9,8 @@ #include #include +#include "flutter/flutter_vma/flutter_skia_vma.h" +#include "flutter/vulkan/vulkan_skia_proc_table.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "vulkan_application.h" #include "vulkan_device.h" @@ -80,6 +82,12 @@ VulkanWindow::VulkanWindow(const sk_sp& context, return; } + // Needs to happen before GrDirectContext is created. + memory_allocator_ = flutter::FlutterSkiaVulkanMemoryAllocator::Make( + application_->GetAPIVersion(), application_->GetInstance(), + logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), + vk, true); + // Create the Skia GrDirectContext. if (!skia_gr_context_ && !CreateSkiaGrContext()) { @@ -131,7 +139,7 @@ bool VulkanWindow::CreateSkiaGrContext() { } bool VulkanWindow::CreateSkiaBackendContext(GrVkBackendContext* context) { - auto getProc = vk->CreateSkiaGetProc(); + auto getProc = CreateSkiaGetProc(vk); if (getProc == nullptr) { return false; @@ -154,6 +162,7 @@ bool VulkanWindow::CreateSkiaBackendContext(GrVkBackendContext* context) { context->fFeatures = skia_features; context->fGetProc = std::move(getProc); context->fOwnsInstanceAndDevice = false; + context->fMemoryAllocator = memory_allocator_; return true; } diff --git a/vulkan/vulkan_window.h b/vulkan/vulkan_window.h index bbaba38d47e1b..1a0509025481e 100644 --- a/vulkan/vulkan_window.h +++ b/vulkan/vulkan_window.h @@ -10,14 +10,15 @@ #include #include +#include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" -#include "vulkan_proc_table.h" namespace vulkan { @@ -63,6 +64,7 @@ class VulkanWindow { std::unique_ptr logical_device_; std::unique_ptr surface_; std::unique_ptr swapchain_; + sk_sp memory_allocator_; sk_sp skia_gr_context_; bool CreateSkiaGrContext();