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