Rendering to the mipmap level of a texture - opengl

I want to write to a particular texture mipmap level. The problem is that OpenGL says "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT​" and "Framebuffer is not completed" if I don't generate the mipmaps before(glGenerateMipmap(GL_TEXTURE_2D);).
Generating the mipmaps before writing to them works, but it is an stupid performance cost since the automatically generated mipmap levels would never be used.
Is it possible to avoid this?
Note: I know that not writing directly to the levels and calling glGenerateMipmaps is faster, but I need to do this.

It seems like you simply did not create the storage for the mipmap level you tried to render to, glTexImage[n]D() does not do that - it only creates a storage for one single mipmap level. You need to separately creaet each mipmap level separately. glGenerateMipmaps does this implicitely. However, you only actually need a tiny bit of what it does, so it is better to avoid it here. Your best option is to create the mipmap chain from level 0 to the level you need manually.
With really modern GL, I would recommend you use immutable texures from GL_ARB_texture_storage. The glTexStorage() function allows creating the storage for all required mipmap levels in a single call. With immutable textures, you can still change the content any time, the only thing you can't is creating new data storage (with potentially different formats or sizes), so you can't repeatedly call glTexImage[n]D() on such texture object. However, you still can delete the whole object and create a new one, if the need arises.

Related

Supplying data to an immutable texture storage

Is there a way to directly (i.e., not a copy or a fill) supply data to a texture with immutable storage that isn't glTexSubImage*? I know there might not be an actual need for a separate function to fulfill this role, but I do wonder why you can't specify the data in the same line you allocate your memory (in the same manner as immutable buffer objects).
I do wonder why you can't specify the data in the same line you allocate your memory (in the same manner as immutable buffer objects).
Textures are far more complex than buffer objects.
The immutable storage APIs for textures allocate all of the specified mipmap levels for that texture. However, the various pixel transfer functions only ever upload, at most, a single mipmap level's worth of pixel data in a single operation. There is no provision in any pixel transfer operation to transfer more than a single mipmap level of data. Indeed, the process of pixel transferring only makes sense with a single image of a given dimensionality (array textures are considered treated as a higher-dimensional image). Mipmap levels change their size from layer to layer, which makes the pixel transfer operation change its meaning. Particularly with regard to some of the pixel transfer parameters like sub-image selectors.
So if you're uploading to a texture with multiple mipmaps, you're going to need to make multiple calls anyway. So what's one more?
Furthermore, note that glTexImage* and glCompressedTexImage* take different parameters. The former takes pixel data via pixel transfer functionality, and the latter takes pre-compressed data. But they both allocate storage. If you're going to make glTexStorage* more analogous to glTexImage*, then you have to also add glCompressedTexStorage*. So now you have another series of functions, and the only difference is what kind of upload they do.
By contrast, buffers only contain a single array of bytes, and there's only one way to upload to them.
Overall, it's better to just use the existing SubImage infrastructure for uploading, and have allocation be entirely separate from that.

Occlusion Queries and Instanced Rendering

I'm facing a problem where the use of an occlusion query in combination with instanced rendering would be desirable.
As far as I understood, something like
glBeginQuery(GL_ANY_SAMPLES_PASSED, occlusionQuery);
glDrawArraysInstanced(mode, i, j, countInstances);
glEndQuery(GL_ANY_SAMPLES_PASSED);
will only tell me, if any of the instances were drawn.
What I would need to know is, what set of instances has been drawn (giving me the IDs of all visible instances). Drawing each instance in an own call is no option for me.
An alternative would be to color-code the instances and detect the visible instances manually.
But is there really no way to solve this problem with a query command and why would it not be possible?
It's not possible for several reasons.
Query objects only contain a single counter value. What you want would require a separate sample passed count for each instance.
Even if query objects stored arrays of sample counts, you can issue more than one draw call in the begin/end scope of a query. So how would OpenGL know which part of which draw call belonged to which query value in the array? You can even change other state within the query scope; uniform bindings, programs, pretty much anything.
The samples-passed count is determined entirely by the rasterizer hardware on the GPU. And the rasterizer neither knows nor cares which instance generated a triangle.
Instancing is a function of the vertex processing and/or vertex specification stages; by the time the rasterizer sees it, that information is gone. Notice that fragment shaders don't even get an instance ID as input, unless you explicitly create one by passing it from your vertex processing stage(s).
However, if you truly want to do this you could use image load/store and its atomic operations. That is, pass the fragment shader the instance in question (as an int data type, with flat interpolation). This FS also uses a uimageBuffer buffer texture, which uses the GL_R32UI format (or you can use an SSBO unbounded array). It then performs an imageAtomicAdd, using the instance value passed in as the index to the buffer. Oh, and you'll need to have the FS explicitly require early tests, so that samples which fail the fragment tests will not execute.
Then use a compute shader to build up a list of rendering commands for the instances which have non-zero values in the array. Then use an indirect rendering call to draw the results of this computation. Now obviously, you will need to properly synchronize access between these various operations. So you'll need to use appropriate glMemoryBarrier calls between each one.
Even if queries worked the way you want them to, this would be overall far more preferable than using a query object. Unless you're reading a query into a buffer object, reading a query object requires a GPU/CPU synchronization of some form. Whereas the above requires some synchronization and barrier operations, but they're all on-GPU operations, rather than synchronizing with the CPU.

OpenGL Texture and Object Streaming

I have a need to stream a texture (essentially a camera feed).
With object streaming, the following scenarios seem to be arise:
Is the new object's data store larger, smaller or same size as the old one?
Subset of or whole texture being updated?
Are we streaming a buffer object or texture object (any difference?)
Here are the following approaches I have come across:
Allocate object data store (either BufferData for buffers or TexImage2D for textures) and then each frame, update subset of data with BufferSubData or TexSubImage2D
Nullify/invalidate the object after the last call (eg. draw) that uses the object either with:
Nullify: glTexSubImage2D( ..., NULL), glBufferSubData( ..., NULL)
Invalidate: glBufferInvalidate(), glMapBufferRange​ with the GL_MAP_INVALIDATE_BUFFER_BIT​, glDeleteTextures ?
Simpliy reinvoke BufferData or TexImage2D with the new data
Manually implement object multi-buffering / buffer ping-ponging.
Most immediately, my problem scenario is: entire texture being replaced with new one of same size. How do I implement this? Will (1) implicitly synchronize ? Does (2) avoid the synchronization? Will (3) synchronize or will a new data store for the object be allocated, where our update can be uploaded without waiting for all drawing using the old object state to finish? This passage from the Red Book V4.3 makes be believe so:
Data can also be copied between buffer objects using the
glCopyBufferSubData() function. Rather than assembling chunks of data
in one large buffer object using glBufferSubData(), it is possible to
upload the data into separate buffers using glBufferData() and then
copy from those buffers into the larger buffer using
glCopyBufferSubData(). Depending on the OpenGL implementation, it may
be able to overlap these copies because each time you call
glBufferData() on a buffer object, it invalidates whatever contents
may have been there before. Therefore, OpenGL can sometimes just
allocate a whole new data store for your data, even though a copy
operation from the previous store has not completed yet. It will then
release the old storage at a later opportunity.
But if so, why the need for (2)[nullify/invalidates]?
Also, please discuss the above approaches, and others, and their effectiveness for the various scenarios, while keeping in mind atleast the following issues:
Whether implicit synchronization to object (ie. synchronizing our update with OpenGL's usage) occurs
Memory usage
Speed
I've read http://www.opengl.org/wiki/Buffer_Object_Streaming but it doesn't offer conclusive information.
Let me try to answer at least a few of the questions you raised.
The scenarios you talk about can have a great impact on the performance on the different approaches, especially when considering the first point about the dynamic size of the buffer. In your scenario of video streaming, the size will rarely change, so a more expensive "re-configuration" of the data structures you use might be possible. If the size changes every frame or every few frames, this is typically not feasable. However, if a resonable maximum size limit can be enforced, just using buffers/textures with the maximum size might be a good strategy. Neither with buffers nor with textures you have to use all the space there is (although there are some smaller issues when you do this with texures, like wrap modes).
3.Are we streaming a buffer object or texture object (any difference?)
Well, the only way to efficiently stream image data to or from the GL is to use pixel buffer objects (PBOs). So you always have to deal with buffer objects in the first place, no matter if vertex data, image data or whatever data is to be tranfered. The buffer is just the source for some glTex*Image() call in the texture case, and of course you'll need a texture object for that.
Let's come to your approaches:
In approach (1), you use the "Sub" variant of the update commands. In that case, (parts of or the whole) storage of the existing object is updated. This is likely to trigger an implicit synchronziation ifold data is still in use. The GL has basically only two options: wait for all operations (potentially) depending on that data to complete, or make an intermediate copy of the new data and let the client go on. Both options are not good from a performance point of view.
In approach (2), you have some misconception. The "Sub" variants of the update commands will never invalidate/orphan your buffers. The "non-sub" glBufferData() will create a completely new storage for the object, and using it with NULL as data pointer will leave that storage unintialized. Internally, the GL implementation might re-use some memory which was in use for earlier buffer storage. So if you do this scheme, there is some probablity that you effectively end up using a ring-buffer of the same memory areas if you always use the same buffer size.
The other methods for invalidation you mentiond allow you to also invalidate parts of the buffer and also a more fine-grained control of what is happening.
Approach (3) is basically the same as (2) with the glBufferData() oprhaning, but you just specify the new data directly at this stage.
Approach (4) is the one I actually would recommend, as it is the one which gives the application the most control over what is happening, without having to relies on the GL implementation's specific internal workings.
Without taking synchronization into account, the "sub" variant of the update commands is
more efficient, even if the whole data storage is to be changed, not just some part. That is because the "non-sub" variants of the commands basically recreate the storage and introduce some overhead with this. With manually managing the ring buffers, you can avoid any of that overhead, and you don't have to rely in the GL to be clever, by just using the "sub" variants of the updates functions. At the same time, you can avoid implicit synchroniztion by only updating buffers which aren't in use by th GL any more. This scheme can also nicely be extenden into a multi-threaded scenario. You can have one (or several) extra threads with separate (but shared) GL contexts to fill the buffers for you, and just passing the buffer handlings to the draw thread as soon as the update is complete. You can also just map the buffers in the draw thread and let the be filled by worker threads (wihtout the need for additional GL contexts at all).
OpenGL 4.4 introduced GL_ARB_buffer_storage and with it came the GL_MAP_PERSISTEN_BIT for glMapBufferRange. That will allow you to keep all of the buffers mapped while they are used by the GL - so it allows you to avoid the overhead of mapping the buffers into the address space again and again. You then will have no implicit synchronzation at all - but you have to synchronize the operations manually. OpenGL's synchronization objects (see GL_ARB_sync) might help you with that, but the main burden on synchronization is on your applications logic itself. When streaming videos to the GL, just avoid re-using the buffer which was the source for the glTexSubImage() call immediately and try to delay its re-use as long as possible. You are of course also trading throughput for latency. If you need to minimize latency, you might to have to tweak this logic a bit.
Comparing the approaches for "memory usage" is really hard. There are a lot of of implementation specific details to consider here. A GL implementation might keep some old buffer memories around for some time to fullfill recreation requests of the same size. Also, an GL implementation might make shadow copies of any data at any time. The approaches which don't orphan and recreate storages all the time in principle expose more control of the memory which is in use.
"Speed" itself is also not a very useful metric. You basically have to balance throughput and latency here, according to the requirements of your application.

Is glTexStorage2D imperative when auto generating mipmaps

I do update to a texture2D in OpenGL 4.0 using gltexSubImage2D().The texture has mipmaps auto generated using
glGenerateMipmap(GL_TEXTURE_2D);
My texture update was failing till I understood I had to regenerate mipmaps on update too (or remove mipmaps generation).Then I read this wiki where there is a usage of glTexStorage2D when generating mipmaps.I actually never paid attention to this method.So I wonder if I have to use it every time I generate a texture with mipmaps?
Update :
I see from the method specs that it
specifies the storage requirements for all levels
of a two-dimensional texture or one-dimensional texture array simultaneously
I guess using it should improve the performance when generating mipmaps?Is it true?
The two functions are completely orthogonal.
The choice is between glTexImage2D and glTexStorage2D. Both of these allocate storage for texture images; they just do it in different ways.
glTexImage2D is the old way of allocating storage. It creates mutable storage (there are other functions that create mutable storage too). If you want mipmaps, you have to allocate each mipmap level with a separate call to the function, manually computing the size of the mipmap image (see below for the exception to this).
glTexStorage2D allocates immutable storage for the image data. It allocates all of the mipmaps you want all at once.
Immutable storage, as the name suggests, cannot be changed. See, you can call glTexImage2D on the same mipmap level, with a different size. And if you do, OpenGL will destroy the original mipmap level and allocate storage for the new one. You can even change formats.
Immutable storage won't let you change any of that. You can upload new data, using functions like glTexSubImage2D. But those functions don't change the storage; they change the contents.
glTexImage2D and glTexStorage2D are like malloc. glTexSubImage2D is like memcpy; it only works for existing memory.
glGenerateMipmap is a function that will take the base layer of a texture and generate the data for all of the mipmaps from that base layer (given the mipmap range). It does this one time. Think of it like a rendering function; it does its job and then it's done.
For mutable storage textures, glGenerateMipmap will also allocate storage for any mipmaps in the mipmap range that were not previously allocated. That's why you can call glTexImage2D once, then call glGenerateMipmap to force it to make all of the other mipmaps without having to do it manually.
Before there was glTexStorage, each mipmap level had to be initialized by a separate call to glTexImage. glTexImage triggers a lot of complex internal state changes, which are rather expensive. Every time glTexImage is called, the layout of the texture object is altered.
Hence you try to avoid using it, if possible. As you discovered, you must first initialize all desired mipmap levels before you can update them by glTexSubImage. glGenerateMipmap will create them, which introduce layout changes, which is, yes, expensive.
glTexStorage initializes the whole texture object once for a desired, immutable format. Yes, using glTexStorage improves performance when used together wigh glGenerateMipmap or data updates by glTexSubImage, but the improvements happen very early at texture object creation, and not so much when its data is changed.

What does glTexStorage do?

The documentation indicates that this "allocates" storage for a texture and its levels. The pseudocode provided seems to indicate that this is for the mipmap levels.
How does usage of glTexStorage relate to glGenerateMipmap? glTexStorage seems to "lock" a texture's storage size. It seems to me this would only serve to make things less flexible. Are there meant to be performance gains to be had here?
It's pretty new and only available in 4.2 so I'm going to try to avoid using it, but I'm confused because its description makes it sound kind of important.
How is storage for textures managed in earlier GL versions? When i call glTexImage2D I effectively erase and free the storage previously associated with the texture handle, yes? and generating mipmaps also automatically handles storage for me as well.
I remember using the old-school glTexSubImage2D method to implement OpenGL 2-style render-to-texture to do some post-process effects in my previous engine experiment. It makes sense that glTexStorage will bring about a more sensible way of managing texture-related resources, now that we have better ways to do RTT.
To understand what glTexStorage does, you need to understand what the glTexImage* functions do.
glTexImage2D does three things:
It allocates OpenGL storage for a specific mipmap layer, with a specific size. For example, you could allocate a 64x64 2D image as mipmap level 2.
It sets the internal format for the mipmap level.
It uploads pixel data to the texture. The last step is optional; if you pass NULL as the pointer value (and no buffer object is bound to GL_PIXEL_UNPACK_BUFFER), then no pixel transfer takes place.
Creating a mipmapped texture by hand requires a sequence of glTexImage calls, one for each mipmap level. Each of the sizes of the mipmap levels needs to be the proper size based on the previous level's size.
Now, if you look at section 3.9.14 of the GL 4.2 specification, you will see two pages of rules that a texture object must follow to be "complete". A texture object that is incomplete cannot be accessed from.
Among those rules are things like, "mipmaps must have the appropriate size". Take the example I gave above: a 64x64 2D image, which is mipmap level 2. It would be perfectly valid OpenGL code to allocate a mipmap level 1 that used a 256x256 texture. Or a 16x16. Or a 10x345. All of those would be perfectly functional as far as source code is concerned. Obviously they would produce nonsense as a texture, since the texture would be incomplete.
Again consider the 64x64 mipmap 2. I create that as my first image. Now, I could create a 128x128 mipmap 1. But I could also create a 128x129 mipmap 1. Both of these are completely consistent with the 64x64 mipmap level 2 (mipmap sizes always round down). While they are both consistent, they're also both different sizes. If a driver has to allocate the full mipmap chain at once (which is entirely possible), which size does it allocate? It doesn't know. It can't know until you explicitly allocate the rest.
Here's another problem. Let's say I have a texture with a full mipmap chain. It is completely texture complete, according to the rules. And then I call glTexImage2D on it again. Now what? I could accidentally change the internal format. Each mipmap level has a separate internal format; if they don't all agree, then the texture is incomplete. I could accidentally change the size of the texture, again making the texture incomplete.
glTexStorage prevents all of these possible errors. It creates all the mipmaps you want up-front, given the base level's size. It allocates all of those mipmaps with the same image format, so you can't screw that up. It makes the texture immutable, so you can't come along and try to break the texture with a bad glTexImage2D call. And it prevents other errors I didn't even bother to cover.
The question isn't "what does glTexStorage do?" The question is "why did we go so long without it."
glTexStorage has no relation to glGenerateMipmap; they are orthogonal functionality. glTexStorage does exactly what it says: it allocates texture storage space. It does not fill that space with anything. So it creates a texture with a given size filled with uninitialized data. Much like glRenderbufferStorage allocates a renderbuffer with a given size filled with uninitialized data. If you use glTexStorage, you need to upload data with glTexSubImage (since glTexImage is forbidden on an immutable texture).
glTexStorage creates space for mipmaps. glGenerateMipmap creates the mipmap data itself (the smaller versions of the base layer). It can also create space for mipmaps if that space doesn't already exist. They're used for two different things.
Before calling glGenerateMipmap​, the base mipmap level must be established. (either with mutable or immutable storage).so...,you can using glTexImage2D+glGenerateMipmap only,more simple!