buffer_cache: Use buffer methods instead of cache virtual methods
This commit is contained in:
parent
39c97f1b65
commit
32a2dcd415
5 changed files with 90 additions and 99 deletions
|
@ -269,15 +269,6 @@ protected:
|
||||||
|
|
||||||
virtual std::shared_ptr<Buffer> CreateBlock(VAddr cpu_addr, std::size_t size) = 0;
|
virtual std::shared_ptr<Buffer> CreateBlock(VAddr cpu_addr, std::size_t size) = 0;
|
||||||
|
|
||||||
virtual void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
const u8* data) = 0;
|
|
||||||
|
|
||||||
virtual void DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
u8* data) = 0;
|
|
||||||
|
|
||||||
virtual void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
|
|
||||||
std::size_t dst_offset, std::size_t size) = 0;
|
|
||||||
|
|
||||||
virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) {
|
virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -339,11 +330,11 @@ private:
|
||||||
const VAddr cpu_addr_end = cpu_addr + size;
|
const VAddr cpu_addr_end = cpu_addr + size;
|
||||||
if (memory_manager.IsGranularRange(gpu_addr, size)) {
|
if (memory_manager.IsGranularRange(gpu_addr, size)) {
|
||||||
u8* host_ptr = memory_manager.GetPointer(gpu_addr);
|
u8* host_ptr = memory_manager.GetPointer(gpu_addr);
|
||||||
UploadBlockData(*block, block->Offset(cpu_addr), size, host_ptr);
|
block->Upload(block->Offset(cpu_addr), size, host_ptr);
|
||||||
} else {
|
} else {
|
||||||
staging_buffer.resize(size);
|
staging_buffer.resize(size);
|
||||||
memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size);
|
memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size);
|
||||||
UploadBlockData(*block, block->Offset(cpu_addr), size, staging_buffer.data());
|
block->Upload(block->Offset(cpu_addr), size, staging_buffer.data());
|
||||||
}
|
}
|
||||||
return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr));
|
return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr));
|
||||||
}
|
}
|
||||||
|
@ -402,7 +393,7 @@ private:
|
||||||
}
|
}
|
||||||
staging_buffer.resize(size);
|
staging_buffer.resize(size);
|
||||||
system.Memory().ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size);
|
system.Memory().ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size);
|
||||||
UploadBlockData(*block, block->Offset(interval.lower()), size, staging_buffer.data());
|
block->Upload(block->Offset(interval.lower()), size, staging_buffer.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +430,7 @@ private:
|
||||||
|
|
||||||
const std::size_t size = map->end - map->start;
|
const std::size_t size = map->end - map->start;
|
||||||
staging_buffer.resize(size);
|
staging_buffer.resize(size);
|
||||||
DownloadBlockData(*block, block->Offset(map->start), size, staging_buffer.data());
|
block->Download(block->Offset(map->start), size, staging_buffer.data());
|
||||||
system.Memory().WriteBlockUnsafe(map->start, staging_buffer.data(), size);
|
system.Memory().WriteBlockUnsafe(map->start, staging_buffer.data(), size);
|
||||||
map->MarkAsModified(false, 0);
|
map->MarkAsModified(false, 0);
|
||||||
}
|
}
|
||||||
|
@ -467,7 +458,7 @@ private:
|
||||||
const std::size_t new_size = old_size + BLOCK_PAGE_SIZE;
|
const std::size_t new_size = old_size + BLOCK_PAGE_SIZE;
|
||||||
const VAddr cpu_addr = buffer->CpuAddr();
|
const VAddr cpu_addr = buffer->CpuAddr();
|
||||||
std::shared_ptr<Buffer> new_buffer = CreateBlock(cpu_addr, new_size);
|
std::shared_ptr<Buffer> new_buffer = CreateBlock(cpu_addr, new_size);
|
||||||
CopyBlock(*buffer, *new_buffer, 0, 0, old_size);
|
new_buffer->CopyFrom(*buffer, 0, 0, old_size);
|
||||||
QueueDestruction(std::move(buffer));
|
QueueDestruction(std::move(buffer));
|
||||||
|
|
||||||
const VAddr cpu_addr_end = cpu_addr + new_size - 1;
|
const VAddr cpu_addr_end = cpu_addr + new_size - 1;
|
||||||
|
@ -489,8 +480,8 @@ private:
|
||||||
const std::size_t new_size = size_1 + size_2;
|
const std::size_t new_size = size_1 + size_2;
|
||||||
|
|
||||||
std::shared_ptr<Buffer> new_buffer = CreateBlock(new_addr, new_size);
|
std::shared_ptr<Buffer> new_buffer = CreateBlock(new_addr, new_size);
|
||||||
CopyBlock(*first, *new_buffer, 0, new_buffer->Offset(first_addr), size_1);
|
new_buffer->CopyFrom(*first, 0, new_buffer->Offset(first_addr), size_1);
|
||||||
CopyBlock(*second, *new_buffer, 0, new_buffer->Offset(second_addr), size_2);
|
new_buffer->CopyFrom(*second, 0, new_buffer->Offset(second_addr), size_2);
|
||||||
QueueDestruction(std::move(first));
|
QueueDestruction(std::move(first));
|
||||||
QueueDestruction(std::move(second));
|
QueueDestruction(std::move(second));
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,24 @@ Buffer::Buffer(const Device& device, VAddr cpu_addr, std::size_t size)
|
||||||
|
|
||||||
Buffer::~Buffer() = default;
|
Buffer::~Buffer() = default;
|
||||||
|
|
||||||
|
void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const {
|
||||||
|
glNamedBufferSubData(Handle(), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size),
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const {
|
||||||
|
MICROPROFILE_SCOPE(OpenGL_Buffer_Download);
|
||||||
|
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
|
||||||
|
glGetNamedBufferSubData(Handle(), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size),
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
|
||||||
|
std::size_t size) const {
|
||||||
|
glCopyNamedBufferSubData(src.Handle(), Handle(), static_cast<GLintptr>(src_offset),
|
||||||
|
static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
|
||||||
|
}
|
||||||
|
|
||||||
OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system,
|
OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system,
|
||||||
const Device& device_, std::size_t stream_size)
|
const Device& device_, std::size_t stream_size)
|
||||||
: GenericBufferCache{rasterizer, system,
|
: GenericBufferCache{rasterizer, system,
|
||||||
|
@ -62,26 +80,6 @@ OGLBufferCache::BufferInfo OGLBufferCache::GetEmptyBuffer(std::size_t) {
|
||||||
return {0, 0, 0};
|
return {0, 0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
const u8* data) {
|
|
||||||
glNamedBufferSubData(buffer.Handle(), static_cast<GLintptr>(offset),
|
|
||||||
static_cast<GLsizeiptr>(size), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
u8* data) {
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_Buffer_Download);
|
|
||||||
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
|
|
||||||
glGetNamedBufferSubData(buffer.Handle(), static_cast<GLintptr>(offset),
|
|
||||||
static_cast<GLsizeiptr>(size), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
|
|
||||||
std::size_t dst_offset, std::size_t size) {
|
|
||||||
glCopyNamedBufferSubData(src.Handle(), dst.Handle(), static_cast<GLintptr>(src_offset),
|
|
||||||
static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer,
|
OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer,
|
||||||
std::size_t size) {
|
std::size_t size) {
|
||||||
DEBUG_ASSERT(cbuf_cursor < std::size(cbufs));
|
DEBUG_ASSERT(cbuf_cursor < std::size(cbufs));
|
||||||
|
|
|
@ -28,6 +28,13 @@ public:
|
||||||
explicit Buffer(const Device& device, VAddr cpu_addr, std::size_t size);
|
explicit Buffer(const Device& device, VAddr cpu_addr, std::size_t size);
|
||||||
~Buffer();
|
~Buffer();
|
||||||
|
|
||||||
|
void Upload(std::size_t offset, std::size_t size, const u8* data) const;
|
||||||
|
|
||||||
|
void Download(std::size_t offset, std::size_t size, u8* data) const;
|
||||||
|
|
||||||
|
void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
|
||||||
|
std::size_t size) const;
|
||||||
|
|
||||||
GLuint Handle() const noexcept {
|
GLuint Handle() const noexcept {
|
||||||
return gl_buffer.handle;
|
return gl_buffer.handle;
|
||||||
}
|
}
|
||||||
|
@ -57,15 +64,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Buffer> CreateBlock(VAddr cpu_addr, std::size_t size) override;
|
std::shared_ptr<Buffer> CreateBlock(VAddr cpu_addr, std::size_t size) override;
|
||||||
|
|
||||||
void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
const u8* data) override;
|
|
||||||
|
|
||||||
void DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
u8* data) override;
|
|
||||||
|
|
||||||
void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
|
|
||||||
std::size_t dst_offset, std::size_t size) override;
|
|
||||||
|
|
||||||
BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) override;
|
BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -37,9 +37,9 @@ std::unique_ptr<VKStreamBuffer> CreateStreamBuffer(const VKDevice& device, VKSch
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
Buffer::Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VAddr cpu_addr,
|
Buffer::Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VKScheduler& scheduler_,
|
||||||
std::size_t size)
|
VKStagingBufferPool& staging_pool_, VAddr cpu_addr, std::size_t size)
|
||||||
: VideoCommon::BufferBlock{cpu_addr, size} {
|
: VideoCommon::BufferBlock{cpu_addr, size}, scheduler{scheduler_}, staging_pool{staging_pool_} {
|
||||||
VkBufferCreateInfo ci;
|
VkBufferCreateInfo ci;
|
||||||
ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
ci.pNext = nullptr;
|
ci.pNext = nullptr;
|
||||||
|
@ -56,40 +56,15 @@ Buffer::Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VAddr cp
|
||||||
|
|
||||||
Buffer::~Buffer() = default;
|
Buffer::~Buffer() = default;
|
||||||
|
|
||||||
VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
|
void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const {
|
||||||
const VKDevice& device, VKMemoryManager& memory_manager,
|
|
||||||
VKScheduler& scheduler, VKStagingBufferPool& staging_pool)
|
|
||||||
: VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, system,
|
|
||||||
CreateStreamBuffer(device,
|
|
||||||
scheduler)},
|
|
||||||
device{device}, memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{
|
|
||||||
staging_pool} {}
|
|
||||||
|
|
||||||
VKBufferCache::~VKBufferCache() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<Buffer> VKBufferCache::CreateBlock(VAddr cpu_addr, std::size_t size) {
|
|
||||||
return std::make_shared<Buffer>(device, memory_manager, cpu_addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
VKBufferCache::BufferInfo VKBufferCache::GetEmptyBuffer(std::size_t size) {
|
|
||||||
size = std::max(size, std::size_t(4));
|
|
||||||
const auto& empty = staging_pool.GetUnusedBuffer(size, false);
|
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
|
||||||
scheduler.Record([size, buffer = *empty.handle](vk::CommandBuffer cmdbuf) {
|
|
||||||
cmdbuf.FillBuffer(buffer, 0, size, 0);
|
|
||||||
});
|
|
||||||
return {*empty.handle, 0, 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
const u8* data) {
|
|
||||||
const auto& staging = staging_pool.GetUnusedBuffer(size, true);
|
const auto& staging = staging_pool.GetUnusedBuffer(size, true);
|
||||||
std::memcpy(staging.commit->Map(size), data, size);
|
std::memcpy(staging.commit->Map(size), data, size);
|
||||||
|
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
scheduler.Record([staging = *staging.handle, buffer = buffer.Handle(), offset,
|
|
||||||
size](vk::CommandBuffer cmdbuf) {
|
const VkBuffer handle = Handle();
|
||||||
cmdbuf.CopyBuffer(staging, buffer, VkBufferCopy{0, offset, size});
|
scheduler.Record([staging = *staging.handle, handle, offset, size](vk::CommandBuffer cmdbuf) {
|
||||||
|
cmdbuf.CopyBuffer(staging, handle, VkBufferCopy{0, offset, size});
|
||||||
|
|
||||||
VkBufferMemoryBarrier barrier;
|
VkBufferMemoryBarrier barrier;
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||||
|
@ -98,7 +73,7 @@ void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, st
|
||||||
barrier.dstAccessMask = UPLOAD_ACCESS_BARRIERS;
|
barrier.dstAccessMask = UPLOAD_ACCESS_BARRIERS;
|
||||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.buffer = buffer;
|
barrier.buffer = handle;
|
||||||
barrier.offset = offset;
|
barrier.offset = offset;
|
||||||
barrier.size = size;
|
barrier.size = size;
|
||||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, UPLOAD_PIPELINE_STAGE, 0, {},
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, UPLOAD_PIPELINE_STAGE, 0, {},
|
||||||
|
@ -106,12 +81,12 @@ void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, st
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const {
|
||||||
u8* data) {
|
|
||||||
const auto& staging = staging_pool.GetUnusedBuffer(size, true);
|
const auto& staging = staging_pool.GetUnusedBuffer(size, true);
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
scheduler.Record([staging = *staging.handle, buffer = buffer.Handle(), offset,
|
|
||||||
size](vk::CommandBuffer cmdbuf) {
|
const VkBuffer handle = Handle();
|
||||||
|
scheduler.Record([staging = *staging.handle, handle, offset, size](vk::CommandBuffer cmdbuf) {
|
||||||
VkBufferMemoryBarrier barrier;
|
VkBufferMemoryBarrier barrier;
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||||
barrier.pNext = nullptr;
|
barrier.pNext = nullptr;
|
||||||
|
@ -119,7 +94,7 @@ void VKBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset,
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.buffer = buffer;
|
barrier.buffer = handle;
|
||||||
barrier.offset = offset;
|
barrier.offset = offset;
|
||||||
barrier.size = size;
|
barrier.size = size;
|
||||||
|
|
||||||
|
@ -127,17 +102,19 @@ void VKBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset,
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, {}, barrier, {});
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, {}, barrier, {});
|
||||||
cmdbuf.CopyBuffer(buffer, staging, VkBufferCopy{offset, 0, size});
|
cmdbuf.CopyBuffer(handle, staging, VkBufferCopy{offset, 0, size});
|
||||||
});
|
});
|
||||||
scheduler.Finish();
|
scheduler.Finish();
|
||||||
|
|
||||||
std::memcpy(data, staging.commit->Map(size), size);
|
std::memcpy(data, staging.commit->Map(size), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
|
void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
|
||||||
std::size_t dst_offset, std::size_t size) {
|
std::size_t size) const {
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
scheduler.Record([src_buffer = src.Handle(), dst_buffer = dst.Handle(), src_offset, dst_offset,
|
|
||||||
|
const VkBuffer dst_buffer = Handle();
|
||||||
|
scheduler.Record([src_buffer = src.Handle(), dst_buffer, src_offset, dst_offset,
|
||||||
size](vk::CommandBuffer cmdbuf) {
|
size](vk::CommandBuffer cmdbuf) {
|
||||||
cmdbuf.CopyBuffer(src_buffer, dst_buffer, VkBufferCopy{src_offset, dst_offset, size});
|
cmdbuf.CopyBuffer(src_buffer, dst_buffer, VkBufferCopy{src_offset, dst_offset, size});
|
||||||
|
|
||||||
|
@ -165,4 +142,30 @@ void VKBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
|
||||||
|
const VKDevice& device, VKMemoryManager& memory_manager,
|
||||||
|
VKScheduler& scheduler, VKStagingBufferPool& staging_pool)
|
||||||
|
: VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, system,
|
||||||
|
CreateStreamBuffer(device,
|
||||||
|
scheduler)},
|
||||||
|
device{device}, memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{
|
||||||
|
staging_pool} {}
|
||||||
|
|
||||||
|
VKBufferCache::~VKBufferCache() = default;
|
||||||
|
|
||||||
|
std::shared_ptr<Buffer> VKBufferCache::CreateBlock(VAddr cpu_addr, std::size_t size) {
|
||||||
|
return std::make_shared<Buffer>(device, memory_manager, scheduler, staging_pool, cpu_addr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
VKBufferCache::BufferInfo VKBufferCache::GetEmptyBuffer(std::size_t size) {
|
||||||
|
size = std::max(size, std::size_t(4));
|
||||||
|
const auto& empty = staging_pool.GetUnusedBuffer(size, false);
|
||||||
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
|
scheduler.Record([size, buffer = *empty.handle](vk::CommandBuffer cmdbuf) {
|
||||||
|
cmdbuf.FillBuffer(buffer, 0, size, 0);
|
||||||
|
});
|
||||||
|
return {*empty.handle, 0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
@ -25,10 +25,17 @@ class VKScheduler;
|
||||||
|
|
||||||
class Buffer final : public VideoCommon::BufferBlock {
|
class Buffer final : public VideoCommon::BufferBlock {
|
||||||
public:
|
public:
|
||||||
explicit Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VAddr cpu_addr,
|
explicit Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VKScheduler& scheduler,
|
||||||
std::size_t size);
|
VKStagingBufferPool& staging_pool, VAddr cpu_addr, std::size_t size);
|
||||||
~Buffer();
|
~Buffer();
|
||||||
|
|
||||||
|
void Upload(std::size_t offset, std::size_t size, const u8* data) const;
|
||||||
|
|
||||||
|
void Download(std::size_t offset, std::size_t size, u8* data) const;
|
||||||
|
|
||||||
|
void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
|
||||||
|
std::size_t size) const;
|
||||||
|
|
||||||
VkBuffer Handle() const {
|
VkBuffer Handle() const {
|
||||||
return *buffer.handle;
|
return *buffer.handle;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +45,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
VKScheduler& scheduler;
|
||||||
|
VKStagingBufferPool& staging_pool;
|
||||||
|
|
||||||
VKBuffer buffer;
|
VKBuffer buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,15 +63,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Buffer> CreateBlock(VAddr cpu_addr, std::size_t size) override;
|
std::shared_ptr<Buffer> CreateBlock(VAddr cpu_addr, std::size_t size) override;
|
||||||
|
|
||||||
void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
const u8* data) override;
|
|
||||||
|
|
||||||
void DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
||||||
u8* data) override;
|
|
||||||
|
|
||||||
void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
|
|
||||||
std::size_t dst_offset, std::size_t size) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const VKDevice& device;
|
const VKDevice& device;
|
||||||
VKMemoryManager& memory_manager;
|
VKMemoryManager& memory_manager;
|
||||||
|
|
Loading…
Reference in a new issue