libdrm: migrate to external patches model (Rule 2) — replace old in-tree patches
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -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 <stddef.h>
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#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
|
||||
@@ -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 <stdint.h>
|
||||
+
|
||||
+#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
|
||||
@@ -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 <stdint.h>
|
||||
+
|
||||
+#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
|
||||
@@ -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;
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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;
|
||||
@@ -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];
|
||||
@@ -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;
|
||||
@@ -0,0 +1,82 @@
|
||||
From f69c8e8cb4feb81b3923d869a2f529b2b4d58c1c Mon Sep 17 00:00:00 2001
|
||||
From: Red Bear OS <vasilito@redbearos.org>
|
||||
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 <sys/ioccom.h> 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
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 169f895ebdc63799d2230e0d01b57ea8fdb8b6ca Mon Sep 17 00:00:00 2001
|
||||
From: Red Bear OS <vasilito@redbearos.org>
|
||||
Date: Thu, 11 Jun 2026 02:14:44 +0300
|
||||
Subject: [PATCH] vk_sync.h: include <wchar.h> 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
|
||||
<wchar.h>. Under glibc, wchar_t is transitively pulled in via
|
||||
<vulkan/vulkan_core.h>. 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 <wchar.h> 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 <stdbool.h>
|
||||
+#include <wchar.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@@ -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 \\
|
||||
|
||||
Reference in New Issue
Block a user