Ensure texture ID is valid before getting texture descriptor (#3406)

This commit is contained in:
gdkchan 2022-06-23 21:41:57 -03:00 committed by GitHub
parent 8aff17a93c
commit e747f5cd83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 25 deletions

View File

@ -101,6 +101,16 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <returns>The GPU resource with the given ID</returns> /// <returns>The GPU resource with the given ID</returns>
public abstract T1 Get(int id); 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> /// <summary>
/// Synchronizes host memory with guest memory. /// Synchronizes host memory with guest memory.
/// This causes invalidation of pool entries, /// This causes invalidation of pool entries,

View File

@ -738,7 +738,22 @@ namespace Ryujinx.Graphics.Gpu.Image
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId); 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> /// <summary>

View File

@ -241,25 +241,6 @@ namespace Ryujinx.Graphics.Gpu.Image
return (TextureMsaaMode)((Word7 >> 8) & 0xf); return (TextureMsaaMode)((Word7 >> 8) & 0xf);
} }
/// <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> /// <summary>
/// Check if two descriptors are equal. /// Check if two descriptors are equal.
/// </summary> /// </summary>

View File

@ -579,14 +579,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
textureKey.StageIndex); textureKey.StageIndex);
int packedId = TextureHandle.ReadPackedId(textureKey.Handle, cachedTextureBuffer, cachedSamplerBuffer); int packedId = TextureHandle.ReadPackedId(textureKey.Handle, cachedTextureBuffer, cachedSamplerBuffer);
int textureId = TextureHandle.UnpackTextureId(packedId); int textureId = TextureHandle.UnpackTextureId(packedId);
ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId); if (pool.IsValidId(textureId))
if (!MatchesTexture(kv.Value, descriptor))
{ {
return false; ref readonly Image.TextureDescriptor descriptor = ref pool.GetDescriptorRef(textureId);
if (!MatchesTexture(kv.Value, descriptor))
{
return false;
}
} }
} }
} }