diff --git a/sys/d3d11/gstd3d11shader.c b/sys/d3d11/gstd3d11shader.c index 38a65230e0..d2ab639ac8 100644 --- a/sys/d3d11/gstd3d11shader.c +++ b/sys/d3d11/gstd3d11shader.c @@ -24,10 +24,61 @@ #include "gstd3d11shader.h" #include "gstd3d11device.h" #include "gstd3d11utils.h" +#include GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_shader_debug); #define GST_CAT_DEFAULT gst_d3d11_shader_debug +static GModule *d3d_compiler_module = NULL; +static pD3DCompile GstD3DCompileFunc = NULL; + +gboolean +gst_d3d11_shader_init (void) +{ + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { +#if GST_D3D11_WINAPI_ONLY_APP + /* Assuming that d3d compiler library is available */ + GstD3DCompileFunc = D3DCompile; +#else + static const gchar *d3d_compiler_names[] = { + "d3dcompiler_47.dll", + "d3dcompiler_46.dll", + "d3dcompiler_45.dll", + "d3dcompiler_44.dll", + "d3dcompiler_43.dll", + }; + gint i; + for (i = 0; i < G_N_ELEMENTS (d3d_compiler_names); i++) { + d3d_compiler_module = + g_module_open (d3d_compiler_names[i], G_MODULE_BIND_LAZY); + + if (d3d_compiler_module) { + GST_INFO ("D3D compiler %s is available", d3d_compiler_names[i]); + if (!g_module_symbol (d3d_compiler_module, "D3DCompile", + (gpointer *) & GstD3DCompileFunc)) { + GST_ERROR ("Cannot load D3DCompile symbol from %s", + d3d_compiler_names[i]); + g_module_close (d3d_compiler_module); + d3d_compiler_module = NULL; + GstD3DCompileFunc = NULL; + } else { + break; + } + } + } + + if (!GstD3DCompileFunc) + GST_WARNING ("D3D11 compiler library is unavailable"); +#endif + + g_once_init_leave (&_init, 1); + } + + return ! !GstD3DCompileFunc; +} + static ID3DBlob * compile_shader (GstD3D11Device * device, const gchar * shader_source, gboolean is_pixel_shader) @@ -38,6 +89,11 @@ compile_shader (GstD3D11Device * device, const gchar * shader_source, D3D_FEATURE_LEVEL feature_level; HRESULT hr; + if (!gst_d3d11_shader_init ()) { + GST_ERROR ("D3DCompiler is unavailable"); + return NULL; + } + feature_level = gst_d3d11_device_get_chosen_feature_level (device); if (is_pixel_shader) { @@ -56,8 +112,10 @@ compile_shader (GstD3D11Device * device, const gchar * shader_source, shader_target = "vs_4_0_level_9_1"; } - hr = D3DCompile (shader_source, strlen (shader_source), NULL, NULL, NULL, - "main", shader_target, 0, 0, &ret, &error); + g_assert (GstD3DCompileFunc); + + hr = GstD3DCompileFunc (shader_source, strlen (shader_source), NULL, NULL, + NULL, "main", shader_target, 0, 0, &ret, &error); if (!gst_d3d11_result (hr, device)) { const gchar *err = NULL; diff --git a/sys/d3d11/gstd3d11shader.h b/sys/d3d11/gstd3d11shader.h index 4d9e166a00..4c1e062f78 100644 --- a/sys/d3d11/gstd3d11shader.h +++ b/sys/d3d11/gstd3d11shader.h @@ -30,6 +30,8 @@ G_BEGIN_DECLS typedef struct _GstD3D11Quad GstD3D11Quad; +gboolean gst_d3d11_shader_init (void); + gboolean gst_d3d11_create_pixel_shader (GstD3D11Device * device, const gchar * source, ID3D11PixelShader ** shader); diff --git a/sys/d3d11/meson.build b/sys/d3d11/meson.build index f634e1d450..9f911603e4 100644 --- a/sys/d3d11/meson.build +++ b/sys/d3d11/meson.build @@ -110,10 +110,6 @@ if get_option('debug') set_variable(f.get(3), true) endif endforeach - - if have_d3d11sdk_h or have_dxgidebug_h - extra_dep += [gmodule_dep] - endif endif d3d11_conf.set10('HAVE_D3D11SDKLAYERS_H', have_d3d11sdk_h) @@ -134,7 +130,7 @@ winapi_desktop = cxx.compiles('''#include dependencies: [d3d11_lib, dxgi_lib], name: 'checking if building for Win32') -if runtimeobject_lib.found() +if runtimeobject_lib.found() and d3dcompiler_lib.found() winapi_app = cxx.compiles('''#include #include #include @@ -157,7 +153,7 @@ winapi_app_only = winapi_app and not winapi_desktop if winapi_app_only d3d11_sources += ['gstd3d11window_corewindow.cpp', 'gstd3d11window_swapchainpanel.cpp'] - extra_dep += [runtimeobject_lib] + extra_dep += [runtimeobject_lib, d3dcompiler_lib] else d3d11_sources += ['gstd3d11window_win32.cpp'] endif @@ -174,7 +170,7 @@ gstd3d11 = library('gstd3d11', c_args : gst_plugins_bad_args + extra_c_args, cpp_args: gst_plugins_bad_args, include_directories : [configinc], - dependencies : [gstbase_dep, gstvideo_dep, d3d11_lib, dxgi_lib, d3dcompiler_lib] + extra_dep, + dependencies : [gstbase_dep, gstvideo_dep, gmodule_dep, d3d11_lib, dxgi_lib] + extra_dep, install : true, install_dir : plugins_install_dir, ) diff --git a/sys/d3d11/plugin.c b/sys/d3d11/plugin.c index e4cd3a7fbe..d00a2592ee 100644 --- a/sys/d3d11/plugin.c +++ b/sys/d3d11/plugin.c @@ -29,6 +29,7 @@ #include "gstd3d11download.h" #include "gstd3d11colorconvert.h" #include "gstd3d11videosinkbin.h" +#include "gstd3d11shader.h" #ifdef HAVE_DXVA_H #include "gstd3d11utils.h" #include "gstd3d11h264dec.h" @@ -37,6 +38,7 @@ #include "gstd3d11vp8dec.h" #endif +GST_DEBUG_CATEGORY (gst_d3d11_debug); GST_DEBUG_CATEGORY (gst_d3d11_shader_debug); GST_DEBUG_CATEGORY (gst_d3d11_colorconverter_debug); GST_DEBUG_CATEGORY (gst_d3d11_utils_debug); @@ -57,9 +59,12 @@ GST_DEBUG_CATEGORY (gst_d3d11_vp9_dec_debug); GST_DEBUG_CATEGORY (gst_d3d11_vp8_dec_debug); #endif +#define GST_CAT_DEFAULT gst_d3d11_debug + static gboolean plugin_init (GstPlugin * plugin) { + GST_DEBUG_CATEGORY_INIT (gst_d3d11_debug, "d3d11", 0, "direct3d 11 plugin"); GST_DEBUG_CATEGORY_INIT (gst_d3d11_shader_debug, "d3d11shader", 0, "d3d11shader"); GST_DEBUG_CATEGORY_INIT (gst_d3d11_colorconverter_debug, @@ -83,6 +88,11 @@ plugin_init (GstPlugin * plugin) "d3d11debuglayer", 0, "native d3d11 and dxgi debug"); #endif + if (!gst_d3d11_shader_init ()) { + GST_WARNING ("Cannot initialize d3d11 shader"); + return TRUE; + } + gst_element_register (plugin, "d3d11upload", GST_RANK_NONE, GST_TYPE_D3D11_UPLOAD); gst_element_register (plugin,