|
|
|
@ -32,6 +32,7 @@ |
|
|
|
|
package com.jme3.opencl.jocl; |
|
|
|
|
|
|
|
|
|
import com.jme3.opencl.*; |
|
|
|
|
import com.jogamp.common.nio.Buffers; |
|
|
|
|
import com.jogamp.common.nio.PointerBuffer; |
|
|
|
|
import com.jogamp.opencl.CLPlatform; |
|
|
|
|
import com.jogamp.opencl.CLProgram; |
|
|
|
@ -133,16 +134,47 @@ public class JoclProgram extends Program { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public ByteBuffer getBinary(Device device) { |
|
|
|
|
//There is no way to do this in Jocl:
|
|
|
|
|
//The low-level bindings need a buffer of adresses to buffers. For that
|
|
|
|
|
//the class InternalBufferUtil is used, but this class is not public.
|
|
|
|
|
//I also can't create a temporal instance of CLProgram because the constructor
|
|
|
|
|
//that takes only the native pointer is private.
|
|
|
|
|
//So the only way would be to create the CLProgram directly from the beginning.
|
|
|
|
|
//I don't want to do this because then I would have to use the whole
|
|
|
|
|
//bunch of garbage the CLProgram class is doing in background.
|
|
|
|
|
throw new UnsupportedOperationException("Jocl does not expose this operation"); |
|
|
|
|
public ByteBuffer getBinary(Device d) { |
|
|
|
|
|
|
|
|
|
JoclDevice device = (JoclDevice) d; |
|
|
|
|
|
|
|
|
|
Utils.tempBuffers[0].b16i.rewind(); |
|
|
|
|
int ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_NUM_DEVICES, 4, Utils.tempBuffers[0].b16i, null); |
|
|
|
|
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_NUM_DEVICES"); |
|
|
|
|
int numDevices = Utils.tempBuffers[0].b16i.get(0); |
|
|
|
|
|
|
|
|
|
PointerBuffer devices = PointerBuffer.allocateDirect(numDevices); |
|
|
|
|
ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_DEVICES, numDevices * PointerBuffer.ELEMENT_SIZE, devices.getBuffer(), null); |
|
|
|
|
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_DEVICES"); |
|
|
|
|
int index = -1; |
|
|
|
|
for (int i=0; i<numDevices; ++i) { |
|
|
|
|
if (devices.get(i) == device.id) { |
|
|
|
|
index = i; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (index == -1) { |
|
|
|
|
throw new com.jme3.opencl.OpenCLException("Program was not built against the specified device "+device); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
final PointerBuffer sizes = PointerBuffer.allocateDirect(numDevices); |
|
|
|
|
ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_BINARY_SIZES, numDevices * PointerBuffer.ELEMENT_SIZE, sizes.getBuffer(), null); |
|
|
|
|
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_BINARY_SIZES"); |
|
|
|
|
|
|
|
|
|
final ByteBuffer binaries = Buffers.newDirectByteBuffer((int) sizes.get(index)); |
|
|
|
|
final PointerBuffer addresses = PointerBuffer.allocateDirect(numDevices); |
|
|
|
|
for (int i=0; i<numDevices; ++i) { |
|
|
|
|
if (index == i) { |
|
|
|
|
addresses.referenceBuffer(binaries); |
|
|
|
|
} else { |
|
|
|
|
addresses.put(0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
addresses.rewind(); |
|
|
|
|
|
|
|
|
|
ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_BINARIES, numDevices * PointerBuffer.ELEMENT_SIZE, addresses.getBuffer(), null); |
|
|
|
|
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_BINARIES"); |
|
|
|
|
|
|
|
|
|
return binaries; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static class ReleaserImpl implements ObjectReleaser { |
|
|
|
|