#parse("main/Header.vm") package com.nativelibs4java.opencl; import static com.nativelibs4java.opencl.CLException.error; import static com.nativelibs4java.opencl.JavaCL.CL; import static com.nativelibs4java.opencl.JavaCL.check; import static com.nativelibs4java.opencl.library.IOpenCLLibrary.CL_FALSE; import static com.nativelibs4java.opencl.library.IOpenCLLibrary.CL_IMAGE_ELEMENT_SIZE; import static com.nativelibs4java.opencl.library.IOpenCLLibrary.CL_IMAGE_FORMAT; import static com.nativelibs4java.opencl.library.IOpenCLLibrary.CL_TRUE; import static com.nativelibs4java.util.NIOUtils.directCopy; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import com.nativelibs4java.opencl.library.cl_image_format; import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_event; import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_mem; import com.nativelibs4java.util.NIOUtils; import com.nativelibs4java.util.Pair; import org.bridj.*; import static org.bridj.Pointer.*; /** * OpenCL Image Memory Object.<br> * An image object is used to store a two- or three- dimensional texture, frame-buffer or image<br> * An image object is used to represent a buffer that can be used as a texture or a frame-buffer. The elements of an image object are selected from a list of predefined image formats. * @author Oliveir Chafik */ public abstract class CLImage extends CLMem { CLImageFormat format; CLImage(CLContext context, long entityPeer, CLImageFormat format) { super(context, -1, entityPeer); this.format = format; } protected abstract long[] getDimensions(); /** * Return image format descriptor specified when image is created with CLContext.create{Input|Output|InputOutput}{2D|3D}. */ @InfoName("CL_IMAGE_FORMAT") public CLImageFormat getFormat() { if (format == null) { format = new CLImageFormat(new cl_image_format(infos.getMemory(getEntity(), CL_IMAGE_FORMAT))); } return format; } /** * Return size of each element of the image memory object given by image. <br> * An element is made up of n channels. The value of n is given in cl_image_format descriptor. */ @InfoName("CL_IMAGE_ELEMENT_SIZE") public long getElementSize() { return infos.getIntOrLong(getEntity(), CL_IMAGE_ELEMENT_SIZE); } /** #documentCallsFunction("clEnqueueReadImage") */ protected CLEvent read(CLQueue queue, Pointer<SizeT> origin, Pointer<SizeT> region, long rowPitch, long slicePitch, Buffer out, boolean blocking, CLEvent... eventsToWaitFor) { return read(queue, origin, region, rowPitch, slicePitch, pointerToBuffer(out), blocking, eventsToWaitFor); } /** #documentCallsFunction("clEnqueueReadImage") */ protected CLEvent read(CLQueue queue, Pointer<SizeT> origin, Pointer<SizeT> region, long rowPitch, long slicePitch, Pointer<?> out, boolean blocking, CLEvent... eventsToWaitFor) { /*if (!out.isDirect()) { }*/ #declareReusablePtrsAndEventsInOutBlockable() error(CL.clEnqueueReadImage( queue.getEntity(), getEntity(), blocking ? CL_TRUE : CL_FALSE, getPeer(origin), getPeer(region), rowPitch, slicePitch, getPeer(out), #eventsInOutArgsRaw() )); #returnEventOut("queue") } /** #documentCallsFunction("clEnqueueWriteImage") */ protected CLEvent write(CLQueue queue, Pointer<SizeT> origin, Pointer<SizeT> region, long rowPitch, long slicePitch, Buffer in, boolean blocking, CLEvent... eventsToWaitFor) { return write(queue, origin, region, rowPitch, slicePitch, pointerToBuffer(in), blocking, eventsToWaitFor); } /** #documentCallsFunction("clEnqueueWriteImage") */ protected CLEvent write(CLQueue queue, Pointer<SizeT> origin, Pointer<SizeT> region, long rowPitch, long slicePitch, Pointer<?> in, boolean blocking, CLEvent... eventsToWaitFor) { #declareReusablePtrsAndEventsInOutBlockable() error(CL.clEnqueueWriteImage( queue.getEntity(), getEntity(), blocking ? CL_TRUE : CL_FALSE, getPeer(origin), getPeer(region), rowPitch, slicePitch, getPeer(in), #eventsInOutArgsRaw() )); CLEvent evt = #eventOutWrapper("queue"); if (!blocking) { final Pointer<?> toHold = in; evt.invokeUponCompletion(new Runnable() { public void run() { // Make sure the GC held a reference to directData until the write was completed ! toHold.order(); } }); } return evt; } /** #documentCallsFunction("clEnqueueFillImage") * @param queue * @param queue Queue on which to enqueue this fill buffer command. * @param color Color components to fill the buffer with. #documentEventsToWaitForAndReturn() */ public CLEvent fillImage(CLQueue queue, Object color, CLEvent... eventsToWaitFor) { long[] region = getDimensions(); long[] origin = new long[region.length]; return fillImage(queue, color, origin, region, eventsToWaitFor); } /** #documentCallsFunction("clEnqueueFillImage") * @param queue * @param queue Queue on which to enqueue this fill buffer command. * @param color Color components to fill the buffer with. * @param origin Origin point. * @param region Size of the region to fill. #documentEventsToWaitForAndReturn() */ public CLEvent fillImage(CLQueue queue, Object color, long[] origin, long[] region, CLEvent... eventsToWaitFor) { context.getPlatform().requireMinVersionValue("clEnqueueFillImage", 1.2); Pointer<?> pColor; if (color instanceof int[]) { pColor = pointerToInts((int[]) color); } else if (color instanceof float[]) { pColor = pointerToFloats((float[]) color); } else { throw new IllegalArgumentException("Color should be an int[] or a float[] with 4 elements."); } check(pColor.getValidElements() == 4, "Color should have 4 elements."); #declareReusablePtrsAndEventsInOut() error(CL.clEnqueueFillImage( queue.getEntity(), getEntity(), getPeer(pColor), getPeer(writeOrigin(origin, ptrs.sizeT3_1)), getPeer(writeRegion(region, ptrs.sizeT3_2)), #eventsInOutArgsRaw() )); #returnEventOut("queue") } // clEnqueueFillImage ( cl_command_queue command_queue, // cl_mem image, // const void *fill_color, // const size_t *origin, // const size_t *region, // cl_uint num_events_in_wait_list, // const cl_event *event_wait_list, // cl_event *event) protected Pair<ByteBuffer, CLEvent> map(CLQueue queue, MapFlags flags, Pointer<SizeT> offset3, Pointer<SizeT> length3, Long imageRowPitch, Long imageSlicePitch, boolean blocking, CLEvent... eventsToWaitFor) { if (flags == MapFlags.WriteInvalidateRegion) { context.getPlatform().requireMinVersionValue("CL_MAP_WRITE_INVALIDATE_REGION", 1.2); } #declareReusablePtrsAndEventsInOutBlockable() #declarePErr() long mappedPeer = CL.clEnqueueMapImage( queue.getEntity(), getEntity(), blocking ? CL_TRUE : CL_FALSE, flags.value(), getPeer(offset3), getPeer(length3), imageRowPitch == null ? 0 : getPeer(ptrs.sizeT3_1.pointerToSizeTs((long)imageRowPitch)), imageSlicePitch == null ? 0 : getPeer(ptrs.sizeT3_2.pointerToSizeTs((long)imageSlicePitch)), #eventsInOutArgsRaw(), getPeer(pErr) ); #checkPErr() return new Pair<ByteBuffer, CLEvent>( pointerToAddress(mappedPeer).getByteBuffer(getByteCount()), #eventOutWrapper("queue") ); } /** #documentCallsFunction("clEnqueueUnmapMemObject") * see {@link CLImage2D#map(com.nativelibs4java.opencl.CLQueue, com.nativelibs4java.opencl.CLMem.MapFlags, com.nativelibs4java.opencl.CLEvent[]) } * see {@link CLImage3D#map(com.nativelibs4java.opencl.CLQueue, com.nativelibs4java.opencl.CLMem.MapFlags, com.nativelibs4java.opencl.CLEvent[]) } * @param queue * @param buffer #documentEventsToWaitForAndReturn() */ public CLEvent unmap(CLQueue queue, ByteBuffer buffer, CLEvent... eventsToWaitFor) { #declareReusablePtrsAndEventsInOut() Pointer<?> pBuffer = pointerToBuffer(buffer); error(CL.clEnqueueUnmapMemObject(queue.getEntity(), getEntity(), getPeer(pBuffer), #eventsInOutArgsRaw())); #returnEventOut("queue") } protected abstract Pointer<SizeT> writeOrigin(long[] origin, ReusablePointer out); protected abstract Pointer<SizeT> writeRegion(long[] region, ReusablePointer out); /** #documentCallsFunction("clEnqueueCopyImage") * @param queue #documentEventsToWaitForAndReturn() */ public CLEvent copyTo(CLQueue queue, CLImage destination, CLEvent... eventsToWaitFor) { long[] region = getDimensions(); long[] origin = new long[region.length]; return copyTo(queue, destination, origin, origin, region, eventsToWaitFor); } /** #documentCallsFunction("clEnqueueCopyImage") * @param queue #documentEventsToWaitForAndReturn() */ public CLEvent copyTo(CLQueue queue, CLImage destination, long[] sourceOrigin, long[] destinationOrigin, long[] region, CLEvent... eventsToWaitFor) { #declareReusablePtrsAndEventsInOut() error(CL.clEnqueueCopyImage( queue.getEntity(), getEntity(), destination.getEntity(), getPeer(writeOrigin(sourceOrigin, ptrs.sizeT3_1)), getPeer(writeOrigin(destinationOrigin, ptrs.sizeT3_2)), getPeer(writeRegion(region, ptrs.sizeT3_3)), #eventsInOutArgsRaw())); #returnEventOut("queue") } }