From 2c062f389b32f569de51bfeb6a980e66ad233cea Mon Sep 17 00:00:00 2001 From: kuba Date: Thu, 1 Oct 2026 16:56:14 +0200 Subject: [PATCH] [ShaderCompiler] Bind cached graph payloads to their input keys --- .../Resources/ScalarGraphDiskCache.cs | 9 +++++++-- .../Resources/ScalarGraphDiskCacheTests.cs | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/SharpEmu.ShaderCompiler/Resources/ScalarGraphDiskCache.cs b/src/SharpEmu.ShaderCompiler/Resources/ScalarGraphDiskCache.cs index 5c876e4..550ff99 100644 --- a/src/SharpEmu.ShaderCompiler/Resources/ScalarGraphDiskCache.cs +++ b/src/SharpEmu.ShaderCompiler/Resources/ScalarGraphDiskCache.cs @@ -9,7 +9,7 @@ namespace SharpEmu.ShaderCompiler.Resources; internal static class ScalarGraphDiskCache { - private const int Version = 1; + private const int Version = 2; private const int MaxEntryBytes = 32 * 1024 * 1024; private const long MaxCacheBytes = 256L * 1024 * 1024; private static readonly string CachePath = Environment.GetEnvironmentVariable("SHARPEMU_SHADER_ANALYSIS_CACHE_PATH") ?? @@ -36,6 +36,7 @@ internal static class ScalarGraphDiskCache if (CryptographicOperations.FixedTimeEquals(digest, SHA256.HashData(bytes))) { using var reader = new BinaryReader(new MemoryStream(bytes, false)); + if (reader.ReadString() != key) throw new InvalidDataException("Graph cache key mismatch."); var cached = ScalarValueGraph.ReadSnapshot(reader, program, userDataBase, userDataCount, fixedFunctionVertexLoads, waveSize); if (Trace) Console.Error.WriteLine($"[SHADER_ANALYSIS_CACHE] hit key={key} bytes={bytes.Length}"); return cached; @@ -48,7 +49,11 @@ internal static class ScalarGraphDiskCache try { using var stream = new MemoryStream(); - using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) graph.WriteSnapshot(writer); + using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) + { + writer.Write(key); + graph.WriteSnapshot(writer); + } if (stream.Length <= MaxEntryBytes - 32) { var bytes = stream.GetBuffer().AsSpan(0, (int)stream.Length); diff --git a/tests/SharpEmu.ShaderCompiler.Tests/Resources/ScalarGraphDiskCacheTests.cs b/tests/SharpEmu.ShaderCompiler.Tests/Resources/ScalarGraphDiskCacheTests.cs index cd9479e..7f63153 100644 --- a/tests/SharpEmu.ShaderCompiler.Tests/Resources/ScalarGraphDiskCacheTests.cs +++ b/tests/SharpEmu.ShaderCompiler.Tests/Resources/ScalarGraphDiskCacheTests.cs @@ -55,6 +55,12 @@ public sealed class ScalarGraphDiskCacheTests Assert.Equal(timestamp, File.GetLastWriteTimeUtc(file)); Assert.NotSame(first, second); Assert.Equal(first.Values.Count, second.Values.Count); + var different = Program(ScalarLoad(0, 2, 4), EndProgram(8)); + var differentKey = ScalarGraphDiskCache.Key(different, 0, 4, null, 64); + var differentFile = Path.Combine(directory, differentKey + ".graph"); + File.WriteAllBytes(differentFile, bytes); + _ = ScalarGraphDiskCache.Build(different, 0, 4, null, 64, directory); + Assert.NotEqual(bytes, File.ReadAllBytes(differentFile)); foreach (var corrupt in new[] { bytes[..20], bytes.Select((b, i) => i == 40 ? (byte)(b ^ 1) : b).ToArray() }) { File.WriteAllBytes(file, corrupt);