We're explicitly replacing zero with one in the only place where the
plane count being zero or one makes a difference. It also make sense:
UNKNOWN is used for buffers, which for all intents and purposes have one
plane.
Currently, when using Vulkan heaps, we create descriptor set
layouts with as many descriptors as allowed by the Vulkan
implementation limits. For some implementations this can mean
hundreds of millions of descriptors or more, which is wasteful,
given that even on the best resource binding tier Direct3D 12
applications should not expect to have more than a million usable
descriptors.
Recently this began being a problem, because since Mesa 24.2.7
the Intel driver advertises more than 200 million descriptors,
but pipeline compilation takes linear RAM in the number of
descriptors declared in the pipeline layout. This means that
compiling even a simple shader requires 10-20 GB of RAM.
In order to avoid using too much memory, with this commit we clamp
the number of descriptors declared in the set layouts to how many
we actually need to guarantee tier 3 resource binding support.
Creating a pool of 16k descriptors is wasteful if an allocator only uses
a fraction of them, so start at 1k and double for each subsequent
allocation until 16k is reached.
Now that our Vulkan descriptor sets contain only a single vkd3d
descriptor type, we're able to create descriptor pools containing only a
single vkd3d descriptor type as well. This avoids wasting unallocated
descriptors of one type when we run out of descriptors of another type.
ERR is used to indicate internal inconsistencies in vkd3d. Here that's
not the case, we simply have to forward the error condition to the
caller.
This fixes failures on the CI with llvmpipe, because the build we use is
compiled without support for VK_KHR_surface and related extensions.
Without LTO, gcc doesn't know that hresult_from_vk_result() will always return a
failure HRESULT for a failure VkResult, and so thinks that we might exit from
vkd3d_check_device_extensions() with a success HRESULT but without initializing
vk_extensions.
So we avoid hardcoding that it is number zero. There are two
goals here: first making the code easier to understand and
second allow reshuffling the descriptor set allocation in a
later commit.
The descriptor heap implementation is a rather central behavior element
in vkd3d, so it's useful to have all the relevant information logged
in a single place.
Based on the design document, "The runtime will not clamp or validate
the input, but implementations may clamp to the range [0,1] if necessary.",
so we test for the EXT_depth_range_unrestricted extension, and only clamp if
it's not available (thus, necessary to do so).
NaNs are converted to zero as per "NaNs must be treated as 0, but the runtime
will convert NaNs to 0 on behalf of the implementation.", and a default bounds
are set to 0.0 and 1.0.
vkd3d might decide to disable some extensions after the chain is created,
so the chain must be recreated with only the structures corresponding to
enabled extensions.
Similarly to a54187f3c9c9ad4a5d1357721104f28c498ac112, this fixes some validation
errors on devices that do not support tessellation; the Adreno 540 on my OnePlus 5
phone in my specific case.