Step back + keeping fixes from unified download + shared mem refactor

This commit is contained in:
CamilleLaVey 2026-08-11 18:50:22 -04:00
parent 17463f7b0d
commit d93039fb42
11 changed files with 53 additions and 133 deletions

View file

@ -412,56 +412,33 @@ void BufferCacheRuntime::TryEnableUnifiedMemory(void* base, size_t size,
}
}
void BufferCacheRuntime::QueueUnifiedCopy(size_t window_index, VkBuffer buffer,
std::span<const VideoCommon::BufferCopy> copies,
bool reads_window) {
if (!unified_memory || buffer == VK_NULL_HANDLE || copies.empty() ||
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() ||
unified_memory->GetWindowBuffer(window_index) == VK_NULL_HANDLE) {
return;
}
PendingUnifiedCopy& pending = pending_unified_copies.emplace_back();
pending.window = window_index;
pending.buffer = buffer;
pending.reads_window = reads_window;
pending.buffer = src_buffer;
pending.copies.resize(copies.size());
std::ranges::transform(copies, pending.copies.begin(), MakeBufferCopy);
}
void BufferCacheRuntime::CopyToUnifiedMemory(
size_t window_index, VkBuffer src_buffer,
std::span<const VideoCommon::BufferCopy> copies) {
QueueUnifiedCopy(window_index, src_buffer, copies, false);
}
void BufferCacheRuntime::CopyFromUnifiedMemory(
size_t window_index, VkBuffer dst_buffer,
std::span<const VideoCommon::BufferCopy> copies) {
QueueUnifiedCopy(window_index, dst_buffer, copies, true);
}
void BufferCacheRuntime::FlushUnifiedMemoryCopies() {
if (pending_unified_copies.empty()) {
return;
}
struct UnifiedCopyCommand {
VkBuffer buffer;
bool reads_window;
boost::container::small_vector<VkBufferCopy, 8> copies;
};
static constexpr VkMemoryBarrier WINDOW_TRANSFER_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
};
std::stable_sort(pending_unified_copies.begin(), pending_unified_copies.end(),
[](const PendingUnifiedCopy& lhs, const PendingUnifiedCopy& rhs) {
if (lhs.window != rhs.window) {
return lhs.window < rhs.window;
}
return lhs.reads_window && !rhs.reads_window;
});
const bool foreign = unified_memory->NeedsForeignOwnershipTransfer();
@ -478,20 +455,9 @@ void BufferCacheRuntime::FlushUnifiedMemoryCopies() {
const VkBuffer window_buffer = unified_memory->GetWindowBuffer(window);
WindowRanges ranges;
VkAccessFlags window_access = 0;
size_t reads_in_group = 0;
for (size_t index = group_begin; index < group_end; ++index) {
const PendingUnifiedCopy& pending = pending_unified_copies[index];
if (pending.reads_window) {
window_access |= VK_ACCESS_TRANSFER_READ_BIT;
++reads_in_group;
} else {
window_access |= VK_ACCESS_TRANSFER_WRITE_BIT;
}
for (const VkBufferCopy& copy : pending.copies) {
const VkDeviceSize offset =
pending.reads_window ? copy.srcOffset : copy.dstOffset;
ranges.emplace_back(offset, offset + copy.size);
for (const VkBufferCopy& copy : pending_unified_copies[index].copies) {
ranges.emplace_back(copy.dstOffset, copy.dstOffset + copy.size);
}
}
CoalesceWindowRanges(ranges);
@ -504,7 +470,7 @@ void BufferCacheRuntime::FlushUnifiedMemoryCopies() {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = 0,
.dstAccessMask = window_access,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
.dstQueueFamilyIndex = queue_family,
.buffer = window_buffer,
@ -514,7 +480,7 @@ void BufferCacheRuntime::FlushUnifiedMemoryCopies() {
release.push_back(VkBufferMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = window_access,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = 0,
.srcQueueFamilyIndex = queue_family,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
@ -529,37 +495,21 @@ void BufferCacheRuntime::FlushUnifiedMemoryCopies() {
commands.reserve(group_end - group_begin);
for (size_t index = group_begin; index < group_end; ++index) {
PendingUnifiedCopy& pending = pending_unified_copies[index];
commands.push_back(UnifiedCopyCommand{pending.buffer, pending.reads_window,
std::move(pending.copies)});
commands.push_back(UnifiedCopyCommand{pending.buffer, std::move(pending.copies)});
}
const size_t barrier_before_writes = (reads_in_group > 0 && reads_in_group < commands.size())
? reads_in_group
: commands.size();
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([window_buffer, barrier_before_writes, acquire = std::move(acquire),
release = std::move(release),
scheduler.Record([window_buffer, acquire = std::move(acquire), release = std::move(release),
commands = std::move(commands)](vk::CommandBuffer cmdbuf) {
if (!acquire.empty()) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, {},
VideoCommon::FixSmallVectorADL(acquire), {});
}
for (size_t index = 0; index < commands.size(); ++index) {
if (index == barrier_before_writes) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
WINDOW_TRANSFER_BARRIER);
}
const UnifiedCopyCommand& command = commands[index];
if (command.reads_window) {
cmdbuf.CopyBuffer(window_buffer, command.buffer,
VideoCommon::FixSmallVectorADL(command.copies));
} else {
for (const UnifiedCopyCommand& command : commands) {
cmdbuf.CopyBuffer(command.buffer, window_buffer,
VideoCommon::FixSmallVectorADL(command.copies));
}
}
if (!release.empty()) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, {},

View file

@ -135,9 +135,6 @@ public:
void CopyToUnifiedMemory(size_t window_index, VkBuffer src_buffer,
std::span<const VideoCommon::BufferCopy> copies);
void CopyFromUnifiedMemory(size_t window_index, VkBuffer dst_buffer,
std::span<const VideoCommon::BufferCopy> copies);
void FlushUnifiedMemoryCopies();
void UnifiedMemoryHostBarrier();
@ -268,13 +265,9 @@ private:
struct PendingUnifiedCopy {
size_t window;
VkBuffer buffer;
bool reads_window;
boost::container::small_vector<VkBufferCopy, 8> copies;
};
void QueueUnifiedCopy(size_t window_index, VkBuffer buffer,
std::span<const VideoCommon::BufferCopy> copies, bool reads_window);
void BindBuffer(const Buffer& buffer, u32 offset, u32 size) {
const VkBuffer handle = buffer.Handle();
if (handle == VK_NULL_HANDLE) {

View file

@ -451,6 +451,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.has_broken_fp32_denorm_flush = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
.ignore_nan_fp_comparisons = false,
.has_broken_spirv_subgroup_mask_vector_extract_dynamic = false,
.max_shared_memory_size = device.GetMaxComputeSharedMemorySize(),
.has_broken_robust =
device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Pascal,
.min_ssbo_alignment = device.GetStorageBufferAlignment(),
@ -969,19 +970,6 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
}
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
const VkDriverIdKHR driver_id = device.GetDriverID();
const bool needs_shared_mem_clamp =
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
const u32 max_shared_memory = device.GetMaxComputeSharedMemorySize();
if (needs_shared_mem_clamp && program.shared_memory_size > max_shared_memory) {
LOG_WARNING(Render_Vulkan,
"Compute shader {:#016x} requests {}KB shared memory but device max is {}KB - clamping",
key.unique_hash,
program.shared_memory_size / 1024,
max_shared_memory / 1024);
program.shared_memory_size = max_shared_memory;
}
const std::vector<u32> code{EmitSPIRV(profile, program)};
device.SaveShader(code);
vk::ShaderModule spv_module{BuildShader(device, code)};