[vlc-commits] [Git][videolan/vlc][master] 4 commits: direct3d11: separate the swapchain creation from the local swapchain handler

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Mar 22 13:14:25 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
3a28ed58 by Steve Lhomme at 2024-03-22T12:36:16+00:00
direct3d11: separate the swapchain creation from the local swapchain handler

Only one of them needs special handling between DComp/HWND.

- - - - -
27b8a911 by Steve Lhomme at 2024-03-22T12:36:16+00:00
direct3d11: tell the local swapchain whether it should try to match the display

When forcing or disabling HDR we don't want to match the display

- - - - -
e9b4339f by Steve Lhomme at 2024-03-22T12:36:16+00:00
direct3d11: initialize HDR mode earlier

- - - - -
be507fef by Steve Lhomme at 2024-03-22T12:36:16+00:00
direct3d11: disable generated HDR on SDR screens

We assume the first display must be in HDR for Windows to enable SDR. We don't know
which adapter will be used at this point nor on which output.

- - - - -


6 changed files:

- modules/video_output/Makefile.am
- modules/video_output/win32/d3d11_shaders.h
- modules/video_output/win32/d3d11_swapchain.cpp
- modules/video_output/win32/d3d11_swapchain.h
- modules/video_output/win32/direct3d11.cpp
- modules/video_output/win32/meson.build


Changes:

=====================================
modules/video_output/Makefile.am
=====================================
@@ -204,7 +204,7 @@ libdirect3d11_plugin_la_SOURCES = video_output/win32/direct3d11.cpp \
  video_output/win32/d3d_dynamic_shader.c video_output/win32/d3d_dynamic_shader.h \
  video_output/win32/common.c video_output/win32/common.h
 libdirect3d11_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(LIBCOMCXXFLAGS)
-libdirect3d11_plugin_la_LIBADD = libchroma_copy.la libd3d11_common.la $(LIBCOM) -luuid
+libdirect3d11_plugin_la_LIBADD = libchroma_copy.la libd3d11_common.la $(LIBCOM) -luuid -ldxgi
 libdirect3d11_plugin_la_CPPFLAGS = $(AM_CPPFLAGS)
 if !HAVE_WINSTORE
 libdirect3d11_plugin_la_CPPFLAGS += -DHAVE_WIN32_SENSORS


=====================================
modules/video_output/win32/d3d11_shaders.h
=====================================
@@ -95,27 +95,4 @@ void D3D11_ClearRenderTargets(d3d11_device_t *, const d3d_format_t *,
 
 void D3D11_ReleaseVertexShader(d3d11_vertex_shader_t *);
 
-enum d3d11_hdr
-{
-    hdr_Auto,
-    hdr_Never,
-    hdr_Always,
-    hdr_Fake,
-};
-
-static inline enum d3d11_hdr HdrModeFromString(vlc_logger *logger, const char *psz_hdr)
-{
-    if (strcmp("auto", psz_hdr) == 0)
-        return hdr_Auto;
-    if (strcmp("never", psz_hdr) == 0)
-        return hdr_Never;
-    if (strcmp("always", psz_hdr) == 0)
-        return hdr_Always;
-    if (strcmp("generate", psz_hdr) == 0)
-        return hdr_Fake;
-
-    vlc_warning(logger, "unknown HDR mode %s, using auto mode", psz_hdr);
-    return hdr_Auto;
-}
-
 #endif /* VLC_D3D11_SHADERS_H */


=====================================
modules/video_output/win32/d3d11_swapchain.cpp
=====================================
@@ -49,6 +49,7 @@ struct d3d11_local_swapchain
 
     vlc_object_t           *obj = nullptr;
     d3d11_device_t         *d3d_dev = nullptr;
+    bool                   match_display = true;
 
     ComPtr<ID3D11RenderTargetView> swapchainTargetView[DXGI_MAX_RENDER_TARGET];
 };
@@ -114,12 +115,8 @@ static bool UpdateSwapchain( d3d11_local_swapchain *display, const libvlc_video_
         return false;
     }
 
-    char *psz_hdr = var_InheritString(display->obj, "d3d11-hdr-mode");
-    auto hdrMode = HdrModeFromString(vlc_object_logger(display->obj), psz_hdr);
-    free(psz_hdr);
-
     if (!DXGI_UpdateSwapChain( display->sys, dxgiadapter.Get(), display->d3d_dev->d3ddevice,
-                               newPixelFormat, cfg, hdrMode == hdr_Auto ))
+                               newPixelFormat, cfg, display->match_display ))
         return false;
 
     ComPtr<ID3D11Resource> pBackBuffer;
@@ -189,36 +186,16 @@ bool D3D11_LocalSwapchainSelectPlane( void *opaque, size_t plane, void *out )
     return true;
 }
 
-void *D3D11_CreateLocalSwapchainHandleHwnd(vlc_object_t *o, HWND hwnd, d3d11_device_t *d3d_dev)
-{
-    d3d11_local_swapchain *display = new (std::nothrow) d3d11_local_swapchain();
-    if (unlikely(display == NULL))
-        return NULL;
-
-    display->sys = DXGI_CreateLocalSwapchainHandleHwnd(o, hwnd);
-    if (unlikely(display->sys == NULL))
-        return NULL;
-
-    display->obj = o;
-    display->d3d_dev = d3d_dev;
-
-    return display;
-}
-
-#if defined(HAVE_DCOMP_H)
-void *D3D11_CreateLocalSwapchainHandleDComp(vlc_object_t *o, void* dcompDevice, void* dcompVisual, d3d11_device_t *d3d_dev)
+void *D3D11_CreateLocalSwapchain(vlc_object_t *o, d3d11_device_t *d3d_dev, dxgi_swapchain *sys, bool match_display)
 {
     d3d11_local_swapchain *display = new (std::nothrow) d3d11_local_swapchain();
     if (unlikely(display == NULL))
         return NULL;
 
-    display->sys = DXGI_CreateLocalSwapchainHandleDComp(o, dcompDevice, dcompVisual);
-    if (unlikely(display->sys == NULL))
-        return NULL;
-
+    display->sys = sys;
     display->obj = o;
     display->d3d_dev = d3d_dev;
+    display->match_display = match_display;
 
     return display;
 }
-#endif // HAVE_DCOMP_H


=====================================
modules/video_output/win32/d3d11_swapchain.h
=====================================
@@ -29,11 +29,7 @@
 #include "../../video_chroma/d3d11_fmt.h"
 
 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-void *D3D11_CreateLocalSwapchainHandleHwnd(vlc_object_t *, HWND, d3d11_device_t *d3d_dev);
-#if defined(HAVE_DCOMP_H)
-void *D3D11_CreateLocalSwapchainHandleDComp(vlc_object_t *, void* dcompDevice, void* dcompVisual, d3d11_device_t *d3d_dev);
-#endif // HAVE_DCOMP_H
-
+void *D3D11_CreateLocalSwapchain(vlc_object_t *, d3d11_device_t *, struct dxgi_swapchain *, bool match_display);
 void D3D11_LocalSwapchainCleanupDevice( void *opaque );
 bool D3D11_LocalSwapchainUpdateOutput( void *opaque, const libvlc_video_render_cfg_t *cfg, libvlc_video_output_cfg_t *out );
 bool D3D11_LocalSwapchainStartEndRendering( void *opaque, bool enter );


=====================================
modules/video_output/win32/direct3d11.cpp
=====================================
@@ -53,6 +53,10 @@
 #include "common.h"
 #include "../../video_chroma/copy.h"
 
+#ifdef HAVE_DXGI1_6_H
+# include <dxgi1_6.h>
+#endif
+
 using Microsoft::WRL::ComPtr;
 
 static int  Open(vout_display_t *,
@@ -106,6 +110,14 @@ enum d3d11_upscale
     upscale_SuperResolution,
 };
 
+enum d3d11_hdr
+{
+    hdr_Auto,
+    hdr_Never,
+    hdr_Always,
+    hdr_Fake,
+};
+
 typedef struct vout_display_sys_t
 {
     display_win32_area_t     area = {};
@@ -404,6 +416,74 @@ static int UpdateStaging(vout_display_t *vd, const video_format_t *fmt)
     return VLC_SUCCESS;
 }
 
+static enum d3d11_hdr HdrModeFromString(vlc_logger *logger, const char *psz_hdr)
+{
+    if (strcmp("auto", psz_hdr) == 0)
+        return hdr_Auto;
+    if (strcmp("never", psz_hdr) == 0)
+        return hdr_Never;
+    if (strcmp("always", psz_hdr) == 0)
+        return hdr_Always;
+    if (strcmp("generate", psz_hdr) == 0)
+        return hdr_Fake;
+
+    vlc_warning(logger, "unknown HDR mode %s, using auto mode", psz_hdr);
+    return hdr_Auto;
+}
+
+static void InitTonemapProcessor(vout_display_t *vd, const video_format_t *fmt_in)
+{
+    vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
+    if (sys->hdrMode != hdr_Fake)
+        return;
+
+#ifdef HAVE_DXGI1_6_H
+    { // check the main display is in HDR mode
+    HRESULT hr;
+
+    ComPtr<IDXGIAdapter> adapter;
+    ComPtr<IDXGIFactory2> factory;
+    ComPtr<IDXGIOutput> dxgiOutput;
+    ComPtr<IDXGIOutput6> dxgiOutput6;
+    DXGI_OUTPUT_DESC1 desc1;
+
+    hr = CreateDXGIFactory1(IID_GRAPHICS_PPV_ARGS(factory.GetAddressOf()));
+    if (FAILED(hr))
+        goto error;
+    UINT adapter_index = 0;
+    hr = factory->EnumAdapters(adapter_index, adapter.GetAddressOf());
+    if (FAILED(hr))
+        goto error;
+    UINT output_index = 0;
+    hr = adapter->EnumOutputs(output_index, dxgiOutput.GetAddressOf());
+    if (FAILED(hr))
+        goto error;
+    hr = dxgiOutput.As(&dxgiOutput6);
+    if (FAILED(hr))
+        goto error;
+    hr = dxgiOutput6->GetDesc1(&desc1);
+    if (FAILED(hr))
+        goto error;
+    if (desc1.ColorSpace != DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
+    {
+        msg_Warn(vd, "not an HDR display");
+        goto error;
+    }
+    }
+#endif
+
+    sys->tonemapProc = D3D11_TonemapperCreate(VLC_OBJECT(vd), sys->d3d_dev, fmt_in);
+    if (sys->tonemapProc != NULL)
+    {
+        msg_Dbg(vd, "Using tonemapper");
+        return;
+    }
+
+error:
+    sys->hdrMode = hdr_Auto;
+    msg_Dbg(vd, "failed to create the tone mapper, using default HDR mode");
+}
+
 static const auto ops = []{
     struct vlc_display_operations ops {};
     ops.close = Close;
@@ -422,6 +502,10 @@ static int Open(vout_display_t *vd,
         return VLC_ENOMEM;
     vd->sys = sys;
 
+    char *psz_hdr = var_InheritString(vd, "d3d11-hdr-mode");
+    sys->hdrMode = HdrModeFromString(vlc_object_logger(vd), psz_hdr);
+    free(psz_hdr);
+
     d3d11_decoder_device_t *dev_sys = NULL;
 
     int ret = D3D_CreateShaderCompiler(VLC_OBJECT(vd), &sys->shaders);
@@ -450,6 +534,8 @@ static int Open(vout_display_t *vd,
     }
     sys->d3d_dev = &dev_sys->d3d_dev;
 
+    InitTonemapProcessor(vd, vd->source);
+
     if ( sys->swapCb == NULL || sys->startEndRenderingCb == NULL || sys->updateOutputCb == NULL )
     {
 #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
@@ -464,17 +550,26 @@ static int Open(vout_display_t *vd,
         }
 
         /* use our internal swapchain callbacks */
+        dxgi_swapchain *swap = nullptr;
 #if defined(HAVE_DCOMP_H)
         if (vd->cfg->window->type == VLC_WINDOW_TYPE_DCOMP)
-            sys->outside_opaque =
-                D3D11_CreateLocalSwapchainHandleDComp(VLC_OBJECT(vd),
-                                                      vd->cfg->window->display.dcomp_device,
-                                                      vd->cfg->window->handle.dcomp_visual, sys->d3d_dev);
+            swap = DXGI_CreateLocalSwapchainHandleDComp(VLC_OBJECT(vd),
+                                                        vd->cfg->window->display.dcomp_device,
+                                                        vd->cfg->window->handle.dcomp_visual);
         else
 #endif //HAVE_DCOMP_H
-            sys->outside_opaque      = D3D11_CreateLocalSwapchainHandleHwnd(VLC_OBJECT(vd), CommonVideoHWND(&sys->area), sys->d3d_dev);
+            swap = DXGI_CreateLocalSwapchainHandleHwnd(VLC_OBJECT(vd), CommonVideoHWND(&sys->area));
+        if (unlikely(swap == NULL))
+            goto error;
+
+        sys->outside_opaque = D3D11_CreateLocalSwapchain(VLC_OBJECT(vd), sys->d3d_dev, swap,
+                                                         sys->hdrMode != hdr_Never && sys->hdrMode != hdr_Always);
         if (unlikely(sys->outside_opaque == NULL))
+        {
+            DXGI_LocalSwapchainCleanupDevice(swap);
             goto error;
+        }
+
         sys->updateOutputCb      = D3D11_LocalSwapchainUpdateOutput;
         sys->swapCb              = D3D11_LocalSwapchainSwap;
         sys->startEndRenderingCb = D3D11_LocalSwapchainStartEndRendering;
@@ -839,23 +934,6 @@ static const d3d_format_t *GetBlendableFormat(vout_display_t *vd, vlc_fourcc_t i
     return FindD3D11Format( vd, sys->d3d_dev, i_src_chroma, DXGI_RGB_FORMAT|DXGI_YUV_FORMAT, 0, 0, 0, 8, DXGI_CHROMA_CPU, supportFlags );
 }
 
-static void InitTonemapProcessor(vout_display_t *vd, const video_format_t *fmt_in)
-{
-    vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
-    if (sys->hdrMode != hdr_Fake)
-        return;
-
-    sys->tonemapProc = D3D11_TonemapperCreate(VLC_OBJECT(vd), sys->d3d_dev, fmt_in);
-    if (sys->tonemapProc == NULL)
-    {
-        sys->hdrMode = hdr_Auto;
-        msg_Dbg(vd, "failed to create the tone mapper, using default HDR mode");
-        return;
-    }
-
-    msg_Dbg(vd, "Using tonemapper");
-}
-
 static void InitScaleProcessor(vout_display_t *vd)
 {
     vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
@@ -878,12 +956,6 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmtp, vlc_video_co
     vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
     video_format_t fmt;
 
-    char *psz_hdr = var_InheritString(vd, "d3d11-hdr-mode");
-    sys->hdrMode = HdrModeFromString(vlc_object_logger(vd), psz_hdr);
-    free(psz_hdr);
-
-    InitTonemapProcessor(vd, vd->source);
-
     video_format_Copy(&fmt, vd->source);
     video_format_Copy(&sys->picQuad.quad_fmt, &fmt);
     int err = SetupOutputFormat(vd, &fmt, vctx, &sys->picQuad.quad_fmt);


=====================================
modules/video_output/win32/meson.build
=====================================
@@ -9,7 +9,7 @@ d3d11_sources = files('direct3d11.cpp', 'd3d11_quad.cpp', 'd3d11_scaler.cpp',
 d3d11_link_with = [ d3d11_common_lib ]
 d3d11_cargs = []
 d3d11_cxxargs = [ libcom_cppflags ]
-d3d11_deps = []
+d3d11_deps = [ cc.find_library('dxgi') ]
 if get_option('winstore_app')
     d3d11_deps += [
         cc.find_library('d3d11'),



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/36f6d1c59bf73038ae36ce56fa47a06cbf100fbd...be507fef3f5fdcb3419a6830761f7dadd7e6b5bf

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/36f6d1c59bf73038ae36ce56fa47a06cbf100fbd...be507fef3f5fdcb3419a6830761f7dadd7e6b5bf
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list