diff --git a/libweston/renderer-vulkan/vulkan-pixel-format.c b/libweston/renderer-vulkan/vulkan-pixel-format.c index 514008546..046548365 100644 --- a/libweston/renderer-vulkan/vulkan-pixel-format.c +++ b/libweston/renderer-vulkan/vulkan-pixel-format.c @@ -217,3 +217,27 @@ vulkan_renderer_query_dmabuf_format(struct vulkan_renderer *vr, const struct pix return true; } + +static const VkFormatFeatureFlags format_shm_tex_features = + VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | + VK_FORMAT_FEATURE_TRANSFER_DST_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + +bool +vulkan_renderer_query_shm_format(struct vulkan_renderer *vr, const struct pixel_format_info *format) +{ + assert(vulkan_instance_has(vr, EXTENSION_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2)); + + VkFormatProperties2 format_props = { + .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, + }; + + vkGetPhysicalDeviceFormatProperties2(vr->phys_dev, format->vulkan_format, &format_props); + + if ((format_props.formatProperties.optimalTilingFeatures & format_shm_tex_features) != format_shm_tex_features) + return false; + + return true; +} + diff --git a/libweston/renderer-vulkan/vulkan-renderer-internal.h b/libweston/renderer-vulkan/vulkan-renderer-internal.h index 3b065bbad..fb9859df8 100644 --- a/libweston/renderer-vulkan/vulkan-renderer-internal.h +++ b/libweston/renderer-vulkan/vulkan-renderer-internal.h @@ -245,4 +245,8 @@ bool vulkan_renderer_query_dmabuf_format(struct vulkan_renderer *vr, const struct pixel_format_info *format); +bool +vulkan_renderer_query_shm_format(struct vulkan_renderer *vr, + const struct pixel_format_info *format); + #endif /* VULKAN_RENDERER_INTERNAL_H */ diff --git a/libweston/renderer-vulkan/vulkan-renderer.c b/libweston/renderer-vulkan/vulkan-renderer.c index 03cda279d..8bf234a07 100644 --- a/libweston/renderer-vulkan/vulkan-renderer.c +++ b/libweston/renderer-vulkan/vulkan-renderer.c @@ -4162,6 +4162,34 @@ open_drm_device_node(struct vulkan_renderer *vr) return drm_fd; } +static int +populate_supported_shm_formats(struct weston_compositor *ec) +{ + struct vulkan_renderer *vr = get_renderer(ec); + + for (unsigned int i = 0; i < pixel_format_get_info_count(); i++) { + const struct pixel_format_info *info = pixel_format_get_info_by_index(i); + + /* libwayland registers XRGB8888 and ARGB8888 by default. */ + if (info->format == WL_SHM_FORMAT_XRGB8888 || + info->format == WL_SHM_FORMAT_ARGB8888) + continue; + + if (info->hide_from_clients) + continue; + + if (info->vulkan_format == VK_FORMAT_UNDEFINED) + continue; + + if (!vulkan_renderer_query_shm_format(vr, info)) + continue; + + wl_display_add_shm_format(ec->wl_display, info->format); + } + + return 0; +} + /* * Add extension flags to the bitfield that 'flags_out' points to. * 'table' stores extension names and flags to check for and 'avail' @@ -4404,11 +4432,6 @@ vulkan_renderer_display_create(struct weston_compositor *ec, wl_list_init(&vr->dmabuf_formats); wl_signal_init(&vr->destroy_signal); - // TODO: probe and register remaining shm formats - wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_XRGB8888); - wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_ARGB8888); - wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_ABGR2101010); - vulkan_renderer_create_instance(vr); vulkan_renderer_choose_physical_device(vr); @@ -4433,6 +4456,8 @@ vulkan_renderer_display_create(struct weston_compositor *ec, yesno(vulkan_device_has(vr, ext->flag))); } + populate_supported_shm_formats(ec); + vr->drm_fd = -1; if (vulkan_device_has(vr, EXTENSION_EXT_PHYSICAL_DEVICE_DRM)) vr->drm_fd = open_drm_device_node(vr);