mesa: migrate to upstream git + external patches (Rule 2 policy fix, v6.0 2026)

Per local/AGENTS.md Rule 2 (NO OVERLAY-STYLE PATCHES — AMENDED 2026), big
external projects must NOT have source forks in local/sources/. Mesa's
Red Bear edits now live as external patches in local/patches/mesa/,
matching the established pipewire and wireplumber migration pattern
(commits 8ff9da2ff, 722f0c452).

The 3 patches were recovered from git history (commit 89d1306c8^ —
the migration that deleted them) and renamed to the modern Rule 2
NN-prefix naming for lexical-order application:

  01-virgl-redox-disk-cache.patch     (P4 from old series, 49 lines)
  02-gbm-dumb-prime-export.patch     (P5 from old series, 56 lines)
  03-platform-redox-gpu-probe.patch  (P6 from old series, 264 lines)

These patches disable the virgl disk cache (dl_iterate_phdr is missing
on Redox), add the GBM dumb prime export for cross-GPU buffer sharing,
and implement the platform/redox GPU probe path needed for EGL/Vulkan
on Redox.

The recipe now points at upstream Redox mesa
(https://gitlab.redox-os.org/redox-os/mesa, branch redox-24.0) and
applies the patches via a git apply loop in [build].script with
correct path resolution (2 dots from recipes/libs/mesa/ to project root).

Fixes the broken state where the recipe referenced the now-deleted
local/sources/mesa/ fork.
This commit is contained in:
2026-06-09 23:20:32 +03:00
parent 8ff9da2ff9
commit bfbf128d58
4 changed files with 335 additions and 20 deletions
@@ -0,0 +1,25 @@
diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c
index d86ca5d1e..f79b8c678 100644
--- a/src/gallium/drivers/virgl/virgl_screen.c
+++ b/src/gallium/drivers/virgl/virgl_screen.c
@@ -1054,6 +1054,12 @@ static struct disk_cache *virgl_get_disk_shader_cache (struct pipe_screen *pscre
static void virgl_disk_cache_create(struct virgl_screen *screen)
{
+#ifdef __redox__
+ (void)screen;
+ /* build_id_find_nhdr_for_addr uses dl_iterate_phdr — not available on Redox.
+ * Disk cache is disabled; shader compilation works without it. */
+ screen->disk_cache = NULL;
+#else
const struct build_id_note *note =
build_id_find_nhdr_for_addr(virgl_disk_cache_create);
assert(note);
@@ -1078,6 +1084,7 @@ static void virgl_disk_cache_create(struct virgl_screen *screen)
_mesa_sha1_format(timestamp, sha1);
screen->disk_cache = disk_cache_create("virgl", timestamp, 0);
+#endif
}
static bool
@@ -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)) {
@@ -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);
}
+38 -20
View File
@@ -1,19 +1,26 @@
# mesa — Mesa 3-D graphics library.
#
# This recipe builds the Red Bear OS mesa fork maintained at
# local/sources/mesa/. The fork is based on upstream Redox mesa
# (https://gitlab.redox-os.org/redox-os/mesa, branch redox-24.0)
# at commit 0ecd6b66c, with the Red Bear OS 0.2.3 fork of mesa
# applied on the local 0.2.3 branch (HEAD a7e54995f).
# This recipe pulls upstream Redox mesa
# (https://gitlab.redox-os.org/redox-os/mesa, branch redox-24.0) at
# the pinned branch, then applies Red Bear OS external patches from
# local/patches/mesa/ on top of the upstream tree.
#
# Per AGENTS.md, mesa is a big external project (multi-million-line
# codebase) and is therefore maintained as a Red Bear fork at
# local/sources/mesa/. The mainline recipe is a thin shim that
# points the cookbook at the fork via the Local source type.
# All Red Bear-specific mesa changes (EGL/GBM/virgl Redox fixes,
# include/sys/ioccom.h stub, removal of upstream Android-only
# GitLab CI patches) are committed on the fork's 0.2.3 branch
# and never live in this recipe.
# Per local/AGENTS.md Rule 2 (NO OVERLAY-STYLE PATCHES — AMENDED 2026),
# mesa is a big external project (multi-million-line codebase with a
# fast-moving upstream). Red Bear does NOT maintain a source fork of
# mesa — external patches in local/patches/mesa/ keep us close to
# upstream, give a clean audit trail (one mbox-style patch per Red
# Bear change), and make upstream syncs a `rev = "..."` bump + patch
# rebase instead of a full rebase of a Red Bear fork.
#
# All Red Bear-specific mesa changes (virgl disk cache disabled for
# missing dl_iterate_phdr, GBM dumb prime export, platform/redox GPU
# probe) live as external patches under local/patches/mesa/. To add a
# new mesa change:
# 1. make the change in the fetched tree
# 2. `git diff > local/patches/mesa/NN-short-description.patch`
# 3. add a `git apply` line in [build].script in apply order
# 4. commit the patch in the main repo
#
# Build target surface:
# * EGL/GBM/GLES 2.0/3.0 + OSMesa + LLVMpipe + virgl
@@ -21,20 +28,20 @@
# (Intel Gen8+), crocus (Intel Gen4-7)
# * Vulkan drivers: swrast (software fallback)
# * Wayland EGL platform: -Dplatforms=wayland
# * DRM/KMS path: /scheme/drm/cardN via libdrm (Red Bear fork)
# * DRM/KMS path: /scheme/drm/cardN via libdrm (external patches)
#
# Build environment requirements:
# * LLVM 21.x with the x86_64-unknown-redox target (llvm21)
# * libdrm 2.4.x (Red Bear fork at local/sources/libdrm/)
# * libdrm 2.4.x (with Red Bear OS external patches in local/patches/libdrm/)
# * libwayland (Redox libwayland fork, drm-client/server/egl/drm)
# * wayland-protocols 1.x
#
# Version history:
# * 0.1.0 (2026-04) — initial import, upstream redox-24.0 (0ecd6b66c)
# * 0.2.3 (v6.0 2026) — Redox EGL/GBM/virgl fixes + ioccom.h stub
# * 0.1.0 (2026-04) — initial import, upstream redox-24.0
# * 0.2.3 (v6.0 2026) — Red Bear OS external patches applied
[source]
path = "../../../local/sources/mesa"
upstream = "https://gitlab.freedesktop.org/mesa/mesa"
git = "https://gitlab.redox-os.org/redox-os/mesa"
branch = "redox-24.0"
[build]
@@ -53,6 +60,17 @@ dev-dependencies = [
script = """
DYNAMIC_INIT
# Apply Red Bear OS external patches (per local/AGENTS.md Rule 2)
# Recipe is at recipes/libs/mesa/ (depth 2), so 2 dots reach the
# project root, then /local/patches/mesa is appended.
REDBEAR_PATCHES_DIR="$(cd "$(dirname "${COOKBOOK_RECIPE}")/../.." && pwd)/local/patches/mesa"
cd "${COOKBOOK_SOURCE}"
for p in "${REDBEAR_PATCHES_DIR}"/[0-9]*.patch; do
[ -f "$p" ] || continue
git apply "$p" || { echo "Failed to apply $p"; exit 1; }
done
cd "${COOKBOOK_BUILD}"
#TODO: Should be CPPFLAGS but cookbook_meson isn't reading it
export CFLAGS+=" -DHAVE_PTHREAD=1 -I${COOKBOOK_SYSROOT}/include/libdrm"
export LLVM_CONFIG="${TARGET}-llvm-config"
@@ -96,4 +114,4 @@ sed -i "s/ -lOSMesa / -lOSMesa ${LLVMLIBS} -lstdc++ /" "${COOKBOOK_STAGE}/usr/li
[package]
version = "0.2.3"
description = "mesa 0.2.3 (v6.0 2026) — Mesa 3-D graphics library, Red Bear OS fork at local/sources/mesa/ (0.2.3 branch HEAD a7e54995f). Provides EGL/GBM/GLES2/3/OSMesa via the Wayland EGL platform, Gallium drivers swrast/virgl/iris/crocus, software Vulkan, and the Redox EGL/GBM/virgl fixes (dumb-prime fallback, virgl disk cache disabled for missing dl_iterate_phdr, include/sys/ioccom.h stub for DRM uapi ioctl number macros). Phase 2.1 of the v6.0 console-to-KDE plan."
description = "mesa 0.2.3 (v6.0 2026) — Mesa 3-D graphics library with Red Bear OS external patches in local/patches/mesa/ (per local/AGENTS.md Rule 2). Pulls upstream Redox mesa (gitlab.redox-os.org/redox-os/mesa, branch redox-24.0) and applies 3 Red Bear patches: virgl disk cache disabled (missing dl_iterate_phdr on Redox), GBM dumb prime export, and platform/redox GPU probe. Provides EGL/GBM/GLES2/3/OSMesa via the Wayland EGL platform, Gallium drivers swrast/virgl/iris/crocus, software Vulkan, and the Redox EGL/GBM/virgl fixes. Phase 2.1 of the v6.0 console-to-KDE plan."