/** * Creates a shared image object from a jME3 render buffer. * The returned image shares the same memory with the jME3 render buffer, changes * in one view are visible in the other view. * <br> * This can be used as an alternative to post processing effects * (e.g. reduce sum operations, needed e.g. for tone mapping). * <br> * <b>Note:</b> The renderbuffer must already been uploaded to the GPU, * i.e. it must be used at least once for drawing. * <p> * Before the returned image can be used, it must be acquried explicitly * by {@link Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) } * and after modifying it, released by {@link Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) } * This is needed so that OpenGL and OpenCL operations do not interfer with each other. * * @param buffer * @param access * @return */ public Image bindRenderBuffer(FrameBuffer.RenderBuffer buffer, MemoryAccess access) { if (buffer.getTexture() == null) { return bindPureRenderBuffer(buffer, access); } else { return bindImage(buffer.getTexture(), access); } } protected abstract Image bindPureRenderBuffer(FrameBuffer.RenderBuffer buffer, MemoryAccess access);
private void updateInfos() { if (testBuffer == null && clContext != null && !bufferCreated) { try { testBuffer = clContext.createBuffer(1024).register(); LOG.info("Test buffer created"); } catch (OpenCLException ex) { LOG.log(Level.SEVERE, "Unable to create buffer", ex); } bufferCreated = true; } Context c = context.getOpenCLContext(); if (c == clContext) { return; } clContext = c; LOG.info("context changed"); testBuffer = null; bufferCreated = false; StringBuilder text = new StringBuilder(); text.append("Current context:\n"); text.append(" Platform: ").append(clContext.getDevices().get(0).getPlatform().getName()).append("\n"); text.append(" Device: ").append(clContext.getDevices().get(0).getName()).append("\n"); text.append(" Profile: ").append(clContext.getDevices().get(0).getProfile()).append("\n"); text.append(" Memory: ").append(clContext.getDevices().get(0).getGlobalMemorySize()).append(" B\n"); text.append(" Compute Units: ").append(clContext.getDevices().get(0).getComputeUnits()).append("\n"); infoLabel.setText(text.toString()); }
/** * Resolves dependencies (using {@code #include } in the source code) * and delegates the combined source code to * {@link #createProgramFromSourceCode(java.lang.String) }. * Important: only absolute paths are allowed. * @param sourceCode the original source code * @param assetManager the asset manager to load the files * @return the created program object * @throws AssetNotFoundException if a dependency could not be loaded */ public Program createProgramFromSourceCodeWithDependencies(String sourceCode, AssetManager assetManager) { StringBuilder builder = new StringBuilder(sourceCode.length()); BufferedReader reader = new BufferedReader(new StringReader(sourceCode)); try { buildSourcesRec(reader, builder, assetManager); } catch (IOException ex) { throw new AssetNotFoundException("Unable to read a dependency file", ex); } return createProgramFromSourceCode(builder.toString()); } private void buildSourcesRec(BufferedReader reader, StringBuilder builder, AssetManager assetManager) throws IOException {
/** * Creates a command queue sending commands to the specified device. * The device must be an entry of {@link #getDevices() }. * @param device the target device * @return the command queue */ public abstract CommandQueue createQueue(Device device);
private void initOpenCL1() { clContext = context.getOpenCLContext(); Device device = clContext.getDevices().get(0); clQueue = clContext.createQueue(device).register(); program = clContext.createProgramFromBinary(bb, device); program.build(); LOG.info("reuse program from cached binaries"); + " vstore3(pos, idx, vb);\n" + "}\n"; program = clContext.createProgramFromSourceCode(source); program.build();
return; Device device = clContext.getDevices().get(0); clQueue = clContext.createQueue(device); clQueue.register(); + " vb[idx] = v;\n" + "}\n"; Program program = clContext.createProgramFromSourceCode(source); program.build(); program.register(); kernel.register(); buffer = clContext.createBuffer(4); buffer.register(); infoText = new BitmapText(fnt, false); infoText.setText("Device: "+clContext.getDevices()); infoText.setLocalTranslation(0, settings.getHeight(), 0); guiNode.attachChild(infoText);
private boolean testRandom(Context clContext, CommandQueue clQueue) { try { boolean supportsDoubles = clContext.getDevices().get(0).hasDouble(); code = "#define RANDOM_DOUBLES\n" + code; Program program = clContext.createProgramFromSourceCodeWithDependencies(code, assetManager); program.build(); seeds[i] = (seeds[i] ^ 0x5DEECE66DL) & ((1L << 48) - 1); //needed because the Random constructor scrambles the initial seed com.jme3.opencl.Buffer seedsBuffer = clContext.createBuffer(8 * count); ByteBuffer tmpByteBuffer = BufferUtils.createByteBuffer(8 * count); tmpByteBuffer.asLongBuffer().put(seeds); FloatBuffer resultFloatBuffer = resultByteBuffer.asFloatBuffer(); DoubleBuffer resultDoubleBuffer = resultByteBuffer.asDoubleBuffer(); com.jme3.opencl.Buffer resultBuffer = clContext.createBuffer(8 * count);
+ " result[2] = mat4Equals(res, m3, 0.0001f) ? 1 : 0;\n" + "}\n"; Program program = clContext.createProgramFromSourceCodeWithDependencies(code, assetManager); program.build(); com.jme3.opencl.Buffer buffer = clContext.createBuffer(3);
/** * Alternative version of {@link #createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.util.List) } * with an empty include string * @throws AssetNotFoundException if a file could not be loaded */ public Program createProgramFromSourceFiles(AssetManager assetManager, List<String> resources) { return createProgramFromSourceFilesWithInclude(assetManager, "", resources); }
Program program = clContext.createProgramFromSourceFilesWithInclude(assetManager, include, "jme3test/opencl/Blas.cl"); program.build(); Kernel kernel = program.createKernel("Fill"); Buffer buffer = clContext.createBuffer(size*4); float value = 5; Event event = kernel.Run1(clQueue, new com.jme3.opencl.Kernel.WorkSize(buffer.getSize() / 4), buffer, value);
/** * Alternative version to {@link #bindImage(com.jme3.texture.Texture, int, com.jme3.opencl.MemoryAccess) }, * uses {@code miplevel=0}. * @param texture the jME3 texture * @param access the allowed memory access for kernels * @return the OpenCL image */ public Image bindImage(Texture texture, MemoryAccess access) { return bindImage(texture, 0, access); } /**
@Override public String toString() { return "Context (" + getDevices() + ')'; }
for (Image.ImageType type : Image.ImageType.values()) { try { System.out.println("Formats for " + ma + " and " + type + ": " + Arrays.toString(clContext.querySupportedFormats(ma, type))); } catch (UnsupportedOperationException e) { LOG.warning(e.getLocalizedMessage()); Image image = clContext.createImage(MemoryAccess.READ_WRITE, format, descr); System.out.println("image created"); Buffer buffer = clContext.createBuffer(4*4*500*1024); Event e3 = image.copyToBufferAsync(clQueue, buffer, new long[]{10,10,0}, new long[]{500,1024,1}, 0); e3.release(); Image image2 = clContext.createImage(MemoryAccess.READ_WRITE, format, descr);
/** * Alternative version of {@link #createBuffer(long, com.jme3.opencl.MemoryAccess) }, * creates a buffer with read and write access. * @param size the size of the buffer in bytes * @return the new buffer */ public Buffer createBuffer(long size) { return createBuffer(size, MemoryAccess.READ_WRITE); }
private void initOpenCL1() { clContext = context.getOpenCLContext(); clQueue = clContext.createQueue().register(); programCache = new ProgramCache(clContext); //create kernel String cacheID = getClass().getName()+".Julia"; Program program = programCache.loadFromCache(cacheID); if (program == null) { LOG.info("Program not loaded from cache, create from sources instead"); program = clContext.createProgramFromSourceFiles(assetManager, "jme3test/opencl/JuliaSet.cl"); program.build(); programCache.saveToCache(cacheID, program); } program.register(); kernel = program.createKernel("JuliaSet").register(); C = new Vector2f(0.12f, -0.2f); } private void initOpenCL2() {
return createProgramFromSourceCodeWithDependencies(str.toString(), assetManager);
program = context.createProgramFromBinary(bb, device); } catch (OpenCLException ex) { LOG.log(Level.FINE, "Unable to create program from binary", ex);
private void buildSourcesRec(BufferedReader reader, StringBuilder builder, AssetManager assetManager) throws IOException { String ln; while ((ln = reader.readLine()) != null) { if (ln.trim().startsWith("#import ")) { ln = ln.trim().substring(8).trim(); if (ln.startsWith("\"")) { ln = ln.substring(1); } if (ln.endsWith("\"")) { ln = ln.substring(0, ln.length()-1); } AssetInfo info = assetManager.locateAsset(new AssetKey<String>(ln)); if (info == null) { throw new AssetNotFoundException("Unable to load source file \""+ln+"\""); } try (BufferedReader r = new BufferedReader(new InputStreamReader(info.openStream()))) { builder.append("//-- begin import ").append(ln).append(" --\n"); buildSourcesRec(r, builder, assetManager); builder.append("//-- end import ").append(ln).append(" --\n"); } } else { builder.append(ln).append('\n'); } } }
return; CommandQueue clQueue = clContext.createQueue(clContext.getDevices().get(0)); .append(clContext.getDevices().get(0).getPlatform().getName()) .append("\n Devices: ").append(clContext.getDevices()); str.append("\nTests:"); str.append("\n Random numbers: ").append(testRandom(clContext, clQueue));
+ " result[0] = mat3Equals(mRes, m, 0.01f) ? 1 : 0;\n" + "}\n"; Program program = clContext.createProgramFromSourceCodeWithDependencies(code, assetManager); program.build(); com.jme3.opencl.Buffer buffer = clContext.createBuffer(1);