diff options
author | gdkchan <gab.dark.100@gmail.com> | 2022-06-23 21:41:57 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-24 02:41:57 +0200 |
commit | e747f5cd836b73661414134b182fc50121e56865 (patch) | |
tree | efaea2ff6ea098ed4f1e0dca35a421020f57ac52 | |
parent | 8aff17a93c27dea7339c20f9cf73535e110ffb72 (diff) |
Ensure texture ID is valid before getting texture descriptor (#3406)1.1.154
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/Pool.cs | 10 | ||||
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs | 17 | ||||
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs | 19 | ||||
-rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs | 12 |
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; + } } } } |