--- OpenCL/OpenCL.xs 2012/04/19 13:49:33 1.28 +++ OpenCL/OpenCL.xs 2012/04/21 17:56:21 1.36 @@ -2,6 +2,10 @@ #include "perl.h" #include "XSUB.h" +#ifdef I_DLFCN + #include +#endif + #ifdef __APPLE__ #include #else @@ -33,6 +37,51 @@ /*****************************************************************************/ +// name must include a leading underscore +// all of this horrors would be unneceesary if somebody wrote a proper OpenGL module +// for perl. doh. +static void * +glsym (const char *name) +{ + void *fun = 0; + + #if defined I_DLFCN && defined RTLD_DEFAULT + fun = dlsym (RTLD_DEFAULT, name + 1); + if (!fun) fun = dlsym (RTLD_DEFAULT, name); + + if (!fun) + { + static void *libgl; + static const char *glso[] = { + "libGL.so.1", + "libGL.so.3", + "libGL.so.4.0", + "libGL.so", + "/usr/lib/libGL.so", + "/usr/X11R6/lib/libGL.1.dylib" + }; + int i; + + for (i = 0; !libgl && i < sizeof (glso) / sizeof (glso [0]); ++i) + { + libgl = dlopen (glso [i], RTLD_LAZY); + if (libgl) + break; + } + + if (libgl) + { + fun = dlsym (libgl, name + 1); + if (!fun) fun = dlsym (libgl, name); + } + } + #endif + + return fun; +} + +/*****************************************************************************/ + /* up to two temporary buffers */ static void * tmpbuf (size_t size) @@ -156,18 +205,34 @@ while (extracount--) *l++ = *extra++; - for (i = 0; i < len; ++i) + for (i = 0; i < len; i += 2) { - cl_context_properties t = SvIV (*av_fetch (av, i, 0)); - cl_context_properties v; - - ++i; + cl_context_properties t = SvIV (*av_fetch (av, i , 0)); + SV *p_sv = *av_fetch (av, i + 1, 0); + cl_context_properties v = SvIV (p_sv); // code below can override switch (t) { + case CL_GLX_DISPLAY_KHR: + if (!SvOK (p_sv)) + { + void *func = glsym ("_glXGetCurrentDisplay"); + if (func) + v = (cl_context_properties)((void *(*)(void))func)(); + } + break; + + case CL_GL_CONTEXT_KHR: + if (!SvOK (p_sv)) + { + void *func = glsym ("_glXGetCurrentContext"); + if (func) + v = (cl_context_properties)((void *(*)(void))func)(); + } + break; + default: /* unknown property, treat as int */ - v = SvIV (*av_fetch (av, i, 0)); break; } @@ -194,22 +259,32 @@ } static cl_event * -event_list (SV **items, int count) +event_list (SV **items, cl_uint *rcount) { + cl_uint count = *rcount; + if (!count) return 0; cl_event *list = tmpbuf (sizeof (cl_event) * count); + int i = 0; - while (count--) - list [count] = SvPTROBJ ("clEnqueue", "wait_events", items [count], "OpenCL::Event"); + do + { + --count; + if (SvOK (items [count])) + list [i++] = SvPTROBJ ("clEnqueue", "wait_events", items [count], "OpenCL::Event"); + } + while (count); + + *rcount = i; - return list; + return i ? list : 0; } #define EVENT_LIST(items,count) \ cl_uint event_list_count = (count); \ - cl_event *event_list_ptr = event_list (&ST (items), event_list_count) + cl_event *event_list_ptr = event_list (&ST (items), &event_list_count) #define INFO(class) \ { \ @@ -792,7 +867,7 @@ char *ptr = SvPVbyte (data, len); EVENT_LIST (5, items - 5); - NEED_SUCCESS (EnqueueReadBuffer, (self, mem, blocking, offset, len, ptr, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); + NEED_SUCCESS (EnqueueWriteBuffer, (self, mem, blocking, offset, len, ptr, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); if (ev) XPUSH_NEW_OBJ ("OpenCL::Event", ev); @@ -1047,7 +1122,7 @@ enqueue_acquire_gl_objects (OpenCL::Queue self, SV *objects, ...) ALIAS: enqueue_release_gl_objects = 1 - CODE: + PPCODE: if (!SvROK (objects) || SvTYPE (SvRV (objects)) != SVt_PVAV) croak ("OpenCL::Queue::enqueue_acquire/release_gl_objects argument 'objects' must be an arrayref with memory objects, in call"); @@ -1247,7 +1322,7 @@ PPCODE: cl_gl_object_type type; cl_GLuint name; - NEED_SUCCESS (clGetGLObjectInfo, (self, &type, &name)); + NEED_SUCCESS (GetGLObjectInfo, (self, &type, &name)); EXTEND (SP, 2); PUSHs (sv_2mortal (newSVuv (type))); PUSHs (sv_2mortal (newSVuv (name))); @@ -1302,7 +1377,7 @@ target (OpenCL::Image self) PPCODE: cl_GLenum value [1]; - NEED_SUCCESS (GetGlTextureInfo, (self, CL_GL_TEXTURE_TARGET, sizeof (value), value, 0)); + NEED_SUCCESS (GetGLTextureInfo, (self, CL_GL_TEXTURE_TARGET, sizeof (value), value, 0)); EXTEND (SP, 1); const int i = 0; PUSHs (sv_2mortal (newSVuv (value [i]))); @@ -1311,7 +1386,7 @@ gl_mipmap_level (OpenCL::Image self) PPCODE: cl_GLint value [1]; - NEED_SUCCESS (GetGlTextureInfo, (self, CL_GL_MIPMAP_LEVEL, sizeof (value), value, 0)); + NEED_SUCCESS (GetGLTextureInfo, (self, CL_GL_MIPMAP_LEVEL, sizeof (value), value, 0)); EXTEND (SP, 1); const int i = 0; PUSHs (sv_2mortal (newSViv (value [i]))); @@ -1627,6 +1702,11 @@ clSetKernelArg (self, idx, sizeof (value), &value); void +set_local (OpenCL::Kernel self, cl_uint idx, size_t size) + CODE: + clSetKernelArg (self, idx, size, 0); + +void set_event (OpenCL::Kernel self, cl_uint idx, OpenCL::Event value) CODE: clSetKernelArg (self, idx, sizeof (value), &value);