Forcing shader ganeration to use vec4 and float only and avoid some specific crashes

This commit is contained in:
Darabat 2018-08-04 00:00:18 -03:00 committed by Gummygamer
parent fa70629fab
commit 328d4db680

View file

@ -23,8 +23,6 @@ namespace Ryujinx.Graphics.Gal.Shader
private const int MaxVertexInput = 3; private const int MaxVertexInput = 3;
private static string[] ElemTypes = new string[] { "float", "vec2", "vec3", "vec4" };
private GlslDecl Decl; private GlslDecl Decl;
private ShaderHeader Header, HeaderB; private ShaderHeader Header, HeaderB;
@ -110,18 +108,18 @@ namespace Ryujinx.Graphics.Gal.Shader
} }
public GlslProgram Decompile( public GlslProgram Decompile(
IGalMemory Memory, IGalMemory Memory,
long VpAPosition, long VpAPosition,
long VpBPosition, long VpBPosition,
GalShaderType ShaderType) GalShaderType ShaderType)
{ {
Header = new ShaderHeader(Memory, VpAPosition); Header = new ShaderHeader(Memory, VpAPosition);
HeaderB = new ShaderHeader(Memory, VpBPosition); HeaderB = new ShaderHeader(Memory, VpBPosition);
Blocks = ShaderDecoder.Decode(Memory, VpAPosition); Blocks = ShaderDecoder.Decode(Memory, VpAPosition);
BlocksB = ShaderDecoder.Decode(Memory, VpBPosition); BlocksB = ShaderDecoder.Decode(Memory, VpBPosition);
GlslDecl DeclVpA = new GlslDecl(Blocks, ShaderType); GlslDecl DeclVpA = new GlslDecl(Blocks, ShaderType);
GlslDecl DeclVpB = new GlslDecl(BlocksB, ShaderType); GlslDecl DeclVpB = new GlslDecl(BlocksB, ShaderType);
Decl = GlslDecl.Merge(DeclVpA, DeclVpB); Decl = GlslDecl.Merge(DeclVpA, DeclVpB);
@ -131,10 +129,10 @@ namespace Ryujinx.Graphics.Gal.Shader
public GlslProgram Decompile(IGalMemory Memory, long Position, GalShaderType ShaderType) public GlslProgram Decompile(IGalMemory Memory, long Position, GalShaderType ShaderType)
{ {
Header = new ShaderHeader(Memory, Position); Header = new ShaderHeader(Memory, Position);
HeaderB = null; HeaderB = null;
Blocks = ShaderDecoder.Decode(Memory, Position); Blocks = ShaderDecoder.Decode(Memory, Position);
BlocksB = null; BlocksB = null;
Decl = new GlslDecl(Blocks, ShaderType); Decl = new GlslDecl(Blocks, ShaderType);
@ -159,7 +157,7 @@ namespace Ryujinx.Graphics.Gal.Shader
if (BlocksB != null) if (BlocksB != null)
{ {
PrintBlockScope(Blocks[0], null, null, "void " + GlslDecl.ProgramAName + "()", IdentationStr); PrintBlockScope(Blocks[0], null, null, "void " + GlslDecl.ProgramAName + "()", IdentationStr);
SB.AppendLine(); SB.AppendLine();
@ -167,7 +165,7 @@ namespace Ryujinx.Graphics.Gal.Shader
} }
else else
{ {
PrintBlockScope(Blocks[0], null, null, "void " + GlslDecl.ProgramName + "()", IdentationStr); PrintBlockScope(Blocks[0], null, null, "void " + GlslDecl.ProgramName + "()", IdentationStr);
} }
SB.AppendLine(); SB.AppendLine();
@ -192,8 +190,8 @@ namespace Ryujinx.Graphics.Gal.Shader
switch (Header.OutputTopology) switch (Header.OutputTopology)
{ {
case ShaderHeader.PointList: OutputTopology = "points"; break; case ShaderHeader.PointList: OutputTopology = "points"; break;
case ShaderHeader.LineStrip: OutputTopology = "line_strip"; break; case ShaderHeader.LineStrip: OutputTopology = "line_strip"; break;
case ShaderHeader.TriangleStrip: OutputTopology = "triangle_strip"; break; case ShaderHeader.TriangleStrip: OutputTopology = "triangle_strip"; break;
default: throw new InvalidOperationException(); default: throw new InvalidOperationException();
@ -266,7 +264,7 @@ namespace Ryujinx.Graphics.Gal.Shader
{ {
if (DeclInfo.Index >= 0) if (DeclInfo.Index >= 0)
{ {
SB.AppendLine(IdentationStr + "layout (location = " + DeclInfo.Index + ") " + GetDecl(DeclInfo) + "; "); SB.AppendLine(IdentationStr + "layout (location = " + DeclInfo.Index + ") " + "vec4 " + DeclInfo.Name + "; ");
} }
} }
@ -297,7 +295,7 @@ namespace Ryujinx.Graphics.Gal.Shader
{ {
if (DeclInfo.Index >= 0) if (DeclInfo.Index >= 0)
{ {
SB.AppendLine("layout (location = " + DeclInfo.Index + ") " + InOut + " " + GetDecl(DeclInfo) + ";"); SB.AppendLine("layout (location = " + DeclInfo.Index + ") " + InOut + " vec4 " + DeclInfo.Name + ";");
Count++; Count++;
} }
@ -331,7 +329,7 @@ namespace Ryujinx.Graphics.Gal.Shader
} }
else if (DeclInfo.Name == GlslDecl.FragmentOutputName) else if (DeclInfo.Name == GlslDecl.FragmentOutputName)
{ {
Name = "layout (location = 0) out " + GetDecl(DeclInfo) + Suffix + ";" + Environment.NewLine; Name = "layout (location = 0) out " + "vec4 " + DeclInfo.Name + Suffix + ";" + Environment.NewLine;
} }
else else
{ {
@ -354,7 +352,14 @@ namespace Ryujinx.Graphics.Gal.Shader
private string GetDecl(ShaderDeclInfo DeclInfo) private string GetDecl(ShaderDeclInfo DeclInfo)
{ {
return ElemTypes[DeclInfo.Size - 1] + " " + DeclInfo.Name; if (DeclInfo.Size == 4)
{
return "vec4 " + DeclInfo.Name;
}
else
{
return "float " + DeclInfo.Name;
}
} }
private void PrintMain() private void PrintMain()
@ -370,13 +375,11 @@ namespace Ryujinx.Graphics.Gal.Shader
ShaderDeclInfo DeclInfo = KV.Value; ShaderDeclInfo DeclInfo = KV.Value;
string Swizzle = ".xyzw".Substring(0, DeclInfo.Size + 1);
if (Decl.ShaderType == GalShaderType.Geometry) if (Decl.ShaderType == GalShaderType.Geometry)
{ {
for (int Vertex = 0; Vertex < MaxVertexInput; Vertex++) for (int Vertex = 0; Vertex < MaxVertexInput; Vertex++)
{ {
string Dst = Attr.Name + "[" + Vertex + "]" + Swizzle; string Dst = Attr.Name + "[" + Vertex + "]";
string Src = "block_in[" + Vertex + "]." + DeclInfo.Name; string Src = "block_in[" + Vertex + "]." + DeclInfo.Name;
@ -385,7 +388,7 @@ namespace Ryujinx.Graphics.Gal.Shader
} }
else else
{ {
SB.AppendLine(IdentationStr + Attr.Name + Swizzle + " = " + DeclInfo.Name + ";"); SB.AppendLine(IdentationStr + Attr.Name + " = " + DeclInfo.Name + ";");
} }
} }
@ -418,8 +421,6 @@ namespace Ryujinx.Graphics.Gal.Shader
ShaderDeclInfo DeclInfo = KV.Value; ShaderDeclInfo DeclInfo = KV.Value;
string Swizzle = ".xyzw".Substring(0, DeclInfo.Size + 1);
string Name = Attr.Name; string Name = Attr.Name;
if (Decl.ShaderType == GalShaderType.Geometry) if (Decl.ShaderType == GalShaderType.Geometry)
@ -427,7 +428,7 @@ namespace Ryujinx.Graphics.Gal.Shader
Name += "[0]"; Name += "[0]";
} }
SB.AppendLine(Identation + DeclInfo.Name + " = " + Name + Swizzle + ";"); SB.AppendLine(Identation + DeclInfo.Name + " = " + Name + ";");
} }
if (Decl.ShaderType == GalShaderType.Vertex) if (Decl.ShaderType == GalShaderType.Vertex)
@ -446,9 +447,9 @@ namespace Ryujinx.Graphics.Gal.Shader
ShaderIrBlock Block, ShaderIrBlock Block,
ShaderIrBlock EndBlock, ShaderIrBlock EndBlock,
ShaderIrBlock LoopBlock, ShaderIrBlock LoopBlock,
string ScopeName, string ScopeName,
string Identation, string Identation,
bool IsDoWhile = false) bool IsDoWhile = false)
{ {
string UpIdent = Identation.Substring(0, Identation.Length - IdentationStr.Length); string UpIdent = Identation.Substring(0, Identation.Length - IdentationStr.Length);
@ -479,10 +480,10 @@ namespace Ryujinx.Graphics.Gal.Shader
} }
private ShaderIrBlock PrintNodes( private ShaderIrBlock PrintNodes(
ShaderIrBlock Block, ShaderIrBlock Block,
ShaderIrBlock EndBlock, ShaderIrBlock EndBlock,
ShaderIrBlock LoopBlock, ShaderIrBlock LoopBlock,
string Identation, string Identation,
params ShaderIrNode[] Nodes) params ShaderIrNode[] Nodes)
{ {
/* /*
@ -667,12 +668,12 @@ namespace Ryujinx.Graphics.Gal.Shader
{ {
switch (Node) switch (Node)
{ {
case ShaderIrOperAbuf Abuf: return GetName (Abuf); case ShaderIrOperAbuf Abuf: return GetName(Abuf);
case ShaderIrOperCbuf Cbuf: return GetName (Cbuf); case ShaderIrOperCbuf Cbuf: return GetName(Cbuf);
case ShaderIrOperGpr Gpr: return GetName (Gpr); case ShaderIrOperGpr Gpr: return GetName(Gpr);
case ShaderIrOperImm Imm: return GetValue(Imm); case ShaderIrOperImm Imm: return GetValue(Imm);
case ShaderIrOperImmf Immf: return GetValue(Immf); case ShaderIrOperImmf Immf: return GetValue(Immf);
case ShaderIrOperPred Pred: return GetName (Pred); case ShaderIrOperPred Pred: return GetName(Pred);
case ShaderIrOp Op: case ShaderIrOp Op:
string Expr; string Expr;
@ -752,7 +753,7 @@ namespace Ryujinx.Graphics.Gal.Shader
{ {
switch (Abuf.Offs) switch (Abuf.Offs)
{ {
case GlslDecl.VertexIdAttr: return "gl_VertexID"; case GlslDecl.VertexIdAttr: return "gl_VertexID";
case GlslDecl.InstanceIdAttr: return "gl_InstanceID"; case GlslDecl.InstanceIdAttr: return "gl_InstanceID";
} }
} }
@ -779,8 +780,8 @@ namespace Ryujinx.Graphics.Gal.Shader
private string GetAttrTempName(ShaderIrOperAbuf Abuf) private string GetAttrTempName(ShaderIrOperAbuf Abuf)
{ {
int Index = Abuf.Offs >> 4; int Index = Abuf.Offs >> 4;
int Elem = (Abuf.Offs >> 2) & 3; int Elem = (Abuf.Offs >> 2) & 3;
string Swizzle = "." + GetAttrSwizzle(Elem); string Swizzle = "." + GetAttrSwizzle(Elem);
@ -820,7 +821,7 @@ namespace Ryujinx.Graphics.Gal.Shader
private string GetValue(ShaderIrOperImm Imm) private string GetValue(ShaderIrOperImm Imm)
{ {
//Only use hex is the value is too big and would likely be hard to read as int. //Only use hex is the value is too big and would likely be hard to read as int.
if (Imm.Value > 0xfff || if (Imm.Value > 0xfff ||
Imm.Value < -0xfff) Imm.Value < -0xfff)
{ {
return "0x" + Imm.Value.ToString("x8", CultureInfo.InvariantCulture); return "0x" + Imm.Value.ToString("x8", CultureInfo.InvariantCulture);
@ -1145,31 +1146,31 @@ namespace Ryujinx.Graphics.Gal.Shader
switch (Src) switch (Src)
{ {
case ShaderIrOperGpr Gpr: case ShaderIrOperGpr Gpr:
{
//When the Gpr is ZR, just return the 0 value directly,
//since the float encoding for 0 is 0.
if (Gpr.IsConst)
{ {
return "0"; //When the Gpr is ZR, just return the 0 value directly,
//since the float encoding for 0 is 0.
if (Gpr.IsConst)
{
return "0";
}
break;
} }
break;
}
case ShaderIrOperImm Imm: case ShaderIrOperImm Imm:
{
//For integer immediates being used as float,
//it's better (for readability) to just return the float value.
if (DstType == OperType.F32)
{ {
float Value = BitConverter.Int32BitsToSingle(Imm.Value); //For integer immediates being used as float,
//it's better (for readability) to just return the float value.
if (!float.IsNaN(Value) && !float.IsInfinity(Value)) if (DstType == OperType.F32)
{ {
return GetFloatConst(Value); float Value = BitConverter.Int32BitsToSingle(Imm.Value);
if (!float.IsNaN(Value) && !float.IsInfinity(Value))
{
return GetFloatConst(Value);
}
} }
break;
} }
break;
}
} }
switch (DstType) switch (DstType)
@ -1231,8 +1232,8 @@ namespace Ryujinx.Graphics.Gal.Shader
: OperType.F32; : OperType.F32;
case ShaderIrOperCbuf Cbuf: return OperType.F32; case ShaderIrOperCbuf Cbuf: return OperType.F32;
case ShaderIrOperGpr Gpr: return OperType.F32; case ShaderIrOperGpr Gpr: return OperType.F32;
case ShaderIrOperImm Imm: return OperType.I32; case ShaderIrOperImm Imm: return OperType.I32;
case ShaderIrOperImmf Immf: return OperType.F32; case ShaderIrOperImmf Immf: return OperType.F32;
case ShaderIrOperPred Pred: return OperType.Bool; case ShaderIrOperPred Pred: return OperType.Bool;