gbm: give a name to rgba fields
[mesa.git] / src / egl / drivers / dri2 / platform_wayland.c
index da46449c439bd2939c3c6026ed6b339c75704511..877f7933b9a13d2c57d6a4a432126883b2965cc0 100644 (file)
 #define DRM_FORMAT_MOD_LINEAR 0
 #endif
 
-enum wl_drm_format_flags {
-   HAS_ARGB8888 = 1,
-   HAS_XRGB8888 = 2,
-   HAS_RGB565 = 4,
-   HAS_ARGB2101010 = 8,
-   HAS_XRGB2101010 = 16,
+/*
+ * The index of entries in this table is used as a bitmask in
+ * dri2_dpy->formats, which tracks the formats supported by our server.
+ */
+static const struct dri2_wl_visual {
+   const char *format_name;
+   uint32_t wl_drm_format;
+   uint32_t wl_shm_format;
+   int dri_image_format;
+   int bpp;
+   unsigned int rgba_masks[4];
+} dri2_wl_visuals[] = {
+   {
+     "XRGB2101010",
+     WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
+     __DRI_IMAGE_FORMAT_XRGB2101010, 32,
+     { 0x3ff00000, 0x000ffc00, 0x000003ff, 0x00000000 }
+   },
+   {
+     "ARGB2101010",
+     WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
+     __DRI_IMAGE_FORMAT_ARGB2101010, 32,
+     { 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 }
+   },
+   {
+     "XRGB8888",
+     WL_DRM_FORMAT_XRGB8888, WL_SHM_FORMAT_XRGB8888,
+     __DRI_IMAGE_FORMAT_XRGB8888, 32,
+     { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }
+   },
+   {
+     "ARGB8888",
+     WL_DRM_FORMAT_ARGB8888, WL_SHM_FORMAT_ARGB8888,
+     __DRI_IMAGE_FORMAT_ARGB8888, 32,
+     { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }
+   },
+   {
+     "RGB565",
+     WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
+     __DRI_IMAGE_FORMAT_RGB565, 16,
+     { 0xf800, 0x07e0, 0x001f, 0x0000 }
+   },
 };
 
+static int
+dri2_wl_visual_idx_from_config(struct dri2_egl_display *dri2_dpy,
+                               const __DRIconfig *config)
+{
+   unsigned int red, green, blue, alpha;
+
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK, &red);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK, &green);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK, &blue);
+   dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK, &alpha);
+
+   for (unsigned int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+      const struct dri2_wl_visual *wl_visual = &dri2_wl_visuals[i];
+
+      if (red == wl_visual->rgba_masks[0] &&
+          green == wl_visual->rgba_masks[1] &&
+          blue == wl_visual->rgba_masks[2] &&
+          alpha == wl_visual->rgba_masks[3]) {
+         return i;
+      }
+   }
+
+   return -1;
+}
+
+static int
+dri2_wl_visual_idx_from_fourcc(uint32_t fourcc)
+{
+   for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+      /* wl_drm format codes overlap with DRIImage FourCC codes for all formats
+       * we support. */
+      if (dri2_wl_visuals[i].wl_drm_format == fourcc)
+         return i;
+   }
+
+   return -1;
+}
+
+static int
+dri2_wl_visual_idx_from_dri_image_format(uint32_t dri_image_format)
+{
+   for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+      if (dri2_wl_visuals[i].dri_image_format == dri_image_format)
+         return i;
+   }
+
+   return -1;
+}
+
+static int
+dri2_wl_visual_idx_from_shm_format(uint32_t shm_format)
+{
+   for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+      if (dri2_wl_visuals[i].wl_shm_format == shm_format)
+         return i;
+   }
+
+   return -1;
+}
+
 static int
 roundtrip(struct dri2_egl_display *dri2_dpy)
 {
@@ -136,6 +232,7 @@ dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
    struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
    struct wl_egl_window *window = native_window;
    struct dri2_egl_surface *dri2_surf;
+   int visual_idx;
    const __DRIconfig *config;
 
    dri2_surf = calloc(1, sizeof *dri2_surf);
@@ -144,28 +241,20 @@ dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
       return NULL;
    }
 
-   if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list, false))
+   if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
+                          attrib_list, false))
       goto cleanup_surf;
 
+   config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+                                dri2_surf->base.GLColorspace);
+   visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config);
+   assert(visual_idx != -1);
+
    if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) {
-      if (conf->RedSize == 5)
-         dri2_surf->format = WL_DRM_FORMAT_RGB565;
-      else if (conf->RedSize == 8 && conf->AlphaSize == 0)
-         dri2_surf->format = WL_DRM_FORMAT_XRGB8888;
-      else if (conf->RedSize == 8)
-         dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
-      else if (conf->RedSize == 10 && conf->AlphaSize == 0)
-         dri2_surf->format = WL_DRM_FORMAT_XRGB2101010;
-      else if (conf->RedSize == 10)
-         dri2_surf->format = WL_DRM_FORMAT_ARGB2101010;
+      dri2_surf->format = dri2_wl_visuals[visual_idx].wl_drm_format;
    } else {
       assert(dri2_dpy->wl_shm);
-      if (conf->RedSize == 5)
-         dri2_surf->format = WL_SHM_FORMAT_RGB565;
-      else if (conf->AlphaSize == 0)
-         dri2_surf->format = WL_SHM_FORMAT_XRGB8888;
-      else
-         dri2_surf->format = WL_SHM_FORMAT_ARGB8888;
+      dri2_surf->format = dri2_wl_visuals[visual_idx].wl_shm_format;
    }
 
    dri2_surf->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
@@ -206,9 +295,6 @@ dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
    if (dri2_dpy->flush)
       dri2_surf->wl_win->resize_callback = resize_callback;
 
-   config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
-                                dri2_surf->base.GLColorspace);
-
    if (dri2_dpy->image_driver)
       createNewDrawable = dri2_dpy->image_driver->createNewDrawable;
    else if (dri2_dpy->dri2)
@@ -342,45 +428,16 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
    struct dri2_egl_display *dri2_dpy =
       dri2_egl_display(dri2_surf->base.Resource.Display);
    int use_flags;
+   int visual_idx;
    unsigned int dri_image_format;
    uint64_t *modifiers;
    int num_modifiers;
 
-   /* currently supports five WL DRM formats,
-    * WL_DRM_FORMAT_ARGB2101010, WL_DRM_FORMAT_XRGB2101010,
-    * WL_DRM_FORMAT_ARGB8888, WL_DRM_FORMAT_XRGB8888,
-    * and WL_DRM_FORMAT_RGB565
-    */
-   switch (dri2_surf->format) {
-   case WL_DRM_FORMAT_ARGB2101010:
-      dri_image_format = __DRI_IMAGE_FORMAT_ARGB2101010;
-      modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.argb2101010);
-      num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.argb2101010);
-      break;
-   case WL_DRM_FORMAT_XRGB2101010:
-      dri_image_format = __DRI_IMAGE_FORMAT_XRGB2101010;
-      modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.xrgb2101010);
-      num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.xrgb2101010);
-      break;
-   case WL_DRM_FORMAT_ARGB8888:
-      dri_image_format = __DRI_IMAGE_FORMAT_ARGB8888;
-      modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.argb8888);
-      num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.argb8888);
-      break;
-   case WL_DRM_FORMAT_XRGB8888:
-      dri_image_format = __DRI_IMAGE_FORMAT_XRGB8888;
-      modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.xrgb8888);
-      num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.xrgb8888);
-      break;
-   case WL_DRM_FORMAT_RGB565:
-      dri_image_format = __DRI_IMAGE_FORMAT_RGB565;
-      modifiers = u_vector_tail(&dri2_dpy->wl_modifiers.rgb565);
-      num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers.rgb565);
-      break;
-   default:
-      /* format is not supported */
-      return -1;
-   }
+   visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
+   assert(visual_idx != -1);
+   dri_image_format = dri2_wl_visuals[visual_idx].dri_image_format;
+   modifiers = u_vector_tail(&dri2_dpy->wl_modifiers[visual_idx]);
+   num_modifiers = u_vector_length(&dri2_dpy->wl_modifiers[visual_idx]);
 
    /* There might be a buffer release already queued that wasn't processed */
    wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_surf->wl_queue);
@@ -595,22 +652,10 @@ dri2_wl_get_buffers(__DRIdrawable * driDrawable,
    struct dri2_egl_surface *dri2_surf = loaderPrivate;
    unsigned int *attachments_with_format;
    __DRIbuffer *buffer;
-   unsigned int bpp;
-
-   switch (dri2_surf->format) {
-   case WL_DRM_FORMAT_ARGB2101010:
-   case WL_DRM_FORMAT_XRGB2101010:
-   case WL_DRM_FORMAT_ARGB8888:
-   case WL_DRM_FORMAT_XRGB8888:
-      bpp = 32;
-      break;
-   case WL_DRM_FORMAT_RGB565:
-      bpp = 16;
-      break;
-   default:
-      /* format is not supported */
+   int visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
+
+   if (visual_idx == -1)
       return NULL;
-   }
 
    attachments_with_format = calloc(count, 2 * sizeof(unsigned int));
    if (!attachments_with_format) {
@@ -620,7 +665,7 @@ dri2_wl_get_buffers(__DRIdrawable * driDrawable,
 
    for (int i = 0; i < count; ++i) {
       attachments_with_format[2*i] = attachments[i];
-      attachments_with_format[2*i + 1] = bpp;
+      attachments_with_format[2*i + 1] = dri2_wl_visuals[visual_idx].bpp;
    }
 
    buffer =
@@ -696,6 +741,7 @@ get_fourcc(struct dri2_egl_display *dri2_dpy,
 {
    EGLBoolean query;
    int dri_format;
+   int visual_idx;
 
    query = dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FOURCC,
                                        fourcc);
@@ -707,16 +753,12 @@ get_fourcc(struct dri2_egl_display *dri2_dpy,
    if (!query)
       return false;
 
-   switch (dri_format) {
-   case __DRI_IMAGE_FORMAT_ARGB8888:
-      *fourcc = __DRI_IMAGE_FOURCC_ARGB8888;
-      return true;
-   case __DRI_IMAGE_FORMAT_XRGB8888:
-      *fourcc = __DRI_IMAGE_FOURCC_XRGB8888;
-      return true;
-   default:
+   visual_idx = dri2_wl_visual_idx_from_dri_image_format(dri_format);
+   if (visual_idx == -1)
       return false;
-   }
+
+   *fourcc = dri2_wl_visuals[visual_idx].wl_drm_format;
+   return true;
 }
 
 static struct wl_buffer *
@@ -772,13 +814,10 @@ create_wl_buffer(struct dri2_egl_display *dri2_dpy,
          int stride, offset;
          int fd = -1;
 
-         if (i == 0)
-            p_image = image;
-         else
-            p_image = dri2_dpy->image->fromPlanar(image, i, NULL);
+         p_image = dri2_dpy->image->fromPlanar(image, i, NULL);
          if (!p_image) {
-            zwp_linux_buffer_params_v1_destroy(params);
-            return NULL;
+            assert(i == 0);
+            p_image = image;
          }
 
          query = dri2_dpy->image->queryImage(p_image,
@@ -987,29 +1026,16 @@ dri2_wl_create_wayland_buffer_from_image(_EGLDriver *drv,
    struct dri2_egl_image *dri2_img = dri2_egl_image(img);
    __DRIimage *image = dri2_img->dri_image;
    struct wl_buffer *buffer;
-   int format;
+   int format, visual_idx;
 
+   /* Check the upstream display supports this buffer's format. */
    dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
-   switch (format) {
-   case __DRI_IMAGE_FORMAT_ARGB2101010:
-      if (!(dri2_dpy->formats & HAS_ARGB2101010))
-         goto bad_format;
-      break;
-   case __DRI_IMAGE_FORMAT_XRGB2101010:
-      if (!(dri2_dpy->formats & HAS_XRGB2101010))
-         goto bad_format;
-      break;
-   case __DRI_IMAGE_FORMAT_ARGB8888:
-      if (!(dri2_dpy->formats & HAS_ARGB8888))
-         goto bad_format;
-      break;
-   case __DRI_IMAGE_FORMAT_XRGB8888:
-      if (!(dri2_dpy->formats & HAS_XRGB8888))
-         goto bad_format;
-      break;
-   default:
+   visual_idx = dri2_wl_visual_idx_from_dri_image_format(format);
+   if (visual_idx == -1)
+      goto bad_format;
+
+   if (!(dri2_dpy->formats & (1 << visual_idx)))
       goto bad_format;
-   }
 
    buffer = create_wl_buffer(dri2_dpy, NULL, image);
 
@@ -1084,24 +1110,12 @@ static void
 drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
 {
    struct dri2_egl_display *dri2_dpy = data;
+   int visual_idx = dri2_wl_visual_idx_from_fourcc(format);
 
-   switch (format) {
-   case WL_DRM_FORMAT_ARGB2101010:
-      dri2_dpy->formats |= HAS_ARGB2101010;
-      break;
-   case WL_DRM_FORMAT_XRGB2101010:
-      dri2_dpy->formats |= HAS_XRGB2101010;
-      break;
-   case WL_DRM_FORMAT_ARGB8888:
-      dri2_dpy->formats |= HAS_ARGB8888;
-      break;
-   case WL_DRM_FORMAT_XRGB8888:
-      dri2_dpy->formats |= HAS_XRGB8888;
-      break;
-   case WL_DRM_FORMAT_RGB565:
-      dri2_dpy->formats |= HAS_RGB565;
-      break;
-   }
+   if (visual_idx == -1)
+      return;
+
+   dri2_dpy->formats |= (1 << visual_idx);
 }
 
 static void
@@ -1140,40 +1154,19 @@ dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
                        uint32_t modifier_lo)
 {
    struct dri2_egl_display *dri2_dpy = data;
-   uint64_t *mod = NULL;
+   int visual_idx = dri2_wl_visual_idx_from_fourcc(format);
+   uint64_t *mod;
+
+   if (visual_idx == -1)
+      return;
 
    if (modifier_hi == (DRM_FORMAT_MOD_INVALID >> 32) &&
        modifier_lo == (DRM_FORMAT_MOD_INVALID & 0xffffffff))
       return;
 
-   switch (format) {
-   case WL_DRM_FORMAT_ARGB2101010:
-      mod = u_vector_add(&dri2_dpy->wl_modifiers.argb2101010);
-      dri2_dpy->formats |= HAS_ARGB2101010;
-      break;
-   case WL_DRM_FORMAT_XRGB2101010:
-      mod = u_vector_add(&dri2_dpy->wl_modifiers.xrgb2101010);
-      dri2_dpy->formats |= HAS_XRGB2101010;
-      break;
-   case WL_DRM_FORMAT_ARGB8888:
-      mod = u_vector_add(&dri2_dpy->wl_modifiers.argb8888);
-      dri2_dpy->formats |= HAS_ARGB8888;
-      break;
-   case WL_DRM_FORMAT_XRGB8888:
-      mod = u_vector_add(&dri2_dpy->wl_modifiers.xrgb8888);
-      dri2_dpy->formats |= HAS_XRGB8888;
-      break;
-   case WL_DRM_FORMAT_RGB565:
-      mod = u_vector_add(&dri2_dpy->wl_modifiers.rgb565);
-      dri2_dpy->formats |= HAS_RGB565;
-      break;
-   default:
-      break;
-   }
-
-   if (!mod)
-      return;
+   dri2_dpy->formats |= (1 << visual_idx);
 
+   mod = u_vector_add(&dri2_dpy->wl_modifiers[visual_idx]);
    *mod = (uint64_t) modifier_hi << 32;
    *mod |= (uint64_t) (modifier_lo & 0xffffffff);
 }
@@ -1263,29 +1256,18 @@ static EGLBoolean
 dri2_wl_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-   static const struct {
-      const char *format_name;
-      int has_format;
-      unsigned int rgba_masks[4];
-   } visuals[] = {
-      { "XRGB2101010", HAS_XRGB2101010, { 0x3ff00000, 0xffc00, 0x3ff, 0 } },
-      { "ARGB2101010", HAS_ARGB2101010, { 0x3ff00000, 0xffc00, 0x3ff, 0xc0000000 } },
-      { "XRGB8888", HAS_XRGB8888, { 0xff0000, 0xff00, 0x00ff, 0xff000000 } },
-      { "ARGB8888", HAS_ARGB8888, { 0xff0000, 0xff00, 0x00ff, 0 } },
-      { "RGB565",   HAS_RGB565,   { 0x00f800, 0x07e0, 0x001f, 0 } },
-   };
-   unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
+   unsigned int format_count[ARRAY_SIZE(dri2_wl_visuals)] = { 0 };
    unsigned int count = 0;
 
    for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
-      for (unsigned j = 0; j < ARRAY_SIZE(visuals); j++) {
+      for (unsigned j = 0; j < ARRAY_SIZE(dri2_wl_visuals); j++) {
          struct dri2_egl_config *dri2_conf;
 
-         if (!(dri2_dpy->formats & visuals[j].has_format))
+         if (!(dri2_dpy->formats & (1 << j)))
             continue;
 
          dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
-               count + 1, EGL_WINDOW_BIT, NULL, visuals[j].rgba_masks);
+               count + 1, EGL_WINDOW_BIT, NULL, dri2_wl_visuals[j].rgba_masks);
          if (dri2_conf) {
             if (dri2_conf->base.ConfigID == count + 1)
                count++;
@@ -1297,7 +1279,7 @@ dri2_wl_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
    for (unsigned i = 0; i < ARRAY_SIZE(format_count); i++) {
       if (!format_count[i]) {
          _eglLog(_EGL_DEBUG, "No DRI config supports native format %s",
-                 visuals[i].format_name);
+                 dri2_wl_visuals[i].format_name);
       }
    }
 
@@ -1326,12 +1308,13 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
       dri2_dpy->wl_dpy = disp->PlatformDisplay;
    }
 
-   if (!u_vector_init(&dri2_dpy->wl_modifiers.xrgb2101010, sizeof(uint64_t), 32) ||
-       !u_vector_init(&dri2_dpy->wl_modifiers.argb2101010, sizeof(uint64_t), 32) ||
-       !u_vector_init(&dri2_dpy->wl_modifiers.xrgb8888, sizeof(uint64_t), 32) ||
-       !u_vector_init(&dri2_dpy->wl_modifiers.argb8888, sizeof(uint64_t), 32) ||
-       !u_vector_init(&dri2_dpy->wl_modifiers.rgb565, sizeof(uint64_t), 32)) {
+   dri2_dpy->wl_modifiers =
+      calloc(ARRAY_SIZE(dri2_wl_visuals), sizeof(*dri2_dpy->wl_modifiers));
+   if (!dri2_dpy->wl_modifiers)
       goto cleanup;
+   for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
+      if (!u_vector_init(&dri2_dpy->wl_modifiers[i], sizeof(uint64_t), 32))
+         goto cleanup;
    }
 
    dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
@@ -1467,10 +1450,11 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
 static int
 dri2_wl_swrast_get_stride_for_format(int format, int w)
 {
-   if (format == WL_SHM_FORMAT_RGB565)
-      return 2 * w;
-   else /* ARGB8888 || XRGB8888 */
-      return 4 * w;
+   int visual_idx = dri2_wl_visual_idx_from_shm_format(format);
+
+   assume(visual_idx != -1);
+
+   return w * (dri2_wl_visuals[visual_idx].bpp / 8);
 }
 
 /*
@@ -1892,18 +1876,12 @@ static void
 shm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
 {
    struct dri2_egl_display *dri2_dpy = data;
+   int visual_idx = dri2_wl_visual_idx_from_shm_format(format);
 
-   switch (format) {
-   case WL_SHM_FORMAT_ARGB8888:
-      dri2_dpy->formats |= HAS_ARGB8888;
-      break;
-   case WL_SHM_FORMAT_XRGB8888:
-      dri2_dpy->formats |= HAS_XRGB8888;
-      break;
-   case WL_SHM_FORMAT_RGB565:
-      dri2_dpy->formats |= HAS_RGB565;
-      break;
-   }
+   if (visual_idx == -1)
+      return;
+
+   dri2_dpy->formats |= (1 << visual_idx);
 }
 
 static const struct wl_shm_listener shm_listener = {
@@ -2069,11 +2047,11 @@ dri2_teardown_wayland(struct dri2_egl_display *dri2_dpy)
       wl_event_queue_destroy(dri2_dpy->wl_queue);
    if (dri2_dpy->wl_dpy_wrapper)
       wl_proxy_wrapper_destroy(dri2_dpy->wl_dpy_wrapper);
-   u_vector_finish(&dri2_dpy->wl_modifiers.argb2101010);
-   u_vector_finish(&dri2_dpy->wl_modifiers.xrgb2101010);
-   u_vector_finish(&dri2_dpy->wl_modifiers.argb8888);
-   u_vector_finish(&dri2_dpy->wl_modifiers.xrgb8888);
-   u_vector_finish(&dri2_dpy->wl_modifiers.rgb565);
+
+   for (int i = 0; dri2_dpy->wl_modifiers && i < ARRAY_SIZE(dri2_wl_visuals); i++)
+      u_vector_finish(&dri2_dpy->wl_modifiers[i]);
+   free(dri2_dpy->wl_modifiers);
+
    if (dri2_dpy->own_device)
       wl_display_disconnect(dri2_dpy->wl_dpy);
 }