aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-06-23 21:41:57 -0300
committerGitHub <noreply@github.com>2022-06-24 02:41:57 +0200
commite747f5cd836b73661414134b182fc50121e56865 (patch)
treeefaea2ff6ea098ed4f1e0dca35a421020f57ac52
parent8aff17a93c27dea7339c20f9cf73535e110ffb72 (diff)
Ensure texture ID is valid before getting texture descriptor (#3406)1.1.154
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Pool.cs10
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs17
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs19
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs12
4 files changed, 33 insertions, 25 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/Pool.cs b/Ryujinx.Graphics.Gpu/Image/Pool.cs
index 8e210513..ddd69807 100644
--- a/Ryujinx.Graphics.Gpu/Image/Pool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Pool.cs
@@ -102,6 +102,16 @@ namespace Ryujinx.Graphics.Gpu.Image
public abstract T1 Get(int id);
/// <summary>
+ /// Checks if a given ID is valid and inside the range of the pool.
+ /// </summary>
+ /// <param name="id">ID of the descriptor. This is effectively a zero-based index</param>
+ /// <returns>True if the specified ID is valid, false otherwise</returns>
+ public bool IsValidId(int id)
+ {
+ return (uint)id <= MaximumId;
+ }
+
+ /// <summary>
/// Synchronizes host memory with guest memory.
/// This causes invalidation of pool entries,
/// if a modification of entries by the CPU is detected.
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
index 91cadde3..a990528e 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
@@ -738,7 +738,22 @@ namespace Ryujinx.Graphics.Gpu.Image
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId);
- return texturePool.GetDescriptor(textureId);
+ TextureDescriptor descriptor;
+
+ if (texturePool.IsValidId(textureId))
+ {
+ descriptor = texturePool.GetDescriptor(textureId);
+ }
+ else
+ {
+ // If the ID is not valid, we just return a default descriptor with the most common state.
+ // Since this is used for shader specialization, doing so might avoid the need for recompilations.
+ descriptor = new TextureDescriptor();
+ descriptor.Word4 |= (uint)TextureTarget.Texture2D << 23;
+ descriptor.Word5 |= 1u << 31; // Coords normalized.
+ }
+
+ return descriptor;
}
/// <summary>
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs b/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs
index 62862e74..73b1232e 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs
@@ -242,25 +242,6 @@ namespace Ryujinx.Graphics.Gpu.Image
}
/// <summary>
- /// Create the equivalent of this TextureDescriptor for the shader cache.
- /// </summary>
- /// <returns>The equivalent of this TextureDescriptor for the shader cache.</returns>
- public GuestTextureDescriptor ToCache()
- {
- GuestTextureDescriptor result = new GuestTextureDescriptor
- {
- Handle = uint.MaxValue,
- Format = UnpackFormat(),
- Target = UnpackTextureTarget(),
- IsSrgb = UnpackSrgb(),
- IsTextureCoordNormalized = UnpackTextureCoordNormalized(),
-
- };
-
- return result;
- }
-
- /// <summary>
/// Check if two descriptors are equal.
/// </summary>
/// <param name="other">The descriptor to compare against</param>
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs
index 44ffd687..587d60a7 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs
@@ -579,14 +579,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
textureKey.StageIndex);
int packedId = TextureHandle.ReadPackedId(textureKey.Handle, cachedTextureBuffer, cachedSamplerBuffer);
-
int textureId = TextureHandle.UnpackTextureId(packedId);
- ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId);
-
- if (!MatchesTexture(kv.Value, descriptor))
+ if (pool.IsValidId(textureId))
{
- return false;
+ ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId);
+
+ if (!MatchesTexture(kv.Value, descriptor))
+ {
+ return false;
+ }
}
}
}