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
@@ -101,6 +101,16 @@ namespace Ryujinx.Graphics.Gpu.Image
/// The GPU resource with the given ID
public abstract T1 Get(int id);
+ ///
+ /// Checks if a given ID is valid and inside the range of the pool.
+ ///
+ /// ID of the descriptor. This is effectively a zero-based index
+ /// True if the specified ID is valid, false otherwise
+ public bool IsValidId(int id)
+ {
+ return (uint)id <= MaximumId;
+ }
+
///
/// Synchronizes host memory with guest memory.
/// This causes invalidation of pool entries,
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;
}
///
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
@@ -241,25 +241,6 @@ namespace Ryujinx.Graphics.Gpu.Image
return (TextureMsaaMode)((Word7 >> 8) & 0xf);
}
- ///
- /// Create the equivalent of this TextureDescriptor for the shader cache.
- ///
- /// The equivalent of this TextureDescriptor for the shader cache.
- public GuestTextureDescriptor ToCache()
- {
- GuestTextureDescriptor result = new GuestTextureDescriptor
- {
- Handle = uint.MaxValue,
- Format = UnpackFormat(),
- Target = UnpackTextureTarget(),
- IsSrgb = UnpackSrgb(),
- IsTextureCoordNormalized = UnpackTextureCoordNormalized(),
-
- };
-
- return result;
- }
-
///
/// Check if two descriptors are equal.
///
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;
+ }
}
}
}