Using glTexImage2D with null data

Hi,

I am using glTexImage2D to allocate texture memory, then later specifying the image with glTexSubImage2D, as we discussed a while back. Everything has been working fine, except I’ve discovered some INVALID_OPERATION errors I cannot explain. Consider:


glGenTextures(1,&name);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,name);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,8192,4096,0,GL_RGB,GL_UNSIGNED_BYTE,0x0000);
glBindTexture(GL_TEXTURE_2D,name);

Here, glTexImage2D is used to allocate texture memory, but it makes the last call to glBindTexture generate INVALID_OPERATION. Likewise, when glTexSubImage2D is called later (using PBO), it also generates INVALID_OPERATION:


glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,buffer);
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,8192,4096,GL_BGRA,GL_UNSIGNED_BYTE,0x0000);

The funny thing is everything appears to work, even though I get these INVALID_OPERATION errors on both NVIDIA and ATI. The only thing I can think of is the texture is in an incomplete state or I somehow change the dimensionality with glTexImage2D. But then how does one use glTexImage2D to just allocate texture memory?

I’ve also tried with much smaller textures. I’m sure I’m overlooking something.

Regards,
Patrick

Yes, the texture is incomplete since you defined only one mipmap level.
Call glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) before glTexImage2D(…, NULL)

Funny, I actually have calls to glTexParameteri right after glTexImage2D. I moved them to before as you suggested:


glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,8192,4096,0,GL_RGB,GL_UNSIGNED_BYTE,0x0000);

But I still get the same GL errors. Any other ideas?

Also, slightly off topic, but does glGenerateMipmap require a call be made for each level to glTexImage2D beforehand, or just one glTexImage2D call for the base level? I’ve seen examples doing both.

Thanks,
Patrick

For glGenerateMipmap it is enough to specify the base level as the other mip sizes are derived from it.

That is what I thought. Thanks!

Patrick

is the GL context current when you allocate the texture?

@Patrick
I think the code fragment is too small to see the problem.
The code is OK (even with incomplete texture) and glBindTexture should not produce this kind of error. (see OGL man page).

Yeap. The calls are basically back to back in this case.

I was trying to keep my post short, but perhaps I am hiding the problem by doing so. Here is more output from GLIntercept:

// Create and upload PBO
glGenBuffers(1,0x2c1acbc)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,3)
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,134217728,0x0000,GL_STREAM_DRAW)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,3)
glBufferSubData(GL_PIXEL_UNPACK_BUFFER_ARB,0,134217728,0x200f0000)

// Create texture
glGenTextures(1,0x35ef0c)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D,1)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE)
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,8192,4096,0,GL_RGB,GL_UNSIGNED_BYTE,0x0000)

// This next line generates INVALID_OPERATION
glBindTexture(GL_TEXTURE_2D,1)

// The call to glTexSubImage2D below also generates INVALID_OPERATION
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,3)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D,1)
glPixelStorei(GL_UNPACK_ALIGNMENT,4)
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,8192,4096,GL_BGRA,GL_UNSIGNED_BYTE,0x0000)

I am using GL 3.3 core profile. Again, even with the errors, everything works just fine on a variety of NVIDIA and ATI cards. Let me know if there’s any other info I can provide.

Thanks for all the input!

Patrick

The issue is that you have a PBO attached while you call glTexImage2D.
While calling glTexImage2D with NULL sent as data indicates to the GL that it should not expect any actual pixel data, in case you have a PBO bound then NULL is also a valid pointer, a pointer to the beginning of the PBO and the error is raised because the PBO is not large enough to contain the whole data needed by your glTexImage2D call.
What you have to do is bind 0 to the current unpack PBO and then no error will be raised.

Not true, see line glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0) after glGenTextures

Ahh, I missed that part, sorry.
I just wanted soo bad to figure out what’s going on with this one.

lol. You and me both.

Patrick

no other unpack states set?
is this error thrown if you pass in a valid pointer in the glTexImage2D call? is it definitely just because of the null pointer?

btw, looks like a nice blog. I’ll have a read.

mmm, so far so advert-for-a-book. <disappointed>

No, these are some of the first GL calls in the application.

Good question. It happens with or without a null pointer. Strangely, I can narrow it down to this:


glGenTextures(1,0x3f9ea4c)
glBindTexture(GL_TEXTURE_2D,1)
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,4,4,0,GL_RGB,GL_UNSIGNED_BYTE,0x1445c48)
glBindTexture(GL_TEXTURE_2D,1) // GL_INVALID_OPERATION

I changed the size of the texture to just 4x4 and am providing non-null data, which I’ve confirmed is uploaded to the texture despite the GL_INVALID_OPERATION. I wonder if issuing a draw call before the second glBindTexture would “fix” it.

At this point, I’m mostly using the blog for news and progress updates for my book. As you can imagine, I am swamped with finishing the manuscript so I haven’t written much else on the blog. One day soon, I promise. I’m almost done! :slight_smile:

Regards,
Patrick

I have no idea at all what’s causing this. I’ve pasted your GL code into a simple GLUT app and a simple app using my own WGL setup code…and glGetError() always reports GL_NO_ERROR.
Are you only getting this error through GLintercept? or through your own asserts?
It’s really annoying me for some reason.

I am using GLintercept.

I just ran without GLintercept, and added a glGetError after the offending glBindTexture, and it returned GL_NO_ERROR. I also checked the offending glTexSubImage2D call, and it did not generate an error. Sounds like it could be an issue with GLintercept.

I am using C# and OpenTK, but I haven’t had false reports from GLintercept before. If GLintercept is still being maintained, I’ll let them know of the potential issue. Now I know to verify things with my own glGetError calls.

If you are still curious, I can provide the full GLintercept report or even the application’s source code. For my purposes, I suppose I am satisfied though.

Thanks!
Patrick

Oh Peter. Deary deary me.
if i remember rightly, glintercept outputs images to the xml log of each texture you bind. It’s probably using glGetTexImage under the hood, which is probably what’s causing the GL error flag to be set.

I bet you are right. Even a call to glDeleteTextures right after glTexImage2D reports an invalid operation. I’m not quite sure why glGetTexImage would generate the error though. I even tried explicitly setting the GL_PIXEL_PACK_BUFFER target to zero.

At this point, I’m ok with moving on. Good eye.

Regards,
Patrick