From d36c957f5e8aa7649ae1f7dc0b59477276120b53 Mon Sep 17 00:00:00 2001 From: shamanDevel Date: Fri, 22 Apr 2016 16:11:55 +0200 Subject: [PATCH] implemented image operations --- .../main/java/com/jme3/opencl/Context.java | 4 +- .../src/main/java/com/jme3/opencl/Image.java | 2 +- .../java/jme3test/opencl/HelloOpenCL.java | 57 +++++ .../com/jme3/opencl/lwjgl/LwjglBuffer.java | 3 + .../com/jme3/opencl/lwjgl/LwjglContext.java | 4 +- .../com/jme3/opencl/lwjgl/LwjglEvent.java | 11 + .../com/jme3/opencl/lwjgl/LwjglImage.java | 230 +++++++++++++++--- 7 files changed, 278 insertions(+), 33 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/opencl/Context.java b/jme3-core/src/main/java/com/jme3/opencl/Context.java index b0168e618..23e38cbd1 100644 --- a/jme3-core/src/main/java/com/jme3/opencl/Context.java +++ b/jme3-core/src/main/java/com/jme3/opencl/Context.java @@ -63,8 +63,8 @@ public abstract class Context { } public abstract CommandQueue createQueue(Device device); - public abstract Buffer createBuffer(int size, MemoryAccess access); - public Buffer createBuffer(int size) { + public abstract Buffer createBuffer(long size, MemoryAccess access); + public Buffer createBuffer(long size) { return createBuffer(size, MemoryAccess.READ_WRITE); } diff --git a/jme3-core/src/main/java/com/jme3/opencl/Image.java b/jme3-core/src/main/java/com/jme3/opencl/Image.java index 8c3134706..d69d6d7a4 100644 --- a/jme3-core/src/main/java/com/jme3/opencl/Image.java +++ b/jme3-core/src/main/java/com/jme3/opencl/Image.java @@ -230,7 +230,7 @@ public interface Image { * @param color * @return */ - Event fillIntegerAsync(CommandQueue queue, long[] origin, long[] region, int[] color); + Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color); Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset); } diff --git a/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java b/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java index e89c598be..79455af74 100644 --- a/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java +++ b/jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java @@ -35,6 +35,7 @@ package jme3test.opencl; import com.jme3.app.SimpleApplication; import com.jme3.font.BitmapFont; import com.jme3.font.BitmapText; +import com.jme3.math.ColorRGBA; import com.jme3.opencl.*; import com.jme3.system.AppSettings; import com.jme3.util.BufferUtils; @@ -86,6 +87,9 @@ public class HelloOpenCL extends SimpleApplication { txt1.setText(str.toString()); txt1.setLocalTranslation(5, settings.getHeight() - 5, 0); guiNode.attachChild(txt1); + + flyCam.setEnabled(false); + inputManager.setCursorVisible(true); } private static void assertEquals(byte expected, byte actual, String message) { @@ -223,6 +227,59 @@ public class HelloOpenCL extends SimpleApplication { assertEquals(descr.width, image.getWidth(), "Wrong width"); assertEquals(descr.height, image.getHeight(), "Wrong height"); + //fill with red and blue + ColorRGBA color1 = ColorRGBA.Red; + ColorRGBA color2 = ColorRGBA.Blue; + Event e1 = image.fillAsync(clQueue, new long[]{0,0,0}, new long[]{descr.width/2, descr.height, 1}, color1); + Event e2 = image.fillAsync(clQueue, new long[]{descr.width/2,0,0}, new long[]{descr.width/2, descr.height, 1}, color2); + e1.waitForFinished(); + e2.waitForFinished(); + + //copy to a buffer + Buffer buffer = clContext.createBuffer(4*4*500*1024); + image.copyToBufferAsync(clQueue, buffer, new long[]{10,10,0}, new long[]{500,1024,1}, 0); + //this buffer must be completely red + ByteBuffer map1 = buffer.map(clQueue, MappingAccess.MAP_READ_ONLY); + FloatBuffer map1F = map1.asFloatBuffer(); map1F.rewind(); + for (int x=0; x<500; ++x) { + for (int y=0; y<1024; ++y) { + float r = map1F.get(); + float g = map1F.get(); + float b = map1F.get(); + float a = map1F.get(); + assertEquals(1, r, "Wrong red component"); + assertEquals(0, g, "Wrong green component"); + assertEquals(0, b, "Wrong blue component"); + assertEquals(1, a, "Wrong alpha component"); + } + } + buffer.unmap(clQueue, map1); + + //create a second image + format = new Image.ImageFormat(Image.ImageChannelOrder.RGBA, Image.ImageChannelType.FLOAT); + descr = new Image.ImageDescriptor(Image.ImageType.IMAGE_2D, 512, 512, 0, 0, 0, 0); + Image image2 = clContext.createImage(MemoryAccess.READ_WRITE, format, descr, null); + //copy an area of image1 to image2 + image.copyTo(clQueue, image2, new long[]{1000, 20,0}, new long[]{0,0,0}, new long[]{512, 512,1}); + //this area should be completely blue + Image.ImageMapping map2 = image2.map(clQueue, new long[]{0,0,0}, new long[]{512,512,1}, MappingAccess.MAP_READ_WRITE); + FloatBuffer map2F = map2.buffer.asFloatBuffer(); + for (int y=0; y<512; ++y) { + for (int x=0; x<512; ++x) { + long index = 4 * x + y * (map2.rowPitch / 4); + map2F.position((int) index); + float r = map2F.get(); + float g = map2F.get(); + float b = map2F.get(); + float a = map2F.get(); + assertEquals(0, r, "Wrong red component"); + assertEquals(0, g, "Wrong green component"); + assertEquals(1, b, "Wrong blue component"); + assertEquals(1, a, "Wrong alpha component"); + } + } + image2.unmap(clQueue, map2); + } catch (AssertionError ex) { LOG.log(Level.SEVERE, "image test failed with an assertion error"); return false; diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java index 7e1563b80..0950db5fa 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java @@ -168,6 +168,9 @@ public class LwjglBuffer extends Buffer { @Override public Event copyToImageAsync(CommandQueue queue, Image dest, long srcOffset, long[] destOrigin, long[] destRegion) { + if (destOrigin.length!=3 || destRegion.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } Utils.pointerBuffers[0].rewind(); Utils.pointerBuffers[1].rewind(); Utils.pointerBuffers[2].rewind(); diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java index 8c5b16f64..d9f4ab0d7 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java +++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java @@ -87,9 +87,9 @@ public class LwjglContext extends Context { } @Override - public Buffer createBuffer(int size, MemoryAccess access) { + public Buffer createBuffer(long size, MemoryAccess access) { long flags = Utils.getMemoryAccessFlags(access); - CLMem mem = CL10.clCreateBuffer(context, flags, (long) size, Utils.errorBuffer); + CLMem mem = CL10.clCreateBuffer(context, flags, size, Utils.errorBuffer); Utils.checkError(Utils.errorBuffer, "clCreateBuffer"); return new LwjglBuffer(mem); } diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java index ebe0ca458..3c7dfec28 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java +++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java @@ -32,6 +32,7 @@ package com.jme3.opencl.lwjgl; import com.jme3.opencl.Event; +import java.util.logging.Logger; import org.lwjgl.opencl.CL10; import org.lwjgl.opencl.CLEvent; @@ -40,10 +41,14 @@ import org.lwjgl.opencl.CLEvent; * @author Sebastian Weiss */ public class LwjglEvent implements Event { + private static final Logger LOG = Logger.getLogger(LwjglEvent.class.getName()); private final CLEvent event; public LwjglEvent(CLEvent event) { this.event = event; + if (event == null) { + LOG.warning("event is null!"); + } } public CLEvent getEvent() { @@ -52,11 +57,17 @@ public class LwjglEvent implements Event { @Override public void waitForFinished() { + if (event==null) { + return; + } CL10.clWaitForEvents(event); } @Override public boolean isCompleted() { + if (event==null) { + return true; + } int status = event.getInfoInt(CL10.CL_EVENT_COMMAND_EXECUTION_STATUS); if (status == CL10.CL_SUCCESS) { return true; diff --git a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java index 4307fdf08..c847228c9 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java +++ b/jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java @@ -36,10 +36,7 @@ import com.jme3.opencl.*; import java.nio.ByteBuffer; import java.util.logging.Level; import java.util.logging.Logger; -import org.lwjgl.opencl.CL10; -import org.lwjgl.opencl.CL11; -import org.lwjgl.opencl.CL12; -import org.lwjgl.opencl.CLMem; +import org.lwjgl.opencl.*; import org.lwjgl.opencl.api.CLImageFormat; /** @@ -121,7 +118,7 @@ public class LwjglImage implements Image { case CL11.CL_Rx: return ImageChannelOrder.Rx; default: - //throw new OpenCLException("unknown image channel order id: " + order); + //throw new com.jme3.opencl.OpenCLException("unknown image channel order id: " + order); LOG.log(Level.WARNING, "Unknown image channel order id: {0}", order); return null; } @@ -197,7 +194,7 @@ public class LwjglImage implements Image { case CL10.CL_UNSIGNED_INT8: return ImageChannelType.UNSIGNED_INT8; default: - //throw new OpenCLException("unknown image channel type id: " + type); + //throw new com.jme3.opencl.OpenCLException("unknown image channel type id: " + type); LOG.log(Level.WARNING, "Unknown image channel type id: {0}", type); return null; } @@ -237,44 +234,46 @@ public class LwjglImage implements Image { case CL10.CL_MEM_OBJECT_IMAGE3D: return ImageType.IMAGE_3D; default: - throw new OpenCLException("Unknown image type id: " + type); + throw new com.jme3.opencl.OpenCLException("Unknown image type id: " + type); } } @Override public long getWidth() { - return image.getInfoSize(CL10.CL_IMAGE_WIDTH); + return image.getImageInfoSize(CL10.CL_IMAGE_WIDTH); } @Override public long getHeight() { - return image.getInfoSize(CL10.CL_IMAGE_HEIGHT); + return image.getImageInfoSize(CL10.CL_IMAGE_HEIGHT); } @Override public long getDepth() { - return image.getInfoSize(CL10.CL_IMAGE_DEPTH); + return image.getImageInfoSize(CL10.CL_IMAGE_DEPTH); } @Override public long getRowPitch() { - return image.getInfoSize(CL10.CL_IMAGE_ROW_PITCH); + return image.getImageInfoSize(CL10.CL_IMAGE_ROW_PITCH); } @Override public long getSlicePitch() { - return image.getInfoSize(CL10.CL_IMAGE_SLICE_PITCH); + return image.getImageInfoSize(CL10.CL_IMAGE_SLICE_PITCH); } @Override public long getArraySize() { - return image.getInfoSize(CL12.CL_IMAGE_ARRAY_SIZE); + return image.getImageInfoSize(CL12.CL_IMAGE_ARRAY_SIZE); } @Override public ImageFormat getImageFormat() { CLImageFormat format = image.getImageFormat(); - return new ImageFormat(encodeImageChannelOrder(format.getChannelOrder()), encodeImageChannelType(format.getChannelType())); + return new ImageFormat( + encodeImageChannelOrder(format.getChannelOrder()), + encodeImageChannelType(format.getChannelType())); } @Override @@ -285,67 +284,242 @@ public class LwjglImage implements Image { @Override public int getElementSize() { - return (int) image.getInfoSize(CL10.CL_IMAGE_ELEMENT_SIZE); + return (int) image.getImageInfoSize(CL10.CL_IMAGE_ELEMENT_SIZE); } @Override public void readImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { - throw new UnsupportedOperationException("Not supported yet."); + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL10.clEnqueueReadImage(q, image, CL10.CL_TRUE, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], + rowPitch, slicePitch, dest, null, null); + Utils.checkError(ret, "clEnqueueReadImage"); } @Override public Event readImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { - throw new UnsupportedOperationException("Not supported yet."); + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL10.clEnqueueReadImage(q, image, CL10.CL_FALSE, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], + rowPitch, slicePitch, dest, null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueReadImage"); + long event = Utils.pointerBuffers[0].get(0); + return new LwjglEvent(q.getCLEvent(event)); } @Override public void writeImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { - throw new UnsupportedOperationException("Not supported yet."); + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL10.clEnqueueWriteImage(q, image, CL10.CL_TRUE, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], + rowPitch, slicePitch, dest, null, null); + Utils.checkError(ret, "clEnqueueWriteImage"); } @Override public Event writeImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { - throw new UnsupportedOperationException("Not supported yet."); + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL10.clEnqueueWriteImage(q, image, CL10.CL_FALSE, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], + rowPitch, slicePitch, dest, null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueWriteImage"); + long event = Utils.pointerBuffers[0].get(0); + return new LwjglEvent(q.getCLEvent(event)); } @Override public void copyTo(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region) { - throw new UnsupportedOperationException("Not supported yet."); + if (srcOrigin.length!=3 || destOrigin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[3].rewind(); + Utils.pointerBuffers[1].put(srcOrigin).position(0); + Utils.pointerBuffers[2].put(destOrigin).position(0); + Utils.pointerBuffers[3].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL10.clEnqueueCopyImage(q, image, ((LwjglImage) dest).getImage(), + Utils.pointerBuffers[1], Utils.pointerBuffers[2], Utils.pointerBuffers[3], + null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueCopyImage"); + long event = Utils.pointerBuffers[0].get(0); + ret = CL10.clWaitForEvents(q.getCLEvent(event)); + Utils.checkError(ret, "clWaitForEvents"); } @Override public Event copyToAsync(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region) { - throw new UnsupportedOperationException("Not supported yet."); + if (srcOrigin.length!=3 || destOrigin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[3].rewind(); + Utils.pointerBuffers[1].put(srcOrigin).position(0); + Utils.pointerBuffers[2].put(destOrigin).position(0); + Utils.pointerBuffers[3].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL10.clEnqueueCopyImage(q, image, ((LwjglImage) dest).getImage(), + Utils.pointerBuffers[1], Utils.pointerBuffers[2], Utils.pointerBuffers[3], + null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueCopyImage"); + long event = Utils.pointerBuffers[0].get(0); + return new LwjglEvent(q.getCLEvent(event)); } @Override public ImageMapping map(CommandQueue queue, long[] origin, long[] region, MappingAccess access) { - throw new UnsupportedOperationException("Not supported yet."); + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[3].rewind(); + Utils.pointerBuffers[4].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + long flags = Utils.getMappingAccessFlags(access); + Utils.errorBuffer.rewind(); + ByteBuffer buf = CL10.clEnqueueMapImage(q, image, CL10.CL_TRUE, flags, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], + Utils.pointerBuffers[3], Utils.pointerBuffers[4], null, null, Utils.errorBuffer); + Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); + long event = Utils.pointerBuffers[0].get(0); + return new ImageMapping(buf, Utils.pointerBuffers[3].get(0), Utils.pointerBuffers[4].get(0), + new LwjglEvent(q.getCLEvent(event))); } @Override public ImageMapping mapAsync(CommandQueue queue, long[] origin, long[] region, MappingAccess access) { - throw new UnsupportedOperationException("Not supported yet."); + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[3].rewind(); + Utils.pointerBuffers[4].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + long flags = Utils.getMappingAccessFlags(access); + Utils.errorBuffer.rewind(); + ByteBuffer buf = CL10.clEnqueueMapImage(q, image, CL10.CL_FALSE, flags, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], + Utils.pointerBuffers[3], Utils.pointerBuffers[4], null, null, Utils.errorBuffer); + Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); + return new ImageMapping(buf, Utils.pointerBuffers[3].get(0), Utils.pointerBuffers[4].get(0)); } @Override public void unmap(CommandQueue queue, ImageMapping mapping) { - throw new UnsupportedOperationException("Not supported yet."); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + Utils.pointerBuffers[0].rewind(); + int ret = CL10.clEnqueueUnmapMemObject(q, image, mapping.buffer, null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueUnmapMemObject"); + long event = Utils.pointerBuffers[0].get(0); + ret = CL10.clWaitForEvents(q.getCLEvent(event)); + Utils.checkError(ret, "clWaitForEvents"); } @Override public Event fillAsync(CommandQueue queue, long[] origin, long[] region, ColorRGBA color) { - throw new UnsupportedOperationException("Not supported yet."); + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + Utils.tempBuffers[0].b16f.rewind(); + Utils.tempBuffers[0].b16f.limit(4); + Utils.tempBuffers[0].b16f.put(color.r).put(color.g).put(color.b).put(color.a); + Utils.tempBuffers[0].b16.rewind(); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL12.clEnqueueFillImage(q, image, Utils.tempBuffers[0].b16, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueFillImage"); + long event = Utils.pointerBuffers[0].get(0); + return new LwjglEvent(q.getCLEvent(event)); + //TODO: why does q.getCLEvent(event) return null? } @Override - public Event fillIntegerAsync(CommandQueue queue, long[] origin, long[] region, int[] color) { - throw new UnsupportedOperationException("Not supported yet."); + public Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color) { + if (color.length != 4) { + throw new IllegalArgumentException("the passed color array must have length 4"); + } + if (origin.length!=3 || region.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[1].put(origin).position(0); + Utils.pointerBuffers[2].put(region).position(0); + Utils.tempBuffers[0].b16i.rewind(); + Utils.tempBuffers[0].b16i.limit(4); + Utils.tempBuffers[0].b16i.put(color); + Utils.tempBuffers[0].b16.rewind(); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL12.clEnqueueFillImage(q, image, Utils.tempBuffers[0].b16, + Utils.pointerBuffers[1], Utils.pointerBuffers[2], null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueFillImage"); + long event = Utils.pointerBuffers[0].get(0); + return new LwjglEvent(q.getCLEvent(event)); } @Override public Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset) { - throw new UnsupportedOperationException("Not supported yet."); + if (srcOrigin.length!=3 || srcRegion.length!=3) { + throw new IllegalArgumentException("origin and region must both be arrays of length 3"); + } + Utils.pointerBuffers[0].rewind(); + Utils.pointerBuffers[1].rewind(); + Utils.pointerBuffers[2].rewind(); + Utils.pointerBuffers[1].put(srcOrigin).position(0); + Utils.pointerBuffers[2].put(srcRegion).position(0); + CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue(); + int ret = CL10.clEnqueueCopyImageToBuffer(q, image, ((LwjglBuffer) dest).getBuffer(), + Utils.pointerBuffers[1], Utils.pointerBuffers[2], destOffset, null, Utils.pointerBuffers[0]); + Utils.checkError(ret, "clEnqueueCopyImageToBuffer"); + long event = Utils.pointerBuffers[0].get(0); + return new LwjglEvent(q.getCLEvent(event)); } }