diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-11-02 23:07:21 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 3ab5c23f492183ae6f5cf8f62c4239bf181d2630 (patch) | |
| tree | 288daa576efbbe3220d835834acd562dff7d6cbd /Ryujinx.Graphics.Shader/Translation/Optimizations | |
| parent | 63345a3098e05e0d0692bc46852dfbfccfdcfae2 (diff) | |
Add partial support for array of samplers, and add pass to identify them from bindless texture accesses
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation/Optimizations')
| -rw-r--r-- | Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs | 84 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs | 5 |
2 files changed, 89 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs new file mode 100644 index 00000000..8cb62db9 --- /dev/null +++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs @@ -0,0 +1,84 @@ +using Ryujinx.Graphics.Shader.IntermediateRepresentation; +using System.Collections.Generic; + +using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; + +namespace Ryujinx.Graphics.Shader.Translation.Optimizations +{ + static class BindlessToIndexed + { + private const int StorageDescsBaseOffset = 0x44; // In words. + + private const int UbeStorageDescsBaseOffset = 0x84; // In words. + private const int UbeStorageMaxCount = 14; + + private const int StorageDescSize = 4; // In words. + private const int StorageMaxCount = 16; + + private const int StorageDescsSize = StorageDescSize * StorageMaxCount; + + public static void RunPass(BasicBlock block) + { + // We can turn a bindless texture access into a indexed access, + // as long the following conditions are true: + // - The handle is loaded using a LDC instruction. + // - The handle is loaded from the constant buffer with the handles (CB2 for NVN). + // - The load has a constant offset. + // The base offset of the array of handles on the constant buffer is the constant offset. + for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next) + { + if (!(node.Value is TextureOperation texOp)) + { + continue; + } + + if ((texOp.Flags & TextureFlags.Bindless) == 0) + { + continue; + } + + if (!(texOp.GetSource(0).AsgOp is Operation handleAsgOp)) + { + continue; + } + + if (handleAsgOp.Inst != Instruction.LoadConstant) + { + continue; + } + + Operand ldcSrc0 = handleAsgOp.GetSource(0); + Operand ldcSrc1 = handleAsgOp.GetSource(1); + + if (ldcSrc0.Type != OperandType.Constant || ldcSrc0.Value != 2) + { + continue; + } + + if (!(ldcSrc1.AsgOp is Operation addOp)) + { + continue; + } + + Operand addSrc1 = addOp.GetSource(1); + + if (addSrc1.Type != OperandType.Constant) + { + continue; + } + + texOp.TurnIntoIndexed(addSrc1.Value); + + Operand index = Local(); + + Operand source = addOp.GetSource(0); + + Operation shrBy1 = new Operation(Instruction.ShiftRightU32, index, source, Const(1)); + + block.Operations.AddBefore(node, shrBy1); + + texOp.SetSource(0, index); + } + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs index 22d794a4..6ee27884 100644 --- a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs +++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs @@ -84,6 +84,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations } } while (modified); + + for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) + { + BindlessToIndexed.RunPass(blocks[blkIndex]); + } } private static void PropagateCopy(Operation copyOp) |
