[Mesa-dev] [PATCH mesa 1/6] vulkan/wsi/display: setup the connector earlier

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


Instead of setting it up when the swapchain is presented, set it up when
creating the swapchain. This means that multiple swapchains might use
the same crtc, but only one can be active at a time, and the connectors
are now refcounted.

This is necessary for the next commit.

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

diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index 1dbed08d8a750ce21846..2d378afe3d36fe7cc177 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -20,6 +20,7 @@
  * OF THIS SOFTWARE.
  */
 
+#include "util/u_atomic.h"
 #include "util/macros.h"
 #include <stdlib.h>
 #include <stdio.h>
@@ -76,6 +77,7 @@ typedef struct wsi_display_connector {
    char                         *name;
    bool                         connected;
    bool                         active;
+   int                          refcount; /* swapchains using this connector */
    struct list_head             display_modes;
    wsi_display_mode             *current_mode;
    drmModeModeInfo              current_drm_mode;
@@ -270,6 +272,18 @@ wsi_display_find_connector(struct wsi_device *wsi_device,
    return NULL;
 }
 
+
+static uint32_t
+wsi_display_is_crtc_available(const struct wsi_display * const wsi,
+                             const uint32_t crtc_id)
+{
+   wsi_for_each_connector(connector, wsi)
+      if (connector->crtc_id == crtc_id)
+         return false;
+
+   return true;
+}
+
 static struct wsi_display_connector *
 wsi_display_alloc_connector(struct wsi_display *wsi,
                             uint32_t connector_id)
@@ -1042,6 +1056,12 @@ wsi_display_swapchain_destroy(struct wsi_swapchain *drv_chain,
 
    for (uint32_t i = 0; i < chain->base.image_count; i++)
       wsi_display_image_finish(drv_chain, allocator, &chain->images[i]);
+
+   wsi_display_mode *display_mode =
+      wsi_display_mode_from_handle(chain->surface->displayMode);
+   if (p_atomic_dec_zero(&display_mode->connector->refcount))
+      display_mode->connector->crtc_id = 0;
+
    vk_free(allocator, chain);
    return VK_SUCCESS;
 }
@@ -1320,7 +1340,8 @@ wsi_display_select_crtc(const struct wsi_display_connector *connector,
    uint32_t crtc_id = 0;
    for (int c = 0; crtc_id == 0 && c < mode_res->count_crtcs; c++) {
       drmModeCrtcPtr crtc = drmModeGetCrtc(wsi->fd, mode_res->crtcs[c]);
-      if (crtc && crtc->buffer_id == 0)
+      if (crtc && crtc->buffer_id == 0 &&
+          wsi_display_is_crtc_available(wsi, crtc->crtc_id))
          crtc_id = crtc->crtc_id;
       drmModeFreeCrtc(crtc);
    }
@@ -1614,13 +1635,6 @@ _wsi_display_queue_next(struct wsi_swapchain *drv_chain)
       }
 
       if (ret == -EINVAL) {
-         VkResult result = wsi_display_setup_connector(connector, display_mode);
-
-         if (result != VK_SUCCESS) {
-            image->state = WSI_IMAGE_IDLE;
-            return result;
-         }
-
          /* XXX allow setting of position */
          ret = drmModeSetCrtc(wsi->fd, connector->crtc_id,
                               image->fb_id, 0, 0,
@@ -1729,6 +1743,15 @@ wsi_display_surface_create_swapchain(
 
    chain->surface = (VkIcdSurfaceDisplay *) icd_surface;
 
+   wsi_display_mode *display_mode =
+      wsi_display_mode_from_handle(chain->surface->displayMode);
+
+   result = wsi_display_setup_connector(display_mode->connector, display_mode);
+   if (result != VK_SUCCESS)
+      return result;
+
+   p_atomic_inc(&display_mode->connector->refcount);
+
    for (uint32_t image = 0; image < chain->base.image_count; image++) {
       result = wsi_display_image_init(device, &chain->base,
                                       create_info, allocator,
-- 
Cheers,
  Eric



More information about the mesa-dev mailing list