aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-11-09 21:06:46 -0300
committerGitHub <noreply@github.com>2020-11-10 01:06:46 +0100
commitc3d62bd0783a20efb78fa0776f4c620970774cf9 (patch)
tree9ed3aaf6e7eec9d11e43021633be29f122a1bf4a
parent934a78005e75653529c320cf90e78fe6536447c2 (diff)
Implement ATOM shader instruction (#1687)
* Implement ATOM shader instruction * Fix reduction type decoding
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs3
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs13
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs1
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/ReductionType.cs12
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs38
5 files changed, 45 insertions, 22 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs b/Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs
index 065a57c4..19955192 100644
--- a/Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs
@@ -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.
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs
index 1bf5d0cd..006a91f3 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs
@@ -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);
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
index 302f1fc4..8b9cb20d 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
@@ -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);
diff --git a/Ryujinx.Graphics.Shader/Decoders/ReductionType.cs b/Ryujinx.Graphics.Shader/Decoders/ReductionType.cs
index aaa2186e..4c8bd37e 100644
--- a/Ryujinx.Graphics.Shader/Decoders/ReductionType.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/ReductionType.cs
@@ -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
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index 2a2c8927..63f9cff7 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -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);