diff --git a/local/patches/mesa/P5-gbm-dumb-prime-export.patch b/local/patches/mesa/P5-gbm-dumb-prime-export.patch new file mode 100644 index 0000000000..f27928e1b7 --- /dev/null +++ b/local/patches/mesa/P5-gbm-dumb-prime-export.patch @@ -0,0 +1,32 @@ +diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c +index 91fcc1fd2..af26e20d6 100644 +--- a/src/gbm/backends/dri/gbm_dri.c ++++ b/src/gbm/backends/dri/gbm_dri.c +@@ -578,8 +578,11 @@ gbm_dri_bo_get_fd(struct gbm_bo *_bo) + struct gbm_dri_bo *bo = gbm_dri_bo(_bo); + int fd; + +- if (bo->image == NULL) +- return -1; ++ if (bo->image == NULL) { ++ if (drmPrimeHandleToFD(dri->base.v0.fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, &fd) != 0) ++ return -1; ++ return fd; ++ } + + if (!dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_FD, &fd)) + return -1; +@@ -663,8 +666,11 @@ gbm_dri_bo_get_plane_fd(struct gbm_bo *_bo, int plane) + + /* dumb BOs can only utilize non-planar formats */ + if (!bo->image) { +- errno = EINVAL; +- return -1; ++ if (plane != 0) { ++ errno = EINVAL; ++ return -1; ++ } ++ return gbm_dri_bo_get_fd(_bo); + } + + if (plane >= get_number_planes(dri, bo->image)) { diff --git a/local/patches/mesa/P6-platform-redox-gpu-probe.patch b/local/patches/mesa/P6-platform-redox-gpu-probe.patch new file mode 100644 index 0000000000..ed4f287420 --- /dev/null +++ b/local/patches/mesa/P6-platform-redox-gpu-probe.patch @@ -0,0 +1,240 @@ +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); + } diff --git a/recipes/libs/mesa/recipe.toml b/recipes/libs/mesa/recipe.toml index 743ef6517b..305e81f77a 100644 --- a/recipes/libs/mesa/recipe.toml +++ b/recipes/libs/mesa/recipe.toml @@ -3,7 +3,7 @@ git = "https://gitlab.redox-os.org/redox-os/mesa.git" upstream = "https://gitlab.freedesktop.org/mesa/mesa" branch = "redox-24.0" shallow_clone = true -patches = ["../../../local/patches/mesa/P4-virgl-redox-disk-cache.patch"] +patches = ["../../../local/patches/mesa/P4-virgl-redox-disk-cache.patch", "../../../local/patches/mesa/P5-gbm-dumb-prime-export.patch", "../../../local/patches/mesa/P6-platform-redox-gpu-probe.patch"] [build] template = "custom" dependencies = [