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); device, base, size, hardware_buffers, hardware_buffer_window, hardware_buffer_base);
if (!unified_memory->IsValid()) { if (!unified_memory->IsValid()) {
unified_memory.reset(); 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; 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(); const u32 queue_family = device.GetGraphicsFamily();
scheduler.RequestOutsideRenderPassOperationContext(); 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{ const VkBufferMemoryBarrier acquire{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = 0, .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, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
.dstQueueFamilyIndex = queue_family, .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, 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)); 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) { if (src_buffer == VK_NULL_HANDLE) {
return; 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()); boost::container::small_vector<VkBufferCopy, 8> vk_copies(copies.size());
std::ranges::transform(copies, vk_copies.begin(), MakeUnifiedUploadCopy); std::ranges::transform(copies, vk_copies.begin(), MakeUnifiedUploadCopy);
const bool foreign = unified_memory->NeedsForeignOwnershipTransfer();
const u32 queue_family = device.GetGraphicsFamily();
scheduler.RequestOutsideRenderPassOperationContext(); 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)); 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) { StagingBufferRef BufferCacheRuntime::UploadStagingBuffer(size_t size) {
return staging_pool.Request(size, MemoryUsage::Upload); 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 UnifiedMemoryUploadBarrier();
void UnifiedMemoryShaderWriteBarrier();
u64 CurrentTick(); u64 CurrentTick();
u64 KnownGpuTick(); u64 KnownGpuTick();
@ -253,6 +255,8 @@ private:
VkFormat TexelBufferFormat(VideoCore::Surface::PixelFormat format) const; VkFormat TexelBufferFormat(VideoCore::Surface::PixelFormat format) const;
void AcquireUnifiedWindowsFromForeign();
void ReserveNullBuffer(); void ReserveNullBuffer();
vk::Buffer CreateNullBuffer(); vk::Buffer CreateNullBuffer();

Loading…
Cancel
Save