diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/Translation/Optimizations')
4 files changed, 60 insertions, 21 deletions
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs index ca46a1f5..9a3ae1b8 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToIndexed.cs @@ -32,25 +32,49 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations continue; } - if (handleAsgOp.Inst != Instruction.LoadConstant) + if (handleAsgOp.Inst != Instruction.Load || + handleAsgOp.StorageKind != StorageKind.ConstantBuffer || + handleAsgOp.SourcesCount != 4) { continue; } Operand ldcSrc0 = handleAsgOp.GetSource(0); + + if (ldcSrc0.Type != OperandType.Constant || + !config.ResourceManager.TryGetConstantBufferSlot(ldcSrc0.Value, out int src0CbufSlot) || + src0CbufSlot != 2) + { + continue; + } + Operand ldcSrc1 = handleAsgOp.GetSource(1); - if (ldcSrc0.Type != OperandType.Constant || ldcSrc0.Value != 2) + // We expect field index 0 to be accessed. + if (ldcSrc1.Type != OperandType.Constant || ldcSrc1.Value != 0) + { + continue; + } + + Operand ldcSrc2 = handleAsgOp.GetSource(2); + + // FIXME: This is missing some checks, for example, a check to ensure that the shift value is 2. + // Might be not worth fixing since if that doesn't kick in, the result will be no texture + // to access anyway which is also wrong. + // Plus this whole transform is fundamentally flawed as-is since we have no way to know the array size. + // Eventually, this should be entirely removed in favor of a implementation that supports true bindless + // texture access. + if (!(ldcSrc2.AsgOp is Operation shrOp) || shrOp.Inst != Instruction.ShiftRightU32) { continue; } - if (!(ldcSrc1.AsgOp is Operation shrOp) || shrOp.Inst != Instruction.ShiftRightU32) + if (!(shrOp.GetSource(0).AsgOp is Operation shrOp2) || shrOp2.Inst != Instruction.ShiftRightU32) { continue; } - if (!(shrOp.GetSource(0).AsgOp is Operation addOp) || addOp.Inst != Instruction.Add) + if (!(shrOp2.GetSource(0).AsgOp is Operation addOp) || addOp.Inst != Instruction.Add) { continue; } diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs index 6729f077..4caadb73 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs @@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations { static class ConstantFolding { - public static void RunPass(Operation operation) + public static void RunPass(ShaderConfig config, Operation operation) { if (!AreAllSourcesConstant(operation)) { @@ -153,8 +153,21 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations EvaluateFPUnary(operation, (x) => float.IsNaN(x)); break; - case Instruction.LoadConstant: - operation.TurnIntoCopy(Cbuf(operation.GetSource(0).Value, operation.GetSource(1).Value)); + case Instruction.Load: + if (operation.StorageKind == StorageKind.ConstantBuffer && operation.SourcesCount == 4) + { + int binding = operation.GetSource(0).Value; + int fieldIndex = operation.GetSource(1).Value; + + if (config.ResourceManager.TryGetConstantBufferSlot(binding, out int cbufSlot) && fieldIndex == 0) + { + int vecIndex = operation.GetSource(2).Value; + int elemIndex = operation.GetSource(3).Value; + int cbufOffset = vecIndex * 4 + elemIndex; + + operation.TurnIntoCopy(Cbuf(cbufSlot, cbufOffset)); + } + } break; case Instruction.Maximum: diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs index 774d3e36..7758b4c6 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs @@ -347,21 +347,23 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations return wordOffset; } - Operand[] sources = new Operand[operation.SourcesCount]; + Operand cbufOffset = GetCbufOffset(); + Operand vecIndex = Local(); + Operand elemIndex = Local(); - int cbSlot = UbeFirstCbuf + storageIndex; + node.List.AddBefore(node, new Operation(Instruction.ShiftRightU32, 0, vecIndex, cbufOffset, Const(2))); + node.List.AddBefore(node, new Operation(Instruction.BitwiseAnd, 0, elemIndex, cbufOffset, Const(3))); - sources[0] = Const(cbSlot); - sources[1] = GetCbufOffset(); + Operand[] sources = new Operand[4]; - config.SetUsedConstantBuffer(cbSlot); + int cbSlot = UbeFirstCbuf + storageIndex; - for (int index = 2; index < operation.SourcesCount; index++) - { - sources[index] = operation.GetSource(index); - } + sources[0] = Const(config.ResourceManager.GetConstantBufferBinding(cbSlot)); + sources[1] = Const(0); + sources[2] = vecIndex; + sources[3] = elemIndex; - Operation ldcOp = new Operation(Instruction.LoadConstant, operation.Dest, sources); + Operation ldcOp = new Operation(Instruction.Load, StorageKind.ConstantBuffer, operation.Dest, sources); for (int index = 0; index < operation.SourcesCount; index++) { diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs index b41e47e4..b126e2c4 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs @@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations { public static void RunPass(BasicBlock[] blocks, ShaderConfig config) { - RunOptimizationPasses(blocks); + RunOptimizationPasses(blocks, config); int sbUseMask = 0; int ubeUseMask = 0; @@ -31,10 +31,10 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations config.SetAccessibleBufferMasks(sbUseMask, ubeUseMask); // Run optimizations one last time to remove any code that is now optimizable after above passes. - RunOptimizationPasses(blocks); + RunOptimizationPasses(blocks, config); } - private static void RunOptimizationPasses(BasicBlock[] blocks) + private static void RunOptimizationPasses(BasicBlock[] blocks, ShaderConfig config) { bool modified; @@ -73,7 +73,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations continue; } - ConstantFolding.RunPass(operation); + ConstantFolding.RunPass(config, operation); Simplification.RunPass(operation); if (DestIsLocalVar(operation)) |