From 6493b93b483d65862a22a480b3e72f2967c22f32 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 23 Nov 2020 12:50:48 +0100 Subject: RHI: Reset attribute instancing properly for OpenGL ES Enabling instanced drawing will set glVertexAttribDivisor to 1 for the PerInstance attributes. This is of course a persistent state, because GL, so it will apply to all subsequent draw calls that uses attributes with the same location number, introducing weird and wonderful randomness. Therefore, make sure we set the divisor back to 0 for non-instanced attributes. Change-Id: I2d9115369fa24e8d57396d2a5f88d1435fe98971 Reviewed-by: Laszlo Agocs --- src/gui/rhi/qrhigles2.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'src/gui/rhi') diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 3ebc0f9182..5db9ffb444 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2135,8 +2135,10 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) int binding = 0; } lastBindVertexBuffer; static const int TRACKED_ATTRIB_COUNT = 16; - bool enabledAttribArrays[TRACKED_ATTRIB_COUNT]; - memset(enabledAttribArrays, 0, sizeof(enabledAttribArrays)); + bool enabledAttribArrays[TRACKED_ATTRIB_COUNT] = {}; + bool nonzeroAttribDivisor[TRACKED_ATTRIB_COUNT] = {}; + bool instancedAttributesUsed = false; + int maxUntrackedInstancedAttribute = 0; for (auto it = cbD->commands.cbegin(), end = cbD->commands.cend(); it != end; ++it) { const QGles2CommandBuffer::Command &cmd(*it); @@ -2304,8 +2306,19 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) enabledAttribArrays[locationIdx] = true; f->glEnableVertexAttribArray(GLuint(locationIdx)); } - if (inputBinding->classification() == QRhiVertexInputBinding::PerInstance && caps.instancing) + if (inputBinding->classification() == QRhiVertexInputBinding::PerInstance && caps.instancing) { f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(inputBinding->instanceStepRate())); + if (Q_LIKELY(locationIdx < TRACKED_ATTRIB_COUNT)) + nonzeroAttribDivisor[locationIdx] = true; + else + maxUntrackedInstancedAttribute = qMax(maxUntrackedInstancedAttribute, locationIdx); + instancedAttributesUsed = true; + } else if ((locationIdx < TRACKED_ATTRIB_COUNT && nonzeroAttribDivisor[locationIdx]) + || Q_UNLIKELY(locationIdx >= TRACKED_ATTRIB_COUNT && locationIdx <= maxUntrackedInstancedAttribute)) { + f->glVertexAttribDivisor(GLuint(locationIdx), 0); + if (locationIdx < TRACKED_ATTRIB_COUNT) + nonzeroAttribDivisor[locationIdx] = false; + } } } else { qWarning("No graphics pipeline active for setVertexInput; ignored"); @@ -2623,6 +2636,14 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) break; } } + if (instancedAttributesUsed) { + for (int i = 0; i < TRACKED_ATTRIB_COUNT; ++i) { + if (nonzeroAttribDivisor[i]) + f->glVertexAttribDivisor(GLuint(i), 0); + } + for (int i = TRACKED_ATTRIB_COUNT; i <= maxUntrackedInstancedAttribute; ++i) + f->glVertexAttribDivisor(GLuint(i), 0); + } } void QRhiGles2::executeBindGraphicsPipeline(QGles2CommandBuffer *cbD, QGles2GraphicsPipeline *psD) -- cgit v1.2.3