mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-10-20 16:50:05 +02:00
A quick test on global memory cbuf tracker
This commit is contained in:
parent
b8d9f44421
commit
dfe0b7e7c7
6 changed files with 34 additions and 17 deletions
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -32,10 +35,10 @@ void GlobalStorageOp(EmitContext& ctx, Register address, bool pointer_based, std
|
||||||
std::string_view else_expr = {}) {
|
std::string_view else_expr = {}) {
|
||||||
const size_t num_buffers{ctx.info.storage_buffers_descriptors.size()};
|
const size_t num_buffers{ctx.info.storage_buffers_descriptors.size()};
|
||||||
for (size_t index = 0; index < num_buffers; ++index) {
|
for (size_t index = 0; index < num_buffers; ++index) {
|
||||||
if (!ctx.info.nvn_buffer_used[index]) {
|
const auto& ssbo{ctx.info.storage_buffers_descriptors[index]};
|
||||||
|
if (!ssbo.is_global_fallback) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto& ssbo{ctx.info.storage_buffers_descriptors[index]};
|
|
||||||
const u64 ssbo_align_mask{~(ctx.profile.min_ssbo_alignment - 1U)};
|
const u64 ssbo_align_mask{~(ctx.profile.min_ssbo_alignment - 1U)};
|
||||||
ctx.Add("LDC.U64 DC.x,c{}[{}];" // unaligned_ssbo_addr
|
ctx.Add("LDC.U64 DC.x,c{}[{}];" // unaligned_ssbo_addr
|
||||||
"AND.U64 DC.x,DC.x,{};" // ssbo_addr = unaligned_ssbo_addr & ssbo_align_mask
|
"AND.U64 DC.x,DC.x,{};" // ssbo_addr = unaligned_ssbo_addr & ssbo_align_mask
|
||||||
|
|
@ -65,9 +68,10 @@ void GlobalStorageOp(EmitContext& ctx, Register address, bool pointer_based, std
|
||||||
if (!else_expr.empty()) {
|
if (!else_expr.empty()) {
|
||||||
ctx.Add("{}", else_expr);
|
ctx.Add("{}", else_expr);
|
||||||
}
|
}
|
||||||
const size_t num_used_buffers{ctx.info.nvn_buffer_used.count()};
|
for (const auto& ssbo : ctx.info.storage_buffers_descriptors) {
|
||||||
for (size_t index = 0; index < num_used_buffers; ++index) {
|
if (ssbo.is_global_fallback) {
|
||||||
ctx.Add("ENDIF;");
|
ctx.Add("ENDIF;");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -633,7 +633,7 @@ std::string EmitContext::DefineGlobalMemoryFunctions() {
|
||||||
std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){"};
|
std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){"};
|
||||||
const size_t num_buffers{info.storage_buffers_descriptors.size()};
|
const size_t num_buffers{info.storage_buffers_descriptors.size()};
|
||||||
for (size_t index = 0; index < num_buffers; ++index) {
|
for (size_t index = 0; index < num_buffers; ++index) {
|
||||||
if (!info.nvn_buffer_used[index]) {
|
if (!info.storage_buffers_descriptors[index].is_global_fallback) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
define_body(write_func, index, "{0}[uint(addr-{1})>>2]=data;return;}}");
|
define_body(write_func, index, "{0}[uint(addr-{1})>>2]=data;return;}}");
|
||||||
|
|
|
||||||
|
|
@ -948,12 +948,16 @@ void EmitContext::DefineGlobalMemoryFunctions(const Info& info) {
|
||||||
const auto define_body{[&](DefPtr ssbo_member, Id addr, Id element_pointer, u32 shift,
|
const auto define_body{[&](DefPtr ssbo_member, Id addr, Id element_pointer, u32 shift,
|
||||||
auto&& callback) {
|
auto&& callback) {
|
||||||
AddLabel();
|
AddLabel();
|
||||||
|
const Id addr_words{OpBitcast(U32[2], addr)};
|
||||||
|
const Id addr_low{OpCompositeExtract(U32[1], addr_words, 0U)};
|
||||||
|
const Id addr_high{OpCompositeExtract(U32[1], addr_words, 1U)};
|
||||||
|
const Id align_mask{Const(~(static_cast<u32>(profile.min_ssbo_alignment) - 1U))};
|
||||||
const size_t num_buffers{info.storage_buffers_descriptors.size()};
|
const size_t num_buffers{info.storage_buffers_descriptors.size()};
|
||||||
for (size_t index = 0; index < num_buffers; ++index) {
|
for (size_t index = 0; index < num_buffers; ++index) {
|
||||||
if (!info.nvn_buffer_used[index]) {
|
const auto& ssbo{info.storage_buffers_descriptors[index]};
|
||||||
|
if (!ssbo.is_global_fallback) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto& ssbo{info.storage_buffers_descriptors[index]};
|
|
||||||
const Id ssbo_addr_cbuf_offset{Const(ssbo.cbuf_offset / 8)};
|
const Id ssbo_addr_cbuf_offset{Const(ssbo.cbuf_offset / 8)};
|
||||||
const Id ssbo_size_cbuf_offset{Const(ssbo.cbuf_offset / 4 + 2)};
|
const Id ssbo_size_cbuf_offset{Const(ssbo.cbuf_offset / 4 + 2)};
|
||||||
const Id ssbo_addr_pointer{OpAccessChain(
|
const Id ssbo_addr_pointer{OpAccessChain(
|
||||||
|
|
@ -961,20 +965,23 @@ void EmitContext::DefineGlobalMemoryFunctions(const Info& info) {
|
||||||
const Id ssbo_size_pointer{OpAccessChain(uniform_types.U32, cbufs[ssbo.cbuf_index].U32,
|
const Id ssbo_size_pointer{OpAccessChain(uniform_types.U32, cbufs[ssbo.cbuf_index].U32,
|
||||||
zero, ssbo_size_cbuf_offset)};
|
zero, ssbo_size_cbuf_offset)};
|
||||||
|
|
||||||
const u64 ssbo_align_mask{~(profile.min_ssbo_alignment - 1U)};
|
const Id ssbo_addr{OpLoad(U32[2], ssbo_addr_pointer)};
|
||||||
const Id unaligned_addr{OpBitcast(U64, OpLoad(U32[2], ssbo_addr_pointer))};
|
const Id ssbo_low{
|
||||||
const Id ssbo_addr{OpBitwiseAnd(U64, unaligned_addr, Constant(U64, ssbo_align_mask))};
|
OpBitwiseAnd(U32[1], OpCompositeExtract(U32[1], ssbo_addr, 0U), align_mask)};
|
||||||
const Id ssbo_size{OpUConvert(U64, OpLoad(U32[1], ssbo_size_pointer))};
|
const Id ssbo_high{OpCompositeExtract(U32[1], ssbo_addr, 1U)};
|
||||||
const Id ssbo_end{OpIAdd(U64, ssbo_addr, ssbo_size)};
|
const Id ssbo_size{OpLoad(U32[1], ssbo_size_pointer)};
|
||||||
const Id cond{OpLogicalAnd(U1, OpUGreaterThanEqual(U1, addr, ssbo_addr),
|
const Id ssbo_offset{OpISub(U32[1], addr_low, ssbo_low)};
|
||||||
OpULessThan(U1, addr, ssbo_end))};
|
const Id borrow{
|
||||||
|
OpSelect(U32[1], OpULessThan(U1, addr_low, ssbo_low), Const(1U), zero)};
|
||||||
|
const Id cond{
|
||||||
|
OpLogicalAnd(U1, OpULessThan(U1, ssbo_offset, ssbo_size),
|
||||||
|
OpIEqual(U1, OpISub(U32[1], addr_high, borrow), ssbo_high))};
|
||||||
const Id then_label{OpLabel()};
|
const Id then_label{OpLabel()};
|
||||||
const Id else_label{OpLabel()};
|
const Id else_label{OpLabel()};
|
||||||
OpSelectionMerge(else_label, spv::SelectionControlMask::MaskNone);
|
OpSelectionMerge(else_label, spv::SelectionControlMask::MaskNone);
|
||||||
OpBranchConditional(cond, then_label, else_label);
|
OpBranchConditional(cond, then_label, else_label);
|
||||||
AddLabel(then_label);
|
AddLabel(then_label);
|
||||||
const Id ssbo_id{ssbos[index].*ssbo_member};
|
const Id ssbo_id{ssbos[index].*ssbo_member};
|
||||||
const Id ssbo_offset{OpUConvert(U32[1], OpISub(U64, addr, ssbo_addr))};
|
|
||||||
const Id ssbo_index{OpShiftRightLogical(U32[1], ssbo_offset, Const(shift))};
|
const Id ssbo_index{OpShiftRightLogical(U32[1], ssbo_offset, Const(shift))};
|
||||||
const Id ssbo_pointer{OpAccessChain(element_pointer, ssbo_id, zero, ssbo_index)};
|
const Id ssbo_pointer{OpAccessChain(element_pointer, ssbo_id, zero, ssbo_index)};
|
||||||
callback(ssbo_pointer);
|
callback(ssbo_pointer);
|
||||||
|
|
|
||||||
|
|
@ -121,9 +121,12 @@ void AddNVNStorageBuffers(IR::Program& program) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const u32 offset{base + index * descriptor_size};
|
const u32 offset{base + index * descriptor_size};
|
||||||
const auto it{std::ranges::find(descs, offset, &StorageBufferDescriptor::cbuf_offset)};
|
const auto it{std::ranges::find_if(descs, [&](const StorageBufferDescriptor& desc) {
|
||||||
|
return desc.cbuf_index == driver_cbuf && desc.cbuf_offset == offset;
|
||||||
|
})};
|
||||||
if (it != descs.end()) {
|
if (it != descs.end()) {
|
||||||
it->is_written |= program.info.stores_global_memory;
|
it->is_written |= program.info.stores_global_memory;
|
||||||
|
it->is_global_fallback = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
descs.push_back({
|
descs.push_back({
|
||||||
|
|
@ -131,6 +134,7 @@ void AddNVNStorageBuffers(IR::Program& program) {
|
||||||
.cbuf_offset = offset,
|
.cbuf_offset = offset,
|
||||||
.count = 1,
|
.count = 1,
|
||||||
.is_written = program.info.stores_global_memory,
|
.is_written = program.info.stores_global_memory,
|
||||||
|
.is_global_fallback = true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -562,6 +562,7 @@ void JoinStorageInfo(Info& base, Info& source) {
|
||||||
})};
|
})};
|
||||||
if (it != descriptors.end()) {
|
if (it != descriptors.end()) {
|
||||||
it->is_written |= desc.is_written;
|
it->is_written |= desc.is_written;
|
||||||
|
it->is_global_fallback |= desc.is_global_fallback;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
descriptors.push_back(desc);
|
descriptors.push_back(desc);
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,7 @@ struct StorageBufferDescriptor {
|
||||||
u32 cbuf_offset;
|
u32 cbuf_offset;
|
||||||
u32 count;
|
u32 count;
|
||||||
bool is_written;
|
bool is_written;
|
||||||
|
bool is_global_fallback{};
|
||||||
|
|
||||||
auto operator<=>(const StorageBufferDescriptor&) const = default;
|
auto operator<=>(const StorageBufferDescriptor&) const = default;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue