From 8fb6916ee438b2068645c24d861e8cbfad84718d Mon Sep 17 00:00:00 2001 From: Hatem ElKharashy Date: Mon, 24 Jan 2022 15:07:01 +0200 Subject: Fix indices alignment problem The buffer that holds the data is now 4 byte aligned in case of the usage of shared buffer for vertices and indices. Fixes: QTBUG-83315 Change-Id: I8b1c11c7cf0d4ca052fbaaa749828d28589fc297 Reviewed-by: Laszlo Agocs --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index a749e1c92b..a6c07d5964 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -2215,6 +2215,15 @@ void Renderer::uploadBatch(Batch *b) */ int bufferSize = b->vertexCount * g->sizeOfVertex(); int ibufferSize = 0; + // At this point, we need to check if the vertices byte size is 4 byte aligned or not. + // If an unaligned value is used in a shared buffer with indices, it causes problems with + // glDrawElements. We need to do a 4 byte alignment so that it can work with both + // QSGGeometry::UnsignedShortType and QSGGeometry::UnsignedIntType + int paddingBytes = 0; + if (!m_context->separateIndexBuffer()) { + paddingBytes = aligned(bufferSize, 4) - bufferSize; + bufferSize += paddingBytes; + } if (b->merged) { ibufferSize = b->indexCount * mergedIndexElemSize(); if (m_useDepthBuffer) @@ -2239,7 +2248,7 @@ void Renderer::uploadBatch(Batch *b) char *zData = vertexData + b->vertexCount * g->sizeOfVertex(); char *indexData = separateIndexBuffer ? b->ibo.data - : zData + (int(m_useDepthBuffer) * b->vertexCount * sizeof(float)); + : zData + (int(m_useDepthBuffer) * b->vertexCount * sizeof(float)) + paddingBytes; quint16 iOffset16 = 0; quint32 iOffset32 = 0; @@ -2287,7 +2296,7 @@ void Renderer::uploadBatch(Batch *b) } else { char *vboData = b->vbo.data; char *iboData = separateIndexBuffer ? b->ibo.data - : vboData + b->vertexCount * g->sizeOfVertex(); + : vboData + b->vertexCount * g->sizeOfVertex() + paddingBytes; Element *e = b->first; while (e) { QSGGeometry *g = e->node->geometry(); @@ -3176,8 +3185,14 @@ void Renderer::renderUnmergedBatch(const Batch *batch) // legacy (GL-only) int vOffset = 0; char *iOffset = indexBase; + // If a shared buffer is used, 4 byte alignment was done to avoid issues + // while using glDrawElements with both QSGGeometry::UnsignedShortType and + // QSGGeometry::UnsignedIntType. Here, we need to take this into account + // while calculating iOffset value to end up with the correct offset for drawing. + int vertexDataByteSize = batch->vertexCount * gn->geometry()->sizeOfVertex(); + vertexDataByteSize = aligned(vertexDataByteSize, 4); if (!separateIndexBuffer) - iOffset += batch->vertexCount * gn->geometry()->sizeOfVertex(); + iOffset += vertexDataByteSize; QMatrix4x4 rootMatrix = batch->root ? qsg_matrixForRoot(batch->root) : QMatrix4x4(); -- cgit v1.2.3