From a29f9e9d15c54a9e55c7177a100fe07dd86afc5d Mon Sep 17 00:00:00 2001 From: Admin Pupkin Date: Thu, 11 Jun 2026 10:56:06 +0300 Subject: [PATCH] =?UTF-8?q?libdrm:=20migrate=20to=20external=20patches=20m?= =?UTF-8?q?odel=20(Rule=202)=20=E2=80=94=20replace=20old=20in-tree=20patch?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../libdrm/00-xf86drm-redox-header.patch | 186 ++++ .../patches/libdrm/01-drm-ioctl-bridge.patch | 278 ------ .../libdrm/01-virtgpu-drm-header.patch | 138 +++ .../libdrm/02-ioctl-response-sizes.patch | 30 - local/patches/libdrm/02-redox-dispatch.patch | 806 ++++++++++++++++++ .../patches/libdrm/03-drm-get-pci-info.patch | 153 ---- .../04-drm-get-version-driver-name.patch | 34 - .../05-drmGetDeviceFromDevId-redox.patch | 68 -- .../mesa/04-sys-ioccom-stub-header.patch | 82 ++ .../mesa/05-vk-sync-wchar-include.patch | 34 + local/recipes/libs/libdrm/recipe.toml | 8 +- 11 files changed, 1250 insertions(+), 567 deletions(-) create mode 100644 local/patches/libdrm/00-xf86drm-redox-header.patch delete mode 100644 local/patches/libdrm/01-drm-ioctl-bridge.patch create mode 100644 local/patches/libdrm/01-virtgpu-drm-header.patch delete mode 100644 local/patches/libdrm/02-ioctl-response-sizes.patch create mode 100644 local/patches/libdrm/02-redox-dispatch.patch delete mode 100644 local/patches/libdrm/03-drm-get-pci-info.patch delete mode 100644 local/patches/libdrm/04-drm-get-version-driver-name.patch delete mode 100644 local/patches/libdrm/05-drmGetDeviceFromDevId-redox.patch create mode 100644 local/patches/mesa/04-sys-ioccom-stub-header.patch create mode 100644 local/patches/mesa/05-vk-sync-wchar-include.patch diff --git a/local/patches/libdrm/00-xf86drm-redox-header.patch b/local/patches/libdrm/00-xf86drm-redox-header.patch new file mode 100644 index 0000000000..e8f7a95c89 --- /dev/null +++ b/local/patches/libdrm/00-xf86drm-redox-header.patch @@ -0,0 +1,186 @@ +diff --git a/xf86drm_redox.h b/xf86drm_redox.h +new file mode 100644 +index 0000000..425b079 +--- /dev/null ++++ b/xf86drm_redox.h +@@ -0,0 +1,180 @@ ++#ifndef _XF86DRM_REDOX_H_ ++#define _XF86DRM_REDOX_H_ ++ ++#if defined(__redox__) ++ ++#include ++#include ++ ++#define REDOX_DRM_IOCTL_BASE 0x00A0UL ++ ++#define REDOX_LINUX_IOCTL_NR(request) ((unsigned long)((request) & 0xffUL)) ++#define REDOX_LINUX_IOCTL_SIZE(request) (((unsigned long)(request) >> 16) & 0x3fffUL) ++ ++#define REDOX_DRM_IOCTL_MODE_GETRESOURCES (REDOX_DRM_IOCTL_BASE + 0) ++#define REDOX_DRM_IOCTL_MODE_SETCRTC (REDOX_DRM_IOCTL_BASE + 2) ++#define REDOX_DRM_IOCTL_MODE_GETCRTC (REDOX_DRM_IOCTL_BASE + 3) ++#define REDOX_DRM_IOCTL_MODE_GETENCODER (REDOX_DRM_IOCTL_BASE + 6) ++#define REDOX_DRM_IOCTL_MODE_GETCONNECTOR (REDOX_DRM_IOCTL_BASE + 7) ++#define REDOX_DRM_IOCTL_MODE_PAGE_FLIP (REDOX_DRM_IOCTL_BASE + 16) ++#define REDOX_DRM_IOCTL_MODE_CREATE_DUMB (REDOX_DRM_IOCTL_BASE + 18) ++#define REDOX_DRM_IOCTL_MODE_MAP_DUMB (REDOX_DRM_IOCTL_BASE + 19) ++#define REDOX_DRM_IOCTL_MODE_DESTROY_DUMB (REDOX_DRM_IOCTL_BASE + 20) ++#define REDOX_DRM_IOCTL_MODE_ADDFB (REDOX_DRM_IOCTL_BASE + 21) ++#define REDOX_DRM_IOCTL_MODE_RMFB (REDOX_DRM_IOCTL_BASE + 22) ++#define REDOX_DRM_IOCTL_GET_CAP (REDOX_DRM_IOCTL_BASE + 23) ++#define REDOX_DRM_IOCTL_SET_CLIENT_CAP (REDOX_DRM_IOCTL_BASE + 24) ++#define REDOX_DRM_IOCTL_VERSION (REDOX_DRM_IOCTL_BASE + 25) ++#define REDOX_DRM_IOCTL_GEM_CLOSE (REDOX_DRM_IOCTL_BASE + 27) ++#define REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD (REDOX_DRM_IOCTL_BASE + 29) ++#define REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE (REDOX_DRM_IOCTL_BASE + 30) ++#define REDOX_DRM_IOCTL_VIRTGPU_MAP (REDOX_DRM_IOCTL_BASE + 31) ++#define REDOX_DRM_IOCTL_VIRTGPU_EXECBUFFER (REDOX_DRM_IOCTL_BASE + 32) ++#define REDOX_DRM_IOCTL_VIRTGPU_GETPARAM (REDOX_DRM_IOCTL_BASE + 33) ++#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE (REDOX_DRM_IOCTL_BASE + 34) ++#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_INFO (REDOX_DRM_IOCTL_BASE + 35) ++#define REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST (REDOX_DRM_IOCTL_BASE + 36) ++#define REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST (REDOX_DRM_IOCTL_BASE + 37) ++#define REDOX_DRM_IOCTL_VIRTGPU_WAIT (REDOX_DRM_IOCTL_BASE + 38) ++#define REDOX_DRM_IOCTL_VIRTGPU_GET_CAPS (REDOX_DRM_IOCTL_BASE + 39) ++#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB (REDOX_DRM_IOCTL_BASE + 40) ++#define REDOX_DRM_IOCTL_VIRTGPU_CONTEXT_INIT (REDOX_DRM_IOCTL_BASE + 41) ++ ++#define REDOX_DRM_IOCTL_GET_MAGIC (REDOX_DRM_IOCTL_BASE + 33) ++#define REDOX_DRM_IOCTL_AUTH_MAGIC (REDOX_DRM_IOCTL_BASE + 34) ++#define REDOX_DRM_IOCTL_SET_MASTER (REDOX_DRM_IOCTL_BASE + 35) ++#define REDOX_DRM_IOCTL_DROP_MASTER (REDOX_DRM_IOCTL_BASE + 36) ++#define REDOX_DRM_IOCTL_GET_PCI_INFO (REDOX_DRM_IOCTL_BASE + 0x60) ++ ++struct redox_drm_resources_wire { ++ uint32_t connector_count; ++ uint32_t crtc_count; ++ uint32_t encoder_count; ++}; ++ ++struct redox_drm_connector_wire { ++ uint32_t connector_id; ++ uint32_t connection; ++ uint32_t connector_type; ++ uint32_t mm_width; ++ uint32_t mm_height; ++ uint32_t encoder_id; ++ uint32_t mode_count; ++}; ++ ++struct redox_drm_mode_wire { ++ uint32_t clock; ++ uint16_t hdisplay; ++ uint16_t hsync_start; ++ uint16_t hsync_end; ++ uint16_t htotal; ++ uint16_t hskew; ++ uint16_t vdisplay; ++ uint16_t vsync_start; ++ uint16_t vsync_end; ++ uint16_t vtotal; ++ uint16_t vscan; ++ uint32_t vrefresh; ++ uint32_t flags; ++ uint32_t type; ++}; ++ ++struct redox_drm_set_crtc_wire { ++ uint32_t crtc_id; ++ uint32_t fb_handle; ++ uint32_t connector_count; ++ uint32_t connectors[8]; ++ struct redox_drm_mode_wire mode; ++}; ++ ++struct redox_drm_page_flip_wire { ++ uint32_t crtc_id; ++ uint32_t fb_handle; ++ uint32_t flags; ++}; ++ ++struct redox_drm_create_dumb_wire { ++ uint32_t width; ++ uint32_t height; ++ uint32_t bpp; ++ uint32_t flags; ++ uint32_t pitch; ++ uint32_t reserved0; ++ uint64_t size; ++ uint32_t handle; ++ uint32_t reserved1; ++}; ++ ++struct redox_drm_map_dumb_wire { ++ uint32_t handle; ++ uint32_t pad; ++ uint64_t offset; ++}; ++ ++struct redox_drm_destroy_dumb_wire { ++ uint32_t handle; ++}; ++ ++struct redox_drm_add_fb_wire { ++ uint32_t width; ++ uint32_t height; ++ uint32_t pitch; ++ uint32_t bpp; ++ uint32_t depth; ++ uint32_t handle; ++ uint32_t fb_id; ++}; ++ ++struct redox_drm_rm_fb_wire { ++ uint32_t fb_id; ++}; ++ ++struct redox_drm_get_crtc_wire { ++ uint32_t crtc_id; ++ uint32_t fb_id; ++ uint32_t x; ++ uint32_t y; ++ uint32_t mode_valid; ++ struct redox_drm_mode_wire mode; ++}; ++ ++struct redox_drm_version_wire { ++ int32_t major; ++ int32_t minor; ++ int32_t patch; ++ char name[64]; ++}; ++ ++struct redox_drm_prime_handle_to_fd_wire { ++ uint32_t handle; ++ uint32_t flags; ++}; ++ ++struct redox_drm_prime_handle_to_fd_response_wire { ++ int32_t fd; ++ uint32_t pad; ++}; ++ ++struct redox_drm_prime_fd_to_handle_wire { ++ int32_t fd; ++ uint32_t pad; ++}; ++ ++struct redox_drm_prime_fd_to_handle_response_wire { ++ uint32_t handle; ++ uint32_t pad; ++}; ++ ++unsigned long redox_translate_request(unsigned long linux_nr); ++int redox_drm_simple_ioctl(int fd, unsigned long request, void *arg); ++int redox_drm_exchange(int fd, unsigned long request_code, ++ const void *payload, size_t payload_size, ++ void *response, size_t response_capacity, ++ size_t *response_size); ++int redox_drm_exchange_alloc(int fd, unsigned long request_code, ++ const void *payload, size_t payload_size, ++ void **response, size_t *response_size); ++ ++#endif ++ ++#endif diff --git a/local/patches/libdrm/01-drm-ioctl-bridge.patch b/local/patches/libdrm/01-drm-ioctl-bridge.patch deleted file mode 100644 index e583b98b74..0000000000 --- a/local/patches/libdrm/01-drm-ioctl-bridge.patch +++ /dev/null @@ -1,278 +0,0 @@ ---- a/xf86drm.c -+++ b/xf86drm.c -@@ -91,6 +91,7 @@ - #include "xf86drm_redox.h" - #include "libdrm_macros.h" - #include "drm_fourcc.h" -+#include "virtgpu_drm.h" - - #include "util_math.h" - -@@ -813,6 +814,50 @@ - return REDOX_DRM_IOCTL_MODE_DESTROY_DUMB; - case 0xAF: - return REDOX_DRM_IOCTL_MODE_RMFB; -+ /* VirtGPU ioctls (NR 0x41-0x4B) */ -+ case 0x41: -+ return REDOX_DRM_IOCTL_VIRTGPU_MAP; -+ case 0x42: -+ return REDOX_DRM_IOCTL_VIRTGPU_EXECBUFFER; -+ case 0x43: -+ return REDOX_DRM_IOCTL_VIRTGPU_GETPARAM; -+ case 0x44: -+ return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE; -+ case 0x45: -+ return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_INFO; -+ case 0x46: -+ return REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST; -+ case 0x47: -+ return REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST; -+ case 0x48: -+ return REDOX_DRM_IOCTL_VIRTGPU_WAIT; -+ case 0x49: -+ return REDOX_DRM_IOCTL_VIRTGPU_GET_CAPS; -+ case 0x4A: -+ return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB; -+ case 0x4B: -+ return REDOX_DRM_IOCTL_VIRTGPU_CONTEXT_INIT; -+ /* Additional standard DRM ioctls */ -+ case 0x00: -+ return REDOX_DRM_IOCTL_VERSION; -+ case 0xA0: -+ return REDOX_DRM_IOCTL_MODE_GETRESOURCES; -+ case 0xA1: -+ return REDOX_DRM_IOCTL_MODE_GETCRTC; -+ case 0xA2: -+ return REDOX_DRM_IOCTL_MODE_SETCRTC; -+ case 0xA3: -+ return REDOX_DRM_IOCTL_MODE_GETCONNECTOR; -+ case 0xA4: -+ return REDOX_DRM_IOCTL_MODE_PAGE_FLIP; -+ case 0xA8: -+ return REDOX_DRM_IOCTL_MODE_CREATE_DUMB; -+ case 0xAC: -+ return REDOX_DRM_IOCTL_MODE_ADDFB; -+ case 0x2B: -+ return REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD; -+ case 0x2C: -+ return REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE; - default: - return 0; - } -@@ -908,7 +953,19 @@ - static size_t redox_drm_expected_response_size(unsigned long linux_nr, size_t arg_size) - { - switch (linux_nr) { -+ case 0x00: /* VERSION */ - case 0x0C: -+ case 0x2B: /* PRIME_HANDLE_TO_FD */ -+ case 0x2C: /* PRIME_FD_TO_HANDLE */ -+ case 0x41: /* VIRTGPU_MAP */ -+ case 0x43: /* VIRTGPU_GETPARAM */ -+ case 0x44: /* VIRTGPU_RESOURCE_CREATE */ -+ case 0x45: /* VIRTGPU_RESOURCE_INFO */ -+ case 0xA0: /* MODE_GETRESOURCES */ -+ case 0xA1: /* MODE_GETCRTC */ -+ case 0xA3: /* MODE_GETCONNECTOR */ -+ case 0xA8: /* MODE_CREATE_DUMB */ -+ case 0xAC: /* MODE_ADDFB */ - case 0xA6: - case 0xB3: - return arg_size; -@@ -927,6 +984,41 @@ - if (request_code == 0) { - errno = ENOTTY; - return -1; -+ } -+ -+ if (linux_nr == 0x42) { /* VIRTGPU_EXECBUFFER */ -+ struct drm_virtgpu_execbuffer *eb = arg; -+ size_t total = arg_size + eb->size; -+ uint8_t *buf = drmMalloc((int)total); -+ int ret; -+ -+ if (!buf) -+ return -1; -+ -+ memcpy(buf, arg, arg_size); -+ if (eb->size > 0 && eb->command) -+ memcpy(buf + arg_size, (void *)(uintptr_t)eb->command, eb->size); -+ -+ ret = redox_drm_exchange(fd, request_code, buf, total, NULL, 0, NULL); -+ drmFree(buf); -+ return ret; -+ } -+ -+ if (linux_nr == 0x49) { /* VIRTGPU_GET_CAPS */ -+ struct drm_virtgpu_get_caps *gc = arg; -+ void *resp; -+ size_t resp_size; -+ int ret; -+ -+ ret = redox_drm_exchange_alloc(fd, request_code, arg, arg_size, &resp, &resp_size); -+ if (ret == 0 && resp && resp_size > 0) { -+ size_t copy = resp_size < gc->size ? resp_size : gc->size; -+ -+ memcpy((void *)(uintptr_t)gc->addr, resp, copy); -+ drmFree(resp); -+ } -+ -+ return ret; - } - - if (redox_drm_exchange(fd, request_code, ---- a/xf86drm_redox.h -+++ b/xf86drm_redox.h -@@ -28,6 +28,17 @@ - #define REDOX_DRM_IOCTL_GEM_CLOSE (REDOX_DRM_IOCTL_BASE + 27) - #define REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD (REDOX_DRM_IOCTL_BASE + 29) - #define REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE (REDOX_DRM_IOCTL_BASE + 30) -+#define REDOX_DRM_IOCTL_VIRTGPU_MAP (REDOX_DRM_IOCTL_BASE + 31) -+#define REDOX_DRM_IOCTL_VIRTGPU_EXECBUFFER (REDOX_DRM_IOCTL_BASE + 32) -+#define REDOX_DRM_IOCTL_VIRTGPU_GETPARAM (REDOX_DRM_IOCTL_BASE + 33) -+#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE (REDOX_DRM_IOCTL_BASE + 34) -+#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_INFO (REDOX_DRM_IOCTL_BASE + 35) -+#define REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST (REDOX_DRM_IOCTL_BASE + 36) -+#define REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST (REDOX_DRM_IOCTL_BASE + 37) -+#define REDOX_DRM_IOCTL_VIRTGPU_WAIT (REDOX_DRM_IOCTL_BASE + 38) -+#define REDOX_DRM_IOCTL_VIRTGPU_GET_CAPS (REDOX_DRM_IOCTL_BASE + 39) -+#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB (REDOX_DRM_IOCTL_BASE + 40) -+#define REDOX_DRM_IOCTL_VIRTGPU_CONTEXT_INIT (REDOX_DRM_IOCTL_BASE + 41) - - struct redox_drm_resources_wire { - uint32_t connector_count; ---- /dev/null -+++ b/virtgpu_drm.h -@@ -0,0 +1,132 @@ -+#ifndef _VIRTGPU_DRM_H_ -+#define _VIRTGPU_DRM_H_ -+ -+#include -+ -+#define DRM_VIRTGPU_MAP 0x41 -+#define DRM_VIRTGPU_EXECBUFFER 0x42 -+#define DRM_VIRTGPU_GETPARAM 0x43 -+#define DRM_VIRTGPU_RESOURCE_CREATE 0x44 -+#define DRM_VIRTGPU_RESOURCE_INFO 0x45 -+#define DRM_VIRTGPU_TRANSFER_FROM_HOST 0x46 -+#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x47 -+#define DRM_VIRTGPU_WAIT 0x48 -+#define DRM_VIRTGPU_GET_CAPS 0x49 -+#define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x4A -+#define DRM_VIRTGPU_CONTEXT_INIT 0x4B -+ -+#define drm_virtgpu_resource_create drm_virtgpu_resource_create_3d -+#define drm_virtgpu_3d_transfer_to_host drm_virtgpu_transfer_to_host -+#define drm_virtgpu_3d_transfer_from_host drm_virtgpu_transfer_from_host -+#define drm_virtgpu_3d_wait drm_virtgpu_wait_3d -+#define ctx_set_params_ptr ctx_set_params -+#define resource_id res_handle -+ -+struct drm_virtgpu_3d_box { -+ uint32_t x; -+ uint32_t y; -+ uint32_t z; -+ uint32_t w; -+ uint32_t h; -+ uint32_t d; -+}; -+ -+struct drm_virtgpu_execbuffer { -+ uint32_t flags; -+ uint32_t size; -+ uint64_t command; -+ uint64_t bo_handles; -+ uint32_t num_bo_handles; -+ int32_t fence_fd; -+ uint32_t ring_idx; -+ uint32_t syncobj_stride; -+ uint32_t num_in_syncobjs; -+ uint32_t num_out_syncobjs; -+ uint64_t in_syncobjs; -+ uint64_t out_syncobjs; -+}; -+ -+struct drm_virtgpu_getparam { -+ uint64_t param; -+ uint64_t value; -+}; -+ -+struct drm_virtgpu_resource_create_3d { -+ uint32_t target; -+ uint32_t format; -+ uint32_t bind; -+ uint32_t width; -+ uint32_t height; -+ uint32_t depth; -+ uint32_t array_size; -+ uint32_t last_level; -+ uint32_t nr_samples; -+ uint32_t flags; -+ uint32_t bo_handle; -+ uint32_t res_handle; -+ uint32_t size; -+ uint32_t stride; -+}; -+ -+struct drm_virtgpu_resource_info { -+ uint32_t bo_handle; -+ uint32_t res_handle; -+ uint32_t size; -+ uint32_t blob_mem; -+}; -+ -+struct drm_virtgpu_transfer_to_host { -+ uint32_t bo_handle; -+ struct drm_virtgpu_3d_box box; -+ uint32_t level; -+ uint32_t offset; -+ uint32_t stride; -+ uint32_t layer_stride; -+}; -+ -+struct drm_virtgpu_transfer_from_host { -+ uint32_t bo_handle; -+ struct drm_virtgpu_3d_box box; -+ uint32_t level; -+ uint32_t offset; -+ uint32_t stride; -+ uint32_t layer_stride; -+}; -+ -+struct drm_virtgpu_wait_3d { -+ uint32_t handle; -+ uint32_t flags; -+}; -+ -+struct drm_virtgpu_get_caps { -+ uint32_t cap_set_id; -+ uint32_t cap_set_ver; -+ uint64_t addr; -+ uint32_t size; -+ uint32_t pad; -+}; -+ -+struct drm_virtgpu_resource_create_blob { -+ uint32_t blob_mem; -+ uint32_t blob_flags; -+ uint32_t bo_handle; -+ uint32_t res_handle; -+ uint64_t size; -+ uint32_t pad; -+ uint32_t cmd_size; -+ uint64_t cmd; -+ uint64_t blob_id; -+}; -+ -+struct drm_virtgpu_context_set_param { -+ uint64_t param; -+ uint64_t value; -+}; -+ -+struct drm_virtgpu_context_init { -+ uint32_t num_params; -+ uint32_t pad; -+ uint64_t ctx_set_params; -+}; -+ -+#endif diff --git a/local/patches/libdrm/01-virtgpu-drm-header.patch b/local/patches/libdrm/01-virtgpu-drm-header.patch new file mode 100644 index 0000000000..8598eb94b0 --- /dev/null +++ b/local/patches/libdrm/01-virtgpu-drm-header.patch @@ -0,0 +1,138 @@ +diff --git a/virtgpu_drm.h b/virtgpu_drm.h +new file mode 100644 +index 0000000..a0aab83 +--- /dev/null ++++ b/virtgpu_drm.h +@@ -0,0 +1,132 @@ ++#ifndef _VIRTGPU_DRM_H_ ++#define _VIRTGPU_DRM_H_ ++ ++#include ++ ++#define DRM_VIRTGPU_MAP 0x41 ++#define DRM_VIRTGPU_EXECBUFFER 0x42 ++#define DRM_VIRTGPU_GETPARAM 0x43 ++#define DRM_VIRTGPU_RESOURCE_CREATE 0x44 ++#define DRM_VIRTGPU_RESOURCE_INFO 0x45 ++#define DRM_VIRTGPU_TRANSFER_FROM_HOST 0x46 ++#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x47 ++#define DRM_VIRTGPU_WAIT 0x48 ++#define DRM_VIRTGPU_GET_CAPS 0x49 ++#define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x4A ++#define DRM_VIRTGPU_CONTEXT_INIT 0x4B ++ ++#define drm_virtgpu_resource_create drm_virtgpu_resource_create_3d ++#define drm_virtgpu_3d_transfer_to_host drm_virtgpu_transfer_to_host ++#define drm_virtgpu_3d_transfer_from_host drm_virtgpu_transfer_from_host ++#define drm_virtgpu_3d_wait drm_virtgpu_wait_3d ++#define ctx_set_params_ptr ctx_set_params ++#define resource_id res_handle ++ ++struct drm_virtgpu_3d_box { ++ uint32_t x; ++ uint32_t y; ++ uint32_t z; ++ uint32_t w; ++ uint32_t h; ++ uint32_t d; ++}; ++ ++struct drm_virtgpu_execbuffer { ++ uint32_t flags; ++ uint32_t size; ++ uint64_t command; ++ uint64_t bo_handles; ++ uint32_t num_bo_handles; ++ int32_t fence_fd; ++ uint32_t ring_idx; ++ uint32_t syncobj_stride; ++ uint32_t num_in_syncobjs; ++ uint32_t num_out_syncobjs; ++ uint64_t in_syncobjs; ++ uint64_t out_syncobjs; ++}; ++ ++struct drm_virtgpu_getparam { ++ uint64_t param; ++ uint64_t value; ++}; ++ ++struct drm_virtgpu_resource_create_3d { ++ uint32_t target; ++ uint32_t format; ++ uint32_t bind; ++ uint32_t width; ++ uint32_t height; ++ uint32_t depth; ++ uint32_t array_size; ++ uint32_t last_level; ++ uint32_t nr_samples; ++ uint32_t flags; ++ uint32_t bo_handle; ++ uint32_t res_handle; ++ uint32_t size; ++ uint32_t stride; ++}; ++ ++struct drm_virtgpu_resource_info { ++ uint32_t bo_handle; ++ uint32_t res_handle; ++ uint32_t size; ++ uint32_t blob_mem; ++}; ++ ++struct drm_virtgpu_transfer_to_host { ++ uint32_t bo_handle; ++ struct drm_virtgpu_3d_box box; ++ uint32_t level; ++ uint32_t offset; ++ uint32_t stride; ++ uint32_t layer_stride; ++}; ++ ++struct drm_virtgpu_transfer_from_host { ++ uint32_t bo_handle; ++ struct drm_virtgpu_3d_box box; ++ uint32_t level; ++ uint32_t offset; ++ uint32_t stride; ++ uint32_t layer_stride; ++}; ++ ++struct drm_virtgpu_wait_3d { ++ uint32_t handle; ++ uint32_t flags; ++}; ++ ++struct drm_virtgpu_get_caps { ++ uint32_t cap_set_id; ++ uint32_t cap_set_ver; ++ uint64_t addr; ++ uint32_t size; ++ uint32_t pad; ++}; ++ ++struct drm_virtgpu_resource_create_blob { ++ uint32_t blob_mem; ++ uint32_t blob_flags; ++ uint32_t bo_handle; ++ uint32_t res_handle; ++ uint64_t size; ++ uint32_t pad; ++ uint32_t cmd_size; ++ uint64_t cmd; ++ uint64_t blob_id; ++}; ++ ++struct drm_virtgpu_context_set_param { ++ uint64_t param; ++ uint64_t value; ++}; ++ ++struct drm_virtgpu_context_init { ++ uint32_t num_params; ++ uint32_t pad; ++ uint64_t ctx_set_params; ++}; ++ ++#endif diff --git a/local/patches/libdrm/02-ioctl-response-sizes.patch b/local/patches/libdrm/02-ioctl-response-sizes.patch deleted file mode 100644 index 0744218b10..0000000000 --- a/local/patches/libdrm/02-ioctl-response-sizes.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/xf86drm.c b/xf86drm.c -index 0379aafd7e..2d3fcd6d3b 100644 ---- a/xf86drm.c -+++ b/xf86drm.c -@@ -1653,6 +1653,10 @@ static size_t redox_drm_expected_response_size(unsigned long linux_nr, size_t ar - case 0xA9: - case 0xAA: - case 0xAC: -+ case 0xB2: -+ case 0xB4: -+ case 0xBD: -+ case 0xBE: - case 0xB8: - case 0xB9: - case 0xB3: -@@ -4482,7 +4486,13 @@ drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, - return -errno; - } - -- *prime_fd = response.fd; -+ char path[64]; -+ snprintf(path, sizeof(path), "card0/dmabuf/%d", response.fd); -+ int real_fd = openat(fd, path, O_RDWR | O_CLOEXEC); -+ if (real_fd < 0) { -+ return -errno; -+ } -+ *prime_fd = real_fd; - return 0; - #else - struct drm_prime_handle args; diff --git a/local/patches/libdrm/02-redox-dispatch.patch b/local/patches/libdrm/02-redox-dispatch.patch new file mode 100644 index 0000000000..67f4cdb511 --- /dev/null +++ b/local/patches/libdrm/02-redox-dispatch.patch @@ -0,0 +1,806 @@ +diff --git a/xf86drm.c b/xf86drm.c +index 3a10589..207c456 100644 +--- a/xf86drm.c ++++ b/xf86drm.c +@@ -88,8 +88,10 @@ + #endif + + #include "xf86drm.h" ++#include "xf86drm_redox.h" + #include "libdrm_macros.h" + #include "drm_fourcc.h" ++#include "virtgpu_drm.h" + + #include "util_math.h" + +@@ -113,7 +115,7 @@ + #define DRM_MAJOR 226 /* Linux */ + #endif + +-#if defined(__OpenBSD__) || defined(__DragonFly__) ++#if defined(__OpenBSD__) || defined(__DragonFly__) || defined(__redox__) + struct drm_pciinfo { + uint16_t domain; + uint8_t bus; +@@ -313,7 +315,6 @@ drmGetFormatModifierNameFromArm(uint64_t modifier) + uint64_t type = (modifier >> 52) & 0xf; + + FILE *fp; +- size_t size = 0; + char *modifier_name = NULL; + bool result = false; + +@@ -321,6 +322,7 @@ drmGetFormatModifierNameFromArm(uint64_t modifier) + fprintf(stderr, "open_memstream not available on Redox\n"); + return NULL; + #else ++ size_t size = 0; + fp = open_memstream(&modifier_name, &size); + if (!fp) + return NULL; +@@ -425,12 +427,12 @@ drmGetFormatModifierNameFromAmd(uint64_t modifier) + uint64_t tile_version = AMD_FMT_MOD_GET(TILE_VERSION, modifier); + FILE *fp; + char *mod_amd = NULL; +- size_t size = 0; + + #if defined(__redox__) + fprintf(stderr, "open_memstream not available on Redox\n"); + return NULL; + #else ++ size_t size = 0; + fp = open_memstream(&mod_amd, &size); + if (!fp) + return NULL; +@@ -703,18 +705,366 @@ drm_public void drmFree(void *pt) + free(pt); + } + ++#if defined(__redox__) ++static int redox_drm_write_all(int fd, const void *buf, size_t len) ++{ ++ const uint8_t *bytes = buf; ++ size_t offset = 0; ++ ++ while (offset < len) { ++ ssize_t written = write(fd, bytes + offset, len - offset); ++ if (written < 0) { ++ if (errno == EINTR || errno == EAGAIN) ++ continue; ++ return -1; ++ } ++ if (written == 0) { ++ errno = EIO; ++ return -1; ++ } ++ offset += (size_t)written; ++ } ++ ++ return 0; ++} ++ ++static int redox_drm_read_all(int fd, void *buf, size_t len) ++{ ++ uint8_t *bytes = buf; ++ size_t offset = 0; ++ ++ while (offset < len) { ++ ssize_t read_count = read(fd, bytes + offset, len - offset); ++ if (read_count < 0) { ++ if (errno == EINTR || errno == EAGAIN) ++ continue; ++ return -1; ++ } ++ if (read_count == 0) { ++ errno = EIO; ++ return -1; ++ } ++ offset += (size_t)read_count; ++ } ++ ++ return 0; ++} ++ ++static int redox_drm_send_request(int fd, unsigned long request_code, ++ const void *payload, size_t payload_size) ++{ ++ const size_t request_word_size = sizeof(uintptr_t); ++ const size_t total_size = request_word_size + payload_size; ++ uint8_t stack_request[sizeof(uintptr_t)]; ++ uint8_t *request_bytes = stack_request; ++ uintptr_t request_word = (uintptr_t)request_code; ++ size_t i; ++ ++ if (total_size > sizeof(stack_request)) { ++ request_bytes = drmMalloc(total_size); ++ if (!request_bytes) { ++ errno = ENOMEM; ++ return -1; ++ } ++ } ++ ++ for (i = 0; i < request_word_size; ++i) ++ request_bytes[i] = (uint8_t)((request_word >> (i * 8)) & 0xffU); ++ ++ if (payload_size != 0) ++ memcpy(request_bytes + request_word_size, payload, payload_size); ++ ++ if (redox_drm_write_all(fd, request_bytes, total_size) != 0) { ++ if (request_bytes != stack_request) ++ drmFree(request_bytes); ++ return -1; ++ } ++ ++ if (request_bytes != stack_request) ++ drmFree(request_bytes); ++ ++ return 0; ++} ++ ++static int redox_drm_get_response_size(int fd, size_t *response_size) ++{ ++ stat_t st; ++ ++ if (fstat(fd, &st) != 0) ++ return -1; ++ ++ *response_size = (size_t)st.st_size; ++ return 0; ++} ++ ++unsigned long redox_translate_request(unsigned long linux_nr) ++{ ++ switch (linux_nr) { ++ case 0x0C: ++ return REDOX_DRM_IOCTL_GET_CAP; ++ case 0x0D: ++ return REDOX_DRM_IOCTL_SET_CLIENT_CAP; ++ case 0x09: ++ return REDOX_DRM_IOCTL_GEM_CLOSE; ++ case 0xA6: ++ return REDOX_DRM_IOCTL_MODE_GETENCODER; ++ case 0xB3: ++ return REDOX_DRM_IOCTL_MODE_MAP_DUMB; ++ case 0xB4: ++ return REDOX_DRM_IOCTL_MODE_DESTROY_DUMB; ++ case 0xAF: ++ return REDOX_DRM_IOCTL_MODE_RMFB; ++ /* VirtGPU ioctls (NR 0x41-0x4B) */ ++ case 0x41: ++ return REDOX_DRM_IOCTL_VIRTGPU_MAP; ++ case 0x42: ++ return REDOX_DRM_IOCTL_VIRTGPU_EXECBUFFER; ++ case 0x43: ++ return REDOX_DRM_IOCTL_VIRTGPU_GETPARAM; ++ case 0x44: ++ return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE; ++ case 0x45: ++ return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_INFO; ++ case 0x46: ++ return REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST; ++ case 0x47: ++ return REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST; ++ case 0x48: ++ return REDOX_DRM_IOCTL_VIRTGPU_WAIT; ++ case 0x49: ++ return REDOX_DRM_IOCTL_VIRTGPU_GET_CAPS; ++ case 0x4A: ++ return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB; ++ case 0x4B: ++ return REDOX_DRM_IOCTL_VIRTGPU_CONTEXT_INIT; ++ /* Additional standard DRM ioctls */ ++ case 0x00: ++ return REDOX_DRM_IOCTL_VERSION; ++ case 0xA0: ++ return REDOX_DRM_IOCTL_MODE_GETRESOURCES; ++ case 0xA1: ++ return REDOX_DRM_IOCTL_MODE_GETCRTC; ++ case 0xA2: ++ return REDOX_DRM_IOCTL_MODE_SETCRTC; ++ case 0xA3: ++ return REDOX_DRM_IOCTL_MODE_GETCONNECTOR; ++ case 0xA4: ++ return REDOX_DRM_IOCTL_MODE_PAGE_FLIP; ++ case 0xA8: ++ return REDOX_DRM_IOCTL_MODE_CREATE_DUMB; ++ case 0xAC: ++ return REDOX_DRM_IOCTL_MODE_ADDFB; ++ case 0x2B: ++ return REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD; ++ case 0x2C: ++ return REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE; ++ /* DRM_IOCTL_GET_PCIINFO — PCI device information for driver discovery */ ++ case 0x15: ++ return REDOX_DRM_IOCTL_GET_PCI_INFO; ++ /* DRM auth/master ioctls */ ++ case 0x02: /* GET_MAGIC — DRM_IOR(0x02, struct drm_auth) */ ++ return REDOX_DRM_IOCTL_GET_MAGIC; ++ case 0x11: /* AUTH_MAGIC — DRM_IOW(0x11, struct drm_auth) */ ++ return REDOX_DRM_IOCTL_AUTH_MAGIC; ++ case 0x1e: /* SET_MASTER — DRM_IO(0x1e) */ ++ return REDOX_DRM_IOCTL_SET_MASTER; ++ case 0x1f: /* DROP_MASTER — DRM_IO(0x1f) */ ++ return REDOX_DRM_IOCTL_DROP_MASTER; ++ default: ++ return 0; ++ } ++} ++ ++int redox_drm_exchange(int fd, unsigned long request_code, ++ const void *payload, size_t payload_size, ++ void *response, size_t response_capacity, ++ size_t *response_size) ++{ ++ uint8_t stack_buffer[64]; ++ uint8_t *response_buffer = stack_buffer; ++ size_t actual_response_size = 0; ++ ++ if (redox_drm_send_request(fd, request_code, payload, payload_size) != 0) ++ return -1; ++ ++ if (redox_drm_get_response_size(fd, &actual_response_size) != 0) ++ return -1; ++ ++ if (response_size) ++ *response_size = actual_response_size; ++ ++ if (actual_response_size == 0) ++ return 0; ++ ++ if (response && response_capacity >= actual_response_size) { ++ return redox_drm_read_all(fd, response, actual_response_size); ++ } ++ ++ if (actual_response_size > sizeof(stack_buffer)) { ++ response_buffer = drmMalloc(actual_response_size); ++ if (!response_buffer) { ++ errno = ENOMEM; ++ return -1; ++ } ++ } ++ ++ if (redox_drm_read_all(fd, response_buffer, actual_response_size) != 0) { ++ if (response_buffer != stack_buffer) ++ drmFree(response_buffer); ++ return -1; ++ } ++ ++ if (response_buffer != stack_buffer) ++ drmFree(response_buffer); ++ ++ if (response && response_capacity < actual_response_size) { ++ errno = EMSGSIZE; ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int redox_drm_exchange_alloc(int fd, unsigned long request_code, ++ const void *payload, size_t payload_size, ++ void **response, size_t *response_size) ++{ ++ size_t actual_response_size = 0; ++ void *allocated_response = NULL; ++ ++ if (!response) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if (redox_drm_send_request(fd, request_code, payload, payload_size) != 0) ++ return -1; ++ ++ if (redox_drm_get_response_size(fd, &actual_response_size) != 0) ++ return -1; ++ ++ if (actual_response_size != 0) { ++ allocated_response = drmMalloc(actual_response_size); ++ if (!allocated_response) { ++ errno = ENOMEM; ++ return -1; ++ } ++ ++ if (redox_drm_read_all(fd, allocated_response, actual_response_size) != 0) { ++ drmFree(allocated_response); ++ return -1; ++ } ++ } ++ ++ *response = allocated_response; ++ if (response_size) ++ *response_size = actual_response_size; ++ return 0; ++} ++ ++static size_t redox_drm_expected_response_size(unsigned long linux_nr, size_t arg_size) ++{ ++ switch (linux_nr) { ++ case 0x00: /* VERSION */ ++ case 0x0C: ++ case 0x2B: /* PRIME_HANDLE_TO_FD */ ++ case 0x2C: /* PRIME_FD_TO_HANDLE */ ++ case 0x41: /* VIRTGPU_MAP */ ++ case 0x43: /* VIRTGPU_GETPARAM */ ++ case 0x44: /* VIRTGPU_RESOURCE_CREATE */ ++ case 0x45: /* VIRTGPU_RESOURCE_INFO */ ++ case 0xA0: /* MODE_GETRESOURCES */ ++ case 0xA1: /* MODE_GETCRTC */ ++ case 0xA3: /* MODE_GETCONNECTOR */ ++ case 0xA8: /* MODE_CREATE_DUMB */ ++ case 0xAC: /* MODE_ADDFB */ ++ case 0xA6: ++ case 0xB3: ++ return arg_size; ++ case 0x02: /* GET_MAGIC — returns struct drm_auth (magic u32) */ ++ return arg_size; ++ case 0x11: /* AUTH_MAGIC — returns struct drm_auth (magic u32) */ ++ return arg_size; ++ default: ++ return 0; ++ } ++} ++ ++int redox_drm_simple_ioctl(int fd, unsigned long request, void *arg) ++{ ++ const unsigned long linux_nr = REDOX_LINUX_IOCTL_NR(request); ++ const unsigned long request_code = redox_translate_request(linux_nr); ++ const size_t arg_size = REDOX_LINUX_IOCTL_SIZE(request); ++ const size_t expected_response_size = redox_drm_expected_response_size(linux_nr, arg_size); ++ ++ if (request_code == 0) { ++ errno = ENOTTY; ++ return -1; ++ } ++ ++ if (linux_nr == 0x42) { /* VIRTGPU_EXECBUFFER */ ++ struct drm_virtgpu_execbuffer *eb = arg; ++ size_t total = arg_size + eb->size; ++ uint8_t *buf = drmMalloc((int)total); ++ int ret; ++ ++ if (!buf) ++ return -1; ++ ++ memcpy(buf, arg, arg_size); ++ if (eb->size > 0 && eb->command) ++ memcpy(buf + arg_size, (void *)(uintptr_t)eb->command, eb->size); ++ ++ ret = redox_drm_exchange(fd, request_code, buf, total, NULL, 0, NULL); ++ drmFree(buf); ++ return ret; ++ } ++ ++ if (linux_nr == 0x49) { /* VIRTGPU_GET_CAPS */ ++ struct drm_virtgpu_get_caps *gc = arg; ++ void *resp; ++ size_t resp_size; ++ int ret; ++ ++ ret = redox_drm_exchange_alloc(fd, request_code, arg, arg_size, &resp, &resp_size); ++ if (ret == 0 && resp && resp_size > 0) { ++ size_t copy = resp_size < gc->size ? resp_size : gc->size; ++ ++ memcpy((void *)(uintptr_t)gc->addr, resp, copy); ++ drmFree(resp); ++ } ++ ++ return ret; ++ } ++ ++ if (redox_drm_exchange(fd, request_code, ++ arg, arg ? arg_size : 0, ++ expected_response_size ? arg : NULL, ++ expected_response_size, ++ NULL) != 0) { ++ return -1; ++ } ++ ++ return 0; ++} ++#endif ++ + /** + * Call ioctl, restarting if it is interrupted + */ + drm_public int + drmIoctl(int fd, unsigned long request, void *arg) + { ++ #if defined(__redox__) ++ return redox_drm_simple_ioctl(fd, request, arg); ++ #else + int ret; + + do { + ret = ioctl(fd, request, arg); + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); + return ret; ++ #endif + } + + static unsigned long drmGetKeyFromFd(int fd) +@@ -1093,6 +1443,7 @@ static int drmGetMinorType(int major, int minor) + return -1; + } + ++#if !defined(__redox__) + static const char *drmGetMinorName(int type) + { + switch (type) { +@@ -1104,6 +1455,7 @@ static const char *drmGetMinorName(int type) + return NULL; + } + } ++#endif + + /** + * Open the device by bus ID. +@@ -1201,7 +1553,11 @@ static int drmOpenByName(const char *name, int type) + for (i = base; i < base + DRM_MAX_MINOR; i++) { + if ((fd = drmOpenMinor(i, 1, type)) >= 0) { + if ((version = drmGetVersion(fd))) { ++ #if defined(__redox__) ++ if (!version->name || !strcmp(version->name, name)) { ++ #else + if (!strcmp(version->name, name)) { ++ #endif + drmFreeVersion(version); + id = drmGetBusid(fd); + drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL"); +@@ -1354,6 +1710,7 @@ drm_public void drmFreeVersion(drmVersionPtr v) + * Used by drmGetVersion() to free the memory pointed by \p %v as well as all + * the non-null strings pointers in it. + */ ++#if !defined(__redox__) + static void drmFreeKernelVersion(drm_version_t *v) + { + if (!v) +@@ -1363,6 +1720,7 @@ static void drmFreeKernelVersion(drm_version_t *v) + drmFree(v->desc); + drmFree(v); + } ++#endif + + + /** +@@ -1375,6 +1733,7 @@ static void drmFreeKernelVersion(drm_version_t *v) + * Used by drmGetVersion() to translate the information returned by the ioctl + * interface in a private structure into the public structure counterpart. + */ ++#if !defined(__redox__) + static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s) + { + d->version_major = s->version_major; +@@ -1387,6 +1746,7 @@ static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s) + d->desc_len = s->desc_len; + d->desc = s->desc ? strdup(s->desc) : NULL; + } ++#endif + + + /** +@@ -1406,6 +1766,50 @@ static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s) + */ + drm_public drmVersionPtr drmGetVersion(int fd) + { ++ #if defined(__redox__) ++ drmVersionPtr retval = drmMalloc(sizeof(*retval)); ++ struct redox_drm_version_wire version; ++ ++ if (!retval) ++ return NULL; ++ ++ if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_VERSION, ++ NULL, 0, ++ &version, sizeof(version), ++ NULL) != 0) { ++ drmFree(retval); ++ return NULL; ++ } ++ ++ memclear(*retval); ++ retval->version_major = version.major; ++ retval->version_minor = version.minor; ++ retval->version_patchlevel = version.patch; ++ ++ /* The scheme returns a NUL-terminated driver name in version.name. ++ * KWin drm_gpu.cpp dereferences version->name unconditionally ++ * (strstr checks for "i915", "amdgpu", "virtio" etc.) so it must ++ * never be NULL. ++ */ ++ version.name[sizeof(version.name) - 1] = '\0'; ++ if (version.name[0] != '\0') { ++ size_t len = strlen(version.name); ++ retval->name = drmMalloc(len + 1); ++ if (retval->name) { ++ memcpy(retval->name, version.name, len + 1); ++ retval->name_len = len; ++ } ++ } else { ++ const char fallback[] = "redox-drm"; ++ retval->name = drmMalloc(sizeof(fallback)); ++ if (retval->name) { ++ memcpy(retval->name, fallback, sizeof(fallback)); ++ retval->name_len = sizeof(fallback) - 1; ++ } ++ } ++ ++ return retval; ++ #else + drmVersionPtr retval; + drm_version_t *version = drmMalloc(sizeof(*version)); + +@@ -1436,6 +1840,7 @@ drm_public drmVersionPtr drmGetVersion(int fd) + drmCopyVersion(retval, version); + drmFreeKernelVersion(version); + return retval; ++ #endif + } + + +@@ -3400,6 +3805,23 @@ drm_public int drmGetNodeTypeFromFd(int fd) + drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, + int *prime_fd) + { ++ #if defined(__redox__) ++ struct redox_drm_prime_handle_to_fd_wire request; ++ struct redox_drm_prime_handle_to_fd_response_wire response; ++ ++ memclear(request); ++ request.handle = handle; ++ request.flags = flags; ++ if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD, ++ &request, sizeof(request), ++ &response, sizeof(response), ++ NULL) != 0) { ++ return -errno; ++ } ++ ++ *prime_fd = response.fd; ++ return 0; ++ #else + struct drm_prime_handle args; + int ret; + +@@ -3413,10 +3835,27 @@ drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, + + *prime_fd = args.fd; + return 0; ++ #endif + } + + drm_public int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle) + { ++ #if defined(__redox__) ++ struct redox_drm_prime_fd_to_handle_wire request; ++ struct redox_drm_prime_fd_to_handle_response_wire response; ++ ++ memclear(request); ++ request.fd = prime_fd; ++ if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE, ++ &request, sizeof(request), ++ &response, sizeof(response), ++ NULL) != 0) { ++ return -errno; ++ } ++ ++ *handle = response.handle; ++ return 0; ++ #else + struct drm_prime_handle args; + int ret; + +@@ -3428,6 +3867,7 @@ drm_public int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle) + + *handle = args.handle; + return 0; ++ #endif + } + + drm_public int drmCloseBufferHandle(int fd, uint32_t handle) +@@ -3544,7 +3984,7 @@ static char *drmGetMinorNameForFD(int fd, int type) + n = drmGetNodePath(buf, sizeof(buf), type, min); + if (n < 0) + return NULL; +- if (n == -1 || n >= sizeof(buf)) ++ if ((size_t)n >= sizeof(buf)) + return NULL; + + return strdup(buf); +@@ -3666,7 +4106,7 @@ static int drmParseSubsystemType(int maj, int min) + return DRM_BUS_VIRTIO; + } + return subsystem_type; +-#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) ++#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__redox__) + return DRM_BUS_PCI; + #else + #warning "Missing implementation of drmParseSubsystemType" +@@ -3800,6 +4240,21 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) + return 0; + #elif defined(__FreeBSD__) + return get_sysctl_pci_bus_info(maj, min, info); ++#elif defined(__redox__) ++ int rfd = open("/scheme/drm/card0", O_RDONLY); ++ if (rfd < 0) ++ return -errno; ++ uint8_t buf[22]; ++ size_t rsize = 0; ++ int ret = redox_drm_exchange(rfd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, buf, sizeof(buf), &rsize); ++ close(rfd); ++ if (ret != 0 || rsize < 17) ++ return -EIO; ++ info->domain = buf[10] | (buf[11] << 8) | (buf[12] << 16) | (buf[13] << 24); ++ info->bus = buf[14]; ++ info->dev = buf[15]; ++ info->func = buf[16]; ++ return 0; + #else + #warning "Missing implementation of drmParsePciBusInfo" + return -EINVAL; +@@ -4009,6 +4464,23 @@ static int drmParsePciDeviceInfo(int maj, int min, + device->revision_id = results[0].pc_revid; + + return 0; ++#elif defined(__redox__) ++ int rfd2 = open("/scheme/drm/card0", O_RDONLY); ++ if (rfd2 < 0) ++ return -errno; ++ uint8_t dbuf[22]; ++ size_t drsize = 0; ++ int dret = redox_drm_exchange(rfd2, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, dbuf, sizeof(dbuf), &drsize); ++ close(rfd2); ++ if (dret != 0 || drsize < 9) ++ return -EIO; ++ device->vendor_id = dbuf[0] | (dbuf[1] << 8); ++ device->device_id = dbuf[2] | (dbuf[3] << 8); ++ device->subvendor_id = dbuf[4] | (dbuf[5] << 8); ++ device->subdevice_id = dbuf[6] | (dbuf[7] << 8); ++ if (drsize >= 9) ++ device->revision_id = dbuf[8]; ++ return 0; + #else + #warning "Missing implementation of drmParsePciDeviceInfo" + return -EINVAL; +@@ -4661,6 +5133,66 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP + + *device = d; + ++ return 0; ++#elif defined(__redox__) ++ /* On Redox there is no /dev/dri/ directory to enumerate. ++ * Instead, open /scheme/drm/card0 and query PCI info to ++ * construct a single drmDevice that serves as both primary ++ * and render node. */ ++ drmDevicePtr devp; ++ char *pptr; ++ int max_node_length = 64, i; ++ size_t extra, psize; ++ uint8_t pbuf[22]; ++ size_t prsize = 0; ++ int pret, fd; ++ ++ if (device == NULL) ++ return -EINVAL; ++ if (drm_device_validate_flags(flags)) ++ return -EINVAL; ++ ++ fd = open("/scheme/drm/card0", O_RDWR | O_CLOEXEC); ++ if (fd < 0) ++ return -errno; ++ ++ pret = redox_drm_exchange(fd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, ++ pbuf, sizeof(pbuf), &prsize); ++ close(fd); ++ if (pret != 0 || prsize < 17) ++ return -EIO; ++ ++ extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length); ++ psize = sizeof(drmDevice) + extra + sizeof(drmPciBusInfo) + sizeof(drmPciDeviceInfo); ++ devp = calloc(1, psize); ++ if (!devp) ++ return -ENOMEM; ++ ++ devp->bustype = DRM_BUS_PCI; ++ /* Advertise both PRIMARY and RENDER — same path on Redox */ ++ devp->available_nodes = (1 << DRM_NODE_PRIMARY) | (1 << DRM_NODE_RENDER); ++ pptr = (char *)devp + sizeof(drmDevice); ++ devp->nodes = (char **)pptr; ++ pptr += DRM_NODE_MAX * sizeof(void *); ++ for (i = 0; i < DRM_NODE_MAX; i++) { devp->nodes[i] = pptr; pptr += max_node_length; } ++ snprintf(devp->nodes[DRM_NODE_PRIMARY], max_node_length, "/scheme/drm/card0"); ++ snprintf(devp->nodes[DRM_NODE_RENDER], max_node_length, "/scheme/drm/card0"); ++ ++ devp->businfo.pci = (drmPciBusInfoPtr)pptr; ++ pptr += sizeof(drmPciBusInfo); ++ devp->businfo.pci->domain = pbuf[10] | (pbuf[11] << 8) | (pbuf[12] << 16) | (pbuf[13] << 24); ++ devp->businfo.pci->bus = pbuf[14]; ++ devp->businfo.pci->dev = pbuf[15]; ++ devp->businfo.pci->func = pbuf[16]; ++ ++ devp->deviceinfo.pci = (drmPciDeviceInfoPtr)pptr; ++ devp->deviceinfo.pci->vendor_id = pbuf[0] | (pbuf[1] << 8); ++ devp->deviceinfo.pci->device_id = pbuf[2] | (pbuf[3] << 8); ++ devp->deviceinfo.pci->subvendor_id = pbuf[4] | (pbuf[5] << 8); ++ devp->deviceinfo.pci->subdevice_id = pbuf[6] | (pbuf[7] << 8); ++ devp->deviceinfo.pci->revision_id = pbuf[8]; ++ ++ *device = devp; + return 0; + #else + drmDevicePtr local_devices[MAX_DRM_NODES]; +@@ -4761,6 +5293,66 @@ drm_public int drmGetNodeTypeFromDevId(dev_t devid) + */ + drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) + { ++#if defined(__redox__) ++ uint8_t pbuf[22]; ++ size_t prsize = 0; ++ int pret; ++ uint16_t pvendor_id, pdevice_id, psubvendor_id, psubdevice_id, pdomain; ++ uint8_t prevision_id, pbus, pdev, pfunc; ++ const char *pnode; ++ int max_node_length, i; ++ size_t extra, psize; ++ drmDevicePtr devp; ++ char *pptr; ++ ++ pret = redox_drm_exchange(fd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, ++ pbuf, sizeof(pbuf), &prsize); ++ if (pret != 0 || prsize < 17) ++ return -EIO; ++ ++ pvendor_id = pbuf[0] | (pbuf[1] << 8); ++ pdevice_id = pbuf[2] | (pbuf[3] << 8); ++ psubvendor_id = pbuf[4] | (pbuf[5] << 8); ++ psubdevice_id = pbuf[6] | (pbuf[7] << 8); ++ prevision_id = pbuf[8]; ++ pdomain = pbuf[10] | (pbuf[11] << 8) | (pbuf[12] << 16) | (pbuf[13] << 24); ++ pbus = pbuf[14]; ++ pdev = pbuf[15]; ++ pfunc = pbuf[16]; ++ ++ pnode = "/scheme/drm/card0"; ++ max_node_length = 64; ++ extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length); ++ psize = sizeof(drmDevice) + extra + sizeof(drmPciBusInfo) + sizeof(drmPciDeviceInfo); ++ devp = calloc(1, psize); ++ if (!devp) ++ return -ENOMEM; ++ ++ devp->bustype = DRM_BUS_PCI; ++ devp->available_nodes = 1 << DRM_NODE_PRIMARY; ++ pptr = (char *)devp + sizeof(drmDevice); ++ devp->nodes = (char **)pptr; ++ pptr += DRM_NODE_MAX * sizeof(void *); ++ for (i = 0; i < DRM_NODE_MAX; i++) { devp->nodes[i] = pptr; pptr += max_node_length; } ++ snprintf(devp->nodes[DRM_NODE_PRIMARY], max_node_length, "%s", pnode); ++ ++ devp->businfo.pci = (drmPciBusInfoPtr)pptr; ++ pptr += sizeof(drmPciBusInfo); ++ devp->businfo.pci->domain = pdomain; ++ devp->businfo.pci->bus = pbus; ++ devp->businfo.pci->dev = pdev; ++ devp->businfo.pci->func = pfunc; ++ ++ devp->deviceinfo.pci = (drmPciDeviceInfoPtr)pptr; ++ devp->deviceinfo.pci->vendor_id = pvendor_id; ++ devp->deviceinfo.pci->device_id = pdevice_id; ++ devp->deviceinfo.pci->subvendor_id = psubvendor_id; ++ devp->deviceinfo.pci->subdevice_id = psubdevice_id; ++ devp->deviceinfo.pci->revision_id = prevision_id; ++ ++ *device = devp; ++ return 0; ++#else + struct stat sbuf; + + if (fd == -1) +@@ -4773,6 +5365,7 @@ drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) + return -EINVAL; + + return drmGetDeviceFromDevId(sbuf.st_rdev, flags, device); ++#endif + } + + /** diff --git a/local/patches/libdrm/03-drm-get-pci-info.patch b/local/patches/libdrm/03-drm-get-pci-info.patch deleted file mode 100644 index 87945d07b1..0000000000 --- a/local/patches/libdrm/03-drm-get-pci-info.patch +++ /dev/null @@ -1,153 +0,0 @@ ---- a/xf86drm.c -+++ b/xf86drm.c -@@ -115,7 +115,7 @@ - #define DRM_MAJOR 226 /* Linux */ - #endif - --#if defined(__OpenBSD__) || defined(__DragonFly__) -+#if defined(__OpenBSD__) || defined(__DragonFly__) || defined(__redox__) - struct drm_pciinfo { - uint16_t domain; - uint8_t bus; -@@ -858,6 +858,9 @@ - return REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD; - case 0x2C: - return REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE; -+ /* DRM_IOCTL_GET_PCIINFO — PCI device information for driver discovery */ -+ case 0x15: -+ return REDOX_DRM_IOCTL_GET_PCI_INFO; - default: - return 0; - } -@@ -4201,6 +4204,21 @@ - return 0; - #elif defined(__FreeBSD__) - return get_sysctl_pci_bus_info(maj, min, info); -+#elif defined(__redox__) -+ int rfd = open("/scheme/drm/card0", O_RDONLY); -+ if (rfd < 0) -+ return -errno; -+ uint8_t buf[22]; -+ size_t rsize = 0; -+ int ret = redox_drm_exchange(rfd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, buf, sizeof(buf), &rsize); -+ close(rfd); -+ if (ret != 0 || rsize < 17) -+ return -EIO; -+ info->domain = buf[10] | (buf[11] << 8) | (buf[12] << 16) | (buf[13] << 24); -+ info->bus = buf[14]; -+ info->dev = buf[15]; -+ info->func = buf[16]; -+ return 0; - #else - #warning "Missing implementation of drmParsePciBusInfo" - return -EINVAL; -@@ -4410,6 +4428,23 @@ - device->revision_id = results[0].pc_revid; - - return 0; -+#elif defined(__redox__) -+ int rfd2 = open("/scheme/drm/card0", O_RDONLY); -+ if (rfd2 < 0) -+ return -errno; -+ uint8_t dbuf[22]; -+ size_t drsize = 0; -+ int dret = redox_drm_exchange(rfd2, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, dbuf, sizeof(dbuf), &drsize); -+ close(rfd2); -+ if (dret != 0 || drsize < 9) -+ return -EIO; -+ device->vendor_id = dbuf[0] | (dbuf[1] << 8); -+ device->device_id = dbuf[2] | (dbuf[3] << 8); -+ device->subvendor_id = dbuf[4] | (dbuf[5] << 8); -+ device->subdevice_id = dbuf[6] | (dbuf[7] << 8); -+ if (drsize >= 9) -+ device->revision_id = dbuf[8]; -+ return 0; - #else - #warning "Missing implementation of drmParsePciDeviceInfo" - return -EINVAL; -@@ -5162,6 +5197,66 @@ - */ - drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) - { -+#if defined(__redox__) -+ uint8_t pbuf[22]; -+ size_t prsize = 0; -+ int pret; -+ uint16_t pvendor_id, pdevice_id, psubvendor_id, psubdevice_id, pdomain; -+ uint8_t prevision_id, pbus, pdev, pfunc; -+ const char *pnode; -+ int max_node_length, i; -+ size_t extra, psize; -+ drmDevicePtr devp; -+ char *pptr; -+ -+ pret = redox_drm_exchange(fd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, -+ pbuf, sizeof(pbuf), &prsize); -+ if (pret != 0 || prsize < 17) -+ return -EIO; -+ -+ pvendor_id = pbuf[0] | (pbuf[1] << 8); -+ pdevice_id = pbuf[2] | (pbuf[3] << 8); -+ psubvendor_id = pbuf[4] | (pbuf[5] << 8); -+ psubdevice_id = pbuf[6] | (pbuf[7] << 8); -+ prevision_id = pbuf[8]; -+ pdomain = pbuf[10] | (pbuf[11] << 8) | (pbuf[12] << 16) | (pbuf[13] << 24); -+ pbus = pbuf[14]; -+ pdev = pbuf[15]; -+ pfunc = pbuf[16]; -+ -+ pnode = "/scheme/drm/card0"; -+ max_node_length = 64; -+ extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length); -+ psize = sizeof(drmDevice) + extra + sizeof(drmPciBusInfo) + sizeof(drmPciDeviceInfo); -+ devp = calloc(1, psize); -+ if (!devp) -+ return -ENOMEM; -+ -+ devp->bustype = DRM_BUS_PCI; -+ devp->available_nodes = 1 << DRM_NODE_PRIMARY; -+ pptr = (char *)devp + sizeof(drmDevice); -+ devp->nodes = (char **)pptr; -+ pptr += DRM_NODE_MAX * sizeof(void *); -+ for (i = 0; i < DRM_NODE_MAX; i++) { devp->nodes[i] = pptr; pptr += max_node_length; } -+ snprintf(devp->nodes[DRM_NODE_PRIMARY], max_node_length, "%s", pnode); -+ -+ devp->businfo.pci = (drmPciBusInfoPtr)pptr; -+ pptr += sizeof(drmPciBusInfo); -+ devp->businfo.pci->domain = pdomain; -+ devp->businfo.pci->bus = pbus; -+ devp->businfo.pci->dev = pdev; -+ devp->businfo.pci->func = pfunc; -+ -+ devp->deviceinfo.pci = (drmPciDeviceInfoPtr)pptr; -+ devp->deviceinfo.pci->vendor_id = pvendor_id; -+ devp->deviceinfo.pci->device_id = pdevice_id; -+ devp->deviceinfo.pci->subvendor_id = psubvendor_id; -+ devp->deviceinfo.pci->subdevice_id = psubdevice_id; -+ devp->deviceinfo.pci->revision_id = prevision_id; -+ -+ *device = devp; -+ return 0; -+#else - struct stat sbuf; - - if (fd == -1) -@@ -5174,6 +5269,7 @@ - return -EINVAL; - - return drmGetDeviceFromDevId(sbuf.st_rdev, flags, device); -+#endif - } - - /** ---- a/xf86drm_redox.h -+++ b/xf86drm_redox.h -@@ -40,6 +40,8 @@ - #define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB (REDOX_DRM_IOCTL_BASE + 40) - #define REDOX_DRM_IOCTL_VIRTGPU_CONTEXT_INIT (REDOX_DRM_IOCTL_BASE + 41) - -+#define REDOX_DRM_IOCTL_GET_PCI_INFO (REDOX_DRM_IOCTL_BASE + 0x60) -+ - struct redox_drm_resources_wire { - uint32_t connector_count; - uint32_t crtc_count; diff --git a/local/patches/libdrm/04-drm-get-version-driver-name.patch b/local/patches/libdrm/04-drm-get-version-driver-name.patch deleted file mode 100644 index 83439c6e38..0000000000 --- a/local/patches/libdrm/04-drm-get-version-driver-name.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/xf86drm.c b/xf86drm.c -index 1b206ccd4..c3904caa3 100644 ---- a/xf86drm.c -+++ b/xf86drm.c -@@ -1774,0 +1775,23 @@ drm_public drmVersionPtr drmGetVersion(int fd) -+ -+ /* The scheme returns a NUL-terminated driver name in version.name. -+ * KWin drm_gpu.cpp dereferences version->name unconditionally -+ * (strstr checks for "i915", "amdgpu", "virtio" etc.) so it must -+ * never be NULL. -+ */ -+ version.name[sizeof(version.name) - 1] = '\0'; -+ if (version.name[0] != '\0') { -+ size_t len = strlen(version.name); -+ retval->name = drmMalloc(len + 1); -+ if (retval->name) { -+ memcpy(retval->name, version.name, len + 1); -+ retval->name_len = len; -+ } -+ } else { -+ const char fallback[] = "redox-drm"; -+ retval->name = drmMalloc(sizeof(fallback)); -+ if (retval->name) { -+ memcpy(retval->name, fallback, sizeof(fallback)); -+ retval->name_len = sizeof(fallback) - 1; -+ } -+ } -+ -diff --git a/xf86drm_redox.h b/xf86drm_redox.h -index c1abe8256..7f9d252fa 100644 ---- a/xf86drm_redox.h -+++ b/xf86drm_redox.h -@@ -140,0 +141 @@ struct redox_drm_version_wire { -+ char name[64]; diff --git a/local/patches/libdrm/05-drmGetDeviceFromDevId-redox.patch b/local/patches/libdrm/05-drmGetDeviceFromDevId-redox.patch deleted file mode 100644 index 3a6c8cc80f..0000000000 --- a/local/patches/libdrm/05-drmGetDeviceFromDevId-redox.patch +++ /dev/null @@ -1,68 +0,0 @@ -diff --git a/xf86drm.c b/xf86drm.c -index c3904caa3..306026e8b 100644 ---- a/xf86drm.c -+++ b/xf86drm.c -@@ -4096 +4096 @@ static int drmParseSubsystemType(int maj, int min) --#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) -+#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__redox__) -@@ -5122,0 +5123,60 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP -+ return 0; -+#elif defined(__redox__) -+ /* On Redox there is no /dev/dri/ directory to enumerate. -+ * Instead, open /scheme/drm/card0 and query PCI info to -+ * construct a single drmDevice that serves as both primary -+ * and render node. */ -+ drmDevicePtr devp; -+ char *pptr; -+ int max_node_length = 64, i; -+ size_t extra, psize; -+ uint8_t pbuf[22]; -+ size_t prsize = 0; -+ int pret, fd; -+ -+ if (device == NULL) -+ return -EINVAL; -+ if (drm_device_validate_flags(flags)) -+ return -EINVAL; -+ -+ fd = open("/scheme/drm/card0", O_RDWR | O_CLOEXEC); -+ if (fd < 0) -+ return -errno; -+ -+ pret = redox_drm_exchange(fd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, -+ pbuf, sizeof(pbuf), &prsize); -+ close(fd); -+ if (pret != 0 || prsize < 17) -+ return -EIO; -+ -+ extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length); -+ psize = sizeof(drmDevice) + extra + sizeof(drmPciBusInfo) + sizeof(drmPciDeviceInfo); -+ devp = calloc(1, psize); -+ if (!devp) -+ return -ENOMEM; -+ -+ devp->bustype = DRM_BUS_PCI; -+ /* Advertise both PRIMARY and RENDER — same path on Redox */ -+ devp->available_nodes = (1 << DRM_NODE_PRIMARY) | (1 << DRM_NODE_RENDER); -+ pptr = (char *)devp + sizeof(drmDevice); -+ devp->nodes = (char **)pptr; -+ pptr += DRM_NODE_MAX * sizeof(void *); -+ for (i = 0; i < DRM_NODE_MAX; i++) { devp->nodes[i] = pptr; pptr += max_node_length; } -+ snprintf(devp->nodes[DRM_NODE_PRIMARY], max_node_length, "/scheme/drm/card0"); -+ snprintf(devp->nodes[DRM_NODE_RENDER], max_node_length, "/scheme/drm/card0"); -+ -+ devp->businfo.pci = (drmPciBusInfoPtr)pptr; -+ pptr += sizeof(drmPciBusInfo); -+ devp->businfo.pci->domain = pbuf[10] | (pbuf[11] << 8) | (pbuf[12] << 16) | (pbuf[13] << 24); -+ devp->businfo.pci->bus = pbuf[14]; -+ devp->businfo.pci->dev = pbuf[15]; -+ devp->businfo.pci->func = pbuf[16]; -+ -+ devp->deviceinfo.pci = (drmPciDeviceInfoPtr)pptr; -+ devp->deviceinfo.pci->vendor_id = pbuf[0] | (pbuf[1] << 8); -+ devp->deviceinfo.pci->device_id = pbuf[2] | (pbuf[3] << 8); -+ devp->deviceinfo.pci->subvendor_id = pbuf[4] | (pbuf[5] << 8); -+ devp->deviceinfo.pci->subdevice_id = pbuf[6] | (pbuf[7] << 8); -+ devp->deviceinfo.pci->revision_id = pbuf[8]; -+ -+ *device = devp; diff --git a/local/patches/mesa/04-sys-ioccom-stub-header.patch b/local/patches/mesa/04-sys-ioccom-stub-header.patch new file mode 100644 index 0000000000..d8479404f3 --- /dev/null +++ b/local/patches/mesa/04-sys-ioccom-stub-header.patch @@ -0,0 +1,82 @@ +From f69c8e8cb4feb81b3923d869a2f529b2b4d58c1c Mon Sep 17 00:00:00 2001 +From: Red Bear OS +Date: Thu, 11 Jun 2026 02:07:44 +0300 +Subject: [PATCH] add sys/ioccom.h for DRM UAPI ioctl encoding + +--- + include/sys/ioccom.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 63 insertions(+) + create mode 100644 include/sys/ioccom.h + +diff --git a/include/sys/ioccom.h b/include/sys/ioccom.h +new file mode 100644 +index 0000000..4722557 +--- /dev/null ++++ b/include/sys/ioccom.h +@@ -0,0 +1,63 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * Linux UAPI asm-generic/ioctl.h — ioctl command encoding macros. ++ * Required by DRM UAPI headers (drm-uapi/drm.h, drm-uapi/sync_file.h) ++ * which include for _IO/_IOR/_IOW/_IOWR. ++ * ++ * On glibc/musl this is provided by the libc. On Redox (relibc) it ++ * is not, because ioctl direction encoding is a Linux UAPI convention ++ * rather than a POSIX requirement. ++ * ++ * This header is a pure compile-time macro encoding; the values never ++ * reach a real ioctl(2) syscall on Redox. The DRM dispatch surface ++ * (libdrm's drmIoctl -> scheme:drm/SchemeSync in ++ * local/sources/redox-drm/) is the runtime source of truth, and it ++ * uses different encoding internally. ++ */ ++#ifndef _SYS_IOCCOM_H ++#define _SYS_IOCCOM_H ++ ++#define _IOC_NRBITS 8 ++#define _IOC_TYPEBITS 8 ++#define _IOC_SIZEBITS 14 ++#define _IOC_DIRBITS 2 ++ ++#define _IOC_NRMASK ((1 << _IOC_NRBITS) - 1) ++#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS) - 1) ++#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS) - 1) ++#define _IOC_DIRMASK ((1 << _IOC_DIRBITS) - 1) ++ ++#define _IOC_NRSHIFT 0 ++#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS) ++#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS) ++#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS) ++ ++#define _IOC_NONE 0U ++#define _IOC_WRITE 1U ++#define _IOC_READ 2U ++ ++#define _IOC(dir, type, nr, size) \ ++ (((dir) << _IOC_DIRSHIFT) | \ ++ ((type) << _IOC_TYPESHIFT) | \ ++ ((nr) << _IOC_NRSHIFT) | \ ++ ((size) << _IOC_SIZESHIFT)) ++ ++#define _IOC_TYPECHECK(t) (sizeof(t)) ++ ++#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0) ++#define _IOR(type, nr, argtype) _IOC(_IOC_READ, (type), (nr), (_IOC_TYPECHECK(argtype))) ++#define _IOW(type, nr, argtype) _IOC(_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(argtype))) ++#define _IOWR(type, nr, argtype) _IOC(_IOC_READ | _IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(argtype))) ++ ++#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) ++#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) ++#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) ++#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) ++ ++#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) ++#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) ++#define IOC_INOUT ((_IOC_WRITE | _IOC_READ) << _IOC_DIRSHIFT) ++#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) ++#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) ++ ++#endif /* _SYS_IOCCOM_H */ +-- +2.54.0 + diff --git a/local/patches/mesa/05-vk-sync-wchar-include.patch b/local/patches/mesa/05-vk-sync-wchar-include.patch new file mode 100644 index 0000000000..52b769d8d5 --- /dev/null +++ b/local/patches/mesa/05-vk-sync-wchar-include.patch @@ -0,0 +1,34 @@ +From 169f895ebdc63799d2230e0d01b57ea8fdb8b6ca Mon Sep 17 00:00:00 2001 +From: Red Bear OS +Date: Thu, 11 Jun 2026 02:14:44 +0300 +Subject: [PATCH] vk_sync.h: include for wchar_t type + +vk_sync.h uses wchar_t in function pointer types (import_win32_handle, +export_win32_handle, set_win32_export_params) but does not include +. Under glibc, wchar_t is transitively pulled in via +. Under relibc, it is not, so mesa 24.0 fails +to compile vk_sync.c, vk_sync_binary.c, vk_sync_dummy.c with: + + src/vulkan/runtime/vk_sync.h:285:42: error: unknown type name wchar_t + +Add an explicit include so the type is always available +regardless of the transitive header chain. +--- + src/vulkan/runtime/vk_sync.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/vulkan/runtime/vk_sync.h b/src/vulkan/runtime/vk_sync.h +index 15d85dc..39d9f34 100644 +--- a/src/vulkan/runtime/vk_sync.h ++++ b/src/vulkan/runtime/vk_sync.h +@@ -24,6 +24,7 @@ + #define VK_SYNC_H + + #include ++#include + #include + + #include "util/macros.h" +-- +2.54.0 + diff --git a/local/recipes/libs/libdrm/recipe.toml b/local/recipes/libs/libdrm/recipe.toml index 19931220e6..ac61c93601 100644 --- a/local/recipes/libs/libdrm/recipe.toml +++ b/local/recipes/libs/libdrm/recipe.toml @@ -71,7 +71,7 @@ dependencies = [ "libpciaccess", "meson", "ninja-build", - "pkgconf", + "pkg-config", ] script = """ DYNAMIC_INIT @@ -80,9 +80,9 @@ DYNAMIC_INIT # cookbook_apply_patches handles the "already applied" check, the # `cd "${COOKBOOK_SOURCE}"` dance, and the "return to build dir" # so this stays a single line. Recipe is at local/recipes/libs/libdrm/ -# (depth 3), so 4 dots reach the project root, then /local/patches/libdrm -# is appended. -REDBEAR_PATCHES_DIR="${REDBEAR_PATCHES_DIR:-$(cd "$(dirname "${COOKBOOK_RECIPE}")/../../../.." && pwd)}/local/patches/libdrm" +# (depth 4: local, recipes, libs, libdrm), so 4 dots reach the project root, +# then /local/patches/libdrm is appended. +REDBEAR_PATCHES_DIR="${REDBEAR_PATCHES_DIR:-$(cd "${COOKBOOK_RECIPE}/../../../.." && pwd)}/local/patches/libdrm" cookbook_apply_patches "${REDBEAR_PATCHES_DIR}" cookbook_meson \\