forked from Mirror/Ryujinx
Make the shader translator more error resilient (part 2)
This commit is contained in:
parent
04102e5c9d
commit
8eb773d81f
5 changed files with 67 additions and 31 deletions
|
@ -60,6 +60,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
IntegerType intType = (IntegerType)op.RawOpCode.Extract(8, 2);
|
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;
|
bool isSmallInt = intType <= IntegerType.U16;
|
||||||
|
|
||||||
FPType floatType = (FPType)op.RawOpCode.Extract(10, 2);
|
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);
|
IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2);
|
||||||
|
|
||||||
|
// TODO: Handle S/U64.
|
||||||
|
|
||||||
bool isSmallInt = srcType <= IntegerType.U16;
|
bool isSmallInt = srcType <= IntegerType.U16;
|
||||||
|
|
||||||
bool isSignedInt = op.RawOpCode.Extract(13);
|
bool isSignedInt = op.RawOpCode.Extract(13);
|
||||||
|
@ -153,7 +162,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
if (srcType == IntegerType.U64 || dstType == IntegerType.U64)
|
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;
|
bool srcIsSmallInt = srcType <= IntegerType.U16;
|
||||||
|
|
|
@ -56,7 +56,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
// TODO.
|
// 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)
|
public static Operand GetSrcB(EmitterContext context)
|
||||||
|
|
|
@ -14,6 +14,15 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
{
|
{
|
||||||
OpCodeImage op = (OpCodeImage)context.CurrOp;
|
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 raIndex = op.Ra.Index;
|
||||||
int rbIndex = op.Rb.Index;
|
int rbIndex = op.Rb.Index;
|
||||||
|
|
||||||
|
@ -49,8 +58,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
sourcesList.Add(context.Copy(Register(op.Rc)));
|
sourcesList.Add(context.Copy(Register(op.Rc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
SamplerType type = GetSamplerType(op.Dimensions);
|
|
||||||
|
|
||||||
int coordsCount = type.GetDimensions();
|
int coordsCount = type.GetDimensions();
|
||||||
|
|
||||||
for (int index = 0; index < coordsCount; index++)
|
for (int index = 0; index < coordsCount; index++)
|
||||||
|
@ -169,8 +176,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
if (op is OpCodeTexs texsOp)
|
if (op is OpCodeTexs texsOp)
|
||||||
{
|
{
|
||||||
type = GetSamplerType (texsOp.Target);
|
type = ConvertSamplerType(texsOp.Target);
|
||||||
flags = GetTextureFlags(texsOp.Target);
|
|
||||||
|
if (type == SamplerType.None)
|
||||||
|
{
|
||||||
|
// TODO: Error, encoding is invalid.
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = ConvertTextureFlags(texsOp.Target);
|
||||||
|
|
||||||
if ((type & SamplerType.Array) != 0)
|
if ((type & SamplerType.Array) != 0)
|
||||||
{
|
{
|
||||||
|
@ -239,8 +254,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
}
|
}
|
||||||
else if (op is OpCodeTlds tldsOp)
|
else if (op is OpCodeTlds tldsOp)
|
||||||
{
|
{
|
||||||
type = GetSamplerType (tldsOp.Target);
|
type = ConvertSamplerType (tldsOp.Target);
|
||||||
flags = GetTextureFlags(tldsOp.Target) | TextureFlags.IntCoords;
|
|
||||||
|
if (type == SamplerType.None)
|
||||||
|
{
|
||||||
|
// TODO: Error, encoding is invalid.
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = ConvertTextureFlags(tldsOp.Target) | TextureFlags.IntCoords;
|
||||||
|
|
||||||
switch (tldsOp.Target)
|
switch (tldsOp.Target)
|
||||||
{
|
{
|
||||||
|
@ -428,7 +451,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new List<Operand>();
|
||||||
|
|
||||||
SamplerType type = GetSamplerType(op.Dimensions);
|
SamplerType type = ConvertSamplerType(op.Dimensions);
|
||||||
|
|
||||||
TextureFlags flags = TextureFlags.Gather;
|
TextureFlags flags = TextureFlags.Gather;
|
||||||
|
|
||||||
|
@ -553,7 +576,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
sourcesList.Add(Ra());
|
sourcesList.Add(Ra());
|
||||||
}
|
}
|
||||||
|
|
||||||
SamplerType type = GetSamplerType(op.Dimensions);
|
SamplerType type = ConvertSamplerType(op.Dimensions);
|
||||||
|
|
||||||
int coordsCount = type.GetDimensions();
|
int coordsCount = type.GetDimensions();
|
||||||
|
|
||||||
|
@ -752,7 +775,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
sourcesList.Add(Rb());
|
sourcesList.Add(Rb());
|
||||||
}
|
}
|
||||||
|
|
||||||
SamplerType type = GetSamplerType(op.Dimensions);
|
SamplerType type = ConvertSamplerType(op.Dimensions);
|
||||||
|
|
||||||
int coordsCount = type.GetDimensions();
|
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)
|
switch (target)
|
||||||
{
|
{
|
||||||
|
@ -874,12 +897,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
return SamplerType.Texture3D;
|
return SamplerType.Texture3D;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Error.
|
return SamplerType.None;
|
||||||
|
|
||||||
return SamplerType.Texture2D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SamplerType GetSamplerType(TextureDimensions dimensions)
|
private static SamplerType ConvertSamplerType(TextureDimensions dimensions)
|
||||||
{
|
{
|
||||||
switch (dimensions)
|
switch (dimensions)
|
||||||
{
|
{
|
||||||
|
@ -892,7 +913,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".");
|
throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SamplerType GetSamplerType(Decoders.TextureTarget type)
|
private static SamplerType ConvertSamplerType(Decoders.TextureTarget type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -925,12 +946,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
return SamplerType.TextureCube;
|
return SamplerType.TextureCube;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Error.
|
return SamplerType.None;
|
||||||
|
|
||||||
return SamplerType.Texture2D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SamplerType GetSamplerType(TexelLoadTarget type)
|
private static SamplerType ConvertSamplerType(TexelLoadTarget type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -954,12 +973,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
return SamplerType.Texture2D | SamplerType.Array;
|
return SamplerType.Texture2D | SamplerType.Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Error.
|
return SamplerType.None;
|
||||||
|
|
||||||
return SamplerType.Texture2D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextureFlags GetTextureFlags(Decoders.TextureTarget type)
|
private static TextureFlags ConvertTextureFlags(Decoders.TextureTarget type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -982,12 +999,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
return TextureFlags.None;
|
return TextureFlags.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Error.
|
|
||||||
|
|
||||||
return TextureFlags.None;
|
return TextureFlags.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextureFlags GetTextureFlags(TexelLoadTarget type)
|
private static TextureFlags ConvertTextureFlags(TexelLoadTarget type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -1005,8 +1020,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
return TextureFlags.LodLevel | TextureFlags.Offset;
|
return TextureFlags.LodLevel | TextureFlags.Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Error.
|
|
||||||
|
|
||||||
return TextureFlags.None;
|
return TextureFlags.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Ryujinx.Graphics.Shader
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum SamplerType
|
public enum SamplerType
|
||||||
{
|
{
|
||||||
|
None = 0,
|
||||||
Texture1D,
|
Texture1D,
|
||||||
TextureBuffer,
|
TextureBuffer,
|
||||||
Texture2D,
|
Texture2D,
|
||||||
|
@ -32,7 +33,7 @@ namespace Ryujinx.Graphics.Shader
|
||||||
case SamplerType.TextureCube: return 3;
|
case SamplerType.TextureCube: return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ArgumentException($"Invalid texture type \"{type}\".");
|
throw new ArgumentException($"Invalid sampler type \"{type}\".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,6 +28,13 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
Block[] cfg = Decoder.Decode(code, (ulong)headerSize);
|
Block[] cfg = Decoder.Decode(code, (ulong)headerSize);
|
||||||
|
|
||||||
|
if (cfg == null)
|
||||||
|
{
|
||||||
|
// TODO: Error.
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
ulong endAddress = 0;
|
ulong endAddress = 0;
|
||||||
|
|
||||||
foreach (Block block in cfg)
|
foreach (Block block in cfg)
|
||||||
|
@ -163,6 +170,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
if (cfg == null)
|
if (cfg == null)
|
||||||
{
|
{
|
||||||
|
// TODO: Error.
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
return new Operation[0];
|
return new Operation[0];
|
||||||
|
|
Loading…
Reference in a new issue