Unable to read from SSBO

Hello!
I’m facing some problems with reading from SSBO.
For some reason the buffer assigned for SSBO is either empty (not filled in shader)
or not accessible (glMapBuffer returns NULL and err code 1282).
I’ve already tried several approaches from different forums and books but the result is the same.
The best result that I could get is that sometimes it actually returns non-empty buffer with expected content but it occurs only once per program run and very unstably.

Could your please explain why this happens and where I’m wrong?
Also some advises on how to achieve stable behavior are appreciated!

Application code:

....
// Buffer initialization and bindings
     GLuint imageBuffer;
    //std::vector<glm::vec3> image;
    std::vector<float> image;
    image.resize(width*height*3);
    cv::Mat img = cv::Mat(height, width, CV_32FC3);

glCreateBuffers(1, &imageBuffer);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, imageBuffer);
    glNamedBufferStorage(imageBuffer, // Name of the buffer
                            //width*height*sizeof(glm::vec3), // Storage size in bytes
                            width*height*sizeof(float)*3, // Storage size in bytes
                            img.data,//&image[0], //  initial data
                            GL_MAP_WRITE_BIT | GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT ); // Allow map for writing
    glBufferData(GL_SHADER_STORAGE_BUFFER, /*width*height*sizeof(glm::vec3)*/width*height*sizeof(float)*3, /*&image[0]*/img.data, GL_DYNAMIC_COPY);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2/*see fragment shader binding*/, imageBuffer);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
......

glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT  | GL_SHADER_STORAGE_BARRIER_BIT); // missed previously call to memory barrier
do{
		
		glBindBuffer(GL_SHADER_STORAGE_BUFFER, imageBuffer);
        	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2/*see fragment shader binding*/, imageBuffer);

	/* here goes rendering and other bindings*/
	....

	glDrawArrays(GL_TRIANGLES, 0, vertices.size() );

	std::this_thread::sleep_for(std::chrono::milliseconds(10));

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	glDisableVertexAttribArray(2);

	// Swap buffers
	glfwSwapBuffers(window);
	glfwPollEvents();
        
	//here we gona read the SSBO content
        
	glFinish();
	//void * ptr = glMapNamedBuffer(imageBuffer, GL_READ_WRITE);//GL_READ_ONLY);
	void * ptr = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_WRITE);//GL_READ_ONLY);

	/*void * ptr = glMapBufferRange( 	GL_SHADER_STORAGE_BUFFER,
  	0,
  	width*height*sizeof(float)*3,
  	GL_READ_ONLY);*/
       if(ptr != NULL)
       {
		// Sometime in the first iteration of the cycle the program manage to get here but the buffer is sometimes empty, sometimes filled
		// Copy our data into it...
	       memcpy(img.data, ptr,  width*height*sizeof(float)*3);

		// Tell OpenGL that we're done with the pointer
	       glUnmapNamedBuffer(GL_SHADER_STORAGE_BUFFER);
	       glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);


		cv::imshow("Suzane",img);
		
		std::cout<<"Image read"<<std::endl;
			cv::waitKey();

	}
	else{
		// the program always end up here.
		std::cout<<"glMapNamedBuffer return NULL"<<std::endl;
		checkGLError(""); // prints MyApp: glError 1282
	}
	glUnmapNamedBuffer(GL_SHADER_STORAGE_BUFFER);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

}



...
// much later
void checkGLError(std::string op) {
    int error;
    while ((error = glGetError()) != GL_NO_ERROR) {
            std::cout<<"MyApp"<< op << ": glError " << error<<std::endl;
    }
}

Fragment shader code:

#version 430 core

// Interpolated values from the vertex shaders
in vec2 UV;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 LightDirection_cameraspace;
in vec3 colorIn;
layout(origin_upper_left) in vec4 gl_FragCoord ;

// Ouput data
out vec3 color;

uniform int imageBufferID;
uniform int imageWidth;
uniform int imageHeight;

layout(std430, binding = 2) buffer imageLayout
{
    //vec3 image[];
    float image[];
} SharedBuffer;


void main(){

//----------------------------------------------------------------
        vec4 xy = gl_FragCoord;
        highp int x = int(xy.x);
        highp int y = int(xy.y);
        int stride = imageWidth*3;
        int maxOffset = imageWidth*imageHeight*3;
	
        int offset = int(3*x + y*stride);
	if(offset>=maxOffset) offset= maxOffset-1;
	int ind = offset;

        SharedBuffer.image[offset] = colorIn.x;
        SharedBuffer.image[offset+1] = colorIn.y;
        SharedBuffer.image[offset+2] = colorIn.z;
//--------------------------------------------------------------

	color = colorIn;
}

I don’t see your call to glMemoryBarrier.

Right before “do{ …”, forgot to copy
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
GL_SHADER_STORAGE_BARRIER_BIT);

Didn’t help…

That’s the wrong barrier. You’re supposed to specify how you’re accessing the buffer, not how you put the data into it that you want to access. Since you’re accessing it by mapping the buffer after the writes, that would be GL_BUFFER_UPDATE_BARRIER_BIT.

This makes no sense. The argument to glUnmapNamedBuffer is a buffer name (handle, ID), not a target. Either pass the buffer name or use glUnmapBuffer instead. As it stands, this call will fail (with GL_INVALID_OPERATION) and leave the buffer mapped; any subsequent glMapBuffer call will also fail (with GL_INVALID_OPERATION) because the buffer is still mapped.

More generally, there’s no reason to mix and match the use of gl*Buffer* and gl*NamedBuffer* functions. If you’re going to use the DSA interfaces, use them exclusively. In that case, the only time you should use the GL_SHADER_STORAGE_BUFFER target is for glBindBufferBase.

Thank a lot! This was stupid mistake…

I’ve tried this as well but seems it is working as is also