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