d3d11: Load HLSL compiler library using g_module_open
authorSeungha Yang <seungha@centricular.com>
Fri, 19 Jun 2020 12:24:59 +0000 (21:24 +0900)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 22 Jun 2020 14:36:16 +0000 (14:36 +0000)
Depending on OS version, available d3dcompiler library name is different.
But for UWP, we can still use the current way

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1355>

sys/d3d11/gstd3d11shader.c
sys/d3d11/gstd3d11shader.h
sys/d3d11/meson.build
sys/d3d11/plugin.c

index 38a6523..d2ab639 100644 (file)
 #include "gstd3d11shader.h"
 #include "gstd3d11device.h"
 #include "gstd3d11utils.h"
+#include <gmodule.h>
 
 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;
index 4d9e166..4c1e062 100644 (file)
@@ -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);
index f634e1d..9f91160 100644 (file)
@@ -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 <winapifamily.h>
     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 <winapifamily.h>
       #include <windows.applicationmodel.core.h>
       #include <wrl.h>
@@ -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,
 )
index e4cd3a7..d00a259 100644 (file)
@@ -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,