[vlc-devel] [PATCH 1/3] d3d11: factorize the creation of the D3D11 device/context

Steve Lhomme robux4 at videolabs.io
Tue Oct 17 14:20:08 CEST 2017


This way you cannot use D3D11VA with a D3D9 vout by default.

Fix #18923
---
 modules/codec/avcodec/d3d11va.c         | 33 +--------------
 modules/video_chroma/d3d11_fmt.h        | 71 +++++++++++++++++++++++++++++++++
 modules/video_output/win32/direct3d11.c | 55 ++-----------------------
 3 files changed, 76 insertions(+), 83 deletions(-)

diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index f95174e5bc..b0fd17ca24 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -68,10 +68,6 @@ vlc_module_begin()
     set_callbacks(Open, Close)
 vlc_module_end()
 
-#if VLC_WINSTORE_APP
-#define pf_CreateDevice                 D3D11CreateDevice
-#endif
-
 /*
  * In this mode libavcodec doesn't need the whole array on texture on startup
  * So we get the surfaces from the decoder pool when needed. We don't need to
@@ -430,36 +426,11 @@ static int D3dCreateDevice(vlc_va_t *va)
         return VLC_SUCCESS;
     }
 
-#if !VLC_WINSTORE_APP
-    /* */
-    PFN_D3D11_CREATE_DEVICE pf_CreateDevice;
-    pf_CreateDevice = (void *)GetProcAddress(dx_sys->hdecoder_dll, "D3D11CreateDevice");
-    if (!pf_CreateDevice) {
-        msg_Err(va, "Cannot locate reference to D3D11CreateDevice ABI in DLL");
-        return VLC_EGENERIC;
-    }
-#endif
-
-    UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
-#if !defined(NDEBUG)
-#if !VLC_WINSTORE_APP
-    if (IsDebuggerPresent())
-#endif
-    {
-        HINSTANCE sdklayer_dll = LoadLibrary(TEXT("d3d11_1sdklayers.dll"));
-        if (sdklayer_dll) {
-            creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
-            FreeLibrary(sdklayer_dll);
-        }
-    }
-#endif
-
     /* */
     ID3D11Device *d3ddev;
     ID3D11DeviceContext *d3dctx;
-    hr = pf_CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
-                                 creationFlags, NULL, 0,
-                                 D3D11_SDK_VERSION, &d3ddev, NULL, &d3dctx);
+    hr = D3D11_CreateDevice(VLC_OBJECT(va), dx_sys->hdecoder_dll, true,
+                            &d3ddev, &d3dctx);
     if (FAILED(hr)) {
         msg_Err(va, "D3D11CreateDevice failed. (hr=0x%lX)", hr);
         return VLC_EGENERIC;
diff --git a/modules/video_chroma/d3d11_fmt.h b/modules/video_chroma/d3d11_fmt.h
index d88c3d2419..04ff38ba60 100644
--- a/modules/video_chroma/d3d11_fmt.h
+++ b/modules/video_chroma/d3d11_fmt.h
@@ -149,4 +149,75 @@ static inline int AllocateShaderView(vlc_object_t *obj, ID3D11Device *d3ddevice,
     return VLC_SUCCESS;
 }
 
+static inline HRESULT D3D11_CreateDevice(vlc_object_t *obj, HINSTANCE hdecoder_dll,
+                                         bool hw_decoding,
+                                         ID3D11Device **pp_d3ddevice,
+                                         ID3D11DeviceContext **pp_d3dcontext)
+{
+#if !VLC_WINSTORE_APP
+# define D3D11CreateDevice(args...)             pf_CreateDevice(args)
+    /* */
+    PFN_D3D11_CREATE_DEVICE pf_CreateDevice;
+    pf_CreateDevice = (void *)GetProcAddress(hdecoder_dll, "D3D11CreateDevice");
+    if (!pf_CreateDevice) {
+        msg_Err(obj, "Cannot locate reference to D3D11CreateDevice ABI in DLL");
+        return E_NOINTERFACE;
+    }
+#endif
+
+    HRESULT hr = E_NOTIMPL;
+    UINT creationFlags = 0;
+
+    if (hw_decoding)
+        creationFlags |= D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
+
+#if !defined(NDEBUG)
+# if !VLC_WINSTORE_APP
+    if (IsDebuggerPresent())
+# endif
+    {
+        HINSTANCE sdklayer_dll = LoadLibrary(TEXT("d3d11_1sdklayers.dll"));
+        if (sdklayer_dll) {
+            creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
+            FreeLibrary(sdklayer_dll);
+        }
+    }
+#endif
+
+    static const D3D_DRIVER_TYPE driverAttempts[] = {
+        D3D_DRIVER_TYPE_HARDWARE,
+        D3D_DRIVER_TYPE_WARP,
+#if 0 /* ifndef NDEBUG */
+        D3D_DRIVER_TYPE_REFERENCE,
+#endif
+    };
+
+    static D3D_FEATURE_LEVEL D3D11_features[] = {
+        D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
+        D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0,
+        D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1
+    };
+
+    for (UINT driver = 0; driver < ARRAYSIZE(driverAttempts); driver++) {
+        D3D_FEATURE_LEVEL i_feature_level;
+        hr = D3D11CreateDevice(NULL, driverAttempts[driver], NULL, creationFlags,
+                    D3D11_features, ARRAY_SIZE(D3D11_features), D3D11_SDK_VERSION,
+                    pp_d3ddevice, &i_feature_level, pp_d3dcontext);
+        if (SUCCEEDED(hr)) {
+#ifndef NDEBUG
+            msg_Dbg(obj, "Created the D3D11 device 0x%p ctx 0x%p type %d level %x.",
+                    (void *)*pp_d3ddevice, (void *)*pp_d3dcontext,
+                    driverAttempts[driver], i_feature_level);
+#endif
+            if ( obj->obj.force || i_feature_level >= D3D_FEATURE_LEVEL_11_1 )
+                break;
+            ID3D11DeviceContext_Release(*pp_d3dcontext);
+            *pp_d3dcontext = NULL;
+            ID3D11Device_Release(*pp_d3ddevice);
+            *pp_d3ddevice = NULL;
+        }
+    }
+    return hr;
+}
+
 #endif /* include-guard */
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 10494f99d4..15ce7c63ed 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -1587,26 +1587,8 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
     IDXGIFactory2 *dxgifactory;
 
 #if !VLC_WINSTORE_APP
-
-    UINT creationFlags = 0;
     HRESULT hr = S_OK;
 
-# if !defined(NDEBUG)
-#  if !VLC_WINSTORE_APP
-    if (IsDebuggerPresent())
-#  endif
-    {
-        HINSTANCE sdklayer_dll = LoadLibrary(TEXT("d3d11_1sdklayers.dll"));
-        if (sdklayer_dll) {
-            creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
-            FreeLibrary(sdklayer_dll);
-        }
-    }
-# endif
-
-    if (is_d3d11_opaque(fmt->i_chroma))
-        creationFlags |= D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
-
     DXGI_SWAP_CHAIN_DESC1 scd;
     memset(&scd, 0, sizeof(scd));
     scd.BufferCount = 3;
@@ -1627,40 +1609,9 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
     //scd.Flags = 512; // DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO;
     scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
 
-    static const D3D_DRIVER_TYPE driverAttempts[] = {
-        D3D_DRIVER_TYPE_HARDWARE,
-        D3D_DRIVER_TYPE_WARP,
-#if 0 /* ifndef NDEBUG */
-        D3D_DRIVER_TYPE_REFERENCE,
-#endif
-    };
-
-    D3D_FEATURE_LEVEL features[] = {
-       D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
-       D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0,
-       D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1
-    };
-
-    for (UINT driver = 0; driver < ARRAYSIZE(driverAttempts); driver++) {
-        D3D_FEATURE_LEVEL i_feature_level;
-        hr = D3D11CreateDevice(NULL, driverAttempts[driver], NULL, creationFlags,
-                    features, ARRAY_SIZE(features), D3D11_SDK_VERSION,
-                    &sys->d3ddevice, &i_feature_level, &sys->d3dcontext);
-        if (SUCCEEDED(hr)) {
-#ifndef NDEBUG
-            msg_Dbg(vd, "Created the D3D11 device 0x%p ctx 0x%p type %d level %x.",
-                    (void *)sys->d3ddevice, (void *)sys->d3dcontext,
-                    driverAttempts[driver], i_feature_level);
-#endif
-            if ( vd->obj.force || i_feature_level >= D3D_FEATURE_LEVEL_11_1 )
-                break;
-            ID3D11DeviceContext_Release(sys->d3dcontext);
-            sys->d3dcontext = NULL;
-            ID3D11Device_Release(sys->d3ddevice);
-            sys->d3ddevice = NULL;
-        }
-    }
-
+    hr = D3D11_CreateDevice(VLC_OBJECT(vd), sys->hd3d11_dll,
+                            is_d3d11_opaque(fmt->i_chroma),
+                            &sys->d3ddevice, &sys->d3dcontext);
     if (FAILED(hr)) {
        msg_Err(vd, "Could not Create the D3D11 device. (hr=0x%lX)", hr);
        return VLC_EGENERIC;
-- 
2.14.2



More information about the vlc-devel mailing list