diff options
-rw-r--r-- | src/com/jogamp/opencl/CLBuffer.java | 65 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLCommandQueue.java | 4 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLImage.java | 2 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLMemory.java | 34 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLSubBuffer.java | 18 | ||||
-rw-r--r-- | src/com/jogamp/opencl/gl/CLGLBuffer.java | 2 | ||||
-rw-r--r-- | test/com/jogamp/opencl/CLBufferTest.java | 70 |
7 files changed, 155 insertions, 40 deletions
diff --git a/src/com/jogamp/opencl/CLBuffer.java b/src/com/jogamp/opencl/CLBuffer.java index e2c74c7d..2c3fd2af 100644 --- a/src/com/jogamp/opencl/CLBuffer.java +++ b/src/com/jogamp/opencl/CLBuffer.java @@ -6,23 +6,24 @@ import com.jogamp.common.nio.PointerBuffer; import com.jogamp.opencl.CLMemory.Mem; import java.nio.Buffer; import java.util.ArrayList; +import java.util.Collections; import static com.jogamp.opencl.CLException.*; /** - * OpenCL buffer object. + * OpenCL buffer object wrapping an optional NIO buffer. * @author Michael Bien */ public class CLBuffer<B extends Buffer> extends CLMemory<B> { - private List<CLBuffer<B>> childs; + private List<CLSubBuffer<B>> childs; - protected CLBuffer(CLContext context, long id, int flags) { - super(context, id, flags); + protected CLBuffer(CLContext context, long size, long id, int flags) { + this(context, null, size, id, flags); } - protected CLBuffer(CLContext context, B directBuffer, long id, int flags) { - super(context, directBuffer, id, flags); + protected CLBuffer(CLContext context, B directBuffer, long size, long id, int flags) { + super(context, directBuffer, size, id, flags); } @SuppressWarnings("unchecked") @@ -38,7 +39,7 @@ public class CLBuffer<B extends Buffer> extends CLMemory<B> { long id = cl.clCreateBuffer(context.ID, flags, size, null, result, 0); checkForError(result[0], "can not create cl buffer"); - return new CLBuffer(context, id, flags); + return new CLBuffer(context, size, id, flags); } static <B extends Buffer> CLBuffer<B> create(CLContext context, B directBuffer, int flags) { @@ -53,32 +54,43 @@ public class CLBuffer<B extends Buffer> extends CLMemory<B> { if(isHostPointerFlag(flags)) { host_ptr = directBuffer; } - long id = cl.clCreateBuffer(context.ID, flags, sizeOfBufferElem(directBuffer)*directBuffer.capacity(), host_ptr, result, 0); + int size = sizeOfBufferElem(directBuffer) * directBuffer.capacity(); + long id = cl.clCreateBuffer(context.ID, flags, size, host_ptr, result, 0); checkForError(result[0], "can not create cl buffer"); - return new CLBuffer<B>(context, directBuffer, id, flags); + return new CLBuffer<B>(context, directBuffer, size, id, flags); } /** * Creates a sub buffer with the specified region from this buffer. + * If this buffer contains a NIO buffer, the sub buffer will also contain a slice + * matching the specified region of the parent buffer. The region is specified + * by the offset and size in buffer elements or bytes if this buffer does not + * contain any NIO buffer. + * @param offset The offset in buffer elements. + * @param size The size in buffer elements. */ - public CLBuffer<B> createSubBuffer(int origin, int size, Mem... flags) { + public CLSubBuffer<B> createSubBuffer(int offset, int size, Mem... flags) { + + B slice = null; + if(buffer != null) { + slice = (B)Buffers.slice(buffer, offset, size); + int elemSize = Buffers.sizeOfBufferElem(buffer); + offset *= elemSize; + size *= elemSize; + } + PointerBuffer info = PointerBuffer.allocateDirect(2); - info.put(origin).put(size).rewind(); + info.put(offset).put(size).rewind(); int bitset = Mem.flagsToInt(flags); int[] err = new int[1]; long subID = cl.clCreateSubBuffer(ID, bitset, CL.CL_BUFFER_CREATE_TYPE_REGION, info.getBuffer(), err, 0); checkForError(err[0], "can not create sub buffer"); - B slice = null; - if(buffer != null) { - slice = (B)Buffers.slice(buffer, origin, size); - } - - CLSubBuffer<B> clSubBuffer = new CLSubBuffer<B>(this, origin, slice, subID, bitset); + CLSubBuffer<B> clSubBuffer = new CLSubBuffer<B>(this, offset, size, slice, subID, bitset); if(childs == null) { - childs = new ArrayList<CLBuffer<B>>(); + childs = new ArrayList<CLSubBuffer<B>>(); } childs.add(clSubBuffer); return clSubBuffer; @@ -87,8 +99,8 @@ public class CLBuffer<B extends Buffer> extends CLMemory<B> { @Override public void release() { if(childs != null) { - for (CLBuffer<B> child : childs) { - child.release(); + while(!childs.isEmpty()) { + childs.get(0).release(); } } super.release(); @@ -99,6 +111,17 @@ public class CLBuffer<B extends Buffer> extends CLMemory<B> { } /** + * Returns the list of subbuffers. + */ + public List<CLSubBuffer<B>> getSubBuffers() { + if(childs == null) { + return Collections.EMPTY_LIST; + }else{ + return Collections.unmodifiableList(childs); + } + } + + /** * Returns true if this is a sub buffer. */ public boolean isSubBuffer() { @@ -107,7 +130,7 @@ public class CLBuffer<B extends Buffer> extends CLMemory<B> { @Override public <T extends Buffer> CLBuffer<T> cloneWith(T directBuffer) { - return new CLBuffer<T>(context, directBuffer, ID, FLAGS); + return new CLBuffer<T>(context, directBuffer, size, ID, FLAGS); } } diff --git a/src/com/jogamp/opencl/CLCommandQueue.java b/src/com/jogamp/opencl/CLCommandQueue.java index d7fc7748..7dee2cf7 100644 --- a/src/com/jogamp/opencl/CLCommandQueue.java +++ b/src/com/jogamp/opencl/CLCommandQueue.java @@ -89,7 +89,7 @@ public class CLCommandQueue extends CLObject implements CLResource { int ret = cl.clEnqueueWriteBuffer( ID, writeBuffer.ID, clBoolean(blockingWrite), - 0, writeBuffer.getSize(), writeBuffer.buffer, + 0, writeBuffer.getNIOSize(), writeBuffer.buffer, conditions, conditionIDs, events==null ? null : events.IDs); if(ret != CL_SUCCESS) { @@ -133,7 +133,7 @@ public class CLCommandQueue extends CLObject implements CLResource { int ret = cl.clEnqueueReadBuffer( ID, readBuffer.ID, clBoolean(blockingRead), - 0, readBuffer.getSize(), readBuffer.buffer, + 0, readBuffer.getNIOSize(), readBuffer.buffer, conditions, conditionIDs, events==null ? null : events.IDs); if(ret != CL_SUCCESS) { diff --git a/src/com/jogamp/opencl/CLImage.java b/src/com/jogamp/opencl/CLImage.java index cc1eb59e..434acc24 100644 --- a/src/com/jogamp/opencl/CLImage.java +++ b/src/com/jogamp/opencl/CLImage.java @@ -23,7 +23,7 @@ public abstract class CLImage<B extends Buffer> extends CLMemory<B> { } protected CLImage(CLContext context, B directBuffer, CLImageFormat format, CLImageInfoAccessor accessor, int width, int height, long id, int flags) { - super(context, directBuffer, id, flags); + super(context, directBuffer, getSizeImpl(context.cl, id), id, flags); this.imageInfo = accessor; this.format = format; this.width = width; diff --git a/src/com/jogamp/opencl/CLMemory.java b/src/com/jogamp/opencl/CLMemory.java index 6ab5cd02..d66db3c8 100644 --- a/src/com/jogamp/opencl/CLMemory.java +++ b/src/com/jogamp/opencl/CLMemory.java @@ -18,22 +18,24 @@ import static com.jogamp.opencl.gl.CLGLI.*; /** * Common superclass for all OpenCL memory types. + * Represents an OpenCL memory object and wraps an optional NIO buffer. * @author Michael Bien */ public abstract class CLMemory <B extends Buffer> extends CLObject implements CLResource { B buffer; protected final int FLAGS; + protected final long size; - protected <Buffer> CLMemory(CLContext context, long id, int flags) { - super(context, id); - this.FLAGS = flags; + protected <Buffer> CLMemory(CLContext context, long size, long id, int flags) { + this(context, null, size, id, flags); } - protected CLMemory(CLContext context, B directBuffer, long id, int flags) { + protected CLMemory(CLContext context, B directBuffer, long size, long id, int flags) { super(context, id); this.buffer = directBuffer; this.FLAGS = flags; + this.size = size; } /** @@ -59,6 +61,13 @@ public abstract class CLMemory <B extends Buffer> extends CLObject implements CL throw new RuntimeException("Unexpected buffer type " + buffer.getClass().getName()); } + protected static long getSizeImpl(CL cl, long id) { + PointerBuffer pb = PointerBuffer.allocateDirect(1); + int ret = cl.clGetMemObjectInfo(id, CL_MEM_SIZE, PointerBuffer.elementSize(), pb.getBuffer(), null); + checkForError(ret, "can not obtain buffer info"); + return pb.get(); + } + protected static CL getCL(CLContext context) { return context.cl; } @@ -89,7 +98,7 @@ public abstract class CLMemory <B extends Buffer> extends CLObject implements CL /** * Returns the capacity of the wrapped direct buffer or 0 if no buffer available. */ - public int getCapacity() { + public int getNIOCapacity() { if(buffer == null) { return 0; } @@ -99,7 +108,7 @@ public abstract class CLMemory <B extends Buffer> extends CLObject implements CL /** * Returns the size of the wrapped direct buffer in byte or 0 if no buffer available. */ - public int getSize() { + public int getNIOSize() { if(buffer == null) { return 0; } @@ -110,10 +119,15 @@ public abstract class CLMemory <B extends Buffer> extends CLObject implements CL * Returns the size of the allocated OpenCL memory. */ public long getCLSize() { - PointerBuffer pb = PointerBuffer.allocateDirect(1); - int ret = cl.clGetMemObjectInfo(ID, CL_MEM_SIZE, PointerBuffer.elementSize(), pb.getBuffer(), null); - checkForError(ret, "can not obtain buffer info"); - return pb.get(); + return size; + } + + /** + * Returns the size in buffer elements of this memory object. + */ + public int getCLCapacity() { + int elemSize = buffer==null ? 1 : sizeOfBufferElem(buffer); + return (int) (getCLSize() / elemSize); } /** diff --git a/src/com/jogamp/opencl/CLSubBuffer.java b/src/com/jogamp/opencl/CLSubBuffer.java index 614dfa80..165df23f 100644 --- a/src/com/jogamp/opencl/CLSubBuffer.java +++ b/src/com/jogamp/opencl/CLSubBuffer.java @@ -12,18 +12,18 @@ public class CLSubBuffer<B extends Buffer> extends CLBuffer<B> { private CLBuffer<B> parent; private final int offset; - CLSubBuffer(CLBuffer<B> parent, int origin, B directBuffer, long id, int flags) { - super(parent.getContext(), directBuffer, id, flags); + CLSubBuffer(CLBuffer<B> parent, int origin, int size, B directBuffer, long id, int flags) { + super(parent.getContext(), directBuffer, size, id, flags); this.parent = parent; this.offset = origin; } /** * Throws an UnsupportedOperationException since creating sub buffers - * from sub buffers is not allowed. + * from sub buffers is not allowed as of OpenCL 1.1. */ @Override - public CLBuffer<B> createSubBuffer(int origin, int size, Mem... flags) { + public CLSubBuffer<B> createSubBuffer(int origin, int size, Mem... flags) { throw new UnsupportedOperationException("creating sub buffers from sub buffers is not allowed."); } @@ -41,9 +41,17 @@ public class CLSubBuffer<B extends Buffer> extends CLBuffer<B> { } /** - * Returns the offset of this sub buffer to its parent. + * Returns the offset of this sub buffer to its parent in buffer elements. */ public int getOffset() { + int elemSize = buffer==null ? 1 : sizeOfBufferElem(buffer); + return offset/elemSize; + } + + /** + * Returns the offset of this sub buffer to its parent in bytes. + */ + public int getCLOffset() { return offset; } diff --git a/src/com/jogamp/opencl/gl/CLGLBuffer.java b/src/com/jogamp/opencl/gl/CLGLBuffer.java index 6a658ea5..ab998c14 100644 --- a/src/com/jogamp/opencl/gl/CLGLBuffer.java +++ b/src/com/jogamp/opencl/gl/CLGLBuffer.java @@ -21,7 +21,7 @@ public final class CLGLBuffer<B extends Buffer> extends CLBuffer<B> implements C public final int GLID; private CLGLBuffer(CLContext context, B directBuffer, long id, int glObject, int flags) { - super(context, directBuffer, id, flags); + super(context, directBuffer, getSizeImpl(context.getCL(), id), id, flags); this.GLID = glObject; } diff --git a/test/com/jogamp/opencl/CLBufferTest.java b/test/com/jogamp/opencl/CLBufferTest.java index d0c8c2f9..f2d2d609 100644 --- a/test/com/jogamp/opencl/CLBufferTest.java +++ b/test/com/jogamp/opencl/CLBufferTest.java @@ -4,6 +4,7 @@ import com.jogamp.opencl.CLMemory.Mem; import com.jogamp.opencl.CLMemory.Map; import com.jogamp.common.nio.Buffers; import java.nio.ByteBuffer; +import java.nio.FloatBuffer; import org.junit.Test; import static org.junit.Assert.*; @@ -145,5 +146,74 @@ public class CLBufferTest { context.release(); } + + @Test + public void subBufferTest() { + + CLPlatform[] platforms = CLPlatform.listCLPlatforms(); + CLPlatform theChosenOne = null; + for (CLPlatform platform : platforms) { + if(platform.isAtLeast(CLVersion.CL_1_1)) { + theChosenOne = platform; + break; + } + } + + if(theChosenOne == null) { + out.println("aborting subBufferTest"); + return; + } + + CLContext context = CLContext.create(theChosenOne); + try{ + final int subelements = 5; + // device only + { + CLBuffer<?> buffer = context.createBuffer(64); + + assertFalse(buffer.isSubBuffer()); + assertNotNull(buffer.getSubBuffers()); + assertTrue(buffer.getSubBuffers().isEmpty()); + + CLSubBuffer<?> subBuffer = buffer.createSubBuffer(10, subelements); + + assertTrue(subBuffer.isSubBuffer()); + assertEquals(subelements, subBuffer.getCLSize()); + assertEquals(10, subBuffer.getOffset()); + assertEquals(10, subBuffer.getCLOffset()); + assertEquals(buffer, subBuffer.getParent()); + assertEquals(1, buffer.getSubBuffers().size()); + + subBuffer.release(); + assertEquals(0, buffer.getSubBuffers().size()); + } + + // device + direct buffer + { + CLBuffer<FloatBuffer> buffer = context.createFloatBuffer(64); + assertFalse(buffer.isSubBuffer()); + assertNotNull(buffer.getSubBuffers()); + assertTrue(buffer.getSubBuffers().isEmpty()); + + CLSubBuffer<FloatBuffer> subBuffer = buffer.createSubBuffer(10, subelements); + + assertTrue(subBuffer.isSubBuffer()); + assertEquals(subelements, subBuffer.getBuffer().capacity()); + assertEquals(10, subBuffer.getOffset()); + assertEquals(40, subBuffer.getCLOffset()); + assertEquals(buffer, subBuffer.getParent()); + assertEquals(1, buffer.getSubBuffers().size()); + + assertEquals(subBuffer.getCLCapacity(), subBuffer.getBuffer().capacity()); + + subBuffer.release(); + assertEquals(0, buffer.getSubBuffers().size()); + } + + }finally{ + context.release(); + } + + } } |