/*
 * Copyright © 2017 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting documentation, and
 * that the name of the copyright holders not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  The copyright holders make no representations
 * about the suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

#include "util/macros.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <poll.h>
#include <stdbool.h>
#include <math.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "drm-uapi/drm_fourcc.h"
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
#include <xcb/randr.h>
#include <X11/Xlib-xcb.h>
#endif
#include "util/hash_table.h"
#include "util/list.h"

#include "vk_util.h"
#include "wsi_common_private.h"
#include "wsi_common_display.h"
#include "wsi_common_queue.h"

#if 0
#define wsi_display_debug(...) fprintf(stderr, __VA_ARGS__)
#define wsi_display_debug_code(...)     __VA_ARGS__
#else
#define wsi_display_debug(...)
#define wsi_display_debug_code(...)
#endif

/* These have lifetime equal to the instance, so they effectively
 * never go away. This means we must keep track of them separately
 * from all other resources.
 */
typedef struct wsi_display_mode {
   struct list_head             list;
   struct wsi_display_connector *connector;
   bool                         valid; /* was found in most recent poll */
   bool                         preferred;
   uint32_t                     clock; /* in kHz */
   uint16_t                     hdisplay, hsync_start, hsync_end, htotal, hskew;
   uint16_t                     vdisplay, vsync_start, vsync_end, vtotal, vscan;
   uint32_t                     flags;
} wsi_display_mode;

typedef struct wsi_display_connector {
   struct list_head             list;
   struct wsi_display           *wsi;
   uint32_t                     id;
   uint32_t                     crtc_id;
   char                         *name;
   bool                         connected;
   bool                         active;
   struct list_head             display_modes;
   wsi_display_mode             *current_mode;
   drmModeModeInfo              current_drm_mode;
   uint32_t                     dpms_property;
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
   xcb_randr_output_t           output;
#endif
} wsi_display_connector;

struct wsi_display {
   struct wsi_interface         base;

   const VkAllocationCallbacks  *alloc;

   int                          fd;

   pthread_mutex_t              wait_mutex;
   pthread_cond_t               wait_cond;
   pthread_t                    wait_thread;

   struct list_head             connectors; /* list of all discovered connectors */
};

#define wsi_for_each_display_mode(_mode, _conn)                 \
   list_for_each_entry_safe(struct wsi_display_mode, _mode,     \
                            &(_conn)->display_modes, list)

#define wsi_for_each_connector(_conn, _dev)                             \
   list_for_each_entry_safe(struct wsi_display_connector, _conn,        \
                            &(_dev)->connectors, list)

enum wsi_image_state {
   WSI_IMAGE_IDLE,
   WSI_IMAGE_DRAWING,
   WSI_IMAGE_QUEUED,
   WSI_IMAGE_FLIPPING,
   WSI_IMAGE_DISPLAYING
};

struct wsi_display_image {
   struct wsi_image             base;
   struct wsi_display_swapchain *chain;
   enum wsi_image_state         state;
   uint32_t                     fb_id;
   uint32_t                     buffer[4];
   uint64_t                     flip_sequence;
};

struct wsi_display_swapchain {
   struct wsi_swapchain         base;
   struct wsi_display           *wsi;
   VkIcdSurfaceDisplay          *surface;
   uint64_t                     flip_sequence;
   VkResult                     status;
   struct wsi_display_image     images[0];
};

struct wsi_display_fence {
   struct wsi_fence             base;
   bool                         event_received;
   bool                         destroyed;
   uint64_t                     sequence;
};

static uint64_t fence_sequence;

ICD_DEFINE_NONDISP_HANDLE_CASTS(wsi_display_mode, VkDisplayModeKHR)
ICD_DEFINE_NONDISP_HANDLE_CASTS(wsi_display_connector, VkDisplayKHR)

static bool
wsi_display_mode_matches_drm(wsi_display_mode *wsi,
                             drmModeModeInfoPtr drm)
{
   return wsi->clock == drm->clock &&
      wsi->hdisplay == drm->hdisplay &&
      wsi->hsync_start == drm->hsync_start &&
      wsi->hsync_end == drm->hsync_end &&
      wsi->htotal == drm->htotal &&
      wsi->hskew == drm->hskew &&
      wsi->vdisplay == drm->vdisplay &&
      wsi->vsync_start == drm->vsync_start &&
      wsi->vsync_end == drm->vsync_end &&
      wsi->vtotal == drm->vtotal &&
      MAX2(wsi->vscan, 1) == MAX2(drm->vscan, 1) &&
      wsi->flags == drm->flags;
}

static double
wsi_display_mode_refresh(struct wsi_display_mode *wsi)
{
   return (double) wsi->clock * 1000.0 / ((double) wsi->htotal *
                                          (double) wsi->vtotal *
                                          (double) MAX2(wsi->vscan, 1));
}

static uint64_t wsi_rel_to_abs_time(uint64_t rel_time)
{
   uint64_t current_time = wsi_common_get_current_time();

   /* check for overflow */
   if (rel_time > UINT64_MAX - current_time)
      return UINT64_MAX;

   return current_time + rel_time;
}

static struct wsi_display_mode *
wsi_display_find_drm_mode(struct wsi_device *wsi_device,
                          struct wsi_display_connector *connector,
                          drmModeModeInfoPtr mode)
{
   wsi_for_each_display_mode(display_mode, connector) {
      if (wsi_display_mode_matches_drm(display_mode, mode))
         return display_mode;
   }
   return NULL;
}

static void
wsi_display_invalidate_connector_modes(struct wsi_device *wsi_device,
                                       struct wsi_display_connector *connector)
{
   wsi_for_each_display_mode(display_mode, connector) {
      display_mode->valid = false;
   }
}

static VkResult
wsi_display_register_drm_mode(struct wsi_device *wsi_device,
                              struct wsi_display_connector *connector,
                              drmModeModeInfoPtr drm_mode)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_mode *display_mode =
      wsi_display_find_drm_mode(wsi_device, connector, drm_mode);

   if (display_mode) {
      display_mode->valid = true;
      return VK_SUCCESS;
   }

   display_mode = vk_zalloc(wsi->alloc, sizeof (struct wsi_display_mode),
                            8, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
   if (!display_mode)
      return VK_ERROR_OUT_OF_HOST_MEMORY;

   display_mode->connector = connector;
   display_mode->valid = true;
   display_mode->preferred = (drm_mode->type & DRM_MODE_TYPE_PREFERRED) != 0;
   display_mode->clock = drm_mode->clock; /* kHz */
   display_mode->hdisplay = drm_mode->hdisplay;
   display_mode->hsync_start = drm_mode->hsync_start;
   display_mode->hsync_end = drm_mode->hsync_end;
   display_mode->htotal = drm_mode->htotal;
   display_mode->hskew = drm_mode->hskew;
   display_mode->vdisplay = drm_mode->vdisplay;
   display_mode->vsync_start = drm_mode->vsync_start;
   display_mode->vsync_end = drm_mode->vsync_end;
   display_mode->vtotal = drm_mode->vtotal;
   display_mode->vscan = drm_mode->vscan;
   display_mode->flags = drm_mode->flags;

   list_addtail(&display_mode->list, &connector->display_modes);
   return VK_SUCCESS;
}

/*
 * Update our information about a specific connector
 */

static struct wsi_display_connector *
wsi_display_find_connector(struct wsi_device *wsi_device,
                          uint32_t connector_id)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   wsi_for_each_connector(connector, wsi) {
      if (connector->id == connector_id)
         return connector;
   }

   return NULL;
}

static struct wsi_display_connector *
wsi_display_alloc_connector(struct wsi_display *wsi,
                            uint32_t connector_id)
{
   struct wsi_display_connector *connector =
      vk_zalloc(wsi->alloc, sizeof (struct wsi_display_connector),
                8, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);

   connector->id = connector_id;
   connector->wsi = wsi;
   connector->active = false;
   /* XXX use EDID name */
   connector->name = "monitor";
   list_inithead(&connector->display_modes);
   return connector;
}

static struct wsi_display_connector *
wsi_display_get_connector(struct wsi_device *wsi_device,
                          uint32_t connector_id)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   if (wsi->fd < 0)
      return NULL;

   drmModeConnectorPtr drm_connector =
      drmModeGetConnector(wsi->fd, connector_id);

   if (!drm_connector)
      return NULL;

   struct wsi_display_connector *connector =
      wsi_display_find_connector(wsi_device, connector_id);

   if (!connector) {
      connector = wsi_display_alloc_connector(wsi, connector_id);
      if (!connector) {
         drmModeFreeConnector(drm_connector);
         return NULL;
      }
      list_addtail(&connector->list, &wsi->connectors);
   }

   connector->connected = drm_connector->connection != DRM_MODE_DISCONNECTED;

   /* Look for a DPMS property if we haven't already found one */
   for (int p = 0; connector->dpms_property == 0 &&
           p < drm_connector->count_props; p++)
   {
      drmModePropertyPtr prop = drmModeGetProperty(wsi->fd,
                                                   drm_connector->props[p]);
      if (!prop)
         continue;
      if (prop->flags & DRM_MODE_PROP_ENUM) {
         if (!strcmp(prop->name, "DPMS"))
            connector->dpms_property = drm_connector->props[p];
      }
      drmModeFreeProperty(prop);
   }

   /* Mark all connector modes as invalid */
   wsi_display_invalidate_connector_modes(wsi_device, connector);

   /*
    * List current modes, adding new ones and marking existing ones as
    * valid
    */
   for (int m = 0; m < drm_connector->count_modes; m++) {
      VkResult result = wsi_display_register_drm_mode(wsi_device,
                                                      connector,
                                                      &drm_connector->modes[m]);
      if (result != VK_SUCCESS) {
         drmModeFreeConnector(drm_connector);
         return NULL;
      }
   }

   drmModeFreeConnector(drm_connector);

   return connector;
}

#define MM_PER_PIXEL     (1.0/96.0 * 25.4)

static uint32_t
mode_size(struct wsi_display_mode *mode)
{
   /* fortunately, these are both uint16_t, so this is easy */
   return (uint32_t) mode->hdisplay * (uint32_t) mode->vdisplay;
}

static void
wsi_display_fill_in_display_properties(struct wsi_device *wsi_device,
                                       struct wsi_display_connector *connector,
                                       VkDisplayProperties2KHR *properties2)
{
   assert(properties2->sType == VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR);
   VkDisplayPropertiesKHR *properties = &properties2->displayProperties;

   properties->display = wsi_display_connector_to_handle(connector);
   properties->displayName = connector->name;

   /* Find the first preferred mode and assume that's the physical
    * resolution. If there isn't a preferred mode, find the largest mode and
    * use that.
    */

   struct wsi_display_mode *preferred_mode = NULL, *largest_mode = NULL;
   wsi_for_each_display_mode(display_mode, connector) {
      if (!display_mode->valid)
         continue;
      if (display_mode->preferred) {
         preferred_mode = display_mode;
         break;
      }
      if (largest_mode == NULL ||
          mode_size(display_mode) > mode_size(largest_mode))
      {
         largest_mode = display_mode;
      }
   }

   if (preferred_mode) {
      properties->physicalResolution.width = preferred_mode->hdisplay;
      properties->physicalResolution.height = preferred_mode->vdisplay;
   } else if (largest_mode) {
      properties->physicalResolution.width = largest_mode->hdisplay;
      properties->physicalResolution.height = largest_mode->vdisplay;
   } else {
      properties->physicalResolution.width = 1024;
      properties->physicalResolution.height = 768;
   }

   /* Make up physical size based on 96dpi */
   properties->physicalDimensions.width =
      floor(properties->physicalResolution.width * MM_PER_PIXEL + 0.5);
   properties->physicalDimensions.height =
      floor(properties->physicalResolution.height * MM_PER_PIXEL + 0.5);

   properties->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
   properties->planeReorderPossible = VK_FALSE;
   properties->persistentContent = VK_FALSE;
}

/*
 * Implement vkGetPhysicalDeviceDisplayPropertiesKHR (VK_KHR_display)
 */
VkResult
wsi_display_get_physical_device_display_properties(
   VkPhysicalDevice physical_device,
   struct wsi_device *wsi_device,
   uint32_t *property_count,
   VkDisplayPropertiesKHR *properties)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   if (properties == NULL) {
      return wsi_display_get_physical_device_display_properties2(
            physical_device, wsi_device, property_count, NULL);
   } else {
      /* If we're actually returning properties, allocate a temporary array of
       * VkDisplayProperties2KHR structs, call properties2 to fill them out,
       * and then copy them to the client.  This seems a bit expensive but
       * wsi_display_get_physical_device_display_properties2() calls
       * drmModeGetResources() which does an ioctl and then a bunch of
       * allocations so this should get lost in the noise.
       */
      VkDisplayProperties2KHR *props2 =
         vk_zalloc(wsi->alloc, sizeof(*props2) * *property_count, 8,
                   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
      if (props2 == NULL)
         return VK_ERROR_OUT_OF_HOST_MEMORY;

      for (uint32_t i = 0; i < *property_count; i++)
         props2[i].sType = VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR;

      VkResult result = wsi_display_get_physical_device_display_properties2(
            physical_device, wsi_device, property_count, props2);

      if (result == VK_SUCCESS || result == VK_INCOMPLETE) {
         for (uint32_t i = 0; i < *property_count; i++)
            properties[i] = props2[i].displayProperties;
      }

      vk_free(wsi->alloc, props2);

      return result;
   }
}

VkResult
wsi_display_get_physical_device_display_properties2(
   VkPhysicalDevice physical_device,
   struct wsi_device *wsi_device,
   uint32_t *property_count,
   VkDisplayProperties2KHR *properties)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   if (wsi->fd < 0)
      goto bail;

   drmModeResPtr mode_res = drmModeGetResources(wsi->fd);

   if (!mode_res)
      goto bail;

   VK_OUTARRAY_MAKE(conn, properties, property_count);

   /* Get current information */

   for (int c = 0; c < mode_res->count_connectors; c++) {
      struct wsi_display_connector *connector =
         wsi_display_get_connector(wsi_device, mode_res->connectors[c]);

      if (!connector) {
         drmModeFreeResources(mode_res);
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      }

      if (connector->connected) {
         vk_outarray_append(&conn, prop) {
            wsi_display_fill_in_display_properties(wsi_device,
                                                   connector,
                                                   prop);
         }
      }
   }

   drmModeFreeResources(mode_res);

   return vk_outarray_status(&conn);

bail:
   *property_count = 0;
   return VK_SUCCESS;
}

/*
 * Implement vkGetPhysicalDeviceDisplayPlanePropertiesKHR (VK_KHR_display
 */
static void
wsi_display_fill_in_display_plane_properties(
   struct wsi_device *wsi_device,
   struct wsi_display_connector *connector,
   VkDisplayPlaneProperties2KHR *properties)
{
   assert(properties->sType == VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR);
   VkDisplayPlanePropertiesKHR *prop = &properties->displayPlaneProperties;

   if (connector && connector->active) {
      prop->currentDisplay = wsi_display_connector_to_handle(connector);
      prop->currentStackIndex = 0;
   } else {
      prop->currentDisplay = VK_NULL_HANDLE;
      prop->currentStackIndex = 0;
   }
}

VkResult
wsi_display_get_physical_device_display_plane_properties(
   VkPhysicalDevice physical_device,
   struct wsi_device *wsi_device,
   uint32_t *property_count,
   VkDisplayPlanePropertiesKHR *properties)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   VK_OUTARRAY_MAKE(conn, properties, property_count);

   wsi_for_each_connector(connector, wsi) {
      vk_outarray_append(&conn, prop) {
         VkDisplayPlaneProperties2KHR prop2 = {
            .sType = VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR,
         };
         wsi_display_fill_in_display_plane_properties(wsi_device, connector,
                                                      &prop2);
         *prop = prop2.displayPlaneProperties;
      }
   }
   return vk_outarray_status(&conn);
}

VkResult
wsi_display_get_physical_device_display_plane_properties2(
   VkPhysicalDevice physical_device,
   struct wsi_device *wsi_device,
   uint32_t *property_count,
   VkDisplayPlaneProperties2KHR *properties)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   VK_OUTARRAY_MAKE(conn, properties, property_count);

   wsi_for_each_connector(connector, wsi) {
      vk_outarray_append(&conn, prop) {
         wsi_display_fill_in_display_plane_properties(wsi_device, connector,
                                                      prop);
      }
   }
   return vk_outarray_status(&conn);
}

/*
 * Implement vkGetDisplayPlaneSupportedDisplaysKHR (VK_KHR_display)
 */

VkResult
wsi_display_get_display_plane_supported_displays(
   VkPhysicalDevice physical_device,
   struct wsi_device *wsi_device,
   uint32_t plane_index,
   uint32_t *display_count,
   VkDisplayKHR *displays)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   VK_OUTARRAY_MAKE(conn, displays, display_count);

   int c = 0;

   wsi_for_each_connector(connector, wsi) {
      if (c == plane_index && connector->connected) {
         vk_outarray_append(&conn, display) {
            *display = wsi_display_connector_to_handle(connector);
         }
      }
      c++;
   }
   return vk_outarray_status(&conn);
}

/*
 * Implement vkGetDisplayModePropertiesKHR (VK_KHR_display)
 */

static void
wsi_display_fill_in_display_mode_properties(
   struct wsi_device *wsi_device,
   struct wsi_display_mode *display_mode,
   VkDisplayModeProperties2KHR *properties)
{
   assert(properties->sType == VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR);
   VkDisplayModePropertiesKHR *prop = &properties->displayModeProperties;

   prop->displayMode = wsi_display_mode_to_handle(display_mode);
   prop->parameters.visibleRegion.width = display_mode->hdisplay;
   prop->parameters.visibleRegion.height = display_mode->vdisplay;
   prop->parameters.refreshRate =
      (uint32_t) (wsi_display_mode_refresh(display_mode) * 1000 + 0.5);
}

VkResult
wsi_display_get_display_mode_properties(VkPhysicalDevice physical_device,
                                        struct wsi_device *wsi_device,
                                        VkDisplayKHR display,
                                        uint32_t *property_count,
                                        VkDisplayModePropertiesKHR *properties)
{
   struct wsi_display_connector *connector =
      wsi_display_connector_from_handle(display);

   VK_OUTARRAY_MAKE(conn, properties, property_count);

   wsi_for_each_display_mode(display_mode, connector) {
      if (!display_mode->valid)
         continue;

      vk_outarray_append(&conn, prop) {
         VkDisplayModeProperties2KHR prop2 = {
            .sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR,
         };
         wsi_display_fill_in_display_mode_properties(wsi_device,
                                                     display_mode, &prop2);
         *prop = prop2.displayModeProperties;
      }
   }
   return vk_outarray_status(&conn);
}

VkResult
wsi_display_get_display_mode_properties2(VkPhysicalDevice physical_device,
                                         struct wsi_device *wsi_device,
                                         VkDisplayKHR display,
                                         uint32_t *property_count,
                                         VkDisplayModeProperties2KHR *properties)
{
   struct wsi_display_connector *connector =
      wsi_display_connector_from_handle(display);

   VK_OUTARRAY_MAKE(conn, properties, property_count);

   wsi_for_each_display_mode(display_mode, connector) {
      if (!display_mode->valid)
         continue;

      vk_outarray_append(&conn, prop) {
         wsi_display_fill_in_display_mode_properties(wsi_device,
                                                     display_mode, prop);
      }
   }
   return vk_outarray_status(&conn);
}

static bool
wsi_display_mode_matches_vk(wsi_display_mode *wsi,
                            const VkDisplayModeParametersKHR *vk)
{
   return (vk->visibleRegion.width == wsi->hdisplay &&
           vk->visibleRegion.height == wsi->vdisplay &&
           fabs(wsi_display_mode_refresh(wsi) * 1000.0 - vk->refreshRate) < 10);
}

/*
 * Implement vkCreateDisplayModeKHR (VK_KHR_display)
 */
VkResult
wsi_display_create_display_mode(VkPhysicalDevice physical_device,
                                struct wsi_device *wsi_device,
                                VkDisplayKHR display,
                                const VkDisplayModeCreateInfoKHR *create_info,
                                const VkAllocationCallbacks *allocator,
                                VkDisplayModeKHR *mode)
{
   struct wsi_display_connector *connector =
      wsi_display_connector_from_handle(display);

   if (create_info->flags != 0)
      return VK_ERROR_INITIALIZATION_FAILED;

   /* Check and see if the requested mode happens to match an existing one and
    * return that. This makes the conformance suite happy. Doing more than
    * this would involve embedding the CVT function into the driver, which seems
    * excessive.
    */
   wsi_for_each_display_mode(display_mode, connector) {
      if (display_mode->valid) {
         if (wsi_display_mode_matches_vk(display_mode, &create_info->parameters)) {
            *mode = wsi_display_mode_to_handle(display_mode);
            return VK_SUCCESS;
         }
      }
   }
   return VK_ERROR_INITIALIZATION_FAILED;
}

/*
 * Implement vkGetDisplayPlaneCapabilities
 */
VkResult
wsi_get_display_plane_capabilities(VkPhysicalDevice physical_device,
                                   struct wsi_device *wsi_device,
                                   VkDisplayModeKHR mode_khr,
                                   uint32_t plane_index,
                                   VkDisplayPlaneCapabilitiesKHR *capabilities)
{
   struct wsi_display_mode *mode = wsi_display_mode_from_handle(mode_khr);

   /* XXX use actual values */
   capabilities->supportedAlpha = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
   capabilities->minSrcPosition.x = 0;
   capabilities->minSrcPosition.y = 0;
   capabilities->maxSrcPosition.x = 0;
   capabilities->maxSrcPosition.y = 0;
   capabilities->minSrcExtent.width = mode->hdisplay;
   capabilities->minSrcExtent.height = mode->vdisplay;
   capabilities->maxSrcExtent.width = mode->hdisplay;
   capabilities->maxSrcExtent.height = mode->vdisplay;
   capabilities->minDstPosition.x = 0;
   capabilities->minDstPosition.y = 0;
   capabilities->maxDstPosition.x = 0;
   capabilities->maxDstPosition.y = 0;
   capabilities->minDstExtent.width = mode->hdisplay;
   capabilities->minDstExtent.height = mode->vdisplay;
   capabilities->maxDstExtent.width = mode->hdisplay;
   capabilities->maxDstExtent.height = mode->vdisplay;
   return VK_SUCCESS;
}

VkResult
wsi_get_display_plane_capabilities2(
   VkPhysicalDevice physical_device,
   struct wsi_device *wsi_device,
   const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
   VkDisplayPlaneCapabilities2KHR *capabilities)
{
   assert(capabilities->sType ==
          VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR);

   VkResult result =
      wsi_get_display_plane_capabilities(physical_device, wsi_device,
                                         pDisplayPlaneInfo->mode,
                                         pDisplayPlaneInfo->planeIndex,
                                         &capabilities->capabilities);

   vk_foreach_struct(ext, capabilities->pNext) {
      switch (ext->sType) {
      case VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR: {
         VkSurfaceProtectedCapabilitiesKHR *protected = (void *)ext;
         protected->supportsProtected = VK_FALSE;
         break;
      }

      default:
         /* Ignored */
         break;
      }
   }

   return result;
}

VkResult
wsi_create_display_surface(VkInstance instance,
                           const VkAllocationCallbacks *allocator,
                           const VkDisplaySurfaceCreateInfoKHR *create_info,
                           VkSurfaceKHR *surface_khr)
{
   VkIcdSurfaceDisplay *surface = vk_zalloc(allocator, sizeof *surface, 8,
                                            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);

   if (surface == NULL)
      return VK_ERROR_OUT_OF_HOST_MEMORY;

   surface->base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;

   surface->displayMode = create_info->displayMode;
   surface->planeIndex = create_info->planeIndex;
   surface->planeStackIndex = create_info->planeStackIndex;
   surface->transform = create_info->transform;
   surface->globalAlpha = create_info->globalAlpha;
   surface->alphaMode = create_info->alphaMode;
   surface->imageExtent = create_info->imageExtent;

   *surface_khr = VkIcdSurfaceBase_to_handle(&surface->base);
   return VK_SUCCESS;
}


static VkResult
wsi_display_surface_get_support(VkIcdSurfaceBase *surface,
                                struct wsi_device *wsi_device,
                                uint32_t queueFamilyIndex,
                                VkBool32* pSupported)
{
   *pSupported = VK_TRUE;
   return VK_SUCCESS;
}

static VkResult
wsi_display_surface_get_capabilities(VkIcdSurfaceBase *surface_base,
                                     struct wsi_device *wsi_device,
                                     VkSurfaceCapabilitiesKHR* caps)
{
   VkIcdSurfaceDisplay *surface = (VkIcdSurfaceDisplay *) surface_base;
   wsi_display_mode *mode = wsi_display_mode_from_handle(surface->displayMode);

   caps->currentExtent.width = mode->hdisplay;
   caps->currentExtent.height = mode->vdisplay;

   caps->minImageExtent = (VkExtent2D) { 1, 1 };
   caps->maxImageExtent = (VkExtent2D) {
      wsi_device->maxImageDimension2D,
      wsi_device->maxImageDimension2D,
   };

   caps->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

   caps->minImageCount = 2;
   caps->maxImageCount = 0;

   caps->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
   caps->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
   caps->maxImageArrayLayers = 1;
   caps->supportedUsageFlags =
      VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
      VK_IMAGE_USAGE_SAMPLED_BIT |
      VK_IMAGE_USAGE_TRANSFER_DST_BIT |
      VK_IMAGE_USAGE_STORAGE_BIT |
      VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

   return VK_SUCCESS;
}

static VkResult
wsi_display_surface_get_surface_counters(
   VkIcdSurfaceBase *surface_base,
   VkSurfaceCounterFlagsEXT *counters)
{
   *counters = VK_SURFACE_COUNTER_VBLANK_EXT;
   return VK_SUCCESS;
}

static VkResult
wsi_display_surface_get_capabilities2(VkIcdSurfaceBase *icd_surface,
                                      struct wsi_device *wsi_device,
                                      const void *info_next,
                                      VkSurfaceCapabilities2KHR *caps)
{
   assert(caps->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR);
   VkResult result;

   result = wsi_display_surface_get_capabilities(icd_surface, wsi_device,
                                                 &caps->surfaceCapabilities);
   if (result != VK_SUCCESS)
      return result;

   struct wsi_surface_supported_counters *counters =
      vk_find_struct( caps->pNext, WSI_SURFACE_SUPPORTED_COUNTERS_MESA);

   if (counters) {
      result = wsi_display_surface_get_surface_counters(
         icd_surface,
         &counters->supported_surface_counters);
   }

   return result;
}

static const struct {
   VkFormat     format;
   uint32_t     drm_format;
} available_surface_formats[] = {
   { .format = VK_FORMAT_B8G8R8A8_SRGB, .drm_format = DRM_FORMAT_XRGB8888 },
   { .format = VK_FORMAT_B8G8R8A8_UNORM, .drm_format = DRM_FORMAT_XRGB8888 },
};

static VkResult
wsi_display_surface_get_formats(VkIcdSurfaceBase *icd_surface,
                                struct wsi_device *wsi_device,
                                uint32_t *surface_format_count,
                                VkSurfaceFormatKHR *surface_formats)
{
   VK_OUTARRAY_MAKE(out, surface_formats, surface_format_count);

   for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
      vk_outarray_append(&out, f) {
         f->format = available_surface_formats[i].format;
         f->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
      }
   }

   return vk_outarray_status(&out);
}

static VkResult
wsi_display_surface_get_formats2(VkIcdSurfaceBase *surface,
                                 struct wsi_device *wsi_device,
                                 const void *info_next,
                                 uint32_t *surface_format_count,
                                 VkSurfaceFormat2KHR *surface_formats)
{
   VK_OUTARRAY_MAKE(out, surface_formats, surface_format_count);

   for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
      vk_outarray_append(&out, f) {
         assert(f->sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR);
         f->surfaceFormat.format = available_surface_formats[i].format;
         f->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
      }
   }

   return vk_outarray_status(&out);
}

static VkResult
wsi_display_surface_get_present_modes(VkIcdSurfaceBase *surface,
                                      uint32_t *present_mode_count,
                                      VkPresentModeKHR *present_modes)
{
   VK_OUTARRAY_MAKE(conn, present_modes, present_mode_count);

   vk_outarray_append(&conn, present) {
      *present = VK_PRESENT_MODE_FIFO_KHR;
   }

   return vk_outarray_status(&conn);
}

static VkResult
wsi_display_surface_get_present_rectangles(VkIcdSurfaceBase *surface_base,
                                           struct wsi_device *wsi_device,
                                           uint32_t* pRectCount,
                                           VkRect2D* pRects)
{
   VkIcdSurfaceDisplay *surface = (VkIcdSurfaceDisplay *) surface_base;
   wsi_display_mode *mode = wsi_display_mode_from_handle(surface->displayMode);
   VK_OUTARRAY_MAKE(out, pRects, pRectCount);

   if (wsi_device_matches_drm_fd(wsi_device, mode->connector->wsi->fd)) {
      vk_outarray_append(&out, rect) {
         *rect = (VkRect2D) {
            .offset = { 0, 0 },
            .extent = { mode->hdisplay, mode->vdisplay },
         };
      }
   }

   return vk_outarray_status(&out);
}

static void
wsi_display_destroy_buffer(struct wsi_display *wsi,
                           uint32_t buffer)
{
   (void) drmIoctl(wsi->fd, DRM_IOCTL_GEM_CLOSE,
                   &((struct drm_gem_close) { .handle = buffer }));
}

static VkResult
wsi_display_image_init(VkDevice device_h,
                       struct wsi_swapchain *drv_chain,
                       const VkSwapchainCreateInfoKHR *create_info,
                       const VkAllocationCallbacks *allocator,
                       struct wsi_display_image *image)
{
   struct wsi_display_swapchain *chain =
      (struct wsi_display_swapchain *) drv_chain;
   struct wsi_display *wsi = chain->wsi;
   uint32_t drm_format = 0;

   for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
      if (create_info->imageFormat == available_surface_formats[i].format) {
         drm_format = available_surface_formats[i].drm_format;
         break;
      }
   }

   /* the application provided an invalid format, bail */
   if (drm_format == 0)
      return VK_ERROR_DEVICE_LOST;

   VkResult result = wsi_create_native_image(&chain->base, create_info,
                                             0, NULL, NULL,
                                             &image->base);
   if (result != VK_SUCCESS)
      return result;

   memset(image->buffer, 0, sizeof (image->buffer));

   for (unsigned int i = 0; i < image->base.num_planes; i++) {
      int ret = drmPrimeFDToHandle(wsi->fd, image->base.fds[i],
                                   &image->buffer[i]);

      close(image->base.fds[i]);
      image->base.fds[i] = -1;
      if (ret < 0)
         goto fail_handle;
   }

   image->chain = chain;
   image->state = WSI_IMAGE_IDLE;
   image->fb_id = 0;

   int ret = drmModeAddFB2(wsi->fd,
                           create_info->imageExtent.width,
                           create_info->imageExtent.height,
                           drm_format,
                           image->buffer,
                           image->base.row_pitches,
                           image->base.offsets,
                           &image->fb_id, 0);

   if (ret)
      goto fail_fb;

   return VK_SUCCESS;

fail_fb:
fail_handle:
   for (unsigned int i = 0; i < image->base.num_planes; i++) {
      if (image->buffer[i])
         wsi_display_destroy_buffer(wsi, image->buffer[i]);
      if (image->base.fds[i] != -1) {
         close(image->base.fds[i]);
         image->base.fds[i] = -1;
      }
   }

   wsi_destroy_image(&chain->base, &image->base);

   return VK_ERROR_OUT_OF_HOST_MEMORY;
}

static void
wsi_display_image_finish(struct wsi_swapchain *drv_chain,
                         const VkAllocationCallbacks *allocator,
                         struct wsi_display_image *image)
{
   struct wsi_display_swapchain *chain =
      (struct wsi_display_swapchain *) drv_chain;
   struct wsi_display *wsi = chain->wsi;

   drmModeRmFB(wsi->fd, image->fb_id);
   for (unsigned int i = 0; i < image->base.num_planes; i++)
      wsi_display_destroy_buffer(wsi, image->buffer[i]);
   wsi_destroy_image(&chain->base, &image->base);
}

static VkResult
wsi_display_swapchain_destroy(struct wsi_swapchain *drv_chain,
                              const VkAllocationCallbacks *allocator)
{
   struct wsi_display_swapchain *chain =
      (struct wsi_display_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_swapchain_finish(&chain->base);
   vk_free(allocator, chain);
   return VK_SUCCESS;
}

static struct wsi_image *
wsi_display_get_wsi_image(struct wsi_swapchain *drv_chain,
                          uint32_t image_index)
{
   struct wsi_display_swapchain *chain =
      (struct wsi_display_swapchain *) drv_chain;

   return &chain->images[image_index].base;
}

static void
wsi_display_idle_old_displaying(struct wsi_display_image *active_image)
{
   struct wsi_display_swapchain *chain = active_image->chain;

   wsi_display_debug("idle everyone but %ld\n",
                     active_image - &(chain->images[0]));
   for (uint32_t i = 0; i < chain->base.image_count; i++)
      if (chain->images[i].state == WSI_IMAGE_DISPLAYING &&
          &chain->images[i] != active_image)
      {
         wsi_display_debug("idle %d\n", i);
         chain->images[i].state = WSI_IMAGE_IDLE;
      }
}

static VkResult
_wsi_display_queue_next(struct wsi_swapchain *drv_chain);

static void
wsi_display_page_flip_handler2(int fd,
                               unsigned int frame,
                               unsigned int sec,
                               unsigned int usec,
                               uint32_t crtc_id,
                               void *data)
{
   struct wsi_display_image *image = data;
   struct wsi_display_swapchain *chain = image->chain;

   wsi_display_debug("image %ld displayed at %d\n",
                     image - &(image->chain->images[0]), frame);
   image->state = WSI_IMAGE_DISPLAYING;
   wsi_display_idle_old_displaying(image);
   VkResult result = _wsi_display_queue_next(&(chain->base));
   if (result != VK_SUCCESS)
      chain->status = result;
}

static void wsi_display_fence_event_handler(struct wsi_display_fence *fence);

static void wsi_display_page_flip_handler(int fd,
                                          unsigned int frame,
                                          unsigned int sec,
                                          unsigned int usec,
                                          void *data)
{
   wsi_display_page_flip_handler2(fd, frame, sec, usec, 0, data);
}

static void wsi_display_vblank_handler(int fd, unsigned int frame,
                                       unsigned int sec, unsigned int usec,
                                       void *data)
{
   struct wsi_display_fence *fence = data;

   wsi_display_fence_event_handler(fence);
}

static void wsi_display_sequence_handler(int fd, uint64_t frame,
                                         uint64_t nsec, uint64_t user_data)
{
   struct wsi_display_fence *fence =
      (struct wsi_display_fence *) (uintptr_t) user_data;

   wsi_display_fence_event_handler(fence);
}

static drmEventContext event_context = {
   .version = DRM_EVENT_CONTEXT_VERSION,
   .page_flip_handler = wsi_display_page_flip_handler,
#if DRM_EVENT_CONTEXT_VERSION >= 3
   .page_flip_handler2 = wsi_display_page_flip_handler2,
#endif
   .vblank_handler = wsi_display_vblank_handler,
   .sequence_handler = wsi_display_sequence_handler,
};

static void *
wsi_display_wait_thread(void *data)
{
   struct wsi_display *wsi = data;
   struct pollfd pollfd = {
      .fd = wsi->fd,
      .events = POLLIN
   };

   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
   for (;;) {
      int ret = poll(&pollfd, 1, -1);
      if (ret > 0) {
         pthread_mutex_lock(&wsi->wait_mutex);
         (void) drmHandleEvent(wsi->fd, &event_context);
         pthread_mutex_unlock(&wsi->wait_mutex);
         pthread_cond_broadcast(&wsi->wait_cond);
      }
   }
   return NULL;
}

static int
wsi_display_start_wait_thread(struct wsi_display *wsi)
{
   if (!wsi->wait_thread) {
      int ret = pthread_create(&wsi->wait_thread, NULL,
                               wsi_display_wait_thread, wsi);
      if (ret)
         return ret;
   }
   return 0;
}

/*
 * Wait for at least one event from the kernel to be processed.
 * Call with wait_mutex held
 */
static int
wsi_display_wait_for_event(struct wsi_display *wsi,
                           uint64_t timeout_ns)
{
   int ret;

   ret = wsi_display_start_wait_thread(wsi);

   if (ret)
      return ret;

   struct timespec abs_timeout = {
      .tv_sec = timeout_ns / 1000000000ULL,
      .tv_nsec = timeout_ns % 1000000000ULL,
   };

   ret = pthread_cond_timedwait(&wsi->wait_cond, &wsi->wait_mutex,
                                &abs_timeout);

   wsi_display_debug("%9ld done waiting for event %d\n", pthread_self(), ret);
   return ret;
}

static VkResult
wsi_display_acquire_next_image(struct wsi_swapchain *drv_chain,
                               const VkAcquireNextImageInfoKHR *info,
                               uint32_t *image_index)
{
   struct wsi_display_swapchain *chain =
      (struct wsi_display_swapchain *)drv_chain;
   struct wsi_display *wsi = chain->wsi;
   int ret = 0;
   VkResult result = VK_SUCCESS;

   /* Bail early if the swapchain is broken */
   if (chain->status != VK_SUCCESS)
      return chain->status;

   uint64_t timeout = info->timeout;
   if (timeout != 0 && timeout != UINT64_MAX)
      timeout = wsi_rel_to_abs_time(timeout);

   pthread_mutex_lock(&wsi->wait_mutex);
   for (;;) {
      for (uint32_t i = 0; i < chain->base.image_count; i++) {
         if (chain->images[i].state == WSI_IMAGE_IDLE) {
            *image_index = i;
            wsi_display_debug("image %d available\n", i);
            chain->images[i].state = WSI_IMAGE_DRAWING;
            result = VK_SUCCESS;
            goto done;
         }
         wsi_display_debug("image %d state %d\n", i, chain->images[i].state);
      }

      if (ret == ETIMEDOUT) {
         result = VK_TIMEOUT;
         goto done;
      }

      ret = wsi_display_wait_for_event(wsi, timeout);

      if (ret && ret != ETIMEDOUT) {
         result = VK_ERROR_SURFACE_LOST_KHR;
         goto done;
      }
   }
done:
   pthread_mutex_unlock(&wsi->wait_mutex);

   if (result != VK_SUCCESS)
      return result;

   return chain->status;
}

/*
 * Check whether there are any other connectors driven by this crtc
 */
static bool
wsi_display_crtc_solo(struct wsi_display *wsi,
                      drmModeResPtr mode_res,
                      drmModeConnectorPtr connector,
                      uint32_t crtc_id)
{
   /* See if any other connectors share the same encoder */
   for (int c = 0; c < mode_res->count_connectors; c++) {
      if (mode_res->connectors[c] == connector->connector_id)
         continue;

      drmModeConnectorPtr other_connector =
         drmModeGetConnector(wsi->fd, mode_res->connectors[c]);

      if (other_connector) {
         bool match = (other_connector->encoder_id == connector->encoder_id);
         drmModeFreeConnector(other_connector);
         if (match)
            return false;
      }
   }

   /* See if any other encoders share the same crtc */
   for (int e = 0; e < mode_res->count_encoders; e++) {
      if (mode_res->encoders[e] == connector->encoder_id)
         continue;

      drmModeEncoderPtr other_encoder =
         drmModeGetEncoder(wsi->fd, mode_res->encoders[e]);

      if (other_encoder) {
         bool match = (other_encoder->crtc_id == crtc_id);
         drmModeFreeEncoder(other_encoder);
         if (match)
            return false;
      }
   }
   return true;
}

/*
 * Pick a suitable CRTC to drive this connector. Prefer a CRTC which is
 * currently driving this connector and not any others. Settle for a CRTC
 * which is currently idle.
 */
static uint32_t
wsi_display_select_crtc(const struct wsi_display_connector *connector,
                        drmModeResPtr mode_res,
                        drmModeConnectorPtr drm_connector)
{
   struct wsi_display *wsi = connector->wsi;

   /* See what CRTC is currently driving this connector */
   if (drm_connector->encoder_id) {
      drmModeEncoderPtr encoder =
         drmModeGetEncoder(wsi->fd, drm_connector->encoder_id);

      if (encoder) {
         uint32_t crtc_id = encoder->crtc_id;
         drmModeFreeEncoder(encoder);
         if (crtc_id) {
            if (wsi_display_crtc_solo(wsi, mode_res, drm_connector, crtc_id))
               return crtc_id;
         }
      }
   }
   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)
         crtc_id = crtc->crtc_id;
      drmModeFreeCrtc(crtc);
   }
   return crtc_id;
}

static VkResult
wsi_display_setup_connector(wsi_display_connector *connector,
                            wsi_display_mode *display_mode)
{
   struct wsi_display *wsi = connector->wsi;

   if (connector->current_mode == display_mode && connector->crtc_id)
      return VK_SUCCESS;

   VkResult result = VK_SUCCESS;

   drmModeResPtr mode_res = drmModeGetResources(wsi->fd);
   if (!mode_res) {
      if (errno == ENOMEM)
         result = VK_ERROR_OUT_OF_HOST_MEMORY;
      else
         result = VK_ERROR_SURFACE_LOST_KHR;
      goto bail;
   }

   drmModeConnectorPtr drm_connector =
      drmModeGetConnectorCurrent(wsi->fd, connector->id);

   if (!drm_connector) {
      if (errno == ENOMEM)
         result = VK_ERROR_OUT_OF_HOST_MEMORY;
      else
         result = VK_ERROR_SURFACE_LOST_KHR;
      goto bail_mode_res;
   }

   /* Pick a CRTC if we don't have one */
   if (!connector->crtc_id) {
      connector->crtc_id = wsi_display_select_crtc(connector,
                                                   mode_res, drm_connector);
      if (!connector->crtc_id) {
         result = VK_ERROR_SURFACE_LOST_KHR;
         goto bail_connector;
      }
   }

   if (connector->current_mode != display_mode) {

      /* Find the drm mode corresponding to the requested VkDisplayMode */
      drmModeModeInfoPtr drm_mode = NULL;

      for (int m = 0; m < drm_connector->count_modes; m++) {
         drm_mode = &drm_connector->modes[m];
         if (wsi_display_mode_matches_drm(display_mode, drm_mode))
            break;
         drm_mode = NULL;
      }

      if (!drm_mode) {
         result = VK_ERROR_SURFACE_LOST_KHR;
         goto bail_connector;
      }

      connector->current_mode = display_mode;
      connector->current_drm_mode = *drm_mode;
   }

bail_connector:
   drmModeFreeConnector(drm_connector);
bail_mode_res:
   drmModeFreeResources(mode_res);
bail:
   return result;

}

static VkResult
wsi_display_fence_wait(struct wsi_fence *fence_wsi, uint64_t timeout)
{
   const struct wsi_device *wsi_device = fence_wsi->wsi_device;
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_fence *fence = (struct wsi_display_fence *) fence_wsi;

   wsi_display_debug("%9lu wait fence %lu %ld\n",
                     pthread_self(), fence->sequence,
                     (int64_t) (timeout - wsi_common_get_current_time()));
   wsi_display_debug_code(uint64_t start_ns = wsi_common_get_current_time());
   pthread_mutex_lock(&wsi->wait_mutex);

   VkResult result;
   int ret = 0;
   for (;;) {
      if (fence->event_received) {
         wsi_display_debug("%9lu fence %lu passed\n",
                           pthread_self(), fence->sequence);
         result = VK_SUCCESS;
         break;
      }

      if (ret == ETIMEDOUT) {
         wsi_display_debug("%9lu fence %lu timeout\n",
                           pthread_self(), fence->sequence);
         result = VK_TIMEOUT;
         break;
      }

      ret = wsi_display_wait_for_event(wsi, timeout);

      if (ret && ret != ETIMEDOUT) {
         wsi_display_debug("%9lu fence %lu error\n",
                           pthread_self(), fence->sequence);
         result = VK_ERROR_DEVICE_LOST;
         break;
      }
   }
   pthread_mutex_unlock(&wsi->wait_mutex);
   wsi_display_debug("%9lu fence wait %f ms\n",
                     pthread_self(),
                     ((int64_t) (wsi_common_get_current_time() - start_ns)) /
                     1.0e6);
   return result;
}

static void
wsi_display_fence_check_free(struct wsi_display_fence *fence)
{
   if (fence->event_received && fence->destroyed)
      vk_free(fence->base.alloc, fence);
}

static void wsi_display_fence_event_handler(struct wsi_display_fence *fence)
{
   fence->event_received = true;
   wsi_display_fence_check_free(fence);
}

static void
wsi_display_fence_destroy(struct wsi_fence *fence_wsi)
{
   struct wsi_display_fence *fence = (struct wsi_display_fence *) fence_wsi;

   assert(!fence->destroyed);
   fence->destroyed = true;
   wsi_display_fence_check_free(fence);
}

static struct wsi_display_fence *
wsi_display_fence_alloc(VkDevice device,
                        const struct wsi_device *wsi_device,
                        VkDisplayKHR display,
                        const VkAllocationCallbacks *allocator)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_fence *fence =
      vk_zalloc2(wsi->alloc, allocator, sizeof (*fence),
                8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);

   if (!fence)
      return NULL;

   fence->base.device = device;
   fence->base.display = display;
   fence->base.wsi_device = wsi_device;
   fence->base.alloc = allocator ? allocator : wsi->alloc;
   fence->base.wait = wsi_display_fence_wait;
   fence->base.destroy = wsi_display_fence_destroy;
   fence->event_received = false;
   fence->destroyed = false;
   fence->sequence = ++fence_sequence;
   return fence;
}

static VkResult
wsi_register_vblank_event(struct wsi_display_fence *fence,
                          const struct wsi_device *wsi_device,
                          VkDisplayKHR display,
                          uint32_t flags,
                          uint64_t frame_requested,
                          uint64_t *frame_queued)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_connector *connector =
      wsi_display_connector_from_handle(display);

   if (wsi->fd < 0)
      return VK_ERROR_INITIALIZATION_FAILED;

   for (;;) {
      int ret = drmCrtcQueueSequence(wsi->fd, connector->crtc_id,
                                     flags,
                                     frame_requested,
                                     frame_queued,
                                     (uintptr_t) fence);

      if (!ret)
         return VK_SUCCESS;

      if (errno != ENOMEM) {

         /* Something unexpected happened. Pause for a moment so the
          * application doesn't just spin and then return a failure indication
          */

         wsi_display_debug("queue vblank event %lu failed\n", fence->sequence);
         struct timespec delay = {
            .tv_sec = 0,
            .tv_nsec = 100000000ull,
         };
         nanosleep(&delay, NULL);
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      }

      /* The kernel event queue is full. Wait for some events to be
       * processed and try again
       */

      pthread_mutex_lock(&wsi->wait_mutex);
      ret = wsi_display_wait_for_event(wsi, wsi_rel_to_abs_time(100000000ull));
      pthread_mutex_unlock(&wsi->wait_mutex);

      if (ret) {
         wsi_display_debug("vblank queue full, event wait failed\n");
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      }
   }
}

/*
 * Check to see if the kernel has no flip queued and if there's an image
 * waiting to be displayed.
 */
static VkResult
_wsi_display_queue_next(struct wsi_swapchain *drv_chain)
{
   struct wsi_display_swapchain *chain =
      (struct wsi_display_swapchain *) drv_chain;
   struct wsi_display *wsi = chain->wsi;
   VkIcdSurfaceDisplay *surface = chain->surface;
   wsi_display_mode *display_mode =
      wsi_display_mode_from_handle(surface->displayMode);
   wsi_display_connector *connector = display_mode->connector;

   if (wsi->fd < 0)
      return VK_ERROR_SURFACE_LOST_KHR;

   if (display_mode != connector->current_mode)
      connector->active = false;

   for (;;) {

      /* Check to see if there is an image to display, or if some image is
       * already queued */

      struct wsi_display_image *image = NULL;

      for (uint32_t i = 0; i < chain->base.image_count; i++) {
         struct wsi_display_image *tmp_image = &chain->images[i];

         switch (tmp_image->state) {
         case WSI_IMAGE_FLIPPING:
            /* already flipping, don't send another to the kernel yet */
            return VK_SUCCESS;
         case WSI_IMAGE_QUEUED:
            /* find the oldest queued */
            if (!image || tmp_image->flip_sequence < image->flip_sequence)
               image = tmp_image;
            break;
         default:
            break;
         }
      }

      if (!image)
         return VK_SUCCESS;

      int ret;
      if (connector->active) {
         ret = drmModePageFlip(wsi->fd, connector->crtc_id, image->fb_id,
                                   DRM_MODE_PAGE_FLIP_EVENT, image);
         if (ret == 0) {
            image->state = WSI_IMAGE_FLIPPING;
            return VK_SUCCESS;
         }
         wsi_display_debug("page flip err %d %s\n", ret, strerror(-ret));
      } else {
         ret = -EINVAL;
      }

      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,
                              &connector->id, 1,
                              &connector->current_drm_mode);
         if (ret == 0) {
            /* Assume that the mode set is synchronous and that any
             * previous image is now idle.
             */
            image->state = WSI_IMAGE_DISPLAYING;
            wsi_display_idle_old_displaying(image);
            connector->active = true;
            return VK_SUCCESS;
         }
      }

      if (ret != -EACCES) {
         connector->active = false;
         image->state = WSI_IMAGE_IDLE;
         return VK_ERROR_SURFACE_LOST_KHR;
      }

      /* Some other VT is currently active. Sit here waiting for
       * our VT to become active again by polling once a second
       */
      usleep(1000 * 1000);
      connector->active = false;
   }
}

static VkResult
wsi_display_queue_present(struct wsi_swapchain *drv_chain,
                          uint32_t image_index,
                          const VkPresentRegionKHR *damage)
{
   struct wsi_display_swapchain *chain =
      (struct wsi_display_swapchain *) drv_chain;
   struct wsi_display *wsi = chain->wsi;
   struct wsi_display_image *image = &chain->images[image_index];
   VkResult result;

   /* Bail early if the swapchain is broken */
   if (chain->status != VK_SUCCESS)
      return chain->status;

   assert(image->state == WSI_IMAGE_DRAWING);
   wsi_display_debug("present %d\n", image_index);

   pthread_mutex_lock(&wsi->wait_mutex);

   image->flip_sequence = ++chain->flip_sequence;
   image->state = WSI_IMAGE_QUEUED;

   result = _wsi_display_queue_next(drv_chain);
   if (result != VK_SUCCESS)
      chain->status = result;

   pthread_mutex_unlock(&wsi->wait_mutex);

   if (result != VK_SUCCESS)
      return result;

   return chain->status;
}

static VkResult
wsi_display_surface_create_swapchain(
   VkIcdSurfaceBase *icd_surface,
   VkDevice device,
   struct wsi_device *wsi_device,
   const VkSwapchainCreateInfoKHR *create_info,
   const VkAllocationCallbacks *allocator,
   struct wsi_swapchain **swapchain_out)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   assert(create_info->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);

   const unsigned num_images = create_info->minImageCount;
   struct wsi_display_swapchain *chain =
      vk_zalloc(allocator,
                sizeof(*chain) + num_images * sizeof(chain->images[0]),
                8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);

   if (chain == NULL)
      return VK_ERROR_OUT_OF_HOST_MEMORY;

   VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device,
                                        create_info, allocator);
   if (result != VK_SUCCESS) {
      vk_free(allocator, chain);
      return result;
   }

   chain->base.destroy = wsi_display_swapchain_destroy;
   chain->base.get_wsi_image = wsi_display_get_wsi_image;
   chain->base.acquire_next_image = wsi_display_acquire_next_image;
   chain->base.queue_present = wsi_display_queue_present;
   chain->base.present_mode = wsi_swapchain_get_present_mode(wsi_device, create_info);
   chain->base.image_count = num_images;

   chain->wsi = wsi;
   chain->status = VK_SUCCESS;

   chain->surface = (VkIcdSurfaceDisplay *) icd_surface;

   for (uint32_t image = 0; image < chain->base.image_count; image++) {
      result = wsi_display_image_init(device, &chain->base,
                                      create_info, allocator,
                                      &chain->images[image]);
      if (result != VK_SUCCESS) {
         while (image > 0) {
            --image;
            wsi_display_image_finish(&chain->base, allocator,
                                     &chain->images[image]);
         }
         vk_free(allocator, chain);
         goto fail_init_images;
      }
   }

   *swapchain_out = &chain->base;

   return VK_SUCCESS;

fail_init_images:
   return result;
}

static bool
wsi_init_pthread_cond_monotonic(pthread_cond_t *cond)
{
   pthread_condattr_t condattr;
   bool ret = false;

   if (pthread_condattr_init(&condattr) != 0)
      goto fail_attr_init;

   if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) != 0)
      goto fail_attr_set;

   if (pthread_cond_init(cond, &condattr) != 0)
      goto fail_cond_init;

   ret = true;

fail_cond_init:
fail_attr_set:
   pthread_condattr_destroy(&condattr);
fail_attr_init:
   return ret;
}


/*
 * Local version fo the libdrm helper. Added to avoid depending on bleeding
 * edge version of the library.
 */
static int
local_drmIsMaster(int fd)
{
   /* Detect master by attempting something that requires master.
    *
    * Authenticating magic tokens requires master and 0 is an
    * internal kernel detail which we could use. Attempting this on
    * a master fd would fail therefore fail with EINVAL because 0
    * is invalid.
    *
    * A non-master fd will fail with EACCES, as the kernel checks
    * for master before attempting to do anything else.
    *
    * Since we don't want to leak implementation details, use
    * EACCES.
    */
   return drmAuthMagic(fd, 0) != -EACCES;
}

VkResult
wsi_display_init_wsi(struct wsi_device *wsi_device,
                     const VkAllocationCallbacks *alloc,
                     int display_fd)
{
   struct wsi_display *wsi = vk_zalloc(alloc, sizeof(*wsi), 8,
                                       VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
   VkResult result;

   if (!wsi) {
      result = VK_ERROR_OUT_OF_HOST_MEMORY;
      goto fail;
   }

   wsi->fd = display_fd;
   if (wsi->fd != -1 && !local_drmIsMaster(wsi->fd))
      wsi->fd = -1;

   wsi->alloc = alloc;

   list_inithead(&wsi->connectors);

   int ret = pthread_mutex_init(&wsi->wait_mutex, NULL);
   if (ret) {
      result = VK_ERROR_OUT_OF_HOST_MEMORY;
      goto fail_mutex;
   }

   if (!wsi_init_pthread_cond_monotonic(&wsi->wait_cond)) {
      result = VK_ERROR_OUT_OF_HOST_MEMORY;
      goto fail_cond;
   }

   wsi->base.get_support = wsi_display_surface_get_support;
   wsi->base.get_capabilities2 = wsi_display_surface_get_capabilities2;
   wsi->base.get_formats = wsi_display_surface_get_formats;
   wsi->base.get_formats2 = wsi_display_surface_get_formats2;
   wsi->base.get_present_modes = wsi_display_surface_get_present_modes;
   wsi->base.get_present_rectangles = wsi_display_surface_get_present_rectangles;
   wsi->base.create_swapchain = wsi_display_surface_create_swapchain;

   wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY] = &wsi->base;

   return VK_SUCCESS;

fail_cond:
   pthread_mutex_destroy(&wsi->wait_mutex);
fail_mutex:
   vk_free(alloc, wsi);
fail:
   return result;
}

void
wsi_display_finish_wsi(struct wsi_device *wsi_device,
                       const VkAllocationCallbacks *alloc)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   if (wsi) {
      wsi_for_each_connector(connector, wsi) {
         wsi_for_each_display_mode(mode, connector) {
            vk_free(wsi->alloc, mode);
         }
         vk_free(wsi->alloc, connector);
      }

      pthread_mutex_lock(&wsi->wait_mutex);
      if (wsi->wait_thread) {
         pthread_cancel(wsi->wait_thread);
         pthread_join(wsi->wait_thread, NULL);
      }
      pthread_mutex_unlock(&wsi->wait_mutex);
      pthread_mutex_destroy(&wsi->wait_mutex);
      pthread_cond_destroy(&wsi->wait_cond);

      vk_free(alloc, wsi);
   }
}

/*
 * Implement vkReleaseDisplay
 */
VkResult
wsi_release_display(VkPhysicalDevice            physical_device,
                    struct wsi_device           *wsi_device,
                    VkDisplayKHR                display)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   if (wsi->fd >= 0) {
      close(wsi->fd);
      wsi->fd = -1;
   }
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
   wsi_display_connector_from_handle(display)->output = None;
#endif

   return VK_SUCCESS;
}

#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT

static struct wsi_display_connector *
wsi_display_find_output(struct wsi_device *wsi_device,
                        xcb_randr_output_t output)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];

   wsi_for_each_connector(connector, wsi) {
      if (connector->output == output)
         return connector;
   }

   return NULL;
}

/*
 * Given a RandR output, find the associated kernel connector_id by
 * looking at the CONNECTOR_ID property provided by the X server
 */

static uint32_t
wsi_display_output_to_connector_id(xcb_connection_t *connection,
                                   xcb_atom_t *connector_id_atom_p,
                                   xcb_randr_output_t output)
{
   uint32_t connector_id = 0;
   xcb_atom_t connector_id_atom = *connector_id_atom_p;

   if (connector_id_atom == 0) {
   /* Go dig out the CONNECTOR_ID property */
      xcb_intern_atom_cookie_t ia_c = xcb_intern_atom(connection,
                                                          true,
                                                          12,
                                                          "CONNECTOR_ID");
      xcb_intern_atom_reply_t *ia_r = xcb_intern_atom_reply(connection,
                                                                 ia_c,
                                                                 NULL);
      if (ia_r) {
         *connector_id_atom_p = connector_id_atom = ia_r->atom;
         free(ia_r);
      }
   }

   /* If there's an CONNECTOR_ID atom in the server, then there may be a
    * CONNECTOR_ID property. Otherwise, there will not be and we don't even
    * need to bother.
    */
   if (connector_id_atom) {

      xcb_randr_query_version_cookie_t qv_c =
         xcb_randr_query_version(connection, 1, 6);
      xcb_randr_get_output_property_cookie_t gop_c =
         xcb_randr_get_output_property(connection,
                                       output,
                                       connector_id_atom,
                                       0,
                                       0,
                                       0xffffffffUL,
                                       0,
                                       0);
      xcb_randr_query_version_reply_t *qv_r =
         xcb_randr_query_version_reply(connection, qv_c, NULL);
      free(qv_r);
      xcb_randr_get_output_property_reply_t *gop_r =
         xcb_randr_get_output_property_reply(connection, gop_c, NULL);
      if (gop_r) {
         if (gop_r->num_items == 1 && gop_r->format == 32)
            memcpy(&connector_id, xcb_randr_get_output_property_data(gop_r), 4);
         free(gop_r);
      }
   }
   return connector_id;
}

static bool
wsi_display_check_randr_version(xcb_connection_t *connection)
{
   xcb_randr_query_version_cookie_t qv_c =
      xcb_randr_query_version(connection, 1, 6);
   xcb_randr_query_version_reply_t *qv_r =
      xcb_randr_query_version_reply(connection, qv_c, NULL);
   bool ret = false;

   if (!qv_r)
      return false;

   /* Check for version 1.6 or newer */
   ret = (qv_r->major_version > 1 ||
          (qv_r->major_version == 1 && qv_r->minor_version >= 6));

   free(qv_r);
   return ret;
}

/*
 * Given a kernel connector id, find the associated RandR output using the
 * CONNECTOR_ID property
 */

static xcb_randr_output_t
wsi_display_connector_id_to_output(xcb_connection_t *connection,
                                   uint32_t connector_id)
{
   if (!wsi_display_check_randr_version(connection))
      return 0;

   const xcb_setup_t *setup = xcb_get_setup(connection);

   xcb_atom_t connector_id_atom = 0;
   xcb_randr_output_t output = 0;

   /* Search all of the screens for the provided output */
   xcb_screen_iterator_t iter;
   for (iter = xcb_setup_roots_iterator(setup);
        output == 0 && iter.rem;
        xcb_screen_next(&iter))
   {
      xcb_randr_get_screen_resources_cookie_t gsr_c =
         xcb_randr_get_screen_resources(connection, iter.data->root);
      xcb_randr_get_screen_resources_reply_t *gsr_r =
         xcb_randr_get_screen_resources_reply(connection, gsr_c, NULL);

      if (!gsr_r)
         return 0;

      xcb_randr_output_t *ro = xcb_randr_get_screen_resources_outputs(gsr_r);
      int o;

      for (o = 0; o < gsr_r->num_outputs; o++) {
         if (wsi_display_output_to_connector_id(connection,
                                                &connector_id_atom, ro[o])
             == connector_id)
         {
            output = ro[o];
            break;
         }
      }
      free(gsr_r);
   }
   return output;
}

/*
 * Given a RandR output, find out which screen it's associated with
 */
static xcb_window_t
wsi_display_output_to_root(xcb_connection_t *connection,
                           xcb_randr_output_t output)
{
   if (!wsi_display_check_randr_version(connection))
      return 0;

   const xcb_setup_t *setup = xcb_get_setup(connection);
   xcb_window_t root = 0;

   /* Search all of the screens for the provided output */
   for (xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
        root == 0 && iter.rem;
        xcb_screen_next(&iter))
   {
      xcb_randr_get_screen_resources_cookie_t gsr_c =
         xcb_randr_get_screen_resources(connection, iter.data->root);
      xcb_randr_get_screen_resources_reply_t *gsr_r =
         xcb_randr_get_screen_resources_reply(connection, gsr_c, NULL);

      if (!gsr_r)
         return 0;

      xcb_randr_output_t *ro = xcb_randr_get_screen_resources_outputs(gsr_r);

      for (int o = 0; o < gsr_r->num_outputs; o++) {
         if (ro[o] == output) {
            root = iter.data->root;
            break;
         }
      }
      free(gsr_r);
   }
   return root;
}

static bool
wsi_display_mode_matches_x(struct wsi_display_mode *wsi,
                           xcb_randr_mode_info_t *xcb)
{
   return wsi->clock == (xcb->dot_clock + 500) / 1000 &&
      wsi->hdisplay == xcb->width &&
      wsi->hsync_start == xcb->hsync_start &&
      wsi->hsync_end == xcb->hsync_end &&
      wsi->htotal == xcb->htotal &&
      wsi->hskew == xcb->hskew &&
      wsi->vdisplay == xcb->height &&
      wsi->vsync_start == xcb->vsync_start &&
      wsi->vsync_end == xcb->vsync_end &&
      wsi->vtotal == xcb->vtotal &&
      wsi->vscan <= 1 &&
      wsi->flags == xcb->mode_flags;
}

static struct wsi_display_mode *
wsi_display_find_x_mode(struct wsi_device *wsi_device,
                        struct wsi_display_connector *connector,
                        xcb_randr_mode_info_t *mode)
{
   wsi_for_each_display_mode(display_mode, connector) {
      if (wsi_display_mode_matches_x(display_mode, mode))
         return display_mode;
   }
   return NULL;
}

static VkResult
wsi_display_register_x_mode(struct wsi_device *wsi_device,
                            struct wsi_display_connector *connector,
                            xcb_randr_mode_info_t *x_mode,
                            bool preferred)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_mode *display_mode =
      wsi_display_find_x_mode(wsi_device, connector, x_mode);

   if (display_mode) {
      display_mode->valid = true;
      return VK_SUCCESS;
   }

   display_mode = vk_zalloc(wsi->alloc, sizeof (struct wsi_display_mode),
                            8, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
   if (!display_mode)
      return VK_ERROR_OUT_OF_HOST_MEMORY;

   display_mode->connector = connector;
   display_mode->valid = true;
   display_mode->preferred = preferred;
   display_mode->clock = (x_mode->dot_clock + 500) / 1000; /* kHz */
   display_mode->hdisplay = x_mode->width;
   display_mode->hsync_start = x_mode->hsync_start;
   display_mode->hsync_end = x_mode->hsync_end;
   display_mode->htotal = x_mode->htotal;
   display_mode->hskew = x_mode->hskew;
   display_mode->vdisplay = x_mode->height;
   display_mode->vsync_start = x_mode->vsync_start;
   display_mode->vsync_end = x_mode->vsync_end;
   display_mode->vtotal = x_mode->vtotal;
   display_mode->vscan = 0;
   display_mode->flags = x_mode->mode_flags;

   list_addtail(&display_mode->list, &connector->display_modes);
   return VK_SUCCESS;
}

static struct wsi_display_connector *
wsi_display_get_output(struct wsi_device *wsi_device,
                       xcb_connection_t *connection,
                       xcb_randr_output_t output)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_connector *connector;
   uint32_t connector_id;

   xcb_window_t root = wsi_display_output_to_root(connection, output);
   if (!root)
      return NULL;

   /* See if we already have a connector for this output */
   connector = wsi_display_find_output(wsi_device, output);

   if (!connector) {
      xcb_atom_t connector_id_atom = 0;

      /*
       * Go get the kernel connector ID for this X output
       */
      connector_id = wsi_display_output_to_connector_id(connection,
                                                        &connector_id_atom,
                                                        output);

      /* Any X server with lease support will have this atom */
      if (!connector_id) {
         return NULL;
      }

      /* See if we already have a connector for this id */
      connector = wsi_display_find_connector(wsi_device, connector_id);

      if (connector == NULL) {
         connector = wsi_display_alloc_connector(wsi, connector_id);
         if (!connector) {
            return NULL;
         }
         list_addtail(&connector->list, &wsi->connectors);
      }
      connector->output = output;
   }

   xcb_randr_get_screen_resources_cookie_t src =
      xcb_randr_get_screen_resources(connection, root);
   xcb_randr_get_output_info_cookie_t oic =
      xcb_randr_get_output_info(connection, output, XCB_CURRENT_TIME);
   xcb_randr_get_screen_resources_reply_t *srr =
      xcb_randr_get_screen_resources_reply(connection, src, NULL);
   xcb_randr_get_output_info_reply_t *oir =
      xcb_randr_get_output_info_reply(connection, oic, NULL);

   if (oir && srr) {
      /* Get X modes and add them */

      connector->connected =
         oir->connection != XCB_RANDR_CONNECTION_DISCONNECTED;

      wsi_display_invalidate_connector_modes(wsi_device, connector);

      xcb_randr_mode_t *x_modes = xcb_randr_get_output_info_modes(oir);
      for (int m = 0; m < oir->num_modes; m++) {
         xcb_randr_mode_info_iterator_t i =
            xcb_randr_get_screen_resources_modes_iterator(srr);
         while (i.rem) {
            xcb_randr_mode_info_t *mi = i.data;
            if (mi->id == x_modes[m]) {
               VkResult result = wsi_display_register_x_mode(
                  wsi_device, connector, mi, m < oir->num_preferred);
               if (result != VK_SUCCESS) {
                  free(oir);
                  free(srr);
                  return NULL;
               }
               break;
            }
            xcb_randr_mode_info_next(&i);
         }
      }
   }

   free(oir);
   free(srr);
   return connector;
}

static xcb_randr_crtc_t
wsi_display_find_crtc_for_output(xcb_connection_t *connection,
                                 xcb_window_t root,
                                 xcb_randr_output_t output)
{
   xcb_randr_get_screen_resources_cookie_t gsr_c =
      xcb_randr_get_screen_resources(connection, root);
   xcb_randr_get_screen_resources_reply_t *gsr_r =
      xcb_randr_get_screen_resources_reply(connection, gsr_c, NULL);

   if (!gsr_r)
      return 0;

   xcb_randr_crtc_t *rc = xcb_randr_get_screen_resources_crtcs(gsr_r);
   xcb_randr_crtc_t idle_crtc = 0;
   xcb_randr_crtc_t active_crtc = 0;

   /* Find either a crtc already connected to the desired output or idle */
   for (int c = 0; active_crtc == 0 && c < gsr_r->num_crtcs; c++) {
      xcb_randr_get_crtc_info_cookie_t gci_c =
         xcb_randr_get_crtc_info(connection, rc[c], gsr_r->config_timestamp);
      xcb_randr_get_crtc_info_reply_t *gci_r =
         xcb_randr_get_crtc_info_reply(connection, gci_c, NULL);

      if (gci_r) {
         if (gci_r->mode) {
            int num_outputs = xcb_randr_get_crtc_info_outputs_length(gci_r);
            xcb_randr_output_t *outputs =
               xcb_randr_get_crtc_info_outputs(gci_r);

            if (num_outputs == 1 && outputs[0] == output)
               active_crtc = rc[c];

         } else if (idle_crtc == 0) {
            int num_possible = xcb_randr_get_crtc_info_possible_length(gci_r);
            xcb_randr_output_t *possible =
               xcb_randr_get_crtc_info_possible(gci_r);

            for (int p = 0; p < num_possible; p++)
               if (possible[p] == output) {
                  idle_crtc = rc[c];
                  break;
               }
         }
         free(gci_r);
      }
   }
   free(gsr_r);

   if (active_crtc)
      return active_crtc;
   return idle_crtc;
}

VkResult
wsi_acquire_xlib_display(VkPhysicalDevice physical_device,
                         struct wsi_device *wsi_device,
                         Display *dpy,
                         VkDisplayKHR display)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   xcb_connection_t *connection = XGetXCBConnection(dpy);
   struct wsi_display_connector *connector =
      wsi_display_connector_from_handle(display);
   xcb_window_t root;

   /* XXX no support for multiple leases yet */
   if (wsi->fd >= 0)
      return VK_ERROR_INITIALIZATION_FAILED;

   if (!connector->output) {
      connector->output = wsi_display_connector_id_to_output(connection,
                                                             connector->id);

      /* Check and see if we found the output */
      if (!connector->output)
         return VK_ERROR_INITIALIZATION_FAILED;
   }

   root = wsi_display_output_to_root(connection, connector->output);
   if (!root)
      return VK_ERROR_INITIALIZATION_FAILED;

   xcb_randr_crtc_t crtc = wsi_display_find_crtc_for_output(connection,
                                                            root,
                                                            connector->output);

   if (!crtc)
      return VK_ERROR_INITIALIZATION_FAILED;

#ifdef HAVE_DRI3_MODIFIERS
   xcb_randr_lease_t lease = xcb_generate_id(connection);
   xcb_randr_create_lease_cookie_t cl_c =
      xcb_randr_create_lease(connection, root, lease, 1, 1,
                             &crtc, &connector->output);
   xcb_randr_create_lease_reply_t *cl_r =
      xcb_randr_create_lease_reply(connection, cl_c, NULL);
   if (!cl_r)
      return VK_ERROR_INITIALIZATION_FAILED;

   int fd = -1;
   if (cl_r->nfd > 0) {
      int *rcl_f = xcb_randr_create_lease_reply_fds(connection, cl_r);

      fd = rcl_f[0];
   }
   free (cl_r);
   if (fd < 0)
      return VK_ERROR_INITIALIZATION_FAILED;

   wsi->fd = fd;
#endif

   return VK_SUCCESS;
}

VkResult
wsi_get_randr_output_display(VkPhysicalDevice physical_device,
                             struct wsi_device *wsi_device,
                             Display *dpy,
                             RROutput output,
                             VkDisplayKHR *display)
{
   xcb_connection_t *connection = XGetXCBConnection(dpy);
   struct wsi_display_connector *connector =
      wsi_display_get_output(wsi_device, connection, (xcb_randr_output_t) output);

   if (connector)
      *display = wsi_display_connector_to_handle(connector);
   else
      *display = VK_NULL_HANDLE;
   return VK_SUCCESS;
}

#endif

/* VK_EXT_display_control */
VkResult
wsi_display_power_control(VkDevice device,
                          struct wsi_device *wsi_device,
                          VkDisplayKHR display,
                          const VkDisplayPowerInfoEXT *display_power_info)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_connector *connector =
      wsi_display_connector_from_handle(display);
   int mode;

   if (wsi->fd < 0)
      return VK_ERROR_INITIALIZATION_FAILED;

   switch (display_power_info->powerState) {
   case VK_DISPLAY_POWER_STATE_OFF_EXT:
      mode = DRM_MODE_DPMS_OFF;
      break;
   case VK_DISPLAY_POWER_STATE_SUSPEND_EXT:
      mode = DRM_MODE_DPMS_SUSPEND;
      break;
   default:
      mode = DRM_MODE_DPMS_ON;
      break;
   }
   drmModeConnectorSetProperty(wsi->fd,
                               connector->id,
                               connector->dpms_property,
                               mode);
   return VK_SUCCESS;
}

VkResult
wsi_register_device_event(VkDevice device,
                          struct wsi_device *wsi_device,
                          const VkDeviceEventInfoEXT *device_event_info,
                          const VkAllocationCallbacks *allocator,
                          struct wsi_fence **fence_p)
{
   return VK_ERROR_FEATURE_NOT_PRESENT;
}

VkResult
wsi_register_display_event(VkDevice device,
                           struct wsi_device *wsi_device,
                           VkDisplayKHR display,
                           const VkDisplayEventInfoEXT *display_event_info,
                           const VkAllocationCallbacks *allocator,
                           struct wsi_fence **fence_p)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_fence *fence;
   VkResult ret;

   switch (display_event_info->displayEvent) {
   case VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT:

      fence = wsi_display_fence_alloc(device, wsi_device, display, allocator);

      if (!fence)
         return VK_ERROR_OUT_OF_HOST_MEMORY;

      ret = wsi_register_vblank_event(fence, wsi_device, display,
                                      DRM_CRTC_SEQUENCE_RELATIVE, 1, NULL);

      if (ret == VK_SUCCESS)
         *fence_p = &fence->base;
      else if (fence != NULL)
         vk_free2(wsi->alloc, allocator, fence);

      break;
   default:
      ret = VK_ERROR_FEATURE_NOT_PRESENT;
      break;
   }

   return ret;
}


VkResult
wsi_get_swapchain_counter(VkDevice device,
                          struct wsi_device *wsi_device,
                          VkSwapchainKHR _swapchain,
                          VkSurfaceCounterFlagBitsEXT flag_bits,
                          uint64_t *value)
{
   struct wsi_display *wsi =
      (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
   struct wsi_display_swapchain *swapchain =
      (struct wsi_display_swapchain *) wsi_swapchain_from_handle(_swapchain);
   struct wsi_display_connector *connector =
      wsi_display_mode_from_handle(swapchain->surface->displayMode)->connector;

   if (wsi->fd < 0)
      return VK_ERROR_INITIALIZATION_FAILED;

   if (!connector->active) {
      *value = 0;
      return VK_SUCCESS;
   }

   int ret = drmCrtcGetSequence(wsi->fd, connector->crtc_id, value, NULL);
   if (ret)
      *value = 0;

   return VK_SUCCESS;
}

