v3dv: fix regressions for cubemap array load/store

It seems that we only want to set the texture state's depth to the
number of 2D layers divided by 6 when sampling, not wen doing
load/store.

This means that we need to generate two different states and choose
the one to use depending on the descriptor.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
diff --git a/src/broadcom/vulkan/v3dv_descriptor_set.c b/src/broadcom/vulkan/v3dv_descriptor_set.c
index ca20687..8746b67 100644
--- a/src/broadcom/vulkan/v3dv_descriptor_set.c
+++ b/src/broadcom/vulkan/v3dv_descriptor_set.c
@@ -883,7 +883,8 @@
 }
 
 static void
-write_image_descriptor(struct v3dv_descriptor_set *set,
+write_image_descriptor(VkDescriptorType desc_type,
+                       struct v3dv_descriptor_set *set,
                        const struct v3dv_descriptor_set_binding_layout *binding_layout,
                        struct v3dv_image_view *iview,
                        struct v3dv_sampler *sampler,
@@ -892,9 +893,12 @@
    void *desc_map = descriptor_bo_map(set, binding_layout, array_index);
 
    if (iview) {
+      const uint32_t tex_state_index =
+         iview->type != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY ||
+         desc_type != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 0 : 1;
       memcpy(desc_map,
-             iview->texture_shader_state,
-             sizeof(iview->texture_shader_state));
+             iview->texture_shader_state[tex_state_index],
+             sizeof(iview->texture_shader_state[0]));
       desc_map += offsetof(struct v3dv_combined_image_sampler_descriptor,
                            sampler_state);
    }
@@ -960,7 +964,8 @@
 
             descriptor->sampler = sampler;
 
-            write_image_descriptor(set, binding_layout, NULL, sampler,
+            write_image_descriptor(writeset->descriptorType,
+                                   set, binding_layout, NULL, sampler,
                                    writeset->dstArrayElement + j);
 
             break;
@@ -973,7 +978,8 @@
 
             descriptor->image_view = iview;
 
-            write_image_descriptor(set, binding_layout, iview, NULL,
+            write_image_descriptor(writeset->descriptorType,
+                                   set, binding_layout, iview, NULL,
                                    writeset->dstArrayElement + j);
 
             break;
@@ -986,7 +992,8 @@
             descriptor->image_view = iview;
             descriptor->sampler = sampler;
 
-            write_image_descriptor(set, binding_layout, iview, sampler,
+            write_image_descriptor(writeset->descriptorType,
+                                   set, binding_layout, iview, sampler,
                                    writeset->dstArrayElement + j);
 
             break;
diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c
index df752f3..6bf6405 100644
--- a/src/broadcom/vulkan/v3dv_image.c
+++ b/src/broadcom/vulkan/v3dv_image.c
@@ -435,14 +435,19 @@
  * Packs and ensure bo for the shader state (the latter can be temporal).
  */
 static void
-pack_texture_shader_state(struct v3dv_device *device,
-                          struct v3dv_image_view *image_view)
+pack_texture_shader_state_helper(struct v3dv_device *device,
+                                 struct v3dv_image_view *image_view,
+                                 bool for_cube_map_array_storage)
 {
+   assert(!for_cube_map_array_storage ||
+          image_view->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
+   const uint32_t index = for_cube_map_array_storage ? 1 : 0;
+
    assert(image_view->image);
    const struct v3dv_image *image = image_view->image;
 
    int msaa_scale = 1; /* FIXME: hardcoded. Revisit when msaa get supported */
-   v3dv_pack(image_view->texture_shader_state, TEXTURE_SHADER_STATE, tex) {
+   v3dv_pack(image_view->texture_shader_state[index], TEXTURE_SHADER_STATE, tex) {
 
       tex.level_0_is_strictly_uif =
          (image->slices[0].tiling == VC5_TILING_UIF_XOR ||
@@ -478,7 +483,12 @@
          tex.image_depth = (image_view->last_layer - image_view->first_layer) + 1;
       }
 
-      if (image_view->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
+      /* Empirical testing with CTS shows that when we are sampling from cube
+       * arrays we want to set image depth to layers / 6, but not when doing
+       * image load/store.
+       */
+      if (image_view->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY &&
+          !for_cube_map_array_storage) {
          assert(tex.image_depth % 6 == 0);
          tex.image_depth /= 6;
       }
@@ -511,6 +521,15 @@
    }
 }
 
+static void
+pack_texture_shader_state(struct v3dv_device *device,
+                          struct v3dv_image_view *iview)
+{
+   pack_texture_shader_state_helper(device, iview, false);
+   if (iview->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
+      pack_texture_shader_state_helper(device, iview, true);
+}
+
 static enum pipe_swizzle
 vk_component_mapping_to_pipe_swizzle(VkComponentSwizzle comp,
                                      VkComponentSwizzle swz)
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index f53b7a6..e19dbc8 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -441,9 +441,14 @@
    uint8_t swizzle[4];
 
    /* Prepacked TEXTURE_SHADER_STATE. It will be copied to the descriptor info
-    * during UpdateDescriptorSets
+    * during UpdateDescriptorSets.
+    *
+    * Empirical tests show that cube arrays need a different shader state
+    * depending on whether they are used with a sampler or not, so for these
+    * we generate two states and select the one to use based on the descriptor
+    * type.
     */
-   uint8_t texture_shader_state[cl_packet_length(TEXTURE_SHADER_STATE)];
+   uint8_t texture_shader_state[2][cl_packet_length(TEXTURE_SHADER_STATE)];
 };
 
 uint32_t v3dv_layer_offset(const struct v3dv_image *image, uint32_t level, uint32_t layer);