aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-11-15 20:41:06 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit8eb773d81f0b580851b840f3abc222b784523fbc (patch)
tree7be5a2a09072363d287728080224c1ad1188d286
parent04102e5c9db600d4ea4ffc0b514bda6f5e300bca (diff)
Make the shader translator more error resilient (part 2)
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs13
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs4
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs69
-rw-r--r--Ryujinx.Graphics.Shader/SamplerType.cs3
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Translator.cs9
5 files changed, 67 insertions, 31 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
index 95e9a20a..5aa925d9 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
@@ -60,6 +60,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
IntegerType intType = (IntegerType)op.RawOpCode.Extract(8, 2);
+ if (intType == IntegerType.U64)
+ {
+ // TODO: Warning. This instruction supports 64-bits integers, but it is not implemented.
+
+ return;
+ }
+
bool isSmallInt = intType <= IntegerType.U16;
FPType floatType = (FPType)op.RawOpCode.Extract(10, 2);
@@ -118,6 +125,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2);
+ // TODO: Handle S/U64.
+
bool isSmallInt = srcType <= IntegerType.U16;
bool isSignedInt = op.RawOpCode.Extract(13);
@@ -153,7 +162,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (srcType == IntegerType.U64 || dstType == IntegerType.U64)
{
- // TODO: Warning. This instruction doesn't support 64-bits integers
+ // TODO: Warning. This instruction doesn't support 64-bits integers.
+
+ return;
}
bool srcIsSmallInt = srcType <= IntegerType.U16;
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
index ddacc151..4b85e96f 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
@@ -56,7 +56,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
// TODO.
}
- throw new ArgumentException($"Invalid floating point type \"{floatType}\".");
+ // TODO: Warn about invalid floating point type.
+
+ return Const(0);
}
public static Operand GetSrcB(EmitterContext context)
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index 4a05b43b..41ba740e 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -14,6 +14,15 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
OpCodeImage op = (OpCodeImage)context.CurrOp;
+ SamplerType type = ConvertSamplerType(op.Dimensions);
+
+ if (type == SamplerType.None)
+ {
+ // TODO: Error, encoding is invalid.
+
+ return;
+ }
+
int raIndex = op.Ra.Index;
int rbIndex = op.Rb.Index;
@@ -49,8 +58,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
sourcesList.Add(context.Copy(Register(op.Rc)));
}
- SamplerType type = GetSamplerType(op.Dimensions);
-
int coordsCount = type.GetDimensions();
for (int index = 0; index < coordsCount; index++)
@@ -169,8 +176,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (op is OpCodeTexs texsOp)
{
- type = GetSamplerType (texsOp.Target);
- flags = GetTextureFlags(texsOp.Target);
+ type = ConvertSamplerType(texsOp.Target);
+
+ if (type == SamplerType.None)
+ {
+ // TODO: Error, encoding is invalid.
+
+ return;
+ }
+
+ flags = ConvertTextureFlags(texsOp.Target);
if ((type & SamplerType.Array) != 0)
{
@@ -239,8 +254,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else if (op is OpCodeTlds tldsOp)
{
- type = GetSamplerType (tldsOp.Target);
- flags = GetTextureFlags(tldsOp.Target) | TextureFlags.IntCoords;
+ type = ConvertSamplerType (tldsOp.Target);
+
+ if (type == SamplerType.None)
+ {
+ // TODO: Error, encoding is invalid.
+
+ return;
+ }
+
+ flags = ConvertTextureFlags(tldsOp.Target) | TextureFlags.IntCoords;
switch (tldsOp.Target)
{
@@ -428,7 +451,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
List<Operand> sourcesList = new List<Operand>();
- SamplerType type = GetSamplerType(op.Dimensions);
+ SamplerType type = ConvertSamplerType(op.Dimensions);
TextureFlags flags = TextureFlags.Gather;
@@ -553,7 +576,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
sourcesList.Add(Ra());
}
- SamplerType type = GetSamplerType(op.Dimensions);
+ SamplerType type = ConvertSamplerType(op.Dimensions);
int coordsCount = type.GetDimensions();
@@ -752,7 +775,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
sourcesList.Add(Rb());
}
- SamplerType type = GetSamplerType(op.Dimensions);
+ SamplerType type = ConvertSamplerType(op.Dimensions);
int coordsCount = type.GetDimensions();
@@ -851,7 +874,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
}
- private static SamplerType GetSamplerType(ImageDimensions target)
+ private static SamplerType ConvertSamplerType(ImageDimensions target)
{
switch (target)
{
@@ -874,12 +897,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
return SamplerType.Texture3D;
}
- // TODO: Error.
-
- return SamplerType.Texture2D;
+ return SamplerType.None;
}
- private static SamplerType GetSamplerType(TextureDimensions dimensions)
+ private static SamplerType ConvertSamplerType(TextureDimensions dimensions)
{
switch (dimensions)
{
@@ -892,7 +913,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".");
}
- private static SamplerType GetSamplerType(Decoders.TextureTarget type)
+ private static SamplerType ConvertSamplerType(Decoders.TextureTarget type)
{
switch (type)
{
@@ -925,12 +946,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
return SamplerType.TextureCube;
}
- // TODO: Error.
-
- return SamplerType.Texture2D;
+ return SamplerType.None;
}
- private static SamplerType GetSamplerType(TexelLoadTarget type)
+ private static SamplerType ConvertSamplerType(TexelLoadTarget type)
{
switch (type)
{
@@ -954,12 +973,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
return SamplerType.Texture2D | SamplerType.Array;
}
- // TODO: Error.
-
- return SamplerType.Texture2D;
+ return SamplerType.None;
}
- private static TextureFlags GetTextureFlags(Decoders.TextureTarget type)
+ private static TextureFlags ConvertTextureFlags(Decoders.TextureTarget type)
{
switch (type)
{
@@ -982,12 +999,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
return TextureFlags.None;
}
- // TODO: Error.
-
return TextureFlags.None;
}
- private static TextureFlags GetTextureFlags(TexelLoadTarget type)
+ private static TextureFlags ConvertTextureFlags(TexelLoadTarget type)
{
switch (type)
{
@@ -1005,8 +1020,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
return TextureFlags.LodLevel | TextureFlags.Offset;
}
- // TODO: Error.
-
return TextureFlags.None;
}
}
diff --git a/Ryujinx.Graphics.Shader/SamplerType.cs b/Ryujinx.Graphics.Shader/SamplerType.cs
index 5e0b776c..9546efe4 100644
--- a/Ryujinx.Graphics.Shader/SamplerType.cs
+++ b/Ryujinx.Graphics.Shader/SamplerType.cs
@@ -5,6 +5,7 @@ namespace Ryujinx.Graphics.Shader
[Flags]
public enum SamplerType
{
+ None = 0,
Texture1D,
TextureBuffer,
Texture2D,
@@ -32,7 +33,7 @@ namespace Ryujinx.Graphics.Shader
case SamplerType.TextureCube: return 3;
}
- throw new ArgumentException($"Invalid texture type \"{type}\".");
+ throw new ArgumentException($"Invalid sampler type \"{type}\".");
}
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs
index 3e5cb4a8..2f33997c 100644
--- a/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -28,6 +28,13 @@ namespace Ryujinx.Graphics.Shader.Translation
Block[] cfg = Decoder.Decode(code, (ulong)headerSize);
+ if (cfg == null)
+ {
+ // TODO: Error.
+
+ return code;
+ }
+
ulong endAddress = 0;
foreach (Block block in cfg)
@@ -163,6 +170,8 @@ namespace Ryujinx.Graphics.Shader.Translation
if (cfg == null)
{
+ // TODO: Error.
+
size = 0;
return new Operation[0];