diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-11-19 15:10:44 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-19 15:10:44 -0300 |
commit | 0b58f462668694db1a035e8be40d2a6d366635e1 (patch) | |
tree | 15e19f00ec58321d982eb48da337d49230fbf82d | |
parent | aa96dcb1bede3693877e2f1eca3e169d8ee13ef1 (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
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs | 2 | ||||
-rw-r--r-- | src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs | 58 |
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 0dc4b1a72..403e039a4 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 | |||
22 | private const ushort FileFormatVersionMajor = 1; | 22 | private const ushort FileFormatVersionMajor = 1; |
23 | private const ushort FileFormatVersionMinor = 2; | 23 | private const ushort FileFormatVersionMinor = 2; |
24 | private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; | 24 | private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; |
25 | private const uint CodeGenVersion = 5791; | 25 | private const uint CodeGenVersion = 5957; |
26 | 26 | ||
27 | private const string SharedTocFileName = "shared.toc"; | 27 | private const string SharedTocFileName = "shared.toc"; |
28 | private const string SharedDataFileName = "shared.data"; | 28 | 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 19b7999a7..c955f5b5f 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 | |||
55 | continue; | 55 | continue; |
56 | } | 56 | } |
57 | 57 | ||
58 | if (bindlessHandle.AsgOp is not Operation handleCombineOp) | 58 | if (!TryGetOperation(bindlessHandle.AsgOp, out Operation handleCombineOp)) |
59 | { | 59 | { |
60 | continue; | 60 | continue; |
61 | } | 61 | } |
@@ -199,9 +199,64 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations | |||
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | private static bool TryGetOperation(INode asgOp, out Operation outOperation) | ||
203 | { | ||
204 | if (asgOp is PhiNode phi) | ||
205 | { | ||
206 | // If we have a phi, let's check if all inputs are effectively the same value. | ||
207 | // If so, we can "see through" the phi and pick any of the inputs (since they are all the same). | ||
208 | |||
209 | Operand firstSrc = phi.GetSource(0); | ||
210 | |||
211 | for (int index = 1; index < phi.SourcesCount; index++) | ||
212 | { | ||
213 | if (!IsSameOperand(firstSrc, phi.GetSource(index))) | ||
214 | { | ||
215 | outOperation = null; | ||
216 | |||
217 | return false; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | asgOp = firstSrc.AsgOp; | ||
222 | } | ||
223 | |||
224 | if (asgOp is Operation operation) | ||
225 | { | ||
226 | outOperation = operation; | ||
227 | |||
228 | return true; | ||
229 | } | ||
230 | |||
231 | outOperation = null; | ||
232 | |||
233 | return false; | ||
234 | } | ||
235 | |||
236 | private static bool IsSameOperand(Operand x, Operand y) | ||
237 | { | ||
238 | if (x.Type == y.Type && x.Type == OperandType.LocalVariable) | ||
239 | { | ||
240 | return x.AsgOp is Operation xOp && | ||
241 | y.AsgOp is Operation yOp && | ||
242 | xOp.Inst == Instruction.BitwiseOr && | ||
243 | yOp.Inst == Instruction.BitwiseOr && | ||
244 | AreBothEqualConstantBuffers(xOp.GetSource(0), yOp.GetSource(0)) && | ||
245 | AreBothEqualConstantBuffers(xOp.GetSource(1), yOp.GetSource(1)); | ||
246 | } | ||
247 | |||
248 | return false; | ||
249 | } | ||
250 | |||
251 | private static bool AreBothEqualConstantBuffers(Operand x, Operand y) | ||
252 | { | ||
253 | return x.Type == y.Type && x.Value == y.Value && x.Type == OperandType.ConstantBuffer; | ||
254 | } | ||
255 | |||
202 | private static Operand GetSourceForMaskedHandle(Operation asgOp, uint mask) | 256 | private static Operand GetSourceForMaskedHandle(Operation asgOp, uint mask) |
203 | { | 257 | { |
204 | // Assume it was already checked that the operation is bitwise AND. | 258 | // Assume it was already checked that the operation is bitwise AND. |
259 | |||
205 | Operand src0 = asgOp.GetSource(0); | 260 | Operand src0 = asgOp.GetSource(0); |
206 | Operand src1 = asgOp.GetSource(1); | 261 | Operand src1 = asgOp.GetSource(1); |
207 | 262 | ||
@@ -210,6 +265,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations | |||
210 | // We can't check if the mask matches here as both operands are from a constant buffer. | 265 | // We can't check if the mask matches here as both operands are from a constant buffer. |
211 | // Be optimistic and assume it matches. Avoid constant buffer 1 as official drivers | 266 | // Be optimistic and assume it matches. Avoid constant buffer 1 as official drivers |
212 | // uses this one to store compiler constants. | 267 | // uses this one to store compiler constants. |
268 | |||
213 | return src0.GetCbufSlot() == 1 ? src1 : src0; | 269 | return src0.GetCbufSlot() == 1 ? src1 : src0; |
214 | } | 270 | } |
215 | else if (src0.Type == OperandType.ConstantBuffer && src1.Type == OperandType.Constant) | 271 | else if (src0.Type == OperandType.ConstantBuffer && src1.Type == OperandType.Constant) |