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 
6 
7 #include <memory>
8 
9 #include "flutter/fml/memory/ref_ptr.h"
10 #include "flutter/fml/trace_event.h"
11 #include "impeller/core/formats.h"
15 #include "vulkan/vulkan_enums.hpp"
16 
17 namespace impeller {
18 
19 static constexpr vk::Flags<vk::MemoryPropertyFlagBits>
21  switch (mode) {
23  return vk::MemoryPropertyFlagBits::eHostVisible;
25  return vk::MemoryPropertyFlagBits::eDeviceLocal;
27  return vk::MemoryPropertyFlagBits::eLazilyAllocated;
28  }
29  FML_UNREACHABLE();
30 }
31 
32 static VmaAllocationCreateFlags ToVmaAllocationBufferCreateFlags(
33  StorageMode mode) {
34  VmaAllocationCreateFlags flags = 0;
35  switch (mode) {
37  flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
38  flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
39  return flags;
41  return flags;
43  return flags;
44  }
45  FML_UNREACHABLE();
46 }
47 
48 static PoolVMA CreateBufferPool(VmaAllocator allocator) {
49  vk::BufferCreateInfo buffer_info;
50  buffer_info.usage = vk::BufferUsageFlagBits::eVertexBuffer |
51  vk::BufferUsageFlagBits::eIndexBuffer |
52  vk::BufferUsageFlagBits::eUniformBuffer |
53  vk::BufferUsageFlagBits::eStorageBuffer |
54  vk::BufferUsageFlagBits::eTransferSrc |
55  vk::BufferUsageFlagBits::eTransferDst;
56  buffer_info.size = 1u; // doesn't matter
57  buffer_info.sharingMode = vk::SharingMode::eExclusive;
58  auto buffer_info_native =
59  static_cast<vk::BufferCreateInfo::NativeType>(buffer_info);
60 
61  VmaAllocationCreateInfo allocation_info = {};
62  allocation_info.usage = VMA_MEMORY_USAGE_AUTO;
63  allocation_info.preferredFlags = static_cast<VkMemoryPropertyFlags>(
65  allocation_info.flags =
67 
68  uint32_t memTypeIndex;
69  auto result = vk::Result{vmaFindMemoryTypeIndexForBufferInfo(
70  allocator, &buffer_info_native, &allocation_info, &memTypeIndex)};
71  if (result != vk::Result::eSuccess) {
72  return {};
73  }
74 
75  VmaPoolCreateInfo pool_create_info = {};
76  pool_create_info.memoryTypeIndex = memTypeIndex;
77  pool_create_info.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT;
78 
79  VmaPool pool = {};
80  result = vk::Result{::vmaCreatePool(allocator, &pool_create_info, &pool)};
81  if (result != vk::Result::eSuccess) {
82  return {};
83  }
84  return {allocator, pool};
85 }
86 
87 AllocatorVK::AllocatorVK(std::weak_ptr<Context> context,
88  uint32_t vulkan_api_version,
89  const vk::PhysicalDevice& physical_device,
90  const std::shared_ptr<DeviceHolder>& device_holder,
91  const vk::Instance& instance,
92  const CapabilitiesVK& capabilities)
93  : context_(std::move(context)), device_holder_(device_holder) {
94  auto limits = physical_device.getProperties().limits;
95  max_texture_size_.width = max_texture_size_.height =
96  limits.maxImageDimension2D;
97 
98  VmaVulkanFunctions proc_table = {};
99 
100 #define BIND_VMA_PROC(x) proc_table.x = VULKAN_HPP_DEFAULT_DISPATCHER.x;
101 #define BIND_VMA_PROC_KHR(x) \
102  proc_table.x##KHR = VULKAN_HPP_DEFAULT_DISPATCHER.x \
103  ? VULKAN_HPP_DEFAULT_DISPATCHER.x \
104  : VULKAN_HPP_DEFAULT_DISPATCHER.x##KHR;
105  BIND_VMA_PROC(vkGetInstanceProcAddr);
106  BIND_VMA_PROC(vkGetDeviceProcAddr);
107  BIND_VMA_PROC(vkGetPhysicalDeviceProperties);
108  BIND_VMA_PROC(vkGetPhysicalDeviceMemoryProperties);
109  BIND_VMA_PROC(vkAllocateMemory);
110  BIND_VMA_PROC(vkFreeMemory);
111  BIND_VMA_PROC(vkMapMemory);
112  BIND_VMA_PROC(vkUnmapMemory);
113  BIND_VMA_PROC(vkFlushMappedMemoryRanges);
114  BIND_VMA_PROC(vkInvalidateMappedMemoryRanges);
115  BIND_VMA_PROC(vkBindBufferMemory);
116  BIND_VMA_PROC(vkBindImageMemory);
117  BIND_VMA_PROC(vkGetBufferMemoryRequirements);
118  BIND_VMA_PROC(vkGetImageMemoryRequirements);
119  BIND_VMA_PROC(vkCreateBuffer);
120  BIND_VMA_PROC(vkDestroyBuffer);
121  BIND_VMA_PROC(vkCreateImage);
122  BIND_VMA_PROC(vkDestroyImage);
123  BIND_VMA_PROC(vkCmdCopyBuffer);
124  BIND_VMA_PROC_KHR(vkGetBufferMemoryRequirements2);
125  BIND_VMA_PROC_KHR(vkGetImageMemoryRequirements2);
126  BIND_VMA_PROC_KHR(vkBindBufferMemory2);
127  BIND_VMA_PROC_KHR(vkBindImageMemory2);
128  BIND_VMA_PROC_KHR(vkGetPhysicalDeviceMemoryProperties2);
129 #undef BIND_VMA_PROC_KHR
130 #undef BIND_VMA_PROC
131 
132  VmaAllocatorCreateInfo allocator_info = {};
133  allocator_info.vulkanApiVersion = vulkan_api_version;
134  allocator_info.physicalDevice = physical_device;
135  allocator_info.device = device_holder->GetDevice();
136  allocator_info.instance = instance;
137  allocator_info.pVulkanFunctions = &proc_table;
138 
139  VmaAllocator allocator = {};
140  auto result = vk::Result{::vmaCreateAllocator(&allocator_info, &allocator)};
141  if (result != vk::Result::eSuccess) {
142  VALIDATION_LOG << "Could not create memory allocator";
143  return;
144  }
145  staging_buffer_pool_.reset(CreateBufferPool(allocator));
146  created_buffer_pool_ &= staging_buffer_pool_.is_valid();
147  allocator_.reset(allocator);
148  supports_memoryless_textures_ =
149  capabilities.SupportsDeviceTransientTextures();
150  supports_framebuffer_fetch_ = capabilities.SupportsFramebufferFetch();
151  is_valid_ = true;
152 }
153 
154 AllocatorVK::~AllocatorVK() = default;
155 
156 // |Allocator|
157 bool AllocatorVK::IsValid() const {
158  return is_valid_;
159 }
160 
161 // |Allocator|
162 ISize AllocatorVK::GetMaxTextureSizeSupported() const {
163  return max_texture_size_;
164 }
165 
166 static constexpr vk::ImageUsageFlags ToVKImageUsageFlags(
167  PixelFormat format,
168  TextureUsageMask usage,
169  StorageMode mode,
170  bool supports_memoryless_textures,
171  bool supports_framebuffer_fetch) {
172  vk::ImageUsageFlags vk_usage;
173 
174  switch (mode) {
175  case StorageMode::kHostVisible:
176  case StorageMode::kDevicePrivate:
177  break;
178  case StorageMode::kDeviceTransient:
179  if (supports_memoryless_textures) {
180  vk_usage |= vk::ImageUsageFlagBits::eTransientAttachment;
181  }
182  break;
183  }
184 
185  if (usage & static_cast<TextureUsageMask>(TextureUsage::kRenderTarget)) {
186  if (PixelFormatIsDepthStencil(format)) {
187  vk_usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
188  } else {
189  vk_usage |= vk::ImageUsageFlagBits::eColorAttachment;
190  }
191  if (supports_framebuffer_fetch) {
192  vk_usage |= vk::ImageUsageFlagBits::eInputAttachment;
193  }
194  }
195 
196  if (usage & static_cast<TextureUsageMask>(TextureUsage::kShaderRead)) {
197  vk_usage |= vk::ImageUsageFlagBits::eSampled;
198  // Device transient images can only be used as attachments. The caller
199  // specified incorrect usage flags and is attempting to read a device
200  // transient image in a shader. Unset the transient attachment flag. See:
201  // https://github.com/flutter/flutter/issues/121633
202  if (mode == StorageMode::kDeviceTransient) {
203  vk_usage &= ~vk::ImageUsageFlagBits::eTransientAttachment;
204  }
205  }
206 
207  if (usage & static_cast<TextureUsageMask>(TextureUsage::kShaderWrite)) {
208  vk_usage |= vk::ImageUsageFlagBits::eStorage;
209  // Device transient images can only be used as attachments. The caller
210  // specified incorrect usage flags and is attempting to read a device
211  // transient image in a shader. Unset the transient attachment flag. See:
212  // https://github.com/flutter/flutter/issues/121633
213  if (mode == StorageMode::kDeviceTransient) {
214  vk_usage &= ~vk::ImageUsageFlagBits::eTransientAttachment;
215  }
216  }
217 
218  if (mode != StorageMode::kDeviceTransient) {
219  // Add transfer usage flags to support blit passes only if image isn't
220  // device transient.
221  vk_usage |= vk::ImageUsageFlagBits::eTransferSrc |
222  vk::ImageUsageFlagBits::eTransferDst;
223  }
224 
225  return vk_usage;
226 }
227 
228 static constexpr VmaMemoryUsage ToVMAMemoryUsage() {
229  return VMA_MEMORY_USAGE_AUTO;
230 }
231 
232 static constexpr vk::Flags<vk::MemoryPropertyFlagBits>
234  bool supports_memoryless_textures) {
235  switch (mode) {
236  case StorageMode::kHostVisible:
237  return vk::MemoryPropertyFlagBits::eHostVisible |
238  vk::MemoryPropertyFlagBits::eDeviceLocal;
239  case StorageMode::kDevicePrivate:
240  return vk::MemoryPropertyFlagBits::eDeviceLocal;
241  case StorageMode::kDeviceTransient:
242  if (supports_memoryless_textures) {
243  return vk::MemoryPropertyFlagBits::eLazilyAllocated |
244  vk::MemoryPropertyFlagBits::eDeviceLocal;
245  }
246  return vk::MemoryPropertyFlagBits::eDeviceLocal;
247  }
248  FML_UNREACHABLE();
249 }
250 
251 static VmaAllocationCreateFlags ToVmaAllocationCreateFlags(StorageMode mode) {
252  VmaAllocationCreateFlags flags = 0;
253  switch (mode) {
254  case StorageMode::kHostVisible:
255  return flags;
256  case StorageMode::kDevicePrivate:
257  return flags;
258  case StorageMode::kDeviceTransient:
259  return flags;
260  }
261  FML_UNREACHABLE();
262 }
263 
265  public:
266  AllocatedTextureSourceVK(std::weak_ptr<ResourceManagerVK> resource_manager,
267  const TextureDescriptor& desc,
268  VmaAllocator allocator,
269  vk::Device device,
270  bool supports_memoryless_textures,
271  bool supports_framebuffer_fetch)
272  : TextureSourceVK(desc), resource_(std::move(resource_manager)) {
273  FML_DCHECK(desc.format != PixelFormat::kUnknown);
274  vk::ImageCreateInfo image_info;
275  image_info.flags = ToVKImageCreateFlags(desc.type);
276  image_info.imageType = vk::ImageType::e2D;
277  image_info.format = ToVKImageFormat(desc.format);
278  image_info.extent = VkExtent3D{
279  static_cast<uint32_t>(desc.size.width), // width
280  static_cast<uint32_t>(desc.size.height), // height
281  1u // depth
282  };
283  image_info.samples = ToVKSampleCount(desc.sample_count);
284  image_info.mipLevels = desc.mip_count;
285  image_info.arrayLayers = ToArrayLayerCount(desc.type);
286  image_info.tiling = vk::ImageTiling::eOptimal;
287  image_info.initialLayout = vk::ImageLayout::eUndefined;
288  image_info.usage = ToVKImageUsageFlags(
289  desc.format, desc.usage, desc.storage_mode,
290  supports_memoryless_textures, supports_framebuffer_fetch);
291  image_info.sharingMode = vk::SharingMode::eExclusive;
292 
293  VmaAllocationCreateInfo alloc_nfo = {};
294 
295  alloc_nfo.usage = ToVMAMemoryUsage();
296  alloc_nfo.preferredFlags =
297  static_cast<VkMemoryPropertyFlags>(ToVKTextureMemoryPropertyFlags(
298  desc.storage_mode, supports_memoryless_textures));
299  alloc_nfo.flags = ToVmaAllocationCreateFlags(desc.storage_mode);
300 
301  auto create_info_native =
302  static_cast<vk::ImageCreateInfo::NativeType>(image_info);
303 
304  VkImage vk_image = VK_NULL_HANDLE;
305  VmaAllocation allocation = {};
306  VmaAllocationInfo allocation_info = {};
307  {
308  auto result = vk::Result{::vmaCreateImage(allocator, //
309  &create_info_native, //
310  &alloc_nfo, //
311  &vk_image, //
312  &allocation, //
313  &allocation_info //
314  )};
315  if (result != vk::Result::eSuccess) {
316  VALIDATION_LOG << "Unable to allocate Vulkan Image: "
317  << vk::to_string(result)
318  << " Type: " << TextureTypeToString(desc.type)
319  << " Mode: " << StorageModeToString(desc.storage_mode)
320  << " Usage: " << TextureUsageMaskToString(desc.usage)
321  << " [VK]Flags: " << vk::to_string(image_info.flags)
322  << " [VK]Format: " << vk::to_string(image_info.format)
323  << " [VK]Usage: " << vk::to_string(image_info.usage)
324  << " [VK]Mem. Flags: "
325  << vk::to_string(vk::MemoryPropertyFlags(
326  alloc_nfo.preferredFlags));
327  return;
328  }
329  }
330 
331  auto image = vk::Image{vk_image};
332 
333  vk::ImageViewCreateInfo view_info = {};
334  view_info.image = image;
335  view_info.viewType = ToVKImageViewType(desc.type);
336  view_info.format = image_info.format;
337  view_info.subresourceRange.aspectMask = ToVKImageAspectFlags(desc.format);
338  view_info.subresourceRange.levelCount = image_info.mipLevels;
339  view_info.subresourceRange.layerCount = ToArrayLayerCount(desc.type);
340 
341  // Vulkan does not have an image format that is equivalent to
342  // `MTLPixelFormatA8Unorm`, so we use `R8Unorm` instead. Given that the
343  // shaders expect that alpha channel to be set in the cases, we swizzle.
344  // See: https://github.com/flutter/flutter/issues/115461 for more details.
345  if (desc.format == PixelFormat::kA8UNormInt) {
346  view_info.components.a = vk::ComponentSwizzle::eR;
347  view_info.components.r = vk::ComponentSwizzle::eA;
348  }
349 
350  auto [result, image_view] = device.createImageViewUnique(view_info);
351  if (result != vk::Result::eSuccess) {
352  VALIDATION_LOG << "Unable to create an image view for allocation: "
353  << vk::to_string(result);
354  return;
355  }
356  resource_.Swap(ImageResource(ImageVMA{allocator, allocation, image},
357  std::move(image_view)));
358  is_valid_ = true;
359  }
360 
361  ~AllocatedTextureSourceVK() = default;
362 
363  bool IsValid() const { return is_valid_; }
364 
365  vk::Image GetImage() const override { return resource_->image.get().image; }
366 
367  vk::ImageView GetImageView() const override {
368  return resource_->image_view.get();
369  }
370 
371  private:
372  struct ImageResource {
373  UniqueImageVMA image;
374  vk::UniqueImageView image_view;
375 
376  ImageResource() = default;
377 
378  ImageResource(ImageVMA p_image, vk::UniqueImageView p_image_view)
379  : image(p_image), image_view(std::move(p_image_view)) {}
380 
381  ImageResource(ImageResource&& o) {
382  std::swap(image, o.image);
383  std::swap(image_view, o.image_view);
384  }
385 
386  ImageResource(const ImageResource&) = delete;
387 
388  ImageResource& operator=(const ImageResource&) = delete;
389  };
390 
391  UniqueResourceVKT<ImageResource> resource_;
392  bool is_valid_ = false;
393 
394  AllocatedTextureSourceVK(const AllocatedTextureSourceVK&) = delete;
395 
396  AllocatedTextureSourceVK& operator=(const AllocatedTextureSourceVK&) = delete;
397 };
398 
399 // |Allocator|
400 std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
401  const TextureDescriptor& desc) {
402  if (!IsValid()) {
403  return nullptr;
404  }
405  auto device_holder = device_holder_.lock();
406  if (!device_holder) {
407  return nullptr;
408  }
409  auto context = context_.lock();
410  if (!context) {
411  return nullptr;
412  }
413  auto source = std::make_shared<AllocatedTextureSourceVK>(
414  ContextVK::Cast(*context).GetResourceManager(), //
415  desc, //
416  allocator_.get(), //
417  device_holder->GetDevice(), //
418  supports_memoryless_textures_, //
419  supports_framebuffer_fetch_ //
420  );
421  if (!source->IsValid()) {
422  return nullptr;
423  }
424  return std::make_shared<TextureVK>(context_, std::move(source));
425 }
426 
427 void AllocatorVK::DidAcquireSurfaceFrame() {
428  frame_count_++;
429  raster_thread_id_ = std::this_thread::get_id();
430 }
431 
432 // |Allocator|
433 std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(
434  const DeviceBufferDescriptor& desc) {
435  vk::BufferCreateInfo buffer_info;
436  buffer_info.usage = vk::BufferUsageFlagBits::eVertexBuffer |
437  vk::BufferUsageFlagBits::eIndexBuffer |
438  vk::BufferUsageFlagBits::eUniformBuffer |
439  vk::BufferUsageFlagBits::eStorageBuffer |
440  vk::BufferUsageFlagBits::eTransferSrc |
441  vk::BufferUsageFlagBits::eTransferDst;
442  buffer_info.size = desc.size;
443  buffer_info.sharingMode = vk::SharingMode::eExclusive;
444  auto buffer_info_native =
445  static_cast<vk::BufferCreateInfo::NativeType>(buffer_info);
446 
447  VmaAllocationCreateInfo allocation_info = {};
448  allocation_info.usage = ToVMAMemoryUsage();
449  allocation_info.preferredFlags = static_cast<VkMemoryPropertyFlags>(
450  ToVKBufferMemoryPropertyFlags(desc.storage_mode));
451  allocation_info.flags = ToVmaAllocationBufferCreateFlags(desc.storage_mode);
452  if (created_buffer_pool_ && desc.storage_mode == StorageMode::kHostVisible &&
453  raster_thread_id_ == std::this_thread::get_id()) {
454  allocation_info.pool = staging_buffer_pool_.get().pool;
455  }
456 
457  VkBuffer buffer = {};
458  VmaAllocation buffer_allocation = {};
459  VmaAllocationInfo buffer_allocation_info = {};
460  auto result = vk::Result{::vmaCreateBuffer(allocator_.get(), //
461  &buffer_info_native, //
462  &allocation_info, //
463  &buffer, //
464  &buffer_allocation, //
465  &buffer_allocation_info //
466  )};
467 
468  if (result != vk::Result::eSuccess) {
469  VALIDATION_LOG << "Unable to allocate a device buffer: "
470  << vk::to_string(result);
471  return {};
472  }
473 
474  return std::make_shared<DeviceBufferVK>(
475  desc, //
476  context_, //
477  UniqueBufferVMA{BufferVMA{allocator_.get(), //
478  buffer_allocation, //
479  vk::Buffer{buffer}}}, //
480  buffer_allocation_info //
481  );
482 }
483 
484 } // namespace impeller
impeller::TextureSourceVK
Definition: texture_source_vk.h:22
impeller::ToVKSampleCount
constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count)
Definition: formats_vk.h:204
BIND_VMA_PROC_KHR
#define BIND_VMA_PROC_KHR(x)
allocator_vk.h
impeller::PixelFormatIsDepthStencil
constexpr bool PixelFormatIsDepthStencil(PixelFormat format)
Definition: formats_vk.h:373
impeller::AllocatedTextureSourceVK::GetImageView
vk::ImageView GetImageView() const override
Definition: allocator_vk.cc:367
impeller::TextureUsageMask
uint64_t TextureUsageMask
Definition: formats.h:295
impeller::ToVmaAllocationBufferCreateFlags
static VmaAllocationCreateFlags ToVmaAllocationBufferCreateFlags(StorageMode mode)
Definition: allocator_vk.cc:32
impeller::ToVKTextureMemoryPropertyFlags
static constexpr vk::Flags< vk::MemoryPropertyFlagBits > ToVKTextureMemoryPropertyFlags(StorageMode mode, bool supports_memoryless_textures)
Definition: allocator_vk.cc:233
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:40
impeller::ToArrayLayerCount
constexpr uint32_t ToArrayLayerCount(TextureType type)
Definition: formats_vk.h:594
formats.h
impeller::TextureDescriptor::mip_count
size_t mip_count
Definition: texture_descriptor.h:42
impeller::ToVKImageCreateFlags
constexpr vk::ImageCreateFlags ToVKImageCreateFlags(TextureType type)
Definition: formats_vk.h:622
impeller::PoolVMA
Definition: vma.h:37
impeller::AllocatedTextureSourceVK::AllocatedTextureSourceVK
AllocatedTextureSourceVK(std::weak_ptr< ResourceManagerVK > resource_manager, const TextureDescriptor &desc, VmaAllocator allocator, vk::Device device, bool supports_memoryless_textures, bool supports_framebuffer_fetch)
Definition: allocator_vk.cc:266
formats_vk.h
impeller::StorageMode::kHostVisible
@ kHostVisible
impeller::TextureDescriptor::sample_count
SampleCount sample_count
Definition: texture_descriptor.h:45
impeller::TextureDescriptor::usage
TextureUsageMask usage
Definition: texture_descriptor.h:43
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:94
impeller::TextureDescriptor::type
TextureType type
Definition: texture_descriptor.h:39
impeller::ImageVMA
Definition: vma.h:104
impeller::StorageMode::kDeviceTransient
@ kDeviceTransient
impeller::StorageMode
StorageMode
Specified where the allocation resides and how it is used.
Definition: formats.h:27
impeller::ToVKImageFormat
constexpr vk::Format ToVKImageFormat(PixelFormat format)
Definition: formats_vk.h:136
impeller::AllocatedTextureSourceVK::IsValid
bool IsValid() const
Definition: allocator_vk.cc:363
impeller::StorageMode::kDevicePrivate
@ kDevicePrivate
impeller::StorageModeToString
constexpr const char * StorageModeToString(StorageMode mode)
Definition: formats.h:55
BIND_VMA_PROC
#define BIND_VMA_PROC(x)
impeller::ToVKImageViewType
constexpr vk::ImageViewType ToVKImageViewType(TextureType type)
Definition: formats_vk.h:608
impeller::ToVKImageAspectFlags
constexpr vk::ImageAspectFlags ToVKImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:568
impeller::TSize::width
Type width
Definition: size.h:22
texture_vk.h
impeller::TextureUsageMaskToString
std::string TextureUsageMaskToString(TextureUsageMask mask)
Definition: formats.cc:81
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
impeller::ToVKImageUsageFlags
static constexpr vk::ImageUsageFlags ToVKImageUsageFlags(PixelFormat format, TextureUsageMask usage, StorageMode mode, bool supports_memoryless_textures, bool supports_framebuffer_fetch)
Definition: allocator_vk.cc:166
impeller::ToVMAMemoryUsage
static constexpr VmaMemoryUsage ToVMAMemoryUsage()
Definition: allocator_vk.cc:228
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
impeller::TextureTypeToString
constexpr const char * TextureTypeToString(TextureType type)
Definition: formats.h:264
std
Definition: comparable.h:95
device_buffer_vk.h
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:38
impeller::TSize::height
Type height
Definition: size.h:23
impeller::CreateBufferPool
static PoolVMA CreateBufferPool(VmaAllocator allocator)
Definition: allocator_vk.cc:48
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:37
impeller::AllocatedTextureSourceVK::GetImage
vk::Image GetImage() const override
Definition: allocator_vk.cc:365
impeller::UniqueBufferVMA
fml::UniqueObject< BufferVMA, BufferVMATraits > UniqueBufferVMA
Definition: vma.h:98
impeller::ToVKBufferMemoryPropertyFlags
static constexpr vk::Flags< vk::MemoryPropertyFlagBits > ToVKBufferMemoryPropertyFlags(StorageMode mode)
Definition: allocator_vk.cc:20
impeller::AllocatedTextureSourceVK
Definition: allocator_vk.cc:264
impeller
Definition: aiks_context.cc:10
impeller::ToVmaAllocationCreateFlags
static VmaAllocationCreateFlags ToVmaAllocationCreateFlags(StorageMode mode)
Definition: allocator_vk.cc:251
impeller::UniqueImageVMA
fml::UniqueObject< ImageVMA, ImageVMATraits > UniqueImageVMA
Definition: vma.h:133