diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2021-01-27 20:59:47 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-28 10:59:47 +1100 |
| commit | 4b7c7dab9e33faaf4eb58342f1f7ad8ada354591 (patch) | |
| tree | d912e9e3434fb3ba53afad5fee216eadde731cc6 /Ryujinx.Graphics.Shader/IntermediateRepresentation | |
| parent | dcce4070719a3798bb96d3aa02b9ba02a7fecc16 (diff) | |
Support multiple destination operands on shader IR and shuffle predicates (#1964)
* Support multiple destination operands on shader IR and shuffle predicates
* Cache version change
Diffstat (limited to 'Ryujinx.Graphics.Shader/IntermediateRepresentation')
3 files changed, 94 insertions, 19 deletions
diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/INode.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/INode.cs index 48dda24b..0f545e56 100644 --- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/INode.cs +++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/INode.cs @@ -4,8 +4,10 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation { Operand Dest { get; set; } + int DestsCount { get; } int SourcesCount { get; } + Operand GetDest(int index); Operand GetSource(int index); void SetSource(int index, Operand operand); diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs index a86a278a..4f0801b7 100644 --- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs +++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs @@ -6,25 +6,42 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation { public Instruction Inst { get; private set; } - private Operand _dest; + private Operand[] _dests; public Operand Dest { - get => _dest; - set => _dest = AssignDest(value); + get + { + return _dests.Length != 0 ? _dests[0] : null; + } + set + { + if (value != null && value.Type == OperandType.LocalVariable) + { + value.AsgOp = this; + } + + if (value != null) + { + _dests = new[] { value }; + } + else + { + _dests = Array.Empty<Operand>(); + } + } } + public int DestsCount => _dests.Length; + private Operand[] _sources; public int SourcesCount => _sources.Length; public int Index { get; } - public Operation(Instruction inst, Operand dest, params Operand[] sources) + private Operation(Operand[] sources) { - Inst = inst; - Dest = dest; - // The array may be modified externally, so we store a copy. _sources = (Operand[])sources.Clone(); @@ -39,11 +56,42 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation } } - public Operation( - Instruction inst, - int index, - Operand dest, - params Operand[] sources) : this(inst, dest, sources) + public Operation(Instruction inst, int index, Operand[] dests, Operand[] sources) : this(sources) + { + Inst = inst; + Index = index; + + // The array may be modified externally, so we store a copy. + _dests = (Operand[])dests.Clone(); + + for (int dstIndex = 0; dstIndex < dests.Length; dstIndex++) + { + Operand dest = dests[dstIndex]; + + if (dest != null && dest.Type == OperandType.LocalVariable) + { + dest.AsgOp = this; + } + } + } + + public Operation(Instruction inst, Operand dest, params Operand[] sources) : this(sources) + { + Inst = inst; + + if (dest != null) + { + dest.AsgOp = this; + + _dests = new[] { dest }; + } + else + { + _dests = Array.Empty<Operand>(); + } + } + + public Operation(Instruction inst, int index, Operand dest, params Operand[] sources) : this(inst, dest, sources) { Index = index; } @@ -67,14 +115,9 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation } } - private Operand AssignDest(Operand dest) + public Operand GetDest(int index) { - if (dest != null && dest.Type == OperandType.LocalVariable) - { - dest.AsgOp = this; - } - - return dest; + return _dests[index]; } public Operand GetSource(int index) @@ -82,6 +125,23 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation return _sources[index]; } + public void SetDest(int index, Operand dest) + { + Operand oldDest = _dests[index]; + + if (oldDest != null && oldDest.Type == OperandType.LocalVariable) + { + oldDest.AsgOp = null; + } + + if (dest != null && dest.Type == OperandType.LocalVariable) + { + dest.AsgOp = this; + } + + _dests[index] = dest; + } + public void SetSource(int index, Operand source) { Operand oldSrc = _sources[index]; diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/PhiNode.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/PhiNode.cs index 13ff41bd..8fa25ae9 100644 --- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/PhiNode.cs +++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/PhiNode.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace Ryujinx.Graphics.Shader.IntermediateRepresentation @@ -12,6 +13,8 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation set => _dest = AssignDest(value); } + public int DestsCount => _dest != null ? 1 : 0; + private HashSet<BasicBlock> _blocks; private class PhiSource @@ -64,6 +67,16 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation } } + public Operand GetDest(int index) + { + if (index != 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return _dest; + } + public Operand GetSource(int index) { return _sources[index].Operand; |
