5

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.

MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
  • "*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.*" How will you *not* know? It doesn't make sense that you can render a scene without knowing what's in that scene. – Nicol Bolas Apr 14 '16 at 02:13
  • Yes, of course the objects in the scene are known, but there is no 'global list' of techniques used to render them. Different techniques might require different resources, in this case some might require a stencil buffer. I could 'scan' the scene, and determine whether a stencil buffer is needed (or not), before starting the render pass. However, that isn't necessary with any other rendering APIs I've implemented my renderer for, and would reduce performance. – MuertoExcobito Apr 14 '16 at 02:59
  • "*However, that isn't necessary with any other rendering APIs I've implemented my renderer for, and would reduce performance.*" How do you know if it "would reduce performance"? On what hardware would having a stencil buffer that goes unused "reduce performance"? It seems to me that on a TBR, an unused stencil buffer costs very little. Not to mention, some hardware (like TBRs) may need to patch your shader if stenciling is a possibility, since they may use fragment shader logic to do the stencil operation. – Nicol Bolas Apr 14 '16 at 03:10
  • It would reduce performance, because I would need to spend execution time in my code scanning the scene. Also, the surface in other APIs can be allocated on-demand, whereas with Vulkan (without lazily allocated memory), it would need to be allocated up front, consuming more video memory. – MuertoExcobito Apr 14 '16 at 10:38
  • "*It would reduce performance, because I would need to spend execution time in my code scanning the scene.*" Or you could just declare in your render pass that you have a stencil buffer. "*Also, the surface in other APIs can be allocated on-demand*" You say that as if the driver isn't jumping through those same hoops *for you*. – Nicol Bolas Apr 14 '16 at 13:50
  • Without iterating through my scene (or more specifically sub-scene - this applies to offscreen targets), I do not know whether I actually need a stencil buffer or not. Obviously I can't declare that I have one, when there actually isn't one. This means that one would always need to be allocated. If actually needing it is rare, this is pretty wasteful. – MuertoExcobito Apr 14 '16 at 15:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109175/discussion-between-nicol-bolas-and-muertoexcobito). – Nicol Bolas Apr 14 '16 at 15:44

1 Answers1

12

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • I am not using the depth buffer, I am trying to make the allocation of yhe stencil buffer optional. But, it appears in Vulkan this just isn't possible, if drivers (currently none) implement this feature. – MuertoExcobito Apr 14 '16 at 11:24
  • Do you know if the drivers do not implement this because the currently available hardware does not yet support lazily allocated memory, or because the drivers simply have not gotten around to implementing it yet? – Colonel Thirty Two Apr 16 '16 at 15:34
  • @ColonelThirtyTwo: No idea. I'm not sure what hardware exactly would be necessary to implement it though. It's mostly a matter of realizing that you're about to use a `VkImage` in a way that will require a backing store for the memory, then allocating that memory. – Nicol Bolas Apr 16 '16 at 17:39