Support multiple destination operands on shader IR and shuffle predicates (#1964)
* Support multiple destination operands on shader IR and shuffle predicates * Cache version change
This commit is contained in:
parent
dcce407071
commit
4b7c7dab9e
16 changed files with 199 additions and 79 deletions
|
@ -37,6 +37,17 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return dest;
|
||||
}
|
||||
|
||||
public (Operand, Operand) Add(Instruction inst, (Operand, Operand) dest, params Operand[] sources)
|
||||
{
|
||||
Operand[] dests = new[] { dest.Item1, dest.Item2 };
|
||||
|
||||
Operation operation = new Operation(inst, 0, dests, sources);
|
||||
|
||||
Add(operation);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
public void Add(Operation operation)
|
||||
{
|
||||
_operations.Add(operation);
|
||||
|
|
|
@ -588,24 +588,24 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return context.Add(Instruction.ShiftRightU32, Local(), a, b);
|
||||
}
|
||||
|
||||
public static Operand Shuffle(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
public static (Operand, Operand) Shuffle(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
{
|
||||
return context.Add(Instruction.Shuffle, Local(), a, b, c);
|
||||
return context.Add(Instruction.Shuffle, (Local(), Local()), a, b, c);
|
||||
}
|
||||
|
||||
public static Operand ShuffleDown(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
public static (Operand, Operand) ShuffleDown(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
{
|
||||
return context.Add(Instruction.ShuffleDown, Local(), a, b, c);
|
||||
return context.Add(Instruction.ShuffleDown, (Local(), Local()), a, b, c);
|
||||
}
|
||||
|
||||
public static Operand ShuffleUp(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
public static (Operand, Operand) ShuffleUp(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
{
|
||||
return context.Add(Instruction.ShuffleUp, Local(), a, b, c);
|
||||
return context.Add(Instruction.ShuffleUp, (Local(), Local()), a, b, c);
|
||||
}
|
||||
|
||||
public static Operand ShuffleXor(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
public static (Operand, Operand) ShuffleXor(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
{
|
||||
return context.Add(Instruction.ShuffleXor, Local(), a, b, c);
|
||||
return context.Add(Instruction.ShuffleXor, (Local(), Local()), a, b, c);
|
||||
}
|
||||
|
||||
public static Operand StoreGlobal(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
else if ((operation.Inst == Instruction.PackHalf2x16 && PropagatePack(operation)) ||
|
||||
(operation.Inst == Instruction.ShuffleXor && MatchDdxOrDdy(operation)))
|
||||
{
|
||||
if (operation.Dest.UseOps.Count == 0)
|
||||
if (DestHasNoUses(operation))
|
||||
{
|
||||
RemoveNode(block, node);
|
||||
}
|
||||
|
@ -260,6 +260,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
if (src.UseOps.Remove(node) && src.UseOps.Count == 0)
|
||||
{
|
||||
Debug.Assert(src.AsgOp != null);
|
||||
nodes.Enqueue(src.AsgOp);
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +269,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
private static bool IsUnused(INode node)
|
||||
{
|
||||
return !HasSideEffects(node) && DestIsLocalVar(node) && node.Dest.UseOps.Count == 0;
|
||||
return !HasSideEffects(node) && DestIsLocalVar(node) && DestHasNoUses(node);
|
||||
}
|
||||
|
||||
private static bool HasSideEffects(INode node)
|
||||
|
@ -298,7 +299,33 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
private static bool DestIsLocalVar(INode node)
|
||||
{
|
||||
return node.Dest != null && node.Dest.Type == OperandType.LocalVariable;
|
||||
if (node.DestsCount == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = 0; index < node.DestsCount; index++)
|
||||
{
|
||||
if (node.GetDest(index).Type != OperandType.LocalVariable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DestHasNoUses(INode node)
|
||||
{
|
||||
for (int index = 0; index < node.DestsCount; index++)
|
||||
{
|
||||
if (node.GetDest(index).UseOps.Count != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -116,13 +116,18 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
operation.SetSource(index, RenameLocal(operation.GetSource(index)));
|
||||
}
|
||||
|
||||
if (operation.Dest != null && operation.Dest.Type == OperandType.Register)
|
||||
for (int index = 0; index < operation.DestsCount; index++)
|
||||
{
|
||||
Operand local = Local();
|
||||
Operand dest = operation.GetDest(index);
|
||||
|
||||
localDefs[GetKeyFromRegister(operation.Dest.GetRegister())] = local;
|
||||
if (dest.Type == OperandType.Register)
|
||||
{
|
||||
Operand local = Local();
|
||||
|
||||
operation.Dest = local;
|
||||
localDefs[GetKeyFromRegister(dest.GetRegister())] = local;
|
||||
|
||||
operation.SetDest(index, local);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,9 +190,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return operand;
|
||||
}
|
||||
|
||||
LinkedListNode<INode> node = block.Operations.First;
|
||||
|
||||
while (node != null)
|
||||
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
|
||||
{
|
||||
if (node.Value is Operation operation)
|
||||
{
|
||||
|
@ -196,8 +199,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
operation.SetSource(index, RenameGlobal(operation.GetSource(index)));
|
||||
}
|
||||
}
|
||||
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue