]> git.sesse.net Git - vlc/blobdiff - modules/video_output/msw/direct3d11.c
D3D11: use defines for DXGI
[vlc] / modules / video_output / msw / direct3d11.c
index 18552ee624dae5bc879c7883718a1f8c82306f0b..f98858b76a32986b5e47d43f66237fa25a170551 100644 (file)
@@ -93,7 +93,7 @@ static void Close(vlc_object_t *object);
 static void Prepare(vout_display_t *, picture_t *, subpicture_t *subpicture);
 static void Display(vout_display_t *, picture_t *, subpicture_t *subpicture);
 
-static int  Direct3D11Create (vout_display_t *);
+static HINSTANCE Direct3D11LoadShaderLibrary(void);
 static void Direct3D11Destroy(vout_display_t *);
 
 static int  Direct3D11Open (vout_display_t *, video_format_t *);
@@ -104,9 +104,9 @@ static void Direct3D11DestroyResources(vout_display_t *);
 
 static int  Direct3D11MapTexture(picture_t *);
 
-/* All the #if 0 contain an alternative method to setup dx11
+/* All the #if USE_DXGI contain an alternative method to setup dx11
    They both need to be benchmarked to see which performs better */
-#if 0
+#if USE_DXGI
 /* I have no idea why MS decided dxgi headers do not define this
    As they do have prototypes for d3d11 functions */
 typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
@@ -179,23 +179,107 @@ static const char* globPixelShaderBiplanarYUV2RGB = "\
   }\
 ";
 
+
 static int Open(vlc_object_t *object)
 {
     vout_display_t *vd = (vout_display_t *)object;
 
-    if (Direct3D11Create(vd)) {
-        msg_Err(vd, "Direct3D11 could not be initialized");
+#if !VLC_WINSTORE_APP
+    HINSTANCE hd3d11_dll = LoadLibrary(TEXT("D3D11.DLL"));
+    if (!hd3d11_dll) {
+        msg_Warn(vd, "cannot load d3d11.dll, aborting");
+        return VLC_EGENERIC;
+    }
+
+    HINSTANCE hd3dcompiler_dll = Direct3D11LoadShaderLibrary();
+    if (!hd3dcompiler_dll) {
+        msg_Err(vd, "cannot load d3dcompiler.dll, aborting");
+        FreeLibrary(hd3d11_dll);
+        return VLC_EGENERIC;
+    }
+
+# if USE_DXGI
+    HINSTANCE hdxgi_dll = LoadLibrary(TEXT("DXGI.DLL"));
+    if (!hdxgi_dll) {
+        msg_Warn(vd, "cannot load dxgi.dll, aborting");
+        return VLC_EGENERIC;
+    }
+# endif
+
+#else
+    IDXGISwapChain1* dxgiswapChain  = var_InheritInteger(vd, "winrt-dxgiswapchain");
+    if (!dxgiswapChain)
+        return VLC_EGENERIC;
+    ID3D11Device* d3ddevice         = var_InheritInteger(vd, "winrt-d3ddevice");
+    if (!d3ddevice)
+        return VLC_EGENERIC;
+    ID3D11DeviceContext* d3dcontext = var_InheritInteger(vd, "winrt-d3dcontext");
+    if (!d3dcontext)
+        return VLC_EGENERIC;
+#endif
+
+    vout_display_sys_t *sys = vd->sys = calloc(1, sizeof(vout_display_sys_t));
+    if (!sys)
+        return VLC_ENOMEM;
+
+#if !VLC_WINSTORE_APP
+    sys->hd3d11_dll       = hd3d11_dll;
+    sys->hd3dcompiler_dll = hd3dcompiler_dll;
+
+    sys->OurD3DCompile = (void *)GetProcAddress(sys->hd3dcompiler_dll, "D3DCompile");
+    if (!sys->OurD3DCompile) {
+        msg_Err(vd, "Cannot locate reference to D3DCompile in d3dcompiler DLL");
+        Direct3D11Destroy(vd);
+        return VLC_EGENERIC;
+    }
+
+# if USE_DXGI
+    sys->hdxgi_dll = hdxgi_dll;
+
+    /* TODO : enable all dxgi versions from 1.3 -> 1.1 */
+    PFN_CREATE_DXGI_FACTORY OurCreateDXGIFactory =
+        (void *)GetProcAddress(sys->hdxgi_dll, "CreateDXGIFactory");
+    if (!OurCreateDXGIFactory) {
+        msg_Err(vd, "Cannot locate reference to CreateDXGIFactory in dxgi DLL");
         Direct3D11Destroy(vd);
         return VLC_EGENERIC;
     }
 
+    /* TODO : detect the directx version supported and use IID_IDXGIFactory3 or 2 */
+    HRESULT hr = OurCreateDXGIFactory(&IID_IDXGIFactory, (void **)&sys->dxgifactory);
+    if (FAILED(hr)) {
+        msg_Err(vd, "Could not create dxgi factory. (hr=0x%lX)", hr);
+        Direct3D11Destroy(vd);
+        return VLC_EGENERIC;
+    }
+
+    sys->OurD3D11CreateDeviceAndSwapChain =
+        (void *)GetProcAddress(sys->hd3d11_dll, "D3D11CreateDeviceAndSwapChain");
+    if (!sys->OurD3D11CreateDeviceAndSwapChain) {
+        msg_Err(vd, "Cannot locate reference to D3D11CreateDeviceAndSwapChain in d3d11 DLL");
+        Direct3D11Destroy(vd);
+        return VLC_EGENERIC;
+    }
+
+# else
+    sys->OurD3D11CreateDevice =
+        (void *)GetProcAddress(sys->hd3d11_dll, "D3D11CreateDevice");
+    if (!sys->OurD3D11CreateDevice) {
+        msg_Err(vd, "Cannot locate reference to D3D11CreateDevice in d3d11 DLL");
+        Direct3D11Destroy(vd);
+        return VLC_EGENERIC;
+    }
+# endif
+
+#else
+    sys->dxgiswapChain = dxgiswapChain;
+    sys->d3ddevice     = d3ddevice;
+    sys->d3dcontext    = d3dcontext;
+#endif
+
     if (CommonInit(vd))
         goto error;
 
-    /* TODO : A fallback system */
-    vd->sys->d3dFormat = d3d_formats[0].format;
-    vd->sys->vlcFormat = d3d_formats[0].fourcc;
-
     video_format_t fmt;
     if (Direct3D11Open(vd, &fmt)) {
         msg_Err(vd, "Direct3D11 could not be opened");
@@ -278,124 +362,6 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
     CommonDisplay(vd);
 }
 
-#if !VLC_WINSTORE_APP
-static HINSTANCE Direct3D11LoadShaderLibrary(void)
-{
-    HINSTANCE instance = NULL;
-    /* d3dcompiler_47 is the latest on windows 8.1 */
-    for (int i = 47; i > 41; --i) {
-        TCHAR filename[18];
-        _sntprintf(filename, 18, TEXT("D3DCOMPILER_%d.dll"), i);
-        instance = LoadLibrary(filename);
-        if (instance) break;
-    }
-    return instance;
-}
-#endif
-
-static int Direct3D11Create(vout_display_t *vd)
-{
-
-#if !VLC_WINSTORE_APP
-
-    HINSTANCE hd3d11_dll = LoadLibrary(TEXT("D3D11.DLL"));
-    if (!hd3d11_dll) {
-        msg_Warn(vd, "cannot load d3d11.dll, aborting");
-        return VLC_EGENERIC;
-    }
-
-# if 0
-    HINSTANCE hdxgi_dll = LoadLibrary(TEXT("DXGI.DLL"));
-    if (!hdxgi_dll) {
-        msg_Warn(vd, "cannot load dxgi.dll, aborting");
-        return VLC_EGENERIC;
-    }
-# endif
-
-    HINSTANCE hd3dcompiler_dll = Direct3D11LoadShaderLibrary();
-    if (!hd3dcompiler_dll) {
-        msg_Err(vd, "cannot load d3dcompiler.dll, aborting");
-        return VLC_EGENERIC;
-    }
-
-#else
-
-    IDXGISwapChain1* dxgiswapChain  = var_InheritInteger(vd, "winrt-dxgiswapchain");
-    if (!dxgiswapChain)
-        return VLC_EGENERIC;
-    ID3D11Device* d3ddevice         = var_InheritInteger(vd, "winrt-d3ddevice");
-    if (!d3ddevice)
-        return VLC_EGENERIC;
-    ID3D11DeviceContext* d3dcontext = var_InheritInteger(vd, "winrt-d3dcontext");
-    if (!d3dcontext)
-        return VLC_EGENERIC;
-
-#endif
-
-    vout_display_sys_t *sys = vd->sys = calloc(1, sizeof(vout_display_sys_t));
-    if (!sys)
-        return VLC_ENOMEM;
-
-#if !VLC_WINSTORE_APP
-
-    sys->hd3d11_dll       = hd3d11_dll;
-    sys->hd3dcompiler_dll = hd3dcompiler_dll;
-
-    sys->OurD3DCompile = (void *)GetProcAddress(sys->hd3dcompiler_dll, "D3DCompile");
-    if (!sys->OurD3DCompile) {
-        msg_Err(vd, "Cannot locate reference to D3DCompile in d3dcompiler DLL");
-        return VLC_EGENERIC;
-    }
-
-# if 0
-
-    sys->hdxgi_dll = hdxgi_dll;
-
-    /* TODO : enable all dxgi versions from 1.3 -> 1.1 */
-    PFN_CREATE_DXGI_FACTORY OurCreateDXGIFactory =
-        (void *)GetProcAddress(sys->hdxgi_dll, "CreateDXGIFactory");
-    if (!OurCreateDXGIFactory) {
-        msg_Err(vd, "Cannot locate reference to CreateDXGIFactory in dxgi DLL");
-        return VLC_EGENERIC;
-    }
-
-    /* TODO : detect the directx version supported and use IID_IDXGIFactory3 or 2 */
-    HRESULT hr = OurCreateDXGIFactory(&IID_IDXGIFactory, (void **)&sys->dxgifactory);
-    if (FAILED(hr)) {
-        msg_Err(vd, "Could not create dxgi factory. (hr=0x%lX)", hr);
-        return VLC_EGENERIC;
-    }
-
-    sys->OurD3D11CreateDeviceAndSwapChain =
-        (void *)GetProcAddress(sys->hd3d11_dll, "D3D11CreateDeviceAndSwapChain");
-    if (!sys->OurD3D11CreateDeviceAndSwapChain) {
-        msg_Err(vd, "Cannot locate reference to D3D11CreateDeviceAndSwapChain in d3d11 DLL");
-        return VLC_EGENERIC;
-    }
-
-# else
-
-    sys->OurD3D11CreateDevice =
-        (void *)GetProcAddress(sys->hd3d11_dll, "D3D11CreateDevice");
-    if (!sys->OurD3D11CreateDevice) {
-        msg_Err(vd, "Cannot locate reference to D3D11CreateDevice in d3d11 DLL");
-        return VLC_EGENERIC;
-    }
-
-# endif
-
-#else
-
-    sys->dxgiswapChain = dxgiswapChain;
-    sys->d3ddevice     = d3ddevice;
-    sys->d3dcontext    = d3dcontext;
-
-#endif
-
-    return VLC_SUCCESS;
-}
-
-
 static void Direct3D11Destroy(vout_display_t *vd)
 {
 
@@ -403,7 +369,7 @@ static void Direct3D11Destroy(vout_display_t *vd)
 
     vout_display_sys_t *sys = vd->sys;
 
-# if 0
+# if USE_DXGI
     if (sys->hdxgi_dll)
         FreeLibrary(sys->hdxgi_dll);
 # endif
@@ -426,8 +392,23 @@ static void Direct3D11Destroy(vout_display_t *vd)
     VLC_UNUSED(vd);
 
 #endif
+}
 
+#if !VLC_WINSTORE_APP
+static HINSTANCE Direct3D11LoadShaderLibrary(void)
+{
+    HINSTANCE instance = NULL;
+    /* d3dcompiler_47 is the latest on windows 8.1 */
+    for (int i = 47; i > 41; --i) {
+        TCHAR filename[19];
+        _sntprintf(filename, 19, TEXT("D3DCOMPILER_%d.dll"), i);
+        instance = LoadLibrary(filename);
+        if (instance) break;
+    }
+    return instance;
 }
+#endif
+
 
 static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
 {
@@ -450,7 +431,7 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
         D3D_FEATURE_LEVEL_9_1
     };
 
-# ifndef NDEBUG
+# if !defined(NDEBUG) && defined(_MSC_VER)
     creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
 # endif
 
@@ -477,7 +458,7 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
     scd.OutputWindow = sys->hvideownd;
 # endif
 
-# if 0
+# if USE_DXGI
 
     /* TODO : list adapters for the user to choose from */
     hr = IDXGIFactory_EnumAdapters(sys->dxgifactory, 0, &sys->dxgiadapter);
@@ -586,6 +567,25 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
 # endif
 #endif
 
+    for (unsigned i = 0; d3d_formats[i].name != 0; i++)
+    {
+        UINT i_formatSupport;
+        if( SUCCEEDED( ID3D11Device_CheckFormatSupport(sys->d3ddevice,
+                                                       d3d_formats[i].format,
+                                                       &i_formatSupport)) &&
+                ( i_formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D ))
+        {
+            msg_Dbg(vd, "Using pixel format %s", d3d_formats[i].name );
+            sys->d3dFormat = d3d_formats[i].format;
+            sys->vlcFormat = d3d_formats[i].fourcc;
+            break;
+        }
+    }
+    if ( !sys->vlcFormat ) {
+       msg_Err(vd, "Could not get a suitable texture pixel format");
+       return VLC_EGENERIC;
+    }
+
     UpdateRects(vd, NULL, NULL, true);
 
     if (Direct3D11CreateResources(vd, fmt)) {
@@ -605,8 +605,10 @@ static void Direct3D11Close(vout_display_t *vd)
     vout_display_sys_t *sys = vd->sys;
 
     Direct3D11DestroyResources(vd);
-    ID3D11DeviceContext_Release(sys->d3dcontext);
-    ID3D11Device_Release(sys->d3ddevice);
+    if ( sys->d3dcontext )
+        ID3D11DeviceContext_Release(sys->d3dcontext);
+    if ( sys->d3ddevice )
+        ID3D11Device_Release(sys->d3ddevice);
     msg_Dbg(vd, "Direct3D11 device adapter closed");
 }
 
@@ -825,17 +827,17 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
 
     D3D11_SHADER_RESOURCE_VIEW_DESC resviewDesc;
     memset(&resviewDesc, 0, sizeof(resviewDesc));
-    resviewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
-    resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
-    resviewDesc.Texture2D.MipLevels = texDesc.MipLevels;
-
     if (sys->vlcFormat == VLC_CODEC_NV12)
         resviewDesc.Format = DXGI_FORMAT_R8_UNORM;
+    else
+        resviewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+    resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+    resviewDesc.Texture2D.MipLevels = texDesc.MipLevels;
 
     hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewY);
     if (FAILED(hr)) {
         if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
-        msg_Err(vd, "Could not Create the Y D3d11 Texture ResoureView. (hr=0x%lX)", hr);
+        msg_Err(vd, "Could not Create the Y D3d11 Texture ResourceView. (hr=0x%lX)", hr);
         return VLC_EGENERIC;
     }
 
@@ -844,7 +846,7 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
         hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewUV);
         if (FAILED(hr)) {
             if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
-            msg_Err(vd, "Could not Create the U D3d11 Texture ResoureView. (hr=0x%lX)", hr);
+            msg_Err(vd, "Could not Create the UV D3d11 Texture ResourceView. (hr=0x%lX)", hr);
             return VLC_EGENERIC;
         }
     }