zink: handle mutable swapchain images with dmabuf
if a non-kopper swapchain image supports srgb, add a VkImageFormatListCreateInfo to permit srgb mutability and avoid violating spec cc: mesa-stable Acked-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17773>
This commit is contained in:

committed by
Marge Bot

parent
0a4e599918
commit
28ee911ad6
@@ -212,6 +212,8 @@ check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, uint64_t modifier)
|
||||
props2.pNext = &ycbcr_props;
|
||||
VkPhysicalDeviceImageFormatInfo2 info;
|
||||
info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
|
||||
/* possibly VkImageFormatListCreateInfo */
|
||||
info.pNext = ici->pNext;
|
||||
info.format = ici->format;
|
||||
info.type = ici->imageType;
|
||||
info.tiling = ici->tiling;
|
||||
@@ -221,13 +223,12 @@ check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, uint64_t modifier)
|
||||
VkPhysicalDeviceImageDrmFormatModifierInfoEXT mod_info;
|
||||
if (modifier != DRM_FORMAT_MOD_INVALID) {
|
||||
mod_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT;
|
||||
mod_info.pNext = NULL;
|
||||
mod_info.pNext = info.pNext;
|
||||
mod_info.drmFormatModifier = modifier;
|
||||
mod_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
mod_info.queueFamilyIndexCount = 0;
|
||||
info.pNext = &mod_info;
|
||||
} else
|
||||
info.pNext = NULL;
|
||||
}
|
||||
|
||||
ret = VKSCR(GetPhysicalDeviceImageFormatProperties2)(screen->pdev, &info, &props2);
|
||||
/* this is using VK_IMAGE_CREATE_EXTENDED_USAGE_BIT and can't be validated */
|
||||
@@ -324,6 +325,30 @@ find_modifier_feats(const struct zink_modifier_prop *prop, uint64_t modifier, ui
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the driver can't do mutable with this ICI, then try again after removing mutable (and
|
||||
* thus also the list of formats we might might mutate to)
|
||||
*/
|
||||
static bool
|
||||
double_check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, VkImageUsageFlags usage, uint64_t *mod)
|
||||
{
|
||||
if (!usage)
|
||||
return false;
|
||||
|
||||
const void *pNext = ici->pNext;
|
||||
ici->usage = usage;
|
||||
if (check_ici(screen, ici, *mod))
|
||||
return true;
|
||||
if (pNext) {
|
||||
ici->pNext = NULL;
|
||||
ici->flags &= ~VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
if (check_ici(screen, ici, *mod))
|
||||
return true;
|
||||
ici->pNext = pNext;
|
||||
ici->flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -345,11 +370,8 @@ get_image_usage(struct zink_screen *screen, VkImageCreateInfo *ici, const struct
|
||||
if (feats) {
|
||||
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))
|
||||
return usage;
|
||||
}
|
||||
if (double_check_ici(screen, ici, usage, mod))
|
||||
return usage;
|
||||
}
|
||||
}
|
||||
/* only try linear if no other options available */
|
||||
@@ -358,11 +380,8 @@ get_image_usage(struct zink_screen *screen, VkImageCreateInfo *ici, const struct
|
||||
if (feats) {
|
||||
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))
|
||||
return usage;
|
||||
}
|
||||
if (double_check_ici(screen, ici, usage, mod))
|
||||
return usage;
|
||||
}
|
||||
}
|
||||
} else
|
||||
@@ -377,11 +396,8 @@ get_image_usage(struct zink_screen *screen, VkImageCreateInfo *ici, const struct
|
||||
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))
|
||||
return usage;
|
||||
}
|
||||
if (double_check_ici(screen, ici, usage, mod))
|
||||
return usage;
|
||||
}
|
||||
*mod = DRM_FORMAT_MOD_INVALID;
|
||||
return 0;
|
||||
@@ -391,11 +407,17 @@ static uint64_t
|
||||
create_ici(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe_resource *templ, bool dmabuf, unsigned bind, unsigned modifiers_count, const uint64_t *modifiers, bool *success)
|
||||
{
|
||||
ici->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
ici->pNext = NULL;
|
||||
/* pNext may already be set */
|
||||
if (util_format_get_num_planes(templ->format) > 1)
|
||||
ici->flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
else
|
||||
ici->flags = modifiers_count || dmabuf || bind & (PIPE_BIND_SCANOUT | PIPE_BIND_DEPTH_STENCIL) ? 0 : VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
if (ici->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)
|
||||
/* unset VkImageFormatListCreateInfo if mutable */
|
||||
ici->pNext = NULL;
|
||||
else if (ici->pNext)
|
||||
/* add mutable if VkImageFormatListCreateInfo */
|
||||
ici->flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
ici->usage = 0;
|
||||
ici->queueFamilyIndexCount = 0;
|
||||
|
||||
@@ -634,6 +656,27 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
unsigned ici_modifier_count = winsys_modifier ? 1 : modifiers_count;
|
||||
bool success = false;
|
||||
VkImageCreateInfo ici;
|
||||
enum pipe_format srgb = PIPE_FORMAT_NONE;
|
||||
if (screen->info.have_KHR_swapchain_mutable_format) {
|
||||
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)
|
||||
srgb = PIPE_FORMAT_NONE;
|
||||
}
|
||||
VkFormat formats[2];
|
||||
VkImageFormatListCreateInfo format_list;
|
||||
if (srgb) {
|
||||
format_list.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;
|
||||
format_list.pNext = NULL;
|
||||
format_list.viewFormatCount = 2;
|
||||
format_list.pViewFormats = formats;
|
||||
|
||||
formats[0] = zink_get_format(screen, templ->format);
|
||||
formats[1] = zink_get_format(screen, srgb);
|
||||
ici.pNext = &format_list;
|
||||
} else {
|
||||
ici.pNext = NULL;
|
||||
}
|
||||
uint64_t mod = create_ici(screen, &ici, templ, external == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||
templ->bind, ici_modifier_count, ici_modifiers, &success);
|
||||
VkExternalMemoryImageCreateInfo emici;
|
||||
@@ -651,6 +694,7 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
goto fail1;
|
||||
|
||||
obj->render_target = (ici.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0;
|
||||
const void *pNext = ici.pNext;
|
||||
|
||||
if (shared || external) {
|
||||
emici.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
|
||||
@@ -687,7 +731,7 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
ici.pNext = &idfmlci;
|
||||
} else if (ici.tiling == VK_IMAGE_TILING_OPTIMAL) {
|
||||
if (!external)
|
||||
ici.pNext = NULL;
|
||||
ici.pNext = pNext;
|
||||
shared = false;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user