我有一个Unity项目,其中我正在通过计算着色器中的AppendStructuredBuffer<Triangle>
写入Append(triangle)
。
在这种情况下,我知道可能存在的三角形数量的理论限制,因此显而易见的正确方法是相应地调整缓冲区的大小。不过,作为黑客,我正在尝试分配大得多的缓冲区,以便可以由系统的其他部分更有效地处理它们(尤其是读回CPU)。人们可能会想到其他情况,在这些情况下可能不知道或可能会错误地假定特定限制。
显然,这有潜在危险。我敢肯定,在不牺牲性能的前提下,有一些更健壮的方法可以用于我当前的系统(或更广泛地说),但是我并没有(尤其是)寻求建议。
我想知道的是,程序调用{{1}}超出了此类缓冲区的容量时,预期的行为是什么。我认为它是未定义的,并且可能会损坏VRAM的其他区域,在某种程度上取决于GPU驱动程序/ DirectX版本等。可能是它是更正式地指定的,但是我无法发现这一点。
当然,即使指定了行为 ,蓄意冒险似乎也有些鲁ck。不过,我想知道:
如果多余的数据将被简单地丢失而没有成本,那么这也许是“安全的”。在任何情况下,该系统都可以(例如)定期检查缓冲区是否已满,并做任何可能需要做的额外的工作……剩下的问题是这种系统的调整有多严重。
答案 0 :(得分:0)
在很多情况下,至少在DirectX中,越界访问被定义为返回0。我仍然不确定写入,但认为有理由相信它们在当前实现中通常是安全的。
5.3.10.2使用无序计数和追加缓冲区
... imm_atomic_alloc和imm_atomic_consume后面的计数器没有 上溢或下溢钳位,并且没有反馈给 有关是否发生上溢/下溢的着色器( 计数器)。计数器真正完成的唯一工作就是 生成独特的地址,并方便地与无人机捆绑在一起。
没有计数的限制,因此溢出时会自动结束。
在这些情况下,我认为将“包装”解释为缓冲区的长度并没有错。
因此,据我所知,答案是内部计数器将在Append()
上包装,随后的调用最终将覆盖较早的数据。碰巧的是,我当前正在渲染缓冲区而未引用此类计数器(因为我再次对“三角形”进行了传递,以将其变为用于渲染的顶点,而我目前在非AppendBuffer上进行了渲染)。我应该尝试将带有计数的缓冲区传递给该绘制调用,这应该允许我验证我的大多数模型在溢出时是否突然消失。
无论如何,从不破坏系统其他部分的角度来看,该操作应该是安全的,但是引用计数器可能是检测问题的错误方法。