Use structures for GLSL input and output attributes
* Better end-of-line styling
This commit is contained in:
parent
af5f059d4e
commit
f6ebea82ca
2 changed files with 113 additions and 15 deletions
|
@ -14,6 +14,9 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
private const int AttrStartIndex = 8;
|
private const int AttrStartIndex = 8;
|
||||||
private const int TexStartIndex = 8;
|
private const int TexStartIndex = 8;
|
||||||
|
|
||||||
|
public const string StageAFunctionName = "StageA";
|
||||||
|
public const string StageBFunctionName = "StageB";
|
||||||
|
|
||||||
public const string PositionOutAttrName = "position";
|
public const string PositionOutAttrName = "position";
|
||||||
|
|
||||||
private const string InAttrName = "in_attr";
|
private const string InAttrName = "in_attr";
|
||||||
|
|
|
@ -114,14 +114,25 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
SB.AppendLine("#version 410 core");
|
SB.AppendLine("#version 410 core");
|
||||||
|
|
||||||
|
//TODO: Decide if Stage B has to be called
|
||||||
|
SB.AppendLine("#define HAS_STAGE_B 0" + Environment.NewLine);
|
||||||
|
|
||||||
PrintDeclTextures();
|
PrintDeclTextures();
|
||||||
PrintDeclUniforms();
|
PrintDeclUniforms();
|
||||||
PrintDeclInAttributes();
|
PrintDeclInAttributes();
|
||||||
PrintDeclOutAttributes();
|
PrintDeclOutAttributes();
|
||||||
|
PrintDeclInStruct();
|
||||||
|
PrintDeclOutStruct();
|
||||||
PrintDeclGprs();
|
PrintDeclGprs();
|
||||||
PrintDeclPreds();
|
PrintDeclPreds();
|
||||||
|
|
||||||
PrintBlockScope(Blocks[0], null, null, "void main()", IdentationStr);
|
//TODO: Build Stage B here
|
||||||
|
|
||||||
|
string StageAFunc = "void " + GlslDecl.StageAFunctionName + "(in Input IN, out Output OUT)";
|
||||||
|
|
||||||
|
PrintBlockScope(Blocks[0], null, null, StageAFunc, IdentationStr);
|
||||||
|
|
||||||
|
PrintMain();
|
||||||
|
|
||||||
string GlslCode = SB.ToString();
|
string GlslCode = SB.ToString();
|
||||||
|
|
||||||
|
@ -196,6 +207,40 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PrintDeclInStruct()
|
||||||
|
{
|
||||||
|
SB.AppendLine("struct Input {");
|
||||||
|
|
||||||
|
PrintDeclStructAttributes(Decl.InAttributes.Values);
|
||||||
|
|
||||||
|
SB.AppendLine("};" + Environment.NewLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrintDeclOutStruct()
|
||||||
|
{
|
||||||
|
SB.AppendLine("struct Output {");
|
||||||
|
|
||||||
|
PrintDeclStructAttributes(Decl.OutAttributes.Values);
|
||||||
|
|
||||||
|
SB.AppendLine("};" + Environment.NewLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrintDeclStructAttributes(IEnumerable<ShaderDeclInfo> Decls)
|
||||||
|
{
|
||||||
|
if (Decls.Count() > 0)
|
||||||
|
{
|
||||||
|
foreach (ShaderDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector))
|
||||||
|
{
|
||||||
|
SB.AppendLine(IdentationStr + GetDecl(DeclInfo) + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Looks like GLSL doesn't like empty structs
|
||||||
|
SB.AppendLine(IdentationStr + "float dummy;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void PrintDeclGprs()
|
private void PrintDeclGprs()
|
||||||
{
|
{
|
||||||
PrintDecls(Decl.Gprs);
|
PrintDecls(Decl.Gprs);
|
||||||
|
@ -244,6 +289,63 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
return ElemTypes[DeclInfo.Size - 1] + " " + DeclInfo.Name;
|
return ElemTypes[DeclInfo.Size - 1] + " " + DeclInfo.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PrintMain()
|
||||||
|
{
|
||||||
|
SB.AppendLine("void main() {");
|
||||||
|
|
||||||
|
//Build host input attributes
|
||||||
|
SB.AppendLine(IdentationStr + "Input in_B;");
|
||||||
|
|
||||||
|
foreach (ShaderDeclInfo DeclInfo in Decl.InAttributes.Values.OrderBy(DeclKeySelector))
|
||||||
|
{
|
||||||
|
SB.AppendLine(IdentationStr + "in_B." + DeclInfo.Name + " = " + DeclInfo.Name + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
SB.AppendLine();
|
||||||
|
|
||||||
|
//Build Stage A input (IN)
|
||||||
|
SB.AppendLine(IdentationStr + "Input in_A;");
|
||||||
|
|
||||||
|
SB.AppendLine("#if HAS_STAGE_B");
|
||||||
|
|
||||||
|
SB.AppendLine(IdentationStr + GlslDecl.StageBFunctionName + "(in_B, in_A);");
|
||||||
|
|
||||||
|
SB.AppendLine("#else");
|
||||||
|
|
||||||
|
SB.AppendLine(IdentationStr + "in_A = in_B;");
|
||||||
|
|
||||||
|
SB.AppendLine("#endif" + Environment.NewLine);
|
||||||
|
|
||||||
|
//Call Stage A
|
||||||
|
SB.AppendLine(IdentationStr + "Output out_host;");
|
||||||
|
|
||||||
|
SB.AppendLine(IdentationStr + GlslDecl.StageAFunctionName + "(in_A, out_host);");
|
||||||
|
|
||||||
|
//Write host output attributes
|
||||||
|
if (Decl.OutAttributes.Count > 0)
|
||||||
|
{
|
||||||
|
SB.AppendLine();
|
||||||
|
|
||||||
|
foreach (ShaderDeclInfo DeclInfo in Decl.OutAttributes.Values.OrderBy(DeclKeySelector))
|
||||||
|
{
|
||||||
|
SB.AppendLine(IdentationStr + DeclInfo.Name + " = out_host." + DeclInfo.Name + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Do end-of-vertex stuff (host specific)
|
||||||
|
if (Decl.ShaderType == GalShaderType.Vertex)
|
||||||
|
{
|
||||||
|
SB.AppendLine();
|
||||||
|
|
||||||
|
SB.AppendLine(IdentationStr + "gl_Position.xy *= " + GlslDecl.FlipUniformName + ";");
|
||||||
|
|
||||||
|
SB.AppendLine(IdentationStr + GlslDecl.PositionOutAttrName + " = out_host.gl_Position;");
|
||||||
|
SB.AppendLine(IdentationStr + GlslDecl.PositionOutAttrName + ".w = 1;");
|
||||||
|
}
|
||||||
|
|
||||||
|
SB.AppendLine("}");
|
||||||
|
}
|
||||||
|
|
||||||
private void PrintBlockScope(
|
private void PrintBlockScope(
|
||||||
ShaderIrBlock Block,
|
ShaderIrBlock Block,
|
||||||
ShaderIrBlock EndBlock,
|
ShaderIrBlock EndBlock,
|
||||||
|
@ -278,6 +380,11 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
{
|
{
|
||||||
SB.AppendLine(UpIdent + "}");
|
SB.AppendLine(UpIdent + "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EndBlock == null)
|
||||||
|
{
|
||||||
|
SB.AppendLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ShaderIrBlock PrintNodes(
|
private ShaderIrBlock PrintNodes(
|
||||||
|
@ -383,18 +490,6 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (Op.Inst == ShaderIrInst.Exit)
|
|
||||||
{
|
|
||||||
//Do everything that needs to be done before
|
|
||||||
//the shader ends here.
|
|
||||||
if (Decl.ShaderType == GalShaderType.Vertex)
|
|
||||||
{
|
|
||||||
SB.AppendLine(Identation + "gl_Position.xy *= flip;");
|
|
||||||
|
|
||||||
SB.AppendLine(Identation + GlslDecl.PositionOutAttrName + " = gl_Position;");
|
|
||||||
SB.AppendLine(Identation + GlslDecl.PositionOutAttrName + ".w = 1;");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SB.AppendLine(Identation + GetSrcExpr(Op, true) + ";");
|
SB.AppendLine(Identation + GetSrcExpr(Op, true) + ";");
|
||||||
}
|
}
|
||||||
|
@ -546,7 +641,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
private string GetOutAbufName(ShaderIrOperAbuf Abuf)
|
private string GetOutAbufName(ShaderIrOperAbuf Abuf)
|
||||||
{
|
{
|
||||||
return GetName(Decl.OutAttributes, Abuf);
|
return "OUT." + GetName(Decl.OutAttributes, Abuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetName(ShaderIrOperAbuf Abuf)
|
private string GetName(ShaderIrOperAbuf Abuf)
|
||||||
|
@ -569,7 +664,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetName(Decl.InAttributes, Abuf);
|
return "IN." + GetName(Decl.InAttributes, Abuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetName(IReadOnlyDictionary<int, ShaderDeclInfo> Dict, ShaderIrOperAbuf Abuf)
|
private string GetName(IReadOnlyDictionary<int, ShaderDeclInfo> Dict, ShaderIrOperAbuf Abuf)
|
||||||
|
|
Loading…
Reference in a new issue