我有一个计算着色器,我想将其输出到图像/缓冲区,该图像/缓冲区旨在作为两个管线(计算管线和图形管线)之间的中间存储。图形管道实际上是一个“虚拟”,因为它除了将中间缓冲区的内容复制到交换链映像中外没有任何作用。 DX12弃用了计算管道使用UAVS直接写入交换链映像的功能,因此需要这样做。
在Vulkan的意义上,我认为中间存储应该是“临时”附件:
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
指定绑定到该映像的内存将与VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
一起分配(有关更多详细信息,请参见内存分配)。可以为可用于创建VkImageView
的任何图像设置该位,该图像适合用作颜色,分辨率,深度/模板或输入附件。
这在this article中有解释:
最后,Vulkan包含临时附件的概念。这些是帧缓冲区附件,它们在渲染通道开始时以未初始化或清除的状态开始,由一个或多个子通道写入,被一个或多个子通道消耗,并最终在渲染通道结束时被丢弃。在这种情况下,附件中的数据仅存在于渲染通道中,而无需将其写入主内存。尽管我们仍将为此类附件分配内存,但是数据可能永远不会离开GPU,而只会驻留在缓存中。这样可以节省带宽,减少延迟并提高电源效率。
DirectX 12是否具有类似的图像使用概念?
答案 0 :(得分:6)
Direct3D 12没有这个概念。造成这种限制的原因最终归结为存在瞬时分配的原因。 TL; DR:这不是为了做您想做的事情。
Vulkan的渲染过程系统存在一个目的:使基于图块的渲染器成为渲染系统的一等公民。 TBR不太适合OpenGL或D3D的帧缓冲区模型。在这两种API中,您都可以随时随地交换帧缓冲区。
TBR不会直接呈现到内存中。它们将渲染操作执行到内部缓冲区中,这些缓冲区从内存中播种,然后有可能在渲染操作完成后写入内存。只要需要,就可以切换渲染的图像,这与这种结构是一致的,这就是为什么TBR供应商列出了您想要在OpenGL ES代码中实现高性能的不应该做的事情。
Vulkan的渲染过程系统是TBR系统的抽象。在抽象模型中,渲染过程系统可能会从帧缓冲区中的图像中读取数据,然后对该数据的副本执行一堆子过程,最后,可能会将更新后的数据写回图像中。因此,从过程的外部看,您似乎正在渲染图像,但实际上不是。为了保持这种错觉,在渲染过程中,您可以仅以渲染过程模型允许的方式使用那些帧缓冲图像:作为附件。
现在考虑延迟渲染。在延迟渲染中,渲染到g缓冲区,然后在照明遍历中读取该缓冲区以生成最终图像。生成最终图像后,就不再需要这些g缓冲区了。在常规GPU中,这没有任何意义。因为渲染直接进入内存,所以这些g缓冲区必须占用实际存储空间。
但是请考虑一下TBR的工作原理。它确实渲染为单个图块;在最佳情况下,它会一次处理单个图块的 all 个片段。这意味着它要通过几何和光照。对于TBR,g缓冲区只是您用于获得最终答案的一块暂存内存。不需要从内存中读取或复制到内存中。
简而言之,它不需要内存。
输入延迟分配的内存和临时附件映像。它们的存在是为了允许TBR将g缓冲区保留在切片内存中,而不必为它们分配实际的存储空间(至少,只有在某些运行时环境迫使它发生时,例如在GPU上填充过多的几何体,这种情况才会发生)。而且它仅在渲染通道内有效;如果结束渲染过程并且必须在另一个渲染过程中使用一个g缓冲区,那么魔术就必须消失,数据必须接触实际的存储空间。
Vulkan API使此用例非常明确。您不能将一块延迟分配的内存绑定到未设置USAGE_TRANSIENT_ATTACHMENT
标志的图像(或任何类型的缓冲区 )。而且您会注意到它说的是“瞬态附件”,就像在渲染过程 attachments 中一样。之所以这样说是因为,您还会注意到临时附件不能用于非附件用途(valid usage tests for VkImageCreateInfo
的一部分)。完全没有。
您想要做的不是那种延迟分配内存的事情。这行不通。
对于Direct3D 12,该API并非旨在在移动GPU上运行,并且由于仅移动GPU是基于图块的渲染器(一些近期的台式机GPU具有TBR相似性,但不是完整的TBR),因此没有设计任何功能明确地为他们服务。因此,它不需要延迟分配的内存或临时附件。