st/pbo: fix pbo uploads without PIPE_CAP_TGSI_VS_LAYER_VIEWPORT and skip gs

the previous commit handling this forced geometry shader usage for all cases,
but this is not ideal, so instead there are now fragment shader variants for
both depth==1 and depth!=1, corresponding to the existence of gl_Layer in the
shader

Fixes: 614c77772ac ("st/pbo: fix pbo uploads without PIPE_CAP_TGSI_VS_LAYER_VIEWPORT")

Acked-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8089>
(cherry picked from commit 36097fc7ef70471ecfecd428f990233276e9c45b)
diff --git a/.pick_status.json b/.pick_status.json
index 6f742b1..2cb82f5 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -103,7 +103,7 @@
         "description": "st/pbo: fix pbo uploads without PIPE_CAP_TGSI_VS_LAYER_VIEWPORT and skip gs",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": "614c77772ac2f48955537efcfefaf0609d6c03e5"
     },
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 642ea0d..e2edcbc 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -235,7 +235,7 @@
 
    /* Set up the fragment shader */
    {
-      void *fs = st_pbo_get_download_fs(st, view_target, src_format, dst_format);
+      void *fs = st_pbo_get_download_fs(st, view_target, src_format, dst_format, addr.depth != 1);
       if (!fs)
          goto fail;
 
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 2296dd6..9f94566 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -1271,7 +1271,7 @@
    bool success = false;
    void *fs;
 
-   fs = st_pbo_get_upload_fs(st, src_format, surface->format);
+   fs = st_pbo_get_upload_fs(st, src_format, surface->format, addr->depth != 1);
    if (!fs)
       return false;
 
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index d467dee..b1fda06 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -317,8 +317,8 @@
       struct pipe_blend_state upload_blend;
       void *vs;
       void *gs;
-      void *upload_fs[3];
-      void *download_fs[3][PIPE_MAX_TEXTURE_TYPES];
+      void *upload_fs[3][2];
+      void *download_fs[3][PIPE_MAX_TEXTURE_TYPES][2];
       bool upload_enabled;
       bool download_enabled;
       bool rgba_only;
diff --git a/src/mesa/state_tracker/st_pbo.c b/src/mesa/state_tracker/st_pbo.c
index e4464bd..65a1ce8 100644
--- a/src/mesa/state_tracker/st_pbo.c
+++ b/src/mesa/state_tracker/st_pbo.c
@@ -202,7 +202,7 @@
          return false;
    }
 
-   if (st->pbo.use_gs && !st->pbo.gs) {
+   if (addr->depth != 1 && st->pbo.use_gs && !st->pbo.gs) {
       st->pbo.gs = st_pbo_create_gs(st);
       if (!st->pbo.gs)
          return false;
@@ -403,7 +403,8 @@
 static void *
 create_fs(struct st_context *st, bool download,
           enum pipe_texture_target target,
-          enum st_pbo_conversion conversion)
+          enum st_pbo_conversion conversion,
+          bool need_layer)
 {
    struct pipe_screen *screen = st->pipe->screen;
    struct nir_builder b;
@@ -430,11 +431,11 @@
    nir_ssa_def *coord = nir_load_var(&b, fragcoord);
 
    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 (st->pbo.layers && need_layer && (!download || target == PIPE_TEXTURE_1D_ARRAY ||
+                                                     target == PIPE_TEXTURE_2D_ARRAY ||
+                                                     target == PIPE_TEXTURE_3D ||
+                                                     target == PIPE_TEXTURE_CUBE ||
+                                                     target == PIPE_TEXTURE_CUBE_ARRAY)) {
       nir_variable *var = nir_variable_create(b.shader, nir_var_shader_in,
                                               glsl_int_type(), "gl_Layer");
       var->data.location = VARYING_SLOT_LAYER;
@@ -563,32 +564,34 @@
 void *
 st_pbo_get_upload_fs(struct st_context *st,
                      enum pipe_format src_format,
-                     enum pipe_format dst_format)
+                     enum pipe_format dst_format,
+                     bool need_layer)
 {
    STATIC_ASSERT(ARRAY_SIZE(st->pbo.upload_fs) == ST_NUM_PBO_CONVERSIONS);
 
    enum st_pbo_conversion conversion = get_pbo_conversion(src_format, dst_format);
 
-   if (!st->pbo.upload_fs[conversion])
-      st->pbo.upload_fs[conversion] = create_fs(st, false, 0, conversion);
+   if (!st->pbo.upload_fs[conversion][need_layer])
+      st->pbo.upload_fs[conversion][need_layer] = create_fs(st, false, 0, conversion, need_layer);
 
-   return st->pbo.upload_fs[conversion];
+   return st->pbo.upload_fs[conversion][need_layer];
 }
 
 void *
 st_pbo_get_download_fs(struct st_context *st, enum pipe_texture_target target,
                        enum pipe_format src_format,
-                       enum pipe_format dst_format)
+                       enum pipe_format dst_format,
+                       bool need_layer)
 {
    STATIC_ASSERT(ARRAY_SIZE(st->pbo.download_fs) == ST_NUM_PBO_CONVERSIONS);
    assert(target < PIPE_MAX_TEXTURE_TYPES);
 
    enum st_pbo_conversion conversion = get_pbo_conversion(src_format, dst_format);
 
-   if (!st->pbo.download_fs[conversion][target])
-      st->pbo.download_fs[conversion][target] = create_fs(st, true, target, conversion);
+   if (!st->pbo.download_fs[conversion][target][need_layer])
+      st->pbo.download_fs[conversion][target][need_layer] = create_fs(st, true, target, conversion, need_layer);
 
-   return st->pbo.download_fs[conversion][target];
+   return st->pbo.download_fs[conversion][target][need_layer];
 }
 
 void
@@ -638,17 +641,21 @@
    unsigned i;
 
    for (i = 0; i < ARRAY_SIZE(st->pbo.upload_fs); ++i) {
-      if (st->pbo.upload_fs[i]) {
-         st->pipe->delete_fs_state(st->pipe, st->pbo.upload_fs[i]);
-         st->pbo.upload_fs[i] = NULL;
+      for (unsigned j = 0; j < ARRAY_SIZE(st->pbo.upload_fs[0]); j++) {
+         if (st->pbo.upload_fs[i][j]) {
+            st->pipe->delete_fs_state(st->pipe, st->pbo.upload_fs[i][j]);
+            st->pbo.upload_fs[i][j] = NULL;
+         }
       }
    }
 
    for (i = 0; i < ARRAY_SIZE(st->pbo.download_fs); ++i) {
       for (unsigned j = 0; j < ARRAY_SIZE(st->pbo.download_fs[0]); ++j) {
-         if (st->pbo.download_fs[i][j]) {
-            st->pipe->delete_fs_state(st->pipe, st->pbo.download_fs[i][j]);
-            st->pbo.download_fs[i][j] = NULL;
+         for (unsigned k = 0; k < ARRAY_SIZE(st->pbo.download_fs[0][0]); k++) {
+            if (st->pbo.download_fs[i][j][k]) {
+               st->pipe->delete_fs_state(st->pipe, st->pbo.download_fs[i][j][k]);
+               st->pbo.download_fs[i][j][k] = NULL;
+            }
          }
       }
    }
diff --git a/src/mesa/state_tracker/st_pbo.h b/src/mesa/state_tracker/st_pbo.h
index 54ae776..5462658 100644
--- a/src/mesa/state_tracker/st_pbo.h
+++ b/src/mesa/state_tracker/st_pbo.h
@@ -87,12 +87,14 @@
 void *
 st_pbo_get_upload_fs(struct st_context *st,
                      enum pipe_format src_format,
-                     enum pipe_format dst_format);
+                     enum pipe_format dst_format,
+                     bool need_layer);
 
 void *
 st_pbo_get_download_fs(struct st_context *st, enum pipe_texture_target target,
                        enum pipe_format src_format,
-                       enum pipe_format dst_format);
+                       enum pipe_format dst_format,
+                       bool need_layer);
 
 extern void
 st_init_pbo_helpers(struct st_context *st);