d3d11: Enable dxgi debug layer and always try to pop d3d11/dxgi debug message if...
authorSeungha Yang <seungha.yang@navercorp.com>
Fri, 20 Dec 2019 09:56:08 +0000 (18:56 +0900)
committerSeungha Yang <seungha.yang@navercorp.com>
Tue, 24 Dec 2019 10:00:40 +0000 (19:00 +0900)
Note that dxgi and d3d11 sdk debug will be enabled on debug build

13 files changed:
sys/d3d11/gstd3d11colorconvert.c
sys/d3d11/gstd3d11colorconverter.c
sys/d3d11/gstd3d11device.c
sys/d3d11/gstd3d11device.h
sys/d3d11/gstd3d11memory.c
sys/d3d11/gstd3d11shader.c
sys/d3d11/gstd3d11upload.c
sys/d3d11/gstd3d11utils.c
sys/d3d11/gstd3d11utils.h
sys/d3d11/gstd3d11videosink.c
sys/d3d11/gstd3d11window.c
sys/d3d11/meson.build
sys/d3d11/plugin.c

index 3541a2d..f163d31 100644 (file)
@@ -527,7 +527,7 @@ create_shader_input_resource (GstD3D11ColorConvert * self,
 
       hr = ID3D11Device_CreateTexture2D (device_handle,
           &texture_desc, NULL, &tex[i]);
-      if (!gst_d3d11_result (hr)) {
+      if (!gst_d3d11_result (hr, device)) {
         GST_ERROR_OBJECT (self, "Failed to create texture (0x%x)", (guint) hr);
         goto error;
       }
@@ -539,7 +539,7 @@ create_shader_input_resource (GstD3D11ColorConvert * self,
 
     hr = ID3D11Device_CreateTexture2D (device_handle,
         &texture_desc, NULL, &tex[0]);
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, device)) {
       GST_ERROR_OBJECT (self, "Failed to create texture (0x%x)", (guint) hr);
       goto error;
     }
@@ -562,7 +562,7 @@ create_shader_input_resource (GstD3D11ColorConvert * self,
     hr = ID3D11Device_CreateShaderResourceView (device_handle,
         (ID3D11Resource *) tex[i], &view_desc, &view[i]);
 
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, device)) {
       GST_ERROR_OBJECT (self,
           "Failed to create resource view (0x%x)", (guint) hr);
       goto error;
@@ -631,7 +631,7 @@ create_shader_output_resource (GstD3D11ColorConvert * self,
 
       hr = ID3D11Device_CreateTexture2D (device_handle,
           &texture_desc, NULL, &tex[i]);
-      if (!gst_d3d11_result (hr)) {
+      if (!gst_d3d11_result (hr, device)) {
         GST_ERROR_OBJECT (self, "Failed to create texture (0x%x)", (guint) hr);
         goto error;
       }
@@ -643,7 +643,7 @@ create_shader_output_resource (GstD3D11ColorConvert * self,
 
     hr = ID3D11Device_CreateTexture2D (device_handle,
         &texture_desc, NULL, &tex[0]);
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, device)) {
       GST_ERROR_OBJECT (self, "Failed to create texture (0x%x)", (guint) hr);
       goto error;
     }
@@ -664,7 +664,7 @@ create_shader_output_resource (GstD3D11ColorConvert * self,
     view_desc.Format = format->resource_format[i];
     hr = ID3D11Device_CreateRenderTargetView (device_handle,
         (ID3D11Resource *) tex[i], &view_desc, &view[i]);
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, device)) {
       GST_ERROR_OBJECT (self,
           "Failed to create %dth render target view (0x%x)", i, (guint) hr);
       goto error;
index 9897e78..3d330ed 100644 (file)
@@ -567,7 +567,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Device * device,
   sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;
 
   hr = ID3D11Device_CreateSamplerState (device_handle, &sampler_desc, &sampler);
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("Couldn't create sampler state, hr: 0x%x", (guint) hr);
     data->ret = FALSE;
     goto clear;
@@ -604,7 +604,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Device * device,
     hr = ID3D11Device_CreateBuffer (device_handle, &const_buffer_desc, NULL,
         &const_buffer);
 
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, device)) {
       GST_ERROR ("Couldn't create constant buffer, hr: 0x%x", (guint) hr);
       data->ret = FALSE;
       goto clear;
@@ -614,7 +614,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Device * device,
     hr = ID3D11DeviceContext_Map (context_handle,
         (ID3D11Resource *) const_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
 
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, device)) {
       GST_ERROR ("Couldn't map constant buffer, hr: 0x%x", (guint) hr);
       data->ret = FALSE;
       gst_d3d11_device_unlock (device);
@@ -661,7 +661,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Device * device,
   hr = ID3D11Device_CreateBuffer (device_handle, &buffer_desc, NULL,
       &vertex_buffer);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("Couldn't create vertex buffer, hr: 0x%x", (guint) hr);
     data->ret = FALSE;
     goto clear;
@@ -675,7 +675,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Device * device,
   hr = ID3D11Device_CreateBuffer (device_handle, &buffer_desc, NULL,
       &index_buffer);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("Couldn't create index buffer, hr: 0x%x", (guint) hr);
     data->ret = FALSE;
     goto clear;
@@ -685,7 +685,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Device * device,
   hr = ID3D11DeviceContext_Map (context_handle,
       (ID3D11Resource *) vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("Couldn't map vertex buffer, hr: 0x%x", (guint) hr);
     data->ret = FALSE;
     gst_d3d11_device_unlock (device);
@@ -697,7 +697,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Device * device,
   hr = ID3D11DeviceContext_Map (context_handle,
       (ID3D11Resource *) index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("Couldn't map index buffer, hr: 0x%x", (guint) hr);
     ID3D11DeviceContext_Unmap (context_handle,
         (ID3D11Resource *) vertex_buffer, 0);
index d18e3f0..7f09631 100644 (file)
 #include "gstd3d11utils.h"
 #include "gmodule.h"
 
-#ifdef HAVE_D3D11SDKLAYER_H
+#if HAVE_D3D11SDKLAYERS_H
 #include <d3d11sdklayers.h>
-#endif
-
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
-GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_device_debug);
-#define GST_CAT_DEFAULT gst_d3d11_device_debug
-
-#ifdef HAVE_D3D11SDKLAYER_H
-static GModule *sdk_layer = NULL;
+static GModule *d3d11_debug_module = NULL;
 
 /* mingw header does not define D3D11_RLDO_IGNORE_INTERNAL
  * D3D11_RLDO_SUMMARY = 0x1,
@@ -46,6 +39,21 @@ static GModule *sdk_layer = NULL;
 #define GST_D3D11_RLDO_FLAGS (0x2 | 0x4)
 #endif
 
+#if HAVE_DXGIDEBUG_H
+#include <dxgidebug.h>
+typedef HRESULT (WINAPI * DXGIGetDebugInterface_t) (REFIID riid,
+    void **ppDebug);
+static GModule *dxgi_debug_module = NULL;
+static DXGIGetDebugInterface_t GstDXGIGetDebugInterface = NULL;
+
+#endif
+
+#if (HAVE_D3D11SDKLAYERS_H || HAVE_DXGIDEBUG_H)
+GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_debug_layer_debug);
+#endif
+GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_device_debug);
+#define GST_CAT_DEFAULT gst_d3d11_device_debug
+
 enum
 {
   PROP_0,
@@ -77,9 +85,14 @@ struct _GstD3D11DevicePrivate
 
   GRecMutex extern_lock;
 
-#ifdef HAVE_D3D11SDKLAYER_H
-  ID3D11Debug *debug;
-  ID3D11InfoQueue *info_queue;
+#if HAVE_D3D11SDKLAYERS_H
+  ID3D11Debug *d3d11_debug;
+  ID3D11InfoQueue *d3d11_info_queue;
+#endif
+
+#if HAVE_DXGIDEBUG_H
+  IDXGIDebug *dxgi_debug;
+  IDXGIInfoQueue *dxgi_info_queue;
 #endif
 };
 
@@ -94,52 +107,181 @@ static void gst_d3d11_device_constructed (GObject * object);
 static void gst_d3d11_device_dispose (GObject * object);
 static void gst_d3d11_device_finalize (GObject * object);
 
-#ifdef HAVE_D3D11SDKLAYER_H
+#if HAVE_D3D11SDKLAYERS_H
 static gboolean
-gst_d3d11_device_enable_debug_layer (void)
+gst_d3d11_device_enable_d3d11_debug (void)
 {
   static volatile gsize _init = 0;
 
+  /* If all below libraries are unavailable, d3d11 device would fail with
+   * D3D11_CREATE_DEVICE_DEBUG flag */
   if (g_once_init_enter (&_init)) {
-    sdk_layer = g_module_open ("d3d11sdklayers.dll", G_MODULE_BIND_LAZY);
+    d3d11_debug_module =
+        g_module_open ("d3d11sdklayers.dll", G_MODULE_BIND_LAZY);
 
-    if (!sdk_layer)
-      sdk_layer = g_module_open ("d3d11_1sdklayers.dll", G_MODULE_BIND_LAZY);
+    if (!d3d11_debug_module)
+      d3d11_debug_module =
+          g_module_open ("d3d11_1sdklayers.dll", G_MODULE_BIND_LAZY);
 
     g_once_init_leave (&_init, 1);
   }
 
-  return ! !sdk_layer;
+  return ! !d3d11_debug_module;
 }
 
-static gboolean
-gst_d3d11_device_get_message (GstD3D11Device * self)
+static inline GstDebugLevel
+d3d11_message_severity_to_gst (D3D11_MESSAGE_SEVERITY level)
 {
-  GstD3D11DevicePrivate *priv = self->priv;
+  switch (level) {
+    case D3D11_MESSAGE_SEVERITY_CORRUPTION:
+    case D3D11_MESSAGE_SEVERITY_ERROR:
+      return GST_LEVEL_ERROR;
+    case D3D11_MESSAGE_SEVERITY_WARNING:
+      return GST_LEVEL_WARNING;
+    case D3D11_MESSAGE_SEVERITY_INFO:
+      return GST_LEVEL_INFO;
+    case D3D11_MESSAGE_SEVERITY_MESSAGE:
+      return GST_LEVEL_DEBUG;
+    default:
+      break;
+  }
+
+  return GST_LEVEL_LOG;
+}
+
+void
+gst_d3d11_device_d3d11_debug (GstD3D11Device * device,
+    const gchar * file, const gchar * function, gint line)
+{
+  GstD3D11DevicePrivate *priv = device->priv;
   D3D11_MESSAGE *msg;
   SIZE_T msg_len = 0;
   HRESULT hr;
   UINT64 num_msg, i;
 
-  num_msg = ID3D11InfoQueue_GetNumStoredMessages (priv->info_queue);
+  if (!priv->d3d11_info_queue)
+    return;
+
+  num_msg = ID3D11InfoQueue_GetNumStoredMessages (priv->d3d11_info_queue);
+
+  for (i = 0; i < num_msg; i++) {
+    GstDebugLevel level;
+
+    hr = ID3D11InfoQueue_GetMessage (priv->d3d11_info_queue, i, NULL, &msg_len);
+
+    if (FAILED (hr) || msg_len == 0) {
+      return;
+    }
+
+    msg = (D3D11_MESSAGE *) g_alloca (msg_len);
+    hr = ID3D11InfoQueue_GetMessage (priv->d3d11_info_queue, i, msg, &msg_len);
+
+    level = d3d11_message_severity_to_gst (msg->Severity);
+    gst_debug_log (gst_d3d11_debug_layer_debug, level, file, function, line,
+        G_OBJECT (device), "D3D11InfoQueue: %s", msg->pDescription);
+  }
+
+  ID3D11InfoQueue_ClearStoredMessages (priv->d3d11_info_queue);
+
+  return;
+}
+#else
+void
+gst_d3d11_device_d3d11_debug (GstD3D11Device * device,
+    const gchar * file, const gchar * function, gint line)
+{
+  /* do nothing */
+  return;
+}
+#endif
+
+#if HAVE_DXGIDEBUG_H
+static gboolean
+gst_d3d11_device_enable_dxgi_debug (void)
+{
+  static volatile gsize _init = 0;
+
+  /* If all below libraries are unavailable, d3d11 device would fail with
+   * D3D11_CREATE_DEVICE_DEBUG flag */
+  if (g_once_init_enter (&_init)) {
+    dxgi_debug_module = g_module_open ("dxgidebug.dll", G_MODULE_BIND_LAZY);
+
+    if (dxgi_debug_module)
+      g_module_symbol (dxgi_debug_module,
+          "DXGIGetDebugInterface", (gpointer *) & GstDXGIGetDebugInterface);
+
+    g_once_init_leave (&_init, 1);
+  }
+
+  return ! !GstDXGIGetDebugInterface;
+}
+
+static inline GstDebugLevel
+dxgi_info_queue_message_severity_to_gst (DXGI_INFO_QUEUE_MESSAGE_SEVERITY level)
+{
+  switch (level) {
+    case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION:
+    case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR:
+      return GST_LEVEL_ERROR;
+    case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING:
+      return GST_LEVEL_WARNING;
+    case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_INFO:
+      return GST_LEVEL_INFO;
+    case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_MESSAGE:
+      return GST_LEVEL_DEBUG;
+    default:
+      break;
+  }
+
+  return GST_LEVEL_LOG;
+}
+
+void
+gst_d3d11_device_dxgi_debug (GstD3D11Device * device,
+    const gchar * file, const gchar * function, gint line)
+{
+  GstD3D11DevicePrivate *priv = device->priv;
+  DXGI_INFO_QUEUE_MESSAGE *msg;
+  SIZE_T msg_len = 0;
+  HRESULT hr;
+  UINT64 num_msg, i;
+
+  if (!priv->dxgi_info_queue)
+    return;
+
+  num_msg = IDXGIInfoQueue_GetNumStoredMessages (priv->dxgi_info_queue,
+      DXGI_DEBUG_ALL);
 
   for (i = 0; i < num_msg; i++) {
-    hr = ID3D11InfoQueue_GetMessage (priv->info_queue, i, NULL, &msg_len);
+    GstDebugLevel level;
 
-    if (!gst_d3d11_result (hr) || msg_len == 0) {
-      return G_SOURCE_CONTINUE;
+    hr = IDXGIInfoQueue_GetMessage (priv->dxgi_info_queue,
+        DXGI_DEBUG_ALL, i, NULL, &msg_len);
+
+    if (FAILED (hr) || msg_len == 0) {
+      return;
     }
 
-    msg = (D3D11_MESSAGE *) g_malloc0 (msg_len);
-    hr = ID3D11InfoQueue_GetMessage (priv->info_queue, i, msg, &msg_len);
+    msg = (DXGI_INFO_QUEUE_MESSAGE *) g_alloca (msg_len);
+    hr = IDXGIInfoQueue_GetMessage (priv->dxgi_info_queue,
+        DXGI_DEBUG_ALL, i, msg, &msg_len);
 
-    GST_TRACE_OBJECT (self, "D3D11 Message - %s", msg->pDescription);
-    g_free (msg);
+    level = dxgi_info_queue_message_severity_to_gst (msg->Severity);
+    gst_debug_log (gst_d3d11_debug_layer_debug, level, file, function, line,
+        G_OBJECT (device), "DXGIInfoQueue: %s", msg->pDescription);
   }
 
-  ID3D11InfoQueue_ClearStoredMessages (priv->info_queue);
+  IDXGIInfoQueue_ClearStoredMessages (priv->dxgi_info_queue, DXGI_DEBUG_ALL);
 
-  return G_SOURCE_CONTINUE;
+  return;
+}
+#else
+void
+gst_d3d11_device_dxgi_debug (GstD3D11Device * device,
+    const gchar * file, const gchar * function, gint line)
+{
+  /* do nothing */
+  return;
 }
 #endif
 
@@ -184,8 +326,6 @@ gst_d3d11_device_class_init (GstD3D11DeviceClass * klass)
       g_param_spec_boolean ("allow-tearing", "Allow tearing",
           "Whether dxgi device supports allow-tearing feature or not", FALSE,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
-  GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT");
 }
 
 static void
@@ -225,9 +365,40 @@ gst_d3d11_device_constructed (GObject * object)
   GST_DEBUG_OBJECT (self,
       "Built with DXGI header version %d", DXGI_HEADER_VERSION);
 
+#if HAVE_DXGIDEBUG_H
+  if (gst_debug_category_get_threshold (gst_d3d11_debug_layer_debug) >
+      GST_LEVEL_NONE) {
+    if (gst_d3d11_device_enable_dxgi_debug ()) {
+      IDXGIDebug *debug = NULL;
+      IDXGIInfoQueue *info_queue = NULL;
+
+      GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+          "dxgi debug library was loaded");
+      hr = GstDXGIGetDebugInterface (&IID_IDXGIDebug, (void **) &debug);
+
+      if (SUCCEEDED (hr)) {
+        GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+            "IDXGIDebug interface available");
+        priv->dxgi_debug = debug;
+
+        hr = GstDXGIGetDebugInterface (&IID_IDXGIInfoQueue,
+            (void **) &info_queue);
+        if (SUCCEEDED (hr)) {
+          GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+              "IDXGIInfoQueue interface available");
+          priv->dxgi_info_queue = info_queue;
+        }
+      }
+    } else {
+      GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+          "couldn't load dxgi debug library");
+    }
+  }
+#endif
+
 #if (DXGI_HEADER_VERSION >= 5)
   hr = CreateDXGIFactory1 (&IID_IDXGIFactory5, (void **) &factory);
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, NULL)) {
     GST_INFO_OBJECT (self, "IDXGIFactory5 was unavailable");
     factory = NULL;
   } else {
@@ -250,7 +421,7 @@ gst_d3d11_device_constructed (GObject * object)
     hr = CreateDXGIFactory1 (&IID_IDXGIFactory1, (void **) &factory);
   }
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, NULL)) {
     GST_ERROR_OBJECT (self, "cannot create dxgi factory, hr: 0x%x", (guint) hr);
     goto error;
   }
@@ -285,12 +456,17 @@ gst_d3d11_device_constructed (GObject * object)
     }
   }
 
-#ifdef HAVE_D3D11SDKLAYER_H
-  if (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >= GST_LEVEL_TRACE) {
+#if HAVE_D3D11SDKLAYERS_H
+  if (gst_debug_category_get_threshold (gst_d3d11_debug_layer_debug) >
+      GST_LEVEL_NONE) {
     /* DirectX SDK should be installed on system for this */
-    if (gst_d3d11_device_enable_debug_layer ()) {
-      GST_INFO_OBJECT (self, "sdk layer library was loaded");
+    if (gst_d3d11_device_enable_d3d11_debug ()) {
+      GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+          "d3d11 debug library was loaded");
       d3d11_flags |= D3D11_CREATE_DEVICE_DEBUG;
+    } else {
+      GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+          "couldn't load d3d11 debug library");
     }
   }
 #endif
@@ -300,7 +476,7 @@ gst_d3d11_device_constructed (GObject * object)
       D3D11_SDK_VERSION, &priv->device, &selected_level, &priv->device_context);
   priv->feature_level = selected_level;
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, NULL)) {
     /* Retry if the system could not recognize D3D_FEATURE_LEVEL_11_1 */
     hr = D3D11CreateDevice ((IDXGIAdapter *) adapter, D3D_DRIVER_TYPE_UNKNOWN,
         NULL, d3d11_flags, &feature_levels[1],
@@ -309,7 +485,7 @@ gst_d3d11_device_constructed (GObject * object)
     priv->feature_level = selected_level;
   }
 
-  if (gst_d3d11_result (hr)) {
+  if (gst_d3d11_result (hr, NULL)) {
     GST_DEBUG_OBJECT (self, "Selected feature level 0x%x", selected_level);
   } else {
     GST_ERROR_OBJECT (self, "cannot create d3d11 device, hr: 0x%x", (guint) hr);
@@ -318,7 +494,7 @@ gst_d3d11_device_constructed (GObject * object)
 
   priv->factory = factory;
 
-#ifdef HAVE_D3D11SDKLAYER_H
+#if HAVE_D3D11SDKLAYERS_H
   if ((d3d11_flags & D3D11_CREATE_DEVICE_DEBUG) == D3D11_CREATE_DEVICE_DEBUG) {
     ID3D11Debug *debug;
     ID3D11InfoQueue *info_queue;
@@ -327,17 +503,17 @@ gst_d3d11_device_constructed (GObject * object)
         &IID_ID3D11Debug, (void **) &debug);
 
     if (SUCCEEDED (hr)) {
-      GST_DEBUG_OBJECT (self, "D3D11Debug interface available");
-      ID3D11Debug_ReportLiveDeviceObjects (debug,
-          (D3D11_RLDO_FLAGS) GST_D3D11_RLDO_FLAGS);
-      priv->debug = debug;
-    }
-
-    hr = ID3D11Device_QueryInterface (priv->device,
-        &IID_ID3D11InfoQueue, (void **) &info_queue);
-    if (SUCCEEDED (hr)) {
-      GST_DEBUG_OBJECT (self, "D3D11InfoQueue interface available");
-      priv->info_queue = info_queue;
+      GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+          "D3D11Debug interface available");
+      priv->d3d11_debug = debug;
+
+      hr = ID3D11Device_QueryInterface (priv->device,
+          &IID_ID3D11InfoQueue, (void **) &info_queue);
+      if (SUCCEEDED (hr)) {
+        GST_CAT_INFO_OBJECT (gst_d3d11_debug_layer_debug, self,
+            "ID3D11InfoQueue interface available");
+        priv->d3d11_info_queue = info_queue;
+      }
     }
   }
 #endif
@@ -431,19 +607,35 @@ gst_d3d11_device_dispose (GObject * object)
     IDXGIFactory1_Release (priv->factory);
     priv->factory = NULL;
   }
-#ifdef HAVE_D3D11SDKLAYER_H
-  if (priv->debug) {
-    ID3D11Debug_ReportLiveDeviceObjects (priv->debug,
+#if HAVE_D3D11SDKLAYERS_H
+  if (priv->d3d11_debug) {
+    ID3D11Debug_ReportLiveDeviceObjects (priv->d3d11_debug,
         (D3D11_RLDO_FLAGS) GST_D3D11_RLDO_FLAGS);
-    ID3D11Debug_Release (priv->debug);
-    priv->debug = NULL;
+    ID3D11Debug_Release (priv->d3d11_debug);
+    priv->d3d11_debug = NULL;
+  }
+
+  if (priv->d3d11_info_queue) {
+    gst_d3d11_device_d3d11_debug (self, __FILE__, GST_FUNCTION, __LINE__);
+
+    ID3D11InfoQueue_Release (priv->d3d11_info_queue);
+    priv->d3d11_info_queue = NULL;
+  }
+#endif
+
+#if HAVE_DXGIDEBUG_H
+  if (priv->dxgi_debug) {
+    IDXGIDebug_ReportLiveObjects (priv->dxgi_debug, DXGI_DEBUG_ALL,
+        (DXGI_DEBUG_RLO_FLAGS) GST_D3D11_RLDO_FLAGS);
+    IDXGIDebug_Release (priv->dxgi_debug);
+    priv->dxgi_debug = NULL;
   }
 
-  if (priv->info_queue) {
-    gst_d3d11_device_get_message (self);
+  if (priv->dxgi_info_queue) {
+    gst_d3d11_device_dxgi_debug (self, __FILE__, GST_FUNCTION, __LINE__);
 
-    ID3D11InfoQueue_Release (priv->info_queue);
-    priv->info_queue = NULL;
+    IDXGIInfoQueue_Release (priv->dxgi_info_queue);
+    priv->dxgi_info_queue = NULL;
   }
 #endif
 
@@ -569,7 +761,7 @@ gst_d3d11_device_create_swap_chain (GstD3D11Device * device,
       (DXGI_SWAP_CHAIN_DESC *) desc, &swap_chain);
   gst_d3d11_device_unlock (device);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR_OBJECT (device, "Cannot create SwapChain Object: 0x%x",
         (guint) hr);
     swap_chain = NULL;
@@ -614,7 +806,7 @@ gst_d3d11_device_create_swap_chain_for_hwnd (GstD3D11Device * device,
       output, &swap_chain);
   gst_d3d11_device_unlock (device);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR_OBJECT (device, "Cannot create SwapChain Object: 0x%x",
         (guint) hr);
     swap_chain = NULL;
@@ -658,7 +850,7 @@ gst_d3d11_device_create_texture (GstD3D11Device * device,
   priv = device->priv;
 
   hr = ID3D11Device_CreateTexture2D (priv->device, desc, inital_data, &texture);
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("Failed to create texture (0x%x)", (guint) hr);
 
     GST_WARNING ("Direct3D11 Allocation params");
index 08ccdfb..5cffd8a 100644 (file)
@@ -112,6 +112,15 @@ void                  gst_d3d11_device_lock               (GstD3D11Device * devi
 
 void                  gst_d3d11_device_unlock             (GstD3D11Device * device);
 
+void                  gst_d3d11_device_d3d11_debug (GstD3D11Device * device,
+                                                    const gchar * file,
+                                                    const gchar * function,
+                                                    gint line);
+
+void                  gst_d3d11_device_dxgi_debug  (GstD3D11Device * device,
+                                                    const gchar * file,
+                                                    const gchar * function,
+                                                    gint line);
 G_END_DECLS
 
 #endif /* __GST_D3D11_DEVICE_H__ */
index 5e17d71..13e4818 100644 (file)
@@ -218,7 +218,7 @@ map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type)
   hr = ID3D11DeviceContext_Map (device_context,
       staging, 0, map_type, 0, &dmem->map);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, dmem->device)) {
     GST_ERROR_OBJECT (GST_MEMORY_CAST (dmem)->allocator,
         "Failed to map staging texture (0x%x)", (guint) hr);
     ret = FALSE;
@@ -459,7 +459,7 @@ calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture,
   hr = ID3D11DeviceContext_Map (device_context,
       (ID3D11Resource *) texture, 0, map_type, 0, &map);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR_OBJECT (device, "Failed to map texture (0x%x)", (guint) hr);
     gst_d3d11_device_unlock (device);
     return FALSE;
@@ -527,7 +527,7 @@ create_shader_resource_views (GstD3D11Memory * mem)
           (ID3D11Resource *) mem->texture, &resource_desc,
           &mem->shader_resource_view[i]);
 
-      if (!gst_d3d11_result (hr)) {
+      if (!gst_d3d11_result (hr, mem->device)) {
         GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator,
             "Failed to create %dth resource view (0x%x)", i, (guint) hr);
         goto error;
@@ -602,7 +602,7 @@ create_render_target_views (GstD3D11Memory * mem)
       hr = ID3D11Device_CreateRenderTargetView (device_handle,
           (ID3D11Resource *) mem->texture, &render_desc,
           &mem->render_target_view[i]);
-      if (!gst_d3d11_result (hr)) {
+      if (!gst_d3d11_result (hr, mem->device)) {
         GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator,
             "Failed to create %dth render target view (0x%x)", i, (guint) hr);
         goto error;
index cdd424e..73ab40b 100644 (file)
@@ -55,7 +55,7 @@ compile_shader (GstD3D11Device * device, const gchar * shader_source,
   hr = D3DCompile (shader_source, strlen (shader_source), NULL, NULL, NULL,
       "main", shader_target, 0, 0, &ret, &error);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     const gchar *err = NULL;
 
     if (error)
@@ -99,7 +99,7 @@ gst_d3d11_create_pixel_shader (GstD3D11Device * device,
       (gpointer) ID3D10Blob_GetBufferPointer (ps_blob),
       ID3D10Blob_GetBufferSize (ps_blob), NULL, shader);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("could not create pixel shader, hr: 0x%x", (guint) hr);
     gst_d3d11_device_unlock (device);
     return FALSE;
@@ -143,7 +143,7 @@ gst_d3d11_create_vertex_shader (GstD3D11Device * device, const gchar * source,
       (gpointer) ID3D10Blob_GetBufferPointer (vs_blob),
       ID3D10Blob_GetBufferSize (vs_blob), NULL, &vshader);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("could not create vertex shader, hr: 0x%x", (guint) hr);
     ID3D10Blob_Release (vs_blob);
     goto done;
@@ -153,7 +153,7 @@ gst_d3d11_create_vertex_shader (GstD3D11Device * device, const gchar * source,
       desc_len, (gpointer) ID3D10Blob_GetBufferPointer (vs_blob),
       ID3D10Blob_GetBufferSize (vs_blob), &in_layout);
 
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, device)) {
     GST_ERROR ("could not create input layout shader, hr: 0x%x", (guint) hr);
     ID3D10Blob_Release (vs_blob);
     ID3D11VertexShader_Release (vshader);
index 7ab75cd..4141b3a 100644 (file)
@@ -342,7 +342,7 @@ upload_transform_dynamic (GstD3D11BaseFilter * filter,
     hr = ID3D11DeviceContext_Map (device_context,
         (ID3D11Resource *) dmem->texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
 
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, device)) {
       GST_ERROR_OBJECT (filter,
           "Failed to map staging texture (0x%x)", (guint) hr);
       gst_d3d11_device_unlock (device);
index 4c9a9a8..4419b02 100644 (file)
@@ -21,6 +21,8 @@
 #include "config.h"
 #endif
 
+#include "d3d11config.h"
+
 #include "gstd3d11utils.h"
 #include "gstd3d11device.h"
 
@@ -618,3 +620,56 @@ gst_d3d11_caps_fixate_format (GstCaps * caps, GstCaps * othercaps)
 
   return result;
 }
+
+static gchar *
+gst_d3d11_hres_to_string (HRESULT hr)
+{
+  DWORD flags;
+  gchar *ret_text;
+  LPTSTR error_text = NULL;
+
+  flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
+      | FORMAT_MESSAGE_IGNORE_INSERTS;
+  FormatMessage (flags, NULL, hr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+      (LPTSTR) & error_text, 0, NULL);
+
+#ifdef UNICODE
+  /* If UNICODE is defined, LPTSTR is LPWSTR which is UTF-16 */
+  ret_text = g_utf16_to_utf8 (error_text, 0, NULL, NULL, NULL);
+#else
+  ret_text = g_strdup (error_text);
+#endif
+
+  LocalFree (error_text);
+  return ret_text;
+}
+
+gboolean
+_gst_d3d11_result (HRESULT hr, GstD3D11Device * device, GstDebugCategory * cat,
+    const gchar * file, const gchar * function, gint line)
+{
+#ifndef GST_DISABLE_GST_DEBUG
+  gboolean ret = TRUE;
+
+  if (FAILED (hr)) {
+    gchar *error_text = NULL;
+
+    error_text = gst_d3d11_hres_to_string (hr);
+    gst_debug_log (cat, GST_LEVEL_WARNING, file, function, line,
+        NULL, "D3D11 call failed: 0x%x, %s", (guint) hr, error_text);
+    g_free (error_text);
+
+    ret = FALSE;
+  }
+#if (HAVE_D3D11SDKLAYERS_H || HAVE_DXGIDEBUG_H)
+  if (device) {
+    gst_d3d11_device_d3d11_debug (device, file, function, line);
+    gst_d3d11_device_dxgi_debug (device, file, function, line);
+  }
+#endif
+
+  return ret;
+#else
+  return SUCCEEDED (hr);
+#endif
+}
index be9d064..5deafce 100644 (file)
@@ -58,63 +58,21 @@ gboolean        gst_query_is_d3d11_usage            (GstQuery * query);
 GstCaps *       gst_d3d11_caps_fixate_format        (GstCaps * caps,
                                                      GstCaps * othercaps);
 
-static void
-gst_d3d11_format_error (gint error_code, gchar ** str)
-{
-  g_return_if_fail(str);
-
-  FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-    NULL, error_code,
-    MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
-    (LPTSTR)str, 0, NULL);
-};
-
-#ifndef GST_DISABLE_GST_DEBUG
-static inline gboolean
-_gst_d3d11_debug(HRESULT result, GstDebugCategory * category,
-    const gchar * file, const gchar * function, gint line)
-{
-  if (FAILED(result)) {
-    gchar *error_text = NULL;
-
-    gst_d3d11_format_error(result,&error_text);
-    gst_debug_log (category, GST_LEVEL_WARNING, file, function, line,
-        NULL, "D3D11 call failed: 0x%x, %s", (guint)result, error_text);
-    LocalFree(error_text);
-
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
- * gst_d3d11_result:
- * @result: D3D11 API return code #HRESULT
- *
- * Returns: %TRUE if D3D11 API call result is SUCCESS
- */
-#define gst_d3d11_result(result) \
-    _gst_d3d11_debug(result, GST_CAT_DEFAULT, __FILE__, GST_FUNCTION, __LINE__)
-#else
-
-static inline gboolean
-_gst_d3d11_debug(HRESULT result, GstDebugCategory * category,
-    const gchar * file, const gchar * function, gint line)
-{
-  return SUCCESS(result);
-}
-
+gboolean       _gst_d3d11_result                    (HRESULT hr,
+                                                     GstD3D11Device * device,
+                                                     GstDebugCategory * cat,
+                                                     const gchar * file,
+                                                     const gchar * function,
+                                                     gint line);
 /**
  * gst_d3d11_result:
  * @result: D3D11 API return code #HRESULT
+ * @device: (nullable): Associated #GstD3D11Device
  *
  * Returns: %TRUE if D3D11 API call result is SUCCESS
  */
-#define gst_d3d11_result(result) \
-  _gst_d3d11_debug(result, NULL, __FILE__, GST_FUNCTION, __LINE__)
-#endif
-
+#define gst_d3d11_result(result,device) \
+    _gst_d3d11_result (result, device, GST_CAT_DEFAULT, __FILE__, GST_FUNCTION, __LINE__)
 
 
 G_END_DECLS
index aaf42a8..67c6716 100644 (file)
@@ -707,7 +707,7 @@ gst_d3d11_video_sink_upload_frame (GstD3D11VideoSink * self, GstBuffer * inbuf,
     hr = ID3D11DeviceContext_Map (device_context,
         (ID3D11Resource *) dmem->texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
 
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, self->device)) {
       GST_ERROR_OBJECT (self, "Failed to map texture (0x%x)", (guint) hr);
       gst_d3d11_device_unlock (self->device);
       ret = FALSE;
index 52283cd..e051078 100644 (file)
@@ -592,14 +592,14 @@ gst_d3d11_window_on_resize (GstD3D11Window * window, gboolean redraw)
   IDXGISwapChain_GetDesc (window->swap_chain, &swap_desc);
   hr = IDXGISwapChain_ResizeBuffers (window->swap_chain,
       0, 0, 0, DXGI_FORMAT_UNKNOWN, swap_desc.Flags);
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, window->device)) {
     GST_ERROR_OBJECT (window, "Couldn't resize buffers, hr: 0x%x", (guint) hr);
     goto done;
   }
 
   hr = IDXGISwapChain_GetBuffer (window->swap_chain,
       0, &IID_ID3D11Texture2D, (void **) &backbuffer);
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, window->device)) {
     GST_ERROR_OBJECT (window,
         "Cannot get backbuffer from swapchain, hr: 0x%x", (guint) hr);
     goto done;
@@ -643,7 +643,7 @@ gst_d3d11_window_on_resize (GstD3D11Window * window, gboolean redraw)
 
   hr = ID3D11Device_CreateRenderTargetView (d3d11_dev,
       (ID3D11Resource *) backbuffer, NULL, &window->rtv);
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, window->device)) {
     GST_ERROR_OBJECT (window, "Cannot create render target view, hr: 0x%x",
         (guint) hr);
 
@@ -1096,7 +1096,7 @@ gst_d3d11_window_disable_alt_enter (GstD3D11Window * window,
 
   hr = IDXGISwapChain_GetParent (swap_chain, &IID_IDXGIFactory1,
       (void **) &factory);
-  if (!gst_d3d11_result (hr) || !factory) {
+  if (!gst_d3d11_result (hr, window->device) || !factory) {
     GST_WARNING_OBJECT (window,
         "Cannot get parent dxgi factory for swapchain %p, hr: 0x%x",
         swap_chain, (guint) hr);
@@ -1105,7 +1105,7 @@ gst_d3d11_window_disable_alt_enter (GstD3D11Window * window,
 
   hr = IDXGIFactory1_MakeWindowAssociation (factory,
       hwnd, DXGI_MWA_NO_ALT_ENTER);
-  if (!gst_d3d11_result (hr)) {
+  if (!gst_d3d11_result (hr, window->device)) {
     GST_WARNING_OBJECT (window,
         "MakeWindowAssociation failure, hr: 0x%x", (guint) hr);
   }
@@ -1337,7 +1337,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
       hr = IDXGISwapChain4_SetColorSpace1 ((IDXGISwapChain4 *)
           window->swap_chain, (DXGI_COLOR_SPACE_TYPE) ctype);
 
-      if (!gst_d3d11_result (hr)) {
+      if (!gst_d3d11_result (hr, window->device)) {
         GST_WARNING_OBJECT (window, "Failed to set colorspace %d, hr: 0x%x",
             ctype, (guint) hr);
       } else {
@@ -1355,7 +1355,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
         hr = IDXGISwapChain4_SetHDRMetaData ((IDXGISwapChain4 *)
             window->swap_chain, DXGI_HDR_METADATA_TYPE_HDR10,
             sizeof (DXGI_HDR_METADATA_HDR10), &metadata);
-        if (!gst_d3d11_result (hr)) {
+        if (!gst_d3d11_result (hr, window->device)) {
           GST_WARNING_OBJECT (window, "Couldn't set HDR metadata, hr 0x%x",
               (guint) hr);
         }
@@ -1495,7 +1495,7 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer)
 
     hr = IDXGISwapChain_Present (self->swap_chain, 0, present_flags);
 
-    if (!gst_d3d11_result (hr)) {
+    if (!gst_d3d11_result (hr, self->device)) {
       GST_WARNING_OBJECT (self, "Direct3D cannot present texture, hr: 0x%x",
           (guint) hr);
     }
index 5b84d7b..71ca923 100644 (file)
@@ -28,6 +28,8 @@ dxgi_headers = [
 have_d3d11 = false
 extra_c_args = ['-DCOBJMACROS']
 have_dxgi_header = false
+have_d3d11sdk_h = false
+have_dxgidebug_h = false
 extra_dep = []
 d3d11_conf = configuration_data()
 
@@ -56,11 +58,38 @@ if not have_d3d11
 endif
 
 # for enabling debug layer
-if cc.has_header('d3d11sdklayers.h')
-  d3d11_conf.set('HAVE_D3D11SDKLAYER_H', 1)
-  extra_dep += [gmodule_dep]
+if get_option('buildtype').startswith('debug')
+  d3d11_debug_libs = [
+    ['d3d11sdklayers.h', 'ID3D11Debug', 'ID3D11InfoQueue', 'have_d3d11sdk_h'],
+    ['dxgidebug.h', 'IDXGIDebug', 'IDXGIInfoQueue', 'have_dxgidebug_h'],
+  ]
+
+  foreach f : d3d11_debug_libs
+    header = f.get(0)
+    debug_obj = f.get(1)
+    info_obj = f.get(2)
+    compile_code = '''
+                   #include <d3d11.h>
+                   #include <dxgi.h>
+                   #include <@0@>
+                   int main(int arc, char ** argv) {
+                     @1@ *debug = NULL;
+                     @2@ *info_queue = NULL;
+                     return 0;
+                   }'''.format(header, debug_obj, info_obj)
+    if cc.compiles(compile_code, dependencies: [d3d11_lib, dxgi_lib], name: debug_obj)
+      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)
+d3d11_conf.set10('HAVE_DXGIDEBUG_H', have_dxgidebug_h)
+
 configure_file(
   output: 'd3d11config.h',
   configuration: d3d11_conf,
index 102e53e..ea822f1 100644 (file)
@@ -21,6 +21,8 @@
 #include "config.h"
 #endif
 
+#include "d3d11config.h"
+
 #include <gst/gst.h>
 #include "gstd3d11videosink.h"
 #include "gstd3d11upload.h"
@@ -34,6 +36,10 @@ GST_DEBUG_CATEGORY (gst_d3d11_utils_debug);
 GST_DEBUG_CATEGORY (gst_d3d11_format_debug);
 GST_DEBUG_CATEGORY (gst_d3d11_device_debug);
 
+#if (HAVE_D3D11SDKLAYERS_H || HAVE_DXGIDEBUG_H)
+GST_DEBUG_CATEGORY (gst_d3d11_debug_layer_debug);
+#endif
+
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
@@ -47,6 +53,11 @@ plugin_init (GstPlugin * plugin)
       "d3d11format", 0, "d3d11 specific formats");
   GST_DEBUG_CATEGORY_INIT (gst_d3d11_device_debug,
       "d3d11device", 0, "d3d11 device object");
+#if (HAVE_D3D11SDKLAYERS_H || HAVE_DXGIDEBUG_H)
+  /* NOTE: enabled only for debug build */
+  GST_DEBUG_CATEGORY_INIT (gst_d3d11_debug_layer_debug,
+      "d3d11debuglayer", 0, "native d3d11 and dxgi debug");
+#endif
 
   gst_element_register (plugin,
       "d3d11upload", GST_RANK_NONE, GST_TYPE_D3D11_UPLOAD);