7 Replies Latest reply on Oct 10, 2018 9:23 PM by xhuang

    OpenGL (v4.3) vertex_attrib_binding problem with AMD R5

    tom_vrx

      Hi,

      I'm a senior developer and have been working with OpenGL for almost two decades now.

      I recently bought a laptop with AMD A9 9420 (integrated Radeon R530).

      The installed driver on Windows 10 64 bit is: Adrenalin Edition 18.8.1 (18.30.01.01 RC5), atiglpxx.dll version 8.14.01.6564

       

      I've noticed a problem with OpenGL 4.3 feature ARB_vertex_attrib_binding (VAB), when used with a single vertex array object (VAO).

      In my minimal example I'm drawing with two programs configuring the VAB for each draw, but reusing the same VAO and the problem manifests itself as driver not honoring the set VAB config, specifically glVertexAttribBinding and/or glBindVertexBuffer.

       

      Initial VAO/VAB config is done like this:

      glBindVertexArray(d->vao); // VAO has an element array bound for drawing single quad
      
      // shaderA uses 2 vertex attrib inputs (VA idx 1, 2 - vert and col) coming from vbo0 at vertex binding index 0
      
      // shaderB uses 2 vertex attrib inputs (VA idx 1, 2 - vert and col) coming from vbo1 at vertex binding index 1
      // shaderB uses 1 vertex array input (VA idx 0 - integer index) coming from vbo2 at vertex binding index 2
      
      glEnableVertexAttribArray(0);
      glEnableVertexAttribArray(1);
      glEnableVertexAttribArray(2);
      
      // this vert input and VAB index is used with shaderB
      glVertexAttribIFormat(0, 4, GL_UNSIGNED_BYTE, 0);   // VA 0 is integer vbo3
      glVertexAttribBinding(0, 2);                        // it goes to VAB index 2
      glBindVertexBuffer(2, d->vbos[2], 0, 4);            // and it sources from vbo2
      
      // these inputs are used with both shaderA and shaderB
      glVertexAttribFormat(1, 4, GL_FLOAT, 0, 0);         // VA 1 is float vec4 vert
      glVertexAttribFormat(2, 4, GL_FLOAT, 0, 16);        // VA 2 is float vec4 col
      glVertexAttribBinding(1, 0);                        // it goes to VAB index 0. initially
      glVertexAttribBinding(2, 0);                        // it goes to VAB index 0. initially
      glBindVertexBuffer(0, d->vbos[0], 0, 32);           // and it sources from vbo0 (for shaderA, and from vbo1 for shaderB)
      
      // we will render with shaderA first, which doesn't need vertex attrib 0
      glDisableVertexAttribArray(0);
      

       

       

      Frame drawing looks like this:

      glClear(GL_COLOR_BUFFER_BIT);
      
      // both shaders use the same VAO and it's already bound
      
      
      // shaderA uses 2 vertex attrib inputs (VA idx 1, 2 - vert and col) coming from vbo0 at vertex binding index 0
      glDisableVertexAttribArray(0);
      glVertexAttribBinding(1, 0);
      glVertexAttribBinding(2, 0);
      glBindVertexBuffer(0, d->vbos[0], 0, 32);
      
      glUseProgram(d->progA);
      glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
      
      
      
      // shaderB uses 2 vertex attrib inputs (VA idx 1, 2 - vert and col) coming from vbo1 at vertex binding index 1
      // shaderB uses 1 vertex array input (VA idx 0 - integer index) coming from vbo2 at vertex binding index 2
      glEnableVertexAttribArray(0);
      glVertexAttribBinding(0, 2);
      glVertexAttribBinding(1, 1);
      glVertexAttribBinding(2, 1);
      glBindVertexBuffer(2, d->vbos[2], 0, 4);
      glBindVertexBuffer(1, d->vbos[1], 0, 32);
      
      glUseProgram(d->progB);
      glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      

       

      This should draw two colored quads, but on my card it draws only one (the second draw in this minimal example, but in real life example it draws everything, but with wrong buffer bound in the later calls).

      I have managed to do a workaround in this minimal example by forcing VAO rebind before setting up VAB before every draw.

      If adding those, two quads are drawn as expected

      glBindVertexArray(0);
      glBindVertexArray(d->vao);
      // ... set up vertex attribs and VAB and do draw call 1
      
      glBindVertexArray(0);
      glBindVertexArray(d->vao);
      // ... set up vertex attribs and VAB and do draw call 2
      
      
      
      

       

      It seems to me that after issuing a draw call, VAO state gets somehow reused for the following draw calls, not honoring VAB calls which configure vertex attrib binding indexes.

      I have the full minimal example (with binaries, and all needed to build on Windows) attached here: