1
0
Fork 0
mirror of https://github.com/Ryujinx/Ryujinx.git synced 2024-10-01 12:30:00 +02:00

Implement ATOM shader instruction (#1687)

* Implement ATOM shader instruction

* Fix reduction type decoding
This commit is contained in:
gdkchan 2020-11-09 21:06:46 -03:00 committed by GitHub
parent 934a78005e
commit c3d62bd078
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 22 deletions

View file

@ -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.
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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
}
}

View file

@ -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);