summaryrefslogtreecommitdiffstats
path: root/src/render/graphicshelpers
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/graphicshelpers')
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp163
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h10
-rw-r--r--src/render/graphicshelpers/graphicshelperes2.cpp41
-rw-r--r--src/render/graphicshelpers/graphicshelperes2_p.h8
-rw-r--r--src/render/graphicshelpers/graphicshelpergl2.cpp26
-rw-r--r--src/render/graphicshelpers/graphicshelpergl2_p.h4
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_2.cpp44
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_2_p.h4
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_3.cpp12
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_3_p.h4
-rw-r--r--src/render/graphicshelpers/graphicshelpergl4.cpp44
-rw-r--r--src/render/graphicshelpers/graphicshelpergl4_p.h4
-rw-r--r--src/render/graphicshelpers/graphicshelperinterface_p.h7
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 &parameterPack);
@@ -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;