Add support for fragment shader interlock (#2768)
* Support coherent images * Add support for fragment shader interlock * Change to tree based match approach * Refactor + check for branch targets and external registers * Make detection more robust * Use Intel fragment shader ordering if interlock is not available, use nothing if both are not available * Remove unused field
This commit is contained in:
@ -56,14 +56,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
||||
public static void Cont(EmitterContext context)
|
||||
{
|
||||
InstContUnsup op = context.GetOp<InstContUnsup>();
|
||||
InstCont op = context.GetOp<InstCont>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction ContUnsup is not implemented.");
|
||||
}
|
||||
|
||||
public static void Cset(EmitterContext context)
|
||||
{
|
||||
InstCsetUnsup op = context.GetOp<InstCsetUnsup>();
|
||||
InstCset op = context.GetOp<InstCset>();
|
||||
|
||||
context.Config.GpuAccessor.Log("Shader instruction CsetUnsup is not implemented.");
|
||||
}
|
||||
|
@ -67,7 +67,24 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
{
|
||||
InstCal op = context.GetOp<InstCal>();
|
||||
|
||||
context.Call(context.GetFunctionId(context.CurrOp.GetAbsoluteAddress()), false);
|
||||
DecodedFunction function = context.Program.GetFunctionByAddress(context.CurrOp.GetAbsoluteAddress());
|
||||
|
||||
if (function.IsCompilerGenerated)
|
||||
{
|
||||
switch (function.Type)
|
||||
{
|
||||
case FunctionType.BuiltInFSIBegin:
|
||||
context.FSIBegin();
|
||||
break;
|
||||
case FunctionType.BuiltInFSIEnd:
|
||||
context.FSIEnd();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Call(function.Id, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Exit(EmitterContext context)
|
||||
|
@ -109,28 +109,28 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
{
|
||||
InstSuldDB op = context.GetOp<InstSuldDB>();
|
||||
|
||||
EmitSuld(context, op.Dim, op.Size, 0, 0, op.SrcA, op.Dest, op.SrcC, useComponents: false, op.Ba, isBindless: true);
|
||||
EmitSuld(context, op.CacheOp, op.Dim, op.Size, 0, 0, op.SrcA, op.Dest, op.SrcC, useComponents: false, op.Ba, isBindless: true);
|
||||
}
|
||||
|
||||
public static void SuldD(EmitterContext context)
|
||||
{
|
||||
InstSuldD op = context.GetOp<InstSuldD>();
|
||||
|
||||
EmitSuld(context, op.Dim, op.Size, op.TidB, 0, op.SrcA, op.Dest, 0, useComponents: false, op.Ba, isBindless: false);
|
||||
EmitSuld(context, op.CacheOp, op.Dim, op.Size, op.TidB, 0, op.SrcA, op.Dest, 0, useComponents: false, op.Ba, isBindless: false);
|
||||
}
|
||||
|
||||
public static void SuldB(EmitterContext context)
|
||||
{
|
||||
InstSuldB op = context.GetOp<InstSuldB>();
|
||||
|
||||
EmitSuld(context, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: true);
|
||||
EmitSuld(context, op.CacheOp, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: true);
|
||||
}
|
||||
|
||||
public static void Suld(EmitterContext context)
|
||||
{
|
||||
InstSuld op = context.GetOp<InstSuld>();
|
||||
|
||||
EmitSuld(context, op.Dim, 0, op.TidB, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: false);
|
||||
EmitSuld(context, op.CacheOp, op.Dim, 0, op.TidB, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: false);
|
||||
}
|
||||
|
||||
public static void SuredB(EmitterContext context)
|
||||
@ -151,28 +151,28 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
{
|
||||
InstSustDB op = context.GetOp<InstSustDB>();
|
||||
|
||||
EmitSust(context, op.Dim, op.Size, 0, 0, op.SrcA, op.Dest, op.SrcC, useComponents: false, op.Ba, isBindless: true);
|
||||
EmitSust(context, op.CacheOp, op.Dim, op.Size, 0, 0, op.SrcA, op.Dest, op.SrcC, useComponents: false, op.Ba, isBindless: true);
|
||||
}
|
||||
|
||||
public static void SustD(EmitterContext context)
|
||||
{
|
||||
InstSustD op = context.GetOp<InstSustD>();
|
||||
|
||||
EmitSust(context, op.Dim, op.Size, op.TidB, 0, op.SrcA, op.Dest, 0, useComponents: false, op.Ba, isBindless: false);
|
||||
EmitSust(context, op.CacheOp, op.Dim, op.Size, op.TidB, 0, op.SrcA, op.Dest, 0, useComponents: false, op.Ba, isBindless: false);
|
||||
}
|
||||
|
||||
public static void SustB(EmitterContext context)
|
||||
{
|
||||
InstSustB op = context.GetOp<InstSustB>();
|
||||
|
||||
EmitSust(context, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, op.SrcC, useComponents: true, false, isBindless: true);
|
||||
EmitSust(context, op.CacheOp, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, op.SrcC, useComponents: true, false, isBindless: true);
|
||||
}
|
||||
|
||||
public static void Sust(EmitterContext context)
|
||||
{
|
||||
InstSust op = context.GetOp<InstSust>();
|
||||
|
||||
EmitSust(context, op.Dim, 0, op.TidB, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: false);
|
||||
EmitSust(context, op.CacheOp, op.Dim, 0, op.TidB, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: false);
|
||||
}
|
||||
|
||||
private static void EmitSuatom(
|
||||
@ -299,6 +299,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
||||
private static void EmitSuld(
|
||||
EmitterContext context,
|
||||
CacheOpLd cacheOp,
|
||||
SuDim dimensions,
|
||||
SuSize size,
|
||||
int imm,
|
||||
@ -363,6 +364,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
||||
TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
|
||||
|
||||
if (cacheOp == CacheOpLd.Cg)
|
||||
{
|
||||
flags |= TextureFlags.Coherent;
|
||||
}
|
||||
|
||||
if (useComponents)
|
||||
{
|
||||
for (int compMask = (int)componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
|
||||
@ -546,6 +552,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
||||
private static void EmitSust(
|
||||
EmitterContext context,
|
||||
CacheOpSt cacheOp,
|
||||
SuDim dimensions,
|
||||
SuSize size,
|
||||
int imm,
|
||||
@ -654,6 +661,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
||||
TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
|
||||
|
||||
if (cacheOp == CacheOpSt.Cg)
|
||||
{
|
||||
flags |= TextureFlags.Coherent;
|
||||
}
|
||||
|
||||
TextureOperation operation = context.CreateTextureOperation(
|
||||
Instruction.ImageStore,
|
||||
type,
|
||||
|
Reference in New Issue
Block a user