11 Replies Latest reply on Mar 31, 2016 6:15 AM by dwitczak

    glDrawArrays random crash only happening on AMD

    therealnox

      I've just realised that my application is crashing on a AMD GPU.

      I have been investigating and the only thing that I am sure of is that this only happens on AMD GPU and always on the same function: glDrawArrays.

       

      I am on Windows 10 (1510) x64, using a R9 380.
      I am developing under Visual Studio 2013, with an openGL Core Profile 4.0 (used through Qt 5.5.1 wrapper).

      My openGL using VAO/VBO, FBO and RBO for offscreen rendering and subroutines if that helps.

       

      I have check using gDEBugger but nothing showed up on the output, even with the openGL Debug Logger...

       

      The exception is coming from atio6axx.dll.

       

      From there, I can only tell it's either a driver issue (very unlikely) or it's a openGL state issue. I am already aware that NVidia implementation of openGL is more permissive but still, that shouldn't crash like that.

      Maybe it's my VAO/VBO setup that is problematic but I can't seems to find anything.

       

      I've already been through the full "Common mistakes" wiki page from openGL but no success...

       

      Thanks guys!

        • Re: glDrawArrays random crash only happening on AMD
          deedeeyelverton

          I've added you to the developer white list and moved this message to the OpenGL forum.

          • Re: glDrawArrays random crash only happening on AMD
            therealnox

            Ok, so looks like I narrow it down to one function:
            DrvPresentBuffers (- N/A - N/A - C:\Windows\SYSTEM32\atio6axx.dll - 0x00000000661ac870 -)

            Does anyone here know the purpose of that little guy here? Or at least, what kind of buffer that might be (PBO, FBO, VAO, VBO, etc.) ?

            • Re: glDrawArrays random crash only happening on AMD
              therealnox

              Sweet, it seems to be a driver issue, nothing to do with my code.
              If anyone at AMD wants to find out what is going on, you are welcome to contact me and I will provide source code and what exactly I am doing in my app.

              • Re: glDrawArrays random crash only happening on AMD
                cgrant78@netzero.com

                You do realize that client side issue, such as incorrectly sized/invalid buffer etc..will end up crashing inside the driver when it goes to use the said resource. Crashing in the driver does NOT necessarily make it a driver bug. Ex. If I allocated a buffer to store 3 vertices for a triangle and then try to draw 3 triangles, the driver will try to access memory out of bounds and will most likely cause a crash. This would not be a driver bug..In either case, you have not given enough details for anyone to really make any suggestion. You said you are using gDebugger, that tools is a little bit long in the tooth and AMD has more update debugging tools available. Try CodeXL with break on all errors and see if that helps.

                  • Re: glDrawArrays random crash only happening on AMD
                    therealnox

                    Thanks for the reply cgrant78.
                    I am aware that if I made a mistake within my client side memory code, it will crash there as well.
                    I am only suggesting a driver issue because it is only crashing randomly after some time (from like 200 frames rendered to sometimes 300000 frames rendered without any issue) and I am not changing any geometry, my VAO and VBOs remain the same all the time.

                    In the case you are explaining, I would have a crash every time I am out of bounds, right?
                    Also, thanks for the tips about CodeXl, this is actually the tool I have been using for like 3 weeks now. Really great tool, and it has allowed me to debug and find a lot more infos.
                    As for not giving details, I need to remove all the proprietary code own by my company first. And I am also using Qt, which I will remove and replace by pure openGL function to avoid confusion.
                    I am rendering always 2 triangles with a texture on it.

                    So I have a main VAO containing 3 VBO, 1 with my vertices, one with my main textures coordinates and one with a watermark texture coord.
                    Here is where I could have mess the number and create a buffer overflow (only showing one of the init for now):

                    //INIT
                      this->_VAOandVBO.mainVAO->create(); 
                    this->_VAOandVBO.mainVAO->bind(); 
                     this->_VAOandVBO.verticeVBO->create(); 
                    this->_VAOandVBO.verticeVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
                     this->_VAOandVBO.verticeVBO->bind(); 
                     this->_VAOandVBO.vertices = new float[12];
                     this->_VAOandVBO.vertices[0] = -1.0f;
                     this->_VAOandVBO.vertices[1] = -1.0f;
                      this->_VAOandVBO.vertices[2] = -1.0f;
                     this->_VAOandVBO.vertices[3] = 1.0f; 
                     this->_VAOandVBO.vertices[4] = 1.0f;
                     this->_VAOandVBO.vertices[5] = 1.0f; 
                     this->_VAOandVBO.vertices[6] = -1.0f; 
                    this->_VAOandVBO.vertices[7] = -1.0f; 
                     this->_VAOandVBO.vertices[8] = 1.0f;
                     this->_VAOandVBO.vertices[9] = 1.0f; 
                     this->_VAOandVBO.vertices[10] = 1.0f; 
                    this->_VAOandVBO.vertices[11] = -1.0f;
                      this->_VAOandVBO.verticeVBO->allocate(this->_VAOandVBO.vertices, 6 * 2 * sizeof(float));
                      this->_shaderProgram->bind();
                     glEnableVertexAttribArray(this->_locVertices);
                     glVertexAttribPointer(this->_locVertices, 2, GL_FLOAT, GL_TRUE, 0, 0);
                     this->_shaderProgram->release();
                     this->_VAOandVBO.verticeVBO->release();
                     this->_VAOandVBO.mainVAO->release(); 
                    [...]  
                    
                    //DRAW
                     this->_shaderProgram->bind();
                      this->_VAOandVBO.mainVAO->bind(); 
                     glActiveTexture(GL_TEXTURE0);
                      glBindTexture(GL_TEXTURE_2D, this->_textureID[0]); 
                     glDrawArrays(GL_TRIANGLES, 0, 6);
                      glBindTexture(GL_TEXTURE_2D, 0); 
                    this->_VAOandVBO.mainVAO->release();
                     this->_shaderProgram->release();
                    


                    Hope you might find something odd. In the meantime, I'll try to switch to glDrawElements.

                  • Re: glDrawArrays random crash only happening on AMD
                    dutta

                    I had the same issue trying to use subroutines together with uniform buffers. For some reason, reading uniform buffer values inside a subroutine or submitting one as an argument to a subroutine would cause a crash after some time.  The time seemed random. Removing the subroutines, which in my case involved generating new shaders based on the different set of subroutines, resolved the issue entirely, and the access violation disappeared.

                     

                    Have in mind this was some months ago and since then I haven't tested subroutines again. And the access violation I was seeing was always in the atioglxx.dll.

                      • Re: glDrawArrays random crash only happening on AMD
                        therealnox

                        Thanks for the feedback.

                        I do have a few subroutines yes but my crash occurs inside the atio6xx.dll not the one you are specifying. Is actually the one you meant to write maybe?
                        I am currently switching from glDrawArrays to glDrawElements just to see if it is still there or not. If it is, I will be 100% sure it is within my code.

                         

                        EDIT:
                        I have just found your post and realized I already found it before and click on "I have the same question".
                        Would you mind sharing how you were settings your subroutines in order for me to find any similitude?
                        Also, maybe the order of setting up thing is important. in My case I was doing my init in that order:

                        1. Init, link, compile my shaders
                        2. resolve shader locations (attribute and uniforms, except subroutines)
                        3. glUniform1i my uniforms
                        4. Init and set my VAO and VBO
                        5. Init my subroutines
                        6. Init my Textures

                        (when writing that down, I am actually wondering if I should glUniform1i with my VAO bind?) [EDIT2:] -< Nope, that was just my brain messing with me. Uniform are program related.

                          • Re: glDrawArrays random crash only happening on AMD
                            dutta

                            The way I found out was by a brute force find and eliminate method which took days before I found the culprit. I'm using a somewhat advanced game engine so shaders and resources don't have to be loaded in some specific order, and there is tons of other stuff going on.

                             

                            What are  you using the glUniform1i for? You also have to set the subroutines each time you run glUseProgram, because otherwise your subroutines won't be bound (if I remember it correctly).

                              • Re: glDrawArrays random crash only happening on AMD
                                therealnox

                                Ok,

                                I am using the glUniform1i to bind texture unit to my uniform sampler like that: this->glUniform1i(this->_locationsShader.locVideoFrame, GL_TEXTURE0);

                                And yes, every time you bind your shader program you have to set the subroutines, which I do like that:

                                this->glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, this->_subroutineShader.totalSubroutines, this->_defaultSubroutinesIndices); (defaultSubIndices is a arrayof GLunit which contains my default subroutines path).