有人可以帮助检查为什么此OpenGL计算着色器在我的Nvidia GT440,Windows 7 64bit上导致APPCRASH吗?我想了解GLSL中定义的内存顺序,因此我编写了这个简单的着色器。我认为着色器代码没有任何问题。
image0,image1和output_image的大小均为1024x768。 output_image仅用于检查结果是否正确。
工作组大小为16x16。在X / Y / Z维度中启动的工作组数为1024 / 16、768 / 16和1,即glDispatchCompute(64, 48, 1)
。如果调用ID的x索引是偶数,它将设置image0的像素(x,y),然后设置image1。如果调用ID的x索引为奇数,则读取image1并等待,直到设置了image1的相应像素(x-1,y),然后读取image0。
#version 450 core
layout (local_size_x = 16, local_size_y = 16) in;
layout (binding = 0, rgba8ui) uniform uimage2D output_image;
layout (binding = 1, r32ui) uniform volatile coherent uimage2D image0;
layout (binding = 2, r32ui) uniform volatile coherent uimage2D image1;
void main(void)
{
// thread 0 of each work group clears a portion of output image
if (gl_LocalInvocationIndex == 0) {
uvec2 start = gl_WorkGroupSize.xy * gl_WorkGroupID.xy;
for (uint j = start.y; j < start.y + gl_WorkGroupSize.y; ++j)
for (uint i = start.x; i < start.x + gl_WorkGroupSize.x; ++i)
imageStore(output_image, ivec2(i, j), uvec4(0));
}
barrier();
if (gl_GlobalInvocationID.x % 2 == 0) {
// store to image0, then image1
imageStore(image0, ivec2(gl_GlobalInvocationID.xy), uvec4(1));
imageStore(image1, ivec2(gl_GlobalInvocationID.xy), uvec4(1));
}
else {
ivec2 coord = ivec2(gl_GlobalInvocationID.xy) - ivec2(1, 0);
// wait for image1 to be set
uint flag;
do {
flag = imageLoad(image1, coord).x;
}
while (flag != 1);
// check if image0 is set
uint color = imageLoad(image0, coord).x * 255;
// write output image
imageStore(output_image, coord, uvec4(flag));
imageStore(output_image, ivec2(gl_GlobalInvocationID.xy), uvec4(color));
}
}