diff --git a/src/broadcom/vulkan/v3dv_descriptor_set.c b/src/broadcom/vulkan/v3dv_descriptor_set.c index ca20687b96d..8746b67320b 100644 --- a/src/broadcom/vulkan/v3dv_descriptor_set.c +++ b/src/broadcom/vulkan/v3dv_descriptor_set.c @@ -883,7 +883,8 @@ descriptor_bo_copy(struct v3dv_descriptor_set *dst_set, } 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 @@ write_image_descriptor(struct v3dv_descriptor_set *set, 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 @@ v3dv_UpdateDescriptorSets(VkDevice _device, 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 @@ v3dv_UpdateDescriptorSets(VkDevice _device, 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 @@ v3dv_UpdateDescriptorSets(VkDevice _device, 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 df752f3eff5..6bf6405fe18 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -435,14 +435,19 @@ translate_swizzle(unsigned char pipe_swizzle) * 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 @@ pack_texture_shader_state(struct v3dv_device *device, 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 @@ pack_texture_shader_state(struct v3dv_device *device, } } +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 f53b7a6f4a8..e19dbc87d8c 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -441,9 +441,14 @@ struct v3dv_image_view { 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);