aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/IntermediateRepresentation
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-01-27 20:59:47 -0300
committerGitHub <noreply@github.com>2021-01-28 10:59:47 +1100
commit4b7c7dab9e33faaf4eb58342f1f7ad8ada354591 (patch)
treed912e9e3434fb3ba53afad5fee216eadde731cc6 /Ryujinx.Graphics.Shader/IntermediateRepresentation
parentdcce4070719a3798bb96d3aa02b9ba02a7fecc16 (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')
-rw-r--r--Ryujinx.Graphics.Shader/IntermediateRepresentation/INode.cs2
-rw-r--r--Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs98
-rw-r--r--Ryujinx.Graphics.Shader/IntermediateRepresentation/PhiNode.cs13
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;