Login  Register

Re: Multiple OpenCL contexts

Posted by shaman on May 29, 2016; 12:14pm
URL: https://forum.jogamp.org/Multiple-OpenCL-contexts-tp4036753p4036756.html

Here is a simple example. I copy'n'paste all important parts from jME3 together so that it works (more or less).
Now the second context fails in creating the OpenCL context.


import com.jogamp.opencl.CLBuffer;
import com.jogamp.opencl.CLDevice;
import com.jogamp.opencl.CLMemory;
import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.gl.CLGLContext;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.AnimatorBase;
import com.jogamp.opengl.util.FPSAnimator;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;


/**
 *
 * @author Sebastian Weiss
 */
public class MultiContextTest implements GLEventListener {

    protected GraphicsDevice device;
    protected GLCanvas canvas;
    protected AnimatorBase animator;
    protected Frame frame;
    protected CLDevice clDevice;
    protected CLGLContext clContext;
    protected int index;
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //query platform
        final CLPlatform platform = CLPlatform.listCLPlatforms()[0];
        System.out.println("Platform Name: "+platform.getName());
        final CLDevice[] devices = platform.listCLDevices();
        for (int i=0; i<devices.length; ++i) {
            final CLDevice device = devices[i];
            final int ii = i;
            new Thread() {
                public void run() {
                    new MultiContextTest(device, ii);
                }
            }.start();
            try {
                Thread.sleep(200);
            } catch (InterruptedException ex) {
                Logger.getLogger(MultiContextTest.class.getName()).log(Level.SEVERE, null, ex);
            }
            //break;
        }
    }

    public MultiContextTest(CLDevice device, int index) {
        this.index = index;
        launch(device);
    }
   
    private void launch(CLDevice clDevice) {
        this.clDevice = clDevice;
        System.out.println("Device Name: "+clDevice.getName());
        if (!clDevice.isAvailable()) {
            System.out.println("Device not available");
            return;
        }
        if (!clDevice.isGLMemorySharingSupported()) {
            System.out.println("OpenGL sharing not supported");
            return;
        }
       
        //create OpenGL context
        create(true);
       
    }
   
    private void createCLContext(GLContext context) {
        //create OpenCL context
        try {
            clContext = CLGLContext.create(context, new CLDevice[]{clDevice});
            System.out.println("CL context created");
        } catch (Exception ex) {
            System.err.println("Unable to create OpenCL context");
            ex.printStackTrace();
            return;
        }
    }
   
    private void update() {
        if (clContext == null) {
            return;
        }
       
        //test OpenCL
        try {
        CLBuffer buffer = clContext.createBuffer(1024, CLMemory.Mem.READ_WRITE);
        buffer.release();
        } catch (Exception ex) {
            System.err.println(index+": OpenCL exception: "+ex.getLocalizedMessage());
            CLGLContext c = clContext;
            clContext = null;
            c.release();
            return;
        }
       
        System.out.println(index+": update");
    }
   
    private void initGLCanvas() {
        device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
       
        GLCapabilities caps = new GLCapabilities(GLProfile.getMaxProgrammable(true));
       
        caps.setHardwareAccelerated(true);
        caps.setDoubleBuffered(true);
        caps.setStencilBits(8);
        caps.setDepthBits(24);

        canvas = new GLCanvas(caps) {
            @Override
            public void addNotify() {
                super.addNotify();
                onCanvasAdded();
            }

            @Override
            public void removeNotify() {
                onCanvasRemoved();
                super.removeNotify();
            }
        };
        canvas.invoke(false, new GLRunnable() {
            public boolean run(GLAutoDrawable glad) {
                canvas.getGL().setSwapInterval(1);
                return true;
            }
        });
        canvas.setFocusable(true);
        canvas.requestFocus();
        canvas.setSize(800, 600);
        canvas.setIgnoreRepaint(true);
        canvas.addGLEventListener(this);
    }
   
    protected void createGLFrame(){
        frame = new Frame("Test: "+clDevice.getName());
        frame.setResizable(false);
        frame.add(canvas);
       
        applySettings();
       
        // Make the window visible to realize the OpenGL surface.
        frame.setVisible(true);
       
        canvas.setVisible(true);
    }

    protected void applySettings(){
        final boolean isDisplayModeModified;
        final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        // Get the current display mode
        final DisplayMode previousDisplayMode = gd.getDisplayMode();
        // center the window on the screen.
        isDisplayModeModified = false;
        frame.pack();

        int x, y;
        x = (Toolkit.getDefaultToolkit().getScreenSize().width - 800) / 2;
        y = (Toolkit.getDefaultToolkit().getScreenSize().height - 600) / 2;
        frame.setLocation(x, y);
       
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent evt) {
                // If required, restore the previous display mode
                if (isDisplayModeModified) {
                    gd.setDisplayMode(previousDisplayMode);
                }
                // If required, get back to the windowed mode
                if (gd.getFullScreenWindow() == frame) {
                    gd.setFullScreenWindow(null);
                }
//                windowCloseRequest.set(true);
            }
            @Override
            public void windowActivated(WindowEvent evt) {
//                active.set(true);
            }

            @Override
            public void windowDeactivated(WindowEvent evt) {
//                active.set(false);
            }
        });
    }
   
    protected void startGLCanvas() {
        animator = new FPSAnimator(canvas, 30);

        animator.start();
    }
   
    private void initInEDT(){
        initGLCanvas();

        createGLFrame();

        startGLCanvas();
    }


    public void create(boolean waitFor){
        if (SwingUtilities.isEventDispatchThread()) {
            initInEDT();
        } else {
            try {
                if (waitFor) {
                    try {
                        SwingUtilities.invokeAndWait(new Runnable() {
                            public void run() {
                                initInEDT();
                            }
                        });
                    } catch (InterruptedException ex) {
                        System.err.println("Interrupted");
                    }
                } else {
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            initInEDT();
                        }
                    });
                }
            } catch (InvocationTargetException ex) {
                throw new AssertionError(); // can never happen
            }
        }
    }
   
    @Override
    public void init(GLAutoDrawable drawable) {
        canvas.requestFocus();
        createCLContext(drawable.getContext());
    }

    @Override
    public void dispose(GLAutoDrawable drawable) {

    }

    @Override
    public void display(GLAutoDrawable drawable) {
        update();
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
       
    }
   
    protected void onCanvasRemoved(){
    }

    protected void onCanvasAdded(){

    }
}