aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2022-06-17 21:41:38 +0100
committerGitHub <noreply@github.com>2022-06-17 17:41:38 -0300
commit68f909187045c9e5a6c1ecaf3b8160399238f8c5 (patch)
tree931edf4f3b91e9d01cbf0578ee1ef4a163bfb7e9
parent99ffc061d30c92f224c6b839290e181b6179893d (diff)
Account for res scale changes when updating bindings (#3403)1.1.150
Fixes a regression introduced by the texture bindings PR. Also renames TextureStatePerStage, as it's no longer per stage.
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs67
1 files changed, 52 insertions, 15 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
index f15f8885..91cadde3 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
@@ -35,7 +35,7 @@ namespace Ryujinx.Graphics.Gpu.Image
private readonly TextureBindingInfo[][] _textureBindings;
private readonly TextureBindingInfo[][] _imageBindings;
- private struct TextureStatePerStage
+ private struct TextureState
{
public ITexture Texture;
public ISampler Sampler;
@@ -45,10 +45,12 @@ namespace Ryujinx.Graphics.Gpu.Image
public int InvalidatedSequence;
public Texture CachedTexture;
public Sampler CachedSampler;
+ public int ScaleIndex;
+ public TextureUsageFlags UsageFlags;
}
- private TextureStatePerStage[] _textureState;
- private TextureStatePerStage[] _imageState;
+ private TextureState[] _textureState;
+ private TextureState[] _imageState;
private int[] _textureBindingsCount;
private int[] _imageBindingsCount;
@@ -83,8 +85,8 @@ namespace Ryujinx.Graphics.Gpu.Image
_textureBindings = new TextureBindingInfo[stages][];
_imageBindings = new TextureBindingInfo[stages][];
- _textureState = new TextureStatePerStage[InitialTextureStateSize];
- _imageState = new TextureStatePerStage[InitialImageStateSize];
+ _textureState = new TextureState[InitialTextureStateSize];
+ _imageState = new TextureState[InitialImageStateSize];
_textureBindingsCount = 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.
/// </summary>
/// <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="stage">The active shader stage</param>
/// <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;
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;
texture.BlacklistScale();
@@ -469,6 +471,7 @@ namespace Ryujinx.Graphics.Gpu.Image
for (int index = 0; index < textureCount; index++)
{
TextureBindingInfo bindingInfo = _textureBindings[stageIndex][index];
+ TextureUsageFlags usageFlags = bindingInfo.Flags;
(int textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, _textureBufferIndex);
@@ -487,7 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Image
samplerId = TextureHandle.UnpackSamplerId(packedId);
}
- ref TextureStatePerStage state = ref _textureState[bindingInfo.Binding];
+ ref TextureState state = ref _textureState[bindingInfo.Binding];
if (!poolModified &&
state.TextureHandle == textureId &&
@@ -499,6 +502,18 @@ namespace Ryujinx.Graphics.Gpu.Image
// The texture is already bound.
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;
}
@@ -522,12 +537,14 @@ namespace Ryujinx.Graphics.Gpu.Image
{
if (state.Texture != hostTexture)
{
- if (UpdateScale(texture, bindingInfo, index, stage))
+ if (UpdateScale(texture, usageFlags, index, stage))
{
hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
}
state.Texture = hostTexture;
+ state.ScaleIndex = index;
+ state.UsageFlags = usageFlags;
_context.Renderer.Pipeline.SetTexture(bindingInfo.Binding, hostTexture);
}
@@ -589,6 +606,8 @@ namespace Ryujinx.Graphics.Gpu.Image
for (int index = 0; index < imageCount; index++)
{
TextureBindingInfo bindingInfo = _imageBindings[stageIndex][index];
+ TextureUsageFlags usageFlags = bindingInfo.Flags;
+ int scaleIndex = baseScaleIndex + index;
(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 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);
@@ -606,12 +625,28 @@ namespace Ryujinx.Graphics.Gpu.Image
state.CachedTexture != null &&
state.CachedTexture.InvalidatedSequence == state.InvalidatedSequence)
{
+ Texture cachedTexture = state.CachedTexture;
+
// The texture is already bound.
- state.CachedTexture.SynchronizeMemory();
+ cachedTexture.SynchronizeMemory();
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;
@@ -649,12 +684,14 @@ namespace Ryujinx.Graphics.Gpu.Image
if (state.Texture != hostTexture)
{
- if (UpdateScale(texture, bindingInfo, baseScaleIndex + index, stage))
+ if (UpdateScale(texture, usageFlags, scaleIndex, stage))
{
hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
}
state.Texture = hostTexture;
+ state.ScaleIndex = scaleIndex;
+ state.UsageFlags = usageFlags;
Format format = bindingInfo.Format;