forked from Mirror/Ryujinx
Pass CbufSlot when getting info from the texture descriptor (#2291)
* Pass CbufSlot when getting info from the texture descriptor Fixes some issues with bindless textures, when CbufSlot is not equal to the current TextureBufferIndex. Specifically fixes a random chance of full screen colour flickering in Super Mario Party. * Apply suggestions from code review Oops Co-authored-by: gdkchan <gab.dark.100@gmail.com> Co-authored-by: gdkchan <gab.dark.100@gmail.com>
This commit is contained in:
parent
c805542b29
commit
0129250c2e
10 changed files with 35 additions and 27 deletions
|
@ -398,10 +398,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// <param name="state">The current GPU state</param>
|
/// <param name="state">The current GPU state</param>
|
||||||
/// <param name="stageIndex">The stage number where the texture is bound</param>
|
/// <param name="stageIndex">The stage number where the texture is bound</param>
|
||||||
/// <param name="handle">The texture handle</param>
|
/// <param name="handle">The texture handle</param>
|
||||||
|
/// <param name="cbufSlot">The texture handle's constant buffer slot</param>
|
||||||
/// <returns>The texture descriptor for the specified texture</returns>
|
/// <returns>The texture descriptor for the specified texture</returns>
|
||||||
public TextureDescriptor GetTextureDescriptor(GpuState state, int stageIndex, int handle)
|
public TextureDescriptor GetTextureDescriptor(GpuState state, int stageIndex, int handle, int cbufSlot)
|
||||||
{
|
{
|
||||||
int packedId = ReadPackedId(stageIndex, handle, state.Get<int>(MethodOffset.TextureBufferIndex));
|
int packedId = ReadPackedId(stageIndex, handle, cbufSlot < 0 ? state.Get<int>(MethodOffset.TextureBufferIndex) : cbufSlot);
|
||||||
int textureId = UnpackTextureId(packedId);
|
int textureId = UnpackTextureId(packedId);
|
||||||
|
|
||||||
var poolState = state.Get<PoolState>(MethodOffset.TexturePoolState);
|
var poolState = state.Get<PoolState>(MethodOffset.TexturePoolState);
|
||||||
|
|
|
@ -340,10 +340,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="state">Current GPU state</param>
|
/// <param name="state">Current GPU state</param>
|
||||||
/// <param name="handle">Shader "fake" handle of the texture</param>
|
/// <param name="handle">Shader "fake" handle of the texture</param>
|
||||||
|
/// <param name="cbufSlot">Shader constant buffer slot of the texture</param>
|
||||||
/// <returns>The texture descriptor</returns>
|
/// <returns>The texture descriptor</returns>
|
||||||
public TextureDescriptor GetComputeTextureDescriptor(GpuState state, int handle)
|
public TextureDescriptor GetComputeTextureDescriptor(GpuState state, int handle, int cbufSlot)
|
||||||
{
|
{
|
||||||
return _cpBindingsManager.GetTextureDescriptor(state, 0, handle);
|
return _cpBindingsManager.GetTextureDescriptor(state, 0, handle, cbufSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -352,10 +353,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// <param name="state">Current GPU state</param>
|
/// <param name="state">Current GPU state</param>
|
||||||
/// <param name="stageIndex">Index of the shader stage where the texture is bound</param>
|
/// <param name="stageIndex">Index of the shader stage where the texture is bound</param>
|
||||||
/// <param name="handle">Shader "fake" handle of the texture</param>
|
/// <param name="handle">Shader "fake" handle of the texture</param>
|
||||||
|
/// <param name="cbufSlot">Shader constant buffer slot of the texture</param>
|
||||||
/// <returns>The texture descriptor</returns>
|
/// <returns>The texture descriptor</returns>
|
||||||
public TextureDescriptor GetGraphicsTextureDescriptor(GpuState state, int stageIndex, int handle)
|
public TextureDescriptor GetGraphicsTextureDescriptor(GpuState state, int stageIndex, int handle, int cbufSlot)
|
||||||
{
|
{
|
||||||
return _gpBindingsManager.GetTextureDescriptor(state, stageIndex, handle);
|
return _gpBindingsManager.GetTextureDescriptor(state, stageIndex, handle, cbufSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -417,7 +417,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache
|
||||||
{
|
{
|
||||||
foreach (int textureHandle in context.TextureHandlesForCache)
|
foreach (int textureHandle in context.TextureHandlesForCache)
|
||||||
{
|
{
|
||||||
GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle)).ToCache();
|
GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle, -1)).ToCache();
|
||||||
|
|
||||||
textureDescriptor.Handle = (uint)textureHandle;
|
textureDescriptor.Handle = (uint)textureHandle;
|
||||||
|
|
||||||
|
|
|
@ -140,8 +140,9 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// Gets the texture descriptor for a given texture on the pool.
|
/// Gets the texture descriptor for a given texture on the pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
|
/// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
|
||||||
|
/// <param name="cbufSlot">Constant buffer slot for the texture handle</param>
|
||||||
/// <returns>Texture descriptor</returns>
|
/// <returns>Texture descriptor</returns>
|
||||||
public override Image.ITextureDescriptor GetTextureDescriptor(int handle)
|
public override Image.ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot)
|
||||||
{
|
{
|
||||||
if (!_textureDescriptors.TryGetValue(handle, out GuestTextureDescriptor textureDescriptor))
|
if (!_textureDescriptors.TryGetValue(handle, out GuestTextureDescriptor textureDescriptor))
|
||||||
{
|
{
|
||||||
|
|
|
@ -184,16 +184,17 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// Gets the texture descriptor for a given texture on the pool.
|
/// Gets the texture descriptor for a given texture on the pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
|
/// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
|
||||||
|
/// <param name="cbufSlot">Constant buffer slot for the texture handle</param>
|
||||||
/// <returns>Texture descriptor</returns>
|
/// <returns>Texture descriptor</returns>
|
||||||
public override Image.ITextureDescriptor GetTextureDescriptor(int handle)
|
public override Image.ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot)
|
||||||
{
|
{
|
||||||
if (_compute)
|
if (_compute)
|
||||||
{
|
{
|
||||||
return _context.Methods.TextureManager.GetComputeTextureDescriptor(_state, handle);
|
return _context.Methods.TextureManager.GetComputeTextureDescriptor(_state, handle, cbufSlot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(_state, _stageIndex, handle);
|
return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(_state, _stageIndex, handle, cbufSlot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
public abstract T MemoryRead<T>(ulong address) where T : unmanaged;
|
public abstract T MemoryRead<T>(ulong address) where T : unmanaged;
|
||||||
|
|
||||||
public abstract ITextureDescriptor GetTextureDescriptor(int handle);
|
public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries texture format information, for shaders using image load or store.
|
/// Queries texture format information, for shaders using image load or store.
|
||||||
|
@ -18,10 +18,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// If the format of the texture is a compressed, depth or unsupported format, then a default value is returned.
|
/// If the format of the texture is a compressed, depth or unsupported format, then a default value is returned.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="handle">Texture handle</param>
|
/// <param name="handle">Texture handle</param>
|
||||||
|
/// <param name="cbufSlot">Constant buffer slot for the texture handle</param>
|
||||||
/// <returns>Color format of the non-compressed texture</returns>
|
/// <returns>Color format of the non-compressed texture</returns>
|
||||||
public TextureFormat QueryTextureFormat(int handle)
|
public TextureFormat QueryTextureFormat(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
var descriptor = GetTextureDescriptor(handle);
|
var descriptor = GetTextureDescriptor(handle, cbufSlot);
|
||||||
|
|
||||||
if (!FormatTable.TryGetTextureFormat(descriptor.UnpackFormat(), descriptor.UnpackSrgb(), out FormatInfo formatInfo))
|
if (!FormatTable.TryGetTextureFormat(descriptor.UnpackFormat(), descriptor.UnpackSrgb(), out FormatInfo formatInfo))
|
||||||
{
|
{
|
||||||
|
@ -78,20 +79,22 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// Queries texture target information.
|
/// Queries texture target information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">Texture handle</param>
|
/// <param name="handle">Texture handle</param>
|
||||||
|
/// <param name="cbufSlot">Constant buffer slot for the texture handle</param>
|
||||||
/// <returns>True if the texture is a buffer texture, false otherwise</returns>
|
/// <returns>True if the texture is a buffer texture, false otherwise</returns>
|
||||||
public bool QueryIsTextureBuffer(int handle)
|
public bool QueryIsTextureBuffer(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
return GetTextureDescriptor(handle).UnpackTextureTarget() == TextureTarget.TextureBuffer;
|
return GetTextureDescriptor(handle, cbufSlot).UnpackTextureTarget() == TextureTarget.TextureBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries texture target information.
|
/// Queries texture target information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">Texture handle</param>
|
/// <param name="handle">Texture handle</param>
|
||||||
|
/// <param name="cbufSlot">Constant buffer slot for the texture handle</param>
|
||||||
/// <returns>True if the texture is a rectangle texture, false otherwise</returns>
|
/// <returns>True if the texture is a rectangle texture, false otherwise</returns>
|
||||||
public bool QueryIsTextureRectangle(int handle)
|
public bool QueryIsTextureRectangle(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
var descriptor = GetTextureDescriptor(handle);
|
var descriptor = GetTextureDescriptor(handle, cbufSlot);
|
||||||
|
|
||||||
TextureTarget target = descriptor.UnpackTextureTarget();
|
TextureTarget target = descriptor.UnpackTextureTarget();
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,12 @@
|
||||||
return 0xffff;
|
return 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QueryIsTextureBuffer(int handle)
|
bool QueryIsTextureBuffer(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QueryIsTextureRectangle(int handle)
|
bool QueryIsTextureRectangle(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureFormat QueryTextureFormat(int handle)
|
TextureFormat QueryTextureFormat(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
return TextureFormat.R8G8B8A8Unorm;
|
return TextureFormat.R8G8B8A8Unorm;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
if (src0.Type == OperandType.ConstantBuffer)
|
if (src0.Type == OperandType.ConstantBuffer)
|
||||||
{
|
{
|
||||||
texOp.SetHandle(src0.GetCbufOffset(), src0.GetCbufSlot());
|
texOp.SetHandle(src0.GetCbufOffset(), src0.GetCbufSlot());
|
||||||
texOp.Format = config.GetTextureFormat(texOp.Handle);
|
texOp.Format = config.GetTextureFormat(texOp.Handle, texOp.CbufSlot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ 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);
|
bool isRect = config.GpuAccessor.QueryIsTextureRectangle(texOp.Handle, texOp.CbufSlot);
|
||||||
|
|
||||||
if (!(hasInvalidOffset || isRect))
|
if (!(hasInvalidOffset || isRect))
|
||||||
{
|
{
|
||||||
|
@ -433,7 +433,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
TextureOperation texOp = (TextureOperation)node.Value;
|
TextureOperation texOp = (TextureOperation)node.Value;
|
||||||
|
|
||||||
TextureFormat format = config.GpuAccessor.QueryTextureFormat(texOp.Handle);
|
TextureFormat format = config.GpuAccessor.QueryTextureFormat(texOp.Handle, texOp.CbufSlot);
|
||||||
|
|
||||||
int maxPositive = format switch
|
int maxPositive = format switch
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return count + 1;
|
return count + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureFormat GetTextureFormat(int handle)
|
public TextureFormat GetTextureFormat(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
// When the formatted load extension is supported, we don't need to
|
// When the formatted load extension is supported, we don't need to
|
||||||
// specify a format, we can just declare it without a format and the GPU will handle it.
|
// specify a format, we can just declare it without a format and the GPU will handle it.
|
||||||
|
@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return TextureFormat.Unknown;
|
return TextureFormat.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
var format = GpuAccessor.QueryTextureFormat(handle);
|
var format = GpuAccessor.QueryTextureFormat(handle, cbufSlot);
|
||||||
|
|
||||||
if (format == TextureFormat.Unknown)
|
if (format == TextureFormat.Unknown)
|
||||||
{
|
{
|
||||||
|
|
Reference in a new issue