summaryrefslogtreecommitdiffstats
path: root/src/render/renderers/opengl/graphicshelpers
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-06-04 14:37:29 +0200
committerPaul Lemire <paul.lemire@kdab.com>2019-06-05 16:05:13 +0200
commitc7167bac4efa50dcc21ed6ef48cc7a40d0bb5e82 (patch)
treef084b0e83914e02a21acbb4589717d4d55b29d8b /src/render/renderers/opengl/graphicshelpers
parent7f72710d73510b9d58e822ffa5b39dbd3fbbc11a (diff)
Renderer: Image support added
Change-Id: I5b2764f0ae5184c2097d6da5e7a6e24b5c6a5d1b Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/renderers/opengl/graphicshelpers')
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp15
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h4
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri2
-rw-r--r--src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp304
-rw-r--r--src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h95
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp43
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h2
7 files changed, 459 insertions, 6 deletions
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
index 76320cfe5..c9b04fa8f 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
@@ -92,6 +92,10 @@ QT_BEGIN_NAMESPACE
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#endif
+#ifndef GL_MAX_IMAGE_UNITS
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#endif
+
namespace {
QOpenGLShader::ShaderType shaderType(Qt3DRender::QShaderProgram::ShaderType type)
@@ -125,6 +129,7 @@ GraphicsContext::GraphicsContext()
: m_initialized(false)
, m_supportsVAO(false)
, m_maxTextureUnits(0)
+ , m_maxImageUnits(0)
, m_defaultFBO(0)
, m_gl(nullptr)
, m_glHelper(nullptr)
@@ -152,6 +157,8 @@ void GraphicsContext::initialize()
m_gl->functions()->glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_maxTextureUnits);
qCDebug(Backend) << "context supports" << m_maxTextureUnits << "texture units";
+ m_gl->functions()->glGetIntegerv(GL_MAX_IMAGE_UNITS, &m_maxImageUnits);
+ qCDebug(Backend) << "context supports" << m_maxImageUnits << "image units";
if (m_gl->format().majorVersion() >= 3) {
m_supportsVAO = true;
@@ -675,11 +682,17 @@ GLint GraphicsContext::maxClipPlaneCount()
return m_glHelper->maxClipPlaneCount();
}
-GLint GraphicsContext::maxTextureUnitsCount()
+GLint GraphicsContext::maxTextureUnitsCount() const
{
return m_maxTextureUnits;
}
+GLint GraphicsContext::maxImageUnitsCount() const
+{
+ return m_maxImageUnits;
+}
+
+
void GraphicsContext::enablePrimitiveRestart(int restartIndex)
{
if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart))
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h b/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h
index a6cce47cd..2f4df2e22 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h
@@ -156,7 +156,8 @@ public:
void enablePrimitiveRestart(int restartIndex);
void frontFace(GLenum mode);
GLint maxClipPlaneCount();
- GLint maxTextureUnitsCount();
+ GLint maxTextureUnitsCount() const;
+ GLint maxImageUnitsCount() const;
void pointSize(bool programmable, GLfloat value);
void readBuffer(GLenum mode);
void drawBuffer(GLenum mode);
@@ -186,6 +187,7 @@ public:
bool m_initialized;
bool m_supportsVAO;
GLint m_maxTextureUnits;
+ GLint m_maxImageUnits;
GLuint m_defaultFBO;
QOpenGLContext *m_gl;
GraphicsHelperInterface *m_glHelper;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
index ad08038c9..f2f7274d7 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
@@ -14,6 +14,7 @@ HEADERS += \
$$PWD/graphicshelpergl3_3_p.h \
$$PWD/graphicshelpergl4_p.h \
$$PWD/graphicshelpergl3_2_p.h \
+ $$PWD/imagesubmissioncontext_p.h \
$$PWD/submissioncontext_p.h \
$$PWD/texturesubmissioncontext_p.h
@@ -27,5 +28,6 @@ SOURCES += \
$$PWD/graphicshelpergl3_3.cpp \
$$PWD/graphicshelpergl4.cpp \
$$PWD/graphicshelpergl3_2.cpp \
+ $$PWD/imagesubmissioncontext.cpp \
$$PWD/submissioncontext.cpp \
$$PWD/texturesubmissioncontext.cpp
diff --git a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp
new file mode 100644
index 000000000..a5633c306
--- /dev/null
+++ b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "imagesubmissioncontext_p.h"
+#include <Qt3DRender/private/graphicscontext_p.h>
+#include <Qt3DRender/private/gltexture_p.h>
+#include <Qt3DRender/private/shaderimage_p.h>
+#include <Qt3DRender/qshaderimage.h>
+
+QT_BEGIN_NAMESPACE
+
+// ES 3.1+ or GL 4.2+
+#ifndef GL_READ_ONLY
+#define GL_READ_ONLY 0x88B8
+#endif
+#ifndef GL_WRITE_ONLY
+#define GL_WRITE_ONLY 0x88B9
+#endif
+#ifndef GL_READ_WRITE
+#define GL_READ_WRITE 0x88BA
+#endif
+
+namespace Qt3DRender {
+namespace Render {
+
+class GraphicsContext;
+class GLTexture;
+
+namespace {
+
+GLenum glAccessEnumForShaderImageAccess(QShaderImage::Access access)
+{
+ switch (access) {
+ case QShaderImage::ReadOnly:
+ return GL_READ_ONLY;
+ case QShaderImage::WriteOnly:
+ return GL_WRITE_ONLY;
+ case QShaderImage::ReadWrite:
+ return GL_READ_WRITE;
+ }
+}
+
+GLenum glImageFormatToGL(QShaderImage::ImageFormat format)
+{
+ // Right now we can abuse from the fact that the ImageFormat enum values
+ // have been assigned the same value as the GL enum
+ return GLenum(format);
+}
+
+GLenum glImageFormatForShaderImageFormat(QShaderImage::ImageFormat format,
+ QAbstractTexture::TextureFormat textureFormat)
+{
+ Q_ASSERT_X(format != QShaderImage::NoFormat, Q_FUNC_INFO, "Valid image format or Automatic expected");
+
+ if (format != QShaderImage::Automatic)
+ return glImageFormatToGL(format);
+
+ // Otherwise try to mind to best texture format
+ switch (textureFormat) {
+ case QAbstractTexture::R8_UNorm:
+ return glImageFormatToGL(QShaderImage::R8_UNorm);
+ case QAbstractTexture::RG8_UNorm:
+ return glImageFormatToGL(QShaderImage::RG8_UNorm);
+ case QAbstractTexture::RGBA8_UNorm:
+ return glImageFormatToGL(QShaderImage::RGBA8_UNorm);
+
+ case QAbstractTexture::R16_UNorm:
+ return glImageFormatToGL(QShaderImage::R16_UNorm);
+ case QAbstractTexture::RG16_UNorm:
+ return glImageFormatToGL(QShaderImage::RG16_UNorm);
+ case QAbstractTexture::RGBA16_UNorm:
+ return glImageFormatToGL(QShaderImage::RGBA16_UNorm);
+
+ case QAbstractTexture::R8_SNorm:
+ return glImageFormatToGL(QShaderImage::R8_SNorm);
+ case QAbstractTexture::RG8_SNorm:
+ return glImageFormatToGL(QShaderImage::RG8_SNorm);
+ case QAbstractTexture::RGBA8_SNorm:
+ return glImageFormatToGL(QShaderImage::RGBA8_SNorm);
+
+ case QAbstractTexture::R16_SNorm:
+ return glImageFormatToGL(QShaderImage::R16_SNorm);
+ case QAbstractTexture::RG16_SNorm:
+ return glImageFormatToGL(QShaderImage::RG16_SNorm);
+ case QAbstractTexture::RGBA16_SNorm:
+ return glImageFormatToGL(QShaderImage::RGBA16_SNorm);
+
+ case QAbstractTexture::R8U:
+ return glImageFormatToGL(QShaderImage::R8U);
+ case QAbstractTexture::RG8U:
+ return glImageFormatToGL(QShaderImage::RG8U);
+ case QAbstractTexture::RGBA8U:
+ return glImageFormatToGL(QShaderImage::RGBA8U);
+
+ case QAbstractTexture::R16U:
+ return glImageFormatToGL(QShaderImage::R16U);
+ case QAbstractTexture::RG16U:
+ return glImageFormatToGL(QShaderImage::RG16U);
+ case QAbstractTexture::RGBA16U:
+ return glImageFormatToGL(QShaderImage::RGBA16U);
+
+ case QAbstractTexture::R32U:
+ return glImageFormatToGL(QShaderImage::R32U);
+ case QAbstractTexture::RG32U:
+ return glImageFormatToGL(QShaderImage::RG32U);
+ case QAbstractTexture::RGBA32U:
+ return glImageFormatToGL(QShaderImage::RGBA32U);
+
+ case QAbstractTexture::R8I:
+ return glImageFormatToGL(QShaderImage::R8I);
+ case QAbstractTexture::RG8I:
+ return glImageFormatToGL(QShaderImage::RG8I);
+ case QAbstractTexture::RGBA8I:
+ return glImageFormatToGL(QShaderImage::RGBA8I);
+
+ case QAbstractTexture::R16I:
+ return glImageFormatToGL(QShaderImage::R16I);
+ case QAbstractTexture::RG16I:
+ return glImageFormatToGL(QShaderImage::RG16I);
+ case QAbstractTexture::RGBA16I:
+ return glImageFormatToGL(QShaderImage::RGBA16I);
+
+ case QAbstractTexture::R32I:
+ return glImageFormatToGL(QShaderImage::R32I);
+ case QAbstractTexture::RG32I:
+ return glImageFormatToGL(QShaderImage::RG32I);
+ case QAbstractTexture::RGBA32I:
+ return glImageFormatToGL(QShaderImage::RGBA32I);
+
+ case QAbstractTexture::R16F:
+ return glImageFormatToGL(QShaderImage::R16F);
+ case QAbstractTexture::RG16F:
+ return glImageFormatToGL(QShaderImage::RG16F);
+ case QAbstractTexture::RGBA16F:
+ return glImageFormatToGL(QShaderImage::RGBA16F);
+
+ case QAbstractTexture::R32F:
+ return glImageFormatToGL(QShaderImage::R32F);
+ case QAbstractTexture::RG32F:
+ return glImageFormatToGL(QShaderImage::RG32F);
+ case QAbstractTexture::RGBA32F:
+ return glImageFormatToGL(QShaderImage::RGBA32F);
+
+ case QAbstractTexture::RG11B10F:
+ return glImageFormatToGL(QShaderImage::RG11B10F);
+ case QAbstractTexture::RGB10A2:
+ return glImageFormatToGL(QShaderImage::RGB10A2);
+ case QAbstractTexture::RGB10A2U:
+ return glImageFormatToGL(QShaderImage::RGB10A2U);
+
+ default:
+ qWarning() << "Cannot map Texture format" << textureFormat << "to a valid Image Format";
+ Q_UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+} // anonymous
+
+ImageSubmissionContext::ImageSubmissionContext()
+ : m_ctx(nullptr)
+{
+}
+
+void ImageSubmissionContext::initialize(GraphicsContext *context)
+{
+ m_ctx = context;
+ m_activeImages.resize(m_ctx->maxImageUnitsCount());
+}
+
+void ImageSubmissionContext::endDrawing()
+{
+ // Reduce score of all active Images
+ decayImageScores();
+}
+
+// Return Image Unit for Image
+// If Image was used previously and recently, it will return the last used unit
+// for that image. Otherwise it will try to return the image unit the least used.
+int ImageSubmissionContext::activateImage(ShaderImage *image, GLTexture *tex)
+{
+ const int onUnit = assignUnitForImage(image->peerId());
+
+ if (onUnit < 0) {
+ qWarning() << "Unable to find available image unit";
+ return -1;
+ }
+
+ QOpenGLTexture *glTex = tex->getGLTexture();
+ if (glTex == nullptr) {
+ qWarning() << "Unable to retrieve valid texture for Image";
+ return -1;
+ }
+
+ // Bind Image against Texture and resolve Image Format
+ m_ctx->bindImageTexture(onUnit,
+ glTex->textureId(),
+ image->mipLevel(),
+ image->layered(),
+ image->layer(),
+ glAccessEnumForShaderImageAccess(image->access()),
+ glImageFormatForShaderImageFormat(image->format(),
+ tex->properties().format));
+
+ // Store information about the Texture/Image on ActiveImage for given
+ // image unit
+ m_activeImages[onUnit].shaderImageId = image->peerId();
+ m_activeImages[onUnit].texture = tex;
+ m_activeImages[onUnit].score = 200;
+ m_activeImages[onUnit].pinned = true;
+
+ return onUnit;
+}
+
+// Unset pinned Active Image and reduce their score
+void ImageSubmissionContext::deactivateImages()
+{
+ for (int u = 0, m = m_activeImages.size(); u < m; ++u) {
+ if (m_activeImages[u].pinned) {
+ m_activeImages[u].pinned = false;
+ m_activeImages[u].score = qMax(m_activeImages[u].score - 1, 0);
+ return;
+ }
+ }
+}
+
+// Reduce score of all active images (pinned or not)
+void ImageSubmissionContext::decayImageScores()
+{
+ for (int u = 0, m = m_activeImages.size(); u < m; ++u)
+ m_activeImages[u].score = qMax(m_activeImages[u].score - 1, 0);
+}
+
+int ImageSubmissionContext::assignUnitForImage(Qt3DCore::QNodeId shaderImageId)
+{
+ int lowestScoredUnit = -1;
+ int lowestScore = 0xfffffff;
+
+ const int m = m_activeImages.size();
+ for (int u = 0; u < m; ++u) {
+ if (m_activeImages[u].shaderImageId == shaderImageId)
+ return u;
+ }
+
+ for (int u = 0; u < m; ++u) {
+ // No image is currently active on the image unit
+ // we save the image unit with the texture that has been on there
+ // the longest time while not being used
+ if (!m_activeImages[u].pinned) {
+ const int score = m_activeImages[u].score;
+ if (score < lowestScore) {
+ lowestScore = score;
+ lowestScoredUnit = u;
+ }
+ }
+ }
+
+ if (lowestScoredUnit == -1)
+ qCWarning(Backend) << Q_FUNC_INFO << "No free image units!";
+
+ return lowestScoredUnit;
+}
+
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h
new file mode 100644
index 000000000..6d39f469b
--- /dev/null
+++ b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H
+#define QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DCore/QNodeId>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+
+class GraphicsContext;
+class GLTexture;
+class ShaderImage;
+
+class Q_AUTOTEST_EXPORT ImageSubmissionContext
+{
+public:
+ ImageSubmissionContext();
+
+ void initialize(GraphicsContext *context);
+ void endDrawing();
+ int activateImage(ShaderImage *image, GLTexture *tex);
+ void deactivateImages();
+
+private:
+ void decayImageScores();
+ int assignUnitForImage(Qt3DCore::QNodeId shaderImageId);
+
+ struct ActiveImage
+ {
+ Qt3DCore::QNodeId shaderImageId;
+ GLTexture *texture = nullptr;
+ int score = 0;
+ bool pinned = false;
+ };
+ QVector<ActiveImage> m_activeImages;
+ GraphicsContext *m_ctx;
+};
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
index d3bc46c12..028fd607a 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -389,6 +389,7 @@ void SubmissionContext::initialize()
{
GraphicsContext::initialize();
m_textureContext.initialize(this);
+ m_imageContext.initialize(this);
}
void SubmissionContext::resolveRenderTargetFormat()
@@ -479,6 +480,7 @@ void SubmissionContext::endDrawing(bool swapBuffers)
if (m_ownCurrent)
m_gl->doneCurrent();
m_textureContext.endDrawing();
+ m_imageContext.endDrawing();
}
void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, GLuint defaultFboId)
@@ -864,6 +866,7 @@ void SubmissionContext::setActiveMaterial(Material *rmat)
return;
m_textureContext.deactivateTexturesWithScope(TextureSubmissionContext::TextureScopeMaterial);
+ m_imageContext.deactivateImages();
m_material = rmat;
}
@@ -1160,11 +1163,13 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// Update the uniforms with the correct texture unit id's
PackUniformHash &uniformValues = parameterPack.uniforms();
+ // Fill Texture Uniform Value with proper texture units
+ // so that they can be applied as regular uniforms in a second step
for (int i = 0; i < parameterPack.textures().size(); ++i) {
- const ShaderParameterPack::NamedTexture &namedTex = parameterPack.textures().at(i);
+ const ShaderParameterPack::NamedResource &namedTex = parameterPack.textures().at(i);
// Given a Texture QNodeId, we retrieve the associated shared GLTexture
if (uniformValues.contains(namedTex.glslNameId)) {
- GLTexture *t = manager->glTextureManager()->lookupResource(namedTex.texId);
+ GLTexture *t = manager->glTextureManager()->lookupResource(namedTex.nodeId);
if (t != nullptr) {
UniformValue &texUniform = uniformValues[namedTex.glslNameId];
if (texUniform.valueType() == UniformValue::TextureValue) {
@@ -1174,6 +1179,34 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
if (namedTex.glslNameId != irradianceId &&
namedTex.glslNameId != specularId) {
// Only return false if we are not dealing with env light textures
+ qWarning() << "Unable to find suitable Texture Unit";
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Fill Image Uniform Value with proper image units
+ // so that they can be applied as regular uniforms in a second step
+ for (int i = 0; i < parameterPack.images().size(); ++i) {
+ const ShaderParameterPack::NamedResource &namedTex = parameterPack.images().at(i);
+ // Given a Texture QNodeId, we retrieve the associated shared GLTexture
+ if (uniformValues.contains(namedTex.glslNameId)) {
+ ShaderImage *img = manager->shaderImageManager()->lookupResource(namedTex.nodeId);
+ if (img != nullptr) {
+ GLTexture *t = manager->glTextureManager()->lookupResource(img->textureId());
+ if (t == nullptr) {
+ qWarning() << "Shader Image referencing invalid texture";
+ continue;
+ } else {
+ UniformValue &imgUniform = uniformValues[namedTex.glslNameId];
+ if (imgUniform.valueType() == UniformValue::ShaderImageValue) {
+ const int imgUnit = m_imageContext.activateImage(img, t);
+ imgUniform.data<int>()[namedTex.uniformArrayIndex] = imgUnit;
+ if (imgUnit == -1) {
+ qWarning() << "Unable to bind Image to Texture";
return false;
}
}
@@ -1229,8 +1262,10 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// be un activeUniforms if there wasn't a matching value
const UniformValue &v = values[uniform.m_nameId];
- // skip invalid textures
- if (v.valueType() == UniformValue::TextureValue && *v.constData<int>() == -1)
+ // skip invalid textures/images
+ if ((v.valueType() == UniformValue::TextureValue ||
+ v.valueType() == UniformValue::ShaderImageValue) &&
+ *v.constData<int>() == -1)
continue;
applyUniform(uniform, v);
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
index 844e62f15..a8700dd3a 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
@@ -55,6 +55,7 @@
#include <Qt3DRender/private/graphicscontext_p.h>
#include <Qt3DRender/private/texturesubmissioncontext_p.h>
+#include <Qt3DRender/private/imagesubmissioncontext_p.h>
#include <Qt3DRender/qclearbuffers.h>
#include <Qt3DRender/private/glbuffer_p.h>
#include <Qt3DRender/qattribute.h>
@@ -204,6 +205,7 @@ private:
QByteArray m_uboTempArray;
TextureSubmissionContext m_textureContext;
+ ImageSubmissionContext m_imageContext;
// Attributes
friend class OpenGLVertexArrayObject;