summaryrefslogtreecommitdiffstats
path: root/src/com/mbien/opencl/CLGLContext.java
blob: a66772e795aabb374f03eb6ad9b672b4cd571266 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package com.mbien.opencl;

import java.nio.Buffer;
import com.mbien.opencl.CLMemory.Mem;
import com.sun.gluegen.runtime.PointerBuffer;
import com.sun.opengl.impl.GLContextImpl;
import com.sun.opengl.impl.macosx.cgl.MacOSXCGLContext;
import com.sun.opengl.impl.windows.wgl.WindowsWGLContext;
import com.sun.opengl.impl.x11.glx.X11GLXContext;
import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.opengl.GLContext;

import static com.mbien.opencl.CLGLI.*;

/**
 * OpenCL Context supporting interoperablity between JOGL and JOCL.
 * @author Michael Bien
 */
public final class CLGLContext extends CLContext {

    final long glID;

    private CLGLContext(long clContextID, long glContextID) {
        super(clContextID);
        this.glID = glContextID;
    }

    /**
     * Creates a shared context on all available devices (CL_DEVICE_TYPE_ALL).
     */
    public static final CLGLContext create(GLContext glContext) {
        return create(glContext, (CLPlatform)null, CLDevice.Type.ALL);
    }

    /**
     * Creates a shared context on the specified platform on all available devices (CL_DEVICE_TYPE_ALL).
     */
    public static CLGLContext create(GLContext glContext, CLPlatform platform) {
        return create(glContext, platform, CLDevice.Type.ALL);
    }

    public static CLGLContext create(GLContext glContext, CLDevice.Type... deviceTypes) {
        return create(glContext, null, deviceTypes);
    }

    /**
     * Creates a shared context on the specified devices.
     * The platform to be used is implementation dependent.
     */
    public static final CLGLContext create(GLContext glContext, CLDevice... devices) {
        return create(glContext, null, devices);
    }

    /**
     * Creates a shared context on the specified platform and with the specified
     * device types.
     */
    private static final CLGLContext create(GLContext glContext, CLPlatform platform, CLDevice.Type... deviceTypes) {

        long[] glID = new long[1];
        PointerBuffer properties = setupContextProperties(glContext, platform, glID);
        long clID = createContextFromType(properties, toDeviceBitmap(deviceTypes));

        return new CLGLContext(clID, glID[0]);

    }

    /**
     * Creates a shared context on the specified platform and with the specified
     * devices.
     */
    private static final CLGLContext create(GLContext glContext, CLPlatform platform, CLDevice... devices) {

        long[] glID = new long[1];
        PointerBuffer properties = setupContextProperties(glContext, platform, glID);
        long clID = createContext(properties, devices);

        return new CLGLContext(clID, glID[0]);
    }


    private static final PointerBuffer setupContextProperties(GLContext glContext, CLPlatform platform, long[] glID) {

        if(platform == null) {
            platform = CLPlatform.getDefault();
        }

        if(platform == null) {
            throw new RuntimeException("no OpenCL installation found");
        }

        GLContextImpl ctxImpl = (GLContextImpl)glContext;

        DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration)ctxImpl.getDrawableImpl()
             .getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();

        PointerBuffer properties = null;
        if(glContext instanceof X11GLXContext) {
            properties = PointerBuffer.allocateDirect(7);
            long handle = config.getScreen().getDevice().getHandle();
            glID[0] = ((X11GLXContext)glContext).getContext();
            properties.put(CL_GL_CONTEXT_KHR).put(glID[0])
                      .put(CL_GLX_DISPLAY_KHR).put(handle)
                      .put(CL_CONTEXT_PLATFORM).put(platform.ID);
        }else if(glContext instanceof WindowsWGLContext) {
            // TODO test on windows
            //WIN32
            //cl_context_properties props[] = {
            //         CL_GL_CONTEXT_KHR, (cl_context_properties)0,
            //         CL_WGL_HDC_KHR, (cl_context_properties)0,
            //         CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, 0};
            properties = PointerBuffer.allocateDirect(7);
            long handle = config.getScreen().getDevice().getHandle();
            glID[0] = ((WindowsWGLContext)glContext).getHGLRC();
            properties.put(CL_GL_CONTEXT_KHR).put(glID[0])
                      .put(CL_WGL_HDC_KHR).put(handle)
                      .put(CL_CONTEXT_PLATFORM).put(platform.ID);
        }else if(glContext instanceof MacOSXCGLContext) {
            // TODO test on mac
            //MACOSX
            //cl_context_properties props[] = {
            //         CL_CGL_SHAREGROUP_KHR, (cl_context_properties)0,
            //         CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, 0};
            properties = PointerBuffer.allocateDirect(5);
            glID[0] = ((MacOSXCGLContext)glContext).getCGLContext();
            properties.put(CL_CGL_SHAREGROUP_KHR).put(glID[0])
                      .put(CL_CONTEXT_PLATFORM).put(platform.ID);
        }else{
            throw new RuntimeException("unsupported GLContext: "+glContext);
        }

        return properties.put(0).rewind(); // 0 terminated array
    }


    public final <B extends Buffer> CLGLBuffer<B> createFromGLBuffer(B directBuffer, int glBuffer, Mem... flags) {
        return createFromGLBuffer(directBuffer, glBuffer, Mem.flagsToInt(flags));
    }

    public final <B extends Buffer> CLGLBuffer<B> createFromGLBuffer(B directBuffer, int glBuffer, int flags) {
        CLGLBuffer<B> buffer = CLGLBuffer.create(this, directBuffer, flags, glBuffer);
        memoryObjects.add(buffer);
        return buffer;
    }

}