Can GL_SHADER_STORAGE_BUFFER be included in a VAO?

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

Do not touch GL_SHADER_STORAGE_BUFFER as this is for completely different purpose. The GL_ARRAY_BUFFER should be everywhere in your code.

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;
}

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).

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.