Browse Source

[TEST] Adjust introduction on shader write/read

CamilleLaVey 4 days ago
parent
commit
487ff4ed4d
  1. 141
      src/video_core/renderer_vulkan/vk_buffer_cache.cpp
  2. 4
      src/video_core/renderer_vulkan/vk_buffer_cache.h

141
src/video_core/renderer_vulkan/vk_buffer_cache.cpp

@ -381,68 +381,65 @@ void BufferCacheRuntime::TryEnableUnifiedMemory(void* base, size_t size,
device, base, size, hardware_buffers, hardware_buffer_window, hardware_buffer_base);
if (!unified_memory->IsValid()) {
unified_memory.reset();
return;
}
AcquireUnifiedWindowsFromForeign();
}
void BufferCacheRuntime::CopyToUnifiedMemory(
size_t window_index, VkBuffer src_buffer,
std::span<const VideoCommon::BufferCopy> copies) {
if (!unified_memory || src_buffer == VK_NULL_HANDLE || copies.empty() ||
window_index >= unified_memory->GetWindowCount()) {
void BufferCacheRuntime::AcquireUnifiedWindowsFromForeign() {
if (!unified_memory->NeedsForeignOwnershipTransfer()) {
return;
}
const VkBuffer dst_buffer = unified_memory->GetWindowBuffer(window_index);
if (dst_buffer == VK_NULL_HANDLE) {
return;
boost::container::small_vector<VkBuffer, 16> window_buffers;
const size_t window_count = unified_memory->GetWindowCount();
for (size_t i = 0; i < window_count; ++i) {
const VkBuffer buffer = unified_memory->GetWindowBuffer(i);
if (buffer != VK_NULL_HANDLE) {
window_buffers.push_back(buffer);
}
}
VkDeviceSize covered_begin = std::numeric_limits<VkDeviceSize>::max();
VkDeviceSize covered_end = 0;
for (const VideoCommon::BufferCopy& copy : copies) {
covered_begin = (std::min)(covered_begin, static_cast<VkDeviceSize>(copy.dst_offset));
covered_end = (std::max)(covered_end,
static_cast<VkDeviceSize>(copy.dst_offset + copy.size));
if (window_buffers.empty()) {
return;
}
boost::container::small_vector<VkBufferCopy, 8> vk_copies(copies.size());
std::ranges::transform(copies, vk_copies.begin(), MakeBufferCopy);
const bool foreign = unified_memory->NeedsForeignOwnershipTransfer();
const u32 queue_family = device.GetGraphicsFamily();
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer, dst_buffer, vk_copies, foreign, queue_family, covered_begin,
covered_end](vk::CommandBuffer cmdbuf) {
if (foreign) {
scheduler.Record([window_buffers = std::move(window_buffers),
queue_family](vk::CommandBuffer cmdbuf) {
for (const VkBuffer buffer : window_buffers) {
const VkBufferMemoryBarrier acquire{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
.dstQueueFamilyIndex = queue_family,
.buffer = dst_buffer,
.offset = covered_begin,
.size = covered_end - covered_begin,
.buffer = buffer,
.offset = 0,
.size = VK_WHOLE_SIZE,
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, acquire);
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, acquire);
}
});
}
void BufferCacheRuntime::CopyToUnifiedMemory(
size_t window_index, VkBuffer src_buffer,
std::span<const VideoCommon::BufferCopy> copies) {
if (!unified_memory || src_buffer == VK_NULL_HANDLE || copies.empty() ||
window_index >= unified_memory->GetWindowCount()) {
return;
}
const VkBuffer dst_buffer = unified_memory->GetWindowBuffer(window_index);
if (dst_buffer == VK_NULL_HANDLE) {
return;
}
boost::container::small_vector<VkBufferCopy, 8> vk_copies(copies.size());
std::ranges::transform(copies, vk_copies.begin(), MakeBufferCopy);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer, dst_buffer, vk_copies](vk::CommandBuffer cmdbuf) {
cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies));
if (foreign) {
const VkBufferMemoryBarrier release{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = 0,
.srcQueueFamilyIndex = queue_family,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
.buffer = dst_buffer,
.offset = covered_begin,
.size = covered_end - covered_begin,
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, release);
}
});
}
@ -457,54 +454,12 @@ void BufferCacheRuntime::CopyFromUnifiedMemory(
if (src_buffer == VK_NULL_HANDLE) {
return;
}
VkDeviceSize covered_begin = std::numeric_limits<VkDeviceSize>::max();
VkDeviceSize covered_end = 0;
for (const VideoCommon::BufferCopy& copy : copies) {
covered_begin = (std::min)(covered_begin, static_cast<VkDeviceSize>(copy.dst_offset));
covered_end = (std::max)(covered_end,
static_cast<VkDeviceSize>(copy.dst_offset + copy.size));
}
boost::container::small_vector<VkBufferCopy, 8> vk_copies(copies.size());
std::ranges::transform(copies, vk_copies.begin(), MakeUnifiedUploadCopy);
const bool foreign = unified_memory->NeedsForeignOwnershipTransfer();
const u32 queue_family = device.GetGraphicsFamily();
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer, dst_buffer, vk_copies, foreign, queue_family, covered_begin,
covered_end](vk::CommandBuffer cmdbuf) {
if (foreign) {
const VkBufferMemoryBarrier acquire{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
.dstQueueFamilyIndex = queue_family,
.buffer = src_buffer,
.offset = covered_begin,
.size = covered_end - covered_begin,
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, acquire);
}
scheduler.Record([src_buffer, dst_buffer, vk_copies](vk::CommandBuffer cmdbuf) {
cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies));
if (foreign) {
const VkBufferMemoryBarrier release{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.dstAccessMask = 0,
.srcQueueFamilyIndex = queue_family,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
.buffer = src_buffer,
.offset = covered_begin,
.size = covered_end - covered_begin,
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, release);
}
});
}
@ -536,6 +491,20 @@ void BufferCacheRuntime::UnifiedMemoryHostBarrier() {
});
}
void BufferCacheRuntime::UnifiedMemoryShaderWriteBarrier() {
static constexpr VkMemoryBarrier SHADER_WRITE_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_HOST_READ_BIT,
};
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, VK_PIPELINE_STAGE_HOST_BIT, 0,
SHADER_WRITE_BARRIER);
});
}
StagingBufferRef BufferCacheRuntime::UploadStagingBuffer(size_t size) {
return staging_pool.Request(size, MemoryUsage::Upload);
}

4
src/video_core/renderer_vulkan/vk_buffer_cache.h

@ -159,6 +159,8 @@ public:
void UnifiedMemoryUploadBarrier();
void UnifiedMemoryShaderWriteBarrier();
u64 CurrentTick();
u64 KnownGpuTick();
@ -253,6 +255,8 @@ private:
VkFormat TexelBufferFormat(VideoCore::Surface::PixelFormat format) const;
void AcquireUnifiedWindowsFromForeign();
void ReserveNullBuffer();
vk::Buffer CreateNullBuffer();

Loading…
Cancel
Save