diff options
-rw-r--r-- | lib/libdrm/amdgpu/amdgpu_bo.c | 2 | ||||
-rw-r--r-- | lib/libdrm/generated/generated_static_table_fourcc.h | 3 | ||||
-rw-r--r-- | lib/libdrm/include/drm/drm.h | 263 | ||||
-rw-r--r-- | lib/libdrm/mk/libdrm/shlib_version | 2 | ||||
-rw-r--r-- | lib/libdrm/mk/libdrm_amdgpu/shlib_version | 2 | ||||
-rw-r--r-- | lib/libdrm/radeon/radeon_surface.c | 1 | ||||
-rw-r--r-- | lib/libdrm/xf86drm.c | 75 | ||||
-rw-r--r-- | lib/libdrm/xf86drm.h | 23 | ||||
-rw-r--r-- | lib/libdrm/xf86drmMode.c | 14 | ||||
-rw-r--r-- | lib/libdrm/xf86drmMode.h | 9 |
10 files changed, 333 insertions, 61 deletions
diff --git a/lib/libdrm/amdgpu/amdgpu_bo.c b/lib/libdrm/amdgpu/amdgpu_bo.c index f4e043525..672f000d6 100644 --- a/lib/libdrm/amdgpu/amdgpu_bo.c +++ b/lib/libdrm/amdgpu/amdgpu_bo.c @@ -551,7 +551,7 @@ drm_public int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev, if (!bo || !bo->cpu_ptr || size > bo->alloc_size) continue; if (cpu >= bo->cpu_ptr && - cpu < (void*)((uintptr_t)bo->cpu_ptr + bo->alloc_size)) + cpu < (void*)((uintptr_t)bo->cpu_ptr + (size_t)bo->alloc_size)) break; } diff --git a/lib/libdrm/generated/generated_static_table_fourcc.h b/lib/libdrm/generated/generated_static_table_fourcc.h index 7e795a8bc..468b84e20 100644 --- a/lib/libdrm/generated/generated_static_table_fourcc.h +++ b/lib/libdrm/generated/generated_static_table_fourcc.h @@ -15,6 +15,9 @@ static const struct drmFormatModifierInfo drm_format_modifier_table[] = { { DRM_MODIFIER_INTEL(4_TILED_DG2_RC_CCS, 4_TILED_DG2_RC_CCS) }, { DRM_MODIFIER_INTEL(4_TILED_DG2_MC_CCS, 4_TILED_DG2_MC_CCS) }, { DRM_MODIFIER_INTEL(4_TILED_DG2_RC_CCS_CC, 4_TILED_DG2_RC_CCS_CC) }, + { DRM_MODIFIER_INTEL(4_TILED_MTL_RC_CCS, 4_TILED_MTL_RC_CCS) }, + { DRM_MODIFIER_INTEL(4_TILED_MTL_MC_CCS, 4_TILED_MTL_MC_CCS) }, + { DRM_MODIFIER_INTEL(4_TILED_MTL_RC_CCS_CC, 4_TILED_MTL_RC_CCS_CC) }, { DRM_MODIFIER(SAMSUNG, 64_32_TILE, 64_32_TILE) }, { DRM_MODIFIER(SAMSUNG, 16_16_TILE, 16_16_TILE) }, { DRM_MODIFIER(QCOM, COMPRESSED, COMPRESSED) }, diff --git a/lib/libdrm/include/drm/drm.h b/lib/libdrm/include/drm/drm.h index 398c396f7..4e4f7c2c3 100644 --- a/lib/libdrm/include/drm/drm.h +++ b/lib/libdrm/include/drm/drm.h @@ -629,8 +629,8 @@ struct drm_gem_open { /** * DRM_CAP_VBLANK_HIGH_CRTC * - * If set to 1, the kernel supports specifying a CRTC index in the high bits of - * &drm_wait_vblank_request.type. + * If set to 1, the kernel supports specifying a :ref:`CRTC index<crtc_index>` + * in the high bits of &drm_wait_vblank_request.type. * * Starting kernel version 2.6.39, this capability is always set to 1. */ @@ -667,8 +667,11 @@ struct drm_gem_open { * Bitfield of supported PRIME sharing capabilities. See &DRM_PRIME_CAP_IMPORT * and &DRM_PRIME_CAP_EXPORT. * - * PRIME buffers are exposed as dma-buf file descriptors. See - * Documentation/gpu/drm-mm.rst, section "PRIME Buffer Sharing". + * Starting from kernel version 6.6, both &DRM_PRIME_CAP_IMPORT and + * &DRM_PRIME_CAP_EXPORT are always advertised. + * + * PRIME buffers are exposed as dma-buf file descriptors. + * See :ref:`prime_buffer_sharing`. */ #define DRM_CAP_PRIME 0x5 /** @@ -676,6 +679,8 @@ struct drm_gem_open { * * If this bit is set in &DRM_CAP_PRIME, the driver supports importing PRIME * buffers via the &DRM_IOCTL_PRIME_FD_TO_HANDLE ioctl. + * + * Starting from kernel version 6.6, this bit is always set in &DRM_CAP_PRIME. */ #define DRM_PRIME_CAP_IMPORT 0x1 /** @@ -683,6 +688,8 @@ struct drm_gem_open { * * If this bit is set in &DRM_CAP_PRIME, the driver supports exporting PRIME * buffers via the &DRM_IOCTL_PRIME_HANDLE_TO_FD ioctl. + * + * Starting from kernel version 6.6, this bit is always set in &DRM_CAP_PRIME. */ #define DRM_PRIME_CAP_EXPORT 0x2 /** @@ -700,7 +707,8 @@ struct drm_gem_open { /** * DRM_CAP_ASYNC_PAGE_FLIP * - * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC. + * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for legacy + * page-flips. */ #define DRM_CAP_ASYNC_PAGE_FLIP 0x7 /** @@ -750,17 +758,23 @@ struct drm_gem_open { /** * DRM_CAP_SYNCOBJ * - * If set to 1, the driver supports sync objects. See - * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". + * If set to 1, the driver supports sync objects. See :ref:`drm_sync_objects`. */ #define DRM_CAP_SYNCOBJ 0x13 /** * DRM_CAP_SYNCOBJ_TIMELINE * * If set to 1, the driver supports timeline operations on sync objects. See - * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". + * :ref:`drm_sync_objects`. */ #define DRM_CAP_SYNCOBJ_TIMELINE 0x14 +/** + * DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP + * + * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for atomic + * commits. + */ +#define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15 /* DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap { @@ -830,6 +844,31 @@ struct drm_get_cap { */ #define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5 +/** + * DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT + * + * Drivers for para-virtualized hardware (e.g. vmwgfx, qxl, virtio and + * virtualbox) have additional restrictions for cursor planes (thus + * making cursor planes on those drivers not truly universal,) e.g. + * they need cursor planes to act like one would expect from a mouse + * cursor and have correctly set hotspot properties. + * If this client cap is not set the DRM core will hide cursor plane on + * those virtualized drivers because not setting it implies that the + * client is not capable of dealing with those extra restictions. + * Clients which do set cursor hotspot and treat the cursor plane + * like a mouse cursor should set this property. + * The client must enable &DRM_CLIENT_CAP_ATOMIC first. + * + * Setting this property on drivers which do not special case + * cursor planes (i.e. non-virtualized drivers) will return + * EOPNOTSUPP, which can be used by userspace to gauge + * requirements of the hardware/drivers they're running on. + * + * This capability is always supported for atomic-capable virtualized + * drivers starting from kernel version 6.6. + */ +#define DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT 6 + /* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ struct drm_set_client_cap { __u64 capability; @@ -881,6 +920,7 @@ struct drm_syncobj_transfer { #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) /* wait for time point to become available */ +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE (1 << 3) /* set fence deadline to deadline_nsec */ struct drm_syncobj_wait { __u64 handles; /* absolute timeout */ @@ -889,6 +929,14 @@ struct drm_syncobj_wait { __u32 flags; __u32 first_signaled; /* only valid when not waiting all */ __u32 pad; + /** + * @deadline_nsec - fence deadline hint + * + * Deadline hint, in absolute CLOCK_MONOTONIC, to set on backing + * fence(s) if the DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE flag is + * set. + */ + __u64 deadline_nsec; }; struct drm_syncobj_timeline_wait { @@ -901,6 +949,35 @@ struct drm_syncobj_timeline_wait { __u32 flags; __u32 first_signaled; /* only valid when not waiting all */ __u32 pad; + /** + * @deadline_nsec - fence deadline hint + * + * Deadline hint, in absolute CLOCK_MONOTONIC, to set on backing + * fence(s) if the DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE flag is + * set. + */ + __u64 deadline_nsec; +}; + +/** + * struct drm_syncobj_eventfd + * @handle: syncobj handle. + * @flags: Zero to wait for the point to be signalled, or + * &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE to wait for a fence to be + * available for the point. + * @point: syncobj timeline point (set to zero for binary syncobjs). + * @fd: Existing eventfd to sent events to. + * @pad: Must be zero. + * + * Register an eventfd to be signalled by a syncobj. The eventfd counter will + * be incremented by one. + */ +struct drm_syncobj_eventfd { + __u32 handle; + __u32 flags; + __u64 point; + __s32 fd; + __u32 pad; }; @@ -966,6 +1043,19 @@ extern "C" { #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) +/** + * DRM_IOCTL_GEM_CLOSE - Close a GEM handle. + * + * GEM handles are not reference-counted by the kernel. User-space is + * responsible for managing their lifetime. For example, if user-space imports + * the same memory object twice on the same DRM file description, the same GEM + * handle is returned by both imports, and user-space needs to ensure + * &DRM_IOCTL_GEM_CLOSE is performed once only. The same situation can happen + * when a memory object is allocated, then exported and imported again on the + * same DRM file description. The &DRM_IOCTL_MODE_GETFB2 IOCTL is an exception + * and always returns fresh new GEM handles even if an existing GEM handle + * already refers to the same memory object before the IOCTL is performed. + */ #define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close) #define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) #define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) @@ -1006,7 +1096,37 @@ extern "C" { #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) +/** + * DRM_IOCTL_PRIME_HANDLE_TO_FD - Convert a GEM handle to a DMA-BUF FD. + * + * User-space sets &drm_prime_handle.handle with the GEM handle to export and + * &drm_prime_handle.flags, and gets back a DMA-BUF file descriptor in + * &drm_prime_handle.fd. + * + * The export can fail for any driver-specific reason, e.g. because export is + * not supported for this specific GEM handle (but might be for others). + * + * Support for exporting DMA-BUFs is advertised via &DRM_PRIME_CAP_EXPORT. + */ #define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle) +/** + * DRM_IOCTL_PRIME_FD_TO_HANDLE - Convert a DMA-BUF FD to a GEM handle. + * + * User-space sets &drm_prime_handle.fd with a DMA-BUF file descriptor to + * import, and gets back a GEM handle in &drm_prime_handle.handle. + * &drm_prime_handle.flags is unused. + * + * If an existing GEM handle refers to the memory object backing the DMA-BUF, + * that GEM handle is returned. Therefore user-space which needs to handle + * arbitrary DMA-BUFs must have a user-space lookup data structure to manually + * reference-count duplicated GEM handles. For more information see + * &DRM_IOCTL_GEM_CLOSE. + * + * The import can fail for any driver-specific reason, e.g. because import is + * only supported for DMA-BUFs allocated on this DRM device. + * + * Support for importing DMA-BUFs is advertised via &DRM_PRIME_CAP_IMPORT. + */ #define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle) #define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) @@ -1044,10 +1164,40 @@ extern "C" { #define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) +/** + * DRM_IOCTL_MODE_RMFB - Remove a framebuffer. + * + * This removes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL + * argument is a framebuffer object ID. + * + * Warning: removing a framebuffer currently in-use on an enabled plane will + * disable that plane. The CRTC the plane is linked to may also be disabled + * (depending on driver capabilities). + */ #define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) #define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) #define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) +/** + * DRM_IOCTL_MODE_CREATE_DUMB - Create a new dumb buffer object. + * + * KMS dumb buffers provide a very primitive way to allocate a buffer object + * suitable for scanout and map it for software rendering. KMS dumb buffers are + * not suitable for hardware-accelerated rendering nor video decoding. KMS dumb + * buffers are not suitable to be displayed on any other device than the KMS + * device where they were allocated from. Also see + * :ref:`kms_dumb_buffer_objects`. + * + * The IOCTL argument is a struct drm_mode_create_dumb. + * + * User-space is expected to create a KMS dumb buffer via this IOCTL, then add + * it as a KMS framebuffer via &DRM_IOCTL_MODE_ADDFB and map it via + * &DRM_IOCTL_MODE_MAP_DUMB. + * + * &DRM_CAP_DUMB_BUFFER indicates whether this IOCTL is supported. + * &DRM_CAP_DUMB_PREFERRED_DEPTH and &DRM_CAP_DUMB_PREFER_SHADOW indicate + * driver preferences for dumb buffers. + */ #define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb) #define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb) #define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) @@ -1080,8 +1230,58 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) +/** + * DRM_IOCTL_MODE_GETFB2 - Get framebuffer metadata. + * + * This queries metadata about a framebuffer. User-space fills + * &drm_mode_fb_cmd2.fb_id as the input, and the kernels fills the rest of the + * struct as the output. + * + * If the client is DRM master or has &CAP_SYS_ADMIN, &drm_mode_fb_cmd2.handles + * will be filled with GEM buffer handles. Fresh new GEM handles are always + * returned, even if another GEM handle referring to the same memory object + * already exists on the DRM file description. The caller is responsible for + * removing the new handles, e.g. via the &DRM_IOCTL_GEM_CLOSE IOCTL. The same + * new handle will be returned for multiple planes in case they use the same + * memory object. Planes are valid until one has a zero handle -- this can be + * used to compute the number of planes. + * + * Otherwise, &drm_mode_fb_cmd2.handles will be zeroed and planes are valid + * until one has a zero &drm_mode_fb_cmd2.pitches. + * + * If the framebuffer has a format modifier, &DRM_MODE_FB_MODIFIERS will be set + * in &drm_mode_fb_cmd2.flags and &drm_mode_fb_cmd2.modifier will contain the + * modifier. Otherwise, user-space must ignore &drm_mode_fb_cmd2.modifier. + * + * To obtain DMA-BUF FDs for each plane without leaking GEM handles, user-space + * can export each handle via &DRM_IOCTL_PRIME_HANDLE_TO_FD, then immediately + * close each unique handle via &DRM_IOCTL_GEM_CLOSE, making sure to not + * double-close handles which are specified multiple times in the array. + */ #define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) +#define DRM_IOCTL_SYNCOBJ_EVENTFD DRM_IOWR(0xCF, struct drm_syncobj_eventfd) + +/** + * DRM_IOCTL_MODE_CLOSEFB - Close a framebuffer. + * + * This closes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL + * argument is a framebuffer object ID. + * + * This IOCTL is similar to &DRM_IOCTL_MODE_RMFB, except it doesn't disable + * planes and CRTCs. As long as the framebuffer is used by a plane, it's kept + * alive. When the plane no longer uses the framebuffer (because the + * framebuffer is replaced with another one, or the plane is disabled), the + * framebuffer is cleaned up. + * + * This is useful to implement flicker-free transitions between two processes. + * + * Depending on the threat model, user-space may want to ensure that the + * framebuffer doesn't expose any sensitive user information: closed + * framebuffers attached to a plane can be read back by the next DRM master. + */ +#define DRM_IOCTL_MODE_CLOSEFB DRM_IOWR(0xD0, struct drm_mode_closefb) + /* * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. @@ -1093,25 +1293,50 @@ extern "C" { #define DRM_COMMAND_BASE 0x40 #define DRM_COMMAND_END 0xA0 -/* - * Header for events written back to userspace on the drm fd. The - * type defines the type of event, the length specifies the total - * length of the event (including the header), and user_data is - * typically a 64 bit value passed with the ioctl that triggered the - * event. A read on the drm fd will always only return complete - * events, that is, if for example the read buffer is 100 bytes, and - * there are two 64 byte events pending, only one will be returned. - * - * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and - * up are chipset specific. +/** + * struct drm_event - Header for DRM events + * @type: event type. + * @length: total number of payload bytes (including header). + * + * This struct is a header for events written back to user-space on the DRM FD. + * A read on the DRM FD will always only return complete events: e.g. if the + * read buffer is 100 bytes large and there are two 64 byte events pending, + * only one will be returned. + * + * Event types 0 - 0x7fffffff are generic DRM events, 0x80000000 and + * up are chipset specific. Generic DRM events include &DRM_EVENT_VBLANK, + * &DRM_EVENT_FLIP_COMPLETE and &DRM_EVENT_CRTC_SEQUENCE. */ struct drm_event { __u32 type; __u32 length; }; +/** + * DRM_EVENT_VBLANK - vertical blanking event + * + * This event is sent in response to &DRM_IOCTL_WAIT_VBLANK with the + * &_DRM_VBLANK_EVENT flag set. + * + * The event payload is a struct drm_event_vblank. + */ #define DRM_EVENT_VBLANK 0x01 +/** + * DRM_EVENT_FLIP_COMPLETE - page-flip completion event + * + * This event is sent in response to an atomic commit or legacy page-flip with + * the &DRM_MODE_PAGE_FLIP_EVENT flag set. + * + * The event payload is a struct drm_event_vblank. + */ #define DRM_EVENT_FLIP_COMPLETE 0x02 +/** + * DRM_EVENT_CRTC_SEQUENCE - CRTC sequence event + * + * This event is sent in response to &DRM_IOCTL_CRTC_QUEUE_SEQUENCE. + * + * The event payload is a struct drm_event_crtc_sequence. + */ #define DRM_EVENT_CRTC_SEQUENCE 0x03 struct drm_event_vblank { diff --git a/lib/libdrm/mk/libdrm/shlib_version b/lib/libdrm/mk/libdrm/shlib_version index 14ead84ec..f33cb8e75 100644 --- a/lib/libdrm/mk/libdrm/shlib_version +++ b/lib/libdrm/mk/libdrm/shlib_version @@ -1,2 +1,2 @@ major=7 -minor=12 +minor=13 diff --git a/lib/libdrm/mk/libdrm_amdgpu/shlib_version b/lib/libdrm/mk/libdrm_amdgpu/shlib_version index 07ff27595..783f55bf5 100644 --- a/lib/libdrm/mk/libdrm_amdgpu/shlib_version +++ b/lib/libdrm/mk/libdrm_amdgpu/shlib_version @@ -1,2 +1,2 @@ major=1 -minor=12 +minor=13 diff --git a/lib/libdrm/radeon/radeon_surface.c b/lib/libdrm/radeon/radeon_surface.c index ea0a27a94..0ff53a3eb 100644 --- a/lib/libdrm/radeon/radeon_surface.c +++ b/lib/libdrm/radeon/radeon_surface.c @@ -2205,6 +2205,7 @@ static int cik_surface_sanity(struct radeon_surface_manager *surf_man, break; case RADEON_SURF_MODE_LINEAR_ALIGNED: default: + *stencil_tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED; *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED; } diff --git a/lib/libdrm/xf86drm.c b/lib/libdrm/xf86drm.c index e61e3e88c..4cd0a488d 100644 --- a/lib/libdrm/xf86drm.c +++ b/lib/libdrm/xf86drm.c @@ -833,8 +833,6 @@ static const char *drmGetDeviceName(int type) switch (type) { case DRM_NODE_PRIMARY: return DRM_DEV_NAME; - case DRM_NODE_CONTROL: - return DRM_CONTROL_DEV_NAME; case DRM_NODE_RENDER: return DRM_RENDER_DEV_NAME; } @@ -1053,8 +1051,6 @@ static int drmGetMinorBase(int type) switch (type) { case DRM_NODE_PRIMARY: return 0; - case DRM_NODE_CONTROL: - return 64; case DRM_NODE_RENDER: return 128; default: @@ -1075,8 +1071,6 @@ static int drmGetMinorType(int major, int minor) // If not in /dev/drm/ we have the type in the name if (sscanf(name, "dri/card%d\n", &id) >= 1) return DRM_NODE_PRIMARY; - else if (sscanf(name, "dri/control%d\n", &id) >= 1) - return DRM_NODE_CONTROL; else if (sscanf(name, "dri/renderD%d\n", &id) >= 1) return DRM_NODE_RENDER; return -1; @@ -1084,19 +1078,20 @@ static int drmGetMinorType(int major, int minor) minor = id; #endif - int type = minor >> 6; - - if (minor < 0) - return -1; + char path[DRM_NODE_NAME_MAX]; + const char *dev_name; + int i; - switch (type) { - case DRM_NODE_PRIMARY: - case DRM_NODE_CONTROL: - case DRM_NODE_RENDER: - return type; - default: - return -1; + for (i = DRM_NODE_PRIMARY; i < DRM_NODE_MAX; i++) { + dev_name = drmGetDeviceName(i); + if (!dev_name) + continue; + snprintf(path, sizeof(path), dev_name, DRM_DIR_NAME, minor); + if (!access(path, F_OK)) + return i; } + + return -1; } static const char *drmGetMinorName(int type) @@ -1104,8 +1099,6 @@ static const char *drmGetMinorName(int type) switch (type) { case DRM_NODE_PRIMARY: return DRM_PRIMARY_MINOR_NAME; - case DRM_NODE_CONTROL: - return DRM_CONTROL_MINOR_NAME; case DRM_NODE_RENDER: return DRM_RENDER_MINOR_NAME; default: @@ -1292,7 +1285,7 @@ drm_public int drmOpen(const char *name, const char *busid) * * \param name driver name. Not referenced if bus ID is supplied. * \param busid bus ID. Zero if not known. - * \param type the device node type to open, PRIMARY, CONTROL or RENDER + * \param type the device node type to open, PRIMARY or RENDER * * \return a file descriptor on success, or a negative value on error. * @@ -1325,7 +1318,7 @@ drm_public int drmOpenWithType(const char *name, const char *busid, int type) drm_public int drmOpenControl(int minor) { - return drmOpenMinor(minor, 0, DRM_NODE_CONTROL); + return -EINVAL; } drm_public int drmOpenRender(int minor) @@ -3735,12 +3728,9 @@ static int get_sysctl_pci_bus_info(int maj, int min, drmPciBusInfoPtr info) switch (type) { case DRM_NODE_PRIMARY: break; - case DRM_NODE_CONTROL: - id -= 64; - break; case DRM_NODE_RENDER: id -= 128; - break; + break; } if (id < 0) return -EINVAL; @@ -3852,10 +3842,6 @@ drm_public int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b) static int drmGetNodeType(const char *name) { - if (strncmp(name, DRM_CONTROL_MINOR_NAME, - sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0) - return DRM_NODE_CONTROL; - if (strncmp(name, DRM_RENDER_MINOR_NAME, sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0) return DRM_NODE_RENDER; @@ -4684,6 +4670,23 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP return 0; } +drm_public int drmGetNodeTypeFromDevId(dev_t devid) +{ + int maj, min, node_type; + + maj = major(devid); + min = minor(devid); + + if (!drmNodeIsDRM(maj, min)) + return -EINVAL; + + node_type = drmGetMinorType(maj, min); + if (node_type == -1) + return -ENODEV; + + return node_type; +} + /** * Get information about the opened drm device * @@ -5101,6 +5104,20 @@ drm_public int drmSyncobjTransfer(int fd, return ret; } +drm_public int drmSyncobjEventfd(int fd, uint32_t handle, uint64_t point, int ev_fd, + uint32_t flags) +{ + struct drm_syncobj_eventfd args; + + memclear(args); + args.handle = handle; + args.point = point; + args.fd = ev_fd; + args.flags = flags; + + return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_EVENTFD, &args); +} + static char * drmGetFormatModifierFromSimpleTokens(uint64_t modifier) { diff --git a/lib/libdrm/xf86drm.h b/lib/libdrm/xf86drm.h index 9c626e929..01be18788 100644 --- a/lib/libdrm/xf86drm.h +++ b/lib/libdrm/xf86drm.h @@ -44,7 +44,7 @@ extern "C" { #endif #ifndef DRM_MAX_MINOR -#define DRM_MAX_MINOR 16 +#define DRM_MAX_MINOR 64 /* deprecated */ #endif #if defined(__linux__) @@ -78,12 +78,12 @@ extern "C" { #define DRM_DIR_NAME "/dev/dri" #define DRM_PRIMARY_MINOR_NAME "card" -#define DRM_CONTROL_MINOR_NAME "controlD" +#define DRM_CONTROL_MINOR_NAME "controlD" /* deprecated */ #define DRM_RENDER_MINOR_NAME "renderD" #define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */ #define DRM_DEV_NAME "%s/" DRM_PRIMARY_MINOR_NAME "%d" -#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d" +#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d" /* deprecated */ #define DRM_RENDER_DEV_NAME "%s/" DRM_RENDER_MINOR_NAME "%d" #define DRM_NODE_NAME_MAX \ @@ -91,7 +91,7 @@ extern "C" { + MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), \ sizeof(DRM_CONTROL_MINOR_NAME), \ sizeof(DRM_RENDER_MINOR_NAME)) \ - + sizeof("144") /* highest possible node number */ \ + + sizeof("1048575") /* highest possible node number 2^MINORBITS - 1 */ \ + 1) /* NULL-terminator */ #define DRM_ERR_NO_DEVICE (-1001) @@ -589,14 +589,14 @@ extern int drmAvailable(void); extern int drmOpen(const char *name, const char *busid); #define DRM_NODE_PRIMARY 0 -#define DRM_NODE_CONTROL 1 +#define DRM_NODE_CONTROL 1 /* deprecated: never returned */ #define DRM_NODE_RENDER 2 #define DRM_NODE_MAX 3 extern int drmOpenWithType(const char *name, const char *busid, int type); -extern int drmOpenControl(int minor); +extern int drmOpenControl(int minor); /* deprecated: always fails */ extern int drmOpenRender(int minor); extern int drmClose(int fd); extern drmVersionPtr drmGetVersion(int fd); @@ -801,7 +801,7 @@ extern int drmHandleEvent(int fd, drmEventContextPtr evctx); extern char *drmGetDeviceNameFromFd(int fd); /* Improved version of drmGetDeviceNameFromFd which attributes for any type of - * device/node - card, control or renderD. + * device/node - card or renderD. */ extern char *drmGetDeviceNameFromFd2(int fd); extern int drmGetNodeTypeFromFd(int fd); @@ -912,6 +912,13 @@ extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_device 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); @@ -940,6 +947,8 @@ 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); diff --git a/lib/libdrm/xf86drmMode.c b/lib/libdrm/xf86drmMode.c index 22a8a7c22..a4873a0fa 100644 --- a/lib/libdrm/xf86drmMode.c +++ b/lib/libdrm/xf86drmMode.c @@ -320,6 +320,16 @@ drm_public int drmModeRmFB(int fd, uint32_t bufferId) return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId); } +drm_public int drmModeCloseFB(int fd, uint32_t buffer_id) +{ + struct drm_mode_closefb closefb; + + memclear(closefb); + closefb.fb_id = buffer_id; + + return DRM_IOCTL(fd, DRM_IOCTL_MODE_CLOSEFB, &closefb); +} + drm_public drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) { struct drm_mode_fb_cmd info; @@ -1004,8 +1014,8 @@ drm_public int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, } drm_public int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, - uint16_t *red, uint16_t *green, - uint16_t *blue) + const uint16_t *red, const uint16_t *green, + const uint16_t *blue) { struct drm_mode_crtc_lut l; diff --git a/lib/libdrm/xf86drmMode.h b/lib/libdrm/xf86drmMode.h index d911c9a1b..084878879 100644 --- a/lib/libdrm/xf86drmMode.h +++ b/lib/libdrm/xf86drmMode.h @@ -315,6 +315,13 @@ int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height, extern int drmModeRmFB(int fd, uint32_t bufferId); /** + * Close a framebuffer. + * + * Same as drmModeRmFB(), except it doesn't implicitly disable planes and CRTCs. + */ +extern int drmModeCloseFB(int fd, uint32_t buffer_id); + +/** * Mark a region of a framebuffer as dirty. */ extern int drmModeDirtyFB(int fd, uint32_t bufferId, @@ -416,7 +423,7 @@ extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t p extern int drmCheckModesettingSupported(const char *busid); extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, - uint16_t *red, uint16_t *green, uint16_t *blue); + const uint16_t *red, const uint16_t *green, const uint16_t *blue); extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue); extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, |