BufferCache: Use a CircularBuffer as the transient buffer.

This commit is contained in:
Dr. Chat
2016-04-09 21:27:32 -05:00
parent b7f2c93d73
commit 4811ebc2ce
4 changed files with 67 additions and 179 deletions

View File

@@ -13,6 +13,7 @@
#include "xenia/gpu/register_file.h"
#include "xenia/gpu/shader.h"
#include "xenia/gpu/xenos.h"
#include "xenia/ui/vulkan/circular_buffer.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
@@ -50,22 +51,24 @@ class BufferCache {
// The returned offsets may alias.
std::pair<VkDeviceSize, VkDeviceSize> UploadConstantRegisters(
const Shader::ConstantRegisterMap& vertex_constant_register_map,
const Shader::ConstantRegisterMap& pixel_constant_register_map);
const Shader::ConstantRegisterMap& pixel_constant_register_map,
std::shared_ptr<ui::vulkan::Fence> fence);
// Uploads index buffer data from guest memory, possibly eliding with
// recently uploaded data or cached copies.
// Returns a buffer and offset that can be used with vkCmdBindIndexBuffer.
// Size will be VK_WHOLE_SIZE if the data could not be uploaded (OOM).
std::pair<VkBuffer, VkDeviceSize> UploadIndexBuffer(const void* source_ptr,
size_t source_length,
IndexFormat format);
std::pair<VkBuffer, VkDeviceSize> UploadIndexBuffer(
const void* source_ptr, size_t source_length, IndexFormat format,
std::shared_ptr<ui::vulkan::Fence> fence);
// Uploads vertex buffer data from guest memory, possibly eliding with
// recently uploaded data or cached copies.
// Returns a buffer and offset that can be used with vkCmdBindVertexBuffers.
// Size will be VK_WHOLE_SIZE if the data could not be uploaded (OOM).
std::pair<VkBuffer, VkDeviceSize> UploadVertexBuffer(const void* source_ptr,
size_t source_length);
std::pair<VkBuffer, VkDeviceSize> UploadVertexBuffer(
const void* source_ptr, size_t source_length,
std::shared_ptr<ui::vulkan::Fence> fence);
// Flushes all pending data to the GPU.
// Until this is called the GPU is not guaranteed to see any data.
@@ -81,36 +84,26 @@ class BufferCache {
// Clears all cached content and prevents future elision with pending data.
void ClearCache();
// Wipes all data no longer needed.
void Scavenge();
private:
// Allocates a block of memory in the transient buffer.
// When memory is not available fences are checked and space is reclaimed.
// Returns VK_WHOLE_SIZE if requested amount of memory is not available.
VkDeviceSize AllocateTransientData(VkDeviceSize alignment,
VkDeviceSize length);
VkDeviceSize AllocateTransientData(VkDeviceSize length,
std::shared_ptr<ui::vulkan::Fence> fence);
// Tries to allocate a block of memory in the transient buffer.
// Returns VK_WHOLE_SIZE if requested amount of memory is not available.
VkDeviceSize TryAllocateTransientData(VkDeviceSize alignment,
VkDeviceSize length);
VkDeviceSize TryAllocateTransientData(
VkDeviceSize length, std::shared_ptr<ui::vulkan::Fence> fence);
RegisterFile* register_file_ = nullptr;
VkDevice device_ = nullptr;
// Staging ringbuffer we cycle through fast. Used for data we don't
// plan on keeping past the current frame.
size_t transient_capacity_ = 0;
VkBuffer transient_uniform_buffer_ = nullptr;
VkBuffer transient_index_buffer_ = nullptr;
VkBuffer transient_vertex_buffer_ = nullptr;
VkDeviceMemory transient_buffer_memory_ = nullptr;
void* transient_buffer_data_ = nullptr;
VkDeviceSize transient_head_offset_ = 0;
VkDeviceSize transient_tail_offset_ = 0;
// Required alignments for our various types.
// All allocations must start at the appropriate alignment.
VkDeviceSize uniform_buffer_alignment_ = 0;
VkDeviceSize index_buffer_alignment_ = 0;
VkDeviceSize vertex_buffer_alignment_ = 0;
std::unique_ptr<ui::vulkan::CircularBuffer> transient_buffer_ = nullptr;
VkDescriptorPool descriptor_pool_ = nullptr;
VkDescriptorSetLayout descriptor_set_layout_ = nullptr;