forked from Mirror/Ryujinx
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:
parent
0c66d71fe8
commit
5afd521c5a
5 changed files with 78 additions and 25 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue