diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2014-07-24 01:32:52 +0200 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2014-07-24 22:34:06 +0200 |
commit | 9433e6047828583a507ddf118e26c4c150721edf (patch) | |
tree | 7b59f658ba534d68279111187215ba07d8f3bc78 | |
parent | cc9f988a204971b072ddb4796d7bbe97a394f00e (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/Makefile | 4 | ||||
-rw-r--r-- | lib/fosphor/cl.c | 9 | ||||
-rw-r--r-- | lib/fosphor/cl_compat.c | 150 | ||||
-rw-r--r-- | lib/fosphor/cl_compat.h | 65 | ||||
-rw-r--r-- | lib/fosphor/cl_platform.h | 9 |
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 |