From 57a8efa22218cc9c2dec0473762de288e4fd239d Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 6 Jul 2022 17:48:27 +0300 Subject: [PATCH] anv: deal with isl format swizzles for buffer views For some formats like VK_FORMAT_B5G6R5_UNORM_PACK16, we have no direct matching HW format. We can support it by swizzling. We already apply those swizzles for image views. We just forgot to deal with buffer views. Signed-off-by: Lionel Landwerlin Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6235 Reviewed-by: Nanley Chery Part-of: --- src/intel/vulkan/anv_cmd_buffer.c | 3 ++- src/intel/vulkan/anv_descriptor_set.c | 9 ++++--- src/intel/vulkan/anv_device.c | 3 ++- src/intel/vulkan/anv_image.c | 35 +++++++++++++++++---------- src/intel/vulkan/anv_private.h | 2 +- src/intel/vulkan/genX_cmd_buffer.c | 9 ++++--- 6 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index e1a9a0acf47..15d3035555b 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -1472,7 +1472,8 @@ anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer, anv_state_stream_alloc(&cmd_buffer->surface_state_stream, isl_dev->ss.size, isl_dev->ss.align); anv_fill_buffer_surface_state(cmd_buffer->device, - set->desc_surface_state, format, + set->desc_surface_state, + format, ISL_SWIZZLE_IDENTITY, ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, set->desc_addr, layout->descriptor_buffer_size, 1); diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index fff065fbbd5..3b46bdb9f3e 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -1176,7 +1176,8 @@ anv_descriptor_set_create(struct anv_device *device, if (!pool->host_only) { set->desc_surface_state = anv_descriptor_pool_alloc_state(pool); - anv_fill_buffer_surface_state(device, set->desc_surface_state, format, + anv_fill_buffer_surface_state(device, set->desc_surface_state, + format, ISL_SWIZZLE_IDENTITY, ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, set->desc_addr, descriptor_buffer_size, 1); @@ -1631,7 +1632,6 @@ anv_descriptor_set_write_buffer(struct anv_device *device, struct anv_buffer_view *bview = &set->buffer_views[bind_layout->buffer_view_index + element]; - bview->format = anv_isl_format_for_descriptor_type(device, type); bview->range = bind_range; bview->address = bind_addr; @@ -1651,9 +1651,10 @@ anv_descriptor_set_write_buffer(struct anv_device *device, ISL_SURF_USAGE_CONSTANT_BUFFER_BIT : ISL_SURF_USAGE_STORAGE_BIT; + enum isl_format format = anv_isl_format_for_descriptor_type(device, type); anv_fill_buffer_surface_state(device, bview->surface_state, - bview->format, usage, - bind_addr, bind_range, 1); + format, ISL_SWIZZLE_IDENTITY, + usage, bind_addr, bind_range, 1); desc->set_buffer_view = bview; } diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 010acf206d3..6766840851d 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -4532,6 +4532,7 @@ uint64_t anv_GetDeviceMemoryOpaqueCaptureAddress( void anv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state, enum isl_format format, + struct isl_swizzle swizzle, isl_surf_usage_flags_t usage, struct anv_address address, uint32_t range, uint32_t stride) @@ -4542,7 +4543,7 @@ anv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state, address.bo && address.bo->is_external), .size_B = range, .format = format, - .swizzle = ISL_SWIZZLE_IDENTITY, + .swizzle = swizzle, .stride_B = stride); } diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 1aca85ce053..e2c3320e146 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -2860,12 +2860,11 @@ anv_CreateBufferView(VkDevice _device, if (!view) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - /* TODO: Handle the format swizzle? */ + struct anv_format_plane format; + format = anv_get_format_plane(&device->info, pCreateInfo->format, + 0, VK_IMAGE_TILING_LINEAR); - view->format = anv_get_isl_format(&device->info, pCreateInfo->format, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_TILING_LINEAR); - const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8; + const uint32_t format_bs = isl_format_get_layout(format.isl_format)->bpb / 8; view->range = vk_buffer_range(&buffer->vk, pCreateInfo->offset, pCreateInfo->range); view->range = align_down_npot_u32(view->range, format_bs); @@ -2876,7 +2875,8 @@ anv_CreateBufferView(VkDevice _device, view->surface_state = alloc_surface_state(device); anv_fill_buffer_surface_state(device, view->surface_state, - view->format, ISL_SURF_USAGE_TEXTURE_BIT, + format.isl_format, format.swizzle, + ISL_SURF_USAGE_TEXTURE_BIT, view->address, view->range, format_bs); } else { view->surface_state = (struct anv_state){ 0 }; @@ -2887,25 +2887,34 @@ anv_CreateBufferView(VkDevice _device, view->lowered_storage_surface_state = alloc_surface_state(device); anv_fill_buffer_surface_state(device, view->storage_surface_state, - view->format, ISL_SURF_USAGE_STORAGE_BIT, - view->address, view->range, - isl_format_get_layout(view->format)->bpb / 8); + format.isl_format, format.swizzle, + ISL_SURF_USAGE_STORAGE_BIT, + view->address, view->range, format_bs); enum isl_format lowered_format = isl_has_matching_typed_storage_image_format(&device->info, - view->format) ? - isl_lower_storage_image_format(&device->info, view->format) : + format.isl_format) ? + isl_lower_storage_image_format(&device->info, format.isl_format) : ISL_FORMAT_RAW; + /* If we lower the format, we should ensure either they both match in + * bits per channel or that there is no swizzle because we can't use + * the swizzle for a different bit pattern. + */ + assert(isl_formats_have_same_bits_per_channel(lowered_format, + format.isl_format) || + isl_swizzle_is_identity(format.swizzle)); + anv_fill_buffer_surface_state(device, view->lowered_storage_surface_state, - lowered_format, ISL_SURF_USAGE_STORAGE_BIT, + lowered_format, format.swizzle, + ISL_SURF_USAGE_STORAGE_BIT, view->address, view->range, (lowered_format == ISL_FORMAT_RAW ? 1 : isl_format_get_layout(lowered_format)->bpb / 8)); isl_buffer_fill_image_param(&device->isl_dev, &view->lowered_storage_image_param, - view->format, view->range); + format.isl_format, view->range); } else { view->storage_surface_state = (struct anv_state){ 0 }; view->lowered_storage_surface_state = (struct anv_state){ 0 }; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 210d6543b21..300fa951c68 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1965,7 +1965,6 @@ anv_descriptor_set_is_push(struct anv_descriptor_set *set) struct anv_buffer_view { struct vk_object_base base; - enum isl_format format; /**< VkBufferViewCreateInfo::format */ uint64_t range; /**< VkBufferViewCreateInfo::range */ struct anv_address address; @@ -4258,6 +4257,7 @@ anv_get_image_format_features2(const struct intel_device_info *devinfo, void anv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state, enum isl_format format, + struct isl_swizzle swizzle, isl_surf_usage_flags_t usage, struct anv_address address, uint32_t range, uint32_t stride); diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 680dfe25a03..657868c229a 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -2568,8 +2568,8 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, const enum isl_format format = anv_isl_format_for_descriptor_type(cmd_buffer->device, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - anv_fill_buffer_surface_state(cmd_buffer->device, - surface_state, format, + anv_fill_buffer_surface_state(cmd_buffer->device, surface_state, + format, ISL_SWIZZLE_IDENTITY, ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, constant_data, constant_data_size, 1); @@ -2590,7 +2590,7 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, anv_isl_format_for_descriptor_type(cmd_buffer->device, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); anv_fill_buffer_surface_state(cmd_buffer->device, surface_state, - format, + format, ISL_SWIZZLE_IDENTITY, ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, cmd_buffer->state.compute.num_workgroups, 12, 1); @@ -2752,7 +2752,8 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, ISL_SURF_USAGE_STORAGE_BIT; anv_fill_buffer_surface_state(cmd_buffer->device, surface_state, - format, usage, address, range, 1); + format, ISL_SWIZZLE_IDENTITY, + usage, address, range, 1); if (need_client_mem_relocs) add_surface_reloc(cmd_buffer, surface_state, address); } else {