首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算着色共享内存包含工件

计算着色共享内存包含工件
EN

Stack Overflow用户
提问于 2016-12-16 01:25:23
回答 1查看 2.1K关注 0票数 5

我一直在尝试写一个通用的计算阴影,高斯模糊的隐写。

它基本上可以工作,但是它包含的工件可以改变每一个帧,即使场景是静态的。我花了几个小时来调试这个。我已经做到了确保不超过边界,展开所有循环,用常量替换制服,但是工件仍然存在。

我在3台不同的机器/GPU(2个nvidia,1个英特尔)上测试了原始代码,它们都产生了相同的结果。模拟使用使用普通C++代码向前和向后执行的工作组执行的代码的展开/常量版本不会产生这些错误。

通过分配一个96而不是16的共享数组,我可以消除大部分工件。

这让我觉得我错过了一个逻辑错误,所以我成功地制作了一个非常简单的着色器,它仍然在较小的范围内产生错误,如果有人能指出原因,我会很感激的。我查过很多文件,没有发现任何不正确的地方。

分配一个16x48浮点数的共享数组,这是3072字节,大约是最小共享内存限制的10%。

着色器是在16x16工作组中启动的,因此每个线程将写入3个唯一的位置,并从一个唯一的位置读取数据。

纹理将呈现为HSV,0-1之间的值将映射为0-360色调(红色-青色-红色),超出界限的值将为红色。

代码语言:javascript
复制
#version 430
//Execute in 16x16 sized thread blocks
layout(local_size_x=16,local_size_y=16) in;
uniform layout (r32f) restrict writeonly image2D _imageOut;
shared float hoz[16][48];
void main () 
{
    //Init shared memory with a big out of bounds value we can identify
    hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = 20000.0f;
    hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+16] = 20000.0f;
    hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+32] = 20000.0f;
    //Sync shared memory
    memoryBarrierShared();
    //Write the values we want to actually read back
    hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = 0.5f;
    hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+16] = 0.5f;
    hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+32] = 0.5f;
    //Sync shared memory
    memoryBarrierShared();
    //i=0,8,16 work
    //i=1-7,9-5,17 don't work (haven't bothered testing further
    const int i = 17;
    imageStore(_imageOut, ivec2(gl_GlobalInvocationID.xy), vec4(hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+i]));
    //Sync shared memory (can't hurt)
    memoryBarrierShared();
}

以大于8x8的发射尺寸启动此着色器会在图像的受影响区域产生伪影。

glDispatchCompute(9, 9, 0); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

我不得不用断点和步长帧来捕捉这个,大约有14帧。

glDispatchCompute(512/16, 512/16, 0);//Full image is 512x512 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

同样,当运行在60 and (vsync)工件时,我不得不断点和步骤帧来捕获它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-16 01:37:07

memoryBarrierShared();

不,这只会使写入对其他调用可见。如果希望能够从其他调用的数据中读取数据,则必须确保所有的写操作都已经发生。

这是用 function完成的。它应该在memoryBarrierShared之后调用。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41175954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档