clray

changeset 42:1169f3d04135

added CL/GL interop support for macosx (compiles) and windows (untested)
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 28 Aug 2010 02:01:16 +0100
parents 057b8575a1c1
children f9eec11e5acc
files Makefile src/ocl.cc
diffstat 2 files changed, 52 insertions(+), 6 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Fri Aug 27 20:39:55 2010 +0100
     1.2 +++ b/Makefile	Sat Aug 28 02:01:16 2010 +0100
     1.3 @@ -13,7 +13,6 @@
     1.4  else
     1.5  	libgl = -lGL -lglut
     1.6  	libcl = -lOpenCL
     1.7 -
     1.8  	def = -DCLGL_INTEROP
     1.9  endif
    1.10  
     2.1 --- a/src/ocl.cc	Fri Aug 27 20:39:55 2010 +0100
     2.2 +++ b/src/ocl.cc	Sat Aug 28 02:01:16 2010 +0100
     2.3 @@ -21,6 +21,10 @@
     2.4  #include <GL/glx.h>
     2.5  #endif
     2.6  
     2.7 +#ifdef __APPLE__
     2.8 +#include <OpenGL/CGLCurrent.h>
     2.9 +#endif
    2.10 +
    2.11  
    2.12  struct device_info {
    2.13  	cl_device_id id;
    2.14 @@ -33,10 +37,14 @@
    2.15  	size_t work_group_size;
    2.16  
    2.17  	unsigned long mem_size;
    2.18 +
    2.19 +	char *extensions;
    2.20 +	bool gl_sharing;
    2.21  };
    2.22  
    2.23  static int select_device(struct device_info *di, int (*devcmp)(struct device_info*, struct device_info*));
    2.24  static int get_dev_info(cl_device_id dev, struct device_info *di);
    2.25 +static void destroy_dev_info(struct device_info *di);
    2.26  static int devcmp(struct device_info *a, struct device_info *b);
    2.27  static const char *devtypestr(cl_device_type type);
    2.28  static void print_memsize(FILE *out, unsigned long memsz);
    2.29 @@ -53,13 +61,25 @@
    2.30  		return false;
    2.31  	}
    2.32  
    2.33 +
    2.34 +
    2.35  #ifndef CLGL_INTEROP
    2.36  	cl_context_properties *prop = 0;
    2.37 -
    2.38  #else
    2.39  
    2.40  #if defined(__APPLE__)
    2.41 -#error "CL/GL context sharing not implemented on MacOSX yet"
    2.42 +	CGLContextObj glctx = CGLGetCurrentContext();
    2.43 +	CGLShareGroupObj sgrp = CGLGetShareGroup(glctx);
    2.44 +
    2.45 +	cl_context_properties prop[] = {
    2.46 +#ifdef CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE
    2.47 +		CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)sgrp,
    2.48 +#else
    2.49 +		CL_GL_CONTEXT_KHR, (cl_context_properties)glctx,
    2.50 +		CL_CGL_SHAREGROUP_KHR, (cl_context_properties)sgrp,
    2.51 +#endif
    2.52 +		0
    2.53 +	};
    2.54  #elif defined(unix) || defined(__unix__)
    2.55  	Display *dpy = glXGetCurrentDisplay();
    2.56  	GLXContext glctx = glXGetCurrentContext();
    2.57 @@ -72,7 +92,14 @@
    2.58  		0
    2.59  	};
    2.60  #elif defined(WIN32) || defined(__WIN32__)
    2.61 -#error "CL/GL context sharing not implemented on windows yet"
    2.62 +	HGLRC glctx = wglGetCurrentContext();
    2.63 +	HDC dc = wglGetCurrentDC();
    2.64 +
    2.65 +	cl_context_properties prop[] = {
    2.66 +		CL_GL_CONTEXT_KHR, (cl_context_properties)glctx,
    2.67 +		CL_WGL_HDC_KHR, (cl_context_properties)dc,
    2.68 +		0
    2.69 +	};
    2.70  #else
    2.71  #error "unknown or unsupported platform"
    2.72  #endif
    2.73 @@ -631,7 +658,7 @@
    2.74  		struct device_info di;
    2.75  
    2.76  		if(get_dev_info(dev[i], &di) == -1) {
    2.77 -			free(dev_inf->work_item_sizes);
    2.78 +			destroy_dev_info(&di);
    2.79  			return -1;
    2.80  		}
    2.81  
    2.82 @@ -654,6 +681,8 @@
    2.83  		print_memsize(stdout, di.mem_size);
    2.84  		putchar('\n');
    2.85  
    2.86 +		printf("extensions: %s\n", di.extensions);
    2.87 +
    2.88  		if(devcmp(&di, dev_inf) > 0) {
    2.89  			free(dev_inf->work_item_sizes);
    2.90  			memcpy(dev_inf, &di, sizeof di);
    2.91 @@ -673,7 +702,6 @@
    2.92  {
    2.93  	di->id = dev;
    2.94  
    2.95 -
    2.96  	clGetDeviceInfo(dev, CL_DEVICE_TYPE, sizeof di->type, &di->type, 0);
    2.97  	clGetDeviceInfo(dev, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof di->units, &di->units, 0);
    2.98  	clGetDeviceInfo(dev, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof di->clock, &di->clock, 0);
    2.99 @@ -685,9 +713,28 @@
   2.100  	clGetDeviceInfo(dev, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof di->work_group_size, &di->work_group_size, 0);
   2.101  	clGetDeviceInfo(dev, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof di->mem_size, &di->mem_size, 0);
   2.102  
   2.103 +	size_t ext_str_len;
   2.104 +	clGetDeviceInfo(dev, CL_DEVICE_EXTENSIONS, 0, 0, &ext_str_len);
   2.105 +
   2.106 +	di->extensions = new char[ext_str_len + 1];
   2.107 +	clGetDeviceInfo(dev, CL_DEVICE_EXTENSIONS, ext_str_len, di->extensions, 0);
   2.108 +	di->extensions[ext_str_len] = 0;
   2.109 +
   2.110 +	if(strstr(di->extensions, "cl_khr_gl_sharing") || strstr(di->extensions, "cl_APPLE_gl_sharing")) {
   2.111 +		di->gl_sharing = true;
   2.112 +	} else {
   2.113 +		di->gl_sharing = false;
   2.114 +	}
   2.115 +
   2.116  	return 0;
   2.117  }
   2.118  
   2.119 +static void destroy_dev_info(struct device_info *di)
   2.120 +{
   2.121 +	delete [] di->work_item_sizes;
   2.122 +	delete [] di->extensions;
   2.123 +}
   2.124 +
   2.125  static int devcmp(struct device_info *a, struct device_info *b)
   2.126  {
   2.127  	unsigned int aval = a->units * a->clock;