PDA

View Full Version : How to pass data to the compute shader opengl 4.5



meith1
12-03-2015, 06:12 PM
GLuint Mesh_Setup(GLuint render_prog, GLuint comp_prog, struct VertexPos *vert_pos, struct VertexCol *vert_col, GLuint num_verts, GLuint *inds, GLuint num_inds)
{
GLuint vao;
glCreateVertexArrays(1, &vao);

GLuint pos_attrib_loc = glGetAttribLocation(render_prog, "pos");
GLuint col_attrib_loc = glGetAttribLocation(render_prog, "col");

glVertexArrayAttribFormat(vao, pos_attrib_loc, 4, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribFormat(vao, col_attrib_loc, 4, GL_FLOAT, GL_FALSE, 0);

glVertexArrayAttribBinding(vao, pos_attrib_loc, 0);
glVertexArrayAttribBinding(vao, col_attrib_loc, 1);

glEnableVertexArrayAttrib(vao, pos_attrib_loc);
glEnableVertexArrayAttrib(vao, col_attrib_loc);

GLuint pos_vbo;
glCreateBuffers(1, &pos_vbo);
glNamedBufferData(pos_vbo, sizeof(GLfloat) * 4 * num_verts, vert_pos, GL_DYNAMIC_COPY);
glVertexArrayVertexBuffer(vao, 0, pos_vbo, 0, sizeof(struct VertexPos));

GLuint col_vbo;
glCreateBuffers(1, &col_vbo);
glNamedBufferStorage(col_vbo, sizeof(GLfloat) * 4 * num_verts, vert_col, 0);

glVertexArrayVertexBuffer(vao, 1, col_vbo, 0, sizeof(struct VertexCol));

GLuint ebo;
glCreateBuffers(1, &ebo);
glNamedBufferStorage(ebo, sizeof(GLuint) * num_inds, inds, 0);

glVertexArrayElementBuffer(vao, ebo);

return vao;
}

If I'm getting this code right, glVeretxArrayVertexBuffer is being used to pass data to an GL_ARRAY_BUFFER and glVertexArrayElementBuffer is being used to pass data into an GL_ELEMENT_ARRAY_BUFFER, so is there an GL_SHADER_STORAGE_BUFFER equivalent like glVertexArrayShaderStorageBuffer to pass data which can be manipulated in the computed shader? I would like to pass the same pos_buf data to the compute shader.

GClements
12-03-2015, 09:16 PM
Data is passed into compute shaders via uniform variables (either in the default uniform block or a named uniform block), buffer variables, textures or images. Uniform buffers (UBOs) and shader storage buffers (SSBOs) are attached to binding points using glBindBufferBase() or glBindBufferRange() with a target of GL_UNIFORM_BUFFER or GL_SHADER_STORAGE_BUFFER respectively.

But for a vertex array where the number of components is 1, 2 or 4 (not 3) and the data is packed, another option is to attach the buffer to a buffer texture with glTextureBuffer(), bind the texture to an image unit with glBindImageTexture(), and access the data in the compute shader using imageLoad().

Either way, one thing which you can do with vertex arrays but can't do using UBOs, SSBOs or images is decouple the actual data format from the shader. For a vertex shader which has an input variable (attribute) of type vec4, the actual attribute data in the buffer can have any type, any number of components; and any stride between the elements; and the data will appear as a sequence of vec4s to the shader. But for UBOs, SSBOs and images, the data format must match the interface block declaration (for UBOs or SSBOs) or the format qualifier (for images).

Alfonse Reinheart
12-03-2015, 09:52 PM
It should also be noted that compute shaders lack user-defined input variables, so you can't communicate with them like vertex shaders. But they do have their own system-defined input variables (https://www.opengl.org/wiki/Compute_Shader#Inputs), which will be useful for having each invocation pick out its data. So if you want to do vertex shader-like processing, you will need to manually fetch data from SSBOs, using an appropriate input variable to act as the vertex index. `gl_GlobalInvocationID​` would be a good one, for example.

meith1
12-05-2015, 04:09 PM
Thank you so much. I used glBindBufferBase to bind my pos_buf to GL_SHADER_STORAGE_BUFFER. I just had a following question... Does the index parameter in the bindBufferBase fucntion refer to the binding point we write inside the compute shader like :

layout(std430, binding = 0) buffer vert_pos
{
vec4 pos[];
};

In my bindbuferbase function call i wrote my binding point as 0 to match the 0 in the shader. Just want to confirm if thats what its referring to.

GClements
12-05-2015, 06:34 PM
Does the index parameter in the bindBufferBase fucntion refer to the binding point we write inside the compute shader like :

layout(std430, binding = 0) buffer vert_pos
{
vec4 pos[];
};

Yes.

Note that the block's binding point isn't the same thing as the block index, which is used to query properties of the block (and to set its associated binding point programmatically via glShaderStorageBlockBinding).

The index can largely be ignored unless you're in the habit of introspecting shader programs (glGetProgramResource etc). But if you do need to do that, don't confuse the binding point with the index.