mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 10:04:39 +00:00
shader_recompiler: Fix some shared memory accesses when workgroup struct is omitted. (#3110)
This commit is contained in:
parent
efa8f6a154
commit
5bc4cc761a
@ -19,8 +19,7 @@ Id SharedAtomicU32(EmitContext& ctx, Id offset, Id value,
|
|||||||
const Id shift_id{ctx.ConstU32(2U)};
|
const Id shift_id{ctx.ConstU32(2U)};
|
||||||
const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)};
|
const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)};
|
||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
||||||
const Id pointer{
|
const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index)};
|
||||||
ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32, ctx.u32_zero_value, index)};
|
|
||||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||||
return AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
return AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value);
|
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value);
|
||||||
@ -32,8 +31,7 @@ Id SharedAtomicU32IncDec(EmitContext& ctx, Id offset,
|
|||||||
const Id shift_id{ctx.ConstU32(2U)};
|
const Id shift_id{ctx.ConstU32(2U)};
|
||||||
const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)};
|
const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)};
|
||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
||||||
const Id pointer{
|
const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index)};
|
||||||
ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32, ctx.u32_zero_value, index)};
|
|
||||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||||
return AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
return AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics);
|
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics);
|
||||||
@ -45,8 +43,7 @@ Id SharedAtomicU64(EmitContext& ctx, Id offset, Id value,
|
|||||||
const Id shift_id{ctx.ConstU32(3U)};
|
const Id shift_id{ctx.ConstU32(3U)};
|
||||||
const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)};
|
const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)};
|
||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 8u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 8u)};
|
||||||
const Id pointer{
|
const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index)};
|
||||||
ctx.OpAccessChain(ctx.shared_u64, ctx.shared_memory_u64, ctx.u32_zero_value, index)};
|
|
||||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||||
return AccessBoundsCheck<64>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
return AccessBoundsCheck<64>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
return (ctx.*atomic_func)(ctx.U64, pointer, scope, semantics, value);
|
return (ctx.*atomic_func)(ctx.U64, pointer, scope, semantics, value);
|
||||||
|
@ -14,10 +14,7 @@ Id EmitLoadSharedU16(EmitContext& ctx, Id offset) {
|
|||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 2u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 2u)};
|
||||||
|
|
||||||
return AccessBoundsCheck<16>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
return AccessBoundsCheck<16>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
const Id pointer = std::popcount(static_cast<u32>(ctx.info.shared_types)) > 1
|
const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u16, ctx.shared_memory_u16, index);
|
||||||
? ctx.OpAccessChain(ctx.shared_u16, ctx.shared_memory_u16,
|
|
||||||
ctx.u32_zero_value, index)
|
|
||||||
: ctx.OpAccessChain(ctx.shared_u16, ctx.shared_memory_u16, index);
|
|
||||||
return ctx.OpLoad(ctx.U16, pointer);
|
return ctx.OpLoad(ctx.U16, pointer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -28,10 +25,7 @@ Id EmitLoadSharedU32(EmitContext& ctx, Id offset) {
|
|||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
||||||
|
|
||||||
return AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
return AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
const Id pointer = std::popcount(static_cast<u32>(ctx.info.shared_types)) > 1
|
const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index);
|
||||||
? ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32,
|
|
||||||
ctx.u32_zero_value, index)
|
|
||||||
: ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32, index);
|
|
||||||
return ctx.OpLoad(ctx.U32[1], pointer);
|
return ctx.OpLoad(ctx.U32[1], pointer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -42,10 +36,7 @@ Id EmitLoadSharedU64(EmitContext& ctx, Id offset) {
|
|||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 8u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 8u)};
|
||||||
|
|
||||||
return AccessBoundsCheck<64>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
return AccessBoundsCheck<64>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
const Id pointer = std::popcount(static_cast<u32>(ctx.info.shared_types)) > 1
|
const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index);
|
||||||
? ctx.OpAccessChain(ctx.shared_u64, ctx.shared_memory_u64,
|
|
||||||
ctx.u32_zero_value, index)
|
|
||||||
: ctx.OpAccessChain(ctx.shared_u64, ctx.shared_memory_u64, index);
|
|
||||||
return ctx.OpLoad(ctx.U64, pointer);
|
return ctx.OpLoad(ctx.U64, pointer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -56,10 +47,7 @@ void EmitWriteSharedU16(EmitContext& ctx, Id offset, Id value) {
|
|||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 2u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 2u)};
|
||||||
|
|
||||||
AccessBoundsCheck<16>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
AccessBoundsCheck<16>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
const Id pointer = std::popcount(static_cast<u32>(ctx.info.shared_types)) > 1
|
const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u16, ctx.shared_memory_u16, index);
|
||||||
? ctx.OpAccessChain(ctx.shared_u16, ctx.shared_memory_u16,
|
|
||||||
ctx.u32_zero_value, index)
|
|
||||||
: ctx.OpAccessChain(ctx.shared_u16, ctx.shared_memory_u16, index);
|
|
||||||
ctx.OpStore(pointer, value);
|
ctx.OpStore(pointer, value);
|
||||||
return Id{0};
|
return Id{0};
|
||||||
});
|
});
|
||||||
@ -71,10 +59,7 @@ void EmitWriteSharedU32(EmitContext& ctx, Id offset, Id value) {
|
|||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 4u)};
|
||||||
|
|
||||||
AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
AccessBoundsCheck<32>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
const Id pointer = std::popcount(static_cast<u32>(ctx.info.shared_types)) > 1
|
const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index);
|
||||||
? ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32,
|
|
||||||
ctx.u32_zero_value, index)
|
|
||||||
: ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32, index);
|
|
||||||
ctx.OpStore(pointer, value);
|
ctx.OpStore(pointer, value);
|
||||||
return Id{0};
|
return Id{0};
|
||||||
});
|
});
|
||||||
@ -86,10 +71,7 @@ void EmitWriteSharedU64(EmitContext& ctx, Id offset, Id value) {
|
|||||||
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 8u)};
|
const u32 num_elements{Common::DivCeil(ctx.runtime_info.cs_info.shared_memory_size, 8u)};
|
||||||
|
|
||||||
AccessBoundsCheck<64>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
AccessBoundsCheck<64>(ctx, index, ctx.ConstU32(num_elements), [&] {
|
||||||
const Id pointer = std::popcount(static_cast<u32>(ctx.info.shared_types)) > 1
|
const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index);
|
||||||
? ctx.OpAccessChain(ctx.shared_u64, ctx.shared_memory_u64,
|
|
||||||
ctx.u32_zero_value, index)
|
|
||||||
: ctx.OpAccessChain(ctx.shared_u64, ctx.shared_memory_u64, index);
|
|
||||||
ctx.OpStore(pointer, value);
|
ctx.OpStore(pointer, value);
|
||||||
return Id{0};
|
return Id{0};
|
||||||
});
|
});
|
||||||
|
@ -203,6 +203,14 @@ public:
|
|||||||
return final_result;
|
return final_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id EmitSharedMemoryAccess(const Id result_type, const Id shared_mem, const Id index) {
|
||||||
|
if (std::popcount(static_cast<u32>(info.shared_types)) > 1) {
|
||||||
|
return OpAccessChain(result_type, shared_mem, u32_zero_value, index);
|
||||||
|
}
|
||||||
|
// Workgroup layout struct omitted.
|
||||||
|
return OpAccessChain(result_type, shared_mem, index);
|
||||||
|
}
|
||||||
|
|
||||||
Info& info;
|
Info& info;
|
||||||
const RuntimeInfo& runtime_info;
|
const RuntimeInfo& runtime_info;
|
||||||
const Profile& profile;
|
const Profile& profile;
|
||||||
|
Loading…
Reference in New Issue
Block a user