[ShaderCompiler] Bind cached graph payloads to their input keys

This commit is contained in:
kuba 2026-10-01 16:56:14 +02:00
parent d994ff4e34
commit 2c062f389b
2 changed files with 13 additions and 2 deletions

View File

@ -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);

View File

@ -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);