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 *);
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);
}\
";
+
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");
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)
{
vout_display_sys_t *sys = vd->sys;
-# if 0
+# if USE_DXGI
if (sys->hdxgi_dll)
FreeLibrary(sys->hdxgi_dll);
# endif
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)
{
D3D_FEATURE_LEVEL_9_1
};
-# ifndef NDEBUG
+# if !defined(NDEBUG) && defined(_MSC_VER)
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
# endif
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);
# 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)) {
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");
}
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;
}
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;
}
}