summaryrefslogtreecommitdiff
path: root/sys/nvdec/dynlink_cuda.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/nvdec/dynlink_cuda.c')
-rw-r--r--sys/nvdec/dynlink_cuda.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/sys/nvdec/dynlink_cuda.c b/sys/nvdec/dynlink_cuda.c
new file mode 100644
index 000000000..995481b64
--- /dev/null
+++ b/sys/nvdec/dynlink_cuda.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gst/gst.h>
+#include <gst/gl/gstglfuncs.h>
+#include <dynlink_cuda.h>
+#include <gmodule.h>
+
+/* Types that are missing from included headers */
+typedef CUresult CUDAAPI tcuGetErrorName (CUresult error, const char **pStr);
+typedef CUresult CUDAAPI tcuGetErrorString (CUresult error, const char **pStr);
+typedef CUresult CUDAAPI tcuGraphicsGLRegisterImage (CUgraphicsResource *
+ pCudaResource, GLuint image, GLenum target, unsigned int Flags);
+
+tcuInit *_cuInit;
+tcuDriverGetVersion *cuDriverGetVersion;
+tcuCtxCreate *cuCtxCreate;
+tcuCtxDestroy *cuCtxDestroy;
+tcuCtxPopCurrent *cuCtxPopCurrent;
+tcuMemcpy2D *cuMemcpy2D;
+tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource;
+tcuGraphicsSubResourceGetMappedArray *cuGraphicsSubResourceGetMappedArray;
+tcuGraphicsMapResources *cuGraphicsMapResources;
+tcuGraphicsUnmapResources *cuGraphicsUnmapResources;
+
+tcuGetErrorName *cuGetErrorName;
+tcuGetErrorString *cuGetErrorString;
+tcuGraphicsGLRegisterImage *cuGraphicsGLRegisterImage;
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+static char CudaLibName[] = "nvcuda.dll";
+#elif defined(__unix__)
+static char CudaLibName[] = "libcuda.so";
+#endif
+
+#define STRINGIFY(X) #X
+#define GET_PROC(name) \
+ if (!g_module_symbol (module, #name, (gpointer *)&name)) { \
+ GST_ERROR("%s", g_module_error()); \
+ g_module_close(module); \
+ return CUDA_ERROR_UNKNOWN; \
+ }
+
+#define GET_PROC_V2(name) \
+ if(!g_module_symbol (module, STRINGIFY(name##_v2), (gpointer *)&name)) { \
+ GST_ERROR("%s", g_module_error()); \
+ g_module_close(module); \
+ return CUDA_ERROR_UNKNOWN; \
+ }
+
+CUresult CUDAAPI
+cuInit (unsigned int Flags, int cudaVersion, void *pHandleDriver)
+{
+ GModule *module;
+ int driverVer = 1000;
+
+ module = g_module_open (CudaLibName, G_MODULE_BIND_LAZY);
+ if (module == NULL) {
+ GST_ERROR ("%s", g_module_error ());
+ return CUDA_ERROR_UNKNOWN;
+ }
+ //Init
+ g_module_symbol (module, "cuInit", (gpointer *) & _cuInit);
+ if (_cuInit == NULL || _cuInit (Flags) != CUDA_SUCCESS) {
+ GST_ERROR ("Failed to init cuda\n");
+ return CUDA_ERROR_UNKNOWN;
+ }
+
+ GET_PROC (cuDriverGetVersion);
+ if (cuDriverGetVersion == NULL
+ || cuDriverGetVersion (&driverVer) != CUDA_SUCCESS) {
+ GST_ERROR ("Failed to get cuda version\n");
+ return CUDA_ERROR_UNKNOWN;
+ }
+
+ if (cudaVersion < 4000 || __CUDA_API_VERSION < 4000) {
+ GST_ERROR ("cuda version or cuda api version is too old\n");
+ return CUDA_ERROR_UNKNOWN;
+ }
+
+ GET_PROC (cuCtxDestroy);
+ GET_PROC (cuCtxPopCurrent);
+ GET_PROC (cuGetErrorName);
+ GET_PROC (cuGetErrorString);
+
+ GET_PROC_V2 (cuCtxDestroy);
+ GET_PROC_V2 (cuCtxPopCurrent);
+ GET_PROC_V2 (cuCtxCreate);
+ GET_PROC_V2 (cuMemcpy2D);
+ GET_PROC (cuGraphicsGLRegisterImage);
+ GET_PROC (cuGraphicsGLRegisterImage);
+ GET_PROC (cuGraphicsUnregisterResource);
+ GET_PROC (cuGraphicsSubResourceGetMappedArray);
+ GET_PROC (cuGraphicsMapResources);
+ GET_PROC (cuGraphicsUnmapResources);
+
+ return CUDA_SUCCESS;
+}