From 9e83723a210de484be13e691263b048dcd1a3e9d Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 7 Jun 2023 14:37:16 -0400 Subject: [PATCH] zink: add srgb mutable for all resources by default this should enable compression on more intermediate fb attachments it also means that VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT can now be set on images where ZINK_BIND_MUTABLE is not set, so non-resource APIs need to check ZINK_BIND_MUTABLE Part-of: --- src/gallium/drivers/zink/zink_format.h | 8 +++++++- src/gallium/drivers/zink/zink_resource.c | 8 ++++---- src/gallium/drivers/zink/zink_surface.c | 17 +++++++++++++---- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/zink/zink_format.h b/src/gallium/drivers/zink/zink_format.h index 1fff06d2c5e..e78942de1cf 100644 --- a/src/gallium/drivers/zink/zink_format.h +++ b/src/gallium/drivers/zink/zink_format.h @@ -54,6 +54,12 @@ zink_format_clamp_channel_srgb(const struct util_format_description *desc, union static inline bool zink_format_needs_mutable(enum pipe_format a, enum pipe_format b) { - return a != b; + if (a == b) + return false; + if (util_format_is_srgb(a)) + return util_format_linear(a) != b; + if (util_format_is_srgb(b)) + return util_format_linear(b) != a; + return true; } #endif diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 277ca1cb154..c77b38e521c 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -570,7 +570,8 @@ create_ici(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe ici->queueFamilyIndexCount = 0; /* assume we're going to be doing some CompressedTexSubImage */ - if (util_format_is_compressed(templ->format) && (ici->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) + if (util_format_is_compressed(templ->format) && (ici->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && + !vk_find_struct_const(ici->pNext, IMAGE_FORMAT_LIST_CREATE_INFO)) ici->flags |= VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT; if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE) @@ -834,11 +835,10 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t bool success = false; VkImageCreateInfo ici; enum pipe_format srgb = PIPE_FORMAT_NONE; - /* We use modifiers as a proxy for "this surface is used as a window system render target". - * For winsys, we need to be able to mutate between srgb and linear, but we don't need general + /* we often need to be able to mutate between srgb and linear, but we don't need general * image view/shader image format compatibility (that path means losing fast clears or compression on some hardware). */ - if (ici_modifier_count) { + if (!(templ->bind & ZINK_BIND_MUTABLE)) { srgb = util_format_is_srgb(templ->format) ? util_format_linear(templ->format) : util_format_srgb(templ->format); /* why do these helpers have different default return values? */ if (srgb == templ->format) diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c index cd26426ea68..f12663861c5 100644 --- a/src/gallium/drivers/zink/zink_surface.c +++ b/src/gallium/drivers/zink/zink_surface.c @@ -110,7 +110,7 @@ create_ivci(struct zink_screen *screen, /* this is used for framebuffer attachments to set up imageless framebuffers */ static void -init_surface_info(struct zink_surface *surface, struct zink_resource *res, VkImageViewCreateInfo *ivci) +init_surface_info(struct zink_screen *screen, struct zink_surface *surface, struct zink_resource *res, VkImageViewCreateInfo *ivci) { VkImageViewUsageCreateInfo *usage_info = (VkImageViewUsageCreateInfo *)ivci->pNext; surface->info.flags = res->obj->vkflags; @@ -123,6 +123,15 @@ init_surface_info(struct zink_surface *surface, struct zink_resource *res, VkIma struct kopper_displaytarget *cdt = res->obj->dt; if (zink_kopper_has_srgb(cdt)) surface->info.format[1] = ivci->format == cdt->formats[0] ? cdt->formats[1] : cdt->formats[0]; + } else { + enum pipe_format srgb = util_format_is_srgb(surface->base.format) ? util_format_linear(surface->base.format) : util_format_srgb(surface->base.format); + if (srgb == surface->base.format) + srgb = PIPE_FORMAT_NONE; + if (srgb) { + VkFormat format = zink_get_format(screen, srgb); + if (format) + surface->info.format[1] = format; + } } } @@ -188,7 +197,7 @@ create_surface(struct pipe_context *pctx, init_pipe_surface_info(pctx, &surface->base, templ, pres); surface->obj = zink_resource(pres)->obj; - init_surface_info(surface, res, ivci); + init_surface_info(screen, surface, res, ivci); if (!actually) return surface; @@ -240,7 +249,7 @@ zink_get_surface(struct zink_context *ctx, /* create a new surface, but don't actually create the imageview if mutable isn't set and the format is different; * mutable will be set later and the imageview will be filled in */ - bool actually = pres->format == templ->format || (res->obj->vkflags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT); + bool actually = !zink_format_needs_mutable(pres->format, templ->format) || (pres->bind & ZINK_BIND_MUTABLE); surface = do_create_surface(&ctx->base, pres, templ, ivci, hash, actually); entry = _mesa_hash_table_insert_pre_hashed(&res->surface_cache, hash, &surface->ivci, surface); if (!entry) { @@ -512,7 +521,7 @@ zink_surface_swapchain_update(struct zink_context *ctx, struct zink_surface *sur } surface->base.width = res->base.b.width0; surface->base.height = res->base.b.height0; - init_surface_info(surface, res, &surface->ivci); + init_surface_info(screen, surface, res, &surface->ivci); surface->dt_swapchain = cdt->swapchain; } if (!surface->swapchain[res->obj->dt_idx]) {