1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright 2018 Collabora 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Based on platform_surfaceless, which has: 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * Copyright (c) 2014 The Chromium OS Authors. 9bf215546Sopenharmony_ci * Copyright © 2011 Intel Corporation 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 12bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 13bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 14bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 16bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 19bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 20bf215546Sopenharmony_ci * 21bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 28bf215546Sopenharmony_ci */ 29bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 30bf215546Sopenharmony_ci#include <xf86drm.h> 31bf215546Sopenharmony_ci#endif 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include <stdlib.h> 34bf215546Sopenharmony_ci#include <stdio.h> 35bf215546Sopenharmony_ci#include <string.h> 36bf215546Sopenharmony_ci#include <dlfcn.h> 37bf215546Sopenharmony_ci#include <sys/types.h> 38bf215546Sopenharmony_ci#include <sys/stat.h> 39bf215546Sopenharmony_ci#include <fcntl.h> 40bf215546Sopenharmony_ci#include <unistd.h> 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#include "egl_dri2.h" 43bf215546Sopenharmony_ci#include "loader.h" 44bf215546Sopenharmony_ci#include "kopper_interface.h" 45bf215546Sopenharmony_ci#include "util/debug.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_cistatic __DRIimage* 48bf215546Sopenharmony_cidevice_alloc_image(struct dri2_egl_display *dri2_dpy, 49bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf) 50bf215546Sopenharmony_ci{ 51bf215546Sopenharmony_ci return dri2_dpy->image->createImage( 52bf215546Sopenharmony_ci dri2_dpy->dri_screen, 53bf215546Sopenharmony_ci dri2_surf->base.Width, 54bf215546Sopenharmony_ci dri2_surf->base.Height, 55bf215546Sopenharmony_ci dri2_surf->visual, 56bf215546Sopenharmony_ci 0, 57bf215546Sopenharmony_ci NULL); 58bf215546Sopenharmony_ci} 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_cistatic void 61bf215546Sopenharmony_cidevice_free_images(struct dri2_egl_surface *dri2_surf) 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = 64bf215546Sopenharmony_ci dri2_egl_display(dri2_surf->base.Resource.Display); 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci if (dri2_surf->front) { 67bf215546Sopenharmony_ci dri2_dpy->image->destroyImage(dri2_surf->front); 68bf215546Sopenharmony_ci dri2_surf->front = NULL; 69bf215546Sopenharmony_ci } 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci free(dri2_surf->swrast_device_buffer); 72bf215546Sopenharmony_ci dri2_surf->swrast_device_buffer = NULL; 73bf215546Sopenharmony_ci} 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_cistatic int 76bf215546Sopenharmony_cidevice_image_get_buffers(__DRIdrawable *driDrawable, 77bf215546Sopenharmony_ci unsigned int format, 78bf215546Sopenharmony_ci uint32_t *stamp, 79bf215546Sopenharmony_ci void *loaderPrivate, 80bf215546Sopenharmony_ci uint32_t buffer_mask, 81bf215546Sopenharmony_ci struct __DRIimageList *buffers) 82bf215546Sopenharmony_ci{ 83bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 84bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = 85bf215546Sopenharmony_ci dri2_egl_display(dri2_surf->base.Resource.Display); 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci buffers->image_mask = 0; 88bf215546Sopenharmony_ci buffers->front = NULL; 89bf215546Sopenharmony_ci buffers->back = NULL; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically, 92bf215546Sopenharmony_ci * the spec states that they have a back buffer but no front buffer, in 93bf215546Sopenharmony_ci * contrast to pixmaps, which have a front buffer but no back buffer. 94bf215546Sopenharmony_ci * 95bf215546Sopenharmony_ci * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate 96bf215546Sopenharmony_ci * from the spec, following the precedent of Mesa's EGL X11 platform. The 97bf215546Sopenharmony_ci * X11 platform correctly assigns pbuffers to single-buffered configs, but 98bf215546Sopenharmony_ci * assigns the pbuffer a front buffer instead of a back buffer. 99bf215546Sopenharmony_ci * 100bf215546Sopenharmony_ci * Pbuffers in the X11 platform mostly work today, so let's just copy its 101bf215546Sopenharmony_ci * behavior instead of trying to fix (and hence potentially breaking) the 102bf215546Sopenharmony_ci * world. 103bf215546Sopenharmony_ci */ 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) { 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci if (!dri2_surf->front) 108bf215546Sopenharmony_ci dri2_surf->front = 109bf215546Sopenharmony_ci device_alloc_image(dri2_dpy, dri2_surf); 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT; 112bf215546Sopenharmony_ci buffers->front = dri2_surf->front; 113bf215546Sopenharmony_ci } 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci return 1; 116bf215546Sopenharmony_ci} 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_cistatic _EGLSurface * 119bf215546Sopenharmony_cidri2_device_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, 120bf215546Sopenharmony_ci const EGLint *attrib_list) 121bf215546Sopenharmony_ci{ 122bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 123bf215546Sopenharmony_ci struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); 124bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf; 125bf215546Sopenharmony_ci const __DRIconfig *config; 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci /* Make sure to calloc so all pointers 128bf215546Sopenharmony_ci * are originally NULL. 129bf215546Sopenharmony_ci */ 130bf215546Sopenharmony_ci dri2_surf = calloc(1, sizeof *dri2_surf); 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci if (!dri2_surf) { 133bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); 134bf215546Sopenharmony_ci return NULL; 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, 138bf215546Sopenharmony_ci false, NULL)) 139bf215546Sopenharmony_ci goto cleanup_surface; 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci config = dri2_get_dri_config(dri2_conf, type, 142bf215546Sopenharmony_ci dri2_surf->base.GLColorspace); 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci if (!config) { 145bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration"); 146bf215546Sopenharmony_ci goto cleanup_surface; 147bf215546Sopenharmony_ci } 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci dri2_surf->visual = dri2_image_format_for_pbuffer_config(dri2_dpy, config); 150bf215546Sopenharmony_ci if (dri2_surf->visual == __DRI_IMAGE_FORMAT_NONE) 151bf215546Sopenharmony_ci goto cleanup_surface; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf)) 154bf215546Sopenharmony_ci goto cleanup_surface; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci return &dri2_surf->base; 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci cleanup_surface: 159bf215546Sopenharmony_ci free(dri2_surf); 160bf215546Sopenharmony_ci return NULL; 161bf215546Sopenharmony_ci} 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_cistatic EGLBoolean 164bf215546Sopenharmony_cidevice_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) 165bf215546Sopenharmony_ci{ 166bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 167bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci device_free_images(dri2_surf); 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci dri2_fini_surface(surf); 174bf215546Sopenharmony_ci free(dri2_surf); 175bf215546Sopenharmony_ci return EGL_TRUE; 176bf215546Sopenharmony_ci} 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_cistatic _EGLSurface * 179bf215546Sopenharmony_cidri2_device_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf, 180bf215546Sopenharmony_ci const EGLint *attrib_list) 181bf215546Sopenharmony_ci{ 182bf215546Sopenharmony_ci return dri2_device_create_surface(disp, EGL_PBUFFER_BIT, conf, attrib_list); 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_cistatic const struct dri2_egl_display_vtbl dri2_device_display_vtbl = { 186bf215546Sopenharmony_ci .create_pbuffer_surface = dri2_device_create_pbuffer_surface, 187bf215546Sopenharmony_ci .destroy_surface = device_destroy_surface, 188bf215546Sopenharmony_ci .create_image = dri2_create_image_khr, 189bf215546Sopenharmony_ci .get_dri_drawable = dri2_surface_get_dri_drawable, 190bf215546Sopenharmony_ci}; 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_cistatic void 193bf215546Sopenharmony_cidevice_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate) 194bf215546Sopenharmony_ci{ 195bf215546Sopenharmony_ci} 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_cistatic unsigned 198bf215546Sopenharmony_cidevice_get_capability(void *loaderPrivate, enum dri_loader_cap cap) 199bf215546Sopenharmony_ci{ 200bf215546Sopenharmony_ci /* Note: loaderPrivate is _EGLDisplay* */ 201bf215546Sopenharmony_ci switch (cap) { 202bf215546Sopenharmony_ci case DRI_LOADER_CAP_FP16: 203bf215546Sopenharmony_ci return 1; 204bf215546Sopenharmony_ci default: 205bf215546Sopenharmony_ci return 0; 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci} 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_cistatic const __DRIimageLoaderExtension image_loader_extension = { 210bf215546Sopenharmony_ci .base = { __DRI_IMAGE_LOADER, 2 }, 211bf215546Sopenharmony_ci .getBuffers = device_image_get_buffers, 212bf215546Sopenharmony_ci .flushFrontBuffer = device_flush_front_buffer, 213bf215546Sopenharmony_ci .getCapability = device_get_capability, 214bf215546Sopenharmony_ci}; 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_cistatic const __DRIkopperLoaderExtension kopper_loader_extension = { 217bf215546Sopenharmony_ci .base = { __DRI_KOPPER_LOADER, 1 }, 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci .SetSurfaceCreateInfo = NULL, 220bf215546Sopenharmony_ci}; 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_cistatic const __DRIextension *image_loader_extensions[] = { 223bf215546Sopenharmony_ci &image_loader_extension.base, 224bf215546Sopenharmony_ci &image_lookup_extension.base, 225bf215546Sopenharmony_ci &use_invalidate.base, 226bf215546Sopenharmony_ci &kopper_loader_extension.base, 227bf215546Sopenharmony_ci NULL, 228bf215546Sopenharmony_ci}; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_cistatic const __DRIextension *swrast_loader_extensions[] = { 231bf215546Sopenharmony_ci &swrast_pbuffer_loader_extension.base, 232bf215546Sopenharmony_ci &image_lookup_extension.base, 233bf215546Sopenharmony_ci &use_invalidate.base, 234bf215546Sopenharmony_ci &kopper_loader_extension.base, 235bf215546Sopenharmony_ci NULL, 236bf215546Sopenharmony_ci}; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_cistatic int 239bf215546Sopenharmony_cidevice_get_fd(_EGLDisplay *disp, _EGLDevice *dev) 240bf215546Sopenharmony_ci{ 241bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 242bf215546Sopenharmony_ci int fd = disp->Options.fd; 243bf215546Sopenharmony_ci /* The fcntl() code in _eglGetDeviceDisplay() ensures that valid fd >= 3, 244bf215546Sopenharmony_ci * and invalid one is 0. 245bf215546Sopenharmony_ci */ 246bf215546Sopenharmony_ci if (fd) { 247bf215546Sopenharmony_ci /* According to the spec - if the FD does not match the EGLDevice 248bf215546Sopenharmony_ci * behaviour is undefined. 249bf215546Sopenharmony_ci * 250bf215546Sopenharmony_ci * Add a trivial sanity check since it doesn't cost us anything. 251bf215546Sopenharmony_ci */ 252bf215546Sopenharmony_ci if (dev != _eglAddDevice(fd, false)) 253bf215546Sopenharmony_ci return -1; 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci /* No EGL_EXT_output* extensions are supported, hence no master perms 256bf215546Sopenharmony_ci * are needed. Get the render one - otherwise drivers might error out. 257bf215546Sopenharmony_ci */ 258bf215546Sopenharmony_ci char *node = drmGetRenderDeviceNameFromFd(fd); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci /* Don't close the internal fd, get render node one based on it. */ 261bf215546Sopenharmony_ci fd = loader_open_device(node); 262bf215546Sopenharmony_ci free(node); 263bf215546Sopenharmony_ci return fd; 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci const char *node = _eglGetDRMDeviceRenderNode(dev); 266bf215546Sopenharmony_ci return loader_open_device(node); 267bf215546Sopenharmony_ci#else 268bf215546Sopenharmony_ci _eglLog(_EGL_FATAL, "Driver bug: Built without libdrm, yet using a HW device"); 269bf215546Sopenharmony_ci return -1; 270bf215546Sopenharmony_ci#endif 271bf215546Sopenharmony_ci} 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_cistatic bool 274bf215546Sopenharmony_cidevice_probe_device(_EGLDisplay *disp) 275bf215546Sopenharmony_ci{ 276bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 277bf215546Sopenharmony_ci bool request_software = env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false); 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci if (request_software) 280bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "Not allowed to force software rendering when " 281bf215546Sopenharmony_ci "API explicitly selects a hardware device."); 282bf215546Sopenharmony_ci dri2_dpy->fd = device_get_fd(disp, disp->Device); 283bf215546Sopenharmony_ci if (dri2_dpy->fd < 0) 284bf215546Sopenharmony_ci return false; 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd); 287bf215546Sopenharmony_ci if (!dri2_dpy->driver_name) 288bf215546Sopenharmony_ci goto err_name; 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci /* When doing software rendering, some times user still want to explicitly 291bf215546Sopenharmony_ci * choose the render node device since cross node import doesn't work between 292bf215546Sopenharmony_ci * vgem/virtio_gpu yet. It would be nice to have a new EXTENSION for this. 293bf215546Sopenharmony_ci * For now, just fallback to kms_swrast. */ 294bf215546Sopenharmony_ci if (disp->Options.ForceSoftware && !request_software && 295bf215546Sopenharmony_ci (strcmp(dri2_dpy->driver_name, "vgem") == 0 || 296bf215546Sopenharmony_ci strcmp(dri2_dpy->driver_name, "virtio_gpu") == 0)) { 297bf215546Sopenharmony_ci free(dri2_dpy->driver_name); 298bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "NEEDS EXTENSION: falling back to kms_swrast"); 299bf215546Sopenharmony_ci dri2_dpy->driver_name = strdup("kms_swrast"); 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci if (!dri2_load_driver_dri3(disp)) 303bf215546Sopenharmony_ci goto err_load; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci dri2_dpy->loader_extensions = image_loader_extensions; 306bf215546Sopenharmony_ci return true; 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_cierr_load: 309bf215546Sopenharmony_ci free(dri2_dpy->driver_name); 310bf215546Sopenharmony_ci dri2_dpy->driver_name = NULL; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_cierr_name: 313bf215546Sopenharmony_ci close(dri2_dpy->fd); 314bf215546Sopenharmony_ci dri2_dpy->fd = -1; 315bf215546Sopenharmony_ci return false; 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci} 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_cistatic bool 320bf215546Sopenharmony_cidevice_probe_device_sw(_EGLDisplay *disp) 321bf215546Sopenharmony_ci{ 322bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci dri2_dpy->fd = -1; 325bf215546Sopenharmony_ci dri2_dpy->driver_name = strdup(disp->Options.Zink ? "zink" : "swrast"); 326bf215546Sopenharmony_ci if (!dri2_dpy->driver_name) 327bf215546Sopenharmony_ci return false; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci /* HACK: should be driver_swrast_null */ 330bf215546Sopenharmony_ci if (!dri2_load_driver_swrast(disp)) { 331bf215546Sopenharmony_ci free(dri2_dpy->driver_name); 332bf215546Sopenharmony_ci dri2_dpy->driver_name = NULL; 333bf215546Sopenharmony_ci return false; 334bf215546Sopenharmony_ci } 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci dri2_dpy->loader_extensions = swrast_loader_extensions; 337bf215546Sopenharmony_ci return true; 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ciEGLBoolean 341bf215546Sopenharmony_cidri2_initialize_device(_EGLDisplay *disp) 342bf215546Sopenharmony_ci{ 343bf215546Sopenharmony_ci _EGLDevice *dev; 344bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy; 345bf215546Sopenharmony_ci const char* err; 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci dri2_dpy = calloc(1, sizeof *dri2_dpy); 348bf215546Sopenharmony_ci if (!dri2_dpy) 349bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, "eglInitialize"); 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci /* Extension requires a PlatformDisplay - the EGLDevice. */ 352bf215546Sopenharmony_ci dev = disp->PlatformDisplay; 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci dri2_dpy->fd = -1; 355bf215546Sopenharmony_ci disp->Device = dev; 356bf215546Sopenharmony_ci disp->DriverData = (void *) dri2_dpy; 357bf215546Sopenharmony_ci err = "DRI2: failed to load driver"; 358bf215546Sopenharmony_ci if (_eglDeviceSupports(dev, _EGL_DEVICE_DRM)) { 359bf215546Sopenharmony_ci if (!device_probe_device(disp)) 360bf215546Sopenharmony_ci goto cleanup; 361bf215546Sopenharmony_ci } else if (_eglDeviceSupports(dev, _EGL_DEVICE_SOFTWARE)) { 362bf215546Sopenharmony_ci if (!device_probe_device_sw(disp)) 363bf215546Sopenharmony_ci goto cleanup; 364bf215546Sopenharmony_ci } else { 365bf215546Sopenharmony_ci _eglLog(_EGL_FATAL, "Driver bug: exposed device is neither DRM nor SOFTWARE one"); 366bf215546Sopenharmony_ci return EGL_FALSE; 367bf215546Sopenharmony_ci } 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci if (!dri2_create_screen(disp)) { 370bf215546Sopenharmony_ci err = "DRI2: failed to create screen"; 371bf215546Sopenharmony_ci goto cleanup; 372bf215546Sopenharmony_ci } 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci if (!dri2_setup_extensions(disp)) { 375bf215546Sopenharmony_ci err = "DRI2: failed to find required DRI extensions"; 376bf215546Sopenharmony_ci goto cleanup; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci dri2_setup_screen(disp); 380bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 381bf215546Sopenharmony_ci dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd); 382bf215546Sopenharmony_ci#endif 383bf215546Sopenharmony_ci dri2_set_WL_bind_wayland_display(disp); 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci if (!dri2_add_pbuffer_configs_for_visuals(disp)) { 386bf215546Sopenharmony_ci err = "DRI2: failed to add configs"; 387bf215546Sopenharmony_ci goto cleanup; 388bf215546Sopenharmony_ci } 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci /* Fill vtbl last to prevent accidentally calling virtual function during 391bf215546Sopenharmony_ci * initialization. 392bf215546Sopenharmony_ci */ 393bf215546Sopenharmony_ci dri2_dpy->vtbl = &dri2_device_display_vtbl; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci return EGL_TRUE; 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_cicleanup: 398bf215546Sopenharmony_ci dri2_display_destroy(disp); 399bf215546Sopenharmony_ci return _eglError(EGL_NOT_INITIALIZED, err); 400bf215546Sopenharmony_ci} 401