Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vulkan: lazily allocated memory?

Tags:

c++

vulkan

I have a situation in which I might require a stencil buffer in a render pass, but, I will not 'know' until mid-way through executing the render pass. Unfortunately, there is no way in Vulkan to modify attachments to the framebuffer, once a render pass is already in progress (like in D3D12). However, I found in the spec, that there is the concept of "lazily allocated memory" using VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT when allocating the memory, and VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT for the surface.

Unfortunately, it appears that none of the VkMemoryType entries in VkPhysicalDeviceMemoryProperties (returned from vkGetPhysicalDeviceMemoryProperties) actually have this capability bit set. Furthermore, it appears that none of the API-Samples use these bits. Is this just an unimplemented feature at the driver level, and is it common for drivers to not support this feature?

I am using Vulkan SDK 1.0.5, Nvidia driver 356.45.

like image 963
MuertoExcobito Avatar asked Feb 07 '23 06:02

MuertoExcobito


1 Answers

Lazily allocated memory won't help you. Or at least, probably not, depending on your scene. The reasons are two-fold. First, unless you're not rendering with depth, you have to be using a packed depth/stencil image (since you're not allowed to have separate depth and stencil buffers). And since you (presumably) don't want the depth part to be lazily allocated, you have no recourse but to use actual memory rather than lazily allocated memory.

Second, what you're doing is not what lazily allocated memory is for. It's not for parts of the rendering that are intended to be optional. It's for images that are ephemeral by their nature.

For example, consider deferred rendering. You need g-buffers. But you're going to fill them up during the g-buffer pass, and you'll consume them during the lighting pass(es). After that point, you won't be using their contents again.

For many renderers, this doesn't really matter. But with a tile-based renderer, it can. Why? Because if a tile is big enough to store all of the g-buffer data all at once, then the implementation doesn't actually need to write the g-buffer data out to memory. It can just leave everything in tile memory, do the lighting pass(es) within the tile (you read them as input attachments), and then forget they exist.

But Vulkan requires that images have memory bound to them before they can be used. Lazy memory exists so that you can fulfill that requirement while letting the implementation know that you aren't really going to use this memory. Or more to the point, actual memory will only be allocated if you do something that requires it.

Depth buffers and depth/stencil buffers could be lazily allocated too, so long as you don't need to access them like regular images. But even so, it's not about a way to make stenciling or depth testing optional. It's about making their backing storage ephemeral, memory that can live within a TBR's tile and nowhere else. You're still doing the operations; it's just not taking up actual memory.

like image 119
Nicol Bolas Avatar answered Feb 15 '23 22:02

Nicol Bolas