Blank
Blank

Reputation: 57

Updateing SSBO Contents

I am trying to do a simple calculation on a Compute Shader, where after doing one round of computation I give the result of that round back to the Shader as an Input for the second round.

My Compute shader looks like this:

#version 440 core

layout(std430, binding = 0) buffer Result{
  float out_picture[];
};
layout(std430, binding = 1) buffer In_p1{
  float in_p1[];
};
layout(local_size_x = 1000) in;

void main() {
  in_p1[gl_GlobalInvocationID.x] = 1.0f;
  out_picture[gl_GlobalInvocationID.x] = out_picture[gl_GlobalInvocationID.x] + in_p1[gl_GlobalInvocationID.x];

}

Her is my OpenGL code:

int main(int argc, char* argv[]) {

    std::vector<float> result_container;
    std::vector<SSBO> ssbo_container;
    SSBO ssbo_result;

    ssbo_result.NUM_PIX = 1920*1080*4;
    ssbo_result.WORK_GROUP_SIZE = 1000;
    result_container.reserve(ssbo_result.NUM_PIX * sizeof(float));

    glGenBuffers(1, &ssbo_result.handle);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo_result.handle);
    glBufferData(GL_SHADER_STORAGE_BUFFER, ssbo_result.NUM_PIX * sizeof(float), NULL, GL_DYNAMIC_DRAW);

    for(unsigned int i = 1; i < 2; i++){
      SSBO ssbo;
      glGenBuffers(1, &ssbo.handle);
      glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, ssbo.handle);
      glBufferData(GL_SHADER_STORAGE_BUFFER, ssbo_result.NUM_PIX * sizeof(float), NULL, GL_DYNAMIC_DRAW);
      ssbo_container.push_back(ssbo);
    }

    while (!g_win.shouldClose()) {

      std::cout << "container:" << result_container[0] << std::endl;

      glUseProgram(g_avg_program);
      glDispatchCompute(ssbo_result.NUM_PIX / ssbo_result.WORK_GROUP_SIZE, 1, 1);
      glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
      glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);

      glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_result.handle);
      GLfloat *ptr = (GLfloat *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
      memcpy(result_container.data(), ptr, ssbo_result.NUM_PIX * sizeof(float));
      glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

      glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_result.handle);
      ptr = (GLfloat *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
      memcpy(ptr, result_container.data(), ssbo_result.NUM_PIX * sizeof(float));
      glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);


      g_win.update();
      if (glfwGetKey(g_win.getGLFWwindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS) {
        g_win.stop();
      }
    }
    return 0;
}

After initializing the ssbo's and calling glDispatchCompute() and glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT) I read out the result and saving it in std::vector<float>result_container. This fills the container with 1.0f as expected for the first run, ssbo_result.handle beeing my out_picture ssbo

I then try feeding the result back in as an input into out_picture the same way I read the data out of it by just flipping the memcpy dest and source, as I understand it that I now have my previous result in the out_picture GPU Memory

As you can see I am trying to add a value (here 1.0f) to the out_picture and feed it back as an input into out_picture for the next computation. The Idea is to just add the result as an input for the next run. I tryed doing the same with glCopyBufferSubData with the same outcome. Only 1.0 as output everytime instead of a 1, 2, 3 ...

Upvotes: 2

Views: 1212

Answers (1)

Rabbid76
Rabbid76

Reputation: 210998

In the while loop 0 is bound to the binding point 0, after the compute shader was launched:

while (!g_win.shouldClose()) {

    ....
    glDispatchCompute(ssbo_result.NUM_PIX / ssbo_result.WORK_GROUP_SIZE, 1, 1);
    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
    ....
} 

but ssbo_result.handle is never bound to the binding point 0 again. This causes that the computation operates only in the first cycle of the loop, because the binding to the shader storage buffer is broken in the further cycles of the loop.

It is completely superfluous to break the binding of the buffer, since the binding point is not used for anything else.

Delete the line glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); in the loop, to solve the issue. (Of course binding the buffer continuously at the begin of the while loop, would do the job, too - add glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo_result.handle); before glDispatchCompute)

Upvotes: 1

Related Questions