Skip to content
Snippets Groups Projects
Commit 3125a4a8 authored by Martin Storsjö's avatar Martin Storsjö Committed by wm4
Browse files

d3d11va: Link directly to dxgi.dll and d3d11.dll functions if LoadLibrary is unavailable


When targeting the UWP API subset, the LoadLibrary function is not
available (and the fallback, LoadPackagedLibrary, can't be used to
load system DLLs). In these cases, link directly to the functions
in the DLLs instead of trying to load them dynamically at runtime.

Merges Libav commit fd1ffa1f.

Signed-off-by: default avatarMartin Storsjö <martin@martin.st>
parent 70143a39
No related branches found
No related tags found
No related merge requests found
...@@ -6120,6 +6120,10 @@ fi ...@@ -6120,6 +6120,10 @@ fi
check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs" check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs"
# d3d11va requires linking directly to dxgi and d3d11 if not building for
# the desktop api partition
enabled LoadLibrary || d3d11va_extralibs="-ldxgi -ld3d11"
enabled vaapi && enabled vaapi &&
check_lib vaapi va/va.h vaInitialize -lva check_lib vaapi va/va.h vaInitialize -lva
......
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
#include <windows.h> #include <windows.h>
// Include thread.h before redefining _WIN32_WINNT, to get
// the right implementation for AVOnce
#include "thread.h"
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
#undef _WIN32_WINNT #undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600 #define _WIN32_WINNT 0x0600
...@@ -39,6 +43,34 @@ ...@@ -39,6 +43,34 @@
typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory); typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
static AVOnce functions_loaded = AV_ONCE_INIT;
static PFN_CREATE_DXGI_FACTORY mCreateDXGIFactory;
static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice;
static av_cold void load_functions(void)
{
#if HAVE_LOADLIBRARY
// We let these "leak" - this is fine, as unloading has no great benefit, and
// Windows will mark a DLL as loaded forever if its internal refcount overflows
// from too many LoadLibrary calls.
HANDLE d3dlib, dxgilib;
d3dlib = LoadLibrary("d3d11.dll");
dxgilib = LoadLibrary("dxgi.dll");
if (!d3dlib || !dxgilib)
return;
mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) GetProcAddress(d3dlib, "D3D11CreateDevice");
mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) GetProcAddress(dxgilib, "CreateDXGIFactory");
#else
// In UWP (which lacks LoadLibrary), CreateDXGIFactory isn't available,
// only CreateDXGIFactory1
mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) D3D11CreateDevice;
mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) CreateDXGIFactory1;
#endif
}
typedef struct D3D11VAFramesContext { typedef struct D3D11VAFramesContext {
int nb_surfaces_used; int nb_surfaces_used;
...@@ -407,50 +439,32 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, ...@@ -407,50 +439,32 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
AVDictionary *opts, int flags) AVDictionary *opts, int flags)
{ {
AVD3D11VADeviceContext *device_hwctx = ctx->hwctx; AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
HANDLE d3dlib;
HRESULT hr; HRESULT hr;
PFN_D3D11_CREATE_DEVICE createD3D;
IDXGIAdapter *pAdapter = NULL; IDXGIAdapter *pAdapter = NULL;
ID3D10Multithread *pMultithread; ID3D10Multithread *pMultithread;
UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
int ret;
if (device) { if ((ret = ff_thread_once(&functions_loaded, load_functions)) != 0)
PFN_CREATE_DXGI_FACTORY mCreateDXGIFactory; return AVERROR_UNKNOWN;
HMODULE dxgilib = LoadLibrary("dxgi.dll"); if (!mD3D11CreateDevice || !mCreateDXGIFactory) {
if (!dxgilib) av_log(ctx, AV_LOG_ERROR, "Failed to load D3D11 library or its functions\n");
return AVERROR_UNKNOWN;
mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) GetProcAddress(dxgilib, "CreateDXGIFactory");
if (mCreateDXGIFactory) {
IDXGIFactory2 *pDXGIFactory;
hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory);
if (SUCCEEDED(hr)) {
int adapter = atoi(device);
if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
pAdapter = NULL;
IDXGIFactory2_Release(pDXGIFactory);
}
}
FreeLibrary(dxgilib);
}
// We let this "leak" - this is fine, as unloading has no great benefit, and
// Windows will mark a DLL as loaded forever if its internal refcount overflows
// from too many LoadLibrary calls.
d3dlib = LoadLibrary("d3d11.dll");
if (!d3dlib) {
av_log(ctx, AV_LOG_ERROR, "Failed to load D3D11 library\n");
return AVERROR_UNKNOWN; return AVERROR_UNKNOWN;
} }
createD3D = (PFN_D3D11_CREATE_DEVICE) GetProcAddress(d3dlib, "D3D11CreateDevice"); if (device) {
if (!createD3D) { IDXGIFactory2 *pDXGIFactory;
av_log(ctx, AV_LOG_ERROR, "Failed to locate D3D11CreateDevice\n"); hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory);
return AVERROR_UNKNOWN; if (SUCCEEDED(hr)) {
int adapter = atoi(device);
if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
pAdapter = NULL;
IDXGIFactory2_Release(pDXGIFactory);
}
} }
hr = createD3D(pAdapter, pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0, hr = mD3D11CreateDevice(pAdapter, pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0,
D3D11_SDK_VERSION, &device_hwctx->device, NULL, NULL); D3D11_SDK_VERSION, &device_hwctx->device, NULL, NULL);
if (pAdapter) if (pAdapter)
IDXGIAdapter_Release(pAdapter); IDXGIAdapter_Release(pAdapter);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment