在计算着色器中更新 SSBO
Update SSBO in Compute shader
我目前正在尝试将 SSBO linked/bound 更新为 Computeshader。这样做,我只将第一个 32 字节写入 out_picture
,因为我只有 memcpy
那么多 (sizeof(pstruct)
).
计算着色器:
#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
调用拆分为数组和浮点数?如果是的话怎么办?我可以复制第一部分,但不允许我向 ptr
.
添加偏移量
首先,
float picture[1920*1080*3];
显然应该是纹理(无论如何你只是从中读取)或至少是图像。
第二个:
struct Pstruct{
std::vector<float> picture;
float factor;
};
这个定义在任何方面都不符合你着色器中的定义。 std::vector
对象只是一个元对象,在内部管理向量使用的数据存储。 memcpy
将其传递给 GL 缓冲区并将其传递给 GPU 根本没有意义。
正确的方法是将该向量的 contents 单独复制到缓冲区内的适当位置,或者只在客户端给我们一个结构定义,实际上匹配您在着色器中使用的那个(并考虑 std430
的所有规则)。但是,正如我的第一点已经指出的那样,这里的正确解决方案最有可能改用纹理或图像对象。
我目前正在尝试将 SSBO linked/bound 更新为 Computeshader。这样做,我只将第一个 32 字节写入 out_picture
,因为我只有 memcpy
那么多 (sizeof(pstruct)
).
计算着色器:
#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
调用拆分为数组和浮点数?如果是的话怎么办?我可以复制第一部分,但不允许我向 ptr
.
首先,
float picture[1920*1080*3];
显然应该是纹理(无论如何你只是从中读取)或至少是图像。
第二个:
struct Pstruct{ std::vector<float> picture; float factor; };
这个定义在任何方面都不符合你着色器中的定义。 std::vector
对象只是一个元对象,在内部管理向量使用的数据存储。 memcpy
将其传递给 GL 缓冲区并将其传递给 GPU 根本没有意义。
正确的方法是将该向量的 contents 单独复制到缓冲区内的适当位置,或者只在客户端给我们一个结构定义,实际上匹配您在着色器中使用的那个(并考虑 std430
的所有规则)。但是,正如我的第一点已经指出的那样,这里的正确解决方案最有可能改用纹理或图像对象。