Partial support for shader memory barriers
This commit is contained in:
parent
1a550e810c
commit
2eccc7023a
9 changed files with 98 additions and 0 deletions
|
@ -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);
|
||||
|
|
10
Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs
Normal file
10
Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum BarrierLevel
|
||||
{
|
||||
Cta = 0,
|
||||
Gl = 1,
|
||||
Sys = 2,
|
||||
Vc = 3
|
||||
}
|
||||
}
|
12
Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs
Normal file
12
Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
enum BarrierMode
|
||||
{
|
||||
ReductionPopCount = 2,
|
||||
Scan = 3,
|
||||
ReductionAnd = 0xa,
|
||||
ReductionOr = 0x12,
|
||||
Sync = 0x80,
|
||||
Arrive = 0x81
|
||||
}
|
||||
}
|
14
Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs
Normal file
14
Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
14
Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs
Normal file
14
Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Reference in a new issue