aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-11-19 15:10:44 -0300
committerGitHub <noreply@github.com>2023-11-19 15:10:44 -0300
commit0b58f462668694db1a035e8be40d2a6d366635e1 (patch)
tree15e19f00ec58321d982eb48da337d49230fbf82d /src
parentaa96dcb1bede3693877e2f1eca3e169d8ee13ef1 (diff)
Extend bindless elimination to see through Phis with the same results (#5957)1.1.1091
* Extend bindless elimination to see through Phis with the same results * Shader cache version bump
Diffstat (limited to 'src')
-rw-r--r--src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs2
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs58
2 files changed, 58 insertions, 2 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index 0dc4b1a7..403e039a 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 5791;
+ private const uint CodeGenVersion = 5957;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index 19b7999a..c955f5b5 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
continue;
}
- if (bindlessHandle.AsgOp is not Operation handleCombineOp)
+ if (!TryGetOperation(bindlessHandle.AsgOp, out Operation handleCombineOp))
{
continue;
}
@@ -199,9 +199,64 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
}
}
+ private static bool TryGetOperation(INode asgOp, out Operation outOperation)
+ {
+ if (asgOp is PhiNode phi)
+ {
+ // If we have a phi, let's check if all inputs are effectively the same value.
+ // If so, we can "see through" the phi and pick any of the inputs (since they are all the same).
+
+ Operand firstSrc = phi.GetSource(0);
+
+ for (int index = 1; index < phi.SourcesCount; index++)
+ {
+ if (!IsSameOperand(firstSrc, phi.GetSource(index)))
+ {
+ outOperation = null;
+
+ return false;
+ }
+ }
+
+ asgOp = firstSrc.AsgOp;
+ }
+
+ if (asgOp is Operation operation)
+ {
+ outOperation = operation;
+
+ return true;
+ }
+
+ outOperation = null;
+
+ return false;
+ }
+
+ private static bool IsSameOperand(Operand x, Operand y)
+ {
+ if (x.Type == y.Type && x.Type == OperandType.LocalVariable)
+ {
+ return x.AsgOp is Operation xOp &&
+ y.AsgOp is Operation yOp &&
+ xOp.Inst == Instruction.BitwiseOr &&
+ yOp.Inst == Instruction.BitwiseOr &&
+ AreBothEqualConstantBuffers(xOp.GetSource(0), yOp.GetSource(0)) &&
+ AreBothEqualConstantBuffers(xOp.GetSource(1), yOp.GetSource(1));
+ }
+
+ return false;
+ }
+
+ private static bool AreBothEqualConstantBuffers(Operand x, Operand y)
+ {
+ return x.Type == y.Type && x.Value == y.Value && x.Type == OperandType.ConstantBuffer;
+ }
+
private static Operand GetSourceForMaskedHandle(Operation asgOp, uint mask)
{
// Assume it was already checked that the operation is bitwise AND.
+
Operand src0 = asgOp.GetSource(0);
Operand src1 = asgOp.GetSource(1);
@@ -210,6 +265,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
// We can't check if the mask matches here as both operands are from a constant buffer.
// Be optimistic and assume it matches. Avoid constant buffer 1 as official drivers
// uses this one to store compiler constants.
+
return src0.GetCbufSlot() == 1 ? src1 : src0;
}
else if (src0.Type == OperandType.ConstantBuffer && src1.Type == OperandType.Constant)