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);