mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-11-24 14:24:14 +00:00
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,
|
||||
BitwiseOr = 6,
|
||||
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 Rb { get; }
|
||||
|
||||
public ReductionType Type { get; }
|
||||
|
||||
public int Offset { get; }
|
||||
|
||||
public bool Extended { get; }
|
||||
|
||||
public AtomicOp AtomicOp { get; }
|
||||
|
@ -24,15 +20,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
Ra = new Register(opCode.Extract(8, 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);
|
||||
|
||||
AtomicOp = (AtomicOp)opCode.Extract(52, 4);
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
#region Instructions
|
||||
Set("1110111111011x", InstEmit.Ald, OpCodeAttribute.Create);
|
||||
Set("1110111111110x", InstEmit.Ast, OpCodeAttribute.Create);
|
||||
Set("11101101xxxxxx", InstEmit.Atom, OpCodeAtom.Create);
|
||||
Set("11101100xxxxxx", InstEmit.Atoms, OpCodeAtom.Create);
|
||||
Set("1111000010101x", InstEmit.Bar, OpCodeBarrier.Create);
|
||||
Set("0100110000000x", InstEmit.Bfe, OpCodeAluCbuf.Create);
|
||||
|
|
|
@ -2,11 +2,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
{
|
||||
enum ReductionType
|
||||
{
|
||||
U32 = 0,
|
||||
S32 = 1,
|
||||
U64 = 2,
|
||||
FP32FtzRn = 3,
|
||||
U128 = 4,
|
||||
S64 = 5
|
||||
U32 = 0,
|
||||
S32 = 1,
|
||||
U64 = 2,
|
||||
FP32FtzRn = 3,
|
||||
FP16x2FtzRn = 4,
|
||||
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)
|
||||
{
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
|
@ -71,7 +105,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
context,
|
||||
Instruction.MrShared,
|
||||
op.AtomicOp,
|
||||
op.Type,
|
||||
type,
|
||||
offset,
|
||||
Const(0),
|
||||
value);
|
||||
|
|
Loading…
Reference in a new issue