Skip to content

Instantly share code, notes, and snippets.

@max1220
Created February 26, 2024 23:19
Show Gist options
  • Save max1220/3e2774bfe568fa78c1ef23a79b545e98 to your computer and use it in GitHub Desktop.
Save max1220/3e2774bfe568fa78c1ef23a79b545e98 to your computer and use it in GitHub Desktop.
Basic LuaJIT FFI cdefs for using libdrm.
local ffi = require("ffi")
ffi.cdef([[
typedef unsigned int mode_t;
typedef unsigned int pid_t;
typedef unsigned int uid_t;
typedef unsigned int gid_t;
typedef unsigned int id_t;
typedef unsigned int dev_t;
/* from Linux/include/uapi/drm/drm.h */
typedef unsigned int drm_handle_t;
typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
typedef enum {
DRM_DRAWABLE_CLIPRECTS
} drm_drawable_info_type_t;
/* from libdrm/xf86drm.h */
typedef unsigned int drmSize, *drmSizePtr; /**< For mapped regions */
typedef void *drmAddress, **drmAddressPtr; /**< For mapped regions */
typedef enum {
DRM_FRAME_BUFFER = 0, /**< WC, no caching, no core dump */
DRM_REGISTERS = 1, /**< no caching, no core dump */
DRM_SHM = 2, /**< shared, cached */
DRM_AGP = 3, /**< AGP/GART */
DRM_SCATTER_GATHER = 4, /**< PCI scatter/gather */
DRM_CONSISTENT = 5 /**< PCI consistent */
} drmMapType;
typedef enum {
DRM_RESTRICTED = 0x0001, /**< Cannot be mapped to client-virtual */
DRM_READ_ONLY = 0x0002, /**< Read-only in client-virtual */
DRM_LOCKED = 0x0004, /**< Physical pages locked */
DRM_KERNEL = 0x0008, /**< Kernel requires access */
DRM_WRITE_COMBINING = 0x0010, /**< Use write-combining, if available */
DRM_CONTAINS_LOCK = 0x0020, /**< SHM page that contains lock */
DRM_REMOVABLE = 0x0040 /**< Removable mapping */
} drmMapFlags;
typedef struct _drmVersion {
int version_major; /**< Major version */
int version_minor; /**< Minor version */
int version_patchlevel; /**< Patch level */
int name_len; /**< Length of name buffer */
char *name; /**< Name of driver */
int date_len; /**< Length of date buffer */
char *date; /**< User-space buffer to hold date */
int desc_len; /**< Length of desc buffer */
char *desc; /**< User-space buffer to hold desc */
} drmVersion, *drmVersionPtr;
typedef struct _drmSetVersion {
int drm_di_major;
int drm_di_minor;
int drm_dd_major;
int drm_dd_minor;
} drmSetVersion, *drmSetVersionPtr;
typedef struct _drmStats {
unsigned long count; /**< Number of data */
struct {
unsigned long value; /**< Value from kernel */
const char *long_format; /**< Suggested format for long_name */
const char *long_name; /**< Long name for value */
const char *rate_format; /**< Suggested format for rate_name */
const char *rate_name; /**< Short name for value per second */
int isvalue; /**< True if value (vs. counter) */
const char *mult_names; /**< Multiplier names (e.g., "KGM") */
int mult; /**< Multiplier value (e.g., 1024) */
int verbose; /**< Suggest only in verbose output */
} data[15];
} drmStatsT;
typedef enum {
DRM_CONTEXT_PRESERVED = 0x01, /**< This context is preserved and
never swapped. */
DRM_CONTEXT_2DONLY = 0x02 /**< This context is for 2D rendering only. */
} drm_context_tFlags, *drm_context_tFlagsPtr;
typedef struct _drmBufDesc {
int count; /**< Number of buffers of this size */
int size; /**< Size in bytes */
int low_mark; /**< Low water mark */
int high_mark; /**< High water mark */
} drmBufDesc, *drmBufDescPtr;
typedef struct _drmBuf {
int idx; /**< Index into the master buffer list */
int total; /**< Buffer size */
int used; /**< Amount of buffer in use (for DMA) */
drmAddress address; /**< Address */
} drmBuf, *drmBufPtr;
typedef struct _drmBufMap {
int count; /**< Number of buffers mapped */
drmBufPtr list; /**< Buffers */
} drmBufMap, *drmBufMapPtr;
typedef struct _drmBufInfo {
int count; /**< Number of buffers described in list */
drmBufDescPtr list; /**< List of buffer descriptions */
} drmBufInfo, *drmBufInfoPtr;
typedef enum {
/** \name Flags for DMA buffer dispatch */
/*@{*/
DRM_DMA_BLOCK = 0x01, /**<
* Block until buffer dispatched.
*
* \note the buffer may not yet have been
* processed by the hardware -- getting a
* hardware lock with the hardware quiescent
* will ensure that the buffer has been
* processed.
*/
DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
/*@}*/
/** \name Flags for DMA buffer request */
/*@{*/
DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
/*@}*/
} drmDMAFlags;
typedef struct _drmDMAReq {
drm_context_t context; /**< Context handle */
int send_count; /**< Number of buffers to send */
int *send_list; /**< List of handles to buffers */
int *send_sizes; /**< Lengths of data to send, in bytes */
drmDMAFlags flags; /**< Flags */
int request_count; /**< Number of buffers requested */
int request_size; /**< Desired size of buffers requested */
int *request_list; /**< Buffer information */
int *request_sizes; /**< Minimum acceptable sizes */
int granted_count; /**< Number of buffers granted at this size */
} drmDMAReq, *drmDMAReqPtr;
typedef enum {
DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
/* These *HALT* flags aren't supported yet
-- they will be used to support the
full-screen DGA-like mode. */
DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
} drmLockFlags;
typedef enum {
DRM_PAGE_ALIGN = 0x01,
DRM_AGP_BUFFER = 0x02,
DRM_SG_BUFFER = 0x04,
DRM_FB_BUFFER = 0x08,
DRM_PCI_BUFFER_RO = 0x10
} drmBufDescFlags;
typedef enum {
DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
/* bits 1-6 are reserved for high crtcs */
DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e,
DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */
DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
} drmVBlankSeqType;
typedef struct _drmVBlankReq {
drmVBlankSeqType type;
unsigned int sequence;
unsigned long signal;
} drmVBlankReq, *drmVBlankReqPtr;
typedef struct _drmVBlankReply {
drmVBlankSeqType type;
unsigned int sequence;
long tval_sec;
long tval_usec;
} drmVBlankReply, *drmVBlankReplyPtr;
typedef union _drmVBlank {
drmVBlankReq request;
drmVBlankReply reply;
} drmVBlank, *drmVBlankPtr;
typedef struct _drmServerInfo {
int (*debug_print)(const char *format, va_list ap);
int (*load_module)(const char *name);
void (*get_perms)(gid_t *, mode_t *);
} drmServerInfo, *drmServerInfoPtr;
typedef struct drmHashEntry {
int fd;
void (*f)(int, void *, void *);
void *tagTable;
} drmHashEntry;
typedef struct _drmEventContext {
/* This struct is versioned so we can add more pointers if we
* add more events. */
int version;
void (*vblank_handler)(int fd,
unsigned int sequence,
unsigned int tv_sec,
unsigned int tv_usec,
void *user_data);
void (*page_flip_handler)(int fd,
unsigned int sequence,
unsigned int tv_sec,
unsigned int tv_usec,
void *user_data);
void (*page_flip_handler2)(int fd,
unsigned int sequence,
unsigned int tv_sec,
unsigned int tv_usec,
unsigned int crtc_id,
void *user_data);
void (*sequence_handler)(int fd,
uint64_t sequence,
uint64_t ns,
uint64_t user_data);
} drmEventContext, *drmEventContextPtr;
typedef struct _drmPciBusInfo {
uint16_t domain;
uint8_t bus;
uint8_t dev;
uint8_t func;
} drmPciBusInfo, *drmPciBusInfoPtr;
typedef struct _drmPciDeviceInfo {
uint16_t vendor_id;
uint16_t device_id;
uint16_t subvendor_id;
uint16_t subdevice_id;
uint8_t revision_id;
} drmPciDeviceInfo, *drmPciDeviceInfoPtr;
typedef struct _drmUsbBusInfo {
uint8_t bus;
uint8_t dev;
} drmUsbBusInfo, *drmUsbBusInfoPtr;
typedef struct _drmUsbDeviceInfo {
uint16_t vendor;
uint16_t product;
} drmUsbDeviceInfo, *drmUsbDeviceInfoPtr;
typedef struct _drmPlatformBusInfo {
char fullname[512];
} drmPlatformBusInfo, *drmPlatformBusInfoPtr;
typedef struct _drmPlatformDeviceInfo {
char **compatible; /* NULL terminated list of compatible strings */
} drmPlatformDeviceInfo, *drmPlatformDeviceInfoPtr;
typedef struct _drmHost1xBusInfo {
char fullname[512];
} drmHost1xBusInfo, *drmHost1xBusInfoPtr;
typedef struct _drmHost1xDeviceInfo {
char **compatible; /* NULL terminated list of compatible strings */
} drmHost1xDeviceInfo, *drmHost1xDeviceInfoPtr;
typedef struct _drmDevice {
char **nodes; /* DRM_NODE_MAX sized array */
int available_nodes; /* DRM_NODE_* bitmask */
int bustype;
union {
drmPciBusInfoPtr pci;
drmUsbBusInfoPtr usb;
drmPlatformBusInfoPtr platform;
drmHost1xBusInfoPtr host1x;
} businfo;
union {
drmPciDeviceInfoPtr pci;
drmUsbDeviceInfoPtr usb;
drmPlatformDeviceInfoPtr platform;
drmHost1xDeviceInfoPtr host1x;
} deviceinfo;
} drmDevice, *drmDevicePtr;
/* General user-level programmer's API: unprivileged */
extern int drmAvailable(void);
extern int drmOpen(const char *name, const char *busid);
extern int drmOpenWithType(const char *name, const char *busid,
int type);
extern int drmOpenControl(int minor); /* deprecated: always fails */
extern int drmOpenRender(int minor);
extern int drmClose(int fd);
extern drmVersionPtr drmGetVersion(int fd);
extern drmVersionPtr drmGetLibVersion(int fd);
extern int drmGetCap(int fd, uint64_t capability, uint64_t *value);
extern void drmFreeVersion(drmVersionPtr);
extern int drmGetMagic(int fd, drm_magic_t * magic);
extern char *drmGetBusid(int fd);
extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum,
int funcnum);
extern int drmGetMap(int fd, int idx, drm_handle_t *offset,
drmSize *size, drmMapType *type,
drmMapFlags *flags, drm_handle_t *handle,
int *mtrr);
extern int drmGetClient(int fd, int idx, int *auth, int *pid,
int *uid, unsigned long *magic,
unsigned long *iocs);
extern int drmGetStats(int fd, drmStatsT *stats);
extern int drmSetInterfaceVersion(int fd, drmSetVersion *version);
extern int drmCommandNone(int fd, unsigned long drmCommandIndex);
extern int drmCommandRead(int fd, unsigned long drmCommandIndex,
void *data, unsigned long size);
extern int drmCommandWrite(int fd, unsigned long drmCommandIndex,
void *data, unsigned long size);
extern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex,
void *data, unsigned long size);
/* General user-level programmer's API: X server (root) only */
extern void drmFreeBusid(const char *busid);
extern int drmSetBusid(int fd, const char *busid);
extern int drmAuthMagic(int fd, drm_magic_t magic);
extern int drmAddMap(int fd,
drm_handle_t offset,
drmSize size,
drmMapType type,
drmMapFlags flags,
drm_handle_t * handle);
extern int drmRmMap(int fd, drm_handle_t handle);
extern int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
drm_handle_t handle);
extern int drmAddBufs(int fd, int count, int size,
drmBufDescFlags flags,
int agp_offset);
extern int drmMarkBufs(int fd, double low, double high);
extern int drmCreateContext(int fd, drm_context_t * handle);
extern int drmSetContextFlags(int fd, drm_context_t context,
drm_context_tFlags flags);
extern int drmGetContextFlags(int fd, drm_context_t context,
drm_context_tFlagsPtr flags);
extern int drmAddContextTag(int fd, drm_context_t context, void *tag);
extern int drmDelContextTag(int fd, drm_context_t context);
extern void *drmGetContextTag(int fd, drm_context_t context);
extern drm_context_t * drmGetReservedContextList(int fd, int *count);
extern void drmFreeReservedContextList(drm_context_t *);
extern int drmSwitchToContext(int fd, drm_context_t context);
extern int drmDestroyContext(int fd, drm_context_t handle);
extern int drmCreateDrawable(int fd, drm_drawable_t * handle);
extern int drmDestroyDrawable(int fd, drm_drawable_t handle);
extern int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
drm_drawable_info_type_t type,
unsigned int num, void *data);
extern int drmCtlInstHandler(int fd, int irq);
extern int drmCtlUninstHandler(int fd);
extern int drmSetClientCap(int fd, uint64_t capability,
uint64_t value);
extern int drmCrtcGetSequence(int fd, uint32_t crtcId,
uint64_t *sequence, uint64_t *ns);
extern int drmCrtcQueueSequence(int fd, uint32_t crtcId,
uint32_t flags, uint64_t sequence,
uint64_t *sequence_queued,
uint64_t user_data);
/* General user-level programmer's API: authenticated client and/or X */
extern int drmMap(int fd,
drm_handle_t handle,
drmSize size,
drmAddressPtr address);
extern int drmUnmap(drmAddress address, drmSize size);
extern drmBufInfoPtr drmGetBufInfo(int fd);
extern drmBufMapPtr drmMapBufs(int fd);
extern int drmUnmapBufs(drmBufMapPtr bufs);
extern int drmDMA(int fd, drmDMAReqPtr request);
extern int drmFreeBufs(int fd, int count, int *list);
extern int drmGetLock(int fd,
drm_context_t context,
drmLockFlags flags);
extern int drmUnlock(int fd, drm_context_t context);
extern int drmFinish(int fd, int context, drmLockFlags flags);
extern int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
drm_handle_t * handle);
/* AGP/GART support: X server (root) only */
extern int drmAgpAcquire(int fd);
extern int drmAgpRelease(int fd);
extern int drmAgpEnable(int fd, unsigned long mode);
extern int drmAgpAlloc(int fd, unsigned long size,
unsigned long type, unsigned long *address,
drm_handle_t *handle);
extern int drmAgpFree(int fd, drm_handle_t handle);
extern int drmAgpBind(int fd, drm_handle_t handle,
unsigned long offset);
extern int drmAgpUnbind(int fd, drm_handle_t handle);
/* AGP/GART info: authenticated client and/or X */
extern int drmAgpVersionMajor(int fd);
extern int drmAgpVersionMinor(int fd);
extern unsigned long drmAgpGetMode(int fd);
extern unsigned long drmAgpBase(int fd); /* Physical location */
extern unsigned long drmAgpSize(int fd); /* Bytes */
extern unsigned long drmAgpMemoryUsed(int fd);
extern unsigned long drmAgpMemoryAvail(int fd);
extern unsigned int drmAgpVendorId(int fd);
extern unsigned int drmAgpDeviceId(int fd);
/* PCI scatter/gather support: X server (root) only */
extern int drmScatterGatherAlloc(int fd, unsigned long size,
drm_handle_t *handle);
extern int drmScatterGatherFree(int fd, drm_handle_t handle);
extern int drmWaitVBlank(int fd, drmVBlankPtr vbl);
/* Support routines */
extern void drmSetServerInfo(drmServerInfoPtr info);
extern int drmError(int err, const char *label);
extern void *drmMalloc(int size);
extern void drmFree(void *pt);
/* Hash table routines */
extern void *drmHashCreate(void);
extern int drmHashDestroy(void *t);
extern int drmHashLookup(void *t, unsigned long key, void **value);
extern int drmHashInsert(void *t, unsigned long key, void *value);
extern int drmHashDelete(void *t, unsigned long key);
extern int drmHashFirst(void *t, unsigned long *key, void **value);
extern int drmHashNext(void *t, unsigned long *key, void **value);
/* PRNG routines */
extern void *drmRandomCreate(unsigned long seed);
extern int drmRandomDestroy(void *state);
extern unsigned long drmRandom(void *state);
extern double drmRandomDouble(void *state);
/* Skip list routines */
extern void *drmSLCreate(void);
extern int drmSLDestroy(void *l);
extern int drmSLLookup(void *l, unsigned long key, void **value);
extern int drmSLInsert(void *l, unsigned long key, void *value);
extern int drmSLDelete(void *l, unsigned long key);
extern int drmSLNext(void *l, unsigned long *key, void **value);
extern int drmSLFirst(void *l, unsigned long *key, void **value);
extern void drmSLDump(void *l);
extern int drmSLLookupNeighbors(void *l, unsigned long key,
unsigned long *prev_key, void **prev_value,
unsigned long *next_key, void **next_value);
extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened);
extern int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type);
extern void drmCloseOnce(int fd);
extern void drmMsg(const char *format, ...);
extern int drmSetMaster(int fd);
extern int drmDropMaster(int fd);
extern int drmIsMaster(int fd);
extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
extern char *drmGetDeviceNameFromFd(int fd);
extern char *drmGetDeviceNameFromFd2(int fd);
extern int drmGetNodeTypeFromFd(int fd);
extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
extern int drmCloseBufferHandle(int fd, uint32_t handle);
extern char *drmGetPrimaryDeviceNameFromFd(int fd);
extern char *drmGetRenderDeviceNameFromFd(int fd);
extern int drmGetDevice(int fd, drmDevicePtr *device);
extern void drmFreeDevice(drmDevicePtr *device);
extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
extern void drmFreeDevices(drmDevicePtr devices[], int count);
extern int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device);
extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices);
extern int drmGetDeviceFromDevId(dev_t dev_id, uint32_t flags, drmDevicePtr *device);
/**
* Get the node type (DRM_NODE_PRIMARY or DRM_NODE_RENDER) from a device ID.
*
* Returns negative errno on error.
*/
extern int drmGetNodeTypeFromDevId(dev_t devid);
extern int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b);
extern int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle);
extern int drmSyncobjDestroy(int fd, uint32_t handle);
extern int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd);
extern int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle);
extern int drmSyncobjImportSyncFile(int fd, uint32_t handle, int sync_file_fd);
extern int drmSyncobjExportSyncFile(int fd, uint32_t handle, int *sync_file_fd);
extern int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles,
int64_t timeout_nsec, unsigned flags,
uint32_t *first_signaled);
extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t handle_count);
extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t handle_count);
extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
uint64_t *points, uint32_t handle_count);
extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
unsigned num_handles,
int64_t timeout_nsec, unsigned flags,
uint32_t *first_signaled);
extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
uint32_t handle_count);
extern int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
uint32_t handle_count, uint32_t flags);
extern int drmSyncobjTransfer(int fd,
uint32_t dst_handle, uint64_t dst_point,
uint32_t src_handle, uint64_t src_point,
uint32_t flags);
extern int drmSyncobjEventfd(int fd, uint32_t handle, uint64_t point, int ev_fd,
uint32_t flags);
extern char * drmGetFormatModifierVendor(uint64_t modifier);
extern char * drmGetFormatModifierName(uint64_t modifier);
extern char * drmGetFormatName(uint32_t format);
]])
_DRM_NODE_PRIMARY = 0
_DRM_NODE_RENDER = 2
_DRM_NODE_MAX = 3
_DRM_EVENT_CONTEXT_VERSION = 4
_DRM_VBLANK_HIGH_CRTC_SHIFT = 1
_DRM_BUS_PCI = 0
_DRM_BUS_USB = 1
_DRM_BUS_PLATFORM = 2
_DRM_BUS_HOST1X = 3
_DRM_PLATFORM_DEVICE_NAME_LEN = 512
_DRM_HOST1X_DEVICE_NAME_LEN = 512
_DRM_DEVICE_GET_PCI_REVISION = 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment