diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2018-09-13 11:56:08 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2018-09-13 11:56:08 +0000 |
commit | 20ef3ba50ee2d8fcfaece2fb71a1cf67a3b69221 (patch) | |
tree | d2704119ea12bc20b4b8cb72c7f8aeea1361950b | |
parent | 37c386e3c10dcd3d15d2da3063fe6da3e7ca4f90 (diff) |
Import libdrm 2.4.94
131 files changed, 4070 insertions, 907 deletions
diff --git a/lib/libdrm/amdgpu/Makefile.sources b/lib/libdrm/amdgpu/Makefile.sources index 498b64cc3..d6df324a3 100644 --- a/lib/libdrm/amdgpu/Makefile.sources +++ b/lib/libdrm/amdgpu/Makefile.sources @@ -7,10 +7,8 @@ LIBDRM_AMDGPU_FILES := \ amdgpu_internal.h \ amdgpu_vamgr.c \ amdgpu_vm.c \ - util_hash.c \ - util_hash.h \ - util_hash_table.c \ - util_hash_table.h + handle_table.c \ + handle_table.h LIBDRM_AMDGPU_H_FILES := \ amdgpu.h diff --git a/lib/libdrm/amdgpu/amdgpu-symbol-check b/lib/libdrm/amdgpu/amdgpu-symbol-check index 3f298d13c..90b7a1d63 100755 --- a/lib/libdrm/amdgpu/amdgpu-symbol-check +++ b/lib/libdrm/amdgpu/amdgpu-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.am/libdrm_amdgpuinclude_HEADERS -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_amdgpu.so} | awk '{print $3}' | while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_amdgpu.so} | awk '{print $3}' | while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata @@ -40,6 +40,7 @@ amdgpu_cs_fence_to_handle amdgpu_cs_import_syncobj amdgpu_cs_query_fence_status amdgpu_cs_query_reset_state +amdgpu_query_sw_info amdgpu_cs_signal_semaphore amdgpu_cs_submit amdgpu_cs_submit_raw diff --git a/lib/libdrm/amdgpu/amdgpu.h b/lib/libdrm/amdgpu/amdgpu.h index 2eb03bf15..a8c353c6c 100644 --- a/lib/libdrm/amdgpu/amdgpu.h +++ b/lib/libdrm/amdgpu/amdgpu.h @@ -84,7 +84,12 @@ enum amdgpu_bo_handle_type { amdgpu_bo_handle_type_kms = 1, /** DMA-buf fd handle */ - amdgpu_bo_handle_type_dma_buf_fd = 2 + amdgpu_bo_handle_type_dma_buf_fd = 2, + + /** KMS handle, but re-importing as a DMABUF handle through + * drmPrimeHandleToFD is forbidden. (Glamor does that) + */ + amdgpu_bo_handle_type_kms_noimport = 3, }; /** Define known types of GPU VM VA ranges */ @@ -94,6 +99,10 @@ enum amdgpu_gpu_va_range amdgpu_gpu_va_range_general = 0 }; +enum amdgpu_sw_info { + amdgpu_sw_info_address32_hi = 0, +}; + /*--------------------------------------------------------------------------*/ /* -------------------------- Datatypes ----------------------------------- */ /*--------------------------------------------------------------------------*/ @@ -669,6 +678,29 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev, amdgpu_bo_handle *buf_handle); /** + * Validate if the user memory comes from BO + * + * \param dev - [in] Device handle. See #amdgpu_device_initialize() + * \param cpu - [in] CPU address of user allocated memory which we + * want to map to GPU address space (make GPU accessible) + * (This address must be correctly aligned). + * \param size - [in] Size of allocation (must be correctly aligned) + * \param buf_handle - [out] Buffer handle for the userptr memory + * if the user memory is not from BO, the buf_handle will be NULL. + * \param offset_in_bo - [out] offset in this BO for this user memory + * + * + * \return 0 on success\n + * <0 - Negative POSIX Error code + * +*/ +int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev, + void *cpu, + uint64_t size, + amdgpu_bo_handle *buf_handle, + uint64_t *offset_in_bo); + +/** * Free previosuly allocated memory * * \param dev - \c [in] Device handle. See #amdgpu_device_initialize() @@ -1086,6 +1118,23 @@ int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id, unsigned size, void *value); /** + * Query hardware or driver information. + * + * The return size is query-specific and depends on the "info_id" parameter. + * No more than "size" bytes is returned. + * + * \param dev - \c [in] Device handle. See #amdgpu_device_initialize() + * \param info - \c [in] amdgpu_sw_info_* + * \param value - \c [out] Pointer to the return value. + * + * \return 0 on success\n + * <0 - Negative POSIX error code + * +*/ +int amdgpu_query_sw_info(amdgpu_device_handle dev, enum amdgpu_sw_info info, + void *value); + +/** * Query information about GDS * * \param dev - \c [in] Device handle. See #amdgpu_device_initialize() @@ -1141,6 +1190,7 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset, * Flag to request VA address range in the 32bit address space */ #define AMDGPU_VA_RANGE_32_BIT 0x1 +#define AMDGPU_VA_RANGE_HIGH 0x2 /** * Allocate virtual address range diff --git a/lib/libdrm/amdgpu/amdgpu_asic_id.c b/lib/libdrm/amdgpu/amdgpu_asic_id.c index 0c8925e5d..a5007ffc8 100644 --- a/lib/libdrm/amdgpu/amdgpu_asic_id.c +++ b/lib/libdrm/amdgpu/amdgpu_asic_id.c @@ -22,10 +22,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <ctype.h> #include <stdio.h> #include <stdlib.h> @@ -155,7 +151,7 @@ void amdgpu_parse_asic_ids(struct amdgpu_device *dev) if (r == -EINVAL) { fprintf(stderr, "Invalid format: %s: line %d: %s\n", AMDGPU_ASIC_ID_TABLE, line_num, line); - } else if (r) { + } else if (r && r != -EAGAIN) { fprintf(stderr, "%s: Cannot parse ASIC IDs: %s\n", __func__, strerror(-r)); } diff --git a/lib/libdrm/amdgpu/amdgpu_cs.c b/lib/libdrm/amdgpu/amdgpu_cs.c index 987daa403..3c9be6c2e 100644 --- a/lib/libdrm/amdgpu/amdgpu_cs.c +++ b/lib/libdrm/amdgpu/amdgpu_cs.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -195,8 +191,6 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context, return -EINVAL; if (ibs_request->ring >= AMDGPU_CS_MAX_RINGS) return -EINVAL; - if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT) - return -EINVAL; if (ibs_request->number_of_ibs == 0) { ibs_request->seq_no = AMDGPU_NULL_SUBMIT_SEQ; return 0; @@ -582,7 +576,7 @@ static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem) if (!sem || !sem->signal_fence.context) return -EINVAL; - sem->signal_fence.context = NULL;; + sem->signal_fence.context = NULL; sem->signal_fence.ip_type = 0; sem->signal_fence.ip_instance = 0; sem->signal_fence.ring = 0; diff --git a/lib/libdrm/amdgpu/amdgpu_device.c b/lib/libdrm/amdgpu/amdgpu_device.c index eb4b2745f..73eeeed6f 100644 --- a/lib/libdrm/amdgpu/amdgpu_device.c +++ b/lib/libdrm/amdgpu/amdgpu_device.c @@ -28,61 +28,26 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <sys/stat.h> #include <errno.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <fcntl.h> #include "xf86drm.h" #include "amdgpu_drm.h" #include "amdgpu_internal.h" -#include "util_hash_table.h" #include "util_math.h" #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) -#define UINT_TO_PTR(x) ((void *)((intptr_t)(x))) static pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER; -static struct util_hash_table *fd_tab; - -static unsigned handle_hash(void *key) -{ - return PTR_TO_UINT(key); -} - -static int handle_compare(void *key1, void *key2) -{ - return PTR_TO_UINT(key1) != PTR_TO_UINT(key2); -} +static amdgpu_device_handle fd_list; -static unsigned fd_hash(void *key) +static int fd_compare(int fd1, int fd2) { - int fd = PTR_TO_UINT(key); - char *name = drmGetPrimaryDeviceNameFromFd(fd); - unsigned result = 0; - char *c; - - if (name == NULL) - return 0; - - for (c = name; *c; ++c) - result += *c; - - free(name); - - return result; -} - -static int fd_compare(void *key1, void *key2) -{ - int fd1 = PTR_TO_UINT(key1); - int fd2 = PTR_TO_UINT(key2); char *name1 = drmGetPrimaryDeviceNameFromFd(fd1); char *name2 = drmGetPrimaryDeviceNameFromFd(fd2); int result; @@ -130,15 +95,25 @@ static int amdgpu_get_auth(int fd, int *auth) static void amdgpu_device_free_internal(amdgpu_device_handle dev) { - amdgpu_vamgr_deinit(&dev->vamgr_32); - amdgpu_vamgr_deinit(&dev->vamgr); - util_hash_table_destroy(dev->bo_flink_names); - util_hash_table_destroy(dev->bo_handles); - pthread_mutex_destroy(&dev->bo_table_mutex); - util_hash_table_remove(fd_tab, UINT_TO_PTR(dev->fd)); + amdgpu_device_handle *node = &fd_list; + + pthread_mutex_lock(&fd_mutex); + while (*node != dev && (*node)->next) + node = &(*node)->next; + *node = (*node)->next; + pthread_mutex_unlock(&fd_mutex); + close(dev->fd); if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd)) close(dev->flink_fd); + + amdgpu_vamgr_deinit(&dev->vamgr_32); + amdgpu_vamgr_deinit(&dev->vamgr); + amdgpu_vamgr_deinit(&dev->vamgr_high_32); + amdgpu_vamgr_deinit(&dev->vamgr_high); + handle_table_fini(&dev->bo_handles); + handle_table_fini(&dev->bo_flink_names); + pthread_mutex_destroy(&dev->bo_table_mutex); free(dev->marketing_name); free(dev); } @@ -181,8 +156,6 @@ int amdgpu_device_initialize(int fd, *device_handle = NULL; pthread_mutex_lock(&fd_mutex); - if (!fd_tab) - fd_tab = util_hash_table_create(fd_hash, fd_compare); r = amdgpu_get_auth(fd, &flag_auth); if (r) { fprintf(stderr, "%s: amdgpu_get_auth (1) failed (%i)\n", @@ -190,7 +163,11 @@ int amdgpu_device_initialize(int fd, pthread_mutex_unlock(&fd_mutex); return r; } - dev = util_hash_table_get(fd_tab, UINT_TO_PTR(fd)); + + for (dev = fd_list; dev; dev = dev->next) + if (fd_compare(dev->fd, fd) == 0) + break; + if (dev) { r = amdgpu_get_auth(dev->fd, &flag_authexist); if (r) { @@ -200,7 +177,7 @@ int amdgpu_device_initialize(int fd, return r; } if ((flag_auth) && (!flag_authexist)) { - dev->flink_fd = dup(fd); + dev->flink_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); } *major_version = dev->major_version; *minor_version = dev->minor_version; @@ -234,15 +211,12 @@ int amdgpu_device_initialize(int fd, goto cleanup; } - dev->fd = dup(fd); + dev->fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); dev->flink_fd = dev->fd; dev->major_version = version->version_major; dev->minor_version = version->version_minor; drmFreeVersion(version); - dev->bo_flink_names = util_hash_table_create(handle_hash, - handle_compare); - dev->bo_handles = util_hash_table_create(handle_hash, handle_compare); pthread_mutex_init(&dev->bo_table_mutex, NULL); /* Check if acceleration is working. */ @@ -265,21 +239,34 @@ int amdgpu_device_initialize(int fd, } start = dev->dev_info.virtual_address_offset; - max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff); + max = MIN2(dev->dev_info.virtual_address_max, 0x100000000ULL); amdgpu_vamgr_init(&dev->vamgr_32, start, max, dev->dev_info.virtual_address_alignment); - start = MAX2(dev->dev_info.virtual_address_offset, 0x100000000ULL); + start = max; max = MAX2(dev->dev_info.virtual_address_max, 0x100000000ULL); amdgpu_vamgr_init(&dev->vamgr, start, max, dev->dev_info.virtual_address_alignment); + start = dev->dev_info.high_va_offset; + max = MIN2(dev->dev_info.high_va_max, (start & ~0xffffffffULL) + + 0x100000000ULL); + amdgpu_vamgr_init(&dev->vamgr_high_32, start, max, + dev->dev_info.virtual_address_alignment); + + start = max; + max = MAX2(dev->dev_info.high_va_max, (start & ~0xffffffffULL) + + 0x100000000ULL); + amdgpu_vamgr_init(&dev->vamgr_high, start, max, + dev->dev_info.virtual_address_alignment); + amdgpu_parse_asic_ids(dev); *major_version = dev->major_version; *minor_version = dev->minor_version; *device_handle = dev; - util_hash_table_set(fd_tab, UINT_TO_PTR(dev->fd), dev); + dev->next = fd_list; + fd_list = dev; pthread_mutex_unlock(&fd_mutex); return 0; @@ -302,3 +289,19 @@ const char *amdgpu_get_marketing_name(amdgpu_device_handle dev) { return dev->marketing_name; } + +int amdgpu_query_sw_info(amdgpu_device_handle dev, enum amdgpu_sw_info info, + void *value) +{ + uint32_t *val32 = (uint32_t*)value; + + switch (info) { + case amdgpu_sw_info_address32_hi: + if (dev->vamgr_high_32.va_max) + *val32 = (dev->vamgr_high_32.va_max - 1) >> 32; + else + *val32 = (dev->vamgr_32.va_max - 1) >> 32; + return 0; + } + return -EINVAL; +} diff --git a/lib/libdrm/amdgpu/amdgpu_gpu_info.c b/lib/libdrm/amdgpu/amdgpu_gpu_info.c index 1efffc6f1..b68e1c4fe 100644 --- a/lib/libdrm/amdgpu/amdgpu_gpu_info.c +++ b/lib/libdrm/amdgpu/amdgpu_gpu_info.c @@ -22,10 +22,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <string.h> diff --git a/lib/libdrm/amdgpu/amdgpu_internal.h b/lib/libdrm/amdgpu/amdgpu_internal.h index 3e044f11d..a340abbdf 100644 --- a/lib/libdrm/amdgpu/amdgpu_internal.h +++ b/lib/libdrm/amdgpu/amdgpu_internal.h @@ -25,10 +25,6 @@ #ifndef _AMDGPU_INTERNAL_H_ #define _AMDGPU_INTERNAL_H_ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <assert.h> #include <pthread.h> @@ -36,6 +32,7 @@ #include "xf86atomic.h" #include "amdgpu.h" #include "util_double_list.h" +#include "handle_table.h" #define AMDGPU_CS_MAX_RINGS 8 /* do not use below macro if b is not power of 2 aligned value */ @@ -53,8 +50,6 @@ struct amdgpu_bo_va_hole { }; struct amdgpu_bo_va_mgr { - /* the start virtual address */ - uint64_t va_offset; uint64_t va_max; struct list_head va_holes; pthread_mutex_t bo_va_mutex; @@ -71,6 +66,7 @@ struct amdgpu_va { struct amdgpu_device { atomic_t refcount; + struct amdgpu_device *next; int fd; int flink_fd; unsigned major_version; @@ -78,17 +74,21 @@ struct amdgpu_device { char *marketing_name; /** List of buffer handles. Protected by bo_table_mutex. */ - struct util_hash_table *bo_handles; + struct handle_table bo_handles; /** List of buffer GEM flink names. Protected by bo_table_mutex. */ - struct util_hash_table *bo_flink_names; + struct handle_table bo_flink_names; /** This protects all hash tables. */ pthread_mutex_t bo_table_mutex; struct drm_amdgpu_info_device dev_info; struct amdgpu_gpu_info info; - /** The global VA manager for the whole virtual address space */ + /** The VA manager for the lower virtual address space */ struct amdgpu_bo_va_mgr vamgr; /** The VA manager for the 32bit address space */ struct amdgpu_bo_va_mgr vamgr_32; + /** The VA manager for the high virtual address space */ + struct amdgpu_bo_va_mgr vamgr_high; + /** The VA manager for the 32bit high address space */ + struct amdgpu_bo_va_mgr vamgr_high_32; }; struct amdgpu_bo { diff --git a/lib/libdrm/amdgpu/amdgpu_vamgr.c b/lib/libdrm/amdgpu/amdgpu_vamgr.c index ab425ef7c..1de9f952f 100644 --- a/lib/libdrm/amdgpu/amdgpu_vamgr.c +++ b/lib/libdrm/amdgpu/amdgpu_vamgr.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <string.h> #include <errno.h> @@ -48,12 +44,19 @@ int amdgpu_va_range_query(amdgpu_device_handle dev, drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start, uint64_t max, uint64_t alignment) { - mgr->va_offset = start; + struct amdgpu_bo_va_hole *n; + mgr->va_max = max; mgr->va_alignment = alignment; list_inithead(&mgr->va_holes); pthread_mutex_init(&mgr->bo_va_mutex, NULL); + pthread_mutex_lock(&mgr->bo_va_mutex); + n = calloc(1, sizeof(struct amdgpu_bo_va_hole)); + n->size = mgr->va_max - start; + n->offset = start; + list_add(&n->list, &mgr->va_holes); + pthread_mutex_unlock(&mgr->bo_va_mutex); } drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr) @@ -73,6 +76,7 @@ amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size, struct amdgpu_bo_va_hole *hole, *n; uint64_t offset = 0, waste = 0; + alignment = MAX2(alignment, mgr->va_alignment); size = ALIGN(size, mgr->va_alignment); @@ -80,9 +84,7 @@ amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size, return AMDGPU_INVALID_VA_ADDRESS; pthread_mutex_lock(&mgr->bo_va_mutex); - /* TODO: using more appropriate way to track the holes */ - /* first look for a hole */ - LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) { + LIST_FOR_EACH_ENTRY_SAFE_REV(hole, n, &mgr->va_holes, list) { if (base_required) { if (hole->offset > base_required || (hole->offset + hole->size) < (base_required + size)) @@ -124,41 +126,14 @@ amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size, } } - if (base_required) { - if (base_required < mgr->va_offset) { - pthread_mutex_unlock(&mgr->bo_va_mutex); - return AMDGPU_INVALID_VA_ADDRESS; - } - offset = mgr->va_offset; - waste = base_required - mgr->va_offset; - } else { - offset = mgr->va_offset; - waste = offset % alignment; - waste = waste ? alignment - waste : 0; - } - - if (offset + waste + size > mgr->va_max) { - pthread_mutex_unlock(&mgr->bo_va_mutex); - return AMDGPU_INVALID_VA_ADDRESS; - } - - if (waste) { - n = calloc(1, sizeof(struct amdgpu_bo_va_hole)); - n->size = waste; - n->offset = offset; - list_add(&n->list, &mgr->va_holes); - } - - offset += waste; - mgr->va_offset += size + waste; pthread_mutex_unlock(&mgr->bo_va_mutex); - return offset; + return AMDGPU_INVALID_VA_ADDRESS; } static drm_private void amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size) { - struct amdgpu_bo_va_hole *hole; + struct amdgpu_bo_va_hole *hole, *next; if (va == AMDGPU_INVALID_VA_ADDRESS) return; @@ -166,61 +141,47 @@ amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size) size = ALIGN(size, mgr->va_alignment); pthread_mutex_lock(&mgr->bo_va_mutex); - if ((va + size) == mgr->va_offset) { - mgr->va_offset = va; - /* Delete uppermost hole if it reaches the new top */ - if (!LIST_IS_EMPTY(&mgr->va_holes)) { - hole = container_of(mgr->va_holes.next, hole, list); - if ((hole->offset + hole->size) == va) { - mgr->va_offset = hole->offset; + hole = container_of(&mgr->va_holes, hole, list); + LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) { + if (next->offset < va) + break; + hole = next; + } + + if (&hole->list != &mgr->va_holes) { + /* Grow upper hole if it's adjacent */ + if (hole->offset == (va + size)) { + hole->offset = va; + hole->size += size; + /* Merge lower hole if it's adjacent */ + if (next != hole && + &next->list != &mgr->va_holes && + (next->offset + next->size) == va) { + next->size += hole->size; list_del(&hole->list); free(hole); } - } - } else { - struct amdgpu_bo_va_hole *next; - - hole = container_of(&mgr->va_holes, hole, list); - LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) { - if (next->offset < va) - break; - hole = next; - } - - if (&hole->list != &mgr->va_holes) { - /* Grow upper hole if it's adjacent */ - if (hole->offset == (va + size)) { - hole->offset = va; - hole->size += size; - /* Merge lower hole if it's adjacent */ - if (next != hole && - &next->list != &mgr->va_holes && - (next->offset + next->size) == va) { - next->size += hole->size; - list_del(&hole->list); - free(hole); - } - goto out; - } - } - - /* Grow lower hole if it's adjacent */ - if (next != hole && &next->list != &mgr->va_holes && - (next->offset + next->size) == va) { - next->size += size; goto out; } + } - /* FIXME on allocation failure we just lose virtual address space - * maybe print a warning - */ - next = calloc(1, sizeof(struct amdgpu_bo_va_hole)); - if (next) { - next->size = size; - next->offset = va; - list_add(&next->list, &hole->list); - } + /* Grow lower hole if it's adjacent */ + if (next != hole && &next->list != &mgr->va_holes && + (next->offset + next->size) == va) { + next->size += size; + goto out; + } + + /* FIXME on allocation failure we just lose virtual address space + * maybe print a warning + */ + next = calloc(1, sizeof(struct amdgpu_bo_va_hole)); + if (next) { + next->size = size; + next->offset = va; + list_add(&next->list, &hole->list); } + out: pthread_mutex_unlock(&mgr->bo_va_mutex); } @@ -236,10 +197,21 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev, { struct amdgpu_bo_va_mgr *vamgr; - if (flags & AMDGPU_VA_RANGE_32_BIT) - vamgr = &dev->vamgr_32; - else - vamgr = &dev->vamgr; + /* Clear the flag when the high VA manager is not initialized */ + if (flags & AMDGPU_VA_RANGE_HIGH && !dev->vamgr_high_32.va_max) + flags &= ~AMDGPU_VA_RANGE_HIGH; + + if (flags & AMDGPU_VA_RANGE_HIGH) { + if (flags & AMDGPU_VA_RANGE_32_BIT) + vamgr = &dev->vamgr_high_32; + else + vamgr = &dev->vamgr_high; + } else { + if (flags & AMDGPU_VA_RANGE_32_BIT) + vamgr = &dev->vamgr_32; + else + vamgr = &dev->vamgr; + } va_base_alignment = MAX2(va_base_alignment, vamgr->va_alignment); size = ALIGN(size, vamgr->va_alignment); @@ -250,7 +222,10 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev, if (!(flags & AMDGPU_VA_RANGE_32_BIT) && (*va_base_allocated == AMDGPU_INVALID_VA_ADDRESS)) { /* fallback to 32bit address */ - vamgr = &dev->vamgr_32; + if (flags & AMDGPU_VA_RANGE_HIGH) + vamgr = &dev->vamgr_high_32; + else + vamgr = &dev->vamgr_32; *va_base_allocated = amdgpu_vamgr_find_va(vamgr, size, va_base_alignment, va_base_required); } diff --git a/lib/libdrm/amdgpu/amdgpu_vm.c b/lib/libdrm/amdgpu/amdgpu_vm.c index 5ba7c082d..da9d07f81 100644 --- a/lib/libdrm/amdgpu/amdgpu_vm.c +++ b/lib/libdrm/amdgpu/amdgpu_vm.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "amdgpu.h" #include "amdgpu_drm.h" #include "xf86drm.h" diff --git a/lib/libdrm/amdgpu/handle_table.c b/lib/libdrm/amdgpu/handle_table.c new file mode 100644 index 000000000..4fdd29d30 --- /dev/null +++ b/lib/libdrm/amdgpu/handle_table.c @@ -0,0 +1,72 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include "handle_table.h" +#include "util_math.h" + +drm_private int handle_table_insert(struct handle_table *table, uint32_t key, + void *value) +{ + if (key >= table->max_key) { + uint32_t alignment = sysconf(_SC_PAGESIZE) / sizeof(void*); + uint32_t max_key = ALIGN(key + 1, alignment); + void **values; + + values = realloc(table->values, max_key * sizeof(void *)); + if (!values) + return -ENOMEM; + + memset(values + table->max_key, 0, (max_key - table->max_key) * + sizeof(void *)); + + table->max_key = max_key; + table->values = values; + } + table->values[key] = value; + return 0; +} + +drm_private void handle_table_remove(struct handle_table *table, uint32_t key) +{ + if (key < table->max_key) + table->values[key] = NULL; +} + +drm_private void *handle_table_lookup(struct handle_table *table, uint32_t key) +{ + if (key < table->max_key) + return table->values[key]; + else + return NULL; +} + +drm_private void handle_table_fini(struct handle_table *table) +{ + free(table->values); + table->max_key = 0; + table->values = NULL; +} diff --git a/lib/libdrm/amdgpu/handle_table.h b/lib/libdrm/amdgpu/handle_table.h new file mode 100644 index 000000000..461193f6f --- /dev/null +++ b/lib/libdrm/amdgpu/handle_table.h @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _HANDLE_TABLE_H_ +#define _HANDLE_TABLE_H_ + +#include <stdint.h> +#include "libdrm_macros.h" + +struct handle_table { + uint32_t max_key; + void **values; +}; + +drm_private int handle_table_insert(struct handle_table *table, uint32_t key, + void *value); +drm_private void handle_table_remove(struct handle_table *table, uint32_t key); +drm_private void *handle_table_lookup(struct handle_table *table, uint32_t key); +drm_private void handle_table_fini(struct handle_table *table); + +#endif /* _HANDLE_TABLE_H_ */ diff --git a/lib/libdrm/amdgpu/meson.build b/lib/libdrm/amdgpu/meson.build new file mode 100644 index 000000000..d9d7de2d4 --- /dev/null +++ b/lib/libdrm/amdgpu/meson.build @@ -0,0 +1,65 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +datadir_amdgpu = join_paths(get_option('prefix'), get_option('datadir'), 'libdrm') + +libdrm_amdgpu = shared_library( + 'drm_amdgpu', + [ + files( + 'amdgpu_asic_id.c', 'amdgpu_bo.c', 'amdgpu_cs.c', 'amdgpu_device.c', + 'amdgpu_gpu_info.c', 'amdgpu_vamgr.c', 'amdgpu_vm.c', 'handle_table.c', + ), + config_file, + ], + c_args : [ + warn_c_args, + '-DAMDGPU_ASIC_ID_TABLE="@0@"'.format(join_paths(datadir_amdgpu, 'amdgpu.ids')), + ], + include_directories : [inc_root, inc_drm], + link_with : libdrm, + dependencies : [dep_pthread_stubs, dep_atomic_ops], + version : '1.0.0', + install : true, +) + +install_headers('amdgpu.h', subdir : 'libdrm') + +pkg.generate( + name : 'libdrm_amdgpu', + libraries : libdrm_amdgpu, + subdirs : ['.', 'libdrm'], + version : meson.project_version(), + requires_private : 'libdrm', + description : 'Userspace interface to kernel DRM services for amdgpu', +) + +ext_libdrm_amdgpu = declare_dependency( + link_with : [libdrm, libdrm_amdgpu], + include_directories : [inc_drm, include_directories('.')], +) + +test( + 'amdgpu-symbol-check', + prog_bash, + env : env_test, + args : [files('amdgpu-symbol-check'), libdrm_amdgpu] +) diff --git a/lib/libdrm/data/Makefile.am b/lib/libdrm/data/Makefile.am index eba915dd9..897a7f358 100644 --- a/lib/libdrm/data/Makefile.am +++ b/lib/libdrm/data/Makefile.am @@ -20,4 +20,6 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. libdrmdatadir = @libdrmdatadir@ +if HAVE_AMDGPU dist_libdrmdata_DATA = amdgpu.ids +endif diff --git a/lib/libdrm/data/meson.build b/lib/libdrm/data/meson.build new file mode 100644 index 000000000..9c26b66e0 --- /dev/null +++ b/lib/libdrm/data/meson.build @@ -0,0 +1,27 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if with_amdgpu + install_data( + 'amdgpu.ids', + install_mode : 'rw-r--r--', + install_dir : datadir_amdgpu, + ) +endif diff --git a/lib/libdrm/etnaviv/etnaviv_bo.c b/lib/libdrm/etnaviv/etnaviv_bo.c index 78b9cd272..32f7b3487 100644 --- a/lib/libdrm/etnaviv/etnaviv_bo.c +++ b/lib/libdrm/etnaviv/etnaviv_bo.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "etnaviv_priv.h" #include "etnaviv_drmif.h" diff --git a/lib/libdrm/etnaviv/etnaviv_bo_cache.c b/lib/libdrm/etnaviv/etnaviv_bo_cache.c index 6208230dc..c81de262f 100644 --- a/lib/libdrm/etnaviv/etnaviv_bo_cache.c +++ b/lib/libdrm/etnaviv/etnaviv_bo_cache.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "etnaviv_priv.h" #include "etnaviv_drmif.h" diff --git a/lib/libdrm/etnaviv/etnaviv_cmd_stream.c b/lib/libdrm/etnaviv/etnaviv_cmd_stream.c index e8c58cd5d..137301681 100644 --- a/lib/libdrm/etnaviv/etnaviv_cmd_stream.c +++ b/lib/libdrm/etnaviv/etnaviv_cmd_stream.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <assert.h> #include "etnaviv_drmif.h" diff --git a/lib/libdrm/etnaviv/etnaviv_device.c b/lib/libdrm/etnaviv/etnaviv_device.c index 3ce92030e..d83e8d3e6 100644 --- a/lib/libdrm/etnaviv/etnaviv_device.c +++ b/lib/libdrm/etnaviv/etnaviv_device.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <linux/stddef.h> #include <linux/types.h> diff --git a/lib/libdrm/etnaviv/etnaviv_drm.h b/lib/libdrm/etnaviv/etnaviv_drm.h index 110cc73bf..0d5c49dc4 100644 --- a/lib/libdrm/etnaviv/etnaviv_drm.h +++ b/lib/libdrm/etnaviv/etnaviv_drm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2015 Etnaviv Project * @@ -54,6 +55,12 @@ struct drm_etnaviv_timespec { #define ETNAVIV_PARAM_GPU_FEATURES_4 0x07 #define ETNAVIV_PARAM_GPU_FEATURES_5 0x08 #define ETNAVIV_PARAM_GPU_FEATURES_6 0x09 +#define ETNAVIV_PARAM_GPU_FEATURES_7 0x0a +#define ETNAVIV_PARAM_GPU_FEATURES_8 0x0b +#define ETNAVIV_PARAM_GPU_FEATURES_9 0x0c +#define ETNAVIV_PARAM_GPU_FEATURES_10 0x0d +#define ETNAVIV_PARAM_GPU_FEATURES_11 0x0e +#define ETNAVIV_PARAM_GPU_FEATURES_12 0x0f #define ETNAVIV_PARAM_GPU_STREAM_COUNT 0x10 #define ETNAVIV_PARAM_GPU_REGISTER_MAX 0x11 diff --git a/lib/libdrm/etnaviv/etnaviv_gpu.c b/lib/libdrm/etnaviv/etnaviv_gpu.c index bc355e8fc..f7efa0289 100644 --- a/lib/libdrm/etnaviv/etnaviv_gpu.c +++ b/lib/libdrm/etnaviv/etnaviv_gpu.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "etnaviv_priv.h" #include "etnaviv_drmif.h" diff --git a/lib/libdrm/etnaviv/etnaviv_perfmon.c b/lib/libdrm/etnaviv/etnaviv_perfmon.c index aa5130a65..5f408a7bc 100644 --- a/lib/libdrm/etnaviv/etnaviv_perfmon.c +++ b/lib/libdrm/etnaviv/etnaviv_perfmon.c @@ -25,10 +25,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "etnaviv_priv.h" static int etna_perfmon_query_signals(struct etna_perfmon *pm, struct etna_perfmon_domain *dom) diff --git a/lib/libdrm/etnaviv/etnaviv_pipe.c b/lib/libdrm/etnaviv/etnaviv_pipe.c index 94c5d3778..53954aa32 100644 --- a/lib/libdrm/etnaviv/etnaviv_pipe.c +++ b/lib/libdrm/etnaviv/etnaviv_pipe.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "etnaviv_priv.h" int etna_pipe_wait(struct etna_pipe *pipe, uint32_t timestamp, uint32_t ms) diff --git a/lib/libdrm/etnaviv/meson.build b/lib/libdrm/etnaviv/meson.build new file mode 100644 index 000000000..ca2aa544c --- /dev/null +++ b/lib/libdrm/etnaviv/meson.build @@ -0,0 +1,59 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +libdrm_etnaviv = shared_library( + 'drm_etnaviv', + [ + files( + 'etnaviv_device.c', 'etnaviv_gpu.c', 'etnaviv_bo.c', 'etnaviv_bo_cache.c', + 'etnaviv_perfmon.c', 'etnaviv_pipe.c', 'etnaviv_cmd_stream.c', + ), + config_file + ], + include_directories : [inc_root, inc_drm], + link_with : libdrm, + c_args : warn_c_args, + dependencies : [dep_pthread_stubs, dep_rt, dep_atomic_ops], + version : '1.0.0', + install : true, +) + +install_headers('etnaviv_drmif.h', subdir : 'libdrm') + +pkg.generate( + name : 'libdrm_etnaviv', + libraries : libdrm_etnaviv, + subdirs : ['.', 'libdrm'], + version : meson.project_version(), + requires_private : 'libdrm', + description : 'Userspace interface to Tegra kernel DRM services', +) + +ext_libdrm_etnaviv = declare_dependency( + link_with : [libdrm, libdrm_etnaviv], + include_directories : [inc_drm, include_directories('.')], +) + +test( + 'etnaviv-symbol-check', + prog_bash, + args : [files('etnaviv-symbol-check'), libdrm_etnaviv] +) diff --git a/lib/libdrm/exynos/exynos-symbol-check b/lib/libdrm/exynos/exynos-symbol-check index 9692caa68..e9f1b04d5 100755 --- a/lib/libdrm/exynos/exynos-symbol-check +++ b/lib/libdrm/exynos/exynos-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.am/libdrm_exynos*_HEADERS -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_exynos.so} | awk '{print $3}'| while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_exynos.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata diff --git a/lib/libdrm/exynos/exynos_drm.c b/lib/libdrm/exynos/exynos_drm.c index f6204f1c2..e1afef650 100644 --- a/lib/libdrm/exynos/exynos_drm.c +++ b/lib/libdrm/exynos/exynos_drm.c @@ -24,10 +24,6 @@ * Inki Dae <inki.dae@samsung.com> */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> #include <string.h> diff --git a/lib/libdrm/exynos/exynos_fimg2d.c b/lib/libdrm/exynos/exynos_fimg2d.c index 5658a48e0..bca884b9e 100644 --- a/lib/libdrm/exynos/exynos_fimg2d.c +++ b/lib/libdrm/exynos/exynos_fimg2d.c @@ -23,10 +23,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> #include <string.h> diff --git a/lib/libdrm/exynos/meson.build b/lib/libdrm/exynos/meson.build new file mode 100644 index 000000000..30d36405d --- /dev/null +++ b/lib/libdrm/exynos/meson.build @@ -0,0 +1,54 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libdrm_exynos = shared_library( + 'drm_exynos', + [files('exynos_drm.c', 'exynos_fimg2d.c'), config_file], + c_args : warn_c_args, + include_directories : [inc_root, inc_drm], + link_with : libdrm, + dependencies : [dep_pthread_stubs], + version : '1.0.0', + install : true, +) + +install_headers('exynos_drmif.h', subdir : 'libdrm') +install_headers('exynos_drm.h', 'exynos_fimg2d.h', subdir : 'exynos') + +ext_libdrm_exynos = declare_dependency( + link_with : [libdrm, libdrm_exynos], + include_directories : [inc_drm, include_directories('.')], +) + +pkg.generate( + name : 'libdrm_exynos', + libraries : libdrm_exynos, + subdirs : ['.', 'libdrm', 'exynos'], + version : '0.7', + requires_private : 'libdrm', + description : 'Userspace interface to exynos kernel DRM services', +) + +test( + 'exynos-symbol-check', + prog_bash, + env : env_test, + args : [files('exynos-symbol-check'), libdrm_exynos] +) diff --git a/lib/libdrm/freedreno/Makefile.sources b/lib/libdrm/freedreno/Makefile.sources index 68a679bf6..ca89511a0 100644 --- a/lib/libdrm/freedreno/Makefile.sources +++ b/lib/libdrm/freedreno/Makefile.sources @@ -7,7 +7,6 @@ LIBDRM_FREEDRENO_FILES := \ freedreno_bo_cache.c \ msm/msm_bo.c \ msm/msm_device.c \ - msm/msm_drm.h \ msm/msm_pipe.c \ msm/msm_priv.h \ msm/msm_ringbuffer.c diff --git a/lib/libdrm/freedreno/freedreno-symbol-check b/lib/libdrm/freedreno/freedreno-symbol-check index 6b81040c7..e732c9951 100755 --- a/lib/libdrm/freedreno/freedreno-symbol-check +++ b/lib/libdrm/freedreno/freedreno-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata @@ -18,10 +18,12 @@ fd_bo_from_dmabuf fd_bo_from_fbdev fd_bo_from_handle fd_bo_from_name +fd_bo_get_iova fd_bo_get_name fd_bo_handle fd_bo_map fd_bo_new +fd_bo_put_iova fd_bo_ref fd_bo_size fd_device_del @@ -34,6 +36,7 @@ fd_pipe_del fd_pipe_get_param fd_pipe_new fd_pipe_new2 +fd_pipe_ref fd_pipe_wait fd_pipe_wait_timeout fd_ringbuffer_cmd_count @@ -43,10 +46,12 @@ fd_ringbuffer_emit_reloc_ring_full fd_ringbuffer_flush fd_ringbuffer_grow fd_ringbuffer_new +fd_ringbuffer_new_object fd_ringbuffer_reloc fd_ringbuffer_reloc2 fd_ringbuffer_reset fd_ringbuffer_set_parent +fd_ringbuffer_size fd_ringbuffer_timestamp fd_ringmarker_del fd_ringmarker_dwords diff --git a/lib/libdrm/freedreno/freedreno_bo.c b/lib/libdrm/freedreno/freedreno_bo.c index 7f8ea59c2..34c285fbd 100644 --- a/lib/libdrm/freedreno/freedreno_bo.c +++ b/lib/libdrm/freedreno/freedreno_bo.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "freedreno_drmif.h" #include "freedreno_priv.h" @@ -195,6 +191,16 @@ out_unlock: return bo; } +uint64_t fd_bo_get_iova(struct fd_bo *bo) +{ + return bo->funcs->iova(bo); +} + +void fd_bo_put_iova(struct fd_bo *bo) +{ + /* currently a no-op */ +} + struct fd_bo * fd_bo_ref(struct fd_bo *bo) { atomic_inc(&bo->refcnt); @@ -326,7 +332,7 @@ void fd_bo_cpu_fini(struct fd_bo *bo) bo->funcs->cpu_fini(bo); } -#ifndef HAVE_FREEDRENO_KGSL +#if !HAVE_FREEDRENO_KGSL struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size) { return NULL; diff --git a/lib/libdrm/freedreno/freedreno_bo_cache.c b/lib/libdrm/freedreno/freedreno_bo_cache.c index d922f3a90..3b737159c 100644 --- a/lib/libdrm/freedreno/freedreno_bo_cache.c +++ b/lib/libdrm/freedreno/freedreno_bo_cache.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "freedreno_drmif.h" #include "freedreno_priv.h" diff --git a/lib/libdrm/freedreno/freedreno_device.c b/lib/libdrm/freedreno/freedreno_device.c index 12b95fd02..0b42561a4 100644 --- a/lib/libdrm/freedreno/freedreno_device.c +++ b/lib/libdrm/freedreno/freedreno_device.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> @@ -65,7 +61,7 @@ struct fd_device * fd_device_new(int fd) dev = msm_device_new(fd); dev->version = version->version_minor; -#ifdef HAVE_FREEDRENO_KGSL +#if HAVE_FREEDRENO_KGSL } else if (!strcmp(version->name, "kgsl")) { DEBUG_MSG("kgsl DRM device"); dev = kgsl_device_new(fd); diff --git a/lib/libdrm/freedreno/freedreno_drmif.h b/lib/libdrm/freedreno/freedreno_drmif.h index c3b0d02a3..c95c21be0 100644 --- a/lib/libdrm/freedreno/freedreno_drmif.h +++ b/lib/libdrm/freedreno/freedreno_drmif.h @@ -95,6 +95,7 @@ enum fd_version { FD_VERSION_UNLIMITED_CMDS = 1, /* submits w/ >4 cmd buffers (growable ringbuffer) */ FD_VERSION_FENCE_FD = 2, /* submit command supports in/out fences */ FD_VERSION_SUBMIT_QUEUES = 3, /* submit queues and multiple priority levels */ + FD_VERSION_BO_IOVA = 3, /* supports fd_bo_get/put_iova() */ }; enum fd_version fd_device_version(struct fd_device *dev); @@ -103,6 +104,7 @@ enum fd_version fd_device_version(struct fd_device *dev); struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio); +struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe); void fd_pipe_del(struct fd_pipe *pipe); int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value); @@ -123,6 +125,8 @@ struct fd_bo *fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size); struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name); struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd); +uint64_t fd_bo_get_iova(struct fd_bo *bo); +void fd_bo_put_iova(struct fd_bo *bo); struct fd_bo * fd_bo_ref(struct fd_bo *bo); void fd_bo_del(struct fd_bo *bo); int fd_bo_get_name(struct fd_bo *bo, uint32_t *name); diff --git a/lib/libdrm/freedreno/freedreno_pipe.c b/lib/libdrm/freedreno/freedreno_pipe.c index 1540474bd..30d231c7d 100644 --- a/lib/libdrm/freedreno/freedreno_pipe.c +++ b/lib/libdrm/freedreno/freedreno_pipe.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "freedreno_drmif.h" #include "freedreno_priv.h" @@ -61,6 +57,7 @@ fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio) pipe->dev = dev; pipe->id = id; + atomic_set(&pipe->refcnt, 1); fd_pipe_get_param(pipe, FD_GPU_ID, &val); pipe->gpu_id = val; @@ -74,8 +71,16 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) return fd_pipe_new2(dev, id, 1); } +struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe) +{ + atomic_inc(&pipe->refcnt); + return pipe; +} + void fd_pipe_del(struct fd_pipe *pipe) { + if (!atomic_dec_and_test(&pipe->refcnt)) + return; pipe->funcs->destroy(pipe); } diff --git a/lib/libdrm/freedreno/freedreno_priv.h b/lib/libdrm/freedreno/freedreno_priv.h index 273074727..9d51c368b 100644 --- a/lib/libdrm/freedreno/freedreno_priv.h +++ b/lib/libdrm/freedreno/freedreno_priv.h @@ -29,10 +29,6 @@ #ifndef FREEDRENO_PRIV_H_ #define FREEDRENO_PRIV_H_ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <errno.h> #include <string.h> @@ -49,6 +45,7 @@ #include "xf86atomic.h" #include "util_double_list.h" +#include "util_math.h" #include "freedreno_drmif.h" #include "freedreno_ringbuffer.h" @@ -117,8 +114,13 @@ drm_private int fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo); /* for where @table_lock is already held: */ drm_private void fd_device_del_locked(struct fd_device *dev); +enum fd_ringbuffer_flags { + FD_RINGBUFFER_OBJECT = 0x1, +}; + struct fd_pipe_funcs { - struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size); + struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size, + enum fd_ringbuffer_flags flags); int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value); int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout); void (*destroy)(struct fd_pipe *pipe); @@ -128,6 +130,7 @@ struct fd_pipe { struct fd_device *dev; enum fd_pipe_id id; uint32_t gpu_id; + atomic_t refcnt; const struct fd_pipe_funcs *funcs; }; @@ -156,6 +159,7 @@ struct fd_bo_funcs { int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); void (*cpu_fini)(struct fd_bo *bo); int (*madvise)(struct fd_bo *bo, int willneed); + uint64_t (*iova)(struct fd_bo *bo); void (*destroy)(struct fd_bo *bo); }; @@ -173,7 +177,6 @@ struct fd_bo { time_t free_time; /* time when added to bucket-list */ }; -#define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1)) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define enable_debug 0 /* TODO make dynamic */ @@ -200,7 +203,7 @@ offset_bytes(void *end, void *start) return ((char *)end) - ((char *)start); } -#ifdef HAVE_VALGRIND +#if HAVE_VALGRIND # include <memcheck.h> /* diff --git a/lib/libdrm/freedreno/freedreno_ringbuffer.c b/lib/libdrm/freedreno/freedreno_ringbuffer.c index 7310f1fd4..eb6cd0ca1 100644 --- a/lib/libdrm/freedreno/freedreno_ringbuffer.c +++ b/lib/libdrm/freedreno/freedreno_ringbuffer.c @@ -26,25 +26,23 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <assert.h> #include "freedreno_drmif.h" #include "freedreno_priv.h" #include "freedreno_ringbuffer.h" -struct fd_ringbuffer * -fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size) +static struct fd_ringbuffer * +ringbuffer_new(struct fd_pipe *pipe, uint32_t size, + enum fd_ringbuffer_flags flags) { struct fd_ringbuffer *ring; - ring = pipe->funcs->ringbuffer_new(pipe, size); + ring = pipe->funcs->ringbuffer_new(pipe, size, flags); if (!ring) return NULL; + ring->flags = flags; ring->pipe = pipe; ring->start = ring->funcs->hostptr(ring); ring->end = &(ring->start[ring->size/4]); @@ -54,9 +52,27 @@ fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size) return ring; } +struct fd_ringbuffer * +fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size) +{ + return ringbuffer_new(pipe, size, 0); +} + +struct fd_ringbuffer * +fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size) +{ + /* we can't really support "growable" rb's in general for + * stateobj's since we need a single gpu addr (ie. can't + * do the trick of a chain of IB packets): + */ + assert(size); + return ringbuffer_new(pipe, size, FD_RINGBUFFER_OBJECT); +} + void fd_ringbuffer_del(struct fd_ringbuffer *ring) { - fd_ringbuffer_reset(ring); + if (!(ring->flags & FD_RINGBUFFER_OBJECT)) + fd_ringbuffer_reset(ring); ring->funcs->destroy(ring); } @@ -67,6 +83,8 @@ void fd_ringbuffer_del(struct fd_ringbuffer *ring) void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring, struct fd_ringbuffer *parent) { + /* state objects should not be parented! */ + assert(!(ring->flags & FD_RINGBUFFER_OBJECT)); ring->parent = parent; } @@ -155,6 +173,21 @@ fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring, return ring->funcs->emit_reloc_ring(ring, target, cmd_idx, 0, size); } +uint32_t +fd_ringbuffer_size(struct fd_ringbuffer *ring) +{ + /* only really needed for stateobj ringbuffers, and won't really + * do what you expect for growable rb's.. so lets just restrict + * this to stateobj's for now: + */ + assert(ring->flags & FD_RINGBUFFER_OBJECT); + return offset_bytes(ring->cur, ring->start); +} + +/* + * Deprecated ringmarker API: + */ + struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring) { struct fd_ringmarker *marker = NULL; diff --git a/lib/libdrm/freedreno/freedreno_ringbuffer.h b/lib/libdrm/freedreno/freedreno_ringbuffer.h index c501fbadb..69e7ed997 100644 --- a/lib/libdrm/freedreno/freedreno_ringbuffer.h +++ b/lib/libdrm/freedreno/freedreno_ringbuffer.h @@ -33,8 +33,7 @@ /* the ringbuffer object is not opaque so that OUT_RING() type stuff * can be inlined. Note that users should not make assumptions about - * the size of this struct.. more stuff will be added when we eventually - * have a kernel driver that can deal w/ reloc's.. + * the size of this struct. */ struct fd_ringbuffer_funcs; @@ -47,10 +46,20 @@ struct fd_ringbuffer { const struct fd_ringbuffer_funcs *funcs; uint32_t last_timestamp; struct fd_ringbuffer *parent; + + /* for users of fd_ringbuffer to store their own private per- + * ringbuffer data + */ + void *user; + + uint32_t flags; }; struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size); +struct fd_ringbuffer * fd_ringbuffer_new_object(struct fd_pipe *pipe, + uint32_t size); + void fd_ringbuffer_del(struct fd_ringbuffer *ring); void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring, struct fd_ringbuffer *parent); @@ -90,6 +99,7 @@ will_be_deprecated void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring); uint32_t fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring, struct fd_ringbuffer *target, uint32_t cmd_idx); +uint32_t fd_ringbuffer_size(struct fd_ringbuffer *ring); will_be_deprecated struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring); will_be_deprecated void fd_ringmarker_del(struct fd_ringmarker *marker); diff --git a/lib/libdrm/freedreno/kgsl/kgsl_bo.c b/lib/libdrm/freedreno/kgsl/kgsl_bo.c index ab3485e36..c6d2d4999 100644 --- a/lib/libdrm/freedreno/kgsl/kgsl_bo.c +++ b/lib/libdrm/freedreno/kgsl/kgsl_bo.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "kgsl_priv.h" #include <linux/fb.h> diff --git a/lib/libdrm/freedreno/kgsl/kgsl_device.c b/lib/libdrm/freedreno/kgsl/kgsl_device.c index 958e8a728..914f3412d 100644 --- a/lib/libdrm/freedreno/kgsl/kgsl_device.c +++ b/lib/libdrm/freedreno/kgsl/kgsl_device.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> diff --git a/lib/libdrm/freedreno/kgsl/kgsl_pipe.c b/lib/libdrm/freedreno/kgsl/kgsl_pipe.c index 80bd13133..0a8b6586d 100644 --- a/lib/libdrm/freedreno/kgsl/kgsl_pipe.c +++ b/lib/libdrm/freedreno/kgsl/kgsl_pipe.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "kgsl_priv.h" diff --git a/lib/libdrm/freedreno/kgsl/kgsl_priv.h b/lib/libdrm/freedreno/kgsl/kgsl_priv.h index 41b13920e..a6bf2d40c 100644 --- a/lib/libdrm/freedreno/kgsl/kgsl_priv.h +++ b/lib/libdrm/freedreno/kgsl/kgsl_priv.h @@ -106,7 +106,7 @@ drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio); drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size); + uint32_t size, enum fd_ringbuffer_flags flags); drm_private int kgsl_bo_new_handle(struct fd_device *dev, uint32_t size, uint32_t flags, uint32_t *handle); diff --git a/lib/libdrm/freedreno/kgsl/kgsl_ringbuffer.c b/lib/libdrm/freedreno/kgsl/kgsl_ringbuffer.c index f09c433bb..e4fdf342b 100644 --- a/lib/libdrm/freedreno/kgsl/kgsl_ringbuffer.c +++ b/lib/libdrm/freedreno/kgsl/kgsl_ringbuffer.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <assert.h> #include "freedreno_ringbuffer.h" @@ -206,11 +202,13 @@ static const struct fd_ringbuffer_funcs funcs = { }; drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size) + uint32_t size, enum fd_ringbuffer_flags flags) { struct kgsl_ringbuffer *kgsl_ring; struct fd_ringbuffer *ring = NULL; + assert(!flags); + kgsl_ring = calloc(1, sizeof(*kgsl_ring)); if (!kgsl_ring) { ERROR_MSG("allocation failed"); diff --git a/lib/libdrm/freedreno/meson.build b/lib/libdrm/freedreno/meson.build new file mode 100644 index 000000000..015b7fb1c --- /dev/null +++ b/lib/libdrm/freedreno/meson.build @@ -0,0 +1,77 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_freedreno = files( + 'freedreno_device.c', + 'freedreno_pipe.c', + 'freedreno_ringbuffer.c', + 'freedreno_bo.c', + 'freedreno_bo_cache.c', + 'msm/msm_bo.c', + 'msm/msm_device.c', + 'msm/msm_pipe.c', + 'msm/msm_ringbuffer.c', +) + +if with_freedreno_kgsl + files_freedreno += files( + 'kgsl/kgsl_bo.c', + 'kgsl/kgsl_device.c', + 'kgsl/kgsl_pipe.c', + 'kgsl/kgsl_ringbuffer.c', + ) +endif + +libdrm_freedreno = shared_library( + 'drm_freedreno', + [files_freedreno, config_file], + c_args : warn_c_args, + include_directories : [inc_root, inc_drm], + dependencies : [dep_valgrind, dep_pthread_stubs, dep_rt, dep_atomic_ops], + link_with : libdrm, + version : '1.0.0', + install : true, +) + +ext_libdrm_freedreno = declare_dependency( + link_with : [libdrm, libdrm_freedreno], + include_directories : [inc_drm, include_directories('.')], +) + +install_headers( + 'freedreno_drmif.h', 'freedreno_ringbuffer.h', + subdir : 'freedreno' +) + +pkg.generate( + name : 'libdrm_freedreno', + libraries : libdrm_freedreno, + subdirs : ['.', 'libdrm', 'freedreno'], + version : meson.project_version(), + requires_private : 'libdrm', + description : 'Userspace interface to freedreno kernel DRM services', +) + +test( + 'freedreno-symbol-check', + prog_bash, + env : env_test, + args : [files('freedreno-symbol-check'), libdrm_freedreno] +) diff --git a/lib/libdrm/freedreno/msm/msm_bo.c b/lib/libdrm/freedreno/msm/msm_bo.c index 72471df65..8b3d0bcbd 100644 --- a/lib/libdrm/freedreno/msm/msm_bo.c +++ b/lib/libdrm/freedreno/msm/msm_bo.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "msm_priv.h" static int bo_allocate(struct msm_bo *msm_bo) @@ -108,6 +104,18 @@ static int msm_bo_madvise(struct fd_bo *bo, int willneed) return req.retained; } +static uint64_t msm_bo_iova(struct fd_bo *bo) +{ + struct drm_msm_gem_info req = { + .handle = bo->handle, + .flags = MSM_INFO_IOVA, + }; + + drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req)); + + return req.offset; +} + static void msm_bo_destroy(struct fd_bo *bo) { struct msm_bo *msm_bo = to_msm_bo(bo); @@ -120,6 +128,7 @@ static const struct fd_bo_funcs funcs = { .cpu_prep = msm_bo_cpu_prep, .cpu_fini = msm_bo_cpu_fini, .madvise = msm_bo_madvise, + .iova = msm_bo_iova, .destroy = msm_bo_destroy, }; diff --git a/lib/libdrm/freedreno/msm/msm_device.c b/lib/libdrm/freedreno/msm/msm_device.c index c454938d4..7bb576774 100644 --- a/lib/libdrm/freedreno/msm/msm_device.c +++ b/lib/libdrm/freedreno/msm/msm_device.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> diff --git a/lib/libdrm/freedreno/msm/msm_pipe.c b/lib/libdrm/freedreno/msm/msm_pipe.c index 7395e573f..f28778ef9 100644 --- a/lib/libdrm/freedreno/msm/msm_pipe.c +++ b/lib/libdrm/freedreno/msm/msm_pipe.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include "msm_priv.h" static int query_param(struct fd_pipe *pipe, uint32_t param, @@ -100,42 +96,48 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp, return 0; } -static int open_submitqueue(struct fd_device *dev, uint32_t prio, - uint32_t *queue_id) +static int open_submitqueue(struct fd_pipe *pipe, uint32_t prio) { struct drm_msm_submitqueue req = { .flags = 0, .prio = prio, }; + uint64_t nr_rings = 1; int ret; - if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) { - *queue_id = 0; + if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) { + to_msm_pipe(pipe)->queue_id = 0; return 0; } - ret = drmCommandWriteRead(dev->fd, DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req)); + msm_pipe_get_param(pipe, FD_NR_RINGS, &nr_rings); + + req.prio = MIN2(req.prio, MAX2(nr_rings, 1) - 1); + + ret = drmCommandWriteRead(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_NEW, + &req, sizeof(req)); if (ret) { ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno)); return ret; } - *queue_id = req.id; + to_msm_pipe(pipe)->queue_id = req.id; return 0; } -static void close_submitqueue(struct fd_device *dev, uint32_t queue_id) +static void close_submitqueue(struct fd_pipe *pipe, uint32_t queue_id) { - if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) + if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) return; - drmCommandWrite(dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, &queue_id, sizeof(queue_id)); + drmCommandWrite(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, + &queue_id, sizeof(queue_id)); } static void msm_pipe_destroy(struct fd_pipe *pipe) { struct msm_pipe *msm_pipe = to_msm_pipe(pipe); - close_submitqueue(pipe->dev, msm_pipe->queue_id); + close_submitqueue(pipe, msm_pipe->queue_id); free(msm_pipe); } @@ -193,7 +195,7 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id); INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem); - if (open_submitqueue(dev, prio, &msm_pipe->queue_id)) + if (open_submitqueue(pipe, prio)) goto fail; return pipe; diff --git a/lib/libdrm/freedreno/msm/msm_priv.h b/lib/libdrm/freedreno/msm/msm_priv.h index 88ac3aa42..ee0eecb83 100644 --- a/lib/libdrm/freedreno/msm/msm_priv.h +++ b/lib/libdrm/freedreno/msm/msm_priv.h @@ -68,7 +68,7 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio); drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size); + uint32_t size, enum fd_ringbuffer_flags flags); struct msm_bo { struct fd_bo base; @@ -101,4 +101,30 @@ static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns) tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000); } +/* + * Stupid/simple growable array implementation: + */ + +static inline void * +grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz) +{ + if ((nr + 1) > *max) { + if ((*max * 2) < (nr + 1)) + *max = nr + 5; + else + *max = *max * 2; + ptr = realloc(ptr, *max * sz); + } + return ptr; +} + +#define DECLARE_ARRAY(type, name) \ + unsigned nr_ ## name, max_ ## name; \ + type * name; + +#define APPEND(x, name) ({ \ + (x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \ + (x)->nr_ ## name ++; \ +}) + #endif /* MSM_PRIV_H_ */ diff --git a/lib/libdrm/freedreno/msm/msm_ringbuffer.c b/lib/libdrm/freedreno/msm/msm_ringbuffer.c index c75bb1692..35a7a7d44 100644 --- a/lib/libdrm/freedreno/msm/msm_ringbuffer.c +++ b/lib/libdrm/freedreno/msm/msm_ringbuffer.c @@ -26,10 +26,6 @@ * Rob Clark <robclark@freedesktop.org> */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <assert.h> #include <inttypes.h> @@ -46,8 +42,7 @@ struct msm_cmd { struct fd_bo *ring_bo; /* reloc's table: */ - struct drm_msm_gem_submit_reloc *relocs; - uint32_t nr_relocs, max_relocs; + DECLARE_ARRAY(struct drm_msm_gem_submit_reloc, relocs); uint32_t size; }; @@ -55,6 +50,8 @@ struct msm_cmd { struct msm_ringbuffer { struct fd_ringbuffer base; + atomic_t refcnt; + /* submit ioctl related tables: * Note that bos and cmds are tracked by the parent ringbuffer, since * that is global to the submit ioctl call. The reloc's table is tracked @@ -62,22 +59,18 @@ struct msm_ringbuffer { */ struct { /* bo's table: */ - struct drm_msm_gem_submit_bo *bos; - uint32_t nr_bos, max_bos; + DECLARE_ARRAY(struct drm_msm_gem_submit_bo, bos); /* cmd's table: */ - struct drm_msm_gem_submit_cmd *cmds; - uint32_t nr_cmds, max_cmds; + DECLARE_ARRAY(struct drm_msm_gem_submit_cmd, cmds); } submit; /* should have matching entries in submit.bos: */ /* Note, only in parent ringbuffer */ - struct fd_bo **bos; - uint32_t nr_bos, max_bos; + DECLARE_ARRAY(struct fd_bo *, bos); /* should have matching entries in submit.cmds: */ - struct msm_cmd **cmds; - uint32_t nr_cmds, max_cmds; + DECLARE_ARRAY(struct msm_cmd *, cmds); /* List of physical cmdstream buffers (msm_cmd) assocated with this * logical fd_ringbuffer. @@ -104,6 +97,9 @@ static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x) return (struct msm_ringbuffer *)x; } +static void msm_ringbuffer_unref(struct fd_ringbuffer *ring); +static void msm_ringbuffer_ref(struct fd_ringbuffer *ring); + #define INIT_SIZE 0x1000 static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER; @@ -113,6 +109,8 @@ static void ring_bo_del(struct fd_device *dev, struct fd_bo *bo) { int ret; + assert(atomic_read(&bo->refcnt) == 1); + pthread_mutex_lock(&table_lock); ret = fd_bo_cache_free(&to_msm_device(dev)->ring_cache, bo); pthread_mutex_unlock(&table_lock); @@ -174,23 +172,6 @@ fail: return NULL; } -static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz) -{ - if ((nr + 1) > *max) { - if ((*max * 2) < (nr + 1)) - *max = nr + 5; - else - *max = *max * 2; - ptr = realloc(ptr, *max * sz); - } - return ptr; -} - -#define APPEND(x, name) ({ \ - (x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \ - (x)->nr_ ## name ++; \ -}) - static struct msm_cmd *current_cmd(struct fd_ringbuffer *ring) { struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); @@ -258,8 +239,11 @@ static int check_cmd_bo(struct fd_ringbuffer *ring, /* Ensure that submit has corresponding entry in cmds table for the * target cmdstream buffer: + * + * Returns TRUE if new cmd added (else FALSE if it was already in + * the cmds table) */ -static void get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd, +static int get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd, uint32_t submit_offset, uint32_t size, uint32_t type) { struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); @@ -273,7 +257,7 @@ static void get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd, (cmd->size == size) && (cmd->type == type) && check_cmd_bo(ring, cmd, target_cmd->ring_bo)) - return; + return FALSE; } /* create cmd buf if not: */ @@ -288,6 +272,8 @@ static void get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd, cmd->pad = 0; target_cmd->size = size; + + return TRUE; } static void * msm_ringbuffer_hostptr(struct fd_ringbuffer *ring) @@ -326,6 +312,8 @@ static void flush_reset(struct fd_ringbuffer *ring) for (i = 0; i < msm_ring->nr_bos; i++) { struct msm_bo *msm_bo = to_msm_bo(msm_ring->bos[i]); + if (!msm_bo) + continue; msm_bo->current_ring_seqno = 0; fd_bo_del(&msm_bo->base); } @@ -333,6 +321,8 @@ static void flush_reset(struct fd_ringbuffer *ring) /* for each of the cmd buffers, clear their reloc's: */ for (i = 0; i < msm_ring->submit.nr_cmds; i++) { struct msm_cmd *target_cmd = msm_ring->cmds[i]; + if (!target_cmd) + continue; target_cmd->nr_relocs = 0; } @@ -395,6 +385,31 @@ static void dump_submit(struct msm_ringbuffer *msm_ring) } } +static struct drm_msm_gem_submit_reloc * +handle_stateobj_relocs(struct fd_ringbuffer *parent, struct fd_ringbuffer *stateobj, + struct drm_msm_gem_submit_reloc *orig_relocs, unsigned nr_relocs) +{ + struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(stateobj); + struct drm_msm_gem_submit_reloc *relocs = malloc(nr_relocs * sizeof(*relocs)); + unsigned i; + + for (i = 0; i < nr_relocs; i++) { + unsigned idx = orig_relocs[i].reloc_idx; + struct fd_bo *bo = msm_ring->bos[idx]; + unsigned flags = 0; + + if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_READ) + flags |= FD_RELOC_READ; + if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_WRITE) + flags |= FD_RELOC_WRITE; + + relocs[i] = orig_relocs[i]; + relocs[i].reloc_idx = bo2idx(parent, bo, flags); + } + + return relocs; +} + static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start, int in_fence_fd, int *out_fence_fd) { @@ -406,6 +421,8 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start uint32_t i; int ret; + assert(!ring->parent); + if (in_fence_fd != -1) { req.flags |= MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_NO_IMPLICIT; req.fence_fd = in_fence_fd; @@ -417,22 +434,36 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start finalize_current_cmd(ring, last_start); - /* needs to be after get_cmd() as that could create bos/cmds table: */ - req.bos = VOID2U64(msm_ring->submit.bos), - req.nr_bos = msm_ring->submit.nr_bos; - req.cmds = VOID2U64(msm_ring->submit.cmds), - req.nr_cmds = msm_ring->submit.nr_cmds; - /* for each of the cmd's fix up their reloc's: */ for (i = 0; i < msm_ring->submit.nr_cmds; i++) { struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i]; struct msm_cmd *msm_cmd = msm_ring->cmds[i]; uint32_t a = find_next_reloc_idx(msm_cmd, 0, cmd->submit_offset); uint32_t b = find_next_reloc_idx(msm_cmd, a, cmd->submit_offset + cmd->size); - cmd->relocs = VOID2U64(&msm_cmd->relocs[a]); - cmd->nr_relocs = (b > a) ? b - a : 0; + struct drm_msm_gem_submit_reloc *relocs = &msm_cmd->relocs[a]; + unsigned nr_relocs = (b > a) ? b - a : 0; + + /* for reusable stateobjs, the reloc table has reloc_idx that + * points into it's own private bos table, rather than the global + * bos table used for the submit, so we need to add the stateobj's + * bos to the global table and construct new relocs table with + * corresponding reloc_idx + */ + if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) { + relocs = handle_stateobj_relocs(ring, msm_cmd->ring, + relocs, nr_relocs); + } + + cmd->relocs = VOID2U64(relocs); + cmd->nr_relocs = nr_relocs; } + /* needs to be after get_cmd() as that could create bos/cmds table: */ + req.bos = VOID2U64(msm_ring->submit.bos), + req.nr_bos = msm_ring->submit.nr_bos; + req.cmds = VOID2U64(msm_ring->submit.cmds), + req.nr_cmds = msm_ring->submit.nr_cmds; + DEBUG_MSG("nr_cmds=%u, nr_bos=%u", req.nr_cmds, req.nr_bos); ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT, @@ -452,6 +483,26 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start } } + /* free dynamically constructed stateobj relocs tables: */ + for (i = 0; i < msm_ring->submit.nr_cmds; i++) { + struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i]; + struct msm_cmd *msm_cmd = msm_ring->cmds[i]; + if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) { + /* we could have dropped last reference: */ + msm_ring->cmds[i] = NULL; + + /* need to drop ring_bo ref prior to unref'ing the ring, + * because ring_bo_del assumes it is dropping the *last* + * reference: + */ + fd_bo_del(msm_ring->bos[cmd->submit_idx]); + msm_ring->bos[cmd->submit_idx] = NULL; + + msm_ringbuffer_unref(msm_cmd->ring); + free(U642VOID(cmd->relocs)); + } + } + flush_reset(ring); return ret; @@ -527,6 +578,7 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, { struct msm_cmd *cmd = NULL; uint32_t idx = 0; + int added_cmd = FALSE; LIST_FOR_EACH_ENTRY(cmd, &to_msm_ringbuffer(target)->cmd_list, list) { if (idx == cmd_idx) @@ -544,7 +596,9 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, */ size = cmd->size; } else { - get_cmd(ring, cmd, submit_offset, size, MSM_SUBMIT_CMD_IB_TARGET_BUF); + struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring; + added_cmd = get_cmd(parent, cmd, submit_offset, size, + MSM_SUBMIT_CMD_IB_TARGET_BUF); } msm_ringbuffer_emit_reloc(ring, &(struct fd_reloc){ @@ -553,6 +607,14 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, .offset = submit_offset, }); + /* Unlike traditional ringbuffers which are deleted as a set (after + * being flushed), mesa can't really guarantee that a stateobj isn't + * destroyed after emitted but before flush, so we must hold a ref: + */ + if (added_cmd && (target->flags & FD_RINGBUFFER_OBJECT)) { + msm_ringbuffer_ref(target); + } + return size; } @@ -561,10 +623,13 @@ static uint32_t msm_ringbuffer_cmd_count(struct fd_ringbuffer *ring) return to_msm_ringbuffer(ring)->cmd_count; } -static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring) +static void msm_ringbuffer_unref(struct fd_ringbuffer *ring) { struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); + if (!atomic_dec_and_test(&msm_ring->refcnt)) + return; + flush_reset(ring); delete_cmds(msm_ring); @@ -575,6 +640,12 @@ static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring) free(msm_ring); } +static void msm_ringbuffer_ref(struct fd_ringbuffer *ring) +{ + struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); + atomic_inc(&msm_ring->refcnt); +} + static const struct fd_ringbuffer_funcs funcs = { .hostptr = msm_ringbuffer_hostptr, .flush = msm_ringbuffer_flush, @@ -583,11 +654,11 @@ static const struct fd_ringbuffer_funcs funcs = { .emit_reloc = msm_ringbuffer_emit_reloc, .emit_reloc_ring = msm_ringbuffer_emit_reloc_ring, .cmd_count = msm_ringbuffer_cmd_count, - .destroy = msm_ringbuffer_destroy, + .destroy = msm_ringbuffer_unref, }; drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size) + uint32_t size, enum fd_ringbuffer_flags flags) { struct msm_ringbuffer *msm_ring; struct fd_ringbuffer *ring; @@ -606,6 +677,7 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, list_inithead(&msm_ring->cmd_list); msm_ring->seqno = ++to_msm_device(pipe->dev)->ring_cnt; + atomic_set(&msm_ring->refcnt, 1); ring = &msm_ring->base; ring->funcs = &funcs; diff --git a/lib/libdrm/include/drm/README b/lib/libdrm/include/drm/README index 5b518ddf8..521630db8 100644 --- a/lib/libdrm/include/drm/README +++ b/lib/libdrm/include/drm/README @@ -91,14 +91,10 @@ Most UMS headers: Status: ? Promote to fixed size ints, which match the current (32bit) ones. -i915_drm.h - - Missing PARAMS - HAS_POOLED_EU, MIN_EU_IN_POOL CONTEXT_PARAM_NO_ERROR_CAPTURE -Status: Trivial. - nouveau_drm.h - Missing macros NOUVEAU_GETPARAM*, NOUVEAU_DRM_HEADER_PATCHLEVEL, structs, enums -Status: ? +Status: Deliberate UABI choice; nouveau hides the exact kernel ABI behind libdrm r128_drm.h - Broken compat ioctls. @@ -126,11 +122,6 @@ omap_drm.h (living in $TOP/omap) - License mismatch, missing DRM_IOCTL_OMAP_GEM_NEW and related struct Status: ? -msm_drm.h (located in $TOP/freedreno/msm/) - - License mismatch, missing MSM_PIPE_*, MSM_SUBMIT_*. Renamed -drm_msm_gem_submit::flags, missing drm_msm_gem_submit::fence_fd. -Status: ? - exynos_drm.h (living in $TOP/exynos) - License mismatch, now using fixed size ints (but not everywhere). Lots of new stuff. diff --git a/lib/libdrm/include/drm/amdgpu_drm.h b/lib/libdrm/include/drm/amdgpu_drm.h index 919248fb4..c363b67f2 100644 --- a/lib/libdrm/include/drm/amdgpu_drm.h +++ b/lib/libdrm/include/drm/amdgpu_drm.h @@ -160,6 +160,7 @@ union drm_amdgpu_bo_list { #define AMDGPU_CTX_OP_ALLOC_CTX 1 #define AMDGPU_CTX_OP_FREE_CTX 2 #define AMDGPU_CTX_OP_QUERY_STATE 3 +#define AMDGPU_CTX_OP_QUERY_STATE2 4 /* GPU reset status */ #define AMDGPU_CTX_NO_RESET 0 @@ -170,6 +171,13 @@ union drm_amdgpu_bo_list { /* unknown cause */ #define AMDGPU_CTX_UNKNOWN_RESET 3 +/* indicate gpu reset occured after ctx created */ +#define AMDGPU_CTX_QUERY2_FLAGS_RESET (1<<0) +/* indicate vram lost occured after ctx created */ +#define AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST (1<<1) +/* indicate some job from this context once cause gpu hang */ +#define AMDGPU_CTX_QUERY2_FLAGS_GUILTY (1<<2) + /* Context priority level */ #define AMDGPU_CTX_PRIORITY_UNSET -2048 #define AMDGPU_CTX_PRIORITY_VERY_LOW -1023 @@ -610,6 +618,8 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_FW_SOS 0x0c /* Subquery id: Query PSP ASD firmware version */ #define AMDGPU_INFO_FW_ASD 0x0d + /* Subquery id: Query VCN firmware version */ + #define AMDGPU_INFO_FW_VCN 0x0e /* number of bytes moved for TTM migration */ #define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f /* the used VRAM size */ @@ -656,6 +666,10 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_SENSOR_VDDNB 0x6 /* Subquery id: Query graphics voltage */ #define AMDGPU_INFO_SENSOR_VDDGFX 0x7 + /* Subquery id: Query GPU stable pstate shader clock */ + #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK 0x8 + /* Subquery id: Query GPU stable pstate memory clock */ + #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9 /* Number of VRAM page faults on CPU access. */ #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E #define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F @@ -794,6 +808,7 @@ struct drm_amdgpu_info_firmware { #define AMDGPU_VRAM_TYPE_GDDR5 5 #define AMDGPU_VRAM_TYPE_HBM 6 #define AMDGPU_VRAM_TYPE_DDR3 7 +#define AMDGPU_VRAM_TYPE_DDR4 8 struct drm_amdgpu_info_device { /** PCI Device ID */ @@ -869,6 +884,10 @@ struct drm_amdgpu_info_device { __u32 _pad1; /* always on cu bitmap */ __u32 cu_ao_bitmap[4][4]; + /** Starting high virtual address for UMDs. */ + __u64 high_va_offset; + /** The maximum high virtual address */ + __u64 high_va_max; }; struct drm_amdgpu_info_hw_ip { diff --git a/lib/libdrm/include/drm/drm_fourcc.h b/lib/libdrm/include/drm/drm_fourcc.h index 3ad838d3f..e04613d30 100644 --- a/lib/libdrm/include/drm/drm_fourcc.h +++ b/lib/libdrm/include/drm/drm_fourcc.h @@ -178,7 +178,7 @@ extern "C" { #define DRM_FORMAT_MOD_VENDOR_NONE 0 #define DRM_FORMAT_MOD_VENDOR_INTEL 0x01 #define DRM_FORMAT_MOD_VENDOR_AMD 0x02 -#define DRM_FORMAT_MOD_VENDOR_NV 0x03 +#define DRM_FORMAT_MOD_VENDOR_NVIDIA 0x03 #define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04 #define DRM_FORMAT_MOD_VENDOR_QCOM 0x05 #define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06 @@ -188,7 +188,7 @@ extern "C" { #define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) #define fourcc_mod_code(vendor, val) \ - ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) + ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | ((val) & 0x00ffffffffffffffULL)) /* * Format Modifier tokens: @@ -338,29 +338,17 @@ extern "C" { */ #define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4) -/* NVIDIA Tegra frame buffer modifiers */ - -/* - * Some modifiers take parameters, for example the number of vertical GOBs in - * a block. Reserve the lower 32 bits for parameters - */ -#define __fourcc_mod_tegra_mode_shift 32 -#define fourcc_mod_tegra_code(val, params) \ - fourcc_mod_code(NV, ((((__u64)val) << __fourcc_mod_tegra_mode_shift) | params)) -#define fourcc_mod_tegra_mod(m) \ - (m & ~((1ULL << __fourcc_mod_tegra_mode_shift) - 1)) -#define fourcc_mod_tegra_param(m) \ - (m & ((1ULL << __fourcc_mod_tegra_mode_shift) - 1)) +/* NVIDIA frame buffer modifiers */ /* * Tegra Tiled Layout, used by Tegra 2, 3 and 4. * * Pixels are arranged in simple tiles of 16 x 16 bytes. */ -#define NV_FORMAT_MOD_TEGRA_TILED fourcc_mod_tegra_code(1, 0) +#define DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1) /* - * Tegra 16Bx2 Block Linear layout, used by TK1/TX1 + * 16Bx2 Block Linear layout, used by desktop GPUs, and Tegra K1 and later * * Pixels are arranged in 64x8 Groups Of Bytes (GOBs). GOBs are then stacked * vertically by a power of 2 (1 to 32 GOBs) to form a block. @@ -380,7 +368,21 @@ extern "C" { * Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format * in full detail. */ -#define NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(v) fourcc_mod_tegra_code(2, v) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(v) \ + fourcc_mod_code(NVIDIA, 0x10 | ((v) & 0xf)) + +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB \ + fourcc_mod_code(NVIDIA, 0x10) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB \ + fourcc_mod_code(NVIDIA, 0x11) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB \ + fourcc_mod_code(NVIDIA, 0x12) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB \ + fourcc_mod_code(NVIDIA, 0x13) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB \ + fourcc_mod_code(NVIDIA, 0x14) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB \ + fourcc_mod_code(NVIDIA, 0x15) /* * Broadcom VC4 "T" format diff --git a/lib/libdrm/include/drm/drm_mode.h b/lib/libdrm/include/drm/drm_mode.h index 5597a8715..5f9fadbd1 100644 --- a/lib/libdrm/include/drm/drm_mode.h +++ b/lib/libdrm/include/drm/drm_mode.h @@ -38,11 +38,11 @@ extern "C" { #define DRM_DISPLAY_MODE_LEN 32 #define DRM_PROP_NAME_LEN 32 -#define DRM_MODE_TYPE_BUILTIN (1<<0) -#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) -#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) +#define DRM_MODE_TYPE_BUILTIN (1<<0) /* deprecated */ +#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) /* deprecated */ +#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) /* deprecated */ #define DRM_MODE_TYPE_PREFERRED (1<<3) -#define DRM_MODE_TYPE_DEFAULT (1<<4) +#define DRM_MODE_TYPE_DEFAULT (1<<4) /* deprecated */ #define DRM_MODE_TYPE_USERDEF (1<<5) #define DRM_MODE_TYPE_DRIVER (1<<6) @@ -66,8 +66,8 @@ extern "C" { #define DRM_MODE_FLAG_PCSYNC (1<<7) #define DRM_MODE_FLAG_NCSYNC (1<<8) #define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ -#define DRM_MODE_FLAG_BCAST (1<<10) -#define DRM_MODE_FLAG_PIXMUX (1<<11) +#define DRM_MODE_FLAG_BCAST (1<<10) /* deprecated */ +#define DRM_MODE_FLAG_PIXMUX (1<<11) /* deprecated */ #define DRM_MODE_FLAG_DBLCLK (1<<12) #define DRM_MODE_FLAG_CLKDIV2 (1<<13) /* @@ -173,6 +173,10 @@ extern "C" { DRM_MODE_REFLECT_X | \ DRM_MODE_REFLECT_Y) +/* Content Protection Flags */ +#define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0 +#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1 +#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2 struct drm_mode_modeinfo { __u32 clock; @@ -341,7 +345,7 @@ struct drm_mode_get_connector { __u32 pad; }; -#define DRM_MODE_PROP_PENDING (1<<0) +#define DRM_MODE_PROP_PENDING (1<<0) /* deprecated, do not use */ #define DRM_MODE_PROP_RANGE (1<<1) #define DRM_MODE_PROP_IMMUTABLE (1<<2) #define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ @@ -576,8 +580,11 @@ struct drm_mode_crtc_lut { }; struct drm_color_ctm { - /* Conversion matrix in S31.32 format. */ - __s64 matrix[9]; + /* + * Conversion matrix in S31.32 sign-magnitude + * (not two's complement!) format. + */ + __u64 matrix[9]; }; struct drm_color_lut { diff --git a/lib/libdrm/include/drm/msm_drm.h b/lib/libdrm/include/drm/msm_drm.h new file mode 100644 index 000000000..c06d0a5bd --- /dev/null +++ b/lib/libdrm/include/drm/msm_drm.h @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark <robdclark@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __MSM_DRM_H__ +#define __MSM_DRM_H__ + +#include "drm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Please note that modifications to all structs defined here are + * subject to backwards-compatibility constraints: + * 1) Do not use pointers, use __u64 instead for 32 bit / 64 bit + * user/kernel compatibility + * 2) Keep fields aligned to their size + * 3) Because of how drm_ioctl() works, we can add new fields at + * the end of an ioctl if some care is taken: drm_ioctl() will + * zero out the new fields at the tail of the ioctl, so a zero + * value should have a backwards compatible meaning. And for + * output params, userspace won't see the newly added output + * fields.. so that has to be somehow ok. + */ + +#define MSM_PIPE_NONE 0x00 +#define MSM_PIPE_2D0 0x01 +#define MSM_PIPE_2D1 0x02 +#define MSM_PIPE_3D0 0x10 + +/* The pipe-id just uses the lower bits, so can be OR'd with flags in + * the upper 16 bits (which could be extended further, if needed, maybe + * we extend/overload the pipe-id some day to deal with multiple rings, + * but even then I don't think we need the full lower 16 bits). + */ +#define MSM_PIPE_ID_MASK 0xffff +#define MSM_PIPE_ID(x) ((x) & MSM_PIPE_ID_MASK) +#define MSM_PIPE_FLAGS(x) ((x) & ~MSM_PIPE_ID_MASK) + +/* timeouts are specified in clock-monotonic absolute times (to simplify + * restarting interrupted ioctls). The following struct is logically the + * same as 'struct timespec' but 32/64b ABI safe. + */ +struct drm_msm_timespec { + __s64 tv_sec; /* seconds */ + __s64 tv_nsec; /* nanoseconds */ +}; + +#define MSM_PARAM_GPU_ID 0x01 +#define MSM_PARAM_GMEM_SIZE 0x02 +#define MSM_PARAM_CHIP_ID 0x03 +#define MSM_PARAM_MAX_FREQ 0x04 +#define MSM_PARAM_TIMESTAMP 0x05 +#define MSM_PARAM_GMEM_BASE 0x06 +#define MSM_PARAM_NR_RINGS 0x07 + +struct drm_msm_param { + __u32 pipe; /* in, MSM_PIPE_x */ + __u32 param; /* in, MSM_PARAM_x */ + __u64 value; /* out (get_param) or in (set_param) */ +}; + +/* + * GEM buffers: + */ + +#define MSM_BO_SCANOUT 0x00000001 /* scanout capable */ +#define MSM_BO_GPU_READONLY 0x00000002 +#define MSM_BO_CACHE_MASK 0x000f0000 +/* cache modes */ +#define MSM_BO_CACHED 0x00010000 +#define MSM_BO_WC 0x00020000 +#define MSM_BO_UNCACHED 0x00040000 + +#define MSM_BO_FLAGS (MSM_BO_SCANOUT | \ + MSM_BO_GPU_READONLY | \ + MSM_BO_CACHED | \ + MSM_BO_WC | \ + MSM_BO_UNCACHED) + +struct drm_msm_gem_new { + __u64 size; /* in */ + __u32 flags; /* in, mask of MSM_BO_x */ + __u32 handle; /* out */ +}; + +#define MSM_INFO_IOVA 0x01 + +#define MSM_INFO_FLAGS (MSM_INFO_IOVA) + +struct drm_msm_gem_info { + __u32 handle; /* in */ + __u32 flags; /* in - combination of MSM_INFO_* flags */ + __u64 offset; /* out, mmap() offset or iova */ +}; + +#define MSM_PREP_READ 0x01 +#define MSM_PREP_WRITE 0x02 +#define MSM_PREP_NOSYNC 0x04 + +#define MSM_PREP_FLAGS (MSM_PREP_READ | MSM_PREP_WRITE | MSM_PREP_NOSYNC) + +struct drm_msm_gem_cpu_prep { + __u32 handle; /* in */ + __u32 op; /* in, mask of MSM_PREP_x */ + struct drm_msm_timespec timeout; /* in */ +}; + +struct drm_msm_gem_cpu_fini { + __u32 handle; /* in */ +}; + +/* + * Cmdstream Submission: + */ + +/* The value written into the cmdstream is logically: + * + * ((relocbuf->gpuaddr + reloc_offset) << shift) | or + * + * When we have GPU's w/ >32bit ptrs, it should be possible to deal + * with this by emit'ing two reloc entries with appropriate shift + * values. Or a new MSM_SUBMIT_CMD_x type would also be an option. + * + * NOTE that reloc's must be sorted by order of increasing submit_offset, + * otherwise EINVAL. + */ +struct drm_msm_gem_submit_reloc { + __u32 submit_offset; /* in, offset from submit_bo */ + __u32 or; /* in, value OR'd with result */ + __s32 shift; /* in, amount of left shift (can be negative) */ + __u32 reloc_idx; /* in, index of reloc_bo buffer */ + __u64 reloc_offset; /* in, offset from start of reloc_bo */ +}; + +/* submit-types: + * BUF - this cmd buffer is executed normally. + * IB_TARGET_BUF - this cmd buffer is an IB target. Reloc's are + * processed normally, but the kernel does not setup an IB to + * this buffer in the first-level ringbuffer + * CTX_RESTORE_BUF - only executed if there has been a GPU context + * switch since the last SUBMIT ioctl + */ +#define MSM_SUBMIT_CMD_BUF 0x0001 +#define MSM_SUBMIT_CMD_IB_TARGET_BUF 0x0002 +#define MSM_SUBMIT_CMD_CTX_RESTORE_BUF 0x0003 +struct drm_msm_gem_submit_cmd { + __u32 type; /* in, one of MSM_SUBMIT_CMD_x */ + __u32 submit_idx; /* in, index of submit_bo cmdstream buffer */ + __u32 submit_offset; /* in, offset into submit_bo */ + __u32 size; /* in, cmdstream size */ + __u32 pad; + __u32 nr_relocs; /* in, number of submit_reloc's */ + __u64 relocs; /* in, ptr to array of submit_reloc's */ +}; + +/* Each buffer referenced elsewhere in the cmdstream submit (ie. the + * cmdstream buffer(s) themselves or reloc entries) has one (and only + * one) entry in the submit->bos[] table. + * + * As a optimization, the current buffer (gpu virtual address) can be + * passed back through the 'presumed' field. If on a subsequent reloc, + * userspace passes back a 'presumed' address that is still valid, + * then patching the cmdstream for this entry is skipped. This can + * avoid kernel needing to map/access the cmdstream bo in the common + * case. + */ +#define MSM_SUBMIT_BO_READ 0x0001 +#define MSM_SUBMIT_BO_WRITE 0x0002 + +#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE) + +struct drm_msm_gem_submit_bo { + __u32 flags; /* in, mask of MSM_SUBMIT_BO_x */ + __u32 handle; /* in, GEM handle */ + __u64 presumed; /* in/out, presumed buffer address */ +}; + +/* Valid submit ioctl flags: */ +#define MSM_SUBMIT_NO_IMPLICIT 0x80000000 /* disable implicit sync */ +#define MSM_SUBMIT_FENCE_FD_IN 0x40000000 /* enable input fence_fd */ +#define MSM_SUBMIT_FENCE_FD_OUT 0x20000000 /* enable output fence_fd */ +#define MSM_SUBMIT_SUDO 0x10000000 /* run submitted cmds from RB */ +#define MSM_SUBMIT_FLAGS ( \ + MSM_SUBMIT_NO_IMPLICIT | \ + MSM_SUBMIT_FENCE_FD_IN | \ + MSM_SUBMIT_FENCE_FD_OUT | \ + MSM_SUBMIT_SUDO | \ + 0) + +/* Each cmdstream submit consists of a table of buffers involved, and + * one or more cmdstream buffers. This allows for conditional execution + * (context-restore), and IB buffers needed for per tile/bin draw cmds. + */ +struct drm_msm_gem_submit { + __u32 flags; /* MSM_PIPE_x | MSM_SUBMIT_x */ + __u32 fence; /* out */ + __u32 nr_bos; /* in, number of submit_bo's */ + __u32 nr_cmds; /* in, number of submit_cmd's */ + __u64 bos; /* in, ptr to array of submit_bo's */ + __u64 cmds; /* in, ptr to array of submit_cmd's */ + __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */ + __u32 queueid; /* in, submitqueue id */ +}; + +/* The normal way to synchronize with the GPU is just to CPU_PREP on + * a buffer if you need to access it from the CPU (other cmdstream + * submission from same or other contexts, PAGE_FLIP ioctl, etc, all + * handle the required synchronization under the hood). This ioctl + * mainly just exists as a way to implement the gallium pipe_fence + * APIs without requiring a dummy bo to synchronize on. + */ +struct drm_msm_wait_fence { + __u32 fence; /* in */ + __u32 pad; + struct drm_msm_timespec timeout; /* in */ + __u32 queueid; /* in, submitqueue id */ +}; + +/* madvise provides a way to tell the kernel in case a buffers contents + * can be discarded under memory pressure, which is useful for userspace + * bo cache where we want to optimistically hold on to buffer allocate + * and potential mmap, but allow the pages to be discarded under memory + * pressure. + * + * Typical usage would involve madvise(DONTNEED) when buffer enters BO + * cache, and madvise(WILLNEED) if trying to recycle buffer from BO cache. + * In the WILLNEED case, 'retained' indicates to userspace whether the + * backing pages still exist. + */ +#define MSM_MADV_WILLNEED 0 /* backing pages are needed, status returned in 'retained' */ +#define MSM_MADV_DONTNEED 1 /* backing pages not needed */ +#define __MSM_MADV_PURGED 2 /* internal state */ + +struct drm_msm_gem_madvise { + __u32 handle; /* in, GEM handle */ + __u32 madv; /* in, MSM_MADV_x */ + __u32 retained; /* out, whether backing store still exists */ +}; + +/* + * Draw queues allow the user to set specific submission parameter. Command + * submissions specify a specific submitqueue to use. ID 0 is reserved for + * backwards compatibility as a "default" submitqueue + */ + +#define MSM_SUBMITQUEUE_FLAGS (0) + +struct drm_msm_submitqueue { + __u32 flags; /* in, MSM_SUBMITQUEUE_x */ + __u32 prio; /* in, Priority level */ + __u32 id; /* out, identifier */ +}; + +#define DRM_MSM_GET_PARAM 0x00 +/* placeholder: +#define DRM_MSM_SET_PARAM 0x01 + */ +#define DRM_MSM_GEM_NEW 0x02 +#define DRM_MSM_GEM_INFO 0x03 +#define DRM_MSM_GEM_CPU_PREP 0x04 +#define DRM_MSM_GEM_CPU_FINI 0x05 +#define DRM_MSM_GEM_SUBMIT 0x06 +#define DRM_MSM_WAIT_FENCE 0x07 +#define DRM_MSM_GEM_MADVISE 0x08 +/* placeholder: +#define DRM_MSM_GEM_SVM_NEW 0x09 + */ +#define DRM_MSM_SUBMITQUEUE_NEW 0x0A +#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B + +#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) +#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) +#define DRM_IOCTL_MSM_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info) +#define DRM_IOCTL_MSM_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_GEM_CPU_PREP, struct drm_msm_gem_cpu_prep) +#define DRM_IOCTL_MSM_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_GEM_CPU_FINI, struct drm_msm_gem_cpu_fini) +#define DRM_IOCTL_MSM_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit) +#define DRM_IOCTL_MSM_WAIT_FENCE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence) +#define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise) +#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue) +#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32) + +#if defined(__cplusplus) +} +#endif + +#endif /* __MSM_DRM_H__ */ diff --git a/lib/libdrm/include/drm/nouveau_drm.h b/lib/libdrm/include/drm/nouveau_drm.h index cb077821c..d42105c86 100644 --- a/lib/libdrm/include/drm/nouveau_drm.h +++ b/lib/libdrm/include/drm/nouveau_drm.h @@ -104,6 +104,7 @@ struct drm_nouveau_setparam { #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) #define NOUVEAU_GEM_DOMAIN_COHERENT (1 << 4) +#define NOUVEAU_GEM_TILE_COMP 0x00030000 /* nv50-only */ #define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00 #define NOUVEAU_GEM_TILE_16BPP 0x00000001 #define NOUVEAU_GEM_TILE_32BPP 0x00000002 diff --git a/lib/libdrm/include/drm/vc4_drm.h b/lib/libdrm/include/drm/vc4_drm.h index 3415a4b71..4117117b4 100644 --- a/lib/libdrm/include/drm/vc4_drm.h +++ b/lib/libdrm/include/drm/vc4_drm.h @@ -42,6 +42,9 @@ extern "C" { #define DRM_VC4_GET_TILING 0x09 #define DRM_VC4_LABEL_BO 0x0a #define DRM_VC4_GEM_MADVISE 0x0b +#define DRM_VC4_PERFMON_CREATE 0x0c +#define DRM_VC4_PERFMON_DESTROY 0x0d +#define DRM_VC4_PERFMON_GET_VALUES 0x0e #define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) #define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) @@ -55,6 +58,9 @@ extern "C" { #define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling) #define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo) #define DRM_IOCTL_VC4_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GEM_MADVISE, struct drm_vc4_gem_madvise) +#define DRM_IOCTL_VC4_PERFMON_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_CREATE, struct drm_vc4_perfmon_create) +#define DRM_IOCTL_VC4_PERFMON_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_DESTROY, struct drm_vc4_perfmon_destroy) +#define DRM_IOCTL_VC4_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_GET_VALUES, struct drm_vc4_perfmon_get_values) struct drm_vc4_submit_rcl_surface { __u32 hindex; /* Handle index, or ~0 if not present. */ @@ -173,6 +179,15 @@ struct drm_vc4_submit_cl { * wait ioctl). */ __u64 seqno; + + /* ID of the perfmon to attach to this job. 0 means no perfmon. */ + __u32 perfmonid; + + /* Unused field to align this struct on 64 bits. Must be set to 0. + * If one ever needs to add an u32 field to this struct, this field + * can be used. + */ + __u32 pad2; }; /** @@ -308,6 +323,7 @@ struct drm_vc4_get_hang_state { #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5 #define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6 #define DRM_VC4_PARAM_SUPPORTS_MADVISE 7 +#define DRM_VC4_PARAM_SUPPORTS_PERFMON 8 struct drm_vc4_get_param { __u32 param; @@ -352,6 +368,66 @@ struct drm_vc4_gem_madvise { __u32 pad; }; +enum { + VC4_PERFCNT_FEP_VALID_PRIMS_NO_RENDER, + VC4_PERFCNT_FEP_VALID_PRIMS_RENDER, + VC4_PERFCNT_FEP_CLIPPED_QUADS, + VC4_PERFCNT_FEP_VALID_QUADS, + VC4_PERFCNT_TLB_QUADS_NOT_PASSING_STENCIL, + VC4_PERFCNT_TLB_QUADS_NOT_PASSING_Z_AND_STENCIL, + VC4_PERFCNT_TLB_QUADS_PASSING_Z_AND_STENCIL, + VC4_PERFCNT_TLB_QUADS_ZERO_COVERAGE, + VC4_PERFCNT_TLB_QUADS_NON_ZERO_COVERAGE, + VC4_PERFCNT_TLB_QUADS_WRITTEN_TO_COLOR_BUF, + VC4_PERFCNT_PLB_PRIMS_OUTSIDE_VIEWPORT, + VC4_PERFCNT_PLB_PRIMS_NEED_CLIPPING, + VC4_PERFCNT_PSE_PRIMS_REVERSED, + VC4_PERFCNT_QPU_TOTAL_IDLE_CYCLES, + VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_VERTEX_COORD_SHADING, + VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_FRAGMENT_SHADING, + VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_EXEC_VALID_INST, + VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_TMUS, + VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_SCOREBOARD, + VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_VARYINGS, + VC4_PERFCNT_QPU_TOTAL_INST_CACHE_HIT, + VC4_PERFCNT_QPU_TOTAL_INST_CACHE_MISS, + VC4_PERFCNT_QPU_TOTAL_UNIFORM_CACHE_HIT, + VC4_PERFCNT_QPU_TOTAL_UNIFORM_CACHE_MISS, + VC4_PERFCNT_TMU_TOTAL_TEXT_QUADS_PROCESSED, + VC4_PERFCNT_TMU_TOTAL_TEXT_CACHE_MISS, + VC4_PERFCNT_VPM_TOTAL_CLK_CYCLES_VDW_STALLED, + VC4_PERFCNT_VPM_TOTAL_CLK_CYCLES_VCD_STALLED, + VC4_PERFCNT_L2C_TOTAL_L2_CACHE_HIT, + VC4_PERFCNT_L2C_TOTAL_L2_CACHE_MISS, + VC4_PERFCNT_NUM_EVENTS, +}; + +#define DRM_VC4_MAX_PERF_COUNTERS 16 + +struct drm_vc4_perfmon_create { + __u32 id; + __u32 ncounters; + __u8 events[DRM_VC4_MAX_PERF_COUNTERS]; +}; + +struct drm_vc4_perfmon_destroy { + __u32 id; +}; + +/* + * Returns the values of the performance counters tracked by this + * perfmon (as an array of ncounters u64 values). + * + * No implicit synchronization is performed, so the user has to + * guarantee that any jobs using this perfmon have already been + * completed (probably by blocking on the seqno returned by the + * last exec that used the perfmon). + */ +struct drm_vc4_perfmon_get_values { + __u32 id; + __u64 values_ptr; +}; + #if defined(__cplusplus) } #endif diff --git a/lib/libdrm/include/drm/virtgpu_drm.h b/lib/libdrm/include/drm/virtgpu_drm.h index 91a31ffed..9a781f061 100644 --- a/lib/libdrm/include/drm/virtgpu_drm.h +++ b/lib/libdrm/include/drm/virtgpu_drm.h @@ -63,6 +63,7 @@ struct drm_virtgpu_execbuffer { }; #define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */ +#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */ struct drm_virtgpu_getparam { __u64 param; diff --git a/lib/libdrm/include/drm/vmwgfx_drm.h b/lib/libdrm/include/drm/vmwgfx_drm.h index d325a4107..0bc784f5e 100644 --- a/lib/libdrm/include/drm/vmwgfx_drm.h +++ b/lib/libdrm/include/drm/vmwgfx_drm.h @@ -41,6 +41,7 @@ extern "C" { #define DRM_VMW_GET_PARAM 0 #define DRM_VMW_ALLOC_DMABUF 1 #define DRM_VMW_UNREF_DMABUF 2 +#define DRM_VMW_HANDLE_CLOSE 2 #define DRM_VMW_CURSOR_BYPASS 3 /* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/ #define DRM_VMW_CONTROL_STREAM 4 @@ -296,13 +297,17 @@ union drm_vmw_surface_reference_arg { * @version: Allows expanding the execbuf ioctl parameters without breaking * backwards compatibility, since user-space will always tell the kernel * which version it uses. - * @flags: Execbuf flags. None currently. + * @flags: Execbuf flags. + * @imported_fence_fd: FD for a fence imported from another device * * Argument to the DRM_VMW_EXECBUF Ioctl. */ #define DRM_VMW_EXECBUF_VERSION 2 +#define DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD (1 << 0) +#define DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD (1 << 1) + struct drm_vmw_execbuf_arg { __u64 commands; __u32 command_size; @@ -311,7 +316,7 @@ struct drm_vmw_execbuf_arg { __u32 version; __u32 flags; __u32 context_handle; - __u32 pad64; + __s32 imported_fence_fd; }; /** @@ -327,6 +332,7 @@ struct drm_vmw_execbuf_arg { * @passed_seqno: The highest seqno number processed by the hardware * so far. This can be used to mark user-space fence objects as signaled, and * to determine whether a fence seqno might be stale. + * @fd: FD associated with the fence, -1 if not exported * @error: This member should've been set to -EFAULT on submission. * The following actions should be take on completion: * error == -EFAULT: Fence communication failed. The host is synchronized. @@ -344,7 +350,7 @@ struct drm_vmw_fence_rep { __u32 mask; __u32 seqno; __u32 passed_seqno; - __u32 pad64; + __s32 fd; __s32 error; }; @@ -1092,6 +1098,29 @@ union drm_vmw_extended_context_arg { struct drm_vmw_context_arg rep; }; +/*************************************************************************/ +/* + * DRM_VMW_HANDLE_CLOSE - Close a user-space handle and release its + * underlying resource. + * + * Note that this ioctl is overlaid on the DRM_VMW_UNREF_DMABUF Ioctl. + * The ioctl arguments therefore need to be identical in layout. + * + */ + +/** + * struct drm_vmw_handle_close_arg + * + * @handle: Handle to close. + * + * Argument to the DRM_VMW_HANDLE_CLOSE Ioctl. + */ +struct drm_vmw_handle_close_arg { + __u32 handle; + __u32 pad64; +}; + + #if defined(__cplusplus) } #endif diff --git a/lib/libdrm/intel/intel-symbol-check b/lib/libdrm/intel/intel-symbol-check index 2aa2d8192..4d30a4b15 100755 --- a/lib/libdrm/intel/intel-symbol-check +++ b/lib/libdrm/intel/intel-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.sources/LIBDRM_INTEL_H_FILES -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_intel.so} | awk '{print $3}' | while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_intel.so} | awk '{print $3}' | while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata diff --git a/lib/libdrm/intel/meson.build b/lib/libdrm/intel/meson.build new file mode 100644 index 000000000..53c7fce4e --- /dev/null +++ b/lib/libdrm/intel/meson.build @@ -0,0 +1,106 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libdrm_intel = shared_library( + 'drm_intel', + [ + files( + 'intel_bufmgr.c', 'intel_bufmgr_fake.c', 'intel_bufmgr_gem.c', + 'intel_decode.c', 'mm.c', + ), + config_file, + ], + include_directories : [inc_root, inc_drm], + link_with : libdrm, + dependencies : [dep_pciaccess, dep_pthread_stubs, dep_rt, dep_valgrind, dep_atomic_ops], + c_args : warn_c_args, + version : '1.0.0', + install : true, +) + +ext_libdrm_intel = declare_dependency( + link_with : [libdrm, libdrm_intel], + include_directories : [inc_drm, include_directories('.')], +) + +install_headers( + 'intel_bufmgr.h', 'intel_aub.h', 'intel_debug.h', + subdir : 'libdrm', +) + +pkg.generate( + name : 'libdrm_intel', + libraries : libdrm_intel, + subdirs : ['.', 'libdrm'], + version : meson.project_version(), + requires : 'libdrm', + description : 'Userspace interface to intel kernel DRM services', +) + +test_decode = executable( + 'test_decode', + files('test_decode.c'), + include_directories : [inc_root, inc_drm], + link_with : [libdrm, libdrm_intel], + c_args : warn_c_args, +) + +test( + 'gen4-3d.batch', + prog_bash, + args : files('tests/gen4-3d.batch.sh'), + workdir : meson.current_build_dir(), +) +test( + 'gen45-3d.batch', + prog_bash, + args : files('tests/gm45-3d.batch.sh'), + workdir : meson.current_build_dir(), +) +test( + 'gen5-3d.batch', + prog_bash, + args : files('tests/gen5-3d.batch.sh'), + workdir : meson.current_build_dir(), +) +test( + 'gen6-3d.batch', + prog_bash, + args : files('tests/gen6-3d.batch.sh'), + workdir : meson.current_build_dir(), +) +test( + 'gen7-3d.batch', + prog_bash, + args : files('tests/gen7-3d.batch.sh'), + workdir : meson.current_build_dir(), +) +test( + 'gen7-2d-copy.batch', + prog_bash, + args : files('tests/gen7-2d-copy.batch.sh'), + workdir : meson.current_build_dir(), +) +test( + 'intel-symbol-check', + prog_bash, + env : env_test, + args : [files('intel-symbol-check'), libdrm_intel] +) diff --git a/lib/libdrm/intel/test_decode.c b/lib/libdrm/intel/test_decode.c index b4eddcd1d..b9f5b9279 100644 --- a/lib/libdrm/intel/test_decode.c +++ b/lib/libdrm/intel/test_decode.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <string.h> #include <stdlib.h> #include <stdio.h> @@ -91,7 +87,7 @@ compare_batch(struct drm_intel_decode *ctx, const char *batch_filename) { FILE *out = NULL; void *ptr, *ref_ptr, *batch_ptr; -#ifdef HAVE_OPEN_MEMSTREAM +#if HAVE_OPEN_MEMSTREAM size_t size; #endif size_t ref_size, batch_size; @@ -109,7 +105,7 @@ compare_batch(struct drm_intel_decode *ctx, const char *batch_filename) * figure out how to output to a file in a safe and sane way * inside of an automake project's test infrastructure. */ -#ifdef HAVE_OPEN_MEMSTREAM +#if HAVE_OPEN_MEMSTREAM out = open_memstream((char **)&ptr, &size); #else fprintf(stderr, "platform lacks open_memstream, skipping.\n"); diff --git a/lib/libdrm/libkms/exynos.c b/lib/libdrm/libkms/exynos.c index c20b6b05d..ef64a668b 100644 --- a/lib/libdrm/libkms/exynos.c +++ b/lib/libdrm/libkms/exynos.c @@ -25,10 +25,6 @@ * SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <stdio.h> #include <stdlib.h> diff --git a/lib/libdrm/libkms/kms-symbol-check b/lib/libdrm/libkms/kms-symbol-check index 658b26926..a5c2120d5 100755 --- a/lib/libdrm/libkms/kms-symbol-check +++ b/lib/libdrm/libkms/kms-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.sources/LIBKMS_H_FILES -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libkms.so} | awk '{print $3}'| while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libkms.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata diff --git a/lib/libdrm/libkms/meson.build b/lib/libdrm/libkms/meson.build new file mode 100644 index 000000000..86d1a4ee6 --- /dev/null +++ b/lib/libdrm/libkms/meson.build @@ -0,0 +1,75 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libkms_include = [inc_root, inc_drm] +files_libkms = files( + 'linux.c', + 'dumb.c', + 'api.c', +) +if with_vmwgfx + files_libkms += files('vmwgfx.c') +endif +if with_intel + files_libkms += files('intel.c') +endif +if with_nouveau + files_libkms += files('nouveau.c') +endif +if with_radeon + files_libkms += files('radeon.c') +endif +if with_exynos + files_libkms += files('exynos.c') + libkms_include += include_directories('../exynos') +endif + +libkms = shared_library( + 'kms', + [files_libkms, config_file], + c_args : warn_c_args, + include_directories : libkms_include, + link_with : libdrm, + version : '1.0.0', + install : true, +) + +ext_libkms = declare_dependency( + link_with : [libdrm, libkms], + include_directories : [libkms_include], +) + +install_headers('libkms.h', subdir : 'libkms') + +pkg.generate( + name : 'libkms', + libraries : libkms, + subdirs : ['libkms'], + version : '1.0.0', + requires_private : 'libdrm', + description : 'Library that abstracts away the different mm interfaces for kernel drivers', +) + +test( + 'kms-symbol-check', + prog_bash, + env : env_test, + args : [files('kms-symbol-check'), libkms] +) diff --git a/lib/libdrm/man/meson.build b/lib/libdrm/man/meson.build new file mode 100644 index 000000000..45eaeda0f --- /dev/null +++ b/lib/libdrm/man/meson.build @@ -0,0 +1,67 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +xsltproc_args = [ + '--stringparam', 'man.authors.section.enabled', '0', + '--stringparam', 'man.copyright.section.enabled', '0', + '--stringparam', 'funcsynopsis.style', 'ansi', + '--stringparam', 'man.output.quietly', '1', + '--nonet', manpage_style, +] + +xmls = [ + ['drm', '7'], ['drm-kms', '7'], ['drm-memory', '7'], ['drmAvailable', '3'], + ['drmHandleEvent', '3'], ['drmModeGetResources', '3'] +] +foreach x : xmls + m = x[0] + s = x[1] + custom_target( + m, + input : files('@0@.xml'.format(m)), + output : '@0@.@1@'.format(m, s), + command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT0@'], + install : true, + install_dir : join_paths(get_option('mandir'), 'man@0@'.format(s)), + build_by_default : true, + ) +endforeach + +foreach x : ['drm-mm', 'drm-gem', 'drm-ttm'] + gen = custom_target( + 'gen-@0@'.format(x), + input : 'drm-memory.xml', + output : '@0@.xml'.format(x), + command : [ + prog_sed, '-e', 's@^\.so \([a-z_]\+\)\.\([0-9]\)$$@\.so man\2\/\1\.\2@', + '@INPUT@', + ], + capture : true, + ) + custom_target( + '@0@.7'.format(x), + input : gen, + output : '@0@.7'.format(x, '7'), + command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT@'], + install : true, + install_dir : join_paths(get_option('mandir'), 'man7'), + build_by_default : true, + ) +endforeach diff --git a/lib/libdrm/meson.build b/lib/libdrm/meson.build new file mode 100644 index 000000000..75c7bdff6 --- /dev/null +++ b/lib/libdrm/meson.build @@ -0,0 +1,383 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +project( + 'libdrm', + ['c'], + version : '2.4.94', + license : 'MIT', + meson_version : '>= 0.43', + default_options : ['buildtype=debugoptimized', 'c_std=gnu99'], +) + +pkg = import('pkgconfig') + +config = configuration_data() + +config.set10('UDEV', get_option('udev')) +with_freedreno_kgsl = get_option('freedreno-kgsl') +with_install_tests = get_option('install-test-programs') + +if ['freebsd', 'dragonfly', 'netbsd'].contains(host_machine.system()) + dep_pthread_stubs = dependency('pthread-stubs', version : '>= 0.4') +else + dep_pthread_stubs = [] +endif +dep_threads = dependency('threads') + +cc = meson.get_compiler('c') + +# Check for atomics +intel_atomics = false +lib_atomics = false + +dep_atomic_ops = dependency('atomic_ops', required : false) +if cc.compiles(''' + int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); } + int atomic_cmpxchg(int *i, int j, int k) { return __sync_val_compare_and_swap (i, j, k); } + ''', + name : 'Intel Atomics') + intel_atomics = true + with_atomics = true + dep_atomic_ops = [] +elif dep_atomic_ops.found() + lib_atomics = true + with_atomics = true +elif cc.has_function('atomic_cas_uint') + with_atomics = true +else + with_atomics = false +endif + +config.set10('HAVE_LIBDRM_ATOMIC_PRIMITIVES', intel_atomics) +config.set10('HAVE_LIB_ATOMIC_OPS', lib_atomics) + +with_intel = false +_intel = get_option('intel') +if _intel != 'false' + if _intel == 'true' and not with_atomics + error('libdrm_intel requires atomics.') + else + with_intel = _intel == 'true' or host_machine.cpu_family().startswith('x86') + endif +endif + +with_radeon = false +_radeon = get_option('radeon') +if _radeon != 'false' + if _radeon == 'true' and not with_atomics + error('libdrm_radeon requires atomics.') + endif + with_radeon = true +endif + +with_amdgpu = false +_amdgpu = get_option('amdgpu') +if _amdgpu != 'false' + if _amdgpu == 'true' and not with_atomics + error('libdrm_amdgpu requires atomics.') + endif + with_amdgpu = true +endif + +with_nouveau = false +_nouveau = get_option('nouveau') +if _nouveau != 'false' + if _nouveau == 'true' and not with_atomics + error('libdrm_nouveau requires atomics.') + endif + with_nouveau = true +endif + +with_vmwgfx = false +_vmwgfx = get_option('vmwgfx') +if _vmwgfx != 'false' + with_vmwgfx = true +endif + +with_omap = false +_omap = get_option('omap') +if _omap == 'true' + if not with_atomics + error('libdrm_omap requires atomics.') + endif + with_omap = true +endif + +with_freedreno = false +_freedreno = get_option('freedreno') +if _freedreno != 'false' + if _freedreno == 'true' and not with_atomics + error('libdrm_freedreno requires atomics.') + else + with_freedreno = _freedreno == 'true' or ['arm', 'aarch64'].contains(host_machine.cpu_family()) + endif +endif + +with_tegra = false +_tegra = get_option('tegra') +if _tegra == 'true' + if not with_atomics + error('libdrm_tegra requires atomics.') + endif + with_tegra = true +endif + +with_etnaviv = false +_etnaviv = get_option('etnaviv') +if _etnaviv == 'true' + if not with_atomics + error('libdrm_etnaviv requires atomics.') + endif + with_etnaviv = true +endif + +with_exynos = get_option('exynos') == 'true' + +with_vc4 = false +_vc4 = get_option('vc4') +if _vc4 != 'false' + with_vc4 = _vc4 == 'true' or ['arm', 'aarch64'].contains(host_machine.cpu_family()) +endif + +# XXX: Aparently only freebsd and dragonfly bsd actually need this (and +# gnu/kfreebsd), not openbsd and netbsd +with_libkms = false +_libkms = get_option('libkms') +if _libkms != 'false' + with_libkms = _libkms == 'true' or ['linux', 'freebsd', 'dragonfly'].contains(host_machine.system()) +endif + +# Among others FreeBSD does not have a separate dl library. +if not cc.has_function('dlsym') + dep_dl = cc.find_library('dl', required : with_nouveau) +else + dep_dl = [] +endif +# clock_gettime might require -rt, or it might not. find out +if not cc.has_function('clock_gettime', prefix : '#define _GNU_SOURCE\n#include <time.h>') + # XXX: untested + dep_rt = cc.find_library('rt') +else + dep_rt = [] +endif +dep_m = cc.find_library('m', required : false) +foreach header : ['sys/sysctl.h', 'sys/select.h', 'alloca.h'] + config.set('HAVE_' + header.underscorify().to_upper(), + cc.compiles('#include <@0@>'.format(header), name : '@0@ works'.format(header))) +endforeach +if cc.has_header_symbol('sys/sysmacros.h', 'major') + config.set10('MAJOR_IN_SYSMACROS', true) +elif cc.has_header_symbol('sys/mkdev.h', 'major') + config.set10('MAJOR_IN_MKDEV', true) +endif +config.set10('HAVE_OPEN_MEMSTREAM', cc.has_function('open_memstream')) + +warn_c_args = [] +foreach a : ['-Wall', '-Wextra', '-Wsign-compare', '-Werror=undef', + '-Werror-implicit-function-declaration', '-Wpointer-arith', + '-Wwrite-strings', '-Wstrict-prototypes', '-Wmissing-prototypes', + '-Wmissing-declarations', '-Wnested-externs', '-Wpacked', + '-Wswitch-enum', '-Wmissing-format-attribute', + '-Wstrict-aliasing=2', '-Winit-self', '-Winline', '-Wshadow', + '-Wdeclaration-after-statement', '-Wold-style-definition'] + if cc.has_argument(a) + warn_c_args += a + endif +endforeach +# GCC will never error for -Wno-*, so check for -W* then add -Wno-* to the list +# of options +foreach a : ['unused-parameter', 'attributes', 'long-long', + 'missing-field-initializers'] + if cc.has_argument('-W@0@'.format(a)) + warn_c_args += '-Wno-@0@'.format(a) + endif +endforeach + + +dep_pciaccess = dependency('pciaccess', version : '>= 0.10', required : with_intel) +dep_cunit = dependency('cunit', version : '>= 2.1', required : false) +_cairo_tests = get_option('cairo-tests') +if _cairo_tests != 'false' + dep_cairo = dependency('cairo', required : _cairo_tests == 'true') + with_cairo_tests = dep_cairo.found() +else + dep_cairo = [] + with_cairo_tests = false +endif +_valgrind = get_option('valgrind') +if _valgrind != 'false' + dep_valgrind = dependency('valgrind', required : _valgrind == 'true') + with_valgrind = dep_valgrind.found() +else + dep_valgrind = [] + with_valgrind = false +endif + +with_man_pages = get_option('man-pages') +prog_xslt = find_program('xsltproc', required : with_man_pages == 'true') +prog_sed = find_program('sed', required : with_man_pages == 'true') +manpage_style = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' +if prog_xslt.found() + if run_command(prog_xslt, '--nonet', manpage_style).returncode() != 0 + if with_man_pages == 'true' + error('Manpage style sheet cannot be found') + endif + with_man_pages = 'false' + endif +endif +with_man_pages = with_man_pages != 'false' and prog_xslt.found() and prog_sed.found() + +# Used for tets +prog_bash = find_program('bash') + +config.set10('HAVE_VISIBILITY', + cc.compiles('''int foo_hidden(void) __attribute__((visibility(("hidden"))));''', + name : 'compiler supports __attribute__(("hidden"))')) + +foreach t : [ + [with_exynos, 'EXYNOS'], + [with_freedreno_kgsl, 'FREEDRENO_KGSL'], + [with_intel, 'INTEL'], + [with_nouveau, 'NOUVEAU'], + [with_radeon, 'RADEON'], + [with_vc4, 'VC4'], + [with_vmwgfx, 'VMWGFX'], + [with_cairo_tests, 'CAIRO'], + [with_valgrind, 'VALGRIND'], + ] + config.set10('HAVE_@0@'.format(t[1]), t[0]) +endforeach +if with_freedreno_kgsl and not with_freedreno + error('cannot enable freedreno-kgsl without freedreno support') +endif +config.set10('_GNU_SOURCE', true) +config_file = configure_file( + configuration : config, + output : 'config.h', +) +add_project_arguments('-include', 'config.h', language : 'c') + +inc_root = include_directories('.') +inc_drm = include_directories('include/drm') + +libdrm = shared_library( + 'drm', + [files( + 'xf86drm.c', 'xf86drmHash.c', 'xf86drmRandom.c', 'xf86drmSL.c', + 'xf86drmMode.c' + ), + config_file, + ], + c_args : warn_c_args, + dependencies : [dep_valgrind, dep_rt, dep_m], + include_directories : inc_drm, + version : '2.4.0', + install : true, +) + +ext_libdrm = declare_dependency( + link_with : libdrm, + include_directories : [inc_root, inc_drm], +) + +install_headers('libsync.h', 'xf86drm.h', 'xf86drmMode.h') +install_headers( + 'include/drm/drm.h', 'include/drm/drm_fourcc.h', 'include/drm/drm_mode.h', + 'include/drm/drm_sarea.h', 'include/drm/i915_drm.h', + 'include/drm/mach64_drm.h', 'include/drm/mga_drm.h', + 'include/drm/msm_drm.h', 'include/drm/nouveau_drm.h', + 'include/drm/qxl_drm.h', 'include/drm/r128_drm.h', + 'include/drm/radeon_drm.h', 'include/drm/amdgpu_drm.h', + 'include/drm/savage_drm.h', 'include/drm/sis_drm.h', + 'include/drm/tegra_drm.h', 'include/drm/vc4_drm.h', + 'include/drm/via_drm.h', 'include/drm/virtgpu_drm.h', + subdir : 'libdrm', +) +if with_vmwgfx + install_headers('include/drm/vmwgfx_drm.h', subdir : 'libdrm') +endif + +pkg.generate( + name : 'libdrm', + libraries : libdrm, + subdirs : ['.', 'libdrm'], + version : meson.project_version(), + description : 'Userspace interface to kernel DRM services', +) + +env_test = environment() +env_test.set('NM', find_program('nm').path()) + +if with_libkms + subdir('libkms') +endif +if with_intel + subdir('intel') +endif +if with_nouveau + subdir('nouveau') +endif +if with_radeon + subdir('radeon') +endif +if with_amdgpu + subdir('amdgpu') +endif +if with_omap + subdir('omap') +endif +if with_exynos + subdir('exynos') +endif +if with_freedreno + subdir('freedreno') +endif +if with_tegra + subdir('tegra') +endif +if with_vc4 + subdir('vc4') +endif +if with_etnaviv + subdir('etnaviv') +endif +if with_man_pages + subdir('man') +endif +subdir('data') +subdir('tests') + +message('') +message('@0@ will be compiled with:'.format(meson.project_name())) +message('') +message(' libkms @0@'.format(with_libkms)) +message(' Intel API @0@'.format(with_intel)) +message(' vmwgfx API @0@'.format(with_vmwgfx)) +message(' Radeon API @0@'.format(with_radeon)) +message(' AMDGPU API @0@'.format(with_amdgpu)) +message(' Nouveau API @0@'.format(with_nouveau)) +message(' OMAP API @0@'.format(with_omap)) +message(' EXYNOS API @0@'.format(with_exynos)) +message(' Freedreno API @0@ (kgsl: @1@)'.format(with_freedreno, with_freedreno_kgsl)) +message(' Tegra API @0@'.format(with_tegra)) +message(' VC4 API @0@'.format(with_vc4)) +message(' Etnaviv API @0@'.format(with_etnaviv)) +message('') diff --git a/lib/libdrm/meson_options.txt b/lib/libdrm/meson_options.txt new file mode 100644 index 000000000..8af33f1c1 --- /dev/null +++ b/lib/libdrm/meson_options.txt @@ -0,0 +1,143 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +option( + 'libkms', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : 'Build libkms mm abstraction library.', +) +option( + 'intel', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : '''Enable support for Intel's KMS API.''', +) +option( + 'radeon', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : '''Enable support for radeons's KMS API.''', +) +option( + 'amdgpu', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : '''Enable support for amdgpu's KMS API.''', +) +option( + 'nouveau', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : '''Enable support for nouveau's KMS API.''', +) +option( + 'vmwgfx', + type : 'combo', + value : 'true', + choices : ['true', 'false', 'auto'], + description : '''Enable support for vmgfx's KMS API.''', +) +option( + 'omap', + type : 'combo', + value : 'false', + choices : ['true', 'false', 'auto'], + description : '''Enable support for OMAP's experimental KMS API.''', +) +option( + 'exynos', + type : 'combo', + value : 'false', + choices : ['true', 'false', 'auto'], + description : '''Enable support for EXYNOS's experimental KMS API.''', +) +option( + 'freedreno', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : '''Enable support for freedreno's KMS API.''', +) +option( + 'tegra', + type : 'combo', + value : 'false', + choices : ['true', 'false', 'auto'], + description : '''Enable support for Tegra's experimental KMS API.''', +) +option( + 'vc4', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : '''Enable support for vc4's KMS API.''', +) +option( + 'etnaviv', + type : 'combo', + value : 'false', + choices : ['true', 'false', 'auto'], + description : '''Enable support for etnaviv's experimental KMS API.''', +) +option( + 'cairo-tests', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : 'Enable support for Cairo rendering in tests.', +) +option( + 'man-pages', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : 'Enable manpage generation and installation.', +) +option( + 'valgrind', + type : 'combo', + value : 'auto', + choices : ['true', 'false', 'auto'], + description : 'Build libdrm with valgrind support.', +) +option( + 'freedreno-kgsl', + type : 'boolean', + value : false, + description : 'Enable support for freedreno to use downstream android kernel API.', +) +option( + 'install-test-programs', + type : 'boolean', + value : false, + description : 'Install test programs.', +) +option( + 'udev', + type : 'boolean', + value : false, + description : 'Enable support for using udev instead of mknod.', +) diff --git a/lib/libdrm/nouveau/abi16.c b/lib/libdrm/nouveau/abi16.c index ee38c0cb2..ba2501ea3 100644 --- a/lib/libdrm/nouveau/abi16.c +++ b/lib/libdrm/nouveau/abi16.c @@ -22,10 +22,6 @@ * Authors: Ben Skeggs */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <stdlib.h> #include <stdint.h> #include <stddef.h> diff --git a/lib/libdrm/nouveau/bufctx.c b/lib/libdrm/nouveau/bufctx.c index 4f76e5dff..67b7570ef 100644 --- a/lib/libdrm/nouveau/bufctx.c +++ b/lib/libdrm/nouveau/bufctx.c @@ -22,10 +22,6 @@ * Authors: Ben Skeggs */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include <stdio.h> #include <stdlib.h> #include <stdint.h> diff --git a/lib/libdrm/nouveau/meson.build b/lib/libdrm/nouveau/meson.build new file mode 100644 index 000000000..51c9a7123 --- /dev/null +++ b/lib/libdrm/nouveau/meson.build @@ -0,0 +1,59 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +libdrm_nouveau = shared_library( + 'drm_nouveau', + [files( 'nouveau.c', 'pushbuf.c', 'bufctx.c', 'abi16.c'), config_file], + c_args : warn_c_args, + include_directories : [inc_root, inc_drm], + link_with : libdrm, + dependencies : [dep_threads, dep_atomic_ops], + version : '2.0.0', + install : true, +) + +ext_libdrm_nouveau = declare_dependency( + link_with : [libdrm, libdrm_nouveau], + include_directories : [inc_drm, include_directories('.')], +) + +install_headers('nouveau.h', subdir : 'libdrm/nouveau') +install_headers( + 'nvif/class.h', 'nvif/cl0080.h', 'nvif/cl9097.h', 'nvif/if0002.h', + 'nvif/if0003.h', 'nvif/ioctl.h', 'nvif/unpack.h', + subdir : 'libdrm/nouveau/nvif' +) + +pkg.generate( + name : 'libdrm_nouveau', + libraries : libdrm_nouveau, + subdirs : ['.', 'libdrm', 'libdrm/nouveau'], + version : meson.project_version(), + requires_private : 'libdrm', + description : 'Userspace interface to nouveau kernel DRM services', +) + +test( + 'nouveau-symbol-check', + prog_bash, + env : env_test, + args : [files('nouveau-symbol-check'), libdrm_nouveau] +) diff --git a/lib/libdrm/nouveau/nouveau-symbol-check b/lib/libdrm/nouveau/nouveau-symbol-check index b265cea46..b3a24101e 100755 --- a/lib/libdrm/nouveau/nouveau-symbol-check +++ b/lib/libdrm/nouveau/nouveau-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.sources/LIBDRM_NOUVEAU_H_FILES -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_nouveau.so} | awk '{print $3}'| while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_nouveau.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata diff --git a/lib/libdrm/nouveau/nouveau.c b/lib/libdrm/nouveau/nouveau.c index e113a8fe7..555935173 100644 --- a/lib/libdrm/nouveau/nouveau.c +++ b/lib/libdrm/nouveau/nouveau.c @@ -22,10 +22,6 @@ * Authors: Ben Skeggs */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include <stdio.h> #include <stdlib.h> #include <stdint.h> diff --git a/lib/libdrm/nouveau/pushbuf.c b/lib/libdrm/nouveau/pushbuf.c index 035e3019f..445c966e4 100644 --- a/lib/libdrm/nouveau/pushbuf.c +++ b/lib/libdrm/nouveau/pushbuf.c @@ -22,10 +22,6 @@ * Authors: Ben Skeggs */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include <stdio.h> #include <stdlib.h> #include <stdint.h> diff --git a/lib/libdrm/omap/meson.build b/lib/libdrm/omap/meson.build new file mode 100644 index 000000000..e57b8f5da --- /dev/null +++ b/lib/libdrm/omap/meson.build @@ -0,0 +1,54 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libdrm_omap = shared_library( + 'drm_omap', + [files('omap_drm.c'), config_file], + include_directories : [inc_root, inc_drm], + c_args : warn_c_args, + link_with : libdrm, + dependencies : [dep_pthread_stubs, dep_atomic_ops], + version : '1.0.0', + install : true, +) + +ext_libdrm_omap = declare_dependency( + link_with : [libdrm, libdrm_omap], + include_directories : [inc_drm, include_directories('.')], +) + +install_headers('omap_drmif.h', subdir : 'libdrm') +install_headers('omap_drm.h', subdir : 'omap') + +pkg.generate( + name : 'libdrm_omap', + libraries : libdrm_omap, + subdirs : ['.', 'libdrm', 'omap'], + version : '0.6', + requires_private : 'libdrm', + description : 'Userspace interface to omap kernel DRM services', +) + +test( + 'omap-symbol-check', + prog_bash, + env : env_test, + args : [files('omap-symbol-check'), libdrm_omap] +) diff --git a/lib/libdrm/omap/omap-symbol-check b/lib/libdrm/omap/omap-symbol-check index 759c84bd3..0fb4a0f26 100755 --- a/lib/libdrm/omap/omap-symbol-check +++ b/lib/libdrm/omap/omap-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.am/libdrm_omap*HEADERS -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_omap.so} | awk '{print $3}'| while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_omap.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata diff --git a/lib/libdrm/omap/omap_drm.c b/lib/libdrm/omap/omap_drm.c index 08ba64eb6..417d522c3 100644 --- a/lib/libdrm/omap/omap_drm.c +++ b/lib/libdrm/omap/omap_drm.c @@ -26,10 +26,6 @@ * Rob Clark <rob@ti.com> */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <linux/stddef.h> #include <linux/types.h> diff --git a/lib/libdrm/radeon/meson.build b/lib/libdrm/radeon/meson.build new file mode 100644 index 000000000..b08c74421 --- /dev/null +++ b/lib/libdrm/radeon/meson.build @@ -0,0 +1,64 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +libdrm_radeon = shared_library( + 'drm_radeon', + [ + files( + 'radeon_bo_gem.c', 'radeon_cs_gem.c', 'radeon_cs_space.c', 'radeon_bo.c', + 'radeon_cs.c', 'radeon_surface.c', + ), + config_file, + ], + c_args : warn_c_args, + include_directories : [inc_root, inc_drm], + link_with : libdrm, + dependencies : [dep_pthread_stubs, dep_atomic_ops], + version : '1.0.1', + install : true, +) + +ext_libdrm_radeon = declare_dependency( + link_with : [libdrm, libdrm_radeon], + include_directories : [inc_drm, include_directories('.')], +) + +install_headers( + 'radeon_bo.h', 'radeon_cs.h', 'radeon_surface.h', 'radeon_bo_gem.h', + 'radeon_cs_gem.h', 'radeon_bo_int.h', 'radeon_cs_int.h', 'r600_pci_ids.h', + subdir : 'libdrm' +) + +pkg.generate( + name : 'libdrm_radeon', + libraries : libdrm_radeon, + subdirs : ['.', 'libdrm'], + version : meson.project_version(), + requires_private : 'libdrm', + description : 'Userspace interface to kernel DRM services for radeon', +) + +test( + 'radeon-symbol-check', + prog_bash, + env : env_test, + args : [files('radeon-symbol-check'), libdrm_radeon] +) diff --git a/lib/libdrm/radeon/radeon-symbol-check b/lib/libdrm/radeon/radeon-symbol-check index 0bf2ffcbe..7d79d9012 100755 --- a/lib/libdrm/radeon/radeon-symbol-check +++ b/lib/libdrm/radeon/radeon-symbol-check @@ -3,7 +3,7 @@ # The following symbols (past the first five) are taken from the public headers. # A list of the latter should be available Makefile.sources/LIBDRM_RADEON_H_FILES -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_radeon.so} | awk '{print $3}'| while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_radeon.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_start _edata diff --git a/lib/libdrm/tegra/meson.build b/lib/libdrm/tegra/meson.build new file mode 100644 index 000000000..1f5c74b38 --- /dev/null +++ b/lib/libdrm/tegra/meson.build @@ -0,0 +1,53 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libdrm_tegra = shared_library( + 'drm_tegra', + [files('tegra.c'), config_file], + include_directories : [inc_root, inc_drm], + link_with : libdrm, + dependencies : [dep_pthread_stubs, dep_atomic_ops], + c_args : warn_c_args, + version : '0.0.0', + install : true, +) + +ext_libdrm_tegra = declare_dependency( + link_with : [libdrm, libdrm_tegra], + include_directories : [inc_drm, include_directories('.')], +) + +install_headers('tegra.h', subdir : 'libdrm') + +pkg.generate( + name : 'libdrm_tegra', + libraries : libdrm_tegra, + subdirs : ['.', 'libdrm'], + version : meson.project_version(), + requires_private : 'libdrm', + description : 'Userspace interface to Tegra kernel DRM services', +) + +test( + 'tegra-symbol-check', + prog_bash, + env : env_test, + args : [files('tegra-symbol-check'), libdrm_tegra] +) diff --git a/lib/libdrm/tegra/tegra-symbol-check b/lib/libdrm/tegra/tegra-symbol-check index 420469f41..509b678c3 100755 --- a/lib/libdrm/tegra/tegra-symbol-check +++ b/lib/libdrm/tegra/tegra-symbol-check @@ -2,7 +2,7 @@ # The following symbols (past the first nine) are taken from tegra.h. -FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_tegra.so} | awk '{print $3}'| while read func; do +FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_tegra.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF __bss_end__ __bss_start__ diff --git a/lib/libdrm/tegra/tegra.c b/lib/libdrm/tegra/tegra.c index f7dc89ad0..1d7268e5c 100644 --- a/lib/libdrm/tegra/tegra.c +++ b/lib/libdrm/tegra/tegra.c @@ -22,10 +22,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <errno.h> #include <fcntl.h> #include <string.h> diff --git a/lib/libdrm/tests/Makefile.am b/lib/libdrm/tests/Makefile.am index 0355a9255..b72c24f9e 100644 --- a/lib/libdrm/tests/Makefile.am +++ b/lib/libdrm/tests/Makefile.am @@ -43,5 +43,10 @@ TESTS = \ random check_PROGRAMS = \ - $(TESTS) \ - drmdevice + $(TESTS) + +if HAVE_INSTALL_TESTS +bin_PROGRAMS = drmdevice +else +check_PROGRAMS += drmdevice +endif diff --git a/lib/libdrm/tests/amdgpu/amdgpu_test.c b/lib/libdrm/tests/amdgpu/amdgpu_test.c index 8fa3399a4..96fcd687f 100644 --- a/lib/libdrm/tests/amdgpu/amdgpu_test.c +++ b/lib/libdrm/tests/amdgpu/amdgpu_test.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <string.h> #include <stdio.h> #include <stdlib.h> @@ -51,7 +47,7 @@ #include "amdgpu_test.h" #include "amdgpu_internal.h" -/* Test suit names */ +/* Test suite names */ #define BASIC_TESTS_STR "Basic Tests" #define BO_TESTS_STR "BO Tests" #define CS_TESTS_STR "CS Tests" @@ -167,7 +163,7 @@ static Suites_Active_Status suites_active_stat[] = { }, { .pName = VM_TESTS_STR, - .pActive = always_active, + .pActive = suite_vm_tests_enable, }, }; @@ -243,7 +239,6 @@ static const char options[] = "hlrps:t:b:d:f"; static int amdgpu_open_devices(int open_render_node) { drmDevicePtr devices[MAX_CARDS_SUPPORTED]; - int ret; int i; int drm_node; int amd_index = 0; @@ -400,7 +395,7 @@ static int amdgpu_find_device(uint8_t bus, uint16_t dev) return -1; } -static void amdgpu_disable_suits() +static void amdgpu_disable_suites() { amdgpu_device_handle device_handle; uint32_t major_version, minor_version, family_id; @@ -416,11 +411,11 @@ static void amdgpu_disable_suits() if (amdgpu_device_deinitialize(device_handle)) return; - /* Set active status for suits based on their policies */ + /* Set active status for suites based on their policies */ for (i = 0; i < size; ++i) if (amdgpu_set_suite_active(suites_active_stat[i].pName, suites_active_stat[i].pActive())) - fprintf(stderr, "suit deactivation failed - %s\n", CU_get_error_msg()); + fprintf(stderr, "suite deactivation failed - %s\n", CU_get_error_msg()); /* Explicitly disable specific tests due to known bugs or preferences */ /* @@ -433,6 +428,8 @@ static void amdgpu_disable_suits() if (amdgpu_set_test_active(BO_TESTS_STR, "Metadata", CU_FALSE)) fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + if (amdgpu_set_test_active(BASIC_TESTS_STR, "bo eviction Test", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); /* This test was ran on GFX8 and GFX9 only */ if (family_id < AMDGPU_FAMILY_VI || family_id > AMDGPU_FAMILY_RV) @@ -556,8 +553,8 @@ int main(int argc, char **argv) /* Run tests using the CUnit Basic interface */ CU_basic_set_mode(CU_BRM_VERBOSE); - /* Disable suits and individual tests based on misc. conditions */ - amdgpu_disable_suits(); + /* Disable suites and individual tests based on misc. conditions */ + amdgpu_disable_suites(); if (display_list) { display_test_suites(); diff --git a/lib/libdrm/tests/amdgpu/amdgpu_test.h b/lib/libdrm/tests/amdgpu/amdgpu_test.h index 3238e05f6..f2ece3c30 100644 --- a/lib/libdrm/tests/amdgpu/amdgpu_test.h +++ b/lib/libdrm/tests/amdgpu/amdgpu_test.h @@ -30,7 +30,7 @@ /** * Define max. number of card in system which we are able to handle */ -#define MAX_CARDS_SUPPORTED 4 +#define MAX_CARDS_SUPPORTED 128 /* Forward reference for array to keep "drm" handles */ extern int drm_amdgpu[MAX_CARDS_SUPPORTED]; @@ -185,6 +185,11 @@ int suite_vm_tests_init(); int suite_vm_tests_clean(); /** + * Decide if the suite is enabled by default or not. + */ +CU_BOOL suite_vm_tests_enable(void); + +/** * Tests in vm test suite */ extern CU_TestInfo vm_tests[]; @@ -247,6 +252,29 @@ static inline int gpu_mem_free(amdgpu_bo_handle bo, } static inline int +amdgpu_bo_alloc_wrap(amdgpu_device_handle dev, unsigned size, + unsigned alignment, unsigned heap, uint64_t flags, + amdgpu_bo_handle *bo) +{ + struct amdgpu_bo_alloc_request request = {}; + amdgpu_bo_handle buf_handle; + int r; + + request.alloc_size = size; + request.phys_alignment = alignment; + request.preferred_heap = heap; + request.flags = flags; + + r = amdgpu_bo_alloc(dev, &request, &buf_handle); + if (r) + return r; + + *bo = buf_handle; + + return 0; +} + +static inline int amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size, unsigned alignment, unsigned heap, uint64_t flags, amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address, @@ -322,26 +350,26 @@ amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1, } -static inline CU_ErrorCode amdgpu_set_suite_active(const char *suit_name, +static inline CU_ErrorCode amdgpu_set_suite_active(const char *suite_name, CU_BOOL active) { - CU_ErrorCode r = CU_set_suite_active(CU_get_suite(suit_name), active); + CU_ErrorCode r = CU_set_suite_active(CU_get_suite(suite_name), active); if (r != CUE_SUCCESS) - fprintf(stderr, "Failed to obtain suite %s\n", suit_name); + fprintf(stderr, "Failed to obtain suite %s\n", suite_name); return r; } -static inline CU_ErrorCode amdgpu_set_test_active(const char *suit_name, +static inline CU_ErrorCode amdgpu_set_test_active(const char *suite_name, const char *test_name, CU_BOOL active) { CU_ErrorCode r; - CU_pSuite pSuite = CU_get_suite(suit_name); + CU_pSuite pSuite = CU_get_suite(suite_name); if (!pSuite) { fprintf(stderr, "Failed to obtain suite %s\n", - suit_name); + suite_name); return CUE_NOSUITE; } diff --git a/lib/libdrm/tests/amdgpu/basic_tests.c b/lib/libdrm/tests/amdgpu/basic_tests.c index 474a679c0..1adbddd9d 100644 --- a/lib/libdrm/tests/amdgpu/basic_tests.c +++ b/lib/libdrm/tests/amdgpu/basic_tests.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -51,14 +47,22 @@ static void amdgpu_command_submission_sdma(void); static void amdgpu_userptr_test(void); static void amdgpu_semaphore_test(void); static void amdgpu_sync_dependency_test(void); +static void amdgpu_bo_eviction_test(void); static void amdgpu_command_submission_write_linear_helper(unsigned ip_type); static void amdgpu_command_submission_const_fill_helper(unsigned ip_type); static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type); - +static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle, + unsigned ip_type, + int instance, int pm4_dw, uint32_t *pm4_src, + int res_cnt, amdgpu_bo_handle *resources, + struct amdgpu_cs_ib_info *ib_info, + struct amdgpu_cs_request *ibs_request); + CU_TestInfo basic_tests[] = { { "Query Info Test", amdgpu_query_info_test }, { "Userptr Test", amdgpu_userptr_test }, + { "bo eviction Test", amdgpu_bo_eviction_test }, { "Command submission Test (GFX)", amdgpu_command_submission_gfx }, { "Command submission Test (Compute)", amdgpu_command_submission_compute }, { "Command submission Test (Multi-Fence)", amdgpu_command_submission_multi_fence }, @@ -253,10 +257,10 @@ CU_TestInfo basic_tests[] = { -#define SWAP_32(num) ((num>>24)&0xff) | \ - ((num<<8)&0xff0000) | \ - ((num>>8)&0xff00) | \ - ((num<<24)&0xff000000) +#define SWAP_32(num) (((num & 0xff000000) >> 24) | \ + ((num & 0x0000ff00) << 8) | \ + ((num & 0x00ff0000) >> 8) | \ + ((num & 0x000000ff) << 24)) /* Shader code @@ -516,6 +520,156 @@ static void amdgpu_command_submission_gfx_cp_copy_data(void) amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_GFX); } +static void amdgpu_bo_eviction_test(void) +{ + const int sdma_write_length = 1024; + const int pm4_dw = 256; + amdgpu_context_handle context_handle; + amdgpu_bo_handle bo1, bo2, vram_max[2], gtt_max[2]; + amdgpu_bo_handle *resources; + uint32_t *pm4; + struct amdgpu_cs_ib_info *ib_info; + struct amdgpu_cs_request *ibs_request; + uint64_t bo1_mc, bo2_mc; + volatile unsigned char *bo1_cpu, *bo2_cpu; + int i, j, r, loop1, loop2; + uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC}; + amdgpu_va_handle bo1_va_handle, bo2_va_handle; + struct amdgpu_heap_info vram_info, gtt_info; + + pm4 = calloc(pm4_dw, sizeof(*pm4)); + CU_ASSERT_NOT_EQUAL(pm4, NULL); + + ib_info = calloc(1, sizeof(*ib_info)); + CU_ASSERT_NOT_EQUAL(ib_info, NULL); + + ibs_request = calloc(1, sizeof(*ibs_request)); + CU_ASSERT_NOT_EQUAL(ibs_request, NULL); + + r = amdgpu_cs_ctx_create(device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); + + /* prepare resource */ + resources = calloc(4, sizeof(amdgpu_bo_handle)); + CU_ASSERT_NOT_EQUAL(resources, NULL); + + r = amdgpu_query_heap_info(device_handle, AMDGPU_GEM_DOMAIN_VRAM, + 0, &vram_info); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_wrap(device_handle, vram_info.max_allocation, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, &vram_max[0]); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_alloc_wrap(device_handle, vram_info.max_allocation, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, &vram_max[1]); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_query_heap_info(device_handle, AMDGPU_GEM_DOMAIN_GTT, + 0, >t_info); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, >t_max[0]); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, >t_max[1]); + CU_ASSERT_EQUAL(r, 0); + + + + loop1 = loop2 = 0; + /* run 9 circle to test all mapping combination */ + while(loop1 < 2) { + while(loop2 < 2) { + /* allocate UC bo1for sDMA use */ + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length, 4096, + AMDGPU_GEM_DOMAIN_GTT, + gtt_flags[loop1], &bo1, + (void**)&bo1_cpu, &bo1_mc, + &bo1_va_handle); + CU_ASSERT_EQUAL(r, 0); + + /* set bo1 */ + memset((void*)bo1_cpu, 0xaa, sdma_write_length); + + /* allocate UC bo2 for sDMA use */ + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length, 4096, + AMDGPU_GEM_DOMAIN_GTT, + gtt_flags[loop2], &bo2, + (void**)&bo2_cpu, &bo2_mc, + &bo2_va_handle); + CU_ASSERT_EQUAL(r, 0); + + /* clear bo2 */ + memset((void*)bo2_cpu, 0, sdma_write_length); + + resources[0] = bo1; + resources[1] = bo2; + resources[2] = vram_max[loop2]; + resources[3] = gtt_max[loop2]; + + /* fulfill PM4: test DMA copy linear */ + i = j = 0; + if (family_id == AMDGPU_FAMILY_SI) { + pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, 0, 0, 0, + sdma_write_length); + pm4[i++] = 0xffffffff & bo2_mc; + pm4[i++] = 0xffffffff & bo1_mc; + pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + } else { + pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0); + if (family_id >= AMDGPU_FAMILY_AI) + pm4[i++] = sdma_write_length - 1; + else + pm4[i++] = sdma_write_length; + pm4[i++] = 0; + pm4[i++] = 0xffffffff & bo1_mc; + pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + pm4[i++] = 0xffffffff & bo2_mc; + pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + } + + amdgpu_test_exec_cs_helper(context_handle, + AMDGPU_HW_IP_DMA, 0, + i, pm4, + 4, resources, + ib_info, ibs_request); + + /* verify if SDMA test result meets with expected */ + i = 0; + while(i < sdma_write_length) { + CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa); + } + r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc, + sdma_write_length); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc, + sdma_write_length); + CU_ASSERT_EQUAL(r, 0); + loop2++; + } + loop2 = 0; + loop1++; + } + amdgpu_bo_free(vram_max[0]); + amdgpu_bo_free(vram_max[1]); + amdgpu_bo_free(gtt_max[0]); + amdgpu_bo_free(gtt_max[1]); + /* clean resources */ + free(resources); + free(ibs_request); + free(ib_info); + free(pm4); + + /* end of test */ + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + + static void amdgpu_command_submission_gfx(void) { /* write data using the CP */ @@ -681,7 +835,7 @@ static void amdgpu_command_submission_compute_nop(void) struct amdgpu_cs_fence fence_status; uint32_t *ptr; uint32_t expired; - int i, r, instance; + int r, instance; amdgpu_bo_list_handle bo_list; amdgpu_va_handle va_handle; struct drm_amdgpu_info_hw_ip info; @@ -868,9 +1022,10 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type) struct amdgpu_cs_request *ibs_request; uint64_t bo_mc; volatile uint32_t *bo_cpu; - int i, j, r, loop; + int i, j, r, loop, ring_id; uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC}; amdgpu_va_handle va_handle; + struct drm_amdgpu_info_hw_ip hw_ip_info; pm4 = calloc(pm4_dw, sizeof(*pm4)); CU_ASSERT_NOT_EQUAL(pm4, NULL); @@ -881,6 +1036,9 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type) ibs_request = calloc(1, sizeof(*ibs_request)); CU_ASSERT_NOT_EQUAL(ibs_request, NULL); + r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_cs_ctx_create(device_handle, &context_handle); CU_ASSERT_EQUAL(r, 0); @@ -888,65 +1046,66 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type) resources = calloc(1, sizeof(amdgpu_bo_handle)); CU_ASSERT_NOT_EQUAL(resources, NULL); - loop = 0; - while(loop < 2) { - /* allocate UC bo for sDMA use */ - r = amdgpu_bo_alloc_and_map(device_handle, - sdma_write_length * sizeof(uint32_t), - 4096, AMDGPU_GEM_DOMAIN_GTT, - gtt_flags[loop], &bo, (void**)&bo_cpu, - &bo_mc, &va_handle); - CU_ASSERT_EQUAL(r, 0); + for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) { + loop = 0; + while(loop < 2) { + /* allocate UC bo for sDMA use */ + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length * sizeof(uint32_t), + 4096, AMDGPU_GEM_DOMAIN_GTT, + gtt_flags[loop], &bo, (void**)&bo_cpu, + &bo_mc, &va_handle); + CU_ASSERT_EQUAL(r, 0); - /* clear bo */ - memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t)); + /* clear bo */ + memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t)); + resources[0] = bo; - resources[0] = bo; + /* fulfill PM4: test DMA write-linear */ + i = j = 0; + if (ip_type == AMDGPU_HW_IP_DMA) { + if (family_id == AMDGPU_FAMILY_SI) + pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_WRITE, 0, 0, 0, + sdma_write_length); + else + pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE, + SDMA_WRITE_SUB_OPCODE_LINEAR, 0); + pm4[i++] = 0xffffffff & bo_mc; + pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; + if (family_id >= AMDGPU_FAMILY_AI) + pm4[i++] = sdma_write_length - 1; + else if (family_id != AMDGPU_FAMILY_SI) + pm4[i++] = sdma_write_length; + while(j++ < sdma_write_length) + pm4[i++] = 0xdeadbeaf; + } else if ((ip_type == AMDGPU_HW_IP_GFX) || + (ip_type == AMDGPU_HW_IP_COMPUTE)) { + pm4[i++] = PACKET3(PACKET3_WRITE_DATA, 2 + sdma_write_length); + pm4[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; + pm4[i++] = 0xfffffffc & bo_mc; + pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; + while(j++ < sdma_write_length) + pm4[i++] = 0xdeadbeaf; + } - /* fulfill PM4: test DMA write-linear */ - i = j = 0; - if (ip_type == AMDGPU_HW_IP_DMA) { - if (family_id == AMDGPU_FAMILY_SI) - pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_WRITE, 0, 0, 0, - sdma_write_length); - else - pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE, - SDMA_WRITE_SUB_OPCODE_LINEAR, 0); - pm4[i++] = 0xffffffff & bo_mc; - pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; - if (family_id >= AMDGPU_FAMILY_AI) - pm4[i++] = sdma_write_length - 1; - else if (family_id != AMDGPU_FAMILY_SI) - pm4[i++] = sdma_write_length; - while(j++ < sdma_write_length) - pm4[i++] = 0xdeadbeaf; - } else if ((ip_type == AMDGPU_HW_IP_GFX) || - (ip_type == AMDGPU_HW_IP_COMPUTE)) { - pm4[i++] = PACKET3(PACKET3_WRITE_DATA, 2 + sdma_write_length); - pm4[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; - pm4[i++] = 0xfffffffc & bo_mc; - pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; - while(j++ < sdma_write_length) - pm4[i++] = 0xdeadbeaf; - } + amdgpu_test_exec_cs_helper(context_handle, + ip_type, ring_id, + i, pm4, + 1, resources, + ib_info, ibs_request); - amdgpu_test_exec_cs_helper(context_handle, - ip_type, 0, - i, pm4, - 1, resources, - ib_info, ibs_request); + /* verify if SDMA test result meets with expected */ + i = 0; + while(i < sdma_write_length) { + CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf); + } - /* verify if SDMA test result meets with expected */ - i = 0; - while(i < sdma_write_length) { - CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf); + r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc, + sdma_write_length * sizeof(uint32_t)); + CU_ASSERT_EQUAL(r, 0); + loop++; } - - r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc, - sdma_write_length * sizeof(uint32_t)); - CU_ASSERT_EQUAL(r, 0); - loop++; } /* clean resources */ free(resources); @@ -976,9 +1135,10 @@ static void amdgpu_command_submission_const_fill_helper(unsigned ip_type) struct amdgpu_cs_request *ibs_request; uint64_t bo_mc; volatile uint32_t *bo_cpu; - int i, j, r, loop; + int i, j, r, loop, ring_id; uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC}; amdgpu_va_handle va_handle; + struct drm_amdgpu_info_hw_ip hw_ip_info; pm4 = calloc(pm4_dw, sizeof(*pm4)); CU_ASSERT_NOT_EQUAL(pm4, NULL); @@ -989,6 +1149,9 @@ static void amdgpu_command_submission_const_fill_helper(unsigned ip_type) ibs_request = calloc(1, sizeof(*ibs_request)); CU_ASSERT_NOT_EQUAL(ibs_request, NULL); + r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_cs_ctx_create(device_handle, &context_handle); CU_ASSERT_EQUAL(r, 0); @@ -996,83 +1159,86 @@ static void amdgpu_command_submission_const_fill_helper(unsigned ip_type) resources = calloc(1, sizeof(amdgpu_bo_handle)); CU_ASSERT_NOT_EQUAL(resources, NULL); - loop = 0; - while(loop < 2) { - /* allocate UC bo for sDMA use */ - r = amdgpu_bo_alloc_and_map(device_handle, - sdma_write_length, 4096, - AMDGPU_GEM_DOMAIN_GTT, - gtt_flags[loop], &bo, (void**)&bo_cpu, - &bo_mc, &va_handle); - CU_ASSERT_EQUAL(r, 0); + for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) { + loop = 0; + while(loop < 2) { + /* allocate UC bo for sDMA use */ + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length, 4096, + AMDGPU_GEM_DOMAIN_GTT, + gtt_flags[loop], &bo, (void**)&bo_cpu, + &bo_mc, &va_handle); + CU_ASSERT_EQUAL(r, 0); - /* clear bo */ - memset((void*)bo_cpu, 0, sdma_write_length); + /* clear bo */ + memset((void*)bo_cpu, 0, sdma_write_length); - resources[0] = bo; + resources[0] = bo; - /* fulfill PM4: test DMA const fill */ - i = j = 0; - if (ip_type == AMDGPU_HW_IP_DMA) { - if (family_id == AMDGPU_FAMILY_SI) { - pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_CONSTANT_FILL_SI, 0, 0, 0, - sdma_write_length / 4); - pm4[i++] = 0xfffffffc & bo_mc; - pm4[i++] = 0xdeadbeaf; - pm4[i++] = (0xffffffff00000000 & bo_mc) >> 16; - } else { - pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0, - SDMA_CONSTANT_FILL_EXTRA_SIZE(2)); - pm4[i++] = 0xffffffff & bo_mc; - pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; - pm4[i++] = 0xdeadbeaf; - if (family_id >= AMDGPU_FAMILY_AI) - pm4[i++] = sdma_write_length - 1; - else + /* fulfill PM4: test DMA const fill */ + i = j = 0; + if (ip_type == AMDGPU_HW_IP_DMA) { + if (family_id == AMDGPU_FAMILY_SI) { + pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_CONSTANT_FILL_SI, + 0, 0, 0, + sdma_write_length / 4); + pm4[i++] = 0xfffffffc & bo_mc; + pm4[i++] = 0xdeadbeaf; + pm4[i++] = (0xffffffff00000000 & bo_mc) >> 16; + } else { + pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0, + SDMA_CONSTANT_FILL_EXTRA_SIZE(2)); + pm4[i++] = 0xffffffff & bo_mc; + pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; + pm4[i++] = 0xdeadbeaf; + if (family_id >= AMDGPU_FAMILY_AI) + pm4[i++] = sdma_write_length - 1; + else + pm4[i++] = sdma_write_length; + } + } else if ((ip_type == AMDGPU_HW_IP_GFX) || + (ip_type == AMDGPU_HW_IP_COMPUTE)) { + if (family_id == AMDGPU_FAMILY_SI) { + pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4); + pm4[i++] = 0xdeadbeaf; + pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) | + PACKET3_DMA_DATA_SI_DST_SEL(0) | + PACKET3_DMA_DATA_SI_SRC_SEL(2) | + PACKET3_DMA_DATA_SI_CP_SYNC; + pm4[i++] = 0xffffffff & bo_mc; + pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; pm4[i++] = sdma_write_length; + } else { + pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5); + pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) | + PACKET3_DMA_DATA_DST_SEL(0) | + PACKET3_DMA_DATA_SRC_SEL(2) | + PACKET3_DMA_DATA_CP_SYNC; + pm4[i++] = 0xdeadbeaf; + pm4[i++] = 0; + pm4[i++] = 0xfffffffc & bo_mc; + pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; + pm4[i++] = sdma_write_length; + } } - } else if ((ip_type == AMDGPU_HW_IP_GFX) || - (ip_type == AMDGPU_HW_IP_COMPUTE)) { - if (family_id == AMDGPU_FAMILY_SI) { - pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4); - pm4[i++] = 0xdeadbeaf; - pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) | - PACKET3_DMA_DATA_SI_DST_SEL(0) | - PACKET3_DMA_DATA_SI_SRC_SEL(2) | - PACKET3_DMA_DATA_SI_CP_SYNC; - pm4[i++] = 0xffffffff & bo_mc; - pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; - pm4[i++] = sdma_write_length; - } else { - pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5); - pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) | - PACKET3_DMA_DATA_DST_SEL(0) | - PACKET3_DMA_DATA_SRC_SEL(2) | - PACKET3_DMA_DATA_CP_SYNC; - pm4[i++] = 0xdeadbeaf; - pm4[i++] = 0; - pm4[i++] = 0xfffffffc & bo_mc; - pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32; - pm4[i++] = sdma_write_length; - } - } - amdgpu_test_exec_cs_helper(context_handle, - ip_type, 0, - i, pm4, - 1, resources, - ib_info, ibs_request); + amdgpu_test_exec_cs_helper(context_handle, + ip_type, ring_id, + i, pm4, + 1, resources, + ib_info, ibs_request); - /* verify if SDMA test result meets with expected */ - i = 0; - while(i < (sdma_write_length / 4)) { - CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf); - } + /* verify if SDMA test result meets with expected */ + i = 0; + while(i < (sdma_write_length / 4)) { + CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf); + } - r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc, - sdma_write_length); - CU_ASSERT_EQUAL(r, 0); - loop++; + r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc, + sdma_write_length); + CU_ASSERT_EQUAL(r, 0); + loop++; + } } /* clean resources */ free(resources); @@ -1102,9 +1268,10 @@ static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type) struct amdgpu_cs_request *ibs_request; uint64_t bo1_mc, bo2_mc; volatile unsigned char *bo1_cpu, *bo2_cpu; - int i, j, r, loop1, loop2; + int i, j, r, loop1, loop2, ring_id; uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC}; amdgpu_va_handle bo1_va_handle, bo2_va_handle; + struct drm_amdgpu_info_hw_ip hw_ip_info; pm4 = calloc(pm4_dw, sizeof(*pm4)); CU_ASSERT_NOT_EQUAL(pm4, NULL); @@ -1115,6 +1282,9 @@ static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type) ibs_request = calloc(1, sizeof(*ibs_request)); CU_ASSERT_NOT_EQUAL(ibs_request, NULL); + r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_cs_ctx_create(device_handle, &context_handle); CU_ASSERT_EQUAL(r, 0); @@ -1122,107 +1292,111 @@ static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type) resources = calloc(2, sizeof(amdgpu_bo_handle)); CU_ASSERT_NOT_EQUAL(resources, NULL); - loop1 = loop2 = 0; - /* run 9 circle to test all mapping combination */ - while(loop1 < 2) { - while(loop2 < 2) { - /* allocate UC bo1for sDMA use */ - r = amdgpu_bo_alloc_and_map(device_handle, - sdma_write_length, 4096, - AMDGPU_GEM_DOMAIN_GTT, - gtt_flags[loop1], &bo1, - (void**)&bo1_cpu, &bo1_mc, - &bo1_va_handle); - CU_ASSERT_EQUAL(r, 0); - - /* set bo1 */ - memset((void*)bo1_cpu, 0xaa, sdma_write_length); - - /* allocate UC bo2 for sDMA use */ - r = amdgpu_bo_alloc_and_map(device_handle, - sdma_write_length, 4096, - AMDGPU_GEM_DOMAIN_GTT, - gtt_flags[loop2], &bo2, - (void**)&bo2_cpu, &bo2_mc, - &bo2_va_handle); - CU_ASSERT_EQUAL(r, 0); - - /* clear bo2 */ - memset((void*)bo2_cpu, 0, sdma_write_length); - - resources[0] = bo1; - resources[1] = bo2; - - /* fulfill PM4: test DMA copy linear */ - i = j = 0; - if (ip_type == AMDGPU_HW_IP_DMA) { - if (family_id == AMDGPU_FAMILY_SI) { - pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, 0, 0, 0, - sdma_write_length); - pm4[i++] = 0xffffffff & bo2_mc; - pm4[i++] = 0xffffffff & bo1_mc; - pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; - pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; - } else { - pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0); - if (family_id >= AMDGPU_FAMILY_AI) - pm4[i++] = sdma_write_length - 1; - else + for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) { + loop1 = loop2 = 0; + /* run 9 circle to test all mapping combination */ + while(loop1 < 2) { + while(loop2 < 2) { + /* allocate UC bo1for sDMA use */ + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length, 4096, + AMDGPU_GEM_DOMAIN_GTT, + gtt_flags[loop1], &bo1, + (void**)&bo1_cpu, &bo1_mc, + &bo1_va_handle); + CU_ASSERT_EQUAL(r, 0); + + /* set bo1 */ + memset((void*)bo1_cpu, 0xaa, sdma_write_length); + + /* allocate UC bo2 for sDMA use */ + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length, 4096, + AMDGPU_GEM_DOMAIN_GTT, + gtt_flags[loop2], &bo2, + (void**)&bo2_cpu, &bo2_mc, + &bo2_va_handle); + CU_ASSERT_EQUAL(r, 0); + + /* clear bo2 */ + memset((void*)bo2_cpu, 0, sdma_write_length); + + resources[0] = bo1; + resources[1] = bo2; + + /* fulfill PM4: test DMA copy linear */ + i = j = 0; + if (ip_type == AMDGPU_HW_IP_DMA) { + if (family_id == AMDGPU_FAMILY_SI) { + pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, + 0, 0, 0, + sdma_write_length); + pm4[i++] = 0xffffffff & bo2_mc; + pm4[i++] = 0xffffffff & bo1_mc; + pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + } else { + pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, + SDMA_COPY_SUB_OPCODE_LINEAR, + 0); + if (family_id >= AMDGPU_FAMILY_AI) + pm4[i++] = sdma_write_length - 1; + else + pm4[i++] = sdma_write_length; + pm4[i++] = 0; + pm4[i++] = 0xffffffff & bo1_mc; + pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + pm4[i++] = 0xffffffff & bo2_mc; + pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + } + } else if ((ip_type == AMDGPU_HW_IP_GFX) || + (ip_type == AMDGPU_HW_IP_COMPUTE)) { + if (family_id == AMDGPU_FAMILY_SI) { + pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4); + pm4[i++] = 0xfffffffc & bo1_mc; + pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) | + PACKET3_DMA_DATA_SI_DST_SEL(0) | + PACKET3_DMA_DATA_SI_SRC_SEL(0) | + PACKET3_DMA_DATA_SI_CP_SYNC | + (0xffff00000000 & bo1_mc) >> 32; + pm4[i++] = 0xfffffffc & bo2_mc; + pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; pm4[i++] = sdma_write_length; - pm4[i++] = 0; - pm4[i++] = 0xffffffff & bo1_mc; - pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; - pm4[i++] = 0xffffffff & bo2_mc; - pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + } else { + pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5); + pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) | + PACKET3_DMA_DATA_DST_SEL(0) | + PACKET3_DMA_DATA_SRC_SEL(0) | + PACKET3_DMA_DATA_CP_SYNC; + pm4[i++] = 0xfffffffc & bo1_mc; + pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + pm4[i++] = 0xfffffffc & bo2_mc; + pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + pm4[i++] = sdma_write_length; + } } - } else if ((ip_type == AMDGPU_HW_IP_GFX) || - (ip_type == AMDGPU_HW_IP_COMPUTE)) { - if (family_id == AMDGPU_FAMILY_SI) { - pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4); - pm4[i++] = 0xfffffffc & bo1_mc; - pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) | - PACKET3_DMA_DATA_SI_DST_SEL(0) | - PACKET3_DMA_DATA_SI_SRC_SEL(0) | - PACKET3_DMA_DATA_SI_CP_SYNC | - (0xffff00000000 & bo1_mc) >> 32; - pm4[i++] = 0xfffffffc & bo2_mc; - pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; - pm4[i++] = sdma_write_length; - } else { - pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5); - pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) | - PACKET3_DMA_DATA_DST_SEL(0) | - PACKET3_DMA_DATA_SRC_SEL(0) | - PACKET3_DMA_DATA_CP_SYNC; - pm4[i++] = 0xfffffffc & bo1_mc; - pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32; - pm4[i++] = 0xfffffffc & bo2_mc; - pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32; - pm4[i++] = sdma_write_length; - } - } + amdgpu_test_exec_cs_helper(context_handle, + ip_type, ring_id, + i, pm4, + 2, resources, + ib_info, ibs_request); - amdgpu_test_exec_cs_helper(context_handle, - ip_type, 0, - i, pm4, - 2, resources, - ib_info, ibs_request); - - /* verify if SDMA test result meets with expected */ - i = 0; - while(i < sdma_write_length) { - CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa); + /* verify if SDMA test result meets with expected */ + i = 0; + while(i < sdma_write_length) { + CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa); + } + r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc, + sdma_write_length); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc, + sdma_write_length); + CU_ASSERT_EQUAL(r, 0); + loop2++; } - r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc, - sdma_write_length); - CU_ASSERT_EQUAL(r, 0); - r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc, - sdma_write_length); - CU_ASSERT_EQUAL(r, 0); - loop2++; + loop1++; } - loop1++; } /* clean resources */ free(resources); @@ -1453,7 +1627,7 @@ static void amdgpu_sync_dependency_test(void) struct amdgpu_cs_ib_info ib_info; struct amdgpu_cs_fence fence_status; uint32_t expired; - int i, j, r, instance; + int i, j, r; amdgpu_bo_list_handle bo_list; amdgpu_va_handle va_handle; static uint32_t *ptr; @@ -1588,7 +1762,7 @@ static void amdgpu_sync_dependency_test(void) j = i; ptr[i++] = PACKET3(PACKET3_WRITE_DATA, 3); ptr[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; - ptr[i++] = 0xfffffffc & ib_result_mc_address + DATA_OFFSET * 4; + ptr[i++] = 0xfffffffc & (ib_result_mc_address + DATA_OFFSET * 4); ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32; ptr[i++] = 99; diff --git a/lib/libdrm/tests/amdgpu/bo_tests.c b/lib/libdrm/tests/amdgpu/bo_tests.c index 24698bcb0..dc2de9b70 100644 --- a/lib/libdrm/tests/amdgpu/bo_tests.c +++ b/lib/libdrm/tests/amdgpu/bo_tests.c @@ -21,16 +21,13 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include "CUnit/Basic.h" #include "amdgpu_test.h" #include "amdgpu_drm.h" +#include "amdgpu_internal.h" #define BUFFER_SIZE (4*1024) #define BUFFER_ALIGN (4*1024) @@ -48,6 +45,7 @@ static void amdgpu_bo_metadata(void); static void amdgpu_bo_map_unmap(void); static void amdgpu_memory_alloc(void); static void amdgpu_mem_fail_alloc(void); +static void amdgpu_bo_find_by_cpu_mapping(void); CU_TestInfo bo_tests[] = { { "Export/Import", amdgpu_bo_export_import }, @@ -55,6 +53,7 @@ CU_TestInfo bo_tests[] = { { "CPU map/unmap", amdgpu_bo_map_unmap }, { "Memory alloc Test", amdgpu_memory_alloc }, { "Memory fail alloc Test", amdgpu_mem_fail_alloc }, + { "Find bo by CPU mapping", amdgpu_bo_find_by_cpu_mapping }, CU_TEST_INFO_NULL, }; @@ -266,3 +265,33 @@ static void amdgpu_mem_fail_alloc(void) CU_ASSERT_EQUAL(r, 0); } } + +static void amdgpu_bo_find_by_cpu_mapping(void) +{ + amdgpu_bo_handle bo_handle, find_bo_handle; + amdgpu_va_handle va_handle; + void *bo_cpu; + uint64_t bo_mc_address; + uint64_t offset; + int r; + + r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, + &bo_handle, &bo_cpu, + &bo_mc_address, &va_handle); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_find_bo_by_cpu_mapping(device_handle, + bo_cpu, + 4096, + &find_bo_handle, + &offset); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(offset, 0); + CU_ASSERT_EQUAL(bo_handle->handle, find_bo_handle->handle); + + atomic_dec(&find_bo_handle->refcount, 1); + r = amdgpu_bo_unmap_and_free(bo_handle, va_handle, + bo_mc_address, 4096); + CU_ASSERT_EQUAL(r, 0); +} diff --git a/lib/libdrm/tests/amdgpu/cs_tests.c b/lib/libdrm/tests/amdgpu/cs_tests.c index 4880b74f8..7ad0f0dcb 100644 --- a/lib/libdrm/tests/amdgpu/cs_tests.c +++ b/lib/libdrm/tests/amdgpu/cs_tests.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include "CUnit/Basic.h" @@ -273,7 +269,7 @@ static void amdgpu_cs_uvd_create(void) static void amdgpu_cs_uvd_decode(void) { - const unsigned dpb_size = 15923584, ctx_size = 5287680, dt_size = 737280; + const unsigned dpb_size = 15923584, dt_size = 737280; uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr; struct amdgpu_bo_alloc_request req = {0}; amdgpu_bo_handle buf_handle; diff --git a/lib/libdrm/tests/amdgpu/deadlock_tests.c b/lib/libdrm/tests/amdgpu/deadlock_tests.c index 84f4debe3..304482d71 100644 --- a/lib/libdrm/tests/amdgpu/deadlock_tests.c +++ b/lib/libdrm/tests/amdgpu/deadlock_tests.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -90,25 +86,27 @@ static void amdgpu_deadlock_compute(void); CU_BOOL suite_deadlock_tests_enable(void) { + CU_BOOL enable = CU_TRUE; + if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version, &device_handle)) return CU_FALSE; - if (amdgpu_device_deinitialize(device_handle)) - return CU_FALSE; - - - if (device_handle->info.family_id == AMDGPU_FAMILY_AI) { + if (device_handle->info.family_id == AMDGPU_FAMILY_AI || + device_handle->info.family_id == AMDGPU_FAMILY_SI || + device_handle->info.family_id == AMDGPU_FAMILY_RV) { printf("\n\nCurrently hangs the CP on this ASIC, deadlock suite disabled\n"); - return CU_FALSE; + enable = CU_FALSE; } - return CU_TRUE; + if (amdgpu_device_deinitialize(device_handle)) + return CU_FALSE; + + return enable; } int suite_deadlock_tests_init(void) { - struct amdgpu_gpu_info gpu_info = {0}; int r; r = amdgpu_device_initialize(drm_amdgpu[0], &major_version, @@ -175,7 +173,7 @@ static void amdgpu_deadlock_helper(unsigned ip_type) struct amdgpu_cs_ib_info ib_info; struct amdgpu_cs_fence fence_status; uint32_t expired; - int i, r, instance; + int i, r; amdgpu_bo_list_handle bo_list; amdgpu_va_handle va_handle; @@ -229,7 +227,7 @@ static void amdgpu_deadlock_helper(unsigned ip_type) for (i = 0; i < 200; i++) { r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1); - CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); } @@ -242,7 +240,9 @@ static void amdgpu_deadlock_helper(unsigned ip_type) r = amdgpu_cs_query_fence_status(&fence_status, AMDGPU_TIMEOUT_INFINITE,0, &expired); - CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); + + pthread_join(stress_thread, NULL); r = amdgpu_bo_list_destroy(bo_list); CU_ASSERT_EQUAL(r, 0); @@ -253,6 +253,4 @@ static void amdgpu_deadlock_helper(unsigned ip_type) r = amdgpu_cs_ctx_free(context_handle); CU_ASSERT_EQUAL(r, 0); - - pthread_join(stress_thread, NULL); } diff --git a/lib/libdrm/tests/amdgpu/meson.build b/lib/libdrm/tests/amdgpu/meson.build new file mode 100644 index 000000000..4c1237c64 --- /dev/null +++ b/lib/libdrm/tests/amdgpu/meson.build @@ -0,0 +1,34 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if dep_cunit.found() + amdgpu_test = executable( + 'amdgpu_test', + files( + 'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c', + 'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c', + 'vm_tests.c', + ), + dependencies : [dep_cunit, dep_threads], + include_directories : [inc_root, inc_drm, include_directories('../../amdgpu')], + link_with : [libdrm, libdrm_amdgpu], + install : with_install_tests, + ) +endif diff --git a/lib/libdrm/tests/amdgpu/uvd_enc_tests.c b/lib/libdrm/tests/amdgpu/uvd_enc_tests.c index bed8494a8..b4251bcf3 100644 --- a/lib/libdrm/tests/amdgpu/uvd_enc_tests.c +++ b/lib/libdrm/tests/amdgpu/uvd_enc_tests.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include <inttypes.h> @@ -247,8 +243,6 @@ static void free_resource(struct amdgpu_uvd_enc_bo *uvd_enc_bo) static void amdgpu_cs_uvd_enc_create(void) { - int len, r; - enc.width = 160; enc.height = 128; @@ -263,7 +257,7 @@ static void check_result(struct amdgpu_uvd_enc *enc) uint64_t sum; uint32_t s = 175602; uint32_t *ptr, size; - int i, j, r; + int j, r; r = amdgpu_bo_cpu_map(enc->fb.handle, (void **)&enc->fb.ptr); CU_ASSERT_EQUAL(r, 0); @@ -470,7 +464,6 @@ static void amdgpu_cs_uvd_enc_encode(void) static void amdgpu_cs_uvd_enc_destroy(void) { - struct amdgpu_uvd_enc_bo sw_ctx; int len, r; num_resources = 0; diff --git a/lib/libdrm/tests/amdgpu/vce_ib.h b/lib/libdrm/tests/amdgpu/vce_ib.h index 80ab17956..f3108a040 100644 --- a/lib/libdrm/tests/amdgpu/vce_ib.h +++ b/lib/libdrm/tests/amdgpu/vce_ib.h @@ -315,4 +315,21 @@ static const uint32_t vce_destroy[] = { 0x00000008, 0x02000001, }; + +static const uint32_t vce_mv_buffer[] = { + 0x00000038, + 0x0500000d, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; #endif /*_vce_ib_h*/ diff --git a/lib/libdrm/tests/amdgpu/vce_tests.c b/lib/libdrm/tests/amdgpu/vce_tests.c index 75821bbb1..b9e15ee97 100644 --- a/lib/libdrm/tests/amdgpu/vce_tests.c +++ b/lib/libdrm/tests/amdgpu/vce_tests.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include <inttypes.h> @@ -41,6 +37,7 @@ #define IB_SIZE 4096 #define MAX_RESOURCES 16 +#define FW_53_0_03 ((53 << 24) | (0 << 16) | (03 << 8)) struct amdgpu_vce_bo { amdgpu_bo_handle handle; @@ -59,6 +56,9 @@ struct amdgpu_vce_encode { struct amdgpu_vce_bo cpb; unsigned ib_len; bool two_instance; + struct amdgpu_vce_bo mvrefbuf; + struct amdgpu_vce_bo mvb; + unsigned mvbuf_size; }; static amdgpu_device_handle device_handle; @@ -66,6 +66,10 @@ static uint32_t major_version; static uint32_t minor_version; static uint32_t family_id; static uint32_t vce_harvest_config; +static uint32_t chip_rev; +static uint32_t chip_id; +static uint32_t ids_flags; +static bool is_mv_supported = true; static amdgpu_context_handle context_handle; static amdgpu_bo_handle ib_handle; @@ -79,33 +83,58 @@ static unsigned num_resources; static void amdgpu_cs_vce_create(void); static void amdgpu_cs_vce_encode(void); +static void amdgpu_cs_vce_encode_mv(void); static void amdgpu_cs_vce_destroy(void); CU_TestInfo vce_tests[] = { { "VCE create", amdgpu_cs_vce_create }, { "VCE encode", amdgpu_cs_vce_encode }, + { "VCE MV dump", amdgpu_cs_vce_encode_mv }, { "VCE destroy", amdgpu_cs_vce_destroy }, CU_TEST_INFO_NULL, }; - CU_BOOL suite_vce_tests_enable(void) { + uint32_t version, feature; + CU_BOOL ret_mv = CU_FALSE; + if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version, &device_handle)) return CU_FALSE; family_id = device_handle->info.family_id; + chip_rev = device_handle->info.chip_rev; + chip_id = device_handle->info.chip_external_rev; + ids_flags = device_handle->info.ids_flags; + + amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0, + 0, &version, &feature); if (amdgpu_device_deinitialize(device_handle)) return CU_FALSE; - if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI) { printf("\n\nThe ASIC NOT support VCE, suite disabled\n"); return CU_FALSE; } + if (!(chip_id == (chip_rev + 0x3C) || /* FIJI */ + chip_id == (chip_rev + 0x50) || /* Polaris 10*/ + chip_id == (chip_rev + 0x5A) || /* Polaris 11*/ + chip_id == (chip_rev + 0x64) || /* Polaris 12*/ + (family_id >= AMDGPU_FAMILY_AI && !ids_flags))) /* dGPU > Polaris */ + printf("\n\nThe ASIC NOT support VCE MV, suite disabled\n"); + else if (FW_53_0_03 > version) + printf("\n\nThe ASIC FW version NOT support VCE MV, suite disabled\n"); + else + ret_mv = CU_TRUE; + + if (ret_mv == CU_FALSE) { + amdgpu_set_test_active("VCE Tests", "VCE MV dump", ret_mv); + is_mv_supported = false; + } + return CU_TRUE; } @@ -274,6 +303,12 @@ static void amdgpu_cs_vce_create(void) memcpy((ib_cpu + len), vce_create, sizeof(vce_create)); ib_cpu[len + 8] = ALIGN(enc.width, align); ib_cpu[len + 9] = ALIGN(enc.width, align); + if (is_mv_supported == true) {/* disableTwoInstance */ + if (family_id >= AMDGPU_FAMILY_AI) + ib_cpu[len + 11] = 0x01000001; + else + ib_cpu[len + 11] = 0x01000201; + } len += sizeof(vce_create) / 4; memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback)); ib_cpu[len + 2] = enc.fb[0].addr >> 32; @@ -305,13 +340,15 @@ static void amdgpu_cs_vce_config(void) memcpy((ib_cpu + len), vce_rdo, sizeof(vce_rdo)); len += sizeof(vce_rdo) / 4; memcpy((ib_cpu + len), vce_pic_ctrl, sizeof(vce_pic_ctrl)); + if (is_mv_supported == true) + ib_cpu[len + 27] = 0x00000001; /* encSliceMode */ len += sizeof(vce_pic_ctrl) / 4; r = submit(len, AMDGPU_HW_IP_VCE); CU_ASSERT_EQUAL(r, 0); } -static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc) +static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc) { uint64_t luma_offset, chroma_offset; @@ -525,6 +562,180 @@ static void amdgpu_cs_vce_encode(void) free_resource(&enc.cpb); } +static void amdgpu_cs_vce_mv(struct amdgpu_vce_encode *enc) +{ + uint64_t luma_offset, chroma_offset; + uint64_t mv_ref_luma_offset; + unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16; + unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16); + int len = 0, i, r; + + luma_offset = enc->vbuf.addr; + chroma_offset = luma_offset + luma_size; + mv_ref_luma_offset = enc->mvrefbuf.addr; + + memcpy((ib_cpu + len), vce_session, sizeof(vce_session)); + len += sizeof(vce_session) / 4; + memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo)); + len += sizeof(vce_taskinfo) / 4; + memcpy((ib_cpu + len), vce_bs_buffer, sizeof(vce_bs_buffer)); + ib_cpu[len + 2] = enc->bs[0].addr >> 32; + ib_cpu[len + 3] = enc->bs[0].addr; + len += sizeof(vce_bs_buffer) / 4; + memcpy((ib_cpu + len), vce_context_buffer, sizeof(vce_context_buffer)); + ib_cpu[len + 2] = enc->cpb.addr >> 32; + ib_cpu[len + 3] = enc->cpb.addr; + len += sizeof(vce_context_buffer) / 4; + memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer)); + for (i = 0; i < 8; ++i) + ib_cpu[len + 2 + i] = luma_size * 1.5 * (i + 2); + for (i = 0; i < 8; ++i) + ib_cpu[len + 10 + i] = luma_size * 1.5; + len += sizeof(vce_aux_buffer) / 4; + memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback)); + ib_cpu[len + 2] = enc->fb[0].addr >> 32; + ib_cpu[len + 3] = enc->fb[0].addr; + len += sizeof(vce_feedback) / 4; + memcpy((ib_cpu + len), vce_mv_buffer, sizeof(vce_mv_buffer)); + ib_cpu[len + 2] = mv_ref_luma_offset >> 32; + ib_cpu[len + 3] = mv_ref_luma_offset; + ib_cpu[len + 4] = ALIGN(enc->width, align); + ib_cpu[len + 5] = ALIGN(enc->width, align); + ib_cpu[len + 6] = luma_size; + ib_cpu[len + 7] = enc->mvb.addr >> 32; + ib_cpu[len + 8] = enc->mvb.addr; + len += sizeof(vce_mv_buffer) / 4; + memcpy((ib_cpu + len), vce_encode, sizeof(vce_encode)); + ib_cpu[len + 2] = 0; + ib_cpu[len + 3] = 0; + ib_cpu[len + 4] = 0x154000; + ib_cpu[len + 9] = luma_offset >> 32; + ib_cpu[len + 10] = luma_offset; + ib_cpu[len + 11] = chroma_offset >> 32; + ib_cpu[len + 12] = chroma_offset; + ib_cpu[len + 13] = ALIGN(enc->height, 16);; + ib_cpu[len + 14] = ALIGN(enc->width, align); + ib_cpu[len + 15] = ALIGN(enc->width, align); + /* encDisableMBOffloading-encDisableTwoPipeMode-encInputPicArrayMode-encInputPicAddrMode */ + ib_cpu[len + 16] = 0x01010000; + ib_cpu[len + 18] = 0; /* encPicType */ + ib_cpu[len + 19] = 0; /* encIdrFlag */ + ib_cpu[len + 20] = 0; /* encIdrPicId */ + ib_cpu[len + 21] = 0; /* encMGSKeyPic */ + ib_cpu[len + 22] = 0; /* encReferenceFlag */ + ib_cpu[len + 23] = 0; /* encTemporalLayerIndex */ + ib_cpu[len + 55] = 0; /* pictureStructure */ + ib_cpu[len + 56] = 0; /* encPicType -ref[0] */ + ib_cpu[len + 61] = 0; /* pictureStructure */ + ib_cpu[len + 62] = 0; /* encPicType -ref[1] */ + ib_cpu[len + 67] = 0; /* pictureStructure */ + ib_cpu[len + 68] = 0; /* encPicType -ref1 */ + ib_cpu[len + 81] = 1; /* frameNumber */ + ib_cpu[len + 82] = 2; /* pictureOrderCount */ + ib_cpu[len + 83] = 0xffffffff; /* numIPicRemainInRCGOP */ + ib_cpu[len + 84] = 0xffffffff; /* numPPicRemainInRCGOP */ + ib_cpu[len + 85] = 0xffffffff; /* numBPicRemainInRCGOP */ + ib_cpu[len + 86] = 0xffffffff; /* numIRPicRemainInRCGOP */ + ib_cpu[len + 87] = 0; /* remainedIntraRefreshPictures */ + len += sizeof(vce_encode) / 4; + + enc->ib_len = len; + r = submit(len, AMDGPU_HW_IP_VCE); + CU_ASSERT_EQUAL(r, 0); +} + +static void check_mv_result(struct amdgpu_vce_encode *enc) +{ + uint64_t sum; + uint32_t s = 140790; + uint32_t *ptr, size; + int i, j, r; + + r = amdgpu_bo_cpu_map(enc->fb[0].handle, (void **)&enc->fb[0].ptr); + CU_ASSERT_EQUAL(r, 0); + ptr = (uint32_t *)enc->fb[0].ptr; + r = amdgpu_bo_cpu_unmap(enc->fb[0].handle); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_cpu_map(enc->mvb.handle, (void **)&enc->mvb.ptr); + CU_ASSERT_EQUAL(r, 0); + for (j = 0, sum = 0; j < enc->mvbuf_size; ++j) + sum += enc->mvb.ptr[j]; + CU_ASSERT_EQUAL(sum, s); + r = amdgpu_bo_cpu_unmap(enc->mvb.handle); + CU_ASSERT_EQUAL(r, 0); +} + +static void amdgpu_cs_vce_encode_mv(void) +{ + uint32_t vbuf_size, bs_size = 0x154000, cpb_size; + unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16; + int i, r; + + vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5; + enc.mvbuf_size = ALIGN(enc.width, 16) * ALIGN(enc.height, 16) / 8; + cpb_size = vbuf_size * 10; + num_resources = 0; + alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT); + resources[num_resources++] = enc.fb[0].handle; + alloc_resource(&enc.bs[0], bs_size, AMDGPU_GEM_DOMAIN_GTT); + resources[num_resources++] = enc.bs[0].handle; + alloc_resource(&enc.mvb, enc.mvbuf_size, AMDGPU_GEM_DOMAIN_GTT); + resources[num_resources++] = enc.mvb.handle; + alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM); + resources[num_resources++] = enc.vbuf.handle; + alloc_resource(&enc.mvrefbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM); + resources[num_resources++] = enc.mvrefbuf.handle; + alloc_resource(&enc.cpb, cpb_size, AMDGPU_GEM_DOMAIN_VRAM); + resources[num_resources++] = enc.cpb.handle; + resources[num_resources++] = ib_handle; + + r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr); + CU_ASSERT_EQUAL(r, 0); + + memset(enc.vbuf.ptr, 0, vbuf_size); + for (i = 0; i < enc.height; ++i) { + memcpy(enc.vbuf.ptr, (frame + i * enc.width), enc.width); + enc.vbuf.ptr += ALIGN(enc.width, align); + } + for (i = 0; i < enc.height / 2; ++i) { + memcpy(enc.vbuf.ptr, ((frame + enc.height * enc.width) + i * enc.width), enc.width); + enc.vbuf.ptr += ALIGN(enc.width, align); + } + + r = amdgpu_bo_cpu_unmap(enc.vbuf.handle); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_cpu_map(enc.mvrefbuf.handle, (void **)&enc.mvrefbuf.ptr); + CU_ASSERT_EQUAL(r, 0); + + memset(enc.mvrefbuf.ptr, 0, vbuf_size); + for (i = 0; i < enc.height; ++i) { + memcpy(enc.mvrefbuf.ptr, (frame + (enc.height - i -1) * enc.width), enc.width); + enc.mvrefbuf.ptr += ALIGN(enc.width, align); + } + for (i = 0; i < enc.height / 2; ++i) { + memcpy(enc.mvrefbuf.ptr, + ((frame + enc.height * enc.width) + (enc.height / 2 - i -1) * enc.width), enc.width); + enc.mvrefbuf.ptr += ALIGN(enc.width, align); + } + + r = amdgpu_bo_cpu_unmap(enc.mvrefbuf.handle); + CU_ASSERT_EQUAL(r, 0); + + amdgpu_cs_vce_config(); + + vce_taskinfo[3] = 3; + amdgpu_cs_vce_mv(&enc); + check_mv_result(&enc); + + free_resource(&enc.fb[0]); + free_resource(&enc.bs[0]); + free_resource(&enc.vbuf); + free_resource(&enc.cpb); + free_resource(&enc.mvrefbuf); + free_resource(&enc.mvb); +} + static void amdgpu_cs_vce_destroy(void) { int len, r; diff --git a/lib/libdrm/tests/amdgpu/vcn_tests.c b/lib/libdrm/tests/amdgpu/vcn_tests.c index 9224bc371..d9f05af81 100644 --- a/lib/libdrm/tests/amdgpu/vcn_tests.c +++ b/lib/libdrm/tests/amdgpu/vcn_tests.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include <inttypes.h> @@ -283,7 +279,7 @@ static void amdgpu_cs_vcn_dec_create(void) static void amdgpu_cs_vcn_dec_decode(void) { - const unsigned dpb_size = 15923584, ctx_size = 5287680, dt_size = 737280; + const unsigned dpb_size = 15923584, dt_size = 737280; uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr, sum; struct amdgpu_vcn_bo dec_buf; int size, len, i, r; diff --git a/lib/libdrm/tests/amdgpu/vm_tests.c b/lib/libdrm/tests/amdgpu/vm_tests.c index 5f1831076..7b6dc5d6a 100644 --- a/lib/libdrm/tests/amdgpu/vm_tests.c +++ b/lib/libdrm/tests/amdgpu/vm_tests.c @@ -25,6 +25,7 @@ #include "amdgpu_test.h" #include "amdgpu_drm.h" +#include "amdgpu_internal.h" static amdgpu_device_handle device_handle; static uint32_t major_version; @@ -33,9 +34,27 @@ static uint32_t minor_version; static void amdgpu_vmid_reserve_test(void); +CU_BOOL suite_vm_tests_enable(void) +{ + CU_BOOL enable = CU_TRUE; + + if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, + &minor_version, &device_handle)) + return CU_FALSE; + + if (device_handle->info.family_id == AMDGPU_FAMILY_SI) { + printf("\n\nCurrently hangs the CP on this ASIC, VM suite disabled\n"); + enable = CU_FALSE; + } + + if (amdgpu_device_deinitialize(device_handle)) + return CU_FALSE; + + return enable; +} + int suite_vm_tests_init(void) { - struct amdgpu_gpu_info gpu_info = {0}; int r; r = amdgpu_device_initialize(drm_amdgpu[0], &major_version, @@ -78,10 +97,9 @@ static void amdgpu_vmid_reserve_test(void) struct amdgpu_cs_ib_info ib_info; struct amdgpu_cs_fence fence_status; uint32_t expired, flags; - int i, r, instance; + int i, r; amdgpu_bo_list_handle bo_list; amdgpu_va_handle va_handle; - union drm_amdgpu_vm vm; static uint32_t *ptr; r = amdgpu_cs_ctx_create(device_handle, &context_handle); diff --git a/lib/libdrm/tests/drmdevice.c b/lib/libdrm/tests/drmdevice.c index 9dd5098a2..cdf6e8dea 100644 --- a/lib/libdrm/tests/drmdevice.c +++ b/lib/libdrm/tests/drmdevice.c @@ -36,67 +36,66 @@ static void print_device_info(drmDevicePtr device, int i, bool print_revision) { printf("device[%i]\n", i); - printf("\tavailable_nodes %04x\n", device->available_nodes); - printf("\tnodes\n"); + printf("+-> available_nodes %#04x\n", device->available_nodes); + printf("+-> nodes\n"); for (int j = 0; j < DRM_NODE_MAX; j++) if (device->available_nodes & 1 << j) - printf("\t\tnodes[%d] %s\n", j, device->nodes[j]); + printf("| +-> nodes[%d] %s\n", j, device->nodes[j]); - printf("\tbustype %04x\n", device->bustype); - printf("\tbusinfo\n"); + printf("+-> bustype %04x\n", device->bustype); if (device->bustype == DRM_BUS_PCI) { - printf("\t\tpci\n"); - printf("\t\t\tdomain\t%04x\n",device->businfo.pci->domain); - printf("\t\t\tbus\t%02x\n", device->businfo.pci->bus); - printf("\t\t\tdev\t%02x\n", device->businfo.pci->dev); - printf("\t\t\tfunc\t%1u\n", device->businfo.pci->func); - - printf("\tdeviceinfo\n"); - printf("\t\tpci\n"); - printf("\t\t\tvendor_id\t%04x\n", device->deviceinfo.pci->vendor_id); - printf("\t\t\tdevice_id\t%04x\n", device->deviceinfo.pci->device_id); - printf("\t\t\tsubvendor_id\t%04x\n", device->deviceinfo.pci->subvendor_id); - printf("\t\t\tsubdevice_id\t%04x\n", device->deviceinfo.pci->subdevice_id); + printf("| +-> pci\n"); + printf("| +-> domain %04x\n",device->businfo.pci->domain); + printf("| +-> bus %02x\n", device->businfo.pci->bus); + printf("| +-> dev %02x\n", device->businfo.pci->dev); + printf("| +-> func %1u\n", device->businfo.pci->func); + + printf("+-> deviceinfo\n"); + printf(" +-> pci\n"); + printf(" +-> vendor_id %04x\n", device->deviceinfo.pci->vendor_id); + printf(" +-> device_id %04x\n", device->deviceinfo.pci->device_id); + printf(" +-> subvendor_id %04x\n", device->deviceinfo.pci->subvendor_id); + printf(" +-> subdevice_id %04x\n", device->deviceinfo.pci->subdevice_id); if (print_revision) - printf("\t\t\trevision_id\t%02x\n", device->deviceinfo.pci->revision_id); + printf(" +-> revision_id %02x\n", device->deviceinfo.pci->revision_id); else - printf("\t\t\trevision_id\tIGNORED\n"); + printf(" +-> revision_id IGNORED\n"); } else if (device->bustype == DRM_BUS_USB) { - printf("\t\tusb\n"); - printf("\t\t\tbus\t%03u\n", device->businfo.usb->bus); - printf("\t\t\tdev\t%03u\n", device->businfo.usb->dev); - - printf("\tdeviceinfo\n"); - printf("\t\tusb\n"); - printf("\t\t\tvendor\t%04x\n", device->deviceinfo.usb->vendor); - printf("\t\t\tproduct\t%04x\n", device->deviceinfo.usb->product); + printf("| +-> usb\n"); + printf("| +-> bus %03u\n", device->businfo.usb->bus); + printf("| +-> dev %03u\n", device->businfo.usb->dev); + + printf("+-> deviceinfo\n"); + printf(" +-> usb\n"); + printf(" +-> vendor %04x\n", device->deviceinfo.usb->vendor); + printf(" +-> product %04x\n", device->deviceinfo.usb->product); } else if (device->bustype == DRM_BUS_PLATFORM) { char **compatible = device->deviceinfo.platform->compatible; - printf("\t\tplatform\n"); - printf("\t\t\tfullname\t%s\n", device->businfo.platform->fullname); + printf("| +-> platform\n"); + printf("| +-> fullname\t%s\n", device->businfo.platform->fullname); - printf("\tdeviceinfo\n"); - printf("\t\tplatform\n"); - printf("\t\t\tcompatible\n"); + printf("+-> deviceinfo\n"); + printf(" +-> platform\n"); + printf(" +-> compatible\n"); while (*compatible) { - printf("\t\t\t\t%s\n", *compatible); + printf(" %s\n", *compatible); compatible++; } } else if (device->bustype == DRM_BUS_HOST1X) { - char **compatible = device->deviceinfo.platform->compatible; + char **compatible = device->deviceinfo.host1x->compatible; - printf("\t\thost1x\n"); - printf("\t\t\tfullname\t%s\n", device->businfo.host1x->fullname); + printf("| +-> host1x\n"); + printf("| +-> fullname\t%s\n", device->businfo.host1x->fullname); - printf("\tdeviceinfo\n"); - printf("\t\tplatform\n"); - printf("\t\t\tcompatible\n"); + printf("+-> deviceinfo\n"); + printf(" +-> host1x\n"); + printf(" +-> compatible\n"); while (*compatible) { - printf("\t\t\t\t%s\n", *compatible); + printf(" %s\n", *compatible); compatible++; } } else { @@ -112,12 +111,15 @@ main(void) drmDevicePtr device; int fd, ret, max_devices; + printf("--- Checking the number of DRM device available ---\n"); max_devices = drmGetDevices2(0, NULL, 0); if (max_devices <= 0) { printf("drmGetDevices2() has returned %d\n", max_devices); return -1; } + printf("--- Devices reported %d ---\n", max_devices); + devices = calloc(max_devices, sizeof(drmDevicePtr)); if (devices == NULL) { @@ -125,6 +127,7 @@ main(void) return -1; } + printf("--- Retrieving devices information (PCI device revision is ignored) ---\n"); ret = drmGetDevices2(0, devices, max_devices); if (ret < 0) { printf("drmGetDevices2() returned an error %d\n", ret); @@ -137,13 +140,14 @@ main(void) for (int j = 0; j < DRM_NODE_MAX; j++) { if (devices[i]->available_nodes & 1 << j) { - printf("Opening device %d node %s\n", i, devices[i]->nodes[j]); + printf("--- Opening device node %s ---\n", devices[i]->nodes[j]); fd = open(devices[i]->nodes[j], O_RDONLY | O_CLOEXEC, 0); if (fd < 0) { printf("Failed - %s (%d)\n", strerror(errno), errno); continue; } + printf("--- Retrieving device info, for node %s ---\n", devices[i]->nodes[j]); if (drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, &device) == 0) { print_device_info(device, i, true); drmFreeDevice(&device); diff --git a/lib/libdrm/tests/etnaviv/etnaviv_2d_test.c b/lib/libdrm/tests/etnaviv/etnaviv_2d_test.c index 10751c730..8dd77b666 100644 --- a/lib/libdrm/tests/etnaviv/etnaviv_2d_test.c +++ b/lib/libdrm/tests/etnaviv/etnaviv_2d_test.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <fcntl.h> #include <stdio.h> #include <string.h> diff --git a/lib/libdrm/tests/etnaviv/etnaviv_bo_cache_test.c b/lib/libdrm/tests/etnaviv/etnaviv_bo_cache_test.c index fb01f8d37..7fb062930 100644 --- a/lib/libdrm/tests/etnaviv/etnaviv_bo_cache_test.c +++ b/lib/libdrm/tests/etnaviv/etnaviv_bo_cache_test.c @@ -24,10 +24,6 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #undef NDEBUG #include <assert.h> diff --git a/lib/libdrm/tests/etnaviv/meson.build b/lib/libdrm/tests/etnaviv/meson.build new file mode 100644 index 000000000..8b4a3cfb9 --- /dev/null +++ b/lib/libdrm/tests/etnaviv/meson.build @@ -0,0 +1,45 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_etnaviv_tests = [inc_root, inc_drm, include_directories('../../etnaviv')] + +etnaviv_2d_test = executable( + 'etnaviv_2d_test', + files('etnaviv_2d_test.c', 'write_bmp.c'), + include_directories : inc_etnaviv_tests, + link_with : [libdrm, libdrm_etnaviv], + install : with_install_tests, +) + +etnaviv_cmd_stream_test = executable( + 'etnaviv_cmd_stream_test', + files('etnaviv_cmd_stream_test.c'), + include_directories : inc_etnaviv_tests, + link_with : [libdrm, libdrm_etnaviv], + install : with_install_tests, +) + +etnaviv_bo_cache_test = executable( + 'etnaviv_bo_cache_test', + files('etnaviv_bo_cache_test.c'), + include_directories : inc_etnaviv_tests, + link_with : [libdrm, libdrm_etnaviv], + install : with_install_tests, +) diff --git a/lib/libdrm/tests/etnaviv/write_bmp.c b/lib/libdrm/tests/etnaviv/write_bmp.c index 7ae0646c9..f7b6bc69e 100644 --- a/lib/libdrm/tests/etnaviv/write_bmp.c +++ b/lib/libdrm/tests/etnaviv/write_bmp.c @@ -63,7 +63,7 @@ struct dib_header { unsigned int unused[12]; } __attribute__((__packed__)); -static int +static void bmp_header_write(int fd, int width, int height, int bgra, int noflip, int alpha) { struct bmp_header bmp_header = { @@ -98,8 +98,6 @@ bmp_header_write(int fd, int width, int height, int bgra, int noflip, int alpha) write(fd, &bmp_header, sizeof(struct bmp_header)); write(fd, &dib_header, sizeof(struct dib_header)); - - return 0; } void diff --git a/lib/libdrm/tests/exynos/exynos_fimg2d_perf.c b/lib/libdrm/tests/exynos/exynos_fimg2d_perf.c index a2d5c1929..97691a71a 100644 --- a/lib/libdrm/tests/exynos/exynos_fimg2d_perf.c +++ b/lib/libdrm/tests/exynos/exynos_fimg2d_perf.c @@ -274,13 +274,6 @@ int main(int argc, char **argv) goto out; } - if (bufw == 0 || bufh == 0) { - fprintf(stderr, "error: buffer width/height should be non-zero.\n"); - ret = -1; - - goto out; - } - fd = drmOpen("exynos", NULL); if (fd < 0) { fprintf(stderr, "error: failed to open drm\n"); diff --git a/lib/libdrm/tests/exynos/exynos_fimg2d_test.c b/lib/libdrm/tests/exynos/exynos_fimg2d_test.c index b71cf5935..99bb9233a 100644 --- a/lib/libdrm/tests/exynos/exynos_fimg2d_test.c +++ b/lib/libdrm/tests/exynos/exynos_fimg2d_test.c @@ -23,10 +23,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -533,10 +529,10 @@ err_free_userptr: fail: g2d_fini(ctx); - return ret;; + return ret; } -#if EXYNOS_G2D_USERPTR_TEST +#ifdef EXYNOS_G2D_USERPTR_TEST static int g2d_blend_test(struct exynos_device *dev, struct exynos_bo *src, struct exynos_bo *dst, @@ -880,7 +876,7 @@ int main(int argc, char **argv) * * Disable the test for now, until the kernel code has been sanitized. */ -#if EXYNOS_G2D_USERPTR_TEST +#ifdef EXYNOS_G2D_USERPTR_TEST ret = g2d_blend_test(dev, src, bo, G2D_IMGBUF_USERPTR); if (ret < 0) fprintf(stderr, "failed to test blend operation.\n"); diff --git a/lib/libdrm/tests/exynos/meson.build b/lib/libdrm/tests/exynos/meson.build new file mode 100644 index 000000000..940c3ce44 --- /dev/null +++ b/lib/libdrm/tests/exynos/meson.build @@ -0,0 +1,54 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_exynos = include_directories('../../exynos') + +if with_libkms + exynos_fimg2d_test = executable( + 'exynos_fimg2d_test', + files('exynos_fimg2d_test.c'), + c_args : warn_c_args, + include_directories : [inc_root, inc_drm, inc_exynos, + include_directories('../../libkms')], + link_with : [libdrm, libkms, libdrm_exynos], + dependencies : dep_threads, + install : with_install_tests, + ) +endif + +exynos_fimg2d_perf = executable( + 'exynos_fimg2d_perf', + files('exynos_fimg2d_perf.c'), + c_args : warn_c_args, + include_directories : [inc_root, inc_drm, inc_exynos], + link_with : [libdrm, libdrm_exynos], + dependencies : dep_threads, + install : with_install_tests, +) + +exynos_fimg2d_event = executable( + 'exynos_fimg2d_event', + files('exynos_fimg2d_event.c'), + c_args : warn_c_args, + include_directories : [inc_root, inc_drm, inc_exynos], + link_with : [libdrm, libdrm_exynos], + dependencies : dep_threads, + install : with_install_tests, +) diff --git a/lib/libdrm/tests/kms/kms-steal-crtc.c b/lib/libdrm/tests/kms/kms-steal-crtc.c index 4b830d27a..cd40758db 100644 --- a/lib/libdrm/tests/kms/kms-steal-crtc.c +++ b/lib/libdrm/tests/kms/kms-steal-crtc.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <fcntl.h> #include <signal.h> diff --git a/lib/libdrm/tests/kms/kms-universal-planes.c b/lib/libdrm/tests/kms/kms-universal-planes.c index 89057bb50..2163c987c 100644 --- a/lib/libdrm/tests/kms/kms-universal-planes.c +++ b/lib/libdrm/tests/kms/kms-universal-planes.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <fcntl.h> #include <getopt.h> #include <stdbool.h> diff --git a/lib/libdrm/tests/kms/libkms-test-crtc.c b/lib/libdrm/tests/kms/libkms-test-crtc.c index 3adb49039..2c28face0 100644 --- a/lib/libdrm/tests/kms/libkms-test-crtc.c +++ b/lib/libdrm/tests/kms/libkms-test-crtc.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "libkms-test.h" struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id) diff --git a/lib/libdrm/tests/kms/libkms-test-device.c b/lib/libdrm/tests/kms/libkms-test-device.c index 53c7349b8..d3bb11ce1 100644 --- a/lib/libdrm/tests/kms/libkms-test-device.c +++ b/lib/libdrm/tests/kms/libkms-test-device.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdio.h> #include <string.h> #include <unistd.h> @@ -67,7 +63,7 @@ static void kms_device_probe_screens(struct kms_device *device) device->screens = calloc(res->count_connectors, sizeof(screen)); if (!device->screens) - return; + goto err_free_resources; for (i = 0; i < res->count_connectors; i++) { unsigned int *count; @@ -97,6 +93,7 @@ static void kms_device_probe_screens(struct kms_device *device) device->num_screens++; } +err_free_resources: drmModeFreeResources(res); } @@ -112,7 +109,7 @@ static void kms_device_probe_crtcs(struct kms_device *device) device->crtcs = calloc(res->count_crtcs, sizeof(crtc)); if (!device->crtcs) - return; + goto err_free_resources; for (i = 0; i < res->count_crtcs; i++) { crtc = kms_crtc_create(device, res->crtcs[i]); @@ -123,6 +120,7 @@ static void kms_device_probe_crtcs(struct kms_device *device) device->num_crtcs++; } +err_free_resources: drmModeFreeResources(res); } @@ -138,7 +136,7 @@ static void kms_device_probe_planes(struct kms_device *device) device->planes = calloc(res->count_planes, sizeof(plane)); if (!device->planes) - return; + goto err_free_resources; for (i = 0; i < res->count_planes; i++) { plane = kms_plane_create(device, res->planes[i]); @@ -149,6 +147,7 @@ static void kms_device_probe_planes(struct kms_device *device) device->num_planes++; } +err_free_resources: drmModeFreePlaneResources(res); } diff --git a/lib/libdrm/tests/kms/libkms-test-framebuffer.c b/lib/libdrm/tests/kms/libkms-test-framebuffer.c index c9e5ad3c2..9bb2d95b6 100644 --- a/lib/libdrm/tests/kms/libkms-test-framebuffer.c +++ b/lib/libdrm/tests/kms/libkms-test-framebuffer.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <string.h> diff --git a/lib/libdrm/tests/kms/libkms-test-plane.c b/lib/libdrm/tests/kms/libkms-test-plane.c index 8eb78af1d..6c40a3c9e 100644 --- a/lib/libdrm/tests/kms/libkms-test-plane.c +++ b/lib/libdrm/tests/kms/libkms-test-plane.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <string.h> diff --git a/lib/libdrm/tests/kms/libkms-test-screen.c b/lib/libdrm/tests/kms/libkms-test-screen.c index 336902228..bbe972a0b 100644 --- a/lib/libdrm/tests/kms/libkms-test-screen.c +++ b/lib/libdrm/tests/kms/libkms-test-screen.c @@ -21,10 +21,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <string.h> diff --git a/lib/libdrm/tests/kms/meson.build b/lib/libdrm/tests/kms/meson.build new file mode 100644 index 000000000..1f7f724d1 --- /dev/null +++ b/lib/libdrm/tests/kms/meson.build @@ -0,0 +1,49 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +libkms_test = static_library( + 'kms-test', + files( + 'libkms-test-crtc.c', 'libkms-test-device.c', 'libkms-test-framebuffer.c', + 'libkms-test-plane.c', 'libkms-test-screen.c', + ), + include_directories : [inc_root, inc_tests, inc_drm], + link_with : libdrm, + c_args : warn_c_args, +) + +kms_steal_crtc = executable( + 'kms-steal-crtc', + files('kms-steal-crtc.c'), + dependencies : dep_cairo, + include_directories : [inc_root, inc_tests, inc_drm], + link_with : [libkms_test, libutil], + install : with_install_tests, +) + +kms_universal_planes = executable( + 'kms-universal-planes', + files('kms-universal-planes.c'), + dependencies : dep_cairo, + include_directories : [inc_root, inc_tests, inc_drm], + link_with : [libkms_test], + install : with_install_tests, +) diff --git a/lib/libdrm/tests/kmstest/meson.build b/lib/libdrm/tests/kmstest/meson.build new file mode 100644 index 000000000..a47d49519 --- /dev/null +++ b/lib/libdrm/tests/kmstest/meson.build @@ -0,0 +1,30 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +kmstest = executable( + 'kmstest', + files('main.c'), + c_args : warn_c_args, + include_directories : [ + inc_root, inc_tests, include_directories('../../libkms'), inc_drm, + ], + link_with : [libutil, libkms, libdrm], + install : with_install_tests, +) diff --git a/lib/libdrm/tests/meson.build b/lib/libdrm/tests/meson.build new file mode 100644 index 000000000..fdf950b78 --- /dev/null +++ b/lib/libdrm/tests/meson.build @@ -0,0 +1,86 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +inc_tests = include_directories('.') + +subdir('util') +subdir('kms') +subdir('modeprint') +subdir('proptest') +subdir('modetest') +subdir('vbltest') +if with_libkms + subdir('kmstest') +endif +if with_radeon + subdir('radeon') +endif +if with_amdgpu + subdir('amdgpu') +endif +if with_exynos + subdir('exynos') +endif +if with_tegra + subdir('tegra') +endif +if with_etnaviv + subdir('etnaviv') +endif +if with_nouveau + subdir('nouveau') +endif + +drmsl = executable( + 'drmsl', + files('drmsl.c'), + include_directories : [inc_root, inc_drm], + link_with : libdrm, + c_args : warn_c_args, +) + +hash = executable( + 'hash', + files('hash.c'), + include_directories : [inc_root, inc_drm], + link_with : libdrm, + c_args : warn_c_args, +) + +random = executable( + 'random', + files('random.c'), + include_directories : [inc_root, inc_drm], + link_with : libdrm, + c_args : warn_c_args, +) + +drmdevice = executable( + 'drmdevice', + files('drmdevice.c'), + include_directories : [inc_root, inc_drm], + link_with : libdrm, + c_args : warn_c_args, +) + +test('random', random, timeout : 240) +test('hash', hash) +test('drmsl', drmsl) +test('drmdevice', drmdevice) diff --git a/lib/libdrm/tests/modeprint/meson.build b/lib/libdrm/tests/modeprint/meson.build new file mode 100644 index 000000000..5f0eb24b7 --- /dev/null +++ b/lib/libdrm/tests/modeprint/meson.build @@ -0,0 +1,29 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +modeprint = executable( + 'modeprint', + files('modeprint.c'), + c_args : warn_c_args, + include_directories : [inc_root, inc_tests, inc_drm], + link_with : libdrm, + dependencies : dep_threads, + install : with_install_tests, +) diff --git a/lib/libdrm/tests/modeprint/modeprint.c b/lib/libdrm/tests/modeprint/modeprint.c index 0d854103c..c81dd91db 100644 --- a/lib/libdrm/tests/modeprint/modeprint.c +++ b/lib/libdrm/tests/modeprint/modeprint.c @@ -244,7 +244,7 @@ static int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb) printf("\thandle : %i\n", fb->handle); printf("\twidth : %i\n", fb->width); printf("\theight : %i\n", fb->height); - printf("\tpitch : %i\n", fb->pitch);; + printf("\tpitch : %i\n", fb->pitch); printf("\tbpp : %i\n", fb->bpp); printf("\tdepth : %i\n", fb->depth); printf("\tbuffer_id : %i\n", fb->handle); diff --git a/lib/libdrm/tests/modetest/buffers.c b/lib/libdrm/tests/modetest/buffers.c index 4fd310b9b..9b635c0ce 100644 --- a/lib/libdrm/tests/modetest/buffers.c +++ b/lib/libdrm/tests/modetest/buffers.c @@ -24,10 +24,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <assert.h> #include <errno.h> #include <stdio.h> diff --git a/lib/libdrm/tests/modetest/cursor.c b/lib/libdrm/tests/modetest/cursor.c index 6de82a4a7..829bced18 100644 --- a/lib/libdrm/tests/modetest/cursor.c +++ b/lib/libdrm/tests/modetest/cursor.c @@ -22,10 +22,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <assert.h> #include <errno.h> #include <stdio.h> diff --git a/lib/libdrm/tests/modetest/meson.build b/lib/libdrm/tests/modetest/meson.build new file mode 100644 index 000000000..2a081845c --- /dev/null +++ b/lib/libdrm/tests/modetest/meson.build @@ -0,0 +1,29 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +modetest = executable( + 'modetest', + files('buffers.c', 'cursor.c', 'modetest.c'), + c_args : [warn_c_args, '-Wno-pointer-arith'], + include_directories : [inc_root, inc_tests, inc_drm], + dependencies : [dep_threads, dep_cairo], + link_with : [libdrm, libutil], + install : with_install_tests, +) diff --git a/lib/libdrm/tests/modetest/modetest.c b/lib/libdrm/tests/modetest/modetest.c index 62d933272..975dcbcdd 100644 --- a/lib/libdrm/tests/modetest/modetest.c +++ b/lib/libdrm/tests/modetest/modetest.c @@ -38,10 +38,6 @@ * the mode has been programmed, along with possible test patterns. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <assert.h> #include <ctype.h> #include <stdbool.h> @@ -123,6 +119,9 @@ struct device { struct bo *bo; struct bo *cursor_bo; } mode; + + int use_atomic; + drmModeAtomicReq *req; }; static inline int64_t U642I64(uint64_t val) @@ -278,20 +277,20 @@ static const char *modifier_to_string(uint64_t modifier) return "VIVANTE_SPLIT_TILED"; case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED: return "VIVANTE_SPLIT_SUPER_TILED"; - case NV_FORMAT_MOD_TEGRA_TILED: - return "MOD_TEGRA_TILED"; - case NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(0): - return "MOD_TEGRA_16BX2_BLOCK(0)"; - case NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(1): - return "MOD_TEGRA_16BX2_BLOCK(1)"; - case NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(2): - return "MOD_TEGRA_16BX2_BLOCK(2)"; - case NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(3): - return "MOD_TEGRA_16BX2_BLOCK(3)"; - case NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(4): - return "MOD_TEGRA_16BX2_BLOCK(4)"; - case NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(5): - return "MOD_TEGRA_16BX2_BLOCK(5)"; + case DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED: + return "NVIDIA_TEGRA_TILED"; + case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0): + return "NVIDIA_16BX2_BLOCK(0)"; + case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1): + return "NVIDIA_16BX2_BLOCK(1)"; + case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2): + return "NVIDIA_16BX2_BLOCK(2)"; + case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3): + return "NVIDIA_16BX2_BLOCK(3)"; + case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4): + return "NVIDIA_16BX2_BLOCK(4)"; + case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5): + return "NVIDIA_16BX2_BLOCK(5)"; case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: return "MOD_BROADCOM_VC4_T_TILED"; default: @@ -656,10 +655,13 @@ static struct resources *get_resources(struct device *dev) for (i = 0; i < res->res->count_connectors; i++) { struct connector *connector = &res->connectors[i]; drmModeConnector *conn = connector->connector; + int num; - asprintf(&connector->name, "%s-%u", + num = asprintf(&connector->name, "%s-%u", util_lookup_connector_type_name(conn->connector_type), conn->connector_type_id); + if (num < 0) + goto error; } #define get_properties(_res, __res, type, Type) \ @@ -806,7 +808,9 @@ struct plane_arg { uint32_t w, h; double scale; unsigned int fb_id; + unsigned int old_fb_id; struct bo *bo; + struct bo *old_bo; char format_str[5]; /* need to leave room for terminating \0 */ unsigned int fourcc; }; @@ -1000,8 +1004,12 @@ static void set_property(struct device *dev, struct property_arg *p) p->prop_id = props->props[i]; - ret = drmModeObjectSetProperty(dev->fd, p->obj_id, p->obj_type, - p->prop_id, p->value); + if (!dev->use_atomic) + ret = drmModeObjectSetProperty(dev->fd, p->obj_id, p->obj_type, + p->prop_id, p->value); + else + ret = drmModeAtomicAddProperty(dev->req, p->obj_id, p->prop_id, p->value); + if (ret < 0) fprintf(stderr, "failed to set %s %i property %s to %" PRIu64 ": %s\n", obj_type, p->obj_id, p->name, p->value, strerror(errno)); @@ -1050,6 +1058,94 @@ static bool format_support(const drmModePlanePtr ovr, uint32_t fmt) return false; } +static void add_property(struct device *dev, uint32_t obj_id, + const char *name, uint64_t value) +{ + struct property_arg p; + + p.obj_id = obj_id; + strcpy(p.name, name); + p.value = value; + + set_property(dev, &p); +} + +static int atomic_set_plane(struct device *dev, struct plane_arg *p, + int pattern, bool update) +{ + uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; + struct bo *plane_bo; + int crtc_x, crtc_y, crtc_w, crtc_h; + struct crtc *crtc = NULL; + unsigned int i; + unsigned int old_fb_id; + + /* Find an unused plane which can be connected to our CRTC. Find the + * CRTC index first, then iterate over available planes. + */ + for (i = 0; i < (unsigned int)dev->resources->res->count_crtcs; i++) { + if (p->crtc_id == dev->resources->res->crtcs[i]) { + crtc = &dev->resources->crtcs[i]; + break; + } + } + + if (!crtc) { + fprintf(stderr, "CRTC %u not found\n", p->crtc_id); + return -1; + } + + if (!update) + fprintf(stderr, "testing %dx%d@%s on plane %u, crtc %u\n", + p->w, p->h, p->format_str, p->plane_id, p->crtc_id); + + plane_bo = p->old_bo; + p->old_bo = p->bo; + + if (!plane_bo) { + plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, + handles, pitches, offsets, pattern); + + if (plane_bo == NULL) + return -1; + + if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc, + handles, pitches, offsets, &p->fb_id, 0)) { + fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); + return -1; + } + } + + p->bo = plane_bo; + + old_fb_id = p->fb_id; + p->old_fb_id = old_fb_id; + + crtc_w = p->w * p->scale; + crtc_h = p->h * p->scale; + if (!p->has_position) { + /* Default to the middle of the screen */ + crtc_x = (crtc->mode->hdisplay - crtc_w) / 2; + crtc_y = (crtc->mode->vdisplay - crtc_h) / 2; + } else { + crtc_x = p->x; + crtc_y = p->y; + } + + add_property(dev, p->plane_id, "FB_ID", p->fb_id); + add_property(dev, p->plane_id, "CRTC_ID", p->crtc_id); + add_property(dev, p->plane_id, "SRC_X", 0); + add_property(dev, p->plane_id, "SRC_Y", 0); + add_property(dev, p->plane_id, "SRC_W", p->w << 16); + add_property(dev, p->plane_id, "SRC_H", p->h << 16); + add_property(dev, p->plane_id, "CRTC_X", crtc_x); + add_property(dev, p->plane_id, "CRTC_Y", crtc_y); + add_property(dev, p->plane_id, "CRTC_W", crtc_w); + add_property(dev, p->plane_id, "CRTC_H", crtc_h); + + return 0; +} + static int set_plane(struct device *dev, struct plane_arg *p) { drmModePlane *ovr; @@ -1146,6 +1242,64 @@ static int set_plane(struct device *dev, struct plane_arg *p) return 0; } +static void atomic_set_planes(struct device *dev, struct plane_arg *p, + unsigned int count, bool update) +{ + unsigned int i, pattern = UTIL_PATTERN_SMPTE; + + /* set up planes */ + for (i = 0; i < count; i++) { + if (i > 0) + pattern = UTIL_PATTERN_TILES; + + if (atomic_set_plane(dev, &p[i], pattern, update)) + return; + } +} + +static void atomic_clear_planes(struct device *dev, struct plane_arg *p, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) { + add_property(dev, p[i].plane_id, "FB_ID", 0); + add_property(dev, p[i].plane_id, "CRTC_ID", 0); + add_property(dev, p[i].plane_id, "SRC_X", 0); + add_property(dev, p[i].plane_id, "SRC_Y", 0); + add_property(dev, p[i].plane_id, "SRC_W", 0); + add_property(dev, p[i].plane_id, "SRC_H", 0); + add_property(dev, p[i].plane_id, "CRTC_X", 0); + add_property(dev, p[i].plane_id, "CRTC_Y", 0); + add_property(dev, p[i].plane_id, "CRTC_W", 0); + add_property(dev, p[i].plane_id, "CRTC_H", 0); + } +} + +static void atomic_clear_FB(struct device *dev, struct plane_arg *p, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) { + if (p[i].fb_id) { + drmModeRmFB(dev->fd, p[i].fb_id); + p[i].fb_id = 0; + } + if (p[i].old_fb_id) { + drmModeRmFB(dev->fd, p[i].old_fb_id); + p[i].old_fb_id = 0; + } + if (p[i].bo) { + bo_destroy(p[i].bo); + p[i].bo = NULL; + } + if (p[i].old_bo) { + bo_destroy(p[i].old_bo); + p[i].old_bo = NULL; + } + + } +} + static void clear_planes(struct device *dev, struct plane_arg *p, unsigned int count) { unsigned int i; @@ -1158,6 +1312,59 @@ static void clear_planes(struct device *dev, struct plane_arg *p, unsigned int c } } +static void atomic_set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) +{ + unsigned int i; + unsigned int j; + int ret; + + for (i = 0; i < count; i++) { + struct pipe_arg *pipe = &pipes[i]; + + ret = pipe_find_crtc_and_mode(dev, pipe); + if (ret < 0) + continue; + } + + for (i = 0; i < count; i++) { + struct pipe_arg *pipe = &pipes[i]; + uint32_t blob_id; + + if (pipe->mode == NULL) + continue; + + printf("setting mode %s-%dHz@%s on connectors ", + pipe->mode_str, pipe->mode->vrefresh, pipe->format_str); + for (j = 0; j < pipe->num_cons; ++j) { + printf("%s, ", pipe->cons[j]); + add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc->crtc->crtc_id); + } + printf("crtc %d\n", pipe->crtc->crtc->crtc_id); + + drmModeCreatePropertyBlob(dev->fd, pipe->mode, sizeof(*pipe->mode), &blob_id); + add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", blob_id); + add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 1); + } +} + +static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) +{ + unsigned int i; + unsigned int j; + + for (i = 0; i < count; i++) { + struct pipe_arg *pipe = &pipes[i]; + + if (pipe->mode == NULL) + continue; + + for (j = 0; j < pipe->num_cons; ++j) + add_property(dev, pipe->con_ids[j], "CRTC_ID",0); + + add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", 0); + add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 0); + } +} static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) { @@ -1533,7 +1740,7 @@ static int parse_property(struct property_arg *p, const char *arg) static void usage(char *name) { - fprintf(stderr, "usage: %s [-cDdefMPpsCvw]\n", name); + fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name); fprintf(stderr, "\n Query options:\n\n"); fprintf(stderr, "\t-c\tlist connectors\n"); @@ -1547,6 +1754,7 @@ static void usage(char *name) fprintf(stderr, "\t-C\ttest hw cursor\n"); fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n"); + fprintf(stderr, "\t-a \tuse atomic API\n"); fprintf(stderr, "\n Generic options:\n\n"); fprintf(stderr, "\t-d\tdrop master after mode set\n"); @@ -1610,7 +1818,7 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe) return 0; } -static char optstr[] = "cdD:efM:P:ps:Cvw:"; +static char optstr[] = "acdD:efM:P:ps:Cvw:"; int main(int argc, char **argv) { @@ -1621,6 +1829,7 @@ int main(int argc, char **argv) int drop_master = 0; int test_vsync = 0; int test_cursor = 0; + int use_atomic = 0; char *device = NULL; char *module = NULL; unsigned int i; @@ -1639,6 +1848,9 @@ int main(int argc, char **argv) args++; switch (c) { + case 'a': + use_atomic = 1; + break; case 'c': connectors = 1; break; @@ -1718,13 +1930,22 @@ int main(int argc, char **argv) } } - if (!args) + if (!args || (args == 1 && use_atomic)) encoders = connectors = crtcs = planes = framebuffers = 1; dev.fd = util_open(device, module); if (dev.fd < 0) return -1; + ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1); + if (ret && use_atomic) { + fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno)); + drmClose(dev.fd); + return -1; + } + + dev.use_atomic = use_atomic; + if (test_vsync && !page_flipping_supported()) { fprintf(stderr, "page flipping not supported by drm.\n"); return -1; @@ -1765,40 +1986,111 @@ int main(int argc, char **argv) for (i = 0; i < prop_count; ++i) set_property(&dev, &prop_args[i]); - if (count || plane_count) { - uint64_t cap = 0; + if (dev.use_atomic) { + dev.req = drmModeAtomicAlloc(); - ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap); - if (ret || cap == 0) { - fprintf(stderr, "driver doesn't support the dumb buffer API\n"); - return 1; + if (count && plane_count) { + uint64_t cap = 0; + + ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap); + if (ret || cap == 0) { + fprintf(stderr, "driver doesn't support the dumb buffer API\n"); + return 1; + } + + atomic_set_mode(&dev, pipe_args, count); + atomic_set_planes(&dev, plane_args, plane_count, false); + + ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + if (ret) { + fprintf(stderr, "Atomic Commit failed [1]\n"); + return 1; + } + + gettimeofday(&pipe_args->start, NULL); + pipe_args->swap_count = 0; + + while (test_vsync) { + drmModeAtomicFree(dev.req); + dev.req = drmModeAtomicAlloc(); + atomic_set_planes(&dev, plane_args, plane_count, true); + + ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + if (ret) { + fprintf(stderr, "Atomic Commit failed [2]\n"); + return 1; + } + + pipe_args->swap_count++; + if (pipe_args->swap_count == 60) { + struct timeval end; + double t; + + gettimeofday(&end, NULL); + t = end.tv_sec + end.tv_usec * 1e-6 - + (pipe_args->start.tv_sec + pipe_args->start.tv_usec * 1e-6); + fprintf(stderr, "freq: %.02fHz\n", pipe_args->swap_count / t); + pipe_args->swap_count = 0; + pipe_args->start = end; + } + } + + if (drop_master) + drmDropMaster(dev.fd); + + getchar(); + + drmModeAtomicFree(dev.req); + dev.req = drmModeAtomicAlloc(); + + atomic_clear_mode(&dev, pipe_args, count); + atomic_clear_planes(&dev, plane_args, plane_count); + ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + if (ret) { + fprintf(stderr, "Atomic Commit failed\n"); + return 1; + } + + atomic_clear_FB(&dev, plane_args, plane_count); } - if (count) - set_mode(&dev, pipe_args, count); + drmModeAtomicFree(dev.req); + } else { + if (count || plane_count) { + uint64_t cap = 0; - if (plane_count) - set_planes(&dev, plane_args, plane_count); + ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap); + if (ret || cap == 0) { + fprintf(stderr, "driver doesn't support the dumb buffer API\n"); + return 1; + } + + if (count) + set_mode(&dev, pipe_args, count); - if (test_cursor) - set_cursors(&dev, pipe_args, count); + if (plane_count) + set_planes(&dev, plane_args, plane_count); - if (test_vsync) - test_page_flip(&dev, pipe_args, count); + if (test_cursor) + set_cursors(&dev, pipe_args, count); - if (drop_master) - drmDropMaster(dev.fd); + if (test_vsync) + test_page_flip(&dev, pipe_args, count); - getchar(); + if (drop_master) + drmDropMaster(dev.fd); - if (test_cursor) - clear_cursors(&dev); + getchar(); - if (plane_count) - clear_planes(&dev, plane_args, plane_count); + if (test_cursor) + clear_cursors(&dev); - if (count) - clear_mode(&dev); + if (plane_count) + clear_planes(&dev, plane_args, plane_count); + + if (count) + clear_mode(&dev); + } } free_resources(dev.resources); diff --git a/lib/libdrm/tests/nouveau/meson.build b/lib/libdrm/tests/nouveau/meson.build new file mode 100644 index 000000000..f5d73c1e0 --- /dev/null +++ b/lib/libdrm/tests/nouveau/meson.build @@ -0,0 +1,30 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +threaded = executable( + 'threaded', + files('threaded.c'), + dependencies : [dep_dl, dep_threads], + include_directories : [inc_root, inc_drm, include_directories('../../nouveau')], + link_with : [libdrm, libdrm_nouveau], + c_args : warn_c_args, +) + +test('threaded', threaded) diff --git a/lib/libdrm/tests/nouveau/threaded.c b/lib/libdrm/tests/nouveau/threaded.c index 281af4605..3669bcd32 100644 --- a/lib/libdrm/tests/nouveau/threaded.c +++ b/lib/libdrm/tests/nouveau/threaded.c @@ -20,10 +20,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <sys/ioctl.h> #include <dlfcn.h> #include <fcntl.h> diff --git a/lib/libdrm/tests/proptest/meson.build b/lib/libdrm/tests/proptest/meson.build new file mode 100644 index 000000000..22d7473e3 --- /dev/null +++ b/lib/libdrm/tests/proptest/meson.build @@ -0,0 +1,28 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +proptest = executable( + 'proptest', + files('proptest.c'), + c_args : warn_c_args, + include_directories : [inc_root, inc_tests, inc_drm], + link_with : [libdrm, libutil], + install : with_install_tests, +) diff --git a/lib/libdrm/tests/radeon/meson.build b/lib/libdrm/tests/radeon/meson.build new file mode 100644 index 000000000..9e4f916ea --- /dev/null +++ b/lib/libdrm/tests/radeon/meson.build @@ -0,0 +1,27 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +radeon_ttm = executable( + 'radeon_ttm', + files('rbo.c', 'radeon_ttm.c'), + include_directories : [inc_root, inc_drm], + link_with : libdrm, + c_args : warn_c_args, +) diff --git a/lib/libdrm/tests/tegra/meson.build b/lib/libdrm/tests/tegra/meson.build new file mode 100644 index 000000000..9c74ac4ac --- /dev/null +++ b/lib/libdrm/tests/tegra/meson.build @@ -0,0 +1,27 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +openclose = executable( + 'openclose', + files('openclose.c'), + include_directories : [inc_root, inc_drm, include_directories('../../tegra')], + c_args : warn_c_args, + link_with : [libdrm, libdrm_tegra], +) diff --git a/lib/libdrm/tests/tegra/openclose.c b/lib/libdrm/tests/tegra/openclose.c index 881d8aa47..f80f52d47 100644 --- a/lib/libdrm/tests/tegra/openclose.c +++ b/lib/libdrm/tests/tegra/openclose.c @@ -20,10 +20,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <fcntl.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/libdrm/tests/util/format.c b/lib/libdrm/tests/util/format.c index 043cfe7f1..15ac5e1e2 100644 --- a/lib/libdrm/tests/util/format.c +++ b/lib/libdrm/tests/util/format.c @@ -23,10 +23,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdint.h> #include <stdlib.h> #include <string.h> diff --git a/lib/libdrm/tests/util/kms.c b/lib/libdrm/tests/util/kms.c index 028cc8d95..a2d1d7ba2 100644 --- a/lib/libdrm/tests/util/kms.c +++ b/lib/libdrm/tests/util/kms.c @@ -37,10 +37,6 @@ * the mode has been programmed, along with possible test patterns. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <errno.h> #include <stdint.h> #include <stdio.h> @@ -148,6 +144,7 @@ static const char * const modules[] = { "mediatek", "meson", "pl111", + "stm", }; int util_open(const char *device, const char *module) diff --git a/lib/libdrm/tests/util/meson.build b/lib/libdrm/tests/util/meson.build new file mode 100644 index 000000000..7fa1a4b79 --- /dev/null +++ b/lib/libdrm/tests/util/meson.build @@ -0,0 +1,28 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +libutil = static_library( + 'util', + [files('format.c', 'kms.c', 'pattern.c'), config_file], + include_directories : [inc_root, inc_drm], + link_with : libdrm, + dependencies : dep_cairo +) diff --git a/lib/libdrm/tests/util/pattern.c b/lib/libdrm/tests/util/pattern.c index 00b08a8cb..9fa0a417b 100644 --- a/lib/libdrm/tests/util/pattern.c +++ b/lib/libdrm/tests/util/pattern.c @@ -23,10 +23,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -34,7 +30,7 @@ #include <drm_fourcc.h> -#ifdef HAVE_CAIRO +#if HAVE_CAIRO #include <cairo.h> #include <math.h> #endif @@ -546,10 +542,9 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3], static void make_pwetty(void *data, unsigned int width, unsigned int height, unsigned int stride, uint32_t format) { -#ifdef HAVE_CAIRO +#if HAVE_CAIRO cairo_surface_t *surface; cairo_t *cr; - int x, y; cairo_format_t cairo_format; /* we can ignore the order of R,G,B channels */ @@ -576,8 +571,8 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height, cairo_surface_destroy(surface); cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); - for (x = 0; x < width; x += 250) - for (y = 0; y < height; y += 250) { + for (unsigned x = 0; x < width; x += 250) + for (unsigned y = 0; y < height; y += 250) { char buf[64]; cairo_move_to(cr, x, y - 20); @@ -824,8 +819,8 @@ static void fill_tiles(const struct util_format_info *info, void *planes[3], } } -static void fill_plain(const struct util_format_info *info, void *planes[3], - unsigned int width, unsigned int height, +static void fill_plain(void *planes[3], + unsigned int height, unsigned int stride) { memset(planes[0], 0x77, stride * height); @@ -861,7 +856,7 @@ void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern, return fill_smpte(info, planes, width, height, stride); case UTIL_PATTERN_PLAIN: - return fill_plain(info, planes, width, height, stride); + return fill_plain(planes, height, stride); default: printf("Error: unsupported test pattern %u.\n", pattern); diff --git a/lib/libdrm/tests/vbltest/meson.build b/lib/libdrm/tests/vbltest/meson.build new file mode 100644 index 000000000..ae52ab885 --- /dev/null +++ b/lib/libdrm/tests/vbltest/meson.build @@ -0,0 +1,28 @@ +# Copyright © 2017-2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +vbltest = executable( + 'vbltest', + files('vbltest.c'), + c_args : warn_c_args, + include_directories : [inc_root, inc_tests, inc_drm], + link_with : [libdrm, libutil], + install : with_install_tests, +) diff --git a/lib/libdrm/tests/vbltest/vbltest.c b/lib/libdrm/tests/vbltest/vbltest.c index 3f6b803a7..48708d201 100644 --- a/lib/libdrm/tests/vbltest/vbltest.c +++ b/lib/libdrm/tests/vbltest/vbltest.c @@ -24,10 +24,6 @@ * IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <assert.h> #include <stdio.h> #include <stdlib.h> diff --git a/lib/libdrm/vc4/meson.build b/lib/libdrm/vc4/meson.build new file mode 100644 index 000000000..0136987bd --- /dev/null +++ b/lib/libdrm/vc4/meson.build @@ -0,0 +1,28 @@ +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +install_headers('vc4_packet.h', 'vc4_qpu_defines.h', subdir : 'libdrm') + +pkg.generate( + name : 'libdrm_vc4', + version : meson.project_version(), + requires_private : 'libdrm', + description : 'Userspace interface to vc4 kernel DRM services', +) |