--- OpenCL/OpenCL.xs 2012/05/05 15:43:02 1.79 +++ OpenCL/OpenCL.xs 2012/05/05 17:09:19 1.81 @@ -1,3 +1,5 @@ +#include + #include "EXTERN.h" #include "perl.h" #include "XSUB.h" @@ -37,9 +39,11 @@ #include CLHDR(opencl.h) +#if 0 #ifndef CL_VERSION_1_2 #include CLHDR(cl_d3d9.h) #endif +#endif #if _WIN32 #include CLHDR(cl_d3d10.h) @@ -728,10 +732,18 @@ cl_event event; size_t row_pitch; size_t slice_pitch; + + size_t element_size; + size_t width, height, depth; }; static SV * -mapped_new (HV *stash, cl_command_queue queue, cl_mem memobj, cl_map_flags flags, void *ptr, size_t cb, cl_event ev, size_t row_pitch, size_t slice_pitch) +mapped_new ( + HV *stash, cl_command_queue queue, cl_mem memobj, cl_map_flags flags, + void *ptr, size_t cb, cl_event ev, + size_t row_pitch, size_t slice_pitch, size_t element_size, + size_t width, size_t height, size_t depth +) { SV *data = newSV (0); SvUPGRADE (data, SVt_PVMG); @@ -741,13 +753,18 @@ clRetainCommandQueue (queue); - mapped->queue = queue; - mapped->memobj = memobj; - mapped->ptr = ptr; - mapped->cb = cb; - mapped->event = ev; - mapped->row_pitch = row_pitch; - mapped->slice_pitch = slice_pitch; + mapped->queue = queue; + mapped->memobj = memobj; + mapped->ptr = ptr; + mapped->cb = cb; + mapped->event = ev; + mapped->row_pitch = row_pitch; + mapped->slice_pitch = slice_pitch; + + mapped->element_size = element_size; + mapped->width = width; + mapped->height = height; + mapped->depth = depth; sv_magicext (data, 0, PERL_MAGIC_ext, 0, (char *)mapped, 0); @@ -800,6 +817,15 @@ mapped_detach (self, mapped); } +static size_t +mapped_element_size (OpenCL__Mapped self) +{ + if (!self->element_size) + clGetImageInfo (self->memobj, CL_IMAGE_ELEMENT_SIZE, sizeof (self->element_size), &self->element_size, 0); + + return self->element_size; +} + /*****************************************************************************/ MODULE = OpenCL PACKAGE = OpenCL @@ -1842,7 +1868,7 @@ cl_event ev; NEED_SUCCESS_ARG (void *ptr, EnqueueMapBuffer, (self, buf, blocking, map_flags, offset, cb, event_list_count, event_list_ptr, &ev, &res)); - XPUSHs (mapped_new (stash_mappedbuffer, self, buf, map_flags, ptr, cb, ev, 0, 0)); + XPUSHs (mapped_new (stash_mappedbuffer, self, buf, map_flags, ptr, cb, ev, 0, 0, 1, cb, 1, 1)); void map_image (OpenCL::Queue self, OpenCL::Image img, cl_bool blocking = 1, cl_map_flags map_flags = CL_MAP_READ | CL_MAP_WRITE, size_t x = 0, size_t y = 0, size_t z = 0, SV *width_ = &PL_sv_undef, SV *height_ = &PL_sv_undef, SV *depth_ = &PL_sv_undef, ...) @@ -1861,6 +1887,10 @@ { NEED_SUCCESS (GetImageInfo, (img, CL_IMAGE_HEIGHT, sizeof (height), &height, 0)); height -= y; + + // stupid opencl returns 0 for depth, but requires 1 for 2d images + if (!height) + height = 1; } size_t depth = SvIV (width_); @@ -1886,7 +1916,7 @@ : row_pitch ? row_pitch * region [1] : region [0]; - XPUSHs (mapped_new (stash_mappedimage, self, img, map_flags, ptr, cb, ev, row_pitch, slice_pitch)); + XPUSHs (mapped_new (stash_mappedimage, self, img, map_flags, ptr, cb, ev, row_pitch, slice_pitch, 0, width, height, depth)); void unmap (OpenCL::Queue self, OpenCL::Mapped mapped, ...) @@ -3041,10 +3071,24 @@ clRetainEvent (self->event); XPUSH_CLOBJ (stash_event, self->event); -size_t +#define MAPPED_OFFSET_CB offsetof (struct mapped, cb) +#define MAPPED_OFFSET_ROW_PITCH offsetof (struct mapped, row_pitch) +#define MAPPED_OFFSET_SLICE_PITCH offsetof (struct mapped, slice_pitch) +#define MAPPED_OFFSET_WIDTH offsetof (struct mapped, width) +#define MAPPED_OFFSET_HEIGHT offsetof (struct mapped, height) +#define MAPPED_OFFSET_DEPTH offsetof (struct mapped, depth) + +IV size (OpenCL::Mapped self) + ALIAS: + size = MAPPED_OFFSET_CB + row_pitch = MAPPED_OFFSET_ROW_PITCH + slice_pitch = MAPPED_OFFSET_SLICE_PITCH + width = MAPPED_OFFSET_WIDTH + height = MAPPED_OFFSET_HEIGHT + depth = MAPPED_OFFSET_DEPTH CODE: - RETVAL = self->cb; + RETVAL = *(size_t *)((char *)self + ix); OUTPUT: RETVAL @@ -3066,18 +3110,58 @@ memcpy (offset + (char *)self->ptr, ptr, len); +void +get_row (OpenCL::Mapped self, size_t count, size_t x = 0, size_t y = 0, size_t z = 0) + PPCODE: + if (!SvOK (ST (1))) + count = self->width - x; + + if (x + count > self->width) + croak ("OpenCL::Mapped::get: x + count crosses a row boundary"); + + if (y >= self->height) + croak ("OpenCL::Mapped::get: y coordinate out of bounds"); + + if (z >= self->depth) + croak ("OpenCL::Mapped::get: z coordinate out of bounds"); + + size_t element = mapped_element_size (self); + + count *= element; + x *= element; + + char *ptr = (char *)self->ptr + x + y * self->row_pitch + z * self->slice_pitch; + XPUSHs (sv_2mortal (newSVpvn (ptr, count))); + +void +set_row (OpenCL::Mapped self, SV *data, size_t x = 0, size_t y = 0, size_t z = 0) + PPCODE: + STRLEN count; + char *dataptr = SvPVbyte (data, count); + size_t element = mapped_element_size (self); + + x *= element; + + if (x + count > self->width * element) + croak ("OpenCL::Mapped::set: x + data size crosses a row boundary"); + + if (y >= self->height) + croak ("OpenCL::Mapped::set: y coordinate out of bounds"); + + if (z >= self->depth) + croak ("OpenCL::Mapped::set: z coordinate out of bounds"); + + char *ptr = (char *)self->ptr + x + y * self->row_pitch + z * self->slice_pitch; + memcpy (ptr, dataptr, count); + MODULE = OpenCL PACKAGE = OpenCL::MappedBuffer MODULE = OpenCL PACKAGE = OpenCL::MappedImage IV -row_pitch (OpenCL::Mapped self) - ALIAS: - slice_pitch = 1 +element_size (OpenCL::Mapped self) CODE: - RETVAL = ix ? self->slice_pitch : self->row_pitch; + RETVAL = mapped_element_size (self); OUTPUT: RETVAL - -