mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 00:12:40 +00:00
graphics: migrate Vulkan backend to Vulkan-Hpp
This commit is contained in:
1 parent
587cb238f0
commit
7905f2d12f
64 files changed
+4842
-4518
No files matched your search
@@ -421,10 +421,10 @@ struct BufferCache::ReadbackWorker {
|
||||
i, family, ctx->queues[i].family);
|
||||
}
|
||||
}
|
||||
readback.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
readback.memory.property = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
||||
readback.usage = vk::BufferUsageFlagBits::eTransferDst;
|
||||
readback.memory.property = vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent |
|
||||
vk::MemoryPropertyFlagBits::eHostCached;
|
||||
VulkanCreateBuffer(ctx, READBACK_CAPACITY, &readback);
|
||||
VulkanMapMemory(ctx, &readback.memory, &mapped);
|
||||
command = std::make_unique<CommandBuffer>(GraphicContext::QUEUE_UTIL);
|
||||
@@ -456,9 +456,9 @@ struct BufferCache::ReadbackWorker {
|
||||
" page=0x%016" PRIx64 " buffer=0x%016" PRIx64 " size=0x%016" PRIx64 "\n",
|
||||
vaddr, page, cached.vaddr, cached.size);
|
||||
}
|
||||
uint32_t data_offset = 0;
|
||||
std::array<VkBufferCopy, MAX_RANGES> copies {};
|
||||
std::array<VkBufferMemoryBarrier, MAX_RANGES> barriers {};
|
||||
uint32_t data_offset = 0;
|
||||
std::array<vk::BufferCopy, MAX_RANGES> copies {};
|
||||
std::array<vk::BufferMemoryBarrier, MAX_RANGES> barriers {};
|
||||
cache.m_gpu_modified_ranges.ForEachIntersection(
|
||||
page, TRACKER_PAGE_SIZE, [&](RangeSet::Range range) {
|
||||
if (range_count == MAX_RANGES || (range.address - cached.vaddr) % 4 != 0 ||
|
||||
@@ -475,9 +475,9 @@ struct BufferCache::ReadbackWorker {
|
||||
.dstOffset = data_offset,
|
||||
.size = range.size};
|
||||
auto& barrier = barriers[range_count];
|
||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
barrier.sType = vk::StructureType::eBufferMemoryBarrier;
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eMemoryWrite;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eTransferRead;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.buffer = cached.buffer->buffer;
|
||||
@@ -498,13 +498,13 @@ struct BufferCache::ReadbackWorker {
|
||||
" count=%u bytes=%u\n",
|
||||
page, range_count, data_offset);
|
||||
}
|
||||
auto* vk_buffer = command->GetPool()->buffers[command->GetIndex()];
|
||||
auto vk_buffer = command->GetPool()->buffers[command->GetIndex()];
|
||||
command->Begin();
|
||||
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, range_count,
|
||||
barriers.data(), 0, nullptr);
|
||||
vkCmdCopyBuffer(vk_buffer, cached.buffer->buffer, readback.buffer, range_count,
|
||||
copies.data());
|
||||
vk_buffer.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
|
||||
vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlags {},
|
||||
0, nullptr, range_count, barriers.data(), 0, nullptr);
|
||||
vk_buffer.copyBuffer(cached.buffer->buffer, readback.buffer, range_count,
|
||||
copies.data());
|
||||
command->End();
|
||||
command->Execute();
|
||||
command->WaitForFenceAndReset();
|
||||
@@ -687,10 +687,10 @@ std::pair<VulkanBuffer*, uint64_t> BufferCache::ObtainBuffer(CommandBuffer* com
|
||||
!texture_region.gpu_metadata_bytes) {
|
||||
std::array<uint8_t, CACHING_PAGE_SIZE> guest_data;
|
||||
if (Libs::LibKernel::Memory::TryReadBacking(vaddr, guest_data.data(), size)) {
|
||||
VulkanBuffer* stream_buffer = nullptr;
|
||||
VkDeviceSize stream_offset = 0;
|
||||
VkDeviceSize stream_range = 0;
|
||||
const auto stream_alignment = std::max<uint64_t>(ctx->StorageMinAlignment(), 16);
|
||||
VulkanBuffer* stream_buffer = nullptr;
|
||||
vk::DeviceSize stream_offset = 0;
|
||||
vk::DeviceSize stream_range = 0;
|
||||
const auto stream_alignment = std::max<uint64_t>(ctx->StorageMinAlignment(), 16);
|
||||
if (UploadHostData(command, ctx, guest_data.data(), size, stream_alignment,
|
||||
&stream_buffer, &stream_offset, &stream_range)) {
|
||||
return {stream_buffer, stream_offset};
|
||||
@@ -795,20 +795,20 @@ std::pair<VulkanBuffer*, uint64_t> BufferCache::ObtainBuffer(CommandBuffer* com
|
||||
cached->ctx = ctx;
|
||||
cached->buffer = MakeSharedVulkanBuffer(ctx);
|
||||
cached->buffer->usage =
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
cached->buffer->memory.property = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst |
|
||||
vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndexBuffer |
|
||||
vk::BufferUsageFlagBits::eStorageBuffer;
|
||||
cached->buffer->memory.property = vk::MemoryPropertyFlagBits::eDeviceLocal;
|
||||
VulkanCreateBuffer(ctx, cached->size, cached->buffer.get());
|
||||
if (!overlaps.empty()) {
|
||||
auto* vk_buffer = command->GetPool()->buffers[command->GetIndex()];
|
||||
std::vector<VkBufferMemoryBarrier> before;
|
||||
auto vk_buffer = command->GetPool()->buffers[command->GetIndex()];
|
||||
std::vector<vk::BufferMemoryBarrier> before;
|
||||
before.reserve(overlaps.size() + 1);
|
||||
for (const auto& overlap: overlaps) {
|
||||
VkBufferMemoryBarrier barrier {};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
vk::BufferMemoryBarrier barrier {};
|
||||
barrier.sType = vk::StructureType::eBufferMemoryBarrier;
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eMemoryWrite;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eTransferRead;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.buffer = overlap->second->buffer->buffer;
|
||||
@@ -816,37 +816,38 @@ std::pair<VulkanBuffer*, uint64_t> BufferCache::ObtainBuffer(CommandBuffer* com
|
||||
barrier.size = overlap->second->size;
|
||||
before.push_back(barrier);
|
||||
}
|
||||
VkBufferMemoryBarrier destination {};
|
||||
destination.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
destination.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
vk::BufferMemoryBarrier destination {};
|
||||
destination.sType = vk::StructureType::eBufferMemoryBarrier;
|
||||
destination.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
destination.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
destination.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
destination.buffer = cached->buffer->buffer;
|
||||
destination.offset = 0;
|
||||
destination.size = cached->size;
|
||||
before.push_back(destination);
|
||||
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0,
|
||||
nullptr, static_cast<uint32_t>(before.size()), before.data(), 0,
|
||||
nullptr);
|
||||
vk_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::DependencyFlagBits::eByRegion, 0, nullptr, static_cast<uint32_t>(before.size()),
|
||||
before.data(), 0, nullptr);
|
||||
for (const auto& overlap: overlaps) {
|
||||
const auto& old = *overlap->second;
|
||||
const VkBufferCopy copy {
|
||||
const auto& old = *overlap->second;
|
||||
const vk::BufferCopy copy {
|
||||
.srcOffset = 0, .dstOffset = old.vaddr - cached->vaddr, .size = old.size};
|
||||
vkCmdCopyBuffer(vk_buffer, old.buffer->buffer, cached->buffer->buffer, 1, ©);
|
||||
vk_buffer.copyBuffer(old.buffer->buffer, cached->buffer->buffer, 1, ©);
|
||||
}
|
||||
VkBufferMemoryBarrier after {};
|
||||
after.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
after.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
after.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
vk::BufferMemoryBarrier after {};
|
||||
after.sType = vk::StructureType::eBufferMemoryBarrier;
|
||||
after.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
after.dstAccessMask =
|
||||
vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
|
||||
after.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
after.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
after.buffer = cached->buffer->buffer;
|
||||
after.offset = 0;
|
||||
after.size = cached->size;
|
||||
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0,
|
||||
nullptr, 1, &after, 0, nullptr);
|
||||
vk_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eAllCommands,
|
||||
vk::DependencyFlagBits::eByRegion, 0, nullptr, 1, &after, 0, nullptr);
|
||||
for (const auto& overlap: overlaps) {
|
||||
command->RetainResourceUntilFence(overlap->second->buffer);
|
||||
m_buffers.erase(overlap);
|
||||
@@ -896,12 +897,13 @@ VulkanBuffer* BufferCache::ObtainNullBuffer(CommandBuffer* command, GraphicConte
|
||||
if (m_null_buffer == nullptr) {
|
||||
// robustBufferAccess makes every fetch safe; TODO: Use a
|
||||
// persistent 16-byte fallback when Vulkan null vertex descriptors are unavailable.
|
||||
auto buffer = MakeSharedVulkanBuffer(ctx);
|
||||
buffer->usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||
buffer->memory.property = static_cast<uint32_t>(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
||||
auto buffer = MakeSharedVulkanBuffer(ctx);
|
||||
buffer->usage = vk::BufferUsageFlagBits::eStorageBuffer |
|
||||
vk::BufferUsageFlagBits::eVertexBuffer |
|
||||
vk::BufferUsageFlagBits::eIndexBuffer;
|
||||
buffer->memory.property = vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent |
|
||||
vk::MemoryPropertyFlagBits::eHostCached;
|
||||
VulkanCreateBuffer(ctx, 16, buffer.get());
|
||||
void* data = nullptr;
|
||||
VulkanMapMemory(ctx, &buffer->memory, &data);
|
||||
@@ -1040,8 +1042,8 @@ BufferImageCopySource BufferCache::ObtainBufferForImage(uint64_t vaddr, uint64_t
|
||||
}
|
||||
|
||||
namespace {
|
||||
VkBufferMemoryBarrier MakeDmaBarrier(VulkanBuffer* buffer, uint64_t offset, uint64_t size,
|
||||
VkAccessFlags source, VkAccessFlags destination) {
|
||||
vk::BufferMemoryBarrier MakeDmaBarrier(VulkanBuffer* buffer, uint64_t offset, uint64_t size,
|
||||
vk::AccessFlags source, vk::AccessFlags destination) {
|
||||
if (buffer == nullptr || buffer->buffer == nullptr || size == 0 ||
|
||||
offset > buffer->buffer_size || size > buffer->buffer_size - offset) {
|
||||
EXIT("BufferCache: invalid DMA barrier, buffer=%p handle=%p offset=0x%016" PRIx64
|
||||
@@ -1050,8 +1052,8 @@ VkBufferMemoryBarrier MakeDmaBarrier(VulkanBuffer* buffer, uint64_t offset, uint
|
||||
buffer == nullptr ? nullptr : static_cast<const void*>(buffer->buffer), offset, size,
|
||||
buffer == nullptr ? 0 : buffer->buffer_size);
|
||||
}
|
||||
VkBufferMemoryBarrier barrier {};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
vk::BufferMemoryBarrier barrier {};
|
||||
barrier.sType = vk::StructureType::eBufferMemoryBarrier;
|
||||
barrier.srcAccessMask = source;
|
||||
barrier.dstAccessMask = destination;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
@@ -1062,7 +1064,7 @@ VkBufferMemoryBarrier MakeDmaBarrier(VulkanBuffer* buffer, uint64_t offset, uint
|
||||
return barrier;
|
||||
}
|
||||
|
||||
VkCommandBuffer GetDmaCommandBuffer(CommandBuffer* command) {
|
||||
vk::CommandBuffer GetDmaCommandBuffer(CommandBuffer* command) {
|
||||
if (command == nullptr || command->IsInvalid() || command->GetPool() == nullptr ||
|
||||
command->GetIndex() >= command->GetPool()->buffers_count) {
|
||||
EXIT("BufferCache: invalid DMA command buffer, command=%p\n",
|
||||
@@ -1113,19 +1115,20 @@ void BufferCache::FillBuffer(CommandBuffer* command, GraphicContext* ctx, uint64
|
||||
}
|
||||
}
|
||||
const auto [dst, dst_offset] = ObtainBuffer(command, ctx, vaddr, size, true, false);
|
||||
const auto before = MakeDmaBarrier(dst, dst_offset, size,
|
||||
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
const auto before = MakeDmaBarrier(
|
||||
dst, dst_offset, size, vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite,
|
||||
vk::AccessFlagBits::eTransferWrite);
|
||||
const auto vk_buffer = GetDmaCommandBuffer(command);
|
||||
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1,
|
||||
&before, 0, nullptr);
|
||||
vkCmdFillBuffer(vk_buffer, dst->buffer, dst_offset, size, value);
|
||||
const auto after = MakeDmaBarrier(dst, dst_offset, size, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT);
|
||||
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0,
|
||||
nullptr, 1, &after, 0, nullptr);
|
||||
vk_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::DependencyFlagBits::eByRegion, 0, nullptr, 1, &before, 0, nullptr);
|
||||
vk_buffer.fillBuffer(dst->buffer, dst_offset, size, value);
|
||||
const auto after =
|
||||
MakeDmaBarrier(dst, dst_offset, size, vk::AccessFlagBits::eTransferWrite,
|
||||
vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite);
|
||||
vk_buffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::PipelineStageFlagBits::eAllCommands,
|
||||
vk::DependencyFlagBits::eByRegion, 0, nullptr, 1, &after, 0, nullptr);
|
||||
}
|
||||
|
||||
void BufferCache::CopyBuffer(CommandBuffer* command, GraphicContext* ctx, uint64_t dst_vaddr,
|
||||
@@ -1200,28 +1203,28 @@ void BufferCache::CopyBuffer(CommandBuffer* command, GraphicContext* ctx, uint64
|
||||
" dst_offset=0x%016" PRIx64 " size=0x%016" PRIx64 "\n",
|
||||
src_offset, dst_offset, size);
|
||||
}
|
||||
const VkBufferMemoryBarrier before[] = {
|
||||
const vk::BufferMemoryBarrier before[] = {
|
||||
MakeDmaBarrier(dst, dst_offset, size,
|
||||
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT),
|
||||
MakeDmaBarrier(src, src_offset, size, VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT),
|
||||
vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite,
|
||||
vk::AccessFlagBits::eTransferWrite),
|
||||
MakeDmaBarrier(src, src_offset, size, vk::AccessFlagBits::eMemoryWrite,
|
||||
vk::AccessFlagBits::eTransferRead),
|
||||
};
|
||||
const auto vk_buffer = GetDmaCommandBuffer(command);
|
||||
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 2,
|
||||
before, 0, nullptr);
|
||||
const VkBufferCopy copy {src_offset, dst_offset, size};
|
||||
vkCmdCopyBuffer(vk_buffer, src->buffer, dst->buffer, 1, ©);
|
||||
const VkBufferMemoryBarrier after[] = {
|
||||
MakeDmaBarrier(dst, dst_offset, size, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT),
|
||||
MakeDmaBarrier(src, src_offset, size, VK_ACCESS_TRANSFER_READ_BIT,
|
||||
VK_ACCESS_MEMORY_WRITE_BIT),
|
||||
vk_buffer.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
|
||||
vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::DependencyFlagBits::eByRegion, 0, nullptr, 2, before, 0, nullptr);
|
||||
const vk::BufferCopy copy {src_offset, dst_offset, size};
|
||||
vk_buffer.copyBuffer(src->buffer, dst->buffer, 1, ©);
|
||||
const vk::BufferMemoryBarrier after[] = {
|
||||
MakeDmaBarrier(dst, dst_offset, size, vk::AccessFlagBits::eTransferWrite,
|
||||
vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite),
|
||||
MakeDmaBarrier(src, src_offset, size, vk::AccessFlagBits::eTransferRead,
|
||||
vk::AccessFlagBits::eMemoryWrite),
|
||||
};
|
||||
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0,
|
||||
nullptr, 2, after, 0, nullptr);
|
||||
vk_buffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::PipelineStageFlagBits::eAllCommands,
|
||||
vk::DependencyFlagBits::eByRegion, 0, nullptr, 2, after, 0, nullptr);
|
||||
}
|
||||
|
||||
bool BufferCache::HasPageOverlap(uint64_t vaddr, uint64_t size) {
|
||||
|
||||
Reference in new issue
Block a user