Make the shader translator more error resilient
This commit is contained in:
parent
eea73bc421
commit
04102e5c9d
3 changed files with 49 additions and 19 deletions
|
@ -29,6 +29,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||
|
||||
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
|
||||
|
||||
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]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue