egl/gbm: Fix EGL_DEFAULT_DISPLAY
[mesa.git] / src / gallium / state_trackers / egl / common / egl_g3d.c
index d7a2aa8b8ea6e4e32661a31ec2173f5d0c60ab13..6649f02b244fa8e304aa9ae7103354e56f25323f 100644 (file)
@@ -31,6 +31,7 @@
 #include "util/u_memory.h"
 #include "util/u_format.h"
 #include "util/u_string.h"
+#include "util/u_atomic.h"
 
 #include "egl_g3d.h"
 #include "egl_g3d_api.h"
 #include "egl_g3d_loader.h"
 #include "native.h"
 
+static void
+egl_g3d_invalid_surface(struct native_display *ndpy,
+                        struct native_surface *nsurf,
+                        unsigned int seq_num)
+{
+   /* XXX not thread safe? */
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
+
+   if (gsurf && gsurf->stfbi)
+      p_atomic_inc(&gsurf->stfbi->stamp);
+}
+
+static struct pipe_screen *
+egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
+{
+   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   return gdpy->loader->create_drm_screen(name, fd);
+}
+
+static struct pipe_screen *
+egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
+{
+   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   return gdpy->loader->create_sw_screen(ws);
+}
+
+static struct pipe_resource *
+egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image)
+{
+   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct st_egl_image img;
+   struct pipe_resource *resource = NULL;
+
+   memset(&img, 0, sizeof(img));
+   if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img))
+      resource = img.texture;
+
+   return resource;
+}
+
+static const struct native_event_handler egl_g3d_native_event_handler = {
+   egl_g3d_invalid_surface,
+   egl_g3d_new_drm_screen,
+   egl_g3d_new_sw_screen,
+   egl_g3d_lookup_egl_image
+};
+
 /**
  * Get the native platform.
  */
@@ -54,25 +105,31 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
       case _EGL_PLATFORM_WINDOWS:
          plat_name = "Windows";
 #ifdef HAVE_GDI_BACKEND
-         nplat = native_get_gdi_platform();
+         nplat = native_get_gdi_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       case _EGL_PLATFORM_X11:
          plat_name = "X11";
 #ifdef HAVE_X11_BACKEND
-         nplat = native_get_x11_platform();
+         nplat = native_get_x11_platform(&egl_g3d_native_event_handler);
+#endif
+        break;
+      case _EGL_PLATFORM_WAYLAND:
+         plat_name = "wayland";
+#ifdef HAVE_WAYLAND_BACKEND
+         nplat = native_get_wayland_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       case _EGL_PLATFORM_DRM:
          plat_name = "DRM";
-#ifdef HAVE_KMS_BACKEND
-         nplat = native_get_kms_platform();
+#ifdef HAVE_DRM_BACKEND
+         nplat = native_get_drm_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       case _EGL_PLATFORM_FBDEV:
          plat_name = "FBDEV";
 #ifdef HAVE_FBDEV_BACKEND
-         nplat = native_get_fbdev_platform();
+         nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       default:
@@ -126,24 +183,24 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
          continue;
       }
 
-      _eglInitScreen(&gscr->base);
-
-      for (j = 0; j < num_modes; j++) {
+      _eglInitScreen(&gscr->base, dpy, num_modes);
+      for (j = 0; j < gscr->base.NumModes; j++) {
          const struct native_mode *nmode = native_modes[j];
-         _EGLMode *mode;
-
-         mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height,
-               nmode->refresh_rate, nmode->desc);
-         if (!mode)
-            break;
-         /* gscr->native_modes and gscr->base.Modes should be consistent */
-         assert(mode == &gscr->base.Modes[j]);
+         _EGLMode *mode = &gscr->base.Modes[j];
+
+         mode->Width = nmode->width;
+         mode->Height = nmode->height;
+         mode->RefreshRate = nmode->refresh_rate;
+         mode->Optimal = EGL_FALSE;
+         mode->Interlaced = EGL_FALSE;
+         /* no need to strdup() */
+         mode->Name = nmode->desc;
       }
 
       gscr->native = nconn;
       gscr->native_modes = native_modes;
 
-      _eglAddScreen(dpy, &gscr->base);
+      _eglLinkScreen(&gscr->base);
    }
 
    FREE(native_connectors);
@@ -156,7 +213,8 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
  */
 static EGLBoolean
 init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
-                       EGLint api_mask, enum pipe_format depth_stencil_format)
+                       EGLint api_mask, enum pipe_format depth_stencil_format,
+                       EGLBoolean preserve_buffer, EGLint max_swap_interval)
 {
    uint rgba[4], depth_stencil[2], buffer_size;
    EGLint surface_type;
@@ -182,67 +240,70 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
    }
 
    surface_type = 0x0;
-   if (nconf->window_bit)
-      surface_type |= EGL_WINDOW_BIT;
-   if (nconf->pixmap_bit)
-      surface_type |= EGL_PIXMAP_BIT;
+   /* pixmap surfaces should be EGL_SINGLE_BUFFER */
+   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) {
+      if (nconf->pixmap_bit)
+         surface_type |= EGL_PIXMAP_BIT;
+   }
+   /* the others surfaces should be EGL_BACK_BUFFER (or settable) */
+   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) {
+      if (nconf->window_bit)
+         surface_type |= EGL_WINDOW_BIT;
 #ifdef EGL_MESA_screen_surface
-   if (nconf->scanout_bit)
-      surface_type |= EGL_SCREEN_BIT_MESA;
+      if (nconf->scanout_bit)
+         surface_type |= EGL_SCREEN_BIT_MESA;
 #endif
-
-   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
       surface_type |= EGL_PBUFFER_BIT;
+   }
+
+   conf->Conformant = api_mask;
+   conf->RenderableType = api_mask;
 
-   SET_CONFIG_ATTRIB(conf, EGL_CONFORMANT, api_mask);
-   SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, api_mask);
+   conf->RedSize = rgba[0];
+   conf->GreenSize = rgba[1];
+   conf->BlueSize = rgba[2];
+   conf->AlphaSize = rgba[3];
+   conf->BufferSize = buffer_size;
 
-   SET_CONFIG_ATTRIB(conf, EGL_RED_SIZE, rgba[0]);
-   SET_CONFIG_ATTRIB(conf, EGL_GREEN_SIZE, rgba[1]);
-   SET_CONFIG_ATTRIB(conf, EGL_BLUE_SIZE, rgba[2]);
-   SET_CONFIG_ATTRIB(conf, EGL_ALPHA_SIZE, rgba[3]);
-   SET_CONFIG_ATTRIB(conf, EGL_BUFFER_SIZE, buffer_size);
+   conf->DepthSize = depth_stencil[0];
+   conf->StencilSize = depth_stencil[1];
 
-   SET_CONFIG_ATTRIB(conf, EGL_DEPTH_SIZE, depth_stencil[0]);
-   SET_CONFIG_ATTRIB(conf, EGL_STENCIL_SIZE, depth_stencil[1]);
+   /* st/vega will allocate the mask on demand */
+   if (api_mask & EGL_OPENVG_BIT)
+      conf->AlphaMaskSize = 8;
 
-   SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, surface_type);
+   conf->SurfaceType = surface_type;
 
-   SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_TRUE);
+   conf->NativeRenderable = EGL_TRUE;
    if (surface_type & EGL_WINDOW_BIT) {
-      SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_ID, nconf->native_visual_id);
-      SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE,
-            nconf->native_visual_type);
+      conf->NativeVisualID = nconf->native_visual_id;
+      conf->NativeVisualType = nconf->native_visual_type;
    }
 
    if (surface_type & EGL_PBUFFER_BIT) {
-      SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
+      conf->BindToTextureRGB = EGL_TRUE;
       if (rgba[3])
-         SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
+         conf->BindToTextureRGBA = EGL_TRUE;
 
-      SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_WIDTH, 4096);
-      SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_HEIGHT, 4096);
-      SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_PIXELS, 4096 * 4096);
+      conf->MaxPbufferWidth = 4096;
+      conf->MaxPbufferHeight = 4096;
+      conf->MaxPbufferPixels = 4096 * 4096;
    }
 
-   SET_CONFIG_ATTRIB(conf, EGL_LEVEL, nconf->level);
-   SET_CONFIG_ATTRIB(conf, EGL_SAMPLES, nconf->samples);
-   SET_CONFIG_ATTRIB(conf, EGL_SAMPLE_BUFFERS, 1);
-
-   if (nconf->slow_config)
-      SET_CONFIG_ATTRIB(conf, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG);
+   conf->Level = nconf->level;
 
    if (nconf->transparent_rgb) {
-      rgba[0] = nconf->transparent_rgb_values[0];
-      rgba[1] = nconf->transparent_rgb_values[1];
-      rgba[2] = nconf->transparent_rgb_values[2];
-
-      SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RGB);
-      SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_RED_VALUE, rgba[0]);
-      SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_GREEN_VALUE, rgba[1]);
-      SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_BLUE_VALUE, rgba[2]);
+      conf->TransparentType = EGL_TRANSPARENT_RGB;
+      conf->TransparentRedValue = nconf->transparent_rgb_values[0];
+      conf->TransparentGreenValue = nconf->transparent_rgb_values[1];
+      conf->TransparentBlueValue = nconf->transparent_rgb_values[2];
    }
 
+   conf->MinSwapInterval = 0;
+   conf->MaxSwapInterval = max_swap_interval;
+   if (preserve_buffer)
+      conf->SurfaceType |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+
    return _eglValidateConfig(conf, EGL_FALSE);
 }
 
@@ -252,10 +313,11 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
 static EGLBoolean
 egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
                     _EGLConfig *conf, const struct native_config *nconf,
-                    enum pipe_format depth_stencil_format)
+                    enum pipe_format depth_stencil_format,
+                    int preserve_buffer, int max_swap_interval)
 {
    struct egl_g3d_config *gconf = egl_g3d_config(conf);
-   EGLint buffer_mask, api_mask;
+   EGLint buffer_mask;
    EGLBoolean valid;
 
    buffer_mask = 0x0;
@@ -272,24 +334,15 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
    gconf->stvis.color_format = nconf->color_format;
    gconf->stvis.depth_stencil_format = depth_stencil_format;
    gconf->stvis.accum_format = PIPE_FORMAT_NONE;
-   gconf->stvis.samples = nconf->samples;
+   gconf->stvis.samples = 0;
 
+   /* will be overridden per surface */
    gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
       ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
 
-   api_mask = dpy->ClientAPIsMask;
-   /* this is required by EGL, not by OpenGL ES */
-   if (nconf->window_bit &&
-       gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT)
-      api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
-
-   if (!api_mask) {
-      _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
-            nconf->native_visual_id);
-   }
-
    valid = init_config_attributes(&gconf->base,
-         nconf, api_mask, depth_stencil_format);
+         nconf, dpy->ClientAPIs, depth_stencil_format,
+         preserve_buffer, max_swap_interval);
    if (!valid) {
       _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
       return EGL_FALSE;
@@ -328,7 +381,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
       /* pick the first supported format */
       for (i = 0; i < n; i++) {
          if (screen->is_format_supported(screen, fmt[i],
-                  PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) {
+                  PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) {
             formats[count++] = fmt[i];
             break;
          }
@@ -350,6 +403,7 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
    const struct native_config **native_configs;
    enum pipe_format depth_stencil_formats[8];
    int num_formats, num_configs, i, j;
+   int preserve_buffer, max_swap_interval;
 
    native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
    if (!num_configs) {
@@ -358,6 +412,11 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
       return id;
    }
 
+   preserve_buffer =
+      gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER);
+   max_swap_interval =
+      gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL);
+
    num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
          depth_stencil_formats);
 
@@ -369,12 +428,13 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
          if (gconf) {
             _eglInitConfig(&gconf->base, dpy, id);
             if (!egl_g3d_init_config(drv, dpy, &gconf->base,
-                     native_configs[i], depth_stencil_formats[j])) {
+                     native_configs[i], depth_stencil_formats[j],
+                     preserve_buffer, max_swap_interval)) {
                FREE(gconf);
                break;
             }
 
-            _eglAddConfig(dpy, &gconf->base);
+            _eglLinkConfig(&gconf->base);
             id++;
          }
       }
@@ -385,66 +445,40 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
 }
 
 static void
-egl_g3d_invalid_surface(struct native_display *ndpy,
-                        struct native_surface *nsurf,
-                        unsigned int seq_num)
+egl_g3d_free_config(void *conf)
 {
-   /* XXX not thread safe? */
-   struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
-   struct egl_g3d_context *gctx;
-   
-   /*
-    * Some functions such as egl_g3d_copy_buffers create a temporary native
-    * surface.  There is no gsurf associated with it.
-    */
-   gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
-   if (gctx)
-      gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
+   struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf);
+   FREE(gconf);
 }
 
-static struct pipe_screen *
-egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
-{
-   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
-   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
-   return gdpy->loader->create_drm_screen(name, fd);
-}
-
-static struct pipe_screen *
-egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
+static void
+egl_g3d_free_screen(void *scr)
 {
-   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
-   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
-   return gdpy->loader->create_sw_screen(ws);
+#ifdef EGL_MESA_screen_surface
+   struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr);
+   FREE(gscr->native_modes);
+   FREE(gscr);
+#endif
 }
 
-static struct native_event_handler egl_g3d_native_event_handler = {
-   egl_g3d_invalid_surface,
-   egl_g3d_new_drm_screen,
-   egl_g3d_new_sw_screen
-};
-
 static EGLBoolean
 egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
-   EGLint i;
 
    _eglReleaseDisplayResources(drv, dpy);
-   _eglCleanupDisplay(dpy);
-
-   if (gdpy->pipe)
-      gdpy->pipe->destroy(gdpy->pipe);
 
+   if (dpy->Configs) {
+      _eglDestroyArray(dpy->Configs, egl_g3d_free_config);
+      dpy->Configs = NULL;
+   }
    if (dpy->Screens) {
-      for (i = 0; i < dpy->NumScreens; i++) {
-         struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
-         FREE(gscr->native_modes);
-         FREE(gscr);
-      }
-      FREE(dpy->Screens);
+      _eglDestroyArray(dpy->Screens, egl_g3d_free_screen);
+      dpy->Screens = NULL;
    }
 
+   _eglCleanupDisplay(dpy);
+
    if (gdpy->smapi)
       egl_g3d_destroy_st_manager(gdpy->smapi);
 
@@ -458,8 +492,7 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
 }
 
 static EGLBoolean
-egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
-                   EGLint *major, EGLint *minor)
+egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
    struct egl_g3d_display *gdpy;
@@ -469,6 +502,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
    if (!nplat)
       return EGL_FALSE;
 
+   if (dpy->Options.TestOnly)
+      return EGL_TRUE;
+
    gdpy = CALLOC_STRUCT(egl_g3d_display);
    if (!gdpy) {
       _eglError(EGL_BAD_ALLOC, "eglInitialize");
@@ -477,22 +513,29 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
    gdpy->loader = gdrv->loader;
    dpy->DriverData = gdpy;
 
-   _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
-   gdpy->native = nplat->create_display(dpy->PlatformDisplay,
-         &egl_g3d_native_event_handler, (void *) dpy);
+   _eglLog(_EGL_INFO, "use %s for display %p",
+         nplat->name, dpy->PlatformDisplay);
+   gdpy->native =
+      nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback);
    if (!gdpy->native) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
       goto fail;
    }
+   gdpy->native->user_data = (void *) dpy;
+   if (!gdpy->native->init_screen(gdpy->native)) {
+      _eglError(EGL_NOT_INITIALIZED,
+            "eglInitialize(failed to initialize screen)");
+      goto fail;
+   }
 
-   if (gdpy->loader->api_mask & (1 << ST_API_OPENGL))
-      dpy->ClientAPIsMask |= EGL_OPENGL_BIT;
-   if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES1))
-      dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
-   if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES2))
-      dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
-   if (gdpy->loader->api_mask & (1 << ST_API_OPENVG))
-      dpy->ClientAPIsMask |= EGL_OPENVG_BIT;
+   if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
+      dpy->ClientAPIs |= EGL_OPENGL_BIT;
+   if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK)
+      dpy->ClientAPIs |= EGL_OPENGL_ES_BIT;
+   if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK)
+      dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT;
+   if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK)
+      dpy->ClientAPIs |= EGL_OPENVG_BIT;
 
    gdpy->smapi = egl_g3d_create_st_manager(dpy);
    if (!gdpy->smapi) {
@@ -513,13 +556,34 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
    if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
       dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
 
+   dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
+   dpy->Extensions.KHR_fence_sync = EGL_TRUE;
+
+   dpy->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
+   dpy->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
+   dpy->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
+
+   if (dpy->Platform == _EGL_PLATFORM_DRM) {
+      dpy->Extensions.MESA_drm_display = EGL_TRUE;
+      if (gdpy->native->buffer)
+         dpy->Extensions.MESA_drm_image = EGL_TRUE;
+   }
+
+   if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer)
+      dpy->Extensions.MESA_drm_image = EGL_TRUE;
+
+#ifdef EGL_WL_bind_wayland_display
+   if (gdpy->native->wayland_bufmgr)
+      dpy->Extensions.WL_bind_wayland_display = EGL_TRUE;
+#endif
+
    if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
       goto fail;
    }
 
-   *major = 1;
-   *minor = 4;
+   dpy->VersionMajor = 1;
+   dpy->VersionMinor = 4;
 
    return EGL_TRUE;
 
@@ -538,18 +602,12 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
    if (procname && procname[0] == 'v' && procname[1] == 'g')
       stapi = gdrv->loader->get_st_api(ST_API_OPENVG);
    else if (procname && procname[0] == 'g' && procname[1] == 'l')
-      stapi = gdrv->loader->guess_gl_api();
+      stapi = gdrv->loader->get_st_api(ST_API_OPENGL);
 
    return (_EGLProc) ((stapi) ?
          stapi->get_proc_address(stapi, procname) : NULL);
 }
 
-static EGLint
-egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
-{
-   return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0;
-}
-
 _EGLDriver *
 egl_g3d_create_driver(const struct egl_g3d_loader *loader)
 {
@@ -566,8 +624,6 @@ egl_g3d_create_driver(const struct egl_g3d_loader *loader)
    gdrv->base.API.Terminate = egl_g3d_terminate;
    gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
 
-   gdrv->base.Probe = egl_g3d_probe;
-
    /* to be filled by the caller */
    gdrv->base.Name = NULL;
    gdrv->base.Unload = NULL;