14 uint32_t vulkan_api_version,
16 VkPhysicalDevice physicalDevice,
19 bool mustUseCoherentHostVisibleMemory) {
20#define PROVIDE_PROC(tbl, proc, provider) tbl.vk##proc = provider->proc;
22 VmaVulkanFunctions proc_table = {};
23 proc_table.vkGetInstanceProcAddr = vk->NativeGetInstanceProcAddr();
25 PROVIDE_PROC(proc_table, GetPhysicalDeviceProperties, vk);
26 PROVIDE_PROC(proc_table, GetPhysicalDeviceMemoryProperties, vk);
32 PROVIDE_PROC(proc_table, InvalidateMappedMemoryRanges, vk);
35 PROVIDE_PROC(proc_table, GetBufferMemoryRequirements, vk);
36 PROVIDE_PROC(proc_table, GetImageMemoryRequirements, vk);
43#define PROVIDE_PROC_COALESCE(tbl, proc, provider) \
44 tbl.vk##proc##KHR = provider->proc ? provider->proc : provider->proc##KHR;
53#undef PROVIDE_PROC_COALESCE
57 VmaAllocatorCreateInfo allocator_info = {};
58 allocator_info.vulkanApiVersion = vulkan_api_version;
59 allocator_info.physicalDevice = physicalDevice;
60 allocator_info.device =
device;
62 allocator_info.pVulkanFunctions = &proc_table;
64 VmaAllocator allocator;
65 vmaCreateAllocator(&allocator_info, &allocator);
67 return sk_sp<FlutterSkiaVulkanMemoryAllocator>(
69 mustUseCoherentHostVisibleMemory));
88 uint32_t allocationPropertyFlags,
89 skgpu::VulkanBackendMemory* backendMemory) {
90 VmaAllocationCreateInfo info;
92 info.usage = VMA_MEMORY_USAGE_UNKNOWN;
93 info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
94 info.preferredFlags = 0;
95 info.memoryTypeBits = 0;
96 info.pool = VK_NULL_HANDLE;
97 info.pUserData =
nullptr;
99 if (kDedicatedAllocation_AllocationPropertyFlag & allocationPropertyFlags) {
100 info.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
102 if (kLazyAllocation_AllocationPropertyFlag & allocationPropertyFlags) {
103 info.requiredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
105 if (kProtected_AllocationPropertyFlag & allocationPropertyFlags) {
106 info.requiredFlags |= VK_MEMORY_PROPERTY_PROTECTED_BIT;
109 VmaAllocation allocation;
111 vmaAllocateMemoryForImage(allocator_,
image, &info, &allocation,
nullptr);
112 if (VK_SUCCESS == result) {
113 *backendMemory =
reinterpret_cast<skgpu::VulkanBackendMemory
>(allocation);
121 uint32_t allocationPropertyFlags,
122 skgpu::VulkanBackendMemory* backendMemory) {
123 VmaAllocationCreateInfo info;
125 info.usage = VMA_MEMORY_USAGE_UNKNOWN;
126 info.memoryTypeBits = 0;
127 info.pool = VK_NULL_HANDLE;
128 info.pUserData =
nullptr;
131 case BufferUsage::kGpuOnly:
132 info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
133 info.preferredFlags = 0;
135 case BufferUsage::kCpuWritesGpuReads:
151 info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
152 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
153 info.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
155 case BufferUsage::kTransfersFromCpuToGpu:
156 info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
157 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
158 info.preferredFlags = 0;
160 case BufferUsage::kTransfersFromGpuToCpu:
161 info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
162 info.preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
166 if (must_use_coherent_host_visible_memory_ &&
167 (info.requiredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
168 info.requiredFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
170 if (kDedicatedAllocation_AllocationPropertyFlag & allocationPropertyFlags) {
171 info.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
173 if ((kLazyAllocation_AllocationPropertyFlag & allocationPropertyFlags) &&
174 BufferUsage::kGpuOnly == usage) {
175 info.preferredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
178 if (kPersistentlyMapped_AllocationPropertyFlag & allocationPropertyFlags) {
179 SkASSERT(BufferUsage::kGpuOnly != usage);
180 info.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
183 VmaAllocation allocation;
184 VkResult result = vmaAllocateMemoryForBuffer(allocator_,
buffer, &info,
185 &allocation,
nullptr);
186 if (VK_SUCCESS == result) {
187 *backendMemory =
reinterpret_cast<skgpu::VulkanBackendMemory
>(allocation);
201 const skgpu::VulkanBackendMemory& memoryHandle,
202 skgpu::VulkanAlloc* alloc)
const {
203 const VmaAllocation allocation =
204 reinterpret_cast<const VmaAllocation
>(memoryHandle);
205 VmaAllocationInfo vmaInfo;
206 vmaGetAllocationInfo(allocator_, allocation, &vmaInfo);
208 VkMemoryPropertyFlags memFlags;
209 vmaGetMemoryTypeProperties(allocator_, vmaInfo.memoryType, &memFlags);
212 if (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT & memFlags) {
213 flags |= skgpu::VulkanAlloc::kMappable_Flag;
215 if (!(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT & memFlags)) {
216 flags |= skgpu::VulkanAlloc::kNoncoherent_Flag;
218 if (VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT & memFlags) {
219 flags |= skgpu::VulkanAlloc::kLazilyAllocated_Flag;
222 alloc->fMemory = vmaInfo.deviceMemory;
223 alloc->fOffset = vmaInfo.offset;
224 alloc->fSize = vmaInfo.size;
225 alloc->fFlags = flags;
226 alloc->fBackendMemory = memoryHandle;