From 7aee9f12b9c1f17ae2662c8043c8679ce698b731 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 20 Apr 2022 13:51:13 -0400 Subject: [PATCH] zink: force render target usage for sampler-only resources these might hit u_blitter later, which will require rt usage to handle texture views, so add rt usage now to avoid failing later cc: mesa-stable Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_resource.c | 29 ++++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index cb6c17d021a..fb926f41fcc 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -247,10 +247,11 @@ check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, uint64_t modifier) } static VkImageUsageFlags -get_image_usage_for_feats(struct zink_screen *screen, VkFormatFeatureFlags feats, const struct pipe_resource *templ, unsigned bind) +get_image_usage_for_feats(struct zink_screen *screen, VkFormatFeatureFlags feats, const struct pipe_resource *templ, unsigned bind, bool *need_extended) { VkImageUsageFlags usage = 0; bool is_planar = util_format_get_num_planes(templ->format) > 1; + *need_extended = false; if (bind & ZINK_BIND_TRANSIENT) usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; @@ -274,8 +275,18 @@ get_image_usage_for_feats(struct zink_screen *screen, VkFormatFeatureFlags feats usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; if ((bind & (PIPE_BIND_LINEAR | PIPE_BIND_SHARED)) != (PIPE_BIND_LINEAR | PIPE_BIND_SHARED)) usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; - } else + } else { + /* trust that gallium isn't going to give us anything wild */ + *need_extended = true; return 0; + } + } else if ((bind & PIPE_BIND_SAMPLER_VIEW) && !util_format_is_depth_or_stencil(templ->format)) { + if (!(feats & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { + /* ensure we can u_blitter this later */ + *need_extended = true; + return 0; + } + usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; } if (bind & PIPE_BIND_DEPTH_STENCIL) { @@ -313,6 +324,7 @@ static VkImageUsageFlags get_image_usage(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe_resource *templ, unsigned bind, unsigned modifiers_count, const uint64_t *modifiers, uint64_t *mod) { VkImageTiling tiling = ici->tiling; + bool need_extended = false; *mod = DRM_FORMAT_MOD_INVALID; if (modifiers_count) { bool have_linear = false; @@ -327,7 +339,8 @@ get_image_usage(struct zink_screen *screen, VkImageCreateInfo *ici, const struct } VkFormatFeatureFlags feats = find_modifier_feats(prop, modifiers[i], mod); if (feats) { - VkImageUsageFlags usage = get_image_usage_for_feats(screen, feats, templ, bind); + VkImageUsageFlags usage = get_image_usage_for_feats(screen, feats, templ, bind, &need_extended); + assert(!need_extended); if (usage) { ici->usage = usage; if (check_ici(screen, ici, *mod)) @@ -339,7 +352,8 @@ get_image_usage(struct zink_screen *screen, VkImageCreateInfo *ici, const struct if (have_linear) { VkFormatFeatureFlags feats = find_modifier_feats(prop, DRM_FORMAT_MOD_LINEAR, mod); if (feats) { - VkImageUsageFlags usage = get_image_usage_for_feats(screen, feats, templ, bind); + VkImageUsageFlags usage = get_image_usage_for_feats(screen, feats, templ, bind, &need_extended); + assert(!need_extended); if (usage) { ici->usage = usage; if (check_ici(screen, ici, *mod)) @@ -353,7 +367,12 @@ get_image_usage(struct zink_screen *screen, VkImageCreateInfo *ici, const struct VkFormatFeatureFlags feats = tiling == VK_IMAGE_TILING_LINEAR ? props.linearTilingFeatures : props.optimalTilingFeatures; if (ici->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) feats = UINT32_MAX; - VkImageUsageFlags usage = get_image_usage_for_feats(screen, feats, templ, bind); + VkImageUsageFlags usage = get_image_usage_for_feats(screen, feats, templ, bind, &need_extended); + if (need_extended) { + ici->flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT; + feats = UINT32_MAX; + usage = get_image_usage_for_feats(screen, feats, templ, bind, &need_extended); + } if (usage) { ici->usage = usage; if (check_ici(screen, ici, *mod))