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 | |
| parent | f617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff) | |
Initial work
Diffstat (limited to 'Ryujinx.Graphics/Shader')
162 files changed, 0 insertions, 11468 deletions
diff --git a/Ryujinx.Graphics/Shader/CBufferDescriptor.cs b/Ryujinx.Graphics/Shader/CBufferDescriptor.cs deleted file mode 100644 index f99665e1..00000000 --- a/Ryujinx.Graphics/Shader/CBufferDescriptor.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader -{ - public struct CBufferDescriptor - { - public string Name { get; } - - public int Slot { get; } - - public CBufferDescriptor(string name, int slot) - { - Name = name; - Slot = slot; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs deleted file mode 100644 index dcbdc309..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Collections.Generic; -using System.Text; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - class CodeGenContext - { - private const string Tab = " "; - - public ShaderConfig Config { get; } - - public List<CBufferDescriptor> CBufferDescriptors { get; } - public List<TextureDescriptor> TextureDescriptors { get; } - - public OperandManager OperandManager { get; } - - private StringBuilder _sb; - - private int _level; - - private string _indentation; - - public CodeGenContext(ShaderConfig config) - { - Config = config; - - CBufferDescriptors = new List<CBufferDescriptor>(); - TextureDescriptors = new List<TextureDescriptor>(); - - OperandManager = new OperandManager(); - - _sb = new StringBuilder(); - } - - public void AppendLine() - { - _sb.AppendLine(); - } - - public void AppendLine(string str) - { - _sb.AppendLine(_indentation + str); - } - - public string GetCode() - { - return _sb.ToString(); - } - - public void EnterScope() - { - AppendLine("{"); - - _level++; - - UpdateIndentation(); - } - - public void LeaveScope(string suffix = "") - { - if (_level == 0) - { - return; - } - - _level--; - - UpdateIndentation(); - - AppendLine("}" + suffix); - } - - private void UpdateIndentation() - { - _indentation = GetIndentation(_level); - } - - private static string GetIndentation(int level) - { - string indentation = string.Empty; - - for (int index = 0; index < level; index++) - { - indentation += Tab; - } - - return indentation; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs deleted file mode 100644 index 5412d872..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs +++ /dev/null @@ -1,206 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class Declarations - { - public static void Declare(CodeGenContext context, StructuredProgramInfo info) - { - context.AppendLine("#version 420 core"); - - context.AppendLine(); - - context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;"); - - context.AppendLine(); - - if (context.Config.Type == GalShaderType.Geometry) - { - context.AppendLine("layout (points) in;"); - context.AppendLine("layout (triangle_strip, max_vertices = 4) out;"); - - context.AppendLine(); - } - - context.AppendLine("layout (std140) uniform Extra"); - - context.EnterScope(); - - context.AppendLine("vec2 flip;"); - context.AppendLine("int instance;"); - - context.LeaveScope(";"); - - context.AppendLine(); - - if (info.CBuffers.Count != 0) - { - DeclareUniforms(context, info); - - context.AppendLine(); - } - - if (info.Samplers.Count != 0) - { - DeclareSamplers(context, info); - - context.AppendLine(); - } - - if (info.IAttributes.Count != 0) - { - DeclareInputAttributes(context, info); - - context.AppendLine(); - } - - if (info.OAttributes.Count != 0) - { - DeclareOutputAttributes(context, info); - - context.AppendLine(); - } - } - - public static void DeclareLocals(CodeGenContext context, StructuredProgramInfo info) - { - foreach (AstOperand decl in info.Locals) - { - string name = context.OperandManager.DeclareLocal(decl); - - context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";"); - } - } - - private static string GetVarTypeName(VariableType type) - { - switch (type) - { - case VariableType.Bool: return "bool"; - case VariableType.F32: return "float"; - case VariableType.S32: return "int"; - case VariableType.U32: return "uint"; - } - - throw new ArgumentException($"Invalid variable type \"{type}\"."); - } - - private static void DeclareUniforms(CodeGenContext context, StructuredProgramInfo info) - { - foreach (int cbufSlot in info.CBuffers.OrderBy(x => x)) - { - string ubName = OperandManager.GetShaderStagePrefix(context.Config.Type); - - ubName += "_" + DefaultNames.UniformNamePrefix + cbufSlot; - - context.CBufferDescriptors.Add(new CBufferDescriptor(ubName, cbufSlot)); - - context.AppendLine("layout (std140) uniform " + ubName); - - context.EnterScope(); - - string ubSize = "[" + NumberFormatter.FormatInt(context.Config.MaxCBufferSize / 16) + "]"; - - context.AppendLine("vec4 " + OperandManager.GetUbName(context.Config.Type, cbufSlot) + ubSize + ";"); - - context.LeaveScope(";"); - } - } - - private static void DeclareSamplers(CodeGenContext context, StructuredProgramInfo info) - { - Dictionary<string, AstTextureOperation> samplers = new Dictionary<string, AstTextureOperation>(); - - foreach (AstTextureOperation texOp in info.Samplers.OrderBy(x => x.Handle)) - { - string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); - - if (!samplers.TryAdd(samplerName, texOp)) - { - continue; - } - - string samplerTypeName = GetSamplerTypeName(texOp.Type); - - context.AppendLine("uniform " + samplerTypeName + " " + samplerName + ";"); - } - - foreach (KeyValuePair<string, AstTextureOperation> kv in samplers) - { - string samplerName = kv.Key; - - AstTextureOperation texOp = kv.Value; - - TextureDescriptor desc; - - if ((texOp.Flags & TextureFlags.Bindless) != 0) - { - AstOperand operand = texOp.GetSource(0) as AstOperand; - - desc = new TextureDescriptor(samplerName, operand.CbufSlot, operand.CbufOffset); - } - else - { - desc = new TextureDescriptor(samplerName, texOp.Handle); - } - - context.TextureDescriptors.Add(desc); - } - } - - private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info) - { - string suffix = context.Config.Type == GalShaderType.Geometry ? "[]" : string.Empty; - - foreach (int attr in info.IAttributes.OrderBy(x => x)) - { - context.AppendLine($"layout (location = {attr}) in vec4 {DefaultNames.IAttributePrefix}{attr}{suffix};"); - } - } - - private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info) - { - foreach (int attr in info.OAttributes.OrderBy(x => x)) - { - context.AppendLine($"layout (location = {attr}) out vec4 {DefaultNames.OAttributePrefix}{attr};"); - } - } - - private static string GetSamplerTypeName(TextureType type) - { - string typeName; - - switch (type & TextureType.Mask) - { - case TextureType.Texture1D: typeName = "sampler1D"; break; - case TextureType.Texture2D: typeName = "sampler2D"; break; - case TextureType.Texture3D: typeName = "sampler3D"; break; - case TextureType.TextureCube: typeName = "samplerCube"; break; - - default: throw new ArgumentException($"Invalid sampler type \"{type}\"."); - } - - if ((type & TextureType.Multisample) != 0) - { - typeName += "MS"; - } - - if ((type & TextureType.Array) != 0) - { - typeName += "Array"; - } - - if ((type & TextureType.Shadow) != 0) - { - typeName += "Shadow"; - } - - return typeName; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs deleted file mode 100644 index 1d3939fb..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class DefaultNames - { - public const string LocalNamePrefix = "temp"; - - public const string SamplerNamePrefix = "tex"; - - public const string IAttributePrefix = "in_attr"; - public const string OAttributePrefix = "out_attr"; - - public const string UniformNamePrefix = "c"; - public const string UniformNameSuffix = "data"; - - public const string UndefinedName = "undef"; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs deleted file mode 100644 index 4edbda8b..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs +++ /dev/null @@ -1,133 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.TypeConversion; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class GlslGenerator - { - public static GlslProgram Generate(StructuredProgramInfo info, ShaderConfig config) - { - CodeGenContext context = new CodeGenContext(config); - - Declarations.Declare(context, info); - - PrintMainBlock(context, info); - - return new GlslProgram( - context.CBufferDescriptors.ToArray(), - context.TextureDescriptors.ToArray(), - context.GetCode()); - } - - private static void PrintMainBlock(CodeGenContext context, StructuredProgramInfo info) - { - context.AppendLine("void main()"); - - context.EnterScope(); - - Declarations.DeclareLocals(context, info); - - PrintBlock(context, info.MainBlock); - - context.LeaveScope(); - } - - private static void PrintBlock(CodeGenContext context, AstBlock block) - { - AstBlockVisitor visitor = new AstBlockVisitor(block); - - visitor.BlockEntered += (sender, e) => - { - switch (e.Block.Type) - { - case AstBlockType.DoWhile: - context.AppendLine("do"); - break; - - case AstBlockType.Else: - context.AppendLine("else"); - break; - - case AstBlockType.ElseIf: - context.AppendLine($"else if ({GetCondExpr(context, e.Block.Condition)})"); - break; - - case AstBlockType.If: - context.AppendLine($"if ({GetCondExpr(context, e.Block.Condition)})"); - break; - - default: throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\"."); - } - - context.EnterScope(); - }; - - visitor.BlockLeft += (sender, e) => - { - context.LeaveScope(); - - if (e.Block.Type == AstBlockType.DoWhile) - { - context.AppendLine($"while ({GetCondExpr(context, e.Block.Condition)});"); - } - }; - - foreach (IAstNode node in visitor.Visit()) - { - if (node is AstOperation operation) - { - if (operation.Inst == Instruction.Return) - { - PrepareForReturn(context); - } - - context.AppendLine(InstGen.GetExpression(context, operation) + ";"); - } - else if (node is AstAssignment assignment) - { - VariableType srcType = OperandManager.GetNodeDestType(assignment.Source); - VariableType dstType = OperandManager.GetNodeDestType(assignment.Destination); - - string dest; - - if (assignment.Destination is AstOperand operand && operand.Type == OperandType.Attribute) - { - dest = OperandManager.GetOutAttributeName(operand, context.Config.Type); - } - else - { - dest = InstGen.GetExpression(context, assignment.Destination); - } - - string src = ReinterpretCast(context, assignment.Source, srcType, dstType); - - context.AppendLine(dest + " = " + src + ";"); - } - else - { - throw new InvalidOperationException($"Found unexpected node type \"{node?.GetType().Name ?? "null"}\"."); - } - } - } - - private static string GetCondExpr(CodeGenContext context, IAstNode cond) - { - VariableType srcType = OperandManager.GetNodeDestType(cond); - - return ReinterpretCast(context, cond, srcType, VariableType.Bool); - } - - private static void PrepareForReturn(CodeGenContext context) - { - if (context.Config.Type == GalShaderType.Vertex) - { - context.AppendLine("gl_Position.xy *= flip;"); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslProgram.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslProgram.cs deleted file mode 100644 index e616aa1f..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslProgram.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - class GlslProgram - { - public CBufferDescriptor[] CBufferDescriptors { get; } - public TextureDescriptor[] TextureDescriptors { get; } - - public string Code { get; } - - public GlslProgram( - CBufferDescriptor[] cBufferDescs, - TextureDescriptor[] textureDescs, - string code) - { - CBufferDescriptors = cBufferDescs; - TextureDescriptors = textureDescs; - Code = code; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs deleted file mode 100644 index b0b2ec1a..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs +++ /dev/null @@ -1,110 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGen - { - public static string GetExpression(CodeGenContext context, IAstNode node) - { - if (node is AstOperation operation) - { - return GetExpression(context, operation); - } - else if (node is AstOperand operand) - { - return context.OperandManager.GetExpression(operand, context.Config.Type); - } - - throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); - } - - private static string GetExpression(CodeGenContext context, AstOperation operation) - { - Instruction inst = operation.Inst; - - InstInfo info = GetInstructionInfo(inst); - - if ((info.Type & InstType.Call) != 0) - { - int arity = (int)(info.Type & InstType.ArityMask); - - string args = string.Empty; - - for (int argIndex = 0; argIndex < arity; argIndex++) - { - if (argIndex != 0) - { - args += ", "; - } - - VariableType dstType = GetSrcVarType(inst, argIndex); - - args += GetSoureExpr(context, operation.GetSource(argIndex), dstType); - } - - return info.OpName + "(" + args + ")"; - } - else if ((info.Type & InstType.Op) != 0) - { - string op = info.OpName; - - int arity = (int)(info.Type & InstType.ArityMask); - - string[] expr = new string[arity]; - - for (int index = 0; index < arity; index++) - { - IAstNode src = operation.GetSource(index); - - string srcExpr = GetSoureExpr(context, src, GetSrcVarType(inst, index)); - - bool isLhs = arity == 2 && index == 0; - - expr[index] = Enclose(srcExpr, src, inst, info, isLhs); - } - - switch (arity) - { - case 0: - return op; - - case 1: - return op + expr[0]; - - case 2: - return $"{expr[0]} {op} {expr[1]}"; - - case 3: - return $"{expr[0]} {op[0]} {expr[1]} {op[1]} {expr[2]}"; - } - } - else if ((info.Type & InstType.Special) != 0) - { - switch (inst) - { - case Instruction.LoadConstant: - return InstGenMemory.LoadConstant(context, operation); - - case Instruction.PackHalf2x16: - return InstGenPacking.PackHalf2x16(context, operation); - - case Instruction.TextureSample: - return InstGenMemory.TextureSample(context, operation); - - case Instruction.TextureSize: - return InstGenMemory.TextureSize(context, operation); - - case Instruction.UnpackHalf2x16: - return InstGenPacking.UnpackHalf2x16(context, operation); - } - } - - throw new InvalidOperationException($"Unexpected instruction type \"{info.Type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs deleted file mode 100644 index 9855cd91..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs +++ /dev/null @@ -1,170 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.TypeConversion; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGenHelper - { - private static InstInfo[] _infoTbl; - - static InstGenHelper() - { - _infoTbl = new InstInfo[(int)Instruction.Count]; - - Add(Instruction.Absolute, InstType.CallUnary, "abs"); - Add(Instruction.Add, InstType.OpBinaryCom, "+", 2); - Add(Instruction.BitfieldExtractS32, InstType.CallTernary, "bitfieldExtract"); - Add(Instruction.BitfieldExtractU32, InstType.CallTernary, "bitfieldExtract"); - Add(Instruction.BitfieldInsert, InstType.CallQuaternary, "bitfieldInsert"); - Add(Instruction.BitfieldReverse, InstType.CallUnary, "bitfieldReverse"); - Add(Instruction.BitwiseAnd, InstType.OpBinaryCom, "&", 6); - Add(Instruction.BitwiseExclusiveOr, InstType.OpBinaryCom, "^", 7); - Add(Instruction.BitwiseNot, InstType.OpUnary, "~", 0); - Add(Instruction.BitwiseOr, InstType.OpBinaryCom, "|", 8); - Add(Instruction.Ceiling, InstType.CallUnary, "ceil"); - Add(Instruction.Clamp, InstType.CallTernary, "clamp"); - Add(Instruction.ClampU32, InstType.CallTernary, "clamp"); - Add(Instruction.CompareEqual, InstType.OpBinaryCom, "==", 5); - Add(Instruction.CompareGreater, InstType.OpBinary, ">", 4); - Add(Instruction.CompareGreaterOrEqual, InstType.OpBinary, ">=", 4); - Add(Instruction.CompareGreaterOrEqualU32, InstType.OpBinary, ">=", 4); - Add(Instruction.CompareGreaterU32, InstType.OpBinary, ">", 4); - Add(Instruction.CompareLess, InstType.OpBinary, "<", 4); - Add(Instruction.CompareLessOrEqual, InstType.OpBinary, "<=", 4); - Add(Instruction.CompareLessOrEqualU32, InstType.OpBinary, "<=", 4); - Add(Instruction.CompareLessU32, InstType.OpBinary, "<", 4); - Add(Instruction.CompareNotEqual, InstType.OpBinaryCom, "!=", 5); - Add(Instruction.ConditionalSelect, InstType.OpTernary, "?:", 12); - Add(Instruction.ConvertFPToS32, InstType.CallUnary, "int"); - Add(Instruction.ConvertS32ToFP, InstType.CallUnary, "float"); - Add(Instruction.ConvertU32ToFP, InstType.CallUnary, "float"); - Add(Instruction.Cosine, InstType.CallUnary, "cos"); - Add(Instruction.Discard, InstType.OpNullary, "discard"); - Add(Instruction.Divide, InstType.OpBinary, "/", 1); - Add(Instruction.EmitVertex, InstType.CallNullary, "EmitVertex"); - Add(Instruction.EndPrimitive, InstType.CallNullary, "EndPrimitive"); - Add(Instruction.ExponentB2, InstType.CallUnary, "exp2"); - Add(Instruction.Floor, InstType.CallUnary, "floor"); - Add(Instruction.FusedMultiplyAdd, InstType.CallTernary, "fma"); - Add(Instruction.IsNan, InstType.CallUnary, "isnan"); - Add(Instruction.LoadConstant, InstType.Special); - Add(Instruction.LogarithmB2, InstType.CallUnary, "log2"); - Add(Instruction.LogicalAnd, InstType.OpBinaryCom, "&&", 9); - Add(Instruction.LogicalExclusiveOr, InstType.OpBinaryCom, "^^", 10); - Add(Instruction.LogicalNot, InstType.OpUnary, "!", 0); - Add(Instruction.LogicalOr, InstType.OpBinaryCom, "||", 11); - Add(Instruction.LoopBreak, InstType.OpNullary, "break"); - Add(Instruction.LoopContinue, InstType.OpNullary, "continue"); - Add(Instruction.PackHalf2x16, InstType.Special); - Add(Instruction.ShiftLeft, InstType.OpBinary, "<<", 3); - Add(Instruction.ShiftRightS32, InstType.OpBinary, ">>", 3); - Add(Instruction.ShiftRightU32, InstType.OpBinary, ">>", 3); - Add(Instruction.Maximum, InstType.CallBinary, "max"); - Add(Instruction.MaximumU32, InstType.CallBinary, "max"); - Add(Instruction.Minimum, InstType.CallBinary, "min"); - Add(Instruction.MinimumU32, InstType.CallBinary, "min"); - Add(Instruction.Multiply, InstType.OpBinaryCom, "*", 1); - Add(Instruction.Negate, InstType.OpUnary, "-", 0); - Add(Instruction.ReciprocalSquareRoot, InstType.CallUnary, "inversesqrt"); - Add(Instruction.Return, InstType.OpNullary, "return"); - Add(Instruction.Sine, InstType.CallUnary, "sin"); - Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt"); - Add(Instruction.Subtract, InstType.OpBinary, "-", 2); - Add(Instruction.TextureSample, InstType.Special); - Add(Instruction.TextureSize, InstType.Special); - Add(Instruction.Truncate, InstType.CallUnary, "trunc"); - Add(Instruction.UnpackHalf2x16, InstType.Special); - } - - private static void Add(Instruction inst, InstType flags, string opName = null, int precedence = 0) - { - _infoTbl[(int)inst] = new InstInfo(flags, opName, precedence); - } - - public static InstInfo GetInstructionInfo(Instruction inst) - { - return _infoTbl[(int)(inst & Instruction.Mask)]; - } - - public static string GetSoureExpr(CodeGenContext context, IAstNode node, VariableType dstType) - { - return ReinterpretCast(context, node, OperandManager.GetNodeDestType(node), dstType); - } - - public static string Enclose(string expr, IAstNode node, Instruction pInst, bool isLhs) - { - InstInfo pInfo = GetInstructionInfo(pInst); - - return Enclose(expr, node, pInst, pInfo, isLhs); - } - - public static string Enclose(string expr, IAstNode node, Instruction pInst, InstInfo pInfo, bool isLhs = false) - { - if (NeedsParenthesis(node, pInst, pInfo, isLhs)) - { - expr = "(" + expr + ")"; - } - - return expr; - } - - public static bool NeedsParenthesis(IAstNode node, Instruction pInst, InstInfo pInfo, bool isLhs) - { - // If the node isn't a operation, then it can only be a operand, - // and those never needs to be surrounded in parenthesis. - if (!(node is AstOperation operation)) - { - // This is sort of a special case, if this is a negative constant, - // and it is consumed by a unary operation, we need to put on the parenthesis, - // as in GLSL a sequence like --2 or ~-1 is not valid. - if (IsNegativeConst(node) && pInfo.Type == InstType.OpUnary) - { - return true; - } - - return false; - } - - if ((pInfo.Type & (InstType.Call | InstType.Special)) != 0) - { - return false; - } - - InstInfo info = _infoTbl[(int)(operation.Inst & Instruction.Mask)]; - - if ((info.Type & (InstType.Call | InstType.Special)) != 0) - { - return false; - } - - if (info.Precedence < pInfo.Precedence) - { - return false; - } - - if (info.Precedence == pInfo.Precedence && isLhs) - { - return false; - } - - if (pInst == operation.Inst && info.Type == InstType.OpBinaryCom) - { - return false; - } - - return true; - } - - private static bool IsNegativeConst(IAstNode node) - { - if (!(node is AstOperand operand)) - { - return false; - } - - return operand.Type == OperandType.Constant && operand.Value < 0; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs deleted file mode 100644 index 8b5257fc..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs +++ /dev/null @@ -1,244 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGenMemory - { - public static string LoadConstant(CodeGenContext context, AstOperation operation) - { - IAstNode src1 = operation.GetSource(1); - - string offsetExpr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 1)); - - offsetExpr = Enclose(offsetExpr, src1, Instruction.ShiftRightS32, isLhs: true); - - return OperandManager.GetConstantBufferName(operation.GetSource(0), offsetExpr, context.Config.Type); - } - - public static string TextureSample(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0; - bool isGather = (texOp.Flags & TextureFlags.Gather) != 0; - bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0; - bool hasLodBias = (texOp.Flags & TextureFlags.LodBias) != 0; - bool hasLodLevel = (texOp.Flags & TextureFlags.LodLevel) != 0; - bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0; - bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0; - bool isArray = (texOp.Type & TextureType.Array) != 0; - bool isMultisample = (texOp.Type & TextureType.Multisample) != 0; - bool isShadow = (texOp.Type & TextureType.Shadow) != 0; - - string texCall = intCoords ? "texelFetch" : "texture"; - - if (isGather) - { - texCall += "Gather"; - } - else if (hasLodLevel && !intCoords) - { - texCall += "Lod"; - } - - if (hasOffset) - { - texCall += "Offset"; - } - else if (hasOffsets) - { - texCall += "Offsets"; - } - - string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); - - texCall += "(" + samplerName; - - int coordsCount = texOp.Type.GetCoordsCount(); - - int pCount = coordsCount; - - int arrayIndexElem = -1; - - if (isArray) - { - arrayIndexElem = pCount++; - } - - // The sampler 1D shadow overload expects a - // dummy value on the middle of the vector, who knows why... - bool hasDummy1DShadowElem = texOp.Type == (TextureType.Texture1D | TextureType.Shadow); - - if (hasDummy1DShadowElem) - { - pCount++; - } - - if (isShadow && !isGather) - { - pCount++; - } - - // On textureGather*, the comparison value is - // always specified as an extra argument. - bool hasExtraCompareArg = isShadow && isGather; - - if (pCount == 5) - { - pCount = 4; - - hasExtraCompareArg = true; - } - - int srcIndex = isBindless ? 1 : 0; - - string Src(VariableType type) - { - return GetSoureExpr(context, texOp.GetSource(srcIndex++), type); - } - - void Append(string str) - { - texCall += ", " + str; - } - - VariableType coordType = intCoords ? VariableType.S32 : VariableType.F32; - - string AssemblePVector(int count) - { - if (count > 1) - { - string[] elems = new string[count]; - - for (int index = 0; index < count; index++) - { - if (arrayIndexElem == index) - { - elems[index] = Src(VariableType.S32); - - if (!intCoords) - { - elems[index] = "float(" + elems[index] + ")"; - } - } - else if (index == 1 && hasDummy1DShadowElem) - { - elems[index] = NumberFormatter.FormatFloat(0); - } - else - { - elems[index] = Src(coordType); - } - } - - string prefix = intCoords ? "i" : string.Empty; - - return prefix + "vec" + count + "(" + string.Join(", ", elems) + ")"; - } - else - { - return Src(coordType); - } - } - - Append(AssemblePVector(pCount)); - - if (hasExtraCompareArg) - { - Append(Src(VariableType.F32)); - } - - if (isMultisample) - { - Append(Src(VariableType.S32)); - } - else if (hasLodLevel) - { - Append(Src(coordType)); - } - - string AssembleOffsetVector(int count) - { - if (count > 1) - { - string[] elems = new string[count]; - - for (int index = 0; index < count; index++) - { - elems[index] = Src(VariableType.S32); - } - - return "ivec" + count + "(" + string.Join(", ", elems) + ")"; - } - else - { - return Src(VariableType.S32); - } - } - - if (hasOffset) - { - Append(AssembleOffsetVector(coordsCount)); - } - else if (hasOffsets) - { - texCall += $", ivec{coordsCount}[4]("; - - texCall += AssembleOffsetVector(coordsCount) + ", "; - texCall += AssembleOffsetVector(coordsCount) + ", "; - texCall += AssembleOffsetVector(coordsCount) + ", "; - texCall += AssembleOffsetVector(coordsCount) + ")"; - } - - if (hasLodBias) - { - Append(Src(VariableType.F32)); - } - - // textureGather* optional extra component index, - // not needed for shadow samplers. - if (isGather && !isShadow) - { - Append(Src(VariableType.S32)); - } - - texCall += ")" + (isGather || !isShadow ? GetMask(texOp.ComponentMask) : ""); - - return texCall; - } - - public static string TextureSize(CodeGenContext context, AstOperation operation) - { - AstTextureOperation texOp = (AstTextureOperation)operation; - - bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0; - - string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); - - IAstNode src0 = operation.GetSource(isBindless ? 1 : 0); - - string src0Expr = GetSoureExpr(context, src0, GetSrcVarType(operation.Inst, 0)); - - return $"textureSize({samplerName}, {src0Expr}){GetMask(texOp.ComponentMask)}"; - } - - private static string GetMask(int compMask) - { - string mask = "."; - - for (int index = 0; index < 4; index++) - { - if ((compMask & (1 << index)) != 0) - { - mask += "rgba".Substring(index, 1); - } - } - - return mask; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs deleted file mode 100644 index 4a40032c..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenPacking.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Ryujinx.Graphics.Shader.StructuredIr; - -using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper; -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - static class InstGenPacking - { - public static string PackHalf2x16(CodeGenContext context, AstOperation operation) - { - IAstNode src0 = operation.GetSource(0); - IAstNode src1 = operation.GetSource(1); - - string src0Expr = GetSoureExpr(context, src0, GetSrcVarType(operation.Inst, 0)); - string src1Expr = GetSoureExpr(context, src1, GetSrcVarType(operation.Inst, 1)); - - return $"packHalf2x16(vec2({src0Expr}, {src1Expr}))"; - } - - public static string UnpackHalf2x16(CodeGenContext context, AstOperation operation) - { - IAstNode src = operation.GetSource(0); - - string srcExpr = GetSoureExpr(context, src, GetSrcVarType(operation.Inst, 0)); - - return $"unpackHalf2x16({srcExpr}){GetMask(operation.ComponentMask)}"; - } - - private static string GetMask(int compMask) - { - string mask = "."; - - for (int index = 0; index < 2; index++) - { - if ((compMask & (1 << index)) != 0) - { - mask += "xy".Substring(index, 1); - } - } - - return mask; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstInfo.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstInfo.cs deleted file mode 100644 index fc9aef7e..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - struct InstInfo - { - public InstType Type { get; } - - public string OpName { get; } - - public int Precedence { get; } - - public InstInfo(InstType type, string opName, int precedence) - { - Type = type; - OpName = opName; - Precedence = precedence; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstType.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstType.cs deleted file mode 100644 index 121cd079..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstType.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions -{ - [Flags] - enum InstType - { - OpNullary = Op | 0, - OpUnary = Op | 1, - OpBinary = Op | 2, - OpTernary = Op | 3, - OpBinaryCom = OpBinary | Commutative, - - CallNullary = Call | 0, - CallUnary = Call | 1, - CallBinary = Call | 2, - CallTernary = Call | 3, - CallQuaternary = Call | 4, - - Commutative = 1 << 8, - Op = 1 << 9, - Call = 1 << 10, - Special = 1 << 11, - - ArityMask = 0xff - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/NumberFormatter.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/NumberFormatter.cs deleted file mode 100644 index 2ec44277..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/NumberFormatter.cs +++ /dev/null @@ -1,104 +0,0 @@ -using Ryujinx.Graphics.Shader.StructuredIr; -using System; -using System.Globalization; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class NumberFormatter - { - private const int MaxDecimal = 256; - - public static bool TryFormat(int value, VariableType dstType, out string formatted) - { - if (dstType == VariableType.F32) - { - return TryFormatFloat(BitConverter.Int32BitsToSingle(value), out formatted); - } - else if (dstType == VariableType.S32) - { - formatted = FormatInt(value); - } - else if (dstType == VariableType.U32) - { - formatted = FormatUint((uint)value); - } - else if (dstType == VariableType.Bool) - { - formatted = value != 0 ? "true" : "false"; - } - else - { - throw new ArgumentException($"Invalid variable type \"{dstType}\"."); - } - - return true; - } - - public static string FormatFloat(float value) - { - if (!TryFormatFloat(value, out string formatted)) - { - throw new ArgumentException("Failed to convert float value to string."); - } - - return formatted; - } - - public static bool TryFormatFloat(float value, out string formatted) - { - if (float.IsNaN(value) || float.IsInfinity(value)) - { - formatted = null; - - return false; - } - - formatted = value.ToString("G9", CultureInfo.InvariantCulture); - - if (!(formatted.Contains('.') || - formatted.Contains('e') || - formatted.Contains('E'))) - { - formatted += ".0"; - } - - return true; - } - - public static string FormatInt(int value, VariableType dstType) - { - if (dstType == VariableType.S32) - { - return FormatInt(value); - } - else if (dstType == VariableType.U32) - { - return FormatUint((uint)value); - } - else - { - throw new ArgumentException($"Invalid variable type \"{dstType}\"."); - } - } - - public static string FormatInt(int value) - { - if (value <= MaxDecimal && value >= -MaxDecimal) - { - return value.ToString(CultureInfo.InvariantCulture); - } - - return "0x" + value.ToString("X", CultureInfo.InvariantCulture); - } - - public static string FormatUint(uint value) - { - if (value <= MaxDecimal && value >= 0) - { - return value.ToString(CultureInfo.InvariantCulture) + "u"; - } - - return "0x" + value.ToString("X", CultureInfo.InvariantCulture) + "u"; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs deleted file mode 100644 index 19f7185e..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs +++ /dev/null @@ -1,249 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - class OperandManager - { - private static string[] _stagePrefixes = new string[] { "vp", "tcp", "tep", "gp", "fp" }; - - private struct BuiltInAttribute - { - public string Name { get; } - - public VariableType Type { get; } - - public BuiltInAttribute(string name, VariableType type) - { - Name = name; - Type = type; - } - } - - private static Dictionary<int, BuiltInAttribute> _builtInAttributes = - new Dictionary<int, BuiltInAttribute>() - { - { AttributeConsts.Layer, new BuiltInAttribute("gl_Layer", VariableType.S32) }, - { AttributeConsts.PointSize, new BuiltInAttribute("gl_PointSize", VariableType.F32) }, - { AttributeConsts.PositionX, new BuiltInAttribute("gl_Position.x", VariableType.F32) }, - { AttributeConsts.PositionY, new BuiltInAttribute("gl_Position.y", VariableType.F32) }, - { AttributeConsts.PositionZ, new BuiltInAttribute("gl_Position.z", VariableType.F32) }, - { AttributeConsts.PositionW, new BuiltInAttribute("gl_Position.w", VariableType.F32) }, - { AttributeConsts.ClipDistance0, new BuiltInAttribute("gl_ClipDistance[0]", VariableType.F32) }, - { AttributeConsts.ClipDistance1, new BuiltInAttribute("gl_ClipDistance[1]", VariableType.F32) }, - { AttributeConsts.ClipDistance2, new BuiltInAttribute("gl_ClipDistance[2]", VariableType.F32) }, - { AttributeConsts.ClipDistance3, new BuiltInAttribute("gl_ClipDistance[3]", VariableType.F32) }, - { AttributeConsts.ClipDistance4, new BuiltInAttribute("gl_ClipDistance[4]", VariableType.F32) }, - { AttributeConsts.ClipDistance5, new BuiltInAttribute("gl_ClipDistance[5]", VariableType.F32) }, - { AttributeConsts.ClipDistance6, new BuiltInAttribute("gl_ClipDistance[6]", VariableType.F32) }, - { AttributeConsts.ClipDistance7, new BuiltInAttribute("gl_ClipDistance[7]", VariableType.F32) }, - { AttributeConsts.PointCoordX, new BuiltInAttribute("gl_PointCoord.x", VariableType.F32) }, - { AttributeConsts.PointCoordY, new BuiltInAttribute("gl_PointCoord.y", VariableType.F32) }, - { AttributeConsts.TessCoordX, new BuiltInAttribute("gl_TessCoord.x", VariableType.F32) }, - { AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", VariableType.F32) }, - { AttributeConsts.InstanceId, new BuiltInAttribute("instance", VariableType.S32) }, - { AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", VariableType.S32) }, - { AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", VariableType.Bool) }, - { AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", VariableType.F32) } - }; - - private Dictionary<AstOperand, string> _locals; - - public OperandManager() - { - _locals = new Dictionary<AstOperand, string>(); - } - - public string DeclareLocal(AstOperand operand) - { - string name = $"{DefaultNames.LocalNamePrefix}_{_locals.Count}"; - - _locals.Add(operand, name); - - return name; - } - - public string GetExpression(AstOperand operand, GalShaderType shaderType) - { - switch (operand.Type) - { - case OperandType.Attribute: - return GetAttributeName(operand, shaderType); - - case OperandType.Constant: - return NumberFormatter.FormatInt(operand.Value); - - case OperandType.ConstantBuffer: - return GetConstantBufferName(operand, shaderType); - - case OperandType.LocalVariable: - return _locals[operand]; - - case OperandType.Undefined: - return DefaultNames.UndefinedName; - } - - throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."); - } - - public static string GetConstantBufferName(AstOperand cbuf, GalShaderType shaderType) - { - string ubName = GetUbName(shaderType, cbuf.CbufSlot); - - ubName += "[" + (cbuf.CbufOffset >> 2) + "]"; - - return ubName + "." + GetSwizzleMask(cbuf.CbufOffset & 3); - } - - public static string GetConstantBufferName(IAstNode slot, string offsetExpr, GalShaderType shaderType) - { - // Non-constant slots are not supported. - // It is expected that upstream stages are never going to generate non-constant - // slot access. - AstOperand operand = (AstOperand)slot; - - string ubName = GetUbName(shaderType, operand.Value); - - string index0 = "[" + offsetExpr + " >> 4]"; - string index1 = "[" + offsetExpr + " >> 2 & 3]"; - - return ubName + index0 + index1; - } - - public static string GetOutAttributeName(AstOperand attr, GalShaderType shaderType) - { - return GetAttributeName(attr, shaderType, isOutAttr: true); - } - - private static string GetAttributeName(AstOperand attr, GalShaderType shaderType, bool isOutAttr = false) - { - int value = attr.Value; - - string swzMask = GetSwizzleMask((value >> 2) & 3); - - if (value >= AttributeConsts.UserAttributeBase && - value < AttributeConsts.UserAttributeEnd) - { - value -= AttributeConsts.UserAttributeBase; - - string prefix = isOutAttr - ? DefaultNames.OAttributePrefix - : DefaultNames.IAttributePrefix; - - string name = $"{prefix}{(value >> 4)}"; - - if (shaderType == GalShaderType.Geometry && !isOutAttr) - { - name += "[0]"; - } - - name += "." + swzMask; - - return name; - } - else - { - if (value >= AttributeConsts.FragmentOutputColorBase && - value < AttributeConsts.FragmentOutputColorEnd) - { - value -= AttributeConsts.FragmentOutputColorBase; - - return $"{DefaultNames.OAttributePrefix}{(value >> 4)}.{swzMask}"; - } - else if (_builtInAttributes.TryGetValue(value & ~3, out BuiltInAttribute builtInAttr)) - { - // TODO: There must be a better way to handle this... - if (shaderType == GalShaderType.Fragment) - { - switch (value & ~3) - { - case AttributeConsts.PositionX: return "gl_FragCoord.x"; - case AttributeConsts.PositionY: return "gl_FragCoord.y"; - case AttributeConsts.PositionZ: return "gl_FragCoord.z"; - case AttributeConsts.PositionW: return "1.0"; - } - } - - string name = builtInAttr.Name; - - if (shaderType == GalShaderType.Geometry && !isOutAttr) - { - name = "gl_in[0]." + name; - } - - return name; - } - } - - // TODO: Warn about unknown built-in attribute. - - return isOutAttr ? "// bad_attr0x" + value.ToString("X") : "0.0"; - } - - public static string GetUbName(GalShaderType shaderType, int slot) - { - string ubName = GetShaderStagePrefix(shaderType); - - ubName += "_" + DefaultNames.UniformNamePrefix + slot; - - return ubName + "_" + DefaultNames.UniformNameSuffix; - } - - public static string GetSamplerName(GalShaderType shaderType, AstTextureOperation texOp) - { - string suffix; - - if ((texOp.Flags & TextureFlags.Bindless) != 0) - { - AstOperand operand = texOp.GetSource(0) as AstOperand; - - suffix = "_cb" + operand.CbufSlot + "_" + operand.CbufOffset; - } - else - { - suffix = (texOp.Handle - 8).ToString(); - } - - return GetShaderStagePrefix(shaderType) + "_" + DefaultNames.SamplerNamePrefix + suffix; - } - - public static string GetShaderStagePrefix(GalShaderType shaderType) - { - return _stagePrefixes[(int)shaderType]; - } - - private static string GetSwizzleMask(int value) - { - return "xyzw".Substring(value, 1); - } - - public static VariableType GetNodeDestType(IAstNode node) - { - if (node is AstOperation operation) - { - return GetDestVarType(operation.Inst); - } - else if (node is AstOperand operand) - { - if (operand.Type == OperandType.Attribute) - { - if (_builtInAttributes.TryGetValue(operand.Value & ~3, out BuiltInAttribute builtInAttr)) - { - return builtInAttr.Type; - } - } - - return OperandInfo.GetVarType(operand); - } - else - { - throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/TypeConversion.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/TypeConversion.cs deleted file mode 100644 index 7adc5ad3..00000000 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/TypeConversion.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using System; - -namespace Ryujinx.Graphics.Shader.CodeGen.Glsl -{ - static class TypeConversion - { - public static string ReinterpretCast( - CodeGenContext context, - IAstNode node, - VariableType srcType, - VariableType dstType) - { - if (node is AstOperand operand && operand.Type == OperandType.Constant) - { - if (NumberFormatter.TryFormat(operand.Value, dstType, out string formatted)) - { - return formatted; - } - } - - string expr = InstGen.GetExpression(context, node); - - return ReinterpretCast(expr, node, srcType, dstType); - } - - private static string ReinterpretCast(string expr, IAstNode node, VariableType srcType, VariableType dstType) - { - if (srcType == dstType) - { - return expr; - } - - if (srcType == VariableType.F32) - { - switch (dstType) - { - case VariableType.S32: return $"floatBitsToInt({expr})"; - case VariableType.U32: return $"floatBitsToUint({expr})"; - } - } - else if (dstType == VariableType.F32) - { - switch (srcType) - { - case VariableType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, VariableType.S32)})"; - case VariableType.S32: return $"intBitsToFloat({expr})"; - case VariableType.U32: return $"uintBitsToFloat({expr})"; - } - } - else if (srcType == VariableType.Bool) - { - return ReinterpretBoolToInt(expr, node, dstType); - } - else if (dstType == VariableType.Bool) - { - expr = InstGenHelper.Enclose(expr, node, Instruction.CompareNotEqual, isLhs: true); - - return $"({expr} != 0)"; - } - else if (dstType == VariableType.S32) - { - return $"int({expr})"; - } - else if (dstType == VariableType.U32) - { - return $"uint({expr})"; - } - - throw new ArgumentException($"Invalid reinterpret cast from \"{srcType}\" to \"{dstType}\"."); - } - - private static string ReinterpretBoolToInt(string expr, IAstNode node, VariableType dstType) - { - string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType); - string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType); - - expr = InstGenHelper.Enclose(expr, node, Instruction.ConditionalSelect, isLhs: false); - - return $"({expr} ? {trueExpr} : {falseExpr})"; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/BitfieldExtensions.cs b/Ryujinx.Graphics/Shader/Decoders/BitfieldExtensions.cs deleted file mode 100644 index 3bb9bc1f..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/BitfieldExtensions.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class BitfieldExtensions - { - public static bool Extract(this int value, int lsb) - { - return ((int)(value >> lsb) & 1) != 0; - } - - public static int Extract(this int value, int lsb, int length) - { - return (int)(value >> lsb) & (int)(uint.MaxValue >> (32 - length)); - } - - public static bool Extract(this long value, int lsb) - { - return ((int)(value >> lsb) & 1) != 0; - } - - public static int Extract(this long value, int lsb, int length) - { - return (int)(value >> lsb) & (int)(uint.MaxValue >> (32 - length)); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Block.cs b/Ryujinx.Graphics/Shader/Decoders/Block.cs deleted file mode 100644 index b5e610d7..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Block.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class Block - { - public ulong Address { get; set; } - public ulong EndAddress { get; set; } - - public Block Next { get; set; } - public Block Branch { get; set; } - - public List<OpCode> OpCodes { get; } - public List<OpCodeSsy> SsyOpCodes { get; } - - public Block(ulong address) - { - Address = address; - - OpCodes = new List<OpCode>(); - SsyOpCodes = new List<OpCodeSsy>(); - } - - public void Split(Block rightBlock) - { - int splitIndex = BinarySearch(OpCodes, rightBlock.Address); - - if (OpCodes[splitIndex].Address < rightBlock.Address) - { - splitIndex++; - } - - int splitCount = OpCodes.Count - splitIndex; - - if (splitCount <= 0) - { - throw new ArgumentException("Can't split at right block address."); - } - - rightBlock.EndAddress = EndAddress; - - rightBlock.Next = Next; - rightBlock.Branch = Branch; - - rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount)); - - rightBlock.UpdateSsyOpCodes(); - - EndAddress = rightBlock.Address; - - Next = rightBlock; - Branch = null; - - OpCodes.RemoveRange(splitIndex, splitCount); - - UpdateSsyOpCodes(); - } - - private static int BinarySearch(List<OpCode> opCodes, ulong address) - { - int left = 0; - int middle = 0; - int right = opCodes.Count - 1; - - while (left <= right) - { - int size = right - left; - - middle = left + (size >> 1); - - OpCode opCode = opCodes[middle]; - - if (address == opCode.Address) - { - break; - } - - if (address < opCode.Address) - { - right = middle - 1; - } - else - { - left = middle + 1; - } - } - - return middle; - } - - public OpCode GetLastOp() - { - if (OpCodes.Count != 0) - { - return OpCodes[OpCodes.Count - 1]; - } - - return null; - } - - public void UpdateSsyOpCodes() - { - SsyOpCodes.Clear(); - - for (int index = 0; index < OpCodes.Count; index++) - { - if (!(OpCodes[index] is OpCodeSsy op)) - { - continue; - } - - SsyOpCodes.Add(op); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Condition.cs b/Ryujinx.Graphics/Shader/Decoders/Condition.cs deleted file mode 100644 index 10400f94..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Condition.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum Condition - { - Less = 1 << 0, - Equal = 1 << 1, - Greater = 1 << 2, - Nan = 1 << 3, - Unsigned = 1 << 4, - - Never = 0, - - LessOrEqual = Less | Equal, - NotEqual = Less | Greater, - GreaterOrEqual = Greater | Equal, - Number = Greater | Equal | Less, - - LessUnordered = Less | Nan, - EqualUnordered = Equal | Nan, - LessOrEqualUnordered = LessOrEqual | Nan, - GreaterUnordered = Greater | Nan, - NotEqualUnordered = NotEqual | Nan, - GreaterOrEqualUnordered = GreaterOrEqual | Nan, - - Always = 0xf, - - Off = Unsigned | Never, - Lower = Unsigned | Less, - Sff = Unsigned | Equal, - LowerOrSame = Unsigned | LessOrEqual, - Higher = Unsigned | Greater, - Sft = Unsigned | NotEqual, - HigherOrSame = Unsigned | GreaterOrEqual, - Oft = Unsigned | Always, - - CsmTa = 0x18, - CsmTr = 0x19, - CsmMx = 0x1a, - FcsmTa = 0x1b, - FcsmTr = 0x1c, - FcsmMx = 0x1d, - Rle = 0x1e, - Rgt = 0x1f - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/ConditionalOperation.cs b/Ryujinx.Graphics/Shader/Decoders/ConditionalOperation.cs deleted file mode 100644 index 4fc31e84..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/ConditionalOperation.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum ConditionalOperation - { - False = 0, - True = 1, - Zero = 2, - NotZero = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Decoder.cs b/Ryujinx.Graphics/Shader/Decoders/Decoder.cs deleted file mode 100644 index 754e0388..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Decoder.cs +++ /dev/null @@ -1,406 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.Instructions; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Emit; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class Decoder - { - private const long HeaderSize = 0x50; - - private delegate object OpActivator(InstEmitter emitter, ulong address, long opCode); - - private static ConcurrentDictionary<Type, OpActivator> _opActivators; - - static Decoder() - { - _opActivators = new ConcurrentDictionary<Type, OpActivator>(); - } - - public static Block[] Decode(IGalMemory memory, ulong address) - { - List<Block> blocks = new List<Block>(); - - Queue<Block> workQueue = new Queue<Block>(); - - Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>(); - - Block GetBlock(ulong blkAddress) - { - if (!visited.TryGetValue(blkAddress, out Block block)) - { - block = new Block(blkAddress); - - workQueue.Enqueue(block); - - visited.Add(blkAddress, block); - } - - return block; - } - - ulong startAddress = address + HeaderSize; - - GetBlock(startAddress); - - while (workQueue.TryDequeue(out Block currBlock)) - { - // Check if the current block is inside another block. - if (BinarySearch(blocks, currBlock.Address, out int nBlkIndex)) - { - Block nBlock = blocks[nBlkIndex]; - - if (nBlock.Address == currBlock.Address) - { - throw new InvalidOperationException("Found duplicate block address on the list."); - } - - nBlock.Split(currBlock); - - blocks.Insert(nBlkIndex + 1, currBlock); - - continue; - } - - // If we have a block after the current one, set the limit address. - ulong limitAddress = ulong.MaxValue; - - if (nBlkIndex != blocks.Count) - { - Block nBlock = blocks[nBlkIndex]; - - int nextIndex = nBlkIndex + 1; - - if (nBlock.Address < currBlock.Address && nextIndex < blocks.Count) - { - limitAddress = blocks[nextIndex].Address; - } - else if (nBlock.Address > currBlock.Address) - { - limitAddress = blocks[nBlkIndex].Address; - } - } - - FillBlock(memory, currBlock, limitAddress, startAddress); - - if (currBlock.OpCodes.Count != 0) - { - foreach (OpCodeSsy ssyOp in currBlock.SsyOpCodes) - { - GetBlock(ssyOp.GetAbsoluteAddress()); - } - - // Set child blocks. "Branch" is the block the branch instruction - // points to (when taken), "Next" is the block at the next address, - // executed when the branch is not taken. For Unconditional Branches - // or end of program, Next is null. - OpCode lastOp = currBlock.GetLastOp(); - - if (lastOp is OpCodeBranch op) - { - currBlock.Branch = GetBlock(op.GetAbsoluteAddress()); - } - - if (!IsUnconditionalBranch(lastOp)) - { - currBlock.Next = GetBlock(currBlock.EndAddress); - } - } - - // Insert the new block on the list (sorted by address). - if (blocks.Count != 0) - { - Block nBlock = blocks[nBlkIndex]; - - blocks.Insert(nBlkIndex + (nBlock.Address < currBlock.Address ? 1 : 0), currBlock); - } - else - { - blocks.Add(currBlock); - } - } - - foreach (Block ssyBlock in blocks.Where(x => x.SsyOpCodes.Count != 0)) - { - for (int ssyIndex = 0; ssyIndex < ssyBlock.SsyOpCodes.Count; ssyIndex++) - { - PropagateSsy(visited, ssyBlock, ssyIndex); - } - } - - return blocks.ToArray(); - } - - private static bool BinarySearch(List<Block> blocks, ulong address, out int index) - { - index = 0; - - int left = 0; - int right = blocks.Count - 1; - - while (left <= right) - { - int size = right - left; - - int middle = left + (size >> 1); - - Block block = blocks[middle]; - - index = middle; - - if (address >= block.Address && address < block.EndAddress) - { - return true; - } - - if (address < block.Address) - { - right = middle - 1; - } - else - { - left = middle + 1; - } - } - - return false; - } - - private static void FillBlock( - IGalMemory memory, - Block block, - ulong limitAddress, - ulong startAddress) - { - ulong address = block.Address; - - do - { - if (address >= limitAddress) - { - break; - } - - // Ignore scheduling instructions, which are written every 32 bytes. - if (((address - startAddress) & 0x1f) == 0) - { - address += 8; - - continue; - } - - uint word0 = (uint)memory.ReadInt32((long)(address + 0)); - uint word1 = (uint)memory.ReadInt32((long)(address + 4)); - - ulong opAddress = address; - - address += 8; - - long opCode = word0 | (long)word1 << 32; - - (InstEmitter emitter, Type opCodeType) = OpCodeTable.GetEmitter(opCode); - - if (emitter == null) - { - // TODO: Warning, illegal encoding. - continue; - } - - OpCode op = MakeOpCode(opCodeType, emitter, opAddress, opCode); - - block.OpCodes.Add(op); - } - while (!IsBranch(block.GetLastOp())); - - block.EndAddress = address; - - block.UpdateSsyOpCodes(); - } - - private static bool IsUnconditionalBranch(OpCode opCode) - { - return IsUnconditional(opCode) && IsBranch(opCode); - } - - private static bool IsUnconditional(OpCode opCode) - { - if (opCode is OpCodeExit op && op.Condition != Condition.Always) - { - return false; - } - - return opCode.Predicate.Index == RegisterConsts.PredicateTrueIndex && !opCode.InvertPredicate; - } - - private static bool IsBranch(OpCode opCode) - { - return (opCode is OpCodeBranch && opCode.Emitter != InstEmit.Ssy) || - opCode is OpCodeSync || - opCode is OpCodeExit; - } - - private static OpCode MakeOpCode(Type type, InstEmitter emitter, ulong address, long opCode) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - OpActivator createInstance = _opActivators.GetOrAdd(type, CacheOpActivator); - - return (OpCode)createInstance(emitter, address, opCode); - } - - private static OpActivator CacheOpActivator(Type type) - { - Type[] argTypes = new Type[] { typeof(InstEmitter), typeof(ulong), typeof(long) }; - - DynamicMethod mthd = new DynamicMethod($"Make{type.Name}", type, argTypes); - - ILGenerator generator = mthd.GetILGenerator(); - - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Ldarg_1); - generator.Emit(OpCodes.Ldarg_2); - generator.Emit(OpCodes.Newobj, type.GetConstructor(argTypes)); - generator.Emit(OpCodes.Ret); - - return (OpActivator)mthd.CreateDelegate(typeof(OpActivator)); - } - - private struct PathBlockState - { - public Block Block { get; } - - private enum RestoreType - { - None, - PopSsy, - PushSync - } - - private RestoreType _restoreType; - - private ulong _restoreValue; - - public bool ReturningFromVisit => _restoreType != RestoreType.None; - - public PathBlockState(Block block) - { - Block = block; - _restoreType = RestoreType.None; - _restoreValue = 0; - } - - public PathBlockState(int oldSsyStackSize) - { - Block = null; - _restoreType = RestoreType.PopSsy; - _restoreValue = (ulong)oldSsyStackSize; - } - - public PathBlockState(ulong syncAddress) - { - Block = null; - _restoreType = RestoreType.PushSync; - _restoreValue = syncAddress; - } - - public void RestoreStackState(Stack<ulong> ssyStack) - { - if (_restoreType == RestoreType.PushSync) - { - ssyStack.Push(_restoreValue); - } - else if (_restoreType == RestoreType.PopSsy) - { - while (ssyStack.Count > (uint)_restoreValue) - { - ssyStack.Pop(); - } - } - } - } - - private static void PropagateSsy(Dictionary<ulong, Block> blocks, Block ssyBlock, int ssyIndex) - { - OpCodeSsy ssyOp = ssyBlock.SsyOpCodes[ssyIndex]; - - Stack<PathBlockState> workQueue = new Stack<PathBlockState>(); - - HashSet<Block> visited = new HashSet<Block>(); - - Stack<ulong> ssyStack = new Stack<ulong>(); - - void Push(PathBlockState pbs) - { - if (pbs.Block == null || visited.Add(pbs.Block)) - { - workQueue.Push(pbs); - } - } - - Push(new PathBlockState(ssyBlock)); - - while (workQueue.TryPop(out PathBlockState pbs)) - { - if (pbs.ReturningFromVisit) - { - pbs.RestoreStackState(ssyStack); - - continue; - } - - Block current = pbs.Block; - - int ssyOpCodesCount = current.SsyOpCodes.Count; - - if (ssyOpCodesCount != 0) - { - Push(new PathBlockState(ssyStack.Count)); - - for (int index = ssyIndex; index < ssyOpCodesCount; index++) - { - ssyStack.Push(current.SsyOpCodes[index].GetAbsoluteAddress()); - } - } - - ssyIndex = 0; - - if (current.Next != null) - { - Push(new PathBlockState(current.Next)); - } - - if (current.Branch != null) - { - Push(new PathBlockState(current.Branch)); - } - else if (current.GetLastOp() is OpCodeSync op) - { - ulong syncAddress = ssyStack.Pop(); - - if (ssyStack.Count == 0) - { - ssyStack.Push(syncAddress); - - op.Targets.Add(ssyOp, op.Targets.Count); - - ssyOp.Syncs.TryAdd(op, Local()); - } - else - { - Push(new PathBlockState(syncAddress)); - Push(new PathBlockState(blocks[syncAddress])); - } - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/DecoderHelper.cs b/Ryujinx.Graphics/Shader/Decoders/DecoderHelper.cs deleted file mode 100644 index fd0a45e8..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/DecoderHelper.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class DecoderHelper - { - public static int DecodeS20Immediate(long opCode) - { - int imm = opCode.Extract(20, 19); - - bool negate = opCode.Extract(56); - - if (negate) - { - imm = -imm; - } - - return imm; - } - - public static int Decode2xF10Immediate(long opCode) - { - int immH0 = opCode.Extract(20, 9); - int immH1 = opCode.Extract(30, 9); - - bool negateH0 = opCode.Extract(29); - bool negateH1 = opCode.Extract(56); - - if (negateH0) - { - immH0 |= 1 << 9; - } - - if (negateH1) - { - immH1 |= 1 << 9; - } - - return immH1 << 22 | immH0 << 6; - } - - public static float DecodeF20Immediate(long opCode) - { - int imm = opCode.Extract(20, 19); - - bool negate = opCode.Extract(56); - - imm <<= 12; - - if (negate) - { - imm |= 1 << 31; - } - - return BitConverter.Int32BitsToSingle(imm); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/FPHalfSwizzle.cs b/Ryujinx.Graphics/Shader/Decoders/FPHalfSwizzle.cs deleted file mode 100644 index 3ddf17cf..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/FPHalfSwizzle.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum FPHalfSwizzle - { - FP16 = 0, - FP32 = 1, - DupH0 = 2, - DupH1 = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/FPType.cs b/Ryujinx.Graphics/Shader/Decoders/FPType.cs deleted file mode 100644 index e602ad45..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/FPType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum FPType - { - FP16 = 1, - FP32 = 2, - FP64 = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/FmulScale.cs b/Ryujinx.Graphics/Shader/Decoders/FmulScale.cs deleted file mode 100644 index c35c6e48..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/FmulScale.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum FmulScale - { - None = 0, - Divide2 = 1, - Divide4 = 2, - Divide8 = 3, - Multiply8 = 4, - Multiply4 = 5, - Multiply2 = 6 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCode.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCode.cs deleted file mode 100644 index dd6ad79a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCode.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCode - { - InstEmitter Emitter { get; } - - ulong Address { get; } - long RawOpCode { get; } - - Register Predicate { get; } - - bool InvertPredicate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeAlu.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeAlu.cs deleted file mode 100644 index d840d49d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeAlu.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeAlu : IOpCodeRd, IOpCodeRa - { - Register Predicate39 { get; } - - bool InvertP { get; } - bool Extended { get; } - bool SetCondCode { get; } - bool Saturate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeCbuf.cs deleted file mode 100644 index 42a17451..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeCbuf.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeCbuf : IOpCode - { - int Offset { get; } - int Slot { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeFArith.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeFArith.cs deleted file mode 100644 index d68ccf59..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeFArith.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeFArith : IOpCodeAlu - { - RoundingMode RoundingMode { get; } - - FmulScale Scale { get; } - - bool FlushToZero { get; } - bool AbsoluteA { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeHfma.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeHfma.cs deleted file mode 100644 index 4638f660..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeHfma.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeHfma : IOpCode - { - bool NegateB { get; } - bool NegateC { get; } - bool Saturate { get; } - - FPHalfSwizzle SwizzleA { get; } - FPHalfSwizzle SwizzleB { get; } - FPHalfSwizzle SwizzleC { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImm.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeImm.cs deleted file mode 100644 index 9cfcd69b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImm.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeImm : IOpCode - { - int Immediate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImmF.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeImmF.cs deleted file mode 100644 index 629eff79..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeImmF.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeImmF : IOpCode - { - float Immediate { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeLop.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeLop.cs deleted file mode 100644 index 62c87bf4..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeLop.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeLop : IOpCodeAlu - { - LogicalOperation LogicalOp { get; } - - bool InvertA { get; } - bool InvertB { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRa.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRa.cs deleted file mode 100644 index e5902110..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRa.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRa : IOpCode - { - Register Ra { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRc.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRc.cs deleted file mode 100644 index bb806b95..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRc.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRc : IOpCode - { - Register Rc { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRd.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRd.cs deleted file mode 100644 index 099c4061..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRd.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRd : IOpCode - { - Register Rd { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeReg.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeReg.cs deleted file mode 100644 index 3ed157e8..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeReg.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeReg : IOpCode - { - Register Rb { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/IOpCodeRegCbuf.cs deleted file mode 100644 index 429f01bb..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IOpCodeRegCbuf.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - interface IOpCodeRegCbuf : IOpCodeRc - { - int Offset { get; } - int Slot { get; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerCondition.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerCondition.cs deleted file mode 100644 index a1937c2f..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerCondition.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerCondition - { - Less = 1 << 0, - Equal = 1 << 1, - Greater = 1 << 2, - - Never = 0, - - LessOrEqual = Less | Equal, - NotEqual = Less | Greater, - GreaterOrEqual = Greater | Equal, - Number = Greater | Equal | Less, - - Always = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerHalfPart.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerHalfPart.cs deleted file mode 100644 index b779f44d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerHalfPart.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerHalfPart - { - B32 = 0, - H0 = 1, - H1 = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerShift.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerShift.cs deleted file mode 100644 index ce4d9f3b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerShift.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerShift - { - NoShift = 0, - ShiftRight = 1, - ShiftLeft = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerSize.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerSize.cs deleted file mode 100644 index 70fdfc3d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerSize.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerSize - { - U8 = 0, - S8 = 1, - U16 = 2, - S16 = 3, - B32 = 4, - B64 = 5 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/IntegerType.cs b/Ryujinx.Graphics/Shader/Decoders/IntegerType.cs deleted file mode 100644 index 46734dbe..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/IntegerType.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum IntegerType - { - U8 = 0, - U16 = 1, - U32 = 2, - U64 = 3, - S8 = 4, - S16 = 5, - S32 = 6, - S64 = 7 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/LogicalOperation.cs b/Ryujinx.Graphics/Shader/Decoders/LogicalOperation.cs deleted file mode 100644 index 52214425..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/LogicalOperation.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum LogicalOperation - { - And = 0, - Or = 1, - ExclusiveOr = 2, - Passthrough = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/MufuOperation.cs b/Ryujinx.Graphics/Shader/Decoders/MufuOperation.cs deleted file mode 100644 index 88bd1f5c..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/MufuOperation.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum MufuOperation - { - Cosine = 0, - Sine = 1, - ExponentB2 = 2, - LogarithmB2 = 3, - Reciprocal = 4, - ReciprocalSquareRoot = 5, - Reciprocal64H = 6, - ReciprocalSquareRoot64H = 7, - SquareRoot = 8 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCode.cs b/Ryujinx.Graphics/Shader/Decoders/OpCode.cs deleted file mode 100644 index 94af49e0..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCode.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCode - { - public InstEmitter Emitter { get; } - - public ulong Address { get; } - public long RawOpCode { get; } - - public Register Predicate { get; protected set; } - - public bool InvertPredicate { get; protected set; } - - // When inverted, the always true predicate == always false. - public bool NeverExecute => Predicate.Index == RegisterConsts.PredicateTrueIndex && InvertPredicate; - - public OpCode(InstEmitter emitter, ulong address, long opCode) - { - Emitter = emitter; - Address = address; - RawOpCode = opCode; - - Predicate = new Register(opCode.Extract(16, 3), RegisterType.Predicate); - - InvertPredicate = opCode.Extract(19); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAlu.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAlu.cs deleted file mode 100644 index 15fbb9af..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAlu.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAlu : OpCode, IOpCodeAlu, IOpCodeRc - { - public Register Rd { get; } - public Register Ra { get; } - public Register Rc { get; } - public Register Predicate39 { get; } - - public int ByteSelection { get; } - - public bool InvertP { get; } - public bool Extended { get; protected set; } - public bool SetCondCode { get; protected set; } - public bool Saturate { get; protected set; } - - public OpCodeAlu(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr); - Predicate39 = new Register(opCode.Extract(39, 3), RegisterType.Predicate); - - ByteSelection = opCode.Extract(41, 2); - - InvertP = opCode.Extract(42); - Extended = opCode.Extract(43); - SetCondCode = opCode.Extract(47); - Saturate = opCode.Extract(50); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluCbuf.cs deleted file mode 100644 index 9c127989..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluCbuf : OpCodeAlu, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeAluCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm.cs deleted file mode 100644 index a407fc6b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluImm : OpCodeAlu, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeAluImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeS20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm2x10.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm2x10.cs deleted file mode 100644 index 9aeb32bd..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm2x10.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluImm2x10 : OpCodeAlu, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeAluImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.Decode2xF10Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm32.cs deleted file mode 100644 index 5941e0b9..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluImm32.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluImm32 : OpCodeAlu, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeAluImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = opCode.Extract(20, 32); - - SetCondCode = opCode.Extract(52); - Extended = opCode.Extract(53); - Saturate = opCode.Extract(54); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluReg.cs deleted file mode 100644 index 13b96a3a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluReg : OpCodeAlu, IOpCodeReg - { - public Register Rb { get; protected set; } - - public OpCodeAluReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAluRegCbuf.cs deleted file mode 100644 index 6cf6bd2e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAluRegCbuf.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAluRegCbuf : OpCodeAluReg, IOpCodeRegCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeAluRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - - Rb = new Register(opCode.Extract(39, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeAttribute.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeAttribute.cs deleted file mode 100644 index fd8e63fc..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeAttribute.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeAttribute : OpCodeAluReg - { - public int AttributeOffset { get; } - public int Count { get; } - - public OpCodeAttribute(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - AttributeOffset = opCode.Extract(20, 10); - Count = opCode.Extract(47, 2) + 1; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeBranch.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeBranch.cs deleted file mode 100644 index 25941b39..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeBranch.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeBranch : OpCode - { - public int Offset { get; } - - public OpCodeBranch(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = ((int)(opCode >> 20) << 8) >> 8; - } - - public ulong GetAbsoluteAddress() - { - return (ulong)((long)Address + (long)Offset + 8); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs deleted file mode 100644 index d50903eb..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeExit : OpCode - { - public Condition Condition { get; } - - public OpCodeExit(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Condition = (Condition)opCode.Extract(0, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArith.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArith.cs deleted file mode 100644 index c88f7f0e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArith.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArith : OpCodeAlu, IOpCodeFArith - { - public RoundingMode RoundingMode { get; } - - public FmulScale Scale { get; } - - public bool FlushToZero { get; } - public bool AbsoluteA { get; } - - public OpCodeFArith(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - RoundingMode = (RoundingMode)opCode.Extract(39, 2); - - Scale = (FmulScale)opCode.Extract(41, 3); - - FlushToZero = opCode.Extract(44); - AbsoluteA = opCode.Extract(46); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithCbuf.cs deleted file mode 100644 index 5486bb0b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithCbuf : OpCodeFArith, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeFArithCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm.cs deleted file mode 100644 index 1bb6f425..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithImm : OpCodeFArith, IOpCodeImmF - { - public float Immediate { get; } - - public OpCodeFArithImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeF20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm32.cs deleted file mode 100644 index ec9da6f3..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithImm32.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithImm32 : OpCodeAlu, IOpCodeFArith, IOpCodeImmF - { - public RoundingMode RoundingMode => RoundingMode.ToNearest; - - public FmulScale Scale => FmulScale.None; - - public bool FlushToZero { get; } - public bool AbsoluteA { get; } - - public float Immediate { get; } - - public OpCodeFArithImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - int imm = opCode.Extract(20, 32); - - Immediate = BitConverter.Int32BitsToSingle(imm); - - SetCondCode = opCode.Extract(52); - AbsoluteA = opCode.Extract(54); - FlushToZero = opCode.Extract(55); - - Saturate = false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithReg.cs deleted file mode 100644 index 55cf4485..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithReg : OpCodeFArith, IOpCodeReg - { - public Register Rb { get; protected set; } - - public OpCodeFArithReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithRegCbuf.cs deleted file mode 100644 index 315c2c8b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFArithRegCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFArithRegCbuf : OpCodeFArith, IOpCodeRegCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeFArithRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeFsetImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeFsetImm.cs deleted file mode 100644 index cb5f155e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeFsetImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeFsetImm : OpCodeSet, IOpCodeImmF - { - public float Immediate { get; } - - public OpCodeFsetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeF20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfma.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfma.cs deleted file mode 100644 index 32f3cd7a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfma.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfma : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeRc - { - public Register Rd { get; } - public Register Ra { get; } - public Register Rc { get; protected set; } - - public FPHalfSwizzle SwizzleA { get; } - - public OpCodeHfma(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr); - - SwizzleA = (FPHalfSwizzle)opCode.Extract(47, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaCbuf.cs deleted file mode 100644 index 33768c7d..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaCbuf.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public bool NegateB { get; } - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP32; - public FPHalfSwizzle SwizzleC { get; } - - public OpCodeHfmaCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - - NegateC = opCode.Extract(51); - Saturate = opCode.Extract(52); - - SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2); - - NegateB = opCode.Extract(56); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm2x10.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm2x10.cs deleted file mode 100644 index 80a5a140..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm2x10.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaImm2x10 : OpCodeHfma, IOpCodeHfma, IOpCodeImm - { - public int Immediate { get; } - - public bool NegateB => false; - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16; - public FPHalfSwizzle SwizzleC { get; } - - public OpCodeHfmaImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.Decode2xF10Immediate(opCode); - - NegateC = opCode.Extract(51); - Saturate = opCode.Extract(52); - - SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm32.cs deleted file mode 100644 index 05eb9ffe..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaImm32.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaImm32 : OpCodeHfma, IOpCodeHfma, IOpCodeImm - { - public int Immediate { get; } - - public bool NegateB => false; - public bool NegateC { get; } - public bool Saturate => false; - - public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16; - public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP16; - - public OpCodeHfmaImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = opCode.Extract(20, 32); - - NegateC = opCode.Extract(52); - - Rc = Rd; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaReg.cs deleted file mode 100644 index 714c89de..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaReg.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaReg : OpCodeHfma, IOpCodeHfma, IOpCodeReg - { - public Register Rb { get; } - - public bool NegateB { get; } - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB { get; } - public FPHalfSwizzle SwizzleC { get; } - - public OpCodeHfmaReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - - SwizzleB = (FPHalfSwizzle)opCode.Extract(28, 2); - - NegateC = opCode.Extract(30); - NegateB = opCode.Extract(31); - Saturate = opCode.Extract(32); - - SwizzleC = (FPHalfSwizzle)opCode.Extract(35, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaRegCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaRegCbuf.cs deleted file mode 100644 index c0001908..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeHfmaRegCbuf.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeHfmaRegCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeRegCbuf - { - public int Offset { get; } - public int Slot { get; } - - public bool NegateB { get; } - public bool NegateC { get; } - public bool Saturate { get; } - - public FPHalfSwizzle SwizzleB { get; } - public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP32; - - public OpCodeHfmaRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - - NegateC = opCode.Extract(51); - Saturate = opCode.Extract(52); - - SwizzleB = (FPHalfSwizzle)opCode.Extract(53, 2); - - NegateB = opCode.Extract(56); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeIpa.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeIpa.cs deleted file mode 100644 index e21095a3..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeIpa.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeIpa : OpCodeAluReg - { - public int AttributeOffset { get; } - - public OpCodeIpa(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - AttributeOffset = opCode.Extract(28, 10); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLdc.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLdc.cs deleted file mode 100644 index cc9f0658..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLdc.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLdc : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeCbuf - { - public Register Rd { get; } - public Register Ra { get; } - - public int Offset { get; } - public int Slot { get; } - - public IntegerSize Size { get; } - - public OpCodeLdc(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - - Offset = opCode.Extract(22, 14); - Slot = opCode.Extract(36, 5); - - Size = (IntegerSize)opCode.Extract(48, 3); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLop.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLop.cs deleted file mode 100644 index c5f90345..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLop.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLop : OpCodeAlu, IOpCodeLop - { - public bool InvertA { get; protected set; } - public bool InvertB { get; protected set; } - - public LogicalOperation LogicalOp { get; } - - public ConditionalOperation CondOp { get; } - - public Register Predicate48 { get; } - - public OpCodeLop(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - InvertA = opCode.Extract(39); - InvertB = opCode.Extract(40); - - LogicalOp = (LogicalOperation)opCode.Extract(41, 2); - - CondOp = (ConditionalOperation)opCode.Extract(44, 2); - - Predicate48 = new Register(opCode.Extract(48, 3), RegisterType.Predicate); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopCbuf.cs deleted file mode 100644 index f174733c..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopCbuf : OpCodeLop, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeLopCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm.cs deleted file mode 100644 index a2f091a2..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopImm : OpCodeLop, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeLopImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeS20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm32.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm32.cs deleted file mode 100644 index cb48f3a6..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopImm32.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopImm32 : OpCodeAluImm32, IOpCodeLop, IOpCodeImm - { - public LogicalOperation LogicalOp { get; } - - public bool InvertA { get; } - public bool InvertB { get; } - - public OpCodeLopImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - LogicalOp = (LogicalOperation)opCode.Extract(53, 2); - - InvertA = opCode.Extract(55); - InvertB = opCode.Extract(56); - - Extended = opCode.Extract(57); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeLopReg.cs deleted file mode 100644 index 5f43db72..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeLopReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeLopReg : OpCodeLop, IOpCodeReg - { - public Register Rb { get; } - - public OpCodeLopReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodePsetp.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodePsetp.cs deleted file mode 100644 index 729e3207..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodePsetp.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodePsetp : OpCodeSet - { - public Register Predicate12 { get; } - public Register Predicate29 { get; } - - public LogicalOperation LogicalOpAB { get; } - - public OpCodePsetp(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Predicate12 = new Register(opCode.Extract(12, 3), RegisterType.Predicate); - Predicate29 = new Register(opCode.Extract(29, 3), RegisterType.Predicate); - - LogicalOpAB = (LogicalOperation)opCode.Extract(24, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSet.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSet.cs deleted file mode 100644 index cd6773a1..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSet.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSet : OpCodeAlu - { - public Register Predicate0 { get; } - public Register Predicate3 { get; } - - public bool NegateP { get; } - - public LogicalOperation LogicalOp { get; } - - public bool FlushToZero { get; } - - public OpCodeSet(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Predicate0 = new Register(opCode.Extract(0, 3), RegisterType.Predicate); - Predicate3 = new Register(opCode.Extract(3, 3), RegisterType.Predicate); - - LogicalOp = (LogicalOperation)opCode.Extract(45, 2); - - FlushToZero = opCode.Extract(47); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetCbuf.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSetCbuf.cs deleted file mode 100644 index 4f3dbd74..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetCbuf.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSetCbuf : OpCodeSet, IOpCodeCbuf - { - public int Offset { get; } - public int Slot { get; } - - public OpCodeSetCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Offset = opCode.Extract(20, 14); - Slot = opCode.Extract(34, 5); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetImm.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSetImm.cs deleted file mode 100644 index bc63b9f4..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetImm.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSetImm : OpCodeSet, IOpCodeImm - { - public int Immediate { get; } - - public OpCodeSetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Immediate = DecoderHelper.DecodeS20Immediate(opCode); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetReg.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSetReg.cs deleted file mode 100644 index bbdee196..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSetReg.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSetReg : OpCodeSet, IOpCodeReg - { - public Register Rb { get; protected set; } - - public OpCodeSetReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSsy.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSsy.cs deleted file mode 100644 index 499c0706..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSsy.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSsy : OpCodeBranch - { - public Dictionary<OpCodeSync, Operand> Syncs { get; } - - public OpCodeSsy(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Syncs = new Dictionary<OpCodeSync, Operand>(); - - Predicate = new Register(RegisterConsts.PredicateTrueIndex, RegisterType.Predicate); - - InvertPredicate = false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeSync.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeSync.cs deleted file mode 100644 index 081d08a0..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeSync.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeSync : OpCode - { - public Dictionary<OpCodeSsy, int> Targets { get; } - - public OpCodeSync(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Targets = new Dictionary<OpCodeSsy, int>(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTable.cs deleted file mode 100644 index d588ce8e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTable.cs +++ /dev/null @@ -1,216 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class OpCodeTable - { - private const int EncodingBits = 14; - - private class TableEntry - { - public InstEmitter Emitter { get; } - - public Type OpCodeType { get; } - - public int XBits { get; } - - public TableEntry(InstEmitter emitter, Type opCodeType, int xBits) - { - Emitter = emitter; - OpCodeType = opCodeType; - XBits = xBits; - } - } - - private static TableEntry[] _opCodes; - - static OpCodeTable() - { - _opCodes = new TableEntry[1 << EncodingBits]; - -#region Instructions - Set("1110111111011x", InstEmit.Ald, typeof(OpCodeAttribute)); - Set("1110111111110x", InstEmit.Ast, typeof(OpCodeAttribute)); - Set("0100110000000x", InstEmit.Bfe, typeof(OpCodeAluCbuf)); - Set("0011100x00000x", InstEmit.Bfe, typeof(OpCodeAluImm)); - Set("0101110000000x", InstEmit.Bfe, typeof(OpCodeAluReg)); - Set("111000100100xx", InstEmit.Bra, typeof(OpCodeBranch)); - Set("111000110000xx", InstEmit.Exit, typeof(OpCodeExit)); - Set("0100110010101x", InstEmit.F2F, typeof(OpCodeFArithCbuf)); - Set("0011100x10101x", InstEmit.F2F, typeof(OpCodeFArithImm)); - Set("0101110010101x", InstEmit.F2F, typeof(OpCodeFArithReg)); - Set("0100110010110x", InstEmit.F2I, typeof(OpCodeFArithCbuf)); - Set("0011100x10110x", InstEmit.F2I, typeof(OpCodeFArithImm)); - Set("0101110010110x", InstEmit.F2I, typeof(OpCodeFArithReg)); - Set("0100110001011x", InstEmit.Fadd, typeof(OpCodeFArithCbuf)); - Set("0011100x01011x", InstEmit.Fadd, typeof(OpCodeFArithImm)); - Set("000010xxxxxxxx", InstEmit.Fadd, typeof(OpCodeFArithImm32)); - Set("0101110001011x", InstEmit.Fadd, typeof(OpCodeFArithReg)); - Set("010010011xxxxx", InstEmit.Ffma, typeof(OpCodeFArithCbuf)); - Set("0011001x1xxxxx", InstEmit.Ffma, typeof(OpCodeFArithImm)); - Set("010100011xxxxx", InstEmit.Ffma, typeof(OpCodeFArithRegCbuf)); - Set("010110011xxxxx", InstEmit.Ffma, typeof(OpCodeFArithReg)); - Set("0100110001100x", InstEmit.Fmnmx, typeof(OpCodeFArithCbuf)); - Set("0011100x01100x", InstEmit.Fmnmx, typeof(OpCodeFArithImm)); - Set("0101110001100x", InstEmit.Fmnmx, typeof(OpCodeFArithReg)); - Set("0100110001101x", InstEmit.Fmul, typeof(OpCodeFArithCbuf)); - Set("0011100x01101x", InstEmit.Fmul, typeof(OpCodeFArithImm)); - Set("00011110xxxxxx", InstEmit.Fmul, typeof(OpCodeFArithImm32)); - Set("0101110001101x", InstEmit.Fmul, typeof(OpCodeFArithReg)); - Set("0100100xxxxxxx", InstEmit.Fset, typeof(OpCodeSetCbuf)); - Set("0011000xxxxxxx", InstEmit.Fset, typeof(OpCodeFsetImm)); - Set("01011000xxxxxx", InstEmit.Fset, typeof(OpCodeSetReg)); - Set("010010111011xx", InstEmit.Fsetp, typeof(OpCodeSetCbuf)); - Set("0011011x1011xx", InstEmit.Fsetp, typeof(OpCodeFsetImm)); - Set("010110111011xx", InstEmit.Fsetp, typeof(OpCodeSetReg)); - Set("0111101x1xxxxx", InstEmit.Hadd2, typeof(OpCodeAluCbuf)); - Set("0111101x0xxxxx", InstEmit.Hadd2, typeof(OpCodeAluImm2x10)); - Set("0010110xxxxxxx", InstEmit.Hadd2, typeof(OpCodeAluImm32)); - Set("0101110100010x", InstEmit.Hadd2, typeof(OpCodeAluReg)); - Set("01110xxx1xxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaCbuf)); - Set("01110xxx0xxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaImm2x10)); - Set("0010100xxxxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaImm32)); - Set("0101110100000x", InstEmit.Hfma2, typeof(OpCodeHfmaReg)); - Set("01100xxx1xxxxx", InstEmit.Hfma2, typeof(OpCodeHfmaRegCbuf)); - Set("0111100x1xxxxx", InstEmit.Hmul2, typeof(OpCodeAluCbuf)); - Set("0111100x0xxxxx", InstEmit.Hmul2, typeof(OpCodeAluImm2x10)); - Set("0010101xxxxxxx", InstEmit.Hmul2, typeof(OpCodeAluImm32)); - Set("0101110100001x", InstEmit.Hmul2, typeof(OpCodeAluReg)); - Set("0100110010111x", InstEmit.I2F, typeof(OpCodeAluCbuf)); - Set("0011100x10111x", InstEmit.I2F, typeof(OpCodeAluImm)); - Set("0101110010111x", InstEmit.I2F, typeof(OpCodeAluReg)); - Set("0100110011100x", InstEmit.I2I, typeof(OpCodeAluCbuf)); - Set("0011100x11100x", InstEmit.I2I, typeof(OpCodeAluImm)); - Set("0101110011100x", InstEmit.I2I, typeof(OpCodeAluReg)); - Set("0100110000010x", InstEmit.Iadd, typeof(OpCodeAluCbuf)); - Set("0011100000010x", InstEmit.Iadd, typeof(OpCodeAluImm)); - Set("0001110x0xxxxx", InstEmit.Iadd, typeof(OpCodeAluImm32)); - Set("0101110000010x", InstEmit.Iadd, typeof(OpCodeAluReg)); - Set("010011001100xx", InstEmit.Iadd3, typeof(OpCodeAluCbuf)); - Set("001110001100xx", InstEmit.Iadd3, typeof(OpCodeAluImm)); - Set("010111001100xx", InstEmit.Iadd3, typeof(OpCodeAluReg)); - Set("0100110000100x", InstEmit.Imnmx, typeof(OpCodeAluCbuf)); - Set("0011100x00100x", InstEmit.Imnmx, typeof(OpCodeAluImm)); - Set("0101110000100x", InstEmit.Imnmx, typeof(OpCodeAluReg)); - Set("11100000xxxxxx", InstEmit.Ipa, typeof(OpCodeIpa)); - Set("0100110000011x", InstEmit.Iscadd, typeof(OpCodeAluCbuf)); - Set("0011100x00011x", InstEmit.Iscadd, typeof(OpCodeAluImm)); - Set("000101xxxxxxxx", InstEmit.Iscadd, typeof(OpCodeAluImm32)); - Set("0101110000011x", InstEmit.Iscadd, typeof(OpCodeAluReg)); - Set("010010110101xx", InstEmit.Iset, typeof(OpCodeSetCbuf)); - Set("001101100101xx", InstEmit.Iset, typeof(OpCodeSetImm)); - Set("010110110101xx", InstEmit.Iset, typeof(OpCodeSetReg)); - Set("010010110110xx", InstEmit.Isetp, typeof(OpCodeSetCbuf)); - Set("0011011x0110xx", InstEmit.Isetp, typeof(OpCodeSetImm)); - Set("010110110110xx", InstEmit.Isetp, typeof(OpCodeSetReg)); - Set("111000110011xx", InstEmit.Kil, typeof(OpCodeExit)); - Set("1110111110010x", InstEmit.Ldc, typeof(OpCodeLdc)); - Set("0100110001000x", InstEmit.Lop, typeof(OpCodeLopCbuf)); - Set("0011100001000x", InstEmit.Lop, typeof(OpCodeLopImm)); - Set("000001xxxxxxxx", InstEmit.Lop, typeof(OpCodeLopImm32)); - Set("0101110001000x", InstEmit.Lop, typeof(OpCodeLopReg)); - Set("0010000xxxxxxx", InstEmit.Lop3, typeof(OpCodeLopCbuf)); - Set("001111xxxxxxxx", InstEmit.Lop3, typeof(OpCodeLopImm)); - Set("0101101111100x", InstEmit.Lop3, typeof(OpCodeLopReg)); - Set("0100110010011x", InstEmit.Mov, typeof(OpCodeAluCbuf)); - Set("0011100x10011x", InstEmit.Mov, typeof(OpCodeAluImm)); - Set("000000010000xx", InstEmit.Mov, typeof(OpCodeAluImm32)); - Set("0101110010011x", InstEmit.Mov, typeof(OpCodeAluReg)); - Set("0101000010000x", InstEmit.Mufu, typeof(OpCodeFArith)); - Set("1111101111100x", InstEmit.Out, typeof(OpCode)); - Set("0101000010010x", InstEmit.Psetp, typeof(OpCodePsetp)); - Set("0100110010010x", InstEmit.Rro, typeof(OpCodeFArithCbuf)); - Set("0011100x10010x", InstEmit.Rro, typeof(OpCodeFArithImm)); - Set("0101110010010x", InstEmit.Rro, typeof(OpCodeFArithReg)); - Set("0100110010100x", InstEmit.Sel, typeof(OpCodeAluCbuf)); - Set("0011100010100x", InstEmit.Sel, typeof(OpCodeAluImm)); - Set("0101110010100x", InstEmit.Sel, typeof(OpCodeAluReg)); - Set("0100110001001x", InstEmit.Shl, typeof(OpCodeAluCbuf)); - Set("0011100x01001x", InstEmit.Shl, typeof(OpCodeAluImm)); - Set("0101110001001x", InstEmit.Shl, typeof(OpCodeAluReg)); - Set("0100110000101x", InstEmit.Shr, typeof(OpCodeAluCbuf)); - Set("0011100x00101x", InstEmit.Shr, typeof(OpCodeAluImm)); - Set("0101110000101x", InstEmit.Shr, typeof(OpCodeAluReg)); - Set("111000101001xx", InstEmit.Ssy, typeof(OpCodeSsy)); - Set("1111000011111x", InstEmit.Sync, typeof(OpCodeSync)); - Set("110000xxxx111x", InstEmit.Tex, typeof(OpCodeTex)); - Set("1101111010111x", InstEmit.Tex_B, typeof(OpCodeTex)); - Set("1101x00xxxxxxx", InstEmit.Texs, typeof(OpCodeTexs)); - Set("1101x01xxxxxxx", InstEmit.Texs, typeof(OpCodeTlds)); - Set("1101x11100xxxx", InstEmit.Texs, typeof(OpCodeTld4s)); - Set("11011100xx111x", InstEmit.Tld, typeof(OpCodeTld)); - Set("11011101xx111x", InstEmit.Tld_B, typeof(OpCodeTld)); - Set("110010xxxx111x", InstEmit.Tld4, typeof(OpCodeTld4)); - Set("1101111101001x", InstEmit.Txq, typeof(OpCodeTex)); - Set("1101111101010x", InstEmit.Txq_B, typeof(OpCodeTex)); - Set("0100111xxxxxxx", InstEmit.Xmad, typeof(OpCodeAluCbuf)); - Set("0011011x00xxxx", InstEmit.Xmad, typeof(OpCodeAluImm)); - Set("010100010xxxxx", InstEmit.Xmad, typeof(OpCodeAluRegCbuf)); - Set("0101101100xxxx", InstEmit.Xmad, typeof(OpCodeAluReg)); -#endregion - } - - private static void Set(string encoding, InstEmitter emitter, Type opCodeType) - { - if (encoding.Length != EncodingBits) - { - throw new ArgumentException(nameof(encoding)); - } - - int bit = encoding.Length - 1; - int value = 0; - int xMask = 0; - int xBits = 0; - - int[] xPos = new int[encoding.Length]; - - for (int index = 0; index < encoding.Length; index++, bit--) - { - char chr = encoding[index]; - - if (chr == '1') - { - value |= 1 << bit; - } - else if (chr == 'x') - { - xMask |= 1 << bit; - - xPos[xBits++] = bit; - } - } - - xMask = ~xMask; - - TableEntry entry = new TableEntry(emitter, opCodeType, xBits); - - for (int index = 0; index < (1 << xBits); index++) - { - value &= xMask; - - for (int X = 0; X < xBits; X++) - { - value |= ((index >> X) & 1) << xPos[X]; - } - - if (_opCodes[value] == null || _opCodes[value].XBits > xBits) - { - _opCodes[value] = entry; - } - } - } - - public static (InstEmitter emitter, Type opCodeType) GetEmitter(long OpCode) - { - TableEntry entry = _opCodes[(ulong)OpCode >> (64 - EncodingBits)]; - - if (entry != null) - { - return (entry.Emitter, entry.OpCodeType); - } - - return (null, null); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTex.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTex.cs deleted file mode 100644 index da8756b9..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTex.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTex : OpCodeTexture - { - public OpCodeTex(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasDepthCompare = opCode.Extract(50); - - HasOffset = opCode.Extract(54); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexs.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTexs.cs deleted file mode 100644 index 0822c4c0..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexs.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTexs : OpCodeTextureScalar - { - public TextureScalarType Type => (TextureScalarType)RawType; - - public OpCodeTexs(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexture.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTexture.cs deleted file mode 100644 index 7a7e8f46..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTexture.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTexture : OpCode - { - public Register Rd { get; } - public Register Ra { get; } - public Register Rb { get; } - - public bool IsArray { get; } - - public TextureDimensions Dimensions { get; } - - public int ComponentMask { get; } - - public int Immediate { get; } - - public TextureLodMode LodMode { get; protected set; } - - public bool HasOffset { get; protected set; } - public bool HasDepthCompare { get; protected set; } - public bool IsMultisample { get; protected set; } - - public OpCodeTexture(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - - IsArray = opCode.Extract(28); - - Dimensions = (TextureDimensions)opCode.Extract(29, 2); - - ComponentMask = opCode.Extract(31, 4); - - Immediate = opCode.Extract(36, 13); - - LodMode = (TextureLodMode)opCode.Extract(55, 3); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTextureScalar.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTextureScalar.cs deleted file mode 100644 index 470b81f5..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTextureScalar.cs +++ /dev/null @@ -1,62 +0,0 @@ -// ReSharper disable InconsistentNaming -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTextureScalar : OpCode - { -#region "Component mask LUT" - private const int ____ = 0x0; - private const int R___ = 0x1; - private const int _G__ = 0x2; - private const int RG__ = 0x3; - private const int __B_ = 0x4; - private const int RGB_ = 0x7; - private const int ___A = 0x8; - private const int R__A = 0x9; - private const int _G_A = 0xa; - private const int RG_A = 0xb; - private const int __BA = 0xc; - private const int R_BA = 0xd; - private const int _GBA = 0xe; - private const int RGBA = 0xf; - - private static int[,] _maskLut = new int[,] - { - { R___, _G__, __B_, ___A, RG__, R__A, _G_A, __BA }, - { RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ } - }; -#endregion - - public Register Rd0 { get; } - public Register Ra { get; } - public Register Rb { get; } - public Register Rd1 { get; } - - public int Immediate { get; } - - public int ComponentMask { get; } - - protected int RawType; - - public bool IsFp16 { get; } - - public OpCodeTextureScalar(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - Rd0 = new Register(opCode.Extract(0, 8), RegisterType.Gpr); - Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); - Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); - Rd1 = new Register(opCode.Extract(28, 8), RegisterType.Gpr); - - Immediate = opCode.Extract(36, 13); - - int compSel = opCode.Extract(50, 3); - - RawType = opCode.Extract(53, 4); - - IsFp16 = !opCode.Extract(59); - - ComponentMask = _maskLut[Rd1.IsRZ ? 0 : 1, compSel]; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTld.cs deleted file mode 100644 index 61bd900b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTld : OpCodeTexture - { - public OpCodeTld(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasOffset = opCode.Extract(35); - - IsMultisample = opCode.Extract(50); - - bool isLL = opCode.Extract(55); - - LodMode = isLL - ? TextureLodMode.LodLevel - : TextureLodMode.LodZero; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4.cs deleted file mode 100644 index 485edf93..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTld4 : OpCodeTexture - { - public TextureGatherOffset Offset { get; } - - public int GatherCompIndex { get; } - - public OpCodeTld4(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasDepthCompare = opCode.Extract(50); - - Offset = (TextureGatherOffset)opCode.Extract(54, 2); - - GatherCompIndex = opCode.Extract(56, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4s.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4s.cs deleted file mode 100644 index 0d7b8460..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTld4s.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTld4s : OpCodeTextureScalar - { - public bool HasDepthCompare { get; } - public bool HasOffset { get; } - - public int GatherCompIndex { get; } - - public OpCodeTld4s(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) - { - HasDepthCompare = opCode.Extract(50); - HasOffset = opCode.Extract(51); - - GatherCompIndex = opCode.Extract(52, 2); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeTlds.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeTlds.cs deleted file mode 100644 index e117721e..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeTlds.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.Graphics.Shader.Instructions; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - class OpCodeTlds : OpCodeTextureScalar - { - public TexelLoadScalarType Type => (TexelLoadScalarType)RawType; - - public OpCodeTlds(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/Register.cs b/Ryujinx.Graphics/Shader/Decoders/Register.cs deleted file mode 100644 index 30840d8c..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/Register.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.Decoders -{ - struct Register : IEquatable<Register> - { - public int Index { get; } - - public RegisterType Type { get; } - - public bool IsRZ => Type == RegisterType.Gpr && Index == RegisterConsts.RegisterZeroIndex; - public bool IsPT => Type == RegisterType.Predicate && Index == RegisterConsts.PredicateTrueIndex; - - public Register(int index, RegisterType type) - { - Index = index; - Type = type; - } - - public override int GetHashCode() - { - return (ushort)Index | ((ushort)Type << 16); - } - - public override bool Equals(object obj) - { - return obj is Register reg && Equals(reg); - } - - public bool Equals(Register other) - { - return other.Index == Index && - other.Type == Type; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/RegisterConsts.cs b/Ryujinx.Graphics/Shader/Decoders/RegisterConsts.cs deleted file mode 100644 index d381f954..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/RegisterConsts.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - static class RegisterConsts - { - public const int GprsCount = 255; - public const int PredsCount = 7; - public const int FlagsCount = 4; - public const int TotalCount = GprsCount + PredsCount + FlagsCount; - - public const int RegisterZeroIndex = GprsCount; - public const int PredicateTrueIndex = PredsCount; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/RegisterType.cs b/Ryujinx.Graphics/Shader/Decoders/RegisterType.cs deleted file mode 100644 index 648f816a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/RegisterType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum RegisterType - { - Flag, - Gpr, - Predicate, - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/RoundingMode.cs b/Ryujinx.Graphics/Shader/Decoders/RoundingMode.cs deleted file mode 100644 index 13bb08dc..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/RoundingMode.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum RoundingMode - { - ToNearest = 0, - TowardsNegativeInfinity = 1, - TowardsPositiveInfinity = 2, - TowardsZero = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TexelLoadScalarType.cs b/Ryujinx.Graphics/Shader/Decoders/TexelLoadScalarType.cs deleted file mode 100644 index cef5778a..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TexelLoadScalarType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TexelLoadScalarType - { - Texture1DLodZero = 0x0, - Texture1DLodLevel = 0x1, - Texture2DLodZero = 0x2, - Texture2DLodZeroOffset = 0x4, - Texture2DLodLevel = 0x5, - Texture2DLodZeroMultisample = 0x6, - Texture3DLodZero = 0x7, - Texture2DArrayLodZero = 0x8, - Texture2DLodLevelOffset = 0xc - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureDimensions.cs b/Ryujinx.Graphics/Shader/Decoders/TextureDimensions.cs deleted file mode 100644 index dbdf1927..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureDimensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureDimensions - { - Texture1D = 0, - Texture2D = 1, - Texture3D = 2, - TextureCube = 3 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureGatherOffset.cs b/Ryujinx.Graphics/Shader/Decoders/TextureGatherOffset.cs deleted file mode 100644 index 4e9ade26..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureGatherOffset.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureGatherOffset - { - None = 0, - Offset = 1, - Offsets = 2 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureLodMode.cs b/Ryujinx.Graphics/Shader/Decoders/TextureLodMode.cs deleted file mode 100644 index 0cc6f714..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureLodMode.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureLodMode - { - None = 0, - LodZero = 1, - LodBias = 2, - LodLevel = 3, - LodBiasA = 4, //? - LodLevelA = 5 //? - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureProperty.cs b/Ryujinx.Graphics/Shader/Decoders/TextureProperty.cs deleted file mode 100644 index ea35b1d1..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureProperty.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureProperty - { - Dimensions = 0x1, - Type = 0x2, - SamplePos = 0x5, - Filter = 0xa, - Lod = 0xc, - Wrap = 0xe, - BorderColor = 0x10 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/TextureScalarType.cs b/Ryujinx.Graphics/Shader/Decoders/TextureScalarType.cs deleted file mode 100644 index 0055174b..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/TextureScalarType.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum TextureScalarType - { - Texture1DLodZero = 0x0, - Texture2D = 0x1, - Texture2DLodZero = 0x2, - Texture2DLodLevel = 0x3, - Texture2DDepthCompare = 0x4, - Texture2DLodLevelDepthCompare = 0x5, - Texture2DLodZeroDepthCompare = 0x6, - Texture2DArray = 0x7, - Texture2DArrayLodZero = 0x8, - Texture2DArrayLodZeroDepthCompare = 0x9, - Texture3D = 0xa, - Texture3DLodZero = 0xb, - TextureCube = 0xc, - TextureCubeLodLevel = 0xd - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Decoders/XmadCMode.cs b/Ryujinx.Graphics/Shader/Decoders/XmadCMode.cs deleted file mode 100644 index 949a2ef7..00000000 --- a/Ryujinx.Graphics/Shader/Decoders/XmadCMode.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Decoders -{ - enum XmadCMode - { - Cfull = 0, - Clo = 1, - Chi = 2, - Csfu = 3, - Cbcc = 4 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs deleted file mode 100644 index 8e2b39bf..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs +++ /dev/null @@ -1,684 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Bfe(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isReverse = op.RawOpCode.Extract(40); - bool isSigned = op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - if (isReverse) - { - srcA = context.BitfieldReverse(srcA); - } - - Operand position = context.BitwiseAnd(srcB, Const(0xff)); - - Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8)); - - Operand res = isSigned - ? context.BitfieldExtractS32(srcA, position, size) - : context.BitfieldExtractU32(srcA, position, size); - - context.Copy(GetDest(context), res); - - // TODO: CC, X, corner cases - } - - public static void Iadd(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool negateA = false, negateB = false; - - if (!(op is OpCodeAluImm32)) - { - negateB = op.RawOpCode.Extract(48); - negateA = op.RawOpCode.Extract(49); - } - - Operand srcA = context.INegate(GetSrcA(context), negateA); - Operand srcB = context.INegate(GetSrcB(context), negateB); - - Operand res = context.IAdd(srcA, srcB); - - bool isSubtraction = negateA || negateB; - - if (op.Extended) - { - // Add carry, or subtract borrow. - res = context.IAdd(res, isSubtraction - ? context.BitwiseNot(GetCF(context)) - : context.BitwiseAnd(GetCF(context), Const(1))); - } - - SetIaddFlags(context, res, srcA, srcB, op.SetCondCode, op.Extended, isSubtraction); - - context.Copy(GetDest(context), res); - } - - public static void Iadd3(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - IntegerHalfPart partC = (IntegerHalfPart)op.RawOpCode.Extract(31, 2); - IntegerHalfPart partB = (IntegerHalfPart)op.RawOpCode.Extract(33, 2); - IntegerHalfPart partA = (IntegerHalfPart)op.RawOpCode.Extract(35, 2); - - IntegerShift mode = (IntegerShift)op.RawOpCode.Extract(37, 2); - - bool negateC = op.RawOpCode.Extract(49); - bool negateB = op.RawOpCode.Extract(50); - bool negateA = op.RawOpCode.Extract(51); - - Operand Extend(Operand src, IntegerHalfPart part) - { - if (!(op is OpCodeAluReg) || part == IntegerHalfPart.B32) - { - return src; - } - - if (part == IntegerHalfPart.H0) - { - return context.BitwiseAnd(src, Const(0xffff)); - } - else if (part == IntegerHalfPart.H1) - { - return context.ShiftRightU32(src, Const(16)); - } - else - { - // TODO: Warning. - } - - return src; - } - - Operand srcA = context.INegate(Extend(GetSrcA(context), partA), negateA); - Operand srcB = context.INegate(Extend(GetSrcB(context), partB), negateB); - Operand srcC = context.INegate(Extend(GetSrcC(context), partC), negateC); - - Operand res = context.IAdd(srcA, srcB); - - if (op is OpCodeAluReg && mode != IntegerShift.NoShift) - { - if (mode == IntegerShift.ShiftLeft) - { - res = context.ShiftLeft(res, Const(16)); - } - else if (mode == IntegerShift.ShiftRight) - { - res = context.ShiftRightU32(res, Const(16)); - } - else - { - // TODO: Warning. - } - } - - res = context.IAdd(res, srcC); - - context.Copy(GetDest(context), res); - - // TODO: CC, X, corner cases - } - - public static void Imnmx(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isSignedInt = op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand resMin = isSignedInt - ? context.IMinimumS32(srcA, srcB) - : context.IMinimumU32(srcA, srcB); - - Operand resMax = isSignedInt - ? context.IMaximumS32(srcA, srcB) - : context.IMaximumU32(srcA, srcB); - - Operand pred = GetPredicate39(context); - - Operand dest = GetDest(context); - - context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax)); - - SetZnFlags(context, dest, op.SetCondCode); - - // TODO: X flags. - } - - public static void Iscadd(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool negateA = false, negateB = false; - - if (!(op is OpCodeAluImm32)) - { - negateB = op.RawOpCode.Extract(48); - negateA = op.RawOpCode.Extract(49); - } - - int shift = op is OpCodeAluImm32 - ? op.RawOpCode.Extract(53, 5) - : op.RawOpCode.Extract(39, 5); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - srcA = context.ShiftLeft(srcA, Const(shift)); - - srcA = context.INegate(srcA, negateA); - srcB = context.INegate(srcB, negateB); - - Operand res = context.IAdd(srcA, srcB); - - context.Copy(GetDest(context), res); - - // TODO: CC, X - } - - public static void Iset(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - bool boolFloat = op.RawOpCode.Extract(44); - bool isSigned = op.RawOpCode.Extract(48); - - IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned); - - Operand pred = GetPredicate39(context); - - res = GetPredLogicalOp(context, op.LogicalOp, res, pred); - - Operand dest = GetDest(context); - - if (boolFloat) - { - context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0))); - } - else - { - context.Copy(dest, res); - } - - // TODO: CC, X - } - - public static void Isetp(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - bool isSigned = op.RawOpCode.Extract(48); - - IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand p0Res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned); - - Operand p1Res = context.BitwiseNot(p0Res); - - Operand pred = GetPredicate39(context); - - p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred); - p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred); - - context.Copy(Register(op.Predicate3), p0Res); - context.Copy(Register(op.Predicate0), p1Res); - } - - public static void Lop(EmitterContext context) - { - IOpCodeLop op = (IOpCodeLop)context.CurrOp; - - Operand srcA = context.BitwiseNot(GetSrcA(context), op.InvertA); - Operand srcB = context.BitwiseNot(GetSrcB(context), op.InvertB); - - Operand res = srcB; - - switch (op.LogicalOp) - { - case LogicalOperation.And: res = context.BitwiseAnd (srcA, srcB); break; - case LogicalOperation.Or: res = context.BitwiseOr (srcA, srcB); break; - case LogicalOperation.ExclusiveOr: res = context.BitwiseExclusiveOr(srcA, srcB); break; - } - - EmitLopPredWrite(context, op, res); - - Operand dest = GetDest(context); - - context.Copy(dest, res); - - SetZnFlags(context, dest, op.SetCondCode, op.Extended); - } - - public static void Lop3(EmitterContext context) - { - IOpCodeLop op = (IOpCodeLop)context.CurrOp; - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - Operand srcC = GetSrcC(context); - - bool regVariant = op is OpCodeLopReg; - - int truthTable = regVariant - ? op.RawOpCode.Extract(28, 8) - : op.RawOpCode.Extract(48, 8); - - Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable); - - if (regVariant) - { - EmitLopPredWrite(context, op, res); - } - - Operand dest = GetDest(context); - - context.Copy(dest, res); - - SetZnFlags(context, dest, op.SetCondCode, op.Extended); - } - - public static void Psetp(EmitterContext context) - { - OpCodePsetp op = (OpCodePsetp)context.CurrOp; - - bool invertA = op.RawOpCode.Extract(15); - bool invertB = op.RawOpCode.Extract(32); - - Operand srcA = context.BitwiseNot(Register(op.Predicate12), invertA); - Operand srcB = context.BitwiseNot(Register(op.Predicate29), invertB); - - Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB); - - Operand p1Res = context.BitwiseNot(p0Res); - - Operand pred = GetPredicate39(context); - - p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred); - p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred); - - context.Copy(Register(op.Predicate3), p0Res); - context.Copy(Register(op.Predicate0), p1Res); - } - - public static void Rro(EmitterContext context) - { - // This is the range reduction operator, - // we translate it as a simple move, as it - // should be always followed by a matching - // MUFU instruction. - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcB = GetSrcB(context); - - srcB = context.FPAbsNeg(srcB, absoluteB, negateB); - - context.Copy(GetDest(context), srcB); - } - - public static void Shl(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isMasked = op.RawOpCode.Extract(39); - - Operand srcB = GetSrcB(context); - - if (isMasked) - { - srcB = context.BitwiseAnd(srcB, Const(0x1f)); - } - - Operand res = context.ShiftLeft(GetSrcA(context), srcB); - - if (!isMasked) - { - // Clamped shift value. - Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32)); - - res = context.ConditionalSelect(isLessThan32, res, Const(0)); - } - - // TODO: X, CC - - context.Copy(GetDest(context), res); - } - - public static void Shr(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool isMasked = op.RawOpCode.Extract(39); - bool isReverse = op.RawOpCode.Extract(40); - bool isSigned = op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - if (isReverse) - { - srcA = context.BitfieldReverse(srcA); - } - - if (isMasked) - { - srcB = context.BitwiseAnd(srcB, Const(0x1f)); - } - - Operand res = isSigned - ? context.ShiftRightS32(srcA, srcB) - : context.ShiftRightU32(srcA, srcB); - - if (!isMasked) - { - // Clamped shift value. - Operand resShiftBy32; - - if (isSigned) - { - resShiftBy32 = context.ShiftRightS32(srcA, Const(31)); - } - else - { - resShiftBy32 = Const(0); - } - - Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32)); - - res = context.ConditionalSelect(isLessThan32, res, resShiftBy32); - } - - // TODO: X, CC - - context.Copy(GetDest(context), res); - } - - public static void Xmad(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - bool signedA = context.CurrOp.RawOpCode.Extract(48); - bool signedB = context.CurrOp.RawOpCode.Extract(49); - bool highA = context.CurrOp.RawOpCode.Extract(53); - bool highB = false; - - XmadCMode mode; - - if (op is OpCodeAluReg) - { - highB = context.CurrOp.RawOpCode.Extract(35); - - mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 3); - } - else - { - mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 2); - - if (!(op is OpCodeAluImm)) - { - highB = context.CurrOp.RawOpCode.Extract(52); - } - } - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - Operand srcC = GetSrcC(context); - - // XMAD immediates are 16-bits unsigned integers. - if (srcB.Type == OperandType.Constant) - { - srcB = Const(srcB.Value & 0xffff); - } - - Operand Extend16To32(Operand src, bool high, bool signed) - { - if (signed && high) - { - return context.ShiftRightS32(src, Const(16)); - } - else if (signed) - { - return context.BitfieldExtractS32(src, Const(0), Const(16)); - } - else if (high) - { - return context.ShiftRightU32(src, Const(16)); - } - else - { - return context.BitwiseAnd(src, Const(0xffff)); - } - } - - srcA = Extend16To32(srcA, highA, signedA); - srcB = Extend16To32(srcB, highB, signedB); - - bool productShiftLeft = false; - bool merge = false; - - if (!(op is OpCodeAluRegCbuf)) - { - productShiftLeft = context.CurrOp.RawOpCode.Extract(36); - merge = context.CurrOp.RawOpCode.Extract(37); - } - - bool extended; - - if ((op is OpCodeAluReg) || (op is OpCodeAluImm)) - { - extended = context.CurrOp.RawOpCode.Extract(38); - } - else - { - extended = context.CurrOp.RawOpCode.Extract(54); - } - - Operand res = context.IMultiply(srcA, srcB); - - if (productShiftLeft) - { - res = context.ShiftLeft(res, Const(16)); - } - - switch (mode) - { - case XmadCMode.Cfull: break; - - case XmadCMode.Clo: srcC = Extend16To32(srcC, high: false, signed: false); break; - case XmadCMode.Chi: srcC = Extend16To32(srcC, high: true, signed: false); break; - - case XmadCMode.Cbcc: - { - srcC = context.IAdd(srcC, context.ShiftLeft(GetSrcB(context), Const(16))); - - break; - } - - case XmadCMode.Csfu: - { - Operand signAdjustA = context.ShiftLeft(context.ShiftRightU32(srcA, Const(31)), Const(16)); - Operand signAdjustB = context.ShiftLeft(context.ShiftRightU32(srcB, Const(31)), Const(16)); - - srcC = context.ISubtract(srcC, context.IAdd(signAdjustA, signAdjustB)); - - break; - } - - default: /* TODO: Warning */ break; - } - - Operand product = res; - - if (extended) - { - // Add with carry. - res = context.IAdd(res, context.BitwiseAnd(GetCF(context), Const(1))); - } - else - { - // Add (no carry in). - res = context.IAdd(res, srcC); - } - - SetIaddFlags(context, res, product, srcC, op.SetCondCode, extended); - - if (merge) - { - res = context.BitwiseAnd(res, Const(0xffff)); - res = context.BitwiseOr(res, context.ShiftLeft(GetSrcB(context), Const(16))); - } - - context.Copy(GetDest(context), res); - } - - private static Operand GetIntComparison( - EmitterContext context, - IntegerCondition cond, - Operand srcA, - Operand srcB, - bool isSigned) - { - Operand res; - - if (cond == IntegerCondition.Always) - { - res = Const(IrConsts.True); - } - else if (cond == IntegerCondition.Never) - { - res = Const(IrConsts.False); - } - else - { - Instruction inst; - - switch (cond) - { - case IntegerCondition.Less: inst = Instruction.CompareLessU32; break; - case IntegerCondition.Equal: inst = Instruction.CompareEqual; break; - case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqualU32; break; - case IntegerCondition.Greater: inst = Instruction.CompareGreaterU32; break; - case IntegerCondition.NotEqual: inst = Instruction.CompareNotEqual; break; - case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqualU32; break; - - default: throw new InvalidOperationException($"Unexpected condition \"{cond}\"."); - } - - if (isSigned) - { - switch (cond) - { - case IntegerCondition.Less: inst = Instruction.CompareLess; break; - case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqual; break; - case IntegerCondition.Greater: inst = Instruction.CompareGreater; break; - case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break; - } - } - - res = context.Add(inst, Local(), srcA, srcB); - } - - return res; - } - - private static void EmitLopPredWrite(EmitterContext context, IOpCodeLop op, Operand result) - { - if (op is OpCodeLop opLop && !opLop.Predicate48.IsPT) - { - Operand pRes; - - if (opLop.CondOp == ConditionalOperation.False) - { - pRes = Const(IrConsts.False); - } - else if (opLop.CondOp == ConditionalOperation.True) - { - pRes = Const(IrConsts.True); - } - else if (opLop.CondOp == ConditionalOperation.Zero) - { - pRes = context.ICompareEqual(result, Const(0)); - } - else /* if (opLop.CondOp == ConditionalOperation.NotZero) */ - { - pRes = context.ICompareNotEqual(result, Const(0)); - } - - context.Copy(Register(opLop.Predicate48), pRes); - } - } - - private static void SetIaddFlags( - EmitterContext context, - Operand res, - Operand srcA, - Operand srcB, - bool setCC, - bool extended, - bool isSubtraction = false) - { - if (!setCC) - { - return; - } - - if (!extended || isSubtraction) - { - // C = d < a - context.Copy(GetCF(context), context.ICompareLessUnsigned(res, srcA)); - } - else - { - // C = (d == a && CIn) || d < a - Operand tempC0 = context.ICompareEqual (res, srcA); - Operand tempC1 = context.ICompareLessUnsigned(res, srcA); - - tempC0 = context.BitwiseAnd(tempC0, GetCF(context)); - - context.Copy(GetCF(context), context.BitwiseOr(tempC0, tempC1)); - } - - // V = (d ^ a) & ~(a ^ b) < 0 - Operand tempV0 = context.BitwiseExclusiveOr(res, srcA); - Operand tempV1 = context.BitwiseExclusiveOr(srcA, srcB); - - tempV1 = context.BitwiseNot(tempV1); - - Operand tempV = context.BitwiseAnd(tempV0, tempV1); - - context.Copy(GetVF(context), context.ICompareLess(tempV, Const(0))); - - SetZnFlags(context, res, setCC: true, extended: extended); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs deleted file mode 100644 index 5c4f5398..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static class InstEmitAluHelper - { - public static int GetIntMin(IntegerType type) - { - switch (type) - { - case IntegerType.U8: return byte.MinValue; - case IntegerType.S8: return sbyte.MinValue; - case IntegerType.U16: return ushort.MinValue; - case IntegerType.S16: return short.MinValue; - case IntegerType.U32: return (int)uint.MinValue; - case IntegerType.S32: return int.MinValue; - } - - throw new ArgumentException($"The type \"{type}\" is not a supported int type."); - } - - public static int GetIntMax(IntegerType type) - { - switch (type) - { - case IntegerType.U8: return byte.MaxValue; - case IntegerType.S8: return sbyte.MaxValue; - case IntegerType.U16: return ushort.MaxValue; - case IntegerType.S16: return short.MaxValue; - case IntegerType.U32: return unchecked((int)uint.MaxValue); - case IntegerType.S32: return int.MaxValue; - } - - throw new ArgumentException($"The type \"{type}\" is not a supported int type."); - } - - public static Operand GetPredLogicalOp( - EmitterContext context, - LogicalOperation logicalOp, - Operand input, - Operand pred) - { - switch (logicalOp) - { - case LogicalOperation.And: return context.BitwiseAnd (input, pred); - case LogicalOperation.Or: return context.BitwiseOr (input, pred); - case LogicalOperation.ExclusiveOr: return context.BitwiseExclusiveOr(input, pred); - } - - return input; - } - - public static void SetZnFlags(EmitterContext context, Operand dest, bool setCC, bool extended = false) - { - if (!setCC) - { - return; - } - - if (extended) - { - // When the operation is extended, it means we are doing - // the operation on a long word with any number of bits, - // so we need to AND the zero flag from result with the - // previous result when extended is specified, to ensure - // we have ZF set only if all words are zero, and not just - // the last one. - Operand oldZF = GetZF(context); - - Operand res = context.BitwiseAnd(context.ICompareEqual(dest, Const(0)), oldZF); - - context.Copy(GetZF(context), res); - } - else - { - context.Copy(GetZF(context), context.ICompareEqual(dest, Const(0))); - } - - context.Copy(GetNF(context), context.ICompareLess(dest, Const(0))); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs deleted file mode 100644 index c4de1750..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs +++ /dev/null @@ -1,213 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void F2F(EmitterContext context) - { - OpCodeFArith op = (OpCodeFArith)context.CurrOp; - - FPType srcType = (FPType)op.RawOpCode.Extract(8, 2); - FPType dstType = (FPType)op.RawOpCode.Extract(10, 2); - - bool pass = op.RawOpCode.Extract(40); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - pass &= op.RoundingMode == RoundingMode.TowardsNegativeInfinity; - - Operand srcB = context.FPAbsNeg(GetSrcB(context, srcType), absoluteB, negateB); - - if (!pass) - { - switch (op.RoundingMode) - { - case RoundingMode.TowardsNegativeInfinity: - srcB = context.FPFloor(srcB); - break; - - case RoundingMode.TowardsPositiveInfinity: - srcB = context.FPCeiling(srcB); - break; - - case RoundingMode.TowardsZero: - srcB = context.FPTruncate(srcB); - break; - } - } - - srcB = context.FPSaturate(srcB, op.Saturate); - - WriteFP(context, dstType, srcB); - - // TODO: CC. - } - - public static void F2I(EmitterContext context) - { - OpCodeFArith op = (OpCodeFArith)context.CurrOp; - - IntegerType intType = (IntegerType)op.RawOpCode.Extract(8, 2); - - bool isSmallInt = intType <= IntegerType.U16; - - FPType floatType = (FPType)op.RawOpCode.Extract(10, 2); - - bool isSignedInt = op.RawOpCode.Extract(12); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - if (isSignedInt) - { - intType |= IntegerType.S8; - } - - Operand srcB = context.FPAbsNeg(GetSrcB(context, floatType), absoluteB, negateB); - - switch (op.RoundingMode) - { - case RoundingMode.TowardsNegativeInfinity: - srcB = context.FPFloor(srcB); - break; - - case RoundingMode.TowardsPositiveInfinity: - srcB = context.FPCeiling(srcB); - break; - - case RoundingMode.TowardsZero: - srcB = context.FPTruncate(srcB); - break; - } - - srcB = context.FPConvertToS32(srcB); - - // TODO: S/U64, conversion overflow handling. - if (intType != IntegerType.S32) - { - int min = GetIntMin(intType); - int max = GetIntMax(intType); - - srcB = isSignedInt - ? context.IClampS32(srcB, Const(min), Const(max)) - : context.IClampU32(srcB, Const(min), Const(max)); - } - - Operand dest = GetDest(context); - - context.Copy(dest, srcB); - - // TODO: CC. - } - - public static void I2F(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - FPType dstType = (FPType)op.RawOpCode.Extract(8, 2); - - IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2); - - bool isSmallInt = srcType <= IntegerType.U16; - - bool isSignedInt = op.RawOpCode.Extract(13); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcB = context.IAbsNeg(GetSrcB(context), absoluteB, negateB); - - if (isSmallInt) - { - int size = srcType == IntegerType.U16 ? 16 : 8; - - srcB = isSignedInt - ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size)) - : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size)); - } - - srcB = isSignedInt - ? context.IConvertS32ToFP(srcB) - : context.IConvertU32ToFP(srcB); - - WriteFP(context, dstType, srcB); - - // TODO: CC. - } - - public static void I2I(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - IntegerType dstType = (IntegerType)op.RawOpCode.Extract(8, 2); - IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2); - - if (srcType == IntegerType.U64 || dstType == IntegerType.U64) - { - // TODO: Warning. This instruction doesn't support 64-bits integers - } - - bool srcIsSmallInt = srcType <= IntegerType.U16; - - bool dstIsSignedInt = op.RawOpCode.Extract(12); - bool srcIsSignedInt = op.RawOpCode.Extract(13); - bool negateB = op.RawOpCode.Extract(45); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcB = GetSrcB(context); - - if (srcIsSmallInt) - { - int size = srcType == IntegerType.U16 ? 16 : 8; - - srcB = srcIsSignedInt - ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size)) - : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size)); - } - - srcB = context.IAbsNeg(srcB, absoluteB, negateB); - - if (op.Saturate) - { - if (dstIsSignedInt) - { - dstType |= IntegerType.S8; - } - - int min = GetIntMin(dstType); - int max = GetIntMax(dstType); - - srcB = dstIsSignedInt - ? context.IClampS32(srcB, Const(min), Const(max)) - : context.IClampU32(srcB, Const(min), Const(max)); - } - - context.Copy(GetDest(context), srcB); - - // TODO: CC. - } - - private static void WriteFP(EmitterContext context, FPType type, Operand srcB) - { - Operand dest = GetDest(context); - - if (type == FPType.FP32) - { - context.Copy(dest, srcB); - } - else if (type == FPType.FP16) - { - context.Copy(dest, context.PackHalf2x16(srcB, ConstF(0))); - } - else - { - // TODO. - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs deleted file mode 100644 index b22639de..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs +++ /dev/null @@ -1,370 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper; -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Fadd(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool absoluteA = op.AbsoluteA, absoluteB, negateA, negateB; - - if (op is OpCodeFArithImm32) - { - negateB = op.RawOpCode.Extract(53); - negateA = op.RawOpCode.Extract(56); - absoluteB = op.RawOpCode.Extract(57); - } - else - { - negateB = op.RawOpCode.Extract(45); - negateA = op.RawOpCode.Extract(48); - absoluteB = op.RawOpCode.Extract(49); - } - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand dest = GetDest(context); - - context.Copy(dest, context.FPSaturate(context.FPAdd(srcA, srcB), op.Saturate)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Ffma(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool negateB = op.RawOpCode.Extract(48); - bool negateC = op.RawOpCode.Extract(49); - - Operand srcA = GetSrcA(context); - - Operand srcB = context.FPNegate(GetSrcB(context), negateB); - Operand srcC = context.FPNegate(GetSrcC(context), negateC); - - Operand dest = GetDest(context); - - context.Copy(dest, context.FPSaturate(context.FPFusedMultiplyAdd(srcA, srcB, srcC), op.Saturate)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Fmnmx(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool absoluteA = op.AbsoluteA; - bool negateB = op.RawOpCode.Extract(45); - bool negateA = op.RawOpCode.Extract(48); - bool absoluteB = op.RawOpCode.Extract(49); - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand resMin = context.FPMinimum(srcA, srcB); - Operand resMax = context.FPMaximum(srcA, srcB); - - Operand pred = GetPredicate39(context); - - Operand dest = GetDest(context); - - context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Fmul(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool negateB = !(op is OpCodeFArithImm32) && op.RawOpCode.Extract(48); - - Operand srcA = GetSrcA(context); - - Operand srcB = context.FPNegate(GetSrcB(context), negateB); - - switch (op.Scale) - { - case FmulScale.None: break; - - case FmulScale.Divide2: srcA = context.FPDivide (srcA, ConstF(2)); break; - case FmulScale.Divide4: srcA = context.FPDivide (srcA, ConstF(4)); break; - case FmulScale.Divide8: srcA = context.FPDivide (srcA, ConstF(8)); break; - case FmulScale.Multiply2: srcA = context.FPMultiply(srcA, ConstF(2)); break; - case FmulScale.Multiply4: srcA = context.FPMultiply(srcA, ConstF(4)); break; - case FmulScale.Multiply8: srcA = context.FPMultiply(srcA, ConstF(8)); break; - - default: break; //TODO: Warning. - } - - Operand dest = GetDest(context); - - context.Copy(dest, context.FPSaturate(context.FPMultiply(srcA, srcB), op.Saturate)); - - SetFPZnFlags(context, dest, op.SetCondCode); - } - - public static void Fset(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4); - - bool negateA = op.RawOpCode.Extract(43); - bool absoluteB = op.RawOpCode.Extract(44); - bool boolFloat = op.RawOpCode.Extract(52); - bool negateB = op.RawOpCode.Extract(53); - bool absoluteA = op.RawOpCode.Extract(54); - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand res = GetFPComparison(context, cmpOp, srcA, srcB); - - Operand pred = GetPredicate39(context); - - res = GetPredLogicalOp(context, op.LogicalOp, res, pred); - - Operand dest = GetDest(context); - - if (boolFloat) - { - context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0))); - } - else - { - context.Copy(dest, res); - } - - // TODO: CC, X - } - - public static void Fsetp(EmitterContext context) - { - OpCodeSet op = (OpCodeSet)context.CurrOp; - - Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4); - - bool absoluteA = op.RawOpCode.Extract(7); - bool negateA = op.RawOpCode.Extract(43); - bool absoluteB = op.RawOpCode.Extract(44); - bool negateB = op.RawOpCode.Extract(6); - - Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA); - Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB); - - Operand p0Res = GetFPComparison(context, cmpOp, srcA, srcB); - - Operand p1Res = context.BitwiseNot(p0Res); - - Operand pred = GetPredicate39(context); - - p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred); - p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred); - - context.Copy(Register(op.Predicate3), p0Res); - context.Copy(Register(op.Predicate0), p1Res); - } - - public static void Hadd2(EmitterContext context) - { - Hadd2Hmul2Impl(context, isAdd: true); - } - - public static void Hfma2(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - Operand[] srcA = GetHfmaSrcA(context); - Operand[] srcB = GetHfmaSrcB(context); - Operand[] srcC = GetHfmaSrcC(context); - - Operand[] res = new Operand[2]; - - for (int index = 0; index < res.Length; index++) - { - res[index] = context.FPFusedMultiplyAdd(srcA[index], srcB[index], srcC[index]); - - res[index] = context.FPSaturate(res[index], op.Saturate); - } - - context.Copy(GetDest(context), GetHalfPacked(context, res)); - } - - public static void Hmul2(EmitterContext context) - { - Hadd2Hmul2Impl(context, isAdd: false); - } - - private static void Hadd2Hmul2Impl(EmitterContext context, bool isAdd) - { - OpCode op = context.CurrOp; - - bool saturate = op.RawOpCode.Extract(op is OpCodeAluImm32 ? 52 : 32); - - Operand[] srcA = GetHalfSrcA(context); - Operand[] srcB = GetHalfSrcB(context); - - Operand[] res = new Operand[2]; - - for (int index = 0; index < res.Length; index++) - { - if (isAdd) - { - res[index] = context.FPAdd(srcA[index], srcB[index]); - } - else - { - res[index] = context.FPMultiply(srcA[index], srcB[index]); - } - - res[index] = context.FPSaturate(res[index], saturate); - } - - context.Copy(GetDest(context), GetHalfPacked(context, res)); - } - - public static void Mufu(EmitterContext context) - { - IOpCodeFArith op = (IOpCodeFArith)context.CurrOp; - - bool negateB = op.RawOpCode.Extract(48); - - Operand res = context.FPAbsNeg(GetSrcA(context), op.AbsoluteA, negateB); - - MufuOperation subOp = (MufuOperation)context.CurrOp.RawOpCode.Extract(20, 4); - - switch (subOp) - { - case MufuOperation.Cosine: - res = context.FPCosine(res); - break; - - case MufuOperation.Sine: - res = context.FPSine(res); - break; - - case MufuOperation.ExponentB2: - res = context.FPExponentB2(res); - break; - - case MufuOperation.LogarithmB2: - res = context.FPLogarithmB2(res); - break; - - case MufuOperation.Reciprocal: - res = context.FPReciprocal(res); - break; - - case MufuOperation.ReciprocalSquareRoot: - res = context.FPReciprocalSquareRoot(res); - break; - - case MufuOperation.SquareRoot: - res = context.FPSquareRoot(res); - break; - - default: /* TODO */ break; - } - - context.Copy(GetDest(context), context.FPSaturate(res, op.Saturate)); - } - - private static Operand GetFPComparison( - EmitterContext context, - Condition cond, - Operand srcA, - Operand srcB) - { - Operand res; - - if (cond == Condition.Always) - { - res = Const(IrConsts.True); - } - else if (cond == Condition.Never) - { - res = Const(IrConsts.False); - } - else if (cond == Condition.Nan || cond == Condition.Number) - { - res = context.BitwiseOr(context.IsNan(srcA), context.IsNan(srcB)); - - if (cond == Condition.Number) - { - res = context.BitwiseNot(res); - } - } - else - { - Instruction inst; - - switch (cond & ~Condition.Nan) - { - case Condition.Less: inst = Instruction.CompareLess; break; - case Condition.Equal: inst = Instruction.CompareEqual; break; - case Condition.LessOrEqual: inst = Instruction.CompareLessOrEqual; break; - case Condition.Greater: inst = Instruction.CompareGreater; break; - case Condition.NotEqual: inst = Instruction.CompareNotEqual; break; - case Condition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break; - - default: throw new InvalidOperationException($"Unexpected condition \"{cond}\"."); - } - - res = context.Add(inst | Instruction.FP, Local(), srcA, srcB); - - if ((cond & Condition.Nan) != 0) - { - res = context.BitwiseOr(res, context.IsNan(srcA)); - res = context.BitwiseOr(res, context.IsNan(srcB)); - } - } - - return res; - } - - private static void SetFPZnFlags(EmitterContext context, Operand dest, bool setCC) - { - if (setCC) - { - context.Copy(GetZF(context), context.FPCompareEqual(dest, ConstF(0))); - context.Copy(GetNF(context), context.FPCompareLess (dest, ConstF(0))); - } - } - - private static Operand[] GetHfmaSrcA(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - return GetHalfSources(context, GetSrcA(context), op.SwizzleA); - } - - private static Operand[] GetHfmaSrcB(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - Operand[] operands = GetHalfSources(context, GetSrcB(context), op.SwizzleB); - - return FPAbsNeg(context, operands, false, op.NegateB); - } - - private static Operand[] GetHfmaSrcC(EmitterContext context) - { - IOpCodeHfma op = (IOpCodeHfma)context.CurrOp; - - Operand[] operands = GetHalfSources(context, GetSrcC(context), op.SwizzleC); - - return FPAbsNeg(context, operands, false, op.NegateC); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs deleted file mode 100644 index fb76e06a..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs +++ /dev/null @@ -1,107 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System.Collections.Generic; -using System.Linq; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Bra(EmitterContext context) - { - EmitBranch(context, context.CurrBlock.Branch.Address); - } - - public static void Exit(EmitterContext context) - { - OpCodeExit op = (OpCodeExit)context.CurrOp; - - // TODO: Figure out how this is supposed to work in the - // presence of other condition codes. - if (op.Condition == Condition.Always) - { - context.Return(); - } - } - - public static void Kil(EmitterContext context) - { - context.Discard(); - } - - public static void Ssy(EmitterContext context) - { - OpCodeSsy op = (OpCodeSsy)context.CurrOp; - - foreach (KeyValuePair<OpCodeSync, Operand> kv in op.Syncs) - { - OpCodeSync opSync = kv.Key; - - Operand local = kv.Value; - - int ssyIndex = opSync.Targets[op]; - - context.Copy(local, Const(ssyIndex)); - } - } - - public static void Sync(EmitterContext context) - { - OpCodeSync op = (OpCodeSync)context.CurrOp; - - if (op.Targets.Count == 1) - { - // If we have only one target, then the SSY is basically - // a branch, we can produce better codegen for this case. - OpCodeSsy opSsy = op.Targets.Keys.First(); - - EmitBranch(context, opSsy.GetAbsoluteAddress()); - } - else - { - foreach (KeyValuePair<OpCodeSsy, int> kv in op.Targets) - { - OpCodeSsy opSsy = kv.Key; - - Operand label = context.GetLabel(opSsy.GetAbsoluteAddress()); - - Operand local = opSsy.Syncs[op]; - - int ssyIndex = kv.Value; - - context.BranchIfTrue(label, context.ICompareEqual(local, Const(ssyIndex))); - } - } - } - - private static void EmitBranch(EmitterContext context, ulong address) - { - // If we're branching to the next instruction, then the branch - // is useless and we can ignore it. - if (address == context.CurrOp.Address + 8) - { - return; - } - - Operand label = context.GetLabel(address); - - Operand pred = Register(context.CurrOp.Predicate); - - if (context.CurrOp.Predicate.IsPT) - { - context.Branch(label); - } - else if (context.CurrOp.InvertPredicate) - { - context.BranchIfFalse(label, pred); - } - else - { - context.BranchIfTrue(label, pred); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs deleted file mode 100644 index c87e1789..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs +++ /dev/null @@ -1,267 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static class InstEmitHelper - { - public static Operand GetZF(EmitterContext context) - { - return Register(0, RegisterType.Flag); - } - - public static Operand GetNF(EmitterContext context) - { - return Register(1, RegisterType.Flag); - } - - public static Operand GetCF(EmitterContext context) - { - return Register(2, RegisterType.Flag); - } - - public static Operand GetVF(EmitterContext context) - { - return Register(3, RegisterType.Flag); - } - - public static Operand GetDest(EmitterContext context) - { - return Register(((IOpCodeRd)context.CurrOp).Rd); - } - - public static Operand GetSrcA(EmitterContext context) - { - return Register(((IOpCodeRa)context.CurrOp).Ra); - } - - public static Operand GetSrcB(EmitterContext context, FPType floatType) - { - if (floatType == FPType.FP32) - { - return GetSrcB(context); - } - else if (floatType == FPType.FP16) - { - int h = context.CurrOp.RawOpCode.Extract(41, 1); - - return GetHalfSources(context, GetSrcB(context), FPHalfSwizzle.FP16)[h]; - } - else if (floatType == FPType.FP64) - { - // TODO. - } - - throw new ArgumentException($"Invalid floating point type \"{floatType}\"."); - } - - public static Operand GetSrcB(EmitterContext context) - { - switch (context.CurrOp) - { - case IOpCodeCbuf op: - return Cbuf(op.Slot, op.Offset); - - case IOpCodeImm op: - return Const(op.Immediate); - - case IOpCodeImmF op: - return ConstF(op.Immediate); - - case IOpCodeReg op: - return Register(op.Rb); - - case IOpCodeRegCbuf op: - return Register(op.Rc); - } - - throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\"."); - } - - public static Operand GetSrcC(EmitterContext context) - { - switch (context.CurrOp) - { - case IOpCodeRegCbuf op: - return Cbuf(op.Slot, op.Offset); - - case IOpCodeRc op: - return Register(op.Rc); - } - - throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\"."); - } - - public static Operand[] GetHalfSrcA(EmitterContext context) - { - OpCode op = context.CurrOp; - - bool absoluteA = false, negateA = false; - - if (op is IOpCodeCbuf || op is IOpCodeImm) - { - negateA = op.RawOpCode.Extract(43); - absoluteA = op.RawOpCode.Extract(44); - } - else if (op is IOpCodeReg) - { - absoluteA = op.RawOpCode.Extract(44); - } - else if (op is OpCodeAluImm32 && op.Emitter == InstEmit.Hadd2) - { - negateA = op.RawOpCode.Extract(56); - } - - FPHalfSwizzle swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(47, 2); - - Operand[] operands = GetHalfSources(context, GetSrcA(context), swizzle); - - return FPAbsNeg(context, operands, absoluteA, negateA); - } - - public static Operand[] GetHalfSrcB(EmitterContext context) - { - OpCode op = context.CurrOp; - - FPHalfSwizzle swizzle = FPHalfSwizzle.FP16; - - bool absoluteB = false, negateB = false; - - if (op is IOpCodeReg) - { - swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2); - - absoluteB = op.RawOpCode.Extract(30); - negateB = op.RawOpCode.Extract(31); - } - else if (op is IOpCodeCbuf) - { - swizzle = FPHalfSwizzle.FP32; - - absoluteB = op.RawOpCode.Extract(54); - } - - Operand[] operands = GetHalfSources(context, GetSrcB(context), swizzle); - - return FPAbsNeg(context, operands, absoluteB, negateB); - } - - public static Operand[] FPAbsNeg(EmitterContext context, Operand[] operands, bool abs, bool neg) - { - for (int index = 0; index < operands.Length; index++) - { - operands[index] = context.FPAbsNeg(operands[index], abs, neg); - } - - return operands; - } - - public static Operand[] GetHalfSources(EmitterContext context, Operand src, FPHalfSwizzle swizzle) - { - switch (swizzle) - { - case FPHalfSwizzle.FP16: - return new Operand[] - { - context.UnpackHalf2x16Low (src), - context.UnpackHalf2x16High(src) - }; - - case FPHalfSwizzle.FP32: return new Operand[] { src, src }; - - case FPHalfSwizzle.DupH0: - return new Operand[] - { - context.UnpackHalf2x16Low(src), - context.UnpackHalf2x16Low(src) - }; - - case FPHalfSwizzle.DupH1: - return new Operand[] - { - context.UnpackHalf2x16High(src), - context.UnpackHalf2x16High(src) - }; - } - - throw new ArgumentException($"Invalid swizzle \"{swizzle}\"."); - } - - public static Operand GetHalfPacked(EmitterContext context, Operand[] results) - { - OpCode op = context.CurrOp; - - FPHalfSwizzle swizzle = FPHalfSwizzle.FP16; - - if (!(op is OpCodeAluImm32)) - { - swizzle = (FPHalfSwizzle)context.CurrOp.RawOpCode.Extract(49, 2); - } - - switch (swizzle) - { - case FPHalfSwizzle.FP16: return context.PackHalf2x16(results[0], results[1]); - - case FPHalfSwizzle.FP32: return results[0]; - - case FPHalfSwizzle.DupH0: - { - Operand h1 = GetHalfDest(context, isHigh: true); - - return context.PackHalf2x16(results[0], h1); - } - - case FPHalfSwizzle.DupH1: - { - Operand h0 = GetHalfDest(context, isHigh: false); - - return context.PackHalf2x16(h0, results[1]); - } - } - - throw new ArgumentException($"Invalid swizzle \"{swizzle}\"."); - } - - public static Operand GetHalfDest(EmitterContext context, bool isHigh) - { - if (isHigh) - { - return context.UnpackHalf2x16High(GetDest(context)); - } - else - { - return context.UnpackHalf2x16Low(GetDest(context)); - } - } - - public static Operand GetPredicate39(EmitterContext context) - { - IOpCodeAlu op = (IOpCodeAlu)context.CurrOp; - - Operand local = Register(op.Predicate39); - - if (op.InvertP) - { - local = context.BitwiseNot(local); - } - - return local; - } - - public static Operand SignExtendTo32(EmitterContext context, Operand src, int srcBits) - { - return context.BitfieldExtractS32(src, Const(0), Const(srcBits)); - } - - public static Operand ZeroExtendTo32(EmitterContext context, Operand src, int srcBits) - { - int mask = (int)(0xffffffffu >> (32 - srcBits)); - - return context.BitwiseAnd(src, Const(mask)); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs deleted file mode 100644 index a2a50fce..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs +++ /dev/null @@ -1,138 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Ald(EmitterContext context) - { - OpCodeAttribute op = (OpCodeAttribute)context.CurrOp; - - Operand[] elems = new Operand[op.Count]; - - for (int index = 0; index < op.Count; index++) - { - Operand src = Attribute(op.AttributeOffset + index * 4); - - context.Copy(elems[index] = Local(), src); - } - - for (int index = 0; index < op.Count; index++) - { - Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); - - if (rd.IsRZ) - { - break; - } - - context.Copy(Register(rd), elems[index]); - } - } - - public static void Ast(EmitterContext context) - { - OpCodeAttribute op = (OpCodeAttribute)context.CurrOp; - - for (int index = 0; index < op.Count; index++) - { - if (op.Rd.Index + index > RegisterConsts.RegisterZeroIndex) - { - break; - } - - Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); - - Operand dest = Attribute(op.AttributeOffset + index * 4); - - context.Copy(dest, Register(rd)); - } - } - - public static void Ipa(EmitterContext context) - { - OpCodeIpa op = (OpCodeIpa)context.CurrOp; - - Operand srcA = new Operand(OperandType.Attribute, op.AttributeOffset); - - Operand srcB = GetSrcB(context); - - context.Copy(GetDest(context), srcA); - } - - public static void Ldc(EmitterContext context) - { - OpCodeLdc op = (OpCodeLdc)context.CurrOp; - - if (op.Size > IntegerSize.B64) - { - // TODO: Warning. - } - - bool isSmallInt = op.Size < IntegerSize.B32; - - int count = op.Size == IntegerSize.B64 ? 2 : 1; - - Operand baseOffset = context.Copy(GetSrcA(context)); - - for (int index = 0; index < count; index++) - { - Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); - - if (rd.IsRZ) - { - break; - } - - Operand offset = context.IAdd(baseOffset, Const((op.Offset + index) * 4)); - - Operand value = context.LoadConstant(Const(op.Slot), offset); - - if (isSmallInt) - { - Operand shift = context.BitwiseAnd(baseOffset, Const(3)); - - value = context.ShiftRightU32(value, shift); - - switch (op.Size) - { - case IntegerSize.U8: value = ZeroExtendTo32(context, value, 8); break; - case IntegerSize.U16: value = ZeroExtendTo32(context, value, 16); break; - case IntegerSize.S8: value = SignExtendTo32(context, value, 8); break; - case IntegerSize.S16: value = SignExtendTo32(context, value, 16); break; - } - } - - context.Copy(Register(rd), value); - } - } - - public static void Out(EmitterContext context) - { - OpCode op = context.CurrOp; - - bool emit = op.RawOpCode.Extract(39); - bool cut = op.RawOpCode.Extract(40); - - if (!(emit || cut)) - { - // TODO: Warning. - } - - if (emit) - { - context.EmitVertex(); - } - - if (cut) - { - context.EndPrimitive(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs deleted file mode 100644 index b74dbfd7..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Mov(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - context.Copy(GetDest(context), GetSrcB(context)); - } - - public static void Sel(EmitterContext context) - { - OpCodeAlu op = (OpCodeAlu)context.CurrOp; - - Operand pred = GetPredicate39(context); - - Operand srcA = GetSrcA(context); - Operand srcB = GetSrcB(context); - - Operand res = context.ConditionalSelect(pred, srcA, srcB); - - context.Copy(GetDest(context), res); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs deleted file mode 100644 index a9b29f40..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs +++ /dev/null @@ -1,776 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static partial class InstEmit - { - public static void Tex(EmitterContext context) - { - Tex(context, TextureFlags.None); - } - - public static void Tex_B(EmitterContext context) - { - Tex(context, TextureFlags.Bindless); - } - - public static void Tld(EmitterContext context) - { - Tex(context, TextureFlags.IntCoords); - } - - public static void Tld_B(EmitterContext context) - { - Tex(context, TextureFlags.IntCoords | TextureFlags.Bindless); - } - - public static void Texs(EmitterContext context) - { - OpCodeTextureScalar op = (OpCodeTextureScalar)context.CurrOp; - - if (op.Rd0.IsRZ && op.Rd1.IsRZ) - { - return; - } - - List<Operand> sourcesList = new List<Operand>(); - - int raIndex = op.Ra.Index; - int rbIndex = op.Rb.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - Operand Rb() - { - if (rbIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(rbIndex++, RegisterType.Gpr)); - } - - void AddTextureOffset(int coordsCount, int stride, int size) - { - Operand packedOffs = Rb(); - - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * stride), Const(size))); - } - } - - TextureType type; - TextureFlags flags; - - if (op is OpCodeTexs texsOp) - { - type = GetTextureType (texsOp.Type); - flags = GetTextureFlags(texsOp.Type); - - if ((type & TextureType.Array) != 0) - { - Operand arrayIndex = Ra(); - - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - - sourcesList.Add(arrayIndex); - - if ((type & TextureType.Shadow) != 0) - { - sourcesList.Add(Rb()); - } - - if ((flags & TextureFlags.LodLevel) != 0) - { - sourcesList.Add(ConstF(0)); - } - } - else - { - switch (texsOp.Type) - { - case TextureScalarType.Texture1DLodZero: - sourcesList.Add(Ra()); - break; - - case TextureScalarType.Texture2D: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TextureScalarType.Texture2DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(ConstF(0)); - break; - - case TextureScalarType.Texture2DLodLevel: - case TextureScalarType.Texture2DDepthCompare: - case TextureScalarType.Texture3D: - case TextureScalarType.TextureCube: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TextureScalarType.Texture2DLodZeroDepthCompare: - case TextureScalarType.Texture3DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(ConstF(0)); - break; - - case TextureScalarType.Texture2DLodLevelDepthCompare: - case TextureScalarType.TextureCubeLodLevel: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(Rb()); - break; - } - } - } - else if (op is OpCodeTlds tldsOp) - { - type = GetTextureType (tldsOp.Type); - flags = GetTextureFlags(tldsOp.Type) | TextureFlags.IntCoords; - - switch (tldsOp.Type) - { - case TexelLoadScalarType.Texture1DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture1DLodLevel: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TexelLoadScalarType.Texture2DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture2DLodZeroOffset: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture2DLodZeroMultisample: - case TexelLoadScalarType.Texture2DLodLevel: - case TexelLoadScalarType.Texture2DLodLevelOffset: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - break; - - case TexelLoadScalarType.Texture3DLodZero: - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - sourcesList.Add(Const(0)); - break; - - case TexelLoadScalarType.Texture2DArrayLodZero: - sourcesList.Add(Rb()); - sourcesList.Add(Rb()); - sourcesList.Add(Ra()); - sourcesList.Add(Const(0)); - break; - } - - if ((flags & TextureFlags.Offset) != 0) - { - AddTextureOffset(type.GetCoordsCount(), 4, 4); - } - } - else if (op is OpCodeTld4s tld4sOp) - { - if (!(tld4sOp.HasDepthCompare || tld4sOp.HasOffset)) - { - sourcesList.Add(Ra()); - sourcesList.Add(Rb()); - } - else - { - sourcesList.Add(Ra()); - sourcesList.Add(Ra()); - } - - type = TextureType.Texture2D; - flags = TextureFlags.Gather; - - if (tld4sOp.HasDepthCompare) - { - sourcesList.Add(Rb()); - - type |= TextureType.Shadow; - } - - if (tld4sOp.HasOffset) - { - AddTextureOffset(type.GetCoordsCount(), 8, 6); - - flags |= TextureFlags.Offset; - } - - sourcesList.Add(Const(tld4sOp.GatherCompIndex)); - } - else - { - throw new InvalidOperationException($"Invalid opcode type \"{op.GetType().Name}\"."); - } - - Operand[] sources = sourcesList.ToArray(); - - Operand[] rd0 = new Operand[2] { ConstF(0), ConstF(0) }; - Operand[] rd1 = new Operand[2] { ConstF(0), ConstF(0) }; - - int destIncrement = 0; - - Operand GetDest() - { - int high = destIncrement >> 1; - int low = destIncrement & 1; - - destIncrement++; - - if (op.IsFp16) - { - return high != 0 - ? (rd1[low] = Local()) - : (rd0[low] = Local()); - } - else - { - int rdIndex = high != 0 ? op.Rd1.Index : op.Rd0.Index; - - if (rdIndex < RegisterConsts.RegisterZeroIndex) - { - rdIndex += low; - } - - return Register(rdIndex, RegisterType.Gpr); - } - } - - int handle = op.Immediate; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - Instruction.TextureSample, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - - if (op.IsFp16) - { - context.Copy(Register(op.Rd0), context.PackHalf2x16(rd0[0], rd0[1])); - context.Copy(Register(op.Rd1), context.PackHalf2x16(rd1[0], rd1[1])); - } - } - - public static void Tld4(EmitterContext context) - { - OpCodeTld4 op = (OpCodeTld4)context.CurrOp; - - if (op.Rd.IsRZ) - { - return; - } - - int raIndex = op.Ra.Index; - int rbIndex = op.Rb.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - Operand Rb() - { - if (rbIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(rbIndex++, RegisterType.Gpr)); - } - - Operand arrayIndex = op.IsArray ? Ra() : null; - - List<Operand> sourcesList = new List<Operand>(); - - TextureType type = GetTextureType(op.Dimensions); - - TextureFlags flags = TextureFlags.Gather; - - int coordsCount = type.GetCoordsCount(); - - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(Ra()); - } - - if (op.IsArray) - { - sourcesList.Add(arrayIndex); - - type |= TextureType.Array; - } - - Operand[] packedOffs = new Operand[2]; - - packedOffs[0] = op.Offset != TextureGatherOffset.None ? Rb() : null; - packedOffs[1] = op.Offset == TextureGatherOffset.Offsets ? Rb() : null; - - if (op.HasDepthCompare) - { - sourcesList.Add(Rb()); - - type |= TextureType.Shadow; - } - - if (op.Offset != TextureGatherOffset.None) - { - int offsetTexelsCount = op.Offset == TextureGatherOffset.Offsets ? 4 : 1; - - for (int index = 0; index < coordsCount * offsetTexelsCount; index++) - { - Operand packed = packedOffs[(index >> 2) & 1]; - - sourcesList.Add(context.BitfieldExtractS32(packed, Const((index & 3) * 8), Const(6))); - } - - flags |= op.Offset == TextureGatherOffset.Offsets - ? TextureFlags.Offsets - : TextureFlags.Offset; - } - - sourcesList.Add(Const(op.GatherCompIndex)); - - Operand[] sources = sourcesList.ToArray(); - - int rdIndex = op.Rd.Index; - - Operand GetDest() - { - if (rdIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return Register(rdIndex++, RegisterType.Gpr); - } - - int handle = op.Immediate; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - Instruction.TextureSample, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - } - - public static void Txq(EmitterContext context) - { - Txq(context, bindless: false); - } - - public static void Txq_B(EmitterContext context) - { - Txq(context, bindless: true); - } - - private static void Txq(EmitterContext context, bool bindless) - { - OpCodeTex op = (OpCodeTex)context.CurrOp; - - if (op.Rd.IsRZ) - { - return; - } - - TextureProperty property = (TextureProperty)op.RawOpCode.Extract(22, 6); - - // TODO: Validate and use property. - Instruction inst = Instruction.TextureSize; - - TextureType type = TextureType.Texture2D; - - TextureFlags flags = bindless ? TextureFlags.Bindless : TextureFlags.None; - - int raIndex = op.Ra.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - List<Operand> sourcesList = new List<Operand>(); - - if (bindless) - { - sourcesList.Add(Ra()); - } - - sourcesList.Add(Ra()); - - Operand[] sources = sourcesList.ToArray(); - - int rdIndex = op.Rd.Index; - - Operand GetDest() - { - if (rdIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return Register(rdIndex++, RegisterType.Gpr); - } - - int handle = !bindless ? op.Immediate : 0; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - inst, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - } - - private static void Tex(EmitterContext context, TextureFlags flags) - { - OpCodeTexture op = (OpCodeTexture)context.CurrOp; - - bool isBindless = (flags & TextureFlags.Bindless) != 0; - bool intCoords = (flags & TextureFlags.IntCoords) != 0; - - if (op.Rd.IsRZ) - { - return; - } - - int raIndex = op.Ra.Index; - int rbIndex = op.Rb.Index; - - Operand Ra() - { - if (raIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(raIndex++, RegisterType.Gpr)); - } - - Operand Rb() - { - if (rbIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return context.Copy(Register(rbIndex++, RegisterType.Gpr)); - } - - Operand arrayIndex = op.IsArray ? Ra() : null; - - List<Operand> sourcesList = new List<Operand>(); - - if (isBindless) - { - sourcesList.Add(Rb()); - } - - TextureType type = GetTextureType(op.Dimensions); - - int coordsCount = type.GetCoordsCount(); - - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(Ra()); - } - - if (op.IsArray) - { - sourcesList.Add(arrayIndex); - - type |= TextureType.Array; - } - - bool hasLod = op.LodMode > TextureLodMode.LodZero; - - Operand lodValue = hasLod ? Rb() : ConstF(0); - - Operand packedOffs = op.HasOffset ? Rb() : null; - - if (op.HasDepthCompare) - { - sourcesList.Add(Rb()); - - type |= TextureType.Shadow; - } - - if ((op.LodMode == TextureLodMode.LodZero || - op.LodMode == TextureLodMode.LodLevel || - op.LodMode == TextureLodMode.LodLevelA) && !op.IsMultisample) - { - sourcesList.Add(lodValue); - - flags |= TextureFlags.LodLevel; - } - - if (op.HasOffset) - { - for (int index = 0; index < coordsCount; index++) - { - sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * 4), Const(4))); - } - - flags |= TextureFlags.Offset; - } - - if (op.LodMode == TextureLodMode.LodBias || - op.LodMode == TextureLodMode.LodBiasA) - { - sourcesList.Add(lodValue); - - flags |= TextureFlags.LodBias; - } - - if (op.IsMultisample) - { - sourcesList.Add(Rb()); - - type |= TextureType.Multisample; - } - - Operand[] sources = sourcesList.ToArray(); - - int rdIndex = op.Rd.Index; - - Operand GetDest() - { - if (rdIndex > RegisterConsts.RegisterZeroIndex) - { - return Const(0); - } - - return Register(rdIndex++, RegisterType.Gpr); - } - - int handle = !isBindless ? op.Immediate : 0; - - for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) - { - if ((compMask & 1) != 0) - { - Operand dest = GetDest(); - - TextureOperation operation = new TextureOperation( - Instruction.TextureSample, - type, - flags, - handle, - compIndex, - dest, - sources); - - context.Add(operation); - } - } - } - - private static TextureType GetTextureType(TextureDimensions dimensions) - { - switch (dimensions) - { - case TextureDimensions.Texture1D: return TextureType.Texture1D; - case TextureDimensions.Texture2D: return TextureType.Texture2D; - case TextureDimensions.Texture3D: return TextureType.Texture3D; - case TextureDimensions.TextureCube: return TextureType.TextureCube; - } - - throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\"."); - } - - private static TextureType GetTextureType(TextureScalarType type) - { - switch (type) - { - case TextureScalarType.Texture1DLodZero: - return TextureType.Texture1D; - - case TextureScalarType.Texture2D: - case TextureScalarType.Texture2DLodZero: - case TextureScalarType.Texture2DLodLevel: - return TextureType.Texture2D; - - case TextureScalarType.Texture2DDepthCompare: - case TextureScalarType.Texture2DLodLevelDepthCompare: - case TextureScalarType.Texture2DLodZeroDepthCompare: - return TextureType.Texture2D | TextureType.Shadow; - - case TextureScalarType.Texture2DArray: - case TextureScalarType.Texture2DArrayLodZero: - return TextureType.Texture2D | TextureType.Array; - - case TextureScalarType.Texture2DArrayLodZeroDepthCompare: - return TextureType.Texture2D | TextureType.Array | TextureType.Shadow; - - case TextureScalarType.Texture3D: - case TextureScalarType.Texture3DLodZero: - return TextureType.Texture3D; - - case TextureScalarType.TextureCube: - case TextureScalarType.TextureCubeLodLevel: - return TextureType.TextureCube; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - - private static TextureType GetTextureType(TexelLoadScalarType type) - { - switch (type) - { - case TexelLoadScalarType.Texture1DLodZero: - case TexelLoadScalarType.Texture1DLodLevel: - return TextureType.Texture1D; - - case TexelLoadScalarType.Texture2DLodZero: - case TexelLoadScalarType.Texture2DLodZeroOffset: - case TexelLoadScalarType.Texture2DLodLevel: - case TexelLoadScalarType.Texture2DLodLevelOffset: - return TextureType.Texture2D; - - case TexelLoadScalarType.Texture2DLodZeroMultisample: - return TextureType.Texture2D | TextureType.Multisample; - - case TexelLoadScalarType.Texture3DLodZero: - return TextureType.Texture3D; - - case TexelLoadScalarType.Texture2DArrayLodZero: - return TextureType.Texture2D | TextureType.Array; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - - private static TextureFlags GetTextureFlags(TextureScalarType type) - { - switch (type) - { - case TextureScalarType.Texture1DLodZero: - case TextureScalarType.Texture2DLodZero: - case TextureScalarType.Texture2DLodLevel: - case TextureScalarType.Texture2DLodLevelDepthCompare: - case TextureScalarType.Texture2DLodZeroDepthCompare: - case TextureScalarType.Texture2DArrayLodZero: - case TextureScalarType.Texture2DArrayLodZeroDepthCompare: - case TextureScalarType.Texture3DLodZero: - case TextureScalarType.TextureCubeLodLevel: - return TextureFlags.LodLevel; - - case TextureScalarType.Texture2D: - case TextureScalarType.Texture2DDepthCompare: - case TextureScalarType.Texture2DArray: - case TextureScalarType.Texture3D: - case TextureScalarType.TextureCube: - return TextureFlags.None; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - - private static TextureFlags GetTextureFlags(TexelLoadScalarType type) - { - switch (type) - { - case TexelLoadScalarType.Texture1DLodZero: - case TexelLoadScalarType.Texture1DLodLevel: - case TexelLoadScalarType.Texture2DLodZero: - case TexelLoadScalarType.Texture2DLodLevel: - case TexelLoadScalarType.Texture2DLodZeroMultisample: - case TexelLoadScalarType.Texture3DLodZero: - case TexelLoadScalarType.Texture2DArrayLodZero: - return TextureFlags.LodLevel; - - case TexelLoadScalarType.Texture2DLodZeroOffset: - case TexelLoadScalarType.Texture2DLodLevelOffset: - return TextureFlags.LodLevel | TextureFlags.Offset; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs deleted file mode 100644 index 91c740b6..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Ryujinx.Graphics.Shader.Translation; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - delegate void InstEmitter(EmitterContext context); -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs b/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs deleted file mode 100644 index 67e24957..00000000 --- a/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Instructions -{ - static class Lop3Expression - { - public static Operand GetFromTruthTable( - EmitterContext context, - Operand srcA, - Operand srcB, - Operand srcC, - int imm) - { - Operand expr = null; - - // Handle some simple cases, or cases where - // the KMap would yield poor results (like XORs). - if (imm == 0x96 || imm == 0x69) - { - // XOR (0x96) and XNOR (0x69). - if (imm == 0x69) - { - srcA = context.BitwiseNot(srcA); - } - - expr = context.BitwiseExclusiveOr(srcA, srcB); - expr = context.BitwiseExclusiveOr(expr, srcC); - - return expr; - } - else if (imm == 0) - { - // Always false. - return Const(IrConsts.False); - } - else if (imm == 0xff) - { - // Always true. - return Const(IrConsts.True); - } - - int map; - - // Encode into gray code. - map = ((imm >> 0) & 1) << 0; - map |= ((imm >> 1) & 1) << 4; - map |= ((imm >> 2) & 1) << 1; - map |= ((imm >> 3) & 1) << 5; - map |= ((imm >> 4) & 1) << 3; - map |= ((imm >> 5) & 1) << 7; - map |= ((imm >> 6) & 1) << 2; - map |= ((imm >> 7) & 1) << 6; - - // Solve KMap, get sum of products. - int visited = 0; - - for (int index = 0; index < 8 && visited != 0xff; index++) - { - if ((map & (1 << index)) == 0) - { - continue; - } - - int mask = 0; - - for (int mSize = 4; mSize != 0; mSize >>= 1) - { - mask = RotateLeft4((1 << mSize) - 1, index & 3) << (index & 4); - - if ((map & mask) == mask) - { - break; - } - } - - // The mask should wrap, if we are on the high row, shift to low etc. - int mask2 = (index & 4) != 0 ? mask >> 4 : mask << 4; - - if ((map & mask2) == mask2) - { - mask |= mask2; - } - - if ((mask & visited) == mask) - { - continue; - } - - bool notA = (mask & 0x33) != 0; - bool notB = (mask & 0x99) != 0; - bool notC = (mask & 0x0f) != 0; - - bool aChanges = (mask & 0xcc) != 0 && notA; - bool bChanges = (mask & 0x66) != 0 && notB; - bool cChanges = (mask & 0xf0) != 0 && notC; - - Operand localExpr = null; - - void And(Operand source) - { - if (localExpr != null) - { - localExpr = context.BitwiseAnd(localExpr, source); - } - else - { - localExpr = source; - } - } - - if (!aChanges) - { - And(context.BitwiseNot(srcA, notA)); - } - - if (!bChanges) - { - And(context.BitwiseNot(srcB, notB)); - } - - if (!cChanges) - { - And(context.BitwiseNot(srcC, notC)); - } - - if (expr != null) - { - expr = context.BitwiseOr(expr, localExpr); - } - else - { - expr = localExpr; - } - - visited |= mask; - } - - return expr; - } - - private static int RotateLeft4(int value, int shift) - { - return ((value << shift) | (value >> (4 - shift))) & 0xf; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/BasicBlock.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/BasicBlock.cs deleted file mode 100644 index 94975337..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/BasicBlock.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class BasicBlock - { - public int Index { get; set; } - - public LinkedList<INode> Operations { get; } - - private BasicBlock _next; - private BasicBlock _branch; - - public BasicBlock Next - { - get => _next; - set => _next = AddSuccessor(_next, value); - } - - public BasicBlock Branch - { - get => _branch; - set => _branch = AddSuccessor(_branch, value); - } - - public bool HasBranch => _branch != null; - - public List<BasicBlock> Predecessors { get; } - - public HashSet<BasicBlock> DominanceFrontiers { get; } - - public BasicBlock ImmediateDominator { get; set; } - - public BasicBlock() - { - Operations = new LinkedList<INode>(); - - Predecessors = new List<BasicBlock>(); - - DominanceFrontiers = new HashSet<BasicBlock>(); - } - - public BasicBlock(int index) : this() - { - Index = index; - } - - private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock) - { - oldBlock?.Predecessors.Remove(this); - newBlock?.Predecessors.Add(this); - - return newBlock; - } - - public INode GetLastOp() - { - return Operations.Last?.Value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/INode.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/INode.cs deleted file mode 100644 index 48dda24b..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/INode.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - interface INode - { - Operand Dest { get; set; } - - int SourcesCount { get; } - - Operand GetSource(int index); - - void SetSource(int index, Operand operand); - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Instruction.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/Instruction.cs deleted file mode 100644 index ac0ebc2b..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Instruction.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - [Flags] - enum Instruction - { - Absolute = 1, - Add, - BitfieldExtractS32, - BitfieldExtractU32, - BitfieldInsert, - BitfieldReverse, - BitwiseAnd, - BitwiseExclusiveOr, - BitwiseNot, - BitwiseOr, - Branch, - BranchIfFalse, - BranchIfTrue, - Ceiling, - Clamp, - ClampU32, - CompareEqual, - CompareGreater, - CompareGreaterOrEqual, - CompareGreaterOrEqualU32, - CompareGreaterU32, - CompareLess, - CompareLessOrEqual, - CompareLessOrEqualU32, - CompareLessU32, - CompareNotEqual, - ConditionalSelect, - ConvertFPToS32, - ConvertS32ToFP, - ConvertU32ToFP, - Copy, - Cosine, - Discard, - Divide, - EmitVertex, - EndPrimitive, - ExponentB2, - Floor, - FusedMultiplyAdd, - IsNan, - LoadConstant, - LoadGlobal, - LoadLocal, - LogarithmB2, - LogicalAnd, - LogicalExclusiveOr, - LogicalNot, - LogicalOr, - LoopBreak, - LoopContinue, - MarkLabel, - Maximum, - MaximumU32, - Minimum, - MinimumU32, - Multiply, - Negate, - PackDouble2x32, - PackHalf2x16, - ReciprocalSquareRoot, - Return, - ShiftLeft, - ShiftRightS32, - ShiftRightU32, - Sine, - SquareRoot, - StoreGlobal, - StoreLocal, - Subtract, - TextureSample, - TextureSize, - Truncate, - UnpackDouble2x32, - UnpackHalf2x16, - - Count, - FP = 1 << 16, - Mask = 0xffff - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/IrConsts.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/IrConsts.cs deleted file mode 100644 index c264e47d..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/IrConsts.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - static class IrConsts - { - public const int False = 0; - public const int True = -1; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operand.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operand.cs deleted file mode 100644 index 1df88a3d..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operand.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class Operand - { - private const int CbufSlotBits = 5; - private const int CbufSlotLsb = 32 - CbufSlotBits; - private const int CbufSlotMask = (1 << CbufSlotBits) - 1; - - public OperandType Type { get; } - - public int Value { get; } - - public INode AsgOp { get; set; } - - public HashSet<INode> UseOps { get; } - - private Operand() - { - UseOps = new HashSet<INode>(); - } - - public Operand(OperandType type) : this() - { - Type = type; - } - - public Operand(OperandType type, int value) : this() - { - Type = type; - Value = value; - } - - public Operand(Register reg) : this() - { - Type = OperandType.Register; - Value = PackRegInfo(reg.Index, reg.Type); - } - - public Operand(int slot, int offset) : this() - { - Type = OperandType.ConstantBuffer; - Value = PackCbufInfo(slot, offset); - } - - private static int PackCbufInfo(int slot, int offset) - { - return (slot << CbufSlotLsb) | offset; - } - - private static int PackRegInfo(int index, RegisterType type) - { - return ((int)type << 24) | index; - } - - public int GetCbufSlot() - { - return (Value >> CbufSlotLsb) & CbufSlotMask; - } - - public int GetCbufOffset() - { - return Value & ~(CbufSlotMask << CbufSlotLsb); - } - - public Register GetRegister() - { - return new Register(Value & 0xffffff, (RegisterType)(Value >> 24)); - } - - public float AsFloat() - { - return BitConverter.Int32BitsToSingle(Value); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandHelper.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandHelper.cs deleted file mode 100644 index 6765f8a4..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandHelper.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - static class OperandHelper - { - public static Operand Attribute(int value) - { - return new Operand(OperandType.Attribute, value); - } - - public static Operand Cbuf(int slot, int offset) - { - return new Operand(slot, offset); - } - - public static Operand Const(int value) - { - return new Operand(OperandType.Constant, value); - } - - public static Operand ConstF(float value) - { - return new Operand(OperandType.Constant, BitConverter.SingleToInt32Bits(value)); - } - - public static Operand Label() - { - return new Operand(OperandType.Label); - } - - public static Operand Local() - { - return new Operand(OperandType.LocalVariable); - } - - public static Operand Register(int index, RegisterType type) - { - return Register(new Register(index, type)); - } - - public static Operand Register(Register reg) - { - if (reg.IsRZ) - { - return Const(0); - } - else if (reg.IsPT) - { - return Const(IrConsts.True); - } - - return new Operand(reg); - } - - public static Operand Undef() - { - return new Operand(OperandType.Undefined); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandType.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandType.cs deleted file mode 100644 index e0e2a667..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/OperandType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - enum OperandType - { - Attribute, - Constant, - ConstantBuffer, - GlobalMemory, - Label, - LocalMemory, - LocalVariable, - Register, - Undefined - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operation.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operation.cs deleted file mode 100644 index c60f393e..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/Operation.cs +++ /dev/null @@ -1,101 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class Operation : INode - { - public Instruction Inst { get; private set; } - - private Operand _dest; - - public Operand Dest - { - get => _dest; - set => _dest = AssignDest(value); - } - - private Operand[] _sources; - - public int SourcesCount => _sources.Length; - - public int ComponentIndex { get; } - - public Operation(Instruction inst, Operand dest, params Operand[] sources) - { - Inst = inst; - Dest = dest; - - // The array may be modified externally, so we store a copy. - _sources = (Operand[])sources.Clone(); - - for (int index = 0; index < _sources.Length; index++) - { - Operand source = _sources[index]; - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - } - } - - public Operation( - Instruction inst, - int compIndex, - Operand dest, - params Operand[] sources) : this(inst, dest, sources) - { - ComponentIndex = compIndex; - } - - private Operand AssignDest(Operand dest) - { - if (dest != null && dest.Type == OperandType.LocalVariable) - { - dest.AsgOp = this; - } - - return dest; - } - - public Operand GetSource(int index) - { - return _sources[index]; - } - - public void SetSource(int index, Operand source) - { - Operand oldSrc = _sources[index]; - - if (oldSrc != null && oldSrc.Type == OperandType.LocalVariable) - { - oldSrc.UseOps.Remove(this); - } - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - - _sources[index] = source; - } - - public void TurnIntoCopy(Operand source) - { - Inst = Instruction.Copy; - - foreach (Operand oldSrc in _sources) - { - if (oldSrc.Type == OperandType.LocalVariable) - { - oldSrc.UseOps.Remove(this); - } - } - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - - _sources = new Operand[] { source }; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/PhiNode.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/PhiNode.cs deleted file mode 100644 index 13ff41bd..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/PhiNode.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class PhiNode : INode - { - private Operand _dest; - - public Operand Dest - { - get => _dest; - set => _dest = AssignDest(value); - } - - private HashSet<BasicBlock> _blocks; - - private class PhiSource - { - public BasicBlock Block { get; } - public Operand Operand { get; set; } - - public PhiSource(BasicBlock block, Operand operand) - { - Block = block; - Operand = operand; - } - } - - private List<PhiSource> _sources; - - public int SourcesCount => _sources.Count; - - public PhiNode(Operand dest) - { - _blocks = new HashSet<BasicBlock>(); - - _sources = new List<PhiSource>(); - - dest.AsgOp = this; - - Dest = dest; - } - - private Operand AssignDest(Operand dest) - { - if (dest != null && dest.Type == OperandType.LocalVariable) - { - dest.AsgOp = this; - } - - return dest; - } - - public void AddSource(BasicBlock block, Operand operand) - { - if (_blocks.Add(block)) - { - if (operand.Type == OperandType.LocalVariable) - { - operand.UseOps.Add(this); - } - - _sources.Add(new PhiSource(block, operand)); - } - } - - public Operand GetSource(int index) - { - return _sources[index].Operand; - } - - public BasicBlock GetBlock(int index) - { - return _sources[index].Block; - } - - public void SetSource(int index, Operand source) - { - Operand oldSrc = _sources[index].Operand; - - if (oldSrc != null && oldSrc.Type == OperandType.LocalVariable) - { - oldSrc.UseOps.Remove(this); - } - - if (source.Type == OperandType.LocalVariable) - { - source.UseOps.Add(this); - } - - _sources[index].Operand = source; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureFlags.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureFlags.cs deleted file mode 100644 index 5f0a8427..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureFlags.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - [Flags] - enum TextureFlags - { - None = 0, - Bindless = 1 << 0, - Gather = 1 << 1, - IntCoords = 1 << 2, - LodBias = 1 << 3, - LodLevel = 1 << 4, - Offset = 1 << 5, - Offsets = 1 << 6 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureOperation.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureOperation.cs deleted file mode 100644 index f5f2cc5c..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureOperation.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - class TextureOperation : Operation - { - public TextureType Type { get; } - public TextureFlags Flags { get; } - - public int Handle { get; } - - public TextureOperation( - Instruction inst, - TextureType type, - TextureFlags flags, - int handle, - int compIndex, - Operand dest, - params Operand[] sources) : base(inst, compIndex, dest, sources) - { - Type = type; - Flags = flags; - Handle = handle; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureType.cs b/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureType.cs deleted file mode 100644 index bf207007..00000000 --- a/Ryujinx.Graphics/Shader/IntermediateRepresentation/TextureType.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - [Flags] - enum TextureType - { - Texture1D, - Texture2D, - Texture3D, - TextureCube, - - Mask = 0xff, - - Array = 1 << 8, - Multisample = 1 << 9, - Shadow = 1 << 10 - } - - static class TextureTypeExtensions - { - public static int GetCoordsCount(this TextureType type) - { - switch (type & TextureType.Mask) - { - case TextureType.Texture1D: return 1; - case TextureType.Texture2D: return 2; - case TextureType.Texture3D: return 3; - case TextureType.TextureCube: return 3; - } - - throw new ArgumentException($"Invalid texture type \"{type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderConfig.cs b/Ryujinx.Graphics/Shader/ShaderConfig.cs deleted file mode 100644 index c2a94814..00000000 --- a/Ryujinx.Graphics/Shader/ShaderConfig.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Graphics.Gal; -using System; - -namespace Ryujinx.Graphics.Shader -{ - public struct ShaderConfig - { - public GalShaderType Type { get; } - - public int MaxCBufferSize; - - public ShaderConfig(GalShaderType type, int maxCBufferSize) - { - if (maxCBufferSize <= 0) - { - throw new ArgumentOutOfRangeException(nameof(maxCBufferSize)); - } - - Type = type; - MaxCBufferSize = maxCBufferSize; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderHeader.cs b/Ryujinx.Graphics/Shader/ShaderHeader.cs deleted file mode 100644 index 379f3f35..00000000 --- a/Ryujinx.Graphics/Shader/ShaderHeader.cs +++ /dev/null @@ -1,166 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.Decoders; -using System; - -namespace Ryujinx.Graphics.Shader -{ - struct OutputMapTarget - { - public bool Red { get; } - public bool Green { get; } - public bool Blue { get; } - public bool Alpha { get; } - - public bool Enabled => Red || Green || Blue || Alpha; - - public OutputMapTarget(bool red, bool green, bool blue, bool alpha) - { - Red = red; - Green = green; - Blue = blue; - Alpha = alpha; - } - - public bool ComponentEnabled(int component) - { - switch (component) - { - case 0: return Red; - case 1: return Green; - case 2: return Blue; - case 3: return Alpha; - } - - throw new ArgumentOutOfRangeException(nameof(component)); - } - } - - class ShaderHeader - { - public int SphType { get; } - - public int Version { get; } - - public int ShaderType { get; } - - public bool MrtEnable { get; } - - public bool KillsPixels { get; } - - public bool DoesGlobalStore { get; } - - public int SassVersion { get; } - - public bool DoesLoadOrStore { get; } - - public bool DoesFp64 { get; } - - public int StreamOutMask{ get; } - - public int ShaderLocalMemoryLowSize { get; } - - public int PerPatchAttributeCount { get; } - - public int ShaderLocalMemoryHighSize { get; } - - public int ThreadsPerInputPrimitive { get; } - - public int ShaderLocalMemoryCrsSize { get; } - - public int OutputTopology { get; } - - public int MaxOutputVertexCount { get; } - - public int StoreReqStart { get; } - public int StoreReqEnd { get; } - - public OutputMapTarget[] OmapTargets { get; } - public bool OmapSampleMask { get; } - public bool OmapDepth { get; } - - public ShaderHeader(IGalMemory memory, ulong address) - { - int commonWord0 = memory.ReadInt32((long)address + 0); - int commonWord1 = memory.ReadInt32((long)address + 4); - int commonWord2 = memory.ReadInt32((long)address + 8); - int commonWord3 = memory.ReadInt32((long)address + 12); - int commonWord4 = memory.ReadInt32((long)address + 16); - - SphType = commonWord0.Extract(0, 5); - - Version = commonWord0.Extract(5, 5); - - ShaderType = commonWord0.Extract(10, 4); - - MrtEnable = commonWord0.Extract(14); - - KillsPixels = commonWord0.Extract(15); - - DoesGlobalStore = commonWord0.Extract(16); - - SassVersion = commonWord0.Extract(17, 4); - - DoesLoadOrStore = commonWord0.Extract(26); - - DoesFp64 = commonWord0.Extract(27); - - StreamOutMask = commonWord0.Extract(28, 4); - - ShaderLocalMemoryLowSize = commonWord1.Extract(0, 24); - - PerPatchAttributeCount = commonWord1.Extract(24, 8); - - ShaderLocalMemoryHighSize = commonWord2.Extract(0, 24); - - ThreadsPerInputPrimitive = commonWord2.Extract(24, 8); - - ShaderLocalMemoryCrsSize = commonWord3.Extract(0, 24); - - OutputTopology = commonWord3.Extract(24, 4); - - MaxOutputVertexCount = commonWord4.Extract(0, 12); - - StoreReqStart = commonWord4.Extract(12, 8); - StoreReqEnd = commonWord4.Extract(24, 8); - - int type2OmapTarget = memory.ReadInt32((long)address + 72); - int type2Omap = memory.ReadInt32((long)address + 76); - - OmapTargets = new OutputMapTarget[8]; - - for (int offset = 0; offset < OmapTargets.Length * 4; offset += 4) - { - OmapTargets[offset >> 2] = new OutputMapTarget( - type2OmapTarget.Extract(offset + 0), - type2OmapTarget.Extract(offset + 1), - type2OmapTarget.Extract(offset + 2), - type2OmapTarget.Extract(offset + 3)); - } - - OmapSampleMask = type2Omap.Extract(0); - OmapDepth = type2Omap.Extract(1); - } - - public int DepthRegister - { - get - { - int count = 0; - - for (int index = 0; index < OmapTargets.Length; index++) - { - for (int component = 0; component < 4; component++) - { - if (OmapTargets[index].ComponentEnabled(component)) - { - count++; - } - } - } - - // Depth register is always two registers after the last color output. - return count + 1; - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderProgram.cs b/Ryujinx.Graphics/Shader/ShaderProgram.cs deleted file mode 100644 index 9257fd26..00000000 --- a/Ryujinx.Graphics/Shader/ShaderProgram.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.Graphics.Shader -{ - public class ShaderProgram - { - public ShaderProgramInfo Info { get; } - - public string Code { get; } - - internal ShaderProgram(ShaderProgramInfo info, string code) - { - Info = info; - Code = code; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/ShaderProgramInfo.cs b/Ryujinx.Graphics/Shader/ShaderProgramInfo.cs deleted file mode 100644 index c529a353..00000000 --- a/Ryujinx.Graphics/Shader/ShaderProgramInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.ObjectModel; - -namespace Ryujinx.Graphics.Shader -{ - public class ShaderProgramInfo - { - public ReadOnlyCollection<CBufferDescriptor> CBuffers { get; } - public ReadOnlyCollection<TextureDescriptor> Textures { get; } - - internal ShaderProgramInfo(CBufferDescriptor[] cBuffers, TextureDescriptor[] textures) - { - CBuffers = Array.AsReadOnly(cBuffers); - Textures = Array.AsReadOnly(textures); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstAssignment.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstAssignment.cs deleted file mode 100644 index bb3fe7af..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstAssignment.cs +++ /dev/null @@ -1,35 +0,0 @@ -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstAssignment : AstNode - { - public IAstNode Destination { get; } - - private IAstNode _source; - - public IAstNode Source - { - get - { - return _source; - } - set - { - RemoveUse(_source, this); - - AddUse(value, this); - - _source = value; - } - } - - public AstAssignment(IAstNode destination, IAstNode source) - { - Destination = destination; - Source = source; - - AddDef(destination, this); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstBlock.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstBlock.cs deleted file mode 100644 index fdef87de..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstBlock.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstBlock : AstNode, IEnumerable<IAstNode> - { - public AstBlockType Type { get; private set; } - - private IAstNode _condition; - - public IAstNode Condition - { - get - { - return _condition; - } - set - { - RemoveUse(_condition, this); - - AddUse(value, this); - - _condition = value; - } - } - - private LinkedList<IAstNode> _nodes; - - public IAstNode First => _nodes.First?.Value; - - public int Count => _nodes.Count; - - public AstBlock(AstBlockType type, IAstNode condition = null) - { - Type = type; - Condition = condition; - - _nodes = new LinkedList<IAstNode>(); - } - - public void Add(IAstNode node) - { - Add(node, _nodes.AddLast(node)); - } - - public void AddFirst(IAstNode node) - { - Add(node, _nodes.AddFirst(node)); - } - - public void AddBefore(IAstNode next, IAstNode node) - { - Add(node, _nodes.AddBefore(next.LLNode, node)); - } - - public void AddAfter(IAstNode prev, IAstNode node) - { - Add(node, _nodes.AddAfter(prev.LLNode, node)); - } - - private void Add(IAstNode node, LinkedListNode<IAstNode> newNode) - { - if (node.Parent != null) - { - throw new ArgumentException("Node already belongs to a block."); - } - - node.Parent = this; - node.LLNode = newNode; - } - - public void Remove(IAstNode node) - { - _nodes.Remove(node.LLNode); - - node.Parent = null; - node.LLNode = null; - } - - public void AndCondition(IAstNode cond) - { - Condition = new AstOperation(Instruction.LogicalAnd, Condition, cond); - } - - public void OrCondition(IAstNode cond) - { - Condition = new AstOperation(Instruction.LogicalOr, Condition, cond); - } - public void TurnIntoIf(IAstNode cond) - { - Condition = cond; - - Type = AstBlockType.If; - } - - public void TurnIntoElseIf() - { - Type = AstBlockType.ElseIf; - } - - public IEnumerator<IAstNode> GetEnumerator() - { - return _nodes.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockType.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstBlockType.cs deleted file mode 100644 index c12efda9..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockType.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - enum AstBlockType - { - DoWhile, - If, - Else, - ElseIf, - Main, - While - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockVisitor.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstBlockVisitor.cs deleted file mode 100644 index 10d5dce0..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstBlockVisitor.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstBlockVisitor - { - public AstBlock Block { get; private set; } - - public class BlockVisitationEventArgs : EventArgs - { - public AstBlock Block { get; } - - public BlockVisitationEventArgs(AstBlock block) - { - Block = block; - } - } - - public event EventHandler<BlockVisitationEventArgs> BlockEntered; - public event EventHandler<BlockVisitationEventArgs> BlockLeft; - - public AstBlockVisitor(AstBlock mainBlock) - { - Block = mainBlock; - } - - public IEnumerable<IAstNode> Visit() - { - IAstNode node = Block.First; - - while (node != null) - { - // We reached a child block, visit the nodes inside. - while (node is AstBlock childBlock) - { - Block = childBlock; - - node = childBlock.First; - - BlockEntered?.Invoke(this, new BlockVisitationEventArgs(Block)); - } - - // Node may be null, if the block is empty. - if (node != null) - { - IAstNode next = Next(node); - - yield return node; - - node = next; - } - - // We reached the end of the list, go up on tree to the parent blocks. - while (node == null && Block.Type != AstBlockType.Main) - { - BlockLeft?.Invoke(this, new BlockVisitationEventArgs(Block)); - - node = Next(Block); - - Block = Block.Parent; - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstHelper.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstHelper.cs deleted file mode 100644 index 9d3148e1..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstHelper.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class AstHelper - { - public static void AddUse(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Uses.Add(parent); - } - } - - public static void AddDef(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Defs.Add(parent); - } - } - - public static void RemoveUse(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Uses.Remove(parent); - } - } - - public static void RemoveDef(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Defs.Remove(parent); - } - } - - public static AstAssignment Assign(IAstNode destination, IAstNode source) - { - return new AstAssignment(destination, source); - } - - public static AstOperand Const(int value) - { - return new AstOperand(OperandType.Constant, value); - } - - public static AstOperand Local(VariableType type) - { - AstOperand local = new AstOperand(OperandType.LocalVariable); - - local.VarType = type; - - return local; - } - - public static IAstNode InverseCond(IAstNode cond) - { - return new AstOperation(Instruction.LogicalNot, cond); - } - - public static IAstNode Next(IAstNode node) - { - return node.LLNode.Next?.Value; - } - - public static IAstNode Previous(IAstNode node) - { - return node.LLNode.Previous?.Value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstNode.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstNode.cs deleted file mode 100644 index c667aac9..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstNode.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstNode : IAstNode - { - public AstBlock Parent { get; set; } - - public LinkedListNode<IAstNode> LLNode { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstOperand.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstOperand.cs deleted file mode 100644 index 97ff3ca9..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstOperand.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstOperand : AstNode - { - public HashSet<IAstNode> Defs { get; } - public HashSet<IAstNode> Uses { get; } - - public OperandType Type { get; } - - public VariableType VarType { get; set; } - - public int Value { get; } - - public int CbufSlot { get; } - public int CbufOffset { get; } - - private AstOperand() - { - Defs = new HashSet<IAstNode>(); - Uses = new HashSet<IAstNode>(); - - VarType = VariableType.S32; - } - - public AstOperand(Operand operand) : this() - { - Type = operand.Type; - - if (Type == OperandType.ConstantBuffer) - { - CbufSlot = operand.GetCbufSlot(); - CbufOffset = operand.GetCbufOffset(); - } - else - { - Value = operand.Value; - } - } - - public AstOperand(OperandType type, int value = 0) : this() - { - Type = type; - Value = value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstOperation.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstOperation.cs deleted file mode 100644 index 1607ffec..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstOperation.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstOperation : AstNode - { - public Instruction Inst { get; } - - public int ComponentMask { get; } - - private IAstNode[] _sources; - - public int SourcesCount => _sources.Length; - - public AstOperation(Instruction inst, params IAstNode[] sources) - { - Inst = inst; - _sources = sources; - - foreach (IAstNode source in sources) - { - AddUse(source, this); - } - - ComponentMask = 1; - } - - public AstOperation(Instruction inst, int compMask, params IAstNode[] sources) : this(inst, sources) - { - ComponentMask = compMask; - } - - public IAstNode GetSource(int index) - { - return _sources[index]; - } - - public void SetSource(int index, IAstNode source) - { - RemoveUse(_sources[index], this); - - AddUse(source, this); - - _sources[index] = source; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstOptimizer.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstOptimizer.cs deleted file mode 100644 index 0f5392b7..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstOptimizer.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; -using System.Linq; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class AstOptimizer - { - public static void Optimize(StructuredProgramInfo info) - { - AstBlock mainBlock = info.MainBlock; - - AstBlockVisitor visitor = new AstBlockVisitor(mainBlock); - - foreach (IAstNode node in visitor.Visit()) - { - if (node is AstAssignment assignment && assignment.Destination is AstOperand propVar) - { - bool isWorthPropagating = propVar.Uses.Count == 1 || IsWorthPropagating(assignment.Source); - - if (propVar.Defs.Count == 1 && isWorthPropagating) - { - PropagateExpression(propVar, assignment.Source); - } - - if (propVar.Type == OperandType.LocalVariable && propVar.Uses.Count == 0) - { - visitor.Block.Remove(assignment); - - info.Locals.Remove(propVar); - } - } - } - - RemoveEmptyBlocks(mainBlock); - } - - private static bool IsWorthPropagating(IAstNode source) - { - if (!(source is AstOperation srcOp)) - { - return false; - } - - if (!InstructionInfo.IsUnary(srcOp.Inst)) - { - return false; - } - - return srcOp.GetSource(0) is AstOperand || srcOp.Inst == Instruction.Copy; - } - - private static void PropagateExpression(AstOperand propVar, IAstNode source) - { - IAstNode[] uses = propVar.Uses.ToArray(); - - foreach (IAstNode useNode in uses) - { - if (useNode is AstBlock useBlock) - { - useBlock.Condition = source; - } - else if (useNode is AstOperation useOperation) - { - for (int srcIndex = 0; srcIndex < useOperation.SourcesCount; srcIndex++) - { - if (useOperation.GetSource(srcIndex) == propVar) - { - useOperation.SetSource(srcIndex, source); - } - } - } - else if (useNode is AstAssignment useAssignment) - { - useAssignment.Source = source; - } - } - } - - private static void RemoveEmptyBlocks(AstBlock mainBlock) - { - Queue<AstBlock> pending = new Queue<AstBlock>(); - - pending.Enqueue(mainBlock); - - while (pending.TryDequeue(out AstBlock block)) - { - foreach (IAstNode node in block) - { - if (node is AstBlock childBlock) - { - pending.Enqueue(childBlock); - } - } - - AstBlock parent = block.Parent; - - if (parent == null) - { - continue; - } - - AstBlock nextBlock = Next(block) as AstBlock; - - bool hasElse = nextBlock != null && nextBlock.Type == AstBlockType.Else; - - bool isIf = block.Type == AstBlockType.If; - - if (block.Count == 0) - { - if (isIf) - { - if (hasElse) - { - nextBlock.TurnIntoIf(InverseCond(block.Condition)); - } - - parent.Remove(block); - } - else if (block.Type == AstBlockType.Else) - { - parent.Remove(block); - } - } - else if (isIf && parent.Type == AstBlockType.Else && parent.Count == (hasElse ? 2 : 1)) - { - AstBlock parentOfParent = parent.Parent; - - parent.Remove(block); - - parentOfParent.AddAfter(parent, block); - - if (hasElse) - { - parent.Remove(nextBlock); - - parentOfParent.AddAfter(block, nextBlock); - } - - parentOfParent.Remove(parent); - - block.TurnIntoElseIf(); - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/AstTextureOperation.cs b/Ryujinx.Graphics/Shader/StructuredIr/AstTextureOperation.cs deleted file mode 100644 index e40f7b70..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/AstTextureOperation.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstTextureOperation : AstOperation - { - public TextureType Type { get; } - public TextureFlags Flags { get; } - - public int Handle { get; } - - public AstTextureOperation( - Instruction inst, - TextureType type, - TextureFlags flags, - int handle, - int compMask, - params IAstNode[] sources) : base(inst, compMask, sources) - { - Type = type; - Flags = flags; - Handle = handle; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/GotoElimination.cs b/Ryujinx.Graphics/Shader/StructuredIr/GotoElimination.cs deleted file mode 100644 index 8bcf9d9c..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/GotoElimination.cs +++ /dev/null @@ -1,459 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class GotoElimination - { - // This is a modified version of the algorithm presented on the paper - // "Taming Control Flow: A Structured Approach to Eliminating Goto Statements". - public static void Eliminate(GotoStatement[] gotos) - { - for (int index = gotos.Length - 1; index >= 0; index--) - { - GotoStatement stmt = gotos[index]; - - AstBlock gBlock = ParentBlock(stmt.Goto); - AstBlock lBlock = ParentBlock(stmt.Label); - - int gLevel = Level(gBlock); - int lLevel = Level(lBlock); - - if (IndirectlyRelated(gBlock, lBlock, gLevel, lLevel)) - { - AstBlock drBlock = gBlock; - - int drLevel = gLevel; - - do - { - drBlock = drBlock.Parent; - - drLevel--; - } - while (!DirectlyRelated(drBlock, lBlock, drLevel, lLevel)); - - MoveOutward(stmt, gLevel, drLevel); - - gBlock = drBlock; - gLevel = drLevel; - - if (Previous(stmt.Goto) is AstBlock elseBlock && elseBlock.Type == AstBlockType.Else) - { - // It's possible that the label was enclosed inside an else block, - // in this case we need to update the block and level. - // We also need to set the IsLoop for the case when the label is - // now before the goto, due to the newly introduced else block. - lBlock = ParentBlock(stmt.Label); - - lLevel = Level(lBlock); - - if (!IndirectlyRelated(elseBlock, lBlock, gLevel + 1, lLevel)) - { - stmt.IsLoop = true; - } - } - } - - if (DirectlyRelated(gBlock, lBlock, gLevel, lLevel)) - { - if (gLevel > lLevel) - { - MoveOutward(stmt, gLevel, lLevel); - } - else - { - if (stmt.IsLoop) - { - Lift(stmt); - } - - MoveInward(stmt); - } - } - - gBlock = ParentBlock(stmt.Goto); - - if (stmt.IsLoop) - { - EncloseDoWhile(stmt, gBlock, stmt.Label); - } - else - { - Enclose(gBlock, AstBlockType.If, stmt.Condition, Next(stmt.Goto), stmt.Label); - } - - gBlock.Remove(stmt.Goto); - } - } - - private static bool IndirectlyRelated(AstBlock lBlock, AstBlock rBlock, int lLevel, int rlevel) - { - return !(lBlock == rBlock || DirectlyRelated(lBlock, rBlock, lLevel, rlevel)); - } - - private static bool DirectlyRelated(AstBlock lBlock, AstBlock rBlock, int lLevel, int rLevel) - { - // If the levels are equal, they can be either siblings or indirectly related. - if (lLevel == rLevel) - { - return false; - } - - IAstNode block; - IAstNode other; - - int blockLvl, otherLvl; - - if (lLevel > rLevel) - { - block = lBlock; - blockLvl = lLevel; - other = rBlock; - otherLvl = rLevel; - } - else /* if (rLevel > lLevel) */ - { - block = rBlock; - blockLvl = rLevel; - other = lBlock; - otherLvl = lLevel; - } - - while (blockLvl >= otherLvl) - { - if (block == other) - { - return true; - } - - block = block.Parent; - - blockLvl--; - } - - return false; - } - - private static void Lift(GotoStatement stmt) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label)); - - AstBlock loopFirstStmt = path[path.Length - 1]; - - if (loopFirstStmt.Type == AstBlockType.Else) - { - loopFirstStmt = Previous(loopFirstStmt) as AstBlock; - - if (loopFirstStmt == null || loopFirstStmt.Type != AstBlockType.If) - { - throw new InvalidOperationException("Found an else without a matching if."); - } - } - - AstBlock newBlock = EncloseDoWhile(stmt, block, loopFirstStmt); - - block.Remove(stmt.Goto); - - newBlock.AddFirst(stmt.Goto); - - stmt.IsLoop = false; - } - - private static void MoveOutward(GotoStatement stmt, int gLevel, int lLevel) - { - AstBlock origin = ParentBlock(stmt.Goto); - - AstBlock block = origin; - - // Check if a loop is enclosing the goto, and the block that is - // directly related to the label is above the loop block. - // In that case, we need to introduce a break to get out of the loop. - AstBlock loopBlock = origin; - - int loopLevel = gLevel; - - while (loopLevel > lLevel) - { - AstBlock child = loopBlock; - - loopBlock = loopBlock.Parent; - - loopLevel--; - - if (child.Type == AstBlockType.DoWhile) - { - EncloseSingleInst(stmt, Instruction.LoopBreak); - - block.Remove(stmt.Goto); - - loopBlock.AddAfter(child, stmt.Goto); - - block = loopBlock; - gLevel = loopLevel; - } - } - - // Insert ifs to skip the parts that shouldn't be executed due to the goto. - bool tryInsertElse = stmt.IsUnconditional && origin.Type == AstBlockType.If; - - while (gLevel > lLevel) - { - Enclose(block, AstBlockType.If, stmt.Condition, Next(stmt.Goto)); - - block.Remove(stmt.Goto); - - AstBlock child = block; - - // We can't move the goto in the middle of a if and a else block, in - // this case we need to move it after the else. - // IsLoop may need to be updated if the label is inside the else, as - // introducing a loop is the only way to ensure the else will be executed. - if (Next(child) is AstBlock elseBlock && elseBlock.Type == AstBlockType.Else) - { - child = elseBlock; - } - - block = block.Parent; - - block.AddAfter(child, stmt.Goto); - - gLevel--; - - if (tryInsertElse && child == origin) - { - AstBlock lBlock = ParentBlock(stmt.Label); - - IAstNode last = block == lBlock && !stmt.IsLoop ? stmt.Label : null; - - AstBlock newBlock = Enclose(block, AstBlockType.Else, null, Next(stmt.Goto), last); - - if (newBlock != null) - { - block.Remove(stmt.Goto); - - block.AddAfter(newBlock, stmt.Goto); - } - } - } - } - - private static void MoveInward(GotoStatement stmt) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label)); - - for (int index = path.Length - 1; index >= 0; index--) - { - AstBlock child = path[index]; - AstBlock last = child; - - if (child.Type == AstBlockType.If) - { - // Modify the if condition to allow it to be entered by the goto. - if (!ContainsCondComb(child.Condition, Instruction.LogicalOr, stmt.Condition)) - { - child.OrCondition(stmt.Condition); - } - } - else if (child.Type == AstBlockType.Else) - { - // Modify the matching if condition to force the else to be entered by the goto. - if (!(Previous(child) is AstBlock ifBlock) || ifBlock.Type != AstBlockType.If) - { - throw new InvalidOperationException("Found an else without a matching if."); - } - - IAstNode cond = InverseCond(stmt.Condition); - - if (!ContainsCondComb(ifBlock.Condition, Instruction.LogicalAnd, cond)) - { - ifBlock.AndCondition(cond); - } - - last = ifBlock; - } - - Enclose(block, AstBlockType.If, stmt.Condition, Next(stmt.Goto), last); - - block.Remove(stmt.Goto); - - child.AddFirst(stmt.Goto); - - block = child; - } - } - - private static bool ContainsCondComb(IAstNode node, Instruction inst, IAstNode newCond) - { - while (node is AstOperation operation && operation.SourcesCount == 2) - { - if (operation.Inst == inst && IsSameCond(operation.GetSource(1), newCond)) - { - return true; - } - - node = operation.GetSource(0); - } - - return false; - } - - private static AstBlock EncloseDoWhile(GotoStatement stmt, AstBlock block, IAstNode first) - { - if (block.Type == AstBlockType.DoWhile && first == block.First) - { - // We only need to insert the continue if we're not at the end of the loop, - // or if our condition is different from the loop condition. - if (Next(stmt.Goto) != null || block.Condition != stmt.Condition) - { - EncloseSingleInst(stmt, Instruction.LoopContinue); - } - - // Modify the do-while condition to allow it to continue. - if (!ContainsCondComb(block.Condition, Instruction.LogicalOr, stmt.Condition)) - { - block.OrCondition(stmt.Condition); - } - - return block; - } - - return Enclose(block, AstBlockType.DoWhile, stmt.Condition, first, stmt.Goto); - } - - private static void EncloseSingleInst(GotoStatement stmt, Instruction inst) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock newBlock = new AstBlock(AstBlockType.If, stmt.Condition); - - block.AddAfter(stmt.Goto, newBlock); - - newBlock.AddFirst(new AstOperation(inst)); - } - - private static AstBlock Enclose( - AstBlock block, - AstBlockType type, - IAstNode cond, - IAstNode first, - IAstNode last = null) - { - if (first == last) - { - return null; - } - - if (type == AstBlockType.If) - { - cond = InverseCond(cond); - } - - // Do a quick check, if we are enclosing a single block, - // and the block type/condition matches the one we're going - // to create, then we don't need a new block, we can just - // return the old one. - bool hasSingleNode = Next(first) == last; - - if (hasSingleNode && BlockMatches(first, type, cond)) - { - return first as AstBlock; - } - - AstBlock newBlock = new AstBlock(type, cond); - - block.AddBefore(first, newBlock); - - while (first != last) - { - IAstNode next = Next(first); - - block.Remove(first); - - newBlock.Add(first); - - first = next; - } - - return newBlock; - } - - private static bool BlockMatches(IAstNode node, AstBlockType type, IAstNode cond) - { - if (!(node is AstBlock block)) - { - return false; - } - - return block.Type == type && IsSameCond(block.Condition, cond); - } - - private static bool IsSameCond(IAstNode lCond, IAstNode rCond) - { - if (lCond is AstOperation lCondOp && lCondOp.Inst == Instruction.LogicalNot) - { - if (!(rCond is AstOperation rCondOp) || rCondOp.Inst != lCondOp.Inst) - { - return false; - } - - lCond = lCondOp.GetSource(0); - rCond = rCondOp.GetSource(0); - } - - return lCond == rCond; - } - - private static AstBlock ParentBlock(IAstNode node) - { - if (node is AstBlock block) - { - return block.Parent; - } - - while (!(node is AstBlock)) - { - node = node.Parent; - } - - return node as AstBlock; - } - - private static AstBlock[] BackwardsPath(AstBlock top, AstBlock bottom) - { - AstBlock block = bottom; - - List<AstBlock> path = new List<AstBlock>(); - - while (block != top) - { - path.Add(block); - - block = block.Parent; - } - - return path.ToArray(); - } - - private static int Level(IAstNode node) - { - int level = 0; - - while (node != null) - { - level++; - - node = node.Parent; - } - - return level; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/GotoStatement.cs b/Ryujinx.Graphics/Shader/StructuredIr/GotoStatement.cs deleted file mode 100644 index 25216e55..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/GotoStatement.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class GotoStatement - { - public AstOperation Goto { get; } - public AstAssignment Label { get; } - - public IAstNode Condition => Label.Destination; - - public bool IsLoop { get; set; } - - public bool IsUnconditional => Goto.Inst == Instruction.Branch; - - public GotoStatement(AstOperation branch, AstAssignment label, bool isLoop) - { - Goto = branch; - Label = label; - IsLoop = isLoop; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/IAstNode.cs b/Ryujinx.Graphics/Shader/StructuredIr/IAstNode.cs deleted file mode 100644 index 5ececbb5..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/IAstNode.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - interface IAstNode - { - AstBlock Parent { get; set; } - - LinkedListNode<IAstNode> LLNode { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/InstructionInfo.cs b/Ryujinx.Graphics/Shader/StructuredIr/InstructionInfo.cs deleted file mode 100644 index 46a61553..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/InstructionInfo.cs +++ /dev/null @@ -1,142 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class InstructionInfo - { - private struct InstInfo - { - public VariableType DestType { get; } - - public VariableType[] SrcTypes { get; } - - public InstInfo(VariableType destType, params VariableType[] srcTypes) - { - DestType = destType; - SrcTypes = srcTypes; - } - } - - private static InstInfo[] _infoTbl; - - static InstructionInfo() - { - _infoTbl = new InstInfo[(int)Instruction.Count]; - - Add(Instruction.Absolute, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Add, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.BitfieldExtractS32, VariableType.S32, VariableType.S32, VariableType.S32, VariableType.S32); - Add(Instruction.BitfieldExtractU32, VariableType.U32, VariableType.U32, VariableType.S32, VariableType.S32); - Add(Instruction.BitfieldInsert, VariableType.Int, VariableType.Int, VariableType.Int, VariableType.S32, VariableType.S32); - Add(Instruction.BitfieldReverse, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseAnd, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseExclusiveOr, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseNot, VariableType.Int, VariableType.Int); - Add(Instruction.BitwiseOr, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.BranchIfTrue, VariableType.None, VariableType.Bool); - Add(Instruction.BranchIfFalse, VariableType.None, VariableType.Bool); - Add(Instruction.Ceiling, VariableType.F32, VariableType.F32, VariableType.F32); - Add(Instruction.Clamp, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ClampU32, VariableType.U32, VariableType.U32, VariableType.U32, VariableType.U32); - Add(Instruction.CompareEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareGreater, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareGreaterOrEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareGreaterOrEqualU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareGreaterU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareLess, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareLessOrEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.CompareLessOrEqualU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareLessU32, VariableType.Bool, VariableType.U32, VariableType.U32); - Add(Instruction.CompareNotEqual, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ConditionalSelect, VariableType.Scalar, VariableType.Bool, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ConvertFPToS32, VariableType.S32, VariableType.F32); - Add(Instruction.ConvertS32ToFP, VariableType.F32, VariableType.S32); - Add(Instruction.ConvertU32ToFP, VariableType.F32, VariableType.U32); - Add(Instruction.Cosine, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Divide, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.ExponentB2, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Floor, VariableType.F32, VariableType.F32); - Add(Instruction.FusedMultiplyAdd, VariableType.F32, VariableType.F32, VariableType.F32, VariableType.F32); - Add(Instruction.IsNan, VariableType.Bool, VariableType.F32); - Add(Instruction.LoadConstant, VariableType.F32, VariableType.S32, VariableType.S32); - Add(Instruction.LogarithmB2, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.LogicalAnd, VariableType.Bool, VariableType.Bool, VariableType.Bool); - Add(Instruction.LogicalExclusiveOr, VariableType.Bool, VariableType.Bool, VariableType.Bool); - Add(Instruction.LogicalNot, VariableType.Bool, VariableType.Bool); - Add(Instruction.LogicalOr, VariableType.Bool, VariableType.Bool, VariableType.Bool); - Add(Instruction.ShiftLeft, VariableType.Int, VariableType.Int, VariableType.Int); - Add(Instruction.ShiftRightS32, VariableType.S32, VariableType.S32, VariableType.Int); - Add(Instruction.ShiftRightU32, VariableType.U32, VariableType.U32, VariableType.Int); - Add(Instruction.Maximum, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.MaximumU32, VariableType.U32, VariableType.U32, VariableType.U32); - Add(Instruction.Minimum, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.MinimumU32, VariableType.U32, VariableType.U32, VariableType.U32); - Add(Instruction.Multiply, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Negate, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.PackHalf2x16, VariableType.U32, VariableType.F32, VariableType.F32); - Add(Instruction.ReciprocalSquareRoot, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Sine, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.SquareRoot, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.Subtract, VariableType.Scalar, VariableType.Scalar, VariableType.Scalar); - Add(Instruction.TextureSample, VariableType.F32); - Add(Instruction.TextureSize, VariableType.S32, VariableType.S32, VariableType.S32); - Add(Instruction.Truncate, VariableType.F32, VariableType.F32); - Add(Instruction.UnpackHalf2x16, VariableType.F32, VariableType.U32); - } - - private static void Add(Instruction inst, VariableType destType, params VariableType[] srcTypes) - { - _infoTbl[(int)inst] = new InstInfo(destType, srcTypes); - } - - public static VariableType GetDestVarType(Instruction inst) - { - return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].DestType, inst); - } - - public static VariableType GetSrcVarType(Instruction inst, int index) - { - if (inst == Instruction.TextureSample) - { - return VariableType.F32; - } - - return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].SrcTypes[index], inst); - } - - private static VariableType GetFinalVarType(VariableType type, Instruction inst) - { - if (type == VariableType.Scalar) - { - return (inst & Instruction.FP) != 0 - ? VariableType.F32 - : VariableType.S32; - } - else if (type == VariableType.Int) - { - return VariableType.S32; - } - else if (type == VariableType.None) - { - throw new ArgumentException($"Invalid operand for instruction \"{inst}\"."); - } - - return type; - } - - public static bool IsUnary(Instruction inst) - { - if (inst == Instruction.Copy) - { - return true; - } - else if (inst == Instruction.TextureSample) - { - return false; - } - - return _infoTbl[(int)(inst & Instruction.Mask)].SrcTypes.Length == 1; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/OperandInfo.cs b/Ryujinx.Graphics/Shader/StructuredIr/OperandInfo.cs deleted file mode 100644 index a3a8d138..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/OperandInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class OperandInfo - { - public static VariableType GetVarType(AstOperand operand) - { - if (operand.Type == OperandType.LocalVariable) - { - return operand.VarType; - } - else - { - return GetVarType(operand.Type); - } - } - - public static VariableType GetVarType(OperandType type) - { - switch (type) - { - case OperandType.Attribute: return VariableType.F32; - case OperandType.Constant: return VariableType.S32; - case OperandType.ConstantBuffer: return VariableType.F32; - case OperandType.GlobalMemory: return VariableType.F32; - case OperandType.Undefined: return VariableType.S32; - } - - throw new ArgumentException($"Invalid operand type \"{type}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/PhiFunctions.cs b/Ryujinx.Graphics/Shader/StructuredIr/PhiFunctions.cs deleted file mode 100644 index 53391b62..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/PhiFunctions.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class PhiFunctions - { - public static void Remove(BasicBlock[] blocks) - { - 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; - - if (!(node.Value is PhiNode phi)) - { - node = nextNode; - - continue; - } - - for (int index = 0; index < phi.SourcesCount; index++) - { - Operand src = phi.GetSource(index); - - BasicBlock srcBlock = phi.GetBlock(index); - - Operation copyOp = new Operation(Instruction.Copy, phi.Dest, src); - - AddBeforeBranch(srcBlock, copyOp); - } - - block.Operations.Remove(node); - - node = nextNode; - } - } - } - - private static void AddBeforeBranch(BasicBlock block, INode node) - { - INode lastOp = block.GetLastOp(); - - if (lastOp is Operation operation && IsControlFlowInst(operation.Inst)) - { - block.Operations.AddBefore(block.Operations.Last, node); - } - else - { - block.Operations.AddLast(node); - } - } - - private static bool IsControlFlowInst(Instruction inst) - { - switch (inst) - { - case Instruction.Branch: - case Instruction.BranchIfFalse: - case Instruction.BranchIfTrue: - case Instruction.Discard: - case Instruction.Return: - return true; - } - - return false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgram.cs b/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgram.cs deleted file mode 100644 index 26faaf36..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgram.cs +++ /dev/null @@ -1,254 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class StructuredProgram - { - public static StructuredProgramInfo MakeStructuredProgram(BasicBlock[] blocks) - { - PhiFunctions.Remove(blocks); - - StructuredProgramContext context = new StructuredProgramContext(blocks.Length); - - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - context.EnterBlock(block); - - foreach (INode node in block.Operations) - { - Operation operation = (Operation)node; - - if (IsBranchInst(operation.Inst)) - { - context.LeaveBlock(block, operation); - } - else - { - AddOperation(context, operation); - } - } - } - - GotoElimination.Eliminate(context.GetGotos()); - - AstOptimizer.Optimize(context.Info); - - return context.Info; - } - - private static void AddOperation(StructuredProgramContext context, Operation operation) - { - Instruction inst = operation.Inst; - - IAstNode[] sources = new IAstNode[operation.SourcesCount]; - - for (int index = 0; index < sources.Length; index++) - { - sources[index] = context.GetOperandUse(operation.GetSource(index)); - } - - if (operation.Dest != null) - { - AstOperand dest = context.GetOperandDef(operation.Dest); - - if (inst == Instruction.LoadConstant) - { - Operand ldcSource = operation.GetSource(0); - - if (ldcSource.Type != OperandType.Constant) - { - throw new InvalidOperationException("Found LDC with non-constant constant buffer slot."); - } - - context.Info.CBuffers.Add(ldcSource.Value); - } - - AstAssignment assignment; - - // If all the sources are bool, it's better to use short-circuiting - // logical operations, rather than forcing a cast to int and doing - // a bitwise operation with the value, as it is likely to be used as - // a bool in the end. - if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, VariableType.Bool)) - { - inst = GetLogicalFromBitwiseInst(inst); - } - - bool isCondSel = inst == Instruction.ConditionalSelect; - bool isCopy = inst == Instruction.Copy; - - if (isCondSel || isCopy) - { - VariableType type = GetVarTypeFromUses(operation.Dest); - - if (isCondSel && type == VariableType.F32) - { - inst |= Instruction.FP; - } - - dest.VarType = type; - } - else - { - dest.VarType = InstructionInfo.GetDestVarType(inst); - } - - int componentMask = 1 << operation.ComponentIndex; - - IAstNode source; - - if (operation is TextureOperation texOp) - { - AstTextureOperation astTexOp = new AstTextureOperation( - inst, - texOp.Type, - texOp.Flags, - texOp.Handle, - componentMask, - sources); - - context.Info.Samplers.Add(astTexOp); - - source = astTexOp; - } - else if (!isCopy) - { - source = new AstOperation(inst, componentMask, sources); - } - else - { - source = sources[0]; - } - - assignment = new AstAssignment(dest, source); - - context.AddNode(assignment); - } - else - { - context.AddNode(new AstOperation(inst, sources)); - } - } - - private static VariableType GetVarTypeFromUses(Operand dest) - { - HashSet<Operand> visited = new HashSet<Operand>(); - - Queue<Operand> pending = new Queue<Operand>(); - - bool Enqueue(Operand operand) - { - if (visited.Add(operand)) - { - pending.Enqueue(operand); - - return true; - } - - return false; - } - - Enqueue(dest); - - while (pending.TryDequeue(out Operand operand)) - { - foreach (INode useNode in operand.UseOps) - { - if (!(useNode is Operation operation)) - { - continue; - } - - if (operation.Inst == Instruction.Copy) - { - if (operation.Dest.Type == OperandType.LocalVariable) - { - if (Enqueue(operation.Dest)) - { - break; - } - } - else - { - return OperandInfo.GetVarType(operation.Dest.Type); - } - } - else - { - for (int index = 0; index < operation.SourcesCount; index++) - { - if (operation.GetSource(index) == operand) - { - return InstructionInfo.GetSrcVarType(operation.Inst, index); - } - } - } - } - } - - return VariableType.S32; - } - - private static bool AreAllSourceTypesEqual(IAstNode[] sources, VariableType type) - { - foreach (IAstNode node in sources) - { - if (!(node is AstOperand operand)) - { - return false; - } - - if (operand.VarType != type) - { - return false; - } - } - - return true; - } - - private static bool IsBranchInst(Instruction inst) - { - switch (inst) - { - case Instruction.Branch: - case Instruction.BranchIfFalse: - case Instruction.BranchIfTrue: - return true; - } - - return false; - } - - private static bool IsBitwiseInst(Instruction inst) - { - switch (inst) - { - case Instruction.BitwiseAnd: - case Instruction.BitwiseExclusiveOr: - case Instruction.BitwiseNot: - case Instruction.BitwiseOr: - return true; - } - - return false; - } - - private static Instruction GetLogicalFromBitwiseInst(Instruction inst) - { - switch (inst) - { - case Instruction.BitwiseAnd: return Instruction.LogicalAnd; - case Instruction.BitwiseExclusiveOr: return Instruction.LogicalExclusiveOr; - case Instruction.BitwiseNot: return Instruction.LogicalNot; - case Instruction.BitwiseOr: return Instruction.LogicalOr; - } - - throw new ArgumentException($"Unexpected instruction \"{inst}\"."); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramContext.cs b/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramContext.cs deleted file mode 100644 index 5d6ff890..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramContext.cs +++ /dev/null @@ -1,292 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; -using System.Linq; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class StructuredProgramContext - { - private HashSet<BasicBlock> _loopTails; - - private Stack<(AstBlock Block, int EndIndex)> _blockStack; - - private Dictionary<Operand, AstOperand> _localsMap; - - private Dictionary<int, AstAssignment> _gotoTempAsgs; - - private List<GotoStatement> _gotos; - - private AstBlock _currBlock; - - private int _currEndIndex; - - public StructuredProgramInfo Info { get; } - - public StructuredProgramContext(int blocksCount) - { - _loopTails = new HashSet<BasicBlock>(); - - _blockStack = new Stack<(AstBlock, int)>(); - - _localsMap = new Dictionary<Operand, AstOperand>(); - - _gotoTempAsgs = new Dictionary<int, AstAssignment>(); - - _gotos = new List<GotoStatement>(); - - _currBlock = new AstBlock(AstBlockType.Main); - - _currEndIndex = blocksCount; - - Info = new StructuredProgramInfo(_currBlock); - } - - public void EnterBlock(BasicBlock block) - { - while (_currEndIndex == block.Index) - { - (_currBlock, _currEndIndex) = _blockStack.Pop(); - } - - if (_gotoTempAsgs.TryGetValue(block.Index, out AstAssignment gotoTempAsg)) - { - AddGotoTempReset(block, gotoTempAsg); - } - - LookForDoWhileStatements(block); - } - - public void LeaveBlock(BasicBlock block, Operation branchOp) - { - LookForIfStatements(block, branchOp); - } - - private void LookForDoWhileStatements(BasicBlock block) - { - // Check if we have any predecessor whose index is greater than the - // current block, this indicates a loop. - bool done = false; - - foreach (BasicBlock predecessor in block.Predecessors.OrderByDescending(x => x.Index)) - { - if (predecessor.Index < block.Index) - { - break; - } - - if (predecessor.Index < _currEndIndex && !done) - { - Operation branchOp = (Operation)predecessor.GetLastOp(); - - NewBlock(AstBlockType.DoWhile, branchOp, predecessor.Index + 1); - - _loopTails.Add(predecessor); - - done = true; - } - else - { - AddGotoTempReset(block, GetGotoTempAsg(block.Index)); - - break; - } - } - } - - private void LookForIfStatements(BasicBlock block, Operation branchOp) - { - if (block.Branch == null) - { - return; - } - - bool isLoop = block.Branch.Index <= block.Index; - - if (block.Branch.Index <= _currEndIndex && !isLoop) - { - NewBlock(AstBlockType.If, branchOp, block.Branch.Index); - } - else if (!_loopTails.Contains(block)) - { - AstAssignment gotoTempAsg = GetGotoTempAsg(block.Branch.Index); - - IAstNode cond = GetBranchCond(AstBlockType.DoWhile, branchOp); - - AddNode(Assign(gotoTempAsg.Destination, cond)); - - AstOperation branch = new AstOperation(branchOp.Inst); - - AddNode(branch); - - GotoStatement gotoStmt = new GotoStatement(branch, gotoTempAsg, isLoop); - - _gotos.Add(gotoStmt); - } - } - - private AstAssignment GetGotoTempAsg(int index) - { - if (_gotoTempAsgs.TryGetValue(index, out AstAssignment gotoTempAsg)) - { - return gotoTempAsg; - } - - AstOperand gotoTemp = NewTemp(VariableType.Bool); - - gotoTempAsg = Assign(gotoTemp, Const(IrConsts.False)); - - _gotoTempAsgs.Add(index, gotoTempAsg); - - return gotoTempAsg; - } - - private void AddGotoTempReset(BasicBlock block, AstAssignment gotoTempAsg) - { - AddNode(gotoTempAsg); - - // For block 0, we don't need to add the extra "reset" at the beginning, - // because it is already the first node to be executed on the shader, - // so it is reset to false by the "local" assignment anyway. - if (block.Index != 0) - { - Info.MainBlock.AddFirst(Assign(gotoTempAsg.Destination, Const(IrConsts.False))); - } - } - - private void NewBlock(AstBlockType type, Operation branchOp, int endIndex) - { - NewBlock(type, GetBranchCond(type, branchOp), endIndex); - } - - private void NewBlock(AstBlockType type, IAstNode cond, int endIndex) - { - AstBlock childBlock = new AstBlock(type, cond); - - AddNode(childBlock); - - _blockStack.Push((_currBlock, _currEndIndex)); - - _currBlock = childBlock; - _currEndIndex = endIndex; - } - - private IAstNode GetBranchCond(AstBlockType type, Operation branchOp) - { - IAstNode cond; - - if (branchOp.Inst == Instruction.Branch) - { - cond = Const(type == AstBlockType.If ? IrConsts.False : IrConsts.True); - } - else - { - cond = GetOperandUse(branchOp.GetSource(0)); - - Instruction invInst = type == AstBlockType.If - ? Instruction.BranchIfTrue - : Instruction.BranchIfFalse; - - if (branchOp.Inst == invInst) - { - cond = new AstOperation(Instruction.LogicalNot, cond); - } - } - - return cond; - } - - public void AddNode(IAstNode node) - { - _currBlock.Add(node); - } - - public GotoStatement[] GetGotos() - { - return _gotos.ToArray(); - } - - private AstOperand NewTemp(VariableType type) - { - AstOperand newTemp = Local(type); - - Info.Locals.Add(newTemp); - - return newTemp; - } - - public AstOperand GetOperandDef(Operand operand) - { - if (TryGetUserAttributeIndex(operand, out int attrIndex)) - { - Info.OAttributes.Add(attrIndex); - } - - return GetOperand(operand); - } - - public AstOperand GetOperandUse(Operand operand) - { - if (TryGetUserAttributeIndex(operand, out int attrIndex)) - { - Info.IAttributes.Add(attrIndex); - } - else if (operand.Type == OperandType.ConstantBuffer) - { - Info.CBuffers.Add(operand.GetCbufSlot()); - } - - return GetOperand(operand); - } - - private AstOperand GetOperand(Operand operand) - { - if (operand == null) - { - return null; - } - - if (operand.Type != OperandType.LocalVariable) - { - return new AstOperand(operand); - } - - if (!_localsMap.TryGetValue(operand, out AstOperand astOperand)) - { - astOperand = new AstOperand(operand); - - _localsMap.Add(operand, astOperand); - - Info.Locals.Add(astOperand); - } - - return astOperand; - } - - private static bool TryGetUserAttributeIndex(Operand operand, out int attrIndex) - { - if (operand.Type == OperandType.Attribute) - { - if (operand.Value >= AttributeConsts.UserAttributeBase && - operand.Value < AttributeConsts.UserAttributeEnd) - { - attrIndex = (operand.Value - AttributeConsts.UserAttributeBase) >> 4; - - return true; - } - else if (operand.Value >= AttributeConsts.FragmentOutputColorBase && - operand.Value < AttributeConsts.FragmentOutputColorEnd) - { - attrIndex = (operand.Value - AttributeConsts.FragmentOutputColorBase) >> 4; - - return true; - } - } - - attrIndex = 0; - - return false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramInfo.cs b/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramInfo.cs deleted file mode 100644 index d368ef00..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/StructuredProgramInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class StructuredProgramInfo - { - public AstBlock MainBlock { get; } - - public HashSet<AstOperand> Locals { get; } - - public HashSet<int> CBuffers { get; } - - public HashSet<int> IAttributes { get; } - public HashSet<int> OAttributes { get; } - - public HashSet<AstTextureOperation> Samplers { get; } - - public StructuredProgramInfo(AstBlock mainBlock) - { - MainBlock = mainBlock; - - Locals = new HashSet<AstOperand>(); - - CBuffers = new HashSet<int>(); - - IAttributes = new HashSet<int>(); - OAttributes = new HashSet<int>(); - - Samplers = new HashSet<AstTextureOperation>(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/StructuredIr/VariableType.cs b/Ryujinx.Graphics/Shader/StructuredIr/VariableType.cs deleted file mode 100644 index 4c7f3849..00000000 --- a/Ryujinx.Graphics/Shader/StructuredIr/VariableType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - enum VariableType - { - None, - Bool, - Scalar, - Int, - F32, - S32, - U32 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/TextureDescriptor.cs b/Ryujinx.Graphics/Shader/TextureDescriptor.cs deleted file mode 100644 index 96f0f5b1..00000000 --- a/Ryujinx.Graphics/Shader/TextureDescriptor.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Ryujinx.Graphics.Shader -{ - public struct TextureDescriptor - { - public string Name { get; } - - public int HandleIndex { get; } - - public bool IsBindless { get; } - - public int CbufSlot { get; } - public int CbufOffset { get; } - - public TextureDescriptor(string name, int hIndex) - { - Name = name; - HandleIndex = hIndex; - - IsBindless = false; - - CbufSlot = 0; - CbufOffset = 0; - } - - public TextureDescriptor(string name, int cbufSlot, int cbufOffset) - { - Name = name; - HandleIndex = 0; - - IsBindless = true; - - CbufSlot = cbufSlot; - CbufOffset = cbufOffset; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/AttributeConsts.cs b/Ryujinx.Graphics/Shader/Translation/AttributeConsts.cs deleted file mode 100644 index f21a6252..00000000 --- a/Ryujinx.Graphics/Shader/Translation/AttributeConsts.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Ryujinx.Graphics.Shader.IntermediateRepresentation -{ - static class AttributeConsts - { - public const int Layer = 0x064; - public const int PointSize = 0x06c; - public const int PositionX = 0x070; - public const int PositionY = 0x074; - public const int PositionZ = 0x078; - public const int PositionW = 0x07c; - public const int ClipDistance0 = 0x2c0; - public const int ClipDistance1 = 0x2c4; - public const int ClipDistance2 = 0x2c8; - public const int ClipDistance3 = 0x2cc; - public const int ClipDistance4 = 0x2d0; - public const int ClipDistance5 = 0x2d4; - public const int ClipDistance6 = 0x2d8; - public const int ClipDistance7 = 0x2dc; - public const int PointCoordX = 0x2e0; - public const int PointCoordY = 0x2e4; - public const int TessCoordX = 0x2f0; - public const int TessCoordY = 0x2f4; - public const int InstanceId = 0x2f8; - public const int VertexId = 0x2fc; - public const int FrontFacing = 0x3fc; - - public const int UserAttributesCount = 32; - public const int UserAttributeBase = 0x80; - public const int UserAttributeEnd = UserAttributeBase + UserAttributesCount * 16; - - - // Note: Those attributes are used internally by the translator - // only, they don't exist on Maxwell. - public const int FragmentOutputDepth = 0x1000000; - public const int FragmentOutputColorBase = 0x1000010; - public const int FragmentOutputColorEnd = FragmentOutputColorBase + 8 * 16; - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/ControlFlowGraph.cs b/Ryujinx.Graphics/Shader/Translation/ControlFlowGraph.cs deleted file mode 100644 index e2ca74a4..00000000 --- a/Ryujinx.Graphics/Shader/Translation/ControlFlowGraph.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class ControlFlowGraph - { - public static BasicBlock[] MakeCfg(Operation[] operations) - { - Dictionary<Operand, BasicBlock> labels = new Dictionary<Operand, BasicBlock>(); - - List<BasicBlock> blocks = new List<BasicBlock>(); - - BasicBlock currentBlock = null; - - void NextBlock(BasicBlock nextBlock) - { - if (currentBlock != null && !EndsWithUnconditionalInst(currentBlock.GetLastOp())) - { - currentBlock.Next = nextBlock; - } - - currentBlock = nextBlock; - } - - void NewNextBlock() - { - BasicBlock block = new BasicBlock(blocks.Count); - - blocks.Add(block); - - NextBlock(block); - } - - bool needsNewBlock = true; - - for (int index = 0; index < operations.Length; index++) - { - Operation operation = operations[index]; - - if (operation.Inst == Instruction.MarkLabel) - { - Operand label = operation.Dest; - - if (labels.TryGetValue(label, out BasicBlock nextBlock)) - { - nextBlock.Index = blocks.Count; - - blocks.Add(nextBlock); - - NextBlock(nextBlock); - } - else - { - NewNextBlock(); - - labels.Add(label, currentBlock); - } - } - else - { - if (needsNewBlock) - { - NewNextBlock(); - } - - currentBlock.Operations.AddLast(operation); - } - - needsNewBlock = operation.Inst == Instruction.Branch || - operation.Inst == Instruction.BranchIfTrue || - operation.Inst == Instruction.BranchIfFalse; - - if (needsNewBlock) - { - Operand label = operation.Dest; - - if (!labels.TryGetValue(label, out BasicBlock branchBlock)) - { - branchBlock = new BasicBlock(); - - labels.Add(label, branchBlock); - } - - currentBlock.Branch = branchBlock; - } - } - - return blocks.ToArray(); - } - - private static bool EndsWithUnconditionalInst(INode node) - { - if (node is Operation operation) - { - switch (operation.Inst) - { - case Instruction.Branch: - case Instruction.Discard: - case Instruction.Return: - return true; - } - } - - return false; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Dominance.cs b/Ryujinx.Graphics/Shader/Translation/Dominance.cs deleted file mode 100644 index 6a3ff35f..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Dominance.cs +++ /dev/null @@ -1,127 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class Dominance - { - // Those methods are an implementation of the algorithms on "A Simple, Fast Dominance Algorithm". - // https://www.cs.rice.edu/~keith/EMBED/dom.pdf - public static void FindDominators(BasicBlock entry, int blocksCount) - { - HashSet<BasicBlock> visited = new HashSet<BasicBlock>(); - - Stack<BasicBlock> blockStack = new Stack<BasicBlock>(); - - List<BasicBlock> postOrderBlocks = new List<BasicBlock>(blocksCount); - - int[] postOrderMap = new int[blocksCount]; - - visited.Add(entry); - - blockStack.Push(entry); - - while (blockStack.TryPop(out BasicBlock block)) - { - if (block.Next != null && visited.Add(block.Next)) - { - blockStack.Push(block); - blockStack.Push(block.Next); - } - else if (block.Branch != null && visited.Add(block.Branch)) - { - blockStack.Push(block); - blockStack.Push(block.Branch); - } - else - { - postOrderMap[block.Index] = postOrderBlocks.Count; - - postOrderBlocks.Add(block); - } - } - - BasicBlock Intersect(BasicBlock block1, BasicBlock block2) - { - while (block1 != block2) - { - while (postOrderMap[block1.Index] < postOrderMap[block2.Index]) - { - block1 = block1.ImmediateDominator; - } - - while (postOrderMap[block2.Index] < postOrderMap[block1.Index]) - { - block2 = block2.ImmediateDominator; - } - } - - return block1; - } - - entry.ImmediateDominator = entry; - - bool modified; - - do - { - modified = false; - - for (int blkIndex = postOrderBlocks.Count - 2; blkIndex >= 0; blkIndex--) - { - BasicBlock block = postOrderBlocks[blkIndex]; - - BasicBlock newIDom = null; - - foreach (BasicBlock predecessor in block.Predecessors) - { - if (predecessor.ImmediateDominator != null) - { - if (newIDom != null) - { - newIDom = Intersect(predecessor, newIDom); - } - else - { - newIDom = predecessor; - } - } - } - - if (block.ImmediateDominator != newIDom) - { - block.ImmediateDominator = newIDom; - - modified = true; - } - } - } - while (modified); - } - - public static void FindDominanceFrontiers(BasicBlock[] blocks) - { - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - if (block.Predecessors.Count < 2) - { - continue; - } - - for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++) - { - BasicBlock current = block.Predecessors[pBlkIndex]; - - while (current != block.ImmediateDominator) - { - current.DominanceFrontiers.Add(block); - - current = current.ImmediateDominator; - } - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/EmitterContext.cs b/Ryujinx.Graphics/Shader/Translation/EmitterContext.cs deleted file mode 100644 index 6c2bf6e4..00000000 --- a/Ryujinx.Graphics/Shader/Translation/EmitterContext.cs +++ /dev/null @@ -1,105 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - class EmitterContext - { - public Block CurrBlock { get; set; } - public OpCode CurrOp { get; set; } - - private GalShaderType _shaderType; - - private ShaderHeader _header; - - private List<Operation> _operations; - - private Dictionary<ulong, Operand> _labels; - - public EmitterContext(GalShaderType shaderType, ShaderHeader header) - { - _shaderType = shaderType; - _header = header; - - _operations = new List<Operation>(); - - _labels = new Dictionary<ulong, Operand>(); - } - - public Operand Add(Instruction inst, Operand dest = null, params Operand[] sources) - { - Operation operation = new Operation(inst, dest, sources); - - Add(operation); - - return dest; - } - - public void Add(Operation operation) - { - _operations.Add(operation); - } - - public void MarkLabel(Operand label) - { - Add(Instruction.MarkLabel, label); - } - - public Operand GetLabel(ulong address) - { - if (!_labels.TryGetValue(address, out Operand label)) - { - label = Label(); - - _labels.Add(address, label); - } - - return label; - } - - public void PrepareForReturn() - { - if (_shaderType == GalShaderType.Fragment) - { - if (_header.OmapDepth) - { - Operand dest = Attribute(AttributeConsts.FragmentOutputDepth); - - Operand src = Register(_header.DepthRegister, RegisterType.Gpr); - - this.Copy(dest, src); - } - - int regIndex = 0; - - for (int attachment = 0; attachment < 8; attachment++) - { - OutputMapTarget target = _header.OmapTargets[attachment]; - - for (int component = 0; component < 4; component++) - { - if (target.ComponentEnabled(component)) - { - Operand dest = Attribute(AttributeConsts.FragmentOutputColorBase + regIndex * 4); - - Operand src = Register(regIndex, RegisterType.Gpr); - - this.Copy(dest, src); - - regIndex++; - } - } - } - } - } - - public Operation[] GetOperations() - { - return _operations.ToArray(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/EmitterContextInsts.cs b/Ryujinx.Graphics/Shader/Translation/EmitterContextInsts.cs deleted file mode 100644 index 604aa67d..00000000 --- a/Ryujinx.Graphics/Shader/Translation/EmitterContextInsts.cs +++ /dev/null @@ -1,420 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class EmitterContextInsts - { - public static Operand BitfieldExtractS32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.BitfieldExtractS32, Local(), a, b, c); - } - - public static Operand BitfieldExtractU32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.BitfieldExtractU32, Local(), a, b, c); - } - - public static Operand BitfieldInsert(this EmitterContext context, Operand a, Operand b, Operand c, Operand d) - { - return context.Add(Instruction.BitfieldInsert, Local(), a, b, c, d); - } - - public static Operand BitfieldReverse(this EmitterContext context, Operand a) - { - return context.Add(Instruction.BitfieldReverse, Local(), a); - } - - public static Operand BitwiseAnd(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.BitwiseAnd, Local(), a, b); - } - - public static Operand BitwiseExclusiveOr(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.BitwiseExclusiveOr, Local(), a, b); - } - - public static Operand BitwiseNot(this EmitterContext context, Operand a, bool invert) - { - if (invert) - { - a = context.BitwiseNot(a); - } - - return a; - } - - public static Operand BitwiseNot(this EmitterContext context, Operand a) - { - return context.Add(Instruction.BitwiseNot, Local(), a); - } - - public static Operand BitwiseOr(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.BitwiseOr, Local(), a, b); - } - - public static Operand Branch(this EmitterContext context, Operand d) - { - return context.Add(Instruction.Branch, d); - } - - public static Operand BranchIfFalse(this EmitterContext context, Operand d, Operand a) - { - return context.Add(Instruction.BranchIfFalse, d, a); - } - - public static Operand BranchIfTrue(this EmitterContext context, Operand d, Operand a) - { - return context.Add(Instruction.BranchIfTrue, d, a); - } - - public static Operand ConditionalSelect(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.ConditionalSelect, Local(), a, b, c); - } - - public static Operand Copy(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Copy, Local(), a); - } - - public static void Copy(this EmitterContext context, Operand d, Operand a) - { - if (d.Type == OperandType.Constant) - { - return; - } - - context.Add(Instruction.Copy, d, a); - } - - public static Operand Discard(this EmitterContext context) - { - return context.Add(Instruction.Discard); - } - - public static Operand EmitVertex(this EmitterContext context) - { - return context.Add(Instruction.EmitVertex); - } - - public static Operand EndPrimitive(this EmitterContext context) - { - return context.Add(Instruction.EndPrimitive); - } - - public static Operand FPAbsNeg(this EmitterContext context, Operand a, bool abs, bool neg) - { - return context.FPNegate(context.FPAbsolute(a, abs), neg); - } - - public static Operand FPAbsolute(this EmitterContext context, Operand a, bool abs) - { - if (abs) - { - a = context.FPAbsolute(a); - } - - return a; - } - - public static Operand FPAbsolute(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Absolute, Local(), a); - } - - public static Operand FPAdd(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Add, Local(), a, b); - } - - public static Operand FPCeiling(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Ceiling, Local(), a); - } - - public static Operand FPCompareEqual(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.CompareEqual, Local(), a, b); - } - - public static Operand FPCompareLess(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.CompareLess, Local(), a, b); - } - - public static Operand FPConvertToS32(this EmitterContext context, Operand a) - { - return context.Add(Instruction.ConvertFPToS32, Local(), a); - } - - public static Operand FPCosine(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Cosine, Local(), a); - } - - public static Operand FPDivide(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Divide, Local(), a, b); - } - - public static Operand FPExponentB2(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.ExponentB2, Local(), a); - } - - public static Operand FPFloor(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Floor, Local(), a); - } - - public static Operand FPLogarithmB2(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.LogarithmB2, Local(), a); - } - - public static Operand FPMaximum(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Maximum, Local(), a, b); - } - - public static Operand FPMinimum(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Minimum, Local(), a, b); - } - - public static Operand FPMultiply(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.FP | Instruction.Multiply, Local(), a, b); - } - - public static Operand FPFusedMultiplyAdd(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.FusedMultiplyAdd, Local(), a, b, c); - } - - public static Operand FPNegate(this EmitterContext context, Operand a, bool neg) - { - if (neg) - { - a = context.FPNegate(a); - } - - return a; - } - - public static Operand FPNegate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Negate, Local(), a); - } - - public static Operand FPReciprocal(this EmitterContext context, Operand a) - { - return context.FPDivide(ConstF(1), a); - } - - public static Operand FPReciprocalSquareRoot(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.ReciprocalSquareRoot, Local(), a); - } - - public static Operand FPSaturate(this EmitterContext context, Operand a, bool sat) - { - if (sat) - { - a = context.FPSaturate(a); - } - - return a; - } - - public static Operand FPSaturate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Clamp, Local(), a, ConstF(0), ConstF(1)); - } - - public static Operand FPSine(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.Sine, Local(), a); - } - - public static Operand FPSquareRoot(this EmitterContext context, Operand a) - { - return context.Add(Instruction.FP | Instruction.SquareRoot, Local(), a); - } - - public static Operand FPTruncate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Truncate, Local(), a); - } - - public static Operand IAbsNeg(this EmitterContext context, Operand a, bool abs, bool neg) - { - return context.INegate(context.IAbsolute(a, abs), neg); - } - - public static Operand IAbsolute(this EmitterContext context, Operand a, bool abs) - { - if (abs) - { - a = context.IAbsolute(a); - } - - return a; - } - - public static Operand IAbsolute(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Absolute, Local(), a); - } - - public static Operand IAdd(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Add, Local(), a, b); - } - - public static Operand IClampS32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.Clamp, Local(), a, b, c); - } - - public static Operand IClampU32(this EmitterContext context, Operand a, Operand b, Operand c) - { - return context.Add(Instruction.ClampU32, Local(), a, b, c); - } - - public static Operand ICompareEqual(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareEqual, Local(), a, b); - } - - public static Operand ICompareLess(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareLess, Local(), a, b); - } - - public static Operand ICompareLessUnsigned(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareLessU32, Local(), a, b); - } - - public static Operand ICompareNotEqual(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.CompareNotEqual, Local(), a, b); - } - - public static Operand IConvertS32ToFP(this EmitterContext context, Operand a) - { - return context.Add(Instruction.ConvertS32ToFP, Local(), a); - } - - public static Operand IConvertU32ToFP(this EmitterContext context, Operand a) - { - return context.Add(Instruction.ConvertU32ToFP, Local(), a); - } - - public static Operand IMaximumS32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Maximum, Local(), a, b); - } - - public static Operand IMaximumU32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.MaximumU32, Local(), a, b); - } - - public static Operand IMinimumS32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Minimum, Local(), a, b); - } - - public static Operand IMinimumU32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.MinimumU32, Local(), a, b); - } - - public static Operand IMultiply(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Multiply, Local(), a, b); - } - - public static Operand INegate(this EmitterContext context, Operand a, bool neg) - { - if (neg) - { - a = context.INegate(a); - } - - return a; - } - - public static Operand INegate(this EmitterContext context, Operand a) - { - return context.Add(Instruction.Negate, Local(), a); - } - - public static Operand ISubtract(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.Subtract, Local(), a, b); - } - - public static Operand IsNan(this EmitterContext context, Operand a) - { - return context.Add(Instruction.IsNan, Local(), a); - } - - public static Operand LoadConstant(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.LoadConstant, Local(), a, b); - } - - public static Operand PackHalf2x16(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.PackHalf2x16, Local(), a, b); - } - - public static Operand Return(this EmitterContext context) - { - context.PrepareForReturn(); - - return context.Add(Instruction.Return); - } - - public static Operand ShiftLeft(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.ShiftLeft, Local(), a, b); - } - - public static Operand ShiftRightS32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.ShiftRightS32, Local(), a, b); - } - - public static Operand ShiftRightU32(this EmitterContext context, Operand a, Operand b) - { - return context.Add(Instruction.ShiftRightU32, Local(), a, b); - } - - public static Operand UnpackHalf2x16High(this EmitterContext context, Operand a) - { - return UnpackHalf2x16(context, a, 1); - } - - public static Operand UnpackHalf2x16Low(this EmitterContext context, Operand a) - { - return UnpackHalf2x16(context, a, 0); - } - - private static Operand UnpackHalf2x16(this EmitterContext context, Operand a, int index) - { - Operand dest = Local(); - - context.Add(new Operation(Instruction.UnpackHalf2x16, index, dest, a)); - - return dest; - } - } -}
\ No newline at end of file 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 diff --git a/Ryujinx.Graphics/Shader/Translation/Ssa.cs b/Ryujinx.Graphics/Shader/Translation/Ssa.cs deleted file mode 100644 index a4d763be..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Ssa.cs +++ /dev/null @@ -1,330 +0,0 @@ -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - static class Ssa - { - private const int GprsAndPredsCount = RegisterConsts.GprsCount + RegisterConsts.PredsCount; - - private class DefMap - { - private Dictionary<Register, Operand> _map; - - private long[] _phiMasks; - - public DefMap() - { - _map = new Dictionary<Register, Operand>(); - - _phiMasks = new long[(RegisterConsts.TotalCount + 63) / 64]; - } - - public bool TryAddOperand(Register reg, Operand operand) - { - return _map.TryAdd(reg, operand); - } - - public bool TryGetOperand(Register reg, out Operand operand) - { - return _map.TryGetValue(reg, out operand); - } - - public bool AddPhi(Register reg) - { - int key = GetKeyFromRegister(reg); - - int index = key / 64; - int bit = key & 63; - - long mask = 1L << bit; - - if ((_phiMasks[index] & mask) != 0) - { - return false; - } - - _phiMasks[index] |= mask; - - return true; - } - - public bool HasPhi(Register reg) - { - int key = GetKeyFromRegister(reg); - - int index = key / 64; - int bit = key & 63; - - return (_phiMasks[index] & (1L << bit)) != 0; - } - } - - private struct Definition - { - public BasicBlock Block { get; } - public Operand Local { get; } - - public Definition(BasicBlock block, Operand local) - { - Block = block; - Local = local; - } - } - - public static void Rename(BasicBlock[] blocks) - { - DefMap[] globalDefs = new DefMap[blocks.Length]; - - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - globalDefs[blkIndex] = new DefMap(); - } - - Queue<BasicBlock> dfPhiBlocks = new Queue<BasicBlock>(); - - // First pass, get all defs and locals uses. - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - Operand[] localDefs = new Operand[RegisterConsts.TotalCount]; - - Operand RenameLocal(Operand operand) - { - if (operand != null && operand.Type == OperandType.Register) - { - Operand local = localDefs[GetKeyFromRegister(operand.GetRegister())]; - - operand = local ?? operand; - } - - return operand; - } - - BasicBlock block = blocks[blkIndex]; - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - if (node.Value is Operation operation) - { - for (int index = 0; index < operation.SourcesCount; index++) - { - operation.SetSource(index, RenameLocal(operation.GetSource(index))); - } - - if (operation.Dest != null && operation.Dest.Type == OperandType.Register) - { - Operand local = Local(); - - localDefs[GetKeyFromRegister(operation.Dest.GetRegister())] = local; - - operation.Dest = local; - } - } - - node = node.Next; - } - - for (int index = 0; index < RegisterConsts.TotalCount; index++) - { - Operand local = localDefs[index]; - - if (local == null) - { - continue; - } - - Register reg = GetRegisterFromKey(index); - - globalDefs[block.Index].TryAddOperand(reg, local); - - dfPhiBlocks.Enqueue(block); - - while (dfPhiBlocks.TryDequeue(out BasicBlock dfPhiBlock)) - { - foreach (BasicBlock domFrontier in dfPhiBlock.DominanceFrontiers) - { - if (globalDefs[domFrontier.Index].AddPhi(reg)) - { - dfPhiBlocks.Enqueue(domFrontier); - } - } - } - } - } - - // Second pass, rename variables with definitions on different blocks. - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - Operand[] localDefs = new Operand[RegisterConsts.TotalCount]; - - BasicBlock block = blocks[blkIndex]; - - Operand RenameGlobal(Operand operand) - { - if (operand != null && operand.Type == OperandType.Register) - { - int key = GetKeyFromRegister(operand.GetRegister()); - - Operand local = localDefs[key]; - - if (local != null) - { - return local; - } - - operand = FindDefinitionForCurr(globalDefs, block, operand.GetRegister()); - - localDefs[key] = operand; - } - - return operand; - } - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - if (node.Value is Operation operation) - { - for (int index = 0; index < operation.SourcesCount; index++) - { - operation.SetSource(index, RenameGlobal(operation.GetSource(index))); - } - } - - node = node.Next; - } - } - } - - private static Operand FindDefinitionForCurr(DefMap[] globalDefs, BasicBlock current, Register reg) - { - if (globalDefs[current.Index].HasPhi(reg)) - { - return InsertPhi(globalDefs, current, reg); - } - - if (current != current.ImmediateDominator) - { - return FindDefinition(globalDefs, current.ImmediateDominator, reg).Local; - } - - return Undef(); - } - - private static Definition FindDefinition(DefMap[] globalDefs, BasicBlock current, Register reg) - { - foreach (BasicBlock block in SelfAndImmediateDominators(current)) - { - DefMap defMap = globalDefs[block.Index]; - - if (defMap.TryGetOperand(reg, out Operand lastDef)) - { - return new Definition(block, lastDef); - } - - if (defMap.HasPhi(reg)) - { - return new Definition(block, InsertPhi(globalDefs, block, reg)); - } - } - - return new Definition(current, Undef()); - } - - private static IEnumerable<BasicBlock> SelfAndImmediateDominators(BasicBlock block) - { - while (block != block.ImmediateDominator) - { - yield return block; - - block = block.ImmediateDominator; - } - - yield return block; - } - - private static Operand InsertPhi(DefMap[] globalDefs, BasicBlock block, Register reg) - { - // This block has a Phi that has not been materialized yet, but that - // would define a new version of the variable we're looking for. We need - // to materialize the Phi, add all the block/operand pairs into the Phi, and - // then use the definition from that Phi. - Operand local = Local(); - - PhiNode phi = new PhiNode(local); - - AddPhi(block, phi); - - globalDefs[block.Index].TryAddOperand(reg, local); - - foreach (BasicBlock predecessor in block.Predecessors) - { - Definition def = FindDefinition(globalDefs, predecessor, reg); - - phi.AddSource(def.Block, def.Local); - } - - return local; - } - - private static void AddPhi(BasicBlock block, PhiNode phi) - { - LinkedListNode<INode> node = block.Operations.First; - - if (node != null) - { - while (node.Next?.Value is PhiNode) - { - node = node.Next; - } - } - - if (node?.Value is PhiNode) - { - block.Operations.AddAfter(node, phi); - } - else - { - block.Operations.AddFirst(phi); - } - } - - private static int GetKeyFromRegister(Register reg) - { - if (reg.Type == RegisterType.Gpr) - { - return reg.Index; - } - else if (reg.Type == RegisterType.Predicate) - { - return RegisterConsts.GprsCount + reg.Index; - } - else /* if (reg.Type == RegisterType.Flag) */ - { - return GprsAndPredsCount + reg.Index; - } - } - - private static Register GetRegisterFromKey(int key) - { - if (key < RegisterConsts.GprsCount) - { - return new Register(key, RegisterType.Gpr); - } - else if (key < GprsAndPredsCount) - { - return new Register(key - RegisterConsts.GprsCount, RegisterType.Predicate); - } - else /* if (key < RegisterConsts.TotalCount) */ - { - return new Register(key - GprsAndPredsCount, RegisterType.Flag); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Translator.cs b/Ryujinx.Graphics/Shader/Translation/Translator.cs deleted file mode 100644 index fcebe913..00000000 --- a/Ryujinx.Graphics/Shader/Translation/Translator.cs +++ /dev/null @@ -1,219 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Shader.CodeGen.Glsl; -using Ryujinx.Graphics.Shader.Decoders; -using Ryujinx.Graphics.Shader.Instructions; -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.StructuredIr; -using Ryujinx.Graphics.Shader.Translation.Optimizations; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; - -namespace Ryujinx.Graphics.Shader.Translation -{ - public static class Translator - { - public static ShaderProgram Translate(IGalMemory memory, ulong address, ShaderConfig config) - { - return Translate(memory, address, 0, config); - } - - public static ShaderProgram Translate( - IGalMemory memory, - ulong address, - ulong addressB, - ShaderConfig config) - { - Operation[] shaderOps = DecodeShader(memory, address, config.Type); - - if (addressB != 0) - { - // Dual vertex shader. - Operation[] shaderOpsB = DecodeShader(memory, addressB, config.Type); - - shaderOps = Combine(shaderOps, shaderOpsB); - } - - BasicBlock[] irBlocks = ControlFlowGraph.MakeCfg(shaderOps); - - Dominance.FindDominators(irBlocks[0], irBlocks.Length); - - Dominance.FindDominanceFrontiers(irBlocks); - - Ssa.Rename(irBlocks); - - Optimizer.Optimize(irBlocks); - - StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(irBlocks); - - GlslProgram program = GlslGenerator.Generate(sInfo, config); - - ShaderProgramInfo spInfo = new ShaderProgramInfo( - program.CBufferDescriptors, - program.TextureDescriptors); - - return new ShaderProgram(spInfo, program.Code); - } - - private static Operation[] DecodeShader(IGalMemory memory, ulong address, GalShaderType shaderType) - { - ShaderHeader header = new ShaderHeader(memory, address); - - Block[] cfg = Decoder.Decode(memory, address); - - EmitterContext context = new EmitterContext(shaderType, header); - - for (int blkIndex = 0; blkIndex < cfg.Length; blkIndex++) - { - Block block = cfg[blkIndex]; - - context.CurrBlock = block; - - context.MarkLabel(context.GetLabel(block.Address)); - - for (int opIndex = 0; opIndex < block.OpCodes.Count; opIndex++) - { - OpCode op = block.OpCodes[opIndex]; - - if (op.NeverExecute) - { - continue; - } - - Operand predSkipLbl = null; - - bool skipPredicateCheck = op.Emitter == InstEmit.Bra; - - if (op is OpCodeSync opSync) - { - // If the instruction is a SYNC instruction with only one - // possible target address, then the instruction is basically - // just a simple branch, we can generate code similar to branch - // instructions, with the condition check on the branch itself. - skipPredicateCheck |= opSync.Targets.Count < 2; - } - - if (!(op.Predicate.IsPT || skipPredicateCheck)) - { - Operand label; - - if (opIndex == block.OpCodes.Count - 1 && block.Next != null) - { - label = context.GetLabel(block.Next.Address); - } - else - { - label = Label(); - - predSkipLbl = label; - } - - Operand pred = Register(op.Predicate); - - if (op.InvertPredicate) - { - context.BranchIfTrue(label, pred); - } - else - { - context.BranchIfFalse(label, pred); - } - } - - context.CurrOp = op; - - op.Emitter(context); - - if (predSkipLbl != null) - { - context.MarkLabel(predSkipLbl); - } - } - } - - return context.GetOperations(); - } - - private static Operation[] Combine(Operation[] a, Operation[] b) - { - // Here we combine two shaders. - // For shader A: - // - All user attribute stores on shader A are turned into copies to a - // temporary variable. It's assumed that shader B will consume them. - // - All return instructions are turned into branch instructions, the - // branch target being the start of the shader B code. - // For shader B: - // - All user attribute loads on shader B are turned into copies from a - // temporary variable, as long that attribute is written by shader A. - List<Operation> output = new List<Operation>(a.Length + b.Length); - - Operand[] temps = new Operand[AttributeConsts.UserAttributesCount * 4]; - - Operand lblB = Label(); - - for (int index = 0; index < a.Length; index++) - { - Operation operation = a[index]; - - if (IsUserAttribute(operation.Dest)) - { - int tIndex = (operation.Dest.Value - AttributeConsts.UserAttributeBase) / 4; - - Operand temp = temps[tIndex]; - - if (temp == null) - { - temp = Local(); - - temps[tIndex] = temp; - } - - operation.Dest = temp; - } - - if (operation.Inst == Instruction.Return) - { - output.Add(new Operation(Instruction.Branch, lblB)); - } - else - { - output.Add(operation); - } - } - - output.Add(new Operation(Instruction.MarkLabel, lblB)); - - for (int index = 0; index < b.Length; index++) - { - Operation operation = b[index]; - - for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++) - { - Operand src = operation.GetSource(srcIndex); - - if (IsUserAttribute(src)) - { - Operand temp = temps[(src.Value - AttributeConsts.UserAttributeBase) / 4]; - - if (temp != null) - { - operation.SetSource(srcIndex, temp); - } - } - } - - output.Add(operation); - } - - return output.ToArray(); - } - - private static bool IsUserAttribute(Operand operand) - { - return operand != null && - operand.Type == OperandType.Attribute && - operand.Value >= AttributeConsts.UserAttributeBase && - operand.Value < AttributeConsts.UserAttributeEnd; - } - } -}
\ No newline at end of file |
