The Vulkan API was recently clarified to allow image views of different formats to be used for rendering to the same image. Due to certain incompatible clear-color encodings on gen7-8, we must be more careful about which fast-clear values we allow.
Makes the following crucible test pass pre-SKL: func.renderpass.clear.color-view-one Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105826 Cc: <mesa-sta...@lists.freedesktop.org> --- The crucible test currently only exists in a merge request: https://gitlab.freedesktop.org/mesa/crucible/merge_requests/11 src/intel/vulkan/anv_image.c | 36 ++++++++++++++++++++++++++++++ src/intel/vulkan/anv_private.h | 6 +++++ src/intel/vulkan/genX_cmd_buffer.c | 19 +++++++++++++--- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index b0d8c560adb..4eb06501f8d 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -156,6 +156,40 @@ add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane) surf->isl.alignment_B); } +static bool +all_formats_flt_xor_int(const struct gen_device_info *devinfo, + const struct VkImageCreateInfo *vk_info) +{ + if (!(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) + return true; + + const VkImageFormatListCreateInfoKHR *fmt_list = + vk_find_struct_const(vk_info->pNext, IMAGE_FORMAT_LIST_CREATE_INFO_KHR); + + if (!fmt_list || fmt_list->viewFormatCount == 0) + return false; + + enum isl_format format = + anv_get_isl_format(devinfo, vk_info->format, + VK_IMAGE_ASPECT_COLOR_BIT, vk_info->tiling); + + const bool is_int = isl_format_has_int_channel(format) || + isl_format_has_uint_channel(format); + + for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) { + enum isl_format view_format = + anv_get_isl_format(devinfo, fmt_list->pViewFormats[i], + VK_IMAGE_ASPECT_COLOR_BIT, vk_info->tiling); + + const bool view_is_int = isl_format_has_int_channel(view_format) || + isl_format_has_uint_channel(view_format); + + if (is_int != view_is_int) + return false; + } + + return true; +} static bool all_formats_ccs_e_compatible(const struct gen_device_info *devinfo, @@ -593,6 +627,8 @@ anv_image_create(VkDevice _device, image->usage = pCreateInfo->usage; image->tiling = pCreateInfo->tiling; image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT; + image->fmts_flt_xor_int = + all_formats_flt_xor_int(&device->info, pCreateInfo); image->needs_set_tiling = wsi_info && wsi_info->scanout; image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier : DRM_FORMAT_MOD_INVALID; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 60f40c7e2ae..07dcc9f9b37 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2641,6 +2641,12 @@ struct anv_image { VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */ VkImageTiling tiling; /** VkImageCreateInfo::tiling */ + /** + * True if this image may be used with integer or float formats, but not + * both. + */ + bool fmts_flt_xor_int; + /** True if this is needs to be bound to an appropriately tiled BO. * * When not using modifiers, consumers such as X11, Wayland, and KMS need diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 099c30f3d66..da01795db10 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -322,9 +322,22 @@ color_attachment_compute_aux_usage(struct anv_device * device, render_area.extent.height != iview->extent.height) att_state->fast_clear = false; - /* On Broadwell and earlier, we can only handle 0/1 clear colors */ - if (GEN_GEN <= 8 && !att_state->clear_color_is_zero_one) - att_state->fast_clear = false; + /* Broadwell and earlier have restrictions due to integer and float + * texture clears being viewed incorrectly for certain values. Float + * texture clears to 1.0 (0x3F80_0000) are encoded as 1 in the surface + * state. Integer texture clears to 1 (0x1) share the same encoding. To + * avoid this conflict, only allow clearing with ones if the image format + * type is immutable. + */ + if (GEN_GEN <= 8) { + if (!iview->image->fmts_flt_xor_int && + !att_state->clear_color_is_zero) { + att_state->fast_clear = false; + } else if (iview->image->fmts_flt_xor_int && + !att_state->clear_color_is_zero_one) { + att_state->fast_clear = false; + } + } /* We only allow fast clears to the first slice of an image (level 0, * layer 0) and only for the entire slice. This guarantees us that, at -- 2.19.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev