reworked releasing system.

Now one has to either release a native OpenCLObject manually with release() or register it for automatic garbage collection using register().
These changes greatly improve the performance by reducing the load on the OpenCLObjectManager.
define_list_fix
shamanDevel 9 years ago
parent a26e526945
commit 4be6013068
  1. 62
      jme3-core/src/main/java/com/jme3/opencl/AbstractOpenCLObject.java
  2. 6
      jme3-core/src/main/java/com/jme3/opencl/Buffer.java
  3. 10
      jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java
  4. 6
      jme3-core/src/main/java/com/jme3/opencl/Context.java
  5. 16
      jme3-core/src/main/java/com/jme3/opencl/Event.java
  6. 52
      jme3-core/src/main/java/com/jme3/opencl/Image.java
  7. 5
      jme3-core/src/main/java/com/jme3/opencl/Kernel.java
  8. 34
      jme3-core/src/main/java/com/jme3/opencl/OpenCLObject.java
  9. 7
      jme3-core/src/main/java/com/jme3/opencl/OpenCLObjectManager.java
  10. 18
      jme3-core/src/main/java/com/jme3/opencl/Program.java
  11. 19
      jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java
  12. 10
      jme3-examples/src/main/java/jme3test/opencl/TestVertexBufferSharing.java
  13. 11
      jme3-examples/src/main/java/jme3test/opencl/TestWriteToTexture.java
  14. 6
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclBuffer.java
  15. 14
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclCommandQueue.java
  16. 8
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclContext.java
  17. 11
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclEvent.java
  18. 8
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclImage.java
  19. 6
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclKernel.java
  20. 13
      jme3-jogl/src/main/java/com/jme3/opencl/jocl/JoclProgram.java
  21. 6
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java
  22. 8
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglCommandQueue.java
  23. 6
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java
  24. 20
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java
  25. 8
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java
  26. 2
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java
  27. 13
      jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java

@ -0,0 +1,62 @@
/*
* Copyright (c) 2009-2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.opencl;
/**
* Abstract implementation of {@link OpenCLObject} providing the release
* mechanisms.
* @author Sebastian Weiss
*/
public abstract class AbstractOpenCLObject implements OpenCLObject {
protected final ObjectReleaser releaser;
protected AbstractOpenCLObject(ObjectReleaser releaser) {
this.releaser = releaser;
}
@Override
public void register() {
OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
public void release() {
releaser.release();
}
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
release();
}
@Override
public ObjectReleaser getReleaser() {
return releaser;
}
}

@ -47,8 +47,12 @@ import java.nio.ByteBuffer;
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
* @author shaman
*/
public abstract class Buffer implements OpenCLObject {
public abstract class Buffer extends AbstractOpenCLObject {
protected Buffer(ObjectReleaser releaser) {
super(releaser);
}
/**
* @return the size of the buffer in bytes.
* @see Context#createBuffer(long)

@ -42,8 +42,12 @@ package com.jme3.opencl;
* and all commands are sent to this device.
* @author shaman
*/
public interface CommandQueue extends OpenCLObject {
public abstract class CommandQueue extends AbstractOpenCLObject {
protected CommandQueue(ObjectReleaser releaser) {
super(releaser);
}
/**
* Issues all previously queued OpenCL commands in command_queue to the
* device associated with command queue. Flush only guarantees that all
@ -51,7 +55,7 @@ public interface CommandQueue extends OpenCLObject {
* appropriate device. There is no guarantee that they will be complete
* after flush returns.
*/
void flush();
public abstract void flush();
/**
* Blocks until all previously queued OpenCL commands in command queue are
@ -59,6 +63,6 @@ public interface CommandQueue extends OpenCLObject {
* return until all previously queued commands in command queue have been
* processed and completed. Finish is also a synchronization point.
*/
void finish();
public abstract void finish();
}

@ -63,9 +63,13 @@ import java.util.logging.Logger;
* </ul>
* @author shaman
*/
public abstract class Context implements OpenCLObject {
public abstract class Context extends AbstractOpenCLObject {
private static final Logger LOG = Logger.getLogger(Context.class.getName());
protected Context(ObjectReleaser releaser) {
super(releaser);
}
/**
* Returns all available devices for this context.
* These devices all belong to the same {@link Platform}.

@ -38,16 +38,22 @@ package com.jme3.opencl;
* is done.
* @author shaman
*/
public interface Event extends OpenCLObject {
public abstract class Event extends AbstractOpenCLObject {
protected Event(ObjectReleaser releaser) {
super(releaser);
}
/**
* Waits until the action has finished (blocking)
* Waits until the action has finished (blocking).
* This automatically releases the event.
*/
void waitForFinished();
public abstract void waitForFinished();
/**
* Tests if the action is completed
* Tests if the action is completed.
* If the action is completed, the event is released.
* @return {@code true} if the action is completed
*/
boolean isCompleted();
public abstract boolean isCompleted();
}

@ -74,7 +74,7 @@ import java.util.Objects;
*
* @author shaman
*/
public interface Image extends OpenCLObject {
public abstract class Image extends AbstractOpenCLObject {
/**
* {@code ImageChannelType} describes the size of the channel data type.
@ -245,47 +245,51 @@ memory layout in which channels are stored in the image.
}
}
protected Image(ObjectReleaser releaser) {
super(releaser);
}
/**
* @return the width of the image
*/
long getWidth();
public abstract long getWidth();
/**
* @return the height of the image
*/
long getHeight();
public abstract long getHeight();
/**
* @return the depth of the image
*/
long getDepth();
public abstract long getDepth();
/**
* @return the row pitch when the image was created from a host buffer
* @see ImageDescriptor#ImageDescriptor(com.jme3.opencl.Image.ImageType, long, long, long, long, long, long, java.nio.ByteBuffer)
*/
long getRowPitch();
public abstract long getRowPitch();
/**
* @return the slice pitch when the image was created from a host buffer
* @see ImageDescriptor#ImageDescriptor(com.jme3.opencl.Image.ImageType, long, long, long, long, long, long, java.nio.ByteBuffer)
*/
long getSlicePitch();
public abstract long getSlicePitch();
/**
* @return the number of elements in the image array
* @see ImageType#IMAGE_1D_ARRAY
* @see ImageType#IMAGE_2D_ARRAY
*/
long getArraySize();
public abstract long getArraySize();
/**
* @return the image format
*/
ImageFormat getImageFormat();
public abstract ImageFormat getImageFormat();
/**
* @return the image type
*/
ImageType getImageType();
public abstract ImageType getImageType();
/**
* @return the number of bytes per pixel
*/
int getElementSize();
public abstract int getElementSize();
/**
* Performs a blocking read of the image into the specified byte buffer.
@ -298,7 +302,7 @@ memory layout in which channels are stored in the image.
* @param slicePitch the slice pitch of the target buffer, must be set to 0 for 1D and 2D images.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/
void readImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
public abstract void readImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs an async/non-blocking read of the image into the specified byte buffer.
* @param queue the command queue
@ -311,7 +315,7 @@ memory layout in which channels are stored in the image.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
* @return the event object indicating the status of the operation
*/
Event readImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
public abstract Event readImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs a blocking write from the specified byte buffer into the image.
@ -324,7 +328,7 @@ memory layout in which channels are stored in the image.
* @param slicePitch the slice pitch of the target buffer, must be set to 0 for 1D and 2D images.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/
void writeImage(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
public abstract void writeImage(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs an async/non-blocking write from the specified byte buffer into the image.
* @param queue the command queue
@ -337,7 +341,7 @@ memory layout in which channels are stored in the image.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
* @return the event object indicating the status of the operation
*/
Event writeImageAsync(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
public abstract Event writeImageAsync(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs a blocking copy operation from one image to another.
@ -348,7 +352,7 @@ memory layout in which channels are stored in the image.
* @param destOrigin the target image origin, see class description for the format
* @param region the copied region, see class description for the format
*/
void copyTo(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
public abstract void copyTo(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
/**
* Performs an async/non-blocking copy operation from one image to another.
* <b>Important:</b> Both images must have the same format!
@ -359,7 +363,7 @@ memory layout in which channels are stored in the image.
* @param region the copied region, see class description for the format
* @return the event object indicating the status of the operation
*/
Event copyToAsync(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
public abstract Event copyToAsync(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
/**
* Maps the image into host memory.
@ -373,7 +377,7 @@ memory layout in which channels are stored in the image.
* @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/
ImageMapping map(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
public abstract ImageMapping map(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
/**
* Non-blocking version of {@link #map(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess) }.
* The returned structure contains the mapped byte buffer and row and slice pitch.
@ -385,13 +389,13 @@ memory layout in which channels are stored in the image.
* @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/
ImageMapping mapAsync(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
public abstract ImageMapping mapAsync(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
/**
* Unmaps the mapped memory
* @param queue the command queue
* @param mapping the mapped memory
*/
void unmap(CommandQueue queue, ImageMapping mapping);
public abstract void unmap(CommandQueue queue, ImageMapping mapping);
/**
* Describes a mapped region of the image
@ -442,7 +446,7 @@ memory layout in which channels are stored in the image.
* @param color the color to fill
* @return an event object to detect for the completion
*/
Event fillAsync(CommandQueue queue, long[] origin, long[] region, ColorRGBA color);
public abstract Event fillAsync(CommandQueue queue, long[] origin, long[] region, ColorRGBA color);
/**
* Fills the image with the specified color given as four integer variables.
* Does <b>not</b> work if the image channel is {@link ImageChannelType#FLOAT}
@ -453,7 +457,7 @@ memory layout in which channels are stored in the image.
* @param color the color to fill, must be an array of length 4
* @return an event object to detect for the completion
*/
Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color);
public abstract Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color);
/**
* Copies this image into the specified buffer, no format conversion is done.
@ -466,7 +470,7 @@ memory layout in which channels are stored in the image.
* @param destOffset an offset into the target buffer
* @return the event object to detect the completion of the operation
*/
Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset);
public abstract Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset);
/**
* Aquires this image object for using. Only call this method if this image
@ -480,7 +484,7 @@ memory layout in which channels are stored in the image.
* @param queue the command queue
* @return the event object
*/
Event acquireImageForSharingAsync(CommandQueue queue);
public abstract Event acquireImageForSharingAsync(CommandQueue queue);
/**
* Releases a shared image object.
* Call this method after the image object was acquired by
@ -489,7 +493,7 @@ memory layout in which channels are stored in the image.
* @param queue the command queue
* @return the event object
*/
Event releaseImageForSharingAsync(CommandQueue queue);
public abstract Event releaseImageForSharingAsync(CommandQueue queue);
//TODO: add variants of the above two methods that don't create the event object, but release the event immediately
}

@ -82,7 +82,7 @@ import java.util.Arrays;
* @author shaman
* @see Program#createKernel(java.lang.String)
*/
public abstract class Kernel implements OpenCLObject {
public abstract class Kernel extends AbstractOpenCLObject {
/**
* The current global work size
*/
@ -92,7 +92,8 @@ public abstract class Kernel implements OpenCLObject {
*/
protected final WorkSize workGroupSize;
protected Kernel() {
protected Kernel(ObjectReleaser releaser) {
super(releaser);
this.globalWorkSize = new WorkSize(0);
this.workGroupSize = new WorkSize(0);
}

@ -32,14 +32,44 @@
package com.jme3.opencl;
/**
*
* Base interface of all native OpenCL objects.
* This interface provides the functionality for savely release the object.
* @author shaman
*/
public interface OpenCLObject {
/**
* Releaser for an {@link OpenCLObject}.
* Implementations of this interface must not hold a reference to the
* {@code OpenCLObject} directly.
*/
public static interface ObjectReleaser {
/**
* Releases the native resources of the associated {@link OpenCLObject}.
* This method must be guarded against multiple calls: only the first
* call should release, the next ones must not throw an exception.
*/
void release();
}
/**
* Returns the releaser object. Multiple calls should return the same object.
* The ObjectReleaser is used to release the OpenCLObject when it is garbage
* collected. Therefore, the returned object must not hold a reference to
* the OpenCLObject.
* @return the object releaser
*/
ObjectReleaser getReleaser();
/**
* Releases this native object.
* Should delegate to {@code getReleaser().release()}.
*/
void release();
/**
* Registers this object for automatic releasing on garbage collection.
* By default, OpenCLObjects are not registered in the
* {@link OpenCLObjectManager}, you have to release it manually
* by calling {@link #release() }.
* Without registering or releasing, a memory leak might occur.
*/
void register();
}

@ -43,8 +43,8 @@ import java.util.logging.Logger;
*/
public class OpenCLObjectManager {
private static final Logger LOG = Logger.getLogger(OpenCLObjectManager.class.getName());
private static final Level LOG_LEVEL1 = Level.FINER;
private static final Level LOG_LEVEL2 = Level.FINE;
private static final Level LOG_LEVEL1 = Level.INFO;
private static final Level LOG_LEVEL2 = Level.INFO;
/**
* Call Runtime.getRuntime().gc() every these frames
*/
@ -85,6 +85,7 @@ public class OpenCLObjectManager {
public void deleteUnusedObjects() {
if (activeObjects.isEmpty()) {
LOG.log(LOG_LEVEL2, "no active natives");
return; //nothing to do
}
@ -108,7 +109,7 @@ public class OpenCLObjectManager {
removed++;
}
if (removed >= 1) {
LOG.log(LOG_LEVEL2, "NativeObjectManager: {0} native objects were removed from native", removed);
LOG.log(LOG_LEVEL2, "{0} native objects were removed from native", removed);
}
}

@ -42,8 +42,12 @@ package com.jme3.opencl;
* @see #createKernel(java.lang.String)
* @author shaman
*/
public interface Program extends OpenCLObject {
public abstract class Program extends AbstractOpenCLObject {
protected Program(ObjectReleaser releaser) {
super(releaser);
}
/**
* Builds this program with the specified argument string.
* Please see the official OpenCL specification for a definition of
@ -52,13 +56,15 @@ public interface Program extends OpenCLObject {
* @throws KernelCompilationException if the compilation fails
* @see #build()
*/
void build(String args) throws KernelCompilationException;
public abstract void build(String args) throws KernelCompilationException;
/**
* Builds this program without additional arguments
* @throws KernelCompilationException if the compilation fails
* @see #build(java.lang.String)
*/
void build() throws KernelCompilationException;
public void build() throws KernelCompilationException {
build("");
}
/**
* Creates the kernel with the specified name.
@ -67,13 +73,13 @@ public interface Program extends OpenCLObject {
* @throws OpenCLException if the kernel was not found or some other
* error occured
*/
Kernel createKernel(String name);
public abstract Kernel createKernel(String name);
/**
* Creates all available kernels in this program.
* The names of the kernels can then by queried by {@link Kernel#getName() }.
* @return an array of all kernels
*/
Kernel[] createAllKernels();
public abstract Kernel[] createAllKernels();
}

@ -85,6 +85,8 @@ public class HelloOpenCL extends SimpleApplication {
str.append("\n Kernel: ").append(testKernel(clContext, clQueue));
str.append("\n Images: ").append(testImages(clContext, clQueue));
clQueue.release();
BitmapText txt1 = new BitmapText(fnt);
txt1.setText(str.toString());
txt1.setLocalTranslation(5, settings.getHeight() - 5, 0);
@ -159,6 +161,10 @@ public class HelloOpenCL extends SimpleApplication {
assertEquals((byte) (i+low), b, "Wrong byte read");
}
//release
b1.release();
b2.release();
} catch (AssertionError ex) {
LOG.log(Level.SEVERE, "Buffer test failed with an assertion error");
return false;
@ -193,6 +199,11 @@ public class HelloOpenCL extends SimpleApplication {
assertEquals(value, v, "Buffer filled with the wrong value at index "+i);
}
buffer.unmap(clQueue, buf);
//release
buffer.release();
kernel.release();
program.release();
} catch (AssertionError ex) {
LOG.log(Level.SEVERE, "kernel test failed with an assertion error");
@ -239,7 +250,8 @@ public class HelloOpenCL extends SimpleApplication {
//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);
Event e3 = image.copyToBufferAsync(clQueue, buffer, new long[]{10,10,0}, new long[]{500,1024,1}, 0);
e3.release();
//this buffer must be completely red
ByteBuffer map1 = buffer.map(clQueue, MappingAccess.MAP_READ_ONLY);
FloatBuffer map1F = map1.asFloatBuffer(); map1F.rewind();
@ -282,6 +294,11 @@ public class HelloOpenCL extends SimpleApplication {
}
image2.unmap(clQueue, map2);
//release
image.release();
image2.release();
buffer.release();
} catch (AssertionError ex) {
LOG.log(Level.SEVERE, "image test failed with an assertion error");
return false;

@ -107,6 +107,7 @@ public class TestVertexBufferSharing extends SimpleApplication {
private void initOpenCL1() {
clContext = context.getOpenCLContext();
clQueue = clContext.createQueue();
clQueue.register();
//create kernel
String source = ""
+ "__kernel void ScaleKernel(__global float* vb, float scale)\n"
@ -118,12 +119,15 @@ public class TestVertexBufferSharing extends SimpleApplication {
+ "}\n";
Program program = clContext.createProgramFromSourceCode(source);
program.build();
program.register();
kernel = program.createKernel("ScaleKernel");
kernel.register();
}
private void initOpenCL2() {
//bind vertex buffer to OpenCL
VertexBuffer vb = geom.getMesh().getBuffer(VertexBuffer.Type.Position);
buffer = clContext.bindVertexBuffer(vb, MemoryAccess.READ_WRITE);
buffer.register();
ws = new com.jme3.opencl.Kernel.WorkSize(geom.getMesh().getVertexCount());
}
private void updateOpenCL(float tpf) {
@ -131,15 +135,15 @@ public class TestVertexBufferSharing extends SimpleApplication {
time += tpf;
//aquire resource
buffer.acquireBufferForSharingAsync(clQueue);
buffer.acquireBufferForSharingAsync(clQueue).release();
//no need to wait for the returned event, since the kernel implicitely waits for it (same command queue)
//execute kernel
float scale = (float) Math.pow(1.1, (1.0 - time%2) / 16.0);
kernel.Run1(clQueue, ws, buffer, scale);
kernel.Run1(clQueue, ws, buffer, scale).release();
//release resource
buffer.releaseBufferForSharingAsync(clQueue);
buffer.releaseBufferForSharingAsync(clQueue).release();
}
}

@ -120,26 +120,31 @@ public class TestWriteToTexture extends SimpleApplication implements AnalogListe
private void initOpenCL1() {
clContext = context.getOpenCLContext();
clQueue = clContext.createQueue();
clQueue.register();
//create kernel
Program program = clContext.createProgramFromSourceFiles(assetManager, "jme3test/opencl/JuliaSet.cl");
program.build();
program.register();
kernel = program.createKernel("JuliaSet");
kernel.register();
C = new Vector2f(0.12f, -0.2f);
}
private void initOpenCL2() {
//bind image to OpenCL
texCL = clContext.bindImage(tex, MemoryAccess.WRITE_ONLY);
texCL.register();
}
private void updateOpenCL(float tpf) {
//aquire resource
texCL.acquireImageForSharingAsync(clQueue);
texCL.acquireImageForSharingAsync(clQueue).release();
//no need to wait for the returned event, since the kernel implicitely waits for it (same command queue)
//execute kernel
kernel.Run1(clQueue, new com.jme3.opencl.Kernel.WorkSize(settings.getWidth(), settings.getHeight()), texCL, C, 16);
kernel.Run1(clQueue, new com.jme3.opencl.Kernel.WorkSize(settings.getWidth(), settings.getHeight()), texCL, C, 16)
.release();
//release resource
texCL.releaseImageForSharingAsync(clQueue);
texCL.releaseImageForSharingAsync(clQueue).release();
}
@Override

@ -48,9 +48,9 @@ public class JoclBuffer extends Buffer {
final CL cl;
public JoclBuffer(long id) {
super(new ReleaserImpl(id));
this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@ -203,10 +203,6 @@ public class JoclBuffer extends Buffer {
return new JoclEvent(event);
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id);
}
private static class ReleaserImpl implements ObjectReleaser {
private long mem;
private ReleaserImpl(long mem) {

@ -42,15 +42,15 @@ import com.jogamp.opencl.llb.CLCommandQueueBinding;
*
* @author shaman
*/
public class JoclCommandQueue implements CommandQueue {
public class JoclCommandQueue extends CommandQueue {
final CL cl;
final long id;
public JoclCommandQueue(long id) {
super(new ReleaserImpl(id));
this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@ -65,23 +65,17 @@ public class JoclCommandQueue implements CommandQueue {
Utils.checkError(ret, "clFinish");
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id, cl);
}
private static class ReleaserImpl implements ObjectReleaser {
private long id;
private CLCommandQueueBinding cl;
private ReleaserImpl(long id, CLCommandQueueBinding cl) {
private ReleaserImpl(long id) {
this.id = id;
this.cl = cl;
}
@Override
public void release() {
if (id != 0) {
int ret = cl.clReleaseCommandQueue(id);
int ret = CLPlatform.getLowLevelCLInterface().clReleaseCommandQueue(id);
id = 0;
Utils.reportError(ret, "clReleaseCommandQueue");
}

@ -40,7 +40,6 @@ import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Texture;
import com.jogamp.opencl.CLContext;
import com.jogamp.opencl.CLImageFormat;
import com.jogamp.opencl.CLMemory;
import com.jogamp.opencl.CLMemory.Mem;
import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.llb.CL;
@ -48,7 +47,6 @@ import com.jogamp.opencl.llb.gl.CLGL;
import com.jogamp.opencl.llb.impl.CLImageFormatImpl;
import com.jogamp.opengl.GL;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -66,11 +64,11 @@ public class JoclContext extends Context {
private final List<JoclDevice> devices;
public JoclContext(CLContext context, List<JoclDevice> devices) {
super(new ReleaserImpl(context.ID, devices));
this.context = context;
this.id = context.ID;
this.cl = context.getCL();
this.devices = devices;
OpenCLObjectManager.getInstance().registerObject(this);
}
public CLContext getContext() {
@ -224,10 +222,6 @@ public class JoclContext extends Context {
return new JoclProgram(p, this);
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id, devices);
}
private static class ReleaserImpl implements ObjectReleaser {
private long id;
private final List<JoclDevice> devices;

@ -41,16 +41,16 @@ import java.util.logging.Logger;
*
* @author shaman
*/
public class JoclEvent implements Event {
public class JoclEvent extends Event {
private static final Logger LOG = Logger.getLogger(JoclEvent.class.getName());
final long id;
final CL cl;
public JoclEvent(long id) {
super(new ReleaserImpl(id));
this.id = id;
this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@ -59,6 +59,7 @@ public class JoclEvent implements Event {
Utils.pointers[0].put(0, id);
int ret = cl.clWaitForEvents(1, Utils.pointers[0]);
Utils.checkError(ret, "clWaitForEvents");
release();
}
@Override
@ -68,6 +69,7 @@ public class JoclEvent implements Event {
Utils.checkError(err, "clGetEventInfo");
int status = Utils.tempBuffers[0].b16i.get(0);
if (status == CL.CL_SUCCESS) {
release();
return true;
} else if (status < 0) {
Utils.checkError(status, "EventStatus");
@ -76,11 +78,6 @@ public class JoclEvent implements Event {
return false;
}
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id);
}
private static class ReleaserImpl implements ObjectReleaser {
private long event;

@ -44,16 +44,16 @@ import java.util.logging.Logger;
*
* @author shaman
*/
public class JoclImage implements Image {
public class JoclImage extends Image {
private static final Logger LOG = Logger.getLogger(JoclImage.class.getName());
final long id;
final CL cl;
public JoclImage(long image) {
super(new ReleaserImpl(image));
this.id = image;
this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
}
public static int decodeImageChannelOrder(ImageChannelOrder order) {
@ -512,10 +512,6 @@ public class JoclImage implements Image {
return new JoclEvent(event);
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(id);
}
private static class ReleaserImpl implements ObjectReleaser {
private long mem;
private ReleaserImpl(long mem) {

@ -37,7 +37,6 @@ import com.jme3.math.Vector4f;
import com.jme3.opencl.*;
import com.jme3.opencl.Buffer;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.opencl.CLKernel;
import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.llb.CL;
import java.nio.*;
@ -55,6 +54,7 @@ public class JoclKernel extends Kernel {
final CL cl;
public JoclKernel(long kernel) {
super(new ReleaserImpl(kernel));
this.kernel = kernel;
this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
@ -240,10 +240,6 @@ public class JoclKernel extends Kernel {
return new JoclEvent(Utils.pointers[0].get(0));
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(kernel);
}
private static class ReleaserImpl implements ObjectReleaser {
private long kernel;
private ReleaserImpl(long kernel) {

@ -50,7 +50,7 @@ import static com.jogamp.opencl.llb.CL.CL_SUCCESS;
*
* @author shaman
*/
public class JoclProgram implements Program {
public class JoclProgram extends Program {
private static final Logger LOG = Logger.getLogger(JoclProgram.class.getName());
final long program;
@ -58,10 +58,10 @@ public class JoclProgram implements Program {
private final JoclContext context;
public JoclProgram(long program, JoclContext context) {
super(new ReleaserImpl(program));
this.program = program;
this.context = context;
this.cl = CLPlatform.getLowLevelCLInterface();
OpenCLObjectManager.getInstance().registerObject(this);
}
@Override
@ -79,11 +79,6 @@ public class JoclProgram implements Program {
LOG.log(Level.INFO, "Program compiled:\n{0}", Log());
}
}
@Override
public void build() throws KernelCompilationException {
build("");
}
private String Log(long device) {
Utils.pointers[0].rewind();
@ -131,10 +126,6 @@ public class JoclProgram implements Program {
return kx;
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(program);
}
private static class ReleaserImpl implements ObjectReleaser {
private long program;
private ReleaserImpl(long program) {

@ -44,8 +44,8 @@ public class LwjglBuffer extends Buffer {
private final CLMem buffer;
public LwjglBuffer(CLMem buffer) {
super(new ReleaserImpl(buffer));
this.buffer = buffer;
OpenCLObjectManager.getInstance().registerObject(this);
}
public CLMem getBuffer() {
return buffer;
@ -205,10 +205,6 @@ public class LwjglBuffer extends Buffer {
return new LwjglEvent(q.getCLEvent(event));
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(buffer);
}
private static class ReleaserImpl implements ObjectReleaser {
private CLMem mem;
private ReleaserImpl(CLMem mem) {

@ -40,13 +40,13 @@ import org.lwjgl.opencl.CLCommandQueue;
*
* @author shaman
*/
public class LwjglCommandQueue implements CommandQueue {
public class LwjglCommandQueue extends CommandQueue {
private final CLCommandQueue queue;
public LwjglCommandQueue(CLCommandQueue queue) {
super(new ReleaserImpl(queue));
this.queue = queue;
OpenCLObjectManager.getInstance().registerObject(this);
}
public CLCommandQueue getQueue() {
@ -65,10 +65,6 @@ public class LwjglCommandQueue implements CommandQueue {
Utils.checkError(ret, "clFinish");
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(queue);
}
private static class ReleaserImpl implements ObjectReleaser {
private CLCommandQueue queue;
private ReleaserImpl(CLCommandQueue queue) {

@ -57,9 +57,9 @@ public class LwjglContext extends Context {
private final List<LwjglDevice> devices;
public LwjglContext(CLContext context, List<LwjglDevice> devices) {
super(new ReleaserImpl(context, devices));
this.context = context;
this.devices = devices;
OpenCLObjectManager.getInstance().registerObject(this);
}
public CLContext getContext() {
@ -208,10 +208,6 @@ public class LwjglContext extends Context {
return new LwjglProgram(p, this);
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(context, devices);
}
private static class ReleaserImpl implements ObjectReleaser {
private CLContext context;
private final List<LwjglDevice> devices;

@ -41,31 +41,24 @@ import org.lwjgl.opencl.CLEvent;
*
* @author shaman
*/
public class LwjglEvent implements Event {
public class LwjglEvent extends Event {
private static final Logger LOG = Logger.getLogger(LwjglEvent.class.getName());
private CLEvent event;
private ReleaserImpl releaser;
public LwjglEvent(CLEvent event) {
super(new ReleaserImpl(event));
this.event = event;
if (event == null) {
LOG.warning("event is null!");
} else {
OpenCLObjectManager.getInstance().registerObject(this);
this.releaser = new ReleaserImpl(event);
}
}
public CLEvent getEvent() {
return event;
}
protected void release() {
if (event != null && event.isValid()) {
int ret = CL10.clReleaseEvent(event);
event = null;
Utils.reportError(ret, "clReleaseEvent");
LOG.finer("Event deleted");
}
}
@Override
public void waitForFinished() {
@ -93,11 +86,6 @@ public class LwjglEvent implements Event {
}
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(event);
}
private static class ReleaserImpl implements ObjectReleaser {
private CLEvent event;

@ -43,14 +43,14 @@ import org.lwjgl.opencl.api.CLImageFormat;
*
* @author shaman
*/
public class LwjglImage implements Image {
public class LwjglImage extends Image {
private static final Logger LOG = Logger.getLogger(LwjglImage.class.getName());
private final CLMem image;
public LwjglImage(CLMem image) {
super(new ReleaserImpl(image));
this.image = image;
OpenCLObjectManager.getInstance().registerObject(this);
}
public CLMem getImage() {
@ -543,10 +543,6 @@ public class LwjglImage implements Image {
return new LwjglEvent(q.getCLEvent(event));
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(image);
}
private static class ReleaserImpl implements ObjectReleaser {
private CLMem mem;
private ReleaserImpl(CLMem mem) {

@ -52,8 +52,8 @@ public class LwjglKernel extends Kernel {
private final CLKernel kernel;
public LwjglKernel(CLKernel kernel) {
super(new ReleaserImpl(kernel));
this.kernel = kernel;
OpenCLObjectManager.getInstance().registerObject(this);
}
public CLKernel getKernel() {

@ -44,16 +44,16 @@ import org.lwjgl.opencl.*;
*
* @author shaman
*/
public class LwjglProgram implements Program {
public class LwjglProgram extends Program {
private static final Logger LOG = Logger.getLogger(LwjglProgram.class.getName());
private final CLProgram program;
private final LwjglContext context;
public LwjglProgram(CLProgram program, LwjglContext context) {
super(new ReleaserImpl(program));
this.program = program;
this.context = context;
OpenCLObjectManager.getInstance().registerObject(this);
}
public CLProgram getProgram() {
@ -75,11 +75,6 @@ public class LwjglProgram implements Program {
LOG.log(Level.INFO, "Program compiled:\n{0}", Log());
}
}
@Override
public void build() throws KernelCompilationException {
build("");
}
private String Log() {
StringBuilder str = new StringBuilder();
@ -109,10 +104,6 @@ public class LwjglProgram implements Program {
return kx;
}
@Override
public ObjectReleaser getReleaser() {
return new ReleaserImpl(program);
}
private static class ReleaserImpl implements ObjectReleaser {
private CLProgram program;
private ReleaserImpl(CLProgram program) {

Loading…
Cancel
Save