PDA

View Full Version : Can GL_SHADER_STORAGE_BUFFER be included in a VAO?



David Lofstrand
08-29-2014, 04:42 AM
Hi there,

I have a VAO with a shader that renders a circular shape.

When I'm setting up my VAO I have the following working code that works:



glGenVertexArrays(1, &m_vao_id);
glGenBuffers(1, &m_radius_id);
GLint rad_attrib = glGetAttribLocation(m_prog_id, "radius");
. . .
glBindVertexArray(m_vao_id);
. . .


glBindBuffer(GL_ARRAY_BUFFER, m_radius_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_radii[0]) * m_num_vertices, m_radii, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(rad_attrib);
glVertexAttribPointer(rad_attrib, 1, GL_FLOAT, GL_FALSE, 0, 0);


However when I replace it with the following code it does not work.


glGenVertexArrays(1, &m_vao_id);
glGenBuffers(1, &m_radius_id);
GLint rad_attrib = glGetAttribLocation(m_prog_id, "radius");
. . .
glBindVertexArray(m_vao_id);
. . .


glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_radius_id);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_radius_vtx[0]) * m_num_vertices, nullptr, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(rad_attrib);
glVertexAttribPointer(rad_attrib, 1, GL_FLOAT, GL_FALSE, 0, 0);
GLuint accessMask = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
float *rad =
(float *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_num_vertices*sizeof(m_radii[0]), accessMask);
// temporary hack: radius set to 0.1
for (int i = 0; i < m_num_vertices; ++i)
rad[i] = 0.1;//m_radii[i];
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);


m_radii is a float array.

So naturally I'm probably doing something wrong so asking you if you can see something obviously wrong here.
Best Regards,
David

Yandersen
08-29-2014, 04:58 AM
Do not touch GL_SHADER_STORAGE_BUFFER as this is for completely different purpose. The GL_ARRAY_BUFFER should be everywhere in your code.

David Lofstrand
08-29-2014, 05:45 AM
I need to pass the data to a compute shader that will modify the radius.
I tried to use the GL_ARRAY_BUFFER but it does not seem to work.
The code that runs the compute shader that should modify the radius looks like this at this stage:


glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_radius_id);
glUseProgram(m_compute_prog);
#define WORK_GROUP_SIZE 16
glDispatchCompute(m_num_vertices/WORK_GROUP_SIZE, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glUseProgram(0);



compute shader:


#version 430 compatibility
#extension GL_ARB_compute_shader : enable
#extension GL_ARB_shader_storage_buffer_object : enable


layout( std140, binding=2) buffer some_name {
float radius_out[ ];
};


layout( local_size_x = 16, local_size_y = 1, local_size_z = 1 ) in;


void main()
{
uint i = gl_GlobalInvocationID.x;
radius_out[i] = 0.1;
}

Yandersen
08-29-2014, 06:14 AM
Oh, well, then ensure the buffer you bind is the GL_SHADER_STORAGE_BUFFER also, because in your code you bind your m_radius_id buffer as GL_ARRAY_BUFFER and then set a data for the buffer bound to the GL_SHADER_STORAGE_BUFFER target (which, I assume, has 0 bound at that moment).

David Lofstrand
08-29-2014, 07:36 AM
Sorry that was a typo from the cut'n'paste of my source code.
The buffer is bound as GL_SHADER_STORAGE_BUFFER.
Maybe it's my drivers... I'll try update them.