sharpemu/tests/SharpEmu.ShaderCompiler.Tests/Resources/ResourceSnapshotStorageTest...

80 lines
3.7 KiB
C#

// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using SharpEmu.ShaderCompiler.Resources;
using Xunit;
using static SharpEmu.ShaderCompiler.Tests.Resources.ResourceTestProgram;
namespace SharpEmu.ShaderCompiler.Tests.Resources;
public sealed class ResourceSnapshotStorageTests
{
[Fact]
public void WrittenRangeWordsFollowEvaluatedTableWithoutReplacingIt()
{
var plan = Extract(Program(
ScalarLoad(0, 0, 4),
Vop1(8, "VMovB32", 0, Operand(0)),
GlobalAccess(12, "GlobalStoreDword", 0, offset: 8),
EndProgram(20)));
var memory = new TestWordMemory { Words = [0xAABBCCDD] };
var inputs = Inputs([0x1000, 0], memory.Read);
var snapshot = new ResourceSnapshot();
var specialization = new ResourceSpecialization();
Assert.True(ResourceMaterializer.Materialize(plan, inputs, ref snapshot, ref specialization));
Assert.Single(plan.TableReads);
Assert.Equal(1, plan.WrittenRangeCount);
Assert.Equal(new uint[] { 0xAABBCCDD, 0x1008, 0, 4 }, snapshot.FlattenedResourceTable);
Assert.True(RuntimeValueEvaluator.FlattenResourceTable(plan, inputs, out var tableOnly));
Assert.Equal(new uint[] { 0xAABBCCDD }, tableOnly);
tableOnly[0] = 0;
Assert.Equal(0xAABBCCDDu, snapshot.FlattenedResourceTable[0]);
}
[Fact]
public void IndirectMappingsFollowWrittenRangesAndKeepEarlierSnapshotsIndependent()
{
var original = ResourceTrackerTests.IndirectImageProgram(false);
var plan = Extract(Program([
.. original.Instructions.Take(original.Instructions.Count - 1),
Vop1(0x2000, "VMovB32", 0, Operand(0)),
GlobalAccess(0x2004, "GlobalStoreDword", 0, offset: 8),
EndProgram(0x200C),
]));
uint[] userData = [0x1000, 224 << 16, 2, 0, 0x2000, 16 << 16, 4, 0, 7];
var memory = ResourceTrackerTests.LinearMemory();
var firstImage = ResourceTrackerTests.ImageDescriptor();
var secondImage = firstImage.ToArray();
secondImage[0]++;
ResourceTrackerTests.WriteImage(memory, 0x2000, firstImage);
ResourceTrackerTests.WriteImage(memory, 0x2020, secondImage);
memory.At(0x1000 + 36) = 1;
var inputs = Inputs(userData, readCleanMemory: memory.Read);
var first = new ResourceSnapshot();
var specialization = new ResourceSpecialization();
Assert.True(ResourceMaterializer.Materialize(plan, inputs, ref first, ref specialization));
Assert.Equal(1, plan.WrittenRangeCount);
var range = Assert.Single(first.DeviceAddressRanges);
var rangeOffset = plan.TableReads.Count;
Assert.Equal((uint)range.Base, first.FlattenedResourceTable[rangeOffset]);
Assert.Equal((uint)(range.Base >> 32), first.FlattenedResourceTable[rangeOffset + 1]);
Assert.Equal((uint)range.Size, first.FlattenedResourceTable[rangeOffset + 2]);
var mappingOffset = checked((int)specialization.Images[0].IndirectMappingOffset);
Assert.Equal(plan.FlattenedTableReservedCount, mappingOffset);
Assert.Equal(new uint[] { 2, 0, 0, 1, 1 }, first.FlattenedResourceTable[mappingOffset..]);
Assert.Equal(2, first.Images.Length);
var originalTable = first.FlattenedResourceTable.ToArray();
var next = new ResourceSnapshot();
Assert.True(ResourceMaterializer.Materialize(plan, inputs, ref next, ref specialization));
next.FlattenedResourceTable[mappingOffset] = 0;
next.Images[1][0] = 0;
Assert.Equal(originalTable, first.FlattenedResourceTable);
Assert.Equal(secondImage[0], first.Images[1][0]);
}
}