PDA

View Full Version : qt and gl/cl interop



giugio
12-24-2012, 04:20 AM
h?llo.
I'm trying to use an interop with opengl and opencl in qt.
this is my code:


GLuint id = 0;
glGenBuffers(1, &id);
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, lSize, NULL, GL_STATIC_DRAW);

int err;
cl::BufferGL buff;
buff= cl::BufferGL(context, CL_MEM_WRITE_ONLY, id, &err);

glBindBuffer(GL_ARRAY_BUFFER, 0);
vertexBufferObject = id;

I get always the same error:
-60: CL_INVALID_GL_OBJECT.
i omitted the construction of the gl/cl context code, but I'm was try this without qt and all works fine.
When i use the code in qt i get the error.
What can be?
the threads and contexts that are used in qt?
How i can resolve?
But I wish understand and use my own library, rather than use an already done library .
thanks.

Dithermaster
12-24-2012, 08:47 PM
Just guessing here, perhaps the Qt OpenGL context is different than the OpenGL context you are creating in your non-Qt example? Do you get any error when you create the OpenCL context from (or using) the OpenGL (in order to allow sharing)?

giugio
12-25-2012, 09:54 AM
no,
thanks

giugio
12-25-2012, 10:58 AM
this is the create procedure:


bool QCLContextGL::create(const QCLPlatform &platform)
{
Q_D(QCLContextGL);

// Bail out if the context already exists.
if (isCreated())
return true;

// Bail out if we don't have an OpenGL context.
if (!QGLContext::currentContext()) {
qWarning() << "QCLContextGL::create: needs a current GL context";
setLastError(CL_INVALID_CONTEXT);
return false;
}

// Find the first gpu device.
QList<QCLDevice> devices;
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
devices = QCLDevice::devices(QCLDevice::GPU, platform);
if (devices.isEmpty()) {
// Find the first default device.
devices = QCLDevice::devices(QCLDevice::Default, platform);
deviceType = CL_DEVICE_TYPE_DEFAULT;
}
if (devices.isEmpty()) {
qWarning() << "QCLContextGL::create: no gpu devices found";
setLastError(CL_DEVICE_NOT_FOUND);
return false;
}
QCLDevice gpu = devices[0];
QVarLengthArray<cl_device_id> devs;
foreach (QCLDevice dev, devices)
devs.append(dev.deviceId());

// Add the platform identifier to the properties.
QVarLengthArray<cl_context_properties> properties;
properties.append(CL_CONTEXT_PLATFORM);
properties.append(cl_context_properties(gpu.platfo rm().platformId()));

bool hasSharing = false;
#ifndef QT_NO_CL_OPENGL
// Determine what kind of OpenCL-OpenGL sharing we have and enable it.
#if defined(__APPLE__) || defined(__MACOSX)
bool appleSharing = gpu.hasExtension("cl_apple_gl_sharing");
if (appleSharing) {
CGLContextObj cglContext = CGLGetCurrentContext();
CGLShareGroupObj cglShareGroup = CGLGetShareGroup(cglContext);
properties.append(CL_CGL_SHAREGROUP_KHR);
properties.append(cl_context_properties(cglShareGr oup));
hasSharing = true;
}
#else
bool khrSharing = gpu.hasExtension("cl_khr_gl_sharing");
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES)
if (khrSharing) {
properties.append(CL_EGL_DISPLAY_KHR);
properties.append(cl_context_properties(eglGetCurr entDisplay()));
#ifdef EGL_OPENGL_ES_API
eglBindAPI(EGL_OPENGL_ES_API);
#endif
properties.append(CL_GL_CONTEXT_KHR);
properties.append(cl_context_properties(eglGetCurr entContext()));
hasSharing = true;
}
#elif defined(Q_WS_X11)
if (khrSharing) {
properties.append(CL_GLX_DISPLAY_KHR);
properties.append(cl_context_properties(glXGetCurr entDisplay()));
properties.append(CL_GL_CONTEXT_KHR);
properties.append(cl_context_properties(glXGetCurr entContext()));
hasSharing = true;
}
#else
// Needs to be ported to other platforms.
if (khrSharing)
qWarning() << "QCLContextGL::create: do not know how to enable sharing";
#endif
#endif
#endif // !QT_NO_CL_OPENGL
properties.append(0);

#ifndef QT_NO_CL_OPENGL
// Query the actual OpenCL devices we should use with the OpenGL context.
typedef cl_int (*q_PFNCLGETGLCONTEXTINFOKHR)
(const cl_context_properties *, cl_uint, size_t, void *, size_t *);
q_PFNCLGETGLCONTEXTINFOKHR getGLContextInfo =
(q_PFNCLGETGLCONTEXTINFOKHR)clGetExtensionFunction Address
("clGetGLContextInfoKHR");
if (getGLContextInfo && hasSharing) {
size_t size;
cl_device_id currentDev;
if(getGLContextInfo(properties.data(),
CL_DEVICES_FOR_GL_CONTEXT_KHR,
0, 0, &size) == CL_SUCCESS && size > 0) {
QVarLengthArray<cl_device_id> buf(size / sizeof(cl_device_id));
getGLContextInfo(properties.data(),
CL_DEVICES_FOR_GL_CONTEXT_KHR,
size, buf.data(), 0);
devs = buf;
gpu = QCLDevice(devs[0]);
}
if (getGLContextInfo(properties.data(),
CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
sizeof(currentDev), &currentDev, 0)
== CL_SUCCESS) {
gpu = QCLDevice(currentDev);
}
}
#endif

// Create the OpenCL context.
cl_context id;
cl_int error;
id = clCreateContext
(properties.data(), devs.size(), devs.data(),
qt_clgl_context_notify, 0, &error);
if (!id && hasSharing) {
// Try again without the sharing parameters.
properties.resize(2);
properties.append(0);
hasSharing = false;
id = clCreateContext
(properties.data(), devs.size(), devs.data(),
qt_clgl_context_notify, 0, &error);
}
setLastError(error);
if (id == 0) {
qWarning() << "QCLContextGL::create:" << errorName(error);
d->supportsSharing = false;
} else {
setContextId(id);
clReleaseContext(id); // setContextId() adds an extra reference.
setDefaultDevice(gpu);
d->supportsSharing = hasSharing;
}
return id != 0;
}


i see better and i have this warning:
if (khrSharing)//is true
qWarning() << "QCLContextGL::create: do not know how to enable sharing";
and hasSharing is alwais false;
thanks.

Dithermaster
12-26-2012, 06:54 PM
I'm guessing you are on Windows. That code appears to support sharing under Mac OS X and X11 but not Windows. You'll need to add GL/CL sharing code appropriate for Windows. There are examples around, and it sounds like you have it working already in your non-Qt code (so copy from that).