Add Linux and AMD support to the OpenCL filter example

Change-Id: I1ea91f93677c53322c3867db6069e4362c58cebd
Reviewed-by: Yoann Lopes <yoann.lopes@theqtcompany.com>
This commit is contained in:
Laszlo Agocs
2015-02-23 14:50:11 +01:00
committed by Laszlo Agocs
parent b35a55f215
commit f86a3b7bb3
3 changed files with 45 additions and 19 deletions

View File

@@ -1,18 +1,18 @@
This example performs some simple OpenCL operations on camera or video input which
is assumed to be provided in RGB format. The OpenCL operation is done on an
OpenGL texture using CL-GL interop, without any further readbacks or copies
This example performs some simple OpenCL operations on camera or video input
which is assumed to be provided in RGB format. The OpenCL operation is done on
an OpenGL texture using CL-GL interop, without any further readbacks or copies
(except for the initial texture upload, when necessary).
Currently only OS X and Windows with desktop OpenGL (opengl32.dll) are supported.
On Windows you may need to edit testplugin.pro to specify the location of the OpenCL
headers and libraries.
Currently OS X, Windows with real OpenGL (opengl32.dll) and Linux (GLX only) are
supported. Note that an OpenCL implementation with GPU support is required. The
platform and device selection logic supports NVIDIA, AMD and Intel. Porting to
other platforms is probably simple, see clCreateContextFromType.
Note that an OpenCL implementation with GPU support is required.
The platform and device selection logic supports NVIDIA and Intel.
Porting to other platforms is probably simple, see clCreateContextFromType.
Note however that YUV formats, that are commonly used also for camera input
on some platforms, are not supported in this example.
On Windows you may need to edit testplugin.pro to specify the location of the
OpenCL headers and libraries.
YUV formats are not supported in this example. This is probably not an issue an
OS X and Windows, but will most likely disable the example on Linux.
Pass the name of a video file to perform video playback or launch without
arguments to use the camera.

View File

@@ -46,6 +46,10 @@
#include <CL/opencl.h>
#endif
#ifdef Q_OS_LINUX
#include <QtPlatformHeaders/QGLXNativeContext>
#endif
#include "rgbframehelper.h"
static const char *openclSrc =
@@ -119,10 +123,17 @@ CLFilterRunnable::CLFilterRunnable(CLFilter *filter) :
// Set up OpenCL.
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
cl_int err;
cl_uint n;
if (clGetPlatformIDs(0, 0, &n) != CL_SUCCESS) {
qWarning("Failed to get platform ID count");
cl_int err = clGetPlatformIDs(0, 0, &n);
if (err != CL_SUCCESS) {
qWarning("Failed to get platform ID count (error %d)", err);
if (err == -1001) {
qDebug("Could not find OpenCL implementation. ICD missing?"
#ifdef Q_OS_LINUX
" Check /etc/OpenCL/vendors."
#endif
);
}
return;
}
if (n == 0) {
@@ -140,6 +151,7 @@ CLFilterRunnable::CLFilterRunnable(CLFilter *filter) :
qDebug("GL_VENDOR: %s", vendor);
const bool isNV = vendor && strstr(vendor, "NVIDIA");
const bool isIntel = vendor && strstr(vendor, "Intel");
const bool isAMD = vendor && strstr(vendor, "ATI");
qDebug("Found %u OpenCL platforms:", n);
for (cl_uint i = 0; i < n; ++i) {
QByteArray name;
@@ -153,6 +165,8 @@ CLFilterRunnable::CLFilterRunnable(CLFilter *filter) :
platform = platformIds[i];
else if (isIntel && name.contains(QByteArrayLiteral("Intel")))
platform = platformIds[i];
else if (isAMD && name.contains(QByteArrayLiteral("AMD")))
platform = platformIds[i];
}
qDebug("Using platform %p", platform);
@@ -166,6 +180,18 @@ CLFilterRunnable::CLFilterRunnable(CLFilter *filter) :
CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(),
CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(),
0 };
#elif defined(Q_OS_LINUX)
// An elegant alternative to glXGetCurrentContext. This will even survive
// (without interop) when using something other than GLX.
QVariant nativeGLXHandle = QOpenGLContext::currentContext()->nativeHandle();
QGLXNativeContext nativeGLXContext;
if (!nativeGLXHandle.isNull() && nativeGLXHandle.canConvert<QGLXNativeContext>())
nativeGLXContext = nativeGLXHandle.value<QGLXNativeContext>();
else
qWarning("Failed to get the underlying GLX context from the current QOpenGLContext");
cl_context_properties contextProps[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
CL_GL_CONTEXT_KHR, (cl_context_properties) nativeGLXContext.context(),
0 };
#endif
m_clContext = clCreateContextFromType(contextProps, CL_DEVICE_TYPE_GPU, 0, 0, &err);

View File

@@ -12,10 +12,10 @@ OTHER_FILES = main.qml
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideofilter_opencl
INSTALLS += target
# Edit these as necessary
osx {
LIBS += -framework OpenCL
} else {
osx: LIBS += -framework OpenCL
unix: !osx: LIBS += -lOpenCL
win32:!winrt {
# Edit these as necessary
INCLUDEPATH += c:/cuda/include
LIBPATH += c:/cuda/lib/x64
LIBS += -lopengl32 -lOpenCL