From 0cbb7ab027734c51daa6b9130c71fa0f1f3ed32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 22 Nov 2021 09:04:05 +0100 Subject: [PATCH] Change the PushBuffer API a bit to not take explicit memory types. --- Common/GPU/Vulkan/VulkanMemory.cpp | 18 ++++++++++++++---- Common/GPU/Vulkan/VulkanMemory.h | 20 ++++++++++++++------ Common/GPU/Vulkan/thin3d_vulkan.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 20 +++++--------------- GPU/Vulkan/DrawEngineVulkan.h | 8 -------- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanMemory.cpp b/Common/GPU/Vulkan/VulkanMemory.cpp index 986f3b2c79..f720b34e90 100644 --- a/Common/GPU/Vulkan/VulkanMemory.cpp +++ b/Common/GPU/Vulkan/VulkanMemory.cpp @@ -26,8 +26,8 @@ using namespace PPSSPP_VK; -VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyMask) - : vulkan_(vulkan), memoryPropertyMask_(memoryPropertyMask), size_(size), usage_(usage) { +VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, PushBufferType type) + : vulkan_(vulkan), size_(size), usage_(usage), type_(type) { bool res = AddBuffer(); _assert_(res); } @@ -54,6 +54,13 @@ bool VulkanPushBuffer::AddBuffer() { return false; } + VkMemoryPropertyFlags memoryPropertyMask_; + if (type_ == PushBufferType::CPU_TO_GPU) { + memoryPropertyMask_ = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + } else { + memoryPropertyMask_ = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + // Get the buffer memory requirements. None of this can be cached! VkMemoryRequirements reqs; vkGetBufferMemoryRequirements(device, info.buffer, &reqs); @@ -92,7 +99,7 @@ void VulkanPushBuffer::Destroy(VulkanContext *vulkan) { void VulkanPushBuffer::NextBuffer(size_t minSize) { // First, unmap the current memory. - if (memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + if (type_ == PushBufferType::CPU_TO_GPU) Unmap(); buf_++; @@ -112,7 +119,7 @@ void VulkanPushBuffer::NextBuffer(size_t minSize) { // Now, move to the next buffer and map it. offset_ = 0; - if (memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + if (type_ == PushBufferType::CPU_TO_GPU) Map(); } @@ -150,6 +157,8 @@ void VulkanPushBuffer::Unmap() { if (!writePtr_) return; + /* + // We could never hit this path before because we specified the mask explicitly. if ((memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) { VkMappedMemoryRange range{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; range.offset = 0; @@ -157,6 +166,7 @@ void VulkanPushBuffer::Unmap() { range.memory = buffers_[buf_].deviceMemory; vkFlushMappedMemoryRanges(vulkan_->GetDevice(), 1, &range); } + */ vkUnmapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory); writePtr_ = nullptr; diff --git a/Common/GPU/Vulkan/VulkanMemory.h b/Common/GPU/Vulkan/VulkanMemory.h index c61ad0b874..0508bb2102 100644 --- a/Common/GPU/Vulkan/VulkanMemory.h +++ b/Common/GPU/Vulkan/VulkanMemory.h @@ -6,10 +6,18 @@ #include "Common/Log.h" #include "Common/GPU/Vulkan/VulkanContext.h" +// Forward declaration +VK_DEFINE_HANDLE(VmaAllocation); + // VulkanMemory // // Vulkan memory management utils. +enum class PushBufferType { + CPU_TO_GPU, + GPU_ONLY, +}; + // VulkanPushBuffer // Simple incrementing allocator. // Use these to push vertex, index and uniform data. Generally you'll have two of these @@ -24,10 +32,10 @@ class VulkanPushBuffer { }; public: - // NOTE: If you create a push buffer with only VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + // NOTE: If you create a push buffer with PushBufferType::GPU_ONLY, // then you can't use any of the push functions as pointers will not be reachable from the CPU. // You must in this case use Allocate() only, and pass the returned offset and the VkBuffer to Vulkan APIs. - VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyMask = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, PushBufferType type); ~VulkanPushBuffer(); void Destroy(VulkanContext *vulkan); @@ -40,17 +48,17 @@ public: offset_ = 0; // Note: we must defrag because some buffers may be smaller than size_. Defragment(vulkan); - if (memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + if (type_ == PushBufferType::CPU_TO_GPU) Map(); } void BeginNoReset() { - if (memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + if (type_ == PushBufferType::CPU_TO_GPU) Map(); } void End() { - if (memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + if (type_ == PushBufferType::CPU_TO_GPU) Unmap(); } @@ -117,7 +125,7 @@ private: void Defragment(VulkanContext *vulkan); VulkanContext *vulkan_; - VkMemoryPropertyFlags memoryPropertyMask_; + PushBufferType type_; std::vector buffers_; size_t buf_ = 0; diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 9bc29bd3bb..f50eec3062 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -835,7 +835,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - frame_[i].pushBuffer = new VulkanPushBuffer(vulkan_, 1024 * 1024, usage); + frame_[i].pushBuffer = new VulkanPushBuffer(vulkan_, 1024 * 1024, usage, PushBufferType::CPU_TO_GPU); VkResult res = RecreateDescriptorPool(&frame_[i]); _assert_(res == VK_SUCCESS); } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 56633ffc7b..171240cab0 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -148,11 +148,9 @@ void DrawEngineVulkan::InitDeviceObjects() { // We now create descriptor pools on demand, so removed from here. // Note that pushUBO is also used for tessellation data (search for SetPushBuffer), and to upload // the null texture. This should be cleaned up... - frame_[i].pushUBO = new VulkanPushBuffer(vulkan, 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - frame_[i].pushVertex = new VulkanPushBuffer(vulkan, 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - frame_[i].pushIndex = new VulkanPushBuffer(vulkan, 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); - - frame_[i].pushLocal = new VulkanPushBuffer(vulkan, 1 * 1024 * 1024, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + frame_[i].pushUBO = new VulkanPushBuffer(vulkan, 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, PushBufferType::CPU_TO_GPU); + frame_[i].pushVertex = new VulkanPushBuffer(vulkan, 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); + frame_[i].pushIndex = new VulkanPushBuffer(vulkan, 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); } VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; @@ -177,7 +175,7 @@ void DrawEngineVulkan::InitDeviceObjects() { res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); _dbg_assert_(VK_SUCCESS == res); - vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan); tessDataTransfer = tessDataTransferVulkan; @@ -210,11 +208,6 @@ void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) { delete pushIndex; pushIndex = nullptr; } - if (pushLocal) { - pushLocal->Destroy(vulkan); - delete pushLocal; - pushLocal = nullptr; - } } void DrawEngineVulkan::DestroyDeviceObjects() { @@ -272,13 +265,11 @@ void DrawEngineVulkan::BeginFrame() { frame->pushUBO->Reset(); frame->pushVertex->Reset(); frame->pushIndex->Reset(); - frame->pushLocal->Reset(); VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); frame->pushUBO->Begin(vulkan); frame->pushVertex->Begin(vulkan); frame->pushIndex->Begin(vulkan); - frame->pushLocal->Begin(vulkan); // TODO: How can we make this nicer... tessDataTransferVulkan->SetPushBuffer(frame->pushUBO); @@ -289,7 +280,7 @@ void DrawEngineVulkan::BeginFrame() { if (vertexCache_->GetTotalSize() > VERTEX_CACHE_SIZE) { vertexCache_->Destroy(vulkan); delete vertexCache_; // orphans the buffers, they'll get deleted once no longer used by an in-flight frame. - vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); vai_.Iterate([&](uint32_t hash, VertexArrayInfoVulkan *vai) { delete vai; }); @@ -338,7 +329,6 @@ void DrawEngineVulkan::EndFrame() { frame->pushUBO->End(); frame->pushVertex->End(); frame->pushIndex->End(); - frame->pushLocal->End(); vertexCache_->End(); } diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index cea9cb3546..105bf12268 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -177,11 +177,6 @@ public: return GetCurFrame().pushUBO; } - // Only use Allocate on this one. - VulkanPushBuffer *GetPushBufferLocal() { - return GetCurFrame().pushLocal; - } - const DrawEngineVulkanStats &GetStats() const { return stats_; } @@ -250,9 +245,6 @@ private: VulkanPushBuffer *pushVertex = nullptr; VulkanPushBuffer *pushIndex = nullptr; - // Special push buffer in GPU local memory, for texture data conversion and similar tasks. - VulkanPushBuffer *pushLocal; - // We do rolling allocation and reset instead of caching across frames. That we might do later. DenseHashMap descSets; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 18f55ffdc1..2b17082232 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -501,7 +501,7 @@ void GPU_Vulkan::InitDeviceObjects() { for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { _assert_(!frameData_[i].push_); VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - frameData_[i].push_ = new VulkanPushBuffer(vulkan, 256 * 1024, usage); + frameData_[i].push_ = new VulkanPushBuffer(vulkan, 256 * 1024, usage, PushBufferType::CPU_TO_GPU); } VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);