aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2014-07-24 01:32:52 +0200
committerSylvain Munaut <tnt@246tNt.com>2014-07-24 22:34:06 +0200
commit9433e6047828583a507ddf118e26c4c150721edf (patch)
tree7b59f658ba534d68279111187215ba07d8f3bc78
parentcc9f988a204971b072ddb4796d7bbe97a394f00e (diff)
fosphor/cl: Handle CL 1.1 vs 1.2 differently
The OpenCL 1.2 is nicer but we can't always use it and on linux, even if the CL_VERSION_1_2 exists, we can't trust it because distrib sometimes have CL 1.2 headers with a CL 1.1 dispatcher. So instead, we only assume we have 1.1 header and lib at compile time. Then at run-time we do a dynamic lookup of the 1.2 symbols from the lib. We also check if the actual selected platform does support 1.2 (you could have a 1.2 dispatcher with a 1.1 platform implementation). If both conditions are satisfied, then we dispatch the call to the 1.2 implementation and if not, then we dispatch them to a local fallback implementation of the functions (but limited to the functions we need) It's not pretty but it should work and it isolates all the hack magic inside cl_compat.{c,h} and you just use the CL1.2 API normally outside of it. Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--lib/fosphor/Makefile4
-rw-r--r--lib/fosphor/cl.c9
-rw-r--r--lib/fosphor/cl_compat.c150
-rw-r--r--lib/fosphor/cl_compat.h65
-rw-r--r--lib/fosphor/cl_platform.h9
5 files changed, 225 insertions, 12 deletions
diff --git a/lib/fosphor/Makefile b/lib/fosphor/Makefile
index 9007af3..a8fb3bb 100644
--- a/lib/fosphor/Makefile
+++ b/lib/fosphor/Makefile
@@ -6,7 +6,7 @@ ifneq ($(AMDAPPSDKROOT), )
CFLAGS+=-I$(AMDAPPSDKROOT)/include
endif
ifeq ($(UNAME), Linux)
-LDLIBS+=-lOpenCL -lGL
+LDLIBS+=-lOpenCL -lGL -ldl
endif
ifeq ($(UNAME), Darwin)
LDLIBS+=-framework OpenCL -framework OpenGL -framework Cocoa -framework IOKit
@@ -20,7 +20,7 @@ all: main
resource_data.c: $(RESOURCE_FILES) mkresources.py
./mkresources.py $(RESOURCE_FILES) > resource_data.c
-main: resource.o resource_data.o axis.o cl.o fosphor.o gl.o gl_cmap.o gl_cmap_gen.o gl_font.o main.o
+main: resource.o resource_data.o axis.o cl.o cl_compat.o fosphor.o gl.o gl_cmap.o gl_cmap_gen.o gl_font.o main.o
clean:
rm -f main *.o resource_data.c
diff --git a/lib/fosphor/cl.c b/lib/fosphor/cl.c
index 7cbb795..edf82c3 100644
--- a/lib/fosphor/cl.c
+++ b/lib/fosphor/cl.c
@@ -34,6 +34,7 @@
#include <string.h>
#include "cl_platform.h"
+#include "cl_compat.h"
#if defined(__APPLE__) || defined(MAXOSX)
# include <OpenGL/OpenGL.h>
@@ -461,7 +462,7 @@ cl_do_init(struct fosphor *self)
/* GL shared objects */
/* Waterfall texture */
- cl->mem_waterfall = clCreateFromGLTexture2D(cl->ctx,
+ cl->mem_waterfall = clCreateFromGLTexture(cl->ctx,
CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0,
fosphor_gl_get_shared_id(self, GL_ID_TEX_WATERFALL),
&err
@@ -469,7 +470,7 @@ cl_do_init(struct fosphor *self)
CL_ERR_CHECK(err, "Unable to share waterfall texture into OpenCL context");
/* Histogram texture */
- cl->mem_histogram = clCreateFromGLTexture2D(cl->ctx,
+ cl->mem_histogram = clCreateFromGLTexture(cl->ctx,
CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0,
fosphor_gl_get_shared_id(self, GL_ID_TEX_HISTOGRAM),
&err
@@ -600,6 +601,10 @@ fosphor_cl_init(struct fosphor *self)
fprintf(stderr, "[+] Selected device: %s\n", dev_name);
+ /* Setup compatibility layer for this platform */
+ cl_compat_init();
+ cl_compat_check_platform(cl->pl_id);
+
/* Initialize selected platform / device */
err = cl_do_init(self);
if (err)
diff --git a/lib/fosphor/cl_compat.c b/lib/fosphor/cl_compat.c
new file mode 100644
index 0000000..f735a97
--- /dev/null
+++ b/lib/fosphor/cl_compat.c
@@ -0,0 +1,150 @@
+/*
+ * cl_compat.c
+ *
+ * Handle OpenCL 1.1 <> 1.2 fallback and the related uglyness
+ *
+ * Copyright (C) 2013-2014 Sylvain Munaut
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*! \addtogroup cl
+ * @{
+ */
+
+/*! \file cl_compat.c
+ * \brief Handle OpenCL 1.1 <> 1.2 fallback and the related uglyness
+ */
+
+/* Include whatever is needed for dynamic symbol lookup */
+#ifdef _WIN32
+# include <Windows.h>
+#else
+# define _GNU_SOURCE
+# include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+/* Make sure we allow OpenCL 1.1 fn without warnings */
+#define CL_USE_DEPRECATED_OPENCL_1_1_APIS
+
+#include "cl_compat.h"
+
+
+/* -------------------------------------------------------------------------- */
+/* Fallback magic */
+/* -------------------------------------------------------------------------- */
+
+#define ALT_WRAP(rtype, fn, arg_list, arg_call) \
+ \
+ static CL_API_ENTRY rtype CL_API_CALL (* fn ## _icd) arg_list = NULL; \
+ static rtype fn ## _alt arg_list; \
+ \
+ CL_API_ENTRY rtype CL_API_CALL fn arg_list \
+ { \
+ if (g_allow_cl12 && fn ## _icd) \
+ return fn ## _icd arg_call; \
+ else \
+ return fn ## _alt arg_call; \
+ } \
+ \
+ static rtype fn ## _alt arg_list
+
+#define ALT_INIT(fn) \
+ *(void **)(&fn ## _icd) = _cl_icd_get_sym(#fn); \
+ if (!fn ## _icd) \
+ g_allow_cl12 = 0;
+
+
+/*! \brief Whether to allow direct CL 1.2 usage or not */
+static int g_allow_cl12 = 1;
+
+
+/*! \brief Tries to find a function pointer to a given OpenCL function
+ * \param[in] fn The name of the function to lookup
+ */
+static void *
+_cl_icd_get_sym(const char *fn)
+{
+#ifdef _WIN32
+ static HMODULE h = NULL;
+ if (!h)
+ h = GetModuleHandle(L"OpenCL.dll");
+ return GetProcAddress(h, fn);
+#else
+ return dlsym(RTLD_NEXT, fn);
+#endif
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* Fallback implementations */
+/* -------------------------------------------------------------------------- */
+/* These are only valid for fosphor and might not cover all use cases ! */
+
+ALT_WRAP(cl_mem,
+ clCreateFromGLTexture,
+ (cl_context context,
+ cl_mem_flags flags,
+ GLenum texture_target,
+ GLint miplevel,
+ GLuint texture,
+ cl_int *errcode_ret),
+ (context, flags, texture_target, miplevel, texture, errcode_ret)
+)
+{
+ return clCreateFromGLTexture2D(
+ context,
+ flags,
+ texture_target,
+ miplevel,
+ texture,
+ errcode_ret
+ );
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* Compat API control */
+/* -------------------------------------------------------------------------- */
+
+void
+cl_compat_init(void)
+{
+ ALT_INIT(clCreateFromGLTexture)
+}
+
+void
+cl_compat_check_platform(cl_platform_id pl_id)
+{
+ cl_int err;
+ char buf[128];
+
+ if (!g_allow_cl12)
+ return;
+
+ err = clGetPlatformInfo(pl_id, CL_PLATFORM_VERSION, sizeof(buf), buf, NULL);
+ if (err != CL_SUCCESS) {
+ fprintf(stderr, "[!] Failed to fetch platform version. Assume it can't do OpenCL 1.2\n");
+ g_allow_cl12 = 0;
+ }
+
+ if (strncmp(buf, "OpenCL 1.2 ", 11)) {
+ g_allow_cl12 = 0;
+ }
+}
+
+/*! @} */
diff --git a/lib/fosphor/cl_compat.h b/lib/fosphor/cl_compat.h
new file mode 100644
index 0000000..a1c5b33
--- /dev/null
+++ b/lib/fosphor/cl_compat.h
@@ -0,0 +1,65 @@
+/*
+ * cl_compat.h
+ *
+ * Handle OpenCL 1.1 <> 1.2 fallback and the related uglyness
+ *
+ * Copyright (C) 2013-2014 Sylvain Munaut
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __FOSPHOR_CL_COMPAT_H__
+#define __FOSPHOR_CL_COMPAT_H__
+
+/*! \ingroup cl
+ * @{
+ */
+
+/*! \file cl_compat.h
+ * \brief Handle OpenCL 1.1 <> 1.2 fallback and the related uglyness
+ */
+
+#include "cl_platform.h"
+#include "gl_platform.h"
+
+
+/* Define NVidia specific attributes */
+#ifndef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
+# define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
+# define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
+#endif
+
+
+/* If OpenCL 1.2 isn't supported in the header, add our prototypes */
+#ifndef CL_VERSION_1_2
+
+cl_mem
+clCreateFromGLTexture(cl_context context,
+ cl_mem_flags flags,
+ GLenum texture_target,
+ GLint miplevel,
+ GLuint texture,
+ cl_int *errcode_ret);
+
+#endif
+
+
+/* The actual API */
+void cl_compat_init(void);
+void cl_compat_check_platform(cl_platform_id pl_id);
+
+
+/*! @} */
+
+#endif /* __FOSPHOR_CL_COMPAT_H__ */
diff --git a/lib/fosphor/cl_platform.h b/lib/fosphor/cl_platform.h
index 38ba8ab..2816726 100644
--- a/lib/fosphor/cl_platform.h
+++ b/lib/fosphor/cl_platform.h
@@ -27,22 +27,15 @@
# define _WIN32
#endif
+
#if defined(__APPLE__) || defined(MAXOSX)
# include <OpenCL/cl.h>
# include <OpenCL/cl_ext.h>
# include <OpenCL/cl_gl.h>
# include <OpenCL/cl_gl_ext.h>
-# ifdef CL_VERSION_1_2
-# define clCreateFromGLTexture2D clCreateFromGLTexture
-# endif
#else
# define CL_USE_DEPRECATED_OPENCL_1_1_APIS
# include <CL/cl.h>
# include <CL/cl_ext.h>
# include <CL/cl_gl.h>
#endif
-
-#ifndef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
-# define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
-# define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
-#endif