1616
1717namespace impeller {
1818
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+ VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;
79+
80+ VmaPool pool = {};
81+ result = vk::Result{::vmaCreatePool (allocator, &pool_create_info, &pool)};
82+ if (result != vk::Result::eSuccess) {
83+ return {};
84+ }
85+ return {allocator, pool};
86+ }
87+
1988AllocatorVK::AllocatorVK (std::weak_ptr<Context> context,
2089 uint32_t vulkan_api_version,
2190 const vk::PhysicalDevice& physical_device,
@@ -93,26 +162,16 @@ AllocatorVK::AllocatorVK(std::weak_ptr<Context> context,
93162 VALIDATION_LOG << " Could not create memory allocator" ;
94163 return ;
95164 }
96- for (auto i = 0u ; i < kPoolCount ; i++) {
97- created_buffer_pools_ &=
98- CreateBufferPool (allocator, & staging_buffer_pools_[i]);
165+ for (size_t i = 0u ; i < staging_buffer_pools_. size () ; i++) {
166+ staging_buffer_pools_[i]. reset ( CreateBufferPool (allocator));
167+ created_buffer_pools_ &= staging_buffer_pools_[i]. is_valid ( );
99168 }
100- allocator_ = allocator;
169+ allocator_. reset ( allocator) ;
101170 supports_memoryless_textures_ = capabilities.SupportsMemorylessTextures ();
102171 is_valid_ = true ;
103172}
104173
105- AllocatorVK::~AllocatorVK () {
106- TRACE_EVENT0 (" impeller" , " DestroyAllocatorVK" );
107- if (allocator_) {
108- for (auto i = 0u ; i < kPoolCount ; i++) {
109- if (staging_buffer_pools_[i]) {
110- ::vmaDestroyPool (allocator_, staging_buffer_pools_[i]);
111- }
112- }
113- ::vmaDestroyAllocator (allocator_);
114- }
115- }
174+ AllocatorVK::~AllocatorVK () = default ;
116175
117176// |Allocator|
118177bool AllocatorVK::IsValid () const {
@@ -206,35 +265,6 @@ ToVKTextureMemoryPropertyFlags(StorageMode mode,
206265 FML_UNREACHABLE ();
207266}
208267
209- static constexpr vk::Flags<vk::MemoryPropertyFlagBits>
210- ToVKBufferMemoryPropertyFlags (StorageMode mode) {
211- switch (mode) {
212- case StorageMode::kHostVisible :
213- return vk::MemoryPropertyFlagBits::eHostVisible;
214- case StorageMode::kDevicePrivate :
215- return vk::MemoryPropertyFlagBits::eDeviceLocal;
216- case StorageMode::kDeviceTransient :
217- return vk::MemoryPropertyFlagBits::eLazilyAllocated;
218- }
219- FML_UNREACHABLE ();
220- }
221-
222- static VmaAllocationCreateFlags ToVmaAllocationBufferCreateFlags (
223- StorageMode mode) {
224- VmaAllocationCreateFlags flags = 0 ;
225- switch (mode) {
226- case StorageMode::kHostVisible :
227- flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
228- flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
229- return flags;
230- case StorageMode::kDevicePrivate :
231- return flags;
232- case StorageMode::kDeviceTransient :
233- return flags;
234- }
235- FML_UNREACHABLE ();
236- }
237-
238268static VmaAllocationCreateFlags ToVmaAllocationCreateFlags (StorageMode mode,
239269 bool is_texture,
240270 size_t size) {
@@ -357,61 +387,36 @@ class AllocatedTextureSourceVK final : public TextureSourceVK {
357387 << vk::to_string (result);
358388 return ;
359389 }
360- resource_.Reset (
361- ImageResource (image, allocator, allocation, std::move (image_view)));
390+ resource_.Reset (ImageResource (ImageVMA{allocator, allocation, image},
391+ std::move (image_view)));
362392 is_valid_ = true ;
363393 }
364394
365395 ~AllocatedTextureSourceVK () = default ;
366396
367397 bool IsValid () const { return is_valid_; }
368398
369- vk::Image GetImage () const override { return resource_->image ; }
399+ vk::Image GetImage () const override { return resource_->image . get (). image ; }
370400
371401 vk::ImageView GetImageView () const override {
372402 return resource_->image_view .get ();
373403 }
374404
375405 private:
376406 struct ImageResource {
377- vk::Image image = {};
378- VmaAllocator allocator = {};
379- VmaAllocation allocation = {};
407+ UniqueImageVMA image;
380408 vk::UniqueImageView image_view;
381409
382410 ImageResource () = default ;
383411
384- ImageResource (vk::Image p_image,
385- VmaAllocator p_allocator,
386- VmaAllocation p_allocation,
387- vk::UniqueImageView p_image_view)
388- : image(p_image),
389- allocator (p_allocator),
390- allocation(p_allocation),
391- image_view(std::move(p_image_view)) {}
412+ ImageResource (ImageVMA p_image, vk::UniqueImageView p_image_view)
413+ : image(p_image), image_view(std::move(p_image_view)) {}
392414
393415 ImageResource (ImageResource&& o) {
394416 std::swap (image, o.image );
395- std::swap (allocator, o.allocator );
396- std::swap (allocation, o.allocation );
397417 std::swap (image_view, o.image_view );
398418 }
399419
400- ~ImageResource () {
401- if (!image) {
402- return ;
403- }
404- TRACE_EVENT0 (" impeller" , " DestroyDeviceTexture" );
405- image_view.reset ();
406- if (image) {
407- ::vmaDestroyImage (
408- allocator, //
409- static_cast <typename decltype (image)::NativeType>(image), //
410- allocation //
411- );
412- }
413- }
414-
415420 FML_DISALLOW_COPY_AND_ASSIGN (ImageResource);
416421 };
417422
@@ -439,7 +444,7 @@ std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
439444 auto source = std::make_shared<AllocatedTextureSourceVK>(
440445 ContextVK::Cast (*context).GetResourceManager (), //
441446 desc, //
442- allocator_, //
447+ allocator_. get (), //
443448 device_holder->GetDevice (), //
444449 supports_memoryless_textures_ //
445450 );
@@ -477,13 +482,16 @@ std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(
477482 allocation_info.flags = ToVmaAllocationBufferCreateFlags (desc.storage_mode );
478483 if (created_buffer_pools_ && desc.storage_mode == StorageMode::kHostVisible &&
479484 raster_thread_id_ == std::this_thread::get_id ()) {
480- allocation_info.pool = staging_buffer_pools_[frame_count_ % kPoolCount ];
485+ allocation_info.pool =
486+ staging_buffer_pools_[frame_count_ % staging_buffer_pools_.size ()]
487+ .get ()
488+ .pool ;
481489 }
482490
483491 VkBuffer buffer = {};
484492 VmaAllocation buffer_allocation = {};
485493 VmaAllocationInfo buffer_allocation_info = {};
486- auto result = vk::Result{::vmaCreateBuffer (allocator_, //
494+ auto result = vk::Result{::vmaCreateBuffer (allocator_. get (), //
487495 &buffer_info_native, //
488496 &allocation_info, //
489497 &buffer, //
@@ -497,53 +505,14 @@ std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(
497505 return {};
498506 }
499507
500- return std::make_shared<DeviceBufferVK>(desc, //
501- context_, //
502- allocator_, //
503- buffer_allocation, //
504- buffer_allocation_info, //
505- vk::Buffer{buffer} //
508+ return std::make_shared<DeviceBufferVK>(
509+ desc, //
510+ context_, //
511+ UniqueBufferVMA{BufferVMA{allocator_.get (), //
512+ buffer_allocation, //
513+ vk::Buffer{buffer}}}, //
514+ buffer_allocation_info //
506515 );
507516}
508517
509- // static
510- bool AllocatorVK::CreateBufferPool (VmaAllocator allocator, VmaPool* pool) {
511- vk::BufferCreateInfo buffer_info;
512- buffer_info.usage = vk::BufferUsageFlagBits::eVertexBuffer |
513- vk::BufferUsageFlagBits::eIndexBuffer |
514- vk::BufferUsageFlagBits::eUniformBuffer |
515- vk::BufferUsageFlagBits::eStorageBuffer |
516- vk::BufferUsageFlagBits::eTransferSrc |
517- vk::BufferUsageFlagBits::eTransferDst;
518- buffer_info.size = 1u ; // doesn't matter
519- buffer_info.sharingMode = vk::SharingMode::eExclusive;
520- auto buffer_info_native =
521- static_cast <vk::BufferCreateInfo::NativeType>(buffer_info);
522-
523- VmaAllocationCreateInfo allocation_info = {};
524- allocation_info.usage = VMA_MEMORY_USAGE_AUTO;
525- allocation_info.preferredFlags = static_cast <VkMemoryPropertyFlags>(
526- ToVKBufferMemoryPropertyFlags (StorageMode::kHostVisible ));
527- allocation_info.flags =
528- ToVmaAllocationBufferCreateFlags (StorageMode::kHostVisible );
529-
530- uint32_t memTypeIndex;
531- auto result = vk::Result{vmaFindMemoryTypeIndexForBufferInfo (
532- allocator, &buffer_info_native, &allocation_info, &memTypeIndex)};
533- if (result != vk::Result::eSuccess) {
534- return false ;
535- }
536-
537- VmaPoolCreateInfo pool_create_info = {};
538- pool_create_info.memoryTypeIndex = memTypeIndex;
539- pool_create_info.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT |
540- VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;
541-
542- result = vk::Result{vmaCreatePool (allocator, &pool_create_info, pool)};
543- if (result != vk::Result::eSuccess) {
544- return false ;
545- }
546- return true ;
547- }
548-
549518} // namespace impeller
0 commit comments