Skip to content

v3dv: remove the need to combine texture and sampler ids

At the mid-stage of the v3dv Vulkan driver we decided that we would combine the texture and sampler ids. There was two reasons:

  1. v3d compiler used them combined: as it had OpenGL in mind. One of the things we were trying to avoid during the Vulkan driver development is to modify too much the v3d compiler. First to avoid affecting the OpenGL driver, and second to avoid having too many moving pieces.
  2. output size for texture sampling: when doing a texture operation, we need to specify the return size, 32 or 16bit. Although it is a sampling parameter, the more straighforward way to decide it was using the texture format. So we would use a 16bit output size for 16bit formats, and 32bit for 32bit formats. This is what the OpenGL driver was doing too, and was easy to do, as texture and sampler ids for OpenGL are the same (or in other words, they are combined).

So from the Vulkan side we were working with different texture/sampler ids to handle all the resources defined though the Vulkan API, but for the output size and to interact with the v3d compiler we were using a combined idx.

But, all that was adding some artificial complexity, affected how many texture/sampler we could define, and was after all, doing things in a non-Vulkan way.

This MR fixes that. So in relation to the previous two reasons:

  1. v3d compiler: this MR updates the v3d compiler to handle separately texture and sampler. This was far easier that I initially thought. It helped that the nir lowering texture already handled them separately.
  2. So now we would not be able to rely on the texture format: fwiw, the output_size for texture operations main reason is precision. In fact testing to hardcode it to 16bit, most tests using 32bit texture formats passes using a 16bit output size. Only the high precision tests fail. So we decided that it would be more straightforward to use the spir-v RelaxedPrecision decorator. So now our default would be 32, and we go down for 16bit with RelaxedPrecision. It is fair to assume that for most of the Vulkan apps for this embedded device, the shaders would be really well annotated. And if not, we already tested the performance hit with some apps forcing one value and the other, and it is really small.

Relying on RelaxedPrecision to decide the output type has an additional advantage: while we don't know about the final texture format until those are bound, that can be after the pipeline is created, we know about RelaxedPrecision when we are compiling the shader. That means that we would not need to pre-generate a 16 and a 32bit variant of the same shader, neither chose between one or the other as part of the cmd buffer operations.

Having said so, until now spirv_to_nir was not handling RelaxedPrecision. This MR includes one patch to use it, but only handles one specific case. Thats enough to decide on some scenarios, and as a example of how to use it, but it can be improved. I plan to create a RFC to discuss how it should be handled.

Merge request reports