aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-07-02 15:03:35 -0300
committerGitHub <noreply@github.com>2022-07-02 15:03:35 -0300
commit5afd521c5a75da956448df76e415528316ee8a8d (patch)
tree17b069087f83301289f1b0de2d7087690f39d5cd
parent0c66d71fe8e1f096a940571b644eca9b5896931d (diff)
Bindless elimination for constant sampler handle (#3424)1.1.161
* Bindless elimination for constant sampler handle * Shader cache version bump * Update TextureHandle.ReadPackedId for new bindless elimination
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs20
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs2
-rw-r--r--Ryujinx.Graphics.Shader/IGpuAccessor.cs2
-rw-r--r--Ryujinx.Graphics.Shader/TextureHandle.cs17
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs62
5 files changed, 78 insertions, 25 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
index 18f5a74a..fcd23441 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
@@ -792,13 +792,23 @@ namespace Ryujinx.Graphics.Gpu.Image
// turn that into a regular texture access and produce those special handles with values on the higher 16 bits.
if (handleType != TextureHandleType.CombinedSampler)
{
- ulong samplerBufferAddress = _isCompute
- ? _channel.BufferManager.GetComputeUniformBufferAddress(samplerBufferIndex)
- : _channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, samplerBufferIndex);
+ int samplerHandle;
- int samplerHandle = _channel.MemoryManager.Physical.Read<int>(samplerBufferAddress + (uint)samplerWordOffset * 4);
+ if (handleType != TextureHandleType.SeparateConstantSamplerHandle)
+ {
+ ulong samplerBufferAddress = _isCompute
+ ? _channel.BufferManager.GetComputeUniformBufferAddress(samplerBufferIndex)
+ : _channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, samplerBufferIndex);
+
+ samplerHandle = _channel.MemoryManager.Physical.Read<int>(samplerBufferAddress + (uint)samplerWordOffset * 4);
+ }
+ else
+ {
+ samplerHandle = samplerWordOffset;
+ }
- if (handleType == TextureHandleType.SeparateSamplerId)
+ if (handleType == TextureHandleType.SeparateSamplerId ||
+ handleType == TextureHandleType.SeparateConstantSamplerHandle)
{
samplerHandle <<= 20;
}
diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index 5d99957f..59801001 100644
--- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 1;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 1;
+ private const uint CodeGenVersion = 3424;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
diff --git a/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/Ryujinx.Graphics.Shader/IGpuAccessor.cs
index 180fc187..42f210a5 100644
--- a/Ryujinx.Graphics.Shader/IGpuAccessor.cs
+++ b/Ryujinx.Graphics.Shader/IGpuAccessor.cs
@@ -237,7 +237,7 @@ namespace Ryujinx.Graphics.Shader
/// <returns>True if the coordinates are normalized, false otherwise</returns>
bool QueryTextureCoordNormalized(int handle, int cbufSlot = -1)
{
- return false;
+ return true;
}
/// <summary>
diff --git a/Ryujinx.Graphics.Shader/TextureHandle.cs b/Ryujinx.Graphics.Shader/TextureHandle.cs
index d468188b..a2842bb8 100644
--- a/Ryujinx.Graphics.Shader/TextureHandle.cs
+++ b/Ryujinx.Graphics.Shader/TextureHandle.cs
@@ -7,7 +7,8 @@ namespace Ryujinx.Graphics.Shader
{
CombinedSampler = 0, // Must be 0.
SeparateSamplerHandle = 1,
- SeparateSamplerId = 2
+ SeparateSamplerId = 2,
+ SeparateConstantSamplerHandle = 3
}
public static class TextureHandle
@@ -97,9 +98,19 @@ namespace Ryujinx.Graphics.Shader
// turn that into a regular texture access and produce those special handles with values on the higher 16 bits.
if (handleType != TextureHandleType.CombinedSampler)
{
- int samplerHandle = cachedSamplerBuffer[samplerWordOffset];
+ int samplerHandle;
- if (handleType == TextureHandleType.SeparateSamplerId)
+ if (handleType != TextureHandleType.SeparateConstantSamplerHandle)
+ {
+ samplerHandle = cachedSamplerBuffer[samplerWordOffset];
+ }
+ else
+ {
+ samplerHandle = samplerWordOffset;
+ }
+
+ if (handleType == TextureHandleType.SeparateSamplerId ||
+ handleType == TextureHandleType.SeparateConstantSamplerHandle)
{
samplerHandle <<= 20;
}
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index 1b303caf..73d89761 100644
--- a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -51,16 +51,32 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
Operand src0 = Utils.FindLastOperation(handleCombineOp.GetSource(0), block);
Operand src1 = Utils.FindLastOperation(handleCombineOp.GetSource(1), block);
+ // For cases where we have a constant, ensure that the constant is always
+ // the second operand.
+ // Since this is a commutative operation, both are fine,
+ // and having a "canonical" representation simplifies some checks below.
+ if (src0.Type == OperandType.Constant && src1.Type != OperandType.Constant)
+ {
+ Operand temp = src1;
+ src1 = src0;
+ src0 = temp;
+ }
+
TextureHandleType handleType = TextureHandleType.SeparateSamplerHandle;
- // Try to match masked pattern:
- // - samplerHandle = samplerHandle & 0xFFF00000;
- // - textureHandle = textureHandle & 0xFFFFF;
- // - combinedHandle = samplerHandle | textureHandle;
- // where samplerHandle and textureHandle comes from a constant buffer, and shifted pattern:
- // - samplerHandle = samplerId << 20;
- // - combinedHandle = samplerHandle | textureHandle;
- // where samplerId and textureHandle comes from a constant buffer.
+ // Try to match the following patterns:
+ // Masked pattern:
+ // - samplerHandle = samplerHandle & 0xFFF00000;
+ // - textureHandle = textureHandle & 0xFFFFF;
+ // - combinedHandle = samplerHandle | textureHandle;
+ // Where samplerHandle and textureHandle comes from a constant buffer.
+ // Shifted pattern:
+ // - samplerHandle = samplerId << 20;
+ // - combinedHandle = samplerHandle | textureHandle;
+ // Where samplerId and textureHandle comes from a constant buffer.
+ // Constant pattern:
+ // - combinedHandle = samplerHandleConstant | textureHandle;
+ // Where samplerHandleConstant is a constant value, and textureHandle comes from a constant buffer.
if (src0.AsgOp is Operation src0AsgOp)
{
if (src1.AsgOp is Operation src1AsgOp &&
@@ -104,18 +120,34 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
handleType = TextureHandleType.SeparateSamplerId;
}
}
+ else if (src1.Type == OperandType.Constant && (src1.Value & 0xfffff) == 0)
+ {
+ handleType = TextureHandleType.SeparateConstantSamplerHandle;
+ }
- if (src0.Type != OperandType.ConstantBuffer || src1.Type != OperandType.ConstantBuffer)
+ if (src0.Type != OperandType.ConstantBuffer)
{
continue;
}
- SetHandle(
- config,
- texOp,
- TextureHandle.PackOffsets(src0.GetCbufOffset(), src1.GetCbufOffset(), handleType),
- TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()),
- rewriteSamplerType);
+ if (handleType == TextureHandleType.SeparateConstantSamplerHandle)
+ {
+ SetHandle(
+ config,
+ texOp,
+ TextureHandle.PackOffsets(src0.GetCbufOffset(), ((src1.Value >> 20) & 0xfff), handleType),
+ TextureHandle.PackSlots(src0.GetCbufSlot(), 0),
+ rewriteSamplerType);
+ }
+ else if (src1.Type == OperandType.ConstantBuffer)
+ {
+ SetHandle(
+ config,
+ texOp,
+ TextureHandle.PackOffsets(src0.GetCbufOffset(), src1.GetCbufOffset(), handleType),
+ TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()),
+ rewriteSamplerType);
+ }
}
else if (texOp.Inst == Instruction.ImageLoad ||
texOp.Inst == Instruction.ImageStore ||