On Mon, 29 Nov 2021 at 13:58, Conor McCarthy cmccarthy@codeweavers.com wrote:
November 27, 2021 10:02 PM, "Henri Verbeet" hverbeet@gmail.com wrote:
We could, but it's weird in terms of API consistency. From the point of view of a user of the API, there doesn't seem to be a good reason specialisation constant arrays wouldn't/shouldn't/couldn't be supported. It doesn't seem terribly hard to add either.
I think the only reasonable way to use the array is similar to what I've already done, i.e. find the u32 array and store it in the compiler object, because the indexed value needs to be subtracted from the base register index in vkd3d_dxbc_compiler_get_descriptor_binding(). To load an offset value in vkd3d_dxbc_compiler_get_descriptor_index() as a variable id means adding extra SPIR-V for the subtraction, plus the overhead of finding the parameter each time a descriptor is accessed. It's a performance cost for no advantage.
Finding the parameter shouldn't be an issue. In the worst case we can just store a pointer in the vkd3d_symbol for the descriptor array, but more likely we'd be able to store a SPIR-V id for the result of the subtraction.
The run-time overhead may not be that bad either. After specialisation, the subtraction in question would be a constant expression, and at least in theory, a Vulkan driver could constant-fold that before generating code for the GPU.
Perhaps more importantly, much of what you write above would equally apply to the push constant path, and I think that's perhaps the more appropriate comparison. An application using vkd3d-shader (or vkd3d-compiler) for offline compilation could use push constants to specify offsets at run-time, but if it's known up-front that these offsets will be constant over the lifetime of the pipeline object, specialisation constants would be the more appropriate choice.