diff --git a/src/egl/drivers/dri2/platform_redox.c b/src/egl/drivers/dri2/platform_redox.c index d6ceb1107..03d8e4c21 100644 --- a/src/egl/drivers/dri2/platform_redox.c +++ b/src/egl/drivers/dri2/platform_redox.c @@ -62,10 +62,46 @@ redox_free_images(struct dri2_egl_surface *dri2_surf) dri2_surf->front = NULL; } + if (dri2_surf->dri_image_back) { + dri2_dpy->image->destroyImage(dri2_surf->dri_image_back); + dri2_surf->dri_image_back = NULL; + } + free(dri2_surf->swrast_device_buffer); dri2_surf->swrast_device_buffer = NULL; } +static int +redox_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format, + uint32_t *stamp, void *loaderPrivate, + uint32_t buffer_mask, + struct __DRIimageList *buffers) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + + buffers->image_mask = 0; + buffers->front = NULL; + buffers->back = NULL; + + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) { + if (!dri2_surf->front) + dri2_surf->front = redox_alloc_image(dri2_dpy, dri2_surf); + buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT; + buffers->front = dri2_surf->front; + } + + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) { + if (!dri2_surf->dri_image_back) + dri2_surf->dri_image_back = redox_alloc_image(dri2_dpy, dri2_surf); + buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK; + buffers->back = dri2_surf->dri_image_back; + } + + return 1; +} + static EGLBoolean redox_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval) { @@ -220,6 +256,10 @@ dri2_redox_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, goto cleanup_surface; } + dri2_surf->visual = dri2_image_format_for_pbuffer_config(dri2_dpy, config); + if (dri2_surf->visual == __DRI_IMAGE_FORMAT_NONE) + goto cleanup_surface; + if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf)) { goto cleanup_surface; } @@ -366,6 +406,27 @@ static const __DRIkopperLoaderExtension kopper_loader_extension = { .SetSurfaceCreateInfo = NULL, }; +static void +redox_hw_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate) +{ +} + +static const __DRIimageLoaderExtension redox_image_loader_extension = { + .base = {__DRI_IMAGE_LOADER, 2}, + .getBuffers = redox_image_get_buffers, + .flushFrontBuffer = redox_hw_flush_front_buffer, + .getCapability = redox_get_capability, +}; + +static const __DRIextension *redox_hw_loader_extensions[] = { + &redox_image_loader_extension.base, + &image_lookup_extension.base, + &use_invalidate.base, + &background_callable_extension.base, + &kopper_loader_extension.base, + NULL, +}; + static const __DRIswrastLoaderExtension swrast_loader_extension = { .base = {__DRI_SWRAST_LOADER, 1}, .getDrawableInfo = redox_swrast_get_drawable_info, @@ -381,6 +442,92 @@ static const __DRIextension *redox_swrast_loader_extensions[] = { NULL, }; +static bool +redox_probe_device_hw(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct _egl_device *device; + int fd = -1; + + /* Try to open a DRM device on Redox first, then the conventional path. */ + const char *drm_paths[] = { + "/scheme/drm/card0", + "/dev/dri/card0", + NULL, + }; + + fprintf(stderr, "[REDOX-EGL] redox_probe_device_hw: starting\n"); + + for (int i = 0; drm_paths[i]; i++) { + fd = open(drm_paths[i], O_RDWR | O_CLOEXEC); + fprintf(stderr, "[REDOX-EGL] open(%s) = %d\n", drm_paths[i], fd); + if (fd >= 0) + break; + } + + if (fd < 0) { + fprintf(stderr, "[REDOX-EGL] no DRM device found\n"); + return false; + } + + /* Resolve the DRI driver from the DRM fd via PCI ID lookup. */ + char *driver_name = loader_get_driver_for_fd(fd); + fprintf(stderr, "[REDOX-EGL] loader_get_driver_for_fd returned: %s\n", + driver_name ? driver_name : "(null)"); + if (!driver_name) { + close(fd); + return false; + } + + if (strcmp(driver_name, "swrast") == 0 || + strcmp(driver_name, "kms_swrast") == 0) { + fprintf(stderr, "[REDOX-EGL] driver is swrast/kms_swrast, skipping HW path\n"); + free(driver_name); + close(fd); + return false; + } + + dri2_dpy->fd_render_gpu = fd; + dri2_dpy->driver_name = driver_name; + + device = _eglFindDevice(fd, false); + fprintf(stderr, "[REDOX-EGL] _eglFindDevice returned: %p\n", (void *)device); + if (!device) { + free(driver_name); + close(fd); + dri2_dpy->driver_name = NULL; + dri2_dpy->fd_render_gpu = -1; + return false; + } + + if (_eglHasAttrib(disp, EGL_DEVICE_EXT) && disp->Device != device) { + fprintf(stderr, "[REDOX-EGL] EGL_DEVICE_EXT mismatch\n"); + free(driver_name); + close(fd); + dri2_dpy->driver_name = NULL; + dri2_dpy->fd_render_gpu = -1; + return false; + } + disp->Device = device; + + /* Hardware drivers expose the DRI3/image entrypoints we need here. */ + fprintf(stderr, "[REDOX-EGL] calling dri2_load_driver_dri3 (driver=%s)...\n", driver_name); + if (!dri2_load_driver_dri3(disp)) { + fprintf(stderr, "[REDOX-EGL] dri2_load_driver_dri3 FAILED\n"); + free(driver_name); + close(fd); + dri2_dpy->driver_name = NULL; + dri2_dpy->fd_render_gpu = -1; + return false; + } + fprintf(stderr, "[REDOX-EGL] dri2_load_driver_dri3 succeeded\n"); + + dri2_dpy->loader_extensions = redox_hw_loader_extensions; + + fprintf(stderr, "[REDOX-EGL] redox_probe_device_hw: SUCCESS (driver=%s)\n", driver_name); + return true; +} + static bool redox_probe_device_sw(_EGLDisplay *disp) { @@ -488,6 +635,8 @@ dri2_initialize_redox(_EGLDisplay *disp) bool driver_loaded = false; struct dri2_egl_display *dri2_dpy = dri2_display_create(); + fprintf(stderr, "[REDOX-EGL] dri2_initialize_redox: starting\n"); + if (!dri2_dpy) { err = "dri2_display_create failed"; goto cleanup; @@ -495,7 +644,12 @@ dri2_initialize_redox(_EGLDisplay *disp) disp->DriverData = (void *)dri2_dpy; - driver_loaded = redox_probe_device_sw(disp); + /* Try hardware GPU first (virgl, amdgpu, etc.). */ + driver_loaded = redox_probe_device_hw(disp); + fprintf(stderr, "[REDOX-EGL] HW probe: %s\n", driver_loaded ? "SUCCESS" : "FAILED"); + /* Fall back to software rendering (llvmpipe/softpipe). */ + if (!driver_loaded) + driver_loaded = redox_probe_device_sw(disp); if (!driver_loaded) { err = "DRI2: failed to load driver"; @@ -503,16 +657,21 @@ dri2_initialize_redox(_EGLDisplay *disp) } dri2_dpy->fd_display_gpu = dri2_dpy->fd_render_gpu; + fprintf(stderr, "[REDOX-EGL] calling dri2_create_screen...\n"); if (!dri2_create_screen(disp)) { err = "DRI2: failed to create screen"; + fprintf(stderr, "[REDOX-EGL] dri2_create_screen FAILED\n"); goto cleanup; } + fprintf(stderr, "[REDOX-EGL] dri2_create_screen succeeded\n"); if (!dri2_setup_extensions(disp)) { err = "DRI2: failed to find required DRI extensions"; + fprintf(stderr, "[REDOX-EGL] dri2_setup_extensions FAILED\n"); goto cleanup; } + fprintf(stderr, "[REDOX-EGL] dri2_setup_extensions succeeded\n"); dri2_setup_screen(disp); @@ -532,9 +691,11 @@ dri2_initialize_redox(_EGLDisplay *disp) dri2_dpy->vtbl = &dri2_redox_display_vtbl; + fprintf(stderr, "[REDOX-EGL] dri2_initialize_redox: COMPLETE\n"); return EGL_TRUE; cleanup: + fprintf(stderr, "[REDOX-EGL] dri2_initialize_redox: FAILED: %s\n", err); dri2_display_destroy(disp); return _eglError(EGL_NOT_INITIALIZED, err); }