From 3e9800cb8161c39d5c37cf0822f94746a4569f0d Mon Sep 17 00:00:00 2001 From: Gabriel A Date: Thu, 23 May 2024 01:53:34 -0300 Subject: [PATCH] Extend full bindless to cover cases with phi nodes --- .../Optimizations/BindlessElimination.cs | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs index 29501b710e..bab7dd03a7 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs @@ -64,15 +64,20 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations Operand nvHandle = texOp.GetSource(0); - if (nvHandle.AsgOp is not Operation handleOp || - handleOp.Inst != Instruction.Load || - (handleOp.StorageKind != StorageKind.Input && handleOp.StorageKind != StorageKind.StorageBuffer)) + if (nvHandle.AsgOp is PhiNode phi) { - // Right now, we only allow bindless access when the handle comes from a shader input or storage buffer. - // This is an artificial limitation to prevent it from being used in cases where it - // would have a large performance impact of loading all textures in the pool. - // It might be removed in the future, if we can mitigate the performance impact. + for (int srcIndex = 0; srcIndex < phi.SourcesCount; srcIndex++) + { + Operand phiSource = phi.GetSource(srcIndex); + if (phiSource.AsgOp is not PhiNode && !IsBindlessAccessAllowed(phiSource)) + { + return false; + } + } + } + else if (!IsBindlessAccessAllowed(nvHandle)) + { return false; } @@ -130,6 +135,30 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations return true; } + private static bool IsBindlessAccessAllowed(Operand nvHandle) + { + if (nvHandle.Type == OperandType.ConstantBuffer) + { + // Bindless access with handles from constant buffer is allowed. + + return true; + } + + if (nvHandle.AsgOp is not Operation handleOp || + handleOp.Inst != Instruction.Load || + (handleOp.StorageKind != StorageKind.Input && handleOp.StorageKind != StorageKind.StorageBuffer)) + { + // Right now, we only allow bindless access when the handle comes from a shader input or storage buffer. + // This is an artificial limitation to prevent it from being used in cases where it + // would have a large performance impact of loading all textures in the pool. + // It might be removed in the future, if we can mitigate the performance impact. + + return false; + } + + return true; + } + private static bool TryConvertBindless(BasicBlock block, ResourceManager resourceManager, IGpuAccessor gpuAccessor, TextureOperation texOp) { if (texOp.Inst == Instruction.TextureSample || texOp.Inst.IsTextureQuery())