我当前正在尝试更新链接/绑定到Computeshader的SSBO。这样,我只将前32个字节写入out_picture
,因为我只memcpy
个那么多(sizeof(pstruct)
)。
Computeshader:
#version 440 core
struct Pstruct{
float picture[1920*1080*3];
float factor;
};
layout(std430, binding = 0) buffer Result{
float out_picture[];
};
layout(std430, binding = 1) buffer In_p1{
Pstruct in_p1;
};
layout(local_size_x = 1000) in;
void main() {
out_picture[gl_GlobalInvocationID.x] = out_picture[gl_GlobalInvocationID.x] +
in_p1.picture[gl_GlobalInvocationID.x] * in_p1.factor;
}
GLSL:
struct Pstruct{
std::vector<float> picture;
float factor;
};
Pstruct tmp;
tmp.factor = 1.0f;
for(int i = 0; i < getNUM_PIX(); i++){
tmp.picture.push_back(5.0f);
}
SSBO ssbo;
glGenBuffers(1, &ssbo.handle);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo.handle);
glBufferData(GL_SHADER_STORAGE_BUFFER, (getNUM_PIX() + 1) * sizeof(float), NULL, GL_DYNAMIC_DRAW);
...
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo.handle);
Pstruct* ptr = (Pstruct *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
memcpy(ptr, &pstruct, sizeof(pstruct));
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
...
glUseProgram(program);
glDispatchCompute(getNUM_PIX() / getWORK_GROUP_SIZE(), 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
如何同时复制picture array
和float factor
?
我是否必须将memcpy
调用拆分为array和float?如果是的话如何?我可以复制第一部分,但是不允许向ptr
添加偏移量。
答案 0 :(得分:1)
首先
显然,float picture[1920*1080*3];
应该是纹理(无论如何也只能从中读取)或至少是图像。
第二:
struct Pstruct{ std::vector<float> picture; float factor; };
此定义与着色器中的定义完全不匹配。 std::vector
对象将只是内部管理矢量使用的数据存储的元对象。 memcpy
传递给GL缓冲区并将其传递给GPU根本没有任何意义。
正确的方法是将向量的 contents 分别复制到缓冲区内的适当位置,或者只给我们一个客户端上的结构定义,该定义实际上与您的结构匹配在着色器中重新使用(并考虑std430
的所有规则)。但是,正如我首先提到的那样,这里的正确解决方案最有可能使用纹理或图像对象代替。