aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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();
+ }
+
+ }
}