diff options
-rw-r--r-- | src/com/jogamp/opencl/CLMemory.java | 13 | ||||
-rw-r--r-- | src/com/jogamp/opencl/gl/CLGLBuffer.java | 29 | ||||
-rw-r--r-- | src/com/jogamp/opencl/gl/CLGLContext.java | 42 | ||||
-rw-r--r-- | test/com/jogamp/opencl/gl/CLGLTest.java | 137 |
4 files changed, 181 insertions, 40 deletions
diff --git a/src/com/jogamp/opencl/CLMemory.java b/src/com/jogamp/opencl/CLMemory.java index 7a3e82f7..f299439d 100644 --- a/src/com/jogamp/opencl/CLMemory.java +++ b/src/com/jogamp/opencl/CLMemory.java @@ -50,7 +50,7 @@ public abstract class CLMemory <B extends Buffer> extends CLObject implements CL B buffer; protected final int FLAGS; - protected final long size; + protected long size; // depends on the nio buffer type protected int elementSize; @@ -65,11 +65,15 @@ public abstract class CLMemory <B extends Buffer> extends CLObject implements CL this.buffer = directBuffer; this.FLAGS = flags; this.size = size; - initElementSizes(); + initElementSize(); + initCLCapacity(); } - private void initElementSizes() { + private void initElementSize() { this.elementSize = (buffer==null) ? 1 : Buffers.sizeOfBufferElem(buffer); + } + + protected final void initCLCapacity() { this.clCapacity = (int) (size / elementSize); } @@ -118,7 +122,8 @@ public abstract class CLMemory <B extends Buffer> extends CLObject implements CL +" but got " + buffer.getClass()); } this.buffer = buffer; - initElementSizes(); + initElementSize(); + initCLCapacity(); return this; } diff --git a/src/com/jogamp/opencl/gl/CLGLBuffer.java b/src/com/jogamp/opencl/gl/CLGLBuffer.java index 86fef680..148aa83d 100644 --- a/src/com/jogamp/opencl/gl/CLGLBuffer.java +++ b/src/com/jogamp/opencl/gl/CLGLBuffer.java @@ -28,9 +28,10 @@ package com.jogamp.opencl.gl; -import com.jogamp.opencl.CL; import com.jogamp.opencl.CLBuffer; +import com.jogamp.opencl.CLCommandQueue; import com.jogamp.opencl.CLContext; +import com.jogamp.opencl.CLException; import java.nio.Buffer; import javax.media.opengl.GLContext; @@ -48,22 +49,22 @@ 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, getSizeImpl(context.getCL(), id), id, flags); + private CLGLBuffer(CLContext context, B directBuffer, long id, int glObject, long size, int flags) { + super(context, directBuffer, size, id, flags); this.GLID = glObject; } - static <B extends Buffer> CLGLBuffer<B> create(CLContext context, B directBuffer, int flags, int glObject) { + static <B extends Buffer> CLGLBuffer<B> create(CLContext context, B directBuffer, long size, int flags, int glObject) { checkBuffer(directBuffer, flags); - CL cl = getCL(context); - int[] result = new int[1]; - CLGLI clgli = (CLGLI)cl; + CLGLI clgli = (CLGLI)getCL(context); + int[] result = new int[1]; long id = clgli.clCreateFromGLBuffer(context.ID, flags, glObject, result, 0); + CLException.checkForError(result[0], "can not create CLGLObject from #"+glObject); - return new CLGLBuffer<B>(context, directBuffer, id, glObject, flags); + return new CLGLBuffer<B>(context, directBuffer, id, glObject, size, flags); } static <B extends Buffer> void checkBuffer(B directBuffer, int flags) throws IllegalArgumentException { @@ -75,6 +76,16 @@ public final class CLGLBuffer<B extends Buffer> extends CLBuffer<B> implements C } } + /** + * Updates the size of this CLGLBuffer by querying OpenGL. + * This method may only be called if this memory object has been acquired by calling + * {@link CLCommandQueue#putAcquireGLObject(com.jogamp.opencl.gl.CLGLObject)}. + */ + public void updateSize() { + size = getSizeImpl(cl, ID); + initCLCapacity(); + } + public int getGLObjectID() { return GLID; } @@ -94,7 +105,7 @@ public final class CLGLBuffer<B extends Buffer> extends CLBuffer<B> implements C @Override public <T extends Buffer> CLGLBuffer<T> cloneWith(T directBuffer) { - return new CLGLBuffer<T>(context, directBuffer, ID, GLID, FLAGS); + return new CLGLBuffer<T>(context, directBuffer, ID, GLID, size, FLAGS); } @Override diff --git a/src/com/jogamp/opencl/gl/CLGLContext.java b/src/com/jogamp/opencl/gl/CLGLContext.java index f8ca70af..6482f041 100644 --- a/src/com/jogamp/opencl/gl/CLGLContext.java +++ b/src/com/jogamp/opencl/gl/CLGLContext.java @@ -201,20 +201,46 @@ public final class CLGLContext extends CLContext { } // Buffers - public final CLGLBuffer<?> createFromGLBuffer(int glBuffer, Mem... flags) { - return createFromGLBuffer(null, glBuffer, Mem.flagsToInt(flags)); + /** + * Creates a CLGLBuffer for memory sharing with the specified OpenGL buffer. + * @param glBuffer The OpenGL buffer handle like a vertex buffer or pixel buffer object. + * @param glBufferSize The size of the OpenGL buffer in bytes + * @param flags optional flags. + */ + public final CLGLBuffer<?> createFromGLBuffer(int glBuffer, long glBufferSize, Mem... flags) { + return createFromGLBuffer(null, glBuffer, glBufferSize, Mem.flagsToInt(flags)); } - public final CLGLBuffer<?> createFromGLBuffer(int glBuffer, int flags) { - return createFromGLBuffer(null, glBuffer, flags); + /** + * Creates a CLGLBuffer for memory sharing with the specified OpenGL buffer. + * @param glBuffer The OpenGL buffer handle like a vertex buffer or pixel buffer object. + * @param glBufferSize The size of the OpenGL buffer in bytes + * @param flags optional flags. + */ + public final CLGLBuffer<?> createFromGLBuffer(int glBuffer, long glBufferSize, int flags) { + return createFromGLBuffer(null, glBuffer, glBufferSize, flags); } - public final <B extends Buffer> CLGLBuffer<B> createFromGLBuffer(B directBuffer, int glBuffer, Mem... flags) { - return createFromGLBuffer(directBuffer, glBuffer, Mem.flagsToInt(flags)); + /** + * Creates a CLGLBuffer for memory sharing with the specified OpenGL buffer. + * @param directBuffer A direct allocated NIO buffer for data transfers between java and OpenCL. + * @param glBuffer The OpenGL buffer handle like a vertex buffer or pixel buffer object. + * @param glBufferSize The size of the OpenGL buffer in bytes + * @param flags optional flags. + */ + public final <B extends Buffer> CLGLBuffer<B> createFromGLBuffer(B directBuffer, int glBuffer, long glBufferSize, Mem... flags) { + return createFromGLBuffer(directBuffer, glBuffer, glBufferSize, Mem.flagsToInt(flags)); } - public final <B extends Buffer> CLGLBuffer<B> createFromGLBuffer(B directBuffer, int glBuffer, int flags) { - CLGLBuffer<B> buffer = CLGLBuffer.create(this, directBuffer, flags, glBuffer); + /** + * Creates a CLGLBuffer for memory sharing with the specified OpenGL buffer. + * @param directBuffer A direct allocated NIO buffer for data transfers between java and OpenCL. + * @param glBuffer The OpenGL buffer handle like a vertex buffer or pixel buffer object. + * @param glBufferSize The size of the OpenGL buffer in bytes + * @param flags optional flags. + */ + public final <B extends Buffer> CLGLBuffer<B> createFromGLBuffer(B directBuffer, int glBuffer, long glBufferSize, int flags) { + CLGLBuffer<B> buffer = CLGLBuffer.create(this, directBuffer, glBufferSize, flags, glBuffer); memoryObjects.add(buffer); return buffer; } diff --git a/test/com/jogamp/opencl/gl/CLGLTest.java b/test/com/jogamp/opencl/gl/CLGLTest.java index 01fd4679..aba827e7 100644 --- a/test/com/jogamp/opencl/gl/CLGLTest.java +++ b/test/com/jogamp/opencl/gl/CLGLTest.java @@ -32,10 +32,11 @@ package com.jogamp.opencl.gl; +import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.Platform; -import org.junit.Rule; -import org.junit.rules.MethodRule; -import org.junit.rules.Timeout; +import com.jogamp.opencl.CLCommandQueue; +import javax.media.opengl.GL2; +import javax.media.opengl.GLException; import com.jogamp.opencl.CLDevice; import com.jogamp.newt.Display; import com.jogamp.newt.NewtFactory; @@ -43,12 +44,20 @@ import com.jogamp.newt.Screen; import com.jogamp.newt.Window; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opencl.CLContext; +import com.jogamp.opencl.CLMemory.Mem; import com.jogamp.opencl.CLPlatform; +import com.jogamp.opencl.util.CLDeviceFilters; +import com.jogamp.opencl.util.CLPlatformFilters; +import java.nio.IntBuffer; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; import javax.media.opengl.GLContext; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.MethodRule; +import org.junit.rules.Timeout; +import static com.jogamp.opencl.util.CLPlatformFilters.*; import static org.junit.Assert.*; import static java.lang.System.*; @@ -65,8 +74,7 @@ public class CLGLTest { private static GLWindow glWindow; private static Window window; -// @BeforeClass - public static void init() { + public static void initGL() { GLProfile.initSingleton(true); // FIXME remove when JOCL is stabelized on mac @@ -92,25 +100,30 @@ public class CLGLTest { glcontext = glWindow.getContext(); // glcontext.makeCurrent(); - out.println("useing glcontext:"); - out.println(glcontext); +// out.println(" - - - - glcontext - - - - "); +// out.println(glcontext); +// out.println(" - - - - - - - - - - - - - "); + } + + private void deinitGL() throws GLException { + glcontext.release(); + glWindow.destroy(); + window.destroy(); + + glcontext = null; + glWindow = null; + window = null; } @Test public void createContextTest() { - init(); + initGL(); out.println(" - - - glcl; createContextTest - - - "); - CLDevice[] devices = CLPlatform.getDefault().listCLDevices(); - CLDevice device = null; - for (CLDevice d : devices) { - if(d.isGLMemorySharingSupported()) { - device = d; - break; - } - } + CLPlatform platform = CLPlatform.getDefault(CLPlatformFilters.glSharing()); + CLDevice device = platform.getMaxFlopsDevice(CLDeviceFilters.glSharing()); if(device == null) { out.println("Aborting test: no GLCL capable devices found."); @@ -122,7 +135,7 @@ public class CLGLTest { out.println(device.getPlatform()); assertNotNull(glcontext); - glcontext.makeCurrent(); + makeGLCurrent(); assertTrue(glcontext.isCurrent()); CLContext context = CLGLContext.create(glcontext, device); @@ -139,10 +152,96 @@ public class CLGLTest { // destroy cl context, gl context still current context.release(); - glcontext.release(); - glWindow.destroy(); + deinitGL(); + } + + } + + @Test + public void vboSharing() { + + out.println(" - - - glcl; vboSharing - - - "); + + initGL(); + makeGLCurrent(); + assertTrue(glcontext.isCurrent()); + + CLPlatform platform = CLPlatform.getDefault(glSharing(glcontext)); + if(platform == null) { + out.println("test aborted"); + return; + } + + CLDevice theChosenOne = platform.getMaxFlopsDevice(CLDeviceFilters.glSharing()); + out.println(theChosenOne); + + CLGLContext context = CLGLContext.create(glcontext, theChosenOne); + + try{ + out.println(context); + + GL2 gl = glcontext.getGL().getGL2(); + + int[] id = new int[1]; + gl.glGenBuffers(id.length, id, 0); + + IntBuffer glData = Buffers.newDirectIntBuffer(new int[] {0,1,2,3,4,5,6,7,8}); + glData.rewind(); + + // create and write GL buffer + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, id[0]); + gl.glBufferData(GL2.GL_ARRAY_BUFFER, glData.capacity()*4, glData, GL2.GL_STATIC_DRAW); + gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + gl.glFinish(); + + + // create CLGL buffer + IntBuffer clData = Buffers.newDirectIntBuffer(9); + CLGLBuffer<IntBuffer> clBuffer = context.createFromGLBuffer(clData, id[0], glData.capacity()*4, Mem.READ_ONLY); + + assertEquals(glData.capacity(), clBuffer.getCLCapacity()); + assertEquals(glData.capacity()*4, clBuffer.getCLSize()); + + + CLCommandQueue queue = theChosenOne.createCommandQueue(); + + // read gl buffer into cl nio buffer + queue.putAcquireGLObject(clBuffer) + .putReadBuffer(clBuffer, true) + .putReleaseGLObject(clBuffer); + + while(clData.hasRemaining()) { + assertEquals(glData.get(), clData.get()); + } + + out.println(clBuffer); + + clBuffer.release(); + + gl.glDeleteBuffers(1, id, 0); + + }finally{ + context.release(); + deinitGL(); } + + } + private void makeGLCurrent() { + // we are patient... + while(true) { + try{ + glcontext.makeCurrent(); + break; + }catch(RuntimeException ex) { + try { + Thread.sleep(200); + // I don't give up yet! + } catch (InterruptedException ignore) { } + } + } } |