From 387a61adfb2c4e0ea2fd1c17f00c783e4bb6d3a0 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 1 Oct 2020 13:29:22 +0200 Subject: [PATCH] rhi: gl: Stop flooding with glVertexAttribPointers Artificial tests like the BechmarkDemo are full of drawing the exact same mesh multiple times in a row. These do not need respecifying anything related to vertex or index data. Also move the buffer binding out from the loop. Change-Id: I0f27a39fecebc7ca8e1fa635c63819f116867e19 Reviewed-by: Andy Nichols --- src/gui/rhi/qrhigles2.cpp | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index b57558889a..4c21804596 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2155,6 +2155,12 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) quint32 indexOffset = 0; GLuint currentArrayBuffer = 0; GLuint currentElementArrayBuffer = 0; + struct { + QRhiGraphicsPipeline *ps = nullptr; + GLuint buffer; + quint32 offset; + int binding; + } lastBindVertexBuffer; static const int TRACKED_ATTRIB_COUNT = 16; bool enabledAttribArrays[TRACKED_ATTRIB_COUNT]; memset(enabledAttribArrays, 0, sizeof(enabledAttribArrays)); @@ -2203,6 +2209,26 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) { QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.bindVertexBuffer.ps); if (psD) { + if (lastBindVertexBuffer.ps == psD + && lastBindVertexBuffer.buffer == cmd.args.bindVertexBuffer.buffer + && lastBindVertexBuffer.offset == cmd.args.bindVertexBuffer.offset + && lastBindVertexBuffer.binding == cmd.args.bindVertexBuffer.binding) + { + // The pipeline and so the vertex input layout is + // immutable, no point in issuing the exact same set of + // glVertexAttribPointer again and again for the same buffer. + break; + } + lastBindVertexBuffer.ps = psD; + lastBindVertexBuffer.buffer = cmd.args.bindVertexBuffer.buffer; + lastBindVertexBuffer.offset = cmd.args.bindVertexBuffer.offset; + lastBindVertexBuffer.binding = cmd.args.bindVertexBuffer.binding; + + if (cmd.args.bindVertexBuffer.buffer != currentArrayBuffer) { + currentArrayBuffer = cmd.args.bindVertexBuffer.buffer; + // we do not support more than one vertex buffer + f->glBindBuffer(GL_ARRAY_BUFFER, currentArrayBuffer); + } for (auto it = psD->m_vertexInputLayout.cbeginAttributes(), itEnd = psD->m_vertexInputLayout.cendAttributes(); it != itEnd; ++it) { @@ -2210,12 +2236,6 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) if (bindingIdx != cmd.args.bindVertexBuffer.binding) continue; - if (cmd.args.bindVertexBuffer.buffer != currentArrayBuffer) { - currentArrayBuffer = cmd.args.bindVertexBuffer.buffer; - // we do not support more than one vertex buffer - f->glBindBuffer(GL_ARRAY_BUFFER, currentArrayBuffer); - } - const QRhiVertexInputBinding *inputBinding = psD->m_vertexInputLayout.bindingAt(bindingIdx); const int stride = int(inputBinding->stride()); int size = 1;