started with the documentation
This commit is contained in:
parent
03282a7c86
commit
196cbc8042
@ -34,98 +34,283 @@ package com.jme3.opencl;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Wrapper for an OpenCL buffer object.
|
||||
* A buffer object stores a one-dimensional collection of elements. Elements of a buffer object can
|
||||
* be a scalar data type (such as an int, float), vector data type, or a user-defined structure.
|
||||
* <br>
|
||||
* Buffers are created by the {@link Context}.
|
||||
* <br>
|
||||
* 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 have the prefix -Async in their name.
|
||||
*
|
||||
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
|
||||
* @author Sebastian Weiss
|
||||
*/
|
||||
public abstract class Buffer implements OpenCLObject {
|
||||
|
||||
public abstract int getSize();
|
||||
/**
|
||||
* @return the size of the buffer in bytes.
|
||||
* @see Context#createBuffer(long)
|
||||
*/
|
||||
public abstract long getSize();
|
||||
|
||||
/**
|
||||
* @return the memory access flags set on creation.
|
||||
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
|
||||
*/
|
||||
public abstract MemoryAccess getMemoryAccessFlags();
|
||||
|
||||
public abstract void read(CommandQueue queue, ByteBuffer dest, int size, int offset);
|
||||
/**
|
||||
* Performs a blocking read of the buffer.
|
||||
* The target buffer must have at least {@code size} bytes remaining.
|
||||
* This method may set the limit to the last byte read.
|
||||
* @param queue the command queue
|
||||
* @param dest the target buffer
|
||||
* @param size the size in bytes being read
|
||||
* @param offset the offset in bytes in the buffer to read from
|
||||
*/
|
||||
public abstract void read(CommandQueue queue, ByteBuffer dest, long size, long offset);
|
||||
|
||||
public void read(CommandQueue queue, ByteBuffer dest, int size) {
|
||||
/**
|
||||
* Alternative version of {@link #read(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
|
||||
* sets {@code offset} to zero.
|
||||
*/
|
||||
public void read(CommandQueue queue, ByteBuffer dest, long size) {
|
||||
read(queue, dest, size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative version of {@link #read(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long) },
|
||||
* sets {@code size} to {@link #getSize() }.
|
||||
*/
|
||||
public void read(CommandQueue queue, ByteBuffer dest) {
|
||||
read(queue, dest, getSize());
|
||||
}
|
||||
|
||||
public abstract Event readAsync(CommandQueue queue, ByteBuffer dest, int size, int offset);
|
||||
/**
|
||||
* Performs an async/non-blocking read of the buffer.
|
||||
* The target buffer must have at least {@code size} bytes remaining.
|
||||
* This method may set the limit to the last byte read.
|
||||
* @param queue the command queue
|
||||
* @param dest the target buffer
|
||||
* @param size the size in bytes being read
|
||||
* @param offset the offset in bytes in the buffer to read from
|
||||
* @return the event indicating when the memory has been fully read into the provided buffer
|
||||
*/
|
||||
public abstract Event readAsync(CommandQueue queue, ByteBuffer dest, long size, long offset);
|
||||
|
||||
public Event readAsync(CommandQueue queue, ByteBuffer dest, int size) {
|
||||
/**
|
||||
* Alternative version of {@link #readAsync(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
|
||||
* sets {@code offset} to zero.
|
||||
*/
|
||||
public Event readAsync(CommandQueue queue, ByteBuffer dest, long size) {
|
||||
return readAsync(queue, dest, size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative version of {@link #readAsync(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long) },
|
||||
* sets {@code size} to {@link #getSize() }
|
||||
*/
|
||||
public Event readAsync(CommandQueue queue, ByteBuffer dest) {
|
||||
return readAsync(queue, dest, getSize());
|
||||
}
|
||||
|
||||
public abstract void write(CommandQueue queue, ByteBuffer src, int size, int offset);
|
||||
/**
|
||||
* Performs a blocking write to the buffer.
|
||||
* 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.
|
||||
* @param queue the command queue
|
||||
* @param src the source buffer, its data is written to this buffer
|
||||
* @param size the size in bytes to write
|
||||
* @param offset the offset into the target buffer
|
||||
*/
|
||||
public abstract void write(CommandQueue queue, ByteBuffer src, long size, long offset);
|
||||
|
||||
public void write(CommandQueue queue, ByteBuffer src, int size) {
|
||||
/**
|
||||
* Alternative version of {@link #write(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
|
||||
* sets {@code offset} to zero.
|
||||
*/
|
||||
public void write(CommandQueue queue, ByteBuffer src, long size) {
|
||||
write(queue, src, size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative version of {@link #write(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long) },
|
||||
* sets {@code size} to {@link #getSize() }.
|
||||
*/
|
||||
public void write(CommandQueue queue, ByteBuffer src) {
|
||||
write(queue, src, getSize());
|
||||
}
|
||||
|
||||
public abstract Event writeAsync(CommandQueue queue, ByteBuffer src, int size, int offset);
|
||||
/**
|
||||
* Performs an async/non-blocking write to the buffer.
|
||||
* 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.
|
||||
* @param queue the command queue
|
||||
* @param src the source buffer, its data is written to this buffer
|
||||
* @param size the size in bytes to write
|
||||
* @param offset the offset into the target buffer
|
||||
* @return the event object indicating when the write operation is completed
|
||||
*/
|
||||
public abstract Event writeAsync(CommandQueue queue, ByteBuffer src, long size, long offset);
|
||||
|
||||
public Event writeAsync(CommandQueue queue, ByteBuffer src, int size) {
|
||||
/**
|
||||
* Alternative version of {@link #writeAsync(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
|
||||
* sets {@code offset} to zero.
|
||||
*/
|
||||
public Event writeAsync(CommandQueue queue, ByteBuffer src, long size) {
|
||||
return writeAsync(queue, src, size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative version of {@link #writeAsync(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long) },
|
||||
* sets {@code size} to {@link #getSize() }.
|
||||
*/
|
||||
public Event writeAsync(CommandQueue queue, ByteBuffer src) {
|
||||
return writeAsync(queue, src, getSize());
|
||||
}
|
||||
|
||||
public abstract void copyTo(CommandQueue queue, Buffer dest, int size, int srcOffset, int destOffset);
|
||||
/**
|
||||
* Performs a blocking copy operation from this buffer to the specified buffer.
|
||||
* @param queue the command queue
|
||||
* @param dest the target buffer
|
||||
* @param size the size in bytes to copy
|
||||
* @param srcOffset offset in bytes into this buffer
|
||||
* @param destOffset offset in bytes into the target buffer
|
||||
*/
|
||||
public abstract void copyTo(CommandQueue queue, Buffer dest, long size, long srcOffset, long destOffset);
|
||||
|
||||
public void copyTo(CommandQueue queue, Buffer dest, int size) {
|
||||
/**
|
||||
* Alternative version of {@link #copyTo(com.jme3.opencl.CommandQueue, com.jme3.opencl.Buffer, long, long, long) },
|
||||
* sets {@code srcOffset} and {@code destOffset} to zero.
|
||||
*/
|
||||
public void copyTo(CommandQueue queue, Buffer dest, long size) {
|
||||
copyTo(queue, dest, size, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative version of {@link #copyTo(com.jme3.opencl.CommandQueue, com.jme3.opencl.Buffer, long) },
|
||||
* sets {@code size} to {@code this.getSize()}.
|
||||
*/
|
||||
public void copyTo(CommandQueue queue, Buffer dest) {
|
||||
copyTo(queue, dest, getSize());
|
||||
}
|
||||
|
||||
public abstract Event copyToAsync(CommandQueue queue, Buffer dest, int size, int srcOffset, int destOffset);
|
||||
/**
|
||||
* Performs an async/non-blocking copy operation from this buffer to the specified buffer.
|
||||
* @param queue the command queue
|
||||
* @param dest the target buffer
|
||||
* @param size the size in bytes to copy
|
||||
* @param srcOffset offset in bytes into this buffer
|
||||
* @param destOffset offset in bytes into the target buffer
|
||||
* @return the event object indicating when the copy operation is finished
|
||||
*/
|
||||
public abstract Event copyToAsync(CommandQueue queue, Buffer dest, long size, long srcOffset, long destOffset);
|
||||
|
||||
public Event copyToAsync(CommandQueue queue, Buffer dest, int size) {
|
||||
/**
|
||||
* Alternative version of {@link #copyToAsync(com.jme3.opencl.CommandQueue, com.jme3.opencl.Buffer, long, long, long) },
|
||||
* sets {@code srcOffset} and {@code destOffset} to zero.
|
||||
*/
|
||||
public Event copyToAsync(CommandQueue queue, Buffer dest, long size) {
|
||||
return copyToAsync(queue, dest, size, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative version of {@link #copyToAsync(com.jme3.opencl.CommandQueue, com.jme3.opencl.Buffer, long) },
|
||||
* sets {@code size} to {@code this.getSize()}.
|
||||
*/
|
||||
public Event copyToAsync(CommandQueue queue, Buffer dest) {
|
||||
return copyToAsync(queue, dest, getSize());
|
||||
}
|
||||
|
||||
public abstract ByteBuffer map(CommandQueue queue, int size, int offset, MappingAccess access);
|
||||
/**
|
||||
* 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
|
||||
* provides the memory.<br>
|
||||
* <b>Important:</b> The mapped memory MUST be released by calling
|
||||
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
|
||||
* @param queue the command queue
|
||||
* @param size the size in bytes to map
|
||||
* @param offset the offset into this buffer
|
||||
* @param access specifies the possible access to the memory: READ_ONLY, WRITE_ONLY, READ_WRITE
|
||||
* @return the byte buffer directly reflecting the buffer contents
|
||||
*/
|
||||
public abstract ByteBuffer map(CommandQueue queue, long size, long offset, MappingAccess access);
|
||||
|
||||
public ByteBuffer map(CommandQueue queue, int size, MappingAccess access) {
|
||||
/**
|
||||
* Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) },
|
||||
* sets {@code offset} to zero.
|
||||
* <b>Important:</b> The mapped memory MUST be released by calling
|
||||
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
|
||||
*/
|
||||
public ByteBuffer map(CommandQueue queue, long size, MappingAccess access) {
|
||||
return map(queue, size, 0, access);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) },
|
||||
* sets {@code size} to {@link #getSize() }.
|
||||
* <b>Important:</b> The mapped memory MUST be released by calling
|
||||
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
|
||||
*/
|
||||
public ByteBuffer map(CommandQueue queue, MappingAccess access) {
|
||||
return map(queue, getSize(), access);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmaps a previously mapped memory.
|
||||
* This releases the native resources and for WRITE_ONLY or READ_WRITE access,
|
||||
* the memory content is sent back to the GPU.
|
||||
* @param queue the command queue
|
||||
* @param ptr the buffer that was previously mapped
|
||||
*/
|
||||
public abstract void unmap(CommandQueue queue, ByteBuffer ptr);
|
||||
|
||||
public abstract AsyncMapping mapAsync(CommandQueue queue, int size, int offset, MappingAccess access);
|
||||
public AsyncMapping mapAsync(CommandQueue queue, int size, MappingAccess access) {
|
||||
/**
|
||||
* 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
|
||||
* provides the memory.<br>
|
||||
* <b>Important:</b> The mapped memory MUST be released by calling
|
||||
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
|
||||
* @param queue the command queue
|
||||
* @param size the size in bytes to map
|
||||
* @param offset the offset into this buffer
|
||||
* @param access specifies the possible access to the memory: READ_ONLY, WRITE_ONLY, READ_WRITE
|
||||
* @return the byte buffer directly reflecting the buffer contents
|
||||
* and the event indicating when the buffer contents are available
|
||||
*/
|
||||
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) },
|
||||
* sets {@code offset} to zero.
|
||||
* <b>Important:</b> The mapped memory MUST be released by calling
|
||||
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
|
||||
*/
|
||||
public AsyncMapping mapAsync(CommandQueue queue, long size, MappingAccess access) {
|
||||
return mapAsync(queue, size, 0, access);
|
||||
}
|
||||
/**
|
||||
* Alternative version of {@link #mapAsync(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) },
|
||||
* sets {@code size} to {@link #getSize() }.
|
||||
* <b>Important:</b> The mapped memory MUST be released by calling
|
||||
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
|
||||
*/
|
||||
public AsyncMapping mapAsync(CommandQueue queue, MappingAccess access) {
|
||||
return mapAsync(queue, getSize(), 0, access);
|
||||
}
|
||||
|
||||
public abstract Event fillAsync(CommandQueue queue, ByteBuffer pattern, int size, int offset);
|
||||
|
||||
//TODO: copy to image
|
||||
/**
|
||||
* Enqueues a fill operation. This method can be used to initialize or clear
|
||||
* a buffer with a certain value.
|
||||
* @param queue the command queue
|
||||
* @param pattern the buffer containing the filling pattern.
|
||||
* The remaining bytes specify the pattern length
|
||||
* @param size the size in bytes to fill, must be a multiple of the pattern length
|
||||
* @param offset the offset in bytes into the buffer, must be a multiple of the pattern length
|
||||
* @return an event indicating when this operation is finished
|
||||
*/
|
||||
public abstract Event fillAsync(CommandQueue queue, ByteBuffer pattern, long size, long offset);
|
||||
|
||||
/**
|
||||
* Result of an async mapping operation, contains the event and the target byte buffer.
|
||||
@ -144,18 +329,58 @@ public abstract class Buffer implements OpenCLObject {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the event object indicating when the data in the mapped buffer
|
||||
* is available
|
||||
*/
|
||||
public Event getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mapped buffer, only valid when the event object signals completion
|
||||
*/
|
||||
public ByteBuffer getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies this buffer to the specified image.
|
||||
* Note that no format conversion is done.
|
||||
* <br>
|
||||
* For detailed description of the origin and region paramenter, see the
|
||||
* documentation of the {@link Image} class.
|
||||
*
|
||||
* @param queue the command queue
|
||||
* @param dest the target image
|
||||
* @param srcOffset the offset in bytes into this buffer
|
||||
* @param destOrigin the origin of the copied area
|
||||
* @param destRegion the size of the copied area
|
||||
* @return the event object
|
||||
*/
|
||||
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
|
||||
* represents a shared object from OpenGL, created with e.g.
|
||||
* {@link Context#bindVertexBuffer(com.jme3.scene.VertexBuffer, com.jme3.opencl.MemoryAccess) }.
|
||||
* This method must be called before the buffer is used. After the work is
|
||||
* done, the buffer must be released by calling
|
||||
* {@link #releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
|
||||
* so that OpenGL can use the VertexBuffer again.
|
||||
* @param queue the command queue
|
||||
* @return the event object
|
||||
*/
|
||||
public abstract Event acquireBufferForSharingAsync(CommandQueue queue);
|
||||
/**
|
||||
* Releases a shared buffer object.
|
||||
* Call this method after the buffer object was acquired by
|
||||
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
|
||||
* to hand the control back to OpenGL.
|
||||
* @param queue the command queue
|
||||
* @return the event object
|
||||
*/
|
||||
public abstract Event releaseBufferForSharingAsync(CommandQueue queue);
|
||||
//TODO: add variants of the above two methods that don't create the event object, but release the event immediately
|
||||
}
|
||||
|
@ -31,15 +31,14 @@
|
||||
*/
|
||||
package com.jme3.opencl;
|
||||
|
||||
import com.jme3.opencl.Device;
|
||||
import com.jme3.opencl.Platform;
|
||||
import com.jme3.opencl.PlatformChooser;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* A default implementation of {@link PlatformChooser}.
|
||||
* It favors GPU devices with OpenGL sharing, then any devices with OpenGL sharing,
|
||||
* then any possible device.
|
||||
* @author Sebastian Weiss
|
||||
*/
|
||||
public class DefaultPlatformChooser implements PlatformChooser {
|
||||
|
@ -31,7 +31,13 @@
|
||||
*/
|
||||
package com.jme3.opencl;
|
||||
|
||||
|
||||
/**
|
||||
* This exception is thrown by {@link Program#build() } and {@link Program#build(java.lang.String) }
|
||||
* when the compilation failed.
|
||||
* The error log returned by {@link #getLog() } contains detailed information
|
||||
* where the error occured.
|
||||
* @author Sebastian Weiss
|
||||
*/
|
||||
public class KernelCompilationException extends OpenCLException {
|
||||
|
||||
private final String log;
|
||||
@ -41,6 +47,10 @@ public class KernelCompilationException extends OpenCLException {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
/**
|
||||
* The output of the compiler
|
||||
* @return
|
||||
*/
|
||||
public String getLog() {
|
||||
return log;
|
||||
}
|
||||
|
@ -32,6 +32,117 @@
|
||||
|
||||
/**
|
||||
* This package contains an API for using OpenCL together with jME3.
|
||||
* <p>
|
||||
* <b>Activation:</b><br>
|
||||
* OpenCL is deactivated by default. To activate it, set {@link com.jme3.system.AppSettings#setOpenCLSupport(boolean) }
|
||||
* to {@code true}.
|
||||
* If the current platform supports OpenCL, then the central {@link com.jme3.opencl.Context}
|
||||
* can be fetched by {@link com.jme3.system.JmeContext#getOpenCLContext() } which is
|
||||
* available in each application. If OpenCL is deactivated or not available,
|
||||
* this method returns {@code null}.
|
||||
*
|
||||
* <p>
|
||||
* <b>First steps:</b><br>
|
||||
* Once you have obtained your {@link com.jme3.opencl.Context} you start by
|
||||
* creating a {@link com.jme3.opencl.CommandQueue} by calling
|
||||
* {@link com.jme3.opencl.Context#createQueue() } or alternative versions.
|
||||
* The command queue must be passed to every following method that execute
|
||||
* some action involving the GPU. All actions are executed in the order in which they
|
||||
* are added to the queue.
|
||||
* <br>
|
||||
* <b>Programs and Kernels:</b>
|
||||
* The main purpose of OpenCL is to execute code in parallel
|
||||
* on the GPU. From the source code, a {@link com.jme3.opencl.Program} object
|
||||
* is created by {@link com.jme3.opencl.Context#createProgramFromSourceCode(java.lang.String) },
|
||||
* {@link com.jme3.opencl.Context#createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.util.List) }
|
||||
* or alternative versions.
|
||||
* Before using it, the source code must be build using {@link com.jme3.opencl.Program#build() }.
|
||||
* Any compilation error is thrown here. Each program consists of multiple kernels.
|
||||
* Each kernel represents one executable unit and is declared in the source code
|
||||
* with the following syntax: {@code __kernel void KernelName(KernelArgs) {Code} }.
|
||||
* On the programming side, a {@link com.jme3.opencl.Kernel} instance is obtained
|
||||
* by calling {@link com.jme3.opencl.Program#createKernel(java.lang.String) }.
|
||||
* To execute the kernel, the method {@link com.jme3.opencl.Kernel#Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.WorkSize, java.lang.Object...) }
|
||||
* is provided. You first pass the command queue and the work size (i.e. the number of parallel executed threads)
|
||||
* followed by the kernel arguments.
|
||||
* <br>
|
||||
* <b>Buffers and Images:</b>
|
||||
* OpenCL Kernels show their true power first when they operate on buffers and images.
|
||||
* Buffers are simple one dimensional consecutive chunks of memory of arbitrary size.
|
||||
* These {@link com.jme3.opencl.Buffer} instances are created by calling
|
||||
* {@link com.jme3.opencl.Context#createBuffer(long)} with the size in bytes as
|
||||
* the argument. A buffer on its own is typeless. In the kernel, you then specify
|
||||
* the type of the buffer by argument declarations like {@code __global float* buffer}.
|
||||
* Note that OpenCL does not check buffer boundaries. If you read or write outside
|
||||
* of the buffer, the behavior is completely undefined and may often result in
|
||||
* a program cache later on.
|
||||
* {@link com.jme3.opencl.Image} objects are structured one, two or three dimensional
|
||||
* memory chunks of a fixed type. They are created by
|
||||
* {@link com.jme3.opencl.Context#createImage(com.jme3.opencl.MemoryAccess, com.jme3.opencl.Image.ImageFormat, com.jme3.opencl.Image.ImageDescriptor, java.nio.ByteBuffer) }.
|
||||
* They need special functions in the kernel code to write to or read from images.
|
||||
* Both buffer and image objects provide methods for copying between buffers and images,
|
||||
* reading and writing to host code and directly mapping memory parts to the host code.
|
||||
* <br>
|
||||
* <b>Events:</b>
|
||||
* Most methods are provided in two variations: blocking calls or asynchronous
|
||||
* calls (the later one have the suffix -Async, or all kernel calls).
|
||||
* These async calls all return {@link com.jme3.opencl.Event} objects.
|
||||
* These events can be used to check (non-blocking) if the action has completed, e.g. a memory copy
|
||||
* is finished, or to block the execution until the action has finished.
|
||||
*
|
||||
* <p>
|
||||
* <b>Interoperability between OpenCL and jME3:</b><br>
|
||||
* This Wrapper allows to share jME3 Images and VertexBuffers with OpenCL.<br>
|
||||
* {@link com.jme3.scene.VertexBuffer} objects can be shared with OpenCL
|
||||
* by calling {@link com.jme3.opencl.Context#bindVertexBuffer(com.jme3.scene.VertexBuffer, com.jme3.opencl.MemoryAccess) }
|
||||
* resulting in a {@link com.jme3.opencl.Buffer} object. This buffer object
|
||||
* can then be used as usual, allowing e.g. the dynamic modification of position buffers for particle systems.<br>
|
||||
* {@link com.jme3.texture.Image} and {@link com.jme3.texture.Texture} objects can be used in OpenCL with the method
|
||||
* {@link com.jme3.opencl.Context#bindImage(com.jme3.texture.Texture, com.jme3.opencl.MemoryAccess) }
|
||||
* or variations of this method. The same holds for {@link com.jme3.texture.FrameBuffer.RenderBuffer} objects
|
||||
* using {@link com.jme3.opencl.Context#bindRenderBuffer(com.jme3.texture.FrameBuffer.RenderBuffer, com.jme3.opencl.MemoryAccess) }.
|
||||
* These methods result in an OpenCL-Image. Usages are e.g. animated textures,
|
||||
* terrain based on height maps, post processing effects and so forth.
|
||||
* <br>
|
||||
* <i>Important:</i> Before shared objects can be used by any OpenCL function
|
||||
* like kernel calls or read/write/copy methods, they must be aquired explicitly
|
||||
* by {@link com.jme3.opencl.Buffer#acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
|
||||
* or {@link com.jme3.opencl.Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }.
|
||||
* After the work is done, release the resource with
|
||||
* {@link com.jme3.opencl.Buffer#releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
|
||||
* or {@link com.jme3.opencl.Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }.
|
||||
* This ensures the synchronization of OpenCL and OpenGL.
|
||||
*
|
||||
* <p>
|
||||
* <b>Experts: choosing the right platform and devices</b><br>
|
||||
* OpenCL can run on different platforms and different devices. On some systems,
|
||||
* like multi-GPU setups, this choice really matters. To specify which platform
|
||||
* and which devices are used, a custom implementation of
|
||||
* {@link com.jme3.opencl.PlatformChooser} can be used by calling
|
||||
* {@link com.jme3.system.AppSettings#setOpenCLPlatformChooser(java.lang.Class) }.
|
||||
* For more details, see the documentation of {@code PlatformChooser}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Exception handling:</b><br>
|
||||
* All OpenCL-wrapper classes in this package
|
||||
* (this includes {@link com.jme3.opencl.Platform}, {@link com.jme3.opencl.Device},
|
||||
* {@link com.jme3.opencl.Context}, {@link com.jme3.opencl.CommandQueue},
|
||||
* {@link com.jme3.opencl.Buffer}, {@link com.jme3.opencl.Image},
|
||||
* {@link com.jme3.opencl.Program}, {@link com.jme3.opencl.Kernel} and
|
||||
* {@link com.jme3.opencl.Event})
|
||||
* may throw the following exceptions in each method without being mentioned
|
||||
* explicetly in the documentation:
|
||||
* <ul>
|
||||
* <li>{@code NullPointerException}: one of the arguments is {@code null} and
|
||||
* {@code null} is not allowed</li>
|
||||
* <li>{@code IllegalArgumentException}: the arguments don't follow the rules
|
||||
* as specified in the documentation of the method, e.g. values are out of range
|
||||
* or an array has the wrong size</li>
|
||||
* <li>{@link com.jme3.opencl.OpenCLException}: some low-level exception was
|
||||
* thrown. The exception always records the error code and error name and the
|
||||
* OpenCL function call where the error was detected. Please check the official
|
||||
* OpenCL specification for the meanings of these errors for that particular function.</li>
|
||||
* </ul>
|
||||
*/
|
||||
package com.jme3.opencl;
|
||||
|
||||
|
@ -52,8 +52,8 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return buffer.getInfoInt(CL10.CL_MEM_SIZE);
|
||||
public long getSize() {
|
||||
return buffer.getInfoSize(CL10.CL_MEM_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,18 +62,18 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CommandQueue queue, ByteBuffer dest, int size, int offset) {
|
||||
public void read(CommandQueue queue, ByteBuffer dest, long size, long offset) {
|
||||
//Note: LWJGL does not support the size parameter, I have to set the buffer limit
|
||||
dest.limit(dest.position() + size);
|
||||
dest.limit((int) (dest.position() + size));
|
||||
int ret = CL10.clEnqueueReadBuffer(((LwjglCommandQueue)queue).getQueue(),
|
||||
buffer, CL10.CL_TRUE, offset, dest, null, null);
|
||||
Utils.checkError(ret, "clEnqueueReadBuffer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event readAsync(CommandQueue queue, ByteBuffer dest, int size, int offset) {
|
||||
public Event readAsync(CommandQueue queue, ByteBuffer dest, long size, long offset) {
|
||||
//Note: LWJGL does not support the size parameter, I have to set the buffer limit
|
||||
dest.limit(dest.position() + size);
|
||||
dest.limit((int) (dest.position() + size));
|
||||
Utils.pointerBuffers[0].rewind();
|
||||
CLCommandQueue q = ((LwjglCommandQueue)queue).getQueue();
|
||||
int ret = CL10.clEnqueueReadBuffer(q, buffer, CL10.CL_FALSE, offset, dest, null, Utils.pointerBuffers[0]);
|
||||
@ -83,18 +83,18 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CommandQueue queue, ByteBuffer src, int size, int offset) {
|
||||
public void write(CommandQueue queue, ByteBuffer src, long size, long offset) {
|
||||
//Note: LWJGL does not support the size parameter, I have to set the buffer limit
|
||||
src.limit(src.position() + size);
|
||||
src.limit((int) (src.position() + size));
|
||||
CLCommandQueue q = ((LwjglCommandQueue)queue).getQueue();
|
||||
int ret = CL10.clEnqueueWriteBuffer(q, buffer, CL10.CL_TRUE, offset, src, null, null);
|
||||
Utils.checkError(ret, "clEnqueueWriteBuffer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event writeAsync(CommandQueue queue, ByteBuffer src, int size, int offset) {
|
||||
public Event writeAsync(CommandQueue queue, ByteBuffer src, long size, long offset) {
|
||||
//Note: LWJGL does not support the size parameter, I have to set the buffer limit
|
||||
src.limit(src.position() + size);
|
||||
src.limit((int) (src.position() + size));
|
||||
Utils.pointerBuffers[0].rewind();
|
||||
CLCommandQueue q = ((LwjglCommandQueue)queue).getQueue();
|
||||
int ret = CL10.clEnqueueWriteBuffer(q, buffer, CL10.CL_FALSE, offset, src, null, Utils.pointerBuffers[0]);
|
||||
@ -104,7 +104,7 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(CommandQueue queue, Buffer dest, int size, int srcOffset, int destOffset) {
|
||||
public void copyTo(CommandQueue queue, Buffer dest, long size, long srcOffset, long destOffset) {
|
||||
CLCommandQueue q = ((LwjglCommandQueue)queue).getQueue();
|
||||
Utils.pointerBuffers[0].rewind();
|
||||
int ret = CL10.clEnqueueCopyBuffer(q, buffer, ((LwjglBuffer) dest).buffer, srcOffset, destOffset, size, null, Utils.pointerBuffers[0]);
|
||||
@ -115,7 +115,7 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event copyToAsync(CommandQueue queue, Buffer dest, int size, int srcOffset, int destOffset) {
|
||||
public Event copyToAsync(CommandQueue queue, Buffer dest, long size, long srcOffset, long destOffset) {
|
||||
CLCommandQueue q = ((LwjglCommandQueue)queue).getQueue();
|
||||
Utils.pointerBuffers[0].rewind();
|
||||
int ret = CL10.clEnqueueCopyBuffer(q, buffer, ((LwjglBuffer) dest).buffer, srcOffset, destOffset, size, null, Utils.pointerBuffers[0]);
|
||||
@ -125,7 +125,7 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer map(CommandQueue queue, int size, int offset, MappingAccess access) {
|
||||
public ByteBuffer map(CommandQueue queue, long size, long offset, MappingAccess access) {
|
||||
CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue();
|
||||
long flags = Utils.getMappingAccessFlags(access);
|
||||
Utils.errorBuffer.rewind();
|
||||
@ -146,7 +146,7 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.jme3.opencl.Buffer.AsyncMapping mapAsync(CommandQueue queue, int size, int offset, MappingAccess access) {
|
||||
public com.jme3.opencl.Buffer.AsyncMapping mapAsync(CommandQueue queue, long size, long offset, MappingAccess access) {
|
||||
Utils.pointerBuffers[0].rewind();
|
||||
Utils.errorBuffer.rewind();
|
||||
CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue();
|
||||
@ -158,7 +158,7 @@ public class LwjglBuffer extends Buffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event fillAsync(CommandQueue queue, ByteBuffer pattern, int size, int offset) {
|
||||
public Event fillAsync(CommandQueue queue, ByteBuffer pattern, long size, long offset) {
|
||||
Utils.pointerBuffers[0].rewind();
|
||||
CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue();
|
||||
int ret = CL12.clEnqueueFillBuffer(q, buffer, pattern, offset, size, null, Utils.pointerBuffers[0]);
|
||||
|
@ -183,7 +183,7 @@ public class LwjglContext extends Context {
|
||||
throw new IllegalArgumentException("renderbuffer was not yet uploaded to the GPU");
|
||||
}
|
||||
long memFlags = Utils.getMemoryAccessFlags(access);
|
||||
Utils.errorBuffer.rewind();
|
||||
Utils.errorBuffer.rewind();
|
||||
CLMem mem = CL10GL.clCreateFromGLRenderbuffer(context, memFlags, renderbuffer, Utils.errorBuffer);
|
||||
Utils.checkError(Utils.errorBuffer, "clCreateFromGLRenderbuffer");
|
||||
return new LwjglImage(mem);
|
||||
|
Loading…
x
Reference in New Issue
Block a user