[Mesa-dev] [PATCH mesa 3/6] vulkan/wsi/display: pass the plane's modifiers to the image

Eric Engestrom eric.engestrom at intel.com
Wed Sep 26 15:38:07 UTC 2018


Signed-off-by: Eric Engestrom <eric.engestrom at intel.com>
---
 src/vulkan/wsi/wsi_common_display.c | 95 ++++++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 1 deletion(-)

diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index 6c9160a445c8f25a8ad5..2a30b1139f06cbb56769 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -958,6 +958,87 @@ wsi_display_destroy_buffer(struct wsi_display *wsi,
                    &((struct drm_mode_destroy_dumb) { .handle = buffer }));
 }
 
+static uint64_t*
+wsi_get_modifiers_for_format(const struct wsi_display * const wsi,
+                             const uint32_t plane_id,
+                             const uint32_t drm_format,
+                             uint32_t * const modifiers_count)
+{
+   /* Get the properties of the plane */
+   drmModeObjectProperties *props =
+      drmModeObjectGetProperties(wsi->fd, plane_id,
+                                 DRM_MODE_OBJECT_PLANE);
+   if (!props)
+      return NULL;
+
+   /* Find the blob the contains the formats and their modifiers */
+   uint32_t blob_id = 0;
+   for (size_t i = 0; i< props->count_props; i++) {
+      const drmModePropertyPtr prop =
+         drmModeGetProperty(wsi->fd, props->props[i]);
+
+      if (!strcmp(prop->name, "IN_FORMATS")) {
+         blob_id = props->prop_values[i];
+         drmModeFreeProperty(prop);
+         break;
+      }
+
+      drmModeFreeProperty(prop);
+   }
+
+   /* Property not found, which means old kernel, so definitely no
+    * modifiers support */
+   if (blob_id == 0)
+      return NULL;
+
+   /* Grab the IN_FORMATS blob */
+   drmModePropertyBlobRes *blob = drmModeGetPropertyBlob(wsi->fd, blob_id);
+   if (!blob)
+      return NULL;
+
+   /* Get the formats and modifiers out of the blob */
+   struct drm_format_modifier_blob *fmt_mod_blob = blob->data;
+   uint32_t *blob_formats = (uint32_t*)((char*)fmt_mod_blob +
+                                        fmt_mod_blob->formats_offset);
+   struct drm_format_modifier *blob_modifiers =
+      (struct drm_format_modifier *)((char*)fmt_mod_blob +
+                                     fmt_mod_blob->modifiers_offset);
+
+   /* Find the format we care about in the list */
+   size_t format_index = 0;
+   for (size_t i = 0; i < fmt_mod_blob->count_formats; i++) {
+      if (blob_formats[i] == drm_format) {
+         format_index = i;
+         break;
+      }
+   }
+
+   /* Get the list of modifiers supported by that format */
+   uint32_t count_modifiers = 0;
+   uint64_t *modifiers = NULL;
+   for (size_t i = 0; i < fmt_mod_blob->count_modifiers; i++) {
+      struct drm_format_modifier *mod = &blob_modifiers[i];
+
+      if ((format_index < mod->offset) || (format_index > mod->offset + 63))
+         continue;
+      if (!(mod->formats & (1 << (format_index - mod->offset))))
+         continue;
+
+      modifiers = realloc(modifiers,
+                          (count_modifiers + 1) *
+                          sizeof(modifiers[0]));
+      assert(modifiers);
+      modifiers[count_modifiers++] = mod->modifier;
+   }
+
+   drmModeFreePropertyBlob(blob);
+
+   drmModeFreeObjectProperties(props);
+
+   *modifiers_count = count_modifiers;
+   return modifiers;
+}
+
 static VkResult
 wsi_display_image_init(VkDevice device_h,
                        struct wsi_swapchain *drv_chain,
@@ -969,6 +1050,10 @@ wsi_display_image_init(VkDevice device_h,
       (struct wsi_display_swapchain *) drv_chain;
    struct wsi_display *wsi = chain->wsi;
    uint32_t drm_format = 0;
+   VkIcdSurfaceDisplay *surface = chain->surface;
+   wsi_display_mode *display_mode =
+      wsi_display_mode_from_handle(surface->displayMode);
+   wsi_display_connector *connector = display_mode->connector;
 
    for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
       if (create_info->imageFormat == available_surface_formats[i].format) {
@@ -981,9 +1066,17 @@ wsi_display_image_init(VkDevice device_h,
    if (drm_format == 0)
       return VK_ERROR_DEVICE_LOST;
 
+   uint32_t modifiers_count = 0;
+   uint64_t *modifiers = wsi_get_modifiers_for_format(wsi, connector->plane_id, drm_format,
+                                                      &modifiers_count);
+   assume(!modifiers || modifiers_count > 0);
+
    VkResult result = wsi_create_native_image(&chain->base, create_info,
-                                             0, NULL, NULL,
+                                             !!modifiers_count,
+                                             &modifiers_count,
+                                             (const uint64_t * const *)&modifiers,
                                              &image->base);
+   free(modifiers);
    if (result != VK_SUCCESS)
       return result;
 
-- 
Cheers,
  Eric



More information about the mesa-dev mailing list