111 lines
4.3 KiB
C#
111 lines
4.3 KiB
C#
// Copyright (C) 2026 SharpEmu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
using SharpEmu.ShaderCompiler;
|
|
using SharpEmu.ShaderCompiler.Resources;
|
|
using Xunit;
|
|
using static SharpEmu.ShaderCompiler.Tests.Resources.ResourceTestProgram;
|
|
|
|
namespace SharpEmu.ShaderCompiler.Tests.Resources;
|
|
|
|
public sealed class DeviceAddressRangePlannerTests
|
|
{
|
|
[Fact]
|
|
public void BoundedOffsets_GiveTheLargestExtent()
|
|
{
|
|
var plan = Extract(Program(
|
|
Vop1(0, "VMovB32", 0, Operand(0)),
|
|
GlobalAccess(4, "GlobalLoadDword", 0, offset: 8),
|
|
GlobalAccess(12, "GlobalLoadDwordx4", 0, offset: 32, dwords: 4),
|
|
EndProgram(20)));
|
|
|
|
var range = Assert.Single(plan.DeviceAddressRanges);
|
|
Assert.True(range.Bounded);
|
|
Assert.True(range.Plannable);
|
|
Assert.False(range.Written);
|
|
Assert.Equal(8, range.FirstByte);
|
|
Assert.Equal(48, range.EndByte);
|
|
Assert.Equal(40ul, range.Extent);
|
|
Assert.Equal(2, range.MemoryIndices.Count);
|
|
var evaluated = Assert.Single(DeviceAddressRangePlanner.Evaluate(plan, Inputs([0x1000, 0])));
|
|
Assert.True(evaluated.Planned);
|
|
Assert.Equal(0x1008ul, evaluated.Base);
|
|
Assert.Equal(40ul, evaluated.Size);
|
|
}
|
|
|
|
// A store 8 bytes below the handle starts the range there; the range covers the
|
|
// lowest byte through the end of the highest access.
|
|
[Fact]
|
|
public void NegativeOffset_StartsTheRangeAtTheLowestByte()
|
|
{
|
|
var plan = Extract(Program(
|
|
Vop1(0, "VMovB32", 0, Operand(0)),
|
|
GlobalAccess(4, "GlobalStoreDword", 0, offset: -8),
|
|
GlobalAccess(12, "GlobalLoadDwordx2", 0, offset: 8, dwords: 2),
|
|
EndProgram(20)));
|
|
|
|
var range = Assert.Single(plan.DeviceAddressRanges);
|
|
Assert.True(range.Bounded);
|
|
Assert.True(range.Written);
|
|
Assert.Equal(-8, range.FirstByte);
|
|
Assert.Equal(16, range.EndByte);
|
|
Assert.Equal(24ul, range.Extent);
|
|
var evaluated = Assert.Single(DeviceAddressRangePlanner.Evaluate(plan, Inputs([0x2008, 0])));
|
|
Assert.True(evaluated.Planned);
|
|
Assert.Equal(0x2000ul, evaluated.Base);
|
|
Assert.Equal(24ul, evaluated.Size);
|
|
|
|
var storeOnly = Extract(Program(
|
|
Vop1(0, "VMovB32", 0, Operand(0)),
|
|
GlobalAccess(4, "GlobalStoreDword", 0, offset: -8),
|
|
EndProgram(12)));
|
|
var single = Assert.Single(DeviceAddressRangePlanner.Evaluate(storeOnly, Inputs([0x2008, 0])));
|
|
Assert.Equal(0x2000ul, single.Base);
|
|
Assert.Equal(4ul, single.Size);
|
|
}
|
|
|
|
[Fact]
|
|
public void RuntimeOffset_ExtendsToTheMappedEndUpToTheCap()
|
|
{
|
|
var plan = Extract(Program(
|
|
GlobalAccess(0, "GlobalLoadDword", 0, offset: 8, vectorAddress: 0),
|
|
EndProgram(8)));
|
|
|
|
var range = Assert.Single(plan.DeviceAddressRanges);
|
|
Assert.False(range.Bounded);
|
|
Assert.True(range.Plannable);
|
|
var evaluated = Assert.Single(DeviceAddressRangePlanner.Evaluate(plan, Inputs([0x1000, 0])));
|
|
Assert.True(evaluated.Planned);
|
|
Assert.Equal(DeviceAddressRangePlanner.MaxRangeBytes, evaluated.Size);
|
|
}
|
|
|
|
[Fact]
|
|
public void UnplannableHandle_DoesNotFailThePlan()
|
|
{
|
|
var plan = Extract(Program(GlobalAccess(0, "FlatLoadDword", 0, vectorAddress: 2), EndProgram(8)));
|
|
|
|
Assert.True(plan.Info.UsesDeviceAddresses);
|
|
var range = Assert.Single(plan.DeviceAddressRanges);
|
|
Assert.False(range.Plannable);
|
|
var evaluated = Assert.Single(DeviceAddressRangePlanner.Evaluate(plan, Inputs([])));
|
|
Assert.False(evaluated.Planned);
|
|
Assert.Equal(0ul, evaluated.Size);
|
|
}
|
|
|
|
[Fact]
|
|
public void WrittenUnplannableHandle_IsReportedForTheHost()
|
|
{
|
|
var plan = Extract(Program(GlobalAccess(0, "FlatStoreDword", 0, vectorAddress: 2), EndProgram(8)));
|
|
|
|
var range = Assert.Single(plan.DeviceAddressRanges);
|
|
Assert.True(range.Written);
|
|
Assert.False(range.Plannable);
|
|
var snapshot = new ResourceSnapshot();
|
|
var specialization = new ResourceSpecialization();
|
|
Assert.True(ResourceMaterializer.Materialize(plan, Inputs([]), ref snapshot, ref specialization));
|
|
var reported = Assert.Single(snapshot.DeviceAddressRanges);
|
|
Assert.True(reported.Written);
|
|
Assert.False(reported.Planned);
|
|
}
|
|
}
|