Files
sharpemu/tests/SharpEmu.Libs.Tests/VideoOut/VulkanPresentEncodeFormatTests.cs
T
kuba 327018e80a Encode linear-float flips to sRGB at present (#448)
PS5 float VideoOut buffers (A16B16G16R16F flips) hold linear scRGB
light where 1.0 is SDR white; hardware scan-out applies the display
transfer function. vkCmdBlitImage converts numerically only, so
raw-blitting a linear-float guest frame into a UNORM swapchain crushes
dim scenes to near-black.

Blit float flip sources through a cached swapchain-sized sRGB
intermediate (the sRGB store performs the linear->sRGB encode), then
raw vkCmdCopyImage the encoded bytes into the same-compatibility-class
UNORM swapchain image. Swapchains that are already sRGB keep the
direct blit (their store encodes), and swapchain formats without an
sRGB counterpart keep today's raw blit unchanged.
2026-07-20 01:29:38 +03:00

60 lines
1.9 KiB
C#

// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using SharpEmu.Libs.VideoOut;
using Silk.NET.Vulkan;
using Xunit;
namespace SharpEmu.Libs.Tests.VideoOut;
public sealed class VulkanPresentEncodeFormatTests
{
[Theory]
[InlineData(Format.B8G8R8A8Unorm, Format.B8G8R8A8Srgb)]
[InlineData(Format.R8G8B8A8Unorm, Format.R8G8B8A8Srgb)]
public void UnormSwapchainFormatsHaveSrgbCounterparts(
Format swapchainFormat,
Format expected)
{
Assert.Equal(
expected,
VulkanVideoPresenter.GetSrgbCounterpart(swapchainFormat));
}
[Theory]
// Already-sRGB swapchains encode on store; the direct blit stays.
[InlineData(Format.B8G8R8A8Srgb)]
[InlineData(Format.R8G8B8A8Srgb)]
// No same-class sRGB counterpart exists; the raw blit must remain.
[InlineData(Format.A2B10G10R10UnormPack32)]
[InlineData(Format.R16G16B16A16Sfloat)]
[InlineData(Format.R5G6B5UnormPack16)]
[InlineData(Format.Undefined)]
public void OtherSwapchainFormatsKeepTheDirectBlit(Format swapchainFormat)
{
Assert.Equal(
Format.Undefined,
VulkanVideoPresenter.GetSrgbCounterpart(swapchainFormat));
}
[Theory]
[InlineData(Format.R16G16B16A16Sfloat)]
[InlineData(Format.R32G32B32A32Sfloat)]
public void FloatFlipSourcesNeedLinearToSrgbEncode(Format sourceFormat)
{
Assert.True(VulkanVideoPresenter.IsLinearFloatPresentSource(sourceFormat));
}
[Theory]
[InlineData(Format.B8G8R8A8Unorm)]
[InlineData(Format.R8G8B8A8Unorm)]
[InlineData(Format.B8G8R8A8Srgb)]
[InlineData(Format.A2B10G10R10UnormPack32)]
[InlineData(Format.B10G11R11UfloatPack32)]
[InlineData(Format.Undefined)]
public void NonFloatFlipSourcesKeepTheDirectBlit(Format sourceFormat)
{
Assert.False(VulkanVideoPresenter.IsLinearFloatPresentSource(sourceFormat));
}
}