package edu.stanford.rsl.conrad.opencl.shapes; import java.nio.FloatBuffer; import java.util.ArrayList; import com.jogamp.opencl.CLBuffer; import com.jogamp.opencl.CLCommandQueue; import com.jogamp.opencl.CLDevice; import com.jogamp.opencl.CLImage3d; import com.jogamp.opencl.CLImageFormat; import com.jogamp.opencl.CLKernel; import com.jogamp.opencl.CLMemory; import com.jogamp.opencl.CLMemory.Mem; import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND; import edu.stanford.rsl.conrad.geometry.splines.SurfaceBSpline; import edu.stanford.rsl.conrad.geometry.splines.TimeVariantSurfaceBSpline; import edu.stanford.rsl.conrad.opencl.OpenCLUtil; public class OpenCLTextureTimeVariantSurfaceBSpline extends OpenCLTimeVariantSurfaceBSpline { CLImage3d<FloatBuffer> texture; public OpenCLTextureTimeVariantSurfaceBSpline( TimeVariantSurfaceBSpline timeVariantSpline, CLDevice device) { super(timeVariantSpline, device); } public OpenCLTextureTimeVariantSurfaceBSpline( ArrayList<SurfaceBSpline> splines, CLDevice device) { super(splines, device); } protected void handleControlPoints(){ int size = this.timeVariantShapes.size() * this.timeVariantShapes.get(0).getControlPoints().size(); //int count = 0; this.controlPoints = context.createFloatBuffer(size*4, Mem.READ_ONLY); for (int j = 0; j < timeVariantShapes.size(); j++){ ArrayList<PointND> controlPoints = timeVariantShapes.get(j).getControlPoints(); for(int i=0;i<controlPoints.size();i++) { this.controlPoints.getBuffer().put((float)controlPoints.get(i).get(0)); this.controlPoints.getBuffer().put((float)controlPoints.get(i).get(1)); this.controlPoints.getBuffer().put((float)controlPoints.get(i).get(2)); this.controlPoints.getBuffer().put(0f); //count ++; } } //System.out.println(size + " " + count); this.controlPoints.getBuffer().rewind(); texture = context.createImage3d(this.controlPoints.getBuffer(), this.timeVariantShapes.get(0).getVKnots().getLen()-4, this.timeVariantShapes.get(0).getUKnots().getLen()-4, this.timeVariantShapes.size(), new CLImageFormat(CLImageFormat.ChannelOrder.RGBA, CLImageFormat.ChannelType.FLOAT), CLMemory.Mem.READ_ONLY); device.createCommandQueue().putWriteImage(texture, true).finish().release(); } /* * Tessellate a 3D spline using texture interpolation. * Used to be called evaluteNoTransfer, but the old evaluate function caused a memory leak * @see edu.stanford.rsl.conrad.opencl.OpenCLTimeVariantSurfaceBSpline#evaluate(com.jogamp.opencl.CLBuffer, com.jogamp.opencl.CLBuffer) */ @Override public void evaluate(CLBuffer<FloatBuffer> samplingPoints, CLBuffer<FloatBuffer> outputBuffer, int elementCountU, int elementCountV) { int elementCount = samplingPoints.getBuffer().capacity()/3; // Length of arrays to process int localWorkSize = Math.min(device.getMaxWorkGroupSize(), 256); // Local work size dimensions int globalWorkSize = OpenCLUtil.roundUp(localWorkSize, elementCount); // rounded up to the nearest multiple of the localWorkSize CLKernel kernel = OpenCLUtil.getProgramInstance().createCLKernel("evaluate3DTextureInterp"); kernel.putArgs(texture, samplingPoints, outputBuffer) .putArg(elementCountU).putArg(elementCountV).putArg(timeVariantShapes.size()+4) .putArg(elementCount); // asynchronous write of data to GPU device, // followed by blocking read to get the computed results back. CLCommandQueue clc = device.createCommandQueue(); clc.put1DRangeKernel(kernel, 0, globalWorkSize, localWorkSize).finish(); kernel.release(); clc.release(); } /** * */ private static final long serialVersionUID = -1682699329382911891L; } /* * Copyright (C) 2010-2014 Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */