diff options
Diffstat (limited to 'src/render/graphicshelpers')
-rw-r--r-- | src/render/graphicshelpers/graphicscontext.cpp | 163 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicscontext_p.h | 10 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelperes2.cpp | 41 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelperes2_p.h | 8 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl2.cpp | 26 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl2_p.h | 4 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3_2.cpp | 44 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3_2_p.h | 4 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3_3.cpp | 12 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3_3_p.h | 4 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl4.cpp | 44 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl4_p.h | 4 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelperinterface_p.h | 7 |
13 files changed, 258 insertions, 113 deletions
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index dea8c1fc6..80e8267da 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -81,6 +81,14 @@ QT_BEGIN_NAMESPACE +#ifndef GL_READ_FRAMEBUFFER +#define GL_READ_FRAMEBUFFER 0x8CA8 +#endif + +#ifndef GL_DRAW_FRAMEBUFFER +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#endif + namespace { QOpenGLShader::ShaderType shaderType(Qt3DRender::QShaderProgram::ShaderType type) @@ -154,6 +162,7 @@ GraphicsContext::GraphicsContext() , m_ownCurrent(true) , m_activeShader(nullptr) , m_activeShaderDNA(0) + , m_renderTargetFormat(QAbstractTexture::NoFormat) , m_currClearStencilValue(0) , m_currClearDepthValue(1.f) , m_currClearColorValue(0,0,0,0) @@ -207,7 +216,7 @@ void GraphicsContext::initialize() void GraphicsContext::resolveRenderTargetFormat() { const QSurfaceFormat format = m_gl->format(); - const uint a = format.alphaBufferSize(); + const uint a = (format.alphaBufferSize() == -1) ? 0 : format.alphaBufferSize(); const uint r = format.redBufferSize(); const uint g = format.greenBufferSize(); const uint b = format.blueBufferSize(); @@ -459,11 +468,14 @@ QOpenGLShaderProgram *GraphicsContext::createShaderProgram(Shader *shaderNode) // Compile shaders const auto shaderCode = shaderNode->shaderCode(); + QString logs; for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) { QShaderProgram::ShaderType type = static_cast<const QShaderProgram::ShaderType>(i); - if (!shaderCode.at(i).isEmpty() && - !shaderProgram->addShaderFromSourceCode(shaderType(type), shaderCode.at(i))) { - qWarning().noquote() << "Failed to compile shader:" << shaderProgram->log(); + if (!shaderCode.at(i).isEmpty()) { + // Note: logs only return the error but not all the shader code + // we could append it + if (!shaderProgram->addShaderFromSourceCode(shaderType(type), shaderCode.at(i))) + logs += shaderProgram->log(); } } @@ -471,17 +483,31 @@ QOpenGLShaderProgram *GraphicsContext::createShaderProgram(Shader *shaderNode) // Since we are sharing shaders in the backend, we assume that if using custom // fragOutputs, they should all be the same for a given shader bindFragOutputs(shaderProgram->programId(), shaderNode->fragOutputs()); - if (!shaderProgram->link()) { - qWarning().noquote() << "Failed to link shader program:" << shaderProgram->log(); + + const bool linkSucceeded = shaderProgram->link(); + logs += shaderProgram->log(); + shaderNode->setLog(logs); + shaderNode->setStatus(linkSucceeded ? QShaderProgram::Ready : QShaderProgram::Error); + + if (!linkSucceeded) return nullptr; - } // take from scoped-pointer so it doesn't get deleted return shaderProgram.take(); } // That assumes that the shaderProgram in Shader stays the same -void GraphicsContext::loadShader(Shader *shader) +void GraphicsContext::introspectShaderInterface(Shader *shader, QOpenGLShaderProgram *shaderProgram) +{ + shader->initializeUniforms(m_glHelper->programUniformsAndLocations(shaderProgram->programId())); + shader->initializeAttributes(m_glHelper->programAttributesAndLocations(shaderProgram->programId())); + if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject)) + shader->initializeUniformBlocks(m_glHelper->programUniformBlocks(shaderProgram->programId())); + if (m_glHelper->supportsFeature(GraphicsHelperInterface::ShaderStorageObject)) + shader->initializeShaderStorageBlocks(m_glHelper->programShaderStorageBlocks(shaderProgram->programId())); +} + +void GraphicsContext::loadShader(Shader *shader, ShaderManager *manager) { QOpenGLShaderProgram *shaderProgram = m_shaderCache.getShaderProgramAndAddRef(shader->dna(), shader->peerId()); if (!shaderProgram) { @@ -493,20 +519,31 @@ void GraphicsContext::loadShader(Shader *shader) } // Ensure the Shader node knows about the program interface - // TODO: Improve this so we only introspect once per actual OpenGL shader program - // rather than once per ShaderNode. Could cache the interface description along - // with the QOpenGLShaderProgram in the ShaderCache. if (Q_LIKELY(shaderProgram != nullptr) && !shader->isLoaded()) { - // Introspect and set up interface description on Shader backend node - shader->initializeUniforms(m_glHelper->programUniformsAndLocations(shaderProgram->programId())); - shader->initializeAttributes(m_glHelper->programAttributesAndLocations(shaderProgram->programId())); - if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject)) - shader->initializeUniformBlocks(m_glHelper->programUniformBlocks(shaderProgram->programId())); - if (m_glHelper->supportsFeature(GraphicsHelperInterface::ShaderStorageObject)) - shader->initializeShaderStorageBlocks(m_glHelper->programShaderStorageBlocks(shaderProgram->programId())); + + // Find an already loaded shader that shares the same QOpenGLShaderProgram + Shader *refShader = nullptr; + const QVector<Qt3DCore::QNodeId> sharedShaderIds = m_shaderCache.shaderIdsForProgram(shader->dna()); + for (const Qt3DCore::QNodeId sharedShaderId : sharedShaderIds) { + Shader *sharedShader = manager->lookupResource(sharedShaderId); + // Note: no need to check if shader->peerId != sharedShader->peerId + // as we are sure that this code path is executed only if !shared->isLoaded + if (sharedShader->isLoaded()) { + refShader = sharedShader; + break; + } + } + + // We only introspect once per actual OpenGL shader program + // rather than once per ShaderNode. + if (refShader != nullptr) + shader->initializeFromReference(*refShader); + else // Introspect and set up interface description on Shader backend node + introspectShaderInterface(shader, shaderProgram); shader->setGraphicsContext(this); shader->setLoaded(true); + shader->markDirty(AbstractRenderer::AllDirty); } } @@ -1045,6 +1082,16 @@ void GraphicsContext::dispatchCompute(int x, int y, int z) m_glHelper->dispatchCompute(x, y, z); } +GLboolean GraphicsContext::unmapBuffer(GLenum target) +{ + return m_glHelper->unmapBuffer(target); +} + +char *GraphicsContext::mapBuffer(GLenum target) +{ + return m_glHelper->mapBuffer(target); +} + void GraphicsContext::enablei(GLenum cap, GLuint index) { m_glHelper->enablei(cap, index); @@ -1273,16 +1320,16 @@ void GraphicsContext::applyUniform(const ShaderUniform &description, const Unifo break; case UniformType::UInt: - applyUniformHelper<UniformType::Int>(description.m_location, description.m_size, v); + applyUniformHelper<UniformType::UInt>(description.m_location, description.m_size, v); break; case UniformType::UIVec2: - applyUniformHelper<UniformType::IVec2>(description.m_location, description.m_size, v); + applyUniformHelper<UniformType::UIVec2>(description.m_location, description.m_size, v); break; case UniformType::UIVec3: - applyUniformHelper<UniformType::IVec3>(description.m_location, description.m_size, v); + applyUniformHelper<UniformType::UIVec3>(description.m_location, description.m_size, v); break; case UniformType::UIVec4: - applyUniformHelper<UniformType::IVec4>(description.m_location, description.m_size, v); + applyUniformHelper<UniformType::UIVec4>(description.m_location, description.m_size, v); break; case UniformType::Bool: @@ -1398,6 +1445,16 @@ void GraphicsContext::updateBuffer(Buffer *buffer) uploadDataToGLBuffer(buffer, m_renderer->nodeManagers()->glBufferManager()->data(it.value())); } +QByteArray GraphicsContext::downloadBufferContent(Buffer *buffer) +{ + const QHash<Qt3DCore::QNodeId, HGLBuffer>::iterator it = m_renderBufferHash.find(buffer->peerId()); + if (it != m_renderBufferHash.end()) + return downloadDataFromGLBuffer(buffer, m_renderer->nodeManagers()->glBufferManager()->data(it.value())); + return QByteArray(); +} + + + void GraphicsContext::releaseBuffer(Qt3DCore::QNodeId bufferId) { auto it = m_renderBufferHash.find(bufferId); @@ -1421,7 +1478,7 @@ bool GraphicsContext::hasGLBufferForBuffer(Buffer *buffer) return (it != m_renderBufferHash.end()); } -void GraphicsContext::memoryBarrier(QMemoryBarrier::BarrierTypes barriers) +void GraphicsContext::memoryBarrier(QMemoryBarrier::Operations barriers) { m_glHelper->memoryBarrier(barriers); } @@ -1444,8 +1501,6 @@ HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer) if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type()))) qCWarning(Render::Io) << Q_FUNC_INFO << "buffer binding failed"; - // TO DO: Handle usage pattern - b->allocate(this, buffer->data().constData(), buffer->data().size(), false); return m_renderer->nodeManagers()->glBufferManager()->lookupHandle(buffer->peerId()); } @@ -1471,21 +1526,39 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel // * setData was called changing the whole data or functor (or the usage pattern) // * partial buffer updates where received - // Note: we assume the case where both setData/functor and updates are called to be a misuse - // with unexpected behavior - const QVector<Qt3DRender::QBufferUpdate> updates = std::move(buffer->pendingBufferUpdates()); - if (!updates.empty()) { - for (const Qt3DRender::QBufferUpdate &update : updates) { + // TO DO: Handle usage pattern + QVector<Qt3DRender::QBufferUpdate> updates = std::move(buffer->pendingBufferUpdates()); + for (auto it = updates.begin(); it != updates.end(); ++it) { + auto update = it; + // We have a partial update + if (update->offset >= 0) { + //accumulate sequential updates as single one + int bufferSize = update->data.size(); + auto it2 = it + 1; + while ((it2 != updates.end()) + && (it2->offset - update->offset == bufferSize)) { + bufferSize += it2->data.size(); + ++it2; + } + update->data.resize(bufferSize); + while (it + 1 != it2) { + ++it; + update->data.replace(it->offset - update->offset, it->data.size(), it->data); + it->data.clear(); + } // TO DO: based on the number of updates .., it might make sense to // sometime use glMapBuffer rather than glBufferSubData - b->update(this, update.data.constData(), update.data.size(), update.offset); + b->update(this, update->data.constData(), update->data.size(), update->offset); + } else { + // We have an update that was done by calling QBuffer::setData + // which is used to resize or entirely clear the buffer + // Note: we use the buffer data directly in that case + const int bufferSize = buffer->data().size(); + b->allocate(this, bufferSize, false); // orphan the buffer + b->allocate(this, buffer->data().constData(), bufferSize, false); } - } else { - const int bufferSize = buffer->data().size(); - // TO DO: Handle usage pattern - b->allocate(this, bufferSize, false); // orphan the buffer - b->allocate(this, buffer->data().constData(), bufferSize, false); } + if (releaseBuffer) { b->release(this); if (bufferTypeToGLBufferType(buffer->type()) == GLBuffer::ArrayBuffer) @@ -1494,6 +1567,15 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel qCDebug(Render::Io) << "uploaded buffer size=" << buffer->data().size(); } +QByteArray GraphicsContext::downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b) +{ + if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type()))) + qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed"; + + QByteArray data = b->download(this, buffer->data().size()); + return data; +} + GLint GraphicsContext::elementType(GLint type) { switch (type) { @@ -1649,10 +1731,8 @@ QImage GraphicsContext::readFramebuffer(QSize size) QImage::Format imageFormat; uint stride; -#ifndef QT_OPENGL_ES_2 /* format value should match GL internalFormat */ GLenum internalFormat = m_renderTargetFormat; -#endif switch (m_renderTargetFormat) { case QAbstractTexture::RGBAFormat: @@ -1728,18 +1808,15 @@ QImage GraphicsContext::readFramebuffer(QSize size) return img; } -#ifndef QT_OPENGL_ES_2 GLint samples = 0; m_gl->functions()->glGetIntegerv(GL_SAMPLES, &samples); if (samples > 0 && !m_glHelper->supportsFeature(GraphicsHelperInterface::BlitFramebuffer)) return img; -#endif img = QImage(size.width(), size.height(), imageFormat); QScopedArrayPointer<uchar> data(new uchar [bytes]); -#ifndef QT_OPENGL_ES_2 if (samples > 0) { // resolve multisample-framebuffer to renderbuffer and read pixels from it GLuint fbo, rb; @@ -1771,14 +1848,10 @@ QImage GraphicsContext::readFramebuffer(QSize size) gl->glBindFramebuffer(GL_FRAMEBUFFER, m_activeFBO); gl->glDeleteFramebuffers(1, &fbo); } else { -#endif // read pixels directly from framebuffer m_gl->functions()->glReadPixels(0,0,size.width(), size.height(), format, type, data.data()); copyGLFramebufferDataToImage(img, data.data(), stride, size.width(), size.height(), m_renderTargetFormat); - -#ifndef QT_OPENGL_ES_2 } -#endif return img; } diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h index 133c84b8c..4358da999 100644 --- a/src/render/graphicshelpers/graphicscontext_p.h +++ b/src/render/graphicshelpers/graphicscontext_p.h @@ -91,6 +91,7 @@ class RenderTarget; class AttachmentPack; class Attribute; class Buffer; +class ShaderManager; enum TextureScope { @@ -130,9 +131,10 @@ public: bool isInitialized() const; QOpenGLShaderProgram *createShaderProgram(Shader *shaderNode); - void loadShader(Shader* shader); + void loadShader(Shader* shader, ShaderManager *manager); bool activateShader(ProgramDNA shaderDNA); void removeShaderProgramReference(Shader *shaderNode); + void introspectShaderInterface(Shader *shader, QOpenGLShaderProgram *shaderProgram); GLuint activeFBO() const { return m_activeFBO; } GLuint defaultFBO() const { return m_defaultFBO; } @@ -157,10 +159,11 @@ public: void specifyAttribute(const Attribute *attribute, Buffer *buffer, int attributeLocation); void specifyIndices(Buffer *buffer); void updateBuffer(Buffer *buffer); + QByteArray downloadBufferContent(Buffer *buffer); void releaseBuffer(Qt3DCore::QNodeId bufferId); bool hasGLBufferForBuffer(Buffer *buffer); - void memoryBarrier(QMemoryBarrier::BarrierTypes barriers); + void memoryBarrier(QMemoryBarrier::Operations barriers); void setParameters(ShaderParameterPack ¶meterPack); @@ -208,6 +211,8 @@ public: void disablei(GLenum cap, GLuint index); void disablePrimitiveRestart(); void dispatchCompute(int x, int y, int z); + char * mapBuffer(GLenum target); + GLboolean unmapBuffer(GLenum target); void drawArrays(GLenum primitiveType, GLint first, GLsizei count); void drawArraysIndirect(GLenum mode,void *indirect); void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances); @@ -252,6 +257,7 @@ private: void activateDrawBuffers(const AttachmentPack &attachments); HGLBuffer createGLBufferFor(Buffer *buffer); void uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer = false); + QByteArray downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b); bool bindGLBuffer(GLBuffer *buffer, GLBuffer::Type type); void resolveRenderTargetFormat(); diff --git a/src/render/graphicshelpers/graphicshelperes2.cpp b/src/render/graphicshelpers/graphicshelperes2.cpp index a89f0ff8b..3b821f804 100644 --- a/src/render/graphicshelpers/graphicshelperes2.cpp +++ b/src/render/graphicshelpers/graphicshelperes2.cpp @@ -65,8 +65,9 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -GraphicsHelperES2::GraphicsHelperES2() : - m_funcs(0) +GraphicsHelperES2::GraphicsHelperES2() + : m_funcs(0) + , m_supportFramebufferBlit(false) { } @@ -80,6 +81,9 @@ void GraphicsHelperES2::initializeHelper(QOpenGLContext *context, Q_ASSERT(context); m_funcs = context->functions(); Q_ASSERT(m_funcs); + m_ext.reset(new QOpenGLExtensions(context)); + if (m_ext->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) + m_supportFramebufferBlit = true; } void GraphicsHelperES2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, @@ -366,6 +370,8 @@ bool GraphicsHelperES2::supportsFeature(GraphicsHelperInterface::Feature feature switch (feature) { case RenderBufferDimensionRetrieval: return true; + case BlitFramebuffer: + return m_supportFramebufferBlit; default: return false; } @@ -492,7 +498,7 @@ GLint GraphicsHelperES2::maxClipPlaneCount() return 0; } -void GraphicsHelperES2::memoryBarrier(QMemoryBarrier::BarrierTypes barriers) +void GraphicsHelperES2::memoryBarrier(QMemoryBarrier::Operations barriers) { Q_UNUSED(barriers); qWarning() << "memory barrier is not supported by OpenGL ES 2.0 (since 4.3)"; @@ -575,6 +581,20 @@ void GraphicsHelperES2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by ES 2.0 (since ES 3.1)"; } +char *GraphicsHelperES2::mapBuffer(GLenum target) +{ + Q_UNUSED(target); + qWarning() << "Map buffer is not a core requirement for ES 2.0"; + return nullptr; +} + +GLboolean GraphicsHelperES2::unmapBuffer(GLenum target) +{ + Q_UNUSED(target); + qWarning() << "unMap buffer is not a core requirement for ES 2.0"; + return false; +} + void GraphicsHelperES2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) { m_funcs->glUniform1fv(location, count, values); @@ -725,17 +745,10 @@ UniformType GraphicsHelperES2::uniformTypeFromGLType(GLenum type) void GraphicsHelperES2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - Q_UNUSED(srcX0); - Q_UNUSED(srcX1); - Q_UNUSED(srcY0); - Q_UNUSED(srcY1); - Q_UNUSED(dstX0); - Q_UNUSED(dstX1); - Q_UNUSED(dstY0); - Q_UNUSED(dstY1); - Q_UNUSED(mask); - Q_UNUSED(filter); - qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)"; + if (!m_supportFramebufferBlit) + qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)"; + else + m_ext->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } } // namespace Render diff --git a/src/render/graphicshelpers/graphicshelperes2_p.h b/src/render/graphicshelpers/graphicshelperes2_p.h index 2a1f3cf05..f34eb7f87 100644 --- a/src/render/graphicshelpers/graphicshelperes2_p.h +++ b/src/render/graphicshelpers/graphicshelperes2_p.h @@ -57,6 +57,8 @@ QT_BEGIN_NAMESPACE +class QOpenGLExtensions; + namespace Qt3DRender { namespace Render { @@ -89,6 +91,8 @@ public: void disablei(GLenum cap, GLuint index) Q_DECL_OVERRIDE; void disablePrimitiveRestart() Q_DECL_OVERRIDE; void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) Q_DECL_OVERRIDE; + char *mapBuffer(GLenum target) Q_DECL_OVERRIDE; + GLboolean unmapBuffer(GLenum target) Q_DECL_OVERRIDE; void drawArrays(GLenum primitiveType, GLint first, GLsizei count) Q_DECL_OVERRIDE; void drawArraysIndirect(GLenum mode,void *indirect) Q_DECL_OVERRIDE; void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) Q_DECL_OVERRIDE; @@ -106,7 +110,7 @@ public: void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE; void pointSize(bool programmable, GLfloat value) Q_DECL_OVERRIDE; GLint maxClipPlaneCount() Q_DECL_OVERRIDE; - void memoryBarrier(QMemoryBarrier::BarrierTypes barriers) Q_DECL_OVERRIDE; + void memoryBarrier(QMemoryBarrier::Operations barriers) Q_DECL_OVERRIDE; QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; @@ -151,6 +155,8 @@ public: protected: QOpenGLFunctions *m_funcs; + bool m_supportFramebufferBlit; + QScopedPointer<QOpenGLExtensions> m_ext; }; } // namespace Render diff --git a/src/render/graphicshelpers/graphicshelpergl2.cpp b/src/render/graphicshelpers/graphicshelpergl2.cpp index 765a12f42..5f798f94e 100644 --- a/src/render/graphicshelpers/graphicshelpergl2.cpp +++ b/src/render/graphicshelpers/graphicshelpergl2.cpp @@ -518,7 +518,7 @@ GLint GraphicsHelperGL2::maxClipPlaneCount() return max; } -void GraphicsHelperGL2::memoryBarrier(QMemoryBarrier::BarrierTypes barriers) +void GraphicsHelperGL2::memoryBarrier(QMemoryBarrier::Operations barriers) { Q_UNUSED(barriers); qWarning() << "memory barrier is not supported by OpenGL 2.0 (since 4.3)"; @@ -541,15 +541,11 @@ void GraphicsHelperGL2::clearBufferf(GLint drawbuffer, const QVector4D &values) void GraphicsHelperGL2::pointSize(bool programmable, GLfloat value) { - // Print a warning once for trying to set GL_PROGRAM_POINT_SIZE - if (programmable) { - static bool warned = false; - if (!warned) { - qWarning() << "GL_PROGRAM_POINT_SIZE is not supported by OpenGL 2.0 (since 3.2)"; - warned = true; - } - } - m_funcs->glPointSize(value); + m_funcs->glEnable(GL_POINT_SPRITE); + if (programmable) + m_funcs->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + else + m_funcs->glPointSize(value); } void GraphicsHelperGL2::enablei(GLenum cap, GLuint index) @@ -600,6 +596,16 @@ void GraphicsHelperGL2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by OpenGL 2.0 (since OpenGL 4.3)"; } +char *GraphicsHelperGL2::mapBuffer(GLenum target) +{ + return static_cast<char*>(m_funcs->glMapBuffer(target, GL_READ_WRITE)); +} + +GLboolean GraphicsHelperGL2::unmapBuffer(GLenum target) +{ + return m_funcs->glUnmapBuffer(target); +} + void GraphicsHelperGL2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) { m_funcs->glUniform1fv(location, count, values); diff --git a/src/render/graphicshelpers/graphicshelpergl2_p.h b/src/render/graphicshelpers/graphicshelpergl2_p.h index a6fa6dba5..8966e48b2 100644 --- a/src/render/graphicshelpers/graphicshelpergl2_p.h +++ b/src/render/graphicshelpers/graphicshelpergl2_p.h @@ -91,6 +91,8 @@ public: void disablei(GLenum cap, GLuint index) Q_DECL_OVERRIDE; void disablePrimitiveRestart() Q_DECL_OVERRIDE; void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) Q_DECL_OVERRIDE; + char *mapBuffer(GLenum target) Q_DECL_OVERRIDE; + GLboolean unmapBuffer(GLenum target) Q_DECL_OVERRIDE; void drawArrays(GLenum primitiveType, GLint first, GLsizei count) Q_DECL_OVERRIDE; void drawArraysIndirect(GLenum mode,void *indirect) Q_DECL_OVERRIDE; void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) Q_DECL_OVERRIDE; @@ -108,7 +110,7 @@ public: void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE; void pointSize(bool programmable, GLfloat value) Q_DECL_OVERRIDE; GLint maxClipPlaneCount() Q_DECL_OVERRIDE; - void memoryBarrier(QMemoryBarrier::BarrierTypes barriers) Q_DECL_OVERRIDE; + void memoryBarrier(QMemoryBarrier::Operations barriers) Q_DECL_OVERRIDE; QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl3_2.cpp b/src/render/graphicshelpers/graphicshelpergl3_2.cpp index 382078ac6..6c768e94e 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_2.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3_2.cpp @@ -82,7 +82,7 @@ GraphicsHelperGL3_2::~GraphicsHelperGL3_2() } void GraphicsHelperGL3_2::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) + QAbstractOpenGLFunctions *functions) { m_funcs = static_cast<QOpenGLFunctions_3_2_Core*>(functions); const bool ok = m_funcs->initializeOpenGLFunctions(); @@ -96,12 +96,12 @@ void GraphicsHelperGL3_2::initializeHelper(QOpenGLContext *context, } void GraphicsHelperGL3_2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) + GLsizei primitiveCount, + GLint indexType, + void *indices, + GLsizei instances, + GLint baseVertex, + GLint baseInstance) { if (baseInstance != 0) qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2"; @@ -116,9 +116,9 @@ void GraphicsHelperGL3_2::drawElementsInstancedBaseVertexBaseInstance(GLenum pri } void GraphicsHelperGL3_2::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) + GLint first, + GLsizei count, + GLsizei instances) { // glDrawArraysInstanced OpenGL 3.1 or greater m_funcs->glDrawArraysInstanced(primitiveType, @@ -138,10 +138,10 @@ void GraphicsHelperGL3_2::drawArraysInstancedBaseInstance(GLenum primitiveType, } void GraphicsHelperGL3_2::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) + GLsizei primitiveCount, + GLint indexType, + void *indices, + GLint baseVertex) { m_funcs->glDrawElementsBaseVertex(primitiveType, primitiveCount, @@ -151,8 +151,8 @@ void GraphicsHelperGL3_2::drawElements(GLenum primitiveType, } void GraphicsHelperGL3_2::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) + GLint first, + GLsizei count) { m_funcs->glDrawArrays(primitiveType, first, @@ -797,7 +797,7 @@ GLint GraphicsHelperGL3_2::maxClipPlaneCount() return max; } -void GraphicsHelperGL3_2::memoryBarrier(QMemoryBarrier::BarrierTypes barriers) +void GraphicsHelperGL3_2::memoryBarrier(QMemoryBarrier::Operations barriers) { Q_UNUSED(barriers); qWarning() << "memory barrier is not supported by OpenGL 3.0 (since 4.3)"; @@ -882,6 +882,16 @@ void GraphicsHelperGL3_2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by OpenGL 3.2 (since OpenGL 4.3)"; } +char *GraphicsHelperGL3_2::mapBuffer(GLenum target) +{ + return static_cast<char*>(m_funcs->glMapBuffer(target, GL_READ_WRITE)); +} + +GLboolean GraphicsHelperGL3_2::unmapBuffer(GLenum target) +{ + return m_funcs->glUnmapBuffer(target); +} + void GraphicsHelperGL3_2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) { m_funcs->glUniform1fv(location, count, values); diff --git a/src/render/graphicshelpers/graphicshelpergl3_2_p.h b/src/render/graphicshelpers/graphicshelpergl3_2_p.h index d10bda40b..fbca14361 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_2_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_2_p.h @@ -93,6 +93,8 @@ public: void disablei(GLenum cap, GLuint index) Q_DECL_OVERRIDE; void disablePrimitiveRestart() Q_DECL_OVERRIDE; void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) Q_DECL_OVERRIDE; + char *mapBuffer(GLenum target) Q_DECL_OVERRIDE; + GLboolean unmapBuffer(GLenum target) Q_DECL_OVERRIDE; void drawArrays(GLenum primitiveType, GLint first, GLsizei count) Q_DECL_OVERRIDE; void drawArraysIndirect(GLenum mode,void *indirect) Q_DECL_OVERRIDE; void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) Q_DECL_OVERRIDE; @@ -110,7 +112,7 @@ public: void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE; void pointSize(bool programmable, GLfloat value) Q_DECL_OVERRIDE; GLint maxClipPlaneCount() Q_DECL_OVERRIDE; - void memoryBarrier(QMemoryBarrier::BarrierTypes barriers) Q_DECL_OVERRIDE; + void memoryBarrier(QMemoryBarrier::Operations barriers) Q_DECL_OVERRIDE; QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/graphicshelpers/graphicshelpergl3_3.cpp index 023e90965..6959bdc6b 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3_3.cpp @@ -794,7 +794,7 @@ GLint GraphicsHelperGL3_3::maxClipPlaneCount() return max; } -void GraphicsHelperGL3_3::memoryBarrier(QMemoryBarrier::BarrierTypes barriers) +void GraphicsHelperGL3_3::memoryBarrier(QMemoryBarrier::Operations barriers) { Q_UNUSED(barriers); qWarning() << "memory barrier is not supported by OpenGL 3.3 (since 4.3)"; @@ -879,6 +879,16 @@ void GraphicsHelperGL3_3::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by OpenGL 3.3 (since OpenGL 4.3)"; } +char *GraphicsHelperGL3_3::mapBuffer(GLenum target) +{ + return static_cast<char*>(m_funcs->glMapBuffer(target, GL_READ_WRITE)); +} + +GLboolean GraphicsHelperGL3_3::unmapBuffer(GLenum target) +{ + return m_funcs->glUnmapBuffer(target); +} + void GraphicsHelperGL3_3::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) { m_funcs->glUniform1fv(location, count, values); diff --git a/src/render/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/graphicshelpers/graphicshelpergl3_3_p.h index 9e97f3dc4..c093c801e 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_3_p.h @@ -93,6 +93,8 @@ public: void disablei(GLenum cap, GLuint index) Q_DECL_OVERRIDE; void disablePrimitiveRestart() Q_DECL_OVERRIDE; void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) Q_DECL_OVERRIDE; + char *mapBuffer(GLenum target) Q_DECL_OVERRIDE; + GLboolean unmapBuffer(GLenum target) Q_DECL_OVERRIDE; void drawArrays(GLenum primitiveType, GLint first, GLsizei count) Q_DECL_OVERRIDE; void drawArraysIndirect(GLenum mode,void *indirect) Q_DECL_OVERRIDE; void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) Q_DECL_OVERRIDE; @@ -110,7 +112,7 @@ public: void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE; void pointSize(bool programmable, GLfloat value) Q_DECL_OVERRIDE; GLint maxClipPlaneCount() Q_DECL_OVERRIDE; - void memoryBarrier(QMemoryBarrier::BarrierTypes barriers) Q_DECL_OVERRIDE; + void memoryBarrier(QMemoryBarrier::Operations barriers) Q_DECL_OVERRIDE; QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl4.cpp b/src/render/graphicshelpers/graphicshelpergl4.cpp index 6972864cf..26f03ac8a 100644 --- a/src/render/graphicshelpers/graphicshelpergl4.cpp +++ b/src/render/graphicshelpers/graphicshelpergl4.cpp @@ -88,42 +88,42 @@ namespace Render { namespace { -GLbitfield memoryBarrierGLBitfield(QMemoryBarrier::BarrierTypes barriers) +GLbitfield memoryBarrierGLBitfield(QMemoryBarrier::Operations barriers) { GLbitfield bits = 0; - if (barriers.testFlag(QMemoryBarrier::AllBarrier)) { + if (barriers.testFlag(QMemoryBarrier::All)) { bits |= GL_ALL_BARRIER_BITS; return bits; } - if (barriers.testFlag(QMemoryBarrier::VertexAttributeArrayBarrier)) + if (barriers.testFlag(QMemoryBarrier::VertexAttributeArray)) bits |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ElementArrayBarrier)) + if (barriers.testFlag(QMemoryBarrier::ElementArray)) bits |= GL_ELEMENT_ARRAY_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::UniformBarrier)) + if (barriers.testFlag(QMemoryBarrier::Uniform)) bits |= GL_UNIFORM_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TextureFetchBarrier)) + if (barriers.testFlag(QMemoryBarrier::TextureFetch)) bits |= GL_TEXTURE_FETCH_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ShaderImageAccessBarrier)) + if (barriers.testFlag(QMemoryBarrier::ShaderImageAccess)) bits |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::CommandBarrier)) + if (barriers.testFlag(QMemoryBarrier::Command)) bits |= GL_COMMAND_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::PixelBufferBarrier)) + if (barriers.testFlag(QMemoryBarrier::PixelBuffer)) bits |= GL_PIXEL_BUFFER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TextureUpdateBarrier)) + if (barriers.testFlag(QMemoryBarrier::TextureUpdate)) bits |= GL_TEXTURE_UPDATE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::BufferUpdateBarrier)) + if (barriers.testFlag(QMemoryBarrier::BufferUpdate)) bits |= GL_BUFFER_UPDATE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::FrameBufferBarrier)) + if (barriers.testFlag(QMemoryBarrier::FrameBuffer)) bits |= GL_FRAMEBUFFER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TransformFeedbackBarrier)) + if (barriers.testFlag(QMemoryBarrier::TransformFeedback)) bits |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::AtomicCounterBarrier)) + if (barriers.testFlag(QMemoryBarrier::AtomicCounter)) bits |= GL_ATOMIC_COUNTER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ShaderStorageBarrier)) + if (barriers.testFlag(QMemoryBarrier::ShaderStorage)) bits |= GL_SHADER_STORAGE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::QueryBufferBarrier)) + if (barriers.testFlag(QMemoryBarrier::QueryBuffer)) bits |= GL_QUERY_BUFFER_BARRIER_BIT; return bits; @@ -1047,7 +1047,7 @@ GLint GraphicsHelperGL4::maxClipPlaneCount() return max; } -void GraphicsHelperGL4::memoryBarrier(QMemoryBarrier::BarrierTypes barriers) +void GraphicsHelperGL4::memoryBarrier(QMemoryBarrier::Operations barriers) { m_funcs->glMemoryBarrier(memoryBarrierGLBitfield(barriers)); } @@ -1128,6 +1128,16 @@ void GraphicsHelperGL4::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) m_funcs->glDispatchCompute(wx, wy, wz); } +char *GraphicsHelperGL4::mapBuffer(GLenum target) +{ + return static_cast<char*>(m_funcs->glMapBuffer(target, GL_READ_WRITE)); +} + +GLboolean GraphicsHelperGL4::unmapBuffer(GLenum target) +{ + return m_funcs->glUnmapBuffer(target); +} + void GraphicsHelperGL4::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { m_funcs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); diff --git a/src/render/graphicshelpers/graphicshelpergl4_p.h b/src/render/graphicshelpers/graphicshelpergl4_p.h index df4cf5dd9..6b3385838 100644 --- a/src/render/graphicshelpers/graphicshelpergl4_p.h +++ b/src/render/graphicshelpers/graphicshelpergl4_p.h @@ -91,6 +91,8 @@ public: void disablei(GLenum cap, GLuint index) Q_DECL_OVERRIDE; void disablePrimitiveRestart() Q_DECL_OVERRIDE; void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) Q_DECL_OVERRIDE; + char *mapBuffer(GLenum target) Q_DECL_OVERRIDE; + GLboolean unmapBuffer(GLenum target) Q_DECL_OVERRIDE; void drawArrays(GLenum primitiveType, GLint first, GLsizei count) Q_DECL_OVERRIDE; void drawArraysIndirect(GLenum mode,void *indirect) Q_DECL_OVERRIDE; void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) Q_DECL_OVERRIDE; @@ -108,7 +110,7 @@ public: void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE; void pointSize(bool programmable, GLfloat value) Q_DECL_OVERRIDE; GLint maxClipPlaneCount() Q_DECL_OVERRIDE; - void memoryBarrier(QMemoryBarrier::BarrierTypes barriers) Q_DECL_OVERRIDE; + void memoryBarrier(QMemoryBarrier::Operations barriers) Q_DECL_OVERRIDE; QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelperinterface_p.h b/src/render/graphicshelpers/graphicshelperinterface_p.h index 847b2fc9e..4b2569263 100644 --- a/src/render/graphicshelpers/graphicshelperinterface_p.h +++ b/src/render/graphicshelpers/graphicshelperinterface_p.h @@ -80,7 +80,8 @@ public: Compute, DrawBuffersBlend, BlitFramebuffer, - IndirectDrawing + IndirectDrawing, + MapBuffer }; virtual ~GraphicsHelperInterface() {} @@ -106,6 +107,8 @@ public: virtual void disablei(GLenum cap, GLuint index) = 0; virtual void disablePrimitiveRestart() = 0; virtual void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) = 0; + virtual char *mapBuffer(GLenum target) = 0; + virtual GLboolean unmapBuffer(GLenum target) = 0; virtual void drawArrays(GLenum primitiveType, GLint first, GLsizei count) = 0; virtual void drawArraysIndirect(GLenum mode,void *indirect) = 0; virtual void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) = 0; @@ -122,7 +125,7 @@ public: virtual QSize getTextureDimensions(GLuint textureId, GLenum target, uint level = 0) = 0; virtual void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) = 0; virtual GLint maxClipPlaneCount() = 0; - virtual void memoryBarrier(QMemoryBarrier::BarrierTypes barriers) = 0; + virtual void memoryBarrier(QMemoryBarrier::Operations barriers) = 0; virtual void pointSize(bool programmable, GLfloat value) = 0; virtual QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) = 0; virtual QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) = 0; |