clray

diff src/ocl.cc @ 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
line diff
     1.1 --- a/src/ocl.cc	Fri Aug 27 20:39:55 2010 +0100
     1.2 +++ b/src/ocl.cc	Sat Aug 28 02:01:16 2010 +0100
     1.3 @@ -21,6 +21,10 @@
     1.4  #include <GL/glx.h>
     1.5  #endif
     1.6  
     1.7 +#ifdef __APPLE__
     1.8 +#include <OpenGL/CGLCurrent.h>
     1.9 +#endif
    1.10 +
    1.11  
    1.12  struct device_info {
    1.13  	cl_device_id id;
    1.14 @@ -33,10 +37,14 @@
    1.15  	size_t work_group_size;
    1.16  
    1.17  	unsigned long mem_size;
    1.18 +
    1.19 +	char *extensions;
    1.20 +	bool gl_sharing;
    1.21  };
    1.22  
    1.23  static int select_device(struct device_info *di, int (*devcmp)(struct device_info*, struct device_info*));
    1.24  static int get_dev_info(cl_device_id dev, struct device_info *di);
    1.25 +static void destroy_dev_info(struct device_info *di);
    1.26  static int devcmp(struct device_info *a, struct device_info *b);
    1.27  static const char *devtypestr(cl_device_type type);
    1.28  static void print_memsize(FILE *out, unsigned long memsz);
    1.29 @@ -53,13 +61,25 @@
    1.30  		return false;
    1.31  	}
    1.32  
    1.33 +
    1.34 +
    1.35  #ifndef CLGL_INTEROP
    1.36  	cl_context_properties *prop = 0;
    1.37 -
    1.38  #else
    1.39  
    1.40  #if defined(__APPLE__)
    1.41 -#error "CL/GL context sharing not implemented on MacOSX yet"
    1.42 +	CGLContextObj glctx = CGLGetCurrentContext();
    1.43 +	CGLShareGroupObj sgrp = CGLGetShareGroup(glctx);
    1.44 +
    1.45 +	cl_context_properties prop[] = {
    1.46 +#ifdef CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE
    1.47 +		CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)sgrp,
    1.48 +#else
    1.49 +		CL_GL_CONTEXT_KHR, (cl_context_properties)glctx,
    1.50 +		CL_CGL_SHAREGROUP_KHR, (cl_context_properties)sgrp,
    1.51 +#endif
    1.52 +		0
    1.53 +	};
    1.54  #elif defined(unix) || defined(__unix__)
    1.55  	Display *dpy = glXGetCurrentDisplay();
    1.56  	GLXContext glctx = glXGetCurrentContext();
    1.57 @@ -72,7 +92,14 @@
    1.58  		0
    1.59  	};
    1.60  #elif defined(WIN32) || defined(__WIN32__)
    1.61 -#error "CL/GL context sharing not implemented on windows yet"
    1.62 +	HGLRC glctx = wglGetCurrentContext();
    1.63 +	HDC dc = wglGetCurrentDC();
    1.64 +
    1.65 +	cl_context_properties prop[] = {
    1.66 +		CL_GL_CONTEXT_KHR, (cl_context_properties)glctx,
    1.67 +		CL_WGL_HDC_KHR, (cl_context_properties)dc,
    1.68 +		0
    1.69 +	};
    1.70  #else
    1.71  #error "unknown or unsupported platform"
    1.72  #endif
    1.73 @@ -631,7 +658,7 @@
    1.74  		struct device_info di;
    1.75  
    1.76  		if(get_dev_info(dev[i], &di) == -1) {
    1.77 -			free(dev_inf->work_item_sizes);
    1.78 +			destroy_dev_info(&di);
    1.79  			return -1;
    1.80  		}
    1.81  
    1.82 @@ -654,6 +681,8 @@
    1.83  		print_memsize(stdout, di.mem_size);
    1.84  		putchar('\n');
    1.85  
    1.86 +		printf("extensions: %s\n", di.extensions);
    1.87 +
    1.88  		if(devcmp(&di, dev_inf) > 0) {
    1.89  			free(dev_inf->work_item_sizes);
    1.90  			memcpy(dev_inf, &di, sizeof di);
    1.91 @@ -673,7 +702,6 @@
    1.92  {
    1.93  	di->id = dev;
    1.94  
    1.95 -
    1.96  	clGetDeviceInfo(dev, CL_DEVICE_TYPE, sizeof di->type, &di->type, 0);
    1.97  	clGetDeviceInfo(dev, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof di->units, &di->units, 0);
    1.98  	clGetDeviceInfo(dev, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof di->clock, &di->clock, 0);
    1.99 @@ -685,9 +713,28 @@
   1.100  	clGetDeviceInfo(dev, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof di->work_group_size, &di->work_group_size, 0);
   1.101  	clGetDeviceInfo(dev, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof di->mem_size, &di->mem_size, 0);
   1.102  
   1.103 +	size_t ext_str_len;
   1.104 +	clGetDeviceInfo(dev, CL_DEVICE_EXTENSIONS, 0, 0, &ext_str_len);
   1.105 +
   1.106 +	di->extensions = new char[ext_str_len + 1];
   1.107 +	clGetDeviceInfo(dev, CL_DEVICE_EXTENSIONS, ext_str_len, di->extensions, 0);
   1.108 +	di->extensions[ext_str_len] = 0;
   1.109 +
   1.110 +	if(strstr(di->extensions, "cl_khr_gl_sharing") || strstr(di->extensions, "cl_APPLE_gl_sharing")) {
   1.111 +		di->gl_sharing = true;
   1.112 +	} else {
   1.113 +		di->gl_sharing = false;
   1.114 +	}
   1.115 +
   1.116  	return 0;
   1.117  }
   1.118  
   1.119 +static void destroy_dev_info(struct device_info *di)
   1.120 +{
   1.121 +	delete [] di->work_item_sizes;
   1.122 +	delete [] di->extensions;
   1.123 +}
   1.124 +
   1.125  static int devcmp(struct device_info *a, struct device_info *b)
   1.126  {
   1.127  	unsigned int aval = a->units * a->clock;