* This shifts from reporting from the old style bindset/bind to the new system
of only referencing by shader interface and index (independent of binding
model).
* The vulkan shader debugger re-uses the replay interface to cache descriptor
access and descriptor contents in a fashion friendly to interface-index
lookup.
* These are temporarily given separate names, to allow them to exist in parallel
with the existing helpers, but in future these will be renamed when the older
helpers are removed.
* Previously this was provided by the ShaderBindpointMapping, but since we plan
to remove that we add the information here. These will be purely for
informational purposes and will not be used to look up bound resources etc.
They exist for display only, or for API-specific interpretation if e.g. the
bindpoint is known ahead of time it can be identified here without having to
jump through hoops to get which descriptor a given bind accesses and get the
register number for that descriptor.
* On OpenGL this information will not be present because bindings are mutable
(even if they are declared in the shader). The only way to identify a
particular binding by register will be with those hoops
* This is a consideration for any cases where binding numbers are relevant -
primarily D3D11 and GL - where the offset into an arbitrary (and possibly
fake) descriptor storage is not helpful but knowing the register binding
definitely is.
* If someone wants to look at the raw descriptor contents without respect to a
particular shader access they can use this query to determine a more useful
'name' for any given descriptor. On D3D11 and GL this gives the register
number, on Vulkan it gives the binding number (and array element). On D3D12 it
just repeats the offset effectively.
* This avoids the need to communicate this information in the descriptor type.
Since descriptors must match the shader in this area, it's easier to
communicate this through shader reflection.
* On vulkan immutable samplers mostly work as-is because they have a descriptor
set space even if they may not be written dynamically. We just set a flag so
the replay API is aware they're compile-time constant.
* On D3D12 we follow the path of root constants and other non-descriptor backed
bindings, by creating virtual descriptor store in the root signature where the
static samplers are created.
* Baking these into descriptors when we get arbitrary 'GetDescriptor' queries
independent of the bound descriptor sets is not possible - a descriptor set
could be in theory bound twice to two places with different dynamic offsets.
* Instead we report these as part of the pipeline states and the abstraction &
replay API consumer will need to manually apply them to get the true buffer
offset.
* The offsets are indexed by descriptor storage byte offset for easier
processing (the dynamic offset struct can be turned into a pair and used to
initialise a dict)
* Root descriptors don't have concrete backing storage so they don't quite fit
the model, so instead we pretend their backing storage is in the pipeline as a
'virtual' descriptor indexed by the root index.
* Things hat don't neatly fit into our descriptor-based model like push
constants, specialisation constants, and inline UBOs inside descriptor sets.
* In these cases (except for the last case) we don't have an explicit
descriptor, so we create a virtual one that lives in the corresponding object
- pipeline, command buffer, etc and some virtual storage to reference.
* Since D3D11 is entirely non-bindless we can precalculate the descriptor access
for a shader up-front from its reflection and combine at query time from the
currently bound shaders. This effectively replaces the old bindpoint mapping.
* For descriptors with immutable samplers the existing code already refuses to
update/change them, but the descriptor won't contain the sampler unless it
goes through init contents at which point we slot it in for easier validity
checking. Instead we can set the immutable samplers at creation time when we
know them. We can also set the descriptor type here as mutable descriptors
cannot use immutable samplers.
* Similarly for inline uniform blocks if they are variable sized we can set
their size here as well as the variable size is known at creation time.
* With these changes the contents of a descriptor can be processed entirely from
the DescriptorSetSlot with two exceptions:
- An immutable sampler flag, the source of the sampler is unknown
- Dynamic offsets on descriptors, which vary based on where the descriptor set
is bound (and in theory one descriptor set could be bound twice with two
different offsets)
* Separated into normal descriptors and sampler descriptors, since they are
almost equal in size so there's no need to inflate the descriptor size for
non-sampler descriptors which are much rarer.
* This doesn't change our minimum specs as we already required GCC 5, clang 3.4,
which fully support C++14. Interestingly only VS2015 is the odd one out but we
don't rely on any features from C++14 that it doesn't support.