diff options
author | Nanley Chery <nanley.g.chery@intel.com> | 2018-08-30 09:24:45 -0700 |
---|---|---|
committer | Nanley Chery <nanley.g.chery@intel.com> | 2018-10-19 11:28:19 -0700 |
commit | b93528f44ddc5c5fbe42dde53711b5cd793cde7e (patch) | |
tree | 45e0fadc14fdebbc69dc271f3f780aa2e46ea59b | |
parent | f91f9bab83dd87034acc520d51d2f9f84984cec6 (diff) |
anv: Restrict some fast-clear values gen7-8sent/fix/gen78clear
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-stable@lists.freedesktop.org>
-rw-r--r-- | src/intel/vulkan/anv_image.c | 36 | ||||
-rw-r--r-- | src/intel/vulkan/anv_private.h | 6 | ||||
-rw-r--r-- | 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 e89ce012be7..e0a6c147a35 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 a3a041ab322..7582e2ef5be 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2670,6 +2670,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 43a02f22567..b050e57711b 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -334,9 +334,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 |