DirectX 12 是否消除了纹理图集的需要?

Does DirectX 12 eliminate the need for texture atlasing?

我记得当我看到关于 DirectX 12 的最初讨论时,我认为它消除了对纹理图集的需要。但是,现在我正在阅读文档,结论似乎并不那么明显。

我看到的一个可以替代它的功能是 HLSL 中资源数组的动态非统一索引:

Texture2D<float4> textures[128];
SamplerState sampler;

textures[NonUniformResourceIndex(textureIndex)].Sample(sampler, uv);

另一个潜在的功能是 ExecuteIndirect,它将仍然是一堆单独的绘制和资源更改调用编码到缓冲区,并在单个 CPU 调用中立即将其提交给 GPU .

这两者都将解决纹理图集的局限性(无法在图集区域上使用边界模式,有问​​题的 mipmap),但我想知道性能特征或预期是否与纹理图集相似,或者该技术是否还是有道理的。

我也很想知道答案是否适用于 Mantle、Vulkan 和 Metal。

简短的回答是肯定的,长的回答是也许在某些情况下 atlas 会有轻微的性能优势。

有了 DX12 和 Vulkan,您就可以忘掉 Mantle。当前带有描述符的纹理表示接近于金属,使用无绑定不会涉及太多性能损失,并且常规纹理或无绑定纹理的纹理获取在当前硬件上是相同的,并且可能会更好未来,因为这是要走的路。

在 nVidia 上,绝对没有惩罚,并且 NonUniformResourceIndex 不是他们架构的要求,bindless 就可以工作。

在 AMD 上,NonUniformResourceIndex 具有着色器代码生成含义,如果将它们相乘可能会产生成本,最好避免它们。理想情况下,您不要一次使用多个索引(在一个实例或跨实例中)使用绘制调用。这是因为 GPU 使用矢量和标量寄存器的组合。纹理和采样器描述符被加载到标量寄存器中。如果你的纹理有不同的索引,它就不能正常工作。 NonUniformResourceIndex 的作用是在活动线程上生成一个循环,使用索引,为它屏蔽线程并执行获取,循环直到它处理完所有线程。但是忽略这些考虑,无绑定纹理使用与常规绑定相同的系统。

ExecuteIndirect也是一个很好的交易,现在在驱动方面并不是一直都完美优化,但是随着DX12引擎的游戏越来越多,它会有所改善。 API 是 gpu 剔除和许多解决方案的大门,可以进一步减少 cpu 的工作。在 Xbox One 上,甚至可以用它更改 PipelineStateObject