diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs index 1f1b9bf7cf..ce5d7b949e 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs @@ -1,4 +1,3 @@ -using Ryujinx.Graphics.Shader.StructuredIr; using System.Collections.Generic; using System.Text; @@ -13,9 +12,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl public List CBufferDescriptors { get; } public List TextureDescriptors { get; } - private StringBuilder _sb; + public OperandManager OperandManager { get; } - private Dictionary _locals; + private StringBuilder _sb; private int _level; @@ -28,9 +27,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl CBufferDescriptors = new List(); TextureDescriptors = new List(); - _sb = new StringBuilder(); + OperandManager = new OperandManager(); - _locals = new Dictionary(); + _sb = new StringBuilder(); } public void AppendLine() @@ -87,19 +86,5 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl return identation; } - - public string DeclareLocal(AstOperand operand) - { - string name = $"temp_{_locals.Count}"; - - _locals.Add(operand, name); - - return name; - } - - public string GetLocalName(AstOperand operand) - { - return _locals[operand]; - } } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs index 8e7280e6bb..5412d87281 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs @@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { foreach (AstOperand decl in info.Locals) { - string name = context.DeclareLocal(decl); + string name = context.OperandManager.DeclareLocal(decl); context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";"); } diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs index 6e5d129fc0..1d3939fb79 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/DefaultNames.cs @@ -2,6 +2,8 @@ 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"; diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs index eb1e748e31..4edbda8b9e 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs @@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl if (assignment.Destination is AstOperand operand && operand.Type == OperandType.Attribute) { - dest = OperandManager.GetOutAttributeName(context, operand); + dest = OperandManager.GetOutAttributeName(operand, context.Config.Type); } else { diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs index 62d4b36c2c..b0b2ec1a99 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs @@ -17,25 +17,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions } else if (node is AstOperand operand) { - switch (operand.Type) - { - case OperandType.Attribute: - return OperandManager.GetAttributeName(context, operand); - - case OperandType.Constant: - return NumberFormatter.FormatInt(operand.Value); - - case OperandType.ConstantBuffer: - return OperandManager.GetConstantBufferName(context.Config.Type, operand); - - case OperandType.LocalVariable: - return context.GetLocalName(operand); - - case OperandType.Undefined: - return DefaultNames.UndefinedName; - } - - return DefaultNames.UndefinedName; + return context.OperandManager.GetExpression(operand, context.Config.Type); } throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs index 4c48683905..9523a1184c 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs @@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions offsetExpr = Enclose(offsetExpr, src1, Instruction.ShiftRightS32, isLhs: true); - return OperandManager.GetConstantBufferName(context, operation.GetSource(0), offsetExpr); + return OperandManager.GetConstantBufferName(operation.GetSource(0), offsetExpr, context.Config.Type); } public static string TextureSample(CodeGenContext context, AstOperation operation) diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs index d6e7ebf667..debba42843 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs @@ -44,7 +44,46 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", VariableType.F32) } }; - public static string GetConstantBufferName(GalShaderType shaderType, AstOperand cbuf) + private Dictionary _locals; + + public OperandManager() + { + _locals = new Dictionary(); + } + + 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); @@ -53,14 +92,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl return ubName + "." + GetSwizzleMask(cbuf.CbufOffset & 3); } - public static string GetConstantBufferName(CodeGenContext context, IAstNode slot, string offsetExpr) + 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(context.Config.Type, operand.Value); + string ubName = GetUbName(shaderType, operand.Value); string index0 = "[" + offsetExpr + " >> 4]"; string index1 = "[" + offsetExpr + " >> 2 & 3]"; @@ -68,12 +107,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl return ubName + index0 + index1; } - public static string GetOutAttributeName(CodeGenContext context, AstOperand attr) + public static string GetOutAttributeName(AstOperand attr, GalShaderType shaderType) { - return GetAttributeName(context, attr, isOutAttr: true); + return GetAttributeName(attr, shaderType, isOutAttr: true); } - public static string GetAttributeName(CodeGenContext context, AstOperand attr, bool isOutAttr = false) + private static string GetAttributeName(AstOperand attr, GalShaderType shaderType, bool isOutAttr = false) { int value = attr.Value; @@ -90,7 +129,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl string name = $"{prefix}{(value >> 4)}"; - if (context.Config.Type == GalShaderType.Geometry && !isOutAttr) + if (shaderType == GalShaderType.Geometry && !isOutAttr) { name += "[0]"; } @@ -111,7 +150,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl else if (_builtInAttributes.TryGetValue(value & ~3, out BuiltInAttribute builtInAttr)) { //TODO: There must be a better way to handle this... - if (context.Config.Type == GalShaderType.Fragment) + if (shaderType == GalShaderType.Fragment) { switch (value & ~3) { @@ -124,7 +163,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl string name = builtInAttr.Name; - if (context.Config.Type == GalShaderType.Geometry && !isOutAttr) + if (shaderType == GalShaderType.Geometry && !isOutAttr) { name = "gl_in[0]." + name; }