diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs index 9f039b948..5cee5b3ae 100644 --- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs +++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs @@ -29,6 +29,8 @@ namespace Ryujinx.Graphics.Shader.Decoders Dictionary visited = new Dictionary(); + ulong maxAddress = (ulong)code.Length - headerSize; + Block GetBlock(ulong blkAddress) { if (!visited.TryGetValue(blkAddress, out Block block)) @@ -45,8 +47,6 @@ namespace Ryujinx.Graphics.Shader.Decoders GetBlock(0); - ulong maxAddress = (ulong)code.Length - headerSize; - while (workQueue.TryDequeue(out Block currBlock)) { // Check if the current block is inside another block. @@ -93,6 +93,11 @@ namespace Ryujinx.Graphics.Shader.Decoders // including those from SSY/PBK instructions. foreach (OpCodePush pushOp in currBlock.PushOpCodes) { + if (pushOp.GetAbsoluteAddress() >= maxAddress) + { + return null; + } + GetBlock(pushOp.GetAbsoluteAddress()); } @@ -104,6 +109,11 @@ namespace Ryujinx.Graphics.Shader.Decoders if (lastOp is OpCodeBranch opBr) { + if (opBr.GetAbsoluteAddress() >= maxAddress) + { + return null; + } + currBlock.Branch = GetBlock(opBr.GetAbsoluteAddress()); } else if (lastOp is OpCodeBranchIndir opBrIndir) @@ -431,11 +441,11 @@ namespace Ryujinx.Graphics.Shader.Decoders } else if (current.GetLastOp() is OpCodeBranchPop op) { - ulong syncAddress = branchStack.Pop(); + ulong targetAddress = branchStack.Pop(); if (branchStack.Count == 0) { - branchStack.Push(syncAddress); + branchStack.Push(targetAddress); op.Targets.Add(pushOp, op.Targets.Count); @@ -443,8 +453,8 @@ namespace Ryujinx.Graphics.Shader.Decoders } else { - Push(new PathBlockState(syncAddress)); - Push(new PathBlockState(blocks[syncAddress])); + Push(new PathBlockState(targetAddress)); + Push(new PathBlockState(blocks[targetAddress])); } } } diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs index 2654a05b8..4a05b43b1 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs @@ -170,7 +170,7 @@ namespace Ryujinx.Graphics.Shader.Instructions if (op is OpCodeTexs texsOp) { type = GetSamplerType (texsOp.Target); - flags = GetSamplerFlags(texsOp.Target); + flags = GetTextureFlags(texsOp.Target); if ((type & SamplerType.Array) != 0) { @@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Shader.Instructions else if (op is OpCodeTlds tldsOp) { type = GetSamplerType (tldsOp.Target); - flags = GetSamplerFlags(tldsOp.Target) | TextureFlags.IntCoords; + flags = GetTextureFlags(tldsOp.Target) | TextureFlags.IntCoords; switch (tldsOp.Target) { @@ -874,7 +874,9 @@ namespace Ryujinx.Graphics.Shader.Instructions return SamplerType.Texture3D; } - throw new ArgumentException($"Invalid image target \"{target}\"."); + // TODO: Error. + + return SamplerType.Texture2D; } private static SamplerType GetSamplerType(TextureDimensions dimensions) @@ -923,7 +925,9 @@ namespace Ryujinx.Graphics.Shader.Instructions return SamplerType.TextureCube; } - throw new ArgumentException($"Invalid texture type \"{type}\"."); + // TODO: Error. + + return SamplerType.Texture2D; } private static SamplerType GetSamplerType(TexelLoadTarget type) @@ -950,10 +954,12 @@ namespace Ryujinx.Graphics.Shader.Instructions return SamplerType.Texture2D | SamplerType.Array; } - throw new ArgumentException($"Invalid texture type \"{type}\"."); + // TODO: Error. + + return SamplerType.Texture2D; } - private static TextureFlags GetSamplerFlags(Decoders.TextureTarget type) + private static TextureFlags GetTextureFlags(Decoders.TextureTarget type) { switch (type) { @@ -976,10 +982,12 @@ namespace Ryujinx.Graphics.Shader.Instructions return TextureFlags.None; } - throw new ArgumentException($"Invalid texture type \"{type}\"."); + // TODO: Error. + + return TextureFlags.None; } - private static TextureFlags GetSamplerFlags(TexelLoadTarget type) + private static TextureFlags GetTextureFlags(TexelLoadTarget type) { switch (type) { @@ -997,7 +1005,9 @@ namespace Ryujinx.Graphics.Shader.Instructions return TextureFlags.LodLevel | TextureFlags.Offset; } - throw new ArgumentException($"Invalid texture type \"{type}\"."); + // TODO: Error. + + return TextureFlags.None; } } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs index 55617b24c..3e5cb4a89 100644 --- a/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs @@ -105,13 +105,16 @@ namespace Ryujinx.Graphics.Shader.Translation { BasicBlock[] irBlocks = ControlFlowGraph.MakeCfg(ops); - Dominance.FindDominators(irBlocks[0], irBlocks.Length); + if (irBlocks.Length > 0) + { + Dominance.FindDominators(irBlocks[0], irBlocks.Length); - Dominance.FindDominanceFrontiers(irBlocks); + Dominance.FindDominanceFrontiers(irBlocks); - Ssa.Rename(irBlocks); + Ssa.Rename(irBlocks); - Optimizer.Optimize(irBlocks, config.Stage); + Optimizer.Optimize(irBlocks, config.Stage); + } StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(irBlocks, config); @@ -158,6 +161,13 @@ namespace Ryujinx.Graphics.Shader.Translation context = new EmitterContext(header.Stage, header); } + if (cfg == null) + { + size = 0; + + return new Operation[0]; + } + ulong maxEndAddress = 0; for (int blkIndex = 0; blkIndex < cfg.Length; blkIndex++)