summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2010-07-05 00:10:15 +0200
committerMichael Bien <[email protected]>2010-07-05 00:10:15 +0200
commita81e907b30364b1abc2a75d446772f066fbf74ff (patch)
tree6b61b193829bb72c3a0432afffc36d469950314c
parente5208ab035bc454730edc847cad9d5af3ed92e8c (diff)
finished CLSubBuffer, added junit testcase, perf improvements and cleanup.
CLMemory methods contain now NIO infix for nio buffer specific queries and CL infix for memory object queries.
-rw-r--r--src/com/jogamp/opencl/CLBuffer.java65
-rw-r--r--src/com/jogamp/opencl/CLCommandQueue.java4
-rw-r--r--src/com/jogamp/opencl/CLImage.java2
-rw-r--r--src/com/jogamp/opencl/CLMemory.java34
-rw-r--r--src/com/jogamp/opencl/CLSubBuffer.java18
-rw-r--r--src/com/jogamp/opencl/gl/CLGLBuffer.java2
-rw-r--r--test/com/jogamp/opencl/CLBufferTest.java70
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();
+ }
+
+ }
}