Account for res scale changes when updating bindings (#3403)
Fixes a regression introduced by the texture bindings PR. Also renames TextureStatePerStage, as it's no longer per stage.
This commit is contained in:
parent
99ffc061d3
commit
68f9091870
1 changed files with 52 additions and 15 deletions
|
@ -35,7 +35,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
private readonly TextureBindingInfo[][] _textureBindings;
|
private readonly TextureBindingInfo[][] _textureBindings;
|
||||||
private readonly TextureBindingInfo[][] _imageBindings;
|
private readonly TextureBindingInfo[][] _imageBindings;
|
||||||
|
|
||||||
private struct TextureStatePerStage
|
private struct TextureState
|
||||||
{
|
{
|
||||||
public ITexture Texture;
|
public ITexture Texture;
|
||||||
public ISampler Sampler;
|
public ISampler Sampler;
|
||||||
|
@ -45,10 +45,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
public int InvalidatedSequence;
|
public int InvalidatedSequence;
|
||||||
public Texture CachedTexture;
|
public Texture CachedTexture;
|
||||||
public Sampler CachedSampler;
|
public Sampler CachedSampler;
|
||||||
|
public int ScaleIndex;
|
||||||
|
public TextureUsageFlags UsageFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextureStatePerStage[] _textureState;
|
private TextureState[] _textureState;
|
||||||
private TextureStatePerStage[] _imageState;
|
private TextureState[] _imageState;
|
||||||
|
|
||||||
private int[] _textureBindingsCount;
|
private int[] _textureBindingsCount;
|
||||||
private int[] _imageBindingsCount;
|
private int[] _imageBindingsCount;
|
||||||
|
@ -83,8 +85,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
_textureBindings = new TextureBindingInfo[stages][];
|
_textureBindings = new TextureBindingInfo[stages][];
|
||||||
_imageBindings = new TextureBindingInfo[stages][];
|
_imageBindings = new TextureBindingInfo[stages][];
|
||||||
|
|
||||||
_textureState = new TextureStatePerStage[InitialTextureStateSize];
|
_textureState = new TextureState[InitialTextureStateSize];
|
||||||
_imageState = new TextureStatePerStage[InitialImageStateSize];
|
_imageState = new TextureState[InitialImageStateSize];
|
||||||
|
|
||||||
_textureBindingsCount = new int[stages];
|
_textureBindingsCount = new int[stages];
|
||||||
_imageBindingsCount = new int[stages];
|
_imageBindingsCount = new int[stages];
|
||||||
|
@ -230,18 +232,18 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// Updates the texture scale for a given texture or image.
|
/// Updates the texture scale for a given texture or image.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="texture">Start GPU virtual address of the pool</param>
|
/// <param name="texture">Start GPU virtual address of the pool</param>
|
||||||
/// <param name="binding">The related texture binding</param>
|
/// <param name="usageFlags">The related texture usage flags</param>
|
||||||
/// <param name="index">The texture/image binding index</param>
|
/// <param name="index">The texture/image binding index</param>
|
||||||
/// <param name="stage">The active shader stage</param>
|
/// <param name="stage">The active shader stage</param>
|
||||||
/// <returns>True if the given texture has become blacklisted, indicating that its host texture may have changed.</returns>
|
/// <returns>True if the given texture has become blacklisted, indicating that its host texture may have changed.</returns>
|
||||||
private bool UpdateScale(Texture texture, TextureBindingInfo binding, int index, ShaderStage stage)
|
private bool UpdateScale(Texture texture, TextureUsageFlags usageFlags, int index, ShaderStage stage)
|
||||||
{
|
{
|
||||||
float result = 1f;
|
float result = 1f;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
if ((binding.Flags & TextureUsageFlags.NeedsScaleValue) != 0 && texture != null)
|
if ((usageFlags & TextureUsageFlags.NeedsScaleValue) != 0 && texture != null)
|
||||||
{
|
{
|
||||||
if ((binding.Flags & TextureUsageFlags.ResScaleUnsupported) != 0)
|
if ((usageFlags & TextureUsageFlags.ResScaleUnsupported) != 0)
|
||||||
{
|
{
|
||||||
changed = texture.ScaleMode != TextureScaleMode.Blacklisted;
|
changed = texture.ScaleMode != TextureScaleMode.Blacklisted;
|
||||||
texture.BlacklistScale();
|
texture.BlacklistScale();
|
||||||
|
@ -469,6 +471,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
for (int index = 0; index < textureCount; index++)
|
for (int index = 0; index < textureCount; index++)
|
||||||
{
|
{
|
||||||
TextureBindingInfo bindingInfo = _textureBindings[stageIndex][index];
|
TextureBindingInfo bindingInfo = _textureBindings[stageIndex][index];
|
||||||
|
TextureUsageFlags usageFlags = bindingInfo.Flags;
|
||||||
|
|
||||||
(int textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, _textureBufferIndex);
|
(int textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, _textureBufferIndex);
|
||||||
|
|
||||||
|
@ -487,7 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
samplerId = TextureHandle.UnpackSamplerId(packedId);
|
samplerId = TextureHandle.UnpackSamplerId(packedId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref TextureStatePerStage state = ref _textureState[bindingInfo.Binding];
|
ref TextureState state = ref _textureState[bindingInfo.Binding];
|
||||||
|
|
||||||
if (!poolModified &&
|
if (!poolModified &&
|
||||||
state.TextureHandle == textureId &&
|
state.TextureHandle == textureId &&
|
||||||
|
@ -499,6 +502,18 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
// The texture is already bound.
|
// The texture is already bound.
|
||||||
state.CachedTexture.SynchronizeMemory();
|
state.CachedTexture.SynchronizeMemory();
|
||||||
|
|
||||||
|
if ((state.ScaleIndex != index || state.UsageFlags != usageFlags) &&
|
||||||
|
UpdateScale(state.CachedTexture, usageFlags, index, stage))
|
||||||
|
{
|
||||||
|
ITexture hostTextureRebind = state.CachedTexture.GetTargetTexture(bindingInfo.Target);
|
||||||
|
|
||||||
|
state.Texture = hostTextureRebind;
|
||||||
|
state.ScaleIndex = index;
|
||||||
|
state.UsageFlags = usageFlags;
|
||||||
|
|
||||||
|
_context.Renderer.Pipeline.SetTexture(bindingInfo.Binding, hostTextureRebind);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,12 +537,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
if (state.Texture != hostTexture)
|
if (state.Texture != hostTexture)
|
||||||
{
|
{
|
||||||
if (UpdateScale(texture, bindingInfo, index, stage))
|
if (UpdateScale(texture, usageFlags, index, stage))
|
||||||
{
|
{
|
||||||
hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
|
hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.Texture = hostTexture;
|
state.Texture = hostTexture;
|
||||||
|
state.ScaleIndex = index;
|
||||||
|
state.UsageFlags = usageFlags;
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetTexture(bindingInfo.Binding, hostTexture);
|
_context.Renderer.Pipeline.SetTexture(bindingInfo.Binding, hostTexture);
|
||||||
}
|
}
|
||||||
|
@ -589,6 +606,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
for (int index = 0; index < imageCount; index++)
|
for (int index = 0; index < imageCount; index++)
|
||||||
{
|
{
|
||||||
TextureBindingInfo bindingInfo = _imageBindings[stageIndex][index];
|
TextureBindingInfo bindingInfo = _imageBindings[stageIndex][index];
|
||||||
|
TextureUsageFlags usageFlags = bindingInfo.Flags;
|
||||||
|
int scaleIndex = baseScaleIndex + index;
|
||||||
|
|
||||||
(int textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, _textureBufferIndex);
|
(int textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, _textureBufferIndex);
|
||||||
|
|
||||||
|
@ -597,7 +616,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
int packedId = TextureHandle.ReadPackedId(bindingInfo.Handle, cachedTextureBuffer, cachedSamplerBuffer);
|
int packedId = TextureHandle.ReadPackedId(bindingInfo.Handle, cachedTextureBuffer, cachedSamplerBuffer);
|
||||||
int textureId = TextureHandle.UnpackTextureId(packedId);
|
int textureId = TextureHandle.UnpackTextureId(packedId);
|
||||||
|
|
||||||
ref TextureStatePerStage state = ref _imageState[bindingInfo.Binding];
|
ref TextureState state = ref _imageState[bindingInfo.Binding];
|
||||||
|
|
||||||
bool isStore = bindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore);
|
bool isStore = bindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore);
|
||||||
|
|
||||||
|
@ -606,12 +625,28 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
state.CachedTexture != null &&
|
state.CachedTexture != null &&
|
||||||
state.CachedTexture.InvalidatedSequence == state.InvalidatedSequence)
|
state.CachedTexture.InvalidatedSequence == state.InvalidatedSequence)
|
||||||
{
|
{
|
||||||
|
Texture cachedTexture = state.CachedTexture;
|
||||||
|
|
||||||
// The texture is already bound.
|
// The texture is already bound.
|
||||||
state.CachedTexture.SynchronizeMemory();
|
cachedTexture.SynchronizeMemory();
|
||||||
|
|
||||||
if (isStore)
|
if (isStore)
|
||||||
{
|
{
|
||||||
state.CachedTexture?.SignalModified();
|
cachedTexture?.SignalModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((state.ScaleIndex != index || state.UsageFlags != usageFlags) &&
|
||||||
|
UpdateScale(state.CachedTexture, usageFlags, scaleIndex, stage))
|
||||||
|
{
|
||||||
|
ITexture hostTextureRebind = state.CachedTexture.GetTargetTexture(bindingInfo.Target);
|
||||||
|
|
||||||
|
Format format = bindingInfo.Format == 0 ? cachedTexture.Format : bindingInfo.Format;
|
||||||
|
|
||||||
|
state.Texture = hostTextureRebind;
|
||||||
|
state.ScaleIndex = scaleIndex;
|
||||||
|
state.UsageFlags = usageFlags;
|
||||||
|
|
||||||
|
_context.Renderer.Pipeline.SetImage(bindingInfo.Binding, hostTextureRebind, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -649,12 +684,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (state.Texture != hostTexture)
|
if (state.Texture != hostTexture)
|
||||||
{
|
{
|
||||||
if (UpdateScale(texture, bindingInfo, baseScaleIndex + index, stage))
|
if (UpdateScale(texture, usageFlags, scaleIndex, stage))
|
||||||
{
|
{
|
||||||
hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
|
hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.Texture = hostTexture;
|
state.Texture = hostTexture;
|
||||||
|
state.ScaleIndex = scaleIndex;
|
||||||
|
state.UsageFlags = usageFlags;
|
||||||
|
|
||||||
Format format = bindingInfo.Format;
|
Format format = bindingInfo.Format;
|
||||||
|
|
||||||
|
|
Reference in a new issue