| Flutter Impeller |

allocator_vk.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "impeller/renderer/backend/vulkan/allocator_vk.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "flutter/fml/memory/ref_ptr.h"
11 #include "flutter/fml/trace_event.h"
12 #include "impeller/base/allocation_size.h"
13 #include "impeller/core/formats.h"
14 #include "impeller/renderer/backend/vulkan/capabilities_vk.h"
15 #include "impeller/renderer/backend/vulkan/device_buffer_vk.h"
16 #include "impeller/renderer/backend/vulkan/device_holder_vk.h"
17 #include "impeller/renderer/backend/vulkan/formats_vk.h"
18 #include "impeller/renderer/backend/vulkan/texture_vk.h"
19 #include "vulkan/vulkan_enums.hpp"
20
21 namespace impeller {
22
23 static constexpr vk::Flags<vk::MemoryPropertyFlagBits>
24 ToVKBufferMemoryPropertyFlags(StorageMode mode) {
25 switch (mode) {
26 case StorageMode::kHostVisible:
27 return vk::MemoryPropertyFlagBits::eHostVisible;
28 case StorageMode::kDevicePrivate:
29 return vk::MemoryPropertyFlagBits::eDeviceLocal;
30 case StorageMode::kDeviceTransient:
31 return vk::MemoryPropertyFlagBits::eLazilyAllocated;
32 }
33 FML_UNREACHABLE();
34 }
35
36 static VmaAllocationCreateFlags ToVmaAllocationBufferCreateFlags(
37 StorageMode mode,
38 bool readback) {
39 VmaAllocationCreateFlags flags = 0;
40 switch (mode) {
41 case StorageMode::kHostVisible:
42 if (!readback) {
43 flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
44 } else {
45 flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
46 }
47 flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
48 return flags;
49 case StorageMode::kDevicePrivate:
50 FML_DCHECK(!readback);
51 return flags;
52 case StorageMode::kDeviceTransient:
53 FML_DCHECK(!readback);
54 return flags;
55 }
56 FML_UNREACHABLE();
57 }
58
59 static PoolVMA CreateBufferPool(VmaAllocator allocator) {
60 vk::BufferCreateInfo buffer_info;
61 buffer_info.usage = vk::BufferUsageFlagBits::eVertexBuffer |
62 vk::BufferUsageFlagBits::eIndexBuffer |
63 vk::BufferUsageFlagBits::eUniformBuffer |
64 vk::BufferUsageFlagBits::eStorageBuffer |
65 vk::BufferUsageFlagBits::eTransferSrc |
66 vk::BufferUsageFlagBits::eTransferDst;
67 buffer_info.size = 1u; // doesn't matter
68 buffer_info.sharingMode = vk::SharingMode::eExclusive;
69 auto buffer_info_native =
70 static_cast<vk::BufferCreateInfo::NativeType>(buffer_info);
71
72 VmaAllocationCreateInfo allocation_info = {};
73 allocation_info.usage = VMA_MEMORY_USAGE_AUTO;
74 allocation_info.preferredFlags = static_cast<VkMemoryPropertyFlags>(
75 ToVKBufferMemoryPropertyFlags(StorageMode::kHostVisible));
76 allocation_info.flags = ToVmaAllocationBufferCreateFlags(
77 StorageMode::kHostVisible, /*readback=*/false);
78
79 uint32_t memTypeIndex;
80 auto result = vk::Result{vmaFindMemoryTypeIndexForBufferInfo(
81 allocator, &buffer_info_native, &allocation_info, &memTypeIndex)};
82 if (result != vk::Result::eSuccess) {
83 return {};
84 }
85
86 VmaPoolCreateInfo pool_create_info = {};
87 pool_create_info.memoryTypeIndex = memTypeIndex;
88 pool_create_info.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT;
89 pool_create_info.minBlockCount = 1;
90
91 VmaPool pool = {};
92 result = vk::Result{::vmaCreatePool(allocator, &pool_create_info, &pool)};
93 if (result != vk::Result::eSuccess) {
94 return {};
95 }
96 return {allocator, pool};
97 }
98
99 AllocatorVK::AllocatorVK(std::weak_ptr<Context> context,
100 uint32_t vulkan_api_version,
101 const vk::PhysicalDevice& physical_device,
102 const std::shared_ptr<DeviceHolderVK>& device_holder,
103 const vk::Instance& instance,
104 const CapabilitiesVK& capabilities)
105 : context_(std::move(context)), device_holder_(device_holder) {
106 auto limits = physical_device.getProperties().limits;
107 max_texture_size_.width = max_texture_size_.height =
108 limits.maxImageDimension2D;
109 physical_device.getMemoryProperties(&memory_properties_);
110
111 VmaVulkanFunctions proc_table = {};
112
113 #define BIND_VMA_PROC(x) proc_table.x = VULKAN_HPP_DEFAULT_DISPATCHER.x;
114 #define BIND_VMA_PROC_KHR(x) \
115 proc_table.x##KHR = VULKAN_HPP_DEFAULT_DISPATCHER.x \
116 ? VULKAN_HPP_DEFAULT_DISPATCHER.x \
117 : VULKAN_HPP_DEFAULT_DISPATCHER.x##KHR;
118 BIND_VMA_PROC(vkGetInstanceProcAddr);
119 BIND_VMA_PROC(vkGetDeviceProcAddr);
120 BIND_VMA_PROC(vkGetPhysicalDeviceProperties);
121 BIND_VMA_PROC(vkGetPhysicalDeviceMemoryProperties);
122 BIND_VMA_PROC(vkAllocateMemory);
123 BIND_VMA_PROC(vkFreeMemory);
124 BIND_VMA_PROC(vkMapMemory);
125 BIND_VMA_PROC(vkUnmapMemory);
126 BIND_VMA_PROC(vkFlushMappedMemoryRanges);
127 BIND_VMA_PROC(vkInvalidateMappedMemoryRanges);
128 BIND_VMA_PROC(vkBindBufferMemory);
129 BIND_VMA_PROC(vkBindImageMemory);
130 BIND_VMA_PROC(vkGetBufferMemoryRequirements);
131 BIND_VMA_PROC(vkGetImageMemoryRequirements);
132 BIND_VMA_PROC(vkCreateBuffer);
133 BIND_VMA_PROC(vkDestroyBuffer);
134 BIND_VMA_PROC(vkCreateImage);
135 BIND_VMA_PROC(vkDestroyImage);
136 BIND_VMA_PROC(vkCmdCopyBuffer);
137 BIND_VMA_PROC_KHR(vkGetBufferMemoryRequirements2);
138 BIND_VMA_PROC_KHR(vkGetImageMemoryRequirements2);
139 BIND_VMA_PROC_KHR(vkBindBufferMemory2);
140 BIND_VMA_PROC_KHR(vkBindImageMemory2);
141 BIND_VMA_PROC_KHR(vkGetPhysicalDeviceMemoryProperties2);
142 #undef BIND_VMA_PROC_KHR
143 #undef BIND_VMA_PROC
144
145 VmaAllocatorCreateInfo allocator_info = {};
146 allocator_info.vulkanApiVersion = vulkan_api_version;
147 allocator_info.physicalDevice = physical_device;
148 allocator_info.device = device_holder->GetDevice();
149 allocator_info.instance = instance;
150 // 4 MB, matching the default used by Skia Vulkan.
151 allocator_info.preferredLargeHeapBlockSize = 4 * 1024 * 1024;
152 allocator_info.pVulkanFunctions = &proc_table;
153
154 VmaAllocator allocator = {};
155 auto result = vk::Result{::vmaCreateAllocator(&allocator_info, &allocator)};
156 if (result != vk::Result::eSuccess) {
157 VALIDATION_LOG << "Could not create memory allocator";
158 return;
159 }
160 staging_buffer_pool_.reset(CreateBufferPool(allocator));
161 created_buffer_pool_ &= staging_buffer_pool_.is_valid();
162 allocator_.reset(allocator);
163 supports_memoryless_textures_ =
164 capabilities.SupportsDeviceTransientTextures();
165 is_valid_ = true;
166 }
167
168 AllocatorVK::~AllocatorVK() = default;
169
170 // |Allocator|
171 bool AllocatorVK::IsValid() const {
172 return is_valid_;
173 }
174
175 // |Allocator|
176 ISize AllocatorVK::GetMaxTextureSizeSupported() const {
177 return max_texture_size_;
178 }
179
180 int32_t AllocatorVK::FindMemoryTypeIndex(
181 uint32_t memory_type_bits_requirement,
182 vk::PhysicalDeviceMemoryProperties& memory_properties) {
183 int32_t type_index = -1;
184 vk::MemoryPropertyFlagBits required_properties =
185 vk::MemoryPropertyFlagBits::eDeviceLocal;
186
187 const uint32_t memory_count = memory_properties.memoryTypeCount;
188 for (uint32_t memory_index = 0; memory_index < memory_count; ++memory_index) {
189 const uint32_t memory_type_bits = (1 << memory_index);
190 const bool is_required_memory_type =
191 memory_type_bits_requirement & memory_type_bits;
192
193 const auto properties =
194 memory_properties.memoryTypes[memory_index].propertyFlags;
195 const bool has_required_properties =
196 (properties & required_properties) == required_properties;
197
198 if (is_required_memory_type && has_required_properties) {
199 return static_cast<int32_t>(memory_index);
200 }
201 }
202
203 return type_index;
204 }
205
206 vk::ImageUsageFlags AllocatorVK::ToVKImageUsageFlags(
207 PixelFormat format,
208 TextureUsageMask usage,
209 StorageMode mode,
210 bool supports_memoryless_textures) {
211 vk::ImageUsageFlags vk_usage;
212
213 switch (mode) {
214 case StorageMode::kHostVisible:
215 case StorageMode::kDevicePrivate:
216 break;
217 case StorageMode::kDeviceTransient:
218 if (supports_memoryless_textures) {
219 vk_usage |= vk::ImageUsageFlagBits::eTransientAttachment;
220 }
221 break;
222 }
223
224 if (usage & TextureUsage::kRenderTarget) {
225 if (PixelFormatIsDepthStencil(format)) {
226 vk_usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
227 } else {
228 vk_usage |= vk::ImageUsageFlagBits::eColorAttachment;
229 vk_usage |= vk::ImageUsageFlagBits::eInputAttachment;
230 }
231 }
232
233 if (usage & TextureUsage::kShaderRead) {
234 vk_usage |= vk::ImageUsageFlagBits::eSampled;
235 }
236
237 if (usage & TextureUsage::kShaderWrite) {
238 vk_usage |= vk::ImageUsageFlagBits::eStorage;
239 }
240
241 if (mode != StorageMode::kDeviceTransient) {
242 // Add transfer usage flags to support blit passes only if image isn't
243 // device transient.
244 vk_usage |= vk::ImageUsageFlagBits::eTransferSrc |
245 vk::ImageUsageFlagBits::eTransferDst;
246 }
247
248 return vk_usage;
249 }
250
251 static constexpr VmaMemoryUsage ToVMAMemoryUsage() {
252 return VMA_MEMORY_USAGE_AUTO;
253 }
254
255 static constexpr vk::Flags<vk::MemoryPropertyFlagBits>
256 ToVKTextureMemoryPropertyFlags(StorageMode mode,
257 bool supports_memoryless_textures) {
258 switch (mode) {
259 case StorageMode::kHostVisible:
260 return vk::MemoryPropertyFlagBits::eHostVisible |
261 vk::MemoryPropertyFlagBits::eDeviceLocal;
262 case StorageMode::kDevicePrivate:
263 return vk::MemoryPropertyFlagBits::eDeviceLocal;
264 case StorageMode::kDeviceTransient:
265 if (supports_memoryless_textures) {
266 return vk::MemoryPropertyFlagBits::eLazilyAllocated |
267 vk::MemoryPropertyFlagBits::eDeviceLocal;
268 }
269 return vk::MemoryPropertyFlagBits::eDeviceLocal;
270 }
271 FML_UNREACHABLE();
272 }
273
274 static VmaAllocationCreateFlags ToVmaAllocationCreateFlags(StorageMode mode) {
275 VmaAllocationCreateFlags flags = 0;
276 switch (mode) {
277 case StorageMode::kHostVisible:
278 return flags;
279 case StorageMode::kDevicePrivate:
280 return flags;
281 case StorageMode::kDeviceTransient:
282 return flags;
283 }
284 FML_UNREACHABLE();
285 }
286
287 class AllocatedTextureSourceVK final : public TextureSourceVK {
288 public:
289 AllocatedTextureSourceVK(const ContextVK& context,
290 const TextureDescriptor& desc,
291 VmaAllocator allocator,
292 vk::Device device,
293 bool supports_memoryless_textures)
294 : TextureSourceVK(desc), resource_(context.GetResourceManager()) {
295 FML_DCHECK(desc.format != PixelFormat::kUnknown);
296 vk::StructureChain<vk::ImageCreateInfo, vk::ImageCompressionControlEXT>
297 image_info_chain;
298 auto& image_info = image_info_chain.get();
299 image_info.flags = ToVKImageCreateFlags(desc.type);
300 image_info.imageType = vk::ImageType::e2D;
301 image_info.format = ToVKImageFormat(desc.format);
302 image_info.extent = VkExtent3D{
303 static_cast<uint32_t>(desc.size.width), // width
304 static_cast<uint32_t>(desc.size.height), // height
305 1u // depth
306 };
307 image_info.samples = ToVKSampleCount(desc.sample_count);
308 image_info.mipLevels = desc.mip_count;
309 image_info.arrayLayers = ToArrayLayerCount(desc.type);
310 image_info.tiling = vk::ImageTiling::eOptimal;
311 image_info.initialLayout = vk::ImageLayout::eUndefined;
312 image_info.usage = AllocatorVK::ToVKImageUsageFlags(
313 desc.format, desc.usage, desc.storage_mode,
314 supports_memoryless_textures);
315 image_info.sharingMode = vk::SharingMode::eExclusive;
316
317 vk::ImageCompressionFixedRateFlagsEXT frc_rates[1] = {
318 vk::ImageCompressionFixedRateFlagBitsEXT::eNone};
319
320 const auto frc_rate =
321 CapabilitiesVK::Cast(*context.GetCapabilities())
322 .GetSupportedFRCRate(desc.compression_type,
323 FRCFormatDescriptor{image_info});
324 if (frc_rate.has_value()) {
325 // This array must not be in a temporary scope.
326 frc_rates[0] = frc_rate.value();
327
328 auto& compression_info =
329 image_info_chain.get<vk::ImageCompressionControlEXT>();
330 compression_info.pFixedRateFlags = frc_rates;
331 compression_info.compressionControlPlaneCount = 1u;
332 compression_info.flags =
333 vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
334 } else {
335 image_info_chain.unlink<vk::ImageCompressionControlEXT>();
336 }
337
338 VmaAllocationCreateInfo alloc_nfo = {};
339
340 alloc_nfo.usage = ToVMAMemoryUsage();
341 alloc_nfo.preferredFlags =
342 static_cast<VkMemoryPropertyFlags>(ToVKTextureMemoryPropertyFlags(
343 desc.storage_mode, supports_memoryless_textures));
344 alloc_nfo.flags = ToVmaAllocationCreateFlags(desc.storage_mode);
345
346 auto create_info_native =
347 static_cast<vk::ImageCreateInfo::NativeType>(image_info);
348
349 VkImage vk_image = VK_NULL_HANDLE;
350 VmaAllocation allocation = {};
351 VmaAllocationInfo allocation_info = {};
352 {
353 auto result = vk::Result{::vmaCreateImage(allocator, //
354 &create_info_native, //
355 &alloc_nfo, //
356 &vk_image, //
357 &allocation, //
358 &allocation_info //
359 )};
360 if (result != vk::Result::eSuccess) {
361 VALIDATION_LOG << "Unable to allocate Vulkan Image: "
362 << vk::to_string(result)
363 << " Type: " << TextureTypeToString(desc.type)
364 << " Mode: " << StorageModeToString(desc.storage_mode)
365 << " Usage: " << TextureUsageMaskToString(desc.usage)
366 << " [VK]Flags: " << vk::to_string(image_info.flags)
367 << " [VK]Format: " << vk::to_string(image_info.format)
368 << " [VK]Usage: " << vk::to_string(image_info.usage)
369 << " [VK]Mem. Flags: "
370 << vk::to_string(vk::MemoryPropertyFlags(
371 alloc_nfo.preferredFlags));
372 return;
373 }
374 }
375
376 auto image = vk::Image{vk_image};
377
378 vk::ImageViewCreateInfo view_info = {};
379 view_info.image = image;
380 view_info.viewType = ToVKImageViewType(desc.type);
381 view_info.format = image_info.format;
382 view_info.subresourceRange.aspectMask = ToVKImageAspectFlags(desc.format);
383 view_info.subresourceRange.levelCount = image_info.mipLevels;
384 view_info.subresourceRange.layerCount = ToArrayLayerCount(desc.type);
385
386 // Vulkan does not have an image format that is equivalent to
387 // `MTLPixelFormatA8Unorm`, so we use `R8Unorm` instead. Given that the
388 // shaders expect that alpha channel to be set in the cases, we swizzle.
389 // See: https://github.com/flutter/flutter/issues/115461 for more details.
390 if (desc.format == PixelFormat::kA8UNormInt) {
391 view_info.components.a = vk::ComponentSwizzle::eR;
392 view_info.components.r = vk::ComponentSwizzle::eA;
393 }
394
395 auto [result, image_view] = device.createImageViewUnique(view_info);
396 if (result != vk::Result::eSuccess) {
397 VALIDATION_LOG << "Unable to create an image view for allocation: "
398 << vk::to_string(result);
399 return;
400 }
401 // Create a specialized view for render target attachments.
402 view_info.subresourceRange.levelCount = 1u;
403 auto [rt_result, rt_image_view] = device.createImageViewUnique(view_info);
404 if (rt_result != vk::Result::eSuccess) {
405 VALIDATION_LOG << "Unable to create an image view for allocation: "
406 << vk::to_string(rt_result);
407 return;
408 }
409
410 resource_.Swap(ImageResource(
411 ImageVMA{allocator, allocation, image}, std::move(image_view),
412 std::move(rt_image_view), context.GetResourceAllocator(),
413 context.GetDeviceHolder()));
414 is_valid_ = true;
415 }
416
417 ~AllocatedTextureSourceVK() = default;
418
419 bool IsValid() const { return is_valid_; }
420
421 vk::Image GetImage() const override { return resource_->image.get().image; }
422
423 vk::ImageView GetImageView() const override {
424 return resource_->image_view.get();
425 }
426
427 vk::ImageView GetRenderTargetView() const override {
428 return resource_->rt_image_view.get();
429 }
430
431 bool IsSwapchainImage() const override { return false; }
432
433 private:
434 struct ImageResource {
435 std::shared_ptr<DeviceHolderVK> device_holder;
436 std::shared_ptr<Allocator> allocator;
437 UniqueImageVMA image;
438 vk::UniqueImageView image_view;
439 vk::UniqueImageView rt_image_view;
440
441 ImageResource() = default;
442
443 ImageResource(ImageVMA p_image,
444 vk::UniqueImageView p_image_view,
445 vk::UniqueImageView p_rt_image_view,
446 std::shared_ptr<Allocator> allocator,
447 std::shared_ptr<DeviceHolderVK> device_holder)
448 : device_holder(std::move(device_holder)),
449 allocator(std::move(allocator)),
450 image(p_image),
451 image_view(std::move(p_image_view)),
452 rt_image_view(std::move(p_rt_image_view)) {}
453
454 ImageResource(ImageResource&& o) = default;
455
456 ImageResource(const ImageResource&) = delete;
457
458 ImageResource& operator=(const ImageResource&) = delete;
459 };
460
461 UniqueResourceVKT<ImageResource> resource_;
462 bool is_valid_ = false;
463
464 AllocatedTextureSourceVK(const AllocatedTextureSourceVK&) = delete;
465
466 AllocatedTextureSourceVK& operator=(const AllocatedTextureSourceVK&) = delete;
467 };
468
469 // |Allocator|
470 std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
471 const TextureDescriptor& desc,
472 bool threadsafe) {
473 if (!IsValid()) {
474 return nullptr;
475 }
476 auto device_holder = device_holder_.lock();
477 if (!device_holder) {
478 return nullptr;
479 }
480 auto context = context_.lock();
481 if (!context) {
482 return nullptr;
483 }
484 auto source = std::make_shared<AllocatedTextureSourceVK>(
485 ContextVK::Cast(*context), //
486 desc, //
487 allocator_.get(), //
488 device_holder->GetDevice(), //
489 supports_memoryless_textures_ //
490 );
491 if (!source->IsValid()) {
492 return nullptr;
493 }
494 return std::make_shared<TextureVK>(context_, std::move(source));
495 }
496
497 // |Allocator|
498 std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(
499 const DeviceBufferDescriptor& desc) {
500 vk::BufferCreateInfo buffer_info;
501 buffer_info.usage = vk::BufferUsageFlagBits::eVertexBuffer |
502 vk::BufferUsageFlagBits::eIndexBuffer |
503 vk::BufferUsageFlagBits::eUniformBuffer |
504 vk::BufferUsageFlagBits::eStorageBuffer |
505 vk::BufferUsageFlagBits::eTransferSrc |
506 vk::BufferUsageFlagBits::eTransferDst;
507 buffer_info.size = desc.size;
508 buffer_info.sharingMode = vk::SharingMode::eExclusive;
509 auto buffer_info_native =
510 static_cast<vk::BufferCreateInfo::NativeType>(buffer_info);
511
512 VmaAllocationCreateInfo allocation_info = {};
513 allocation_info.usage = ToVMAMemoryUsage();
514 allocation_info.preferredFlags = static_cast<VkMemoryPropertyFlags>(
515 ToVKBufferMemoryPropertyFlags(desc.storage_mode));
516 allocation_info.flags =
517 ToVmaAllocationBufferCreateFlags(desc.storage_mode, desc.readback);
518 if (created_buffer_pool_ && desc.storage_mode == StorageMode::kHostVisible &&
519 !desc.readback) {
520 allocation_info.pool = staging_buffer_pool_.get().pool;
521 }
522 VkBuffer buffer = {};
523 VmaAllocation buffer_allocation = {};
524 VmaAllocationInfo buffer_allocation_info = {};
525 auto result = vk::Result{::vmaCreateBuffer(allocator_.get(), //
526 &buffer_info_native, //
527 &allocation_info, //
528 &buffer, //
529 &buffer_allocation, //
530 &buffer_allocation_info //
531 )};
532
533 auto type = memory_properties_.memoryTypes[buffer_allocation_info.memoryType];
534 bool is_host_coherent =
535 !!(type.propertyFlags & vk::MemoryPropertyFlagBits::eHostCoherent);
536
537 if (result != vk::Result::eSuccess) {
538 VALIDATION_LOG << "Unable to allocate a device buffer: "
539 << vk::to_string(result);
540 return {};
541 }
542
543 return std::make_shared<DeviceBufferVK>(
544 desc, //
545 context_, //
546 UniqueBufferVMA{BufferVMA{allocator_.get(), //
547 buffer_allocation, //
548 vk::Buffer{buffer}}}, //
549 buffer_allocation_info, //
550 is_host_coherent);
551 }
552
553 Bytes AllocatorVK::DebugGetHeapUsage() const {
554 auto count = memory_properties_.memoryHeapCount;
555 std::vector<VmaBudget> budgets(count);
556 vmaGetHeapBudgets(allocator_.get(), budgets.data());
557 size_t total_usage = 0;
558 for (auto i = 0u; i < count; i++) {
559 const VmaBudget& budget = budgets[i];
560 total_usage += budget.usage;
561 }
562 return Bytes{static_cast<double>(total_usage)};
563 }
564
565 void AllocatorVK::DebugTraceMemoryStatistics() const {
566 #ifdef IMPELLER_DEBUG
567 FML_TRACE_COUNTER("flutter", "AllocatorVK",
568 reinterpret_cast<int64_t>(this), // Trace Counter ID
569 "MemoryBudgetUsageMB",
570 DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize());
571 #endif // IMPELLER_DEBUG
572 }
573
574 } // namespace impeller
allocation_size.h
BIND_VMA_PROC_KHR
#define BIND_VMA_PROC_KHR(x)
BIND_VMA_PROC
#define BIND_VMA_PROC(x)
allocator_vk.h
type
GLenum type
Definition: blit_command_gles.cc:153
capabilities_vk.h
impeller::AllocatedTextureSourceVK
Definition: allocator_vk.cc:287
impeller::AllocatedTextureSourceVK::GetRenderTargetView
vk::ImageView GetRenderTargetView() const override
Retrieve the image view used for render target attachments with this texture source.
Definition: allocator_vk.cc:427
impeller::AllocatedTextureSourceVK::GetImage
vk::Image GetImage() const override
Get the image handle for this texture source.
Definition: allocator_vk.cc:421
impeller::AllocatedTextureSourceVK::GetImageView
vk::ImageView GetImageView() const override
Retrieve the image view used for sampling/blitting/compute with this texture source.
Definition: allocator_vk.cc:423
impeller::AllocatedTextureSourceVK::AllocatedTextureSourceVK
AllocatedTextureSourceVK(const ContextVK &context, const TextureDescriptor &desc, VmaAllocator allocator, vk::Device device, bool supports_memoryless_textures)
Definition: allocator_vk.cc:289
impeller::AllocatedTextureSourceVK::~AllocatedTextureSourceVK
~AllocatedTextureSourceVK()=default
impeller::AllocatedTextureSourceVK::IsValid
bool IsValid() const
Definition: allocator_vk.cc:419
impeller::AllocatedTextureSourceVK::IsSwapchainImage
bool IsSwapchainImage() const override
Determines if swapchain image. That is, an image used as the root render target.
Definition: allocator_vk.cc:431
impeller::AllocationSize< 1u >
impeller::ContextVK
Definition: context_vk.h:66
impeller::ContextVK::GetResourceAllocator
std::shared_ptr< Allocator > GetResourceAllocator() const override
Returns the allocator used to create textures and buffers on the device.
Definition: context_vk.cc:523
impeller::ContextVK::GetCapabilities
const std::shared_ptr< const Capabilities > & GetCapabilities() const override
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
Definition: context_vk.cc:617
impeller::ContextVK::GetDeviceHolder
std::shared_ptr< DeviceHolderVK > GetDeviceHolder() const
Definition: context_vk.h:191
impeller::TextureSourceVK
Abstract base class that represents a vkImage and an vkImageView.
Definition: texture_source_vk.h:33
formats.h
device_buffer_vk.h
device_holder_vk.h
formats_vk.h
impeller
Definition: allocation.cc:12
impeller::ToArrayLayerCount
constexpr uint32_t ToArrayLayerCount(TextureType type)
Definition: formats_vk.h:543
impeller::ToVmaAllocationBufferCreateFlags
static VmaAllocationCreateFlags ToVmaAllocationBufferCreateFlags(StorageMode mode, bool readback)
Definition: allocator_vk.cc:36
impeller::TextureUsageMaskToString
std::string TextureUsageMaskToString(TextureUsageMask mask)
Definition: formats.cc:81
impeller::StorageMode
StorageMode
Specified where the allocation resides and how it is used.
Definition: formats.h:32
impeller::StorageMode::kDevicePrivate
@ kDevicePrivate
impeller::StorageMode::kHostVisible
@ kHostVisible
impeller::StorageMode::kDeviceTransient
@ kDeviceTransient
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
impeller::TextureTypeToString
constexpr const char * TextureTypeToString(TextureType type)
Definition: formats.h:272
impeller::PixelFormatIsDepthStencil
constexpr bool PixelFormatIsDepthStencil(PixelFormat format)
Definition: formats_vk.h:416
impeller::ToVMAMemoryUsage
static constexpr VmaMemoryUsage ToVMAMemoryUsage()
Definition: allocator_vk.cc:251
impeller::ToVKImageViewType
constexpr vk::ImageViewType ToVKImageViewType(TextureType type)
Definition: formats_vk.h:557
impeller::ToVKSampleCount
constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count)
Definition: formats_vk.h:216
impeller::ToVKImageFormat
constexpr vk::Format ToVKImageFormat(PixelFormat format)
Definition: formats_vk.h:146
impeller::ToVmaAllocationCreateFlags
static VmaAllocationCreateFlags ToVmaAllocationCreateFlags(StorageMode mode)
Definition: allocator_vk.cc:274
impeller::CreateBufferPool
static PoolVMA CreateBufferPool(VmaAllocator allocator)
Definition: allocator_vk.cc:59
impeller::UniqueImageVMA
fml::UniqueObject< ImageVMA, ImageVMATraits > UniqueImageVMA
Definition: vma.h:127
impeller::ToVKTextureMemoryPropertyFlags
static constexpr vk::Flags< vk::MemoryPropertyFlagBits > ToVKTextureMemoryPropertyFlags(StorageMode mode, bool supports_memoryless_textures)
Definition: allocator_vk.cc:256
impeller::ISize
ISize64 ISize
Definition: size.h:162
impeller::StorageModeToString
constexpr const char * StorageModeToString(StorageMode mode)
Definition: formats.h:60
impeller::ToVKImageCreateFlags
constexpr vk::ImageCreateFlags ToVKImageCreateFlags(TextureType type)
Definition: formats_vk.h:571
impeller::ToVKImageAspectFlags
constexpr vk::ImageAspectFlags ToVKImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:516
impeller::UniqueBufferVMA
fml::UniqueObject< BufferVMA, BufferVMATraits > UniqueBufferVMA
Definition: vma.h:92
impeller::ToVKBufferMemoryPropertyFlags
static constexpr vk::Flags< vk::MemoryPropertyFlagBits > ToVKBufferMemoryPropertyFlags(StorageMode mode)
Definition: allocator_vk.cc:24
std
Definition: comparable.h:95
impeller::FRCFormatDescriptor
A pixel format and usage that is sufficient to check if images of that format and usage are suitable ...
Definition: capabilities_vk.h:162
impeller::ImageVMA
Definition: vma.h:98
impeller::Mask< TextureUsage >
impeller::PoolVMA
Definition: vma.h:37
impeller::TSize::height
Type height
Definition: size.h:29
impeller::TSize::width
Type width
Definition: size.h:28
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:38
impeller::TextureDescriptor::usage
TextureUsageMask usage
Definition: texture_descriptor.h:44
impeller::TextureDescriptor::compression_type
CompressionType compression_type
Definition: texture_descriptor.h:46
impeller::TextureDescriptor::type
TextureType type
Definition: texture_descriptor.h:40
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:39
impeller::TextureDescriptor::sample_count
SampleCount sample_count
Definition: texture_descriptor.h:45
impeller::TextureDescriptor::mip_count
size_t mip_count
Definition: texture_descriptor.h:43
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:41
texture_vk.h
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91