使用重复映射的磁贴访问限制

本部分介绍重复映射的磁贴访问限制。

复制源和目标重叠的平铺资源

如果 Copy* 操作的源区域和目标区域中的磁贴在复制区域中具有重复的映射,即使两个资源都不是平铺资源,并且 Copy* 操作支持重叠副本,则 Copy* 操作的行为 (就像在转到目标) 之前将源复制到临时位置一样。 但是,如果重叠不明显(例如,源区域和目标区域虽不同,但共享映射,或者映射复制在特定表面),那么共享磁贴上的复制操作的结果则不明确。

复制到目标区域中具有重复磁贴的平铺资源

复制到目标区域中具有重复磁贴的平铺资源将在这些磁贴中产生未定义的结果,除非数据本身相同:不同的磁贴可能会按不同的顺序写入磁贴。

对重复磁贴映射的 UAV 访问

假设对平铺资源 (UAV) 的无序访问视图在其区域中具有重复的磁贴映射,或者具有绑定到管道的其他资源。 如果由不同线程执行,那么这些重复磁贴的访问排序则不明确,正如内存访问 UAV 的任何排序通常都是无序。

磁贴映射变更或从映射外部更新内容后的渲染

如果平铺资源的磁贴映射已更改,或者映射平铺池磁贴中的内容通过另一个平铺资源的映射发生了更改, 并且将通过呈现目标视图或深度模具视图呈现平铺资源,应用程序必须使用固定函数清除 (清除 API) 或使用复制*/更新* API 完全复制 (映射或不) 呈现区域中已更改的磁贴。 在这种情况下,应用程序无法清除或复制会导致给定呈现目标视图或深度模具视图的硬件优化结构过时,并将导致某些硬件上的垃圾呈现结果和不同硬件之间的不一致。 硬件使用的这些隐藏优化数据结构可能存在于各个映射的本地,并且对相同内存的其他映射不可见。

ID3D11DeviceContext1::ClearView 操作支持使用矩形清除呈现目标视图。 对于支持平铺资源的硬件, ClearView 还必须支持使用矩形清除深度模具视图,对于深度图面 (没有模具) 。 这项操作可让应用程序仅清除表面的必要区域。

如果应用程序需要保留映射已更改的平铺资源中区域的现有内存内容,则该应用程序必须解决明确的要求。 应用程序可以通过将磁贴映射复制到临时图面(例如,使用 ID3D11DeviceContext2::CopyTiles) ,发出所需的清除命令,然后复制回内容)来保存磁贴映射已更改 (的内容来完成此解决方法。 尽管这能够完成保留表面内容的任务,进而实现增量渲染,但缺点是表面上后续的渲染性能会受到影响,因为渲染优化可能会丢失。

如果磁贴同时映射到多个平铺资源,并且通过任何方式操作磁贴内容, (呈现、复制等通过其中一个平铺资源) ,则如果要通过任何其他平铺资源呈现同一磁贴,则必须首先清除磁贴,如前所述。

渲染至在渲染区外共享的磁贴

假设正在将平铺资源中的一个区域呈现到,并且呈现区域引用的磁贴池磁贴也从呈现区域外部映射到, (包括通过其他平铺资源,同时或不) 。 即使底层内存布局兼容,在通过其他映射查看时,渲染至这些磁贴的数据也不一定会正确呈现。 这种现象是因为某些硬件所使用的优化数据结构存在于可渲染表面的各个映射的本地,对相同内存位置的其他映射不可见。 你可从渲染映射复制到可访问的相同内存的所有其他映射(如果不再需要旧内容,则可以清理该内存或将其他数据复制到其中),进而绕开这种限制。 尽管看似多余,但是这种绕开限制的方法可让相同内存的所有其他映射正确了解如何访问其内容,至少保证只需一个物理内存备份所节约的内存的完整性。 此外,在使用共享映射 (的不同平铺资源(除非仅读取) )之间进行切换时,必须在开关之间调用 ID3D11DeviceContext2::TiledResourceBarrier API。

渲染至在渲染区内共享的磁贴

如果平铺资源中的某个区域正在呈现,并且呈现区域中多个磁贴映射到同一磁贴池位置,则呈现结果在这些磁贴上未定义。

跨共享磁贴的平铺资源的数据兼容性

假设多个平铺资源映射到相同的磁贴池位置,并且每个资源都用于访问相同的数据。 仅当避免了有关避免硬件优化结构问题的其他规则,对 ID3D11DeviceContext2::TiledResourceBarrier 进行适当调用,并且平铺资源彼此兼容时,此方案才有效。 此处介绍了后者对于共享磁贴的平铺资源不兼容意味着什么。 访问重复磁贴映射上相同数据的不兼容条件是使用不同的表面尺寸或格式,或者资源上渲染目标或深度模具绑定标记的差异。 如果你之后通过来自不兼容资源的映射进行读取或渲染,那么以一种映射写入内存会产生不明确的结果。 如果其他资源共享映射首先使用新数据进行初始化(循环内存用于不同目的),那么由于数据并未在不兼容的解释中流出,因此后续的读取或渲染操作不受影响。 但是,在访问不兼容的映射之间切换时,必须调用 TiledResourceBarrier API,如下所示。

如果渲染目标或深度模具绑定标记在任何相互的资源共享映射上不固定,则限制会少得多。 只要格式和表面类型(例如 Texture2D)相同,就可以共享磁贴。 不同格式兼容的情况有 BC* 表面和同等大小的未压缩 32 位或 16 位逐组件格式,例如 BC6H 和 R32G32B32A32。 许多每个元素 32 位格式可以使用 R32_* 以及 (R10G10B10A2_*、R8G8B8A8_*、B8G8R8A8_*、B8G8R8X8_*、R16G16_*) 进行别名;始终允许对非平铺资源执行此操作。

如果格式相兼容,并且磁贴填充纯色,则不影响填充和非填充磁贴之间的共享。

最后,如果共享磁贴映射的资源之间没有什么共同点(任何资源都没有渲染目标或深度模具绑定标记的情况除外),那么只能安全共享填充为 0 的内存;对于指定资源格式的定义(通常为 0),映射将呈现为 0 所解码的任何内容。

对平铺资源的管道访问