Copying a SSBO Into Another SSBO - opengl

It recently came to my attention that glCopyBufferSubData is not applicable to Shader Storage Buffer Objects as the extension excludes mention of it. To make sure, I tested this by printing out the mapped buffers and the new SSBO contained repetitive nonsense showing that this was the case. Without having to create a custom compute shader to do this, is there any way to copy the data on the GPU from a command issued from the CPU similar to what glCopyBufferSubData would do for other buffer types?

The function glCopyBufferSubData works on buffer objects. A buffer object in itself is nothing special, all buffer objects are the same. Only when binding a buffer object as a shader storage buffer it is used as a shader storage buffer. But if not used as a shader storage buffer, it is just a plain buffer object. So your assumption that glCopyBufferSubData doesn't work on shader storage buffers is plain wrong, it works on buffers, no matter for what you use those buffers later on. The only reason the extension doesn't mention SSBOs is, that SSBOs didn't exist when the copy_buffer extension was introduced, but this functionality is completely orthogonal to SSBOs.
The reason it doesn't work for you is to be searched elsewhere. Maybe you can't use GL_SHADER_STORAGE_BUFFER as a valid target for glCopyBufferSubData, but that isn't required anyway, just bind the buffer to another target, e.g. GL_COPY_READ_BUFFER or GL_COPY_WRITE_BUFFER. Another error source might be that writes from a shader into an SSBO are not necessarily synchronized with following read operations and you might need an additional glMemoryBarrier if copying the data right after computing it.
But to make it clear, glCopyBufferSubData works on any kind of buffer and the target you bind a buffer to is absolutely not tied to the buffer object and its data itself. You can perfectly use an SSBO to compute some data into and then render it as a VBO and so on.

Related

How to use a single buffer object as both VBO and UBO (possibly any other kind of buffers also) in opengl

My question relates to how allocations are handled in opengl.
If you create a buffer object using glGenBuffers(1, &id) then let's say populate it with a mesh's vertex data using glBindBuffer(GL_ARRAY_BUFFER, id) and glBufferData(GL_ARRAY_BUFFER, ...). The question I have now is : will the data I uploaded be bound to the GL_ARRAY_BUFFER tag specifically? So could I for example later use glBindBuffer(GL_UNIFORM_BUFFER, id) and use that data as a uniform buffer or does changing the associated target cause memory to be freed forcing me to use glGetBufferSubData to retrieve and re-upload the data now bound to the GL_UNIFORM_BUFFER tag? It seems intuitive that a buffer object keeps it's data as long as it is not deleted and that the target parameter is more to hint to the gpu where the data might be more optimally stored and what operations might be done with the buffer. What effects does doing something like this have on the state of opengl and is there a recommended alternative other than duel-uploading or re-uploading.
The buffer target does not have any effect on the content of a buffer. A buffer itself doesn't even know to which target it is bound. You can at any time bind the buffer to any other target and it can even be bound to multiple targets at the same time.
Buffer targets are only used by the API to determine which buffer a command should operate on. For example, glBufferData requires you to bind the buffer to the same target that you pass to it. But it doesn't really matter which target you are using. Some other commands, like glVertexAttribPointer expect a buffer to be bound to a certain target, but also here the binding doesn't alter/modify the buffer itself.
Note, that Direct State Access (DSA) methods which are core since OpenGL 4.5 do not use binding targets at all while providing the same functionality as the stateful methods.

Uploading index buffer without changing VAO state

In order to upload an index buffer to the GPU, I have to call glBindBuffer with GL_ELEMENT_ARRAY_BUFFER then call glBufferData etc. on it.
However, for my engine design where everything is condensed into as few functions as possible this comes unhandy as using GL_ELEMENT_ARRAY_BUFFER with glBindBuffer changes VAO state and I would like to deal with the buffers without changing VAO state.
Can someone tell me if it is possible to allocate and upload an index buffer without touching VAO state? Or would I have to restore GL_ELEMENT_ARRAY_BUFFER state manually?
The following assumes that direct state access functionality is not available to you. If it is, you should just use that, so that you don't have to bind objects just to modify them in the first place.
There is no such thing as an "index buffer" in the OpenGL API. There are just buffer objects, which can be at any point used for any number of purposes (one of which is for vertex indices in a rendering command). No buffer is ever wedded to the notion of being specifically for index data.
Buffer binding points therefore are meaningful only to the degree that you use the functionality associated with those binding points. GL_ARRAY_BUFFER is meaningful only because glVertexAttribPointer calls look at the buffer bound to that binding point. But if you're not actually making a glVertexAttribPointer call, then GL_ARRAY_BUFFER is just a binding point, no different from any other.
For general buffer object management, you therefore can bind any buffer to any binding point. GL_UNIFORM_BUFFER, GL_COPY_READ_BUFFER​, whatever. If you're not using the binding for its special purpose, then no binding is different from another (except GL_ELEMENT_ARRAY_BINDING which is part of VAO state).
So just bind the "index buffer" to some innocuous binding point (the indexed ones like GL_UNIFORM_BUFFER are particularly harmless, since they only get special functions when you use glBindBufferRange) and do your upload from there.

First Inizialization of VBO. Does it matter where to bind?

Say i want just to create and fill a buffer.
GLuint ret;
glGenBuffers(1,&ret);
glBindBuffer(GL_ARRAY_BUFFER, ret);
glBufferData(GL_ARRAY_BUFFER,size,data,usage);
glBindBuffer(GL_ARRAY_BUFFER,0);
Does it really matter which target i use in the two calls? (Of course they must be the same).
For example: can i fill the buffer writing to the GL_ARRAY_BUFFER target while it's binded on it and later on in the code bind the sane buffer to the GL_UNIFORM_BUFFER target and use it's data for filling a uniform block with glBindBufferRange?
It does not matter; any target should work. I've created buffers with targets matching the intended usage before and it made no difference.
I guess an OpenGL implementation (i.e. driver) could allocate memory differently depending on the target passed but I've not seen evidence of this.
Also, the newer glNamedBufferData which does the same thing as glBufferData without requiring a previous glBindBuffer call does not have a target parameter. This hints strongly that the targets are interchangeable.

glGenBuffers function usage

For each buffer type, there a special function to generate names for it like glGenFramebuffers for framebuffers, glGenRenderbuffers for render buffers, and glGenTextures for textures.
But there is a function called glGenBuffers. What types of buffers does this function generate? & how these buffers can be used in my program?
glGenBuffers allocates a name for a "Buffer Object". An OpenGL Buffer Object represents a block of memory which can be accessed by both the application and the GPU (though typically not by both at the same time). OpenGL can use the contents of a buffer object for a variety of purposes, and a single buffer object may be used for more than one purpose over its lifetime, though in practice buffer objects are often created exclusively for one type of data.
You can get an idea for the uses that a buffer object has by looking at the list of binding points to which you can attach a buffer object (using the glBindBuffer function). For example:
GL_ARRAY_BUFFER​ - OpenGL will read vertex data from the buffer object.
GL_ELEMENT_ARRAY_BUFFER​ - OpenGL will read vertex indices (e.g., for glDrawElements) from the buffer object.
GL_PIXEL_UNPACK_BUFFER​ - Functions that read pixel data (e.g., glTexImage2D) will read that data from the buffer object.
And many more.
For more information, see the OpenGL wiki page for Buffer Object.

why the second call to glBindBuffer?

I'm reading along in this tutorial and i get down towards the end in how to use Vertex Buffers and i see that the vertex buffer which I generated and called glBindBuffer on once already i have to bind a second time:
glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle);
I'm still very new to openGL (like 3 days) so I'm trying to wrap my mind around how a lot of these things work. I spend most of my time on khronos or opengl.org reading about the commands, but I couldn't figure out why this one gets called twice. any hints? Thanks.
Does that particular example strictly need the second bind? No. OpenGL retains state, so if a buffer object is bound to a target, then it will remain bound until you bind something else to that target.
However, what happens if you insert code after the creation of the buffer that creates a second buffer? After all, you might want to have two objects. Or 10. Or however many you want; they don't have to share buffer objects.
Once you do that, your code breaks because the buffer that your code expects to be bound isn't actually bound. Therefore, unless you're good at managing state and really know what you're doing (and if you're still following tutorials, the answer is "no"), you should set whatever state you need to do what you intend.
Therefore, if you intend to draw from a particular buffer, you should bind it and set the appropriate state (the gl*Pointer calls).
You have to bind and unbind the buffer to copy to it from 'C' and draw with it from openGL.
Think of it as locking/unlocking between the program and the graphics.
So the sequence is
create
bind
stuff data
unbind
bind
display
unbind
Brief : The second one usualy unbinds the first one.
If no buffer object with name buffer exists, one is created with that name. When a buffer object is bound to a target, the previous binding for that target is automatically broken.
Buffer object names are unsigned integers. The value zero is reserved, but there is no default buffer object for each buffer object target. Instead, buffer set to zero effectively unbinds any buffer object previously bound, and restores client memory usage for that buffer object target (if supported for that target). Buffer object names and the corresponding buffer object contents are local to the shared object space of the current GL rendering context; two rendering contexts share buffer object names only if they explicitly enable sharing between contexts through the appropriate GL windows interfaces functions.
Reference : https://www.opengl.org/sdk/docs/man/html/glBindBuffer.xhtml