Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
570 views
in Technique[技术] by (71.8m points)

c++ - Only first Compute Shader array element appears updated

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
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);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...