Implement ATOM shader instruction (#1687)
* Implement ATOM shader instruction * Fix reduction type decoding
This commit is contained in:
parent
934a78005e
commit
c3d62bd078
5 changed files with 45 additions and 22 deletions
|
@ -10,6 +10,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
BitwiseAnd = 5,
|
BitwiseAnd = 5,
|
||||||
BitwiseOr = 6,
|
BitwiseOr = 6,
|
||||||
BitwiseExclusiveOr = 7,
|
BitwiseExclusiveOr = 7,
|
||||||
Swap = 8
|
Swap = 8,
|
||||||
|
SafeAdd = 10 // Only supported by ATOM.
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,10 +8,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
public Register Ra { get; }
|
public Register Ra { get; }
|
||||||
public Register Rb { get; }
|
public Register Rb { get; }
|
||||||
|
|
||||||
public ReductionType Type { get; }
|
|
||||||
|
|
||||||
public int Offset { get; }
|
|
||||||
|
|
||||||
public bool Extended { get; }
|
public bool Extended { get; }
|
||||||
|
|
||||||
public AtomicOp AtomicOp { get; }
|
public AtomicOp AtomicOp { get; }
|
||||||
|
@ -24,15 +20,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
|
Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
|
||||||
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
|
Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
|
||||||
|
|
||||||
Type = (ReductionType)opCode.Extract(28, 2);
|
|
||||||
|
|
||||||
if (Type == ReductionType.FP32FtzRn)
|
|
||||||
{
|
|
||||||
Type = ReductionType.S64;
|
|
||||||
}
|
|
||||||
|
|
||||||
Offset = opCode.Extract(30, 22);
|
|
||||||
|
|
||||||
Extended = opCode.Extract(48);
|
Extended = opCode.Extract(48);
|
||||||
|
|
||||||
AtomicOp = (AtomicOp)opCode.Extract(52, 4);
|
AtomicOp = (AtomicOp)opCode.Extract(52, 4);
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
#region Instructions
|
#region Instructions
|
||||||
Set("1110111111011x", InstEmit.Ald, OpCodeAttribute.Create);
|
Set("1110111111011x", InstEmit.Ald, OpCodeAttribute.Create);
|
||||||
Set("1110111111110x", InstEmit.Ast, OpCodeAttribute.Create);
|
Set("1110111111110x", InstEmit.Ast, OpCodeAttribute.Create);
|
||||||
|
Set("11101101xxxxxx", InstEmit.Atom, OpCodeAtom.Create);
|
||||||
Set("11101100xxxxxx", InstEmit.Atoms, OpCodeAtom.Create);
|
Set("11101100xxxxxx", InstEmit.Atoms, OpCodeAtom.Create);
|
||||||
Set("1111000010101x", InstEmit.Bar, OpCodeBarrier.Create);
|
Set("1111000010101x", InstEmit.Bar, OpCodeBarrier.Create);
|
||||||
Set("0100110000000x", InstEmit.Bfe, OpCodeAluCbuf.Create);
|
Set("0100110000000x", InstEmit.Bfe, OpCodeAluCbuf.Create);
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
S32 = 1,
|
S32 = 1,
|
||||||
U64 = 2,
|
U64 = 2,
|
||||||
FP32FtzRn = 3,
|
FP32FtzRn = 3,
|
||||||
U128 = 4,
|
FP16x2FtzRn = 4,
|
||||||
S64 = 5
|
S64 = 5
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -57,13 +57,47 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Atom(EmitterContext context)
|
||||||
|
{
|
||||||
|
OpCodeAtom op = (OpCodeAtom)context.CurrOp;
|
||||||
|
|
||||||
|
ReductionType type = (ReductionType)op.RawOpCode.Extract(49, 2);
|
||||||
|
|
||||||
|
int sOffset = (op.RawOpCode.Extract(28, 20) << 12) >> 12;
|
||||||
|
|
||||||
|
(Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, op.Ra, op.Extended, sOffset);
|
||||||
|
|
||||||
|
Operand value = GetSrcB(context);
|
||||||
|
|
||||||
|
Operand res = EmitAtomicOp(
|
||||||
|
context,
|
||||||
|
Instruction.MrGlobal,
|
||||||
|
op.AtomicOp,
|
||||||
|
type,
|
||||||
|
addrLow,
|
||||||
|
addrHigh,
|
||||||
|
value);
|
||||||
|
|
||||||
|
context.Copy(GetDest(context), res);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Atoms(EmitterContext context)
|
public static void Atoms(EmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeAtom op = (OpCodeAtom)context.CurrOp;
|
OpCodeAtom op = (OpCodeAtom)context.CurrOp;
|
||||||
|
|
||||||
|
ReductionType type = op.RawOpCode.Extract(28, 2) switch
|
||||||
|
{
|
||||||
|
0 => ReductionType.U32,
|
||||||
|
1 => ReductionType.S32,
|
||||||
|
2 => ReductionType.U64,
|
||||||
|
_ => ReductionType.S64
|
||||||
|
};
|
||||||
|
|
||||||
Operand offset = context.ShiftRightU32(GetSrcA(context), Const(2));
|
Operand offset = context.ShiftRightU32(GetSrcA(context), Const(2));
|
||||||
|
|
||||||
offset = context.IAdd(offset, Const(op.Offset));
|
int sOffset = (op.RawOpCode.Extract(30, 22) << 10) >> 10;
|
||||||
|
|
||||||
|
offset = context.IAdd(offset, Const(sOffset));
|
||||||
|
|
||||||
Operand value = GetSrcB(context);
|
Operand value = GetSrcB(context);
|
||||||
|
|
||||||
|
@ -71,7 +105,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
context,
|
context,
|
||||||
Instruction.MrShared,
|
Instruction.MrShared,
|
||||||
op.AtomicOp,
|
op.AtomicOp,
|
||||||
op.Type,
|
type,
|
||||||
offset,
|
offset,
|
||||||
Const(0),
|
Const(0),
|
||||||
value);
|
value);
|
||||||
|
|
Loading…
Reference in a new issue