Bindless elimination for constant sampler handle (#3424)

* Bindless elimination for constant sampler handle

* Shader cache version bump

* Update TextureHandle.ReadPackedId for new bindless elimination
This commit is contained in:
gdkchan 2022-07-02 15:03:35 -03:00 committed by GitHub
parent 0c66d71fe8
commit 5afd521c5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 25 deletions

View file

@ -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. // turn that into a regular texture access and produce those special handles with values on the higher 16 bits.
if (handleType != TextureHandleType.CombinedSampler) if (handleType != TextureHandleType.CombinedSampler)
{ {
ulong samplerBufferAddress = _isCompute int samplerHandle;
? _channel.BufferManager.GetComputeUniformBufferAddress(samplerBufferIndex)
: _channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, samplerBufferIndex);
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);
if (handleType == TextureHandleType.SeparateSamplerId) samplerHandle = _channel.MemoryManager.Physical.Read<int>(samplerBufferAddress + (uint)samplerWordOffset * 4);
}
else
{
samplerHandle = samplerWordOffset;
}
if (handleType == TextureHandleType.SeparateSamplerId ||
handleType == TextureHandleType.SeparateConstantSamplerHandle)
{ {
samplerHandle <<= 20; samplerHandle <<= 20;
} }

View file

@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 1; private const ushort FileFormatVersionMinor = 1;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; 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 SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View file

@ -237,7 +237,7 @@ namespace Ryujinx.Graphics.Shader
/// <returns>True if the coordinates are normalized, false otherwise</returns> /// <returns>True if the coordinates are normalized, false otherwise</returns>
bool QueryTextureCoordNormalized(int handle, int cbufSlot = -1) bool QueryTextureCoordNormalized(int handle, int cbufSlot = -1)
{ {
return false; return true;
} }
/// <summary> /// <summary>

View file

@ -7,7 +7,8 @@ namespace Ryujinx.Graphics.Shader
{ {
CombinedSampler = 0, // Must be 0. CombinedSampler = 0, // Must be 0.
SeparateSamplerHandle = 1, SeparateSamplerHandle = 1,
SeparateSamplerId = 2 SeparateSamplerId = 2,
SeparateConstantSamplerHandle = 3
} }
public static class TextureHandle 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. // turn that into a regular texture access and produce those special handles with values on the higher 16 bits.
if (handleType != TextureHandleType.CombinedSampler) 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; samplerHandle <<= 20;
} }

View file

@ -51,16 +51,32 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
Operand src0 = Utils.FindLastOperation(handleCombineOp.GetSource(0), block); Operand src0 = Utils.FindLastOperation(handleCombineOp.GetSource(0), block);
Operand src1 = Utils.FindLastOperation(handleCombineOp.GetSource(1), 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; TextureHandleType handleType = TextureHandleType.SeparateSamplerHandle;
// Try to match masked pattern: // Try to match the following patterns:
// - samplerHandle = samplerHandle & 0xFFF00000; // Masked pattern:
// - textureHandle = textureHandle & 0xFFFFF; // - samplerHandle = samplerHandle & 0xFFF00000;
// - combinedHandle = samplerHandle | textureHandle; // - textureHandle = textureHandle & 0xFFFFF;
// where samplerHandle and textureHandle comes from a constant buffer, and shifted pattern: // - combinedHandle = samplerHandle | textureHandle;
// - samplerHandle = samplerId << 20; // Where samplerHandle and textureHandle comes from a constant buffer.
// - combinedHandle = samplerHandle | textureHandle; // Shifted pattern:
// where samplerId and textureHandle comes from a constant buffer. // - 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 (src0.AsgOp is Operation src0AsgOp)
{ {
if (src1.AsgOp is Operation src1AsgOp && if (src1.AsgOp is Operation src1AsgOp &&
@ -104,18 +120,34 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
handleType = TextureHandleType.SeparateSamplerId; 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; continue;
} }
SetHandle( if (handleType == TextureHandleType.SeparateConstantSamplerHandle)
config, {
texOp, SetHandle(
TextureHandle.PackOffsets(src0.GetCbufOffset(), src1.GetCbufOffset(), handleType), config,
TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()), texOp,
rewriteSamplerType); 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 || else if (texOp.Inst == Instruction.ImageLoad ||
texOp.Inst == Instruction.ImageStore || texOp.Inst == Instruction.ImageStore ||