| 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
9 #include "flutter/fml/memory/ref_ptr.h"
10 #include "flutter/fml/trace_event.h"
11 #include "impeller/core/formats.h"
12 #include "impeller/renderer/backend/vulkan/device_buffer_vk.h"
13 #include "impeller/renderer/backend/vulkan/formats_vk.h"
14 #include "impeller/renderer/backend/vulkan/texture_vk.h"
15 #include "vulkan/vulkan_enums.hpp"
16
17 namespace impeller {
18
19 static constexpr vk::Flags<vk::MemoryPropertyFlagBits>
20 ToVKBufferMemoryPropertyFlags(StorageMode mode) {
21 switch (mode) {
22 case StorageMode::kHostVisible:
23 return vk::MemoryPropertyFlagBits::eHostVisible;
24 case StorageMode::kDevicePrivate:
25 return vk::MemoryPropertyFlagBits::eDeviceLocal;
26 case StorageMode::kDeviceTransient:
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) {
36 case StorageMode::kHostVisible:
37 flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
38 flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
39 return flags;
40 case StorageMode::kDevicePrivate:
41 return flags;
42 case StorageMode::kDeviceTransient:
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>(
64 ToVKBufferMemoryPropertyFlags(StorageMode::kHostVisible));
65 allocation_info.flags =
66 ToVmaAllocationBufferCreateFlags(StorageMode::kHostVisible);
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>
233 ToVKTextureMemoryPropertyFlags(StorageMode mode,
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
264 class AllocatedTextureSourceVK final : public TextureSourceVK {
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