mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-22 11:56:58 +02:00
shader: support returning 32-bit LDS compare-exchange (DS_CMPST_RTN_B32) (#1578)
* shader: support DS_CMPST_RTN_B32 Assassin's Creed Valhalla (PPSA01490, #281) stops on DS opcode 0x30 in a compute shader. DS compares DATA and stores DATA2, the opposite of BUFFER_ATOMIC_CMPSWAP, so the 32-bit atomic path swaps the two for this opcode, as the 64-bit form does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * shader: reject unsupported GDS compare-store variant --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
@@ -326,6 +326,7 @@ inline constexpr auto EmitSharedAtomicSMin32 = EmitAtomic32;
|
||||
inline constexpr auto EmitSharedAtomicUMin32 = EmitAtomic32;
|
||||
inline constexpr auto EmitSharedAtomicSMax32 = EmitAtomic32;
|
||||
inline constexpr auto EmitSharedAtomicUMax64 = EmitSharedAtomic64;
|
||||
inline constexpr auto EmitSharedAtomicCmpSwap32 = EmitAtomic32;
|
||||
inline constexpr auto EmitSharedAtomicCmpSwap64 = EmitSharedAtomic64;
|
||||
inline constexpr auto EmitSharedAtomicUMax32 = EmitAtomic32;
|
||||
inline constexpr auto EmitSharedAtomicAnd32 = EmitAtomic32;
|
||||
|
||||
@@ -504,6 +504,7 @@ uint32_t EncodePackedColorComponent(EmitterState& state, const Format::BufferFor
|
||||
|
||||
spv::Op SpirvAtomicOpcode(IR::ValueOpcode opcode) {
|
||||
switch (opcode) {
|
||||
case IR::ValueOpcode::SharedAtomicCmpSwap32:
|
||||
case IR::ValueOpcode::SharedAtomicCmpSwap64:
|
||||
case IR::ValueOpcode::ImageAtomicCompareSwap32:
|
||||
case IR::ValueOpcode::BufferAtomicCmpSwap32: return spv::OpAtomicCompareExchange;
|
||||
@@ -561,8 +562,12 @@ uint32_t EmitAtomicOperation(ValueEmitContext& ctx, const IR::Inst& inst, uint32
|
||||
const bool wide = inst.GetType() == IR::Type::U64;
|
||||
const auto type = wide ? TypeU64(ctx.state) : TypeU32(ctx.state);
|
||||
if (opcode == spv::OpAtomicCompareExchange) {
|
||||
const auto desired = ctx.Arg(inst, inst.NumArgs() - 3);
|
||||
const auto comparator = ctx.Arg(inst, inst.NumArgs() - 2);
|
||||
auto desired = ctx.Arg(inst, inst.NumArgs() - 3);
|
||||
auto comparator = ctx.Arg(inst, inst.NumArgs() - 2);
|
||||
if (inst.GetOpcode() == IR::ValueOpcode::SharedAtomicCmpSwap32) {
|
||||
// RDNA2 DS compares DATA and stores DATA2, opposite to BUFFER atomics.
|
||||
std::swap(desired, comparator);
|
||||
}
|
||||
ctx.state.builder.AddFunction(
|
||||
spv::OpAtomicCompareExchange, TypeU32(ctx.state), old, pointer,
|
||||
ConstantU32(ctx.state, scope), ConstantU32(ctx.state, spv::MemorySemanticsMaskNone),
|
||||
|
||||
Reference in New Issue
Block a user