1

我正在尝试将大量数据传递给我的片段着色器,但是当我尝试编译和链接着色器时,glLinkProgram 会停止并永远挂起(没有引发错误,除了黑屏之外什么都没有发生)片段着色器成功编译,并且也成功连接。使用我的调试器单步执行它会触发glLinkProgram调用,然后就停止了,就好像它正在等待它完成一样。如果我为结构内的数组设置较小的大小,则程序运行时不会挂起。我在文档中找不到关于内部结构数组大小限制的任何内容,所以我很好奇是什么原因造成的?

着色器.frag

#version 460 core
#extension GL_NV_gpu_shader5 : enable

// Program hanging is caused by this size
const int MAX_NODE_POOLS = 0xFFFF;

struct Node
{
    int data;
};

struct NodeMask
{
    uint8_t leaf;
    uint8_t nonLeaf;
};

struct NodePool
{
    Node mNodes[8];
};

struct Block
{
    uint16_t ID;
    NodePool mNodePools[MAX_NODE_POOLS];
    NodeMask mNodeMasks[MAX_NODE_POOLS];
};

layout (std430, binding=2) buffer octreeData
{
    Block blocks[];
};
...

着色器.vert

#version 460 core
layout (location = 0) in vec2 position;

void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
}

和我的着色器编译代码

bool Shader::loadShaders(const char *vertexPath, const char *fragmentPath)
{
    // 1. retrieve the vertex/fragment source code from filePath
    std::string vertexCode;
    std::string fragmentCode;
    std::ifstream vShaderFile;
    std::ifstream fShaderFile;
    bool err = false;

    vShaderFile.open(vertexPath);
    fShaderFile.open(fragmentPath);
    if(!vShaderFile.is_open())
    {
        fprintf(stderr, "Error opening vertex shader: %s\n", vertexPath);
        err = true;
    }
    if(!fShaderFile.is_open())
    {
        fprintf(stderr, "Error opening fragment shader: %s\n", fragmentPath);
        err = true;
    }
    

    std::stringstream vShaderStream, fShaderStream;
    // read file's buffer contents into streams
    vShaderStream << vShaderFile.rdbuf();
    fShaderStream << fShaderFile.rdbuf();
    // close file handlers
    vShaderFile.close();
    fShaderFile.close();
    // convert stream into string
    vertexCode = vShaderStream.str();
    fragmentCode = fShaderStream.str();

    const char* vShaderCode = vertexCode.c_str();
    const char * fShaderCode = fragmentCode.c_str();

    // 2. compile shaders
    unsigned int vertex, fragment;
    // vertex shader
    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vShaderCode, NULL);
    glCompileShader(vertex);
    if(!checkCompileErrors(vertex, "VERTEX", std::string()))
        err = true;
    // fragment Shader
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment, 1, &fShaderCode, NULL);
    glCompileShader(fragment);
    if(!checkCompileErrors(fragment, "FRAGMENT", std::string()))
        err = true;
    // shader Program
    ID = glCreateProgram();
    glAttachShader(ID, vertex);
    glAttachShader(ID, fragment);
/*** Program hangs forever here ***/
    glLinkProgram(ID);
    if(!checkCompileErrors(ID, "PROGRAM", std::string()))
        err = true;
    // delete the shaders as they're linked into our program now and no longer necessery
    glDeleteShader(vertex);
    glDeleteShader(fragment);

    if(err)
        return false;

    return true;
}

添加我的checkCompileErrors函数以显示我们不会意外丢失链接/编译错误。

GLint Shader::checkCompileErrors(GLuint shader, const std::string &type, const std::string &name)
{
    GLint success;
    GLchar infoLog[1024];
    if (type != "PROGRAM")
    {
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(shader, 1024, NULL, infoLog);
            std::cerr << name << std::endl;
            fprintf(stderr, "ERROR::SHADER_COMPILATION_ERROR of type: %s\n%s -- --------------------------------------------------- -- \n", type.c_str(), infoLog);
        }
    }
    else
    {
        glGetProgramiv(shader, GL_LINK_STATUS, &success);
        if (!success)
        {
            std::cerr << name << std::endl;
            glGetProgramInfoLog(shader, 1024, NULL, infoLog);
            fprintf(stderr, "ERROR::PROGRAM_LINKING_ERROR of type: %s\n%s -- --------------------------------------------------- -- \n", type.c_str(), infoLog);
        }
    }
    return success;     
}

还查询我的 GL_MAX_SHADER_STORAGE_BLOCK_SIZE 给我一个大小:2147483647字节(2.15 GB)。我尝试发送的数据大小为 131.748 MB

这里有什么问题?显然这是由于数组大小很大,但我该如何解决这个问题?

4

0 回答 0