diff --git a/.travis.yml b/.travis.yml index 1149c248f..949b9378d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: java sudo: false +jdk: + - oraclejdk8 + addons: ssh_known_hosts: updates.jmonkeyengine.org diff --git a/jme3-core/src/main/java/com/jme3/audio/openal/ALC.java b/jme3-core/src/main/java/com/jme3/audio/openal/ALC.java index aaf08e44c..ef9996de9 100644 --- a/jme3-core/src/main/java/com/jme3/audio/openal/ALC.java +++ b/jme3-core/src/main/java/com/jme3/audio/openal/ALC.java @@ -59,6 +59,8 @@ public interface ALC { */ static final int ALC_DEFAULT_ALL_DEVICES_SPECIFIER = 0x1012; static final int ALC_ALL_DEVICES_SPECIFIER = 0x1013; + + //public static ALCCapabilities createCapabilities(long device); public void createALC(); public void destroyALC(); diff --git a/jme3-lwjgl3/build.gradle b/jme3-lwjgl3/build.gradle index b70cd4303..f172a340c 100644 --- a/jme3-lwjgl3/build.gradle +++ b/jme3-lwjgl3/build.gradle @@ -2,7 +2,9 @@ if (!hasProperty('mainClass')) { ext.mainClass = '' } -def lwjglVersion = '3.0.0b' +def lwjglVersion = '3.0.0' + +sourceCompatibility = '1.8' dependencies { compile project(':jme3-core') diff --git a/jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java b/jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java index c9812d7df..cd4e428c0 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java @@ -31,52 +31,49 @@ */ package com.jme3.audio.lwjgl; -import com.jme3.audio.openal.ALC; +import java.nio.ByteBuffer; import java.nio.IntBuffer; +import org.lwjgl.openal.AL; +import org.lwjgl.openal.ALC; import org.lwjgl.openal.ALC10; -import org.lwjgl.openal.ALContext; -import org.lwjgl.openal.ALDevice; +import org.lwjgl.openal.ALCCapabilities; import org.lwjgl.openal.SOFTPauseDevice; -public class LwjglALC implements ALC { +public class LwjglALC implements com.jme3.audio.openal.ALC { - private ALDevice device; - private ALContext context; - - private long contextId; - private long deviceId; + private long device; + private long context; public void createALC() { - device = ALDevice.create(); - context = ALContext.create(device); - context.makeCurrent(); - - contextId = ALC10.alcGetCurrentContext(); - deviceId = ALC10.alcGetContextsDevice(contextId); + device = ALC10.alcOpenDevice((ByteBuffer) null); + ALCCapabilities deviceCaps = ALC.createCapabilities(device); + context = ALC10.alcCreateContext(device, (IntBuffer) null); + ALC10.alcMakeContextCurrent(context); + AL.createCapabilities(deviceCaps); } public void destroyALC() { - if (context != null) { - context.destroy(); - context = null; + if (context != 0) { + ALC10.alcDestroyContext(context); + context = 0; } - if (device != null) { - device.destroy(); - device = null; + if (device != 0) { + ALC10.alcCloseDevice(device); + device = 0; } } public boolean isCreated() { - return context != null; + return context != 0; } public String alcGetString(final int parameter) { - return ALC10.alcGetString(deviceId, parameter); + return ALC10.alcGetString(device, parameter); } public boolean alcIsExtensionPresent(final String extension) { - return ALC10.alcIsExtensionPresent(deviceId, extension); + return ALC10.alcIsExtensionPresent(device, extension); } public void alcGetInteger(final int param, final IntBuffer buffer, final int size) { @@ -86,15 +83,15 @@ public class LwjglALC implements ALC { if (buffer.limit() != size) { throw new AssertionError(); } - ALC10.alcGetIntegerv(deviceId, param, buffer); + ALC10.alcGetIntegerv(device, param, buffer); } public void alcDevicePauseSOFT() { - SOFTPauseDevice.alcDevicePauseSOFT(deviceId); + SOFTPauseDevice.alcDevicePauseSOFT(device); } public void alcDeviceResumeSOFT() { - SOFTPauseDevice.alcDeviceResumeSOFT(deviceId); + SOFTPauseDevice.alcDeviceResumeSOFT(device); } } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwJoystickInput.java b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwJoystickInput.java index b1063d6b9..764b38379 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwJoystickInput.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwJoystickInput.java @@ -65,7 +65,7 @@ public class GlfwJoystickInput implements JoyInput { @Override public Joystick[] loadJoysticks(final InputManager inputManager) { for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) { - if (glfwJoystickPresent(i) == GL11.GL_TRUE) { + if (glfwJoystickPresent(i)) { final String name = glfwGetJoystickName(i); final GlfwJoystick joystick = new GlfwJoystick(inputManager, this, i, name); joysticks.put(i, joystick); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java index e0fa70b92..971ee98fc 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java @@ -87,6 +87,16 @@ public class GlfwKeyInput implements KeyInput { keyInputEvents.add(event); } + + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); glfwSetCharCallback(context.getWindowHandle(), charCallback = new GLFWCharCallback() { @@ -106,6 +116,16 @@ public class GlfwKeyInput implements KeyInput { keyInputEvents.add(released); } + + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); initialized = true; @@ -132,8 +152,8 @@ public class GlfwKeyInput implements KeyInput { return; } - keyCallback.release(); - charCallback.release(); + keyCallback.close(); + charCallback.close(); logger.fine("Keyboard destroyed."); } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java index 17c91aa33..f9081f731 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java @@ -133,6 +133,16 @@ public class GlfwMouseInput implements MouseInput { public void invoke(long window, double xpos, double ypos) { onCursorPos(window, xpos, ypos); } + + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() { @@ -140,6 +150,15 @@ public class GlfwMouseInput implements MouseInput { public void invoke(final long window, final double xOffset, final double yOffset) { onWheelScroll(window, xOffset, yOffset * WHEEL_SCALE); } + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); glfwSetMouseButtonCallback(context.getWindowHandle(), mouseButtonCallback = new GLFWMouseButtonCallback() { @@ -147,6 +166,15 @@ public class GlfwMouseInput implements MouseInput { public void invoke(final long window, final int button, final int action, final int mods) { onMouseButton(window, button, action, mods); } + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); setCursorVisible(cursorVisible); @@ -177,9 +205,9 @@ public class GlfwMouseInput implements MouseInput { return; } - cursorPosCallback.release(); - scrollCallback.release(); - mouseButtonCallback.release(); + cursorPosCallback.close(); + scrollCallback.close(); + mouseButtonCallback.close(); for (long glfwCursor : jmeToGlfwCursorMap.values()) { glfwDestroyCursor(glfwCursor); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIBuffer.java b/jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIBuffer.java new file mode 100644 index 000000000..32b169bec --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIBuffer.java @@ -0,0 +1,730 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: http://lwjgl.org/license.php + */ +package com.jme3.lwjgl3.utils; + +import org.lwjgl.BufferUtils; +import org.lwjgl.PointerBuffer; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +import static org.lwjgl.system.Pointer.*; +import static org.lwjgl.system.MathUtil.*; +import org.lwjgl.system.MemoryUtil; +import static org.lwjgl.system.MemoryUtil.*; + +/** + * Helper class for alternative API functions. Instead of the user passing their + * own buffer, thread-local instances of this class are used internally instead. + */ +public class APIBuffer { + + private static final int DEFAULT_CAPACITY = 128; + + private ByteBuffer buffer; + private long address; + + private int offset; + + private int stackDepth; + private int[] stack = new int[4]; + + public APIBuffer() { + buffer = BufferUtils.createByteBuffer(DEFAULT_CAPACITY); + address = memAddress(buffer); + } + + /** + * Resets the parameter offset to 0. + */ + public APIBuffer reset() { + offset = 0; + return this; + } + + /** + * Pushes the current parameter offset to a stack. + */ + public APIBuffer push() { + if (stackDepth == stack.length) { + stack = Arrays.copyOf(stack, stack.length << 1); + } + + stack[stackDepth++] = offset; + + // Upward align the current offset to the pointer size. + offset = (offset + (POINTER_SIZE - 1)) & -POINTER_SIZE; + + return this; + } + + /** + * Restores the last pushed parameter offset. + */ + public APIBuffer pop() { + offset = stack[--stackDepth]; + return this; + } + + /** + * Returns the current parameter offset. + */ + public int getOffset() { + return offset; + } + + /** + * Sets the current parameter offset. + */ + public void setOffset(int offset) { + this.offset = offset; + } + + /** + * Returns the memory address of the internal {@link ByteBuffer}. This + * address may change after a call to one of the {@code Param()} + * methods. + */ + public long address() { + return address; + } + + /** + * Returns the memory address of the specified {@code offset}. This address + * may change after a call to one of the {@code Param()} methods. + */ + public long address(int offset) { + return address + offset; + } + + /** + * Returns the memory address of the specified {@code offset} or + * {@link MemoryUtil#NULL NULL} if the specified {@code value} is null. This + * address may change after a call to one of the {@code Param()} + * methods. + */ + public long addressSafe(Object value, int offset) { + return value == null ? NULL : address(offset); + } + + /** + * Returns the {@link ByteBuffer} that backs this {@link APIBuffer}. + */ + public ByteBuffer buffer() { + return buffer; + } + + private void ensureCapacity(int capacity) { + if (capacity <= buffer.capacity()) { + return; + } + + ByteBuffer resized = BufferUtils.createByteBuffer(mathRoundPoT(capacity)); + + resized.put(buffer); + resized.clear(); + + buffer = resized; + address = memAddress(resized); + } + + // --------------------------------------------------------------------------------------------------------------------- + private int param(int bytes) { + return param(bytes, bytes); + } + + private int param(int bytes, int alignment) { + // Upward align the current offset to the specified alignment + int param = (offset + (alignment - 1)) & -alignment; + ensureCapacity(offset = param + bytes); + return param; + } + + /** + * Ensures space for an additional boolean value and returns the address + * offset. + */ + public int booleanParam() { + return param(1); + } + + /** + * Ensures space for an additional byte value and returns the address + * offset. + */ + public int byteParam() { + return param(1); + } + + /** + * Ensures space for an additional short value and returns the address + * offset. + */ + public int shortParam() { + return param(2); + } + + /** + * Ensures space for an additional int value and returns the address offset. + */ + public int intParam() { + return param(4); + } + + /** + * Ensures space for an additional long value and returns the address + * offset. + */ + public int longParam() { + return param(8); + } + + /** + * Ensures space for an additional float value and returns the address + * offset. + */ + public int floatParam() { + return param(4); + } + + /** + * Ensures space for an additional double value and returns the address + * offset. + */ + public int doubleParam() { + return param(8); + } + + /** + * Ensures space for an additional pointer value and returns the address + * offset. + */ + public int pointerParam() { + return param(POINTER_SIZE); + } + + /** + * Ensures space for an additional buffer with the specified size (in bytes) + * and returns the address offset. + */ + public int bufferParam(int size) { + return param(size, POINTER_SIZE); + } + + // --------------------------------------------------------------------------------------------------------------------- + /** + * Ensures space for an additional boolean value, sets the specified value + * at the allocated offset and returns that offset. + */ + public int booleanParam(boolean value) { + int offset = booleanParam(); + buffer.put(offset, value ? (byte) 1 : (byte) 0); + return offset; + } + + /** + * Ensures space for an additional byte value, sets the specified value at + * the allocated offset and returns that offset. + */ + public int byteParam(byte value) { + int offset = byteParam(); + buffer.put(offset, value); + return offset; + } + + /** + * Ensures space for an additional short value, sets the specified value at + * the allocated offset and returns that offset. + */ + public int shortParam(short value) { + int offset = shortParam(); + buffer.putShort(offset, value); + return offset; + } + + /** + * Ensures space for an additional int value, sets the specified value at + * the allocated offset and returns that offset. + */ + public int intParam(int value) { + int offset = intParam(); + buffer.putInt(offset, value); + return offset; + } + + /** + * Ensures space for an additional long value, sets the specified value at + * the allocated offset and returns that offset. + */ + public int longParam(long value) { + int offset = longParam(); + buffer.putLong(offset, value); + return offset; + } + + /** + * Ensures space for an additional float value, sets the specified value at + * the allocated offset and returns that offset. + */ + public int floatParam(float value) { + int offset = floatParam(); + buffer.putFloat(offset, value); + return offset; + } + + /** + * Ensures space for an additional double value, sets the specified value at + * the allocated offset and returns that offset. + */ + public int doubleParam(double value) { + int offset = doubleParam(); + buffer.putDouble(offset, value); + return offset; + } + + /** + * Ensures space for an additional pointer value, sets the specified value + * at the allocated offset and returns that offset. + */ + public int pointerParam(long value) { + int offset = pointerParam(); + PointerBuffer.put(buffer, offset, value); + return offset; + } + // ---- + + /** + * Ensures space for an additional pointer buffer, sets the specified memory + * addresses and returns the address offset. + */ + public int pointerArrayParam(long... pointers) { + int buffersAddress = bufferParam(pointers.length << POINTER_SHIFT); + for (int i = 0; i < pointers.length; i++) { + pointerParam(buffersAddress, i, pointers[i]); + } + + return buffersAddress; + } + + /** + * Ensures space for an additional pointer buffer, sets the memory addresses + * of the specified buffers and returns the address offset. + */ + public int pointerArrayParam(ByteBuffer... buffers) { + int buffersAddress = bufferParam(buffers.length << POINTER_SHIFT); + for (int i = 0; i < buffers.length; i++) { + pointerParam(buffersAddress, i, memAddress(buffers[i])); + } + + return buffersAddress; + } + + /** + * Ensures space for two additional pointer buffers, sets the memory + * addresses and remaining bytes of the specified buffers and returns the + * address offset. + */ + public int pointerArrayParamp(ByteBuffer... buffers) { + int buffersAddress = pointerArrayParam(buffers); + + int buffersLengths = bufferParam(buffers.length << POINTER_SHIFT); + for (int i = 0; i < buffers.length; i++) { + pointerParam(buffersLengths, i, buffers[i].remaining()); + } + + return buffersAddress; + } + + // --------------------------------------------------------------------------------------------------------------------- + /** + * ASCII encodes the specified strings with a null-terminator and ensures + * space for a buffer filled with the memory addresses of the encoded + * strings. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the memory address buffer + */ + public int pointerArrayParamASCII(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memASCII(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + } + + return buffersAddress; + } + + /** + * ASCII encodes the specified strings and ensures space for two additional + * buffers filled with the lengths and memory addresses of the encoded + * strings, respectively. The lengths are 4-bytes integers and the memory + * address buffer starts immediately after the lengths buffer. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the lengths buffer + */ + public int pointerArrayParamASCIIi(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + int lengthsAddress = bufferParam(strings.length << 2); + + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memASCII(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + intParam(lengthsAddress, i, buffer.remaining()); + } + + return buffersAddress; + } + + /** + * ASCII encodes the specified strings and ensures space for two additional + * buffers filled with the lengths and memory addresses of the encoded + * strings, respectively. The lengths are pointer-sized integers and the + * memory address buffer starts immediately after the lengths buffer. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the lengths buffer + */ + public int pointerArrayParamASCIIp(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + int lengthsAddress = bufferParam(strings.length << POINTER_SHIFT); + + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memASCII(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + pointerParam(lengthsAddress, i, buffer.remaining()); + } + + return buffersAddress; + } + + /** + * UTF8 encodes the specified strings with a null-terminator and ensures + * space for a buffer filled with the memory addresses of the encoded + * strings. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the memory address buffer + */ + public int pointerArrayParamUTF8(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memUTF8(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + } + + return buffersAddress; + } + + /** + * UTF8 encodes the specified strings and ensures space for two additional + * buffers filled with the lengths and memory addresses of the encoded + * strings, respectively. The lengths are 4-bytes integers and the memory + * address buffer starts immediately after the lengths buffer. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the lengths buffer + */ + public int pointerArrayParamUTF8i(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + int lengthsAddress = bufferParam(strings.length << 2); + + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memUTF8(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + intParam(lengthsAddress, i, buffer.remaining()); + } + + return buffersAddress; + } + + /** + * UTF8 encodes the specified strings and ensures space for two additional + * buffers filled with the lengths and memory addresses of the encoded + * strings, respectively. The lengths are pointer-sized integers and the + * memory address buffer starts immediately after the lengths buffer. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the lengths buffer + */ + public int pointerArrayParamUTF8p(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + int lengthsAddress = bufferParam(strings.length << POINTER_SHIFT); + + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memUTF8(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + pointerParam(lengthsAddress, i, buffer.remaining()); + } + + return buffersAddress; + } + + /** + * UTF16 encodes the specified strings with a null-terminator and ensures + * space for a buffer filled with the memory addresses of the encoded + * strings. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the memory address buffer + */ + public int pointerArrayParamUTF16(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memUTF16(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + } + + return buffersAddress; + } + + /** + * UTF16 encodes the specified strings and ensures space for two additional + * buffers filled with the lengths and memory addresses of the encoded + * strings, respectively. The lengths are 4-bytes integers and the memory + * address buffer starts immediately after the lengths buffer. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the lengths buffer + */ + public int pointerArrayParamUTF16i(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + int lengthsAddress = bufferParam(strings.length << 2); + + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memUTF16(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + intParam(lengthsAddress, i, buffer.remaining()); + } + + return buffersAddress; + } + + /** + * UTF16 encodes the specified strings and ensures space for two additional + * buffers filled with the lengths and memory addresses of the encoded + * strings, respectively. The lengths are pointer-sized integers and the + * memory address buffer starts immediately after the lengths buffer. + * + *

+ * The encoded buffers must be later freed with + * {@link #pointerArrayFree(int, int)}.

+ * + * @return the offset to the lengths buffer + */ + public int pointerArrayParamUTF16p(CharSequence... strings) { + int buffersAddress = bufferParam(strings.length << POINTER_SHIFT); + int lengthsAddress = bufferParam(strings.length << POINTER_SHIFT); + + for (int i = 0; i < strings.length; i++) { + ByteBuffer buffer = MemoryUtil.memUTF16(strings[i]); + + pointerParam(buffersAddress, i, memAddress(buffer)); + pointerParam(lengthsAddress, i, buffer.remaining()); + } + + return buffersAddress; + } + + // --------------------------------------------------------------------------------------------------------------------- + /** + * Frees {@code length} memory blocks stored in the APIBuffer, starting at + * the specified {@code offset}. + */ + public void pointerArrayFree(int offset, int length) { + for (int i = 0; i < length; i++) { + nmemFree(pointerValue(offset + (i << POINTER_SHIFT))); + } + } + + // --------------------------------------------------------------------------------------------------------------------- + /** + * Sets an int value at the specified index of the int buffer that starts at + * the specified offset. + */ + public void intParam(int offset, int index, int value) { + buffer.putInt(offset + (index << 2), value); + } + + /** + * Sets a pointer value at the specified index of the pointer buffer that + * starts at the specified offset. + */ + public void pointerParam(int offset, int index, long value) { + PointerBuffer.put(buffer, offset + (index << POINTER_SHIFT), value); + } + + // --------------------------------------------------------------------------------------------------------------------- + /** + * Ensures space for the specified string encoded in ASCII, encodes the + * string at the allocated offset and returns that offset. + */ + public int stringParamASCII(CharSequence value, boolean nullTerminated) { + if (value == null) { + return -1; + } + + int offset = bufferParam(value.length() + (nullTerminated ? 1 : 0)); + MemoryUtil.memASCII(value, nullTerminated, buffer, offset); + return offset; + } + + /** + * Ensures space for the specified string encoded in UTF-8, encodes the + * string at the allocated offset and returns that offset. + */ + public int stringParamUTF8(CharSequence value, boolean nullTerminated) { + if (value == null) { + return -1; + } + + int encodedLen = MemoryUtil.memLengthUTF8(value, nullTerminated); + int offset = bufferParam(encodedLen); + MemoryUtil.memUTF8(value, nullTerminated, buffer, offset); + return offset; + } + + /** + * Ensures space for the specified string encoded in UTF-16, encodes the + * string at the allocated offset and returns that offset. + */ + public int stringParamUTF16(CharSequence value, boolean nullTerminated) { + if (value == null) { + return -1; + } + + int offset = bufferParam((value.length() + (nullTerminated ? 1 : 0)) << 1); + MemoryUtil.memUTF16(value, nullTerminated, buffer, offset); + return offset; + } + + // --------------------------------------------------------------------------------------------------------------------- + /** + * Returns the boolean value at the specified offset. + */ + public boolean booleanValue(int offset) { + return buffer.get(offset) != 0; + } + + /** + * Returns the boolean value at the specified offset. + */ + public byte byteValue(int offset) { + return buffer.get(offset); + } + + /** + * Returns the short value at the specified offset. + */ + public short shortValue(int offset) { + return buffer.getShort(offset); + } + + /** + * Returns the int value at the specified offset. + */ + public int intValue(int offset) { + return buffer.getInt(offset); + } + + /** + * Returns the long value at the specified offset. + */ + public long longValue(int offset) { + return buffer.getLong(offset); + } + + /** + * Returns the float value at the specified offset. + */ + public float floatValue(int offset) { + return buffer.getFloat(offset); + } + + /** + * Returns the double value at the specified offset. + */ + public double doubleValue(int offset) { + return buffer.getDouble(offset); + } + + /** + * Returns the pointer value at the specified offset. + */ + public long pointerValue(int offset) { + return PointerBuffer.get(buffer, offset); + } + + /** + * Returns the ASCII string value at the specified byte range. + */ + public String stringValueASCII(int offset, int limit) { + buffer.position(offset); + buffer.limit(limit); + try { + return MemoryUtil.memASCII(buffer); + } finally { + buffer.clear(); + } + } + + /** + * Returns the UTF8 string value at the specified byte range. + */ + public String stringValueUTF8(int offset, int limit) { + buffer.position(offset); + buffer.limit(limit); + try { + return MemoryUtil.memUTF8(buffer); + } finally { + buffer.clear(); + } + } + + /** + * Returns the UTF16 string value at the specified byte range. + */ + public String stringValueUTF16(int offset, int limit) { + buffer.position(offset); + buffer.limit(limit); + try { + return MemoryUtil.memUTF16(buffer); + } finally { + buffer.clear(); + } + } +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIUtil.java b/jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIUtil.java new file mode 100644 index 000000000..689659e3b --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIUtil.java @@ -0,0 +1,218 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: http://lwjgl.org/license.php + */ +package com.jme3.lwjgl3.utils; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Utility class useful to API bindings. [INTERNAL USE ONLY] + * + *

+ * Method names in this class are prefixed with {@code api} to avoid ambiguities + * when used with static imports.

+ */ +public final class APIUtil { + + private static final ThreadLocal API_BUFFERS = new ThreadLocal() { + @Override + protected APIBuffer initialValue() { + return new APIBuffer(); + } + }; + + private APIUtil() { + } + + /** + * Returns a thread-local {@link APIBuffer} that has been reset. + */ + public static APIBuffer apiBuffer() { + return API_BUFFERS.get().reset(); + } + + /** + * Returns a thread-local {@link APIBuffer}, without resetting it. This + * makes the APIBuffer work like a stack when used in nested API calls. The + * user is responsible for resetting the {@link APIBuffer} to an appropriate + * state before the nested call returns. + * + * @see APIBuffer#pop + */ + public static APIBuffer apiStack() { + return API_BUFFERS.get().push(); + } + + /** + * A data class for API versioning information. + */ + public static class APIVersion { + + /** + * Returns the API major version. + */ + public final int major; + /** + * Returns the API minor version. + */ + public final int minor; + + /** + * Returns the API revision. May be null. + */ + public final String revision; + /** + * Returns the API implementation-specific versioning information. May + * be null. + */ + public final String implementation; + + public APIVersion(int major, int minor) { + this(major, minor, null, null); + } + + public APIVersion(int major, int minor, String revision, String implementation) { + this.major = major; + this.minor = minor; + this.revision = revision; + this.implementation = implementation; + } + + } + + /** + * Parses a version string. The version string must have the format + * {@code MAJOR.MINOR.REVISION IMPL}, where {@code MAJOR} is the major + * version (integer), {@code MINOR} is the minor version (integer), + * {@code REVISION} is the revision version (string, optional) and + * {@code IMPL} is implementation-specific information (string, optional). + * + * @param version the API version string + * + * @return the parsed {@link APIVersion} + */ + public static APIVersion apiParseVersion(String version) { + return apiParseVersion(version, null); + } + + /** + * Parses a version string. The version string must have the format + * {@code PREFIX MAJOR.MINOR.REVISION IMPL}, where {@code PREFIX} is the + * specified prefix (string, optional), {@code MAJOR} is the major version + * (integer), {@code MINOR} is the minor version (integer), {@code REVISION} + * is the revision version (string, optional) and {@code IMPL} is + * implementation-specific information (string, optional). + * + * @param version the version string + * @param prefix the version string prefix, may be null + * + * @return the parsed {@link APIVersion} + */ + public static APIVersion apiParseVersion(String version, String prefix) { + String pattern = "([0-9]+)[.]([0-9]+)([.]\\S+)?\\s*(.+)?"; + if (prefix != null) { + pattern = prefix + "\\s+" + pattern; + } + + Matcher matcher = Pattern.compile(pattern).matcher(version); + if (!matcher.matches()) { + throw new IllegalArgumentException(String.format("Malformed API version string [%s]", version)); + } + + return new APIVersion( + Integer.parseInt(matcher.group(1)), + Integer.parseInt(matcher.group(2)), + matcher.group(3), + matcher.group(4) + ); + } + + public static String apiUnknownToken(int token) { + return apiUnknownToken("Unknown", token); + } + + public static String apiUnknownToken(String description, int token) { + return String.format("%s [0x%X]", description, token); + } + + /** + * 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. + * + *

+ * This method is useful when debugging to quickly identify values returned + * from an API.

+ * + * @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 apiClassTokens(TokenFilter filter, Map target, Class... tokenClasses) { + if (target == null) { + target = new HashMap(64); + } + + int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL; + + for (Class tokenClass : tokenClasses) { + if (tokenClass == null) { + continue; + } + + for (Field field : tokenClass.getDeclaredFields()) { + // Get only fields. + if ((field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class) { + try { + int value = field.getInt(null); + if (filter != null && !filter.accept(field, value)) { + continue; + } + + String name = target.get(value); + target.put(value, name == null ? field.getName() : name + "|" + field.getName()); + } catch (IllegalAccessException e) { + // Ignore + } + } + } + } + + return target; + } + + public static Class apiOptionalClass(String className) { + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + return null; + } + } + + /** + * 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 + * + * @return true if the Field is accepted + */ + boolean accept(Field field, int value); + + } + +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java index ea0eb9543..522cb48c7 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java @@ -32,6 +32,7 @@ package com.jme3.opencl.lwjgl; import com.jme3.opencl.*; +import com.jme3.opencl.lwjgl.info.Info; import java.nio.ByteBuffer; import org.lwjgl.opencl.*; diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java index 53267f4cc..99b061099 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java @@ -146,7 +146,7 @@ public class LwjglContext extends Context { } //get formats CLImageFormat.Buffer formatsB = new CLImageFormat.Buffer(BufferUtils.createByteBuffer(count * CLImageFormat.SIZEOF)); - ret = CL10.clGetSupportedImageFormats(context, memFlags, typeFlag, formatsB, null); + ret = CL10.clGetSupportedImageFormats(context, memFlags, typeFlag, formatsB, (IntBuffer) null); Utils.checkError(ret, "clGetSupportedImageFormats"); //convert formats ImageFormat[] formats = new ImageFormat[count]; diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglDevice.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglDevice.java index 31325a469..d75cebd8e 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglDevice.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglDevice.java @@ -33,13 +33,12 @@ package com.jme3.opencl.lwjgl; import com.jme3.opencl.Device; import com.jme3.opencl.Platform; +import com.jme3.opencl.lwjgl.info.Info; import java.util.Arrays; import java.util.Collection; import org.lwjgl.PointerBuffer; import org.lwjgl.opencl.CL10; import org.lwjgl.opencl.CL11; -import org.lwjgl.opencl.CLDevice; -import org.lwjgl.opencl.Info; /** * @@ -47,18 +46,15 @@ import org.lwjgl.opencl.Info; */ public final class LwjglDevice implements Device { - final CLDevice device; + final long device; final LwjglPlatform platform; - public LwjglDevice(CLDevice device, LwjglPlatform platform) { + public LwjglDevice(long device, LwjglPlatform platform) { this.device = device; this.platform = platform; } public long getDevice() { - return device.address(); - } - public CLDevice getCLDevice() { return device; } @@ -69,7 +65,7 @@ public final class LwjglDevice implements Device { @Override public DeviceType getDeviceType() { - int type = Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_TYPE); + int type = Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_TYPE); switch (type) { case CL10.CL_DEVICE_TYPE_ACCELERATOR: return DeviceType.ACCELEARTOR; case CL10.CL_DEVICE_TYPE_CPU: return DeviceType.CPU; @@ -80,17 +76,17 @@ public final class LwjglDevice implements Device { @Override public int getVendorId() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_VENDOR_ID); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_VENDOR_ID); } @Override public boolean isAvailable() { - return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_AVAILABLE); + return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_AVAILABLE); } @Override public boolean hasCompiler() { - return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_COMPILER_AVAILABLE); + return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_COMPILER_AVAILABLE); } @Override @@ -105,17 +101,17 @@ public final class LwjglDevice implements Device { @Override public boolean hasErrorCorrectingMemory() { - return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_ERROR_CORRECTION_SUPPORT); + return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_ERROR_CORRECTION_SUPPORT); } @Override public boolean hasUnifiedMemory() { - return Info.clGetDeviceInfoBoolean(device.address(), CL11.CL_DEVICE_HOST_UNIFIED_MEMORY); + return Info.clGetDeviceInfoBoolean(device, CL11.CL_DEVICE_HOST_UNIFIED_MEMORY); } @Override public boolean hasImageSupport() { - return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_IMAGE_SUPPORT); + return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_IMAGE_SUPPORT); } @Override @@ -135,39 +131,39 @@ public final class LwjglDevice implements Device { @Override public Collection getExtensions() { - return Arrays.asList(Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_EXTENSIONS).split(" ")); + return Arrays.asList(Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_EXTENSIONS).split(" ")); } @Override public int getComputeUnits() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_COMPUTE_UNITS); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_COMPUTE_UNITS); } @Override public int getClockFrequency() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_CLOCK_FREQUENCY); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_CLOCK_FREQUENCY); } @Override public int getAddressBits() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_ADDRESS_BITS); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_ADDRESS_BITS); } @Override public boolean isLittleEndian() { - return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_ENDIAN_LITTLE); + return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_ENDIAN_LITTLE); } @Override public long getMaximumWorkItemDimensions() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS); } @Override public long[] getMaximumWorkItemSizes() { int dim = (int) getMaximumWorkItemDimensions(); PointerBuffer sizes = PointerBuffer.allocateDirect(dim); - Info.clGetDeviceInfoPointers(device.address(), CL10.CL_DEVICE_MAX_WORK_ITEM_SIZES, sizes); + Info.clGetDeviceInfoPointers(device, CL10.CL_DEVICE_MAX_WORK_ITEM_SIZES, sizes); long[] sx = new long[dim]; sizes.get(sx); return sx; @@ -175,74 +171,74 @@ public final class LwjglDevice implements Device { @Override public long getMaxiumWorkItemsPerGroup() { - return Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_MAX_WORK_GROUP_SIZE); + return Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_MAX_WORK_GROUP_SIZE); } @Override public int getMaximumSamplers() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_SAMPLERS); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_SAMPLERS); } @Override public int getMaximumReadImages() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_READ_IMAGE_ARGS); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_READ_IMAGE_ARGS); } @Override public int getMaximumWriteImages() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_WRITE_IMAGE_ARGS); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_WRITE_IMAGE_ARGS); } @Override public long[] getMaximumImage2DSize() { return new long[] { - Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE2D_MAX_WIDTH), - Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE2D_MAX_HEIGHT) + Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE2D_MAX_WIDTH), + Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE2D_MAX_HEIGHT) }; } @Override public long[] getMaximumImage3DSize() { return new long[] { - Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE3D_MAX_WIDTH), - Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE3D_MAX_HEIGHT), - Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE3D_MAX_DEPTH) + Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE3D_MAX_WIDTH), + Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE3D_MAX_HEIGHT), + Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE3D_MAX_DEPTH) }; } @Override public long getMaximumAllocationSize() { - return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_MAX_MEM_ALLOC_SIZE); + return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_MAX_MEM_ALLOC_SIZE); } @Override public long getGlobalMemorySize() { - return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_GLOBAL_MEM_SIZE); + return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_GLOBAL_MEM_SIZE); } @Override public long getLocalMemorySize() { - return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_LOCAL_MEM_SIZE); + return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_LOCAL_MEM_SIZE); } @Override public long getMaximumConstantBufferSize() { - return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE); + return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE); } @Override public int getMaximumConstantArguments() { - return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_CONSTANT_ARGS); + return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_CONSTANT_ARGS); } @Override public String getProfile() { - return Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_PROFILE); + return Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_PROFILE); } @Override public String getVersion() { - return Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_VERSION); + return Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_VERSION); } @Override @@ -257,7 +253,7 @@ public final class LwjglDevice implements Device { @Override public String getCompilerVersion() { - return Info.clGetDeviceInfoStringASCII(device.address(), CL11.CL_DEVICE_OPENCL_C_VERSION); + return Info.clGetDeviceInfoStringASCII(device, CL11.CL_DEVICE_OPENCL_C_VERSION); } @Override @@ -272,7 +268,7 @@ public final class LwjglDevice implements Device { @Override public String getDriverVersion() { - return Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DRIVER_VERSION); + return Info.clGetDeviceInfoStringASCII(device, CL10.CL_DRIVER_VERSION); } @Override @@ -287,12 +283,12 @@ public final class LwjglDevice implements Device { @Override public String getName() { - return Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_NAME); + return Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_NAME); } @Override public String getVendor() { - return Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_VENDOR); + return Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_VENDOR); } @Override diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java index 5ded851d3..96c471113 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java @@ -32,9 +32,9 @@ package com.jme3.opencl.lwjgl; import com.jme3.opencl.Event; +import com.jme3.opencl.lwjgl.info.Info; import java.util.logging.Logger; import org.lwjgl.opencl.CL10; -import org.lwjgl.opencl.Info; /** * diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java index ed9239677..30171772f 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java @@ -33,6 +33,7 @@ package com.jme3.opencl.lwjgl; import com.jme3.math.ColorRGBA; import com.jme3.opencl.*; +import com.jme3.opencl.lwjgl.info.Info; import java.nio.ByteBuffer; import java.util.logging.Level; import java.util.logging.Logger; @@ -272,7 +273,10 @@ public class LwjglImage extends Image { public ImageFormat getImageFormat() { Utils.b80.rewind(); CLImageFormat format = new CLImageFormat(Utils.b80); - int ret = CL10.clGetImageInfo(image, CL10.CL_IMAGE_FORMAT, format.sizeof(), Utils.b80, null); + int limit = Utils.b80.limit(); + Utils.b80.limit(format.sizeof()); + int ret = CL10.clGetImageInfo(image, CL10.CL_IMAGE_FORMAT, Utils.b80, null); + Utils.b80.limit(limit); Utils.checkError(ret, "clGetImageInfo"); return new ImageFormat(encodeImageChannelOrder(format.image_channel_order()), encodeImageChannelType(format.image_channel_data_type())); } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java index b3a668611..f5f97f1bd 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java @@ -37,11 +37,10 @@ import com.jme3.math.Vector2f; import com.jme3.math.Vector4f; import com.jme3.opencl.*; import com.jme3.opencl.Buffer; +import com.jme3.opencl.lwjgl.info.Info; import java.nio.*; import org.lwjgl.PointerBuffer; import org.lwjgl.opencl.CL10; -import org.lwjgl.opencl.CLDevice; -import org.lwjgl.opencl.Info; /** * diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglPlatform.java index 24b95f6c3..6914cba19 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglPlatform.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglPlatform.java @@ -31,16 +31,20 @@ */ package com.jme3.opencl.lwjgl; +import com.jme3.lwjgl3.utils.APIBuffer; +import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer; import com.jme3.opencl.Device; import com.jme3.opencl.Platform; +import com.jme3.opencl.lwjgl.info.Info; +import java.nio.IntBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; +import org.lwjgl.PointerBuffer; import org.lwjgl.opencl.CL10; -import org.lwjgl.opencl.CLDevice; -import org.lwjgl.opencl.CLPlatform; -import org.lwjgl.opencl.Info; +import static org.lwjgl.system.Pointer.POINTER_SHIFT; /** * @@ -48,14 +52,14 @@ import org.lwjgl.opencl.Info; */ public final class LwjglPlatform implements Platform { - final CLPlatform platform; + final long platform; List devices; - public LwjglPlatform(CLPlatform platform) { + public LwjglPlatform(long platform) { this.platform = platform; } - public CLPlatform getPlatform() { + public long getPlatform() { return platform; } @@ -63,16 +67,54 @@ public final class LwjglPlatform implements Platform { public List getDevices() { if (devices == null) { devices = new ArrayList<>(); - for (CLDevice d : platform.getDevices(CL10.CL_DEVICE_TYPE_ALL)) { + for (long d : getDevices(CL10.CL_DEVICE_TYPE_ALL)) { devices.add(new LwjglDevice(d, this)); } } return devices; } + + /** + * Returns a list of the available devices on this platform that match the + * specified type, filtered by the specified filter. + * + * Copied from the old release. + * + * @param device_type the device type + * @param filter the device filter + * + * @return the available devices + */ + private long[] getDevices(int device_type) { + int[] count = new int[1]; + int errcode = CL10.clGetDeviceIDs(platform, device_type, null, count); + if (errcode == CL10.CL_DEVICE_NOT_FOUND) { + return new long[0]; + } + Utils.checkError(errcode, "clGetDeviceIDs"); + + int num_devices = count[0]; + if (num_devices == 0) { + return new long[0]; + } + + PointerBuffer devices = PointerBuffer.allocateDirect(num_devices); + + errcode = CL10.clGetDeviceIDs(platform, device_type,devices, (IntBuffer) null); + Utils.checkError(errcode, "clGetDeviceIDs"); + + long[] deviceIDs = new long[num_devices]; + devices.rewind(); + for (int i = 0; i < num_devices; i++) { + deviceIDs[i] = devices.get(); + } + + return deviceIDs; + } @Override public String getProfile() { - return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_PROFILE); + return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_PROFILE); } @Override @@ -87,7 +129,7 @@ public final class LwjglPlatform implements Platform { @Override public String getVersion() { - return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_VERSION); + return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_VERSION); } @Override @@ -102,12 +144,12 @@ public final class LwjglPlatform implements Platform { @Override public String getName() { - return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_NAME); + return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_NAME); } @Override public String getVendor() { - return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_VENDOR); + return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_VENDOR); } @Override @@ -122,7 +164,7 @@ public final class LwjglPlatform implements Platform { @Override public Collection getExtensions() { - return Arrays.asList(Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_EXTENSIONS).split(" ")); + return Arrays.asList(Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_EXTENSIONS).split(" ")); } @Override diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java index eb8faa199..4d3699a35 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java @@ -32,14 +32,15 @@ package com.jme3.opencl.lwjgl; import com.jme3.opencl.*; +import com.jme3.opencl.lwjgl.info.Info; import java.nio.ByteBuffer; +import java.nio.IntBuffer; import java.util.logging.Level; import java.util.logging.Logger; import org.lwjgl.BufferUtils; import org.lwjgl.PointerBuffer; import org.lwjgl.opencl.*; import org.lwjgl.system.MemoryUtil; -import org.lwjgl.system.Pointer; /** * @@ -94,7 +95,7 @@ public class LwjglProgram extends Program { final ByteBuffer buffer = BufferUtils.createByteBuffer(count); ret = CL10.clGetProgramBuildInfo(program, device, CL10.CL_PROGRAM_BUILD_LOG, buffer, null); Utils.checkError(ret, "clGetProgramBuildInfo"); - return MemoryUtil.memDecodeASCII(buffer); + return MemoryUtil.memASCII(buffer); } private String Log() { @@ -123,7 +124,7 @@ public class LwjglProgram extends Program { Utils.checkError(ret, "clCreateKernelsInProgram"); int count = Utils.tempBuffers[0].b16i.get(0); PointerBuffer buf = PointerBuffer.allocateDirect(count); - ret = CL10.clCreateKernelsInProgram(program, buf, null); + ret = CL10.clCreateKernelsInProgram(program, buf, (IntBuffer) null); Utils.checkError(ret, "clCreateKernelsInProgram"); Kernel[] kx = new Kernel[count]; for (int i=0; i CL_ERROR_TOKENS = apiClassTokens( + new BiPredicate() { + private final List EXCLUDE = Arrays.asList("CL_DEVICE_TYPE_ALL", "CL_BUILD_NONE", "CL_BUILD_ERROR", "CL_BUILD_IN_PROGRESS"); + + @Override + public boolean test(Field field, Integer value) { + return value < 0 && !EXCLUDE.contains(field.getName()); // OpenCL errors have negative values. + } + }, + null, + CL10.class, + apiOptionalClass("org.lwjgl.opencl.CL10GL"), + CL11.class, + CL12.class, + CL20.class, + apiOptionalClass("org.lwjgl.opencl.APPLEGLSharing"), + INTELAccelerator.class, + apiOptionalClass("org.lwjgl.opencl.KHRGLSharing"), + apiOptionalClass("org.lwjgl.opencl.KHREGLEvent"), + apiOptionalClass("org.lwjgl.opencl.KHREGLImage"), + KHRICD.class + /*, EXTDeviceFission.class*/ + ); + + private CLUtil() { + } + + /** + * Checks the {@code errcode} present in the current position of the + * specified {@code errcode_ret} buffer and throws an + * {@link OpenCLException} if it's not equal to {@link CL10#CL_SUCCESS}. + * + * @param errcode_ret the {@code errcode} buffer + * + * @throws OpenCLException + */ + public static void checkCLError(ByteBuffer errcode_ret) { + checkCLError(errcode_ret.getInt(errcode_ret.position())); + } + + /** + * Checks the {@code errcode} present in the current position of the + * specified {@code errcode_ret} buffer and throws an + * {@link OpenCLException} if it's not equal to {@link CL10#CL_SUCCESS}. + * + * @param errcode_ret the {@code errcode} buffer + * + * @throws OpenCLException + */ + public static void checkCLError(IntBuffer errcode_ret) { + checkCLError(errcode_ret.get(errcode_ret.position())); + } + + /** + * Checks the specified {@code errcode} and throws an + * {@link OpenCLException} if it's not equal to {@link CL10#CL_SUCCESS}. + * + * @param errcode the {@code errcode} to check + * + * @throws OpenCLException + */ + public static void checkCLError(int errcode) { + if (errcode != CL_SUCCESS) { + throw new OpenCLException(getErrcodeName(errcode)); + } + } + + /** + * Returns the token name of the specified {@code errcode}. + * + * @param errcode the {@code errcode} + * + * @return the {@code errcode} token name + */ + public static String getErrcodeName(int errcode) { + String errname = CL_ERROR_TOKENS.get(errcode); + if (errname == null) { + errname = apiUnknownToken(errcode); + } + + return errname; + } + +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/Info.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/Info.java new file mode 100644 index 000000000..fd48b21a5 --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/Info.java @@ -0,0 +1,687 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: http://lwjgl.org/license.php + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package com.jme3.opencl.lwjgl.info; + +import org.lwjgl.PointerBuffer; + +import static org.lwjgl.opencl.CL10.*; +import static org.lwjgl.opencl.CL12.*; +import static org.lwjgl.opencl.CL20.*; +import static org.lwjgl.opencl.CL10GL.*; + +/** + * This class provides methods that can be used to query information about + * OpenCL objects. These methods are similar to the corresponding + * {@code clGet<Type>Info} function for each object type, except that only + * a single value is returned. Which one of these methods should be used depends + * on the type of the information being queried. + */ +public final class Info { + + private Info() { + } + + // ------------------------------------ + // Platform (CL10.clGetPlatformInfo) + // ------------------------------------ + private static final InfoQuery PLATFORM = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetPlatformInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * String version of: {@link CL10#clGetPlatformInfo GetPlatformInfo} + */ + public static String clGetPlatformInfoStringASCII(long platform, int param_name) { + return PLATFORM.getStringASCII(platform, param_name); + } + + /** + * String with explicit length version of: {@link CL10#clGetPlatformInfo GetPlatformInfo} + */ + public static String clGetPlatformInfoStringASCII(long platform, int param_name, int param_value_size) { + return PLATFORM.getStringASCII(platform, param_name, param_value_size); + } + + /** + * UTF-8 string version of: {@link CL10#clGetPlatformInfo GetPlatformInfo} + */ + public static String clGetPlatformInfoStringUTF8(long platform, int param_name) { + return PLATFORM.getStringUTF8(platform, param_name); + } + + /** + * UTF-8 string with explicit length version of: + * {@link CL10#clGetPlatformInfo GetPlatformInfo} + */ + public static String clGetPlatformInfoStringUTF8(long platform, int param_name, int param_value_size) { + return PLATFORM.getStringUTF8(platform, param_name, param_value_size); + } + + // ------------------------------------ + // Device (CL10.clGetDeviceInfo) + // ------------------------------------ + private static final InfoQuery DEVICE = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetDeviceInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single boolean value version of: + * {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static boolean clGetDeviceInfoBoolean(long device, int param_name) { + return DEVICE.getBoolean(device, param_name); + } + + /** + * Single int value version of: {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static int clGetDeviceInfoInt(long device, int param_name) { + return DEVICE.getInt(device, param_name); + } + + /** + * Single long value version of: {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static long clGetDeviceInfoLong(long device, int param_name) { + return DEVICE.getLong(device, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static long clGetDeviceInfoPointer(long device, int param_name) { + return DEVICE.getPointer(device, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static int clGetDeviceInfoPointers(long device, int param_name, PointerBuffer target) { + return DEVICE.getPointers(device, param_name, target); + } + + /** + * String version of: {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static String clGetDeviceInfoStringASCII(long device, int param_name) { + return DEVICE.getStringASCII(device, param_name); + } + + /** + * String with explicit length version of: {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static String clGetDeviceInfoStringASCII(long device, int param_name, int param_value_size) { + return DEVICE.getStringASCII(device, param_name, param_value_size); + } + + /** + * UTF-8 string version of: {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static String clGetDeviceInfoStringUTF8(long device, int param_name) { + return DEVICE.getStringUTF8(device, param_name); + } + + /** + * UTF-8 string with explicit length version of: + * {@link CL10#clGetDeviceInfo GetDeviceInfo} + */ + public static String clGetDeviceInfoStringUTF8(long device, int param_name, int param_value_size) { + return DEVICE.getStringUTF8(device, param_name, param_value_size); + } + + // ------------------------------------ + // Context (CL10.clGetContextInfo) + // ------------------------------------ + private static final InfoQuery CONTEXT = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetContextInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: {@link CL10#clGetContextInfo GetContextInfo} + */ + public static int clGetContextInfoInt(long context, int param_name) { + return CONTEXT.getInt(context, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetContextInfo GetContextInfo} + */ + public static long clGetContextInfoPointer(long context, int param_name) { + return CONTEXT.getPointer(context, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetContextInfo GetContextInfo} + */ + public static int clGetContextInfoPointers(long context, int param_name, PointerBuffer target) { + return CONTEXT.getPointers(context, param_name, target); + } + + // ------------------------------------ + // Command Queue (CL10.clGetCommandQueueInfo) + // ------------------------------------ + private static final InfoQuery COMMAND_QUEUE = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetCommandQueueInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: + * {@link CL10#clGetCommandQueueInfo GetCommandQueueInfo} + */ + public static int clGetCommandQueueInfoInt(long command_queue, int param_name) { + return COMMAND_QUEUE.getInt(command_queue, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetCommandQueueInfo GetCommandQueueInfo} + */ + public static long clGetCommandQueueInfoPointer(long command_queue, int param_name) { + return COMMAND_QUEUE.getPointer(command_queue, param_name); + } + + /** + * PointBuffer version of: + * {@link CL10#clGetCommandQueueInfo GetCommandQueueInfo} + */ + public static int clGetCommandQueueInfoPointers(long command_queue, int param_name, PointerBuffer target) { + return COMMAND_QUEUE.getPointers(command_queue, param_name, target); + } + + // ------------------------------------ + // Mem Object (CL10.clGetMemObjectInfo) + // ------------------------------------ + private static final InfoQuery MEM_OBJECT = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetMemObjectInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single boolean value version of: + * {@link CL10#clGetMemObjectInfo GetMemObjectInfo} + */ + public static boolean clGetMemObjectInfoBoolean(long memobj, int param_name) { + return MEM_OBJECT.getBoolean(memobj, param_name); + } + + /** + * Single int value version of: + * {@link CL10#clGetMemObjectInfo GetMemObjectInfo} + */ + public static int clGetMemObjectInfoInt(long memobj, int param_name) { + return MEM_OBJECT.getInt(memobj, param_name); + } + + /** + * Single long value version of: + * {@link CL10#clGetMemObjectInfo GetMemObjectInfo} + */ + public static long clGetMemObjectInfoLong(long memobj, int param_name) { + return MEM_OBJECT.getLong(memobj, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetMemObjectInfo GetMemObjectInfo} + */ + public static long clGetMemObjectInfoPointer(long memobj, int param_name) { + return MEM_OBJECT.getPointer(memobj, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetMemObjectInfo GetMemObjectInfo} + */ + public static int clGetMemObjectInfoPointers(long memobj, int param_name, PointerBuffer target) { + return MEM_OBJECT.getPointers(memobj, param_name, target); + } + + // ------------------------------------ + // Image (CL10.clGetImageInfo) + // ------------------------------------ + private static final InfoQuery IMAGE = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetImageInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: {@link CL10#clGetImageInfo GetImageInfo} + */ + public static int clGetImageInfoInt(long image, int param_name) { + return IMAGE.getInt(image, param_name); + } + + /** + * Single pointer value version of: {@link CL10#clGetImageInfo GetImageInfo} + */ + public static long clGetImageInfoPointer(long image, int param_name) { + return IMAGE.getPointer(image, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetImageInfo GetImageInfo} + */ + public static int clGetImageInfoPointers(long image, int param_name, PointerBuffer target) { + return IMAGE.getPointers(image, param_name, target); + } + + // ------------------------------------ + // Pipe (CL20.clGetPipeInfo) + // ------------------------------------ + private static final InfoQuery PIPE = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetPipeInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: {@link CL20#clGetPipeInfo GetPipeInfo} + */ + public static int clGetPipeInfoInt(long pipe, int param_name) { + return PIPE.getInt(pipe, param_name); + } + + // ------------------------------------ + // Program (CL10.clGetProgramInfo) + // ------------------------------------ + private static final InfoQuery PROGRAM = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetProgramInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: {@link CL10#clGetProgramInfo GetProgramInfo} + */ + public static int clGetProgramInfoInt(long program, int param_name) { + return PROGRAM.getInt(program, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetProgramInfo GetProgramInfo} + */ + public static long clGetProgramInfoPointer(long program, int param_name) { + return PROGRAM.getPointer(program, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetProgramInfo GetProgramInfo} + */ + public static int clGetProgramInfoPointers(long program, int param_name, PointerBuffer target) { + return PROGRAM.getPointers(program, param_name, target); + } + + /** + * String version of: {@link CL10#clGetProgramInfo GetProgramInfo} + */ + public static String clGetProgramInfoStringASCII(long program, int param_name) { + return PROGRAM.getStringASCII(program, param_name); + } + + /** + * String with explicit length version of: {@link CL10#clGetProgramInfo GetProgramInfo} + */ + public static String clGetProgramInfoStringASCII(long program, int param_name, int param_value_size) { + return PROGRAM.getStringASCII(program, param_name, param_value_size); + } + + /** + * UTF-8 string version of: {@link CL10#clGetProgramInfo GetProgramInfo} + */ + public static String clGetProgramInfoStringUTF8(long program, int param_name) { + return PROGRAM.getStringUTF8(program, param_name); + } + + /** + * UTF-8 string with explicit length version of: + * {@link CL10#clGetProgramInfo GetProgramInfo} + */ + public static String clGetProgramInfoStringUTF8(long program, int param_name, int param_value_size) { + return PROGRAM.getStringUTF8(program, param_name, param_value_size); + } + + // ------------------------------------ + // Program Build (CL10.clGetProgramBuildInfo) + // ------------------------------------ + private static final InfoQueryObject PROGRAM_BUILD = new InfoQueryObject() { + @Override + protected int get(long pointer, long arg, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetProgramBuildInfo(pointer, arg, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: + * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo} + */ + public static int clGetProgramBuildInfoInt(long program, long device, int param_name) { + return PROGRAM_BUILD.getInt(program, device, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo} + */ + public static long clGetProgramBuildInfoPointer(long program, long device, int param_name) { + return PROGRAM_BUILD.getPointer(program, device, param_name); + } + + /** + * PointBuffer version of: + * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo} + */ + public static int clGetProgramBuildInfoPointers(long program, long device, int param_name, PointerBuffer target) { + return PROGRAM_BUILD.getPointers(program, device, param_name, target); + } + + /** + * String version of: {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo} + */ + public static String clGetProgramBuildInfoStringASCII(long program, long device, int param_name) { + return PROGRAM_BUILD.getStringASCII(program, device, param_name); + } + + /** + * String with explicit length version of: {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo} + */ + public static String clGetProgramBuildInfoStringASCII(long program, long device, int param_name, int param_value_size) { + return PROGRAM_BUILD.getStringASCII(program, device, param_name, param_value_size); + } + + /** + * UTF-8 string version of: + * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo} + */ + public static String clGetProgramBuildInfoStringUTF8(long program, long device, int param_name) { + return PROGRAM_BUILD.getStringUTF8(program, device, param_name); + } + + /** + * UTF-8 string with explicit length version of: + * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo} + */ + public static String clGetProgramBuildInfoStringUTF8(long program, long device, int param_name, int param_value_size) { + return PROGRAM_BUILD.getStringUTF8(program, device, param_name, param_value_size); + } + + // ------------------------------------ + // Kernel (CL10.clGetKernelInfo) + // ------------------------------------ + private static final InfoQuery KERNEL = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetKernelInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: {@link CL10#clGetKernelInfo GetKernelInfo} + */ + public static int clGetKernelInfoInt(long kernel, int param_name) { + return KERNEL.getInt(kernel, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetKernelInfo GetKernelInfo} + */ + public static long clGetKernelInfoPointer(long kernel, int param_name) { + return KERNEL.getPointer(kernel, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetKernelInfo GetKernelInfo} + */ + public static int clGetKernelInfoPointers(long kernel, int param_name, PointerBuffer target) { + return KERNEL.getPointers(kernel, param_name, target); + } + + /** + * String version of: {@link CL10#clGetKernelInfo GetKernelInfo} + */ + public static String clGetKernelInfoStringASCII(long kernel, int param_name) { + return KERNEL.getStringASCII(kernel, param_name); + } + + /** + * String with explicit length version of: {@link CL10#clGetKernelInfo GetKernelInfo} + */ + public static String clGetKernelInfoStringASCII(long kernel, int param_name, int param_value_size) { + return KERNEL.getStringASCII(kernel, param_name, param_value_size); + } + + /** + * UTF-8 string version of: {@link CL10#clGetKernelInfo GetKernelInfo} + */ + public static String clGetKernelInfoStringUTF8(long kernel, int param_name) { + return KERNEL.getStringUTF8(kernel, param_name); + } + + /** + * UTF-8 string with explicit length version of: + * {@link CL10#clGetKernelInfo GetKernelInfo} + */ + public static String clGetKernelInfoStringUTF8(long kernel, int param_name, int param_value_size) { + return KERNEL.getStringUTF8(kernel, param_name, param_value_size); + } + + // ------------------------------------ + // Kernel WorkGroup (CL10.clGetKernelWorkGroupInfo) + // ------------------------------------ + private static final InfoQueryObject KERNEL_WORKGROUP = new InfoQueryObject() { + @Override + protected int get(long pointer, long arg, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetKernelWorkGroupInfo(pointer, arg, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single long value version of: + * {@link CL10#clGetKernelWorkGroupInfo GetKernelWorkGroupInfo} + */ + public static long clGetKernelWorkGroupInfoLong(long kernel, long device, int param_name) { + return KERNEL_WORKGROUP.getLong(kernel, device, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetKernelWorkGroupInfo GetKernelWorkGroupInfo} + */ + public static long clGetKernelWorkGroupInfoPointer(long kernel, long device, int param_name) { + return KERNEL_WORKGROUP.getPointer(kernel, device, param_name); + } + + /** + * PointBuffer version of: + * {@link CL10#clGetKernelWorkGroupInfo GetKernelWorkGroupInfo} + */ + public static int clGetKernelWorkGroupInfoPointers(long kernel, long device, int param_name, PointerBuffer target) { + return KERNEL_WORKGROUP.getPointers(kernel, device, param_name, target); + } + + // ------------------------------------ + // Kernel Arg (CL12.clGetKernelArgInfo) + // ------------------------------------ + private static final InfoQueryInt KERNEL_ARG = new InfoQueryInt() { + @Override + protected int get(long pointer, int arg, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetKernelArgInfo(pointer, arg, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: + * {@link CL12#clGetKernelArgInfo GetKernelArgInfo} + */ + public static int clGetKernelArgInfoInt(long kernel, int arg_indx, int param_name) { + return KERNEL_ARG.getInt(kernel, arg_indx, param_name); + } + + /** + * Single long value version of: + * {@link CL12#clGetKernelArgInfo GetKernelArgInfo} + */ + public static long clGetKernelArgInfoLong(long kernel, int arg_indx, int param_name) { + return KERNEL_ARG.getLong(kernel, arg_indx, param_name); + } + + /** + * String version of: {@link CL12#clGetKernelArgInfo GetKernelArgInfo} + */ + public static String clGetKernelArgInfoStringASCII(long kernel, int arg_indx, int param_name) { + return KERNEL_ARG.getStringASCII(kernel, arg_indx, param_name); + } + + /** + * String with explicit length version of: {@link CL12#clGetKernelArgInfo GetKernelArgInfo} + */ + public static String clGetKernelArgInfoStringASCII(long kernel, int arg_indx, int param_name, int param_value_size) { + return KERNEL_ARG.getStringASCII(kernel, arg_indx, param_name, param_value_size); + } + + /** + * UTF-8 string version of: {@link CL12#clGetKernelArgInfo GetKernelArgInfo} + */ + public static String clGetKernelArgInfoStringUTF8(long kernel, int arg_indx, int param_name) { + return KERNEL_ARG.getStringUTF8(kernel, arg_indx, param_name); + } + + /** + * UTF-8 string with explicit length version of: + * {@link CL12#clGetKernelArgInfo GetKernelArgInfo} + */ + public static String clGetKernelArgInfoStringUTF8(long kernel, int arg_indx, int param_name, int param_value_size) { + return KERNEL_ARG.getStringUTF8(kernel, arg_indx, param_name, param_value_size); + } + + // ------------------------------------ + // Sampler (CL10.clGetSamplerInfo) + // ------------------------------------ + private static final InfoQuery SAMPLER = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetSamplerInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single boolean value version of: + * {@link CL10#clGetSamplerInfo GetSamplerInfo} + */ + public static boolean clGetSamplerInfoBoolean(long sampler, int param_name) { + return SAMPLER.getBoolean(sampler, param_name); + } + + /** + * Single int value version of: {@link CL10#clGetSamplerInfo GetSamplerInfo} + */ + public static int clGetSamplerInfoInt(long sampler, int param_name) { + return SAMPLER.getInt(sampler, param_name); + } + + /** + * Single pointer value version of: + * {@link CL10#clGetSamplerInfo GetSamplerInfo} + */ + public static long clGetSamplerInfoPointer(long sampler, int param_name) { + return SAMPLER.getPointer(sampler, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetSamplerInfo GetSamplerInfo} + */ + public static int clGetSamplerInfoPointers(long sampler, int param_name, PointerBuffer target) { + return SAMPLER.getPointers(sampler, param_name, target); + } + + // ------------------------------------ + // Event (CL10.clGetEventInfo) + // ------------------------------------ + private static final InfoQuery EVENT = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetEventInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: {@link CL10#clGetEventInfo GetEventInfo} + */ + public static int clGetEventInfoInt(long event, int param_name) { + return EVENT.getInt(event, param_name); + } + + /** + * Single pointer value version of: {@link CL10#clGetEventInfo GetEventInfo} + */ + public static long clGetEventInfoPointer(long event, int param_name) { + return EVENT.getPointer(event, param_name); + } + + /** + * PointBuffer version of: {@link CL10#clGetEventInfo GetEventInfo} + */ + public static int clGetEventInfoPointers(long event, int param_name, PointerBuffer target) { + return EVENT.getPointers(event, param_name, target); + } + + // ------------------------------------ + // Event Profiling (CL10.clGetEventProfilingInfo) + // ------------------------------------ + private static final InfoQuery EVENT_PROFILING = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetEventProfilingInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single long value version of: + * {@link CL10#clGetEventProfilingInfo GetEventProfilingInfo} + */ + public static long clGetEventProfilingInfoLong(long event, int param_name) { + return EVENT_PROFILING.getLong(event, param_name); + } + + // ------------------------------------ + // GL Texture (CL10GL.clGetGLTextureInfo) + // ------------------------------------ + private static final InfoQuery GL_TEXTURE = new InfoQuery() { + @Override + protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) { + return nclGetGLTextureInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret); + } + }; + + /** + * Single int value version of: + * {@link CL10GL#clGetGLTextureInfo GetGLTextureInfo} + */ + public static int clGetGLTextureInfoInt(long memobj, int param_name) { + return GL_TEXTURE.getInt(memobj, param_name); + } + +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQuery.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQuery.java new file mode 100644 index 000000000..53411b385 --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQuery.java @@ -0,0 +1,215 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: http://lwjgl.org/license.php + */ +package com.jme3.opencl.lwjgl.info; + +import com.jme3.lwjgl3.utils.APIBuffer; +import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer; +import static com.jme3.opencl.lwjgl.info.CLUtil.checkCLError; +import org.lwjgl.PointerBuffer; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.MemoryUtil.*; +import static org.lwjgl.system.Pointer.*; + +/** + * Base class for OpenCL object information queries. + *

+ * All methods require the object being queried (a pointer value) and the + * integer parameter name. + * + * @see Info + */ +abstract class InfoQuery { + + protected abstract int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret); + + InfoQuery() { + } + + /** + * Returns the integer value for the specified {@code param_name}, converted + * to a boolean. + * + * @param object the object to query + * @param param_name the parameter to query + * + * @return the parameter's boolean value + */ + boolean getBoolean(long object, int param_name) { + return getInt(object, param_name) != 0; + } + + /** + * Returns the integer value for the specified {@code param_name}. + *

+ * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}), + * {@link #getPointer} should be used instead. + * + * @param object the object to query + * @param param_name the parameter to query + * + * @return the parameter's int value + */ + int getInt(long object, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, param_name, 4L, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.intValue(0); + } + + /** + * Returns the long value for the specified {@code param_name}. + *

+ * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}), + * {@link #getPointer} should be used instead. + * + * @param object the object to query + * @param param_name the parameter to query + * + * @return the parameter's long value + */ + long getLong(long object, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, param_name, 8L, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.longValue(0); + } + + /** + * Returns the pointer value for the specified {@code param_name}. + *

+ * This method should also be used for integer parameters that may be 32 or + * 64 bits (e.g. {@code size_t}). + * + * @param object the object to query + * @param param_name the parameter to query + * + * @return the parameter's pointer value + */ + long getPointer(long object, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, param_name, POINTER_SIZE, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.pointerValue(0); + } + + /** + * Writes the pointer list for the specified {@code param_name} into + * {@code target}. + *

+ * This method should also be used for integer parameters that may be 32 or + * 64 bits (e.g. {@code size_t}). + * + * @param object the object to query + * @param param_name the parameter to query + * @param target the buffer in which to put the returned pointer list + * + * @return how many pointers were actually returned + */ + int getPointers(long object, int param_name, PointerBuffer target) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, param_name, target.remaining() * POINTER_SIZE, memAddress(target), __buffer.address()); + if (DEBUG) { + checkCLError(errcode); + } + return (int) (__buffer.pointerValue(0) >> POINTER_SHIFT); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be ASCII encoded. + * + * @param object the object to query + * @param param_name the parameter to query + * + * @return the parameter's string value + */ + String getStringASCII(long object, int param_name) { + APIBuffer __buffer = apiBuffer(); + int bytes = getString(object, param_name, __buffer); + return __buffer.stringValueASCII(0, bytes); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be ASCII encoded and have length equal to {@code + * param_value_size}. + * + * @param object the object to query + * @param param_name the parameter to query + * @param param_value_size the explicit string length + * + * @return the parameter's string value + */ + String getStringASCII(long object, int param_name, int param_value_size) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, param_name, param_value_size, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.stringValueASCII(0, param_value_size); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be UTF-8 encoded. + * + * @param object the object to query + * @param param_name the parameter to query + * + * @return the parameter's string value + */ + String getStringUTF8(long object, int param_name) { + APIBuffer __buffer = apiBuffer(); + int bytes = getString(object, param_name, __buffer); + return __buffer.stringValueUTF8(0, bytes); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be UTF-8 encoded and have length equal to {@code + * param_value_size}. + * + * @param object the object to query + * @param param_name the parameter to query + * @param param_value_size the explicit string length + * + * @return the parameter's string value + */ + String getStringUTF8(long object, int param_name, int param_value_size) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, param_name, param_value_size, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.stringValueUTF8(0, param_value_size); + } + + private int getString(long object, int param_name, APIBuffer __buffer) { + // Get string length + int errcode = get(object, param_name, 0, NULL, __buffer.address()); + if (DEBUG) { + checkCLError(errcode); + } + + int bytes = (int) __buffer.pointerValue(0); + __buffer.bufferParam(bytes); + + // Get string + errcode = get(object, param_name, bytes, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + + return bytes - 1; // all OpenCL char[] parameters are null-terminated + } + +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryInt.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryInt.java new file mode 100644 index 000000000..b900887d7 --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryInt.java @@ -0,0 +1,224 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: http://lwjgl.org/license.php + */ +package com.jme3.opencl.lwjgl.info; + +import com.jme3.lwjgl3.utils.APIBuffer; +import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer; +import static com.jme3.opencl.lwjgl.info.CLUtil.checkCLError; +import org.lwjgl.PointerBuffer; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.MemoryUtil.*; +import static org.lwjgl.system.Pointer.*; + +/** + * Base class for OpenCL object information queries. + *

+ * All methods require the object being queried (a pointer value), a second + * integer argument and the integer parameter name. + * + * @see Info + */ +abstract class InfoQueryInt { + + protected abstract int get(long pointer, int arg, int param_name, long param_value_size, long param_value, long param_value_size_ret); + + InfoQueryInt() { + } + + /** + * Returns the integer value for the specified {@code param_name}, converted + * to a boolean. + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * + * @return the parameter's boolean value + */ + boolean getBoolean(long object, int arg, int param_name) { + return getInt(object, arg, param_name) != 0; + } + + /** + * Returns the integer value for the specified {@code param_name}. + *

+ * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}), + * {@link #getPointer} should be used instead. + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * + * @return the parameter's int value + */ + int getInt(long object, int arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, 4L, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.intValue(0); + } + + /** + * Returns the long value for the specified {@code param_name}. + *

+ * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}), + * {@link #getPointer} should be used instead. + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * + * @return the parameter's long value + */ + long getLong(long object, int arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, 8L, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.longValue(0); + } + + /** + * Returns the pointer value for the specified {@code param_name}. + *

+ * This method should also be used for integer parameters that may be 32 or + * 64 bits (e.g. {@code size_t}). + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * + * @return the parameter's pointer value + */ + long getPointer(long object, int arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, POINTER_SIZE, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.pointerValue(0); + } + + /** + * Writes the pointer list for the specified {@code param_name} into + * {@code target}. + *

+ * This method should also be used for integer parameters that may be 32 or + * 64 bits (e.g. {@code size_t}). + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * @param target the buffer in which to put the returned pointer list + * + * @return how many pointers were actually returned + */ + int getPointers(long object, int arg, int param_name, PointerBuffer target) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, target.remaining() * POINTER_SIZE, memAddress(target), __buffer.address()); + if (DEBUG) { + checkCLError(errcode); + } + return (int) (__buffer.pointerValue(0) >> POINTER_SHIFT); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be ASCII encoded. + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * + * @return the parameter's string value + */ + String getStringASCII(long object, int arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int bytes = getString(object, arg, param_name, __buffer); + return __buffer.stringValueASCII(0, bytes); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be ASCII encoded and have length equal to {@code + * param_value_size}. + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * @param param_value_size the explicit string length + * + * @return the parameter's string value + */ + String getStringASCII(long object, int arg, int param_name, int param_value_size) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.stringValueASCII(0, param_value_size); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be UTF-8 encoded. + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * + * @return the parameter's string value + */ + String getStringUTF8(long object, int arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int bytes = getString(object, arg, param_name, __buffer); + return __buffer.stringValueUTF8(0, bytes); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be UTF-8 encoded and have length equal to {@code + * param_value_size}. + * + * @param object the object to query + * @param arg an integer argument + * @param param_name the parameter to query + * @param param_value_size the explicit string length + * + * @return the parameter's string value + */ + String getStringUTF8(long object, int arg, int param_name, int param_value_size) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.stringValueUTF8(0, param_value_size); + } + + private int getString(long object, int arg, int param_name, APIBuffer __buffer) { + // Get string length + int errcode = get(object, arg, param_name, 0, NULL, __buffer.address()); + if (DEBUG) { + checkCLError(errcode); + } + + int bytes = (int) __buffer.pointerValue(0); + __buffer.bufferParam(bytes + POINTER_SIZE); + + // Get string + errcode = get(object, arg, param_name, bytes, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + + return bytes - 1; // all OpenCL char[] parameters are null-terminated + } + +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryObject.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryObject.java new file mode 100644 index 000000000..da9dc846f --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryObject.java @@ -0,0 +1,224 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: http://lwjgl.org/license.php + */ +package com.jme3.opencl.lwjgl.info; + +import com.jme3.lwjgl3.utils.APIBuffer; +import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer; +import static com.jme3.opencl.lwjgl.info.CLUtil.checkCLError; +import org.lwjgl.PointerBuffer; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.MemoryUtil.*; +import static org.lwjgl.system.Pointer.*; + +/** + * Base class for OpenCL object information queries. + *

+ * All methods require the object being queried (a pointer value), a second + * object argument (another pointer value) and the integer parameter name. + * + * @see org.lwjgl.opencl.Info + */ +abstract class InfoQueryObject { + + protected abstract int get(long pointer, long arg, int param_name, long param_value_size, long param_value, long param_value_size_ret); + + InfoQueryObject() { + } + + /** + * Returns the integer value for the specified {@code param_name}, converted + * to a boolean. + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * + * @return the parameter's boolean value + */ + boolean getBoolean(long object, long arg, int param_name) { + return getInt(object, arg, param_name) != 0; + } + + /** + * Returns the integer value for the specified {@code param_name}. + *

+ * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}), + * {@link #getPointer} should be used instead. + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * + * @return the parameter's int value + */ + int getInt(long object, long arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, 4L, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.intValue(0); + } + + /** + * Returns the long value for the specified {@code param_name}. + *

+ * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}), + * {@link #getPointer} should be used instead. + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * + * @return the parameter's long value + */ + long getLong(long object, long arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, 8L, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.longValue(0); + } + + /** + * Returns the pointer value for the specified {@code param_name}. + *

+ * This method should also be used for integer parameters that may be 32 or + * 64 bits (e.g. {@code size_t}). + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * + * @return the parameter's pointer value + */ + long getPointer(long object, long arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, POINTER_SIZE, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.pointerValue(0); + } + + /** + * Writes the pointer list for the specified {@code param_name} into + * {@code target}. + *

+ * This method should also be used for integer parameters that may be 32 or + * 64 bits (e.g. {@code size_t}). + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * @param target the buffer in which to put the returned pointer list + * + * @return how many pointers were actually returned + */ + int getPointers(long object, long arg, int param_name, PointerBuffer target) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, target.remaining() * POINTER_SIZE, memAddress(target), __buffer.address()); + if (DEBUG) { + checkCLError(errcode); + } + return (int) (__buffer.pointerValue(0) >> POINTER_SHIFT); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be ASCII encoded. + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * + * @return the parameter's string value + */ + String getStringASCII(long object, long arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int bytes = getString(object, arg, param_name, __buffer); + return __buffer.stringValueASCII(0, bytes); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be ASCII encoded and have length equal to {@code + * param_value_size}. + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * @param param_value_size the explicit string length + * + * @return the parameter's string value + */ + String getStringASCII(long object, long arg, int param_name, int param_value_size) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.stringValueASCII(0, param_value_size); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be UTF-8 encoded. + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * + * @return the parameter's string value + */ + String getStringUTF8(long object, long arg, int param_name) { + APIBuffer __buffer = apiBuffer(); + int bytes = getString(object, arg, param_name, __buffer); + return __buffer.stringValueUTF8(0, bytes); + } + + /** + * Returns the string value for the specified {@code param_name}. The raw + * bytes returned are assumed to be UTF-8 encoded and have length equal to {@code + * param_value_size}. + * + * @param object the object to query + * @param arg an object argument + * @param param_name the parameter to query + * @param param_value_size the explicit string length + * + * @return the parameter's string value + */ + String getStringUTF8(long object, long arg, int param_name, int param_value_size) { + APIBuffer __buffer = apiBuffer(); + int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + return __buffer.stringValueUTF8(0, param_value_size); + } + + private int getString(long object, long arg, int param_name, APIBuffer __buffer) { + // Get string length + int errcode = get(object, arg, param_name, 0, NULL, __buffer.address()); + if (DEBUG) { + checkCLError(errcode); + } + + int bytes = (int) __buffer.pointerValue(0); + __buffer.bufferParam(bytes + POINTER_SIZE); + + // Get string + errcode = get(object, arg, param_name, bytes, __buffer.address(), NULL); + if (DEBUG) { + checkCLError(errcode); + } + + return bytes - 1; // all OpenCL char[] parameters are null-terminated + } + +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java index 9c31f2085..04265df97 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java @@ -50,6 +50,7 @@ import com.jme3.renderer.lwjgl.LwjglGLFboEXT; import com.jme3.renderer.lwjgl.LwjglGLFboGL3; import com.jme3.renderer.opengl.*; import com.jme3.system.*; +import java.nio.IntBuffer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -105,9 +106,9 @@ public abstract class LwjglContext implements JmeContext { protected int determineMaxSamples() { // If we already have a valid context, determine samples using current context. - if (GLFW.glfwExtensionSupported("GL_ARB_framebuffer_object") == GLFW_TRUE) { + if (GLFW.glfwExtensionSupported("GL_ARB_framebuffer_object")) { return glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES); - } else if (GLFW.glfwExtensionSupported("GL_EXT_framebuffer_multisample") == GLFW_TRUE) { + } else if (GLFW.glfwExtensionSupported("GL_EXT_framebuffer_multisample")) { return glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT); } @@ -197,7 +198,40 @@ public abstract class LwjglContext implements JmeContext { renderable.set(true); } - + + /** + * Returns a list of the available platforms, filtered by the specified + * filter. + * + * Copied from the old release + * + * @param filter the platform filter + * + * @return the available platforms + */ + private static long[] getPlatforms() { + int[] count = new int[1]; + int errcode = CL10.clGetPlatformIDs(null, count); + Utils.checkError(errcode, "clGetDeviceIDs"); + + int num_platforms = count[0]; + if (num_platforms == 0) { + return new long[0]; + } + + PointerBuffer platforms = PointerBuffer.allocateDirect(num_platforms); + errcode = CL10.clGetPlatformIDs(platforms, (IntBuffer) null); + Utils.checkError(errcode, "clGetDeviceIDs"); + + platforms.rewind(); + long[] platformIDs = new long[num_platforms]; + for (int i = 0; i < num_platforms; i++) { + platformIDs[i] = platforms.get(); + } + + return platformIDs; + } + protected void initOpenCL(long window) { logger.info("Initialize OpenCL with LWJGL3"); @@ -211,7 +245,7 @@ public abstract class LwjglContext implements JmeContext { //load platforms and devices StringBuilder platformInfos = new StringBuilder(); ArrayList platforms = new ArrayList<>(); - for (CLPlatform p : CLPlatform.getPlatforms()) { + for (long p : getPlatforms()) { platforms.add(new LwjglPlatform(p)); } platformInfos.append("Available OpenCL platforms:"); @@ -260,7 +294,7 @@ public abstract class LwjglContext implements JmeContext { chooser = new DefaultPlatformChooser(); } List choosenDevices = chooser.chooseDevices(platforms); - List devices = new ArrayList<>(choosenDevices.size()); + List devices = new ArrayList<>(choosenDevices.size()); LwjglPlatform platform = null; for (Device d : choosenDevices) { if (!(d instanceof LwjglDevice)) { @@ -274,7 +308,7 @@ public abstract class LwjglContext implements JmeContext { logger.severe("attempt to use devices from different platforms"); return; } - devices.add(ld.getCLDevice()); + devices.add(ld.getDevice()); } if (devices.isEmpty()) { logger.warning("no devices specified, no OpenCL context created"); @@ -294,7 +328,7 @@ public abstract class LwjglContext implements JmeContext { logger.info("OpenCL context created"); } - private long createContext(final CLPlatform platform, final List devices, long window) throws Exception { + private long createContext(final long platform, final List devices, long window) throws Exception { final int propertyCount = 2 + 4 + 1; @@ -330,7 +364,7 @@ public abstract class LwjglContext implements JmeContext { Utils.errorBuffer.rewind(); PointerBuffer deviceBuffer = PointerBuffer.allocateDirect(devices.size()); - for (CLDevice d : devices) { + for (long d : devices) { deviceBuffer.put(d); } deviceBuffer.flip(); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglGLDebugOutputHandler.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglGLDebugOutputHandler.java index aa9c46511..d03f54962 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglGLDebugOutputHandler.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglGLDebugOutputHandler.java @@ -75,4 +75,14 @@ class LwjglGLDebugOutputHandler extends GLDebugMessageARBCallback { System.err.println(String.format(MESSAGE_FORMAT, id, sourceStr, typeStr, severityStr, message)); } + + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index 6e351d8b2..d5e515410 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -132,9 +132,19 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { final String message = GLFWErrorCallback.getDescription(description); listener.handleError(message, new Exception(message)); } + + @Override + public void close(){ + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); - if (glfwInit() != GLFW_TRUE) { + if (!glfwInit()) { throw new IllegalStateException("Unable to initialize GLFW"); } @@ -161,7 +171,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { glfwWindowHint(GLFW_VISIBLE, GL_FALSE); glfwWindowHint(GLFW_RESIZABLE, settings.isResizable() ? GLFW_TRUE : GLFW_FALSE); - glfwWindowHint(GLFW_DOUBLE_BUFFER, GLFW_TRUE); + //glfwWindowHint(GLFW_DOUBLE_BUFFER, GLFW_TRUE); glfwWindowHint(GLFW_DEPTH_BITS, settings.getDepthBits()); glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits()); glfwWindowHint(GLFW_SAMPLES, settings.getSamples()); @@ -206,12 +216,21 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { settings.setResolution(width, height); listener.reshape(width, height); } + + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); glfwSetWindowFocusCallback(window, windowFocusCallback = new GLFWWindowFocusCallback() { @Override - public void invoke(final long window, final int focused) { - final boolean focus = (focused == GL_TRUE); + public void invoke(final long window, final boolean focus) { if (wasActive != focus) { if (!wasActive) { listener.gainFocus(); @@ -223,6 +242,16 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { wasActive = !wasActive; } } + + @Override + public void close() { + super.close(); + } + + @Override + public void callback(long args) { + super.callback(args); + } }); // Center the window @@ -260,17 +289,17 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { } if (errorCallback != null) { - errorCallback.release(); + errorCallback.close(); errorCallback = null; } if (windowSizeCallback != null) { - windowSizeCallback.release(); + windowSizeCallback.close(); windowSizeCallback = null; } if (windowFocusCallback != null) { - windowFocusCallback.release(); + windowFocusCallback.close(); windowFocusCallback = null; } @@ -460,7 +489,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable { break; } - if (glfwWindowShouldClose(window) == GL_TRUE) { + if (glfwWindowShouldClose(window)) { listener.requestClose(false); } }