--- OpenCL/OpenCL.pm 2012/04/19 14:36:46 1.37 +++ OpenCL/OpenCL.pm 2012/04/21 19:17:09 1.46 @@ -162,7 +162,7 @@ my $prog = $ctx->program_with_source ($src); # build croaks on compile errors, so catch it and print the compile errors - eval { $prog->build ($dev); 1 } + eval { $prog->build ($dev, "-cl-fast-relaxed-math"); 1 } or die $prog->build_log; my $kernel = $prog->kernel ("squareit"); @@ -213,6 +213,101 @@ # wait for the last event to complete $ev->wait; +=head2 Use the OpenGL module to share a texture between OpenCL and OpenGL and draw some julia +set tunnel effect. + +This is quite a long example to get you going. + + use OpenGL ":all"; + use OpenCL; + + # open a window and create a gl texture + OpenGL::glpOpenWindow width => 256, height => 256; + my $texid = glGenTextures_p 1; + glBindTexture GL_TEXTURE_2D, $texid; + glTexImage2D_c GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0; + + # find and use the first opencl device that let's us get a shared opengl context + my $platform; + my $dev; + my $ctx; + + for (OpenCL::platforms) { + $platform = $_; + for ($platform->devices) { + $dev = $_; + $ctx = $platform->context ([OpenCL::GLX_DISPLAY_KHR, undef, OpenCL::GL_CONTEXT_KHR, undef], [$dev]) + and last; + } + } + + $ctx + or die "cannot find suitable OpenCL device\n"; + + my $queue = $ctx->queue ($dev); + + # now attach an opencl image2d object to the opengl texture + my $tex = $ctx->gl_texture2d (OpenCL::MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, $texid); + + # now the boring opencl code + my $src = <program_with_source ($src); + eval { $prog->build ($dev); 1 } + or die $prog->build_log ($dev); + + my $kernel = $prog->kernel ("juliatunnel"); + + # program compiled, kernel ready, now draw and loop + + for (my $time; ; ++$time) { + # acquire objects from opengl + $queue->enqueue_acquire_gl_objects ([$tex]); + + # configure and run our kernel + $kernel->set_image2d (0, $tex); + $kernel->set_float (1, $time); + $queue->enqueue_nd_range_kernel ($kernel, undef, [256, 256], undef); + + # release objects to opengl again + $queue->enqueue_release_gl_objects ([$tex]); + + # wait + $queue->finish; + + # now draw the texture, the defaults should be all right + glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST; + + glEnable GL_TEXTURE_2D; + glBegin GL_QUADS; + glTexCoord2f 0, 1; glVertex3i -1, -1, -1; + glTexCoord2f 0, 0; glVertex3i 1, -1, -1; + glTexCoord2f 1, 0; glVertex3i 1, 1, -1; + glTexCoord2f 1, 1; glVertex3i -1, 1, -1; + glEnd; + + glXSwapBuffers; + + select undef, undef, undef, 1/60; + } + =head1 DOCUMENTATION =head2 BASIC CONVENTIONS @@ -243,7 +338,9 @@ =item * When enqueuing commands, the wait list is specified by adding extra arguments to the function - anywhere a C<$wait_events...> argument -is documented this can be any number of event objects. +is documented this can be any number of event objects. As an extsnion +implemented by this module, C values will be ignored in the event +list. =item * When enqueuing commands, if the enqueue method is called in void context, no event is created. In all other contexts an event is returned @@ -277,11 +374,11 @@ Due to the sad state that OpenGL support is in in Perl (mostly the OpenGL module, which has little to no documentation and has little to no support -for glx), this module, as a special extension, treats context creation +for glX), this module, as a special extension, treats context creation properties C and C specially: If either or both of these are C, then the OpenCL -module tries to dynamically resolve C and -C, call these functions and use their return values +module tries to dynamically resolve C and +C, call these functions and use their return values instead. For this to work, the OpenGL library must be loaded, a GLX context must @@ -655,7 +752,7 @@ Calls C with C and returns the result. -=item $uint = $device->reference_count_ext +=item $uint = $device->reference_count_ext Calls C with C and returns the result. @@ -677,6 +774,10 @@ L +Example: create an out-of-order queue. + + $queue = $ctx->queue ($device, OpenCL::QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); + =item $ev = $ctx->user_event Creates a new OpenCL::UserEvent object. @@ -796,11 +897,17 @@ They also allow you to specify any number of other event objects that this request has to wait for before it starts executing, by simply passing the -event objects as extra parameters to the enqueue methods. +event objects as extra parameters to the enqueue methods. To simplify +program design, this module ignores any C values in the list of +events. This makes it possible to code operations such as this, without +having to put a valid event object into C<$event> first: + + $event = $queue->enqueue_xxx (..., $event); Queues execute in-order by default, without any parallelism, so in most cases (i.e. you use only one queue) it's not necessary to wait for or -create event objects. +create event objects, althoguh an our of order queue is often a bit +faster. =over 4 @@ -876,10 +983,6 @@ L -=item $ev = $queue->enqueue_marker ($wait_events...) - -L - =item $ev = $queue->enqueue_acquire_gl_objects ([object, ...], $wait_events...) Enqueues a list (an array-ref of OpenCL::Memory objects) to be acquired @@ -898,9 +1001,13 @@ L -=item $queue->enqueue_barrier +=item $ev = $queue->enqueue_marker ($wait_events...) + +L + +=item $ev = $queue->enqueue_barrier ($wait_events...) -L +L =item $queue->flush @@ -1276,12 +1383,13 @@ TYPE is one of C, C, C, C, C, C, C, C, C, C, C, C, C, -C, C, C or C. +C, C, C, C or C. Chars and integers (including the half type) are specified as integers, float and double as floating point values, memory/buffer/image2d/image3d -must be an object of that type or C, and sampler and event must be -objects of that type. +must be an object of that type or C, local-memory arguments are +set by specifying the size, and sampler and event must be objects of that +type. L @@ -1380,7 +1488,7 @@ use common::sense; BEGIN { - our $VERSION = '0.92'; + our $VERSION = '0.96'; require XSLoader; XSLoader::load (__PACKAGE__, $VERSION);