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:
parent
4da44e09cb
commit
bbb24d8c7e
5 changed files with 38 additions and 5 deletions
|
@ -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";
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Reference in a new issue