Vk_image_layout_dontcare

Why must we supply the old image layout when transitioning image layouts? It’s extremely tedious and should be handled by the driver. Sure, theoretically the driver could be 0.0001% faster by skipping this feature, but you’re just offloading the driver’s job onto the rendering code and causing a lot of confusion and making it error-prone.

The place this really breaks down is when you are interacting with a vkimage created or manipulated by some third-party library like OpenXR. It becomes impossible to track the current state because there is other code acting on the image that you can’t see.

Rendering pipelines were thankfully removed because they crippled the API. Adding the ability to omit the old image layout should be the next fix.

Don’t even suggest that “lol you’re not a real programmer”. Valve and Rockstar can’t even write error-free Vulkan code. The API has serious usability problems.

Because layout transitions wouldn’t make any sense otherwise.

Think of layouts like encryption schemes for data. A layout transition requires decrypting and re-encrypting the data. If you are handed a blob of bits, you don’t know which encryption scheme was used to make it, so you cannot decrypt it.

If you don’t want to deal with layout transitions, that means you don’t want to deal with layouts. So just use general.

Welcome to Vulkan; enjoy your stay!

No, really, the entire point of an explicit, low-level API is to redefine a bunch of things that were previously declared to be “the driver’s job” as “your job”. Command buffers, direct memory allocation, etc all used to be “the driver’s job”. They’re not anymore.

Layouts are just one more thing.

The fundamental problem with layout tracking in the driver is this: the driver simply cannot have the information in all cases. This is endemic to a command-buffer style API.

If I build a CB that uses an image, the code building that CB has no idea what layout the image was in prior to that. That information would be in a different command buffer which put it into that layout beforehand. But “beforehand” is defined at submission time, not at CB creation time.

It is 100% OK to create a CB that uses an image in one layout, then creates a CB that transitions that image to that layout, so long as you submit them in the proper order.

Which means that any layout-related logic that any particular CB command might need would have to be deferred until submission time. Which means submission time would be even more costly than it already is.

And that assumes that the change happened on that queue. Which it doesn’t have to. And with timeline semaphores, it’s even possible that the command that changes the layout has not been submitted to any queue yet at the time the CB that needs to access that image gets submitted.

What you’re asking for can only reasonably be done for hardware that effectively stores the layout as part of the image’s data, such that all operations that act on the image use that internal layout to figure out what’s going on. This would have to be done by the GPU itself, with no intervention by user-land code or CB generation or anything of that sort. NVIDIA does that in most of their hardware, but other driver makers don’t.

And so long as this is the case, user-land code must track the layout themselves.

This is also why Direct3D11’s attempt at deferred contexts were never implemented on non-NVIDIA hardware. Image layouts were not part of the API, but user-land code would have had to provide that information to make deferred contexts work. So drivers for such hardware didn’t implement them.

Any library that manages a Vulkan image and hands it to you with the expectation that you will use it ought to tell you what layout it left that image in (and you ought to tell it what layout it starts in when you tell it to do stuff with the image). If the API doesn’t do that (and I doubt OpenXR’s Vulkan interface has no way to get this information), then that’s a problem with the API.

1 Like

If the validation layer can track what the image layout currently is, why can’t the driver? I don’t believe this would make any significant difference in performance for any real-world applications.

It can’t. Validation layers aren’t perfect. You can construct cases where the layer just doesn’t know.

OK: what is the basis for that belief?

During typical usage image layout transitions don’t happen that often. I would estimate maybe a dozen times per frame. The overhead in my own renderer of managing this is nil, but the major problem arises when there is integration with third-party code.

The usability penalty of this design is significant and the performance gain is very nearly zero in all but the most extreme situations. I fail to see why we are sabotaging our entire industry to uphold some ideological position, unless the stated goals and the actual goals of Vulkan are two different things.

I just did some quick checking, and it seems to me that OpenXR already handles layouts in a reasonable way. At least for swapchain images. The XR_KHR_vulkan_enable extension makes the behavior clear. When you tell OpenXR to acquire a swapchain image, it puts it in a color/depth attachment layout (or a layout compatible with it, which for Vulkan purposes is the same). And when you tell it to release the image, OpenXR requires that it be in the color/depth attachment layout.

In short, there is no ambiguity as to what the layout of the image needs to be.

So it’s not clear what “third-party code” you’re talking about.

Validation layers track things at a cost. That’s why they are a seperate layer from the driver that can be disabled. Oftentimes the cost is locks, when it comes to making something that is stateless into a stateful entity.