Flutter Engine
The Flutter Engine
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"
15#include "vulkan/vulkan_enums.hpp"
16
17namespace impeller {
18
19static constexpr vk::Flags<vk::MemoryPropertyFlagBits>
21 switch (mode) {
23 return vk::MemoryPropertyFlagBits::eHostVisible;
25 return vk::MemoryPropertyFlagBits::eDeviceLocal;
27 return vk::MemoryPropertyFlagBits::eLazilyAllocated;
28 }
30}
31
32static VmaAllocationCreateFlags ToVmaAllocationBufferCreateFlags(
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;
47 return flags;
50 return flags;
51 }
53}
54
55static 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
94AllocatorVK::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;
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
161AllocatorVK::~AllocatorVK() = default;
162
163// |Allocator|
164bool AllocatorVK::IsValid() const {
165 return is_valid_;
166}
167
168// |Allocator|
169ISize AllocatorVK::GetMaxTextureSizeSupported() const {
170 return max_texture_size_;
171}
172
173int32_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
199vk::ImageUsageFlags AllocatorVK::ToVKImageUsageFlags(
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) {
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
244static constexpr VmaMemoryUsage ToVMAMemoryUsage() {
245 return VMA_MEMORY_USAGE_AUTO;
246}
247
248static 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 }
265}
266
267static 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 }
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)) {
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 =
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: "
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: "
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
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 {
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|
433std::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|
460std::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: "
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
512size_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
526void 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
AutoreleasePool pool
static void readback(const SkBitmap &src, int *result, int resultCount)
Definition: BlurTest.cpp:264
int count
Definition: FontMgrTest.cpp:50
#define BIND_VMA_PROC_KHR(x)
#define BIND_VMA_PROC(x)
sk_sp< DlImage > image() const
Definition: image.h:42
const T & get() const
Definition: unique_object.h:87
vk::ImageView GetRenderTargetView() const override
Retrieve the image view used for render target attachments with this texture source.
vk::Image GetImage() const override
Get the image handle for this texture source.
vk::ImageView GetImageView() const override
Retrieve the image view used for sampling/blitting/compute with this texture source.
AllocatedTextureSourceVK(std::weak_ptr< ResourceManagerVK > resource_manager, const TextureDescriptor &desc, VmaAllocator allocator, vk::Device device, bool supports_memoryless_textures)
bool IsSwapchainImage() const override
Determines if swapchain image. That is, an image used as the root render target.
Abstract base class that represents a vkImage and an vkImageView.
VkPhysicalDevice physical_device
Definition: main.cc:51
VkDevice device
Definition: main.cc:53
VkInstance instance
Definition: main.cc:48
SkBitmap source
Definition: examples.cpp:28
FlutterSemanticsFlag flags
GAsyncResult * result
uint32_t uint32_t * format
#define FML_UNREACHABLE()
Definition: logging.h:109
#define FML_DCHECK(condition)
Definition: logging.h:103
sk_sp< const SkImage > image
Definition: SkRecords.h:269
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
CanvasImage Image
Definition: dart_ui.cc:55
static constexpr vk::Flags< vk::MemoryPropertyFlagBits > ToVKBufferMemoryPropertyFlags(StorageMode mode)
Definition: allocator_vk.cc:20
constexpr uint32_t ToArrayLayerCount(TextureType type)
Definition: formats_vk.h:516
static VmaAllocationCreateFlags ToVmaAllocationBufferCreateFlags(StorageMode mode, bool readback)
Definition: allocator_vk.cc:32
std::string TextureUsageMaskToString(TextureUsageMask mask)
Definition: formats.cc:81
StorageMode
Specified where the allocation resides and how it is used.
Definition: formats.h:32
static constexpr vk::Flags< vk::MemoryPropertyFlagBits > ToVKTextureMemoryPropertyFlags(StorageMode mode, bool supports_memoryless_textures)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
constexpr bool PixelFormatIsDepthStencil(PixelFormat format)
Definition: formats_vk.h:391
static constexpr VmaMemoryUsage ToVMAMemoryUsage()
constexpr vk::ImageViewType ToVKImageViewType(TextureType type)
Definition: formats_vk.h:530
constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count)
Definition: formats_vk.h:201
constexpr vk::Format ToVKImageFormat(PixelFormat format)
Definition: formats_vk.h:133
static VmaAllocationCreateFlags ToVmaAllocationCreateFlags(StorageMode mode)
static PoolVMA CreateBufferPool(VmaAllocator allocator)
Definition: allocator_vk.cc:55
constexpr const char * TextureTypeToString(TextureType type)
Definition: formats.h:269
ISize64 ISize
Definition: size.h:140
constexpr const char * StorageModeToString(StorageMode mode)
Definition: formats.h:60
constexpr vk::ImageCreateFlags ToVKImageCreateFlags(TextureType type)
Definition: formats_vk.h:544
constexpr vk::ImageAspectFlags ToVKImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:490
fml::UniqueObject< BufferVMA, BufferVMATraits > UniqueBufferVMA
Definition: vma.h:98
Definition: ref_ptr.h:256
static SkString to_string(int n)
Definition: nanobench.cpp:119
static void usage(char *argv0)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
#define FML_TRACE_COUNTER(category_group, name, counter_id, arg1,...)
Definition: trace_event.h:85
#define VALIDATION_LOG
Definition: validation.h:73
VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset)
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)
VkFlags VkMemoryPropertyFlags
Definition: vulkan_core.h:2410
VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory)
VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements)
VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements)
VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator)
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *pName)
VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage)
VKAPI_ATTR void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator)
VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2 *pInfo, VkMemoryRequirements2 *pMemoryRequirements)
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties)
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties)
VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy *pRegions)
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer)
VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData)
VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges)
VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory memory)
VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2(VkDevice device, const VkBufferMemoryRequirementsInfo2 *pInfo, VkMemoryRequirements2 *pMemoryRequirements)
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges)
VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo *pBindInfos)
VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator)
VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo *pBindInfos)
VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset)