<p>I want to retrieve data that has created by the compute shader but have no clue how it works. After researching a few forums and articles on how it should work and this is what I came up with.</p>
<p><strong>Compute Shader Code</strong></p>
<pre><code>#version 430 core

layout  (local_size_x  =  100)  in;

layout(std430, binding=0) buffer Pos{
    float Position[];
};

void main(){
    Position[gl_GlobalInvocationID.x] = float(gl_GlobalInvocationID.x);
}
</code></pre>
<p><strong>Program Code</strong></p>
<pre><code>public float[] useProgram(int x_size, int y_size, int z_size){
        
        this.group_x_size = (int)Math.ceil(x_size/100);
        this.group_y_size = (int)Math.ceil(y_size/100);
        this.group_z_size = (int)Math.ceil(z_size/100);
        float[] data = new float[x_size];
        FloatBuffer buffer = BufferUtils.createFloatBuffer(x_size);
        buffer.put(data);
        int ssbo = GL15.glGenBuffers();// creates empty VBO as an object and stores it in OpenGl memory
        GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, ssbo);
        GL15.glBufferData(GL43.GL_SHADER_STORAGE_BUFFER,buffer,GL15.GL_DYNAMIC_COPY);
        GL43.glBindBufferBase(GL43.GL_SHADER_STORAGE_BUFFER, 0, ssbo);
        GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0);
        
        GL20.glUseProgram(computeProgram);//start the shader program
        GL43.glDispatchCompute(group_x_size, 1, 1);
        GL43.glMemoryBarrier(GL43.GL_SHADER_STORAGE_BARRIER_BIT);

        GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, ssbo);
        String values = GL43.glMapBuffer(GL43.GL_SHADER_STORAGE_BUFFER, GL43.GL_WRITE_ONLY).asFloatBuffer().toString();
        GL43.glUnmapBuffer(GL43.GL_SHADER_STORAGE_BUFFER);
        System.out.println(values);
        
        return null;
    }
</code></pre>
<p>However this code just simply will not work the way I want it to. When I go to print out the Values it comes up null. Is there something wrong with the code or is there a better way to do it. I've looked through many forums but most of them aren't written in java.</p>

CC BY-SA 4.0
2020-07-21T23:00:29.380Z
One thing is that when you map the buffer you're passing GL_WRITE_ONLY. But you want to retrieve the values in the buffer, so you probably want GL_READ_ONLY for that.
Nathan Reed
CC BY-SA 4.0
2020-07-21T23:05:21.327Z
Also, I think you want GL_BUFFER_UPDATE_BARRIER_BIT instead of GL_SHADER_STORAGE_BARRIER_BIT. The barrier bits refer to operations _after_ the barrier that need to wait for shader writes prior to the barrier. glMapBuffer falls under the BUFFER_UPDATE_BARRIER_BIT.
Nathan Reed
CC BY-SA 4.0
2020-07-22T00:13:11.080Z
@NathanReed The program still somehow returns null whenever I run it.
Ethan Ma
CC BY-SA 4.0
2020-07-22T00:20:02.000Z
Next thing to try might be hooking up [debug output](https://www.khronos.org/opengl/wiki/Debug_Output) to see if there are any errors/warnings that might shed light on what's going wrong. See also [this question](https://computergraphics.stackexchange.com/questions/5945/how-to-do-error-handling-with-opengl).
Nathan Reed
CC BY-SA 4.0
2020-07-22T00:24:55.253Z
@NathanReed after I switched out GL_DYNAMIC_COPY code for GL_READ_ONLY instead of returning null the whole thing just crashed.
Ethan Ma
CC BY-SA 4.0
2020-07-22T23:26:53.793Z
Not sure what you mean there, you don't need to change the GL_DYNAMIC_COPY (and GL_READ_ONLY is not a valid value for that anyway). But you do need to replace GL_WRITE_ONLY with GL_READ_ONLY in the glMapBuffer call.
Nathan Reed
<opengl><compute-shader>
How to retrieve data from Compute Shader to CPU?
Ethan Ma
# How to retrieve data from Compute Shader to CPU?

(Asked by: username_0 on 2020-07-21)

I want to retrieve data that has created by the compute shader but have no clue how it works. After researching a few forums and articles on how it should work and this is what I came up with.

**Compute Shader Code**

```
#version 430 core

layout  (local_size_x  =  100)  in;

layout(std430, binding=0) buffer Pos{
    float Position[];
};

void main(){
    Position[gl_GlobalInvocationID.x] = float(gl_GlobalInvocationID.x);
}

```

**Program Code**

```
public float[] useProgram(int x_size, int y_size, int z_size){
        
        this.group_x_size = (int)Math.ceil(x_size/100);
        this.group_y_size = (int)Math.ceil(y_size/100);
        this.group_z_size = (int)Math.ceil(z_size/100);
        float[] data = new float[x_size];
        FloatBuffer buffer = BufferUtils.createFloatBuffer(x_size);
        buffer.put(data);
        int ssbo = GL15.glGenBuffers();// creates empty VBO as an object and stores it in OpenGl memory
        GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, ssbo);
        GL15.glBufferData(GL43.GL_SHADER_STORAGE_BUFFER,buffer,GL15.GL_DYNAMIC_COPY);
        GL43.glBindBufferBase(GL43.GL_SHADER_STORAGE_BUFFER, 0, ssbo);
        GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, 0);
        
        GL20.glUseProgram(computeProgram);//start the shader program
        GL43.glDispatchCompute(group_x_size, 1, 1);
        GL43.glMemoryBarrier(GL43.GL_SHADER_STORAGE_BARRIER_BIT);

        GL15.glBindBuffer(GL43.GL_SHADER_STORAGE_BUFFER, ssbo);
        String values = GL43.glMapBuffer(GL43.GL_SHADER_STORAGE_BUFFER, GL43.GL_WRITE_ONLY).asFloatBuffer().toString();
        GL43.glUnmapBuffer(GL43.GL_SHADER_STORAGE_BUFFER);
        System.out.println(values);
        
        return null;
    }

```

However this code just simply will not work the way I want it to. When I go to print out the Values it comes up null. Is there something wrong with the code or is there a better way to do it. I've looked through many forums but most of them aren't written in java.

**Tags:** opengl, compute-shader

> **Comments:**
> **username_1**: One thing is that when you map the buffer you're passing GL_WRITE_ONLY. But you want to retrieve the values in the buffer, so you probably want GL_READ_ONLY for that.  
> **username_1**: Also, I think you want GL_BUFFER_UPDATE_BARRIER_BIT instead of GL_SHADER_STORAGE_BARRIER_BIT. The barrier bits refer to operations _after_ the barrier that need to wait for shader writes prior to the barrier. glMapBuffer falls under the BUFFER_UPDATE_BARRIER_BIT.  
> **username_0**: @username_1 The program still somehow returns null whenever I run it.  
> **username_1**: Next thing to try might be hooking up [debug output](https://www.khronos.org/opengl/wiki/Debug_Output) to see if there are any errors/warnings that might shed light on what's going wrong. See also [this question](https://computergraphics.stackexchange.com/questions/5945/how-to-do-error-handling-with-opengl).  
> **username_0**: @username_1 after I switched out GL_DYNAMIC_COPY code for GL_READ_ONLY instead of returning null the whole thing just crashed.  
> **username_1**: Not sure what you mean there, you don't need to change the GL_DYNAMIC_COPY (and GL_READ_ONLY is not a valid value for that anyway). But you do need to replace GL_WRITE_ONLY with GL_READ_ONLY in the glMapBuffer call.  

---

## 0 answers

