diff --git a/sys/d3d11/gstd3d11colorconvert.c b/sys/d3d11/gstd3d11colorconvert.c index 3541a2de2c..f163d31863 100644 --- a/sys/d3d11/gstd3d11colorconvert.c +++ b/sys/d3d11/gstd3d11colorconvert.c @@ -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; diff --git a/sys/d3d11/gstd3d11colorconverter.c b/sys/d3d11/gstd3d11colorconverter.c index 9897e787b5..3d330ed60d 100644 --- a/sys/d3d11/gstd3d11colorconverter.c +++ b/sys/d3d11/gstd3d11colorconverter.c @@ -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); diff --git a/sys/d3d11/gstd3d11device.c b/sys/d3d11/gstd3d11device.c index d18e3f0056..7f09631545 100644 --- a/sys/d3d11/gstd3d11device.c +++ b/sys/d3d11/gstd3d11device.c @@ -27,16 +27,9 @@ #include "gstd3d11utils.h" #include "gmodule.h" -#ifdef HAVE_D3D11SDKLAYER_H +#if HAVE_D3D11SDKLAYERS_H #include -#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 +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++) { - 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 = ID3D11InfoQueue_GetMessage (priv->d3d11_info_queue, 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 = (D3D11_MESSAGE *) g_alloca (msg_len); + hr = ID3D11InfoQueue_GetMessage (priv->d3d11_info_queue, i, msg, &msg_len); - GST_TRACE_OBJECT (self, "D3D11 Message - %s", msg->pDescription); - g_free (msg); + 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->info_queue); + ID3D11InfoQueue_ClearStoredMessages (priv->d3d11_info_queue); - return G_SOURCE_CONTINUE; + 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++) { + GstDebugLevel level; + + hr = IDXGIInfoQueue_GetMessage (priv->dxgi_info_queue, + DXGI_DEBUG_ALL, i, NULL, &msg_len); + + if (FAILED (hr) || msg_len == 0) { + return; + } + + msg = (DXGI_INFO_QUEUE_MESSAGE *) g_alloca (msg_len); + hr = IDXGIInfoQueue_GetMessage (priv->dxgi_info_queue, + DXGI_DEBUG_ALL, i, msg, &msg_len); + + 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); + } + + IDXGIInfoQueue_ClearStoredMessages (priv->dxgi_info_queue, DXGI_DEBUG_ALL); + + 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; - } + 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_DEBUG_OBJECT (self, "D3D11InfoQueue interface available"); - priv->info_queue = info_queue; + 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->info_queue) { - gst_d3d11_device_get_message (self); + if (priv->d3d11_info_queue) { + gst_d3d11_device_d3d11_debug (self, __FILE__, GST_FUNCTION, __LINE__); - ID3D11InfoQueue_Release (priv->info_queue); - priv->info_queue = NULL; + 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->dxgi_info_queue) { + gst_d3d11_device_dxgi_debug (self, __FILE__, GST_FUNCTION, __LINE__); + + 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"); diff --git a/sys/d3d11/gstd3d11device.h b/sys/d3d11/gstd3d11device.h index 08ccdfb5a1..5cffd8a21d 100644 --- a/sys/d3d11/gstd3d11device.h +++ b/sys/d3d11/gstd3d11device.h @@ -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__ */ diff --git a/sys/d3d11/gstd3d11memory.c b/sys/d3d11/gstd3d11memory.c index 5e17d715fa..13e481819b 100644 --- a/sys/d3d11/gstd3d11memory.c +++ b/sys/d3d11/gstd3d11memory.c @@ -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; diff --git a/sys/d3d11/gstd3d11shader.c b/sys/d3d11/gstd3d11shader.c index cdd424e15d..73ab40b178 100644 --- a/sys/d3d11/gstd3d11shader.c +++ b/sys/d3d11/gstd3d11shader.c @@ -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); diff --git a/sys/d3d11/gstd3d11upload.c b/sys/d3d11/gstd3d11upload.c index 7ab75cd2ac..4141b3a7e3 100644 --- a/sys/d3d11/gstd3d11upload.c +++ b/sys/d3d11/gstd3d11upload.c @@ -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); diff --git a/sys/d3d11/gstd3d11utils.c b/sys/d3d11/gstd3d11utils.c index 4c9a9a813c..4419b02fbc 100644 --- a/sys/d3d11/gstd3d11utils.c +++ b/sys/d3d11/gstd3d11utils.c @@ -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 +} diff --git a/sys/d3d11/gstd3d11utils.h b/sys/d3d11/gstd3d11utils.h index be9d064c60..5deafce18d 100644 --- a/sys/d3d11/gstd3d11utils.h +++ b/sys/d3d11/gstd3d11utils.h @@ -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; -} - +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, 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); -} - -/** - * 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, 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 diff --git a/sys/d3d11/gstd3d11videosink.c b/sys/d3d11/gstd3d11videosink.c index aaf42a8d83..67c67161d7 100644 --- a/sys/d3d11/gstd3d11videosink.c +++ b/sys/d3d11/gstd3d11videosink.c @@ -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; diff --git a/sys/d3d11/gstd3d11window.c b/sys/d3d11/gstd3d11window.c index 52283cd55c..e051078b07 100644 --- a/sys/d3d11/gstd3d11window.c +++ b/sys/d3d11/gstd3d11window.c @@ -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); } diff --git a/sys/d3d11/meson.build b/sys/d3d11/meson.build index 5b84d7b1c7..71ca923a94 100644 --- a/sys/d3d11/meson.build +++ b/sys/d3d11/meson.build @@ -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 + #include + #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, diff --git a/sys/d3d11/plugin.c b/sys/d3d11/plugin.c index 102e53e94c..ea822f1f37 100644 --- a/sys/d3d11/plugin.c +++ b/sys/d3d11/plugin.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include "d3d11config.h" + #include #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);