0
0
Fork 0

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

@ -791,14 +791,24 @@ namespace Ryujinx.Graphics.Gpu.Image
// The shader translator has code to detect separate texture and sampler uses with a bindless texture, // The shader translator has code to detect separate texture and sampler uses with a bindless texture,
// 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;
if (handleType != TextureHandleType.SeparateConstantSamplerHandle)
{ {
ulong samplerBufferAddress = _isCompute ulong samplerBufferAddress = _isCompute
? _channel.BufferManager.GetComputeUniformBufferAddress(samplerBufferIndex) ? _channel.BufferManager.GetComputeUniformBufferAddress(samplerBufferIndex)
: _channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, samplerBufferIndex); : _channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, samplerBufferIndex);
int samplerHandle = _channel.MemoryManager.Physical.Read<int>(samplerBufferAddress + (uint)samplerWordOffset * 4); 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; 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:
// Masked pattern:
// - samplerHandle = samplerHandle & 0xFFF00000; // - samplerHandle = samplerHandle & 0xFFF00000;
// - textureHandle = textureHandle & 0xFFFFF; // - textureHandle = textureHandle & 0xFFFFF;
// - combinedHandle = samplerHandle | textureHandle; // - combinedHandle = samplerHandle | textureHandle;
// where samplerHandle and textureHandle comes from a constant buffer, and shifted pattern: // Where samplerHandle and textureHandle comes from a constant buffer.
// Shifted pattern:
// - samplerHandle = samplerId << 20; // - samplerHandle = samplerId << 20;
// - combinedHandle = samplerHandle | textureHandle; // - combinedHandle = samplerHandle | textureHandle;
// where samplerId and textureHandle comes from a constant buffer. // 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,12 +120,27 @@ 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;
} }
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( SetHandle(
config, config,
texOp, texOp,
@ -117,6 +148,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()), TextureHandle.PackSlots(src0.GetCbufSlot(), src1.GetCbufSlot()),
rewriteSamplerType); rewriteSamplerType);
} }
}
else if (texOp.Inst == Instruction.ImageLoad || else if (texOp.Inst == Instruction.ImageLoad ||
texOp.Inst == Instruction.ImageStore || texOp.Inst == Instruction.ImageStore ||
texOp.Inst == Instruction.ImageAtomic) texOp.Inst == Instruction.ImageAtomic)