vk_buffer_cache: Temporarily remove buffer cache
This is intended for a follow up commit to avoid circular dependencies.
This commit is contained in:
		
							parent
							
								
									89fc75d769
								
							
						
					
					
						commit
						85bb6a6f08
					
				@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user