com.jme3.opencl.Buffer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jme3-core Show documentation
Show all versions of jme3-core Show documentation
jMonkeyEngine is a 3-D game engine for adventurous Java developers
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.opencl;
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.
*
* Buffers are created by the {@link Context}.
*
* All access methods (read/write/copy/map) are available in both synchronized/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 shaman
*/
public abstract class Buffer extends AbstractOpenCLObject {
protected Buffer(ObjectReleaser releaser) {
super(releaser);
}
@Override
public Buffer register() {
super.register();
return this;
}
/**
* @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();
/**
* 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);
/**
* Alternative version of {@link #read(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
* sets {@code offset} to zero.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the number of bytes to read
*/
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() }.
*
* @param queue the command queue
* @param dest the target buffer
*/
public void read(CommandQueue queue, ByteBuffer dest) {
read(queue, dest, getSize());
}
/**
* 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);
/**
* Alternative version of {@link #readAsync(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
* sets {@code offset} to zero.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the number of bytes to read
* @return an Event to indicate completion
*/
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() }
*
* @param queue the command queue
* @param dest the target buffer
* @return an Event to indicate completion
*/
public Event readAsync(CommandQueue queue, ByteBuffer dest) {
return readAsync(queue, dest, getSize());
}
/**
* 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);
/**
* Alternative version of {@link #write(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
* sets {@code offset} to zero.
*
* @param queue the command queue
* @param src the source buffer, its data is written to this buffer
* @param size the number of bytes to write
*/
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() }.
*
* @param queue the command queue
* @param src the source buffer, its data is written to this buffer
*/
public void write(CommandQueue queue, ByteBuffer src) {
write(queue, src, getSize());
}
/**
* 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 an Event to indicate completion
*/
public abstract Event writeAsync(CommandQueue queue, ByteBuffer src, long size, long offset);
/**
* Alternative version of {@link #writeAsync(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer, long, long) },
* sets {@code offset} to zero.
*
* @param queue the command queue
* @param src the source buffer, its data is written to this buffer
* @param size the number of bytes to write
* @return an Event to indicate completion
*/
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() }.
*
* @param queue the command queue
* @param src the source buffer, its data is written to this buffer
* @return an Event to indicate completion
*/
public Event writeAsync(CommandQueue queue, ByteBuffer src) {
return writeAsync(queue, src, getSize());
}
/**
* 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);
/**
* Alternative version of {@link #copyTo(com.jme3.opencl.CommandQueue, com.jme3.opencl.Buffer, long, long, long) },
* sets {@code srcOffset} and {@code destOffset} to zero.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the number of bytes to copy
*/
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()}.
*
* @param queue the command queue
* @param dest the target buffer
*/
public void copyTo(CommandQueue queue, Buffer dest) {
copyTo(queue, dest, getSize());
}
/**
* 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);
/**
* Alternative version of {@link #copyToAsync(com.jme3.opencl.CommandQueue, com.jme3.opencl.Buffer, long, long, long) },
* sets {@code srcOffset} and {@code destOffset} to zero.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the number of bytes to copy
* @return an Event to indicate completion
*/
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()}.
*
* @param queue the command queue
* @param dest the target buffer
* @return an Event to indicate completion
*/
public Event copyToAsync(CommandQueue queue, Buffer dest) {
return copyToAsync(queue, dest, getSize());
}
/**
* 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.
* Important: 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);
/**
* Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) },
* sets {@code offset} to zero.
* Important: 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 number of bytes to map
* @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 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() }.
* Important: The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*
* @param queue the command queue
* @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 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);
/**
* 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.
* Important: 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.
* Important: 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 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 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() }.
* Important: The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*
* @param queue the command queue
* @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 AsyncMapping mapAsync(CommandQueue queue, MappingAccess access) {
return mapAsync(queue, getSize(), 0, access);
}
/**
* 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.
* This is a work-around since no generic pair-structure is available.
*
* @author shaman
*/
public static class AsyncMapping {
public final Event event;
public final ByteBuffer buffer;
public AsyncMapping(Event event, ByteBuffer buffer) {
super();
this.event = event;
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.
*
* For detailed description of the origin and region parameter, 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);
/**
* Acquires 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);
/**
* Acquires 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.
*
* The generated event object is directly released.
* 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
* this action). If you need the event, use
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) } instead.
*
* @param queue the command queue
*/
public void acquireBufferForSharingNoEvent(CommandQueue queue) {
//default implementation, overwrite for better performance
acquireBufferForSharingAsync(queue).release();
}
/**
* 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);
/**
* 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.
* The generated event object is directly released, resulting in
* performance improvements.
* @param queue the command queue
*/
public void releaseBufferForSharingNoEvent(CommandQueue queue) {
//default implementation, overwrite for better performance
releaseBufferForSharingAsync(queue).release();
}
@Override
public String toString() {
return "Buffer (" + getSize() + "B)";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy