Vulkan:延迟分配内存?

Vulkan: lazily allocated memory?

我有一种情况,我可能需要在渲染过程中使用模板缓冲区,但是,我不会 'know' 直到执行渲染过程的中途。不幸的是,一旦渲染过程已经在进行中(如在 D3D12 中),Vulkan 就无法修改帧缓冲区的附件。但是,我在规范中发现,分配内存时有 "lazily allocated memory" 使用 VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT 的概念,而表面有 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT 的概念。

不幸的是,VkPhysicalDeviceMemoryProperties 中的 VkMemoryType 条目(从 vkGetPhysicalDeviceMemoryProperties 返回)似乎 none 实际上设置了此功能位。此外,似乎 API 样本中的 none 使用了这些位。这是否只是驱动程序级别未实现的功能,驱动程序不支持此功能是否很常见?

我正在使用 Vulkan SDK 1.0.5,Nvidia 驱动程序 356.45。

延迟分配的内存对您没有帮助。或者至少,可能不会,这取决于您的场景。原因有两个。首先,除非您不使用深度进行渲染,否则您必须使用打包的 depth/stencil 图像(因为您不允许使用单独的深度和模板缓冲区)。并且由于您(大概)不希望延迟分配深度部分,因此您别无选择,只能使用实际内存而不是延迟分配的内存。

其次,您正在做的不是延迟分配内存的目的。它不适用于旨在可选的渲染部分。它适用于本质上短暂的图像。

例如,考虑延迟渲染。你需要 g 缓冲区。但是您将在 g-buffer pass 期间填充它们,并且您将在 lighting pass(es) 期间消耗它们。在那之后,您将不会再使用它们的内容。

对于许多渲染器来说,这并不重要。但是使用基于图块的渲染器,它可以。为什么?因为如果一个 tile 足够大,可以一次存储所有 g-buffer 数据,那么实现实际上不需要将 g-buffer 数据写出到内存中。它可以将所有内容都留在图块内存中,在图块 中执行照明通道 (您将它们作为输入附件阅读),然后忘记它们的存在。

但是 Vulkan 要求图像在使用之前绑定内存。惰性内存的存在使您可以满足该要求,同时让实现知道您实际上不会使用此内存。或者更重要的是,只有在您执行需要它的操作时才会分配实际内存。

深度缓冲区和 depth/stencil 缓冲区也可以延迟分配,只要您不需要像访问常规图像那样访问它们即可。但即便如此,它也不是一种让模板打印或深度测试成为可选项的方法。这是关于让他们的后备存储变得短暂,内存可以存在于 TBR 的区块中,而不是其他任何地方。你还在做手术;它只是没有占用实际内存。