improve format and rm trailing whitespace (10 files in com.jme3.opencl)

master
Stephen Gold 5 years ago
parent a5e0213b01
commit 7212f9b2b2
  1. 79
      jme3-core/src/main/java/com/jme3/opencl/Buffer.java
  2. 42
      jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java
  3. 98
      jme3-core/src/main/java/com/jme3/opencl/Context.java
  4. 176
      jme3-core/src/main/java/com/jme3/opencl/Device.java
  5. 22
      jme3-core/src/main/java/com/jme3/opencl/Event.java
  6. 147
      jme3-core/src/main/java/com/jme3/opencl/Image.java
  7. 160
      jme3-core/src/main/java/com/jme3/opencl/Kernel.java
  8. 24
      jme3-core/src/main/java/com/jme3/opencl/KernelCompilationException.java
  9. 59
      jme3-core/src/main/java/com/jme3/opencl/OpenCLException.java
  10. 50
      jme3-core/src/main/java/com/jme3/opencl/Program.java

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2016 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,8 +43,8 @@ import java.nio.ByteBuffer;
* All access methods (read/write/copy/map) are available in both sychronized/blocking versions * All access methods (read/write/copy/map) are available in both sychronized/blocking versions
* and in async/non-blocking versions. The later ones always return an {@link Event} object * and in async/non-blocking versions. The later ones always return an {@link Event} object
* and have the prefix -Async in their name. * and have the prefix -Async in their name.
* *
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess) * @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
* @author shaman * @author shaman
*/ */
public abstract class Buffer extends AbstractOpenCLObject { public abstract class Buffer extends AbstractOpenCLObject {
@ -53,21 +53,21 @@ public abstract class Buffer extends AbstractOpenCLObject {
super(releaser); super(releaser);
} }
@Override @Override
public Buffer register() { public Buffer register() {
super.register(); super.register();
return this; return this;
} }
/** /**
* @return the size of the buffer in bytes. * @return the size of the buffer in bytes.
* @see Context#createBuffer(long) * @see Context#createBuffer(long)
*/ */
public abstract long getSize(); public abstract long getSize();
/** /**
* @return the memory access flags set on creation. * @return the memory access flags set on creation.
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess) * @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
*/ */
public abstract MemoryAccess getMemoryAccessFlags(); public abstract MemoryAccess getMemoryAccessFlags();
@ -75,6 +75,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs a blocking read of the buffer. * Performs a blocking read of the buffer.
* The target buffer must have at least {@code size} bytes remaining. * The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte read. * This method may set the limit to the last byte read.
*
* @param queue the command queue * @param queue the command queue
* @param dest the target buffer * @param dest the target buffer
* @param size the size in bytes being read * @param size the size in bytes being read
@ -102,6 +103,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs an async/non-blocking read of the buffer. * Performs an async/non-blocking read of the buffer.
* The target buffer must have at least {@code size} bytes remaining. * The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte read. * This method may set the limit to the last byte read.
*
* @param queue the command queue * @param queue the command queue
* @param dest the target buffer * @param dest the target buffer
* @param size the size in bytes being read * @param size the size in bytes being read
@ -130,6 +132,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs a blocking write to the buffer. * Performs a blocking write to the buffer.
* The target buffer must have at least {@code size} bytes remaining. * The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte that will be written. * This method may set the limit to the last byte that will be written.
*
* @param queue the command queue * @param queue the command queue
* @param src the source buffer, its data is written to this buffer * @param src the source buffer, its data is written to this buffer
* @param size the size in bytes to write * @param size the size in bytes to write
@ -157,6 +160,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs an async/non-blocking write to the buffer. * Performs an async/non-blocking write to the buffer.
* The target buffer must have at least {@code size} bytes remaining. * The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte that will be written. * This method may set the limit to the last byte that will be written.
*
* @param queue the command queue * @param queue the command queue
* @param src the source buffer, its data is written to this buffer * @param src the source buffer, its data is written to this buffer
* @param size the size in bytes to write * @param size the size in bytes to write
@ -183,6 +187,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/** /**
* Performs a blocking copy operation from this buffer to the specified buffer. * Performs a blocking copy operation from this buffer to the specified buffer.
*
* @param queue the command queue * @param queue the command queue
* @param dest the target buffer * @param dest the target buffer
* @param size the size in bytes to copy * @param size the size in bytes to copy
@ -209,6 +214,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/** /**
* Performs an async/non-blocking copy operation from this buffer to the specified buffer. * Performs an async/non-blocking copy operation from this buffer to the specified buffer.
*
* @param queue the command queue * @param queue the command queue
* @param dest the target buffer * @param dest the target buffer
* @param size the size in bytes to copy * @param size the size in bytes to copy
@ -238,8 +244,9 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Maps this buffer directly into host memory. This might be the fastest method * Maps this buffer directly into host memory. This might be the fastest method
* to access the contents of the buffer since the OpenCL implementation directly * to access the contents of the buffer since the OpenCL implementation directly
* provides the memory.<br> * provides the memory.<br>
* <b>Important:</b> The mapped memory MUST be released by calling * <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }. * {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*
* @param queue the command queue * @param queue the command queue
* @param size the size in bytes to map * @param size the size in bytes to map
* @param offset the offset into this buffer * @param offset the offset into this buffer
@ -251,7 +258,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/** /**
* Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) }, * Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) },
* sets {@code offset} to zero. * sets {@code offset} to zero.
* <b>Important:</b> The mapped memory MUST be released by calling * <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }. * {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/ */
public ByteBuffer map(CommandQueue queue, long size, MappingAccess access) { public ByteBuffer map(CommandQueue queue, long size, MappingAccess access) {
@ -261,7 +268,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/** /**
* Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) }, * Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) },
* sets {@code size} to {@link #getSize() }. * sets {@code size} to {@link #getSize() }.
* <b>Important:</b> The mapped memory MUST be released by calling * <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }. * {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/ */
public ByteBuffer map(CommandQueue queue, MappingAccess access) { public ByteBuffer map(CommandQueue queue, MappingAccess access) {
@ -272,6 +279,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Unmaps a previously mapped memory. * Unmaps a previously mapped memory.
* This releases the native resources and for WRITE_ONLY or READ_WRITE access, * This releases the native resources and for WRITE_ONLY or READ_WRITE access,
* the memory content is sent back to the GPU. * the memory content is sent back to the GPU.
*
* @param queue the command queue * @param queue the command queue
* @param ptr the buffer that was previously mapped * @param ptr the buffer that was previously mapped
*/ */
@ -281,8 +289,9 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Maps this buffer asynchronously into host memory. This might be the fastest method * Maps this buffer asynchronously into host memory. This might be the fastest method
* to access the contents of the buffer since the OpenCL implementation directly * to access the contents of the buffer since the OpenCL implementation directly
* provides the memory.<br> * provides the memory.<br>
* <b>Important:</b> The mapped memory MUST be released by calling * <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }. * {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*
* @param queue the command queue * @param queue the command queue
* @param size the size in bytes to map * @param size the size in bytes to map
* @param offset the offset into this buffer * @param offset the offset into this buffer
@ -291,28 +300,31 @@ public abstract class Buffer extends AbstractOpenCLObject {
* and the event indicating when the buffer contents are available * and the event indicating when the buffer contents are available
*/ */
public abstract AsyncMapping mapAsync(CommandQueue queue, long size, long offset, MappingAccess access); public abstract AsyncMapping mapAsync(CommandQueue queue, long size, long offset, MappingAccess access);
/** /**
* Alternative version of {@link #mapAsync(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) }, * Alternative version of {@link #mapAsync(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) },
* sets {@code offset} to zero. * sets {@code offset} to zero.
* <b>Important:</b> The mapped memory MUST be released by calling * <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }. * {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/ */
public AsyncMapping mapAsync(CommandQueue queue, long size, MappingAccess access) { public AsyncMapping mapAsync(CommandQueue queue, long size, MappingAccess access) {
return mapAsync(queue, size, 0, access); return mapAsync(queue, size, 0, access);
} }
/** /**
* Alternative version of {@link #mapAsync(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) }, * Alternative version of {@link #mapAsync(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) },
* sets {@code size} to {@link #getSize() }. * sets {@code size} to {@link #getSize() }.
* <b>Important:</b> The mapped memory MUST be released by calling * <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }. * {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/ */
public AsyncMapping mapAsync(CommandQueue queue, MappingAccess access) { public AsyncMapping mapAsync(CommandQueue queue, MappingAccess access) {
return mapAsync(queue, getSize(), 0, access); return mapAsync(queue, getSize(), 0, access);
} }
/** /**
* Enqueues a fill operation. This method can be used to initialize or clear * Enqueues a fill operation. This method can be used to initialize or clear
* a buffer with a certain value. * a buffer with a certain value.
*
* @param queue the command queue * @param queue the command queue
* @param pattern the buffer containing the filling pattern. * @param pattern the buffer containing the filling pattern.
* The remaining bytes specify the pattern length * The remaining bytes specify the pattern length
@ -354,14 +366,14 @@ public abstract class Buffer extends AbstractOpenCLObject {
return buffer; return buffer;
} }
} }
/** /**
* Copies this buffer to the specified image. * Copies this buffer to the specified image.
* Note that no format conversion is done. * Note that no format conversion is done.
* <br> * <br>
* For detailed description of the origin and region paramenter, see the * For detailed description of the origin and region paramenter, see the
* documentation of the {@link Image} class. * documentation of the {@link Image} class.
* *
* @param queue the command queue * @param queue the command queue
* @param dest the target image * @param dest the target image
* @param srcOffset the offset in bytes into this buffer * @param srcOffset the offset in bytes into this buffer
@ -370,7 +382,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* @return the event object * @return the event object
*/ */
public abstract Event copyToImageAsync(CommandQueue queue, Image dest, long srcOffset, long[] destOrigin, long[] destRegion); public abstract Event copyToImageAsync(CommandQueue queue, Image dest, long srcOffset, long[] destOrigin, long[] destRegion);
/** /**
* Aquires this buffer object for using. Only call this method if this buffer * Aquires this buffer object for using. Only call this method if this buffer
* represents a shared object from OpenGL, created with e.g. * represents a shared object from OpenGL, created with e.g.
@ -379,11 +391,12 @@ public abstract class Buffer extends AbstractOpenCLObject {
* done, the buffer must be released by calling * done, the buffer must be released by calling
* {@link #releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the VertexBuffer again. * so that OpenGL can use the VertexBuffer again.
*
* @param queue the command queue * @param queue the command queue
* @return the event object * @return the event object
*/ */
public abstract Event acquireBufferForSharingAsync(CommandQueue queue); public abstract Event acquireBufferForSharingAsync(CommandQueue queue);
/** /**
* Aquires this buffer object for using. Only call this method if this buffer * Aquires this buffer object for using. Only call this method if this buffer
* represents a shared object from OpenGL, created with e.g. * represents a shared object from OpenGL, created with e.g.
@ -392,36 +405,37 @@ public abstract class Buffer extends AbstractOpenCLObject {
* done, the buffer must be released by calling * done, the buffer must be released by calling
* {@link #releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the VertexBuffer again. * so that OpenGL can use the VertexBuffer again.
* *
* The generated event object is directly released. * The generated event object is directly released.
* This brings a performance improvement when the resource is e.g. directly * This brings a performance improvement when the resource is e.g. directly
* used by a kernel afterwards on the same queue (this implicitly waits for * used by a kernel afterwards on the same queue (this implicitly waits for
* this action). If you need the event, use * this action). If you need the event, use
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) } instead. * {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) } instead.
* *
* @param queue the command queue * @param queue the command queue
*/ */
public void acquireBufferForSharingNoEvent(CommandQueue queue) { public void acquireBufferForSharingNoEvent(CommandQueue queue) {
//default implementation, overwrite for better performance //default implementation, overwrite for better performance
acquireBufferForSharingAsync(queue).release(); acquireBufferForSharingAsync(queue).release();
} }
/** /**
* Releases a shared buffer object. * Releases a shared buffer object.
* Call this method after the buffer object was acquired by * Call this method after the buffer object was acquired by
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL. * to hand the control back to OpenGL.
*
* @param queue the command queue * @param queue the command queue
* @return the event object * @return the event object
*/ */
public abstract Event releaseBufferForSharingAsync(CommandQueue queue); public abstract Event releaseBufferForSharingAsync(CommandQueue queue);
/** /**
* Releases a shared buffer object. * Releases a shared buffer object.
* Call this method after the buffer object was acquired by * Call this method after the buffer object was acquired by
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL. * to hand the control back to OpenGL.
* The generated event object is directly released, resulting in * The generated event object is directly released, resulting in
* performance improvements. * performance improvements.
* @param queue the command queue * @param queue the command queue
*/ */
@ -430,9 +444,8 @@ public abstract class Buffer extends AbstractOpenCLObject {
releaseBufferForSharingAsync(queue).release(); releaseBufferForSharingAsync(queue).release();
} }
@Override @Override
public String toString() { public String toString() {
return "Buffer (" + getSize() + "B)"; return "Buffer (" + getSize() + "B)";
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2016 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -34,39 +34,40 @@ package com.jme3.opencl;
/** /**
* Wrapper for an OpenCL command queue. * Wrapper for an OpenCL command queue.
* The command queue serializes every GPU function call: By passing the same * The command queue serializes every GPU function call: By passing the same
* queue to OpenCL function (buffer, image operations, kernel calls), it is * queue to OpenCL function (buffer, image operations, kernel calls), it is
* ensured that they are executed in the order in which they are passed. * ensured that they are executed in the order in which they are passed.
* <br> * <br>
* Each command queue is associtated with exactly one device: that device * Each command queue is associtated with exactly one device: that device
* is specified on creation ({@link Context#createQueue(com.jme3.opencl.Device) }) * is specified on creation ({@link Context#createQueue(com.jme3.opencl.Device) })
* and all commands are sent to this device. * and all commands are sent to this device.
*
* @author shaman * @author shaman
*/ */
public abstract class CommandQueue extends AbstractOpenCLObject { public abstract class CommandQueue extends AbstractOpenCLObject {
protected Device device;
protected Device device;
protected CommandQueue(ObjectReleaser releaser, Device device) { protected CommandQueue(ObjectReleaser releaser, Device device) {
super(releaser); super(releaser);
this.device = device; this.device = device;
} }
@Override @Override
public CommandQueue register() { public CommandQueue register() {
super.register(); super.register();
return this; return this;
} }
/**
* Returns the device associated with this command queue.
* It can be used to query properties of the device that is used to execute
* the commands issued to this command queue.
*
* @return the associated device
*/
public Device getDevice() {
return device;
}
/**
* Returns the device associated with this command queue.
* It can be used to query properties of the device that is used to execute
* the commands issued to this command queue.
* @return the associated device
*/
public Device getDevice() {
return device;
}
/** /**
* Issues all previously queued OpenCL commands in command_queue to the * Issues all previously queued OpenCL commands in command_queue to the
* device associated with command queue. Flush only guarantees that all * device associated with command queue. Flush only guarantees that all
@ -83,5 +84,4 @@ public abstract class CommandQueue extends AbstractOpenCLObject {
* processed and completed. Finish is also a synchronization point. * processed and completed. Finish is also a synchronization point.
*/ */
public abstract void finish(); public abstract void finish();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2019 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -63,6 +63,7 @@ import java.util.logging.Logger;
* <li>Created buffers and images shared with OpenGL vertex buffers, textures and renderbuffers</li> * <li>Created buffers and images shared with OpenGL vertex buffers, textures and renderbuffers</li>
* <li>Create program objects from source code and source files</li> * <li>Create program objects from source code and source files</li>
* </ul> * </ul>
*
* @author shaman * @author shaman
*/ */
public abstract class Context extends AbstractOpenCLObject { public abstract class Context extends AbstractOpenCLObject {
@ -72,11 +73,11 @@ public abstract class Context extends AbstractOpenCLObject {
super(releaser); super(releaser);
} }
@Override @Override
public Context register() { public Context register() {
super.register(); super.register();
return this; return this;
} }
/** /**
* Returns all available devices for this context. * Returns all available devices for this context.
@ -87,6 +88,7 @@ public abstract class Context extends AbstractOpenCLObject {
* memory size and so on, are queried over the Device instances. * memory size and so on, are queried over the Device instances.
* <br> * <br>
* The available devices were specified by a {@link PlatformChooser}. * The available devices were specified by a {@link PlatformChooser}.
*
* @return a list of devices * @return a list of devices
*/ */
public abstract List<? extends Device> getDevices(); public abstract List<? extends Device> getDevices();
@ -94,29 +96,35 @@ public abstract class Context extends AbstractOpenCLObject {
/** /**
* Alternative version of {@link #createQueue(com.jme3.opencl.Device) }, * Alternative version of {@link #createQueue(com.jme3.opencl.Device) },
* just uses the first device returned by {@link #getDevices() }. * just uses the first device returned by {@link #getDevices() }.
*
* @return the command queue * @return the command queue
*/ */
public CommandQueue createQueue() { public CommandQueue createQueue() {
return createQueue(getDevices().get(0)); return createQueue(getDevices().get(0));
} }
/** /**
* Creates a command queue sending commands to the specified device. * Creates a command queue sending commands to the specified device.
* The device must be an entry of {@link #getDevices() }. * The device must be an entry of {@link #getDevices() }.
*
* @param device the target device * @param device the target device
* @return the command queue * @return the command queue
*/ */
public abstract CommandQueue createQueue(Device device); public abstract CommandQueue createQueue(Device device);
/** /**
* Allocates a new buffer of the specific size and access type on the device. * Allocates a new buffer of the specific size and access type on the device.
*
* @param size the size of the buffer in bytes * @param size the size of the buffer in bytes
* @param access the allowed access of this buffer from kernel code * @param access the allowed access of this buffer from kernel code
* @return the new buffer * @return the new buffer
*/ */
public abstract Buffer createBuffer(long size, MemoryAccess access); public abstract Buffer createBuffer(long size, MemoryAccess access);
/** /**
* Alternative version of {@link #createBuffer(long, com.jme3.opencl.MemoryAccess) }, * Alternative version of {@link #createBuffer(long, com.jme3.opencl.MemoryAccess) },
* creates a buffer with read and write access. * creates a buffer with read and write access.
*
* @param size the size of the buffer in bytes * @param size the size of the buffer in bytes
* @return the new buffer * @return the new buffer
*/ */
@ -129,14 +137,17 @@ public abstract class Context extends AbstractOpenCLObject {
* specified by a ByteBuffer can then be used directly by kernel code, * specified by a ByteBuffer can then be used directly by kernel code,
* although the access might be slower than with native buffers * although the access might be slower than with native buffers
* created by {@link #createBuffer(long, com.jme3.opencl.MemoryAccess) }. * created by {@link #createBuffer(long, com.jme3.opencl.MemoryAccess) }.
*
* @param data the host buffer to use * @param data the host buffer to use
* @param access the allowed access of this buffer from kernel code * @param access the allowed access of this buffer from kernel code
* @return the new buffer * @return the new buffer
*/ */
public abstract Buffer createBufferFromHost(ByteBuffer data, MemoryAccess access); public abstract Buffer createBufferFromHost(ByteBuffer data, MemoryAccess access);
/** /**
* Alternative version of {@link #createBufferFromHost(java.nio.ByteBuffer, com.jme3.opencl.MemoryAccess) }, * Alternative version of {@link #createBufferFromHost(java.nio.ByteBuffer, com.jme3.opencl.MemoryAccess) },
* creates a buffer with read and write access. * creates a buffer with read and write access.
*
* @param data the host buffer to use * @param data the host buffer to use
* @return the new buffer * @return the new buffer
*/ */
@ -152,14 +163,15 @@ public abstract class Context extends AbstractOpenCLObject {
* with row and slice pitches. This buffer is then used to store the image. * with row and slice pitches. This buffer is then used to store the image.
* If no ByteBuffer is specified, a new buffer is allocated (this is the * If no ByteBuffer is specified, a new buffer is allocated (this is the
* normal behaviour). * normal behaviour).
*
* @param access the allowed access of this image from kernel code * @param access the allowed access of this image from kernel code
* @param format the image format * @param format the image format
* @param descr the image descriptor * @param descr the image descriptor
* @return the new image object * @return the new image object
*/ */
public abstract Image createImage(MemoryAccess access, ImageFormat format, ImageDescriptor descr); public abstract Image createImage(MemoryAccess access, ImageFormat format, ImageDescriptor descr);
//TODO: add simplified methods for 1D, 2D, 3D textures //TODO: add simplified methods for 1D, 2D, 3D textures
/** /**
* Queries all supported image formats for a specified memory access and * Queries all supported image formats for a specified memory access and
* image type. * image type.
@ -168,16 +180,17 @@ public abstract class Context extends AbstractOpenCLObject {
* where {@code ImageChannelType} or {@code ImageChannelOrder} are {@code null} * where {@code ImageChannelType} or {@code ImageChannelOrder} are {@code null}
* (or both). This is the case when the device supports new formats that * (or both). This is the case when the device supports new formats that
* are not included in this wrapper yet. * are not included in this wrapper yet.
*
* @param access the memory access type * @param access the memory access type
* @param type the image type (1D, 2D, 3D, ...) * @param type the image type (1D, 2D, 3D, ...)
* @return an array of all supported image formats * @return an array of all supported image formats
*/ */
public abstract ImageFormat[] querySupportedFormats(MemoryAccess access, ImageType type); public abstract ImageFormat[] querySupportedFormats(MemoryAccess access, ImageType type);
//Interop //Interop
/** /**
* Creates a shared buffer from a VertexBuffer. * Creates a shared buffer from a VertexBuffer.
* The returned buffer and the vertex buffer operate on the same memory, * The returned buffer and the vertex buffer operate on the same memory,
* changes in one view are visible in the other view. * changes in one view are visible in the other view.
* This can be used to modify meshes directly from OpenCL (e.g. for particle systems). * This can be used to modify meshes directly from OpenCL (e.g. for particle systems).
* <br> * <br>
@ -188,6 +201,7 @@ public abstract class Context extends AbstractOpenCLObject {
* by {@link Buffer#acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) } * by {@link Buffer#acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* and after modifying it, released by {@link Buffer#releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }. * and after modifying it, released by {@link Buffer#releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }.
* This is needed so that OpenGL and OpenCL operations do not interfere with each other. * This is needed so that OpenGL and OpenCL operations do not interfere with each other.
*
* @param vb the vertex buffer to share * @param vb the vertex buffer to share
* @param access the memory access for the kernel * @param access the memory access for the kernel
* @return the new buffer * @return the new buffer
@ -208,7 +222,7 @@ public abstract class Context extends AbstractOpenCLObject {
* by {@link Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) } * by {@link Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* and after modifying it, released by {@link Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) } * and after modifying it, released by {@link Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* This is needed so that OpenGL and OpenCL operations do not interfere with each other. * This is needed so that OpenGL and OpenCL operations do not interfere with each other.
* *
* @param image the jME3 image object * @param image the jME3 image object
* @param textureType the texture type (1D, 2D, 3D), since this is not stored in the image * @param textureType the texture type (1D, 2D, 3D), since this is not stored in the image
* @param miplevel the mipmap level that should be shared * @param miplevel the mipmap level that should be shared
@ -216,6 +230,7 @@ public abstract class Context extends AbstractOpenCLObject {
* @return the OpenCL image * @return the OpenCL image
*/ */
public abstract Image bindImage(com.jme3.texture.Image image, Texture.Type textureType, int miplevel, MemoryAccess access); public abstract Image bindImage(com.jme3.texture.Image image, Texture.Type textureType, int miplevel, MemoryAccess access);
/** /**
* Creates a shared image object from a jME3 texture. * Creates a shared image object from a jME3 texture.
* The returned image shares the same memory with the jME3 texture, changes * The returned image shares the same memory with the jME3 texture, changes
@ -233,7 +248,7 @@ public abstract class Context extends AbstractOpenCLObject {
* <p> * <p>
* This method is equivalent to calling * This method is equivalent to calling
* {@code bindImage(texture.getImage(), texture.getType(), miplevel, access)}. * {@code bindImage(texture.getImage(), texture.getType(), miplevel, access)}.
* *
* @param texture the jME3 texture * @param texture the jME3 texture
* @param miplevel the mipmap level that should be shared * @param miplevel the mipmap level that should be shared
* @param access the allowed memory access for kernels * @param access the allowed memory access for kernels
@ -242,9 +257,11 @@ public abstract class Context extends AbstractOpenCLObject {
public Image bindImage(Texture texture, int miplevel, MemoryAccess access) { public Image bindImage(Texture texture, int miplevel, MemoryAccess access) {
return bindImage(texture.getImage(), texture.getType(), miplevel, access); return bindImage(texture.getImage(), texture.getType(), miplevel, access);
} }
/** /**
* Alternative version to {@link #bindImage(com.jme3.texture.Texture, int, com.jme3.opencl.MemoryAccess) }, * Alternative version to {@link #bindImage(com.jme3.texture.Texture, int, com.jme3.opencl.MemoryAccess) },
* uses {@code miplevel=0}. * uses {@code miplevel=0}.
*
* @param texture the jME3 texture * @param texture the jME3 texture
* @param access the allowed memory access for kernels * @param access the allowed memory access for kernels
* @return the OpenCL image * @return the OpenCL image
@ -252,6 +269,7 @@ public abstract class Context extends AbstractOpenCLObject {
public Image bindImage(Texture texture, MemoryAccess access) { public Image bindImage(Texture texture, MemoryAccess access) {
return bindImage(texture, 0, access); return bindImage(texture, 0, access);
} }
/** /**
* Creates a shared image object from a jME3 render buffer. * Creates a shared image object from a jME3 render buffer.
* The returned image shares the same memory with the jME3 render buffer, changes * The returned image shares the same memory with the jME3 render buffer, changes
@ -267,7 +285,7 @@ public abstract class Context extends AbstractOpenCLObject {
* by {@link Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) } * by {@link Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* and after modifying it, released by {@link Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) } * and after modifying it, released by {@link Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* This is needed so that OpenGL and OpenCL operations do not interfere with each other. * This is needed so that OpenGL and OpenCL operations do not interfere with each other.
* *
* @param buffer * @param buffer
* @param access * @param access
* @return an image * @return an image
@ -279,22 +297,24 @@ public abstract class Context extends AbstractOpenCLObject {
return bindImage(buffer.getTexture(), access); return bindImage(buffer.getTexture(), access);
} }
} }
protected abstract Image bindPureRenderBuffer(FrameBuffer.RenderBuffer buffer, MemoryAccess access); protected abstract Image bindPureRenderBuffer(FrameBuffer.RenderBuffer buffer, MemoryAccess access);
/** /**
* Creates a program object from the provided source code. * Creates a program object from the provided source code.
* The program still needs to be compiled using {@link Program#build() }. * The program still needs to be compiled using {@link Program#build() }.
* *
* @param sourceCode the source code * @param sourceCode the source code
* @return the program object * @return the program object
*/ */
public abstract Program createProgramFromSourceCode(String sourceCode); public abstract Program createProgramFromSourceCode(String sourceCode);
/** /**
* Resolves dependencies (using {@code #include } in the source code) * Resolves dependencies (using {@code #include } in the source code)
* and delegates the combined source code to * and delegates the combined source code to
* {@link #createProgramFromSourceCode(java.lang.String) }. * {@link #createProgramFromSourceCode(java.lang.String) }.
* Important: only absolute paths are allowed. * Important: only absolute paths are allowed.
*
* @param sourceCode the original source code * @param sourceCode the original source code
* @param assetManager the asset manager to load the files * @param assetManager the asset manager to load the files
* @return the created program object * @return the created program object
@ -310,6 +330,7 @@ public abstract class Context extends AbstractOpenCLObject {
} }
return createProgramFromSourceCode(builder.toString()); return createProgramFromSourceCode(builder.toString());
} }
private void buildSourcesRec(BufferedReader reader, StringBuilder builder, AssetManager assetManager) throws IOException { private void buildSourcesRec(BufferedReader reader, StringBuilder builder, AssetManager assetManager) throws IOException {
String ln; String ln;
while ((ln = reader.readLine()) != null) { while ((ln = reader.readLine()) != null) {
@ -319,11 +340,11 @@ public abstract class Context extends AbstractOpenCLObject {
ln = ln.substring(1); ln = ln.substring(1);
} }
if (ln.endsWith("\"")) { if (ln.endsWith("\"")) {
ln = ln.substring(0, ln.length()-1); ln = ln.substring(0, ln.length() - 1);
} }
AssetInfo info = assetManager.locateAsset(new AssetKey<String>(ln)); AssetInfo info = assetManager.locateAsset(new AssetKey<String>(ln));
if (info == null) { if (info == null) {
throw new AssetNotFoundException("Unable to load source file \""+ln+"\""); throw new AssetNotFoundException("Unable to load source file \"" + ln + "\"");
} }
try (BufferedReader r = new BufferedReader(new InputStreamReader(info.openStream()))) { try (BufferedReader r = new BufferedReader(new InputStreamReader(info.openStream()))) {
builder.append("//-- begin import ").append(ln).append(" --\n"); builder.append("//-- begin import ").append(ln).append(" --\n");
@ -335,10 +356,10 @@ public abstract class Context extends AbstractOpenCLObject {
} }
} }
} }
/** /**
* Creates a program object from the provided source code and files. * Creates a program object from the provided source code and files.
* The source code is made up from the specified include string first, * The source code is made up from the specified include string first,
* then all files specified by the resource array (array of asset paths) * then all files specified by the resource array (array of asset paths)
* are loaded by the provided asset manager and appended to the source code. * are loaded by the provided asset manager and appended to the source code.
* <p> * <p>
@ -348,10 +369,10 @@ public abstract class Context extends AbstractOpenCLObject {
* <li>Some common OpenCL files used as libraries (Convention: file names end with {@code .clh}</li> * <li>Some common OpenCL files used as libraries (Convention: file names end with {@code .clh}</li>
* <li>One main OpenCL file containing the actual kernels (Convention: file name ends with {@code .cl})</li> * <li>One main OpenCL file containing the actual kernels (Convention: file name ends with {@code .cl})</li>
* </ul> * </ul>
* *
* After the files were combined, additional include statements are resolved * After the files were combined, additional include statements are resolved
* by {@link #createProgramFromSourceCodeWithDependencies(java.lang.String, com.jme3.asset.AssetManager) }. * by {@link #createProgramFromSourceCodeWithDependencies(java.lang.String, com.jme3.asset.AssetManager) }.
* *
* @param assetManager the asset manager used to load the files * @param assetManager the asset manager used to load the files
* @param include an additional include string * @param include an additional include string
* @param resources an array of asset paths pointing to OpenCL source files * @param resources an array of asset paths pointing to OpenCL source files
@ -364,7 +385,7 @@ public abstract class Context extends AbstractOpenCLObject {
/** /**
* Creates a program object from the provided source code and files. * Creates a program object from the provided source code and files.
* The source code is made up from the specified include string first, * The source code is made up from the specified include string first,
* then all files specified by the resource array (array of asset paths) * then all files specified by the resource array (array of asset paths)
* are loaded by the provided asset manager and appended to the source code. * are loaded by the provided asset manager and appended to the source code.
* <p> * <p>
@ -374,10 +395,10 @@ public abstract class Context extends AbstractOpenCLObject {
* <li>Some common OpenCL files used as libraries (Convention: file names end with {@code .clh}</li> * <li>Some common OpenCL files used as libraries (Convention: file names end with {@code .clh}</li>
* <li>One main OpenCL file containing the actual kernels (Convention: file name ends with {@code .cl})</li> * <li>One main OpenCL file containing the actual kernels (Convention: file name ends with {@code .cl})</li>
* </ul> * </ul>
* *
* After the files were combined, additional include statements are resolved * After the files were combined, additional include statements are resolved
* by {@link #createProgramFromSourceCodeWithDependencies(java.lang.String, com.jme3.asset.AssetManager) }. * by {@link #createProgramFromSourceCodeWithDependencies(java.lang.String, com.jme3.asset.AssetManager) }.
* *
* @param assetManager the asset manager used to load the files * @param assetManager the asset manager used to load the files
* @param include an additional include string * @param include an additional include string
* @param resources an array of asset paths pointing to OpenCL source files * @param resources an array of asset paths pointing to OpenCL source files
@ -390,7 +411,7 @@ public abstract class Context extends AbstractOpenCLObject {
for (String res : resources) { for (String res : resources) {
AssetInfo info = assetManager.locateAsset(new AssetKey<String>(res)); AssetInfo info = assetManager.locateAsset(new AssetKey<String>(res));
if (info == null) { if (info == null) {
throw new AssetNotFoundException("Unable to load source file \""+res+"\""); throw new AssetNotFoundException("Unable to load source file \"" + res + "\"");
} }
try (BufferedReader reader = new BufferedReader(new InputStreamReader(info.openStream()))) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(info.openStream()))) {
while (true) { while (true) {
@ -401,7 +422,7 @@ public abstract class Context extends AbstractOpenCLObject {
str.append(line).append('\n'); str.append(line).append('\n');
} }
} catch (IOException ex) { } catch (IOException ex) {
LOG.log(Level.WARNING, "unable to load source file '"+res+"'", ex); LOG.log(Level.WARNING, "unable to load source file '" + res + "'", ex);
} }
} }
return createProgramFromSourceCodeWithDependencies(str.toString(), assetManager); return createProgramFromSourceCodeWithDependencies(str.toString(), assetManager);
@ -410,6 +431,7 @@ public abstract class Context extends AbstractOpenCLObject {
/** /**
* Alternative version of {@link #createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.lang.String...) } * Alternative version of {@link #createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.lang.String...) }
* with an empty include string * with an empty include string
*
* @throws AssetNotFoundException if a file could not be loaded * @throws AssetNotFoundException if a file could not be loaded
*/ */
public Program createProgramFromSourceFiles(AssetManager assetManager, String... resources) { public Program createProgramFromSourceFiles(AssetManager assetManager, String... resources) {
@ -419,12 +441,13 @@ public abstract class Context extends AbstractOpenCLObject {
/** /**
* Alternative version of {@link #createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.util.List) } * Alternative version of {@link #createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.util.List) }
* with an empty include string * with an empty include string
*
* @throws AssetNotFoundException if a file could not be loaded * @throws AssetNotFoundException if a file could not be loaded
*/ */
public Program createProgramFromSourceFiles(AssetManager assetManager, List<String> resources) { public Program createProgramFromSourceFiles(AssetManager assetManager, List<String> resources) {
return createProgramFromSourceFilesWithInclude(assetManager, "", resources); return createProgramFromSourceFilesWithInclude(assetManager, "", resources);
} }
/** /**
* Creates a program from the specified binaries. * Creates a program from the specified binaries.
* The binaries are created by {@link Program#getBinary(com.jme3.opencl.Device) }. * The binaries are created by {@link Program#getBinary(com.jme3.opencl.Device) }.
@ -432,20 +455,19 @@ public abstract class Context extends AbstractOpenCLObject {
* {@link Program#build(java.lang.String, com.jme3.opencl.Device...) }. * {@link Program#build(java.lang.String, com.jme3.opencl.Device...) }.
* <b>Important:</b>The device passed to {@code Program.getBinary(..)}, * <b>Important:</b>The device passed to {@code Program.getBinary(..)},
* this method and {@code Program#build(..)} must be the same. * this method and {@code Program#build(..)} must be the same.
* *
* The binaries are used to build a program cache across multiple launches * The binaries are used to build a program cache across multiple launches
* of the application. The programs build much faster from binaries than * of the application. The programs build much faster from binaries than
* from sources. * from sources.
* *
* @param binaries the binaries * @param binaries the binaries
* @param device the device to use * @param device the device to use
* @return the new program * @return the new program
*/ */
public abstract Program createProgramFromBinary(ByteBuffer binaries, Device device); public abstract Program createProgramFromBinary(ByteBuffer binaries, Device device);
@Override @Override
public String toString() { public String toString() {
return "Context (" + getDevices() + ')'; return "Context (" + getDevices() + ')';
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2019 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -41,185 +41,217 @@ import java.util.Collection;
* queue ({@link Context#createQueue(com.jme3.opencl.Device) }). * queue ({@link Context#createQueue(com.jme3.opencl.Device) }).
* <p> * <p>
* This class is used to query the capabilities of the underlying device. * This class is used to query the capabilities of the underlying device.
* *
* @author shaman * @author shaman
*/ */
public interface Device { public interface Device {
/** /**
* @return the platform associated with this device * @return the platform associated with this device
*/ */
Platform getPlatform(); Platform getPlatform();
/** /**
* The device type * The device type
*/ */
public static enum DeviceType { public static enum DeviceType {
DEFAULT, DEFAULT,
CPU, CPU,
GPU, GPU,
ACCELEARTOR, ACCELEARTOR,
ALL ALL
} }
/** /**
* @return queries the device type * @return queries the device type
*/ */
DeviceType getDeviceType(); DeviceType getDeviceType();
/** /**
* @return the vendor id * @return the vendor id
*/ */
int getVendorId(); int getVendorId();
/** /**
* checks if this device is available at all, must always be tested * checks if this device is available at all, must always be tested
*
* @return checks if this device is available at all, must always be tested * @return checks if this device is available at all, must always be tested
*/ */
boolean isAvailable(); boolean isAvailable();
/** /**
* @return if this device has a compiler for kernel code * @return if this device has a compiler for kernel code
*/ */
boolean hasCompiler(); boolean hasCompiler();
/** /**
* @return supports double precision floats (64 bit) * @return supports double precision floats (64 bit)
*/ */
boolean hasDouble(); boolean hasDouble();
/** /**
* @return supports half precision floats (16 bit) * @return supports half precision floats (16 bit)
*/ */
boolean hasHalfFloat(); boolean hasHalfFloat();
/** /**
* @return supports error correction for every access to global or constant memory * @return supports error correction for every access to global or constant memory
*/ */
boolean hasErrorCorrectingMemory(); boolean hasErrorCorrectingMemory();
/** /**
* @return supports unified virtual memory (OpenCL 2.0) * @return supports unified virtual memory (OpenCL 2.0)
*/ */
boolean hasUnifiedMemory(); boolean hasUnifiedMemory();
/** /**
* @return supports images * @return supports images
*/ */
boolean hasImageSupport(); boolean hasImageSupport();
/** /**
* @return supports writes to 3d images (this is an extension) * @return supports writes to 3d images (this is an extension)
*/ */
boolean hasWritableImage3D(); boolean hasWritableImage3D();
/** /**
* @return supports sharing with OpenGL * @return supports sharing with OpenGL
*/ */
boolean hasOpenGLInterop(); boolean hasOpenGLInterop();
/** /**
* Explictly tests for the availability of the specified extension * Explictly tests for the availability of the specified extension
*
* @param extension the name of the extension * @param extension the name of the extension
* @return {@code true} iff this extension is supported * @return {@code true} iff this extension is supported
*/ */
boolean hasExtension(String extension); boolean hasExtension(String extension);
/** /**
* Lists all available extensions * Lists all available extensions
*
* @return all available extensions * @return all available extensions
*/ */
Collection<? extends String> getExtensions(); Collection<? extends String> getExtensions();
/** /**
* Returns the number of parallel compute units on * Returns the number of parallel compute units on
* the OpenCL device. A work-group * the OpenCL device. A work-group
* executes on a single compute unit. The * executes on a single compute unit. The
* minimum value is 1. * minimum value is 1.
* @return the number of parallel compute units * @return the number of parallel compute units
* @see #getMaximumWorkItemDimensions() * @see #getMaximumWorkItemDimensions()
* @see #getMaximumWorkItemSizes() * @see #getMaximumWorkItemSizes()
*/ */
int getComputeUnits(); int getComputeUnits();
/** /**
* @return maximum clock frequency of the device in MHz * @return maximum clock frequency of the device in MHz
*/ */
int getClockFrequency(); int getClockFrequency();
/** /**
* Returns the default compute device address space * Returns the default compute device address space
* size specified as an unsigned integer value * size specified as an unsigned integer value
* in bits. Currently supported values are 32 * in bits. Currently supported values are 32
* or 64 bits. * or 64 bits.
*
* @return the size of an address * @return the size of an address
*/ */
int getAddressBits(); int getAddressBits();
/** /**
* @return {@code true} if this device is little endian * @return {@code true} if this device is little endian
*/ */
boolean isLittleEndian(); boolean isLittleEndian();
/** /**
* The maximum dimension that specify the local and global work item ids. * The maximum dimension that specify the local and global work item ids.
* You can always assume to be this at least 3. * You can always assume to be this at least 3.
* Therefore, the ids are always three integers x,y,z. * Therefore, the ids are always three integers x,y,z.
*
* @return the maximum dimension of work item ids * @return the maximum dimension of work item ids
*/ */
long getMaximumWorkItemDimensions(); long getMaximumWorkItemDimensions();
/** /**
* Maximum number of work-items that can be specified in each dimension of the * Maximum number of work-items that can be specified in each dimension of the
* work-group to {@link Kernel#Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)}. * work-group to {@link Kernel#Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)}.
* The array has a length of at least 3. * The array has a length of at least 3.
*
* @return the maximum size of the work group in each dimension * @return the maximum size of the work group in each dimension
*/ */
long[] getMaximumWorkItemSizes(); long[] getMaximumWorkItemSizes();
/** /**
* Maximum number of work-items in a * Maximum number of work-items in a
* work-group executing a kernel on a single * work-group executing a kernel on a single
* compute unit, using the data parallel * compute unit, using the data parallel
* execution model. * execution model.
*
* @return maximum number of work-items in a work-group * @return maximum number of work-items in a work-group
*/ */
long getMaxiumWorkItemsPerGroup(); long getMaxiumWorkItemsPerGroup();
/** /**
* @return the maximum number of samples that can be used in a kernel * @return the maximum number of samples that can be used in a kernel
*/ */
int getMaximumSamplers(); int getMaximumSamplers();
/** /**
* @return the maximum number of images that can be used for reading in a kernel * @return the maximum number of images that can be used for reading in a kernel
*/ */
int getMaximumReadImages(); int getMaximumReadImages();
/** /**
* @return the maximum number of images that can be used for writing in a kernel * @return the maximum number of images that can be used for writing in a kernel
*/ */
int getMaximumWriteImages(); int getMaximumWriteImages();
/** /**
* Queries the maximal size of a 2D image * Queries the maximal size of a 2D image
*
* @return an array of length 2 with the maximal size of a 2D image * @return an array of length 2 with the maximal size of a 2D image
*/ */
long[] getMaximumImage2DSize(); long[] getMaximumImage2DSize();
/** /**
* Queries the maximal size of a 3D image * Queries the maximal size of a 3D image
*
* @return an array of length 3 with the maximal size of a 3D image * @return an array of length 3 with the maximal size of a 3D image
*/ */
long[] getMaximumImage3DSize(); long[] getMaximumImage3DSize();
/** /**
* @return the maximal size of a memory object (buffer and image) in bytes * @return the maximal size of a memory object (buffer and image) in bytes
*/ */
long getMaximumAllocationSize(); long getMaximumAllocationSize();
/** /**
* @return the total available global memory in bytes * @return the total available global memory in bytes
*/ */
long getGlobalMemorySize(); long getGlobalMemorySize();
/** /**
* @return the total available local memory in bytes * @return the total available local memory in bytes
*/ */
long getLocalMemorySize(); long getLocalMemorySize();
/** /**
* Returns the maximal size of a constant buffer. * Returns the maximal size of a constant buffer.
* <br> * <br>
* Constant buffers are normal buffer objects, but passed to the kernel * Constant buffers are normal buffer objects, but passed to the kernel
* with the special declaration {@code __constant BUFFER_TYPE* BUFFER_NAME}. * with the special declaration {@code __constant BUFFER_TYPE* BUFFER_NAME}.
* Because they have a special caching, their size is usually very limited. * Because they have a special caching, their size is usually very limited.
* *
* @return the maximal size of a constant buffer * @return the maximal size of a constant buffer
*/ */
long getMaximumConstantBufferSize(); long getMaximumConstantBufferSize();
/** /**
* @return the maximal number of constant buffer arguments in a kernel call * @return the maximal number of constant buffer arguments in a kernel call
*/ */
int getMaximumConstantArguments(); int getMaximumConstantArguments();
//TODO: cache, prefered sizes properties //TODO: cache, prefered sizes properties
/** /**
* OpenCL profile string. Returns the profile name supported by the device. * OpenCL profile string. Returns the profile name supported by the device.
* The profile name returned can be one of the following strings:<br> * The profile name returned can be one of the following strings:<br>
@ -230,7 +262,8 @@ public interface Device {
* *
* @return the profile string * @return the profile string
*/ */
String getProfile(); String getProfile();
/** /**
* OpenCL version string. Returns the OpenCL version supported by the * OpenCL version string. Returns the OpenCL version supported by the
* device. This version string has the following format: OpenCL space * device. This version string has the following format: OpenCL space
@ -240,20 +273,24 @@ public interface Device {
* *
* @return the version string * @return the version string
*/ */
String getVersion(); String getVersion();
/** /**
* Extracts the major version from the version string * Extracts the major version from the version string
*
* @return the major version * @return the major version
* @see #getVersion() * @see #getVersion()
*/ */
int getVersionMajor(); int getVersionMajor();
/** /**
* Extracts the minor version from the version string * Extracts the minor version from the version string
*
* @return the minor version * @return the minor version
* @see #getVersion() } * @see #getVersion() }
*/ */
int getVersionMinor(); int getVersionMinor();
/** /**
* OpenCL C version string. Returns the highest OpenCL C version supported * OpenCL C version string. Returns the highest OpenCL C version supported
* by the compiler for this device that is not of type * by the compiler for this device that is not of type
@ -268,44 +305,53 @@ public interface Device {
* *
* @return the compiler version * @return the compiler version
*/ */
String getCompilerVersion(); String getCompilerVersion();
/** /**
* Extracts the major version from the compiler version * Extracts the major version from the compiler version
*
* @return the major compiler version * @return the major compiler version
* @see #getCompilerVersion() * @see #getCompilerVersion()
*/ */
int getCompilerVersionMajor(); int getCompilerVersionMajor();
/** /**
* Extracts the minor version from the compiler version * Extracts the minor version from the compiler version
*
* @return the minor compiler version * @return the minor compiler version
* @see #getCompilerVersion() * @see #getCompilerVersion()
*/ */
int getCompilerVersionMinor(); int getCompilerVersionMinor();
/**
/**
* @return the OpenCL software driver version string in the form * @return the OpenCL software driver version string in the form
* major_number.minor_number * major_number.minor_number
*/ */
String getDriverVersion(); String getDriverVersion();
/** /**
* Extracts the major version from the driver version * Extracts the major version from the driver version
*
* @return the major driver version * @return the major driver version
* @see #getDriverVersion() * @see #getDriverVersion()
*/ */
int getDriverVersionMajor(); int getDriverVersionMajor();
/** /**
* Extracts the minor version from the driver version * Extracts the minor version from the driver version
*
* @return the minor driver version * @return the minor driver version
* @see #getDriverVersion() * @see #getDriverVersion()
*/ */
int getDriverVersionMinor(); int getDriverVersionMinor();
/** /**
* @return the device name * @return the device name
*/ */
String getName(); String getName();
/** /**
* @return the vendor * @return the vendor
*/ */
String getVendor(); String getVendor();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2016 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,6 +36,7 @@ package com.jme3.opencl;
* Events are returned from kernel launches and all asynchronous operations. * Events are returned from kernel launches and all asynchronous operations.
* They allow to test if the action has completed and to block until the operation * They allow to test if the action has completed and to block until the operation
* is done. * is done.
*
* @author shaman * @author shaman
*/ */
public abstract class Event extends AbstractOpenCLObject { public abstract class Event extends AbstractOpenCLObject {
@ -44,22 +45,23 @@ public abstract class Event extends AbstractOpenCLObject {
super(releaser); super(releaser);
} }
@Override @Override
public Event register() { public Event register() {
super.register(); super.register();
return this; return this;
} }
/** /**
* Waits until the action has finished (blocking). * Waits until the action has finished (blocking).
* This automatically releases the event. * This automatically releases the event.
*/ */
public abstract 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. * If the action is completed, the event is released.
*
* @return {@code true} if the action is completed * @return {@code true} if the action is completed
*/ */
public abstract boolean isCompleted(); public abstract boolean isCompleted();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2019 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -41,16 +41,16 @@ import java.util.Objects;
* An image object is similar to a {@link Buffer}, but with a specific element * An image object is similar to a {@link Buffer}, but with a specific element
* format and buffer structure. * format and buffer structure.
* <br> * <br>
* The image is specified by the {@link ImageDescriptor}, specifying * The image is specified by the {@link ImageDescriptor}, specifying
* the extend and dimension of the image, and {@link ImageFormat}, specifying * the extend and dimension of the image, and {@link ImageFormat}, specifying
* the type of each pixel. * the type of each pixel.
* <br> * <br>
* An image is created from scratch using * An image is created from scratch using
* {@link Context#createImage(com.jme3.opencl.MemoryAccess, com.jme3.opencl.Image.ImageFormat, com.jme3.opencl.Image.ImageDescriptor) } * {@link Context#createImage(com.jme3.opencl.MemoryAccess, com.jme3.opencl.Image.ImageFormat, com.jme3.opencl.Image.ImageDescriptor) }
* or from OpenGL by * or from OpenGL by
* {@link Context#bindImage(com.jme3.texture.Image, com.jme3.texture.Texture.Type, int, com.jme3.opencl.MemoryAccess) } * {@link Context#bindImage(com.jme3.texture.Image, com.jme3.texture.Texture.Type, int, com.jme3.opencl.MemoryAccess) }
* (and alternative versions). * (and alternative versions).
* *
* <p> * <p>
* Most methods take long arrays as input: {@code long[] origin} and {@code long[] region}. * Most methods take long arrays as input: {@code long[] origin} and {@code long[] region}.
* Both are arrays of length 3. * Both are arrays of length 3.
@ -75,7 +75,6 @@ import java.util.Objects;
* @author shaman * @author shaman
*/ */
public abstract class Image extends AbstractOpenCLObject { public abstract class Image extends AbstractOpenCLObject {
/** /**
* {@code ImageChannelType} describes the size of the channel data type. * {@code ImageChannelType} describes the size of the channel data type.
*/ */
@ -96,10 +95,10 @@ public abstract class Image extends AbstractOpenCLObject {
HALF_FLOAT, HALF_FLOAT,
FLOAT FLOAT
} }
/** /**
* {@code ImageChannelOrder} specifies the number of channels and the channel layout i.e. the * {@code ImageChannelOrder} specifies the number of channels and the channel layout i.e. the
memory layout in which channels are stored in the image. * memory layout in which channels are stored in the image.
*/ */
public static enum ImageChannelOrder { public static enum ImageChannelOrder {
R, Rx, A, R, Rx, A,
@ -112,7 +111,7 @@ memory layout in which channels are stored in the image.
} }
/** /**
* Describes the image format, consisting of * Describes the image format, consisting of
* {@link ImageChannelOrder} and {@link ImageChannelType}. * {@link ImageChannelOrder} and {@link ImageChannelType}.
*/ */
public static class ImageFormat { //Struct public static class ImageFormat { //Struct
@ -157,7 +156,6 @@ memory layout in which channels are stored in the image.
} }
return true; return true;
} }
} }
/** /**
@ -193,13 +191,14 @@ memory layout in which channels are stored in the image.
/* /*
public int numMipLevels; //They must always be set to zero public int numMipLevels; //They must always be set to zero
public int numSamples; public int numSamples;
*/ */
public ImageDescriptor() { public ImageDescriptor() {
} }
/** /**
* Used to specify an image with the provided ByteBuffer as soruce * Used to specify an image with the provided ByteBuffer as soruce
*
* @param type the image type * @param type the image type
* @param width the width * @param width the width
* @param height the height, unused for image types {@code ImageType.IMAGE_1D*} * @param height the height, unused for image types {@code ImageType.IMAGE_1D*}
@ -219,9 +218,11 @@ memory layout in which channels are stored in the image.
this.slicePitch = slicePitch; this.slicePitch = slicePitch;
this.hostPtr = hostPtr; this.hostPtr = hostPtr;
} }
/** /**
* Specifies an image without a host buffer, a new chunk of memory * Specifies an image without a host buffer, a new chunk of memory
* will be allocated. * will be allocated.
*
* @param type the image type * @param type the image type
* @param width the width * @param width the width
* @param height the height, unused for image types {@code ImageType.IMAGE_1D*} * @param height the height, unused for image types {@code ImageType.IMAGE_1D*}
@ -243,60 +244,68 @@ memory layout in which channels are stored in the image.
public String toString() { public String toString() {
return "ImageDescriptor{" + "type=" + type + ", width=" + width + ", height=" + height + ", depth=" + depth + ", arraySize=" + arraySize + ", rowPitch=" + rowPitch + ", slicePitch=" + slicePitch + '}'; return "ImageDescriptor{" + "type=" + type + ", width=" + width + ", height=" + height + ", depth=" + depth + ", arraySize=" + arraySize + ", rowPitch=" + rowPitch + ", slicePitch=" + slicePitch + '}';
} }
} }
protected Image(ObjectReleaser releaser) { protected Image(ObjectReleaser releaser) {
super(releaser); super(releaser);
} }
@Override @Override
public Image register() { public Image register() {
super.register(); super.register();
return this; return this;
} }
/** /**
* @return the width of the image * @return the width of the image
*/ */
public abstract long getWidth(); public abstract long getWidth();
/** /**
* @return the height of the image * @return the height of the image
*/ */
public abstract long getHeight(); public abstract long getHeight();
/** /**
* @return the depth of the image * @return the depth of the image
*/ */
public abstract long getDepth(); public abstract long getDepth();
/** /**
* @return the row pitch when the image was created from a host buffer * @return the row pitch when the image was created from a host buffer
*/ */
public abstract long getRowPitch(); public abstract long getRowPitch();
/** /**
* @return the slice pitch when the image was created from a host buffer * @return the slice pitch when the image was created from a host buffer
*/ */
public abstract long getSlicePitch(); public abstract long getSlicePitch();
/** /**
* @return the number of elements in the image array * @return the number of elements in the image array
* @see ImageType#IMAGE_1D_ARRAY * @see ImageType#IMAGE_1D_ARRAY
* @see ImageType#IMAGE_2D_ARRAY * @see ImageType#IMAGE_2D_ARRAY
*/ */
public abstract long getArraySize(); public abstract long getArraySize();
/** /**
* @return the image format * @return the image format
*/ */
public abstract ImageFormat getImageFormat(); public abstract ImageFormat getImageFormat();
/** /**
* @return the image type * @return the image type
*/ */
public abstract ImageType getImageType(); public abstract ImageType getImageType();
/** /**
* @return the number of bytes per pixel * @return the number of bytes per pixel
*/ */
public abstract int getElementSize(); public abstract int getElementSize();
/** /**
* Performs a blocking read of the image into the specified byte buffer. * Performs a blocking read of the image into the specified byte buffer.
*
* @param queue the command queue * @param queue the command queue
* @param dest the target byte buffer * @param dest the target byte buffer
* @param origin the image origin location, see class description for the format * @param origin the image origin location, see class description for the format
@ -307,8 +316,10 @@ 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} * If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/ */
public abstract 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. * Performs an async/non-blocking read of the image into the specified byte buffer.
*
* @param queue the command queue * @param queue the command queue
* @param dest the target byte buffer * @param dest the target byte buffer
* @param origin the image origin location, see class description for the format * @param origin the image origin location, see class description for the format
@ -320,9 +331,10 @@ memory layout in which channels are stored in the image.
* @return the event object indicating the status of the operation * @return the event object indicating the status of the operation
*/ */
public abstract 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. * Performs a blocking write from the specified byte buffer into the image.
*
* @param queue the command queue * @param queue the command queue
* @param src the source buffer * @param src the source buffer
* @param origin the image origin location, see class description for the format * @param origin the image origin location, see class description for the format
@ -333,8 +345,10 @@ 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} * If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/ */
public abstract 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. * Performs an async/non-blocking write from the specified byte buffer into the image.
*
* @param queue the command queue * @param queue the command queue
* @param src the source buffer * @param src the source buffer
* @param origin the image origin location, see class description for the format * @param origin the image origin location, see class description for the format
@ -346,10 +360,11 @@ memory layout in which channels are stored in the image.
* @return the event object indicating the status of the operation * @return the event object indicating the status of the operation
*/ */
public abstract 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. * Performs a blocking copy operation from one image to another.
* <b>Important:</b> Both images must have the same format! * <b>Important:</b> Both images must have the same format!
*
* @param queue the command queue * @param queue the command queue
* @param dest the target image * @param dest the target image
* @param srcOrigin the source image origin, see class description for the format * @param srcOrigin the source image origin, see class description for the format
@ -357,9 +372,11 @@ memory layout in which channels are stored in the image.
* @param region the copied region, see class description for the format * @param region the copied region, see class description for the format
*/ */
public abstract 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. * Performs an async/non-blocking copy operation from one image to another.
* <b>Important:</b> Both images must have the same format! * <b>Important:</b> Both images must have the same format!
*
* @param queue the command queue * @param queue the command queue
* @param dest the target image * @param dest the target image
* @param srcOrigin the source image origin, see class description for the format * @param srcOrigin the source image origin, see class description for the format
@ -368,20 +385,22 @@ memory layout in which channels are stored in the image.
* @return the event object indicating the status of the operation * @return the event object indicating the status of the operation
*/ */
public abstract 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. * Maps the image into host memory.
* The returned structure contains the mapped byte buffer and row and slice pitch. * The returned structure contains the mapped byte buffer and row and slice pitch.
* The event object is set to {@code null}, it is needed for the asnyc * The event object is set to {@code null}, it is needed for the asnyc
* version {@link #mapAsync(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess) }. * version {@link #mapAsync(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess) }.
*
* @param queue the command queue * @param queue the command queue
* @param origin the image origin, see class description for the format * @param origin the image origin, see class description for the format
* @param region the mapped region, see class description for the format * @param region the mapped region, see class description for the format
* @param access the allowed memory access to the mapped memory * @param access the allowed memory access to the mapped memory
* @return a structure describing the mapped memory * @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping) * @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/ */
public abstract 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) }. * 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. * The returned structure contains the mapped byte buffer and row and slice pitch.
@ -391,16 +410,18 @@ memory layout in which channels are stored in the image.
* @param region the mapped region, see class description for the format * @param region the mapped region, see class description for the format
* @param access the allowed memory access to the mapped memory * @param access the allowed memory access to the mapped memory
* @return a structure describing the mapped memory * @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping) * @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/ */
public abstract 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 * Unmaps the mapped memory
*
* @param queue the command queue * @param queue the command queue
* @param mapping the mapped memory * @param mapping the mapped memory
*/ */
public abstract void unmap(CommandQueue queue, ImageMapping mapping); public abstract void unmap(CommandQueue queue, ImageMapping mapping);
/** /**
* Describes a mapped region of the image * Describes a mapped region of the image
*/ */
@ -421,7 +442,8 @@ memory layout in which channels are stored in the image.
public final long slicePitch; public final long slicePitch;
/** /**
* The event object used to detect when the memory is available. * The event object used to detect when the memory is available.
* @see #mapAsync(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess) *
* @see #mapAsync(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess)
*/ */
public final Event event; public final Event event;
@ -431,19 +453,20 @@ memory layout in which channels are stored in the image.
this.slicePitch = slicePitch; this.slicePitch = slicePitch;
this.event = event; this.event = event;
} }
public ImageMapping(ByteBuffer buffer, long rowPitch, long slicePitch) { public ImageMapping(ByteBuffer buffer, long rowPitch, long slicePitch) {
this.buffer = buffer; this.buffer = buffer;
this.rowPitch = rowPitch; this.rowPitch = rowPitch;
this.slicePitch = slicePitch; this.slicePitch = slicePitch;
this.event = null; this.event = null;
} }
} }
/** /**
* Fills the image with the specified color. * Fills the image with the specified color.
* Does <b>only</b> work if the image channel is {@link ImageChannelType#FLOAT} * Does <b>only</b> work if the image channel is {@link ImageChannelType#FLOAT}
* or {@link ImageChannelType#HALF_FLOAT}. * or {@link ImageChannelType#HALF_FLOAT}.
*
* @param queue the command queue * @param queue the command queue
* @param origin the image origin, see class description for the format * @param origin the image origin, see class description for the format
* @param region the size of the region, see class description for the format * @param region the size of the region, see class description for the format
@ -455,6 +478,7 @@ memory layout in which channels are stored in the image.
* Fills the image with the specified color given as four integer variables. * 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} * Does <b>not</b> work if the image channel is {@link ImageChannelType#FLOAT}
* or {@link ImageChannelType#HALF_FLOAT}. * or {@link ImageChannelType#HALF_FLOAT}.
*
* @param queue the command queue * @param queue the command queue
* @param origin the image origin, see class description for the format * @param origin the image origin, see class description for the format
* @param region the size of the region, see class description for the format * @param region the size of the region, see class description for the format
@ -462,11 +486,12 @@ memory layout in which channels are stored in the image.
* @return an event object to detect for the completion * @return an event object to detect for the completion
*/ */
public abstract 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. * Copies this image into the specified buffer, no format conversion is done.
* This is the dual function to * This is the dual function to
* {@link Buffer#copyToImageAsync(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image, long, long[], long[]) }. * {@link Buffer#copyToImageAsync(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image, long, long[], long[]) }.
*
* @param queue the command queue * @param queue the command queue
* @param dest the target buffer * @param dest the target buffer
* @param srcOrigin the image origin, see class description for the format * @param srcOrigin the image origin, see class description for the format
@ -475,7 +500,7 @@ memory layout in which channels are stored in the image.
* @return the event object to detect the completion of the operation * @return the event object to detect the completion of the operation
*/ */
public abstract 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 * Aquires this image object for using. Only call this method if this image
* represents a shared object from OpenGL, created with e.g. * represents a shared object from OpenGL, created with e.g.
@ -485,11 +510,12 @@ memory layout in which channels are stored in the image.
* done, the image must be released by calling * done, the image must be released by calling
* {@link #releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the image/texture/renderbuffer again. * so that OpenGL can use the image/texture/renderbuffer again.
*
* @param queue the command queue * @param queue the command queue
* @return the event object * @return the event object
*/ */
public abstract Event acquireImageForSharingAsync(CommandQueue queue); public abstract Event acquireImageForSharingAsync(CommandQueue queue);
/** /**
* Aquires this image object for using. Only call this method if this image * Aquires this image object for using. Only call this method if this image
* represents a shared object from OpenGL, created with e.g. * represents a shared object from OpenGL, created with e.g.
@ -499,37 +525,39 @@ memory layout in which channels are stored in the image.
* done, the image must be released by calling * done, the image must be released by calling
* {@link #releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the image/texture/renderbuffer again. * so that OpenGL can use the image/texture/renderbuffer again.
* *
* The generated event object is directly released. * The generated event object is directly released.
* This brings a performance improvement when the resource is e.g. directly * This brings a performance improvement when the resource is e.g. directly
* used by a kernel afterwards on the same queue (this implicitly waits for * used by a kernel afterwards on the same queue (this implicitly waits for
* this action). If you need the event, use * this action). If you need the event, use
* {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }. * {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }.
* *
* @param queue the command queue * @param queue the command queue
*/ */
public void acquireImageForSharingNoEvent(CommandQueue queue) { public void acquireImageForSharingNoEvent(CommandQueue queue) {
//Default implementation, overwrite for performance //Default implementation, overwrite for performance
acquireImageForSharingAsync(queue).release(); acquireImageForSharingAsync(queue).release();
} }
/** /**
* Releases a shared image object. * Releases a shared image object.
* Call this method after the image object was acquired by * Call this method after the image object was acquired by
* {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL. * to hand the control back to OpenGL.
*
* @param queue the command queue * @param queue the command queue
* @return the event object * @return the event object
*/ */
public abstract Event releaseImageForSharingAsync(CommandQueue queue); public abstract Event releaseImageForSharingAsync(CommandQueue queue);
/** /**
* Releases a shared image object. * Releases a shared image object.
* Call this method after the image object was acquired by * Call this method after the image object was acquired by
* {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) } * {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL. * to hand the control back to OpenGL.
* The generated event object is directly released, resulting in * The generated event object is directly released, resulting in
* performance improvements. * performance improvements.
*
* @param queue the command queue * @param queue the command queue
*/ */
public void releaseImageForSharingNoEvent(CommandQueue queue) { public void releaseImageForSharingNoEvent(CommandQueue queue) {
@ -537,25 +565,24 @@ memory layout in which channels are stored in the image.
releaseImageForSharingAsync(queue).release(); releaseImageForSharingAsync(queue).release();
} }
@Override @Override
public String toString() { public String toString() {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append("Image ("); str.append("Image (");
ImageType t = getImageType(); ImageType t = getImageType();
str.append(t); str.append(t);
str.append(", w=").append(getWidth()); str.append(", w=").append(getWidth());
if (t == ImageType.IMAGE_2D || t == ImageType.IMAGE_3D) { if (t == ImageType.IMAGE_2D || t == ImageType.IMAGE_3D) {
str.append(", h=").append(getHeight()); str.append(", h=").append(getHeight());
} }
if (t == ImageType.IMAGE_3D) { if (t == ImageType.IMAGE_3D) {
str.append(", d=").append(getDepth()); str.append(", d=").append(getDepth());
} }
if (t == ImageType.IMAGE_1D_ARRAY || t == ImageType.IMAGE_2D_ARRAY) { if (t == ImageType.IMAGE_1D_ARRAY || t == ImageType.IMAGE_2D_ARRAY) {
str.append(", arrays=").append(getArraySize()); str.append(", arrays=").append(getArraySize());
} }
str.append(", ").append(getImageFormat()); str.append(", ").append(getImageFormat());
str.append(')'); str.append(')');
return str.toString(); return str.toString();
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2018 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -40,7 +40,7 @@ import java.util.Arrays;
* Wrapper for an OpenCL kernel, a piece of executable code on the GPU. * Wrapper for an OpenCL kernel, a piece of executable code on the GPU.
* <p> * <p>
* Terminology:<br> * Terminology:<br>
* A Kernel is executed in parallel. In total number of parallel threads, * A Kernel is executed in parallel. In total number of parallel threads,
* called work items, are specified by the <i>global work size</i> (of type * called work items, are specified by the <i>global work size</i> (of type
* {@link WorkSize}. These threads are organized in a 1D, 2D or 3D grid * {@link WorkSize}. These threads are organized in a 1D, 2D or 3D grid
* (of coarse, this is only a logical view). Inside each kernel, * (of coarse, this is only a logical view). Inside each kernel,
@ -54,7 +54,7 @@ import java.util.Arrays;
* The maximal size of it can be queried by {@link Device#getMaxiumWorkItemsPerGroup() }. * The maximal size of it can be queried by {@link Device#getMaxiumWorkItemsPerGroup() }.
* Again, the threads inside the work group can be organized in a 1D, 2D or 3D * Again, the threads inside the work group can be organized in a 1D, 2D or 3D
* grid, but this is also just a logical view (specifying how the threads are * grid, but this is also just a logical view (specifying how the threads are
* indexed). * indexed).
* The work group is important for another concept: <i> shared memory</i> * The work group is important for another concept: <i> shared memory</i>
* Unlike the normal global or constant memory (passing a {@link Buffer} object * Unlike the normal global or constant memory (passing a {@link Buffer} object
* as argument), shared memory can't be set from outside. Shared memory is * as argument), shared memory can't be set from outside. Shared memory is
@ -64,22 +64,22 @@ import java.util.Arrays;
* {@link LocalMem} or {@link LocalMemPerElement} as argument.<br> * {@link LocalMem} or {@link LocalMemPerElement} as argument.<br>
* Due to heavy register usage or other reasons, a kernel might not be able * Due to heavy register usage or other reasons, a kernel might not be able
* to utilize a whole work group. Therefore, the actual number of threads * to utilize a whole work group. Therefore, the actual number of threads
* that can be executed in a work group can be queried by * that can be executed in a work group can be queried by
* {@link #getMaxWorkGroupSize(com.jme3.opencl.Device) }, which might differ from the * {@link #getMaxWorkGroupSize(com.jme3.opencl.Device) }, which might differ from the
* value returned from the Device. * value returned from the Device.
* *
* <p> * <p>
* There are two ways to launch a kernel:<br> * There are two ways to launch a kernel:<br>
* First, arguments and the work group sizes can be set in advance * First, arguments and the work group sizes can be set in advance
* ({@code setArg(index, ...)}, {@code setGlobalWorkSize(...)} and {@code setWorkGroupSize(...)}. * ({@code setArg(index, ...)}, {@code setGlobalWorkSize(...)} and {@code setWorkGroupSize(...)}.
* Then a kernel is launched by {@link #Run(com.jme3.opencl.CommandQueue) }.<br> * Then a kernel is launched by {@link #Run(com.jme3.opencl.CommandQueue) }.<br>
* Second, two convenient functions are provided that set the arguments * Second, two convenient functions are provided that set the arguments
* and work sizes in one call: * and work sizes in one call:
* {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) } * {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }
* and {@link #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }. * and {@link #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
* *
* @author shaman * @author shaman
* @see Program#createKernel(java.lang.String) * @see Program#createKernel(java.lang.String)
*/ */
public abstract class Kernel extends AbstractOpenCLObject { public abstract class Kernel extends AbstractOpenCLObject {
/** /**
@ -97,12 +97,12 @@ public abstract class Kernel extends AbstractOpenCLObject {
this.workGroupSize = new WorkSize(0); this.workGroupSize = new WorkSize(0);
} }
@Override @Override
public Kernel register() { public Kernel register() {
super.register(); super.register();
return this; return this;
} }
/** /**
* @return the name of the kernel as defined in the program source code * @return the name of the kernel as defined in the program source code
*/ */
@ -122,6 +122,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the global work size. * Sets the global work size.
*
* @param ws the work size to set * @param ws the work size to set
*/ */
public void setGlobalWorkSize(WorkSize ws) { public void setGlobalWorkSize(WorkSize ws) {
@ -130,6 +131,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the global work size to a 1D grid * Sets the global work size to a 1D grid
*
* @param size the size in 1D * @param size the size in 1D
*/ */
public void setGlobalWorkSize(int size) { public void setGlobalWorkSize(int size) {
@ -138,6 +140,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the global work size to be a 2D grid * Sets the global work size to be a 2D grid
*
* @param width the width * @param width the width
* @param height the height * @param height the height
*/ */
@ -147,6 +150,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the global work size to be a 3D grid * Sets the global work size to be a 3D grid
*
* @param width the width * @param width the width
* @param height the height * @param height the height
* @param depth the depth * @param depth the depth
@ -164,6 +168,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the work group size * Sets the work group size
*
* @param ws the work group size to set * @param ws the work group size to set
*/ */
public void setWorkGroupSize(WorkSize ws) { public void setWorkGroupSize(WorkSize ws) {
@ -172,6 +177,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the work group size to be a 1D grid * Sets the work group size to be a 1D grid
*
* @param size the size to set * @param size the size to set
*/ */
public void setWorkGroupSize(int size) { public void setWorkGroupSize(int size) {
@ -180,6 +186,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the work group size to be a 2D grid * Sets the work group size to be a 2D grid
*
* @param width the width * @param width the width
* @param height the height * @param height the height
*/ */
@ -189,6 +196,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the work group size to be a 3D grid * Sets the work group size to be a 3D grid
*
* @param width the width * @param width the width
* @param height the height * @param height the height
* @param depth the depth * @param depth the depth
@ -196,7 +204,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
public void setWorkGroupSdize(int width, int height, int depth) { public void setWorkGroupSdize(int width, int height, int depth) {
workGroupSize.set(3, width, height, depth); workGroupSize.set(3, width, height, depth);
} }
/** /**
* Tells the driver to figure out the work group size on their own. * Tells the driver to figure out the work group size on their own.
* Use this if you do not rely on specific work group layouts, i.e. * Use this if you do not rely on specific work group layouts, i.e.
@ -207,10 +215,11 @@ public abstract class Kernel extends AbstractOpenCLObject {
public void setWorkGroupSizeToNull() { public void setWorkGroupSizeToNull() {
workGroupSize.set(1, 0, 0, 0); workGroupSize.set(1, 0, 0, 0);
} }
/** /**
* Returns the maximal work group size when this kernel is executed on * Returns the maximal work group size when this kernel is executed on
* the specified device * the specified device
*
* @param device the device * @param device the device
* @return the maximal work group size * @return the maximal work group size
*/ */
@ -221,7 +230,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
public abstract void setArg(int index, LocalMem t); public abstract void setArg(int index, LocalMem t);
public abstract void setArg(int index, Buffer t); public abstract void setArg(int index, Buffer t);
public abstract void setArg(int index, Image i); public abstract void setArg(int index, Image i);
public abstract void setArg(int index, byte b); public abstract void setArg(int index, byte b);
@ -237,20 +246,20 @@ public abstract class Kernel extends AbstractOpenCLObject {
public abstract void setArg(int index, double d); public abstract void setArg(int index, double d);
public abstract void setArg(int index, Vector2f v); public abstract void setArg(int index, Vector2f v);
public abstract void setArg(int index, Vector4f v); public abstract void setArg(int index, Vector4f v);
public abstract void setArg(int index, Quaternion q); public abstract void setArg(int index, Quaternion q);
public abstract void setArg(int index, Matrix4f mat); public abstract void setArg(int index, Matrix4f mat);
public void setArg(int index, Matrix3f mat) { public void setArg(int index, Matrix3f mat) {
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
try { try {
Matrix4f m = vars.tempMat4; Matrix4f m = vars.tempMat4;
m.zero(); m.zero();
for (int i=0; i<3; ++i) { for (int i = 0; i < 3; ++i) {
for (int j=0; j<3; ++j) { for (int j = 0; j < 3; ++j) {
m.set(i, j, mat.get(i, j)); m.set(i, j, mat.get(i, j));
} }
} }
@ -259,13 +268,14 @@ public abstract class Kernel extends AbstractOpenCLObject {
vars.release(); vars.release();
} }
} }
/** /**
* Raw version to set an argument. * Raw version to set an argument.
* {@code size} bytes of the provided byte buffer are copied to the kernel * {@code size} bytes of the provided byte buffer are copied to the kernel
* argument. The size in bytes must match exactly the argument size * argument. The size in bytes must match exactly the argument size
* as defined in the kernel code. * as defined in the kernel code.
* Use this method to send custom structures to the kernel * Use this method to send custom structures to the kernel
*
* @param index the index of the argument * @param index the index of the argument
* @param buffer the raw buffer * @param buffer the raw buffer
* @param size the size in bytes * @param size the size in bytes
@ -279,6 +289,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
* long, float, double, Vector2f, Vector4f, Quaternion, Matrix3f, Matrix4f}. * long, float, double, Vector2f, Vector4f, Quaternion, Matrix3f, Matrix4f}.
* <br> * <br>
* Note: Matrix3f and Matrix4f will be mapped to a {@code float16} (row major). * Note: Matrix3f and Matrix4f will be mapped to a {@code float16} (row major).
*
* @param index the index of the argument, from 0 to {@link #getArgCount()}-1 * @param index the index of the argument, from 0 to {@link #getArgCount()}-1
* @param arg the argument * @param arg the argument
* @throws IllegalArgumentException if the argument type is not one of the listed ones * @throws IllegalArgumentException if the argument type is not one of the listed ones
@ -331,24 +342,26 @@ public abstract class Kernel extends AbstractOpenCLObject {
* If the returned event object is not needed and would otherwise be * If the returned event object is not needed and would otherwise be
* released immediately, {@link #RunNoEvent(com.jme3.opencl.CommandQueue) } * released immediately, {@link #RunNoEvent(com.jme3.opencl.CommandQueue) }
* might bring a better performance. * might bring a better performance.
*
* @param queue the command queue * @param queue the command queue
* @return an event object indicating when the kernel is finished * @return an event object indicating when the kernel is finished
* @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize) * @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize) * @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setArg(int, java.lang.Object) * @see #setArg(int, java.lang.Object)
*/ */
public abstract Event Run(CommandQueue queue); public abstract Event Run(CommandQueue queue);
/** /**
* Launches the kernel with the current global work size, work group size * Launches the kernel with the current global work size, work group size
* and arguments without returning an event object. * and arguments without returning an event object.
* The generated event is directly released. Therefore, the performance * The generated event is directly released. Therefore, the performance
* is better, but there is no way to detect when the kernel execution * is better, but there is no way to detect when the kernel execution
* has finished. For this purpose, use {@link #Run(com.jme3.opencl.CommandQueue) }. * has finished. For this purpose, use {@link #Run(com.jme3.opencl.CommandQueue) }.
*
* @param queue the command queue * @param queue the command queue
* @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize) * @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize) * @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setArg(int, java.lang.Object) * @see #setArg(int, java.lang.Object)
*/ */
public void RunNoEvent(CommandQueue queue) { public void RunNoEvent(CommandQueue queue) {
//Default implementation, overwrite to not allocate the event object //Default implementation, overwrite to not allocate the event object
@ -361,11 +374,12 @@ public abstract class Kernel extends AbstractOpenCLObject {
* size is automatically determined by the driver. * size is automatically determined by the driver.
* Each object in the argument array is sent to the kernel by * Each object in the argument array is sent to the kernel by
* {@link #setArg(int, java.lang.Object) }. * {@link #setArg(int, java.lang.Object) }.
*
* @param queue the command queue * @param queue the command queue
* @param globalWorkSize the global work size * @param globalWorkSize the global work size
* @param args the kernel arguments * @param args the kernel arguments
* @return an event object indicating when the kernel is finished * @return an event object indicating when the kernel is finished
* @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) * @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)
*/ */
public Event Run1(CommandQueue queue, WorkSize globalWorkSize, Object... args) { public Event Run1(CommandQueue queue, WorkSize globalWorkSize, Object... args) {
setGlobalWorkSize(globalWorkSize); setGlobalWorkSize(globalWorkSize);
@ -373,7 +387,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
setArgs(args); setArgs(args);
return Run(queue); return Run(queue);
} }
/** /**
* Sets the work sizes and arguments in one call and launches the kernel. * Sets the work sizes and arguments in one call and launches the kernel.
* The global work size is set to the specified size. The work group * The global work size is set to the specified size. The work group
@ -382,12 +396,13 @@ public abstract class Kernel extends AbstractOpenCLObject {
* {@link #setArg(int, java.lang.Object) }. * {@link #setArg(int, java.lang.Object) }.
* The generated event is directly released. Therefore, the performance * The generated event is directly released. Therefore, the performance
* is better, but there is no way to detect when the kernel execution * is better, but there is no way to detect when the kernel execution
* has finished. For this purpose, use * has finished. For this purpose, use
* {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }. * {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
*
* @param queue the command queue * @param queue the command queue
* @param globalWorkSize the global work size * @param globalWorkSize the global work size
* @param args the kernel arguments * @param args the kernel arguments
* @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) * @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)
*/ */
public void Run1NoEvent(CommandQueue queue, WorkSize globalWorkSize, Object... args) { public void Run1NoEvent(CommandQueue queue, WorkSize globalWorkSize, Object... args) {
setGlobalWorkSize(globalWorkSize); setGlobalWorkSize(globalWorkSize);
@ -398,6 +413,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Sets the work sizes and arguments in one call and launches the kernel. * Sets the work sizes and arguments in one call and launches the kernel.
*
* @param queue the command queue * @param queue the command queue
* @param globalWorkSize the global work size * @param globalWorkSize the global work size
* @param workGroupSize the work group size * @param workGroupSize the work group size
@ -416,8 +432,9 @@ public abstract class Kernel extends AbstractOpenCLObject {
* Sets the work sizes and arguments in one call and launches the kernel. * Sets the work sizes and arguments in one call and launches the kernel.
* The generated event is directly released. Therefore, the performance * The generated event is directly released. Therefore, the performance
* is better, but there is no way to detect when the kernel execution * is better, but there is no way to detect when the kernel execution
* has finished. For this purpose, use * has finished. For this purpose, use
* {@link #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }. * {@link #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
*
* @param queue the command queue * @param queue the command queue
* @param globalWorkSize the global work size * @param globalWorkSize the global work size
* @param workGroupSize the work group size * @param workGroupSize the work group size
@ -431,22 +448,22 @@ public abstract class Kernel extends AbstractOpenCLObject {
RunNoEvent(queue); RunNoEvent(queue);
} }
@Override @Override
public String toString() { public String toString() {
return "Kernel (" + getName() + ")"; return "Kernel (" + getName() + ")";
} }
/** /**
* A placeholder for kernel arguments representing local kernel memory. * A placeholder for kernel arguments representing local kernel memory. This
* This defines the size of available shared memory of a {@code __shared} kernel * defines the size of available shared memory of a {@code __shared} kernel
* argument * argument
*/ */
public static final class LocalMem { public static final class LocalMem {
private int size; private int size;
/** /**
* Creates a new LocalMem instance * Creates a new LocalMem instance
*
* @param size the size of the available shared memory in bytes * @param size the size of the available shared memory in bytes
*/ */
public LocalMem(int size) { public LocalMem(int size) {
@ -480,11 +497,11 @@ public abstract class Kernel extends AbstractOpenCLObject {
return true; return true;
} }
@Override @Override
public String toString() { public String toString() {
return "LocalMem (" + size + "B)"; return "LocalMem (" + size + "B)";
} }
} }
/** /**
@ -498,11 +515,11 @@ public abstract class Kernel extends AbstractOpenCLObject {
* (e.g. by {@link #setWorkGroupSizeToNull()} or {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }. * (e.g. by {@link #setWorkGroupSizeToNull()} or {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
*/ */
public static final class LocalMemPerElement { public static final class LocalMemPerElement {
private int size; private int size;
/** /**
* Creates a new LocalMemPerElement instance * Creates a new LocalMemPerElement instance
*
* @param size the number of bytes available for each thread within * @param size the number of bytes available for each thread within
* a work group * a work group
*/ */
@ -537,15 +554,16 @@ public abstract class Kernel extends AbstractOpenCLObject {
return true; return true;
} }
@Override @Override
public String toString() { public String toString() {
return "LocalMemPerElement (" + size + "B)"; return "LocalMemPerElement (" + size + "B)";
} }
} }
/** /**
* The work size (global and local) for executing a kernel * The work size (global and local) for executing a kernel
*
* @author shaman * @author shaman
*/ */
public static final class WorkSize { public static final class WorkSize {
@ -555,6 +573,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Creates a new work size object * Creates a new work size object
*
* @param dimension the dimension (1,2,3) * @param dimension the dimension (1,2,3)
* @param sizes the sizes in each dimension, the length must match the specified dimension * @param sizes the sizes in each dimension, the length must match the specified dimension
*/ */
@ -572,6 +591,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Creates a 1D work size of the specified extend * Creates a 1D work size of the specified extend
*
* @param size the size * @param size the size
*/ */
public WorkSize(long size) { public WorkSize(long size) {
@ -580,6 +600,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Creates a 2D work size of the specified extend * Creates a 2D work size of the specified extend
*
* @param width the width * @param width the width
* @param height the height * @param height the height
*/ */
@ -589,6 +610,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/** /**
* Creates a 3D work size of the specified extend. * Creates a 3D work size of the specified extend.
*
* @param width the width * @param width the width
* @param height the height * @param height the height
* @param depth the depth * @param depth the depth
@ -647,20 +669,18 @@ public abstract class Kernel extends AbstractOpenCLObject {
return true; return true;
} }
@Override @Override
public String toString() { public String toString() {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append("WorkSize["); str.append("WorkSize[");
for (int i=0; i<dimension; ++i) { for (int i = 0; i < dimension; ++i) {
if (i>0) { if (i > 0) {
str.append(", "); str.append(", ");
} }
str.append(sizes[i]); str.append(sizes[i]);
} }
str.append(']'); str.append(']');
return str.toString(); return str.toString();
} }
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2019 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,23 +36,23 @@ package com.jme3.opencl;
* when the compilation failed. * when the compilation failed.
* The error log returned by {@link #getLog() } contains detailed information * The error log returned by {@link #getLog() } contains detailed information
* where the error occurred. * where the error occurred.
*
* @author shaman * @author shaman
*/ */
public class KernelCompilationException extends OpenCLException { public class KernelCompilationException extends OpenCLException {
private final String log;
private final String log; public KernelCompilationException(String msg, int errorCode, String log) {
super(msg, errorCode);
public KernelCompilationException(String msg, int errorCode, String log) { this.log = log;
super(msg, errorCode); }
this.log = log;
}
/** /**
* The output of the compiler * The output of the compiler
*
* @return the output text * @return the output text
*/ */
public String getLog() { public String getLog() {
return log; return log;
} }
}
}

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2016 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,43 +36,42 @@ package com.jme3.opencl;
* The error code and its name is reported in the message string as well as the OpenCL call that * The error code and its name is reported in the message string as well as the OpenCL call that
* causes this exception. Please refer to the official OpenCL specification * causes this exception. Please refer to the official OpenCL specification
* to see what might cause this exception. * to see what might cause this exception.
*
* @author shaman * @author shaman
*/ */
public class OpenCLException extends RuntimeException { public class OpenCLException extends RuntimeException {
private static final long serialVersionUID = 8471229972153694848L; private static final long serialVersionUID = 8471229972153694848L;
private final int errorCode; private final int errorCode;
/**
* Creates a new instance of <code>OpenCLExceptionn</code> without detail
* message.
*/
public OpenCLException() {
errorCode = 0;
}
/** /**
* Constructs an instance of <code>OpenCLExceptionn</code> with the * Creates a new instance of <code>OpenCLExceptionn</code> without detail
* specified detail message. * message.
* */
* @param msg the detail message. public OpenCLException() {
*/ errorCode = 0;
public OpenCLException(String msg) { }
super(msg);
errorCode = 0;
}
public OpenCLException(String msg, int errorCode) {
super(msg);
this.errorCode = errorCode;
}
/** /**
* @return the error code * Constructs an instance of <code>OpenCLExceptionn</code> with the
* specified detail message.
*
* @param msg the detail message.
*/ */
public int getErrorCode() { public OpenCLException(String msg) {
return errorCode; super(msg);
} errorCode = 0;
}
public OpenCLException(String msg, int errorCode) {
super(msg);
this.errorCode = errorCode;
}
/**
* @return the error code
*/
public int getErrorCode() {
return errorCode;
}
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2019 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -39,9 +39,9 @@ import java.nio.ByteBuffer;
* <p> * <p>
* Warning: Creating the same kernel more than one leads to undefined behaviour, * Warning: Creating the same kernel more than one leads to undefined behaviour,
* this is especially important for {@link #createAllKernels() } * this is especially important for {@link #createAllKernels() }
* *
* @see Context#createProgramFromSourceCode(java.lang.String) * @see Context#createProgramFromSourceCode(java.lang.String)
* @see #createKernel(java.lang.String) * @see #createKernel(java.lang.String)
* @author shaman * @author shaman
*/ */
public abstract class Program extends AbstractOpenCLObject { public abstract class Program extends AbstractOpenCLObject {
@ -49,13 +49,13 @@ public abstract class Program extends AbstractOpenCLObject {
protected Program(ObjectReleaser releaser) { protected Program(ObjectReleaser releaser) {
super(releaser); super(releaser);
} }
@Override @Override
public Program register() { public Program register() {
super.register(); super.register();
return this; return this;
} }
/** /**
* Builds this program with the specified argument string on the specified * Builds this program with the specified argument string on the specified
* devices. * devices.
@ -64,46 +64,50 @@ public abstract class Program extends AbstractOpenCLObject {
* The list of devices specify on which device the compiled program * The list of devices specify on which device the compiled program
* can then be executed. It must be a subset of {@link Context#getDevices() }. * can then be executed. It must be a subset of {@link Context#getDevices() }.
* If {@code null} is passed, the program is built on all available devices. * If {@code null} is passed, the program is built on all available devices.
* *
* @param args the compilation arguments * @param args the compilation arguments
* @param devices a list of devices on which the program is build. * @param devices a list of devices on which the program is build.
* @throws KernelCompilationException if the compilation fails * @throws KernelCompilationException if the compilation fails
* @see #build() * @see #build()
*/ */
public abstract void build(String args, Device... devices) throws KernelCompilationException; public abstract void build(String args, Device... devices) throws KernelCompilationException;
/** /**
* Builds this program without additional arguments * Builds this program without additional arguments
*
* @throws KernelCompilationException if the compilation fails * @throws KernelCompilationException if the compilation fails
*/ */
public void build() throws KernelCompilationException { public void build() throws KernelCompilationException {
build("", (Device[]) null); build("", (Device[]) null);
} }
/** /**
* Creates the kernel with the specified name. * Creates the kernel with the specified name.
*
* @param name the name of the kernel as defined in the source code * @param name the name of the kernel as defined in the source code
* @return the kernel object * @return the kernel object
* @throws OpenCLException if the kernel was not found or some other * @throws OpenCLException if the kernel was not found or some other error
* error occurred * occurred
*/ */
public abstract Kernel createKernel(String name); public abstract Kernel createKernel(String name);
/** /**
* Creates all available kernels in this program. * Creates all available kernels in this program.
* The names of the kernels can then by queried by {@link Kernel#getName() }. * The names of the kernels can then by queried by {@link Kernel#getName() }.
*
* @return an array of all kernels * @return an array of all kernels
*/ */
public abstract Kernel[] createAllKernels(); public abstract Kernel[] createAllKernels();
/** /**
* Queries a compiled binary representation of this program for a particular * Queries a compiled binary representation of this program for a particular
* device. This binary can then be used e.g. in the next application launch * device. This binary can then be used e.g. in the next application launch
* to create the program from the binaries and not from the sources. * to create the program from the binaries and not from the sources.
* This saves time. * This saves time.
*
* @param device the device from which the binaries are taken * @param device the device from which the binaries are taken
* @return the binaries * @return the binaries
* @see Context#createProgramFromBinary(java.nio.ByteBuffer, com.jme3.opencl.Device) * @see Context#createProgramFromBinary(java.nio.ByteBuffer, com.jme3.opencl.Device)
*/ */
public abstract ByteBuffer getBinary(Device device); public abstract ByteBuffer getBinary(Device device);
} }

Loading…
Cancel
Save