001/* 002 * JavaCL - Java API and utilities for OpenCL 003 * http://javacl.googlecode.com/ 004 * 005 * Copyright (c) 2009-2013, Olivier Chafik (http://ochafik.com/) 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions are met: 010 * 011 * * Redistributions of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * * Redistributions in binary form must reproduce the above copyright 014 * notice, this list of conditions and the following disclaimer in the 015 * documentation and/or other materials provided with the distribution. 016 * * Neither the name of Olivier Chafik nor the 017 * names of its contributors may be used to endorse or promote products 018 * derived from this software without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY OLIVIER CHAFIK AND CONTRIBUTORS ``AS IS'' AND ANY 021 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 023 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 */ 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050package com.nativelibs4java.opencl; 051import com.nativelibs4java.util.Pair; 052 053import static com.nativelibs4java.opencl.CLException.error; 054import static com.nativelibs4java.opencl.CLException.failedForLackOfMemory; 055import static com.nativelibs4java.opencl.JavaCL.CL; 056import static com.nativelibs4java.opencl.library.OpenCLLibrary.*; 057import static com.nativelibs4java.opencl.library.IOpenCLLibrary.*; 058import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_event; 059import static com.nativelibs4java.util.ImageUtils.getImageIntPixels; 060import static com.nativelibs4java.util.NIOUtils.getSizeInBytes; 061 062import java.awt.Image; 063import java.io.IOException; 064import java.nio.Buffer; 065import java.nio.ByteBuffer; 066import java.nio.ByteOrder; 067import java.nio.CharBuffer; 068import java.nio.DoubleBuffer; 069import java.nio.FloatBuffer; 070import java.nio.IntBuffer; 071import java.nio.LongBuffer; 072import java.nio.ShortBuffer; 073import java.util.ArrayList; 074import java.util.concurrent.ConcurrentHashMap; 075import java.util.concurrent.atomic.AtomicReference; 076import java.util.List; 077import java.util.logging.*; 078 079import com.nativelibs4java.opencl.CLDevice.QueueProperties; 080import com.nativelibs4java.opencl.CLSampler.AddressingMode; 081import com.nativelibs4java.opencl.CLSampler.FilterMode; 082import com.nativelibs4java.opencl.ImageIOUtils.ImageInfo; 083import com.nativelibs4java.opencl.library.OpenGLContextUtils; 084import com.nativelibs4java.opencl.library.cl_image_format; 085import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_context; 086import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_device_id; 087import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_mem; 088import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_sampler; 089import com.nativelibs4java.util.EnumValue; 090import com.nativelibs4java.util.EnumValues; 091import com.nativelibs4java.util.NIOUtils; 092import org.bridj.*; 093import static org.bridj.Pointer.*; 094import static com.nativelibs4java.opencl.proxy.PointerUtils.*; 095import java.io.InputStream; 096import java.util.Arrays; 097import java.util.Map; 098 099 100/** 101 * OpenCL context.<br> 102 * An OpenCL context is created with one or more devices.<br> 103 * Contexts are used by the OpenCL runtime for managing objects such as command-queues, memory, program and kernel objects and for executing kernels on one or more devices specified in the context. 104 * @author Olivier Chafik 105 */ 106public class CLContext extends CLAbstractEntity { 107 108 109 110 111 112 113 114 115 private final AtomicReference<ConcurrentHashMap<Object, Object>> propertiesMapRef = 116 new AtomicReference<ConcurrentHashMap<Object, Object>>(); 117 118 public Object getClientProperty(Object key) { 119 ConcurrentHashMap<Object, Object> propertiesMap = propertiesMapRef.get(); 120 return propertiesMap == null ? null : propertiesMap.get(key); 121 } 122 public Object putClientProperty(Object key, Object value) { 123 ConcurrentHashMap<Object, Object> propertiesMap = propertiesMapRef.get(); 124 if (propertiesMap == null) { 125 propertiesMap = new ConcurrentHashMap<Object, Object>(); 126 if (!propertiesMapRef.compareAndSet(null, propertiesMap)) 127 propertiesMap = propertiesMapRef.get(); 128 } 129 return propertiesMap.put(key, value); 130 } 131 132 private volatile long maxMemAllocSize = -1; 133 134 /** 135 * Max size of memory object allocation in bytes. The minimum value is max (1/4th of CL_DEVICE_GLOBAL_MEM_SIZE , 128*1024*1024) 136 */ 137 public long getMaxMemAllocSize() { 138 if (maxMemAllocSize < 0) { 139 long min = Long.MAX_VALUE; 140 for (CLDevice device : getDevices()) { 141 long m = device.getMaxMemAllocSize(); 142 if (m < min) 143 min = m; 144 } 145 maxMemAllocSize = min; 146 } 147 return maxMemAllocSize; 148 } 149 150 volatile Boolean cacheBinaries; 151 152 /** 153 * Change whether program binaries are automatically cached or not.<br> 154 * By default it is true, it can be set to false with the "javacl.cacheBinaries" Java property or the "JAVACL_CACHE_BINARIES" environment variable (when set to "0").<br> 155 * Each program can be set to be cached or not using {@link CLProgram#setCached(boolean) }.<br> 156 * Caching of binaries might be disabled by default on some platforms (ATI Stream, for instance). 157 */ 158 public synchronized void setCacheBinaries(boolean cacheBinaries) { 159 this.cacheBinaries = cacheBinaries; 160 } 161 /** 162 * Says whether program binaries are automatically cached or not.<br> 163 * By default it is true, it can be set to false with the "javacl.cacheBinaries" Java property, the "JAVACL_CACHE_BINARIES" environment variable (when set to "0") or the {@link CLContext#setCacheBinaries(boolean) } method.<br> 164 * Each program can be set to be cached or not using {@link CLProgram#setCached(boolean) }.<br> 165 * Caching of binaries might be disabled by default on some platforms (ATI Stream, for instance). 166 */ 167 public synchronized boolean getCacheBinaries() { 168 if (cacheBinaries == null) { 169 String prop = System.getProperty("javacl.cacheBinaries"), env = System.getenv("JAVACL_CACHE_BINARIES"); 170 if ("true".equals(prop) || "1".equals(env)) 171 cacheBinaries = true; 172 else if ("false".equals(prop) || "0".equals(env)) 173 cacheBinaries = false; 174 else { 175 cacheBinaries = !PlatformUtils.PlatformKind.AMDApp.equals(PlatformUtils.guessPlatformKind(getPlatform())); 176 } 177 //System.out.println("CACHE BINARIES = " + cacheBinaries); 178 } 179 return cacheBinaries; 180 } 181 182 protected static CLInfoGetter infos = new CLInfoGetter() { 183 @Override 184 protected int getInfo(long entity, int infoTypeEnum, long size, Pointer out, Pointer<SizeT> sizeOut) { 185 return CL.clGetContextInfo(entity, infoTypeEnum, size, getPeer(out), getPeer(sizeOut)); 186 } 187 }; 188 189 CLPlatform platform; 190 protected Pointer<SizeT> deviceIds; 191 192 CLContext(CLPlatform platform, Pointer<SizeT> deviceIds, long context) { 193 super(context); 194 this.platform = platform; 195 this.deviceIds = deviceIds; 196 197 if (getByteOrder() == null) { 198 JavaCL.log(Level.WARNING, "The devices in this context have mismatching byte orders. This mandates the use of __attribute__((endian(host))) in kernel sources or *very* careful use of buffers to avoid facing endianness issues"); 199 } 200 } 201 202 /** 203 * Creates a user event object. <br> 204 * User events allow applications to enqueue commands that wait on a user event to finish before the command is executed by the device. 205 * @since OpenCL 1.1 206 */ 207 public CLUserEvent createUserEvent() { 208 platform.requireMinVersionValue("clCreateUserEvent", 1.1); 209 ReusablePointers ptrs = ReusablePointers.get(); 210 Pointer<Integer> pErr = ptrs.pErr; 211 long evt = CL.clCreateUserEvent(getEntity(), getPeer(pErr)); 212 error(pErr.getInt()); 213 return (CLUserEvent)CLEvent.createEvent(null, evt, true); 214 } 215 216 /** 217 * Create an OpenCL queue on the first device of this context.<br> 218 * Equivalent to calling <code>getDevices()[0].createQueue(context)</code> 219 * @return new OpenCL queue 220 */ 221 public CLQueue createDefaultQueue(QueueProperties... queueProperties) { 222 return new CLDevice(platform, deviceIds.getSizeT()).createQueue(this, queueProperties); 223 } 224 225 /** 226 * Create an out-of-order OpenCL queue on the first device of this context.<br> 227 * Equivalent to calling <code>getDevices()[0].createOutOfOrderQueue(context)</code> 228 * @return new out-of-order OpenCL queue 229 */ 230 public CLQueue createDefaultOutOfOrderQueue() { 231 return new CLDevice(platform, deviceIds.getSizeT()).createOutOfOrderQueue(this); 232 } 233 234 235 public String toString() { 236 StringBuilder b = new StringBuilder("CLContext(platform = ").append(getPlatform().getName()).append("; devices = "); 237 boolean first = true; 238 for (CLDevice d : getDevices()) { 239 if (first) 240 first = false; 241 else 242 b.append(", "); 243 b.append(d.getName()); 244 } 245 b.append(")"); 246 return b.toString(); 247 } 248 public CLQueue createDefaultOutOfOrderQueueIfPossible() { 249 try { 250 return createDefaultOutOfOrderQueue(); 251 } catch (Throwable th) {//CLException.InvalidQueueProperties ex) { 252 return createDefaultQueue(); 253 } 254 } 255 256 /** 257 * Create an profiling-enabled OpenCL queue on the first device of this context.<br> 258 * Equivalent to calling <code>getDevices()[0].createProfilingQueue(context)</code> 259 * @return new profiling-enabled OpenCL queue 260 */ 261 public CLQueue createDefaultProfilingQueue() { 262 return new CLDevice(platform, deviceIds.getSizeT()).createProfilingQueue(this); 263 } 264 265 /** 266 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetSupportedImageFormats.html">clGetSupportedImageFormats</a>.<br> 267 */ 268 @SuppressWarnings("deprecation") 269 public CLImageFormat[] getSupportedImageFormats(CLBuffer.Flags flags, CLBuffer.ObjectType imageType) { 270 Pointer<Integer> pCount = allocateInt(); 271 int memFlags = (int) flags.value(); 272 int imTyp = (int) imageType.value(); 273 CL.clGetSupportedImageFormats(getEntity(), memFlags, imTyp, 0, 0, getPeer(pCount)); 274 //cl_image_format ft = new cl_image_format(); 275 //int sz = ft.size(); 276 int n = pCount.getInt(); 277 if (n == 0) { 278 n = 30; // There HAS to be at least one format. the spec even says even more, but in fact on Mac OS X / CPU there's only one... 279 } 280 Pointer<cl_image_format> formats = allocateArray(cl_image_format.class, n); 281 CL.clGetSupportedImageFormats(getEntity(), memFlags, imTyp, n, getPeer(formats), 0); 282 List<CLImageFormat> ret = new ArrayList<CLImageFormat>(n); 283 for (cl_image_format ft : formats) { 284 if (ft.image_channel_data_type() == 0 && ft.image_channel_order() == 0) 285 break; 286 287 ret.add(new CLImageFormat(ft)); 288 } 289 return ret.toArray(new CLImageFormat[ret.size()]); 290 } 291 292 /** 293 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSampler.html">clCreateSampler</a>.<br> 294 */ 295 @SuppressWarnings("deprecation") 296 public CLSampler createSampler(boolean normalized_coords, AddressingMode addressing_mode, FilterMode filter_mode) { 297 ReusablePointers ptrs = ReusablePointers.get(); 298 Pointer<Integer> pErr = ptrs.pErr; 299 long sampler = CL.clCreateSampler( 300 getEntity(), 301 normalized_coords ? CL_TRUE : CL_FALSE, 302 (int) addressing_mode.value(), 303 (int) filter_mode.value(), 304 getPeer(pErr) 305 ); 306 error(pErr.getInt()); 307 return new CLSampler(sampler); 308 } 309 310 public int getDeviceCount() { 311 return infos.getOptionalFeatureInt(getEntity(), CL.CL_CONTEXT_NUM_DEVICES); 312 } 313 314 /** 315 * Lists the devices of this context 316 * @return array of the devices that form this context 317 */ 318 public synchronized CLDevice[] getDevices() { 319 if (deviceIds == null) { 320 deviceIds = infos.getMemory(getEntity(), CL_CONTEXT_DEVICES).as(SizeT.class); 321 } 322 int n = (int)deviceIds.getValidElements(); 323 324 CLDevice[] devices = new CLDevice[n]; 325 for (int i = n; i-- != 0;) { 326 devices[i] = new CLDevice(platform, deviceIds.getSizeTAtIndex(i)); 327 } 328 return devices; 329 } 330 331 /** 332 * Create a program with all the C source code content provided as argument. 333 * @param srcs list of the content of source code for the program 334 * @return a program that needs to be built 335 */ 336 public CLProgram createProgram(String... srcs) { 337 return createProgram(null, srcs); 338 } 339 340 public CLProgram createProgram(CLDevice[] devices, String... srcs) { 341 CLProgram program = new CLProgram(this, devices); 342 for (String src : srcs) 343 program.addSource(src); 344 return program; 345 } 346 347 /** 348 * Restore a program previously saved with {@link CLProgram#store(java.io.OutputStream) } 349 * @param in will be closed 350 * @return a CLProgram object representing the previously saved program 351 * @throws IOException 352 */ 353 public CLProgram loadProgram(InputStream in) throws IOException { 354 Pair<Map<CLDevice, byte[]>, String> binaries = CLProgram.readBinaries(Arrays.asList(getDevices()), null, in); 355 return createProgram(binaries.getFirst(), binaries.getSecond()); 356 } 357 358 public CLProgram createProgram(Map<CLDevice, byte[]> binaries, String source) { 359 return new CLProgram(this, binaries, source); 360 } 361 362 //cl_queue queue; 363 @Override 364 protected void clear() { 365 error(CL.clReleaseContext(getEntity())); 366 } 367 368 369 370 @Deprecated 371 public CLDevice guessCurrentGLDevice() { 372 long[] props = platform.getContextProps(CLPlatform.getGLContextProperties(getPlatform())); 373 Pointer<SizeT> propsRef = pointerToSizeTs(props); 374 375 Pointer<SizeT> pCount = allocateSizeT(); 376 Pointer<Pointer<?>> mem = allocatePointer(); 377 if (Platform.isMacOSX()) 378 error(CL.clGetGLContextInfoAPPLE( 379 getEntity(), 380 getPeer(OpenGLContextUtils.CGLGetCurrentContext()), 381 CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, 382 Pointer.SIZE, 383 getPeer(mem), 384 getPeer(pCount))); 385 else 386 error(CL.clGetGLContextInfoKHR( 387 getPeer(propsRef), 388 CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, 389 Pointer.SIZE, 390 getPeer(mem), 391 getPeer(pCount) 392 )); 393 394 if (pCount.getSizeT() != Pointer.SIZE) 395 throw new RuntimeException("Not a device : len = " + pCount.get().intValue()); 396 397 Pointer p = mem.getPointer(); 398 if (p.equals(Pointer.NULL)) 399 return null; 400 return new CLDevice(null, getPeer(p)); 401 } 402 403 private static <T extends CLMem> T markAsGL(T mem) { 404 mem.isGL = true; 405 return mem; 406 } 407 408 /** 409 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateFromGLBuffer.html">clCreateFromGLBuffer</a>.<br> 410 * Makes an OpenGL Vertex Buffer Object (VBO) visible to OpenCL as a buffer object.<br> 411 * Note that memory objects shared with OpenGL must be acquired / released before / after use from OpenCL. 412 * see {@link CLMem#acquireGLObject(com.nativelibs4java.opencl.CLQueue, com.nativelibs4java.opencl.CLEvent[]) } 413 * see {@link CLMem#releaseGLObject(com.nativelibs4java.opencl.CLQueue, com.nativelibs4java.opencl.CLEvent[]) } 414 * @param usage flags 415 * @param openGLBufferObject Identifier of a VBO, as generated by glGenBuffers 416 */ 417 @SuppressWarnings("deprecation") 418 public CLBuffer<Byte> createBufferFromGLBuffer(CLMem.Usage usage, int openGLBufferObject) { 419 ReusablePointers ptrs = ReusablePointers.get(); 420 Pointer<Integer> pErr = ptrs.pErr; 421 long mem; 422 int previousAttempts = 0; 423 do { 424 mem = CL.clCreateFromGLBuffer( 425 getEntity(), 426 usage.getIntFlags(), 427 openGLBufferObject, 428 getPeer(pErr) 429 ); 430 } while (failedForLackOfMemory(pErr.getInt(), previousAttempts++)); 431 return markAsGL(new CLBuffer(this, -1, mem, null, PointerIO.getByteInstance())); 432 } 433 434 /** 435 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateFromGLRenderbuffer.html">clCreateFromGLRenderbuffer</a>.<br> 436 * Makes an OpenGL Render Buffer visible to OpenCL as a 2D image.<br> 437 * Note that memory objects shared with OpenGL must be acquired / released before / after use from OpenCL. 438 * see {@link CLMem#acquireGLObject(com.nativelibs4java.opencl.CLQueue, com.nativelibs4java.opencl.CLEvent[]) } 439 * see {@link CLMem#releaseGLObject(com.nativelibs4java.opencl.CLQueue, com.nativelibs4java.opencl.CLEvent[]) } 440 * @param openGLRenderBuffer Identifier of an OpenGL render buffer 441 */ 442 @SuppressWarnings("deprecation") 443 public CLImage2D createImage2DFromGLRenderBuffer(CLMem.Usage usage, int openGLRenderBuffer) { 444 ReusablePointers ptrs = ReusablePointers.get(); 445 Pointer<Integer> pErr = ptrs.pErr; 446 long mem; 447 int previousAttempts = 0; 448 do { 449 mem = CL.clCreateFromGLRenderbuffer( 450 getEntity(), 451 usage.getIntFlags(), 452 openGLRenderBuffer, 453 getPeer(pErr) 454 ); 455 } while (failedForLackOfMemory(pErr.getInt(), previousAttempts++)); 456 return markAsGL(new CLImage2D(this, mem, null)); 457 } 458 459 /** 460 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateFromGLTexture2D.html">clCreateFromGLTexture2D</a>.<br> 461 * Creates an OpenCL 2D image object from an OpenGL 2D texture object, or a single face of an OpenGL cubemap texture object.<br> 462 * Note that memory objects shared with OpenGL must be acquired / released before / after use from OpenCL. 463 * @param usage 464 * @param textureTarget Must be one of GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, or GL_TEXTURE_RECTANGLE47. texture_target is used only to define the image type of texture. No reference to a bound GL texture object is made or implied by this parameter. 465 * @param mipLevel Mipmap level to be used (Implementations may return CL_INVALID_OPERATION for miplevel values > 0) 466 * @param texture Name of a GL 2D, cubemap or rectangle texture object. The texture object must be a complete texture as per OpenGL rules on texture completeness. The texture format and dimensions defined by OpenGL for the specified miplevel of the texture will be used to create the 2D image object. Only GL texture objects with an internal format that maps to appropriate image channel order and data type specified in tables 5.4 and 5.5 may be used to create a 2D image object. 467 * @return valid OpenCL image object if the image object is created successfully 468 * @throws CLException.InvalidMipLevel if miplevel is less than the value of levelbase (for OpenGL implementations) or zero (for OpenGL ES implementations); or greater than the value of q (for both OpenGL and OpenGL ES). levelbase and q are defined for the texture in section 3.8.10 (Texture Completeness) of the OpenGL 2.1 specification and section 3.7.10 of the OpenGL ES 2.0, or if miplevel is greather than zero and the OpenGL implementation does not support creating from non-zero mipmap levels. 469 * @throws CLException.InvalidGLObject if texture is not a GL texture object whose type matches texture_target, if the specified miplevel of texture is not defined, or if the width or height of the specified miplevel is zero. 470 * @throws CLException.InvalidImageFormatDescriptor if the OpenGL texture internal format does not map to a supported OpenCL image format. 471 */ 472 @SuppressWarnings("deprecation") 473 public CLImage2D createImage2DFromGLTexture2D(CLMem.Usage usage, GLTextureTarget textureTarget, int texture, int mipLevel) { 474 platform.requireMinVersionValue("clCreateFromGLTexture2D", 1.1, 1.2); 475 ReusablePointers ptrs = ReusablePointers.get(); 476 Pointer<Integer> pErr = ptrs.pErr; 477 long mem; 478 int previousAttempts = 0; 479 do { 480 mem = CL.clCreateFromGLTexture2D( 481 getEntity(), 482 usage.getIntFlags(), 483 (int)textureTarget.value(), 484 mipLevel, 485 texture, 486 getPeer(pErr) 487 ); 488 } while (failedForLackOfMemory(pErr.getInt(), previousAttempts++)); 489 return markAsGL(new CLImage2D(this, mem, null)); 490 } 491 492 private static final int 493 GL_TEXTURE_2D = 0x0DE1, 494 GL_TEXTURE_3D = 0x806F, 495 GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515, 496 GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516, 497 GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517, 498 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518, 499 GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519, 500 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A, 501 GL_TEXTURE_RECTANGLE = 0x84F5; 502 503 public CLPlatform getPlatform() { 504 return platform; 505 } 506 507 508 public enum GLTextureTarget implements com.nativelibs4java.util.ValuedEnum { 509 510 Texture2D(GL_TEXTURE_2D), 511 //Texture3D(GL_TEXTURE_3D), 512 CubeMapPositiveX(GL_TEXTURE_CUBE_MAP_POSITIVE_X), 513 CubeMapNegativeX(GL_TEXTURE_CUBE_MAP_NEGATIVE_X), 514 CubeMapPositiveY(GL_TEXTURE_CUBE_MAP_POSITIVE_Y), 515 CubeMapNegativeY(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y), 516 CubeMapPositiveZ(GL_TEXTURE_CUBE_MAP_POSITIVE_Z), 517 CubeMapNegativeZ(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z), 518 Rectangle(GL_TEXTURE_RECTANGLE); 519 520 GLTextureTarget(long value) { this.value = value; } 521 long value; 522 @Override 523 public long value() { return value; } 524 public static GLTextureTarget getEnum(int v) { return EnumValues.getEnum(v, GLTextureTarget.class); } 525 } 526 527 /** 528 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateFromGLTexture3D.html">clCreateFromGLTexture3D</a>.<br> 529 * Creates an OpenCL 3D image object from an OpenGL 3D texture object<br> 530 * Note that memory objects shared with OpenGL must be acquired / released before / after use from OpenCL. 531 * @param usage 532 * @param mipLevel Mipmap level to be used (Implementations may return CL_INVALID_OPERATION for miplevel values > 0) 533 * @param texture Name of a GL 3D texture object. The texture object must be a complete texture as per OpenGL rules on texture completeness. The texture format and dimensions defined by OpenGL for the specified miplevel of the texture will be used to create the 3D image object. Only GL texture objects with an internal format that maps to appropriate image channel order and data type specified in tables 5.4 and 5.5 can be used to create the 3D image object. 534 * @return valid OpenCL image object if the image object is created successfully 535 * @throws CLException.InvalidMipLevel if miplevel is less than the value of levelbase (for OpenGL implementations) or zero (for OpenGL ES implementations); or greater than the value of q (for both OpenGL and OpenGL ES). levelbase and q are defined for the texture in section 3.8.10 (Texture Completeness) of the OpenGL 2.1 specification and section 3.7.10 of the OpenGL ES 2.0, or if miplevel is greather than zero and the OpenGL implementation does not support creating from non-zero mipmap levels. 536 * @throws CLException.InvalidGLObject if texture is not a GL texture object whose type matches texture_target, if the specified miplevel of texture is not defined, or if the width or height of the specified miplevel is zero. 537 * @throws CLException.InvalidImageFormatDescriptor if the OpenGL texture internal format does not map to a supported OpenCL image format. 538 */ 539 @SuppressWarnings("deprecation") 540 public CLImage3D createImage3DFromGLTexture3D(CLMem.Usage usage, int texture, int mipLevel) { 541 platform.requireMinVersionValue("clCreateFromGLTexture3D", 1.1, 1.2); 542 ReusablePointers ptrs = ReusablePointers.get(); 543 Pointer<Integer> pErr = ptrs.pErr; 544 long mem; 545 int previousAttempts = 0; 546 do { 547 mem = CL.clCreateFromGLTexture3D( 548 getEntity(), 549 usage.getIntFlags(), 550 GL_TEXTURE_3D, 551 mipLevel, 552 texture, 553 getPeer(pErr) 554 ); 555 } while (failedForLackOfMemory(pErr.getInt(), previousAttempts++)); 556 return markAsGL(new CLImage3D(this, mem, null)); 557 } 558 559 /** 560 * Create an ARGB input 2D image with the content provided 561 * @param allowUnoptimizingDirectRead Some images expose their internal data for direct read, leading to performance increase during the creation of the OpenCL image. However, direct access to the image data disables some Java2D optimizations for this image, leading to degraded performance in subsequent uses with AWT/Swing. 562 */ 563 public CLImage2D createImage2D(CLMem.Usage usage, Image image, boolean allowUnoptimizingDirectRead) { 564 int width = image.getWidth(null), height = image.getHeight(null); 565 ImageInfo info = ImageIOUtils.getImageInfo(image); 566 return createImage2D( 567 usage, 568 info.clImageFormat, 569 width, height, 570 0, 571 info.dataGetter.getData(image, null, true, allowUnoptimizingDirectRead, getByteOrder()), 572 true); 573 } 574 575 /** 576 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateImage2D.html">clCreateImage2D</a>.<br> 577 * @param usage Usage intended for the image. 578 * @param format Format of the image. 579 * @param width Image width 580 * @param height Image height 581 * @return A new image allocated on this context. 582 * @param rowPitch Row pitch. 583 * @param buffer Image data buffer. 584 * @param copy Whether to copy the input buffer. 585 */ 586 @SuppressWarnings("deprecation") 587 public CLImage2D createImage2D(CLMem.Usage usage, CLImageFormat format, long width, long height, long rowPitch, Buffer buffer, boolean copy) { 588 platform.requireMinVersionValue("clCreateImage2D", 1.1, 1.2); 589 590 long memFlags = usage.getIntFlags(); 591 if (buffer != null) { 592 memFlags |= copy ? CL_MEM_COPY_HOST_PTR : CL_MEM_USE_HOST_PTR; 593 } 594 595 ReusablePointers ptrs = ReusablePointers.get(); 596 Pointer<Integer> pErr = ptrs.pErr; 597 Pointer<cl_image_format> pImageFormat = getPointer(format.to_cl_image_format()); 598 Pointer<?> pBuffer = buffer == null ? null : pointerToBuffer(buffer); 599 long mem; 600 int previousAttempts = 0; 601 do { 602 mem = CL.clCreateImage2D( 603 getEntity(), 604 memFlags, 605 getPeer(pImageFormat), 606 width, 607 height, 608 rowPitch, 609 getPeer(pBuffer), 610 getPeer(pErr)); 611 } while (failedForLackOfMemory(pErr.getInt(), previousAttempts++)); 612 return new CLImage2D(this, mem, format); 613 } 614 615 /** 616 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateImage2D.html">clCreateImage2D</a>.<br> 617 * @param usage Usage intended for the image. 618 * @param format Format of the image. 619 * @param width Image width 620 * @param height Image height 621 * @return A new image allocated on this context. 622 * @param rowPitch Row pitch. 623 */ 624 public CLImage2D createImage2D(CLMem.Usage usage, CLImageFormat format, long width, long height, long rowPitch) { 625 return createImage2D(usage, format, width, height, rowPitch, null, false); 626 } 627 628 /** 629 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateImage2D.html">clCreateImage2D</a>.<br> 630 * @param usage Usage intended for the image. 631 * @param format Format of the image. 632 * @param width Image width 633 * @param height Image height 634 * @return A new image allocated on this context. 635 */ 636 public CLImage2D createImage2D(CLMem.Usage usage, CLImageFormat format, long width, long height) { 637 return createImage2D(usage, format, width, height, 0, null, false); 638 } 639 640 /** 641 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateImage3D.html">clCreateImage3D</a>.<br> 642 * @param usage Usage intended for the image. 643 * @param format Format of the image. 644 * @param width Image width 645 * @param height Image height 646 * @return A new image allocated on this context. 647 * @param depth Image depth 648 * @param rowPitch Row pitch. 649 * @param slicePitch Slice pitch. 650 * @param buffer Image data buffer. 651 * @param copy Whether to copy the input buffer. 652 */ 653 @SuppressWarnings("deprecation") 654 public CLImage3D createImage3D(CLMem.Usage usage, CLImageFormat format, long width, long height, long depth, long rowPitch, long slicePitch, Buffer buffer, boolean copy) { 655 platform.requireMinVersionValue("clCreateImage3D", 1.1, 1.2); 656 long memFlags = usage.getIntFlags(); 657 if (buffer != null) { 658 memFlags |= copy ? CL_MEM_COPY_HOST_PTR : CL_MEM_USE_HOST_PTR; 659 } 660 661 ReusablePointers ptrs = ReusablePointers.get(); 662 Pointer<Integer> pErr = ptrs.pErr; 663 Pointer<cl_image_format> pImageFormat = getPointer(format.to_cl_image_format()); 664 Pointer<?> pBuffer = buffer == null ? null : pointerToBuffer(buffer); 665 long mem; 666 int previousAttempts = 0; 667 do { 668 mem = CL.clCreateImage3D( 669 getEntity(), 670 memFlags, 671 getPeer(pImageFormat), 672 width, 673 height, 674 depth, 675 rowPitch, 676 slicePitch, 677 getPeer(pBuffer), 678 getPeer(pErr)); 679 } while (failedForLackOfMemory(pErr.getInt(), previousAttempts++)); 680 return new CLImage3D(this, mem, format); 681 } 682 683 /** 684 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateImage3D.html">clCreateImage3D</a>.<br> 685 * @param usage Usage intended for the image. 686 * @param format Format of the image. 687 * @param width Image width 688 * @param height Image height 689 * @return A new image allocated on this context. 690 * @param depth Image depth 691 * @param rowPitch Row pitch. 692 * @param slicePitch Slice pitch. 693 */ 694 public CLImage3D createImage3D(CLMem.Usage usage, CLImageFormat format, long width, long height, long depth, long rowPitch, long slicePitch) { 695 return createImage3D(usage, format, width, height, depth, rowPitch, slicePitch, null, false); 696 } 697 698 /** 699 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateImage3D.html">clCreateImage3D</a>.<br> 700 * @param usage Usage intended for the image. 701 * @param format Format of the image. 702 * @param width Image width 703 * @param height Image height 704 * @return A new image allocated on this context. 705 * @param depth Image depth 706 */ 707 public CLImage3D createImage3D(CLMem.Usage usage, CLImageFormat format, long width, long height, long depth) { 708 return createImage3D(usage, format, width, height, depth, 0, 0, null, false); 709 } 710 711 712 /** 713 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 714 * Create a <code>CLBuffer<Integer></code> OpenCL buffer with the provided initial values.<br> 715 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 716 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 717 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 718 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 719 * @param data Data buffer. 720 * @param copy Whether to copy the input data. 721 * @return A new buffer allocated on this context. 722 */ 723 public CLBuffer<Integer> createIntBuffer(CLMem.Usage usage, IntBuffer data, boolean copy) { 724 return createBuffer(usage, Pointer.pointerToInts(data), copy); 725 } 726 727 /** 728 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 729 * Create a <code>CLBuffer<Integer></code> OpenCL buffer big enough to hold the valid values of the provided data pointer. 730 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 731 * @param data Host data to copy to the buffer 732 * @return A new buffer allocated on this context. 733 */ 734 public CLBuffer<Integer> createIntBuffer(CLMem.Usage usage, Pointer<Integer> data) { 735 return createIntBuffer(usage, data, true); 736 } 737 /** 738 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 739 * Create a <code>CLBuffer<Integer></code> OpenCL buffer with the provided initial values.<br> 740 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 741 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 742 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 743 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 744 * @param data Data buffer. 745 * @param copy Whether to copy the input data. 746 * @return A new buffer allocated on this context. 747 */ 748 public CLBuffer<Integer> createIntBuffer(CLMem.Usage usage, Pointer<Integer> data, boolean copy) { 749 return createBuffer(usage, data, copy); 750 } 751 752 /** 753 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 754 * Create a <code>CLBuffer<Integer></code> OpenCL buffer big enough to hold 'length' values of type int. 755 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 756 757 * @param elementCount Length of the buffer expressed in elements (for instance, a <code>CLBuffer<Integer></code> of length 10 will actually contain 10 * 4 bytes, as ints are 4-bytes-long) 758 * @return A new buffer allocated on this context. 759 */ 760 public CLBuffer<Integer> createIntBuffer(CLMem.Usage usage, long elementCount) { 761 return createBuffer(usage, Integer.class, elementCount); 762 } 763 764 765 /** 766 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 767 * Create a <code>CLBuffer<Long></code> OpenCL buffer with the provided initial values.<br> 768 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 769 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 770 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 771 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 772 * @param data Data buffer. 773 * @param copy Whether to copy the input data. 774 * @return A new buffer allocated on this context. 775 */ 776 public CLBuffer<Long> createLongBuffer(CLMem.Usage usage, LongBuffer data, boolean copy) { 777 return createBuffer(usage, Pointer.pointerToLongs(data), copy); 778 } 779 780 /** 781 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 782 * Create a <code>CLBuffer<Long></code> OpenCL buffer big enough to hold the valid values of the provided data pointer. 783 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 784 * @param data Host data to copy to the buffer 785 * @return A new buffer allocated on this context. 786 */ 787 public CLBuffer<Long> createLongBuffer(CLMem.Usage usage, Pointer<Long> data) { 788 return createLongBuffer(usage, data, true); 789 } 790 /** 791 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 792 * Create a <code>CLBuffer<Long></code> OpenCL buffer with the provided initial values.<br> 793 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 794 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 795 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 796 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 797 * @param data Data buffer. 798 * @param copy Whether to copy the input data. 799 * @return A new buffer allocated on this context. 800 */ 801 public CLBuffer<Long> createLongBuffer(CLMem.Usage usage, Pointer<Long> data, boolean copy) { 802 return createBuffer(usage, data, copy); 803 } 804 805 /** 806 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 807 * Create a <code>CLBuffer<Long></code> OpenCL buffer big enough to hold 'length' values of type long. 808 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 809 810 * @param elementCount Length of the buffer expressed in elements (for instance, a <code>CLBuffer<Long></code> of length 10 will actually contain 10 * 8 bytes, as longs are 8-bytes-long) 811 * @return A new buffer allocated on this context. 812 */ 813 public CLBuffer<Long> createLongBuffer(CLMem.Usage usage, long elementCount) { 814 return createBuffer(usage, Long.class, elementCount); 815 } 816 817 818 /** 819 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 820 * Create a <code>CLBuffer<Short></code> OpenCL buffer with the provided initial values.<br> 821 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 822 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 823 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 824 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 825 * @param data Data buffer. 826 * @param copy Whether to copy the input data. 827 * @return A new buffer allocated on this context. 828 */ 829 public CLBuffer<Short> createShortBuffer(CLMem.Usage usage, ShortBuffer data, boolean copy) { 830 return createBuffer(usage, Pointer.pointerToShorts(data), copy); 831 } 832 833 /** 834 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 835 * Create a <code>CLBuffer<Short></code> OpenCL buffer big enough to hold the valid values of the provided data pointer. 836 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 837 * @param data Host data to copy to the buffer 838 * @return A new buffer allocated on this context. 839 */ 840 public CLBuffer<Short> createShortBuffer(CLMem.Usage usage, Pointer<Short> data) { 841 return createShortBuffer(usage, data, true); 842 } 843 /** 844 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 845 * Create a <code>CLBuffer<Short></code> OpenCL buffer with the provided initial values.<br> 846 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 847 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 848 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 849 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 850 * @param data Data buffer. 851 * @param copy Whether to copy the input data. 852 * @return A new buffer allocated on this context. 853 */ 854 public CLBuffer<Short> createShortBuffer(CLMem.Usage usage, Pointer<Short> data, boolean copy) { 855 return createBuffer(usage, data, copy); 856 } 857 858 /** 859 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 860 * Create a <code>CLBuffer<Short></code> OpenCL buffer big enough to hold 'length' values of type short. 861 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 862 863 * @param elementCount Length of the buffer expressed in elements (for instance, a <code>CLBuffer<Short></code> of length 10 will actually contain 10 * 2 bytes, as shorts are 2-bytes-long) 864 * @return A new buffer allocated on this context. 865 */ 866 public CLBuffer<Short> createShortBuffer(CLMem.Usage usage, long elementCount) { 867 return createBuffer(usage, Short.class, elementCount); 868 } 869 870 871 /** 872 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 873 * Create a <code>CLBuffer<Byte></code> OpenCL buffer with the provided initial values.<br> 874 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 875 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 876 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 877 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 878 * @param data Data buffer. 879 * @param copy Whether to copy the input data. 880 * @return A new buffer allocated on this context. 881 */ 882 public CLBuffer<Byte> createByteBuffer(CLMem.Usage usage, Buffer data, boolean copy) { 883 return createBuffer(usage, Pointer.pointerToBuffer(data).as(Byte.class), copy); 884 } 885 886 /** 887 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 888 * Create a <code>CLBuffer<Byte></code> OpenCL buffer big enough to hold the valid values of the provided data pointer. 889 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 890 * @param data Host data to copy to the buffer 891 * @return A new buffer allocated on this context. 892 */ 893 public CLBuffer<Byte> createByteBuffer(CLMem.Usage usage, Pointer<Byte> data) { 894 return createByteBuffer(usage, data, true); 895 } 896 /** 897 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 898 * Create a <code>CLBuffer<Byte></code> OpenCL buffer with the provided initial values.<br> 899 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 900 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 901 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 902 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 903 * @param data Data buffer. 904 * @param copy Whether to copy the input data. 905 * @return A new buffer allocated on this context. 906 */ 907 public CLBuffer<Byte> createByteBuffer(CLMem.Usage usage, Pointer<Byte> data, boolean copy) { 908 return createBuffer(usage, data, copy); 909 } 910 911 /** 912 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 913 * Create a <code>CLBuffer<Byte></code> OpenCL buffer big enough to hold 'length' values of type byte. 914 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 915 916 * @param elementCount Length of the buffer expressed in elements (for instance, a <code>CLBuffer<Byte></code> of length 10 will actually contain 10 * 1 bytes, as bytes are 1-bytes-long) 917 * @return A new buffer allocated on this context. 918 */ 919 public CLBuffer<Byte> createByteBuffer(CLMem.Usage usage, long elementCount) { 920 return createBuffer(usage, Byte.class, elementCount); 921 } 922 923 924 /** 925 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 926 * Create a <code>CLBuffer<Character></code> OpenCL buffer with the provided initial values.<br> 927 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 928 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 929 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 930 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 931 * @param data Data buffer. 932 * @param copy Whether to copy the input data. 933 * @return A new buffer allocated on this context. 934 */ 935 public CLBuffer<Character> createCharBuffer(CLMem.Usage usage, CharBuffer data, boolean copy) { 936 return createBuffer(usage, Pointer.pointerToChars(data), copy); 937 } 938 939 /** 940 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 941 * Create a <code>CLBuffer<Character></code> OpenCL buffer big enough to hold the valid values of the provided data pointer. 942 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 943 * @param data Host data to copy to the buffer 944 * @return A new buffer allocated on this context. 945 */ 946 public CLBuffer<Character> createCharBuffer(CLMem.Usage usage, Pointer<Character> data) { 947 return createCharBuffer(usage, data, true); 948 } 949 /** 950 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 951 * Create a <code>CLBuffer<Character></code> OpenCL buffer with the provided initial values.<br> 952 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 953 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 954 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 955 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 956 * @param data Data buffer. 957 * @param copy Whether to copy the input data. 958 * @return A new buffer allocated on this context. 959 */ 960 public CLBuffer<Character> createCharBuffer(CLMem.Usage usage, Pointer<Character> data, boolean copy) { 961 return createBuffer(usage, data, copy); 962 } 963 964 /** 965 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 966 * Create a <code>CLBuffer<Character></code> OpenCL buffer big enough to hold 'length' values of type char. 967 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 968 969 * @param elementCount Length of the buffer expressed in elements (for instance, a <code>CLBuffer<Character></code> of length 10 will actually contain 10 * 2 bytes, as chars are 2-bytes-long) 970 * @return A new buffer allocated on this context. 971 */ 972 public CLBuffer<Character> createCharBuffer(CLMem.Usage usage, long elementCount) { 973 return createBuffer(usage, Character.class, elementCount); 974 } 975 976 977 /** 978 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 979 * Create a <code>CLBuffer<Float></code> OpenCL buffer with the provided initial values.<br> 980 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 981 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 982 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 983 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 984 * @param data Data buffer. 985 * @param copy Whether to copy the input data. 986 * @return A new buffer allocated on this context. 987 */ 988 public CLBuffer<Float> createFloatBuffer(CLMem.Usage usage, FloatBuffer data, boolean copy) { 989 return createBuffer(usage, Pointer.pointerToFloats(data), copy); 990 } 991 992 /** 993 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 994 * Create a <code>CLBuffer<Float></code> OpenCL buffer big enough to hold the valid values of the provided data pointer. 995 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 996 * @param data Host data to copy to the buffer 997 * @return A new buffer allocated on this context. 998 */ 999 public CLBuffer<Float> createFloatBuffer(CLMem.Usage usage, Pointer<Float> data) { 1000 return createFloatBuffer(usage, data, true); 1001 } 1002 /** 1003 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1004 * Create a <code>CLBuffer<Float></code> OpenCL buffer with the provided initial values.<br> 1005 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 1006 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 1007 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1008 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 1009 * @param data Data buffer. 1010 * @param copy Whether to copy the input data. 1011 * @return A new buffer allocated on this context. 1012 */ 1013 public CLBuffer<Float> createFloatBuffer(CLMem.Usage usage, Pointer<Float> data, boolean copy) { 1014 return createBuffer(usage, data, copy); 1015 } 1016 1017 /** 1018 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1019 * Create a <code>CLBuffer<Float></code> OpenCL buffer big enough to hold 'length' values of type float. 1020 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1021 1022 * @param elementCount Length of the buffer expressed in elements (for instance, a <code>CLBuffer<Float></code> of length 10 will actually contain 10 * 4 bytes, as floats are 4-bytes-long) 1023 * @return A new buffer allocated on this context. 1024 */ 1025 public CLBuffer<Float> createFloatBuffer(CLMem.Usage usage, long elementCount) { 1026 return createBuffer(usage, Float.class, elementCount); 1027 } 1028 1029 1030 /** 1031 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1032 * Create a <code>CLBuffer<Double></code> OpenCL buffer with the provided initial values.<br> 1033 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 1034 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 1035 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1036 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 1037 * @param data Data buffer. 1038 * @param copy Whether to copy the input data. 1039 * @return A new buffer allocated on this context. 1040 */ 1041 public CLBuffer<Double> createDoubleBuffer(CLMem.Usage usage, DoubleBuffer data, boolean copy) { 1042 return createBuffer(usage, Pointer.pointerToDoubles(data), copy); 1043 } 1044 1045 /** 1046 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1047 * Create a <code>CLBuffer<Double></code> OpenCL buffer big enough to hold the valid values of the provided data pointer. 1048 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1049 * @param data Host data to copy to the buffer 1050 * @return A new buffer allocated on this context. 1051 */ 1052 public CLBuffer<Double> createDoubleBuffer(CLMem.Usage usage, Pointer<Double> data) { 1053 return createDoubleBuffer(usage, data, true); 1054 } 1055 /** 1056 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1057 * Create a <code>CLBuffer<Double></code> OpenCL buffer with the provided initial values.<br> 1058 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 1059 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 1060 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1061 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 1062 * @param data Data buffer. 1063 * @param copy Whether to copy the input data. 1064 * @return A new buffer allocated on this context. 1065 */ 1066 public CLBuffer<Double> createDoubleBuffer(CLMem.Usage usage, Pointer<Double> data, boolean copy) { 1067 return createBuffer(usage, data, copy); 1068 } 1069 1070 /** 1071 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1072 * Create a <code>CLBuffer<Double></code> OpenCL buffer big enough to hold 'length' values of type double. 1073 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1074 1075 * @param elementCount Length of the buffer expressed in elements (for instance, a <code>CLBuffer<Double></code> of length 10 will actually contain 10 * 8 bytes, as doubles are 8-bytes-long) 1076 * @return A new buffer allocated on this context. 1077 */ 1078 public CLBuffer<Double> createDoubleBuffer(CLMem.Usage usage, long elementCount) { 1079 return createBuffer(usage, Double.class, elementCount); 1080 } 1081 1082 1083 /** 1084 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1085 * Create an OpenCL buffer with the provided initial values, in copy mode (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>). 1086 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1087 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}) 1088 */ 1089 public <T> CLBuffer<T> createBuffer(CLMem.Usage usage, Pointer<T> data) { 1090 return createBuffer(usage, data, true); 1091 } 1092 1093 /** 1094 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1095 * Create a <code>CLBuffer<N></code> OpenCL buffer with the provided initial values.<br> 1096 * If copy is true (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_COPY_HOST_PTR</a>), then the buffer will be hosted in OpenCL and will have the best performance, but any change done to the OpenCL buffer won't be propagated to the original data pointer.<br> 1097 * If copy is false (see <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html">CL_MEM_USE_HOST_PTR</a>), then the provided data pointer will be used for storage of the OpenCL buffer. OpenCL might still cache the data in the OpenCL land, so careful use of {@link CLBuffer#map(CLQueue, CLMem.MapFlags, CLEvent...) CLBuffer#map(CLQueue, MapFlags, CLEvent...)} is then necessary to ensure the data is properly synchronized with the buffer. 1098 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1099 * @param data Pointer to the initial values, must have known bounds (see {@link Pointer#getValidElements()}). 1100 * @param data Data buffer. 1101 * @param copy Whether to copy the input data. 1102 * @return A new buffer allocated on this context. 1103 */ 1104 public <T> CLBuffer<T> createBuffer(CLMem.Usage usage, Pointer<T> data, boolean copy) { 1105 return createBuffer(data.getIO(), data, data.getValidBytes(), usage.getIntFlags() | (copy ? CL_MEM_COPY_HOST_PTR : CL_MEM_USE_HOST_PTR), copy); 1106 } 1107 1108 /** 1109 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1110 * Create a <code>CLBuffer<N></code> OpenCL buffer big enough to hold 'length' values of type T. 1111 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1112 * @param elementClass Primitive type of the buffer. For instance a buffer of 'int' values can be created with elementClass being Integer.class or int.class indifferently. 1113 * @param elementCount Length of the buffer expressed in elements 1114 * @return A new buffer allocated on this context. 1115 */ 1116 public <T> CLBuffer<T> createBuffer(CLMem.Usage usage, Class<T> elementClass, long elementCount) { 1117 PointerIO<T> io = PointerIO.getInstance(elementClass); 1118 if (io == null) 1119 throw new IllegalArgumentException("Unknown target type : " + elementClass.getName()); 1120 return createBuffer(usage, io, elementCount); 1121 } 1122 1123 /** 1124 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1125 * Create an OpenCL buffer big enough to hold the provided amount of values of the specified type. 1126 * @param usage Usage intended for the pointer in OpenCL kernels : a pointer created with {@link CLMem.Usage#Input} cannot be written to in a kernel. 1127 * @param io Delegate responsible for reading and writing values. 1128 * @param elementCount Length of the buffer expressed in elements (for instance, a CLBuffer<Integer> of length 4 will actually contain 4 * 4 bytes, as ints are 4-bytes-long) 1129 * @deprecated Intended for advanced uses in conjunction with BridJ. 1130 */ 1131 @Deprecated 1132 public <T> CLBuffer<T> createBuffer(CLMem.Usage usage, PointerIO<T> io, long elementCount) { 1133 return createBuffer(io, null, io.getTargetSize() * elementCount, usage.getIntFlags(), false); 1134 } 1135 1136 /** 1137 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateBuffer.html">clCreateBuffer</a>.<br> 1138 */ 1139 @SuppressWarnings("deprecation") 1140 private <T> CLBuffer<T> createBuffer(PointerIO<T> io, Pointer<T> data, long byteCount, final int CLBufferFlags, final boolean retainBufferReference) { 1141 if (byteCount <= 0) 1142 throw new IllegalArgumentException("Buffer size must be greater than zero (asked for size " + byteCount + ")"); 1143 1144 if (byteCount > getMaxMemAllocSize()) 1145 throw new OutOfMemoryError("Requested size for buffer allocation is more than the maximum for this context : " + byteCount + " > " + getMaxMemAllocSize()); 1146 1147 if (data != null) { 1148 ByteOrder contextOrder = getByteOrder(); 1149 ByteOrder dataOrder = data.order(); 1150 if (contextOrder != null && !dataOrder.equals(contextOrder) && data.getTargetSize() > 1) 1151 throw new IllegalArgumentException("Byte order of this context is " + contextOrder + ", but was given pointer to data with order " + dataOrder + ". Please create a pointer with correct byte order (Pointer.order(CLContext.getByteOrder()))."); 1152 } 1153 1154 ReusablePointers ptrs = ReusablePointers.get(); 1155 Pointer<Integer> pErr = ptrs.pErr; 1156 long mem; 1157 int previousAttempts = 0; 1158 do { 1159 mem = CL.clCreateBuffer( 1160 getEntity(), 1161 CLBufferFlags, 1162 byteCount, 1163 getPeer(data), 1164 getPeer(pErr)); 1165 } while (failedForLackOfMemory(pErr.getInt(), previousAttempts++)); 1166 return new CLBuffer<T>(this, byteCount, mem, retainBufferReference ? data : null, io); 1167 } 1168 1169 public ByteOrder getKernelsDefaultByteOrder() { 1170 if (kernelsDefaultByteOrder == null) { 1171 ByteOrder order = null; 1172 for (CLDevice device : getDevices()) { 1173 ByteOrder devOrder = device.getKernelsDefaultByteOrder(); 1174 if (order != null && devOrder != order) 1175 return null; 1176 order = devOrder; 1177 } 1178 kernelsDefaultByteOrder = order; 1179 } 1180 return kernelsDefaultByteOrder; 1181 } 1182 1183 private volatile ByteOrder byteOrder, kernelsDefaultByteOrder; 1184 1185 /** 1186 * Get the endianness common to all devices of this context, or null if the devices have mismatching endiannesses. 1187 */ 1188 public ByteOrder getByteOrder() { 1189 if (byteOrder == null) { 1190 ByteOrder order = null; 1191 for (CLDevice device : getDevices()) { 1192 ByteOrder devOrder = device.getByteOrder(); 1193 if (order != null && devOrder != order) 1194 return null; 1195 order = devOrder; 1196 } 1197 byteOrder = order; 1198 } 1199 return byteOrder; 1200 } 1201 1202 private volatile int addressBits = -2; 1203 1204 /** 1205 * Return the number of bits used to represent a pointer on all of the context's devices, or -1 if not all devices use the same number of bits.<br> 1206 * Size of size_t type in OpenCL kernels can be obtained with getAddressBits() / 8. 1207 * @return -1 if the address bits of the context's devices do not match, common address bits otherwise 1208 */ 1209 public int getAddressBits() { 1210 if (addressBits == -2) { 1211 synchronized (this) { 1212 if (addressBits == -2) { 1213 for (CLDevice device : getDevices()) { 1214 int bits = device.getAddressBits(); 1215 if (addressBits != -2 && bits != addressBits) { 1216 addressBits = -1; 1217 break; 1218 } 1219 addressBits = bits; 1220 } 1221 } 1222 } 1223 } 1224 return addressBits; 1225 } 1226 1227 private volatile Boolean doubleSupported; 1228 1229 /** 1230 * Whether all the devices in this context support any double-precision numbers (see {@link CLDevice#isDoubleSupported()}). 1231 */ 1232 public boolean isDoubleSupported() { 1233 if (doubleSupported == null) { 1234 boolean supported = true; 1235 for (CLDevice device : getDevices()) { 1236 if (!device.isDoubleSupported()) { 1237 supported = false; 1238 break; 1239 } 1240 } 1241 doubleSupported = supported; 1242 } 1243 return doubleSupported; 1244 } 1245 1246 private volatile Boolean halfSupported; 1247 1248 /** 1249 * Whether all the devices in this context support half-precision numbers (see {@link CLDevice#isHalfSupported()}). 1250 */ 1251 public boolean isHalfSupported() { 1252 if (halfSupported == null) { 1253 boolean supported = true; 1254 for (CLDevice device : getDevices()) { 1255 if (!device.isHalfSupported()) { 1256 supported = false; 1257 break; 1258 } 1259 } 1260 halfSupported = supported; 1261 } 1262 return halfSupported; 1263 } 1264 1265 private volatile Boolean byteAddressableStoreSupported; 1266 1267 public boolean isByteAddressableStoreSupported() { 1268 if (byteAddressableStoreSupported == null) { 1269 boolean supported = true; 1270 for (CLDevice device : getDevices()) { 1271 if (!device.isByteAddressableStoreSupported()) { 1272 supported = false; 1273 break; 1274 } 1275 } 1276 byteAddressableStoreSupported = supported; 1277 } 1278 return byteAddressableStoreSupported; 1279 } 1280}