GLSL Compute Shader未修改缓冲区问题求助
问题:Compute Shader未修改目标缓冲区(WSL+Mesa环境)
环境说明
- 开发库:OpenGL、GLFW、GLEW、GLM
- 运行环境:Windows子系统(WSL)搭配Mesa
- 硬件:NVIDIA 4060 Ti(驱动为最新版本)
- 现象:编写的Compute Shader未按预期修改目标缓冲区,读取到的是随机垃圾值(或全零、NaN)
完整代码
主文件与glew.c放在src目录,GLM置于include目录:
#include <iostream> #include <cstring> #include <GLFW/glfw3.h> #include "glm.hpp" #include <GL/gl.h> int main(int argc, char **argv) { //Window width and height int window_w = 640, window_h = 480; printf("Startup\n"); //Init and create window glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, false); glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); std::cout << "Trying to create window" << std::endl; GLFWwindow* window = glfwCreateWindow(window_w, window_h, "Marching Cubes", nullptr, nullptr); std::cout << "Just tried to create window\n" << std::endl; if (window == nullptr) { std::cerr << "Failed to create GLFW window" << std::endl; glfwTerminate(); exit(EXIT_FAILURE); } else { std::cerr << "Succeeded at creating window" << std::endl; } //More init glfwMakeContextCurrent(window); printf("Made the window the current context\n"); glEnable ( GL_DEBUG_OUTPUT ); glewInit(); // The buffer for use in the compute shader uint32_t buffer_vertices; uint32_t buffer_size = 10; glCreateBuffers(1, &buffer_vertices); glNamedBufferStorage(buffer_vertices, buffer_size, nullptr, GL_DYNAMIC_STORAGE_BIT); printf("Buffers have been created\n"); // Create the VAO for drawing the resulting triangles uint32_t vao_draw; glCreateVertexArrays(1, &vao_draw); glEnableVertexArrayAttrib(vao_draw, 0); glEnableVertexArrayAttrib(vao_draw, 1); glVertexArrayVertexBuffer(vao_draw, 0, buffer_vertices, 0, sizeof(glm::vec4)); glVertexArrayAttribFormat(vao_draw, 0, 4, GL_FLOAT, false, 0); glVertexArrayAttribFormat(vao_draw, 1, 4, GL_FLOAT, false, 0); glVertexArrayAttribBinding(vao_draw, 0, 0); glVertexArrayAttribBinding(vao_draw, 1, 1); std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; glClearColor(1.0, 1.0, 1.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_TRIANGLES); // The compute shader char* smcsource = "\ #version 430\n\ \n\ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\ \n\ layout(std430, binding = 0) buffer u_buffer_vertices\n\ {\n\ vec4 output_vertices[];\n\ };\n\ \n\ \n\ void main() {\n\ for (float i = 0.0; i < 10.0; i++) output_vertices[int(i)] = vec4(i,i,i,i);\n\ }\n\ "; //Compile the shader GLint length = strlen(smcsource); GLuint compute_shader = glCreateShader(GL_COMPUTE_SHADER); glShaderSource(compute_shader, 1, &smcsource, &length); glCompileShader(compute_shader); GLint smcsuccess = 0; glGetShaderiv(compute_shader, GL_COMPILE_STATUS, &smcsuccess); GLuint smcprogram; if (smcsuccess) { printf("Successfully compiled\n"); smcprogram = glCreateProgram(); glAttachShader(smcprogram, compute_shader); glLinkProgram(smcprogram); GLint TotalLength = 0; glGetShaderiv(compute_shader, GL_INFO_LOG_LENGTH, &TotalLength); std::string logs; logs.resize(TotalLength); glGetShaderInfoLog(compute_shader, TotalLength, NULL, &logs[0]); std::cout << "Shader output log:\n" << logs << std::endl; } else { printf("Failed compile\n"); GLint TotalLength = 0; glGetShaderiv(compute_shader, GL_INFO_LOG_LENGTH, &TotalLength); std::string logs; logs.resize(TotalLength); glGetShaderInfoLog(compute_shader, TotalLength, NULL, &logs[0]); std::cout << "Shader output log:\n" << logs << std::endl; } //Select shader glUseProgram(smcprogram); //Bind buffer glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer_vertices); printf("Buffer binded\n"); //Run shader. Problem happens here: nothing happens to the buffer when I run this glDispatchCompute(1, 1, 1); glMemoryBarrier(GL_ALL_BARRIER_BITS); //Test and print the buffer data //If this is working as intended, it should count up in groups of four, something like: //0.0 0.0 0.0 0.0 | 1.0 1.0 1.0 1.0 | 2.0 2.0 2.0 2.0 | 3.0 3.0 3.0 3.0 | etc. glm::vec4 vertices[16]; glGetBufferSubData(buffer_vertices, 0, 16, &vertices); printf("Vertex data after: "); for (int i = 0; i < 10; i++) printf("%f %f %f %f | ", vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3]); printf("\n"); glEnd(); glfwSwapBuffers(window); return 0; }
编译命令
g++ src/main.cpp src/glew.c -Iinclude -lGLEW -lglut -lglfw -lGL -lX11 -lc -o shader-compiler-bug
预期输出
0.0 0.0 0.0 0.0 | 1.0 1.0 1.0 1.0 | 2.0 2.0 2.0 2.0 | 3.0 3.0 3.0 3.0 | [以此类推到第10组]
实际输出
每次运行结果不同,多为随机垃圾值,示例:
-11653242706460672.000000 0.000000 0.000000 0.000000 | -496068722688.000000 0.000000 -496183017472.000000 0.000000 | -496015245312.000000 0.000000 -496055091200.000000 0.000000 | -496050896896.000000 0.000000 -496059285504.000000 0.000000 | -496066625536.000000 0.000000 -447767117824.000000 0.000000 | 0.000000 0.000000 0.000000 -0.000000 | 0.000000 0.000000 0.000000 0.000000 | 0.000000 0.000000 0.000000 0.000000 | 0.000000 0.000000 0.000000 0.000000 | -496055091200.000000 0.000000 -496025731072.000000 0.000000 |
内容的提问来源于stack exchange,提问作者kronosta
相关产品推荐
相关产品推荐

