From d9fe6977a6af691fb362002d9671d0c50e7ee631 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Fri, 21 Oct 2022 21:29:44 -0700 Subject: [PATCH] libobs-d3d11: Support advanced SDR window preview Displays more than 8 bpc if monitor is configured to be higher. --- libobs-d3d11/d3d11-subsystem.cpp | 35 ++++++++++++++++++++++++-------- libobs-d3d11/d3d11-subsystem.hpp | 12 ++++++++++- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index ed4033a21..ecbebfc0f 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -66,7 +66,8 @@ gs_obj::~gs_obj() next->prev_next = prev_next; } -static bool screen_supports_hdr(gs_device_t *device, HMONITOR hMonitor) +static gs_monitor_color_info get_monitor_color_info(gs_device_t *device, + HMONITOR hMonitor) { IDXGIFactory1 *factory1 = device->factory; if (!factory1->IsCurrent()) { @@ -75,7 +76,8 @@ static bool screen_supports_hdr(gs_device_t *device, HMONITOR hMonitor) device->monitor_to_hdr.clear(); } - for (const std::pair &pair : device->monitor_to_hdr) { + for (const std::pair &pair : + device->monitor_to_hdr) { if (pair.first == hMonitor) return pair.second; } @@ -96,15 +98,19 @@ static bool screen_supports_hdr(gs_device_t *device, HMONITOR hMonitor) const bool hdr = desc1.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020; - device->monitor_to_hdr.emplace_back( - hMonitor, hdr); - return hdr; + return device->monitor_to_hdr + .emplace_back( + hMonitor, + gs_monitor_color_info( + hdr, + desc1.BitsPerColor)) + .second; } } } } - return false; + return gs_monitor_color_info(false, 8); } static enum gs_color_space get_next_space(gs_device_t *device, HWND hwnd, @@ -115,8 +121,12 @@ static enum gs_color_space get_next_space(gs_device_t *device, HWND hwnd, const HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (hMonitor) { - if (screen_supports_hdr(device, hMonitor)) + const gs_monitor_color_info info = + get_monitor_color_info(device, hMonitor); + if (info.hdr) next_space = GS_CS_709_SCRGB; + else if (info.bits_per_color > 8) + next_space = GS_CS_SRGB_16F; } } @@ -126,7 +136,14 @@ static enum gs_color_space get_next_space(gs_device_t *device, HWND hwnd, static enum gs_color_format get_swap_format_from_space(gs_color_space space, gs_color_format sdr_format) { - return (space == GS_CS_709_SCRGB) ? GS_RGBA16F : sdr_format; + gs_color_format format = sdr_format; + switch (space) { + case GS_CS_SRGB_16F: + case GS_CS_709_SCRGB: + format = GS_RGBA16F; + } + + return format; } static inline enum gs_color_space @@ -3068,7 +3085,7 @@ extern "C" EXPORT bool device_p010_available(gs_device_t *device) extern "C" EXPORT bool device_is_monitor_hdr(gs_device_t *device, void *monitor) { const HMONITOR hMonitor = static_cast(monitor); - return screen_supports_hdr(device, hMonitor); + return get_monitor_color_info(device, hMonitor).hdr; } extern "C" EXPORT void device_debug_marker_begin(gs_device_t *, diff --git a/libobs-d3d11/d3d11-subsystem.hpp b/libobs-d3d11/d3d11-subsystem.hpp index 0d4ff24a2..e1125da25 100644 --- a/libobs-d3d11/d3d11-subsystem.hpp +++ b/libobs-d3d11/d3d11-subsystem.hpp @@ -979,6 +979,16 @@ struct mat4float { float mat[16]; }; +struct gs_monitor_color_info { + bool hdr; + UINT bits_per_color; + + gs_monitor_color_info(bool hdr, int bits_per_color) + : hdr(hdr), bits_per_color(bits_per_color) + { + } +}; + struct gs_device { ComPtr factory; ComPtr adapter; @@ -1035,7 +1045,7 @@ struct gs_device { vector loss_callbacks; gs_obj *first_obj = nullptr; - vector> monitor_to_hdr; + vector> monitor_to_hdr; void InitCompiler(); void InitFactory();