循环RWTexture2D(DirectX11,SM5)时设置两个像素时,计算着色器将挂起

时间:2018-09-27 02:15:37

标签: directx shader directx-11 hlsl compute-shader

我正在尝试在计算着色器(DirectCompute)上执行一些基本的元胞自动机,但是没有双重缓冲,所以我正在对数据的RWTexture2D<uint>使用无序访问视图,但是我确实有一些奇怪的挂起/崩溃,我可以制作一个很小的片段来产生问题:

int w = 256;
for (int x = 0; x < w; ++x)
{
    for (int y = 1; y < w; ++y)
    {
        if (map[int2(x, y - 1)])
        {
            map[int2(x, y)] = 10;
            map[int2(x, y-1)] = 30;
        }
    }
}

其中mapRWTexture2D<uint>

如果我删除if或其中的一项分配,它可以工作,我认为这可能是一种限制,所以我尝试仅循环1/4纹理,但问题仍然存在。该代码以(1,1,1)分派,内核numthreads也为(1,1,1),在我的实际场景中,我想从下往上循环并填充空白(0与我当前正在循环播放的像素(考虑到“落沙”类的效果)一样,因此除了在列中,它不能平行,因为它取决于底部像素。

我不明白是什么原因导致着色器挂起,没有任何错误或任何东西,它只是挂起,甚至从未超时。

编辑: 经过进一步的调查,我发现了一些非常有趣的东西。当我在常量缓冲区中传递该w值时,一切正常。我不知道会导致什么,也许是编译优化出了问题,也许它试图展开循环导致了什么问题,然后将值传递到常量缓冲区中会禁用它,但是我在调​​试时编译了着色器没有优化,所以我不知道。

1 个答案:

答案 0 :(得分:0)

像以前这样,我在声明全局范围内的变量时遇到了问题。我相信这是因为它不是静态const(因此声明为静态const,它应该可以工作)。最有可能的是,它将其视为常量缓冲区(带有一些默认命名),并且内容未定义,因为您未绑定缓冲区,这会导致未定义的结果。因此,以下代码应该起作用:

static const int w = 256;
for (int x = 0; x < w; ++x)
{
    for (int y = 1; y < w; ++y)
    {
        if (map[int2(x, y - 1)])
        {
            map[int2(x, y)] = 10;
            map[int2(x, y-1)] = 30;
        }
    }
}