summaryrefslogtreecommitdiffstats
path: root/src/render
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2015-12-09 13:23:07 +0100
committerPaul Lemire <paul.lemire@kdab.com>2016-01-13 16:10:10 +0000
commitd0ab2359f5b4b23dcd017ed6abb2c063deb98a85 (patch)
tree3e574c6172c58a27affb2474a6683a19e83a3794 /src/render
parentd7f99a581d7a0430c25f68449240311152a51b1b (diff)
GraphicsContext: use GLBuffer instead of QOpenGLBuffer
This will be needed to simplify the process of binding SSBO/UBO buffers. Change-Id: Ice3bb97381328c5bddf1c9e46af30b4814ff2572 Note: ShaderData UBO handling temporarly disabled. Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render')
-rw-r--r--src/render/backend/managers_p.h2
-rw-r--r--src/render/backend/renderview.cpp71
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp187
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h10
-rw-r--r--src/render/io/glbuffer.cpp16
-rw-r--r--src/render/io/glbuffer_p.h9
6 files changed, 162 insertions, 133 deletions
diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h
index 94089795c..e3b9cb9d7 100644
--- a/src/render/backend/managers_p.h
+++ b/src/render/backend/managers_p.h
@@ -284,7 +284,7 @@ public:
class GLBufferManager : public Qt3DCore::QResourceManager<
GLBuffer,
- BufferShaderKey,
+ Qt3DCore::QNodeId,
16,
Qt3DCore::ArrayAllocatingPolicy,
Qt3DCore::ObjectLevelLockingPolicy>
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 22aa581a7..120142c51 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -621,41 +621,44 @@ void RenderView::setUniformBlockValue(QUniformPack &uniformPack, Shader *shader,
// Note: we assume that if a buffer is shared accross multiple shaders
// then it implies that they share the same layout
- BufferShaderKey uboKey(shaderData->peerUuid(),
- shader->peerUuid());
-
- BlockToUBO uniformBlockUBO;
- uniformBlockUBO.m_blockIndex = block.m_index;
- uniformBlockUBO.m_shaderDataID = shaderData->peerUuid();
- bool uboNeedsUpdate = false;
-
- // build UBO at uboId if not created before
- if (!m_manager->glBufferManager()->contains(uboKey)) {
- m_manager->glBufferManager()->getOrCreateResource(uboKey);
- uboNeedsUpdate = true;
- }
-
- // If shaderData has been updated (property has changed or one of the nested properties has changed)
- // foreach property defined in the QShaderData, we try to fill the value of the corresponding active uniform(s)
- // for all the updated properties (all the properties if the UBO was just created)
- if (shaderData->updateViewTransform(*m_data->m_viewMatrix) || uboNeedsUpdate) {
- // Clear previous values remaining in the hash
- m_data->m_uniformBlockBuilder.activeUniformNamesToValue.clear();
- // Update only update properties if uboNeedsUpdate is true, otherwise update the whole block
- m_data->m_uniformBlockBuilder.updatedPropertiesOnly = uboNeedsUpdate;
- // Retrieve names and description of each active uniforms in the uniform block
- m_data->m_uniformBlockBuilder.uniforms = shader->activeUniformsForUniformBlock(block.m_index);
- // Builds the name-value map for the block
- m_data->m_uniformBlockBuilder.buildActiveUniformNameValueMapStructHelper(shaderData, block.m_name);
- if (!uboNeedsUpdate)
- shaderData->markDirty();
- // copy the name-value map into the BlockToUBO
- uniformBlockUBO.m_updatedProperties = m_data->m_uniformBlockBuilder.activeUniformNamesToValue;
- uboNeedsUpdate = true;
- }
- uniformBlockUBO.m_needsUpdate = uboNeedsUpdate;
- uniformPack.setUniformBuffer(uniformBlockUBO);
+ // Temporarly disabled
+
+ // BufferShaderKey uboKey(shaderData->peerUuid(),
+ // shader->peerUuid());
+
+ // BlockToUBO uniformBlockUBO;
+ // uniformBlockUBO.m_blockIndex = block.m_index;
+ // uniformBlockUBO.m_shaderDataID = shaderData->peerUuid();
+ // bool uboNeedsUpdate = false;
+
+ // // build UBO at uboId if not created before
+ // if (!m_manager->glBufferManager()->contains(uboKey)) {
+ // m_manager->glBufferManager()->getOrCreateResource(uboKey);
+ // uboNeedsUpdate = true;
+ // }
+
+ // // If shaderData has been updated (property has changed or one of the nested properties has changed)
+ // // foreach property defined in the QShaderData, we try to fill the value of the corresponding active uniform(s)
+ // // for all the updated properties (all the properties if the UBO was just created)
+ // if (shaderData->updateViewTransform(*m_data->m_viewMatrix) || uboNeedsUpdate) {
+ // // Clear previous values remaining in the hash
+ // m_data->m_uniformBlockBuilder.activeUniformNamesToValue.clear();
+ // // Update only update properties if uboNeedsUpdate is true, otherwise update the whole block
+ // m_data->m_uniformBlockBuilder.updatedPropertiesOnly = uboNeedsUpdate;
+ // // Retrieve names and description of each active uniforms in the uniform block
+ // m_data->m_uniformBlockBuilder.uniforms = shader->activeUniformsForUniformBlock(block.m_index);
+ // // Builds the name-value map for the block
+ // m_data->m_uniformBlockBuilder.buildActiveUniformNameValueMapStructHelper(shaderData, block.m_name);
+ // if (!uboNeedsUpdate)
+ // shaderData->markDirty();
+ // // copy the name-value map into the BlockToUBO
+ // uniformBlockUBO.m_updatedProperties = m_data->m_uniformBlockBuilder.activeUniformNamesToValue;
+ // uboNeedsUpdate = true;
+ // }
+
+ // uniformBlockUBO.m_needsUpdate = uboNeedsUpdate;
+ // uniformPack.setUniformBuffer(uniformBlockUBO);
}
}
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 19415d0b8..ad13b2812 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -80,30 +80,20 @@ static QHash<unsigned int, GraphicsContext*> static_contexts;
namespace {
-QOpenGLBuffer createGLBufferFor(Buffer *buffer)
+GLBuffer::Type bufferTypeToGLBufferType(QBuffer::BufferType type)
{
- QOpenGLBuffer b(static_cast<QOpenGLBuffer::Type>(buffer->type()));
- b.setUsagePattern(static_cast<QOpenGLBuffer::UsagePattern>(buffer->usage()));
- if (!b.create())
- qCWarning(Render::Io) << Q_FUNC_INFO << "buffer creation failed";
-
- if (!b.bind())
- qCWarning(Render::Io) << Q_FUNC_INFO << "buffer binding failed";
-
- b.allocate(buffer->data().constData(), buffer->data().size());
- return b;
-}
-
-void uploadDataToGLBuffer(Buffer *buffer, QOpenGLBuffer &b, bool releaseBuffer = false)
-{
- if (!b.bind())
- qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed";
- const int bufferSize = buffer->data().size();
- b.allocate(NULL, bufferSize); // orphan the buffer
- b.allocate(buffer->data().constData(), bufferSize);
- if (releaseBuffer)
- b.release();
- qCDebug(Render::Io) << "uploaded buffer size=" << buffer->data().size();
+ switch (type) {
+ case QBuffer::VertexBuffer:
+ return GLBuffer::ArrayBuffer;
+ case QBuffer::IndexBuffer:
+ return GLBuffer::IndexBuffer;
+ case QBuffer::PixelPackBuffer:
+ return GLBuffer::PixelPackBuffer;
+ case QBuffer::PixelUnpackBuffer:
+ return GLBuffer::PixelUnpackBuffer;
+ default:
+ Q_UNREACHABLE();
+ }
}
} // anonymous
@@ -487,11 +477,6 @@ void GraphicsContext::setActiveMaterial(Material *rmat)
m_material = rmat;
}
-// TO DO : Try to move what's in Renderer here
-void GraphicsContext::executeCommand(const RenderCommand *)
-{
-}
-
int GraphicsContext::activateTexture(TextureScope scope, Texture *tex, int onUnit)
{
// Returns the texture unit to use for the texture
@@ -890,53 +875,56 @@ void GraphicsContext::setUniforms(QUniformPack &uniforms)
const QVector<BlockToUBO> &blockToUbos = uniforms.uniformBuffers();
GLBuffer *ubo = Q_NULLPTR;
bool needsToUnbindUBO = false;
- for (int i = 0; i < blockToUbos.length(); ++i) {
- const ShaderUniformBlock &block = m_activeShader->uniformBlock(blockToUbos[i].m_blockIndex);
- if (block.m_index != -1 && block.m_size > 0) {
- ubo = manager->lookupResource<GLBuffer, GLBufferManager>(BufferShaderKey(blockToUbos[i].m_shaderDataID,
- m_activeShader->peerUuid()));
- // bind Uniform Block of index ubos[i].m_index to binding point i
- bindUniformBlock(m_activeShader->getOrCreateProgram(this)->programId(), block.m_index, i);
- // bind the UBO to the binding point i
- // Specs specify that there are at least 14 binding points
-
- // Allocate ubo if not allocated previously
- if (!ubo->isCreated()) {
- ubo->create(this);
- ubo->bind(this, GLBuffer::UniformBuffer);
- ubo->allocate(this, block.m_size);
- }
- // update the ubo if needed
-
- // TO DO: Maybe QShaderData should act as a QBuffer data provider
- // and internally update a QBuffer which we would then reupload
- // and the ShaderData updates could then be done in some jobs
- // rather than at render time ?
- if (blockToUbos[i].m_needsUpdate) {
- if (!ubo->isBound())
- ubo->bind(this, GLBuffer::UniformBuffer);
- needsToUnbindUBO |= true;
- const QHash<QString, ShaderUniform> &activeUniformsInBlock = m_activeShader->activeUniformsForUniformBlock(block.m_index);
- const QHash<QString, ShaderUniform>::const_iterator uniformsEnd = activeUniformsInBlock.end();
- QHash<QString, ShaderUniform>::const_iterator uniformsIt = activeUniformsInBlock.begin();
-
- while (uniformsIt != uniformsEnd) {
- if (blockToUbos[i].m_updatedProperties.contains(uniformsIt.key())) {
- buildUniformBuffer(blockToUbos[i].m_updatedProperties.value(uniformsIt.key()),
- uniformsIt.value(),
- m_uboTempArray);
- ubo->update(this, m_uboTempArray.constData() + uniformsIt.value().m_offset,
- uniformsIt.value().m_rawByteSize,
- uniformsIt.value().m_offset);
- }
- ++uniformsIt;
- }
- }
- // bind UBO to binding point
- ubo->bindToUniformBlock(this, i);
- }
- }
+ // TEMPORARLY Disabled
+
+ // for (int i = 0; i < blockToUbos.length(); ++i) {
+ // const ShaderUniformBlock &block = m_activeShader->uniformBlock(blockToUbos[i].m_blockIndex);
+ // if (block.m_index != -1 && block.m_size > 0) {
+ // ubo = manager->lookupResource<GLBuffer, GLBufferManager>(BufferShaderKey(blockToUbos[i].m_shaderDataID,
+ // m_activeShader->peerUuid()));
+ // // bind Uniform Block of index ubos[i].m_index to binding point i
+ // bindUniformBlock(m_activeShader->getOrCreateProgram(this)->programId(), block.m_index, i);
+ // // bind the UBO to the binding point i
+ // // Specs specify that there are at least 14 binding points
+
+ // // Allocate ubo if not allocated previously
+ // if (!ubo->isCreated()) {
+ // ubo->create(this);
+ // ubo->bind(this, GLBuffer::UniformBuffer);
+ // ubo->allocate(this, block.m_size);
+ // }
+
+ // // update the ubo if needed
+
+ // // TO DO: Maybe QShaderData should act as a QBuffer data provider
+ // // and internally update a QBuffer which we would then reupload
+ // // and the ShaderData updates could then be done in some jobs
+ // // rather than at render time ?
+ // if (blockToUbos[i].m_needsUpdate) {
+ // if (!ubo->isBound())
+ // ubo->bind(this, GLBuffer::UniformBuffer);
+ // needsToUnbindUBO |= true;
+ // const QHash<QString, ShaderUniform> &activeUniformsInBlock = m_activeShader->activeUniformsForUniformBlock(block.m_index);
+ // const QHash<QString, ShaderUniform>::const_iterator uniformsEnd = activeUniformsInBlock.end();
+ // QHash<QString, ShaderUniform>::const_iterator uniformsIt = activeUniformsInBlock.begin();
+
+ // while (uniformsIt != uniformsEnd) {
+ // if (blockToUbos[i].m_updatedProperties.contains(uniformsIt.key())) {
+ // buildUniformBuffer(blockToUbos[i].m_updatedProperties.value(uniformsIt.key()),
+ // uniformsIt.value(),
+ // m_uboTempArray);
+ // ubo->update(this, m_uboTempArray.constData() + uniformsIt.value().m_offset,
+ // uniformsIt.value().m_rawByteSize,
+ // uniformsIt.value().m_offset);
+ // }
+ // ++uniformsIt;
+ // }
+ // }
+ // // bind UBO to binding point
+ // ubo->bindToUniformBlock(this, i);
+ // }
+ // }
if (needsToUnbindUBO)
ubo->release(this);
@@ -950,8 +938,9 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute, Buffer *buffe
if (attribute == Q_NULLPTR || buffer == Q_NULLPTR)
return;
- QOpenGLBuffer buf = glBufferForRenderBuffer(buffer);
- buf.bind();
+ GLBuffer *buf = glBufferForRenderBuffer(buffer);
+ buf->bind(this, bufferTypeToGLBufferType(buffer->type()));
+ // bound within the current VAO
QOpenGLShaderProgram* prog = activeShader();
int location = prog->attributeLocation(shaderName);
@@ -976,8 +965,8 @@ void GraphicsContext::specifyIndices(Buffer *buffer)
{
Q_ASSERT(buffer->type() == QBuffer::IndexBuffer);
- QOpenGLBuffer buf = glBufferForRenderBuffer(buffer);
- if (!buf.bind())
+ GLBuffer *buf = glBufferForRenderBuffer(buffer);
+ if (!buf->bind(this, GLBuffer::IndexBuffer))
qCWarning(Backend) << Q_FUNC_INFO << "binding index buffer failed";
// bound within the current VAO
@@ -985,19 +974,45 @@ void GraphicsContext::specifyIndices(Buffer *buffer)
void GraphicsContext::updateBuffer(Buffer *buffer)
{
- const QHash<Buffer *, QOpenGLBuffer>::iterator it = m_renderBufferHash.find(buffer);
+ const QHash<Qt3DCore::QNodeId, HGLBuffer>::iterator it = m_renderBufferHash.find(buffer->peerUuid());
if (it != m_renderBufferHash.end())
- uploadDataToGLBuffer(buffer, it.value());
+ uploadDataToGLBuffer(buffer, m_renderer->nodeManagers()->glBufferManager()->data(it.value()));
}
-QOpenGLBuffer GraphicsContext::glBufferForRenderBuffer(Buffer *buf)
+GLBuffer *GraphicsContext::glBufferForRenderBuffer(Buffer *buf)
{
- if (m_renderBufferHash.contains(buf))
- return m_renderBufferHash.value(buf);
+ if (!m_renderBufferHash.contains(buf->peerUuid()))
+ m_renderBufferHash.insert(buf->peerUuid(), createGLBufferFor(buf));
+ return m_renderer->nodeManagers()->glBufferManager()->data(m_renderBufferHash.value(buf->peerUuid()));
+}
- QOpenGLBuffer glbuf = createGLBufferFor(buf);
- m_renderBufferHash.insert(buf, glbuf);
- return glbuf;
+HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer)
+{
+ GLBuffer *b = m_renderer->nodeManagers()->glBufferManager()->getOrCreateResource(buffer->peerUuid());
+ // b.setUsagePattern(static_cast<QOpenGLBuffer::UsagePattern>(buffer->usage()));
+ Q_ASSERT(b);
+ if (!b->create(this))
+ qCWarning(Render::Io) << Q_FUNC_INFO << "buffer creation failed";
+
+ if (!b->bind(this, 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->peerUuid());
+}
+
+void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer)
+{
+ if (!b->isBound() && !b->bind(this, bufferTypeToGLBufferType(buffer->type())))
+ qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed";
+ const int bufferSize = buffer->data().size();
+ // TO DO: Handle usage pattern and sub data updates
+ b->allocate(this, bufferSize, false); // orphan the buffer
+ b->allocate(this, buffer->data().constData(), bufferSize, false);
+ if (releaseBuffer)
+ b->release(this);
+ qCDebug(Render::Io) << "uploaded buffer size=" << buffer->data().size();
}
GLint GraphicsContext::elementType(GLint type)
diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h
index c377d237b..845beaf5b 100644
--- a/src/render/graphicshelpers/graphicscontext_p.h
+++ b/src/render/graphicshelpers/graphicscontext_p.h
@@ -51,7 +51,6 @@
#include <QOpenGLContext>
#include <QOpenGLFunctions>
-#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QHash>
#include <QColor>
@@ -61,6 +60,7 @@
#include <Qt3DRender/qclearbuffer.h>
#include <Qt3DRender/private/shader_p.h>
#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/private/handle_types_p.h>
QT_BEGIN_NAMESPACE
@@ -83,6 +83,7 @@ class RenderTarget;
class AttachmentPack;
class Attribute;
class Buffer;
+class GLBuffer;
enum TextureScope
{
@@ -151,8 +152,7 @@ public:
* @param buf
* @return
*/
- QOpenGLBuffer glBufferForRenderBuffer(Buffer *buf);
-
+ GLBuffer *glBufferForRenderBuffer(Buffer *buf);
/**
* @brief activateTexture - make a texture active on a hardware unit
@@ -218,6 +218,8 @@ private:
void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments);
void activateDrawBuffers(const AttachmentPack &attachments);
+ HGLBuffer createGLBufferFor(Buffer *buffer);
+ void uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer = false);
bool m_initialized;
const unsigned int m_id;
@@ -228,7 +230,7 @@ private:
Shader *m_activeShader;
QHash<ProgramDNA, Shader *> m_renderShaderHash;
- QHash<Buffer *, QOpenGLBuffer> m_renderBufferHash;
+ QHash<Qt3DCore::QNodeId, HGLBuffer> m_renderBufferHash;
QHash<Qt3DCore::QNodeId, GLuint> m_renderTargets;
QHash<GLuint, QSize> m_renderTargetsSize;
diff --git a/src/render/io/glbuffer.cpp b/src/render/io/glbuffer.cpp
index bff4cb3e4..8e7636964 100644
--- a/src/render/io/glbuffer.cpp
+++ b/src/render/io/glbuffer.cpp
@@ -86,23 +86,28 @@ GLBuffer::GLBuffer()
{
}
-void GLBuffer::bind(GraphicsContext *ctx, Type t)
+bool GLBuffer::bind(GraphicsContext *ctx, Type t)
{
+ if (m_bufferId == 0)
+ return false;
m_lastTarget = glBufferTypes[t];
ctx->openGLContext()->functions()->glBindBuffer(m_lastTarget, m_bufferId);
m_bound = true;
+ return true;
}
-void GLBuffer::release(GraphicsContext *ctx)
+bool GLBuffer::release(GraphicsContext *ctx)
{
m_bound = false;
ctx->openGLContext()->functions()->glBindBuffer(m_lastTarget, 0);
+ return true;
}
-void GLBuffer::create(GraphicsContext *ctx)
+bool GLBuffer::create(GraphicsContext *ctx)
{
ctx->openGLContext()->functions()->glGenBuffers(1, &m_bufferId);
m_isCreated = true;
+ return m_bufferId != 0;
}
void GLBuffer::destroy(GraphicsContext *ctx)
@@ -118,6 +123,11 @@ void GLBuffer::allocate(GraphicsContext *ctx, uint size, bool dynamic)
ctx->openGLContext()->functions()->glBufferData(m_lastTarget, size, NULL, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
}
+void GLBuffer::allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic)
+{
+ ctx->openGLContext()->functions()->glBufferData(m_lastTarget, size, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+}
+
void GLBuffer::update(GraphicsContext *ctx, const void *data, uint size, int offset)
{
ctx->openGLContext()->functions()->glBufferSubData(m_lastTarget, offset, size, data);
diff --git a/src/render/io/glbuffer_p.h b/src/render/io/glbuffer_p.h
index 9d47a52db..1dc8adb3c 100644
--- a/src/render/io/glbuffer_p.h
+++ b/src/render/io/glbuffer_p.h
@@ -59,8 +59,6 @@ namespace Render {
class GraphicsContext;
-typedef QPair<Qt3DCore::QNodeId, Qt3DCore::QNodeId> BufferShaderKey;
-
class GLBuffer
{
public:
@@ -76,11 +74,12 @@ public:
PixelUnpackBuffer
};
- void bind(GraphicsContext *ctx, Type t);
- void release(GraphicsContext *ctx);
- void create(GraphicsContext *ctx);
+ bool bind(GraphicsContext *ctx, Type t);
+ bool release(GraphicsContext *ctx);
+ bool create(GraphicsContext *ctx);
void destroy(GraphicsContext *ctx);
void allocate(GraphicsContext *ctx, uint size, bool dynamic = true);
+ void allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic = true);
void update(GraphicsContext *ctx, const void *data, uint size, int offset = 0);
void bindToUniformBlock(GraphicsContext *ctx, int bindingPoint);