Move operand GetExpression and locals management to OperandManager

This commit is contained in:
gdkchan 2019-04-12 16:10:02 -03:00
commit ae9e285947
7 changed files with 58 additions and 50 deletions

View file

@ -1,4 +1,3 @@
using Ryujinx.Graphics.Shader.StructuredIr;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -13,9 +12,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
public List<CBufferDescriptor> CBufferDescriptors { get; } public List<CBufferDescriptor> CBufferDescriptors { get; }
public List<TextureDescriptor> TextureDescriptors { get; } public List<TextureDescriptor> TextureDescriptors { get; }
private StringBuilder _sb; public OperandManager OperandManager { get; }
private Dictionary<AstOperand, string> _locals; private StringBuilder _sb;
private int _level; private int _level;
@ -28,9 +27,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
CBufferDescriptors = new List<CBufferDescriptor>(); CBufferDescriptors = new List<CBufferDescriptor>();
TextureDescriptors = new List<TextureDescriptor>(); TextureDescriptors = new List<TextureDescriptor>();
_sb = new StringBuilder(); OperandManager = new OperandManager();
_locals = new Dictionary<AstOperand, string>(); _sb = new StringBuilder();
} }
public void AppendLine() public void AppendLine()
@ -87,19 +86,5 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return identation; 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];
}
} }
} }

View file

@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{ {
foreach (AstOperand decl in info.Locals) foreach (AstOperand decl in info.Locals)
{ {
string name = context.DeclareLocal(decl); string name = context.OperandManager.DeclareLocal(decl);
context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";"); context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";");
} }

View file

@ -2,6 +2,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{ {
static class DefaultNames static class DefaultNames
{ {
public const string LocalNamePrefix = "temp";
public const string SamplerNamePrefix = "tex"; public const string SamplerNamePrefix = "tex";
public const string IAttributePrefix = "in_attr"; public const string IAttributePrefix = "in_attr";

View file

@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
if (assignment.Destination is AstOperand operand && operand.Type == OperandType.Attribute) if (assignment.Destination is AstOperand operand && operand.Type == OperandType.Attribute)
{ {
dest = OperandManager.GetOutAttributeName(context, operand); dest = OperandManager.GetOutAttributeName(operand, context.Config.Type);
} }
else else
{ {

View file

@ -17,25 +17,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
} }
else if (node is AstOperand operand) else if (node is AstOperand operand)
{ {
switch (operand.Type) return context.OperandManager.GetExpression(operand, context.Config.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;
} }
throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\"."); throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\".");

View file

@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
offsetExpr = Enclose(offsetExpr, src1, Instruction.ShiftRightS32, isLhs: true); 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) public static string TextureSample(CodeGenContext context, AstOperation operation)

View file

@ -44,7 +44,46 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{ AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", VariableType.F32) } { AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", VariableType.F32) }
}; };
public static string GetConstantBufferName(GalShaderType shaderType, AstOperand cbuf) 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); string ubName = GetUbName(shaderType, cbuf.CbufSlot);
@ -53,14 +92,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return ubName + "." + GetSwizzleMask(cbuf.CbufOffset & 3); 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. //Non-constant slots are not supported.
//It is expected that upstream stages are never going to generate non-constant //It is expected that upstream stages are never going to generate non-constant
//slot access. //slot access.
AstOperand operand = (AstOperand)slot; AstOperand operand = (AstOperand)slot;
string ubName = GetUbName(context.Config.Type, operand.Value); string ubName = GetUbName(shaderType, operand.Value);
string index0 = "[" + offsetExpr + " >> 4]"; string index0 = "[" + offsetExpr + " >> 4]";
string index1 = "[" + offsetExpr + " >> 2 & 3]"; string index1 = "[" + offsetExpr + " >> 2 & 3]";
@ -68,12 +107,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return ubName + index0 + index1; 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; int value = attr.Value;
@ -90,7 +129,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string name = $"{prefix}{(value >> 4)}"; string name = $"{prefix}{(value >> 4)}";
if (context.Config.Type == GalShaderType.Geometry && !isOutAttr) if (shaderType == GalShaderType.Geometry && !isOutAttr)
{ {
name += "[0]"; name += "[0]";
} }
@ -111,7 +150,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
else if (_builtInAttributes.TryGetValue(value & ~3, out BuiltInAttribute builtInAttr)) else if (_builtInAttributes.TryGetValue(value & ~3, out BuiltInAttribute builtInAttr))
{ {
//TODO: There must be a better way to handle this... //TODO: There must be a better way to handle this...
if (context.Config.Type == GalShaderType.Fragment) if (shaderType == GalShaderType.Fragment)
{ {
switch (value & ~3) switch (value & ~3)
{ {
@ -124,7 +163,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string name = builtInAttr.Name; string name = builtInAttr.Name;
if (context.Config.Type == GalShaderType.Geometry && !isOutAttr) if (shaderType == GalShaderType.Geometry && !isOutAttr)
{ {
name = "gl_in[0]." + name; name = "gl_in[0]." + name;
} }