From 053dcfdb0572da9c03d4343a82ac69ac44e3276b Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 31 Jan 2021 21:13:38 -0300 Subject: [PATCH 1/2] Use multiple dest operands for shader call instructions (#1975) * Use multiple dest operands for shader call instructions * Passing opNode is no longer needed --- .../IntermediateRepresentation/Instruction.cs | 1 - .../IntermediateRepresentation/Operation.cs | 23 +++++++++++- .../StructuredIr/StructuredProgram.cs | 35 ++----------------- .../Translation/Optimizations/Optimizer.cs | 9 +++-- .../Translation/RegisterUsage.cs | 14 ++++---- Ryujinx.Graphics.Shader/Translation/Ssa.cs | 2 +- .../Translation/Translator.cs | 1 - 7 files changed, 40 insertions(+), 45 deletions(-) diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs index c0356e464..13fd55ec5 100644 --- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs +++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs @@ -32,7 +32,6 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation BranchIfFalse, BranchIfTrue, Call, - CallOutArgument, Ceiling, Clamp, ClampU32, diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs index 4f0801b7b..955beafde 100644 --- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs +++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; namespace Ryujinx.Graphics.Shader.IntermediateRepresentation { @@ -96,7 +97,27 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation Index = index; } - public void AppendOperands(params Operand[] operands) + public void AppendDests(Operand[] operands) + { + int startIndex = _dests.Length; + + Array.Resize(ref _dests, startIndex + operands.Length); + + for (int index = 0; index < operands.Length; index++) + { + Operand dest = operands[index]; + + if (dest != null && dest.Type == OperandType.LocalVariable) + { + Debug.Assert(dest.AsgOp == null); + dest.AsgOp = this; + } + + _dests[startIndex + index] = dest; + } + } + + public void AppendSources(Operand[] operands) { int startIndex = _sources.Length; diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs index 497cffc88..4a0ea8468 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs @@ -51,9 +51,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { context.LeaveBlock(block, operation); } - else if (operation.Inst != Instruction.CallOutArgument) + else { - AddOperation(context, opNode); + AddOperation(context, operation); } } } @@ -68,32 +68,13 @@ namespace Ryujinx.Graphics.Shader.StructuredIr return context.Info; } - private static void AddOperation(StructuredProgramContext context, LinkedListNode opNode) + private static void AddOperation(StructuredProgramContext context, Operation operation) { - Operation operation = (Operation)opNode.Value; - Instruction inst = operation.Inst; - bool isCall = inst == Instruction.Call; - int sourcesCount = operation.SourcesCount; int outDestsCount = operation.DestsCount != 0 ? operation.DestsCount - 1 : 0; - List callOutOperands = new List(); - - if (isCall) - { - LinkedListNode scan = opNode.Next; - - while (scan != null && scan.Value is Operation nextOp && nextOp.Inst == Instruction.CallOutArgument) - { - callOutOperands.Add(nextOp.Dest); - scan = scan.Next; - } - - sourcesCount += callOutOperands.Count; - } - IAstNode[] sources = new IAstNode[sourcesCount + outDestsCount]; for (int index = 0; index < operation.SourcesCount; index++) @@ -101,16 +82,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr sources[index] = context.GetOperandUse(operation.GetSource(index)); } - if (isCall) - { - for (int index = 0; index < callOutOperands.Count; index++) - { - sources[operation.SourcesCount + index] = context.GetOperandDef(callOutOperands[index]); - } - - callOutOperands.Clear(); - } - for (int index = 0; index < outDestsCount; index++) { AstOperand oper = context.GetOperandDef(operation.GetDest(1 + index)); diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs index 9a0815c3a..61b1544f7 100644 --- a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs +++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs @@ -289,7 +289,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations case Instruction.AtomicSwap: case Instruction.AtomicXor: case Instruction.Call: - case Instruction.CallOutArgument: return true; } } @@ -306,7 +305,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations for (int index = 0; index < node.DestsCount; index++) { - if (node.GetDest(index).Type != OperandType.LocalVariable) + Operand dest = node.GetDest(index); + + if (dest != null && dest.Type != OperandType.LocalVariable) { return false; } @@ -319,7 +320,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations { for (int index = 0; index < node.DestsCount; index++) { - if (node.GetDest(index).UseOps.Count != 0) + Operand dest = node.GetDest(index); + + if (dest != null && dest.UseOps.Count != 0) { return false; } diff --git a/Ryujinx.Graphics.Shader/Translation/RegisterUsage.cs b/Ryujinx.Graphics.Shader/Translation/RegisterUsage.cs index fd90391f4..158ba5ef9 100644 --- a/Ryujinx.Graphics.Shader/Translation/RegisterUsage.cs +++ b/Ryujinx.Graphics.Shader/Translation/RegisterUsage.cs @@ -299,21 +299,23 @@ namespace Ryujinx.Graphics.Shader.Translation var fru = frus[funcId.Value]; - Operand[] regs = new Operand[fru.InArguments.Length]; + Operand[] inRegs = new Operand[fru.InArguments.Length]; for (int i = 0; i < fru.InArguments.Length; i++) { - regs[i] = OperandHelper.Register(fru.InArguments[i]); + inRegs[i] = OperandHelper.Register(fru.InArguments[i]); } - operation.AppendOperands(regs); + operation.AppendSources(inRegs); + + Operand[] outRegs = new Operand[1 + fru.OutArguments.Length]; for (int i = 0; i < fru.OutArguments.Length; i++) { - Operation callOutArgOp = new Operation(Instruction.CallOutArgument, OperandHelper.Register(fru.OutArguments[i])); - - node = block.Operations.AddAfter(node, callOutArgOp); + outRegs[1 + i] = OperandHelper.Register(fru.OutArguments[i]); } + + operation.AppendDests(outRegs); } } } diff --git a/Ryujinx.Graphics.Shader/Translation/Ssa.cs b/Ryujinx.Graphics.Shader/Translation/Ssa.cs index ff812e646..ff0fa2b7f 100644 --- a/Ryujinx.Graphics.Shader/Translation/Ssa.cs +++ b/Ryujinx.Graphics.Shader/Translation/Ssa.cs @@ -120,7 +120,7 @@ namespace Ryujinx.Graphics.Shader.Translation { Operand dest = operation.GetDest(index); - if (dest.Type == OperandType.Register) + if (dest != null && dest.Type == OperandType.Register) { Operand local = Local(); diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs index 85a46d196..e52c1ccf4 100644 --- a/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs @@ -88,7 +88,6 @@ namespace Ryujinx.Graphics.Shader.Translation RegisterUsage.FixupCalls(cfg.Blocks, frus); Dominance.FindDominators(cfg); - Dominance.FindDominanceFrontiers(cfg.Blocks); Ssa.Rename(cfg.Blocks); From 67033ed8e05eb70860ac6af2b83deab0256c11eb Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 1 Feb 2021 04:30:16 -0300 Subject: [PATCH 2/2] Do not flush multisample textures (#1973) --- Ryujinx.Graphics.Gpu/Image/Texture.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index 3c576cb71..6dfe46288 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -723,6 +723,12 @@ namespace Ryujinx.Graphics.Gpu.Image return; // Flushing this format is not supported, as it may have been converted to another host format. } + if (Info.Target == Target.Texture2DMultisample || + Info.Target == Target.Texture2DMultisampleArray) + { + return; // Flushing multisample textures is not supported, the host does not allow getting their data. + } + ITexture texture = HostTexture; if (ScaleFactor != 1f) {