|
From: <sp...@us...> - 2010-09-30 17:21:59
|
Revision: 3419
http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3419&view=rev
Author: spasi
Date: 2010-09-30 17:21:50 +0000 (Thu, 30 Sep 2010)
Log Message:
-----------
Misc GL/CL fixes and additions.
Made native calls package private, we can now use them from the high-level API.
Added support for "render-to-texture" in the fractal demo.
Modified Paths:
--------------
trunk/LWJGL/src/java/org/lwjgl/BufferChecks.java
trunk/LWJGL/src/java/org/lwjgl/LWJGLUtil.java
trunk/LWJGL/src/java/org/lwjgl/PointerWrapperAbstract.java
trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java
trunk/LWJGL/src/java/org/lwjgl/opencl/CLChecks.java
trunk/LWJGL/src/java/org/lwjgl/opencl/CLContext.java
trunk/LWJGL/src/java/org/lwjgl/opencl/CLMem.java
trunk/LWJGL/src/java/org/lwjgl/opencl/CLProgram.java
trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilAbstract.java
trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java
trunk/LWJGL/src/java/org/lwjgl/opencl/Util.java
trunk/LWJGL/src/java/org/lwjgl/test/opencl/gl/DemoFractal.java
trunk/LWJGL/src/java/org/lwjgl/test/opencl/gl/Mandelbrot.cl
trunk/LWJGL/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java
trunk/LWJGL/src/templates/org/lwjgl/opengl/EXT_direct_state_access.java
trunk/LWJGL/src/templates/org/lwjgl/opengl/GL40.java
trunk/LWJGL/src/templates/org/lwjgl/opengl/NV_half_float.java
Added Paths:
-----------
trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLBufferRegion.java
trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLImageFormat.java
Modified: trunk/LWJGL/src/java/org/lwjgl/BufferChecks.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/BufferChecks.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/BufferChecks.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -31,13 +31,7 @@
*/
package org.lwjgl;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-import java.nio.LongBuffer;
+import java.nio.*;
/**
* <p>A class to check buffer boundaries in general. If there is unsufficient space
@@ -89,21 +83,21 @@
/** Helper method to ensure an IntBuffer is null-terminated */
public static void checkNullTerminated(IntBuffer buf) {
- if ( buf.get(buf.limit() - 1) != 0 ) {
+ if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
throw new IllegalArgumentException("Missing null termination");
}
}
/** Helper method to ensure a LongBuffer is null-terminated */
public static void checkNullTerminated(LongBuffer buf) {
- if ( buf.get(buf.limit() - 1) != 0 ) {
+ if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
throw new IllegalArgumentException("Missing null termination");
}
}
/** Helper method to ensure a PointerBuffer is null-terminated */
public static void checkNullTerminated(PointerBuffer buf) {
- if ( buf.get(buf.limit() - 1) != 0 ) {
+ if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
throw new IllegalArgumentException("Missing null termination");
}
}
@@ -196,6 +190,41 @@
}
}
+ /**
+ * Detects the buffer type and performs the corresponding check
+ * and also returns the buffer position in bytes.
+ *
+ * @param buffer the buffer to check
+ * @param size the size to check
+ *
+ * @return the buffer position in bytes
+ */
+ public static int checkBuffer(final Buffer buffer, final int size) {
+ final int posShift;
+ if ( buffer instanceof ByteBuffer ) {
+ BufferChecks.checkBuffer((ByteBuffer)buffer, size);
+ posShift = 0;
+ } else if ( buffer instanceof ShortBuffer ) {
+ BufferChecks.checkBuffer((ShortBuffer)buffer, size);
+ posShift = 1;
+ } else if ( buffer instanceof IntBuffer ) {
+ BufferChecks.checkBuffer((IntBuffer)buffer, size);
+ posShift = 2;
+ } else if ( buffer instanceof LongBuffer ) {
+ BufferChecks.checkBuffer((LongBuffer)buffer, size);
+ posShift = 4;
+ } else if ( buffer instanceof FloatBuffer ) {
+ BufferChecks.checkBuffer((FloatBuffer)buffer, size);
+ posShift = 2;
+ } else if ( buffer instanceof DoubleBuffer ) {
+ BufferChecks.checkBuffer((DoubleBuffer)buffer, size);
+ posShift = 4;
+ } else
+ throw new IllegalArgumentException("Unsupported Buffer type specified: " + buffer.getClass());
+
+ return buffer.position() << posShift;
+ }
+
public static void checkBuffer(ByteBuffer buf, int size) {
if ( LWJGLUtil.CHECKS ) {
checkBufferSize(buf, size);
Modified: trunk/LWJGL/src/java/org/lwjgl/LWJGLUtil.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/LWJGLUtil.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/LWJGLUtil.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -32,17 +32,16 @@
package org.lwjgl;
import java.io.File;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
+import java.util.*;
-
/**
* <p>
* Internal library methods
@@ -488,4 +487,92 @@
return major > major_required || (major == major_required && minor >= minor_required);
}
-}
+ /**
+ * Returns a map of public static final integer fields in the specified classes, to their String representations.
+ * An optional filter can be specified to only include specific fields. The target map may be null, in which
+ * case a new map is allocated and returned.
+ * <p>
+ * This method is useful when debugging to quickly identify values returned from the AL/GL/CL APIs.
+ *
+ * @param filter the filter to use (optional)
+ * @param target the target map (optional)
+ * @param tokenClasses an array of classes to get tokens from
+ *
+ * @return the token map
+ */
+
+ public static Map<Integer, String> getClassTokens(final TokenFilter filter, final Map<Integer, String> target, final Class ... tokenClasses) {
+ return getClassTokens(filter, target, Arrays.asList(tokenClasses));
+ }
+
+ /**
+ * Returns a map of public static final integer fields in the specified classes, to their String representations.
+ * An optional filter can be specified to only include specific fields. The target map may be null, in which
+ * case a new map is allocated and returned.
+ * <p>
+ * This method is useful when debugging to quickly identify values returned from the AL/GL/CL APIs.
+ *
+ * @param filter the filter to use (optional)
+ * @param target the target map (optional)
+ * @param tokenClasses the classes to get tokens from
+ *
+ * @return the token map
+ */
+ public static Map<Integer, String> getClassTokens(final TokenFilter filter, Map<Integer, String> target, final Iterable<Class> tokenClasses) {
+ if ( target == null )
+ target = new HashMap<Integer, String>();
+
+ final int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
+
+ for ( final Class tokenClass : tokenClasses ) {
+ for ( final Field field : tokenClass.getDeclaredFields() ) {
+ // Get only <public static final int> fields.
+ if ( (field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class ) {
+ try {
+ final int value = field.getInt(null);
+ if ( filter != null && !filter.accept(field, value) )
+ continue;
+
+ if ( target.containsKey(value) ) // Print colliding tokens in their hex representation.
+ target.put(value, toHexString(value));
+ else
+ target.put(value, field.getName());
+ } catch (IllegalAccessException e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+ return target;
+ }
+
+ /**
+ * Returns a string representation of the integer argument as an
+ * unsigned integer in base 16. The string will be uppercase
+ * and will have a leading '0x'.
+ *
+ * @param value the integer value
+ *
+ * @return the hex string representation
+ */
+ public static String toHexString(final int value) {
+ return "0x" + Integer.toHexString(value).toUpperCase();
+ }
+
+ /** Simple interface for Field filtering. */
+ public interface TokenFilter {
+
+ /**
+ * Should return true if the specified Field passes the filter.
+ *
+ * @param field the Field to test
+ * @param value the integer value of the field
+ *
+ * @result true if the Field is accepted
+ */
+ boolean accept(Field field, int value);
+
+ }
+
+}
\ No newline at end of file
Modified: trunk/LWJGL/src/java/org/lwjgl/PointerWrapperAbstract.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/PointerWrapperAbstract.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/PointerWrapperAbstract.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -63,7 +63,7 @@
*/
public final void checkValid() {
if ( LWJGLUtil.DEBUG && !isValid() )
- throw new IllegalStateException("This pointer is not valid.");
+ throw new IllegalStateException("This " + getClass().getSimpleName() + " pointer is not valid.");
}
public final long getPointer() {
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/APIUtil.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -35,18 +35,15 @@
import org.lwjgl.LWJGLUtil;
import org.lwjgl.PointerBuffer;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
import java.nio.*;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
-import java.util.*;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
-import static org.lwjgl.opencl.CL10.*;
-
/**
* Utility class for OpenCL API calls.
- * TODO: Remove useless stuff
*
* @author spasi
*/
@@ -356,38 +353,6 @@
return (int)size;
}
- static String toHexString(final int value) {
- return "0x" + Integer.toHexString(value).toUpperCase();
- }
-
- static void getClassTokens(final Class[] tokenClasses, final Map<Integer, String> target, final TokenFilter filter) {
- getClassTokens(Arrays.asList(tokenClasses), target, filter);
- }
-
- static void getClassTokens(final Iterable<Class> tokenClasses, final Map<Integer, String> target, final TokenFilter filter) {
- final int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
-
- for ( final Class tokenClass : tokenClasses ) {
- for ( final Field field : tokenClass.getDeclaredFields() ) {
- // Get only <public static final int> fields.
- if ( (field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class ) {
- try {
- final int value = field.getInt(null);
- if ( filter != null && !filter.accept(field, value) )
- continue;
-
- if ( target.containsKey(value) ) // Print colliding tokens in their hex representation.
- target.put(value, toHexString(value));
- else
- target.put(value, field.getName());
- } catch (IllegalAccessException e) {
- // Ignore
- }
- }
- }
- }
- }
-
/**
* A mutable CharSequence with very large initial length. We can wrap this in a re-usable CharBuffer for decoding.
* We cannot subclass CharBuffer because of {@link java.nio.CharBuffer#toString(int,int)}.
@@ -451,14 +416,6 @@
}
- /** Simple interface for Field filtering */
- interface TokenFilter {
-
- /** Should return true if the specified Field passes the filter. */
- boolean accept(Field field, int value);
-
- }
-
/* ------------------------------------------------------------------------
---------------------------------------------------------------------------
OPENCL API UTILITIES BELOW
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/CLChecks.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/CLChecks.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/CLChecks.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -68,24 +68,24 @@
final long y = origin.get(1);
final long z = origin.get(2);
- if ( x < 0 || y < 0 || z < 0 )
+ if ( LWJGLUtil.DEBUG && (x < 0 || y < 0 || z < 0) )
throw new IllegalArgumentException("Invalid cl_mem host origin: " + x + ", " + y + ", " + z);
final long w = region.get(0);
final long h = region.get(1);
final long d = region.get(2);
- if ( w < 1 || h < 1 || d < 1 )
+ if ( LWJGLUtil.DEBUG && (w < 1 || h < 1 || d < 1) )
throw new IllegalArgumentException("Invalid cl_mem rectangle region dimensions: " + w + " x " + h + " x " + d);
if ( row_pitch == 0 )
row_pitch = w;
- else if ( row_pitch < w )
+ else if ( LWJGLUtil.DEBUG && row_pitch < w )
throw new IllegalArgumentException("Invalid host row pitch specified: " + row_pitch);
if ( slice_pitch == 0 )
slice_pitch = row_pitch * h;
- else if ( slice_pitch < (row_pitch * h) )
+ else if ( LWJGLUtil.DEBUG && slice_pitch < (row_pitch * h) )
throw new IllegalArgumentException("Invalid host slice pitch specified: " + slice_pitch);
return (int)((z * slice_pitch + y * row_pitch + x) + (w * h * d));
@@ -110,17 +110,17 @@
final long h = region.get(1);
final long d = region.get(2);
- if ( w < 1 || h < 1 || d < 1 )
+ if ( LWJGLUtil.DEBUG && (w < 1 || h < 1 || d < 1) )
throw new IllegalArgumentException("Invalid cl_mem image region dimensions: " + w + " x " + h + " x " + d);
if ( row_pitch == 0 )
row_pitch = w;
- else if ( row_pitch < w )
+ else if ( LWJGLUtil.DEBUG && row_pitch < w )
throw new IllegalArgumentException("Invalid row pitch specified: " + row_pitch);
if ( slice_pitch == 0 )
slice_pitch = row_pitch * h;
- else if ( slice_pitch < (row_pitch * h) )
+ else if ( LWJGLUtil.DEBUG && slice_pitch < (row_pitch * h) )
throw new IllegalArgumentException("Invalid slice pitch specified: " + slice_pitch);
return (int)(slice_pitch * d);
@@ -138,14 +138,17 @@
* @return the 2D image size in bytes
*/
static int calculateImage2DSize(final ByteBuffer format, final long w, final long h, long row_pitch) {
- if ( LWJGLUtil.CHECKS && (w < 1 || h < 1) )
+ if ( !LWJGLUtil.CHECKS )
+ return 0;
+
+ if ( LWJGLUtil.DEBUG && (w < 1 || h < 1) )
throw new IllegalArgumentException("Invalid 2D image dimensions: " + w + " x " + h);
final int elementSize = getElementSize(format);
if ( row_pitch == 0 )
row_pitch = w * elementSize;
- else if ( LWJGLUtil.CHECKS && ((row_pitch < w * elementSize) || (row_pitch % elementSize != 0)) )
+ else if ( LWJGLUtil.DEBUG && ((row_pitch < w * elementSize) || (row_pitch % elementSize != 0)) )
throw new IllegalArgumentException("Invalid image_row_pitch specified: " + row_pitch);
return (int)(row_pitch * h);
@@ -164,19 +167,22 @@
* @return the 3D image size in bytes
*/
static int calculateImage3DSize(final ByteBuffer format, final long w, final long h, final long d, long row_pitch, long slice_pitch) {
- if ( LWJGLUtil.CHECKS && (w < 1 || h < 1 || d < 2) )
+ if ( !LWJGLUtil.CHECKS )
+ return 0;
+
+ if ( LWJGLUtil.DEBUG && (w < 1 || h < 1 || d < 2) )
throw new IllegalArgumentException("Invalid 3D image dimensions: " + w + " x " + h + " x " + d);
final int elementSize = getElementSize(format);
if ( row_pitch == 0 )
row_pitch = w * elementSize;
- else if ( LWJGLUtil.CHECKS && ((row_pitch < w * elementSize) || (row_pitch % elementSize != 0)) )
+ else if ( LWJGLUtil.DEBUG && ((row_pitch < w * elementSize) || (row_pitch % elementSize != 0)) )
throw new IllegalArgumentException("Invalid image_row_pitch specified: " + row_pitch);
if ( slice_pitch == 0 )
slice_pitch = row_pitch * h;
- else if ( LWJGLUtil.CHECKS && ((row_pitch < row_pitch * h) || (slice_pitch % row_pitch != 0)) )
+ else if ( LWJGLUtil.DEBUG && ((row_pitch < row_pitch * h) || (slice_pitch % row_pitch != 0)) )
throw new IllegalArgumentException("Invalid image_slice_pitch specified: " + row_pitch);
return (int)(slice_pitch * d);
@@ -223,7 +229,7 @@
case CL_ARGB:
return 4;
default:
- throw new IllegalArgumentException("Invalid cl_channel_order specified: " + APIUtil.toHexString(channelOrder));
+ throw new IllegalArgumentException("Invalid cl_channel_order specified: " + LWJGLUtil.toHexString(channelOrder));
}
}
@@ -255,7 +261,7 @@
case CL_FLOAT:
return 4;
default:
- throw new IllegalArgumentException("Invalid cl_channel_type specified: " + APIUtil.toHexString(channelType));
+ throw new IllegalArgumentException("Invalid cl_channel_type specified: " + LWJGLUtil.toHexString(channelType));
}
}
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/CLContext.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/CLContext.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/CLContext.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -31,6 +31,12 @@
*/
package org.lwjgl.opencl;
+import org.lwjgl.LWJGLException;
+import org.lwjgl.opencl.api.CLImageFormat;
+import org.lwjgl.opencl.api.Filter;
+import org.lwjgl.opengl.Drawable;
+
+import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -125,6 +131,100 @@
// ---------------[ UTILITY METHODS ]---------------
/**
+ * Creates a new CLContext.
+ *
+ * @param platform the platform to use
+ * @param devices the devices to use
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLContext
+ *
+ * @throws LWJGLException if an exception occurs while creating the context
+ */
+ public static CLContext create(final CLPlatform platform, final List<CLDevice> devices, final IntBuffer errcode_ret) throws LWJGLException {
+ return create(platform, devices, null, null, errcode_ret);
+ }
+
+ /**
+ * Creates a new CLContext.
+ *
+ * @param platform the platform to use
+ * @param devices the devices to use
+ * @param pfn_notify the context callback function
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLContext
+ *
+ * @throws LWJGLException if an exception occurs while creating the context
+ */
+ public static CLContext create(final CLPlatform platform, final List<CLDevice> devices, final CLContextCallback pfn_notify, final IntBuffer errcode_ret) throws LWJGLException {
+ return create(platform, devices, pfn_notify, null, errcode_ret);
+ }
+
+ /**
+ * Creates a new CLContext.
+ *
+ * @param platform the platform to use
+ * @param devices the devices to use
+ * @param share_drawable the OpenGL drawable to share objects with
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLContext
+ *
+ * @throws LWJGLException if an exception occurs while creating the context
+ */
+ public static CLContext create(final CLPlatform platform, final List<CLDevice> devices, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret) throws LWJGLException {
+ return util.create(platform, devices, pfn_notify, share_drawable, errcode_ret);
+ }
+
+ /**
+ * Creates a new CLContext.
+ *
+ * @param platform the platform to use
+ * @param device_type the device type to use
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLContext
+ *
+ * @throws LWJGLException if an exception occurs while creating the context
+ */
+ public static CLContext createFromType(final CLPlatform platform, final long device_type, final IntBuffer errcode_ret) throws LWJGLException {
+ return util.createFromType(platform, device_type, null, null, errcode_ret);
+ }
+
+ /**
+ * Creates a new CLContext.
+ *
+ * @param platform the platform to use
+ * @param device_type the device type to use
+ * @param pfn_notify the context callback function
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLContext
+ *
+ * @throws LWJGLException if an exception occurs while creating the context
+ */
+ public static CLContext createFromType(final CLPlatform platform, final long device_type, final CLContextCallback pfn_notify, final IntBuffer errcode_ret) throws LWJGLException {
+ return util.createFromType(platform, device_type, pfn_notify, null, errcode_ret);
+ }
+
+ /**
+ * Creates a new CLContext.
+ *
+ * @param platform the platform to use
+ * @param device_type the device type to use
+ * @param share_drawable the OpenGL drawable to share objects with
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLContext
+ *
+ * @throws LWJGLException if an exception occurs while creating the context
+ */
+ public static CLContext createFromType(final CLPlatform platform, final long device_type, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret) throws LWJGLException {
+ return util.createFromType(platform, device_type, pfn_notify, share_drawable, errcode_ret);
+ }
+
+ /**
* Returns the integer value of the specified parameter.
*
* @param param_name the parameter
@@ -144,11 +244,25 @@
return util.getInfoDevices(this);
}
+ public List<CLImageFormat> getSupportedImageFormats(final long flags, final int image_type) {
+ return getSupportedImageFormats(flags, image_type, null);
+ }
+
+ public List<CLImageFormat> getSupportedImageFormats(final long flags, final int image_type, final Filter<CLImageFormat> filter) {
+ return util.getSupportedImageFormats(this, flags, image_type, filter);
+ }
+
/** CLContext utility methods interface. */
interface CLContextUtil extends InfoUtil<CLContext> {
List<CLDevice> getInfoDevices(CLContext context);
+ CLContext create(CLPlatform platform, List<CLDevice> devices, CLContextCallback pfn_notify, Drawable share_drawable, IntBuffer errcode_ret) throws LWJGLException;
+
+ CLContext createFromType(CLPlatform platform, long device_type, CLContextCallback pfn_notify, Drawable share_drawable, IntBuffer errcode_ret) throws LWJGLException;
+
+ List<CLImageFormat> getSupportedImageFormats(CLContext context, final long flags, final int image_type, Filter<CLImageFormat> filter);
+
}
// -------[ IMPLEMENTATION STUFF BELOW ]-------
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/CLMem.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/CLMem.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/CLMem.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -31,7 +31,12 @@
*/
package org.lwjgl.opencl;
+import org.lwjgl.opencl.api.CLBufferRegion;
+import org.lwjgl.opencl.api.CLImageFormat;
+
+import java.nio.Buffer;
import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
/**
* This class is a wrapper around a cl_mem pointer.
@@ -51,6 +56,52 @@
// ---------------[ UTILITY METHODS ]---------------
/**
+ * Creates a new 2D image object.
+ *
+ * @param context the context on which to create the image object
+ * @param flags the memory object flags
+ * @param image_format the image format
+ * @param image_width the image width
+ * @param image_height the image height
+ * @param image_row_pitch the image row pitch
+ * @param host_ptr the host buffer from which to read image data (optional)
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLMem object
+ */
+ public static CLMem createImage2D(final CLContext context, final long flags, final CLImageFormat image_format,
+ final long image_width, final long image_height, final long image_row_pitch,
+ final Buffer host_ptr, final IntBuffer errcode_ret) {
+ return util.createImage2D(context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret);
+ }
+
+ /**
+ * Creates a new 3D image object.
+ *
+ * @param context the context on which to create the image object
+ * @param flags the memory object flags
+ * @param image_format the image format
+ * @param image_width the image width
+ * @param image_height the image height
+ * @param image_depth the image depth
+ * @param image_row_pitch the image row pitch
+ * @param image_slice_pitch the image slice pitch
+ * @param host_ptr the host buffer from which to read image data (optional)
+ * @param errcode_ret the error code result
+ *
+ * @return the new CLMem object
+ */
+ public static CLMem createImage3D(final CLContext context, final long flags, final CLImageFormat image_format,
+ final long image_width, final long image_height, final long image_depth, final long image_row_pitch, final long image_slice_pitch,
+ final Buffer host_ptr, final IntBuffer errcode_ret) {
+ return util.createImage3D(context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret);
+ }
+
+ public CLMem createSubBuffer(final long flags, final int buffer_create_type, final CLBufferRegion buffer_create_info, final IntBuffer errcode_ret) {
+ return util.createSubBuffer(this, flags, buffer_create_type, buffer_create_info, errcode_ret);
+ }
+
+ /**
* Returns the integer value of the specified parameter.
*
* @param param_name the parameter
@@ -109,6 +160,15 @@
}
/**
+ * Returns the image format. Applicable to image objects only.
+ *
+ * @return the parameter value
+ */
+ public CLImageFormat getImageFormat() {
+ return util.getImageInfoFormat(this);
+ }
+
+ /**
* Returns the image channel order. Applicable to image objects only.
*
* @return the parameter value
@@ -165,10 +225,18 @@
/** CLMem utility methods interface. */
interface CLMemUtil extends InfoUtil<CLMem> {
+ CLMem createImage2D(CLContext context, long flags, CLImageFormat image_format, long image_width, long image_height, long image_row_pitch, Buffer host_ptr, IntBuffer errcode_ret);
+
+ CLMem createImage3D(CLContext context, long flags, CLImageFormat image_format, long image_width, long image_height, long image_depth, long image_row_pitch, long image_slice_pitch, Buffer host_ptr, IntBuffer errcode_ret);
+
+ CLMem createSubBuffer(CLMem mem, long flags, int buffer_create_type, CLBufferRegion buffer_create_info, IntBuffer errcode_ret);
+
ByteBuffer getInfoHostBuffer(CLMem mem);
long getImageInfoSize(CLMem mem, int param_name);
+ CLImageFormat getImageInfoFormat(CLMem mem);
+
int getImageInfoFormat(CLMem mem, int index);
int getGLObjectType(CLMem mem);
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/CLProgram.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/CLProgram.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/CLProgram.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -70,6 +70,15 @@
// ---------------[ UTILITY METHODS ]---------------
/**
+ * Creates kernel objects for all kernels functions in this program.
+ *
+ * @return a CLKernel array
+ */
+ public CLKernel[] createKernelsInProgram() {
+ return util.createKernelsInProgram(this);
+ }
+
+ /**
* Returns the String value of the specified parameter.
*
* @param param_name the parameter
@@ -168,6 +177,8 @@
/** CLProgram utility methods interface. */
interface CLProgramUtil extends InfoUtil<CLProgram> {
+ CLKernel[] createKernelsInProgram(CLProgram program);
+
CLDevice[] getInfoDevices(CLProgram program);
ByteBuffer getInfoBinaries(CLProgram program, ByteBuffer target);
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilAbstract.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilAbstract.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilAbstract.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -31,6 +31,7 @@
*/
package org.lwjgl.opencl;
+import org.lwjgl.LWJGLUtil;
import org.lwjgl.PointerBuffer;
import java.nio.ByteBuffer;
@@ -112,8 +113,8 @@
object.checkValid();
final int bytes = getSizeRet(object, param_name);
- if ( bytes == 0 )
- return "";
+ if ( bytes <= 1 )
+ return null;
final ByteBuffer buffer = APIUtil.getBufferByte(bytes);
getInfo(object, param_name, buffer, null);
@@ -126,7 +127,7 @@
final PointerBuffer bytes = APIUtil.getBufferPointer();
final int errcode = getInfo(object, param_name, null, bytes);
if ( errcode != CL_SUCCESS )
- throw new IllegalArgumentException("Invalid parameter specified: " + APIUtil.toHexString(param_name));
+ throw new IllegalArgumentException("Invalid parameter specified: " + LWJGLUtil.toHexString(param_name));
return (int)bytes.get(0);
}
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/InfoUtilFactory.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -32,8 +32,12 @@
package org.lwjgl.opencl;
import org.lwjgl.*;
+import org.lwjgl.opencl.api.CLBufferRegion;
+import org.lwjgl.opencl.api.CLImageFormat;
import org.lwjgl.opencl.api.Filter;
+import org.lwjgl.opengl.Drawable;
+import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
@@ -49,7 +53,6 @@
* so that they can be compiled for the generator.
*
* @author Spasi
- * @since 28 \xD3\xE5\xF0 2010
*/
final class InfoUtilFactory {
@@ -92,6 +95,70 @@
}
+ /** Custom clCreateContext implementation (reuses APIUtil.getBufferPointer) */
+ public CLContext create(final CLPlatform platform, final List<CLDevice> devices, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret) throws LWJGLException {
+ final int propertyCount = 2 + (share_drawable == null ? 0 : 4) + 1;
+
+ final PointerBuffer buffer = APIUtil.getBufferPointer(propertyCount + devices.size());
+ buffer.put(CL_CONTEXT_PLATFORM).put(platform);
+ if ( share_drawable != null )
+ share_drawable.setCLSharingProperties(buffer);
+ buffer.put(0);
+
+ buffer.position(propertyCount); // Make sure we're at the right offset, setCLSharingProperties might not use all 4 positions.
+ for ( CLDevice device : devices )
+ buffer.put(device);
+
+ final long function_pointer = CLCapabilities.clCreateContext;
+ BufferChecks.checkFunctionAddress(function_pointer);
+ final long user_data = pfn_notify == null || pfn_notify.isCustom() ? 0 : CallbackUtil.createGlobalRef(pfn_notify);
+ CLContext __result = null;
+ try {
+ __result = new CLContext(nclCreateContext(buffer.getBuffer(), 0, devices.size(), buffer.getBuffer(), propertyCount * PointerBuffer.getPointerSize(), pfn_notify == null ? 0 : pfn_notify.getPointer(), user_data, errcode_ret, errcode_ret != null ? errcode_ret.position() : 0, function_pointer), platform);
+ return __result;
+ } finally {
+ CallbackUtil.registerCallback(__result, user_data);
+ }
+ }
+
+ public CLContext createFromType(final CLPlatform platform, final long device_type, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret) throws LWJGLException {
+ final int propertyCount = 2 + (share_drawable == null ? 0 : 4) + 1;
+
+ final PointerBuffer properties = APIUtil.getBufferPointer(propertyCount);
+ properties.put(CL_CONTEXT_PLATFORM).put(platform);
+ if ( share_drawable != null )
+ share_drawable.setCLSharingProperties(properties);
+ properties.put(0);
+ properties.flip();
+
+ return clCreateContextFromType(properties, device_type, pfn_notify, errcode_ret);
+ }
+
+ public List<CLImageFormat> getSupportedImageFormats(final CLContext context, final long flags, final int image_type, final Filter<CLImageFormat> filter) {
+ final IntBuffer numBuffer = APIUtil.getBufferInt();
+ clGetSupportedImageFormats(context, flags, image_type, null, numBuffer);
+
+ final int num_image_formats = numBuffer.get(0);
+ if ( num_image_formats == 0 )
+ return null;
+
+ final ByteBuffer formatBuffer = BufferUtils.createByteBuffer(num_image_formats * CLImageFormat.STRUCT_SIZE);
+ clGetSupportedImageFormats(context, flags, image_type, formatBuffer, null);
+
+ final List<CLImageFormat> formats = new ArrayList<CLImageFormat>(num_image_formats);
+ for ( int i = 0; i < num_image_formats; i++ ) {
+ final int offset = num_image_formats * CLImageFormat.STRUCT_SIZE;
+ final CLImageFormat format = new CLImageFormat(
+ formatBuffer.getInt(offset),
+ formatBuffer.getInt(offset + 4)
+ );
+ if ( filter == null || filter.accept(format) )
+ formats.add(format);
+ }
+
+ return formats.size() == 0 ? null : formats;
+ }
+
}
static final InfoUtil<CLDevice> CL_DEVICE_UTIL = new CLDeviceUtil();
@@ -106,7 +173,7 @@
case CL_DEVICE_MAX_WORK_ITEM_SIZES:
return getInfoInt(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
default:
- throw new IllegalArgumentException("Unsupported parameter: " + APIUtil.toHexString(param_name));
+ throw new IllegalArgumentException("Unsupported parameter: " + LWJGLUtil.toHexString(param_name));
}
}
@@ -183,7 +250,7 @@
size = 3;
break;
default:
- throw new IllegalArgumentException("Unsupported parameter: " + APIUtil.toHexString(param_name));
+ throw new IllegalArgumentException("Unsupported parameter: " + LWJGLUtil.toHexString(param_name));
}
final PointerBuffer buffer = APIUtil.getBufferPointer(size);
@@ -215,6 +282,44 @@
return clGetMemObjectInfo(mem, param_name, param_value, param_value_size_ret);
}
+ public CLMem createImage2D(final CLContext context, final long flags, final CLImageFormat image_format, final long image_width, final long image_height, final long image_row_pitch, final Buffer host_ptr, final IntBuffer errcode_ret) {
+ final ByteBuffer formatBuffer = APIUtil.getBufferByte(2 * 4);
+ formatBuffer.putInt(0, image_format.getChannelOrder());
+ formatBuffer.putInt(4, image_format.getChannelType());
+
+ final long function_pointer = CLCapabilities.clCreateImage2D;
+ BufferChecks.checkFunctionAddress(function_pointer);
+ if ( errcode_ret != null )
+ BufferChecks.checkBuffer(errcode_ret, 1);
+ return new CLMem(nclCreateImage2D(context.getPointer(), flags, formatBuffer, 0, image_width, image_height, image_row_pitch, host_ptr,
+ host_ptr != null ? BufferChecks.checkBuffer(host_ptr, CLChecks.calculateImage2DSize(formatBuffer, image_width, image_height, image_row_pitch)) : 0,
+ errcode_ret, errcode_ret != null ? errcode_ret.position() : 0, function_pointer), context);
+ }
+
+ public CLMem createImage3D(final CLContext context, final long flags, final CLImageFormat image_format, final long image_width, final long image_height, final long image_depth, final long image_row_pitch, final long image_slice_pitch, final Buffer host_ptr, final IntBuffer errcode_ret) {
+ final ByteBuffer formatBuffer = APIUtil.getBufferByte(2 * 4);
+ formatBuffer.putInt(0, image_format.getChannelOrder());
+ formatBuffer.putInt(4, image_format.getChannelType());
+
+ final long function_pointer = CLCapabilities.clCreateImage3D;
+ BufferChecks.checkFunctionAddress(function_pointer);
+ if ( errcode_ret != null )
+ BufferChecks.checkBuffer(errcode_ret, 1);
+ return new CLMem(nclCreateImage3D(context.getPointer(), flags, formatBuffer, 0, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr,
+ host_ptr != null ? BufferChecks.checkBuffer(host_ptr, CLChecks.calculateImage3DSize(formatBuffer, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch)) : 0,
+ errcode_ret, errcode_ret != null ? errcode_ret.position() : 0, function_pointer), context);
+ }
+
+ public CLMem createSubBuffer(final CLMem mem, final long flags, final int buffer_create_type, final CLBufferRegion buffer_create_info, final IntBuffer errcode_ret) {
+ final PointerBuffer infoBuffer = APIUtil.getBufferPointer(2);
+
+ infoBuffer.put(buffer_create_info.getOrigin());
+ infoBuffer.put(buffer_create_info.getSize());
+
+ return clCreateSubBuffer(mem, flags, buffer_create_type, infoBuffer.getBuffer(), errcode_ret);
+
+ }
+
public ByteBuffer getInfoHostBuffer(final CLMem mem) {
mem.checkValid();
@@ -242,6 +347,16 @@
return buffer.get(0);
}
+ public CLImageFormat getImageInfoFormat(final CLMem mem) {
+ mem.checkValid();
+
+ final ByteBuffer format = APIUtil.getBufferByte(2 * 4);
+
+ clGetImageInfo(mem, CL_IMAGE_FORMAT, format, null);
+
+ return new CLImageFormat(format.getInt(0), format.getInt(4));
+ }
+
public int getImageInfoFormat(final CLMem mem, final int index) {
mem.checkValid();
@@ -346,10 +461,28 @@
case CL_PROGRAM_BINARY_SIZES:
return getInfoInt(program, CL_PROGRAM_NUM_DEVICES);
default:
- throw new IllegalArgumentException("Unsupported parameter: " + APIUtil.toHexString(param_name));
+ throw new IllegalArgumentException("Unsupported parameter: " + LWJGLUtil.toHexString(param_name));
}
}
+ public CLKernel[] createKernelsInProgram(final CLProgram program) {
+ final IntBuffer numBuffer = APIUtil.getBufferInt();
+ clCreateKernelsInProgram(program, null, numBuffer);
+
+ final int num_kernels = numBuffer.get(0);
+ if ( num_kernels == 0 )
+ return null;
+
+ final PointerBuffer kernelIDs = APIUtil.getBufferPointer(num_kernels);
+ clCreateKernelsInProgram(program, kernelIDs, null);
+
+ final CLKernel[] kernels = new CLKernel[num_kernels];
+ for ( int i = 0; i < num_kernels; i++ )
+ kernels[i] = program.getCLKernel(kernelIDs.get(i));
+
+ return kernels;
+ }
+
public CLDevice[] getInfoDevices(final CLProgram program) {
program.checkValid();
@@ -413,8 +546,8 @@
program.checkValid();
final int bytes = getBuildSizeRet(program, device, param_name);
- if ( bytes == 0 )
- throw new IllegalArgumentException("Invalid parameter specified: " + APIUtil.toHexString(param_name));
+ if ( bytes <= 1 )
+ return null;
final ByteBuffer buffer = APIUtil.getBufferByte(bytes);
clGetProgramBuildInfo(program, device, param_name, buffer, null);
@@ -435,8 +568,10 @@
private static int getBuildSizeRet(final CLProgram program, final CLDevice device, final int param_name) {
final PointerBuffer bytes = APIUtil.getBufferPointer();
final int errcode = clGetProgramBuildInfo(program, device, param_name, null, bytes);
+ if ( errcode != CL_SUCCESS )
+ throw new IllegalArgumentException("Invalid parameter specified: " + LWJGLUtil.toHexString(param_name));
- return errcode == CL_SUCCESS ? (int)bytes.get(0) : 0;
+ return (int)bytes.get(0);
}
}
Modified: trunk/LWJGL/src/java/org/lwjgl/opencl/Util.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/Util.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/Util.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -31,8 +31,9 @@
*/
package org.lwjgl.opencl;
+import org.lwjgl.LWJGLUtil;
+
import java.lang.reflect.Field;
-import java.util.HashMap;
import java.util.Map;
/**
@@ -43,21 +44,12 @@
public final class Util {
/** Maps OpenCL error token values to their String representations. */
- private static final Map<Integer, String> CL_ERROR_TOKENS = new HashMap<Integer, String>(64);
+ private static final Map<Integer, String> CL_ERROR_TOKENS = LWJGLUtil.getClassTokens(new LWJGLUtil.TokenFilter() {
+ public boolean accept(final Field field, final int value) {
+ return value < 0; // Currently, all OpenCL errors have negative values.
+ }
+ }, null, CL10.class, CL11.class, KHRGLSharing.class, KHRICD.class, APPLEGLSharing.class, EXTDeviceFission.class);
- static {
- APIUtil.getClassTokens(new Class[] {
- CL10.class, CL11.class,
- KHRGLSharing.class, KHRICD.class,
- APPLEGLSharing.class,
- EXTDeviceFission.class,
- }, CL_ERROR_TOKENS, new APIUtil.TokenFilter() {
- public boolean accept(final Field field, final int value) {
- return value < 0; // Currently, all OpenCL errors have negative values.
- }
- });
- }
-
private Util() {
}
@@ -70,7 +62,7 @@
String errname = CL_ERROR_TOKENS.get(errcode);
if ( errname == null )
errname = "UNKNOWN";
- throw new OpenCLException("Error Code: " + errname + " (" + APIUtil.toHexString(errcode) + ")");
+ throw new OpenCLException("Error Code: " + errname + " (" + LWJGLUtil.toHexString(errcode) + ")");
}
}
\ No newline at end of file
Added: trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLBufferRegion.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLBufferRegion.java (rev 0)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLBufferRegion.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002-2010 LWJGL Project
+ * 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 'LWJGL' 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 org.lwjgl.opencl.api;
+
+import org.lwjgl.PointerBuffer;
+
+/**
+ * Simple container for cl_buffer_region struct values.
+ *
+ * @author Spasi
+ */
+public final class CLBufferRegion {
+
+ /** The cl_buffer_region struct size in bytes. */
+ public static final int STRUCT_SIZE = 2 * PointerBuffer.getPointerSize();
+
+ private final int origin;
+ private final int size;
+
+ public CLBufferRegion(final int origin, final int size) {
+ this.origin = origin;
+ this.size = size;
+ }
+
+ public int getOrigin() {
+ return origin;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+}
\ No newline at end of file
Added: trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLImageFormat.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLImageFormat.java (rev 0)
+++ trunk/LWJGL/src/java/org/lwjgl/opencl/api/CLImageFormat.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2002-2010 LWJGL Project
+ * 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 'LWJGL' 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 org.lwjgl.opencl.api;
+
+/**
+ * Simple container for cl_image_format struct values.
+ *
+ * @author Spasi
+ */
+public final class CLImageFormat {
+
+ /** The cl_image_format struct size in bytes. */
+ public static final int STRUCT_SIZE = 2 * 4;
+
+ private final int channelOrder;
+ private final int channelType;
+
+ public CLImageFormat(final int channelOrder, final int channelType) {
+ this.channelOrder = channelOrder;
+ this.channelType = channelType;
+ }
+
+ public int getChannelOrder() {
+ return channelOrder;
+ }
+
+ public int getChannelType() {
+ return channelType;
+ }
+
+}
\ No newline at end of file
Modified: trunk/LWJGL/src/java/org/lwjgl/test/opencl/gl/DemoFractal.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/test/opencl/gl/DemoFractal.java 2010-09-28 21:11:35 UTC (rev 3418)
+++ trunk/LWJGL/src/java/org/lwjgl/test/opencl/gl/DemoFractal.java 2010-09-30 17:21:50 UTC (rev 3419)
@@ -43,18 +43,23 @@
import org.lwjgl.util.ReadableColor;
import java.io.*;
+import java.nio.ByteBuffer;
import java.nio.IntBuffer;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import static java.lang.Math.*;
import static org.lwjgl.opencl.CL10.*;
import static org.lwjgl.opencl.CL10GL.*;
import static org.lwjgl.opencl.KHRGLEvent.*;
+import static org.lwjgl.opengl.AMDDebugOutput.*;
import static org.lwjgl.opengl.ARBCLEvent.*;
+import static org.lwjgl.opengl.ARBDebugOutput.*;
import static org.lwjgl.opengl.ARBSync.*;
import static org.lwjgl.opengl.GL11.*;
-import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL21.*;
/*
@@ -118,25 +123,36 @@
// max number of used GPUs
private static final int MAX_PARALLELISM_LEVEL = 8;
- // max per pixel iterations to compute the fractal
- private static final int MAX_ITERATIONS = 500;
+ private static final int COLOR_MAP_SIZE = 32 * 2 * 4;
+ private Set<String> params;
+
private CLContext clContext;
private CLCommandQueue[] queues;
private CLKernel[] kernels;
private CLProgram[] programs;
- private CLMem[] pboBuffers;
- private IntBuffer pboIDs;
+ private CLMem[] glBuffers;
+ private IntBuffer glIDs;
+ private boolean useTextures;
+
+ // Texture rendering
+ private int dlist;
+ private int vsh;
+ private int fsh;
+ private int program;
+
private CLMem[] colorMap;
- private IntBuffer[] colorMapBuffer;
private final PointerBuffer kernel2DGlobalWorkSize;
- private int width;
- private int height;
+ // max per pixel iterations to compute the fractal
+ private int maxIterations = 500;
+ private int width = 512;
+ private int height = 512;
+
private double minX = -2f;
private double minY = -1.2f;
private double maxX = 0.6f;
@@ -174,135 +190,55 @@
private GLSync glSync;
private CLEvent glEvent;
- public DemoFractal(int width, int height) {
- kernel2DGlobalWorkSize = BufferUtils.createPointerBuffer(2);
+ public DemoFractal(final String[] args) {
+ params = new HashSet<String>();
- this.width = width;
- this.height = height;
- }
+ for ( int i = 0; i < args.length; i++ ) {
+ final String arg = args[i];
- private void run() {
- long startTime = System.currentTimeMillis() + 5000;
- long fps = 0;
+ if ( arg.charAt(0) != '-' && arg.charAt(0) != '/' )
+ throw new IllegalArgumentException("Invalid command-line argument: " + args[i]);
- while ( run ) {
- if ( !Display.isVisible() )
- Thread.yield();
+ final String param = arg.substring(1);
- handleIO();
- display();
+ if ( "forcePBO".equalsIgnoreCase(param) )
+ params.add("forcePBO");
+ else if ( "forceCPU".equalsIgnoreCase(param) )
+ params.add("forceCPU");
+ else if ( "debugGL".equalsIgnoreCase(param) )
+ params.add("debugGL");
+ else if ( "iterations".equalsIgnoreCase(param) ) {
+ if ( args.length < i + 1 + 1 )
+ throw new IllegalArgumentException("Invalid iterations argument specified.");
- Display.update();
- if ( Display.isCloseRequested() )
- break;
+ try {
+ this.maxIterations = Integer.parseInt(args[++i]);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid number of iterations specified.");
+ }
+ } else if ( "res".equalsIgnoreCase(param) ) {
+ if ( args.length < i + 2 + 1 )
+ throw new IllegalArgumentException("Invalid res argument specified.");
- if ( startTime > System.currentTimeMillis() ) {
- fps++;
- } else {
- long timeUsed = 5000 + (startTime - System.currentTimeMillis());
- startTime = System.currentTimeMillis() + 5000;
- System.out.println(fps + " frames in 5 seconds = " + (fps / (timeUsed / 1000f)));
- fps = 0;
- }
- }
+ try {
+ this.width = Integer.parseInt(args[++i]);
+ this.height = Integer.parseInt(args[++i]);
- CL.destroy();
- Display.destroy();
- }
-
- private void handleIO() {
- if ( Keyboard.getNumKeyboardEvents() != 0 ) {
- while ( Keyboard.next() ) {
- if ( Keyboard.getEventKeyState() )
- continue;
-
- final int key = Keyboard.getEventKey();
-
- if ( Keyboard.KEY_1 <= key && key <= Keyboard.KEY_8 ) {
- int number = key - Keyboard.KEY_1 + 1;
- slices = min(number, min(queues.length, MAX_PARALLELISM_LEVEL));
- System.out.println("NEW PARALLELISM LEVEL: " + slices);
- buffersInitialized = false;
- } else {
- switch ( Keyboard.getEventKey() ) {
- case Keyboard.KEY_SPACE:
- drawSeparator = !drawSeparator;
- System.out.println("SEPARATOR DRAWING IS NOW: " + (drawSeparator ? "ON" : "OFF"));
- break;
- case Keyboard.KEY_D:
- doublePrecision = !doublePrecision;
- System.out.println("DOUBLE PRECISION IS NOW: " + (doublePrecision ? "ON" : "OFF"));
- rebuild = true;
- break;
- case Keyboard.KEY_HOME:
- minX = -2f;
- minY = -1.2f;
- maxX = 0.6f;
- maxY = 1.3f;
- break;
- case Keyboard.KEY_ESCAPE:
- run = false;
- break;
- }
+ if ( width < 1 || height < 1 )
+ throw new IllegalArgumentException("Invalid res dimensions specified.");
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid res dimensions specified.");
}
}
}
- while ( Mouse.next() ) {
- final int eventBtn = Mouse.getEventButton();
+ kernel2DGlobalWorkSize = BufferUtils.createPointerBuffer(2);
+ }
- final int x = Mouse.getX();
- final int y = Mouse.getY();
-
- if ( Mouse.isButtonDown(0) && (x != mouseX || y != mouseY) ) {
- if ( !dragging ) {
- dragging = true;
-
- dragX = mouseX;
- dragY = mouseY;
-
- dragMinX = minX;
- dragMinY = minY;
- dragMaxX = maxX;
- dragMaxY = maxY;
- }
-
- double offsetX = (x - dragX) * (maxX - minX) / width;
- double offsetY = (y - dragY) * (maxY - minY) / height;
-
- minX = dragMinX - offsetX;
- minY = dragMinY - offsetY;
-
- maxX = dragMaxX - offsetX;
- maxY = dragMaxY - offsetY;
- } else {
- if ( dragging )
- dragging = false;
-
- if ( eventBtn == -1 ) {
- final int dwheel = Mouse.getEventDWheel();
- if ( dwheel != 0 ) {
- double scale = dwheel > 0 ? 0.05 : -0.05;
-
- double deltaX = scale * (maxX - minX);
- double deltaY = scale * (maxY - minY);
-
- // offset for "zoom to cursor"
- double offsetX = (x / (double)width - 0.5) * deltaX * 2.0;
- double offsetY = (y / (double)height - 0.5) * deltaY * 2.0;
-
- minX += deltaX + offsetX;
- minY += deltaY - offsetY;
-
- maxX += -deltaX + offsetX;
- maxY += -deltaY - offsetY;
- }
- }
- }
-
- mouseX = x;
- mouseY = y;
- }
+ public static void main(String args[]) {
+ DemoFractal demo = new DemoFractal(args);
+ demo.init();
+ demo.run();
}
public void init() {
@@ -310,7 +246,8 @@
CL.create();
Display.setDisplayMode(new DisplayMode(width, height));
Display.setTitle("OpenCL Fractal Demo");
- Display.create();
+ Display.setSwapInterval(0);
+ Display.create(new PixelFormat(), new ContextAttribs().withDebug(params.contains("debugGL")));
} catch (LWJGLException e) {
throw new RuntimeException(e);
}
@@ -324,13 +261,12 @@
throw new RuntimeException(e);
}
- Display.setSwapInterval(0);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
initView(Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight());
- initPBO();
+ initGLObjects();
glFinish();
setKernelConstants();
@@ -351,48 +287,40 @@
return caps.CL_KHR_gl_sharing;
}
};
- List<CLDevice> devices = platform.getDevices(CL_DEVICE_TYPE_GPU, glSharingFilter);
+ int device_type = params.contains("forceCPU") ? CL_DEVICE_TYPE_CPU : CL_DEVICE_TYPE_GPU;
+ List<CLDevice> devices = platform.getDevices(device_type, glSharingFilter);
if ( devices == null ) {
- devices = platform.getDevices(CL_DEVICE_TYPE_CPU, glSharingFilter);
+ device_type = CL_DEVICE_TYPE_CPU;
+ devices = platform.getDevices(device_type, glSharingFilter);
if ( devices == null )
throw new RuntimeException("No OpenCL devices found with KHR_gl_sharing support.");
}
// Create the context
- final PointerBuffer deviceIDs = BufferUtils.createPointerBuffer(devices.size());
- for ( CLDevice device : devices )
- deviceIDs.put(device);
- deviceIDs.flip();
+ clContext = CLContext.create(platform, devices, new CLContextCallback() {
+ protected void handleMessage(final String errinfo, final ByteBuffer private_info) {
+ System.out.println("[CONTEXT MESSAGE] " + errinfo);
+ }
+ }, drawable, null);
- final PointerBuffer contextProps = BufferUtils.createPointerBuffer(2 + 4 + 1);
- contextProps.put(CL_CONTEXT_PLATFORM).put(platform);
-
- drawable.setCLSharingProperties(contextProps); // Enable GL sharing
-
- contextProps.put(0);
- contextProps.flip();
- clContext = clCreateContext(contextProps, deviceIDs, null, null);
-
slices = min(devices.size(), MAX_PARALLELISM_LEVEL);
// create command queues for every GPU, setup colormap and init kernels
queues = new CLCommandQueue[slices];
kernels = new CLKernel[slices];
colorMap = new CLMem[slices];
- colorMapBuffer = new IntBuffer[slices];
for ( int i = 0; i < slices; i++ ) {
- colorMapBuffer[i] = BufferUtils.createIntBuffer(32 * 2);
- colorMap[i] = clCreateBuffer(clContext, CL_MEM_READ_ONLY, colorMapBuffer[i].capacity() * 4, null);
+ colorMap[i] = clCreateBuffer(clContext, CL_MEM_READ_ONLY, COLOR_MAP_SIZE, null);
colorMap[i].checkValid();
- initColorMap(colorMapBuffer[i], 32, Color.BLUE, Color.GREEN, Color.RED);
-
// create command queue and upload color map buffer on each used device
queues[i] = clCreateCommandQueue(clContext, devices.get(i), CL_QUEUE_PROFILING_ENABLE, null);
queues[i].checkValid();
- clEnqueueWriteBuffer(queues[i], colorMap[i], CL_TRUE, 0, colorMapBuffer[i], null, null); // blocking upload
+ final ByteBuffer colorMapBuffer = clEnqueueMapBuffer(queues[i], colorMap[i], CL_TRUE, CL_MAP_WRITE, 0, COLOR_MAP_SIZE, null, null, null);
+ initColorMap(colorMapBuffer.asIntBuffer(), 32, Color.BLUE, Color.GREEN, Color.RED);
+ clEnqueueUnmapMemObject(queues[i], colorMap[i], colorMapBuffer, null, null);
}
// check if we have 64bit FP support on all devices
@@ -411,25 +339,51 @@
// load program(s)
programs = new CLProgram[all64bit ? 1 : slices];
- buildPrograms();
-
final ContextCapabilities caps = GLContext.getCapabilities();
- System.out.println("OpenGL caps.OpenGL32 = " + caps.OpenGL32);
- System.out.println("OpenGL caps.GL_ARB_sync = " + caps.GL_ARB_sync);
+ if ( !caps.OpenGL20 )
+ throw new RuntimeException("OpenGL 2.0 is required to run this demo.");
+ else if ( device_type == CL_DEVICE_TYPE_CPU && !caps.OpenGL21 )
+ throw new RuntimeException("OpenGL 2.1 is required to run this demo.");
+
+ if ( caps.GL_ARB_debug_output )
+ glDebugMessageCallbackARB(new ARBDebugOutputCallback());
+ else if ( caps.GL_AMD_debug_output )
+ glDebugMessageCallbackAMD(new AMDDebugOutputCallback());
+
+ if ( device_type == CL_DEVICE_TYPE_GPU )
+ System.out.println("OpenCL Device Type: GPU (Use -forceCPU to use CPU)");
+ else
+ System.out.println("OpenCL Device Type: CPU");
+ for ( int i = 0; i < devices.size(); i++ )
+ System.out.println("OpenCL Device #" + (i + 1) + " supports KHR_gl_event = " + CLCapabilities.getDeviceCapabilities(devices.get(i)).CL_KHR_gl_event);
+
+ System.out.println("\nMax Iterations: " + maxIterations + " (Use -iterations <count> to change)");
+ System.out.println("Display resolution: " + width + "x" + height + " (Use -res <width> <height> to change)");
+
+ System.out.println("\nOpenGL caps.GL_ARB_sync = " + caps.GL_ARB_sync);
System.out.println("OpenGL caps.GL_ARB_cl_event = " + caps.GL_ARB_cl_event);
- for ( int i = 0; i < devices.size(); i++ ) {
- System.out.println("Device #" + (i + 1) + " supports KHR_gl_event = " + CLCapabilities.getDeviceCapabilities(devices.get(i)).CL_KHR_gl_event);
+
+ // Use PBO if we're on a CPU implementation
+ useTextures = device_type == CL_DEVICE_TYPE_GPU && (!caps.OpenGL21 || !params.contains("forcePBO"));
+ if ( useTextures ) {
+ System.out.println("\nCL/GL Sharing method: TEXTURES (use -forcePBO to use PBO + DrawPixels)");
+ System.out.println("Rendering method: Shader on a fullscreen quad");
+ } else {
+ System.out.println("\nCL/GL Sharing method: PIXEL BUFFER OBJECTS");
+ System.out.println("Rendering method: DrawPixels");
}
+ buildPrograms();
+
// Detect GLtoCL synchronization method
syncGLtoCL = caps.GL_ARB_cl_event; // GL3.2 or ARB_sync implied
if ( syncGLtoCL ) {
clEvents = new CLEvent[slices];
clSyncs = new GLSync[slices];
- System.out.println("GL to CL sync: Using OpenCL events");
+ System.out.println("\nGL to CL sync: Using OpenCL events");
} else
- System.out.println("GL to CL sync: Using clFinish");
+ System.out.println("\nGL to CL sync: Using clFinish");
// Detect CLtoGL synchronization method
syncCLtoGL = caps.OpenGL32 || caps.GL_ARB_sync;
@@ -445,92 +399,57 @@
System.out.println("CL to GL sync: Using OpenGL sync objects");
} else
System.out.println("CL to GL sync: Using glFinish");
- }
- private void createPrograms() throws IOException {
- final String source = getProgramSource("Mandelbrot.cl");
- for ( int i = 0; i < programs.length; i++ )
- programs[i] = clCreateProgramWithSource(clContext, source, null);
- }
+ if ( useTextures ) {
+ dlist = glGenLists(1);
- private String getProgramSource(final String file) throws IOException {
- InputStream source = getClass().getResourceAsStream(file);
- if ( source == null ) // dev-mode
- source = new FileInputStream("...
[truncated message content] |