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.Absolute, InstType.CallUnary, "abs");
|
||||||
Add(Instruction.Add, InstType.OpBinaryCom, "+", 2);
|
Add(Instruction.Add, InstType.OpBinaryCom, "+", 2);
|
||||||
Add(Instruction.Ballot, InstType.CallUnary, "ballotARB");
|
Add(Instruction.Ballot, InstType.CallUnary, "ballotARB");
|
||||||
|
Add(Instruction.Barrier, InstType.CallNullary, "barrier");
|
||||||
Add(Instruction.BitCount, InstType.CallUnary, "bitCount");
|
Add(Instruction.BitCount, InstType.CallUnary, "bitCount");
|
||||||
Add(Instruction.BitfieldExtractS32, InstType.CallTernary, "bitfieldExtract");
|
Add(Instruction.BitfieldExtractS32, InstType.CallTernary, "bitfieldExtract");
|
||||||
Add(Instruction.BitfieldExtractU32, 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.FindFirstSetU32, InstType.CallUnary, "findMSB");
|
||||||
Add(Instruction.Floor, InstType.CallUnary, "floor");
|
Add(Instruction.Floor, InstType.CallUnary, "floor");
|
||||||
Add(Instruction.FusedMultiplyAdd, InstType.CallTernary, "fma");
|
Add(Instruction.FusedMultiplyAdd, InstType.CallTernary, "fma");
|
||||||
|
Add(Instruction.GroupMemoryBarrier, InstType.CallNullary, "groupMemoryBarrier");
|
||||||
Add(Instruction.ImageLoad, InstType.Special);
|
Add(Instruction.ImageLoad, InstType.Special);
|
||||||
Add(Instruction.ImageStore, InstType.Special);
|
Add(Instruction.ImageStore, InstType.Special);
|
||||||
Add(Instruction.IsNan, InstType.CallUnary, "isnan");
|
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.ShuffleXor, InstType.CallTernary, HelperFunctionNames.ShuffleXor);
|
||||||
Add(Instruction.Maximum, InstType.CallBinary, "max");
|
Add(Instruction.Maximum, InstType.CallBinary, "max");
|
||||||
Add(Instruction.MaximumU32, InstType.CallBinary, "max");
|
Add(Instruction.MaximumU32, InstType.CallBinary, "max");
|
||||||
|
Add(Instruction.MemoryBarrier, InstType.CallNullary, "memoryBarrier");
|
||||||
Add(Instruction.Minimum, InstType.CallBinary, "min");
|
Add(Instruction.Minimum, InstType.CallBinary, "min");
|
||||||
Add(Instruction.MinimumU32, InstType.CallBinary, "min");
|
Add(Instruction.MinimumU32, InstType.CallBinary, "min");
|
||||||
Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1);
|
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("1110111111011x", InstEmit.Ald, typeof(OpCodeAttribute));
|
||||||
Set("1110111111110x", InstEmit.Ast, typeof(OpCodeAttribute));
|
Set("1110111111110x", InstEmit.Ast, typeof(OpCodeAttribute));
|
||||||
Set("11101100xxxxxx", InstEmit.Atoms, typeof(OpCodeAtom));
|
Set("11101100xxxxxx", InstEmit.Atoms, typeof(OpCodeAtom));
|
||||||
|
Set("1111000010101x", InstEmit.Bar, typeof(OpCodeBarrier));
|
||||||
Set("0100110000000x", InstEmit.Bfe, typeof(OpCodeAluCbuf));
|
Set("0100110000000x", InstEmit.Bfe, typeof(OpCodeAluCbuf));
|
||||||
Set("0011100x00000x", InstEmit.Bfe, typeof(OpCodeAluImm));
|
Set("0011100x00000x", InstEmit.Bfe, typeof(OpCodeAluImm));
|
||||||
Set("0101110000000x", InstEmit.Bfe, typeof(OpCodeAluReg));
|
Set("0101110000000x", InstEmit.Bfe, typeof(OpCodeAluReg));
|
||||||
|
@ -140,6 +141,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
Set("0010000xxxxxxx", InstEmit.Lop3, typeof(OpCodeLopCbuf));
|
Set("0010000xxxxxxx", InstEmit.Lop3, typeof(OpCodeLopCbuf));
|
||||||
Set("001111xxxxxxxx", InstEmit.Lop3, typeof(OpCodeLopImm));
|
Set("001111xxxxxxxx", InstEmit.Lop3, typeof(OpCodeLopImm));
|
||||||
Set("0101101111100x", InstEmit.Lop3, typeof(OpCodeLopReg));
|
Set("0101101111100x", InstEmit.Lop3, typeof(OpCodeLopReg));
|
||||||
|
Set("1110111110011x", InstEmit.Membar, typeof(OpCodeMemoryBarrier));
|
||||||
Set("0100110010011x", InstEmit.Mov, typeof(OpCodeAluCbuf));
|
Set("0100110010011x", InstEmit.Mov, typeof(OpCodeAluCbuf));
|
||||||
Set("0011100x10011x", InstEmit.Mov, typeof(OpCodeAluImm));
|
Set("0011100x10011x", InstEmit.Mov, typeof(OpCodeAluImm));
|
||||||
Set("000000010000xx", InstEmit.Mov, typeof(OpCodeAluImm32));
|
Set("000000010000xx", InstEmit.Mov, typeof(OpCodeAluImm32));
|
||||||
|
|
|
@ -77,6 +77,17 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
context.Copy(GetDest(context), res);
|
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)
|
public static void Ipa(EmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeIpa op = (OpCodeIpa)context.CurrOp;
|
OpCodeIpa op = (OpCodeIpa)context.CurrOp;
|
||||||
|
@ -162,6 +173,20 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
EmitLoad(context, MemoryRegion.Shared);
|
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)
|
public static void Out(EmitterContext context)
|
||||||
{
|
{
|
||||||
OpCode op = context.CurrOp;
|
OpCode op = context.CurrOp;
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
AtomicSwap,
|
AtomicSwap,
|
||||||
AtomicXor,
|
AtomicXor,
|
||||||
Ballot,
|
Ballot,
|
||||||
|
Barrier,
|
||||||
BitCount,
|
BitCount,
|
||||||
BitfieldExtractS32,
|
BitfieldExtractS32,
|
||||||
BitfieldExtractU32,
|
BitfieldExtractU32,
|
||||||
|
@ -62,6 +63,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
FindFirstSetU32,
|
FindFirstSetU32,
|
||||||
Floor,
|
Floor,
|
||||||
FusedMultiplyAdd,
|
FusedMultiplyAdd,
|
||||||
|
GroupMemoryBarrier,
|
||||||
ImageLoad,
|
ImageLoad,
|
||||||
ImageStore,
|
ImageStore,
|
||||||
IsNan,
|
IsNan,
|
||||||
|
@ -82,6 +84,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
MarkLabel,
|
MarkLabel,
|
||||||
Maximum,
|
Maximum,
|
||||||
MaximumU32,
|
MaximumU32,
|
||||||
|
MemoryBarrier,
|
||||||
Minimum,
|
Minimum,
|
||||||
MinimumU32,
|
MinimumU32,
|
||||||
Multiply,
|
Multiply,
|
||||||
|
|
|
@ -61,6 +61,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return context.Add(Instruction.Ballot, Local(), a);
|
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)
|
public static Operand BitCount(this EmitterContext context, Operand a)
|
||||||
{
|
{
|
||||||
return context.Add(Instruction.BitCount, Local(), 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));
|
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)
|
public static Operand IAbsNeg(this EmitterContext context, Operand a, bool abs, bool neg)
|
||||||
{
|
{
|
||||||
return context.INegate(context.IAbsolute(a, abs), 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);
|
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)
|
public static Operand MultiplyHighS32(this EmitterContext context, Operand a, Operand b)
|
||||||
{
|
{
|
||||||
return context.Add(Instruction.MultiplyHighS32, Local(), a, b);
|
return context.Add(Instruction.MultiplyHighS32, Local(), a, b);
|
||||||
|
|
Loading…
Reference in a new issue