aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation')
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs45
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs2
-rw-r--r--Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs21
3 files changed, 52 insertions, 16 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index 9515c349..a26c81c9 100644
--- a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -5,7 +5,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
class BindlessElimination
{
- public static void RunPass(BasicBlock block)
+ private const int NvnTextureBufferSlot = 2;
+
+ public static void RunPass(BasicBlock block, ShaderConfig config)
{
// We can turn a bindless into regular access by recognizing the pattern
// produced by the compiler for separate texture and sampler.
@@ -24,26 +26,39 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
continue;
}
- if (!(texOp.GetSource(0).AsgOp is Operation handleCombineOp))
+ if (texOp.Inst == Instruction.TextureSample)
{
- continue;
- }
+ if (!(texOp.GetSource(0).AsgOp is Operation handleCombineOp))
+ {
+ continue;
+ }
- if (handleCombineOp.Inst != Instruction.BitwiseOr)
- {
- continue;
- }
+ if (handleCombineOp.Inst != Instruction.BitwiseOr)
+ {
+ continue;
+ }
- Operand src0 = handleCombineOp.GetSource(0);
- Operand src1 = handleCombineOp.GetSource(1);
+ Operand src0 = handleCombineOp.GetSource(0);
+ Operand src1 = handleCombineOp.GetSource(1);
- if (src0.Type != OperandType.ConstantBuffer || src0.GetCbufSlot() != 2 ||
- src1.Type != OperandType.ConstantBuffer || src1.GetCbufSlot() != 2)
- {
- continue;
+ if (src0.Type != OperandType.ConstantBuffer || src0.GetCbufSlot() != NvnTextureBufferSlot ||
+ src1.Type != OperandType.ConstantBuffer || src1.GetCbufSlot() != NvnTextureBufferSlot)
+ {
+ continue;
+ }
+
+ texOp.SetHandle(src0.GetCbufOffset() | (src1.GetCbufOffset() << 16));
}
+ else if (texOp.Inst == Instruction.ImageLoad || texOp.Inst == Instruction.ImageStore)
+ {
+ Operand src0 = texOp.GetSource(0);
- texOp.SetHandle(src0.GetCbufOffset() | (src1.GetCbufOffset() << 16));
+ if (src0.Type == OperandType.ConstantBuffer && src0.GetCbufSlot() == NvnTextureBufferSlot)
+ {
+ texOp.SetHandle(src0.GetCbufOffset());
+ texOp.Format = config.GetTextureFormat(texOp.Handle);
+ }
+ }
}
}
}
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
index 10a0e780..286574cf 100644
--- a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
@@ -89,7 +89,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
{
BindlessToIndexed.RunPass(blocks[blkIndex]);
- BindlessElimination.RunPass(blocks[blkIndex]);
+ BindlessElimination.RunPass(blocks[blkIndex], config);
// Try to eliminate any operations that are now unused.
LinkedListNode<INode> node = blocks[blkIndex].Operations.First;
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
index 9e8329de..8b38afb9 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
@@ -68,5 +68,26 @@ namespace Ryujinx.Graphics.Shader.Translation
// The depth register is always two registers after the last color output.
return count + 1;
}
+
+ public TextureFormat GetTextureFormat(int handle)
+ {
+ // When the formatted load extension is supported, we don't need to
+ // specify a format, we can just declare it without a format and the GPU will handle it.
+ if (GpuAccessor.QuerySupportsImageLoadFormatted())
+ {
+ return TextureFormat.Unknown;
+ }
+
+ var format = GpuAccessor.QueryTextureFormat(handle);
+
+ if (format == TextureFormat.Unknown)
+ {
+ GpuAccessor.Log($"Unknown format for texture {handle}.");
+
+ format = TextureFormat.R8G8B8A8Unorm;
+ }
+
+ return format;
+ }
}
} \ No newline at end of file