diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-10-13 03:02:07 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 1876b346fea647e8284a66bb6d62c38801035cff (patch) | |
| tree | 6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics/Shader/Translation/Optimizations | |
| parent | f617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff) | |
Initial work
Diffstat (limited to 'Ryujinx.Graphics/Shader/Translation/Optimizations')
5 files changed, 0 insertions, 753 deletions
diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/BranchElimination.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/BranchElimination.cs deleted file mode 100644 index 070f07a4..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/BranchElimination.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class BranchElimination - { - public static bool Eliminate(BasicBlock block) - { - if (block.HasBranch && IsRedundantBranch((Operation)block.GetLastOp(), Next(block))) - { - block.Branch = null; - - return true; - } - - return false; - } - - private static bool IsRedundantBranch(Operation current, BasicBlock nextBlock) - { - // Here we check that: - // - The current block ends with a branch. - // - The next block only contains a branch. - // - The branch on the next block is unconditional. - // - Both branches are jumping to the same location. - // In this case, the branch on the current block can be removed, - // as the next block is going to jump to the same place anyway. - if (nextBlock == null) - { - return false; - } - - if (!(nextBlock.Operations.First?.Value is Operation next)) - { - return false; - } - - if (next.Inst != Instruction.Branch) - { - return false; - } - - return current.Dest == next.Dest; - } - - private static BasicBlock Next(BasicBlock block) - { - block = block.Next; - - while (block != null && block.Operations.Count == 0) - { - if (block.HasBranch) - { - throw new InvalidOperationException("Found a bogus empty block that \"ends with a branch\"."); - } - - block = block.Next; - } - - return block; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/ConstantFolding.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/ConstantFolding.cs deleted file mode 100644 index a2e05ef1..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/ConstantFolding.cs +++ /dev/null @@ -1,323 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class ConstantFolding - { - public static void Fold(Operation operation) - { - if (!AreAllSourcesConstant(operation)) - { - return; - } - - switch (operation.Inst) - { - case Instruction.Add: - EvaluateBinary(operation, (x, y) => x + y); - break; - - case Instruction.BitwiseAnd: - EvaluateBinary(operation, (x, y) => x & y); - break; - - case Instruction.BitwiseExclusiveOr: - EvaluateBinary(operation, (x, y) => x ^ y); - break; - - case Instruction.BitwiseNot: - EvaluateUnary(operation, (x) => ~x); - break; - - case Instruction.BitwiseOr: - EvaluateBinary(operation, (x, y) => x | y); - break; - - case Instruction.BitfieldExtractS32: - BitfieldExtractS32(operation); - break; - - case Instruction.BitfieldExtractU32: - BitfieldExtractU32(operation); - break; - - case Instruction.Clamp: - EvaluateTernary(operation, (x, y, z) => Math.Clamp(x, y, z)); - break; - - case Instruction.ClampU32: - EvaluateTernary(operation, (x, y, z) => (int)Math.Clamp((uint)x, (uint)y, (uint)z)); - break; - - case Instruction.CompareEqual: - EvaluateBinary(operation, (x, y) => x == y); - break; - - case Instruction.CompareGreater: - EvaluateBinary(operation, (x, y) => x > y); - break; - - case Instruction.CompareGreaterOrEqual: - EvaluateBinary(operation, (x, y) => x >= y); - break; - - case Instruction.CompareGreaterOrEqualU32: - EvaluateBinary(operation, (x, y) => (uint)x >= (uint)y); - break; - - case Instruction.CompareGreaterU32: - EvaluateBinary(operation, (x, y) => (uint)x > (uint)y); - break; - - case Instruction.CompareLess: - EvaluateBinary(operation, (x, y) => x < y); - break; - - case Instruction.CompareLessOrEqual: - EvaluateBinary(operation, (x, y) => x <= y); - break; - - case Instruction.CompareLessOrEqualU32: - EvaluateBinary(operation, (x, y) => (uint)x <= (uint)y); - break; - - case Instruction.CompareLessU32: - EvaluateBinary(operation, (x, y) => (uint)x < (uint)y); - break; - - case Instruction.CompareNotEqual: - EvaluateBinary(operation, (x, y) => x != y); - break; - - case Instruction.Divide: - EvaluateBinary(operation, (x, y) => y != 0 ? x / y : 0); - break; - - case Instruction.FP | Instruction.Add: - EvaluateFPBinary(operation, (x, y) => x + y); - break; - - case Instruction.FP | Instruction.Clamp: - EvaluateFPTernary(operation, (x, y, z) => Math.Clamp(x, y, z)); - break; - - case Instruction.FP | Instruction.CompareEqual: - EvaluateFPBinary(operation, (x, y) => x == y); - break; - - case Instruction.FP | Instruction.CompareGreater: - EvaluateFPBinary(operation, (x, y) => x > y); - break; - - case Instruction.FP | Instruction.CompareGreaterOrEqual: - EvaluateFPBinary(operation, (x, y) => x >= y); - break; - - case Instruction.FP | Instruction.CompareLess: - EvaluateFPBinary(operation, (x, y) => x < y); - break; - - case Instruction.FP | Instruction.CompareLessOrEqual: - EvaluateFPBinary(operation, (x, y) => x <= y); - break; - - case Instruction.FP | Instruction.CompareNotEqual: - EvaluateFPBinary(operation, (x, y) => x != y); - break; - - case Instruction.FP | Instruction.Divide: - EvaluateFPBinary(operation, (x, y) => x / y); - break; - - case Instruction.FP | Instruction.Multiply: - EvaluateFPBinary(operation, (x, y) => x * y); - break; - - case Instruction.FP | Instruction.Negate: - EvaluateFPUnary(operation, (x) => -x); - break; - - case Instruction.FP | Instruction.Subtract: - EvaluateFPBinary(operation, (x, y) => x - y); - break; - - case Instruction.IsNan: - EvaluateFPUnary(operation, (x) => float.IsNaN(x)); - break; - - case Instruction.Maximum: - EvaluateBinary(operation, (x, y) => Math.Max(x, y)); - break; - - case Instruction.MaximumU32: - EvaluateBinary(operation, (x, y) => (int)Math.Max((uint)x, (uint)y)); - break; - - case Instruction.Minimum: - EvaluateBinary(operation, (x, y) => Math.Min(x, y)); - break; - - case Instruction.MinimumU32: - EvaluateBinary(operation, (x, y) => (int)Math.Min((uint)x, (uint)y)); - break; - - case Instruction.Multiply: - EvaluateBinary(operation, (x, y) => x * y); - break; - - case Instruction.Negate: - EvaluateUnary(operation, (x) => -x); - break; - - case Instruction.ShiftLeft: - EvaluateBinary(operation, (x, y) => x << y); - break; - - case Instruction.ShiftRightS32: - EvaluateBinary(operation, (x, y) => x >> y); - break; - - case Instruction.ShiftRightU32: - EvaluateBinary(operation, (x, y) => (int)((uint)x >> y)); - break; - - case Instruction.Subtract: - EvaluateBinary(operation, (x, y) => x - y); - break; - - case Instruction.UnpackHalf2x16: - UnpackHalf2x16(operation); - break; - } - } - - private static bool AreAllSourcesConstant(Operation operation) - { - for (int index = 0; index < operation.SourcesCount; index++) - { - if (operation.GetSource(index).Type != OperandType.Constant) - { - return false; - } - } - - return true; - } - - private static void BitfieldExtractS32(Operation operation) - { - int value = GetBitfieldExtractValue(operation); - - int shift = 32 - operation.GetSource(2).Value; - - value = (value << shift) >> shift; - - operation.TurnIntoCopy(Const(value)); - } - - private static void BitfieldExtractU32(Operation operation) - { - operation.TurnIntoCopy(Const(GetBitfieldExtractValue(operation))); - } - - private static int GetBitfieldExtractValue(Operation operation) - { - int value = operation.GetSource(0).Value; - int lsb = operation.GetSource(1).Value; - int length = operation.GetSource(2).Value; - - return value.Extract(lsb, length); - } - - private static void UnpackHalf2x16(Operation operation) - { - int value = operation.GetSource(0).Value; - - value = (value >> operation.ComponentIndex * 16) & 0xffff; - - operation.TurnIntoCopy(ConstF(HalfConversion.HalfToSingle(value))); - } - - private static void FPNegate(Operation operation) - { - float value = operation.GetSource(0).AsFloat(); - - operation.TurnIntoCopy(ConstF(-value)); - } - - private static void EvaluateUnary(Operation operation, Func<int, int> op) - { - int x = operation.GetSource(0).Value; - - operation.TurnIntoCopy(Const(op(x))); - } - - private static void EvaluateFPUnary(Operation operation, Func<float, float> op) - { - float x = operation.GetSource(0).AsFloat(); - - operation.TurnIntoCopy(ConstF(op(x))); - } - - private static void EvaluateFPUnary(Operation operation, Func<float, bool> op) - { - float x = operation.GetSource(0).AsFloat(); - - operation.TurnIntoCopy(Const(op(x) ? IrConsts.True : IrConsts.False)); - } - - private static void EvaluateBinary(Operation operation, Func<int, int, int> op) - { - int x = operation.GetSource(0).Value; - int y = operation.GetSource(1).Value; - - operation.TurnIntoCopy(Const(op(x, y))); - } - - private static void EvaluateBinary(Operation operation, Func<int, int, bool> op) - { - int x = operation.GetSource(0).Value; - int y = operation.GetSource(1).Value; - - operation.TurnIntoCopy(Const(op(x, y) ? IrConsts.True : IrConsts.False)); - } - - private static void EvaluateFPBinary(Operation operation, Func<float, float, float> op) - { - float x = operation.GetSource(0).AsFloat(); - float y = operation.GetSource(1).AsFloat(); - - operation.TurnIntoCopy(ConstF(op(x, y))); - } - - private static void EvaluateFPBinary(Operation operation, Func<float, float, bool> op) - { - float x = operation.GetSource(0).AsFloat(); - float y = operation.GetSource(1).AsFloat(); - - operation.TurnIntoCopy(Const(op(x, y) ? IrConsts.True : IrConsts.False)); - } - - private static void EvaluateTernary(Operation operation, Func<int, int, int, int> op) - { - int x = operation.GetSource(0).Value; - int y = operation.GetSource(1).Value; - int z = operation.GetSource(2).Value; - - operation.TurnIntoCopy(Const(op(x, y, z))); - } - - private static void EvaluateFPTernary(Operation operation, Func<float, float, float, float> op) - { - float x = operation.GetSource(0).AsFloat(); - float y = operation.GetSource(1).AsFloat(); - float z = operation.GetSource(2).AsFloat(); - - operation.TurnIntoCopy(ConstF(op(x, y, z))); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/HalfConversion.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/HalfConversion.cs deleted file mode 100644 index 96060272..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/HalfConversion.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class HalfConversion - { - public static float HalfToSingle(int value) - { - int mantissa = (value >> 0) & 0x3ff; - int exponent = (value >> 10) & 0x1f; - int sign = (value >> 15) & 0x1; - - if (exponent == 0x1f) - { - // NaN or Infinity. - mantissa <<= 13; - exponent = 0xff; - } - else if (exponent != 0 || mantissa != 0 ) - { - if (exponent == 0) - { - // Denormal. - int e = -1; - int m = mantissa; - - do - { - e++; - m <<= 1; - } - while ((m & 0x400) == 0); - - mantissa = m & 0x3ff; - exponent = e; - } - - mantissa <<= 13; - exponent = 127 - 15 + exponent; - } - - int output = (sign << 31) | (exponent << 23) | mantissa; - - return BitConverter.Int32BitsToSingle(output); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/Optimizer.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/Optimizer.cs deleted file mode 100644 index 8cce0e74..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/Optimizer.cs +++ /dev/null @@ -1,172 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class Optimizer - { - public static void Optimize(BasicBlock[] blocks) - { - bool modified; - - do - { - modified = false; - - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - LinkedListNode<INode> nextNode = node.Next; - - bool isUnused = IsUnused(node.Value); - - if (!(node.Value is Operation operation) || isUnused) - { - if (isUnused) - { - RemoveNode(block, node); - - modified = true; - } - - node = nextNode; - - continue; - } - - ConstantFolding.Fold(operation); - - Simplification.Simplify(operation); - - if (DestIsLocalVar(operation)) - { - if (operation.Inst == Instruction.Copy) - { - PropagateCopy(operation); - - RemoveNode(block, node); - - modified = true; - } - else if (operation.Inst == Instruction.PackHalf2x16 && PropagatePack(operation)) - { - if (operation.Dest.UseOps.Count == 0) - { - RemoveNode(block, node); - } - - modified = true; - } - } - - node = nextNode; - } - - if (BranchElimination.Eliminate(block)) - { - RemoveNode(block, block.Operations.Last); - - modified = true; - } - } - } - while (modified); - } - - private static void PropagateCopy(Operation copyOp) - { - // Propagate copy source operand to all uses of - // the destination operand. - Operand dest = copyOp.Dest; - Operand src = copyOp.GetSource(0); - - INode[] uses = dest.UseOps.ToArray(); - - foreach (INode useNode in uses) - { - for (int index = 0; index < useNode.SourcesCount; index++) - { - if (useNode.GetSource(index) == dest) - { - useNode.SetSource(index, src); - } - } - } - } - - private static bool PropagatePack(Operation packOp) - { - // Propagate pack source operands to uses by unpack - // instruction. The source depends on the unpack instruction. - bool modified = false; - - Operand dest = packOp.Dest; - Operand src0 = packOp.GetSource(0); - Operand src1 = packOp.GetSource(1); - - INode[] uses = dest.UseOps.ToArray(); - - foreach (INode useNode in uses) - { - if (!(useNode is Operation operation) || operation.Inst != Instruction.UnpackHalf2x16) - { - continue; - } - - if (operation.GetSource(0) == dest) - { - operation.TurnIntoCopy(operation.ComponentIndex == 1 ? src1 : src0); - - modified = true; - } - } - - return modified; - } - - private static void RemoveNode(BasicBlock block, LinkedListNode<INode> llNode) - { - // Remove a node from the nodes list, and also remove itself - // from all the use lists on the operands that this node uses. - block.Operations.Remove(llNode); - - Queue<INode> nodes = new Queue<INode>(); - - nodes.Enqueue(llNode.Value); - - while (nodes.TryDequeue(out INode node)) - { - for (int index = 0; index < node.SourcesCount; index++) - { - Operand src = node.GetSource(index); - - if (src.Type != OperandType.LocalVariable) - { - continue; - } - - if (src.UseOps.Remove(node) && src.UseOps.Count == 0) - { - nodes.Enqueue(src.AsgOp); - } - } - } - } - - private static bool IsUnused(INode node) - { - return DestIsLocalVar(node) && node.Dest.UseOps.Count == 0; - } - - private static bool DestIsLocalVar(INode node) - { - return node.Dest != null && node.Dest.Type == OperandType.LocalVariable; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Optimizations/Simplification.cs b/Ryujinx.Graphics/Shader/Translation/Optimizations/Simplification.cs deleted file mode 100644 index d6366dfe..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Optimizations/Simplification.cs +++ /dev/null @@ -1,147 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class Simplification - { - private const int AllOnes = ~0; - - public static void Simplify(Operation operation) - { - switch (operation.Inst) - { - case Instruction.Add: - case Instruction.BitwiseExclusiveOr: - TryEliminateBinaryOpCommutative(operation, 0); - break; - - case Instruction.BitwiseAnd: - TryEliminateBitwiseAnd(operation); - break; - - case Instruction.BitwiseOr: - TryEliminateBitwiseOr(operation); - break; - - case Instruction.ConditionalSelect: - TryEliminateConditionalSelect(operation); - break; - - case Instruction.Divide: - TryEliminateBinaryOpY(operation, 1); - break; - - case Instruction.Multiply: - TryEliminateBinaryOpCommutative(operation, 1); - break; - - case Instruction.ShiftLeft: - case Instruction.ShiftRightS32: - case Instruction.ShiftRightU32: - case Instruction.Subtract: - TryEliminateBinaryOpY(operation, 0); - break; - } - } - - private static void TryEliminateBitwiseAnd(Operation operation) - { - // Try to recognize and optimize those 3 patterns (in order): - // x & 0xFFFFFFFF == x, 0xFFFFFFFF & y == y, - // x & 0x00000000 == 0x00000000, 0x00000000 & y == 0x00000000 - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(x, AllOnes)) - { - operation.TurnIntoCopy(y); - } - else if (IsConstEqual(y, AllOnes)) - { - operation.TurnIntoCopy(x); - } - else if (IsConstEqual(x, 0) || IsConstEqual(y, 0)) - { - operation.TurnIntoCopy(Const(0)); - } - } - - private static void TryEliminateBitwiseOr(Operation operation) - { - // Try to recognize and optimize those 3 patterns (in order): - // x | 0x00000000 == x, 0x00000000 | y == y, - // x | 0xFFFFFFFF == 0xFFFFFFFF, 0xFFFFFFFF | y == 0xFFFFFFFF - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(x, 0)) - { - operation.TurnIntoCopy(y); - } - else if (IsConstEqual(y, 0)) - { - operation.TurnIntoCopy(x); - } - else if (IsConstEqual(x, AllOnes) || IsConstEqual(y, AllOnes)) - { - operation.TurnIntoCopy(Const(AllOnes)); - } - } - - private static void TryEliminateBinaryOpY(Operation operation, int comparand) - { - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(y, comparand)) - { - operation.TurnIntoCopy(x); - } - } - - private static void TryEliminateBinaryOpCommutative(Operation operation, int comparand) - { - Operand x = operation.GetSource(0); - Operand y = operation.GetSource(1); - - if (IsConstEqual(x, comparand)) - { - operation.TurnIntoCopy(y); - } - else if (IsConstEqual(y, comparand)) - { - operation.TurnIntoCopy(x); - } - } - - private static void TryEliminateConditionalSelect(Operation operation) - { - Operand cond = operation.GetSource(0); - - if (cond.Type != OperandType.Constant) - { - return; - } - - // The condition is constant, we can turn it into a copy, and select - // the source based on the condition value. - int srcIndex = cond.Value != 0 ? 1 : 2; - - Operand source = operation.GetSource(srcIndex); - - operation.TurnIntoCopy(source); - } - - private static bool IsConstEqual(Operand operand, int comparand) - { - if (operand.Type != OperandType.Constant) - { - return false; - } - - return operand.Value == comparand; - } - } -}
\ No newline at end of file |
