Restrict shader storage buffer search when match fails (#4011)

* Restrict storage buffer search when match fails

* Shader cache version bump
This commit is contained in:
gdkchan 2022-12-05 16:11:32 -03:00 committed by GitHub
parent 4da44e09cb
commit bbb24d8c7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 5 deletions

View file

@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 3957; private const uint CodeGenVersion = 4011;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View file

@ -8,14 +8,25 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{ {
static class GlobalToStorage static class GlobalToStorage
{ {
public static void RunPass(BasicBlock block, ShaderConfig config) public static void RunPass(BasicBlock block, ShaderConfig config, ref int sbUseMask)
{ {
int sbStart = GetStorageBaseCbOffset(config.Stage); int sbStart = GetStorageBaseCbOffset(config.Stage);
int sbEnd = sbStart + StorageDescsSize; int sbEnd = sbStart + StorageDescsSize;
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next) for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
{ {
for (int index = 0; index < node.Value.SourcesCount; index++)
{
Operand src = node.Value.GetSource(index);
int storageIndex = GetStorageIndex(src, sbStart, sbEnd);
if (storageIndex >= 0)
{
sbUseMask |= 1 << storageIndex;
}
}
if (!(node.Value is Operation operation)) if (!(node.Value is Operation operation))
{ {
continue; continue;
@ -52,6 +63,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
} }
} }
} }
config.SetAccessibleStorageBuffersMask(sbUseMask);
} }
private static LinkedListNode<INode> ReplaceGlobalWithStorage(BasicBlock block, LinkedListNode<INode> node, ShaderConfig config, int storageIndex) private static LinkedListNode<INode> ReplaceGlobalWithStorage(BasicBlock block, LinkedListNode<INode> node, ShaderConfig config, int storageIndex)

View file

@ -11,14 +11,18 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{ {
RunOptimizationPasses(blocks); RunOptimizationPasses(blocks);
int sbUseMask = 0;
// Those passes are looking for specific patterns and only needs to run once. // Those passes are looking for specific patterns and only needs to run once.
for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
{ {
GlobalToStorage.RunPass(blocks[blkIndex], config); GlobalToStorage.RunPass(blocks[blkIndex], config, ref sbUseMask);
BindlessToIndexed.RunPass(blocks[blkIndex], config); BindlessToIndexed.RunPass(blocks[blkIndex], config);
BindlessElimination.RunPass(blocks[blkIndex], config); BindlessElimination.RunPass(blocks[blkIndex], config);
} }
config.SetAccessibleStorageBuffersMask(sbUseMask);
// Run optimizations one last time to remove any code that is now optimizable after above passes. // Run optimizations one last time to remove any code that is now optimizable after above passes.
RunOptimizationPasses(blocks); RunOptimizationPasses(blocks);
} }

View file

@ -2,6 +2,7 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Numerics;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
using static Ryujinx.Graphics.Shader.Translation.GlobalMemory; using static Ryujinx.Graphics.Shader.Translation.GlobalMemory;
@ -88,8 +89,14 @@ namespace Ryujinx.Graphics.Shader.Translation
Operand sbBaseAddrLow = Const(0); Operand sbBaseAddrLow = Const(0);
Operand sbSlot = Const(0); Operand sbSlot = Const(0);
for (int slot = 0; slot < StorageMaxCount; slot++) int sbUseMask = config.AccessibleStorageBuffersMask;
while (sbUseMask != 0)
{ {
int slot = BitOperations.TrailingZeroCount(sbUseMask);
sbUseMask &= ~(1 << slot);
config.SetUsedStorageBuffer(slot, isWrite); config.SetUsedStorageBuffer(slot, isWrite);
int cbOffset = GetStorageCbOffset(config.Stage, slot); int cbOffset = GetStorageCbOffset(config.Stage, slot);

View file

@ -65,6 +65,8 @@ namespace Ryujinx.Graphics.Shader.Translation
public UInt128 NextInputAttributesComponents { get; private set; } public UInt128 NextInputAttributesComponents { get; private set; }
public UInt128 ThisInputAttributesComponents { get; private set; } public UInt128 ThisInputAttributesComponents { get; private set; }
public int AccessibleStorageBuffersMask { get; private set; }
private int _usedConstantBuffers; private int _usedConstantBuffers;
private int _usedStorageBuffers; private int _usedStorageBuffers;
private int _usedStorageBuffersWrite; private int _usedStorageBuffersWrite;
@ -98,6 +100,8 @@ namespace Ryujinx.Graphics.Shader.Translation
GpuAccessor = gpuAccessor; GpuAccessor = gpuAccessor;
Options = options; Options = options;
AccessibleStorageBuffersMask = (1 << GlobalMemory.StorageMaxCount) - 1;
UsedInputAttributesPerPatch = new HashSet<int>(); UsedInputAttributesPerPatch = new HashSet<int>();
UsedOutputAttributesPerPatch = new HashSet<int>(); UsedOutputAttributesPerPatch = new HashSet<int>();
@ -400,6 +404,11 @@ namespace Ryujinx.Graphics.Shader.Translation
UsedFeatures |= flags; UsedFeatures |= flags;
} }
public void SetAccessibleStorageBuffersMask(int mask)
{
AccessibleStorageBuffersMask = mask;
}
public void SetUsedConstantBuffer(int slot) public void SetUsedConstantBuffer(int slot)
{ {
_usedConstantBuffers |= 1 << slot; _usedConstantBuffers |= 1 << slot;