mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-11-08 04:38:37 +00:00
6b23a2c125
* Start implementing a new shader translator * Fix shift instructions and a typo * Small refactoring on StructuredProgram, move RemovePhis method to a separate class * Initial geometry shader support * Implement TLD4 * Fix -- There's no negation on FMUL32I * Add constant folding and algebraic simplification optimizations, nits * Some leftovers from constant folding * Avoid cast for constant assignments * Add a branch elimination pass, and misc small fixes * Remove redundant branches, add expression propagation and other improvements on the code * Small leftovers -- add missing break and continue, remove unused properties, other improvements * Add null check to handle empty block cases on block visitor * Add HADD2 and HMUL2 half float shader instructions * Optimize pack/unpack sequences, some fixes related to half float instructions * Add TXQ, TLD, TLDS and TLD4S shader texture instructions, and some support for bindless textures, some refactoring on codegen * Fix copy paste mistake that caused RZ to be ignored on the AST instruction * Add workaround for conditional exit, and fix half float instruction with constant buffer * Add missing 0.0 source for TLDS.LZ variants * Simplify the switch for TLDS.LZ * Texture instructions related fixes * Implement the HFMA instruction, and some misc. fixes * Enable constant folding on UnpackHalf2x16 instructions * Refactor HFMA to use OpCode* for opcode decoding rather than on the helper methods * Remove the old shader translator * Remove ShaderDeclInfo and other unused things * Add dual vertex shader support * Add ShaderConfig, used to pass shader type and maximum cbuffer size * Move and rename some instruction enums * Move texture instructions into a separate file * Move operand GetExpression and locals management to OperandManager * Optimize opcode decoding using a simple list and binary search * Add missing condition for do-while on goto elimination * Misc. fixes on texture instructions * Simplify TLDS switch * Address PR feedback, and a nit
147 lines
4.6 KiB
C#
147 lines
4.6 KiB
C#
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:
|
|
TryEliminateBinaryOpComutative(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:
|
|
TryEliminateBinaryOpComutative(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 TryEliminateBinaryOpComutative(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;
|
|
}
|
|
}
|
|
} |