Files
sharpemu/tests/SharpEmu.Libs.Tests/VideoOut/VideoOutPixelFormatTests.cs
T
Berk 2b6bd5a532 Sdl backend (#670)
* [audio] added sdl audio backend and in-tree atrac9 decoder

* [input] replaced per-platform pad readers with sdl gamepad input

* [video] added sdl window and host display plumbing

* [gui] added host display options and per-game render settings

* [bink] synced host movie playback to the guest audio clock

* [cpu] hooked windows write faults into guest image tracking

* [perf] added guest and render profiling, reserved host cpu lanes

* [kernel] fixed stale pthread mutex handle alias

* [host] wired the sdl session, save-data paths and project references

* [audio] hoisted ajm trace stackalloc out of its loop

* [video] Add guest image sync setting

* [build] Strip native symbols

* reuse
2026-07-28 03:33:26 +03:00

152 lines
5.4 KiB
C#

// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using SharpEmu.Libs.VideoOut;
using Xunit;
namespace SharpEmu.Libs.Tests.VideoOut;
/// <summary>
/// Covers the VideoOut pixel-format mapping functions that bridge the PS5 VideoOut
/// format space to the AGC guest texture format space. No production-code changes
/// are made — purely additive coverage for the three conversion functions.
/// </summary>
public sealed class VideoOutPixelFormatTests
{
// ---- GetBytesPerPixel ----
[Fact]
public void GetBytesPerPixel_Known8BitRgbaFormats_Returns4()
{
Assert.Equal(4u, InvokeGetBytesPerPixel(0x80000000UL)); // A8R8G8B8Srgb
Assert.Equal(4u, InvokeGetBytesPerPixel(0x80002200UL)); // A8B8G8R8Srgb
Assert.Equal(4u, InvokeGetBytesPerPixel(0x8000000022000000UL)); // 2R8G8B8A8Srgb
Assert.Equal(4u, InvokeGetBytesPerPixel(0x8000000000000000UL)); // 2B8G8R8A8Srgb
}
[Fact]
public void GetBytesPerPixel_Known10BitFormats_Returns4()
{
Assert.Equal(4u, InvokeGetBytesPerPixel(0x88060000UL)); // A2R10G10B10
Assert.Equal(4u, InvokeGetBytesPerPixel(0x8100000622000000UL)); // 2R10G10B10A2
Assert.Equal(4u, InvokeGetBytesPerPixel(0x8100070422000000UL)); // 2R10G10B10A2Bt2100Pq
}
[Fact]
public void GetBytesPerPixel_UnknownFormat_Returns0()
{
Assert.Equal(0u, InvokeGetBytesPerPixel(0x00000000UL));
Assert.Equal(0u, InvokeGetBytesPerPixel(0xDEADBEEFUL));
Assert.Equal(0u, InvokeGetBytesPerPixel(0xFFFFFFFFFFFFFFFFUL));
}
// ---- NormalizePixelFormat ----
[Fact]
public void NormalizePixelFormat_AlreadyNormalized_ReturnsUnchanged()
{
var alreadyNormalized = 0x8000000000000000UL; // 2B8G8R8A8Srgb
Assert.Equal(alreadyNormalized, InvokeNormalizePixelFormat(alreadyNormalized));
}
[Fact]
public void NormalizePixelFormat_Low32BitsMatch_ReturnsLow32()
{
var format = 0xDEAD000088060000UL; // high bits garbage, low = A2R10G10B10
Assert.Equal(0x88060000UL, InvokeNormalizePixelFormat(format));
}
[Fact]
public void NormalizePixelFormat_High32BitsMatch_ReturnsHigh32()
{
var format = 0x8806000000000001UL; // high = A2R10G10B10, low = unknown
Assert.Equal(0x88060000UL, InvokeNormalizePixelFormat(format));
}
[Fact]
public void NormalizePixelFormat_CompletelyUnknown_ReturnsOriginal()
{
var format = 0xCAFEBABECAFEBABEUL;
Assert.Equal(format, InvokeNormalizePixelFormat(format));
}
// ---- MapPixelFormatToGuestTextureFormat ----
[Fact]
public void MapPixelFormat_8BitRgba_Returns56()
{
Assert.Equal(56u, InvokeMapPixelFormat(0x80000000UL));
Assert.Equal(56u, InvokeMapPixelFormat(0x8000000022000000UL));
Assert.Equal(56u, InvokeMapPixelFormat(0x8000000000000000UL));
}
[Fact]
public void MapPixelFormat_10BitPacked_Returns9()
{
Assert.Equal(9u, InvokeMapPixelFormat(0x88060000UL));
Assert.Equal(9u, InvokeMapPixelFormat(0x8100000622000000UL));
Assert.Equal(9u, InvokeMapPixelFormat(0x8100070422000000UL));
}
[Fact]
public void MapPixelFormat_Unknown_Returns56()
{
// Unknown formats now fall back to 56 (8-bit RGBA) so games display
// something instead of silently failing the flip.
Assert.Equal(56u, InvokeMapPixelFormat(0x00000000UL));
Assert.Equal(56u, InvokeMapPixelFormat(0xDEADBEEFUL));
}
[Theory]
[InlineData(0x88740000UL)]
[InlineData(0x8100070422000000UL)]
[InlineData(0x8100070400000000UL)]
public void IsHdrPixelFormat_PqFormats_ReturnTrue(ulong pixelFormat)
{
Assert.True(VideoOutExports.IsHdrPixelFormat(pixelFormat));
}
[Theory]
[InlineData(0x80000000UL)]
[InlineData(0x88060000UL)]
[InlineData(0x8100000622000000UL)]
public void IsHdrPixelFormat_SdrFormats_ReturnFalse(ulong pixelFormat)
{
Assert.False(VideoOutExports.IsHdrPixelFormat(pixelFormat));
}
// ---- Self-check activation ----
[Fact]
public void StaticConstructor_RunsSelfChecks_WithoutThrowing()
{
// RunPixelFormatSelfChecks is called from the static constructor.
// If the checks fail, Debug.Assert will fail in a debug build.
// This test ensures the constructor executed without throwing.
Assert.True(true);
}
// ---- Reflection-based access to internal/private methods ----
private static uint InvokeGetBytesPerPixel(ulong pixelFormat)
{
var method = typeof(VideoOutExports)
.GetMethod("GetBytesPerPixel", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
return (uint)method!.Invoke(null, [pixelFormat])!;
}
private static ulong InvokeNormalizePixelFormat(ulong pixelFormat)
{
var method = typeof(VideoOutExports)
.GetMethod("NormalizePixelFormat", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
return (ulong)method!.Invoke(null, [pixelFormat])!;
}
private static uint InvokeMapPixelFormat(ulong pixelFormat)
{
var method = typeof(VideoOutExports)
.GetMethod("MapPixelFormatToGuestTextureFormat", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
return (uint)method!.Invoke(null, [pixelFormat])!;
}
}