Do not attempt to normalize SNORM image buffers on shaders (#2317)

* Do not attempt to normalize SNORM image buffers on shaders

* Shader cache version bump
This commit is contained in:
gdkchan 2021-05-31 16:59:23 -03:00 committed by GitHub
parent 91fdaea39b
commit 79b3243f54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 13 deletions

View file

@ -365,7 +365,7 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
_context.Methods.BufferManager.SetBufferTextureStorage(hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, format, true); _context.Methods.BufferManager.SetBufferTextureStorage(hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, format, true);
} }
else if (isStore) else if (isStore)
{ {
texture?.SignalModified(); texture?.SignalModified();

View file

@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary> /// <summary>
/// Version of the codegen (to be changed when codegen or guest format change). /// Version of the codegen (to be changed when codegen or guest format change).
/// </summary> /// </summary>
private const ulong ShaderCodeGenVersion = 2301; private const ulong ShaderCodeGenVersion = 2317;
// Progress reporting helpers // Progress reporting helpers
private volatile int _shaderCount; private volatile int _shaderCount;

View file

@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Shader.Translation
for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next) for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
{ {
if (!(node.Value is Operation operation)) if (node.Value is not Operation operation)
{ {
continue; continue;
} }
@ -33,11 +33,11 @@ namespace Ryujinx.Graphics.Shader.Translation
if (texOp.Inst == Instruction.TextureSample) if (texOp.Inst == Instruction.TextureSample)
{ {
node = RewriteTextureSample(node, config); node = RewriteTextureSample(node, config);
}
if (texOp.Type == SamplerType.TextureBuffer) if (texOp.Type == SamplerType.TextureBuffer)
{ {
node = InsertSnormNormalization(node, config); node = InsertSnormNormalization(node, config);
}
} }
} }
} }
@ -147,14 +147,15 @@ namespace Ryujinx.Graphics.Shader.Translation
bool hasInvalidOffset = (hasOffset || hasOffsets) && !config.GpuAccessor.QuerySupportsNonConstantTextureOffset(); bool hasInvalidOffset = (hasOffset || hasOffsets) && !config.GpuAccessor.QuerySupportsNonConstantTextureOffset();
bool isRect = config.GpuAccessor.QueryIsTextureRectangle(texOp.Handle, texOp.CbufSlot); bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
bool isRect = !isBindless && config.GpuAccessor.QueryIsTextureRectangle(texOp.Handle, texOp.CbufSlot);
if (!(hasInvalidOffset || isRect)) if (!(hasInvalidOffset || isRect))
{ {
return node; return node;
} }
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
bool isGather = (texOp.Flags & TextureFlags.Gather) != 0; bool isGather = (texOp.Flags & TextureFlags.Gather) != 0;
bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0; bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0;
bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0; bool intCoords = (texOp.Flags & TextureFlags.IntCoords) != 0;
@ -442,6 +443,13 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
TextureOperation texOp = (TextureOperation)node.Value; TextureOperation texOp = (TextureOperation)node.Value;
// We can't query the format of a bindless texture,
// because the handle is unknown, it can have any format.
if (texOp.Flags.HasFlag(TextureFlags.Bindless))
{
return node;
}
TextureFormat format = config.GpuAccessor.QueryTextureFormat(texOp.Handle, texOp.CbufSlot); TextureFormat format = config.GpuAccessor.QueryTextureFormat(texOp.Handle, texOp.CbufSlot);
int maxPositive = format switch int maxPositive = format switch
@ -455,13 +463,15 @@ namespace Ryujinx.Graphics.Shader.Translation
_ => 0 _ => 0
}; };
// The value being 0 means that the format is not a SNORM format, so there's nothing to do here. // The value being 0 means that the format is not a SNORM format,
// so there's nothing to do here.
if (maxPositive == 0) if (maxPositive == 0)
{ {
return node; return node;
} }
// Do normalization. We assume SINT formats are being used as replacement for SNORM (that is not supported). // Do normalization. We assume SINT formats are being used
// as replacement for SNORM (which is not supported).
INode[] uses = texOp.Dest.UseOps.ToArray(); INode[] uses = texOp.Dest.UseOps.ToArray();
Operation convOp = new Operation(Instruction.ConvertS32ToFP, Local(), texOp.Dest); Operation convOp = new Operation(Instruction.ConvertS32ToFP, Local(), texOp.Dest);
@ -472,7 +482,7 @@ namespace Ryujinx.Graphics.Shader.Translation
foreach (INode useOp in uses) foreach (INode useOp in uses)
{ {
if (!(useOp is Operation op)) if (useOp is not Operation op)
{ {
continue; continue;
} }