首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新SSBO内容

更新SSBO内容
EN

Stack Overflow用户
提问于 2018-08-17 16:42:20
回答 1查看 754关注 0票数 2

我试图在计算阴影上做一个简单的计算,在做了一轮计算之后,我把这一轮的结果作为第二轮的输入返回给阴影。

我的电脑着色器是这样的:

代码语言:javascript
复制
#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];

}

她是我的OpenGL代码:

代码语言:javascript
复制
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;
}

初始化ssbo并调用glDispatchCompute()glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)之后,我读出结果并将其保存在std::vector<float>result_container中。这将为容器填充1.0f,正如第一次运行时所期望的那样,ssbo_result.handle使用out_picture ssbo

然后,我尝试将结果作为输入输入到out_picture中,就像我通过翻转memcpy中的内存和源来读取数据一样,因为我了解到,我现在在out_picture GPU内存中有了以前的结果。

如您所见,我正试图向out_picture中添加一个值(这里为1.0f),并将其作为下一次计算的out_picture输入。其想法是将结果添加为下一次运行的输入。我试着用glCopyBufferSubData做同样的事情,结果是一样的。每次只有1.0作为输出,而不是1,2,3.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-17 19:52:59

在while循环中,在启动计算着色器之后,绑定到绑定点:

代码语言:javascript
复制
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);
    ....
} 

但是ssbo_result.handle再也不会绑定到绑定点了。这导致计算只在循环的第一个周期中运行,因为绑定到着色器存储缓冲区的绑定在循环的进一步循环中被中断。

中断缓冲区的绑定是完全多余的,因为绑定点不用于任何其他事情。

删除循环中的行glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);,解决问题。(当然,在while循环开始时继续绑定缓冲区,也可以在glDispatchCompute之前添加glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo_result.handle); )

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51899747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档