This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Mali-400 strange glDrawElements behavior question

Hi!

I am developing UI application for embedded system running on Mali-400 GPU.

So far I have stumbled with following strange behavior: glDrawElements works differently if called with

different parameters.

Scenario: 8 vertices, 12 indices describing 2 rectangles - dark grey and red above it.

  1. Variant 1:

     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);

     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (const GLushort*)(0) + 6);

     only dark gray triangle is drawn - where is the red triangle???

2. Variant 2:

     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const GLushort*)(0) + 6);

     only dark gray rectangle is drawn (which is expected) - but where is red triangle???

3. Variant 3:

     glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, (const GLushort*)(0));

     both dark and red rectangles are drawn (which is expected result)

Why second glDrawElements call in variants 1 and 2 does not produce anything on screen?

Is it something related to internal pipeline optimizations or am I completely missing something here?

I have checked the same code on another device which is running on PowerVR GPU - everything is

fine there, no questions, that is why I came here to Mali support forums.

Executing grep --binary-files=text REVISION libMali.so on libMali shows some entries of REVISION=467.

I was able to create a reproducible program (for Android) which demonstrates those cases.

All those described scenarios are in jniexports.c:render of attached archive (lines 261-276).

MyApplication.tar.gz
Parents
  • I have found very interesting solution to the problem: if after first call to glDrawElements reset array and element buffers bindings to 0 and after that bind it back again everything works like a charm, i.e.:

                glBindBuffer(GL_ARRAY_BUFFER, vbo);

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); // this draws first rectangle (dark grey)

                // Bind buffers reset trick - first unbind current buffers

                glBindBuffer(GL_ARRAY_BUFFER, 0);

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

                // And restore binding again

                glBindBuffer(GL_ARRAY_BUFFER, vbo);

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const GLushort*)(0) + 6);  // and this works too after glBindBuffer back and forth and draws the second rectangle (red)

    So my assumption here is that libMali makes some optimizations when calling glDrawElements and draws bound at the time of call vertex/element buffer only once. That is why resetting buffers between the calls make second call with the same buffer work.

    I would like to hear some more explanations from community or from Mali development side. First off, what are performance implications when doing such a trick and whether it is possible to do it in some other way.

Reply
  • I have found very interesting solution to the problem: if after first call to glDrawElements reset array and element buffers bindings to 0 and after that bind it back again everything works like a charm, i.e.:

                glBindBuffer(GL_ARRAY_BUFFER, vbo);

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); // this draws first rectangle (dark grey)

                // Bind buffers reset trick - first unbind current buffers

                glBindBuffer(GL_ARRAY_BUFFER, 0);

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

                // And restore binding again

                glBindBuffer(GL_ARRAY_BUFFER, vbo);

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const GLushort*)(0) + 6);  // and this works too after glBindBuffer back and forth and draws the second rectangle (red)

    So my assumption here is that libMali makes some optimizations when calling glDrawElements and draws bound at the time of call vertex/element buffer only once. That is why resetting buffers between the calls make second call with the same buffer work.

    I would like to hear some more explanations from community or from Mali development side. First off, what are performance implications when doing such a trick and whether it is possible to do it in some other way.

Children
No data