com.jme3.opencl.package-info Maven / Gradle / Ivy
Show all versions of jme3-core Show documentation
/*
* 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.
*/
/**
* This package contains an API for using OpenCL together with jME3.
*
* Activation:
* 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}.
*
*
* First steps:
* 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.
*
* Programs and Kernels:
* 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.Kernel.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.
*
* Buffers and Images:
* 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
* 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 Context.createImage().
* 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.
*
* Events:
* 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.
*
* Some methods have the suffix {@code -NoEvent}. This means that these methods
* don't return an event object even if the OpenCL function would return an event.
* There's always an alternative version that does return an event.
* These methods exist to increase the performance: since all actions (like multiple kernel calls)
* that are sent to the same command queue are executed in order, there is no
* need for intermediate events. (These intermediate events would be released
* immediately). Therefore, the no-event alternatives increase the performance
* because no additional event object has to be allocated and less system calls
* are necessary.
*
*
* Interoperability between OpenCL and jME3:
* This Wrapper allows sharing jME3 Images and VertexBuffers with OpenCL.
* {@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.
* {@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.
*
* Important: Before shared objects can be used by any OpenCL function
* like kernel calls or read/write/copy methods, they must be acquired 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.
*
*
* Experts: choosing the right platform and devices
* 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}.
*
*
* Exception handling:
* 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
* explicitly in the documentation:
*
* - {@code NullPointerException}: one of the arguments is {@code null} and
* {@code null} is not allowed
* - {@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
* - {@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.
*
*/
package com.jme3.opencl;
//TODO: add profiling to Kernel, CommandQueue