aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quickcl/histogram/histogram.cpp10
-rw-r--r--examples/quickcl/imageprocess/imageprocess.cpp6
-rw-r--r--examples/quickcl/particles/particles.cpp15
-rw-r--r--src/quickcl/qquickclcontext.cpp112
-rw-r--r--src/quickcl/qquickclcontext.h5
-rw-r--r--src/quickcl/qquickclimagerunnable.cpp13
-rw-r--r--src/quickcl/qquickclitem.cpp111
-rw-r--r--src/quickcl/qquickclitem.h10
8 files changed, 150 insertions, 132 deletions
diff --git a/examples/quickcl/histogram/histogram.cpp b/examples/quickcl/histogram/histogram.cpp
index 6ba0b65..3bd062d 100644
--- a/examples/quickcl/histogram/histogram.cpp
+++ b/examples/quickcl/histogram/histogram.cpp
@@ -46,6 +46,7 @@
#include <QQmlEngine>
#include <QQuickCLItem>
#include <QQuickCLImageRunnable>
+#include <QQuickCLContext>
#include <QAbstractListModel>
static bool profile = false;
@@ -159,9 +160,10 @@ CLRunnable::CLRunnable(CLItem *item)
m_sharedBuf(0),
m_doneEvent(0)
{
- QByteArray platform = m_item->platformName();
+ QQuickCLContext *clctx = m_item->context();
+ QByteArray platform = clctx->platformName();
qDebug("Using platform %s", platform.constData());
- m_program = m_item->buildProgramFromFile(QStringLiteral(":/histogram.cl"));
+ m_program = clctx->buildProgramFromFile(QStringLiteral(":/histogram.cl"));
if (!m_program)
return;
cl_int err;
@@ -175,7 +177,7 @@ CLRunnable::CLRunnable(CLItem *item)
qWarning("Failed to create sum histogram OpenCL kernel: %d", err);
return;
}
- m_resultBuf = clCreateBuffer(m_item->context(), CL_MEM_WRITE_ONLY, 256 * sizeof(cl_uint), 0, &err);
+ m_resultBuf = clCreateBuffer(clctx->context(), CL_MEM_WRITE_ONLY, 256 * sizeof(cl_uint), 0, &err);
if (!m_resultBuf) {
qWarning("Failed to create OpenCL buffer: %d", err);
return;
@@ -235,7 +237,7 @@ void CLRunnable::runKernel(cl_mem inImage, cl_mem, const QSize &size)
cl_int err;
if (!m_sharedBuf) {
const size_t sharedBufSize = num_groups * 256 * sizeof(cl_uint);
- m_sharedBuf = clCreateBuffer(m_item->context(), CL_MEM_READ_WRITE, sharedBufSize, 0, &err);
+ m_sharedBuf = clCreateBuffer(m_item->context()->context(), CL_MEM_READ_WRITE, sharedBufSize, 0, &err);
if (!m_sharedBuf) {
qWarning("Failed to create shared buffer: %d", err);
return;
diff --git a/examples/quickcl/imageprocess/imageprocess.cpp b/examples/quickcl/imageprocess/imageprocess.cpp
index 9738ea4..5534bbb 100644
--- a/examples/quickcl/imageprocess/imageprocess.cpp
+++ b/examples/quickcl/imageprocess/imageprocess.cpp
@@ -46,6 +46,7 @@
#include <QQmlEngine>
#include <QQuickCLItem>
#include <QQuickCLImageRunnable>
+#include <QQuickCLContext>
static bool profile = false;
@@ -120,9 +121,10 @@ CLRunnable::CLRunnable(CLItem *item)
m_clProgram(0),
m_clKernel(0)
{
- QByteArray platform = m_item->platformName();
+ QQuickCLContext *clctx = m_item->context();
+ QByteArray platform = clctx->platformName();
qDebug("Using platform %s", platform.constData());
- m_clProgram = m_item->buildProgram(openclSrc);
+ m_clProgram = clctx->buildProgram(openclSrc);
if (!m_clProgram)
return;
cl_int err;
diff --git a/examples/quickcl/particles/particles.cpp b/examples/quickcl/particles/particles.cpp
index e687084..c1e89df 100644
--- a/examples/quickcl/particles/particles.cpp
+++ b/examples/quickcl/particles/particles.cpp
@@ -49,6 +49,7 @@
#include <QOpenGLShaderProgram>
#include <QQuickCLItem>
#include <QQuickCLRunnable>
+#include <QQuickCLContext>
#include <time.h>
const int PARTICLE_COUNT = 1024;
@@ -219,16 +220,18 @@ CLRunnable::CLRunnable(CLItem *item)
m_lastT(-1),
m_clBufParticleInfo(0)
{
- qDebug() << "Platform" << m_item->platformName() << "Device extensions" << m_item->deviceExtensions();
+ QQuickCLContext *clctx = m_item->context();
+
+ qDebug() << "Platform" << clctx->platformName() << "Device extensions" << clctx->deviceExtensions();
cl_int err;
- m_queue = clCreateCommandQueue(m_item->context(), m_item->device(), 0, &err);
+ m_queue = clCreateCommandQueue(clctx->context(), clctx->device(), 0, &err);
if (!m_queue) {
qWarning("Failed to create OpenCL command queue: %d", err);
return;
}
- m_program = m_item->buildProgramFromFile(QStringLiteral(":/particles.cl"));
+ m_program = clctx->buildProgramFromFile(QStringLiteral(":/particles.cl"));
if (!m_program)
return;
m_kernel = clCreateKernel(m_program, "updateParticles", &err);
@@ -237,11 +240,11 @@ CLRunnable::CLRunnable(CLItem *item)
return;
}
- m_needsExplicitSync = !m_item->deviceExtensions().contains(QByteArrayLiteral("cl_khr_gl_event"));
+ m_needsExplicitSync = !clctx->deviceExtensions().contains(QByteArrayLiteral("cl_khr_gl_event"));
// m_clBufParticleInfo is an ordinary OpenCL buffer.
size_t velBufSize = PARTICLE_COUNT * sizeof(cl_float) * 4;
- m_clBufParticleInfo = clCreateBuffer(m_item->context(), CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, velBufSize, 0, &err);
+ m_clBufParticleInfo = clCreateBuffer(clctx->context(), CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, velBufSize, 0, &err);
if (!m_clBufParticleInfo) {
qWarning("Failed to create CL buffer: %d", err);
return;
@@ -292,7 +295,7 @@ void CLRunnable::createBuffer()
if (m_node->m_clBuf)
clReleaseMemObject(m_node->m_clBuf);
cl_int err;
- m_node->m_clBuf = clCreateFromGLBuffer(m_item->context(), CL_MEM_READ_WRITE, buf, &err);
+ m_node->m_clBuf = clCreateFromGLBuffer(m_item->context()->context(), CL_MEM_READ_WRITE, buf, &err);
if (!m_node->m_clBuf)
qWarning("Failed to create OpenCL object for OpenGL buffer: %d", err);
}
diff --git a/src/quickcl/qquickclcontext.cpp b/src/quickcl/qquickclcontext.cpp
index 14f1647..7aae3fa 100644
--- a/src/quickcl/qquickclcontext.cpp
+++ b/src/quickcl/qquickclcontext.cpp
@@ -102,6 +102,11 @@ bool QQuickCLContext::isValid() const
/*!
\return the OpenCL platform chosen in create().
+
+ \note For contexts belonging to a QQuickCLItem the value is only available
+ after the item is first rendered. It is always safe to call this function
+ from QQuickCLRunnable's constructor, destructor and
+ \l{QQuickCLRunnable::update()}{update()} function.
*/
cl_platform_id QQuickCLContext::platform() const
{
@@ -111,6 +116,11 @@ cl_platform_id QQuickCLContext::platform() const
/*!
\return the OpenCL device chosen in create().
+
+ \note For contexts belonging to a QQuickCLItem the value is only available
+ after the item is first rendered. It is always safe to call this function
+ from QQuickCLRunnable's constructor, destructor and
+ \l{QQuickCLRunnable::update()}{update()} function.
*/
cl_device_id QQuickCLContext::device() const
{
@@ -120,6 +130,11 @@ cl_device_id QQuickCLContext::device() const
/*!
\return the OpenCL context or \c 0 if not yet created.
+
+ \note For contexts belonging to a QQuickCLItem the value is only available
+ after the item is first rendered. It is always safe to call this function
+ from QQuickCLRunnable's constructor, destructor and
+ \l{QQuickCLRunnable::update()}{update()} function.
*/
cl_context QQuickCLContext::context() const
{
@@ -285,4 +300,101 @@ void QQuickCLContext::destroy()
d->platform = 0;
}
+/*!
+ \return the name of the current platform in use.
+
+ \note The value is valid only after create() has been called successfully.
+
+ \note For contexts belonging to a QQuickCLItem this function can only be
+ called from a QQuickCLRunnable's constructor, destructor and
+ \l{QQuickCLRunnable::update()}{update()} function, or after the item has
+ been rendered at least once.
+ */
+QByteArray QQuickCLContext::platformName() const
+{
+ QByteArray name(1024, '\0');
+ clGetPlatformInfo(platform(), CL_PLATFORM_NAME, name.size(), name.data(), 0);
+ name.resize(int(strlen(name.constData())));
+ return name;
+}
+
+/*!
+ \return the list of device extensions.
+
+ \note The value is valid only after create() has been called successfully.
+
+ \note For contexts belonging to a QQuickCLItem this function can only be
+ called from a QQuickCLRunnable's constructor, destructor and
+ \l{QQuickCLRunnable::update()}{update()} function, or after the item has
+ been rendered at least once.
+ */
+QByteArray QQuickCLContext::deviceExtensions() const
+{
+ QByteArray ext(8192, '\0');
+ clGetDeviceInfo(device(), CL_DEVICE_EXTENSIONS, ext.size(), ext.data(), 0);
+ ext.resize(int(strlen(ext.constData())));
+ return ext;
+}
+
+/*!
+ Creates and builds an OpenCL program from the source code in \a src.
+
+ \return the cl_program or \c 0 when failed. Errors and build logs are
+ printed to the warning output.
+
+ \note The value is valid only after create() has been called successfully.
+
+ \note For contexts belonging to a QQuickCLItem this function can only be
+ called from a QQuickCLRunnable's constructor, destructor and
+ \l{QQuickCLRunnable::update()}{update()} function, or after the item has
+ been rendered at least once.
+
+ \sa buildProgramFromFile()
+ */
+cl_program QQuickCLContext::buildProgram(const QByteArray &src)
+{
+ cl_int err;
+ const char *str = src.constData();
+ cl_program prog = clCreateProgramWithSource(context(), 1, &str, 0, &err);
+ if (!prog) {
+ qWarning("Failed to create OpenCL program: %d", err);
+ qWarning("Source was:\n%s", str);
+ return 0;
+ }
+ cl_device_id dev = device();
+ err = clBuildProgram(prog, 1, &dev, 0, 0, 0);
+ if (err != CL_SUCCESS) {
+ qWarning("Failed to build OpenCL program: %d", err);
+ qWarning("Source was:\n%s", str);
+ QByteArray log;
+ log.resize(8192);
+ clGetProgramBuildInfo(prog, dev, CL_PROGRAM_BUILD_LOG, log.size(), log.data(), 0);
+ qWarning("Build log:\n%s", log.constData());
+ return 0;
+ }
+ return prog;
+}
+
+/*!
+ Creates and builds an OpenCL program from the source file \a filename.
+
+ \note The value is valid only after create() has been called successfully.
+
+ \note For contexts belonging to a QQuickCLItem this function can only be
+ called from a QQuickCLRunnable's constructor, destructor and
+ \l{QQuickCLRunnable::update()}{update()} function, or after the item has
+ been rendered at least once.
+
+ \sa buildProgram()
+ */
+cl_program QQuickCLContext::buildProgramFromFile(const QString &filename)
+{
+ QFile f(filename);
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qWarning("Failed to open OpenCL program source file %s", qPrintable(filename));
+ return 0;
+ }
+ return buildProgram(f.readAll());
+}
+
QT_END_NAMESPACE
diff --git a/src/quickcl/qquickclcontext.h b/src/quickcl/qquickclcontext.h
index 2a7e94c..d780ad5 100644
--- a/src/quickcl/qquickclcontext.h
+++ b/src/quickcl/qquickclcontext.h
@@ -60,6 +60,11 @@ public:
cl_device_id device() const;
cl_context context() const;
+ QByteArray platformName() const;
+ QByteArray deviceExtensions() const;
+ cl_program buildProgram(const QByteArray &src);
+ cl_program buildProgramFromFile(const QString &filename);
+
private:
QQuickCLContextPrivate *d_ptr;
};
diff --git a/src/quickcl/qquickclimagerunnable.cpp b/src/quickcl/qquickclimagerunnable.cpp
index 01a7be1..bd1fb51 100644
--- a/src/quickcl/qquickclimagerunnable.cpp
+++ b/src/quickcl/qquickclimagerunnable.cpp
@@ -36,6 +36,7 @@
#include "qquickclimagerunnable.h"
#include "qquickclitem.h"
+#include "qquickclcontext.h"
#include <QSGSimpleTextureNode>
#include <QSGTextureProvider>
#include <QOpenGLTexture>
@@ -173,12 +174,14 @@ QQuickCLImageRunnable::QQuickCLImageRunnable(QQuickCLItem *item, Flags flags)
Q_D(QQuickCLImageRunnable);
cl_int err;
cl_command_queue_properties queueProps = flags.testFlag(Profile) ? CL_QUEUE_PROFILING_ENABLE : 0;
- d->queue = clCreateCommandQueue(item->context(), item->device(), queueProps, &err);
+ QQuickCLContext *clctx = item->context();
+ Q_ASSERT(clctx);
+ d->queue = clCreateCommandQueue(clctx->context(), clctx->device(), queueProps, &err);
if (!d->queue) {
qWarning("Failed to create OpenCL command queue: %d", err);
return;
}
- d->needsExplicitSync = !item->deviceExtensions().contains(QByteArrayLiteral("cl_khr_gl_event"));
+ d->needsExplicitSync = !clctx->deviceExtensions().contains(QByteArrayLiteral("cl_khr_gl_event"));
}
QQuickCLImageRunnable::~QQuickCLImageRunnable()
@@ -243,9 +246,11 @@ QSGNode *QQuickCLImageRunnable::update(QSGNode *node)
node = 0;
}
+ QQuickCLContext *clctx = d->item->context();
+ Q_ASSERT(clctx);
cl_int err = 0;
if (!d->image[0])
- d->image[0] = clCreateFromGLTexture2D(d->item->context(), CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0,
+ d->image[0] = clCreateFromGLTexture2D(clctx->context(), CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0,
texture->textureId(), &err);
if (!d->image[0]) {
if (err == CL_INVALID_GL_OBJECT) // the texture provider may not be ready yet, try again later
@@ -264,7 +269,7 @@ QSGNode *QQuickCLImageRunnable::update(QSGNode *node)
d->outputTexture = new QOpenGLTexture(QImage(d->textureSize, QImage::Format_RGB32));
if (!d->image[1])
- d->image[1] = clCreateFromGLTexture2D(d->item->context(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0,
+ d->image[1] = clCreateFromGLTexture2D(clctx->context(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0,
d->outputTexture->textureId(), &err);
if (!d->image[1]) {
qWarning("Failed to create OpenCL image object for output OpenGL texture: %d", err);
diff --git a/src/quickcl/qquickclitem.cpp b/src/quickcl/qquickclitem.cpp
index 6c88b5d..6947fed 100644
--- a/src/quickcl/qquickclitem.cpp
+++ b/src/quickcl/qquickclitem.cpp
@@ -122,42 +122,16 @@ QQuickCLItem::QQuickCLItem(QQuickItem *parent)
}
/*!
- \return the selected OpenCL platform. Matches the OpenGL context in use.
+ \return the associated QQuickCLContext.
\note The value is only available after the item is first rendered. It is
always safe to call this function from QQuickCLRunnable's constructor,
destructor and \l{QQuickCLRunnable::update()}{update()} function.
*/
-cl_platform_id QQuickCLItem::platform() const
+QQuickCLContext *QQuickCLItem::context() const
{
Q_D(const QQuickCLItem);
- return d->clctx ? d->clctx->platform() : 0;
-}
-
-/*!
- \return the selected OpenCL device. Matches the OpenGL context in use.
-
- \note The value is only available after the item is first rendered. It is
- always safe to call this function from QQuickCLRunnable's constructor,
- destructor and \l{QQuickCLRunnable::update()}{update()} function.
- */
-cl_device_id QQuickCLItem::device() const
-{
- Q_D(const QQuickCLItem);
- return d->clctx ? d->clctx->device() : 0;
-}
-
-/*!
- \return the OpenCL context.
-
- \note The value is only available after the item is first rendered. It is
- always safe to call this function from QQuickCLRunnable's constructor,
- destructor and \l{QQuickCLRunnable::update()}{update()} function.
- */
-cl_context QQuickCLItem::context() const
-{
- Q_D(const QQuickCLItem);
- return d->clctx ? d->clctx->context() : 0;
+ return d->clctx;
}
QSGNode *QQuickCLItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
@@ -253,85 +227,6 @@ void QQuickCLItem::scheduleUpdate()
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EV_UPDATE)));
}
-/*!
- \return the name of the current platform in use.
-
- \note This function can only be called from a QQuickCLRunnable's
- constructor, destructor and \l{QQuickCLRunnable::update()}{update()}
- function, or after the item has been rendered at least once.
- */
-QByteArray QQuickCLItem::platformName() const
-{
- QByteArray name(1024, '\0');
- clGetPlatformInfo(platform(), CL_PLATFORM_NAME, name.size(), name.data(), 0);
- name.resize(int(strlen(name.constData())));
- return name;
-}
-
-/*!
- \return the list of device extensions.
-
- \note This function can only be called from a QQuickCLRunnable's
- constructor, destructor and \l{QQuickCLRunnable::update()}{update()}
- function, or after the item has been rendered at least once.
- */
-QByteArray QQuickCLItem::deviceExtensions() const
-{
- QByteArray ext(8192, '\0');
- clGetDeviceInfo(device(), CL_DEVICE_EXTENSIONS, ext.size(), ext.data(), 0);
- ext.resize(int(strlen(ext.constData())));
- return ext;
-}
-
-/*!
- Creates and builds an OpenCL program from the source code in \a src.
-
- \return the cl_program or \c 0 when failed. Errors and build logs are
- printed to the warning output.
-
- \note This function can only be called from a QQuickCLRunnable's
- constructor, destructor and \l{QQuickCLRunnable::update()}{update()}
- function, or after the item has been rendered at least once.
- */
-cl_program QQuickCLItem::buildProgram(const QByteArray &src)
-{
- cl_int err;
- const char *str = src.constData();
- cl_program prog = clCreateProgramWithSource(context(), 1, &str, 0, &err);
- if (!prog) {
- qWarning("Failed to create OpenCL program: %d", err);
- qWarning("Source was:\n%s", str);
- return 0;
- }
- cl_device_id dev = device();
- err = clBuildProgram(prog, 1, &dev, 0, 0, 0);
- if (err != CL_SUCCESS) {
- qWarning("Failed to build OpenCL program: %d", err);
- qWarning("Source was:\n%s", str);
- QByteArray log;
- log.resize(8192);
- clGetProgramBuildInfo(prog, dev, CL_PROGRAM_BUILD_LOG, log.size(), log.data(), 0);
- qWarning("Build log:\n%s", log.constData());
- return 0;
- }
- return prog;
-}
-
-/*!
- Creates and builds an OpenCL program from the source file \a filename.
-
- \sa buildProgram()
- */
-cl_program QQuickCLItem::buildProgramFromFile(const QString &filename)
-{
- QFile f(filename);
- if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning("Failed to open OpenCL program source file %s", qPrintable(filename));
- return 0;
- }
- return buildProgram(f.readAll());
-}
-
struct EventCallbackParam
{
EventCallbackParam(QQuickCLItem *item) : item(item) { }
diff --git a/src/quickcl/qquickclitem.h b/src/quickcl/qquickclitem.h
index 98ce7fc..c3e93bf 100644
--- a/src/quickcl/qquickclitem.h
+++ b/src/quickcl/qquickclitem.h
@@ -44,6 +44,7 @@
QT_BEGIN_NAMESPACE
class QQuickCLItemPrivate;
+class QQuickCLContext;
class Q_QUICKCL_EXPORT QQuickCLItem : public QQuickItem
{
@@ -53,17 +54,10 @@ class Q_QUICKCL_EXPORT QQuickCLItem : public QQuickItem
public:
QQuickCLItem(QQuickItem *parent = 0);
- cl_platform_id platform() const;
- cl_device_id device() const;
- cl_context context() const;
+ QQuickCLContext *context() const;
void scheduleUpdate();
- QByteArray platformName() const;
- QByteArray deviceExtensions() const;
- cl_program buildProgram(const QByteArray &src);
- cl_program buildProgramFromFile(const QString &filename);
-
void watchEvent(cl_event event);
virtual void eventCompleted(cl_event event);