aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs2
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs55
2 files changed, 46 insertions, 11 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index 990c6ba3..fbf48f01 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 = 6870;
+ private const uint CodeGenVersion = 6852;
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 29501b71..02a83fbe 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -38,6 +38,12 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
// If we can't do bindless elimination, remove the texture operation.
// Set any destination variables to zero.
+ string typeName = texOp.Inst.IsImage()
+ ? texOp.Type.ToGlslImageType(texOp.Format.GetComponentType())
+ : texOp.Type.ToGlslTextureType();
+
+ gpuAccessor.Log($"Failed to find handle source for bindless access of type \"{typeName}\".");
+
for (int destIndex = 0; destIndex < texOp.DestsCount; destIndex++)
{
block.Operations.AddBefore(node, new Operation(Instruction.Copy, texOp.GetDest(destIndex), OperandHelper.Const(0)));
@@ -62,17 +68,22 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
return false;
}
- Operand nvHandle = texOp.GetSource(0);
+ Operand bindlessHandle = texOp.GetSource(0);
- if (nvHandle.AsgOp is not Operation handleOp ||
- handleOp.Inst != Instruction.Load ||
- (handleOp.StorageKind != StorageKind.Input && handleOp.StorageKind != StorageKind.StorageBuffer))
+ if (bindlessHandle.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(bindlessHandle))
+ {
return false;
}
@@ -80,8 +91,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
Operand samplerHandle = OperandHelper.Local();
Operand textureIndex = OperandHelper.Local();
- block.Operations.AddBefore(node, new Operation(Instruction.BitwiseAnd, textureHandle, nvHandle, OperandHelper.Const(0xfffff)));
- block.Operations.AddBefore(node, new Operation(Instruction.ShiftRightU32, samplerHandle, nvHandle, OperandHelper.Const(20)));
+ block.Operations.AddBefore(node, new Operation(Instruction.BitwiseAnd, textureHandle, bindlessHandle, OperandHelper.Const(0xfffff)));
+ block.Operations.AddBefore(node, new Operation(Instruction.ShiftRightU32, samplerHandle, bindlessHandle, OperandHelper.Const(20)));
int texturePoolLength = Math.Max(BindlessToArray.MinimumArrayLength, gpuAccessor.QueryTextureArrayLengthFromPool());
@@ -130,6 +141,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())