cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

anothercoder
Adept I

glGenBuffers returns 0xffff0000 on first call

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

0 Likes
4 Replies
gsellers
Staff

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

0 Likes

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

0 Likes

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

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.

0 Likes