[Vulkan] Basic shared memory uploading

This commit is contained in:
Triang3l
2020-10-04 21:56:54 +03:00
parent 1fd0d48066
commit 2c50c670d8
9 changed files with 810 additions and 12 deletions

View File

@@ -0,0 +1,97 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_VULKAN_SHARED_MEMORY_H_
#define XENIA_GPU_VULKAN_VULKAN_SHARED_MEMORY_H_
#include <algorithm>
#include <memory>
#include <utility>
#include <vector>
#include "xenia/gpu/shared_memory.h"
#include "xenia/gpu/trace_writer.h"
#include "xenia/memory.h"
#include "xenia/ui/vulkan/vulkan_provider.h"
#include "xenia/ui/vulkan/vulkan_upload_buffer_pool.h"
namespace xe {
namespace gpu {
namespace vulkan {
class VulkanCommandProcessor;
class VulkanSharedMemory : public SharedMemory {
public:
VulkanSharedMemory(VulkanCommandProcessor& command_processor, Memory& memory,
TraceWriter& trace_writer);
~VulkanSharedMemory() override;
bool Initialize();
void Shutdown(bool from_destructor = false);
void CompletedSubmissionUpdated();
void EndSubmission();
enum class Usage {
// Index buffer, vfetch, compute read, transfer source.
kRead,
// Index buffer, vfetch, memexport.
kGuestDrawReadWrite,
kComputeWrite,
kTransferDestination,
};
// Places pipeline barrier for the target usage, also ensuring writes of
// adjacent are ordered with writes of each other and reads.
void Use(Usage usage, std::pair<uint32_t, uint32_t> written_range = {});
VkBuffer buffer() const { return buffer_; }
protected:
bool EnsureHostGpuMemoryAllocated(uint32_t start, uint32_t length) override;
bool UploadRanges(const std::vector<std::pair<uint32_t, uint32_t>>&
upload_page_ranges) override;
private:
bool IsSparse() const {
return buffer_allocation_size_log2_ < kBufferSizeLog2;
}
void GetBarrier(Usage usage, VkPipelineStageFlags& stage_mask,
VkAccessFlags& access_mask) const;
VulkanCommandProcessor& command_processor_;
TraceWriter& trace_writer_;
VkBuffer buffer_ = VK_NULL_HANDLE;
uint32_t buffer_memory_type_;
// Maximum of 1024 allocations in the worst case for all of the buffer because
// of the overall 4096 allocation count limit on Windows drivers.
static constexpr uint32_t kMinBufferAllocationSizeLog2 =
std::max(kOptimalAllocationLog2, kBufferSizeLog2 - 10);
uint32_t buffer_allocation_size_log2_ = kBufferSizeLog2;
// Sparse memory allocations, of different sizes.
std::vector<VkDeviceMemory> buffer_memory_;
// One bit per every 2^buffer_allocation_size_log2_ of the buffer.
std::vector<uint64_t> buffer_memory_allocated_;
// First usage will likely be uploading.
Usage last_usage_ = Usage::kTransferDestination;
std::pair<uint32_t, uint32_t> last_written_range_ = {};
std::unique_ptr<ui::vulkan::VulkanUploadBufferPool> upload_buffer_pool_;
std::vector<VkBufferCopy> upload_regions_;
};
} // namespace vulkan
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_VULKAN_VULKAN_SHARED_MEMORY_H_