From 2f506e8ddce626d7b5ddf1b18da31b23fcf97a90 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 10 Aug 2023 01:37:59 +0900 Subject: [PATCH] cudamemory: Add support for virtual memory in pool allocator Adding new memory pool allocator for virtual memory Part-of: --- .../gst-libs/gst/cuda/gstcuda-private.h | 2 + .../gst-libs/gst/cuda/gstcudamemory.cpp | 58 ++++++++++++- .../gst-libs/gst/cuda/gstcudamemory.h | 7 ++ .../gst-libs/gst/cuda/gstcudautils.cpp | 83 +++++++++++++++++++ .../gst-libs/gst/cuda/meson.build | 8 ++ 5 files changed, 156 insertions(+), 2 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcuda-private.h b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcuda-private.h index a1e3a64da0..0e99c6abbd 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcuda-private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcuda-private.h @@ -58,6 +58,8 @@ gboolean gst_cuda_memory_is_from_fixed_pool (GstMemory * mem); gboolean gst_cuda_virtual_memory_symbol_loaded (void); +gpointer gst_cuda_get_win32_handle_metadata (void); + G_END_DECLS #ifdef __cplusplus diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp index 38242b1967..230b2333ed 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp @@ -1363,6 +1363,10 @@ struct _GstCudaPoolAllocatorPrivate GstAtomicQueue *queue; GstPoll *poll; + GstCudaMemoryAllocMethod alloc_method; + CUmemAllocationProp prop; + CUmemAllocationGranularity_flags granularity_flags; + GRecMutex lock; gboolean started; gboolean active; @@ -1412,6 +1416,7 @@ gst_cuda_pool_allocator_init (GstCudaPoolAllocator * allocator) priv->flushing = 1; priv->active = FALSE; priv->started = FALSE; + priv->alloc_method = GST_CUDA_MEMORY_ALLOC_MALLOC; /* 1 control write for flushing - the flush token */ gst_poll_write_control (priv->poll); @@ -1669,8 +1674,14 @@ gst_cuda_pool_allocator_alloc (GstCudaPoolAllocator * self, GstMemory ** mem) /* increment the allocation counter */ g_atomic_int_add (&priv->cur_mems, 1); - new_mem = gst_cuda_allocator_alloc ((GstCudaAllocator *) _gst_cuda_allocator, - self->context, self->stream, &self->info); + if (priv->alloc_method == GST_CUDA_MEMORY_ALLOC_MMAP) { + new_mem = gst_cuda_allocator_virtual_alloc (nullptr, + self->context, self->stream, &self->info, &priv->prop, + priv->granularity_flags); + } else { + new_mem = gst_cuda_allocator_alloc (nullptr, + self->context, self->stream, &self->info); + } if (!new_mem) { GST_ERROR_OBJECT (self, "Failed to allocate new memory"); g_atomic_int_add (&priv->cur_mems, -1); @@ -1797,6 +1808,49 @@ gst_cuda_pool_allocator_new (GstCudaContext * context, GstCudaStream * stream, return self; } +/** + * gst_cuda_pool_allocator_new_for_virtual_memory: + * @context: a #GstCudaContext + * @stream: (allow-none): a #GstCudaStream + * @info: a #GstVideoInfo + * + * Creates a new #GstCudaPoolAllocator instance for virtual memory allocation. + * + * Returns: (transfer full): a new #GstCudaPoolAllocator instance + * + * Since: 1.24 + */ +GstCudaPoolAllocator * +gst_cuda_pool_allocator_new_for_virtual_memory (GstCudaContext * context, + GstCudaStream * stream, const GstVideoInfo * info, + const CUmemAllocationProp * prop, + CUmemAllocationGranularity_flags granularity_flags) +{ + GstCudaPoolAllocator *self; + + g_return_val_if_fail (GST_IS_CUDA_CONTEXT (context), nullptr); + g_return_val_if_fail (!stream || GST_IS_CUDA_STREAM (stream), nullptr); + g_return_val_if_fail (prop, nullptr); + + self = (GstCudaPoolAllocator *) + g_object_new (GST_TYPE_CUDA_POOL_ALLOCATOR, nullptr); + gst_object_ref_sink (self); + + self->context = (GstCudaContext *) gst_object_ref (context); + if (stream) + self->stream = gst_cuda_stream_ref (stream); + self->info = *info; + + self->priv->prop = *prop; + self->priv->alloc_method = GST_CUDA_MEMORY_ALLOC_MMAP; + if (self->priv->prop.requestedHandleTypes == CU_MEM_HANDLE_TYPE_WIN32) { + self->priv->prop.win32HandleMetaData = + gst_cuda_get_win32_handle_metadata (); + } + + return self; +} + /** * gst_cuda_pool_allocator_acquire_memory: * @allocator: a #GstCudaPoolAllocator diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h index 54a2b245db..e3a8eb9912 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h @@ -331,6 +331,13 @@ GstCudaPoolAllocator * gst_cuda_pool_allocator_new (GstCudaContext * context, GstCudaStream * stream, const GstVideoInfo * info); +GST_CUDA_API +GstCudaPoolAllocator * gst_cuda_pool_allocator_new_for_virtual_memory (GstCudaContext * context, + GstCudaStream * stream, + const GstVideoInfo * info, + const CUmemAllocationProp * prop, + CUmemAllocationGranularity_flags granularity_flags); + GST_CUDA_API GstFlowReturn gst_cuda_pool_allocator_acquire_memory (GstCudaPoolAllocator * allocator, GstMemory ** memory); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp index 2f7102e546..dda7cf03f3 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp @@ -35,6 +35,7 @@ #ifdef G_OS_WIN32 #include +#include #endif #ifdef HAVE_NVCODEC_NVMM @@ -1745,3 +1746,85 @@ _gst_cuda_debug (CUresult result, GstDebugCategory * cat, return TRUE; } + +#ifdef G_OS_WIN32 +/* Defined in ntdef.h */ +struct OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + PVOID ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +}; +#endif + +gpointer +gst_cuda_get_win32_handle_metadata (void) +{ +#ifdef G_OS_WIN32 + static const gchar sddl[] = "D:P(OA;;GARCSDWDWORPWPCCDCLCSWLODTCRFA;;;WD)"; + static OBJECT_ATTRIBUTES attr; + static BOOL initialized = FALSE; + + /* + * D:P(string_ace) -> DACL protected with "string_ace" + * + * ace_string format + * ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid + * + * ace_type: OA (ACCESS_ALLOWED_OBJECT_ACE_TYPE) + * + * ace_flags: (empty) + * + * rights: GARCSDWDWOCCDCLCSWLODTWPRPCRFA (allow all) + * - Generic access rights + * GA (GENERIC_ALL) + * - Standard access right + * RC (READ_CONTROL) SD (DELETE) WD (WRITE_DAC) WO (WRITE_OWNER) + * - Directory service object access right + * RP (ADS_RIGHT_DS_READ_PROP) + * WP (ADS_RIGHT_DS_WRITE_PROP) + * CC (ADS_RIGHT_DS_CREATE_CHILD) + * DC (ADS_RIGHT_DS_DELETE_CHILD) + * LC (ADS_RIGHT_ACTRL_DS_LIST) + * SW (ADS_RIGHT_DS_SELF) + * LO (ADS_RIGHT_DS_LIST_OBJECT) + * DT (ADS_RIGHT_DS_DELETE_TREE) + * CR (ADS_RIGHT_DS_CONTROL_ACCESS) + * - File access rights + * FA (FILE_GENERIC_ALL) + * + * object_guid: (empty) + * + * inherit_object_guid (empty) + * + * account_sid: WD (SDDL_EVERYONE) + * + * See also + * https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format + */ + GST_CUDA_CALL_ONCE_BEGIN { + PSECURITY_DESCRIPTOR desc; + + memset (&attr, 0, sizeof (OBJECT_ATTRIBUTES)); + + initialized = ConvertStringSecurityDescriptorToSecurityDescriptorA (sddl, + SDDL_REVISION_1, &desc, nullptr); + if (!initialized) + return; + + attr.Length = sizeof (OBJECT_ATTRIBUTES); + attr.SecurityDescriptor = desc; + } + GST_CUDA_CALL_ONCE_END; + + if (!initialized) + return nullptr; + + return &attr; +#else + return nullptr; +#endif +} diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/meson.build b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/meson.build index 0832a0745f..5a60d0f4cd 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/meson.build +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/meson.build @@ -66,6 +66,14 @@ if host_system == 'windows' subdir_done() endif + # ConvertStringSecurityDescriptorToSecurityDescriptorA + advapi32_lib = cxx.find_library('advapi32', required: false) + if not advapi32_lib.found() + subdir_done() + endif + + gstcuda_platform_dep += [advapi32_lib] + # MinGW 32bits build workaround if cc.get_id() != 'msvc' extra_args += cc.get_supported_arguments([