diff options
| author | 2023-05-24 22:39:58 +0300 | |
|---|---|---|
| committer | 2023-06-18 12:45:18 +0300 | |
| commit | 48e39756f1ec6e6b0ef48f2444ce38a4e861e898 (patch) | |
| tree | 223a51e03aa6da0df85d3a698630ae37315db257 /src/video_core/vulkan_common | |
| parent | memory_allocator: Remove OpenGL interop (diff) | |
| download | yuzu-48e39756f1ec6e6b0ef48f2444ce38a4e861e898.tar.gz yuzu-48e39756f1ec6e6b0ef48f2444ce38a4e861e898.tar.xz yuzu-48e39756f1ec6e6b0ef48f2444ce38a4e861e898.zip | |
renderer_vulkan: Use VMA for images
Diffstat (limited to 'src/video_core/vulkan_common')
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 5 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 30 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_memory_allocator.h | 5 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 28 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 70 |
5 files changed, 100 insertions, 38 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 123d3b1c4..9936f5658 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -210,6 +210,11 @@ public: | |||
| 210 | return dld; | 210 | return dld; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /// Returns the VMA allocator. | ||
| 214 | VmaAllocator GetAllocator() const { | ||
| 215 | return allocator; | ||
| 216 | } | ||
| 217 | |||
| 213 | /// Returns the logical device. | 218 | /// Returns the logical device. |
| 214 | const vk::Device& GetLogical() const { | 219 | const vk::Device& GetLogical() const { |
| 215 | return logical; | 220 | return logical; |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index f87c99603..7f860cccd 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp | |||
| @@ -15,6 +15,10 @@ | |||
| 15 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" | 15 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" |
| 16 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 16 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 17 | 17 | ||
| 18 | #define VMA_STATIC_VULKAN_FUNCTIONS 0 | ||
| 19 | #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 | ||
| 20 | #include <vk_mem_alloc.h> | ||
| 21 | |||
| 18 | namespace Vulkan { | 22 | namespace Vulkan { |
| 19 | namespace { | 23 | namespace { |
| 20 | struct Range { | 24 | struct Range { |
| @@ -180,6 +184,24 @@ MemoryAllocator::MemoryAllocator(const Device& device_) | |||
| 180 | 184 | ||
| 181 | MemoryAllocator::~MemoryAllocator() = default; | 185 | MemoryAllocator::~MemoryAllocator() = default; |
| 182 | 186 | ||
| 187 | vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo& ci) const { | ||
| 188 | const VmaAllocationCreateInfo alloc_info = { | ||
| 189 | .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT, | ||
| 190 | .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, | ||
| 191 | .requiredFlags = 0, | ||
| 192 | .preferredFlags = 0, | ||
| 193 | .pool = VK_NULL_HANDLE, | ||
| 194 | .pUserData = nullptr, | ||
| 195 | }; | ||
| 196 | |||
| 197 | VkImage handle{}; | ||
| 198 | VmaAllocation allocation{}; | ||
| 199 | vk::Check( | ||
| 200 | vmaCreateImage(device.GetAllocator(), &ci, &alloc_info, &handle, &allocation, nullptr)); | ||
| 201 | return vk::Image(handle, *device.GetLogical(), device.GetAllocator(), allocation, | ||
| 202 | device.GetDispatchLoader()); | ||
| 203 | } | ||
| 204 | |||
| 183 | MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) { | 205 | MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) { |
| 184 | // Find the fastest memory flags we can afford with the current requirements | 206 | // Find the fastest memory flags we can afford with the current requirements |
| 185 | const u32 type_mask = requirements.memoryTypeBits; | 207 | const u32 type_mask = requirements.memoryTypeBits; |
| @@ -205,14 +227,6 @@ MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage | |||
| 205 | return commit; | 227 | return commit; |
| 206 | } | 228 | } |
| 207 | 229 | ||
| 208 | MemoryCommit MemoryAllocator::Commit(const vk::Image& image, MemoryUsage usage) { | ||
| 209 | VkMemoryRequirements requirements = device.GetLogical().GetImageMemoryRequirements(*image); | ||
| 210 | requirements.size = Common::AlignUp(requirements.size, buffer_image_granularity); | ||
| 211 | auto commit = Commit(requirements, usage); | ||
| 212 | image.BindMemory(commit.Memory(), commit.Offset()); | ||
| 213 | return commit; | ||
| 214 | } | ||
| 215 | |||
| 216 | bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size) { | 230 | bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size) { |
| 217 | const u32 type = FindType(flags, type_mask).value(); | 231 | const u32 type = FindType(flags, type_mask).value(); |
| 218 | vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({ | 232 | vk::DeviceMemory memory = device.GetLogical().TryAllocateMemory({ |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index 494f30f51..f9ee53cfb 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h | |||
| @@ -80,6 +80,8 @@ public: | |||
| 80 | MemoryAllocator& operator=(const MemoryAllocator&) = delete; | 80 | MemoryAllocator& operator=(const MemoryAllocator&) = delete; |
| 81 | MemoryAllocator(const MemoryAllocator&) = delete; | 81 | MemoryAllocator(const MemoryAllocator&) = delete; |
| 82 | 82 | ||
| 83 | vk::Image CreateImage(const VkImageCreateInfo& ci) const; | ||
| 84 | |||
| 83 | /** | 85 | /** |
| 84 | * Commits a memory with the specified requirements. | 86 | * Commits a memory with the specified requirements. |
| 85 | * | 87 | * |
| @@ -93,9 +95,6 @@ public: | |||
| 93 | /// Commits memory required by the buffer and binds it. | 95 | /// Commits memory required by the buffer and binds it. |
| 94 | MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage); | 96 | MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage); |
| 95 | 97 | ||
| 96 | /// Commits memory required by the image and binds it. | ||
| 97 | MemoryCommit Commit(const vk::Image& image, MemoryUsage usage); | ||
| 98 | |||
| 99 | private: | 98 | private: |
| 100 | /// Tries to allocate a chunk of memory. | 99 | /// Tries to allocate a chunk of memory. |
| 101 | bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size); | 100 | bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size); |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 336f53700..5d088dc58 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | 12 | ||
| 13 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 13 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 14 | 14 | ||
| 15 | #define VMA_STATIC_VULKAN_FUNCTIONS 0 | ||
| 16 | #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 | ||
| 17 | #include <vk_mem_alloc.h> | ||
| 18 | |||
| 15 | namespace Vulkan::vk { | 19 | namespace Vulkan::vk { |
| 16 | 20 | ||
| 17 | namespace { | 21 | namespace { |
| @@ -547,6 +551,16 @@ DebugUtilsMessenger Instance::CreateDebugUtilsMessenger( | |||
| 547 | return DebugUtilsMessenger(object, handle, *dld); | 551 | return DebugUtilsMessenger(object, handle, *dld); |
| 548 | } | 552 | } |
| 549 | 553 | ||
| 554 | void Image::SetObjectNameEXT(const char* name) const { | ||
| 555 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name); | ||
| 556 | } | ||
| 557 | |||
| 558 | void Image::Release() const noexcept { | ||
| 559 | if (handle) { | ||
| 560 | vmaDestroyImage(allocator, handle, allocation); | ||
| 561 | } | ||
| 562 | } | ||
| 563 | |||
| 550 | void Buffer::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const { | 564 | void Buffer::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const { |
| 551 | Check(dld->vkBindBufferMemory(owner, handle, memory, offset)); | 565 | Check(dld->vkBindBufferMemory(owner, handle, memory, offset)); |
| 552 | } | 566 | } |
| @@ -559,14 +573,6 @@ void BufferView::SetObjectNameEXT(const char* name) const { | |||
| 559 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER_VIEW, name); | 573 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_BUFFER_VIEW, name); |
| 560 | } | 574 | } |
| 561 | 575 | ||
| 562 | void Image::BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const { | ||
| 563 | Check(dld->vkBindImageMemory(owner, handle, memory, offset)); | ||
| 564 | } | ||
| 565 | |||
| 566 | void Image::SetObjectNameEXT(const char* name) const { | ||
| 567 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name); | ||
| 568 | } | ||
| 569 | |||
| 570 | void ImageView::SetObjectNameEXT(const char* name) const { | 576 | void ImageView::SetObjectNameEXT(const char* name) const { |
| 571 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE_VIEW, name); | 577 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE_VIEW, name); |
| 572 | } | 578 | } |
| @@ -713,12 +719,6 @@ BufferView Device::CreateBufferView(const VkBufferViewCreateInfo& ci) const { | |||
| 713 | return BufferView(object, handle, *dld); | 719 | return BufferView(object, handle, *dld); |
| 714 | } | 720 | } |
| 715 | 721 | ||
| 716 | Image Device::CreateImage(const VkImageCreateInfo& ci) const { | ||
| 717 | VkImage object; | ||
| 718 | Check(dld->vkCreateImage(handle, &ci, nullptr, &object)); | ||
| 719 | return Image(object, handle, *dld); | ||
| 720 | } | ||
| 721 | |||
| 722 | ImageView Device::CreateImageView(const VkImageViewCreateInfo& ci) const { | 722 | ImageView Device::CreateImageView(const VkImageViewCreateInfo& ci) const { |
| 723 | VkImageView object; | 723 | VkImageView object; |
| 724 | Check(dld->vkCreateImageView(handle, &ci, nullptr, &object)); | 724 | Check(dld->vkCreateImageView(handle, &ci, nullptr, &object)); |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 4ff328a21..8ec708774 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -32,6 +32,9 @@ | |||
| 32 | #pragma warning(disable : 26812) // Disable prefer enum class over enum | 32 | #pragma warning(disable : 26812) // Disable prefer enum class over enum |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | VK_DEFINE_HANDLE(VmaAllocator) | ||
| 36 | VK_DEFINE_HANDLE(VmaAllocation) | ||
| 37 | |||
| 35 | namespace Vulkan::vk { | 38 | namespace Vulkan::vk { |
| 36 | 39 | ||
| 37 | /** | 40 | /** |
| @@ -616,6 +619,60 @@ public: | |||
| 616 | } | 619 | } |
| 617 | }; | 620 | }; |
| 618 | 621 | ||
| 622 | class Image { | ||
| 623 | public: | ||
| 624 | explicit Image(VkImage handle_, VkDevice owner_, VmaAllocator allocator_, | ||
| 625 | VmaAllocation allocation_, const DeviceDispatch& dld_) noexcept | ||
| 626 | : handle{handle_}, owner{owner_}, allocator{allocator_}, | ||
| 627 | allocation{allocation_}, dld{&dld_} {} | ||
| 628 | Image() = default; | ||
| 629 | |||
| 630 | Image(const Image&) = delete; | ||
| 631 | Image& operator=(const Image&) = delete; | ||
| 632 | |||
| 633 | Image(Image&& rhs) noexcept | ||
| 634 | : handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, allocator{rhs.allocator}, | ||
| 635 | allocation{rhs.allocation}, dld{rhs.dld} {} | ||
| 636 | |||
| 637 | Image& operator=(Image&& rhs) noexcept { | ||
| 638 | Release(); | ||
| 639 | handle = std::exchange(rhs.handle, nullptr); | ||
| 640 | owner = rhs.owner; | ||
| 641 | allocator = rhs.allocator; | ||
| 642 | allocation = rhs.allocation; | ||
| 643 | dld = rhs.dld; | ||
| 644 | return *this; | ||
| 645 | } | ||
| 646 | |||
| 647 | ~Image() noexcept { | ||
| 648 | Release(); | ||
| 649 | } | ||
| 650 | |||
| 651 | VkImage operator*() const noexcept { | ||
| 652 | return handle; | ||
| 653 | } | ||
| 654 | |||
| 655 | void reset() noexcept { | ||
| 656 | Release(); | ||
| 657 | handle = nullptr; | ||
| 658 | } | ||
| 659 | |||
| 660 | explicit operator bool() const noexcept { | ||
| 661 | return handle != nullptr; | ||
| 662 | } | ||
| 663 | |||
| 664 | void SetObjectNameEXT(const char* name) const; | ||
| 665 | |||
| 666 | private: | ||
| 667 | void Release() const noexcept; | ||
| 668 | |||
| 669 | VkImage handle = nullptr; | ||
| 670 | VkDevice owner = nullptr; | ||
| 671 | VmaAllocator allocator = nullptr; | ||
| 672 | VmaAllocation allocation = nullptr; | ||
| 673 | const DeviceDispatch* dld = nullptr; | ||
| 674 | }; | ||
| 675 | |||
| 619 | class Queue { | 676 | class Queue { |
| 620 | public: | 677 | public: |
| 621 | /// Construct an empty queue handle. | 678 | /// Construct an empty queue handle. |
| @@ -658,17 +715,6 @@ public: | |||
| 658 | void SetObjectNameEXT(const char* name) const; | 715 | void SetObjectNameEXT(const char* name) const; |
| 659 | }; | 716 | }; |
| 660 | 717 | ||
| 661 | class Image : public Handle<VkImage, VkDevice, DeviceDispatch> { | ||
| 662 | using Handle<VkImage, VkDevice, DeviceDispatch>::Handle; | ||
| 663 | |||
| 664 | public: | ||
| 665 | /// Attaches a memory allocation. | ||
| 666 | void BindMemory(VkDeviceMemory memory, VkDeviceSize offset) const; | ||
| 667 | |||
| 668 | /// Set object name. | ||
| 669 | void SetObjectNameEXT(const char* name) const; | ||
| 670 | }; | ||
| 671 | |||
| 672 | class ImageView : public Handle<VkImageView, VkDevice, DeviceDispatch> { | 718 | class ImageView : public Handle<VkImageView, VkDevice, DeviceDispatch> { |
| 673 | using Handle<VkImageView, VkDevice, DeviceDispatch>::Handle; | 719 | using Handle<VkImageView, VkDevice, DeviceDispatch>::Handle; |
| 674 | 720 | ||
| @@ -844,8 +890,6 @@ public: | |||
| 844 | 890 | ||
| 845 | BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const; | 891 | BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const; |
| 846 | 892 | ||
| 847 | Image CreateImage(const VkImageCreateInfo& ci) const; | ||
| 848 | |||
| 849 | ImageView CreateImageView(const VkImageViewCreateInfo& ci) const; | 893 | ImageView CreateImageView(const VkImageViewCreateInfo& ci) const; |
| 850 | 894 | ||
| 851 | Semaphore CreateSemaphore() const; | 895 | Semaphore CreateSemaphore() const; |