Only first Compute Shader array element appears up

2019-01-29 03:25发布

Trying to send an array of integer to a compute shader, sets an arbitrary value to each integer and then reads back on CPU/HOST. The problem is that only the first element of my array gets updated. My array is initialized with all elements = 5 in the CPU, then I try to sets all the values to 2 in the Compute Shader:

C++ Code:

   this->numOfElements = std::vector<int> numOfElements; //num of elements for each voxel

   //Set the reset grid program as current program
    glUseProgram(this->resetGridProgHandle);

    //Binds and fill the buffer 
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, this->counterBufferHandle);
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * numOfVoxels, this->numOfElements.data(), GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, this->counterBufferHandle);

    //Flag used in the buffer map function
    GLint bufMask = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;

    //calc maximum size for workgroups
    //glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_SIZE, &result);

    //Executes the compute shader
    glDispatchCompute(32, 1, 1); // 
    glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);

    //Gets a pointer to the returned data
    int* returnArray = (int *)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_WRITE);

    //Free the buffer mapping
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

Shader:

#version 430
layout (local_size_x = 32) in;
layout(binding = 0) buffer SSBO{
    int counter[];
};

void main(){
    counter[gl_WorkGroupID.x * gl_WorkGroupSize.x + gl_LocalInvocationID.x] = 2;
}

If I print returnArray[0] it's 2 (correct), but any index > 0 gives me 5, which is the initial value initialized in host.

1条回答
时光不老,我们不散
2楼-- · 2019-01-29 04:01
glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);

//Gets a pointer to the returned data
int* returnArray = (int *)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_WRITE);

The bit you use for glMemoryBarrier represents the way you want to read the data written by the shader. GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT says "I'm going to read this written data by using the buffer for vertex attribute arrays". In reality, you are going to read the buffer by mapping it.

So you should use the proper barrier bit:

glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
查看更多
登录 后发表回答