cudautils: add support of D3D11 resource as Cuda graphics resource type
authorCorentin Damman <c.damman@intopix.com>
Mon, 28 Feb 2022 13:40:51 +0000 (14:40 +0100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 10 Mar 2022 18:08:10 +0000 (18:08 +0000)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1807>

subprojects/gst-plugins-bad/sys/nvcodec/gstcudautils.c
subprojects/gst-plugins-bad/sys/nvcodec/gstcudautils.h
subprojects/gst-plugins-bad/sys/nvcodec/meson.build
subprojects/gst-plugins-bad/sys/nvcodec/stub/cuda.h

index 4fb8312..4d1b661 100644 (file)
 #include <gst/gl/gstglfuncs.h>
 #endif
 
+#ifdef HAVE_NVCODEC_GST_D3D11
+#include <gst/d3d11/gstd3d11.h>
+#endif
+
 GST_DEBUG_CATEGORY_STATIC (gst_cuda_utils_debug);
 #define GST_CAT_DEFAULT gst_cuda_utils_debug
 GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
@@ -458,6 +462,42 @@ gst_cuda_graphics_resource_register_gl_buffer (GstCudaGraphicsResource *
 }
 
 /**
+ * gst_cuda_graphics_resource_register_d3d11_resource: (skip)
+ * @resource a #GstCudaGraphicsResource
+ * @d3d11_resource: a ID3D11Resource
+ * @flags: a #CUgraphicsRegisterFlags
+ *
+ * Register the @d3d11_resource for accessing by CUDA.
+ * Must be called with d3d11 device lock with current cuda context was
+ * pushed on the current thread
+ *
+ * Returns: whether @d3d11_resource was registered or not
+ */
+gboolean
+gst_cuda_graphics_resource_register_d3d11_resource (GstCudaGraphicsResource *
+    resource, gpointer d3d11_resource, CUgraphicsRegisterFlags flags)
+{
+  CUresult cuda_ret;
+
+  g_return_val_if_fail (resource != NULL, FALSE);
+  g_return_val_if_fail (resource->registered == FALSE, FALSE);
+
+  _init_debug ();
+
+  cuda_ret = CuGraphicsD3D11RegisterResource (&resource->resource,
+      d3d11_resource, flags);
+
+  if (!gst_cuda_result (cuda_ret))
+    return FALSE;
+
+  resource->registered = TRUE;
+  resource->type = GST_CUDA_GRAPHICS_RESOURCE_D3D11_RESOURCE;
+  resource->flags = flags;
+
+  return TRUE;
+}
+
+/**
  * gst_cuda_graphics_resource_unregister: (skip)
  * @resource: a #GstCudaGraphicsResource
  *
@@ -561,6 +601,28 @@ unregister_resource_from_gl_thread (GstGLContext * gl_context,
 }
 #endif
 
+#ifdef HAVE_NVCODEC_GST_D3D11
+static void
+unregister_d3d11_resource (GstCudaGraphicsResource * resource)
+{
+  GstCudaContext *cuda_context = resource->cuda_context;
+  GstD3D11Device *device = GST_D3D11_DEVICE (resource->graphics_context);
+
+  if (!gst_cuda_context_push (cuda_context)) {
+    GST_WARNING_OBJECT (cuda_context, "failed to push CUDA context");
+    return;
+  }
+
+  gst_d3d11_device_lock (device);
+  gst_cuda_graphics_resource_unregister (resource);
+  gst_d3d11_device_unlock (device);
+
+  if (!gst_cuda_context_pop (NULL)) {
+    GST_WARNING_OBJECT (cuda_context, "failed to pop CUDA context");
+  }
+}
+#endif
+
 /**
  * gst_cuda_graphics_resource_free: (skip)
  * @resource: a #GstCudaGraphicsResource
@@ -580,8 +642,13 @@ gst_cuda_graphics_resource_free (GstCudaGraphicsResource * resource)
           resource);
     } else
 #endif
+#ifdef HAVE_NVCODEC_GST_D3D11
+    if (resource->type == GST_CUDA_GRAPHICS_RESOURCE_D3D11_RESOURCE) {
+      unregister_d3d11_resource (resource);
+    } else
+#endif
     {
-      /* FIXME: currently opengl only */
+      /* FIXME: currently only opengl & d3d11 */
       g_assert_not_reached ();
     }
   }
index 5906ffa..d1cbd9d 100644 (file)
@@ -83,12 +83,13 @@ typedef enum
 {
   GST_CUDA_GRAPHICS_RESOURCE_NONE = 0,
   GST_CUDA_GRAPHICS_RESOURCE_GL_BUFFER = 1,
+  GST_CUDA_GRAPHICS_RESOURCE_D3D11_RESOURCE = 2,
 } GstCudaGraphicsResourceType;
 
 typedef struct _GstCudaGraphicsResource
 {
   GstCudaContext *cuda_context;
-  /* GL context (or d3d11 context in the future) */
+  /* GL context or D3D11 device */
   GstObject *graphics_context;
 
   GstCudaGraphicsResourceType type;
@@ -124,6 +125,10 @@ gboolean        gst_cuda_graphics_resource_register_gl_buffer (GstCudaGraphicsRe
                                                                guint buffer,
                                                                CUgraphicsRegisterFlags flags);
 
+gboolean        gst_cuda_graphics_resource_register_d3d11_resource (GstCudaGraphicsResource * resource,
+                                                                    gpointer d3d11_resource,
+                                                                    CUgraphicsRegisterFlags flags);
+
 void            gst_cuda_graphics_resource_unregister (GstCudaGraphicsResource * resource);
 
 CUgraphicsResource gst_cuda_graphics_resource_map (GstCudaGraphicsResource * resource,
index 0eff13e..3a868e7 100644 (file)
@@ -42,6 +42,10 @@ if gstgl_dep.found()
   extra_c_args += ['-DHAVE_NVCODEC_GST_GL=1']
 endif
 
+if gstd3d11_dep.found()
+  extra_c_args += ['-DHAVE_NVCODEC_GST_D3D11=1']
+endif
+
 if host_system == 'linux'
   have_nvmm = false
   if cc.has_header('nvbufsurface.h')
@@ -62,7 +66,7 @@ gstnvcodec = library('gstnvcodec',
   nvcodec_sources,
   c_args : gst_plugins_bad_args + extra_c_args,
   include_directories : plugin_incdirs,
-  dependencies : [gstbase_dep, gstvideo_dep, gstpbutils_dep, gstgl_dep, gstglproto_dep, gmodule_dep, gstcodecs_dep],
+  dependencies : [gstbase_dep, gstvideo_dep, gstpbutils_dep, gstgl_dep, gstglproto_dep, gmodule_dep, gstcodecs_dep, gstd3d11_dep],
   install : true,
   install_dir : plugins_install_dir,
 )
index 1ca0a04..2187510 100644 (file)
@@ -60,6 +60,8 @@ typedef enum
   CU_GRAPHICS_REGISTER_FLAGS_NONE = 0x00,
   CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY = 0x01,
   CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD = 0x02,
+  CU_GRAPHICS_REGISTER_FLAGS_SURFACE_LOAD_STORE = 0x04,
+  CU_GRAPHICS_REGISTER_FLAGS_TEXTURE_GATHER = 0x08,
 } CUgraphicsRegisterFlags;
 
 typedef enum