mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-01 15:39:47 +08:00
fix(agc): rect-list/NGG strips, Index8 expand, and GE_INDX_OFFSET
NGG single-rect UI needs triangle-strip expansion; Prospero Index8 must expand to host u16; glyphs need base vertex from GE_INDX_OFFSET. Skip param-less rect-lists instead of inventing colour draws. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
// 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;
|
||||
|
||||
/// <summary>
|
||||
/// Regression coverage for the AGC UI path: index8 expansion and rect-list
|
||||
/// vertex counts / topology selection.
|
||||
/// </summary>
|
||||
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<byte> source = [0x00, 0x01, 0xFF, 0x7F];
|
||||
Span<byte> 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));
|
||||
}
|
||||
Reference in New Issue
Block a user