st/pbo: set layer coord for array textures
authorJuan A. Suarez Romero <jasuarez@igalia.com>
Thu, 14 Oct 2021 16:40:13 +0000 (18:40 +0200)
committerMarge Bot <emma+marge@anholt.net>
Fri, 3 Dec 2021 15:32:36 +0000 (15:32 +0000)
Even for drivers not supporting layers, we need to include the layer
coordinate (zero in this case) when using array textures in the
download/upload FS.

Otherwise we are missing a component to get the texture, which ends up
in a malformed NIR shader.

v5 (Ilia):
 - Do not emit needless layer code.

v6 (Ilia):
 - Add comment clarifying the code logic behind.

Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13409>

src/mesa/state_tracker/st_pbo.c

index 51a29e8..f07f416 100644 (file)
@@ -437,13 +437,19 @@ create_fs(struct st_context *st, bool download,
                                             : VARYING_SLOT_POS;
    nir_ssa_def *coord = nir_load_var(&b, fragcoord);
 
+   /* When st->pbo.layers == false, it is guaranteed we only have a single
+    * layer. But we still need the "layer" variable to add the "array"
+    * coordinate to the texture. Hence we set layer to zero when array texture
+    * is used in case only a single layer is required.
+    */
    nir_ssa_def *layer = NULL;
-   if (st->pbo.layers && (!download || target == PIPE_TEXTURE_1D_ARRAY ||
-                                       target == PIPE_TEXTURE_2D_ARRAY ||
-                                       target == PIPE_TEXTURE_3D ||
-                                       target == PIPE_TEXTURE_CUBE ||
-                                       target == PIPE_TEXTURE_CUBE_ARRAY)) {
+   if (!download || target == PIPE_TEXTURE_1D_ARRAY ||
+                    target == PIPE_TEXTURE_2D_ARRAY ||
+                    target == PIPE_TEXTURE_3D ||
+                    target == PIPE_TEXTURE_CUBE ||
+                    target == PIPE_TEXTURE_CUBE_ARRAY) {
       if (need_layer) {
+         assert(st->pbo.layers);
          nir_variable *var = nir_variable_create(b.shader, nir_var_shader_in,
                                                 glsl_int_type(), "gl_Layer");
          var->data.location = VARYING_SLOT_LAYER;
@@ -465,7 +471,7 @@ create_fs(struct st_context *st, bool download,
       nir_iadd(&b, nir_channel(&b, offset_pos, 0),
                nir_imul(&b, nir_channel(&b, offset_pos, 1),
                         nir_channel(&b, param, 2)));
-   if (layer) {
+   if (layer && layer != zero) {
       /* pbo_addr += image_height * layer */
       pbo_addr = nir_iadd(&b, pbo_addr,
                           nir_imul(&b, layer, nir_channel(&b, param, 3)));