return NULL;
}
- if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
+ if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, false))
goto cleanup_surface;
config = dri2_get_dri_config(dri2_conf, type,
dri2_surf->base.GLColorspace);
- if (!config)
+ if (!config) {
+ _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration");
goto cleanup_surface;
+ }
dri2_surf->dri_drawable =
dri2_dpy->image_driver->createNewDrawable(dri2_dpy->dri_screen, config,
dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
+ dri2_fini_surface(surf);
free(dri2_surf);
return EGL_TRUE;
}
.create_pbuffer_surface = dri2_surfaceless_create_pbuffer_surface,
.destroy_surface = surfaceless_destroy_surface,
.create_image = dri2_create_image_khr,
- .swap_interval = dri2_fallback_swap_interval,
.swap_buffers = surfaceless_swap_buffers,
.swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
.swap_buffers_region = dri2_fallback_swap_buffers_region,
.flushFrontBuffer = surfaceless_flush_front_buffer,
};
+static const __DRIswrastLoaderExtension swrast_loader_extension = {
+ .base = { __DRI_SWRAST_LOADER, 1 },
+ .getDrawableInfo = NULL,
+ .putImage = NULL,
+ .getImage = NULL,
+};
+
#define DRM_RENDER_DEV_NAME "%s/renderD%d"
static const __DRIextension *image_loader_extensions[] = {
NULL,
};
+static const __DRIextension *swrast_loader_extensions[] = {
+ &swrast_loader_extension.base,
+ &image_loader_extension.base,
+ &image_lookup_extension.base,
+ &use_invalidate.base,
+ NULL,
+};
+
+static bool
+surfaceless_probe_device(_EGLDisplay *dpy, bool swrast)
+{
+ struct dri2_egl_display *dri2_dpy = dpy->DriverData;
+ const int limit = 64;
+ const int base = 128;
+ int fd;
+ int i;
+
+ /* Attempt to find DRM device. */
+ for (i = 0; i < limit; ++i) {
+ char *card_path;
+ if (asprintf(&card_path, DRM_RENDER_DEV_NAME, DRM_DIR_NAME, base + i) < 0)
+ continue;
+
+ fd = loader_open_device(card_path);
+ free(card_path);
+ if (fd < 0)
+ continue;
+
+ if (swrast) {
+ dri2_dpy->driver_name = strdup("kms_swrast");
+ dri2_dpy->loader_extensions = swrast_loader_extensions;
+ } else {
+ dri2_dpy->driver_name = loader_get_driver_for_fd(fd);
+ dri2_dpy->loader_extensions = image_loader_extensions;
+ }
+ if (!dri2_dpy->driver_name) {
+ close(fd);
+ continue;
+ }
+
+ dri2_dpy->fd = fd;
+ if (dri2_load_driver_dri3(dpy))
+ return true;
+
+ close(fd);
+ dri2_dpy->fd = -1;
+ free(dri2_dpy->driver_name);
+ dri2_dpy->driver_name = NULL;
+ dri2_dpy->loader_extensions = NULL;
+ }
+
+ /* No DRM device, so attempt to fall back to software path w/o DRM. */
+ if (swrast) {
+ _eglLog(_EGL_DEBUG, "Falling back to surfaceless swrast without DRM.");
+ dri2_dpy->fd = -1;
+ dri2_dpy->driver_name = strdup("swrast");
+ if (!dri2_dpy->driver_name) {
+ return false;
+ }
+
+ if (dri2_load_driver_swrast(dpy)) {
+ dri2_dpy->loader_extensions = swrast_loader_extensions;
+ return true;
+ }
+
+ free(dri2_dpy->driver_name);
+ dri2_dpy->driver_name = NULL;
+ }
+
+ return false;
+}
+
EGLBoolean
dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
const char* err;
- int driver_loaded = 0;
+ bool driver_loaded = false;
loader_set_logger(_eglLog);
dri2_dpy->fd = -1;
disp->DriverData = (void *) dri2_dpy;
- const int limit = 64;
- const int base = 128;
- for (int i = 0; i < limit; ++i) {
- char *card_path;
- if (asprintf(&card_path, DRM_RENDER_DEV_NAME, DRM_DIR_NAME, base + i) < 0)
- continue;
-
- dri2_dpy->fd = loader_open_device(card_path);
-
- free(card_path);
- if (dri2_dpy->fd < 0)
- continue;
-
- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
- if (dri2_dpy->driver_name) {
- if (dri2_load_driver_dri3(disp)) {
- driver_loaded = 1;
- break;
- }
- free(dri2_dpy->driver_name);
- dri2_dpy->driver_name = NULL;
- }
- close(dri2_dpy->fd);
- dri2_dpy->fd = -1;
+ if (!disp->Options.ForceSoftware) {
+ driver_loaded = surfaceless_probe_device(disp, false);
+ if (!driver_loaded)
+ _eglLog(_EGL_WARNING,
+ "No hardware driver found, falling back to software rendering");
}
- if (!driver_loaded) {
+ if (!driver_loaded && !surfaceless_probe_device(disp, true)) {
err = "DRI2: failed to load driver";
goto cleanup;
}
- dri2_dpy->loader_extensions = image_loader_extensions;
-
if (!dri2_create_screen(disp)) {
err = "DRI2: failed to create screen";
goto cleanup;