// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using System.Buffers.Binary;
using SharpEmu.Libs.Agc;
using Xunit;
namespace SharpEmu.Libs.Tests.Agc;
///
/// Regression coverage for the AGC UI path: index8 expansion and rect-list
/// vertex counts / topology selection.
///
public sealed class AgcRectListIndexHelpersTests
{
[Theory]
[InlineData(0u, 0u, 2)] // Index16
[InlineData(1u, 1u, 4)] // Index32
[InlineData(2u, 2u, 1)] // Index8
[InlineData(0x402u, 2u, 1)] // UC 0x400|size -> Index8
public void IndexType_DecodeAndStride_MatchProspero(uint raw, uint expected, int stride)
{
var decoded = AgcIndexHelpers.Decode(raw);
Assert.Equal((AgcIndexHelpers.ProsperoIndexType)expected, decoded);
Assert.Equal(stride, AgcIndexHelpers.GetGuestStrideBytes(decoded));
}
[Fact]
public void ExpandIndex8ToU16_PreservesValues()
{
ReadOnlySpan source = [0x00, 0x01, 0xFF, 0x7F];
Span destination = stackalloc byte[8];
AgcIndexHelpers.ExpandIndex8ToU16(source, destination);
Assert.Equal(0, BinaryPrimitives.ReadUInt16LittleEndian(destination[..2]));
Assert.Equal(1, BinaryPrimitives.ReadUInt16LittleEndian(destination.Slice(2, 2)));
Assert.Equal(255, BinaryPrimitives.ReadUInt16LittleEndian(destination.Slice(4, 2)));
Assert.Equal(127, BinaryPrimitives.ReadUInt16LittleEndian(destination.Slice(6, 2)));
}
[Theory]
// NGG single-rect UI (DualSense): expand even when VBs are present
[InlineData(7u, 3u, false, true, 4u)]
[InlineData(7u, 1u, false, false, 4u)]
[InlineData(7u, 4u, false, true, 4u)]
// Indexed / multi-vert auto: keep guest count (loading video)
[InlineData(7u, 3u, true, false, 3u)]
[InlineData(7u, 6u, false, true, 6u)]
[InlineData(7u, 4u, true, true, 4u)]
[InlineData(0x11u, 3u, false, false, 4u)]
[InlineData(0x11u, 6u, false, false, 6u)]
[InlineData(4u, 3u, false, false, 3u)]
public void RectListDrawVertexCount_MatchesExpansion(
uint primitiveType,
uint vertexCount,
bool indexed,
bool hasVertexBuffers,
uint expected)
{
Assert.Equal(
expected,
AgcPrimitiveHelpers.GetRectListDrawVertexCount(
primitiveType,
vertexCount,
indexed,
hasVertexBuffers));
}
[Theory]
[InlineData(7u, false, 3u, true, true)]
[InlineData(7u, false, 6u, true, false)]
[InlineData(7u, true, 3u, false, false)]
[InlineData(0x11u, false, 3u, true, true)]
[InlineData(0x11u, true, 3u, false, false)]
public void RectListTriangleStrip_MatchesGuards(
uint primitiveType,
bool indexed,
uint vertexCount,
bool hasVertexBuffers,
bool expected) =>
Assert.Equal(
expected,
AgcPrimitiveHelpers.ShouldDrawRectListAsTriangleStrip(
primitiveType,
indexed,
vertexCount,
hasVertexBuffers));
[Theory]
[InlineData(7u, (uint)AgcPrimitiveHelpers.GsOutputPrimitiveType.Rectangle2D)]
[InlineData(0x11u, (uint)AgcPrimitiveHelpers.GsOutputPrimitiveType.RectList)]
[InlineData(4u, (uint)AgcPrimitiveHelpers.GsOutputPrimitiveType.Triangles)]
[InlineData(1u, (uint)AgcPrimitiveHelpers.GsOutputPrimitiveType.Points)]
public void PrimitiveTypeToGsOut_MatchesProspero(uint primitiveType, uint expected) =>
Assert.Equal(expected, AgcPrimitiveHelpers.PrimitiveTypeToGsOut(primitiveType));
}