hip: Add GstHipGraphicsResource object
hipGraphicsResource_t wrapper object for graphics api interop Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8923>
This commit is contained in:
parent
04fb36b2f9
commit
baa9bc9d95
34
subprojects/gst-plugins-bad/sys/hip/gsthip-interop-gl.h
Normal file
34
subprojects/gst-plugins-bad/sys/hip/gsthip-interop-gl.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) 2025 Seungha Yang <seungha@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "gsthip-interop.h"
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
hipError_t
|
||||
gst_hip_get_graphics_resource_from_gl_memory (GstHipDevice * device,
|
||||
GstMemory * mem,
|
||||
GstHipGraphicsResource ** resource);
|
||||
|
||||
G_END_DECLS
|
||||
|
303
subprojects/gst-plugins-bad/sys/hip/gsthip-interop.cpp
Normal file
303
subprojects/gst-plugins-bad/sys/hip/gsthip-interop.cpp
Normal file
@ -0,0 +1,303 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) 2025 Seungha Yang <seungha@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gsthip-config.h"
|
||||
#include "gsthip.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#ifdef HAVE_GST_GL
|
||||
#include "gsthip-interop-gl.h"
|
||||
#include "gsthiploader-gl.h"
|
||||
#endif
|
||||
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
#define GST_CAT_DEFAULT ensure_debug_category()
|
||||
static GstDebugCategory *
|
||||
ensure_debug_category (void)
|
||||
{
|
||||
static GstDebugCategory *cat = nullptr;
|
||||
static std::once_flag once;
|
||||
|
||||
std::call_once (once,[&] {
|
||||
cat = _gst_debug_category_new ("hip-interop", 0, "hip-interop");
|
||||
});
|
||||
|
||||
return cat;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GST_GL
|
||||
static void
|
||||
unregister_resource_on_gl_thread (GstGLContext * gl_context,
|
||||
GstHipGraphicsResource * resource);
|
||||
#endif
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
struct _GstHipGraphicsResource : public GstMiniObject
|
||||
{
|
||||
_GstHipGraphicsResource ()
|
||||
{
|
||||
}
|
||||
|
||||
~_GstHipGraphicsResource ()
|
||||
{
|
||||
#ifdef HAVE_GST_GL
|
||||
if (gl_context) {
|
||||
gst_gl_context_thread_add (gl_context,
|
||||
(GstGLContextThreadFunc) unregister_resource_on_gl_thread,
|
||||
this);
|
||||
|
||||
gst_object_unref (gl_context);
|
||||
} else
|
||||
#else
|
||||
if (gst_hip_device_set_current (device))
|
||||
HipGraphicsUnregisterResource (vendor, handle);
|
||||
#endif
|
||||
|
||||
gst_object_unref (device);
|
||||
}
|
||||
|
||||
GstHipDevice *device = nullptr;
|
||||
GstHipVendor vendor = GST_HIP_VENDOR_UNKNOWN;
|
||||
hipGraphicsResource_t handle = nullptr;
|
||||
std::mutex lock;
|
||||
std::condition_variable cond;
|
||||
guint64 map_count = 0;
|
||||
void *mapped_dev_ptr = nullptr;
|
||||
size_t mapped_size = 0;
|
||||
hipStream_t mapped_stream = nullptr;
|
||||
#ifdef HAVE_GST_GL
|
||||
GstGLContext *gl_context = nullptr;
|
||||
#endif
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#ifdef HAVE_GST_GL
|
||||
static void
|
||||
unregister_resource_on_gl_thread (GstGLContext * gl_context,
|
||||
GstHipGraphicsResource * resource)
|
||||
{
|
||||
if (gst_hip_device_set_current (resource->device))
|
||||
HipGraphicsUnregisterResource (resource->vendor, resource->handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
GST_DEFINE_MINI_OBJECT_TYPE (GstHipGraphicsResource, gst_hip_graphics_resource);
|
||||
|
||||
hipError_t
|
||||
gst_hip_graphics_resource_map (GstHipGraphicsResource * resource,
|
||||
hipStream_t stream)
|
||||
{
|
||||
g_return_val_if_fail (resource, hipErrorInvalidValue);
|
||||
|
||||
std::unique_lock < std::mutex > lk (resource->lock);
|
||||
|
||||
if (resource->map_count > 0) {
|
||||
if (stream == resource->mapped_stream) {
|
||||
resource->map_count++;
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
while (resource->map_count > 0)
|
||||
resource->cond.wait (lk);
|
||||
}
|
||||
|
||||
auto ret = HipGraphicsMapResources (resource->vendor, 1, &resource->handle,
|
||||
stream);
|
||||
if (!gst_hip_result (ret, resource->vendor))
|
||||
return ret;
|
||||
|
||||
resource->map_count++;
|
||||
resource->mapped_stream = stream;
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
hipError_t
|
||||
gst_hip_graphics_resource_unmap (GstHipGraphicsResource * resource,
|
||||
hipStream_t stream)
|
||||
{
|
||||
g_return_val_if_fail (resource, hipErrorInvalidValue);
|
||||
|
||||
std::lock_guard < std::mutex > lk (resource->lock);
|
||||
|
||||
if (resource->map_count == 0) {
|
||||
GST_WARNING ("resource %p is not mapped", resource);
|
||||
return hipErrorNotMapped;
|
||||
}
|
||||
|
||||
resource->map_count--;
|
||||
|
||||
if (resource->map_count > 0)
|
||||
return hipSuccess;
|
||||
|
||||
auto ret = HipGraphicsUnmapResources (resource->vendor, 1, &resource->handle,
|
||||
stream);
|
||||
|
||||
resource->mapped_stream = nullptr;
|
||||
resource->mapped_dev_ptr = nullptr;
|
||||
resource->mapped_size = 0;
|
||||
|
||||
resource->cond.notify_all ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
hipError_t
|
||||
gst_hip_graphics_resource_get_mapped_pointer (GstHipGraphicsResource * resource,
|
||||
void **dev_ptr, size_t *size)
|
||||
{
|
||||
g_return_val_if_fail (resource, hipErrorInvalidValue);
|
||||
|
||||
std::lock_guard < std::mutex > lk (resource->lock);
|
||||
|
||||
if (resource->map_count == 0) {
|
||||
GST_WARNING ("resource %p is not mapped", resource);
|
||||
return hipErrorNotMapped;
|
||||
}
|
||||
|
||||
if (!resource->mapped_dev_ptr) {
|
||||
auto ret = HipGraphicsResourceGetMappedPointer (resource->vendor,
|
||||
&resource->mapped_dev_ptr, &resource->mapped_size, resource->handle);
|
||||
if (!gst_hip_result (ret, resource->vendor))
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dev_ptr)
|
||||
*dev_ptr = resource->mapped_dev_ptr;
|
||||
|
||||
if (size)
|
||||
*size = resource->mapped_size;
|
||||
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
GstHipGraphicsResource *
|
||||
gst_hip_graphics_resource_ref (GstHipGraphicsResource * resource)
|
||||
{
|
||||
return (GstHipGraphicsResource *) gst_mini_object_ref (resource);
|
||||
}
|
||||
|
||||
void
|
||||
gst_hip_graphics_resource_unref (GstHipGraphicsResource * resource)
|
||||
{
|
||||
gst_mini_object_unref (resource);
|
||||
}
|
||||
|
||||
void
|
||||
gst_clear_hip_graphics_resource (GstHipGraphicsResource ** resource)
|
||||
{
|
||||
gst_clear_mini_object (resource);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GST_GL
|
||||
static void
|
||||
gst_hip_graphics_resource_free (GstHipGraphicsResource * resource)
|
||||
{
|
||||
delete resource;
|
||||
}
|
||||
|
||||
struct GetResourceData
|
||||
{
|
||||
GstHipGraphicsResource *resource = nullptr;
|
||||
hipError_t ret = hipSuccess;
|
||||
GstMemory *gl_mem;
|
||||
GstHipDevice *device;
|
||||
};
|
||||
|
||||
static void
|
||||
get_resource_on_gl_thread (GstGLContext * gl_context, GetResourceData * data)
|
||||
{
|
||||
static GQuark gl_quark = 0;
|
||||
static std::once_flag once;
|
||||
|
||||
std::call_once (once,[&] {
|
||||
gl_quark = g_quark_from_static_string ("GstHipGraphicsResourceGL");
|
||||
});
|
||||
|
||||
auto resource = (GstHipGraphicsResource *)
|
||||
gst_mini_object_get_qdata ((GstMiniObject *) data->gl_mem, gl_quark);
|
||||
|
||||
if (resource) {
|
||||
data->resource = gst_hip_graphics_resource_ref (resource);
|
||||
data->ret = hipSuccess;
|
||||
return;
|
||||
}
|
||||
|
||||
auto vendor = gst_hip_device_get_vendor (data->device);
|
||||
auto ret = HipSetDevice (vendor, gst_hip_device_get_device_id (data->device));
|
||||
if (!gst_hip_result (ret, vendor)) {
|
||||
data->ret = ret;
|
||||
return;
|
||||
}
|
||||
|
||||
auto pbo = (GstGLMemoryPBO *) data->gl_mem;
|
||||
hipGraphicsResource *handle;
|
||||
ret = HipGraphicsGLRegisterBuffer (vendor,
|
||||
&handle, pbo->pbo->id, hipGraphicsRegisterFlagsNone);
|
||||
if (!gst_hip_result (ret, vendor)) {
|
||||
data->ret = ret;
|
||||
return;
|
||||
}
|
||||
|
||||
auto new_resource = new GstHipGraphicsResource ();
|
||||
new_resource->device = (GstHipDevice *) gst_object_ref (data->device);
|
||||
new_resource->gl_context = (GstGLContext *) gst_object_ref (gl_context);
|
||||
new_resource->vendor = vendor;
|
||||
new_resource->handle = handle;
|
||||
|
||||
gst_mini_object_init (new_resource, 0, gst_hip_graphics_resource_get_type (),
|
||||
nullptr, nullptr,
|
||||
(GstMiniObjectFreeFunction) gst_hip_graphics_resource_free);
|
||||
|
||||
gst_mini_object_set_qdata ((GstMiniObject *) data->gl_mem, gl_quark,
|
||||
gst_hip_graphics_resource_ref (new_resource),
|
||||
(GDestroyNotify) gst_mini_object_unref);
|
||||
|
||||
data->resource = new_resource;
|
||||
data->ret = hipSuccess;
|
||||
}
|
||||
|
||||
hipError_t
|
||||
gst_hip_get_graphics_resource_from_gl_memory (GstHipDevice * device,
|
||||
GstMemory * mem, GstHipGraphicsResource ** resource)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_HIP_DEVICE (device), hipErrorInvalidValue);
|
||||
g_return_val_if_fail (gst_is_gl_memory_pbo (mem), hipErrorInvalidValue);
|
||||
g_return_val_if_fail (resource, hipErrorInvalidValue);
|
||||
|
||||
GetResourceData data;
|
||||
data.device = device;
|
||||
data.gl_mem = mem;
|
||||
|
||||
gst_gl_context_thread_add (GST_GL_BASE_MEMORY_CAST (mem)->context,
|
||||
(GstGLContextThreadFunc) get_resource_on_gl_thread, &data);
|
||||
|
||||
if (data.ret != hipSuccess)
|
||||
return data.ret;
|
||||
|
||||
*resource = data.resource;
|
||||
return hipSuccess;
|
||||
}
|
||||
#endif
|
47
subprojects/gst-plugins-bad/sys/hip/gsthip-interop.h
Normal file
47
subprojects/gst-plugins-bad/sys/hip/gsthip-interop.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) 2025 Seungha Yang <seungha@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "gsthip_fwd.h"
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GType gst_hip_graphics_resource_get_type (void);
|
||||
|
||||
hipError_t gst_hip_graphics_resource_map (GstHipGraphicsResource * resource,
|
||||
hipStream_t stream);
|
||||
|
||||
hipError_t gst_hip_graphics_resource_unmap (GstHipGraphicsResource * resource,
|
||||
hipStream_t stream);
|
||||
|
||||
hipError_t gst_hip_graphics_resource_get_mapped_pointer (GstHipGraphicsResource * resource,
|
||||
void ** dev_ptr,
|
||||
size_t * size);
|
||||
|
||||
GstHipGraphicsResource * gst_hip_graphics_resource_ref (GstHipGraphicsResource * resource);
|
||||
|
||||
void gst_hip_graphics_resource_unref (GstHipGraphicsResource * resource);
|
||||
|
||||
void gst_clear_hip_graphics_resource (GstHipGraphicsResource ** resource);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -29,4 +29,5 @@
|
||||
#include "gsthipbufferpool.h"
|
||||
#include "gsthiputils.h"
|
||||
#include "gsthiploader.h"
|
||||
#include "gsthip-interop.h"
|
||||
|
||||
|
@ -42,5 +42,7 @@ typedef struct _GstHipBufferPool GstHipBufferPool;
|
||||
typedef struct _GstHipBufferPoolClass GstHipBufferPoolClass;
|
||||
typedef struct _GstHipBufferPoolPrivate GstHipBufferPoolPrivate;
|
||||
|
||||
typedef struct _GstHipGraphicsResource GstHipGraphicsResource;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -10,6 +10,7 @@ hip_sources = [
|
||||
'gsthipmemorycopy.cpp',
|
||||
'gsthiprtc.cpp',
|
||||
'gsthiputils.cpp',
|
||||
'gsthip-interop.cpp',
|
||||
'plugin.cpp',
|
||||
]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user