diff options
Diffstat (limited to 'src')
9 files changed, 86 insertions, 45 deletions
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index f06af06c8..3e3b895e0 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -657,7 +657,7 @@ void VKBlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuff | |||
| 657 | }; | 657 | }; |
| 658 | 658 | ||
| 659 | buffer = device.GetLogical().CreateBuffer(ci); | 659 | buffer = device.GetLogical().CreateBuffer(ci); |
| 660 | buffer_commit = memory_allocator.Commit(buffer, true); | 660 | buffer_commit = memory_allocator.Commit(buffer, MemoryUsage::Upload); |
| 661 | } | 661 | } |
| 662 | 662 | ||
| 663 | void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) { | 663 | void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) { |
| @@ -688,7 +688,7 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) | |||
| 688 | .pQueueFamilyIndices = nullptr, | 688 | .pQueueFamilyIndices = nullptr, |
| 689 | .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, | 689 | .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, |
| 690 | }); | 690 | }); |
| 691 | raw_buffer_commits[i] = memory_allocator.Commit(raw_images[i], false); | 691 | raw_buffer_commits[i] = memory_allocator.Commit(raw_images[i], MemoryUsage::DeviceLocal); |
| 692 | raw_image_views[i] = device.GetLogical().CreateImageView(VkImageViewCreateInfo{ | 692 | raw_image_views[i] = device.GetLogical().CreateImageView(VkImageViewCreateInfo{ |
| 693 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, | 693 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
| 694 | .pNext = nullptr, | 694 | .pNext = nullptr, |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 94d3a9134..d8ad40a0f 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -50,13 +50,13 @@ Buffer::Buffer(const Device& device_, MemoryAllocator& memory_allocator, VKSched | |||
| 50 | .queueFamilyIndexCount = 0, | 50 | .queueFamilyIndexCount = 0, |
| 51 | .pQueueFamilyIndices = nullptr, | 51 | .pQueueFamilyIndices = nullptr, |
| 52 | }); | 52 | }); |
| 53 | commit = memory_allocator.Commit(buffer, false); | 53 | commit = memory_allocator.Commit(buffer, MemoryUsage::DeviceLocal); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | Buffer::~Buffer() = default; | 56 | Buffer::~Buffer() = default; |
| 57 | 57 | ||
| 58 | void Buffer::Upload(std::size_t offset, std::size_t data_size, const u8* data) { | 58 | void Buffer::Upload(std::size_t offset, std::size_t data_size, const u8* data) { |
| 59 | const auto& staging = staging_pool.Request(data_size, true); | 59 | const auto& staging = staging_pool.Request(data_size, MemoryUsage::Upload); |
| 60 | std::memcpy(staging.mapped_span.data(), data, data_size); | 60 | std::memcpy(staging.mapped_span.data(), data, data_size); |
| 61 | 61 | ||
| 62 | scheduler.RequestOutsideRenderPassOperationContext(); | 62 | scheduler.RequestOutsideRenderPassOperationContext(); |
| @@ -98,7 +98,7 @@ void Buffer::Upload(std::size_t offset, std::size_t data_size, const u8* data) { | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | void Buffer::Download(std::size_t offset, std::size_t data_size, u8* data) { | 100 | void Buffer::Download(std::size_t offset, std::size_t data_size, u8* data) { |
| 101 | auto staging = staging_pool.Request(data_size, true); | 101 | auto staging = staging_pool.Request(data_size, MemoryUsage::Download); |
| 102 | scheduler.RequestOutsideRenderPassOperationContext(); | 102 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 103 | 103 | ||
| 104 | const VkBuffer handle = Handle(); | 104 | const VkBuffer handle = Handle(); |
| @@ -179,7 +179,7 @@ std::shared_ptr<Buffer> VKBufferCache::CreateBlock(VAddr cpu_addr, std::size_t s | |||
| 179 | 179 | ||
| 180 | VKBufferCache::BufferInfo VKBufferCache::GetEmptyBuffer(std::size_t size) { | 180 | VKBufferCache::BufferInfo VKBufferCache::GetEmptyBuffer(std::size_t size) { |
| 181 | size = std::max(size, std::size_t(4)); | 181 | size = std::max(size, std::size_t(4)); |
| 182 | const auto& empty = staging_pool.Request(size, false); | 182 | const auto& empty = staging_pool.Request(size, MemoryUsage::DeviceLocal); |
| 183 | scheduler.RequestOutsideRenderPassOperationContext(); | 183 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 184 | scheduler.Record([size, buffer = empty.buffer](vk::CommandBuffer cmdbuf) { | 184 | scheduler.Record([size, buffer = empty.buffer](vk::CommandBuffer cmdbuf) { |
| 185 | cmdbuf.FillBuffer(buffer, 0, size, 0); | 185 | cmdbuf.FillBuffer(buffer, 0, size, 0); |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index d38087f41..5eb6a54be 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp | |||
| @@ -177,7 +177,7 @@ QuadArrayPass::~QuadArrayPass() = default; | |||
| 177 | std::pair<VkBuffer, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) { | 177 | std::pair<VkBuffer, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) { |
| 178 | const u32 num_triangle_vertices = (num_vertices / 4) * 6; | 178 | const u32 num_triangle_vertices = (num_vertices / 4) * 6; |
| 179 | const std::size_t staging_size = num_triangle_vertices * sizeof(u32); | 179 | const std::size_t staging_size = num_triangle_vertices * sizeof(u32); |
| 180 | const auto staging_ref = staging_buffer_pool.Request(staging_size, false); | 180 | const auto staging_ref = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal); |
| 181 | 181 | ||
| 182 | update_descriptor_queue.Acquire(); | 182 | update_descriptor_queue.Acquire(); |
| 183 | update_descriptor_queue.AddBuffer(staging_ref.buffer, 0, staging_size); | 183 | update_descriptor_queue.AddBuffer(staging_ref.buffer, 0, staging_size); |
| @@ -224,7 +224,7 @@ Uint8Pass::~Uint8Pass() = default; | |||
| 224 | std::pair<VkBuffer, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buffer, | 224 | std::pair<VkBuffer, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buffer, |
| 225 | u64 src_offset) { | 225 | u64 src_offset) { |
| 226 | const u32 staging_size = static_cast<u32>(num_vertices * sizeof(u16)); | 226 | const u32 staging_size = static_cast<u32>(num_vertices * sizeof(u16)); |
| 227 | const auto staging_ref = staging_buffer_pool.Request(staging_size, false); | 227 | const auto staging_ref = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal); |
| 228 | 228 | ||
| 229 | update_descriptor_queue.Acquire(); | 229 | update_descriptor_queue.Acquire(); |
| 230 | update_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices); | 230 | update_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices); |
| @@ -286,7 +286,7 @@ std::pair<VkBuffer, u64> QuadIndexedPass::Assemble( | |||
| 286 | const u32 num_tri_vertices = (num_vertices / 4) * 6; | 286 | const u32 num_tri_vertices = (num_vertices / 4) * 6; |
| 287 | 287 | ||
| 288 | const std::size_t staging_size = num_tri_vertices * sizeof(u32); | 288 | const std::size_t staging_size = num_tri_vertices * sizeof(u32); |
| 289 | const auto staging_ref = staging_buffer_pool.Request(staging_size, false); | 289 | const auto staging_ref = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal); |
| 290 | 290 | ||
| 291 | update_descriptor_queue.Acquire(); | 291 | update_descriptor_queue.Acquire(); |
| 292 | update_descriptor_queue.AddBuffer(src_buffer, src_offset, input_size); | 292 | update_descriptor_queue.AddBuffer(src_buffer, src_offset, input_size); |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index f38ead9c2..f0a111829 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -1445,7 +1445,7 @@ VkBuffer RasterizerVulkan::DefaultBuffer() { | |||
| 1445 | .queueFamilyIndexCount = 0, | 1445 | .queueFamilyIndexCount = 0, |
| 1446 | .pQueueFamilyIndices = nullptr, | 1446 | .pQueueFamilyIndices = nullptr, |
| 1447 | }); | 1447 | }); |
| 1448 | default_buffer_commit = memory_allocator.Commit(default_buffer, false); | 1448 | default_buffer_commit = memory_allocator.Commit(default_buffer, MemoryUsage::DeviceLocal); |
| 1449 | 1449 | ||
| 1450 | scheduler.RequestOutsideRenderPassOperationContext(); | 1450 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 1451 | scheduler.Record([buffer = *default_buffer](vk::CommandBuffer cmdbuf) { | 1451 | scheduler.Record([buffer = *default_buffer](vk::CommandBuffer cmdbuf) { |
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 44d332ed2..97fd41cc1 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | #include <fmt/format.h> | 9 | #include <fmt/format.h> |
| 10 | 10 | ||
| 11 | #include "common/assert.h" | ||
| 11 | #include "common/bit_util.h" | 12 | #include "common/bit_util.h" |
| 12 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 13 | #include "video_core/renderer_vulkan/vk_scheduler.h" | 14 | #include "video_core/renderer_vulkan/vk_scheduler.h" |
| @@ -23,23 +24,24 @@ StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& mem | |||
| 23 | 24 | ||
| 24 | StagingBufferPool::~StagingBufferPool() = default; | 25 | StagingBufferPool::~StagingBufferPool() = default; |
| 25 | 26 | ||
| 26 | StagingBufferRef StagingBufferPool::Request(size_t size, bool host_visible) { | 27 | StagingBufferRef StagingBufferPool::Request(size_t size, MemoryUsage usage) { |
| 27 | if (const std::optional<StagingBufferRef> ref = TryGetReservedBuffer(size, host_visible)) { | 28 | if (const std::optional<StagingBufferRef> ref = TryGetReservedBuffer(size, usage)) { |
| 28 | return *ref; | 29 | return *ref; |
| 29 | } | 30 | } |
| 30 | return CreateStagingBuffer(size, host_visible); | 31 | return CreateStagingBuffer(size, usage); |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | void StagingBufferPool::TickFrame() { | 34 | void StagingBufferPool::TickFrame() { |
| 34 | current_delete_level = (current_delete_level + 1) % NUM_LEVELS; | 35 | current_delete_level = (current_delete_level + 1) % NUM_LEVELS; |
| 35 | 36 | ||
| 36 | ReleaseCache(true); | 37 | ReleaseCache(MemoryUsage::DeviceLocal); |
| 37 | ReleaseCache(false); | 38 | ReleaseCache(MemoryUsage::Upload); |
| 39 | ReleaseCache(MemoryUsage::Download); | ||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | std::optional<StagingBufferRef> StagingBufferPool::TryGetReservedBuffer(size_t size, | 42 | std::optional<StagingBufferRef> StagingBufferPool::TryGetReservedBuffer(size_t size, |
| 41 | bool host_visible) { | 43 | MemoryUsage usage) { |
| 42 | StagingBuffers& cache_level = GetCache(host_visible)[Common::Log2Ceil64(size)]; | 44 | StagingBuffers& cache_level = GetCache(usage)[Common::Log2Ceil64(size)]; |
| 43 | 45 | ||
| 44 | const auto is_free = [this](const StagingBuffer& entry) { | 46 | const auto is_free = [this](const StagingBuffer& entry) { |
| 45 | return scheduler.IsFree(entry.tick); | 47 | return scheduler.IsFree(entry.tick); |
| @@ -58,7 +60,7 @@ std::optional<StagingBufferRef> StagingBufferPool::TryGetReservedBuffer(size_t s | |||
| 58 | return it->Ref(); | 60 | return it->Ref(); |
| 59 | } | 61 | } |
| 60 | 62 | ||
| 61 | StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, bool host_visible) { | 63 | StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, MemoryUsage usage) { |
| 62 | const u32 log2 = Common::Log2Ceil64(size); | 64 | const u32 log2 = Common::Log2Ceil64(size); |
| 63 | vk::Buffer buffer = device.GetLogical().CreateBuffer({ | 65 | vk::Buffer buffer = device.GetLogical().CreateBuffer({ |
| 64 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, | 66 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, |
| @@ -76,10 +78,10 @@ StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, bool host_v | |||
| 76 | ++buffer_index; | 78 | ++buffer_index; |
| 77 | buffer.SetObjectNameEXT(fmt::format("Staging Buffer {}", buffer_index).c_str()); | 79 | buffer.SetObjectNameEXT(fmt::format("Staging Buffer {}", buffer_index).c_str()); |
| 78 | } | 80 | } |
| 79 | MemoryCommit commit = memory_allocator.Commit(buffer, host_visible); | 81 | MemoryCommit commit = memory_allocator.Commit(buffer, usage); |
| 80 | const std::span<u8> mapped_span = host_visible ? commit.Map() : std::span<u8>{}; | 82 | const std::span<u8> mapped_span = IsHostVisible(usage) ? commit.Map() : std::span<u8>{}; |
| 81 | 83 | ||
| 82 | StagingBuffer& entry = GetCache(host_visible)[log2].entries.emplace_back(StagingBuffer{ | 84 | StagingBuffer& entry = GetCache(usage)[log2].entries.emplace_back(StagingBuffer{ |
| 83 | .buffer = std::move(buffer), | 85 | .buffer = std::move(buffer), |
| 84 | .commit = std::move(commit), | 86 | .commit = std::move(commit), |
| 85 | .mapped_span = mapped_span, | 87 | .mapped_span = mapped_span, |
| @@ -88,12 +90,22 @@ StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, bool host_v | |||
| 88 | return entry.Ref(); | 90 | return entry.Ref(); |
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | StagingBufferPool::StagingBuffersCache& StagingBufferPool::GetCache(bool host_visible) { | 93 | StagingBufferPool::StagingBuffersCache& StagingBufferPool::GetCache(MemoryUsage usage) { |
| 92 | return host_visible ? host_staging_buffers : device_staging_buffers; | 94 | switch (usage) { |
| 95 | case MemoryUsage::DeviceLocal: | ||
| 96 | return device_local_cache; | ||
| 97 | case MemoryUsage::Upload: | ||
| 98 | return upload_cache; | ||
| 99 | case MemoryUsage::Download: | ||
| 100 | return download_cache; | ||
| 101 | default: | ||
| 102 | UNREACHABLE_MSG("Invalid memory usage={}", usage); | ||
| 103 | return upload_cache; | ||
| 104 | } | ||
| 93 | } | 105 | } |
| 94 | 106 | ||
| 95 | void StagingBufferPool::ReleaseCache(bool host_visible) { | 107 | void StagingBufferPool::ReleaseCache(MemoryUsage usage) { |
| 96 | ReleaseLevel(GetCache(host_visible), current_delete_level); | 108 | ReleaseLevel(GetCache(usage), current_delete_level); |
| 97 | } | 109 | } |
| 98 | 110 | ||
| 99 | void StagingBufferPool::ReleaseLevel(StagingBuffersCache& cache, size_t log2) { | 111 | void StagingBufferPool::ReleaseLevel(StagingBuffersCache& cache, size_t log2) { |
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h index 1a4338609..d42918a47 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h | |||
| @@ -28,7 +28,7 @@ public: | |||
| 28 | VKScheduler& scheduler); | 28 | VKScheduler& scheduler); |
| 29 | ~StagingBufferPool(); | 29 | ~StagingBufferPool(); |
| 30 | 30 | ||
| 31 | StagingBufferRef Request(size_t size, bool host_visible); | 31 | StagingBufferRef Request(size_t size, MemoryUsage usage); |
| 32 | 32 | ||
| 33 | void TickFrame(); | 33 | void TickFrame(); |
| 34 | 34 | ||
| @@ -56,13 +56,13 @@ private: | |||
| 56 | static constexpr size_t NUM_LEVELS = sizeof(size_t) * CHAR_BIT; | 56 | static constexpr size_t NUM_LEVELS = sizeof(size_t) * CHAR_BIT; |
| 57 | using StagingBuffersCache = std::array<StagingBuffers, NUM_LEVELS>; | 57 | using StagingBuffersCache = std::array<StagingBuffers, NUM_LEVELS>; |
| 58 | 58 | ||
| 59 | std::optional<StagingBufferRef> TryGetReservedBuffer(size_t size, bool host_visible); | 59 | std::optional<StagingBufferRef> TryGetReservedBuffer(size_t size, MemoryUsage usage); |
| 60 | 60 | ||
| 61 | StagingBufferRef CreateStagingBuffer(size_t size, bool host_visible); | 61 | StagingBufferRef CreateStagingBuffer(size_t size, MemoryUsage usage); |
| 62 | 62 | ||
| 63 | StagingBuffersCache& GetCache(bool host_visible); | 63 | StagingBuffersCache& GetCache(MemoryUsage usage); |
| 64 | 64 | ||
| 65 | void ReleaseCache(bool host_visible); | 65 | void ReleaseCache(MemoryUsage usage); |
| 66 | 66 | ||
| 67 | void ReleaseLevel(StagingBuffersCache& cache, size_t log2); | 67 | void ReleaseLevel(StagingBuffersCache& cache, size_t log2); |
| 68 | 68 | ||
| @@ -70,8 +70,9 @@ private: | |||
| 70 | MemoryAllocator& memory_allocator; | 70 | MemoryAllocator& memory_allocator; |
| 71 | VKScheduler& scheduler; | 71 | VKScheduler& scheduler; |
| 72 | 72 | ||
| 73 | StagingBuffersCache host_staging_buffers; | 73 | StagingBuffersCache device_local_cache; |
| 74 | StagingBuffersCache device_staging_buffers; | 74 | StagingBuffersCache upload_cache; |
| 75 | StagingBuffersCache download_cache; | ||
| 75 | 76 | ||
| 76 | size_t current_delete_level = 0; | 77 | size_t current_delete_level = 0; |
| 77 | u64 buffer_index = 0; | 78 | u64 buffer_index = 0; |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 15cd50c24..a55f84045 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -554,7 +554,7 @@ void TextureCacheRuntime::Finish() { | |||
| 554 | } | 554 | } |
| 555 | 555 | ||
| 556 | ImageBufferMap TextureCacheRuntime::MapUploadBuffer(size_t size) { | 556 | ImageBufferMap TextureCacheRuntime::MapUploadBuffer(size_t size) { |
| 557 | const auto staging_ref = staging_buffer_pool.Request(size, true); | 557 | const auto staging_ref = staging_buffer_pool.Request(size, MemoryUsage::Upload); |
| 558 | return ImageBufferMap{ | 558 | return ImageBufferMap{ |
| 559 | .handle = staging_ref.buffer, | 559 | .handle = staging_ref.buffer, |
| 560 | .span = staging_ref.mapped_span, | 560 | .span = staging_ref.mapped_span, |
| @@ -788,9 +788,9 @@ Image::Image(TextureCacheRuntime& runtime, const ImageInfo& info_, GPUVAddr gpu_ | |||
| 788 | image(MakeImage(runtime.device, info)), buffer(MakeBuffer(runtime.device, info)), | 788 | image(MakeImage(runtime.device, info)), buffer(MakeBuffer(runtime.device, info)), |
| 789 | aspect_mask(ImageAspectMask(info.format)) { | 789 | aspect_mask(ImageAspectMask(info.format)) { |
| 790 | if (image) { | 790 | if (image) { |
| 791 | commit = runtime.memory_allocator.Commit(image, false); | 791 | commit = runtime.memory_allocator.Commit(image, MemoryUsage::DeviceLocal); |
| 792 | } else { | 792 | } else { |
| 793 | commit = runtime.memory_allocator.Commit(buffer, false); | 793 | commit = runtime.memory_allocator.Commit(buffer, MemoryUsage::DeviceLocal); |
| 794 | } | 794 | } |
| 795 | if (IsPixelFormatASTC(info.format) && !runtime.device.IsOptimalAstcSupported()) { | 795 | if (IsPixelFormatASTC(info.format) && !runtime.device.IsOptimalAstcSupported()) { |
| 796 | flags |= VideoCommon::ImageFlagBits::Converted; | 796 | flags |= VideoCommon::ImageFlagBits::Converted; |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index c1cf292af..8bb15794d 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp | |||
| @@ -156,11 +156,13 @@ MemoryAllocator::MemoryAllocator(const Device& device_) | |||
| 156 | 156 | ||
| 157 | MemoryAllocator::~MemoryAllocator() = default; | 157 | MemoryAllocator::~MemoryAllocator() = default; |
| 158 | 158 | ||
| 159 | MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, bool host_visible) { | 159 | MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) { |
| 160 | const u64 chunk_size = GetAllocationChunkSize(requirements.size); | 160 | const u64 chunk_size = GetAllocationChunkSize(requirements.size); |
| 161 | 161 | ||
| 162 | // When a host visible commit is asked, search for host visible and coherent, otherwise search | 162 | // When a host visible commit is asked, search for host visible and coherent, otherwise search |
| 163 | // for a fast device local type. | 163 | // for a fast device local type. |
| 164 | // TODO: Deduce memory types from usage in a better way | ||
| 165 | const bool host_visible = IsHostVisible(usage); | ||
| 164 | const VkMemoryPropertyFlags wanted_properties = | 166 | const VkMemoryPropertyFlags wanted_properties = |
| 165 | host_visible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | 167 | host_visible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
| 166 | : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; | 168 | : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; |
| @@ -176,14 +178,14 @@ MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, b | |||
| 176 | return TryAllocCommit(requirements, wanted_properties).value(); | 178 | return TryAllocCommit(requirements, wanted_properties).value(); |
| 177 | } | 179 | } |
| 178 | 180 | ||
| 179 | MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, bool host_visible) { | 181 | MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage) { |
| 180 | auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), host_visible); | 182 | auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), usage); |
| 181 | buffer.BindMemory(commit.Memory(), commit.Offset()); | 183 | buffer.BindMemory(commit.Memory(), commit.Offset()); |
| 182 | return commit; | 184 | return commit; |
| 183 | } | 185 | } |
| 184 | 186 | ||
| 185 | MemoryCommit MemoryAllocator::Commit(const vk::Image& image, bool host_visible) { | 187 | MemoryCommit MemoryAllocator::Commit(const vk::Image& image, MemoryUsage usage) { |
| 186 | auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), host_visible); | 188 | auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), usage); |
| 187 | image.BindMemory(commit.Memory(), commit.Offset()); | 189 | image.BindMemory(commit.Memory(), commit.Offset()); |
| 188 | return commit; | 190 | return commit; |
| 189 | } | 191 | } |
| @@ -224,4 +226,16 @@ std::optional<MemoryCommit> MemoryAllocator::TryAllocCommit( | |||
| 224 | return std::nullopt; | 226 | return std::nullopt; |
| 225 | } | 227 | } |
| 226 | 228 | ||
| 229 | bool IsHostVisible(MemoryUsage usage) noexcept { | ||
| 230 | switch (usage) { | ||
| 231 | case MemoryUsage::DeviceLocal: | ||
| 232 | return false; | ||
| 233 | case MemoryUsage::Upload: | ||
| 234 | case MemoryUsage::Download: | ||
| 235 | return true; | ||
| 236 | } | ||
| 237 | UNREACHABLE_MSG("Invalid memory usage={}", usage); | ||
| 238 | return false; | ||
| 239 | } | ||
| 240 | |||
| 227 | } // namespace Vulkan | 241 | } // namespace Vulkan |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index 69a6341e1..efb32167a 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h | |||
| @@ -17,7 +17,16 @@ class Device; | |||
| 17 | class MemoryMap; | 17 | class MemoryMap; |
| 18 | class MemoryAllocation; | 18 | class MemoryAllocation; |
| 19 | 19 | ||
| 20 | class MemoryCommit final { | 20 | /// Hints and requirements for the backing memory type of a commit |
| 21 | enum class MemoryUsage { | ||
| 22 | DeviceLocal, ///< Hints device local usages, fastest memory type to read and write from the GPU | ||
| 23 | Upload, ///< Requires a host visible memory type optimized for CPU to GPU uploads | ||
| 24 | Download, ///< Requires a host visible memory type optimized for GPU to CPU readbacks | ||
| 25 | }; | ||
| 26 | |||
| 27 | /// Ownership handle of a memory commitment. | ||
| 28 | /// Points to a subregion of a memory allocation. | ||
| 29 | class MemoryCommit { | ||
| 21 | public: | 30 | public: |
| 22 | explicit MemoryCommit() noexcept = default; | 31 | explicit MemoryCommit() noexcept = default; |
| 23 | explicit MemoryCommit(const Device& device_, MemoryAllocation* allocation_, | 32 | explicit MemoryCommit(const Device& device_, MemoryAllocation* allocation_, |
| @@ -54,7 +63,9 @@ private: | |||
| 54 | std::span<u8> span; ///< Host visible memory span. Empty if not queried before. | 63 | std::span<u8> span; ///< Host visible memory span. Empty if not queried before. |
| 55 | }; | 64 | }; |
| 56 | 65 | ||
| 57 | class MemoryAllocator final { | 66 | /// Memory allocator container. |
| 67 | /// Allocates and releases memory allocations on demand. | ||
| 68 | class MemoryAllocator { | ||
| 58 | public: | 69 | public: |
| 59 | explicit MemoryAllocator(const Device& device_); | 70 | explicit MemoryAllocator(const Device& device_); |
| 60 | ~MemoryAllocator(); | 71 | ~MemoryAllocator(); |
| @@ -71,13 +82,13 @@ public: | |||
| 71 | * | 82 | * |
| 72 | * @returns A memory commit. | 83 | * @returns A memory commit. |
| 73 | */ | 84 | */ |
| 74 | MemoryCommit Commit(const VkMemoryRequirements& requirements, bool host_visible); | 85 | MemoryCommit Commit(const VkMemoryRequirements& requirements, MemoryUsage usage); |
| 75 | 86 | ||
| 76 | /// Commits memory required by the buffer and binds it. | 87 | /// Commits memory required by the buffer and binds it. |
| 77 | MemoryCommit Commit(const vk::Buffer& buffer, bool host_visible); | 88 | MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage); |
| 78 | 89 | ||
| 79 | /// Commits memory required by the image and binds it. | 90 | /// Commits memory required by the image and binds it. |
| 80 | MemoryCommit Commit(const vk::Image& image, bool host_visible); | 91 | MemoryCommit Commit(const vk::Image& image, MemoryUsage usage); |
| 81 | 92 | ||
| 82 | private: | 93 | private: |
| 83 | /// Allocates a chunk of memory. | 94 | /// Allocates a chunk of memory. |
| @@ -92,4 +103,7 @@ private: | |||
| 92 | std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations. | 103 | std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations. |
| 93 | }; | 104 | }; |
| 94 | 105 | ||
| 106 | /// Returns true when a memory usage is guaranteed to be host visible. | ||
| 107 | bool IsHostVisible(MemoryUsage usage) noexcept; | ||
| 108 | |||
| 95 | } // namespace Vulkan | 109 | } // namespace Vulkan |