The host sampled the shared backbuffer copy through a view typed exactly like the game's backbuffer. For games whose backbuffer is an *_SRGB format (e.g. Life is Strange: Before the Storm -- confirmed R8G8B8A8_UNORM_SRGB / fmt 29 via the hook log), the GPU decoded sRGB->linear on the sample, and the host then wrote those linear values straight to its plain-UNORM swapchain with no re-encode, so the mirror came out noticeably darker than the game. Sample the copy as the plain-UNORM sibling of the format (srgb_to_unorm) so the bytes pass through unchanged -- matching what WGC already does. The UNORM and *_SRGB formats share a typeless group, so CopyResource from the producer's sRGB texture into the host's UNORM copy is allowed. Non-sRGB formats are unaffected. Adds srgb_format_test locking the mapping. All 6 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
42 lines
1.6 KiB
C++
42 lines
1.6 KiB
C++
// Unit test for srgb_to_unorm (host/src/capture/dxgi_format.hpp): the hooked
|
|
// video path samples the shared backbuffer copy as plain UNORM so an *_SRGB game
|
|
// backbuffer isn't darkened by an sRGB->linear decode the host never re-encodes.
|
|
// Locks the format mapping that fix depends on. No device needed.
|
|
|
|
#include <cstdio>
|
|
|
|
#include "capture/dxgi_format.hpp"
|
|
|
|
using namespace coop;
|
|
|
|
namespace
|
|
{
|
|
int g_failures = 0;
|
|
void expect(DXGI_FORMAT in, DXGI_FORMAT want, const char* what)
|
|
{
|
|
const DXGI_FORMAT got = srgb_to_unorm(in);
|
|
if (got != want)
|
|
{
|
|
std::printf(" FAIL: %s (got %d, want %d)\n", what, static_cast<int>(got), static_cast<int>(want));
|
|
++g_failures;
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
int main()
|
|
{
|
|
// sRGB formats map to their plain-UNORM sibling.
|
|
expect(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM, "R8G8B8A8 sRGB -> UNORM");
|
|
expect(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, DXGI_FORMAT_B8G8R8A8_UNORM, "B8G8R8A8 sRGB -> UNORM");
|
|
expect(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, DXGI_FORMAT_B8G8R8X8_UNORM, "B8G8R8X8 sRGB -> UNORM");
|
|
|
|
// Non-sRGB formats pass through unchanged.
|
|
expect(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, "R8G8B8A8 UNORM passthrough");
|
|
expect(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, "B8G8R8A8 UNORM passthrough");
|
|
expect(DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, "R10G10B10A2 passthrough");
|
|
expect(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, "RGBA16F passthrough");
|
|
|
|
std::printf(g_failures == 0 ? "SRGB FORMAT TEST PASS\n" : "SRGB FORMAT TEST FAILED (%d)\n", g_failures);
|
|
return g_failures == 0 ? 0 : 1;
|
|
}
|