【问题标题】:Why doesn't the compute shader do the calculation?为什么计算着色器不进行计算?
【发布时间】:2021-05-25 10:36:36
【问题描述】:

我正在试验计算着色器。我想要做的是将arr1的数据发送到计算着色器变量shader_arr1 [],使其所有元素为1并将结果读回arr2 []变量中的CPU端。但是,运行以下程序,我在 arr2[] 中得到了相同的 arr1[]{1,2,3,4,5,6,7} 初始值,没有任何改变。你能告诉我我做错了什么吗?

        GLuint program = glCreateProgram();
        GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);

        const GLchar* const shaderSrc = {
            "#version 310 es\n"
            "\n"
            "layout (local_size_x = 1) in;\n"
            "layout(std430, binding = 0) writeonly buffer SSBO {\n"
            "   int shader_arr1[];\n"
            "};\n"
            "void main(void)\n"
            "{\n"
            "   shader_arr1[gl_GlobalInvocationID.x] = 1;\n"
            "}\n"
        };

        glShaderSource(computeShader, 1, &shaderSrc, NULL);
        glCompileShader(computeShader);
        int result;
        glGetShaderiv(computeShader, GL_COMPILE_STATUS, &result);

        if(result == GL_FALSE){
            int length;
            glGetShaderiv(computeShader, GL_INFO_LOG_LENGTH, &length);
            char* message = static_cast<char*>(malloc(length));
            glGetShaderInfoLog(computeShader, length, &length, message);
            __android_log_print(ANDROID_LOG_INFO, "MyLog", "Shader Compile Error:  %s", message);
            free(message);
        }


        GL_CALL(glAttachShader(program, computeShader));
        GL_CALL(glLinkProgram(program));
        GL_CALL(glValidateProgram(program));
        GL_CALL(glUseProgram(program));

        GLuint buff1Id, buff2Id;
        glGenBuffers(1, &buff1Id);
        glGenBuffers(1, &buff2Id);
        GLint arr1[7] = {1, 2, 3, 4, 5, 6, 7};
        GLint arr2[7];
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff1Id);
        //glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff2Id);
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0, buff1Id);
        glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(arr1), arr1, GL_DYNAMIC_DRAW);
        //glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(arr2), arr2, GL_DYNAMIC_DRAW);

        GL_CALL(glDispatchCompute(1, 1, 1));
        GL_CALL(glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT));

//        GL_CALL(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buff2Id));
//        GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff2Id));

        GLint* data = static_cast<GLint*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 7,GL_MAP_READ_BIT));
        for(int i = 0; i < 7; ++i) {
            arr2[i] = data[i];
            __android_log_print(ANDROID_LOG_INFO, "MyLog", "Num %d", arr2[i]);
        }
        glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

【问题讨论】:

  • 旁注。您应该为着色器代码使用 C++11 原始字符串。
  • 是的,我以前也是这样的。

标签: c++ opengl-es compute-shader


【解决方案1】:

我修复了代码。这是程序的工作版本

        GLuint program = glCreateProgram();
        GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);

        const GLchar* const shaderSrc = {
            "#version 310 es\n"
            "\n"
            "layout (local_size_x = 1) in;\n"
            "layout(std430, binding = 0) writeonly buffer SSBO1 {\n"
            "   int shader_arr1[];\n"
            "};\n"
            "void main(void)\n"
            "{\n"
            "   shader_arr1[gl_GlobalInvocationID.x] = 1;\n"
            "}\n"
        };

        glShaderSource(computeShader, 1, &shaderSrc, NULL);
        glCompileShader(computeShader);
        int result;
        glGetShaderiv(computeShader, GL_COMPILE_STATUS, &result);

        if(result == GL_FALSE){
            int length;
            glGetShaderiv(computeShader, GL_INFO_LOG_LENGTH, &length);
            char* message = static_cast<char*>(malloc(length));
            glGetShaderInfoLog(computeShader, length, &length, message);
            __android_log_print(ANDROID_LOG_INFO, "MyLog", "Shader Compile Error:  %s", message);
            free(message);
        }


        GL_CALL(glAttachShader(program, computeShader));
        GL_CALL(glLinkProgram(program));
        GL_CALL(glValidateProgram(program));
        GL_CALL(glUseProgram(program));

        GLuint buff1Id, buff2Id;
        GL_CALL(glGenBuffers(1, &buff1Id));
        GL_CALL(glGenBuffers(1, &buff2Id));
        GLint arr1[7] = {1, 2, 3, 4, 5, 6, 7};
        GLint arr2[7];
        GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff1Id));
        GL_CALL(glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0, buff1Id));
        GL_CALL(glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(arr1), arr1, GL_DYNAMIC_DRAW));

        GL_CALL(glDispatchCompute(7, 1, 1));
        GL_CALL(glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT));

        GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0));
        GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff1Id));
        GL_CALL(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buff1Id));

        GLint* data = static_cast<GLint*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLint) * 7,GL_MAP_READ_BIT));
        for(int i = 0; i < 7; ++i) {
            arr2[i] = data[i];
            __android_log_print(ANDROID_LOG_INFO, "MyLog", "Num %d", arr2[i]);
        }
        glUnmapBuffer(GL_SHADER_STORAGE_BUFFER

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-24
    • 2016-09-29
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多