80 lines
3.0 KiB
C#
80 lines
3.0 KiB
C#
// Copyright (C) 2026 SharpEmu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
using Xunit;
|
|
|
|
namespace SharpEmu.ShaderCompiler.Metal.Tests;
|
|
|
|
/// <summary>
|
|
/// Pins the emitted MSL for the synthetic fixtures. Codegen changes show up as a
|
|
/// readable text diff instead of a runtime mystery. Regenerate with
|
|
/// SHARPEMU_UPDATE_GOLDENS=1 (writes into the source tree) after intentional
|
|
/// emitter changes, then review the diff like any other code change.
|
|
/// </summary>
|
|
public sealed class MslGoldenTests
|
|
{
|
|
public static TheoryData<string> FixtureNames()
|
|
{
|
|
var data = new TheoryData<string>();
|
|
foreach (var fixture in Gen5ComputeFixtures.All)
|
|
{
|
|
data.Add(fixture.Name);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
// The same fixtures through a compile request: the argument buffer replaces the uniforms.
|
|
[Theory]
|
|
[MemberData(nameof(FixtureNames))]
|
|
public void RequestPathMatchesGolden(string name)
|
|
{
|
|
var fixture = Gen5ComputeFixtures.All.Single(candidate => candidate.Name == name);
|
|
var shader = Gen5ComputeFixtures.CompileRequestOrThrow(fixture);
|
|
AssertMatchesGolden($"{name}-layout", shader.Source);
|
|
}
|
|
|
|
[Fact]
|
|
public void PixelRequestMatchesGolden()
|
|
{
|
|
var shader = Gen5ComputeFixtures.CompileStageRequestOrThrow(Gen5ComputeFixtures.PixelWords, Resources.ShaderStage.Pixel);
|
|
AssertMatchesGolden("pixel-layout", shader.Source);
|
|
}
|
|
|
|
[Fact]
|
|
public void VertexRequestMatchesGolden()
|
|
{
|
|
var shader = Gen5ComputeFixtures.CompileStageRequestOrThrow(Gen5ComputeFixtures.VertexWords, Resources.ShaderStage.Vertex, requiredVertexOutputCount: 1);
|
|
AssertMatchesGolden("vertex-layout", shader.Source);
|
|
}
|
|
|
|
private static void AssertMatchesGolden(string name, string source)
|
|
{
|
|
var goldenPath = Path.Combine(AppContext.BaseDirectory, "Goldens", $"{name}.msl");
|
|
|
|
if (Environment.GetEnvironmentVariable("SHARPEMU_UPDATE_GOLDENS") == "1")
|
|
{
|
|
var sourcePath = Path.Combine(
|
|
FindSourceDirectory(),
|
|
"Goldens",
|
|
$"{name}.msl");
|
|
Directory.CreateDirectory(Path.GetDirectoryName(sourcePath)!);
|
|
File.WriteAllText(sourcePath, source);
|
|
return;
|
|
}
|
|
|
|
Assert.True(File.Exists(goldenPath), $"missing golden {goldenPath}; run with SHARPEMU_UPDATE_GOLDENS=1 to create it");
|
|
var expected = File.ReadAllText(goldenPath).ReplaceLineEndings();
|
|
Assert.Equal(expected, source.ReplaceLineEndings());
|
|
}
|
|
|
|
private static string FindSourceDirectory([System.Runtime.CompilerServices.CallerFilePath] string sourcePath = "")
|
|
{
|
|
// Binaries land in artifacts/bin (outside the project directory), so
|
|
// walking up from the test binary never finds the csproj; the compiler
|
|
// records this file's source path instead.
|
|
return Path.GetDirectoryName(sourcePath)
|
|
?? throw new InvalidOperationException("test project directory not found");
|
|
}
|
|
}
|