From 83f94732a95a3b600fc2aebbacc4e53e4316eea7 Mon Sep 17 00:00:00 2001 From: "shanlong.li" Date: Thu, 5 May 2022 01:42:30 -0700 Subject: [PATCH] buildroot:libdrm: Uploaded DDK patches for libdrm Uploaded DDK patches for libdrm Signed-off-by: shanlong.li --- ...Add-sync_fence_info-and-sync_pt_info.patch | 212 ++++++++++++++++++ ...d-support-for-populating-drm-formats.patch | 171 ++++++++++++++ ...nc_file_info-and-sync_get_fence_info.patch | 148 ++++++++++++ 3 files changed, 531 insertions(+) create mode 100644 package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch create mode 100644 package/libdrm/0003-xf86drm-add-support-for-populating-drm-formats.patch create mode 100644 package/libdrm/0004-Add-sync_file_info-and-sync_get_fence_info.patch diff --git a/package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch b/package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch new file mode 100644 index 00000000..5a17f323 --- /dev/null +++ b/package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch @@ -0,0 +1,212 @@ +From fef264e0844cfd49be3fdc19a6cea3f2d0f273a8 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Thu, 24 Aug 2017 13:28:38 +0100 +Subject: [PATCH 4/6] Add sync_fence_info and sync_pt_info + +For pre-4.7 kernels, sync_fence_info returns the data from the +SYNC_IOC_FENCE_INFO ioctl. For newer kernels, the SYNC_IOC_FILE_INFO +ioctl is called, and the data converted to SYNC_IOC_FENCE_INFO form. +--- + libsync.h | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 172 insertions(+) + +diff --git a/libsync.h b/libsync.h +index c3b8a38..44f7330 100644 +--- a/libsync.h ++++ b/libsync.h +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -74,6 +75,54 @@ struct sync_legacy_merge_data { + struct sync_legacy_merge_data) + #endif + ++#ifndef SYNC_IOC_FILE_INFO ++/* duplicated from linux/sync_file.h to avoid a build-time dependency ++ * on new (v4.7) kernel headers. ++ */ ++struct sync_fence_info { ++ char obj_name[32]; ++ char driver_name[32]; ++ int32_t status; ++ uint32_t flags; ++ uint64_t timestamp_ns; ++}; ++ ++struct sync_file_info { ++ char name[32]; ++ int32_t status; ++ uint32_t flags; ++ uint32_t num_fences; ++ uint32_t pad; ++ uint64_t sync_fence_info; ++}; ++ ++#define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info) ++#endif ++ ++#ifndef SYNC_IOC_LEGACY_FENCE_INFO ++/* the legacy definitions are based on the contents of ++ * drivers/staging/android/uapi/sync.h in the v4.4 kernel. ++ */ ++struct sync_pt_info { ++ uint32_t len; ++ char obj_name[32]; ++ char driver_name[32]; ++ int32_t status; ++ uint64_t timestamp_ns; ++ uint8_t driver_data[0]; ++}; ++ ++struct sync_fence_info_data { ++ uint32_t len; ++ char name[32]; ++ int32_t status; ++ uint8_t pt_info[0]; ++}; ++ ++#define SYNC_IOC_LEGACY_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2, \ ++ struct sync_fence_info_data) ++#endif ++ + static inline int sync_wait(int fd, int timeout) + { + struct pollfd fds = {0}; +@@ -179,6 +228,129 @@ static inline int sync_accumulate(const char *name, int *fd1, int fd2) + return 0; + } + ++static inline struct sync_pt_info *sync_pt_info( ++ struct sync_fence_info_data *info, ++ struct sync_pt_info *pt_info) ++{ ++ if (!pt_info) ++ pt_info = (struct sync_pt_info *)info->pt_info; ++ else ++ pt_info = (struct sync_pt_info *)((uint8_t *)pt_info + ++ pt_info->len); ++ ++ if ((uint32_t)((uint8_t *)pt_info - (uint8_t *)info) >= info->len) ++ return NULL; ++ ++ return pt_info; ++} ++ ++static inline struct sync_fence_info_data *sync_legacy_fence_info(int fd) ++{ ++ const uint32_t len = 4096; ++ struct sync_fence_info_data *info = malloc(len); ++ int ret; ++ ++ if (!info) ++ return NULL; ++ ++ info->len = len; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ free(info); ++ return NULL; ++ } ++ ++ return info; ++} ++ ++static inline struct sync_fence_info_data *fence_info_from_file_info( ++ struct sync_file_info *file_info, ++ uint32_t num_fences) ++{ ++ struct sync_fence_info_data *info; ++ size_t info_len; ++ struct sync_pt_info *pt_info = NULL; ++ struct sync_fence_info *fence_info; ++ uint32_t i; ++ ++ info_len = sizeof(*info) + num_fences * sizeof(*pt_info); ++ info = malloc(info_len); ++ if (!info) ++ return NULL; ++ ++ info->len = info_len; ++ strncpy(info->name, file_info->name, sizeof(info->name)); ++ info->status = file_info->status; ++ ++ fence_info = (struct sync_fence_info *)(uintptr_t) ++ file_info->sync_fence_info; ++ for (i = 0; i < num_fences; i++) { ++ pt_info = sync_pt_info(info, pt_info); ++ assert(pt_info); ++ ++ pt_info->len = sizeof(*pt_info); ++ strncpy(pt_info->obj_name, fence_info->obj_name, ++ sizeof(pt_info->obj_name)); ++ strncpy(pt_info->driver_name, fence_info->driver_name, ++ sizeof(pt_info->driver_name)); ++ pt_info->status = fence_info->status; ++ pt_info->timestamp_ns = fence_info->timestamp_ns; ++ ++ fence_info++; ++ } ++ ++ return info; ++} ++ ++static inline struct sync_fence_info_data *sync_fence_info(int fd) ++{ ++ struct sync_fence_info_data *info = NULL; ++ struct sync_file_info initial_info = {""}; ++ struct sync_file_info *file_info; ++ int ret; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ if (errno == ENOTTY) ++ return sync_legacy_fence_info(fd); ++ else ++ return NULL; ++ } ++ ++ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences * ++ sizeof(struct sync_fence_info)); ++ if (!file_info) ++ return NULL; ++ ++ file_info->num_fences = initial_info.num_fences; ++ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1); ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) ++ goto free_file_info; ++ ++ info = fence_info_from_file_info(file_info, initial_info.num_fences); ++ ++free_file_info: ++ free(file_info); ++ ++ return info; ++} ++ ++static inline void sync_fence_info_free(struct sync_fence_info_data *info) ++{ ++ free(info); ++} + #if defined(__cplusplus) + } + #endif +-- +2.7.4 + diff --git a/package/libdrm/0003-xf86drm-add-support-for-populating-drm-formats.patch b/package/libdrm/0003-xf86drm-add-support-for-populating-drm-formats.patch new file mode 100644 index 00000000..37969118 --- /dev/null +++ b/package/libdrm/0003-xf86drm-add-support-for-populating-drm-formats.patch @@ -0,0 +1,171 @@ +From 001ef51239541dd91f854ea5a5f569f2b338ad82 Mon Sep 17 00:00:00 2001 +From: Luigi Santivetti +Date: Tue, 24 Sep 2019 13:09:31 +0100 +Subject: [PATCH 5/6] xf86drm: add support for populating drm formats + +This change lets libdrm take care of allocation and deallocation of +the drmModePlane formats on behalf of clients. Weston, xserver and +others can use this functionaly instead of querying and parsing the +drm blob. + +NOTE: this change is based on weston/kms.c + +Change-Id: Id318322ee6b8f02442a37797669edd0363a58d88 +Signed-off-by: Luigi Santivetti +--- + xf86drmMode.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + xf86drmMode.h | 12 +++++++ + 2 files changed, 120 insertions(+) + +diff --git a/xf86drmMode.c b/xf86drmMode.c +index 2399e8e..3a099b2 100644 +--- a/xf86drmMode.c ++++ b/xf86drmMode.c +@@ -718,6 +718,114 @@ err_allocs: + return r; + } + ++static inline uint32_t * ++formats_ptr(struct drm_format_modifier_blob *blob) ++{ ++ return (uint32_t *)(((uint8_t *)blob) + blob->formats_offset); ++} ++ ++static inline struct drm_format_modifier * ++modifiers_ptr(struct drm_format_modifier_blob *blob) ++{ ++ return (struct drm_format_modifier *)(((uint8_t *)blob) + ++ blob->modifiers_offset); ++} ++ ++drm_public void ++drmModeFreeFormats(drmModeFormatsPtr drm_mode_fmt) ++{ ++ uint32_t i; ++ ++ if (!drm_mode_fmt) ++ return; ++ ++ for (i = 0; i < drm_mode_fmt->count; i++) ++ drmFree(drm_mode_fmt->formats[i].modifiers); ++ ++ drmFree(drm_mode_fmt); ++} ++ ++drm_public int ++drmModePopulateFormats(drmModePropertyBlobPtr blob, drmModeFormatsPtr *out_formats) ++{ ++ struct drm_format_modifier_blob *fmt_mod_blob; ++ struct drm_format_modifier *blob_modifiers; ++ drmModeFormatsPtr drm_mode_fmt; ++ uint32_t *blob_formats; ++ uint32_t count_formats; ++ uint32_t i; ++ ++ if (!blob || !out_formats) ++ return -EINVAL; ++ ++ fmt_mod_blob = blob->data; ++ blob_formats = formats_ptr(fmt_mod_blob); ++ blob_modifiers = modifiers_ptr(fmt_mod_blob); ++ ++ if (!fmt_mod_blob->count_formats) ++ return -EINVAL; ++ ++ /* The drmModeFormats type supports C versions earlier than C99 ++ * by explicitly defining an array of length 1. Thus, 1 must be ++ * deducted from the runtime value of fmt_mod_blob->count_formats. ++ */ ++ count_formats = fmt_mod_blob->count_formats - 1; ++ drm_mode_fmt = drmMalloc(sizeof(*drm_mode_fmt) + ++ sizeof(drm_mode_fmt->formats[0]) * count_formats); ++ if (!drm_mode_fmt) ++ return -errno; ++ ++ drm_mode_fmt->count = 0; ++ ++ for (i = 0; i < fmt_mod_blob->count_formats; i++) { ++ uint32_t count_valid_modifiers = 0; ++ uint64_t *modifiers = NULL; ++ unsigned j; ++ ++ for (j = 0; j < fmt_mod_blob->count_modifiers; j++) { ++ struct drm_format_modifier *mod = &blob_modifiers[j]; ++ ++ if ((i < mod->offset) || (i > mod->offset + 63)) ++ continue; ++ if (!(mod->formats & (1 << (i - mod->offset)))) ++ continue; ++ ++ modifiers = realloc(modifiers, ++ (count_valid_modifiers + 1) * ++ sizeof(*modifiers)); ++ if (!modifiers) ++ goto err_allocs; ++ ++ modifiers[count_valid_modifiers++] = mod->modifier; ++ } ++ ++ /* Couldn't find valid modifiers, fallback to use linear */ ++ if (count_valid_modifiers == 0) { ++ modifiers = drmMalloc(sizeof(*modifiers)); ++ if (!modifiers) ++ goto err_allocs; ++ ++ *modifiers = 0; /* as DRM_FORMAT_MOD_LINEAR */ ++ count_valid_modifiers = 1; ++ } ++ ++ /* If realloc fails, in order to free all previoulsy allocated ++ * modifiers, always update drm_mode_fmt->count. ++ */ ++ drm_mode_fmt->count++; ++ drm_mode_fmt->formats[i].format = blob_formats[i]; ++ drm_mode_fmt->formats[i].modifiers = modifiers; ++ drm_mode_fmt->formats[i].count_modifiers = count_valid_modifiers; ++ } ++ ++ *out_formats = drm_mode_fmt; ++ return 0; ++ ++err_allocs: ++ drmModeFreeFormats(drm_mode_fmt); ++ return -errno; ++} ++ + drm_public void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr) + { + if (!ptr) +diff --git a/xf86drmMode.h b/xf86drmMode.h +index 5449320..76e77df 100644 +--- a/xf86drmMode.h ++++ b/xf86drmMode.h +@@ -334,6 +334,15 @@ typedef struct _drmModeObjectProperties { + uint64_t *prop_values; + } drmModeObjectProperties, *drmModeObjectPropertiesPtr; + ++typedef struct _drmModeFormats { ++ uint32_t count; ++ struct { ++ uint32_t format; ++ uint32_t count_modifiers; ++ uint64_t *modifiers; ++ } formats[1]; ++} drmModeFormats, *drmModeFormatsPtr; ++ + typedef struct _drmModePlane { + uint32_t count_formats; + uint32_t *formats; +@@ -484,6 +493,9 @@ extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId); + extern void drmModeFreeProperty(drmModePropertyPtr ptr); + + extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id); ++extern int drmModePopulateFormats(drmModePropertyBlobPtr ptr, ++ drmModeFormatsPtr *out_formats); ++extern void drmModeFreeFormats(drmModeFormatsPtr ptr); + extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr); + extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id, + uint64_t value); +-- +2.7.4 + diff --git a/package/libdrm/0004-Add-sync_file_info-and-sync_get_fence_info.patch b/package/libdrm/0004-Add-sync_file_info-and-sync_get_fence_info.patch new file mode 100644 index 00000000..c2e857cd --- /dev/null +++ b/package/libdrm/0004-Add-sync_file_info-and-sync_get_fence_info.patch @@ -0,0 +1,148 @@ +From a12e3b4490c182ed506f59eda01f1bd0919720f1 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Mon, 9 Mar 2020 14:52:17 +0000 +Subject: [PATCH 6/6] Add sync_file_info and sync_get_fence_info + +For pre-4.7 kernels, sync_file_info calls the SYNC_IOC_FENCE_INFO ioctl, +and converts the data to SYNC_IOC_FILE_INFO form. For newer kernels, +sync_file_info returns data from the SYNC_IOC_FILE_INFO ioctl. + +This patch depends on patch "Add sync_fence_info and sync_pt_info", +which added legacy sync info support, using the structure and ioctl +definitions at the top of the patch, as well as the sync_pt_info +function. +--- + libsync.h | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 117 insertions(+) + +diff --git a/libsync.h b/libsync.h +index 44f7330..54acb6f 100644 +--- a/libsync.h ++++ b/libsync.h +@@ -351,6 +351,123 @@ static inline void sync_fence_info_free(struct sync_fence_info_data *info) + { + free(info); + } ++ ++static inline struct sync_fence_info *sync_get_fence_info( ++ struct sync_file_info *file_info) ++{ ++ return (struct sync_fence_info *)(uintptr_t)file_info->sync_fence_info; ++} ++ ++static inline struct sync_file_info *file_info_from_info_data( ++ struct sync_fence_info_data *info) ++{ ++ struct sync_pt_info *pt_info = NULL; ++ uint32_t num_fences = 0; ++ struct sync_file_info *file_info; ++ struct sync_fence_info *fence_info; ++ uint32_t i; ++ ++ while ((pt_info = sync_pt_info(info, pt_info)) != NULL) ++ num_fences++; ++ ++ file_info = calloc(1, sizeof(*file_info) + num_fences * ++ sizeof(*fence_info)); ++ if (!file_info) ++ return NULL; ++ ++ strncpy(file_info->name, info->name, sizeof(file_info->name)); ++ file_info->status = info->status; ++ file_info->num_fences = num_fences; ++ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1); ++ ++ fence_info = sync_get_fence_info(file_info); ++ for (i = 0; i < num_fences; i++) { ++ pt_info = sync_pt_info(info, pt_info); ++ assert(pt_info); ++ ++ strncpy(fence_info->obj_name, pt_info->obj_name, ++ sizeof(fence_info->obj_name)); ++ strncpy(fence_info->driver_name, pt_info->driver_name, ++ sizeof(fence_info->driver_name)); ++ fence_info->status = pt_info->status; ++ fence_info->timestamp_ns = pt_info->timestamp_ns; ++ ++ fence_info++; ++ } ++ ++ return file_info; ++} ++ ++static inline struct sync_file_info *sync_legacy_file_info(int fd) ++{ ++ const uint32_t len = 4096; ++ struct sync_fence_info_data *info = malloc(len); ++ struct sync_file_info *file_info; ++ int ret; ++ ++ if (!info) ++ return NULL; ++ ++ info->len = len; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ free(info); ++ return NULL; ++ } ++ ++ file_info = file_info_from_info_data(info); ++ ++ free(info); ++ ++ return file_info; ++} ++ ++static inline void sync_file_info_free(struct sync_file_info *file_info) ++{ ++ free(file_info); ++} ++ ++static inline struct sync_file_info *sync_file_info(int fd) ++{ ++ struct sync_file_info initial_info = {""}; ++ struct sync_file_info *file_info; ++ int ret; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ if (errno == ENOTTY) ++ return sync_legacy_file_info(fd); ++ else ++ return NULL; ++ } ++ ++ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences * ++ sizeof(struct sync_fence_info)); ++ if (!file_info) ++ return NULL; ++ ++ file_info->num_fences = initial_info.num_fences; ++ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1); ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ sync_file_info_free(file_info); ++ return NULL; ++ } ++ ++ return file_info; ++} ++ + #if defined(__cplusplus) + } + #endif +-- +2.7.4 +