diff options
-rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.cpp | 122 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.h | 104 |
2 files changed, 0 insertions, 226 deletions
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 46da81aaa..c36ede898 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -1,125 +1,3 @@ // Copyright 2019 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - -#include <cstring> -#include <memory> -#include <optional> -#include <tuple> - -#include "common/alignment.h" -#include "common/assert.h" -#include "core/memory.h" -#include "video_core/memory_manager.h" -#include "video_core/renderer_vulkan/declarations.h" -#include "video_core/renderer_vulkan/vk_buffer_cache.h" -#include "video_core/renderer_vulkan/vk_scheduler.h" -#include "video_core/renderer_vulkan/vk_stream_buffer.h" - -namespace Vulkan { - -CachedBufferEntry::CachedBufferEntry(VAddr cpu_addr, std::size_t size, u64 offset, - std::size_t alignment, u8* host_ptr) - : RasterizerCacheObject{host_ptr}, cpu_addr{cpu_addr}, size{size}, offset{offset}, - alignment{alignment} {} - -VKBufferCache::VKBufferCache(Tegra::MemoryManager& tegra_memory_manager, - Memory::Memory& cpu_memory_, - VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, - VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size) - : RasterizerCache{rasterizer}, tegra_memory_manager{tegra_memory_manager}, cpu_memory{ - cpu_memory_} { - const auto usage = vk::BufferUsageFlagBits::eVertexBuffer | - vk::BufferUsageFlagBits::eIndexBuffer | - vk::BufferUsageFlagBits::eUniformBuffer; - const auto access = vk::AccessFlagBits::eVertexAttributeRead | vk::AccessFlagBits::eIndexRead | - vk::AccessFlagBits::eUniformRead; - stream_buffer = - std::make_unique<VKStreamBuffer>(device, memory_manager, scheduler, size, usage, access, - vk::PipelineStageFlagBits::eAllCommands); - buffer_handle = stream_buffer->GetBuffer(); -} - -VKBufferCache::~VKBufferCache() = default; - -u64 VKBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, u64 alignment, bool cache) { - const auto cpu_addr{tegra_memory_manager.GpuToCpuAddress(gpu_addr)}; - ASSERT_MSG(cpu_addr, "Invalid GPU address"); - - // Cache management is a big overhead, so only cache entries with a given size. - // TODO: Figure out which size is the best for given games. - cache &= size >= 2048; - - u8* const host_ptr{cpu_memory.GetPointer(*cpu_addr)}; - if (cache) { - const auto entry = TryGet(host_ptr); - if (entry) { - if (entry->GetSize() >= size && entry->GetAlignment() == alignment) { - return entry->GetOffset(); - } - Unregister(entry); - } - } - - AlignBuffer(alignment); - const u64 uploaded_offset = buffer_offset; - - if (host_ptr == nullptr) { - return uploaded_offset; - } - - std::memcpy(buffer_ptr, host_ptr, size); - buffer_ptr += size; - buffer_offset += size; - - if (cache) { - auto entry = std::make_shared<CachedBufferEntry>(*cpu_addr, size, uploaded_offset, - alignment, host_ptr); - Register(entry); - } - - return uploaded_offset; -} - -u64 VKBufferCache::UploadHostMemory(const u8* raw_pointer, std::size_t size, u64 alignment) { - AlignBuffer(alignment); - std::memcpy(buffer_ptr, raw_pointer, size); - const u64 uploaded_offset = buffer_offset; - - buffer_ptr += size; - buffer_offset += size; - return uploaded_offset; -} - -std::tuple<u8*, u64> VKBufferCache::ReserveMemory(std::size_t size, u64 alignment) { - AlignBuffer(alignment); - u8* const uploaded_ptr = buffer_ptr; - const u64 uploaded_offset = buffer_offset; - - buffer_ptr += size; - buffer_offset += size; - return {uploaded_ptr, uploaded_offset}; -} - -void VKBufferCache::Reserve(std::size_t max_size) { - bool invalidate; - std::tie(buffer_ptr, buffer_offset_base, invalidate) = stream_buffer->Reserve(max_size); - buffer_offset = buffer_offset_base; - - if (invalidate) { - InvalidateAll(); - } -} - -void VKBufferCache::Send() { - stream_buffer->Send(buffer_offset - buffer_offset_base); -} - -void VKBufferCache::AlignBuffer(std::size_t alignment) { - // Align the offset, not the mapped pointer - const u64 offset_aligned = Common::AlignUp(buffer_offset, alignment); - buffer_ptr += offset_aligned - buffer_offset; - buffer_offset = offset_aligned; -} - -} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index daa8ccf66..bc6e584cf 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -3,107 +3,3 @@ // Refer to the license.txt file included. #pragma once - -#include <memory> -#include <tuple> - -#include "common/common_types.h" -#include "video_core/gpu.h" -#include "video_core/rasterizer_cache.h" -#include "video_core/renderer_vulkan/declarations.h" -#include "video_core/renderer_vulkan/vk_scheduler.h" - -namespace Memory { -class Memory; -} - -namespace Tegra { -class MemoryManager; -} - -namespace Vulkan { - -class VKDevice; -class VKFence; -class VKMemoryManager; -class VKStreamBuffer; - -class CachedBufferEntry final : public RasterizerCacheObject { -public: - explicit CachedBufferEntry(VAddr cpu_addr, std::size_t size, u64 offset, std::size_t alignment, - u8* host_ptr); - - VAddr GetCpuAddr() const override { - return cpu_addr; - } - - std::size_t GetSizeInBytes() const override { - return size; - } - - std::size_t GetSize() const { - return size; - } - - u64 GetOffset() const { - return offset; - } - - std::size_t GetAlignment() const { - return alignment; - } - -private: - VAddr cpu_addr{}; - std::size_t size{}; - u64 offset{}; - std::size_t alignment{}; -}; - -class VKBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> { -public: - explicit VKBufferCache(Tegra::MemoryManager& tegra_memory_manager, Memory::Memory& cpu_memory_, - VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, - VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size); - ~VKBufferCache(); - - /// Uploads data from a guest GPU address. Returns host's buffer offset where it's been - /// allocated. - u64 UploadMemory(GPUVAddr gpu_addr, std::size_t size, u64 alignment = 4, bool cache = true); - - /// Uploads from a host memory. Returns host's buffer offset where it's been allocated. - u64 UploadHostMemory(const u8* raw_pointer, std::size_t size, u64 alignment = 4); - - /// Reserves memory to be used by host's CPU. Returns mapped address and offset. - std::tuple<u8*, u64> ReserveMemory(std::size_t size, u64 alignment = 4); - - /// Reserves a region of memory to be used in subsequent upload/reserve operations. - void Reserve(std::size_t max_size); - - /// Ensures that the set data is sent to the device. - void Send(); - - /// Returns the buffer cache handle. - vk::Buffer GetBuffer() const { - return buffer_handle; - } - -protected: - // We do not have to flush this cache as things in it are never modified by us. - void FlushObjectInner(const std::shared_ptr<CachedBufferEntry>& object) override {} - -private: - void AlignBuffer(std::size_t alignment); - - Tegra::MemoryManager& tegra_memory_manager; - Memory::Memory& cpu_memory; - - std::unique_ptr<VKStreamBuffer> stream_buffer; - vk::Buffer buffer_handle; - - u8* buffer_ptr = nullptr; - u64 buffer_offset = 0; - u64 buffer_offset_base = 0; -}; - -} // namespace Vulkan |