4 Replies Latest reply on Aug 29, 2012 2:57 PM by anothercoder

    glGenBuffers returns 0xffff0000 on first call

    anothercoder

      Using Catalyst 12.8 on a 7850 (also tested on 12.8 on a 6470M in my laptop)

       

      The first call to glGenBuffers returns 0xFFFF0000.

       

      Here's a little code snippet to reproduce:

       

      // create GL context...

       

      // then

      GLuint dummy0 = 0;

      glGenBuffers(1,&dummy0);

      glBindBuffer(GL_ARRAY_BUFFER, dummy0);

      printf("glIsBuffer(0x%X)=%s\n", dummy0, (dummy0 > 0 && glIsBuffer(dummy0)) ? "Yes" : "No");

      glBindBuffer(GL_ARRAY_BUFFER, 0);

       

      GLuint dummy1 = 0;

      glGenBuffers(1,&dummy1);

      glBindBuffer(GL_ARRAY_BUFFER, dummy1);

      printf("glIsBuffer(0x%X)=%s\n", dummy1, (dummy1 > 0 && glIsBuffer(dummy1)) ? "Yes" : "No");

      glBindBuffer(GL_ARRAY_BUFFER, 0);

       

      The output (for me) is:

      glIsBuffer(0xFFFFF000)=Yes

      glIsBuffer(0x1)=Yes

       

      Seems like the driver recognizes the 0xFFFF0000 buffer as valid, but there may be an underlying issue why it assigns them this way.

       

      Thanks

        • Re: glGenBuffers returns 0xffff0000 on first call
          gsellers

          Hi,

           

          We've tried to reproduce this on internal driver builds but have been unable to, unfortunately. Also, the driver code responsible for the generation and management of object names hasn't changed in several months. We'll keep digging, but it's going to be difficult to find a fix without being able to reproduce the problem.

           

          Cheers,

           

          Graham

            • Re: glGenBuffers returns 0xffff0000 on first call
              anothercoder

              Hi Graham - Finally got around in looking this a bit more.

               

              First off, it was a bug in my code; Basically before creating a buffer using glGenBuffers I'm binding an invalid buffer in my GL state cache code. (I'm binding GL_INVALID_INDEX).

               

              However, there's still some inconsistencies.

               

              To reproduce this case use this code here (posted below).

               

              Case #1 is creating a buffer first, then binding an invalid buffer and the driver continues to assign buffers in the correct order.

               

              Case #2 however binds an invalid buffer first (0xdeadbeef), the next glGenBuffers will return 0xdeadb000, and all consecutive calls will assign buffers starting at 1.

               

               

              #if 0

                        { // Case #1

               

               

                                  // [Create GL context]

               

                                  GLuint dummy = 0;

                                  glGenBuffers(1, &dummy);

                                  printf("genBuffers=%X\n", dummy); // returns 1 - as expected

               

               

                                  glBindBuffer(GL_ARRAY_BUFFER, dummy); // bind valid buffer first...

                                  dummy = 0; glGenBuffers(1, &dummy); // create new buffer

                                  printf("genBuffers=%X\n", dummy); // returns 2 - still OK

               

                                  glBindBuffer(GL_ARRAY_BUFFER, 0xdeadbeef); // bind invalid buffer

                                  dummy = 0; glGenBuffers(1, &dummy); // create new buffer

                                  printf("genBuffers=%X\n", dummy);          // returns 3 - still OK

                        }

              #else

                        { // Case #2

               

               

                                  // [Create GL context]

               

               

                                  glBindBuffer(GL_ARRAY_BUFFER, 0xdeadbeef); // bind invalid buffer first...

               

                                  GLuint dummy = 0;

                                  glGenBuffers(1, &dummy);

                                  printf("genBuffers=%X\n", dummy); // returns != 1, in this case: 0xDEADB000

               

               

                                  dummy = 0; glGenBuffers(1, &dummy);

                                  printf("genBuffers=%X\n", dummy); // returns 1

                        }

              #endif

               

              Cheers

                • Re: glGenBuffers returns 0xffff0000 on first call
                  gsellers

                  I see.

                   

                  What you're doing here is relying on OpenGL's 'user generated names' feature. When you bind 0xDEADBEEF as a name, the driver generates an object with that name and gives it to you. I suppose because of the way we manage names internally (using hash tables and pools and all that goodness), we end up handing you back another buffer from a similar range before going back to 1. I can't say why we don't give you 0xDEADB001, 0xDEADB002 and so on, but ultimately, there's no spec requirement that we do.

                   

                  FWIW, you should always use glGenWhatevers() to generate names. A core profile context would enforce this and generate an error if you were to bind an invalid name. It would have caught your bug for you.

                   

                  It is my very strong recommendation that you always use a core profile context for any new application development. It will catch this kind of issue and will run faster. The compatibility profile is really only there for the maintenance of legacy applications. I'd also advise you to create a debug context during development as it will give you gobs of information about errors you might generate. Don't ship with it, though.

                   

                  Cheers,

                   

                  Graham

                    • Re: glGenBuffers returns 0xffff0000 on first call
                      anothercoder

                      Good stuff, thanks. As mentioned binding INVALID_INDEX was the bug on my end, and never intended. I'm caching these bind buffer calls and upon initializing my cache that one slipped in.

                       

                      Very interesting info about the different contexts you can choose, I wasn't aware of that and will look into setting one up for development builds.

                       

                      Cheers.