aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-12-14 14:51:00 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit2eccc7023ae0d1247378516b14507d422e4915c5 (patch)
tree8ae9a8905394717347a775997ae0347483a9b0d8
parent1a550e810c71670e5a2f032ec136fb2f5f57ac9c (diff)
Partial support for shader memory barriers
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs3
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs10
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs12
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs14
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs14
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs2
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs25
-rw-r--r--Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs3
-rw-r--r--Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs15
9 files changed, 98 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
index ef998fdd..8dec3499 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
@@ -26,6 +26,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.Absolute, InstType.CallUnary, "abs");
Add(Instruction.Add, InstType.OpBinaryCom, "+", 2);
Add(Instruction.Ballot, InstType.CallUnary, "ballotARB");
+ Add(Instruction.Barrier, InstType.CallNullary, "barrier");
Add(Instruction.BitCount, InstType.CallUnary, "bitCount");
Add(Instruction.BitfieldExtractS32, InstType.CallTernary, "bitfieldExtract");
Add(Instruction.BitfieldExtractU32, InstType.CallTernary, "bitfieldExtract");
@@ -65,6 +66,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.FindFirstSetU32, InstType.CallUnary, "findMSB");
Add(Instruction.Floor, InstType.CallUnary, "floor");
Add(Instruction.FusedMultiplyAdd, InstType.CallTernary, "fma");
+ Add(Instruction.GroupMemoryBarrier, InstType.CallNullary, "groupMemoryBarrier");
Add(Instruction.ImageLoad, InstType.Special);
Add(Instruction.ImageStore, InstType.Special);
Add(Instruction.IsNan, InstType.CallUnary, "isnan");
@@ -91,6 +93,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.ShuffleXor, InstType.CallTernary, HelperFunctionNames.ShuffleXor);
Add(Instruction.Maximum, InstType.CallBinary, "max");
Add(Instruction.MaximumU32, InstType.CallBinary, "max");
+ Add(Instruction.MemoryBarrier, InstType.CallNullary, "memoryBarrier");
Add(Instruction.Minimum, InstType.CallBinary, "min");
Add(Instruction.MinimumU32, InstType.CallBinary, "min");
Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1);
diff --git a/Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs b/Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs
new file mode 100644
index 00000000..2d99dcfe
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+ enum BarrierLevel
+ {
+ Cta = 0,
+ Gl = 1,
+ Sys = 2,
+ Vc = 3
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs b/Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs
new file mode 100644
index 00000000..a058cbbd
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+ enum BarrierMode
+ {
+ ReductionPopCount = 2,
+ Scan = 3,
+ ReductionAnd = 0xa,
+ ReductionOr = 0x12,
+ Sync = 0x80,
+ Arrive = 0x81
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs
new file mode 100644
index 00000000..81e28aa1
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs
@@ -0,0 +1,14 @@
+using Ryujinx.Graphics.Shader.Instructions;
+
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+ class OpCodeBarrier : OpCode
+ {
+ public BarrierMode Mode { get; }
+
+ public OpCodeBarrier(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
+ {
+ Mode = (BarrierMode)((opCode >> 32) & 0x9b);
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs
new file mode 100644
index 00000000..c31fe87b
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs
@@ -0,0 +1,14 @@
+using Ryujinx.Graphics.Shader.Instructions;
+
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+ class OpCodeMemoryBarrier : OpCode
+ {
+ public BarrierLevel Level { get; }
+
+ public OpCodeMemoryBarrier(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
+ {
+ Level = (BarrierLevel)opCode.Extract(8, 2);
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
index bdc7ed80..87f1de0c 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
@@ -33,6 +33,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
Set("1110111111011x", InstEmit.Ald, typeof(OpCodeAttribute));
Set("1110111111110x", InstEmit.Ast, typeof(OpCodeAttribute));
Set("11101100xxxxxx", InstEmit.Atoms, typeof(OpCodeAtom));
+ Set("1111000010101x", InstEmit.Bar, typeof(OpCodeBarrier));
Set("0100110000000x", InstEmit.Bfe, typeof(OpCodeAluCbuf));
Set("0011100x00000x", InstEmit.Bfe, typeof(OpCodeAluImm));
Set("0101110000000x", InstEmit.Bfe, typeof(OpCodeAluReg));
@@ -140,6 +141,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
Set("0010000xxxxxxx", InstEmit.Lop3, typeof(OpCodeLopCbuf));
Set("001111xxxxxxxx", InstEmit.Lop3, typeof(OpCodeLopImm));
Set("0101101111100x", InstEmit.Lop3, typeof(OpCodeLopReg));
+ Set("1110111110011x", InstEmit.Membar, typeof(OpCodeMemoryBarrier));
Set("0100110010011x", InstEmit.Mov, typeof(OpCodeAluCbuf));
Set("0011100x10011x", InstEmit.Mov, typeof(OpCodeAluImm));
Set("000000010000xx", InstEmit.Mov, typeof(OpCodeAluImm32));
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index 56688161..866df56d 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -77,6 +77,17 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Copy(GetDest(context), res);
}
+ public static void Bar(EmitterContext context)
+ {
+ OpCodeBarrier op = (OpCodeBarrier)context.CurrOp;
+
+ // TODO: Support other modes.
+ if (op.Mode == BarrierMode.Sync)
+ {
+ context.Barrier();
+ }
+ }
+
public static void Ipa(EmitterContext context)
{
OpCodeIpa op = (OpCodeIpa)context.CurrOp;
@@ -162,6 +173,20 @@ namespace Ryujinx.Graphics.Shader.Instructions
EmitLoad(context, MemoryRegion.Shared);
}
+ public static void Membar(EmitterContext context)
+ {
+ OpCodeMemoryBarrier op = (OpCodeMemoryBarrier)context.CurrOp;
+
+ if (op.Level == BarrierLevel.Cta)
+ {
+ context.GroupMemoryBarrier();
+ }
+ else
+ {
+ context.MemoryBarrier();
+ }
+ }
+
public static void Out(EmitterContext context)
{
OpCode op = context.CurrOp;
diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs
index bffdd0fa..7108112c 100644
--- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs
+++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs
@@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
AtomicSwap,
AtomicXor,
Ballot,
+ Barrier,
BitCount,
BitfieldExtractS32,
BitfieldExtractU32,
@@ -62,6 +63,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
FindFirstSetU32,
Floor,
FusedMultiplyAdd,
+ GroupMemoryBarrier,
ImageLoad,
ImageStore,
IsNan,
@@ -82,6 +84,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
MarkLabel,
Maximum,
MaximumU32,
+ MemoryBarrier,
Minimum,
MinimumU32,
Multiply,
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
index e39d8c64..14675a55 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
@@ -61,6 +61,11 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.Ballot, Local(), a);
}
+ public static Operand Barrier(this EmitterContext context)
+ {
+ return context.Add(Instruction.Barrier);
+ }
+
public static Operand BitCount(this EmitterContext context, Operand a)
{
return context.Add(Instruction.BitCount, Local(), a);
@@ -336,6 +341,11 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.SwizzleAdd, Local(), a, b, Const(mask));
}
+ public static Operand GroupMemoryBarrier(this EmitterContext context)
+ {
+ return context.Add(Instruction.GroupMemoryBarrier);
+ }
+
public static Operand IAbsNeg(this EmitterContext context, Operand a, bool abs, bool neg)
{
return context.INegate(context.IAbsolute(a, abs), neg);
@@ -476,6 +486,11 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.LoadShared, Local(), a);
}
+ public static Operand MemoryBarrier(this EmitterContext context)
+ {
+ return context.Add(Instruction.MemoryBarrier);
+ }
+
public static Operand MultiplyHighS32(this EmitterContext context, Operand a, Operand b)
{
return context.Add(Instruction.MultiplyHighS32, Local(), a, b);