当 AppendStructuredBuffer 在计算着色器中溢出时会发生什么?

What happens when an AppendStructuredBuffer overflows in a compute shader?

我有一个 Unity 项目,我在其中通过计算着色器中的 Append(triangle) 写入 AppendStructuredBuffer<Triangle>

在这种情况下,我知道可能存在的三角形数量的理论限制,因此显然正确的方法是相应地调整缓冲区的大小。不过,作为 hack,我正在尝试分配更小的缓冲区,以便系统的其他部分可以更有效地处理它们(特别是回读 CPU)。可以想象在其他情况下可能不知道或错误地假设了特定限制。

显然,这是有潜在危险的。我确信有更强大的方法可以用于我当前的系统(或更一般地)而不牺牲性能,但我不是(特别是)就此寻求建议。

我想知道的是,当程序调用 Append() 超出此类缓冲区的容量时,预期的行为是什么。我想它是未定义的,并且可能会破坏 VRAM 的其他区域,在某种程度上取决于 GPU 驱动程序/DirectX 版本等。它可能是更正式指定的,但我一直无法找到它.

当然,即使行为指定的,故意冒险似乎有些鲁莽。不过,我想知道:

也许是'safe'到这样的程度,多余的数据会毫无代价地简单地丢失到虚无中。在任何情况下,系统都可以 - 例如 - 定期检查缓冲区的完整性并做任何可能需要的额外家务......留下这样一个系统调整中的任何错误可能有多严重的问题。

在许多情况下,至少在 DirectX 中,越界访问被定义为返回 0。我仍然不完全确定写入,但认为有理由相信它们在当前实现中通常应该是安全的。

根据this specification

5.3.10.2 Using Unordered Count and Append Buffers

... The counter behind imm_atomic_alloc and imm_atomic_consume has no overflow or underflow clamping, and there is no feedback given to the shader as to whether overflow/underflow happened (wrapping of the counter). The only thing the counter really accomplishes is a way of generating unique addresses that is conveniently bundled with the UAV.

此外,https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#inst_IMM_ATOMIC_ALLOC

There is no clamping of the count, so it wraps on overflow.

在这些情况下,我认为我将 'wrapping' 解释为缓冲区的长度并没有错。

因此,据我了解,答案是在 Append() 时内部计数器将换行,随后的调用将最终覆盖之前的数据。碰巧的是,我目前正在渲染我的缓冲区而不引用这样的计数器(因为我在 'triangles' 上进行了另一次传递以将它们变成用于渲染的顶点,我目前在 non-AppendBuffer 上进行)。我应该尝试将带有计数的缓冲区传递给该绘制调用,这应该允许我验证我的大部分模型是否在我溢出时突然消失。

无论如何,从不破坏系统其他部分的角度来看,该操作似乎应该是安全的,但引用计数器可能是检测问题的错误方法。