Move operand GetExpression and locals management to OperandManager

This commit is contained in:
gdkchan 2019-04-12 16:10:02 -03:00
parent 66bc1511db
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.Text;
@ -13,9 +12,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
public List<CBufferDescriptor> CBufferDescriptors { get; }
public List<TextureDescriptor> TextureDescriptors { get; }
private StringBuilder _sb;
public OperandManager OperandManager { get; }
private Dictionary<AstOperand, string> _locals;
private StringBuilder _sb;
private int _level;
@ -28,9 +27,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
CBufferDescriptors = new List<CBufferDescriptor>();
TextureDescriptors = new List<TextureDescriptor>();
_sb = new StringBuilder();
OperandManager = new OperandManager();
_locals = new Dictionary<AstOperand, string>();
_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];
}
}
}

View file

@ -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 + ";");
}

View file

@ -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";

View file

@ -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
{

View file

@ -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"}\".");

View file

@ -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)

View file

@ -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<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);
@ -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;
}