shader: add compact f16 arithmetic and compare lowering (#840)

Co-authored-by: Foued Attar <attar.foued@gmail.com>
This commit is contained in:
frangametv
2026-08-24 13:59:51 +02:00
committed by GitHub
parent f8a826ec1b
commit 2b8ef7d8fa
7 changed files with 790 additions and 14 deletions
@@ -0,0 +1,85 @@
// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using SharpEmu.ShaderCompiler;
using SharpEmu.ShaderCompiler.Metal;
using Xunit;
namespace SharpEmu.ShaderCompiler.Metal.Tests;
public sealed class Gen5MslF16CompareTests
{
public static TheoryData<string> Opcodes = new()
{
"VCmpFF16",
"VCmpLtF16",
"VCmpEqF16",
"VCmpLeF16",
"VCmpGtF16",
"VCmpLgF16",
"VCmpGeF16",
"VCmpOF16",
"VCmpxFF16",
"VCmpxLtF16",
"VCmpxEqF16",
"VCmpxLeF16",
"VCmpxGtF16",
"VCmpxLgF16",
"VCmpxGeF16",
"VCmpxOF16",
"VCmpUF16",
"VCmpNgeF16",
"VCmpNlgF16",
"VCmpNgtF16",
"VCmpNleF16",
"VCmpNeqF16",
"VCmpNltF16",
"VCmpTruF16",
"VCmpxUF16",
"VCmpxNgeF16",
"VCmpxNlgF16",
"VCmpxNgtF16",
"VCmpxNleF16",
"VCmpxNeqF16",
"VCmpxNltF16",
"VCmpxTruF16",
};
[Theory]
[MemberData(nameof(Opcodes))]
public void F16CompareOpcodeLowersToMsl(string opcode)
{
var compare = new Gen5ShaderInstruction(
0,
Gen5ShaderEncoding.Vopc,
opcode,
[0u],
[Gen5Operand.Vector(0), Gen5Operand.Vector(1)],
[],
null);
var state = new Gen5ShaderState(
new Gen5ShaderProgram(0x1000, [compare]),
[],
null);
var scalars = new uint[256];
var evaluation = new Gen5ShaderEvaluation(scalars, scalars, [], []);
Assert.True(
Gen5MslTranslator.TryCompileComputeShader(
state,
evaluation,
1,
1,
1,
out var shader,
out var error),
error);
Assert.NotEmpty(shader.Source);
if (opcode is not (
"VCmpFF16" or "VCmpxFF16" or
"VCmpTruF16" or "VCmpxTruF16"))
{
Assert.Contains("half", shader.Source, StringComparison.Ordinal);
}
}
}
@@ -0,0 +1,34 @@
// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using Xunit;
namespace SharpEmu.ShaderCompiler.Metal.Tests;
public sealed class MslFloat16ArithmeticTests
{
[Fact]
public void CompactFloat16ArithmeticUsesHalfOperandsAndPreservesRegisterShape()
{
var fixture = new Gen5ComputeFixture(
"compact-f16-arithmetic",
[
0x64000501,
0x66060B04,
0x680C1107,
0x6A12170A,
0x72181D0D,
0x741E2310,
0xBF810000,
],
StoreScalarResourceBase: 0,
StoreBackingBytes: 0);
var shader = Gen5ComputeFixtures.CompileOrThrow(fixture);
Assert.Contains("as_type<half>", shader.Source, StringComparison.Ordinal);
Assert.Contains("fmin(", shader.Source, StringComparison.Ordinal);
Assert.Contains("fmax(", shader.Source, StringComparison.Ordinal);
Assert.Contains("& 0xFFFF0000u", shader.Source, StringComparison.Ordinal);
}
}