Smithay / drm-rs

A low-level abstraction of the Direct Rendering Manager API
MIT License
77 stars 51 forks source link

Automate binding updates + Use kernel rather than libdrm #165

Closed Slabity closed 10 months ago

Slabity commented 12 months ago

At the moment people have the option to use the use_bindgen feature to generate bindings from libdrm. This means that features get implemented in the kernel first, then into libdrm, then finally here once we manually update.

I'd like to know anyone's opinions on possibly generating these low-level bindings based on the upstream Linux kernel code automatically when new versions come out. This subsystem actually has all the proper #ifdefs to allow for BSD bindings to be generated as well, so I don't think that will be an issue.

All of the required header files are in include/uapi/drm, and that's just pulled directly into libdrm from what I can tell. This would just eliminate using libdrm as a middle-man for those files.

If nobody has any issues with this, I'll use the opportunity to see if we can generate bindings for all the other driver-specific APIs as well (see !105)

Drakulix commented 12 months ago

We currently pull the headers from the ubuntu-images in CI and automatically update them. Ubuntu however is obviously lacking behind libdrm most of the time. So adjusting the CI-script to pull the latest libdrm sources would already be an improvement.

That said generating the ioctl code directly from the kernel seems even better, as well as addressing #105 this way. I don't see any issues with that. :)

ids1024 commented 12 months ago

I wonder if the generic ioctl mechanism added to Rustix recently would be helpful: https://github.com/bytecodealliance/rustix/pull/788. The linux-raw-sys crate used by Rustix seems to have ioctl numbers. Though presumably something else would be needed on BSDs (and I'm not sure if that currently handles all Linux architectures, with different ioctl numbering).

ids1024 commented 11 months ago

It seems like the only differences between architectures here is a few typedefs. (A couple of which may just be differences in different versions and ultimately the same concrete types?)

Looking at https://gitlab.freedesktop.org/mesa/drm/-/blob/main/include/drm/drm.h:

#if   defined(__linux__)

#include <linux/types.h>
#include <asm/ioctl.h>
typedef unsigned int drm_handle_t;

#else /* One of the BSDs */

#include <stdint.h>
#include <sys/ioccom.h>
#include <sys/types.h>
typedef int8_t   __s8;
typedef uint8_t  __u8;
typedef int16_t  __s16;
typedef uint16_t __u16;
typedef int32_t  __s32;
typedef uint32_t __u32;
typedef int64_t  __s64;
typedef uint64_t __u64;
typedef size_t   __kernel_size_t;
typedef unsigned long drm_handle_t;

#endif

So it looks like the same header file is supposed to apply across operating systems and architectures. I guess it's the files like linux/types.h where any actually differences may be?