libdrm: reduce number of reallocations in drmModeAtomicAddProperty
am: c5371788ed
Change-Id: I3815cd86f4bdc41b5c7553e9ca237d8cc8cfd88f
diff --git a/.editorconfig b/.editorconfig
index 893b7be..29b4f39 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -17,3 +17,7 @@
[*.m4]
indent_style = space
indent_size = 2
+
+[{meson.build,meson_options.txt}]
+indent_style = space
+indent_size = 2
diff --git a/Android.bp b/Android.bp
index 429c22c..9121068 100644
--- a/Android.bp
+++ b/Android.bp
@@ -54,7 +54,7 @@
"libdrm_sources",
],
- export_include_dirs: ["include/drm"],
+ export_include_dirs: ["include/drm", "android"],
cflags: [
"-Wno-enum-conversion",
diff --git a/Makefile.am b/Makefile.am
index 2bf644b..6de5677 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -113,6 +113,7 @@
$(TEGRA_SUBDIR) \
$(VC4_SUBDIR) \
$(ETNAVIV_SUBDIR) \
+ data \
tests \
$(MAN_SUBDIR) \
$(ROCKCHIP_SUBDIR)
@@ -139,7 +140,37 @@
klibdrminclude_HEADERS += $(LIBDRM_INCLUDE_VMWGFX_H_FILES)
endif
-EXTRA_DIST = include/drm/README
+EXTRA_DIST = \
+ include/drm/README \
+ amdgpu/meson.build \
+ data/meson.build \
+ etnaviv/meson.build \
+ exynos/meson.build \
+ freedreno/meson.build \
+ intel/meson.build \
+ libkms/meson.build \
+ man/meson.build \
+ nouveau/meson.build \
+ omap/meson.build \
+ radeon/meson.build \
+ tegra/meson.build \
+ tests/amdgpu/meson.build \
+ tests/etnaviv/meson.build \
+ tests/exynos/meson.build \
+ tests/kms/meson.build \
+ tests/kmstest/meson.build \
+ tests/meson.build \
+ tests/modeprint/meson.build \
+ tests/modetest/meson.build \
+ tests/nouveau/meson.build \
+ tests/proptest/meson.build \
+ tests/radeon/meson.build \
+ tests/tegra/meson.build \
+ tests/util/meson.build \
+ tests/vbltest/meson.build \
+ vc4/meson.build \
+ meson.build \
+ meson_options.txt
copy-headers :
cp -r $(kernel_source)/include/uapi/drm/*.h $(top_srcdir)/include/drm/
diff --git a/Makefile.sources b/Makefile.sources
index 10aa1d0..1f8372b 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -37,5 +37,8 @@
include/drm/via_drm.h \
include/drm/virtgpu_drm.h
+LIBDRM_INCLUDE_ANDROID_H_FILES := \
+ android/gralloc_handle.h
+
LIBDRM_INCLUDE_VMWGFX_H_FILES := \
include/drm/vmwgfx_drm.h
diff --git a/README b/README
index 26cab9d..f3df9ac 100644
--- a/README
+++ b/README
@@ -15,9 +15,27 @@
Compiling
---------
-libdrm is a standard autotools package and follows the normal
-configure, build and install steps. The first step is to configure
-the package, which is done by running the configure shell script:
+libdrm has two build systems, a legacy autotools build system, and a newer
+meson build system. The meson build system is much faster, and offers a
+slightly different interface, but otherwise provides an equivalent feature set.
+
+To use it:
+
+ meson builddir/
+
+By default this will install into /usr/local, you can change your prefix
+with --prefix=/usr (or `meson configure builddir/ -Dprefix=/usr` after
+the initial meson setup).
+
+Then use ninja to build and install:
+
+ ninja -C builddir/ install
+
+If you are installing into a system location you will need to run install
+separately, and as root.
+
+
+Alternatively you can invoke autotools configure:
./configure
diff --git a/RELEASING b/RELEASING
index 262ca08..7e03e3b 100644
--- a/RELEASING
+++ b/RELEASING
@@ -9,9 +9,9 @@
Follow these steps to release a new version of libdrm:
- 1) Bump the version number in configure.ac. We seem to have settled
- for 2.4.x as the versioning scheme for libdrm, so just bump the
- micro version.
+ 1) Bump the version number in configure.ac and meson.build. We seem
+ to have settled for 2.4.x as the versioning scheme for libdrm, so
+ just bump the micro version.
2) Run autoconf and then re-run ./configure so the build system
picks up the new version number.
diff --git a/amdgpu/.editorconfig b/amdgpu/.editorconfig
new file mode 100644
index 0000000..426273f
--- /dev/null
+++ b/amdgpu/.editorconfig
@@ -0,0 +1,13 @@
+# To use this config with your editor, follow the instructions at:
+# http://editorconfig.org
+
+[*]
+charset = utf-8
+indent_style = tab
+indent_size = 8
+tab_width = 8
+insert_final_newline = true
+
+[meson.build]
+indent_style = space
+indent_size = 2
diff --git a/amdgpu/Android.bp b/amdgpu/Android.bp
index a63b617..976f03e 100644
--- a/amdgpu/Android.bp
+++ b/amdgpu/Android.bp
@@ -2,6 +2,11 @@
cc_library_shared {
name: "libdrm_amdgpu",
+
+ cflags: [
+ "-DAMDGPU_ASIC_ID_TABLE=\"/vendor/etc/hwdata/amdgpu.ids\""
+ ],
+
defaults: [
"libdrm_defaults",
"libdrm_amdgpu_sources",
diff --git a/amdgpu/Android.sources.bp b/amdgpu/Android.sources.bp
index 62b8f05..ed85682 100644
--- a/amdgpu/Android.sources.bp
+++ b/amdgpu/Android.sources.bp
@@ -3,11 +3,13 @@
cc_defaults {
name: "libdrm_amdgpu_sources",
srcs: [
+ "amdgpu_asic_id.c",
"amdgpu_bo.c",
"amdgpu_cs.c",
"amdgpu_device.c",
"amdgpu_gpu_info.c",
"amdgpu_vamgr.c",
+ "amdgpu_vm.c",
"util_hash.c",
"util_hash_table.c",
],
diff --git a/amdgpu/Makefile.am b/amdgpu/Makefile.am
index cf7bc1b..a1b0d05 100644
--- a/amdgpu/Makefile.am
+++ b/amdgpu/Makefile.am
@@ -30,12 +30,16 @@
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
+libdrmdatadir = @libdrmdatadir@
+AM_CPPFLAGS = -DAMDGPU_ASIC_ID_TABLE=\"${libdrmdatadir}/amdgpu.ids\"
+
libdrm_amdgpu_la_LTLIBRARIES = libdrm_amdgpu.la
libdrm_amdgpu_ladir = $(libdir)
libdrm_amdgpu_la_LDFLAGS = -version-number 1:0:0 -no-undefined
libdrm_amdgpu_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
libdrm_amdgpu_la_SOURCES = $(LIBDRM_AMDGPU_FILES)
+amdgpu_asic_id.lo: $(top_srcdir)/data/amdgpu.ids
libdrm_amdgpuincludedir = ${includedir}/libdrm
libdrm_amdgpuinclude_HEADERS = $(LIBDRM_AMDGPU_H_FILES)
diff --git a/amdgpu/Makefile.sources b/amdgpu/Makefile.sources
index 487b9e0..498b64c 100644
--- a/amdgpu/Makefile.sources
+++ b/amdgpu/Makefile.sources
@@ -1,11 +1,12 @@
LIBDRM_AMDGPU_FILES := \
- amdgpu_asic_id.h \
+ amdgpu_asic_id.c \
amdgpu_bo.c \
amdgpu_cs.c \
amdgpu_device.c \
amdgpu_gpu_info.c \
amdgpu_internal.h \
amdgpu_vamgr.c \
+ amdgpu_vm.c \
util_hash.c \
util_hash.h \
util_hash_table.c \
diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 87f4fd2..90b7a1d 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/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
@@ -22,16 +22,34 @@
amdgpu_bo_query_info
amdgpu_bo_set_metadata
amdgpu_bo_va_op
+amdgpu_bo_va_op_raw
amdgpu_bo_wait_for_idle
amdgpu_create_bo_from_user_mem
+amdgpu_cs_chunk_fence_info_to_data
+amdgpu_cs_chunk_fence_to_dep
amdgpu_cs_create_semaphore
+amdgpu_cs_create_syncobj
+amdgpu_cs_create_syncobj2
amdgpu_cs_ctx_create
+amdgpu_cs_ctx_create2
amdgpu_cs_ctx_free
amdgpu_cs_destroy_semaphore
+amdgpu_cs_destroy_syncobj
+amdgpu_cs_export_syncobj
+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
+amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_reset
+amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_wait
+amdgpu_cs_wait_fences
amdgpu_cs_wait_semaphore
amdgpu_device_deinitialize
amdgpu_device_initialize
@@ -45,10 +63,13 @@
amdgpu_query_hw_ip_count
amdgpu_query_hw_ip_info
amdgpu_query_info
+amdgpu_query_sensor_info
amdgpu_read_mm_registers
amdgpu_va_range_alloc
amdgpu_va_range_free
amdgpu_va_range_query
+amdgpu_vm_reserve_vmid
+amdgpu_vm_unreserve_vmid
EOF
done)
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 7b26a04..36f9105 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -37,6 +37,10 @@
#include <stdint.h>
#include <stdbool.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct drm_amdgpu_info_hw_ip;
/*--------------------------------------------------------------------------*/
@@ -90,6 +94,10 @@
amdgpu_gpu_va_range_general = 0
};
+enum amdgpu_sw_info {
+ amdgpu_sw_info_address32_hi = 0,
+};
+
/*--------------------------------------------------------------------------*/
/* -------------------------- Datatypes ----------------------------------- */
/*--------------------------------------------------------------------------*/
@@ -794,8 +802,9 @@
* context will always be executed in order (first come, first serve).
*
*
- * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
- * \param context - \c [out] GPU Context handle
+ * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
+ * \param priority - \c [in] Context creation flags. See AMDGPU_CTX_PRIORITY_*
+ * \param context - \c [out] GPU Context handle
*
* \return 0 on success\n
* <0 - Negative POSIX Error code
@@ -803,6 +812,18 @@
* \sa amdgpu_cs_ctx_free()
*
*/
+int amdgpu_cs_ctx_create2(amdgpu_device_handle dev,
+ uint32_t priority,
+ amdgpu_context_handle *context);
+/**
+ * Create GPU execution Context
+ *
+ * Refer to amdgpu_cs_ctx_create2 for full documentation. This call
+ * is missing the priority parameter.
+ *
+ * \sa amdgpu_cs_ctx_create2()
+ *
+*/
int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
amdgpu_context_handle *context);
@@ -907,6 +928,29 @@
uint64_t flags,
uint32_t *expired);
+/**
+ * Wait for multiple fences
+ *
+ * \param fences - \c [in] The fence array to wait
+ * \param fence_count - \c [in] The fence count
+ * \param wait_all - \c [in] If true, wait all fences to be signaled,
+ * otherwise, wait at least one fence
+ * \param timeout_ns - \c [in] The timeout to wait, in nanoseconds
+ * \param status - \c [out] '1' for signaled, '0' for timeout
+ * \param first - \c [out] the index of the first signaled fence from @fences
+ *
+ * \return 0 on success
+ * <0 - Negative POSIX Error code
+ *
+ * \note Currently it supports only one amdgpu_device. All fences come from
+ * the same amdgpu_device with the same fd.
+*/
+int amdgpu_cs_wait_fences(struct amdgpu_cs_fence *fences,
+ uint32_t fence_count,
+ bool wait_all,
+ uint64_t timeout_ns,
+ uint32_t *status, uint32_t *first);
+
/*
* Query / Info API
*
@@ -1046,6 +1090,23 @@
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()
@@ -1059,6 +1120,24 @@
struct amdgpu_gds_resource_info *gds_info);
/**
+ * Query information about sensor.
+ *
+ * The return size is query-specific and depends on the "sensor_type"
+ * parameter. No more than "size" bytes is returned.
+ *
+ * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
+ * \param sensor_type - \c [in] AMDGPU_INFO_SENSOR_*
+ * \param size - \c [in] Size of the returned value.
+ * \param value - \c [out] Pointer to the return value.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
+ unsigned size, void *value);
+
+/**
* Read a set of consecutive memory-mapped registers.
* Not all registers are allowed to be read by userspace.
*
@@ -1083,6 +1162,7 @@
* 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
@@ -1186,6 +1266,34 @@
uint32_t ops);
/**
+ * VA mapping/unmapping for a buffer object or PRT region.
+ *
+ * This is not a simple drop-in extension for amdgpu_bo_va_op; instead, all
+ * parameters are treated "raw", i.e. size is not automatically aligned, and
+ * all flags must be specified explicitly.
+ *
+ * \param dev - \c [in] device handle
+ * \param bo - \c [in] BO handle (may be NULL)
+ * \param offset - \c [in] Start offset to map
+ * \param size - \c [in] Size to map
+ * \param addr - \c [in] Start virtual address.
+ * \param flags - \c [in] Supported flags for mapping/unmapping
+ * \param ops - \c [in] AMDGPU_VA_OP_MAP or AMDGPU_VA_OP_UNMAP
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+
+int amdgpu_bo_va_op_raw(amdgpu_device_handle dev,
+ amdgpu_bo_handle bo,
+ uint64_t offset,
+ uint64_t size,
+ uint64_t addr,
+ uint64_t flags,
+ uint32_t ops);
+
+/**
* create semaphore
*
* \param sem - \c [out] semaphore handle
@@ -1255,4 +1363,216 @@
*/
const char *amdgpu_get_marketing_name(amdgpu_device_handle dev);
+/**
+ * Create kernel sync object
+ *
+ * \param dev - \c [in] device handle
+ * \param flags - \c [in] flags that affect creation
+ * \param syncobj - \c [out] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_create_syncobj2(amdgpu_device_handle dev,
+ uint32_t flags,
+ uint32_t *syncobj);
+
+/**
+ * Create kernel sync object
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [out] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_create_syncobj(amdgpu_device_handle dev,
+ uint32_t *syncobj);
+/**
+ * Destroy kernel sync object
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev,
+ uint32_t syncobj);
+
+/**
+ * Reset kernel sync objects to unsignalled state.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobjs - \c [in] array of sync object handles
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
+ const uint32_t *syncobjs, uint32_t syncobj_count);
+
+/**
+ * Signal kernel sync objects.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobjs - \c [in] array of sync object handles
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs, uint32_t syncobj_count);
+
+/**
+ * Wait for one or all sync objects to signal.
+ *
+ * \param dev - \c [in] self-explanatory
+ * \param handles - \c [in] array of sync object handles
+ * \param num_handles - \c [in] self-explanatory
+ * \param timeout_nsec - \c [in] self-explanatory
+ * \param flags - \c [in] a bitmask of DRM_SYNCOBJ_WAIT_FLAGS_*
+ * \param first_signaled - \c [in] self-explanatory
+ *
+ * \return 0 on success\n
+ * -ETIME - Timeout
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
+ uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+
+/**
+ * Export kernel sync object to shareable fd.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param shared_fd - \c [out] shared file descriptor.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int *shared_fd);
+/**
+ * Import kernel sync object from shareable fd.
+ *
+ * \param dev - \c [in] device handle
+ * \param shared_fd - \c [in] shared file descriptor.
+ * \param syncobj - \c [out] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_import_syncobj(amdgpu_device_handle dev,
+ int shared_fd,
+ uint32_t *syncobj);
+
+/**
+ * Export kernel sync object to a sync_file.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param sync_file_fd - \c [out] sync_file file descriptor.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int *sync_file_fd);
+
+/**
+ * Import kernel sync object from a sync_file.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param sync_file_fd - \c [in] sync_file file descriptor.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int sync_file_fd);
+
+/**
+ * Export an amdgpu fence as a handle (syncobj or fd).
+ *
+ * \param what AMDGPU_FENCE_TO_HANDLE_GET_{SYNCOBJ, FD}
+ * \param out_handle returned handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ */
+int amdgpu_cs_fence_to_handle(amdgpu_device_handle dev,
+ struct amdgpu_cs_fence *fence,
+ uint32_t what,
+ uint32_t *out_handle);
+
+/**
+ * Submit raw command submission to kernel
+ *
+ * \param dev - \c [in] device handle
+ * \param context - \c [in] context handle for context id
+ * \param bo_list_handle - \c [in] request bo list handle (0 for none)
+ * \param num_chunks - \c [in] number of CS chunks to submit
+ * \param chunks - \c [in] array of CS chunks
+ * \param seq_no - \c [out] output sequence number for submission.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ */
+struct drm_amdgpu_cs_chunk;
+struct drm_amdgpu_cs_chunk_dep;
+struct drm_amdgpu_cs_chunk_data;
+
+int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
+ amdgpu_context_handle context,
+ amdgpu_bo_list_handle bo_list_handle,
+ int num_chunks,
+ struct drm_amdgpu_cs_chunk *chunks,
+ uint64_t *seq_no);
+
+void amdgpu_cs_chunk_fence_to_dep(struct amdgpu_cs_fence *fence,
+ struct drm_amdgpu_cs_chunk_dep *dep);
+void amdgpu_cs_chunk_fence_info_to_data(struct amdgpu_cs_fence_info *fence_info,
+ struct drm_amdgpu_cs_chunk_data *data);
+
+/**
+ * Reserve VMID
+ * \param context - \c [in] GPU Context
+ * \param flags - \c [in] TBD
+ *
+ * \return 0 on success otherwise POSIX Error code
+*/
+int amdgpu_vm_reserve_vmid(amdgpu_device_handle dev, uint32_t flags);
+
+/**
+ * Free reserved VMID
+ * \param context - \c [in] GPU Context
+ * \param flags - \c [in] TBD
+ *
+ * \return 0 on success otherwise POSIX Error code
+*/
+int amdgpu_vm_unreserve_vmid(amdgpu_device_handle dev, uint32_t flags);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* #ifdef _AMDGPU_H_ */
diff --git a/amdgpu/amdgpu_asic_id.c b/amdgpu/amdgpu_asic_id.c
new file mode 100644
index 0000000..a5007ff
--- /dev/null
+++ b/amdgpu/amdgpu_asic_id.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2017 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * 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 <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "xf86drm.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+static int parse_one_line(struct amdgpu_device *dev, const char *line)
+{
+ char *buf, *saveptr;
+ char *s_did;
+ uint32_t did;
+ char *s_rid;
+ uint32_t rid;
+ char *s_name;
+ char *endptr;
+ int r = -EINVAL;
+
+ /* ignore empty line and commented line */
+ if (strlen(line) == 0 || line[0] == '#')
+ return -EAGAIN;
+
+ buf = strdup(line);
+ if (!buf)
+ return -ENOMEM;
+
+ /* device id */
+ s_did = strtok_r(buf, ",", &saveptr);
+ if (!s_did)
+ goto out;
+
+ did = strtol(s_did, &endptr, 16);
+ if (*endptr)
+ goto out;
+
+ if (did != dev->info.asic_id) {
+ r = -EAGAIN;
+ goto out;
+ }
+
+ /* revision id */
+ s_rid = strtok_r(NULL, ",", &saveptr);
+ if (!s_rid)
+ goto out;
+
+ rid = strtol(s_rid, &endptr, 16);
+ if (*endptr)
+ goto out;
+
+ if (rid != dev->info.pci_rev_id) {
+ r = -EAGAIN;
+ goto out;
+ }
+
+ /* marketing name */
+ s_name = strtok_r(NULL, ",", &saveptr);
+ if (!s_name)
+ goto out;
+
+ /* trim leading whitespaces or tabs */
+ while (isblank(*s_name))
+ s_name++;
+ if (strlen(s_name) == 0)
+ goto out;
+
+ dev->marketing_name = strdup(s_name);
+ if (dev->marketing_name)
+ r = 0;
+ else
+ r = -ENOMEM;
+
+out:
+ free(buf);
+
+ return r;
+}
+
+void amdgpu_parse_asic_ids(struct amdgpu_device *dev)
+{
+ FILE *fp;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t n;
+ int line_num = 1;
+ int r = 0;
+
+ fp = fopen(AMDGPU_ASIC_ID_TABLE, "r");
+ if (!fp) {
+ fprintf(stderr, "%s: %s\n", AMDGPU_ASIC_ID_TABLE,
+ strerror(errno));
+ return;
+ }
+
+ /* 1st valid line is file version */
+ while ((n = getline(&line, &len, fp)) != -1) {
+ /* trim trailing newline */
+ if (line[n - 1] == '\n')
+ line[n - 1] = '\0';
+
+ /* ignore empty line and commented line */
+ if (strlen(line) == 0 || line[0] == '#') {
+ line_num++;
+ continue;
+ }
+
+ drmMsg("%s version: %s\n", AMDGPU_ASIC_ID_TABLE, line);
+ break;
+ }
+
+ while ((n = getline(&line, &len, fp)) != -1) {
+ /* trim trailing newline */
+ if (line[n - 1] == '\n')
+ line[n - 1] = '\0';
+
+ r = parse_one_line(dev, line);
+ if (r != -EAGAIN)
+ break;
+
+ line_num++;
+ }
+
+ if (r == -EINVAL) {
+ fprintf(stderr, "Invalid format: %s: line %d: %s\n",
+ AMDGPU_ASIC_ID_TABLE, line_num, line);
+ } else if (r && r != -EAGAIN) {
+ fprintf(stderr, "%s: Cannot parse ASIC IDs: %s\n",
+ __func__, strerror(-r));
+ }
+
+ free(line);
+ fclose(fp);
+}
diff --git a/amdgpu/amdgpu_asic_id.h b/amdgpu/amdgpu_asic_id.h
deleted file mode 100644
index 3e7d736..0000000
--- a/amdgpu/amdgpu_asic_id.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright © 2016 Advanced Micro Devices, Inc.
- * All Rights Reserved.
- *
- * 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 __AMDGPU_ASIC_ID_H__
-#define __AMDGPU_ASIC_ID_H__
-
-static struct amdgpu_asic_id_table_t {
- uint32_t did;
- uint32_t rid;
- const char *marketing_name;
-} const amdgpu_asic_id_table [] = {
- {0x6600, 0x0, "AMD Radeon HD 8600/8700M"},
- {0x6600, 0x81, "AMD Radeon R7 M370"},
- {0x6601, 0x0, "AMD Radeon HD 8500M/8700M"},
- {0x6604, 0x0, "AMD Radeon R7 M265 Series"},
- {0x6604, 0x81, "AMD Radeon R7 M350"},
- {0x6605, 0x0, "AMD Radeon R7 M260 Series"},
- {0x6605, 0x81, "AMD Radeon R7 M340"},
- {0x6606, 0x0, "AMD Radeon HD 8790M"},
- {0x6607, 0x0, "AMD Radeon HD8530M"},
- {0x6608, 0x0, "AMD FirePro W2100"},
- {0x6610, 0x0, "AMD Radeon HD 8600 Series"},
- {0x6610, 0x81, "AMD Radeon R7 350"},
- {0x6610, 0x83, "AMD Radeon R5 340"},
- {0x6611, 0x0, "AMD Radeon HD 8500 Series"},
- {0x6613, 0x0, "AMD Radeon HD 8500 series"},
- {0x6617, 0xC7, "AMD Radeon R7 240 Series"},
- {0x6640, 0x0, "AMD Radeon HD 8950"},
- {0x6640, 0x80, "AMD Radeon R9 M380"},
- {0x6646, 0x0, "AMD Radeon R9 M280X"},
- {0x6646, 0x80, "AMD Radeon R9 M470X"},
- {0x6647, 0x0, "AMD Radeon R9 M270X"},
- {0x6647, 0x80, "AMD Radeon R9 M380"},
- {0x6649, 0x0, "AMD FirePro W5100"},
- {0x6658, 0x0, "AMD Radeon R7 200 Series"},
- {0x665C, 0x0, "AMD Radeon HD 7700 Series"},
- {0x665D, 0x0, "AMD Radeon R7 200 Series"},
- {0x665F, 0x81, "AMD Radeon R7 300 Series"},
- {0x6660, 0x0, "AMD Radeon HD 8600M Series"},
- {0x6660, 0x81, "AMD Radeon R5 M335"},
- {0x6660, 0x83, "AMD Radeon R5 M330"},
- {0x6663, 0x0, "AMD Radeon HD 8500M Series"},
- {0x6663, 0x83, "AMD Radeon R5 M320"},
- {0x6664, 0x0, "AMD Radeon R5 M200 Series"},
- {0x6665, 0x0, "AMD Radeon R5 M200 Series"},
- {0x6665, 0x83, "AMD Radeon R5 M320"},
- {0x6667, 0x0, "AMD Radeon R5 M200 Series"},
- {0x666F, 0x0, "AMD Radeon HD 8500M"},
- {0x6780, 0x0, "ATI FirePro V (FireGL V) Graphics Adapter"},
- {0x678A, 0x0, "ATI FirePro V (FireGL V) Graphics Adapter"},
- {0x6798, 0x0, "AMD Radeon HD 7900 Series"},
- {0x679A, 0x0, "AMD Radeon HD 7900 Series"},
- {0x679B, 0x0, "AMD Radeon HD 7900 Series"},
- {0x679E, 0x0, "AMD Radeon HD 7800 Series"},
- {0x67A0, 0x0, "HAWAII XTGL (67A0)"},
- {0x67A1, 0x0, "HAWAII GL40 (67A1)"},
- {0x67B0, 0x0, "AMD Radeon R9 200 Series"},
- {0x67B0, 0x80, "AMD Radeon R9 390 Series"},
- {0x67B1, 0x0, "AMD Radeon R9 200 Series"},
- {0x67B1, 0x80, "AMD Radeon R9 390 Series"},
- {0x67B9, 0x0, "AMD Radeon R9 200 Series"},
- {0x67DF, 0xC4, "AMD Radeon RX 480 Graphics"},
- {0x67DF, 0xC5, "AMD Radeon RX 470 Graphics"},
- {0x67DF, 0xC7, "AMD Radeon RX 480 Graphics"},
- {0x67DF, 0xCF, "AMD Radeon RX 470 Graphics"},
- {0x67C4, 0x00, "AMD Radeon Pro WX 7100 Graphics"},
- {0x67C7, 0x00, "AMD Radeon Pro WX 5100 Graphics"},
- {0x67C0, 0x00, "AMD Radeon Pro WX 7100 Graphics"},
- {0x67E0, 0x00, "AMD Radeon Pro WX Series Graphics"},
- {0x67E3, 0x00, "AMD Radeon Pro WX 4100 Graphics"},
- {0x67E8, 0x00, "AMD Radeon Pro WX Series Graphics"},
- {0x67E8, 0x01, "AMD Radeon Pro WX Series Graphics"},
- {0x67E8, 0x80, "AMD Radeon E9260 Graphics"},
- {0x67EB, 0x00, "AMD Radeon Pro WX Series Graphics"},
- {0x67EF, 0xC0, "AMD Radeon RX Graphics"},
- {0x67EF, 0xC1, "AMD Radeon RX 460 Graphics"},
- {0x67EF, 0xC5, "AMD Radeon RX 460 Graphics"},
- {0x67EF, 0xC7, "AMD Radeon RX Graphics"},
- {0x67EF, 0xCF, "AMD Radeon RX 460 Graphics"},
- {0x67EF, 0xEF, "AMD Radeon RX Graphics"},
- {0x67FF, 0xC0, "AMD Radeon RX Graphics"},
- {0x67FF, 0xC1, "AMD Radeon RX Graphics"},
- {0x6800, 0x0, "AMD Radeon HD 7970M"},
- {0x6801, 0x0, "AMD Radeon(TM) HD8970M"},
- {0x6808, 0x0, "ATI FirePro V(FireGL V) Graphics Adapter"},
- {0x6809, 0x0, "ATI FirePro V(FireGL V) Graphics Adapter"},
- {0x6810, 0x0, "AMD Radeon(TM) HD 8800 Series"},
- {0x6810, 0x81, "AMD Radeon R7 370 Series"},
- {0x6811, 0x0, "AMD Radeon(TM) HD8800 Series"},
- {0x6811, 0x81, "AMD Radeon R7 300 Series"},
- {0x6818, 0x0, "AMD Radeon HD 7800 Series"},
- {0x6819, 0x0, "AMD Radeon HD 7800 Series"},
- {0x6820, 0x0, "AMD Radeon HD 8800M Series"},
- {0x6820, 0x81, "AMD Radeon R9 M375"},
- {0x6820, 0x83, "AMD Radeon R9 M375X"},
- {0x6821, 0x0, "AMD Radeon HD 8800M Series"},
- {0x6821, 0x87, "AMD Radeon R7 M380"},
- {0x6821, 0x83, "AMD Radeon R9 M370X"},
- {0x6822, 0x0, "AMD Radeon E8860"},
- {0x6823, 0x0, "AMD Radeon HD 8800M Series"},
- {0x6825, 0x0, "AMD Radeon HD 7800M Series"},
- {0x6827, 0x0, "AMD Radeon HD 7800M Series"},
- {0x6828, 0x0, "ATI FirePro V(FireGL V) Graphics Adapter"},
- {0x682B, 0x0, "AMD Radeon HD 8800M Series"},
- {0x682B, 0x87, "AMD Radeon R9 M360"},
- {0x682C, 0x0, "AMD FirePro W4100"},
- {0x682D, 0x0, "AMD Radeon HD 7700M Series"},
- {0x682F, 0x0, "AMD Radeon HD 7700M Series"},
- {0x6835, 0x0, "AMD Radeon R7 Series / HD 9000 Series"},
- {0x6837, 0x0, "AMD Radeon HD7700 Series"},
- {0x683D, 0x0, "AMD Radeon HD 7700 Series"},
- {0x683F, 0x0, "AMD Radeon HD 7700 Series"},
- {0x6900, 0x0, "AMD Radeon R7 M260"},
- {0x6900, 0x81, "AMD Radeon R7 M360"},
- {0x6900, 0x83, "AMD Radeon R7 M340"},
- {0x6901, 0x0, "AMD Radeon R5 M255"},
- {0x6907, 0x0, "AMD Radeon R5 M255"},
- {0x6907, 0x87, "AMD Radeon R5 M315"},
- {0x6920, 0x0, "AMD Radeon R9 M395X"},
- {0x6920, 0x1, "AMD Radeon R9 M390X"},
- {0x6921, 0x0, "AMD Radeon R9 M295X"},
- {0x6929, 0x0, "AMD FirePro S7150"},
- {0x692B, 0x0, "AMD FirePro W7100"},
- {0x6938, 0x0, "AMD Radeon R9 200 Series"},
- {0x6938, 0xF0, "AMD Radeon R9 200 Series"},
- {0x6938, 0xF1, "AMD Radeon R9 380 Series"},
- {0x6939, 0xF0, "AMD Radeon R9 200 Series"},
- {0x6939, 0x0, "AMD Radeon R9 200 Series"},
- {0x6939, 0xF1, "AMD Radeon R9 380 Series"},
- {0x7300, 0xC8, "AMD Radeon R9 Fury Series"},
- {0x7300, 0xCB, "AMD Radeon R9 Fury Series"},
- {0x7300, 0xCA, "AMD Radeon R9 Fury Series"},
- {0x9874, 0xC4, "AMD Radeon R7 Graphics"},
- {0x9874, 0xC5, "AMD Radeon R6 Graphics"},
- {0x9874, 0xC6, "AMD Radeon R6 Graphics"},
- {0x9874, 0xC7, "AMD Radeon R5 Graphics"},
- {0x9874, 0x81, "AMD Radeon R6 Graphics"},
- {0x9874, 0x87, "AMD Radeon R5 Graphics"},
- {0x9874, 0x85, "AMD Radeon R6 Graphics"},
- {0x9874, 0x84, "AMD Radeon R7 Graphics"},
-
- {0x0000, 0x0, "\0"},
-};
-#endif
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c
index d30fd1e..9e37b14 100644
--- a/amdgpu/amdgpu_bo.c
+++ b/amdgpu/amdgpu_bo.c
@@ -22,10 +22,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
@@ -53,29 +49,6 @@
drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &args);
}
-drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo)
-{
- /* Remove the buffer from the hash tables. */
- pthread_mutex_lock(&bo->dev->bo_table_mutex);
- util_hash_table_remove(bo->dev->bo_handles,
- (void*)(uintptr_t)bo->handle);
- if (bo->flink_name) {
- util_hash_table_remove(bo->dev->bo_flink_names,
- (void*)(uintptr_t)bo->flink_name);
- }
- pthread_mutex_unlock(&bo->dev->bo_table_mutex);
-
- /* Release CPU access. */
- if (bo->cpu_map_count > 0) {
- bo->cpu_map_count = 1;
- amdgpu_bo_cpu_unmap(bo);
- }
-
- amdgpu_close_kms_handle(bo->dev, bo->handle);
- pthread_mutex_destroy(&bo->cpu_access_mutex);
- free(bo);
-}
-
int amdgpu_bo_alloc(amdgpu_device_handle dev,
struct amdgpu_bo_alloc_request *alloc_buffer,
amdgpu_bo_handle *buf_handle)
@@ -273,8 +246,9 @@
case amdgpu_bo_handle_type_dma_buf_fd:
amdgpu_add_handle_to_table(bo);
- return drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC,
- (int*)shared_handle);
+ return drmPrimeHandleToFD(bo->dev->fd, bo->handle,
+ DRM_CLOEXEC | DRM_RDWR,
+ (int*)shared_handle);
}
return -EINVAL;
}
@@ -302,6 +276,7 @@
/* Get a KMS handle. */
r = drmPrimeFDToHandle(dev->fd, shared_handle, &handle);
if (r) {
+ pthread_mutex_unlock(&dev->bo_table_mutex);
return r;
}
@@ -341,10 +316,9 @@
}
if (bo) {
- pthread_mutex_unlock(&dev->bo_table_mutex);
-
/* The buffer already exists, just bump the refcount. */
atomic_inc(&bo->refcount);
+ pthread_mutex_unlock(&dev->bo_table_mutex);
output->buf_handle = bo;
output->alloc_size = bo->alloc_size;
@@ -419,8 +393,35 @@
int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
{
- /* Just drop the reference. */
- amdgpu_bo_reference(&buf_handle, NULL);
+ struct amdgpu_device *dev;
+ struct amdgpu_bo *bo = buf_handle;
+
+ assert(bo != NULL);
+ dev = bo->dev;
+ pthread_mutex_lock(&dev->bo_table_mutex);
+
+ if (update_references(&bo->refcount, NULL)) {
+ /* Remove the buffer from the hash tables. */
+ util_hash_table_remove(dev->bo_handles,
+ (void*)(uintptr_t)bo->handle);
+
+ if (bo->flink_name) {
+ util_hash_table_remove(dev->bo_flink_names,
+ (void*)(uintptr_t)bo->flink_name);
+ }
+
+ /* Release CPU access. */
+ if (bo->cpu_map_count > 0) {
+ bo->cpu_map_count = 1;
+ amdgpu_bo_cpu_unmap(bo);
+ }
+
+ amdgpu_close_kms_handle(dev, bo->handle);
+ pthread_mutex_destroy(&bo->cpu_access_mutex);
+ free(bo);
+ }
+
+ pthread_mutex_unlock(&dev->bo_table_mutex);
return 0;
}
@@ -652,7 +653,7 @@
return -EINVAL;
list = malloc(number_of_resources * sizeof(struct drm_amdgpu_bo_list_entry));
- if (list == NULL)
+ if (!list)
return -ENOMEM;
args.in.operation = AMDGPU_BO_LIST_OP_UPDATE;
@@ -683,21 +684,37 @@
uint32_t ops)
{
amdgpu_device_handle dev = bo->dev;
+
+ size = ALIGN(size, getpagesize());
+
+ return amdgpu_bo_va_op_raw(dev, bo, offset, size, addr,
+ AMDGPU_VM_PAGE_READABLE |
+ AMDGPU_VM_PAGE_WRITEABLE |
+ AMDGPU_VM_PAGE_EXECUTABLE, ops);
+}
+
+int amdgpu_bo_va_op_raw(amdgpu_device_handle dev,
+ amdgpu_bo_handle bo,
+ uint64_t offset,
+ uint64_t size,
+ uint64_t addr,
+ uint64_t flags,
+ uint32_t ops)
+{
struct drm_amdgpu_gem_va va;
int r;
- if (ops != AMDGPU_VA_OP_MAP && ops != AMDGPU_VA_OP_UNMAP)
+ if (ops != AMDGPU_VA_OP_MAP && ops != AMDGPU_VA_OP_UNMAP &&
+ ops != AMDGPU_VA_OP_REPLACE && ops != AMDGPU_VA_OP_CLEAR)
return -EINVAL;
memset(&va, 0, sizeof(va));
- va.handle = bo->handle;
+ va.handle = bo ? bo->handle : 0;
va.operation = ops;
- va.flags = AMDGPU_VM_PAGE_READABLE |
- AMDGPU_VM_PAGE_WRITEABLE |
- AMDGPU_VM_PAGE_EXECUTABLE;
+ va.flags = flags;
va.va_address = addr;
va.offset_in_bo = offset;
- va.map_size = ALIGN(size, getpagesize());
+ va.map_size = size;
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_VA, &va, sizeof(va));
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index fb5b3a8..f986908 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/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>
@@ -46,26 +42,25 @@
/**
* Create command submission context
*
- * \param dev - \c [in] amdgpu device handle
- * \param context - \c [out] amdgpu context handle
+ * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
+ * \param priority - \c [in] Context creation flags. See AMDGPU_CTX_PRIORITY_*
+ * \param context - \c [out] GPU Context handle
*
* \return 0 on success otherwise POSIX Error code
*/
-int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
- amdgpu_context_handle *context)
+int amdgpu_cs_ctx_create2(amdgpu_device_handle dev, uint32_t priority,
+ amdgpu_context_handle *context)
{
struct amdgpu_context *gpu_context;
union drm_amdgpu_ctx args;
int i, j, k;
int r;
- if (NULL == dev)
- return -EINVAL;
- if (NULL == context)
+ if (!dev || !context)
return -EINVAL;
gpu_context = calloc(1, sizeof(struct amdgpu_context));
- if (NULL == gpu_context)
+ if (!gpu_context)
return -ENOMEM;
gpu_context->dev = dev;
@@ -77,6 +72,8 @@
/* Create the context */
memset(&args, 0, sizeof(args));
args.in.op = AMDGPU_CTX_OP_ALLOC_CTX;
+ args.in.priority = priority;
+
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CTX, &args, sizeof(args));
if (r)
goto error;
@@ -96,6 +93,12 @@
return r;
}
+int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
+ amdgpu_context_handle *context)
+{
+ return amdgpu_cs_ctx_create2(dev, AMDGPU_CTX_PRIORITY_NORMAL, context);
+}
+
/**
* Release command submission context
*
@@ -110,7 +113,7 @@
int i, j, k;
int r;
- if (NULL == context)
+ if (!context)
return -EINVAL;
pthread_mutex_destroy(&context->sequence_mutex);
@@ -188,8 +191,6 @@
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;
@@ -330,9 +331,7 @@
uint32_t i;
int r;
- if (NULL == context)
- return -EINVAL;
- if (NULL == ibs_request)
+ if (!context || !ibs_request)
return -EINVAL;
r = 0;
@@ -416,11 +415,7 @@
bool busy = true;
int r;
- if (NULL == fence)
- return -EINVAL;
- if (NULL == expired)
- return -EINVAL;
- if (NULL == fence->context)
+ if (!fence || !expired || !fence->context)
return -EINVAL;
if (fence->ip_type >= AMDGPU_HW_IP_NUM)
return -EINVAL;
@@ -443,15 +438,83 @@
return r;
}
+static int amdgpu_ioctl_wait_fences(struct amdgpu_cs_fence *fences,
+ uint32_t fence_count,
+ bool wait_all,
+ uint64_t timeout_ns,
+ uint32_t *status,
+ uint32_t *first)
+{
+ struct drm_amdgpu_fence *drm_fences;
+ amdgpu_device_handle dev = fences[0].context->dev;
+ union drm_amdgpu_wait_fences args;
+ int r;
+ uint32_t i;
+
+ drm_fences = alloca(sizeof(struct drm_amdgpu_fence) * fence_count);
+ for (i = 0; i < fence_count; i++) {
+ drm_fences[i].ctx_id = fences[i].context->id;
+ drm_fences[i].ip_type = fences[i].ip_type;
+ drm_fences[i].ip_instance = fences[i].ip_instance;
+ drm_fences[i].ring = fences[i].ring;
+ drm_fences[i].seq_no = fences[i].fence;
+ }
+
+ memset(&args, 0, sizeof(args));
+ args.in.fences = (uint64_t)(uintptr_t)drm_fences;
+ args.in.fence_count = fence_count;
+ args.in.wait_all = wait_all;
+ args.in.timeout_ns = amdgpu_cs_calculate_timeout(timeout_ns);
+
+ r = drmIoctl(dev->fd, DRM_IOCTL_AMDGPU_WAIT_FENCES, &args);
+ if (r)
+ return -errno;
+
+ *status = args.out.status;
+
+ if (first)
+ *first = args.out.first_signaled;
+
+ return 0;
+}
+
+int amdgpu_cs_wait_fences(struct amdgpu_cs_fence *fences,
+ uint32_t fence_count,
+ bool wait_all,
+ uint64_t timeout_ns,
+ uint32_t *status,
+ uint32_t *first)
+{
+ uint32_t i;
+
+ /* Sanity check */
+ if (!fences || !status || !fence_count)
+ return -EINVAL;
+
+ for (i = 0; i < fence_count; i++) {
+ if (NULL == fences[i].context)
+ return -EINVAL;
+ if (fences[i].ip_type >= AMDGPU_HW_IP_NUM)
+ return -EINVAL;
+ if (fences[i].ring >= AMDGPU_CS_MAX_RINGS)
+ return -EINVAL;
+ }
+
+ *status = 0;
+
+ return amdgpu_ioctl_wait_fences(fences, fence_count, wait_all,
+ timeout_ns, status, first);
+}
+
int amdgpu_cs_create_semaphore(amdgpu_semaphore_handle *sem)
{
struct amdgpu_semaphore *gpu_semaphore;
- if (NULL == sem)
+ if (!sem)
return -EINVAL;
gpu_semaphore = calloc(1, sizeof(struct amdgpu_semaphore));
- if (NULL == gpu_semaphore)
+ if (!gpu_semaphore)
return -ENOMEM;
atomic_set(&gpu_semaphore->refcount, 1);
@@ -466,14 +529,12 @@
uint32_t ring,
amdgpu_semaphore_handle sem)
{
- if (NULL == ctx)
+ if (!ctx || !sem)
return -EINVAL;
if (ip_type >= AMDGPU_HW_IP_NUM)
return -EINVAL;
if (ring >= AMDGPU_CS_MAX_RINGS)
return -EINVAL;
- if (NULL == sem)
- return -EINVAL;
/* sem has been signaled */
if (sem->signal_fence.context)
return -EINVAL;
@@ -494,16 +555,14 @@
uint32_t ring,
amdgpu_semaphore_handle sem)
{
- if (NULL == ctx)
+ if (!ctx || !sem)
return -EINVAL;
if (ip_type >= AMDGPU_HW_IP_NUM)
return -EINVAL;
if (ring >= AMDGPU_CS_MAX_RINGS)
return -EINVAL;
- if (NULL == sem)
- return -EINVAL;
/* must signal first */
- if (NULL == sem->signal_fence.context)
+ if (!sem->signal_fence.context)
return -EINVAL;
pthread_mutex_lock(&ctx->sequence_mutex);
@@ -514,12 +573,10 @@
static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem)
{
- if (NULL == sem)
- return -EINVAL;
- if (NULL == sem->signal_fence.context)
+ 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;
@@ -530,7 +587,7 @@
static int amdgpu_cs_unreference_sem(amdgpu_semaphore_handle sem)
{
- if (NULL == sem)
+ if (!sem)
return -EINVAL;
if (update_references(&sem->refcount, NULL))
@@ -542,3 +599,172 @@
{
return amdgpu_cs_unreference_sem(sem);
}
+
+int amdgpu_cs_create_syncobj2(amdgpu_device_handle dev,
+ uint32_t flags,
+ uint32_t *handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjCreate(dev->fd, flags, handle);
+}
+
+int amdgpu_cs_create_syncobj(amdgpu_device_handle dev,
+ uint32_t *handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjCreate(dev->fd, 0, handle);
+}
+
+int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev,
+ uint32_t handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjDestroy(dev->fd, handle);
+}
+
+int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
+ const uint32_t *syncobjs, uint32_t syncobj_count)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjReset(dev->fd, syncobjs, syncobj_count);
+}
+
+int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs, uint32_t syncobj_count)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
+}
+
+int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
+ uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjWait(dev->fd, handles, num_handles, timeout_nsec,
+ flags, first_signaled);
+}
+
+int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
+ uint32_t handle,
+ int *shared_fd)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjHandleToFD(dev->fd, handle, shared_fd);
+}
+
+int amdgpu_cs_import_syncobj(amdgpu_device_handle dev,
+ int shared_fd,
+ uint32_t *handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjFDToHandle(dev->fd, shared_fd, handle);
+}
+
+int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int *sync_file_fd)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjExportSyncFile(dev->fd, syncobj, sync_file_fd);
+}
+
+int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int sync_file_fd)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
+}
+
+int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
+ amdgpu_context_handle context,
+ amdgpu_bo_list_handle bo_list_handle,
+ int num_chunks,
+ struct drm_amdgpu_cs_chunk *chunks,
+ uint64_t *seq_no)
+{
+ union drm_amdgpu_cs cs;
+ uint64_t *chunk_array;
+ int i, r;
+ if (num_chunks == 0)
+ return -EINVAL;
+
+ memset(&cs, 0, sizeof(cs));
+ chunk_array = alloca(sizeof(uint64_t) * num_chunks);
+ for (i = 0; i < num_chunks; i++)
+ chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
+ cs.in.chunks = (uint64_t)(uintptr_t)chunk_array;
+ cs.in.ctx_id = context->id;
+ cs.in.bo_list_handle = bo_list_handle ? bo_list_handle->handle : 0;
+ cs.in.num_chunks = num_chunks;
+ r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CS,
+ &cs, sizeof(cs));
+ if (r)
+ return r;
+
+ if (seq_no)
+ *seq_no = cs.out.handle;
+ return 0;
+}
+
+void amdgpu_cs_chunk_fence_info_to_data(struct amdgpu_cs_fence_info *fence_info,
+ struct drm_amdgpu_cs_chunk_data *data)
+{
+ data->fence_data.handle = fence_info->handle->handle;
+ data->fence_data.offset = fence_info->offset * sizeof(uint64_t);
+}
+
+void amdgpu_cs_chunk_fence_to_dep(struct amdgpu_cs_fence *fence,
+ struct drm_amdgpu_cs_chunk_dep *dep)
+{
+ dep->ip_type = fence->ip_type;
+ dep->ip_instance = fence->ip_instance;
+ dep->ring = fence->ring;
+ dep->ctx_id = fence->context->id;
+ dep->handle = fence->fence;
+}
+
+int amdgpu_cs_fence_to_handle(amdgpu_device_handle dev,
+ struct amdgpu_cs_fence *fence,
+ uint32_t what,
+ uint32_t *out_handle)
+{
+ union drm_amdgpu_fence_to_handle fth;
+ int r;
+
+ memset(&fth, 0, sizeof(fth));
+ fth.in.fence.ctx_id = fence->context->id;
+ fth.in.fence.ip_type = fence->ip_type;
+ fth.in.fence.ip_instance = fence->ip_instance;
+ fth.in.fence.ring = fence->ring;
+ fth.in.fence.seq_no = fence->fence;
+ fth.in.what = what;
+
+ r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_FENCE_TO_HANDLE,
+ &fth, sizeof(fth));
+ if (r == 0)
+ *out_handle = fth.out.handle;
+ return r;
+}
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index f4ede03..d81efcf 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -28,10 +28,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
@@ -44,7 +40,6 @@
#include "amdgpu_internal.h"
#include "util_hash_table.h"
#include "util_math.h"
-#include "amdgpu_asic_id.h"
#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
#define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
@@ -131,10 +126,8 @@
static void amdgpu_device_free_internal(amdgpu_device_handle dev)
{
- amdgpu_vamgr_deinit(dev->vamgr);
- free(dev->vamgr);
- amdgpu_vamgr_deinit(dev->vamgr_32);
- free(dev->vamgr_32);
+ 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);
@@ -142,6 +135,7 @@
close(dev->fd);
if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
close(dev->flink_fd);
+ free(dev->marketing_name);
free(dev);
}
@@ -187,6 +181,8 @@
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",
+ __func__, r);
pthread_mutex_unlock(&fd_mutex);
return r;
}
@@ -194,6 +190,8 @@
if (dev) {
r = amdgpu_get_auth(dev->fd, &flag_authexist);
if (r) {
+ fprintf(stderr, "%s: amdgpu_get_auth (2) failed (%i)\n",
+ __func__, r);
pthread_mutex_unlock(&fd_mutex);
return r;
}
@@ -209,6 +207,7 @@
dev = calloc(1, sizeof(struct amdgpu_device));
if (!dev) {
+ fprintf(stderr, "%s: calloc failed\n", __func__);
pthread_mutex_unlock(&fd_mutex);
return -ENOMEM;
}
@@ -244,38 +243,47 @@
/* Check if acceleration is working. */
r = amdgpu_query_info(dev, AMDGPU_INFO_ACCEL_WORKING, 4, &accel_working);
- if (r)
+ if (r) {
+ fprintf(stderr, "%s: amdgpu_query_info(ACCEL_WORKING) failed (%i)\n",
+ __func__, r);
goto cleanup;
+ }
if (!accel_working) {
+ fprintf(stderr, "%s: AMDGPU_INFO_ACCEL_WORKING = 0\n", __func__);
r = -EBADF;
goto cleanup;
}
r = amdgpu_query_gpu_info_init(dev);
- if (r)
+ if (r) {
+ fprintf(stderr, "%s: amdgpu_query_gpu_info_init failed\n", __func__);
goto cleanup;
+ }
- dev->vamgr = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
- if (dev->vamgr == NULL)
- goto cleanup;
-
- amdgpu_vamgr_init(dev->vamgr, dev->dev_info.virtual_address_offset,
- dev->dev_info.virtual_address_max,
+ start = dev->dev_info.virtual_address_offset;
+ max = MIN2(dev->dev_info.virtual_address_max, 0x100000000ULL);
+ amdgpu_vamgr_init(&dev->vamgr_32, start, max,
dev->dev_info.virtual_address_alignment);
- max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff);
- start = amdgpu_vamgr_find_va(dev->vamgr,
- max - dev->dev_info.virtual_address_offset,
- dev->dev_info.virtual_address_alignment, 0);
- if (start > 0xffffffff)
- goto free_va; /* shouldn't get here */
-
- dev->vamgr_32 = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
- if (dev->vamgr_32 == NULL)
- goto free_va;
- amdgpu_vamgr_init(dev->vamgr_32, start, max,
+ 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;
@@ -284,13 +292,6 @@
return 0;
-free_va:
- r = -ENOMEM;
- amdgpu_vamgr_free_va(dev->vamgr, start,
- max - dev->dev_info.virtual_address_offset);
- amdgpu_vamgr_deinit(dev->vamgr);
- free(dev->vamgr);
-
cleanup:
if (dev->fd >= 0)
close(dev->fd);
@@ -307,14 +308,21 @@
const char *amdgpu_get_marketing_name(amdgpu_device_handle dev)
{
- const struct amdgpu_asic_id_table_t *t = amdgpu_asic_id_table;
+ return dev->marketing_name;
+}
- while (t->did) {
- if ((t->did == dev->info.asic_id) &&
- (t->rid == dev->info.pci_rev_id))
- return t->marketing_name;
- t++;
+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 NULL;
+ return -EINVAL;
}
diff --git a/amdgpu/amdgpu_gpu_info.c b/amdgpu/amdgpu_gpu_info.c
index 66c7e0e..b68e1c4 100644
--- a/amdgpu/amdgpu_gpu_info.c
+++ b/amdgpu/amdgpu_gpu_info.c
@@ -22,10 +22,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <string.h>
@@ -169,54 +165,58 @@
dev->info.vce_harvest_config = dev->dev_info.vce_harvest_config;
dev->info.pci_rev_id = dev->dev_info.pci_rev;
- for (i = 0; i < (int)dev->info.num_shader_engines; i++) {
- unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
- (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
- AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
+ if (dev->info.family_id < AMDGPU_FAMILY_AI) {
+ for (i = 0; i < (int)dev->info.num_shader_engines; i++) {
+ unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
+ (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
+ AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
- r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
- &dev->info.backend_disable[i]);
- if (r)
- return r;
- /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
- dev->info.backend_disable[i] =
- (dev->info.backend_disable[i] >> 16) & 0xff;
+ r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
+ &dev->info.backend_disable[i]);
+ if (r)
+ return r;
+ /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
+ dev->info.backend_disable[i] =
+ (dev->info.backend_disable[i] >> 16) & 0xff;
- r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
- &dev->info.pa_sc_raster_cfg[i]);
+ r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
+ &dev->info.pa_sc_raster_cfg[i]);
+ if (r)
+ return r;
+
+ if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
+ r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
+ &dev->info.pa_sc_raster_cfg1[i]);
+ if (r)
+ return r;
+ }
+ }
+ }
+
+ r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
+ &dev->info.gb_addr_cfg);
+ if (r)
+ return r;
+
+ if (dev->info.family_id < AMDGPU_FAMILY_AI) {
+ r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
+ dev->info.gb_tile_mode);
if (r)
return r;
if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
- r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
- &dev->info.pa_sc_raster_cfg1[i]);
+ r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
+ dev->info.gb_macro_tile_mode);
if (r)
return r;
}
- }
- r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
- dev->info.gb_tile_mode);
- if (r)
- return r;
-
- if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
- r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
- dev->info.gb_macro_tile_mode);
+ r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
+ &dev->info.mc_arb_ramcfg);
if (r)
return r;
}
- r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
- &dev->info.gb_addr_cfg);
- if (r)
- return r;
-
- r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
- &dev->info.mc_arb_ramcfg);
- if (r)
- return r;
-
dev->info.cu_active_number = dev->dev_info.cu_active_number;
dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask;
memcpy(&dev->info.cu_bitmap[0][0], &dev->dev_info.cu_bitmap[0][0], sizeof(dev->info.cu_bitmap));
@@ -230,8 +230,9 @@
int amdgpu_query_gpu_info(amdgpu_device_handle dev,
struct amdgpu_gpu_info *info)
{
- if ((dev == NULL) || (info == NULL))
+ if (!dev || !info)
return -EINVAL;
+
/* Get ASIC info*/
*info = dev->info;
@@ -296,7 +297,7 @@
struct drm_amdgpu_info_gds gds_config = {};
int r;
- if (gds_info == NULL)
+ if (!gds_info)
return -EINVAL;
r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG,
@@ -314,3 +315,18 @@
return 0;
}
+
+int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
+ unsigned size, void *value)
+{
+ struct drm_amdgpu_info request;
+
+ memset(&request, 0, sizeof(request));
+ request.return_pointer = (uintptr_t)value;
+ request.return_size = size;
+ request.query = AMDGPU_INFO_SENSOR;
+ request.sensor_info.type = sensor_type;
+
+ return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+ sizeof(struct drm_amdgpu_info));
+}
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 4f039b6..99b8ce0 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/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>
@@ -53,8 +49,6 @@
};
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;
@@ -76,6 +70,7 @@
unsigned major_version;
unsigned minor_version;
+ char *marketing_name;
/** List of buffer handles. Protected by bo_table_mutex. */
struct util_hash_table *bo_handles;
/** List of buffer GEM flink names. Protected by bo_table_mutex. */
@@ -84,10 +79,14 @@
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 */
- struct amdgpu_bo_va_mgr *vamgr;
+ /** 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;
+ 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 {
@@ -135,19 +134,12 @@
* Functions.
*/
-drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo);
-
drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
uint64_t max, uint64_t alignment);
drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
-drm_private uint64_t
-amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
- uint64_t alignment, uint64_t base_required);
-
-drm_private void
-amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size);
+drm_private void amdgpu_parse_asic_ids(struct amdgpu_device *dev);
drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev);
@@ -179,26 +171,4 @@
return false;
}
-/**
- * Assignment between two amdgpu_bo pointers with reference counting.
- *
- * Usage:
- * struct amdgpu_bo *dst = ... , *src = ...;
- *
- * dst = src;
- * // No reference counting. Only use this when you need to move
- * // a reference from one pointer to another.
- *
- * amdgpu_bo_reference(&dst, src);
- * // Reference counters are updated. dst is decremented and src is
- * // incremented. dst is freed if its reference counter is 0.
- */
-static inline void amdgpu_bo_reference(struct amdgpu_bo **dst,
- struct amdgpu_bo *src)
-{
- if (update_references(&(*dst)->refcount, &src->refcount))
- amdgpu_bo_free_internal(*dst);
- *dst = src;
-}
-
#endif
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 8a707cb..1de9f95 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/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>
@@ -34,25 +30,33 @@
#include "util_math.h"
int amdgpu_va_range_query(amdgpu_device_handle dev,
- enum amdgpu_gpu_va_range type, uint64_t *start, uint64_t *end)
+ enum amdgpu_gpu_va_range type,
+ uint64_t *start, uint64_t *end)
{
- if (type == amdgpu_gpu_va_range_general) {
- *start = dev->dev_info.virtual_address_offset;
- *end = dev->dev_info.virtual_address_max;
- return 0;
- }
- return -EINVAL;
+ if (type != amdgpu_gpu_va_range_general)
+ return -EINVAL;
+
+ *start = dev->dev_info.virtual_address_offset;
+ *end = dev->dev_info.virtual_address_max;
+ return 0;
}
drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
- uint64_t max, uint64_t alignment)
+ 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)
@@ -65,13 +69,14 @@
pthread_mutex_destroy(&mgr->bo_va_mutex);
}
-drm_private uint64_t
+static drm_private uint64_t
amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
uint64_t alignment, uint64_t base_required)
{
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);
@@ -79,12 +84,10 @@
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))
+ if (hole->offset > base_required ||
+ (hole->offset + hole->size) < (base_required + size))
continue;
waste = base_required - hole->offset;
offset = base_required;
@@ -123,41 +126,14 @@
}
}
- 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;
}
-drm_private void
+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;
@@ -165,61 +141,47 @@
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);
}
@@ -235,10 +197,21 @@
{
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);
@@ -249,7 +222,10 @@
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/amdgpu/amdgpu_vm.c b/amdgpu/amdgpu_vm.c
new file mode 100644
index 0000000..da9d07f
--- /dev/null
+++ b/amdgpu/amdgpu_vm.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2017 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 "amdgpu.h"
+#include "amdgpu_drm.h"
+#include "xf86drm.h"
+#include "amdgpu_internal.h"
+
+int amdgpu_vm_reserve_vmid(amdgpu_device_handle dev, uint32_t flags)
+{
+ union drm_amdgpu_vm vm;
+
+ vm.in.op = AMDGPU_VM_OP_RESERVE_VMID;
+ vm.in.flags = flags;
+
+ return drmCommandWriteRead(dev->fd, DRM_AMDGPU_VM,
+ &vm, sizeof(vm));
+}
+
+int amdgpu_vm_unreserve_vmid(amdgpu_device_handle dev, uint32_t flags)
+{
+ union drm_amdgpu_vm vm;
+
+ vm.in.op = AMDGPU_VM_OP_UNRESERVE_VMID;
+ vm.in.flags = flags;
+
+ return drmCommandWriteRead(dev->fd, DRM_AMDGPU_VM,
+ &vm, sizeof(vm));
+}
diff --git a/amdgpu/meson.build b/amdgpu/meson.build
new file mode 100644
index 0000000..f39d7bf
--- /dev/null
+++ b/amdgpu/meson.build
@@ -0,0 +1,66 @@
+# 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', 'util_hash.c',
+ 'util_hash_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/amdgpu/util_hash.c b/amdgpu/util_hash.c
index 87cb671..7e59041 100644
--- a/amdgpu/util_hash.c
+++ b/amdgpu/util_hash.c
@@ -30,10 +30,6 @@
* Zack Rusin <zackr@vmware.com>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "util_hash.h"
#include <stdlib.h>
diff --git a/amdgpu/util_hash.h b/amdgpu/util_hash.h
index 01a4779..6eed156 100644
--- a/amdgpu/util_hash.h
+++ b/amdgpu/util_hash.h
@@ -44,10 +44,6 @@
#ifndef UTIL_HASH_H
#define UTIL_HASH_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdbool.h>
#include "libdrm_macros.h"
diff --git a/amdgpu/util_hash_table.c b/amdgpu/util_hash_table.c
index fa7f6ea..89a8bf9 100644
--- a/amdgpu/util_hash_table.c
+++ b/amdgpu/util_hash_table.c
@@ -38,10 +38,6 @@
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "util_hash_table.h"
#include "util_hash.h"
diff --git a/amdgpu/util_hash_table.h b/amdgpu/util_hash_table.h
index e000128..5e295a8 100644
--- a/amdgpu/util_hash_table.h
+++ b/amdgpu/util_hash_table.h
@@ -34,10 +34,6 @@
#ifndef U_HASH_TABLE_H_
#define U_HASH_TABLE_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "libdrm_macros.h"
/**
diff --git a/android/gralloc_handle.h b/android/gralloc_handle.h
new file mode 100644
index 0000000..bcf753d
--- /dev/null
+++ b/android/gralloc_handle.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright (C) 2010-2011 LunarG Inc.
+ * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
+ * Copyright (C) 2018 Collabora, Robert Foss <robert.foss@collabora.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 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 __ANDROID_GRALLOC_HANDLE_H__
+#define __ANDROID_GRALLOC_HANDLE_H__
+
+#include <cutils/native_handle.h>
+#include <stdint.h>
+
+/* support users of drm_gralloc/gbm_gralloc */
+#define gralloc_gbm_handle_t gralloc_handle_t
+#define gralloc_drm_handle_t gralloc_handle_t
+
+struct gralloc_handle_t {
+ native_handle_t base;
+
+ /* dma-buf file descriptor
+ * Must be located first since, native_handle_t is allocated
+ * using native_handle_create(), which allocates space for
+ * sizeof(native_handle_t) + sizeof(int) * (numFds + numInts)
+ * numFds = GRALLOC_HANDLE_NUM_FDS
+ * numInts = GRALLOC_HANDLE_NUM_INTS
+ * Where numFds represents the number of FDs and
+ * numInts represents the space needed for the
+ * remainder of this struct.
+ * And the FDs are expected to be found first following
+ * native_handle_t.
+ */
+ int prime_fd;
+
+ /* api variables */
+ uint32_t magic; /* differentiate between allocator impls */
+ uint32_t version; /* api version */
+
+ uint32_t width; /* width of buffer in pixels */
+ uint32_t height; /* height of buffer in pixels */
+ uint32_t format; /* pixel format (Android) */
+ uint32_t usage; /* android libhardware usage flags */
+
+ uint32_t stride; /* the stride in bytes */
+ uint64_t modifier; /* buffer modifiers */
+
+ int data_owner; /* owner of data (for validation) */
+ union {
+ void *data; /* pointer to struct gralloc_gbm_bo_t */
+ uint64_t reserved;
+ } __attribute__((aligned(8)));
+};
+
+#define GRALLOC_HANDLE_VERSION 3
+#define GRALLOC_HANDLE_MAGIC 0x60585350
+#define GRALLOC_HANDLE_NUM_FDS 1
+#define GRALLOC_HANDLE_NUM_INTS ( \
+ ((sizeof(struct gralloc_handle_t) - sizeof(native_handle_t))/sizeof(int)) \
+ - GRALLOC_HANDLE_NUM_FDS)
+
+static inline struct gralloc_handle_t *gralloc_handle(buffer_handle_t handle)
+{
+ return (struct gralloc_handle_t *)handle;
+}
+
+/**
+ * Create a buffer handle.
+ */
+static inline native_handle_t *gralloc_handle_create(int32_t width,
+ int32_t height,
+ int32_t hal_format,
+ int32_t usage)
+{
+ struct gralloc_handle_t *handle;
+ native_handle_t *nhandle = native_handle_create(GRALLOC_HANDLE_NUM_FDS,
+ GRALLOC_HANDLE_NUM_INTS);
+
+ if (!nhandle)
+ return NULL;
+
+ handle = gralloc_handle(nhandle);
+ handle->magic = GRALLOC_HANDLE_MAGIC;
+ handle->version = GRALLOC_HANDLE_VERSION;
+ handle->width = width;
+ handle->height = height;
+ handle->format = hal_format;
+ handle->usage = usage;
+ handle->prime_fd = -1;
+
+ return nhandle;
+}
+
+#endif
diff --git a/autogen.sh b/autogen.sh
index d82ab18..13d6991 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -6,15 +6,15 @@
ORIGDIR=`pwd`
cd "$srcdir"
-autoreconf --force --verbose --install || exit 1
-cd "$ORIGDIR" || exit $?
-
-git config --local --get format.subjectPrefix ||
+git config --local --get format.subjectPrefix >/dev/null ||
git config --local format.subjectPrefix "PATCH libdrm" 2>/dev/null
-git config --local --get sendemail.to ||
+git config --local --get sendemail.to >/dev/null ||
git config --local sendemail.to "dri-devel@lists.freedesktop.org" 2>/dev/null
+autoreconf --force --verbose --install || exit 1
+cd "$ORIGDIR" || exit $?
+
if test -z "$NOCONFIGURE"; then
"$srcdir"/configure "$@"
fi
diff --git a/configure.ac b/configure.ac
index 1da9d86..98a350c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
AC_PREREQ([2.63])
AC_INIT([libdrm],
- [2.4.75],
+ [2.4.91],
[https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
[libdrm])
@@ -28,6 +28,7 @@
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
+PKG_PROG_PKG_CONFIG
# Require xorg-macros minimum of 1.12 for XORG_WITH_XSLTPROC
m4_ifndef([XORG_MACROS_VERSION],
@@ -44,6 +45,7 @@
# Check for programs
AC_PROG_CC
AC_PROG_CC_C99
+AC_PROG_NM
if test "x$ac_cv_prog_cc_c99" = xno; then
AC_MSG_ERROR([Building libdrm requires C99 enabled compiler])
@@ -53,20 +55,39 @@
AC_SYS_LARGEFILE
AC_FUNC_ALLOCA
+save_CFLAGS="$CFLAGS"
+export CFLAGS="$CFLAGS -Werror"
AC_HEADER_MAJOR
+CFLAGS="$save_CFLAGS"
+
AC_CHECK_HEADERS([sys/sysctl.h sys/select.h])
# Initialize libtool
LT_PREREQ([2.2])
LT_INIT([disable-static])
+dnl pthread-stubs is mandatory on some BSD platforms, due to the nature of the
+dnl project. Even then there's a notable issue as described in the project README
+case "$host_os" in
+linux* | cygwin* | darwin* | solaris* | *-gnu* | gnu* | openbsd*)
+ pthread_stubs_possible="no"
+ ;;
+* )
+ pthread_stubs_possible="yes"
+ ;;
+esac
-
-AC_SUBST(PTHREADSTUBS_CFLAGS)
-AC_SUBST(PTHREADSTUBS_LIBS)
+if test "x$pthread_stubs_possible" = xyes; then
+ PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs >= 0.4)
+ AC_SUBST(PTHREADSTUBS_CFLAGS)
+ AC_SUBST(PTHREADSTUBS_LIBS)
+fi
pkgconfigdir=${libdir}/pkgconfig
AC_SUBST(pkgconfigdir)
+libdrmdatadir=${datadir}/libdrm
+AC_SUBST(libdrmdatadir)
+
AC_ARG_ENABLE([udev],
[AS_HELP_STRING([--enable-udev],
[Enable support for using udev instead of mknod (default: disabled)])],
@@ -173,7 +194,9 @@
[AC_MSG_ERROR([Couldn't find clock_gettime])])])
AC_SUBST([CLOCK_LIB])
-AC_CHECK_FUNCS([open_memstream], [HAVE_OPEN_MEMSTREAM=yes])
+AC_CHECK_FUNCS([open_memstream],
+ [AC_DEFINE([HAVE_OPEN_MEMSTREAM], 1, [Have open_memstream()])],
+ [AC_DEFINE([HAVE_OPEN_MEMSTREAM], 0)])
dnl Use lots of warning flags with with gcc and compatible compilers
@@ -182,7 +205,7 @@
dnl else. If for any reason you need to force a recheck, just change
dnl MAYBE_WARN in an ignorable way (like adding whitespace)
-MAYBE_WARN="-Wall -Wextra \
+MAYBE_WARN="-Wall -Wextra -Werror=undef \
-Wsign-compare -Werror-implicit-function-declaration \
-Wpointer-arith -Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wmissing-declarations -Wnested-externs \
@@ -244,9 +267,13 @@
if test "x$drm_cv_atomic_primitives" = xIntel; then
AC_DEFINE(HAVE_LIBDRM_ATOMIC_PRIMITIVES, 1,
[Enable if your compiler supports the Intel __sync_* atomic primitives])
+else
+ AC_DEFINE(HAVE_LIBDRM_ATOMIC_PRIMITIVES, 0)
fi
if test "x$drm_cv_atomic_primitives" = "xlibatomic-ops"; then
AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 1, [Enable if you have libatomic-ops-dev installed])
+else
+ AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 0)
fi
dnl Print out the approapriate message considering the value set be the
@@ -325,6 +352,8 @@
if test "x$UDEV" = xyes; then
AC_DEFINE(UDEV, 1, [Have UDEV support])
+else
+ AC_DEFINE(UDEV, 0)
fi
AC_CANONICAL_HOST
@@ -343,32 +372,34 @@
AM_CONDITIONAL(HAVE_INTEL, [test "x$INTEL" = xyes])
if test "x$INTEL" = xyes; then
AC_DEFINE(HAVE_INTEL, 1, [Have intel support])
+else
+ AC_DEFINE(HAVE_INTEL, 0)
fi
AM_CONDITIONAL(HAVE_VMWGFX, [test "x$VMWGFX" = xyes])
if test "x$VMWGFX" = xyes; then
AC_DEFINE(HAVE_VMWGFX, 1, [Have vmwgfx kernel headers])
+else
+ AC_DEFINE(HAVE_VMWGFX, 0)
fi
AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" = xyes])
if test "x$NOUVEAU" = xyes; then
AC_DEFINE(HAVE_NOUVEAU, 1, [Have nouveau (nvidia) support])
+else
+ AC_DEFINE(HAVE_NOUVEAU, 0)
fi
AM_CONDITIONAL(HAVE_OMAP, [test "x$OMAP" = xyes])
-if test "x$OMAP" = xyes; then
- AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support])
-fi
AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes])
if test "x$EXYNOS" = xyes; then
AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+else
+ AC_DEFINE(HAVE_EXYNOS, 0)
fi
AM_CONDITIONAL(HAVE_FREEDRENO, [test "x$FREEDRENO" = xyes])
-if test "x$FREEDRENO" = xyes; then
- AC_DEFINE(HAVE_FREEDRENO, 1, [Have freedreno support])
-fi
if test "x$FREEDRENO_KGSL" = xyes; then
if test "x$FREEDRENO" != xyes; then
@@ -378,11 +409,15 @@
AM_CONDITIONAL(HAVE_FREEDRENO_KGSL, [test "x$FREEDRENO_KGSL" = xyes])
if test "x$FREEDRENO_KGSL" = xyes; then
AC_DEFINE(HAVE_FREEDRENO_KGSL, 1, [Have freedreno support for KGSL kernel interface])
+else
+ AC_DEFINE(HAVE_FREEDRENO_KGSL, 0)
fi
AM_CONDITIONAL(HAVE_RADEON, [test "x$RADEON" = xyes])
if test "x$RADEON" = xyes; then
AC_DEFINE(HAVE_RADEON, 1, [Have radeon support])
+else
+ AC_DEFINE(HAVE_RADEON, 0)
fi
if test "x$AMDGPU" != xno; then
@@ -409,36 +444,30 @@
if test "x$AMDGPU" = xyes; then
AC_DEFINE(HAVE_AMDGPU, 1, [Have amdgpu support])
- AC_DEFINE(HAVE_CUNIT, [test "x$have_cunit" != "xno"], [Enable CUNIT Have amdgpu support])
-
if test "x$have_cunit" = "xno"; then
AC_MSG_WARN([Could not find cunit library. Disabling amdgpu tests])
fi
+else
+ AC_DEFINE(HAVE_AMDGPU, 0)
fi
AM_CONDITIONAL(HAVE_TEGRA, [test "x$TEGRA" = xyes])
-if test "x$TEGRA" = xyes; then
- AC_DEFINE(HAVE_TEGRA, 1, [Have Tegra support])
-fi
AM_CONDITIONAL(HAVE_ROCKCHIP, [test "x$ROCKCHIP" = xyes])
if test "x$ROCKCHIP" = xyes; then
AC_DEFINE(HAVE_ROCKCHIP, 1, [Have ROCKCHIP support])
+fi
AM_CONDITIONAL(HAVE_VC4, [test "x$VC4" = xyes])
if test "x$VC4" = xyes; then
AC_DEFINE(HAVE_VC4, 1, [Have VC4 support])
+else
+ AC_DEFINE(HAVE_VC4, 0)
fi
AM_CONDITIONAL(HAVE_ETNAVIV, [test "x$ETNAVIV" = xyes])
-if test "x$ETNAVIV" = xyes; then
- AC_DEFINE(HAVE_ETNAVIV, 1, [Have etnaviv support])
-fi
AM_CONDITIONAL(HAVE_INSTALL_TESTS, [test "x$INSTALL_TESTS" = xyes])
-if test "x$INSTALL_TESTS" = xyes; then
- AC_DEFINE(HAVE_INSTALL_TESTS, 1, [Install test programs])
-fi
AC_ARG_ENABLE([cairo-tests],
[AS_HELP_STRING([--enable-cairo-tests],
@@ -456,6 +485,8 @@
AC_MSG_ERROR([Cairo support required but not present])
fi
AC_DEFINE(HAVE_CAIRO, 1, [Have Cairo support])
+else
+ AC_DEFINE(HAVE_CAIRO, 0)
fi
AC_MSG_RESULT([$CAIRO])
AM_CONDITIONAL(HAVE_CAIRO, [test "x$CAIRO" = xyes])
@@ -497,6 +528,8 @@
AC_MSG_ERROR([Valgrind support required but not present])
fi
AC_DEFINE([HAVE_VALGRIND], 1, [Use valgrind intrinsics to suppress false warnings])
+else
+ AC_DEFINE([HAVE_VALGRIND], 0)
fi
AC_MSG_RESULT([$VALGRIND])
@@ -514,11 +547,16 @@
if test "x$HAVE_ATTRIBUTE_VISIBILITY" = xyes; then
AC_DEFINE(HAVE_VISIBILITY, 1, [Compiler supports __attribute__(("hidden"))])
+else
+ AC_DEFINE(HAVE_VISIBILITY, 0)
fi
+CFLAGS="$CFLAGS -include config.h"
+
AC_SUBST(WARN_CFLAGS)
AC_CONFIG_FILES([
Makefile
+ data/Makefile
libkms/Makefile
libkms/libkms.pc
intel/Makefile
diff --git a/data/Android.mk b/data/Android.mk
new file mode 100644
index 0000000..62013f0
--- /dev/null
+++ b/data/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := amdgpu.ids
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hwdata
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 0000000..897a7f3
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,25 @@
+# Copyright © 2017 Advanced Micro Devices, Inc.
+# All Rights Reserved.
+#
+# 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
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON 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.
+
+libdrmdatadir = @libdrmdatadir@
+if HAVE_AMDGPU
+dist_libdrmdata_DATA = amdgpu.ids
+endif
diff --git a/data/amdgpu.ids b/data/amdgpu.ids
new file mode 100644
index 0000000..1828e41
--- /dev/null
+++ b/data/amdgpu.ids
@@ -0,0 +1,187 @@
+# List of AMDGPU IDs
+#
+# Syntax:
+# device_id, revision_id, product_name <-- single tab after comma
+
+1.0.0
+6600, 0, AMD Radeon HD 8600/8700M
+6600, 81, AMD Radeon (TM) R7 M370
+6601, 0, AMD Radeon (TM) HD 8500M/8700M
+6604, 0, AMD Radeon R7 M265 Series
+6604, 81, AMD Radeon (TM) R7 M350
+6605, 0, AMD Radeon R7 M260 Series
+6605, 81, AMD Radeon (TM) R7 M340
+6606, 0, AMD Radeon HD 8790M
+6607, 0, AMD Radeon (TM) HD8530M
+6608, 0, AMD FirePro W2100
+6610, 0, AMD Radeon HD 8600 Series
+6610, 81, AMD Radeon (TM) R7 350
+6610, 83, AMD Radeon (TM) R5 340
+6611, 0, AMD Radeon HD 8500 Series
+6613, 0, AMD Radeon HD 8500 series
+6617, C7, AMD Radeon R7 240 Series
+6640, 0, AMD Radeon HD 8950
+6640, 80, AMD Radeon (TM) R9 M380
+6646, 0, AMD Radeon R9 M280X
+6646, 80, AMD Radeon (TM) R9 M470X
+6647, 0, AMD Radeon R9 M270X
+6647, 80, AMD Radeon (TM) R9 M380
+6649, 0, AMD FirePro W5100
+6658, 0, AMD Radeon R7 200 Series
+665C, 0, AMD Radeon HD 7700 Series
+665D, 0, AMD Radeon R7 200 Series
+665F, 81, AMD Radeon (TM) R7 300 Series
+6660, 0, AMD Radeon HD 8600M Series
+6660, 81, AMD Radeon (TM) R5 M335
+6660, 83, AMD Radeon (TM) R5 M330
+6663, 0, AMD Radeon HD 8500M Series
+6663, 83, AMD Radeon (TM) R5 M320
+6664, 0, AMD Radeon R5 M200 Series
+6665, 0, AMD Radeon R5 M200 Series
+6665, 83, AMD Radeon (TM) R5 M320
+6667, 0, AMD Radeon R5 M200 Series
+666F, 0, AMD Radeon HD 8500M
+6780, 0, ATI FirePro V (FireGL V) Graphics Adapter
+678A, 0, ATI FirePro V (FireGL V) Graphics Adapter
+6798, 0, AMD Radeon HD 7900 Series
+679A, 0, AMD Radeon HD 7900 Series
+679B, 0, AMD Radeon HD 7900 Series
+679E, 0, AMD Radeon HD 7800 Series
+67A0, 0, AMD Radeon FirePro W9100
+67A1, 0, AMD Radeon FirePro W8100
+67B0, 0, AMD Radeon R9 200 Series
+67B0, 80, AMD Radeon (TM) R9 390 Series
+67B1, 0, AMD Radeon R9 200 Series
+67B1, 80, AMD Radeon (TM) R9 390 Series
+67B9, 0, AMD Radeon R9 200 Series
+67DF, C1, Radeon RX 580 Series
+67DF, C2, Radeon RX 570 Series
+67DF, C3, Radeon RX 580 Series
+67DF, C4, AMD Radeon (TM) RX 480 Graphics
+67DF, C5, AMD Radeon (TM) RX 470 Graphics
+67DF, C6, Radeon RX 570 Series
+67DF, C7, AMD Radeon (TM) RX 480 Graphics
+67DF, CF, AMD Radeon (TM) RX 470 Graphics
+67DF, D7, Radeon(TM) RX 470 Graphics
+67DF, E3, Radeon RX Series
+67DF, E7, Radeon RX 580 Series
+67DF, EF, Radeon RX 570 Series
+67C2, 01, AMD Radeon (TM) Pro V7350x2
+67C2, 02, AMD Radeon (TM) Pro V7300X
+67C4, 00, AMD Radeon (TM) Pro WX 7100 Graphics
+67C7, 00, AMD Radeon (TM) Pro WX 5100 Graphics
+67C0, 00, AMD Radeon (TM) Pro WX 7100 Graphics
+67D0, 01, AMD Radeon (TM) Pro V7350x2
+67D0, 02, AMD Radeon (TM) Pro V7300X
+67E0, 00, AMD Radeon (TM) Pro WX Series
+67E3, 00, AMD Radeon (TM) Pro WX 4100
+67E8, 00, AMD Radeon (TM) Pro WX Series
+67E8, 01, AMD Radeon (TM) Pro WX Series
+67E8, 80, AMD Radeon (TM) E9260 Graphics
+67EB, 00, AMD Radeon (TM) Pro V5300X
+67EF, C0, AMD Radeon (TM) RX Graphics
+67EF, C1, AMD Radeon (TM) RX 460 Graphics
+67EF, C3, Radeon RX Series
+67EF, C5, AMD Radeon (TM) RX 460 Graphics
+67EF, C7, AMD Radeon (TM) RX Graphics
+67EF, CF, AMD Radeon (TM) RX 460 Graphics
+67EF, E0, Radeon RX 560 Series
+67EF, E1, Radeon RX Series
+67EF, E3, Radeon RX Series
+67EF, E5, Radeon RX 560 Series
+67EF, EF, AMD Radeon (TM) RX Graphics
+67EF, FF, Radeon(TM) RX 460 Graphics
+67FF, C0, AMD Radeon (TM) RX Graphics
+67FF, C1, AMD Radeon (TM) RX Graphics
+67FF, CF, Radeon RX 560 Series
+67FF, EF, Radeon RX 560 Series
+67FF, FF, Radeon RX 550 Series
+6800, 0, AMD Radeon HD 7970M
+6801, 0, AMD Radeon(TM) HD8970M
+6808, 0, ATI FirePro V(FireGL V) Graphics Adapter
+6809, 0, ATI FirePro V(FireGL V) Graphics Adapter
+6810, 0, AMD Radeon(TM) HD 8800 Series
+6810, 81, AMD Radeon (TM) R7 370 Series
+6811, 0, AMD Radeon(TM) HD8800 Series
+6811, 81, AMD Radeon (TM) R7 300 Series
+6818, 0, AMD Radeon HD 7800 Series
+6819, 0, AMD Radeon HD 7800 Series
+6820, 0, AMD Radeon HD 8800M Series
+6820, 81, AMD Radeon (TM) R9 M375
+6820, 83, AMD Radeon (TM) R9 M375X
+6821, 0, AMD Radeon HD 8800M Series
+6821, 87, AMD Radeon (TM) R7 M380
+6821, 83, AMD Radeon R9 (TM) M370X
+6822, 0, AMD Radeon E8860
+6823, 0, AMD Radeon HD 8800M Series
+6825, 0, AMD Radeon HD 7800M Series
+6827, 0, AMD Radeon HD 7800M Series
+6828, 0, ATI FirePro V(FireGL V) Graphics Adapter
+682B, 0, AMD Radeon HD 8800M Series
+682B, 87, AMD Radeon (TM) R9 M360
+682C, 0, AMD FirePro W4100
+682D, 0, AMD Radeon HD 7700M Series
+682F, 0, AMD Radeon HD 7700M Series
+6835, 0, AMD Radeon R7 Series / HD 9000 Series
+6837, 0, AMD Radeon HD7700 Series
+683D, 0, AMD Radeon HD 7700 Series
+683F, 0, AMD Radeon HD 7700 Series
+6860, 00, Radeon Instinct MI25
+6860, 01, Radeon Pro V320
+6860, 02, Radeon Instinct MI25
+6860, 03, Radeon Pro V340
+6860, 04, Radeon Instinct MI25x2
+6861, 00, Radeon(TM) Pro WX9100
+6862, 00, Radeon Pro SSG
+6863, 00, Radeon Vega Frontier Edition
+6864, 03, Radeon Pro V340
+6864, 04, Instinct MI25x2
+6868, 00, Radeon(TM) Pro WX8100
+686C, 00, GLXT (Radeon Instinct MI25) MxGPU VFID
+686C, 01, GLXT (Radeon Pro V320) MxGPU
+686C, 02, GLXT (Radeon Instinct MI25) MxGPU
+686C, 03, GLXT (Radeon Pro V340) MxGPU
+686C, 04, GLXT (Radeon Instinct MI25x2) MxGPU
+687F, C0, Radeon RX Vega
+687F, C1, Radeon RX Vega
+687F, C3, Radeon RX Vega
+6900, 0, AMD Radeon R7 M260
+6900, 81, AMD Radeon (TM) R7 M360
+6900, 83, AMD Radeon (TM) R7 M340
+6901, 0, AMD Radeon R5 M255
+6907, 0, AMD Radeon R5 M255
+6907, 87, AMD Radeon (TM) R5 M315
+6920, 0, AMD RADEON R9 M395X
+6920, 1, AMD RADEON R9 M390X
+6921, 0, AMD Radeon R9 M295X
+6929, 0, AMD FirePro S7150
+692B, 0, AMD FirePro W7100
+6938, 0, AMD Radeon R9 200 Series
+6938, F0, AMD Radeon R9 200 Series
+6938, F1, AMD Radeon (TM) R9 380 Series
+6939, F0, AMD Radeon R9 200 Series
+6939, 0, AMD Radeon R9 200 Series
+6939, F1, AMD Radeon (TM) R9 380 Series
+6980, 00, Radeon Pro WX3100
+6985, 00, AMD Radeon Pro WX3100
+6987, 80, AMD Embedded Radeon E9171
+6995, 00, AMD Radeon Pro WX2100
+6997, 00, Radeon Pro WX2100
+699F, 81, AMD Embedded Radeon E9170 Series
+699F, C0, Radeon 500 Series
+699F, C3, Radeon 500 Series
+699F, C7, Radeon RX 550 Series
+7300, C1, AMD FirePro (TM) S9300 x2
+7300, C8, AMD Radeon (TM) R9 Fury Series
+7300, C9, Radeon (TM) Pro Duo
+7300, CB, AMD Radeon (TM) R9 Fury Series
+7300, CA, AMD Radeon (TM) R9 Fury Series
+9874, C4, AMD Radeon R7 Graphics
+9874, C5, AMD Radeon R6 Graphics
+9874, C6, AMD Radeon R6 Graphics
+9874, C7, AMD Radeon R5 Graphics
+9874, C8, AMD Radeon R7 Graphics
+9874, 81, AMD Radeon R6 Graphics
+9874, 87, AMD Radeon R5 Graphics
+9874, 85, AMD Radeon R6 Graphics
+9874, 84, AMD Radeon R7 Graphics
diff --git a/data/meson.build b/data/meson.build
new file mode 100644
index 0000000..9c26b66
--- /dev/null
+++ b/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/etnaviv/Makefile.sources b/etnaviv/Makefile.sources
index 5258056..0eb7378 100644
--- a/etnaviv/Makefile.sources
+++ b/etnaviv/Makefile.sources
@@ -3,6 +3,7 @@
etnaviv_gpu.c \
etnaviv_bo.c \
etnaviv_bo_cache.c \
+ etnaviv_perfmon.c \
etnaviv_pipe.c \
etnaviv_cmd_stream.c \
etnaviv_drm.h \
diff --git a/etnaviv/etnaviv-symbol-check b/etnaviv/etnaviv-symbol-check
index 22afd16..bc50961 100755
--- a/etnaviv/etnaviv-symbol-check
+++ b/etnaviv/etnaviv-symbol-check
@@ -39,8 +39,14 @@
etna_cmd_stream_del
etna_cmd_stream_timestamp
etna_cmd_stream_flush
+etna_cmd_stream_flush2
etna_cmd_stream_finish
+etna_cmd_stream_perf
etna_cmd_stream_reloc
+etna_perfmon_create
+etna_perfmon_del
+etna_perfmon_get_dom_by_name
+etna_perfmon_get_sig_by_name
EOF
done)
diff --git a/etnaviv/etnaviv_bo.c b/etnaviv/etnaviv_bo.c
index 4ad0434..32f7b34 100644
--- a/etnaviv/etnaviv_bo.c
+++ b/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"
@@ -173,7 +169,7 @@
pthread_mutex_lock(&table_lock);
/* check name table first, to see if bo is already open: */
- bo = lookup_bo(dev->name_table, req.handle);
+ bo = lookup_bo(dev->name_table, name);
if (bo)
goto out_unlock;
@@ -206,10 +202,15 @@
int ret, size;
uint32_t handle;
+ /* take the lock before calling drmPrimeFDToHandle to avoid
+ * racing against etna_bo_del, which might invalidate the
+ * returned handle.
+ */
pthread_mutex_lock(&table_lock);
ret = drmPrimeFDToHandle(dev->fd, fd, &handle);
if (ret) {
+ pthread_mutex_unlock(&table_lock);
return NULL;
}
diff --git a/etnaviv/etnaviv_bo_cache.c b/etnaviv/etnaviv_bo_cache.c
index 8924651..c81de26 100644
--- a/etnaviv/etnaviv_bo_cache.c
+++ b/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"
@@ -124,20 +120,32 @@
static struct etna_bo *find_in_bucket(struct etna_bo_bucket *bucket, uint32_t flags)
{
- struct etna_bo *bo = NULL;
+ struct etna_bo *bo = NULL, *tmp;
pthread_mutex_lock(&table_lock);
- while (!LIST_IS_EMPTY(&bucket->list)) {
- bo = LIST_ENTRY(struct etna_bo, bucket->list.next, list);
- if (bo->flags == flags && is_idle(bo)) {
- list_del(&bo->list);
- break;
+ if (LIST_IS_EMPTY(&bucket->list))
+ goto out_unlock;
+
+ LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bucket->list, list) {
+ /* skip BOs with different flags */
+ if (bo->flags != flags)
+ continue;
+
+ /* check if the first BO with matching flags is idle */
+ if (is_idle(bo)) {
+ list_delinit(&bo->list);
+ goto out_unlock;
}
- bo = NULL;
+ /* If the oldest BO is still busy, don't try younger ones */
break;
}
+
+ /* There was no matching buffer found */
+ bo = NULL;
+
+out_unlock:
pthread_mutex_unlock(&table_lock);
return bo;
diff --git a/etnaviv/etnaviv_cmd_stream.c b/etnaviv/etnaviv_cmd_stream.c
index 9ce3f36..1373016 100644
--- a/etnaviv/etnaviv_cmd_stream.c
+++ b/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"
@@ -105,6 +101,7 @@
free(stream->buffer);
free(priv->submit.relocs);
+ free(priv->submit.pmrs);
free(priv);
}
@@ -115,6 +112,7 @@
stream->offset = 0;
priv->submit.nr_bos = 0;
priv->submit.nr_relocs = 0;
+ priv->submit.nr_pmrs = 0;
priv->nr_bos = 0;
if (priv->reset_notify)
@@ -177,7 +175,8 @@
return idx;
}
-static void flush(struct etna_cmd_stream *stream)
+static void flush(struct etna_cmd_stream *stream, int in_fence_fd,
+ int *out_fence_fd)
{
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
int ret, id = priv->pipe->id;
@@ -190,10 +189,20 @@
.nr_bos = priv->submit.nr_bos,
.relocs = VOID2U64(priv->submit.relocs),
.nr_relocs = priv->submit.nr_relocs,
+ .pmrs = VOID2U64(priv->submit.pmrs),
+ .nr_pmrs = priv->submit.nr_pmrs,
.stream = VOID2U64(stream->buffer),
.stream_size = stream->offset * 4, /* in bytes */
};
+ if (in_fence_fd != -1) {
+ req.flags |= ETNA_SUBMIT_FENCE_FD_IN | ETNA_SUBMIT_NO_IMPLICIT;
+ req.fence_fd = in_fence_fd;
+ }
+
+ if (out_fence_fd)
+ req.flags |= ETNA_SUBMIT_FENCE_FD_OUT;
+
ret = drmCommandWriteRead(gpu->dev->fd, DRM_ETNAVIV_GEM_SUBMIT,
&req, sizeof(req));
@@ -208,11 +217,21 @@
bo->current_stream = NULL;
etna_bo_del(bo);
}
+
+ if (out_fence_fd)
+ *out_fence_fd = req.fence_fd;
}
void etna_cmd_stream_flush(struct etna_cmd_stream *stream)
{
- flush(stream);
+ flush(stream, -1, NULL);
+ reset_buffer(stream);
+}
+
+void etna_cmd_stream_flush2(struct etna_cmd_stream *stream, int in_fence_fd,
+ int *out_fence_fd)
+{
+ flush(stream, in_fence_fd, out_fence_fd);
reset_buffer(stream);
}
@@ -220,7 +239,7 @@
{
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
- flush(stream);
+ flush(stream, -1, NULL);
etna_pipe_wait(priv->pipe, priv->last_timestamp, 5000);
reset_buffer(stream);
}
@@ -241,3 +260,19 @@
etna_cmd_stream_emit(stream, addr);
}
+
+void etna_cmd_stream_perf(struct etna_cmd_stream *stream, const struct etna_perf *p)
+{
+ struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
+ struct drm_etnaviv_gem_submit_pmr *pmr;
+ uint32_t idx = APPEND(&priv->submit, pmrs);
+
+ pmr = &priv->submit.pmrs[idx];
+
+ pmr->flags = p->flags;
+ pmr->sequence = p->sequence;
+ pmr->read_offset = p->offset;
+ pmr->read_idx = bo2idx(stream, p->bo, ETNA_SUBMIT_BO_READ | ETNA_SUBMIT_BO_WRITE);
+ pmr->domain = p->signal->domain->id;
+ pmr->signal = p->signal->signal;
+}
diff --git a/etnaviv/etnaviv_device.c b/etnaviv/etnaviv_device.c
index 3ce9203..d83e8d3 100644
--- a/etnaviv/etnaviv_device.c
+++ b/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/etnaviv/etnaviv_drm.h b/etnaviv/etnaviv_drm.h
index 2584c1c..0d5c49d 100644
--- a/etnaviv/etnaviv_drm.h
+++ b/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 @@
#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
@@ -150,10 +157,29 @@
__u64 presumed; /* in/out, presumed buffer address */
};
+/* performance monitor request (pmr) */
+#define ETNA_PM_PROCESS_PRE 0x0001
+#define ETNA_PM_PROCESS_POST 0x0002
+struct drm_etnaviv_gem_submit_pmr {
+ __u32 flags; /* in, when to process request (ETNA_PM_PROCESS_x) */
+ __u8 domain; /* in, pm domain */
+ __u8 pad;
+ __u16 signal; /* in, pm signal */
+ __u32 sequence; /* in, sequence number */
+ __u32 read_offset; /* in, offset from read_bo */
+ __u32 read_idx; /* in, index of read_bo buffer */
+};
+
/* 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.
*/
+#define ETNA_SUBMIT_NO_IMPLICIT 0x0001
+#define ETNA_SUBMIT_FENCE_FD_IN 0x0002
+#define ETNA_SUBMIT_FENCE_FD_OUT 0x0004
+#define ETNA_SUBMIT_FLAGS (ETNA_SUBMIT_NO_IMPLICIT | \
+ ETNA_SUBMIT_FENCE_FD_IN | \
+ ETNA_SUBMIT_FENCE_FD_OUT)
#define ETNA_PIPE_3D 0x00
#define ETNA_PIPE_2D 0x01
#define ETNA_PIPE_VG 0x02
@@ -167,6 +193,11 @@
__u64 bos; /* in, ptr to array of submit_bo's */
__u64 relocs; /* in, ptr to array of submit_reloc's */
__u64 stream; /* in, ptr to cmdstream */
+ __u32 flags; /* in, mask of ETNA_SUBMIT_x */
+ __s32 fence_fd; /* in/out, fence fd (see ETNA_SUBMIT_FENCE_FD_x) */
+ __u64 pmrs; /* in, ptr to array of submit_pmr's */
+ __u32 nr_pmrs; /* in, number of submit_pmr's */
+ __u32 pad;
};
/* The normal way to synchronize with the GPU is just to CPU_PREP on
@@ -202,6 +233,27 @@
struct drm_etnaviv_timespec timeout; /* in */
};
+/*
+ * Performance Monitor (PM):
+ */
+
+struct drm_etnaviv_pm_domain {
+ __u32 pipe; /* in */
+ __u8 iter; /* in/out, select pm domain at index iter */
+ __u8 id; /* out, id of domain */
+ __u16 nr_signals; /* out, how many signals does this domain provide */
+ char name[64]; /* out, name of domain */
+};
+
+struct drm_etnaviv_pm_signal {
+ __u32 pipe; /* in */
+ __u8 domain; /* in, pm domain index */
+ __u8 pad;
+ __u16 iter; /* in/out, select pm source at index iter */
+ __u16 id; /* out, id of signal */
+ char name[64]; /* out, name of domain */
+};
+
#define DRM_ETNAVIV_GET_PARAM 0x00
/* placeholder:
#define DRM_ETNAVIV_SET_PARAM 0x01
@@ -214,7 +266,9 @@
#define DRM_ETNAVIV_WAIT_FENCE 0x07
#define DRM_ETNAVIV_GEM_USERPTR 0x08
#define DRM_ETNAVIV_GEM_WAIT 0x09
-#define DRM_ETNAVIV_NUM_IOCTLS 0x0a
+#define DRM_ETNAVIV_PM_QUERY_DOM 0x0a
+#define DRM_ETNAVIV_PM_QUERY_SIG 0x0b
+#define DRM_ETNAVIV_NUM_IOCTLS 0x0c
#define DRM_IOCTL_ETNAVIV_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GET_PARAM, struct drm_etnaviv_param)
#define DRM_IOCTL_ETNAVIV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_NEW, struct drm_etnaviv_gem_new)
@@ -225,6 +279,8 @@
#define DRM_IOCTL_ETNAVIV_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_WAIT_FENCE, struct drm_etnaviv_wait_fence)
#define DRM_IOCTL_ETNAVIV_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_USERPTR, struct drm_etnaviv_gem_userptr)
#define DRM_IOCTL_ETNAVIV_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_WAIT, struct drm_etnaviv_gem_wait)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_DOM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_DOM, struct drm_etnaviv_pm_domain)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_SIG DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_SIG, struct drm_etnaviv_pm_signal)
#if defined(__cplusplus)
}
diff --git a/etnaviv/etnaviv_drmif.h b/etnaviv/etnaviv_drmif.h
index 8119baa..5a6bef8 100644
--- a/etnaviv/etnaviv_drmif.h
+++ b/etnaviv/etnaviv_drmif.h
@@ -35,6 +35,9 @@
struct etna_gpu;
struct etna_device;
struct etna_cmd_stream;
+struct etna_perfmon;
+struct etna_perfmon_domain;
+struct etna_perfmon_signal;
enum etna_pipe_id {
ETNA_PIPE_3D = 0,
@@ -142,6 +145,8 @@
void etna_cmd_stream_del(struct etna_cmd_stream *stream);
uint32_t etna_cmd_stream_timestamp(struct etna_cmd_stream *stream);
void etna_cmd_stream_flush(struct etna_cmd_stream *stream);
+void etna_cmd_stream_flush2(struct etna_cmd_stream *stream, int in_fence_fd,
+ int *out_fence_fd);
void etna_cmd_stream_finish(struct etna_cmd_stream *stream);
static inline uint32_t etna_cmd_stream_avail(struct etna_cmd_stream *stream)
@@ -188,4 +193,24 @@
void etna_cmd_stream_reloc(struct etna_cmd_stream *stream, const struct etna_reloc *r);
+/* performance monitoring functions:
+ */
+
+struct etna_perfmon *etna_perfmon_create(struct etna_pipe *pipe);
+void etna_perfmon_del(struct etna_perfmon *perfmon);
+struct etna_perfmon_domain *etna_perfmon_get_dom_by_name(struct etna_perfmon *pm, const char *name);
+struct etna_perfmon_signal *etna_perfmon_get_sig_by_name(struct etna_perfmon_domain *dom, const char *name);
+
+struct etna_perf {
+#define ETNA_PM_PROCESS_PRE 0x0001
+#define ETNA_PM_PROCESS_POST 0x0002
+ uint32_t flags;
+ uint32_t sequence;
+ struct etna_perfmon_signal *signal;
+ struct etna_bo *bo;
+ uint32_t offset;
+};
+
+void etna_cmd_stream_perf(struct etna_cmd_stream *stream, const struct etna_perf *p);
+
#endif /* ETNAVIV_DRMIF_H_ */
diff --git a/etnaviv/etnaviv_gpu.c b/etnaviv/etnaviv_gpu.c
index 35dec6c..f7efa02 100644
--- a/etnaviv/etnaviv_gpu.c
+++ b/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"
@@ -61,32 +57,13 @@
gpu->dev = dev;
gpu->core = core;
- /* get specs from kernel space */
- gpu->specs.model = get_param(dev, core, ETNAVIV_PARAM_GPU_MODEL);
- gpu->specs.revision = get_param(dev, core, ETNAVIV_PARAM_GPU_REVISION);
- gpu->specs.features[0] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_0);
- gpu->specs.features[1] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_1);
- gpu->specs.features[2] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_2);
- gpu->specs.features[3] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_3);
- gpu->specs.features[4] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_4);
- gpu->specs.features[5] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_5);
- gpu->specs.features[6] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_6);
- gpu->specs.stream_count = get_param(dev, core, ETNA_GPU_STREAM_COUNT);
- gpu->specs.register_max = get_param(dev, core, ETNA_GPU_REGISTER_MAX);
- gpu->specs.thread_count = get_param(dev, core, ETNA_GPU_THREAD_COUNT);
- gpu->specs.vertex_cache_size = get_param(dev, core, ETNA_GPU_VERTEX_CACHE_SIZE);
- gpu->specs.shader_core_count = get_param(dev, core, ETNA_GPU_SHADER_CORE_COUNT);
- gpu->specs.pixel_pipes = get_param(dev, core, ETNA_GPU_PIXEL_PIPES);
- gpu->specs.vertex_output_buffer_size = get_param(dev, core, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE);
- gpu->specs.buffer_size = get_param(dev, core, ETNA_GPU_BUFFER_SIZE);
- gpu->specs.instruction_count = get_param(dev, core, ETNA_GPU_INSTRUCTION_COUNT);
- gpu->specs.num_constants = get_param(dev, core, ETNA_GPU_NUM_CONSTANTS);
- gpu->specs.num_varyings = get_param(dev, core, ETNA_GPU_NUM_VARYINGS);
+ gpu->model = get_param(dev, core, ETNAVIV_PARAM_GPU_MODEL);
+ gpu->revision = get_param(dev, core, ETNAVIV_PARAM_GPU_REVISION);
- if (!gpu->specs.model)
+ if (!gpu->model)
goto fail;
- INFO_MSG(" GPU model: 0x%x (rev %x)", gpu->specs.model, gpu->specs.revision);
+ INFO_MSG(" GPU model: 0x%x (rev %x)", gpu->model, gpu->revision);
return gpu;
fail:
@@ -104,66 +81,69 @@
int etna_gpu_get_param(struct etna_gpu *gpu, enum etna_param_id param,
uint64_t *value)
{
+ struct etna_device *dev = gpu->dev;
+ unsigned int core = gpu->core;
+
switch(param) {
case ETNA_GPU_MODEL:
- *value = gpu->specs.model;
+ *value = gpu->model;
return 0;
case ETNA_GPU_REVISION:
- *value = gpu->specs.revision;
+ *value = gpu->revision;
return 0;
case ETNA_GPU_FEATURES_0:
- *value = gpu->specs.features[0];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_0);
return 0;
case ETNA_GPU_FEATURES_1:
- *value = gpu->specs.features[1];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_1);
return 0;
case ETNA_GPU_FEATURES_2:
- *value = gpu->specs.features[2];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_2);
return 0;
case ETNA_GPU_FEATURES_3:
- *value = gpu->specs.features[3];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_3);
return 0;
case ETNA_GPU_FEATURES_4:
- *value = gpu->specs.features[4];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_4);
return 0;
case ETNA_GPU_FEATURES_5:
- *value = gpu->specs.features[5];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_5);
return 0;
case ETNA_GPU_FEATURES_6:
- *value = gpu->specs.features[6];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_6);
return 0;
case ETNA_GPU_STREAM_COUNT:
- *value = gpu->specs.stream_count;
+ *value = get_param(dev, core, ETNA_GPU_STREAM_COUNT);
return 0;
case ETNA_GPU_REGISTER_MAX:
- *value = gpu->specs.register_max;
+ *value = get_param(dev, core, ETNA_GPU_REGISTER_MAX);
return 0;
case ETNA_GPU_THREAD_COUNT:
- *value = gpu->specs.thread_count;
+ *value = get_param(dev, core, ETNA_GPU_THREAD_COUNT);
return 0;
case ETNA_GPU_VERTEX_CACHE_SIZE:
- *value = gpu->specs.vertex_cache_size;
+ *value = get_param(dev, core, ETNA_GPU_VERTEX_CACHE_SIZE);
return 0;
case ETNA_GPU_SHADER_CORE_COUNT:
- *value = gpu->specs.shader_core_count;
+ *value = get_param(dev, core, ETNA_GPU_SHADER_CORE_COUNT);
return 0;
case ETNA_GPU_PIXEL_PIPES:
- *value = gpu->specs.pixel_pipes;
+ *value = get_param(dev, core, ETNA_GPU_PIXEL_PIPES);
return 0;
case ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE:
- *value = gpu->specs.vertex_output_buffer_size;
+ *value = get_param(dev, core, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE);
return 0;
case ETNA_GPU_BUFFER_SIZE:
- *value = gpu->specs.buffer_size;
+ *value = get_param(dev, core, ETNA_GPU_BUFFER_SIZE);
return 0;
case ETNA_GPU_INSTRUCTION_COUNT:
- *value = gpu->specs.instruction_count;
+ *value = get_param(dev, core, ETNA_GPU_INSTRUCTION_COUNT);
return 0;
case ETNA_GPU_NUM_CONSTANTS:
- *value = gpu->specs.num_constants;
+ *value = get_param(dev, core, ETNA_GPU_NUM_CONSTANTS);
return 0;
case ETNA_GPU_NUM_VARYINGS:
- *value = gpu->specs.num_varyings;
+ *value = get_param(dev, core, ETNA_GPU_NUM_VARYINGS);
return 0;
default:
diff --git a/etnaviv/etnaviv_perfmon.c b/etnaviv/etnaviv_perfmon.c
new file mode 100644
index 0000000..5f408a7
--- /dev/null
+++ b/etnaviv/etnaviv_perfmon.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2017 Etnaviv Project
+ * Copyright (C) 2017 Zodiac Inflight Innovations
+ *
+ * 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.
+ *
+ * Authors:
+ * Christian Gmeiner <christian.gmeiner@gmail.com>
+ */
+
+#include "etnaviv_priv.h"
+
+static int etna_perfmon_query_signals(struct etna_perfmon *pm, struct etna_perfmon_domain *dom)
+{
+ struct etna_device *dev = pm->pipe->gpu->dev;
+ struct drm_etnaviv_pm_signal req = {
+ .pipe = pm->pipe->id,
+ .domain = dom->id
+ };
+
+ do {
+ struct etna_perfmon_signal *sig;
+ int ret;
+
+ ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_SIG, &req, sizeof(req));
+ if (ret)
+ break;
+
+ sig = calloc(1, sizeof(*sig));
+ if (!sig)
+ return -ENOMEM;
+
+ INFO_MSG("perfmon signal:");
+ INFO_MSG("id = %d", req.id);
+ INFO_MSG("name = %s", req.name);
+
+ sig->domain = dom;
+ sig->signal = req.id;
+ strncpy(sig->name, req.name, sizeof(sig->name));
+ list_addtail(&sig->head, &dom->signals);
+ } while (req.iter != 0xffff);
+
+ return 0;
+}
+
+static int etna_perfmon_query_domains(struct etna_perfmon *pm)
+{
+ struct etna_device *dev = pm->pipe->gpu->dev;
+ struct drm_etnaviv_pm_domain req = {
+ .pipe = pm->pipe->id
+ };
+
+ do {
+ struct etna_perfmon_domain *dom;
+ int ret;
+
+ ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_DOM, &req, sizeof(req));
+ if (ret)
+ break;
+
+ dom = calloc(1, sizeof(*dom));
+ if (!dom)
+ return -ENOMEM;
+
+ list_inithead(&dom->signals);
+ dom->id = req.id;
+ strncpy(dom->name, req.name, sizeof(dom->name));
+ list_addtail(&dom->head, &pm->domains);
+
+ INFO_MSG("perfmon domain:");
+ INFO_MSG("id = %d", req.id);
+ INFO_MSG("name = %s", req.name);
+ INFO_MSG("nr_signals = %d", req.nr_signals);
+
+ /* Query all available signals for this domain. */
+ if (req.nr_signals > 0) {
+ ret = etna_perfmon_query_signals(pm, dom);
+ if (ret)
+ return ret;
+ }
+ } while (req.iter != 0xff);
+
+ return 0;
+}
+
+static void etna_perfmon_free_signals(struct etna_perfmon_domain *dom)
+{
+ struct etna_perfmon_signal *sig, *next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(sig, next, &dom->signals, head) {
+ list_del(&sig->head);
+ free(sig);
+ }
+}
+
+static void etna_perfmon_free_domains(struct etna_perfmon *pm)
+{
+ struct etna_perfmon_domain *dom, *next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(dom, next, &pm->domains, head) {
+ etna_perfmon_free_signals(dom);
+ list_del(&dom->head);
+ free(dom);
+ }
+}
+
+struct etna_perfmon *etna_perfmon_create(struct etna_pipe *pipe)
+{
+ struct etna_perfmon *pm;
+ int ret;
+
+ pm = calloc(1, sizeof(*pm));
+ if (!pm) {
+ ERROR_MSG("allocation failed");
+ return NULL;
+ }
+
+ list_inithead(&pm->domains);
+ pm->pipe = pipe;
+
+ /* query all available domains and sources for this device */
+ ret = etna_perfmon_query_domains(pm);
+ if (ret)
+ goto fail;
+
+ return pm;
+
+fail:
+ etna_perfmon_del(pm);
+ return NULL;
+}
+
+void etna_perfmon_del(struct etna_perfmon *pm)
+{
+ if (!pm)
+ return;
+
+ etna_perfmon_free_domains(pm);
+ free(pm);
+}
+
+struct etna_perfmon_domain *etna_perfmon_get_dom_by_name(struct etna_perfmon *pm, const char *name)
+{
+ struct etna_perfmon_domain *dom;
+
+ if (pm) {
+ LIST_FOR_EACH_ENTRY(dom, &pm->domains, head) {
+ if (!strcmp(dom->name, name))
+ return dom;
+ }
+ }
+
+ return NULL;
+}
+
+struct etna_perfmon_signal *etna_perfmon_get_sig_by_name(struct etna_perfmon_domain *dom, const char *name)
+{
+ struct etna_perfmon_signal *signal;
+
+ if (dom) {
+ LIST_FOR_EACH_ENTRY(signal, &dom->signals, head) {
+ if (!strcmp(signal->name, name))
+ return signal;
+ }
+ }
+
+ return NULL;
+}
diff --git a/etnaviv/etnaviv_pipe.c b/etnaviv/etnaviv_pipe.c
index 94c5d37..53954aa 100644
--- a/etnaviv/etnaviv_pipe.c
+++ b/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/etnaviv/etnaviv_priv.h b/etnaviv/etnaviv_priv.h
index feaa5ad..e45d364 100644
--- a/etnaviv/etnaviv_priv.h
+++ b/etnaviv/etnaviv_priv.h
@@ -47,25 +47,6 @@
#include "etnaviv_drmif.h"
#include "etnaviv_drm.h"
-#define VIV_FEATURES_WORD_COUNT 7
-
-struct etna_specs {
- uint32_t model;
- uint32_t revision;
- uint32_t features[VIV_FEATURES_WORD_COUNT];
- uint32_t stream_count;
- uint32_t register_max;
- uint32_t thread_count;
- uint32_t shader_core_count;
- uint32_t vertex_cache_size;
- uint32_t vertex_output_buffer_size;
- uint32_t pixel_pipes;
- uint32_t instruction_count;
- uint32_t num_constants;
- uint32_t num_varyings;
- uint32_t buffer_size;
-};
-
struct etna_bo_bucket {
uint32_t size;
struct list_head list;
@@ -134,8 +115,9 @@
struct etna_gpu {
struct etna_device *dev;
- struct etna_specs specs;
uint32_t core;
+ uint32_t model;
+ uint32_t revision;
};
struct etna_pipe {
@@ -158,6 +140,10 @@
/* reloc's table: */
struct drm_etnaviv_gem_submit_reloc *relocs;
uint32_t nr_relocs, max_relocs;
+
+ /* perf's table: */
+ struct drm_etnaviv_gem_submit_pmr *pmrs;
+ uint32_t nr_pmrs, max_pmrs;
} submit;
/* should have matching entries in submit.bos: */
@@ -169,6 +155,27 @@
void *reset_notify_priv;
};
+struct etna_perfmon {
+ struct list_head domains;
+ struct etna_pipe *pipe;
+};
+
+struct etna_perfmon_domain
+{
+ struct list_head head;
+ struct list_head signals;
+ uint8_t id;
+ char name[64];
+};
+
+struct etna_perfmon_signal
+{
+ struct list_head head;
+ struct etna_perfmon_domain *domain;
+ uint8_t signal;
+ char name[64];
+};
+
#define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
diff --git a/etnaviv/meson.build b/etnaviv/meson.build
new file mode 100644
index 0000000..ca2aa54
--- /dev/null
+++ b/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/exynos/exynos-symbol-check b/exynos/exynos-symbol-check
index 9692caa..e9f1b04 100755
--- a/exynos/exynos-symbol-check
+++ b/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/exynos/exynos_drm.c b/exynos/exynos_drm.c
index b961e52..e1afef6 100644
--- a/exynos/exynos_drm.c
+++ b/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>
@@ -417,7 +413,7 @@
i = 0;
while (i < len) {
- e = (struct drm_event *) &buffer[i];
+ e = (struct drm_event *)(buffer + i);
switch (e->type) {
case DRM_EVENT_VBLANK:
if (evctx->version < 1 ||
diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h
index 626e399..154439b 100644
--- a/exynos/exynos_drmif.h
+++ b/exynos/exynos_drmif.h
@@ -31,6 +31,10 @@
#include <stdint.h>
#include "exynos_drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
struct exynos_device {
int fd;
};
@@ -109,4 +113,8 @@
struct exynos_event_context *ctx);
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* EXYNOS_DRMIF_H_ */
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c
index 7f1d105..bca884b 100644
--- a/exynos/exynos_fimg2d.c
+++ b/exynos/exynos_fimg2d.c
@@ -3,17 +3,26 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -293,20 +302,6 @@
}
/*
- * g2d_reset - reset fimg2d hardware.
- *
- * @ctx: a pointer to g2d_context structure.
- *
- */
-static void g2d_reset(struct g2d_context *ctx)
-{
- ctx->cmd_nr = 0;
- ctx->cmd_buf_nr = 0;
-
- g2d_add_cmd(ctx, SOFT_RESET_REG, 0x01);
-}
-
-/*
* g2d_flush - submit all commands and values in user side command buffer
* to command queue aware of fimg2d dma.
*
diff --git a/exynos/exynos_fimg2d.h b/exynos/exynos_fimg2d.h
index a825c68..a4dfbe7 100644
--- a/exynos/exynos_fimg2d.h
+++ b/exynos/exynos_fimg2d.h
@@ -3,11 +3,24 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _FIMG2D_H_
diff --git a/exynos/fimg2d_reg.h b/exynos/fimg2d_reg.h
index 07dd634..d42296d 100644
--- a/exynos/fimg2d_reg.h
+++ b/exynos/fimg2d_reg.h
@@ -3,11 +3,24 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _FIMG2D_REG_H_
diff --git a/exynos/meson.build b/exynos/meson.build
new file mode 100644
index 0000000..30d3640
--- /dev/null
+++ b/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/freedreno/Makefile.am b/freedreno/Makefile.am
index 0771d14..cbb0d03 100644
--- a/freedreno/Makefile.am
+++ b/freedreno/Makefile.am
@@ -5,6 +5,7 @@
$(WARN_CFLAGS) \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
+ $(VALGRIND_CFLAGS) \
-I$(top_srcdir)/include/drm
libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la
diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check
index 42f2c43..3b11952 100755
--- a/freedreno/freedreno-symbol-check
+++ b/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_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
@@ -33,6 +35,7 @@
fd_pipe_del
fd_pipe_get_param
fd_pipe_new
+fd_pipe_new2
fd_pipe_wait
fd_pipe_wait_timeout
fd_ringbuffer_cmd_count
diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c
index 996d6b9..34c285f 100644
--- a/freedreno/freedreno_bo.c
+++ b/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"
@@ -102,6 +98,8 @@
bo->bo_reuse = TRUE;
pthread_mutex_unlock(&table_lock);
+ VG_BO_ALLOC(bo);
+
return bo;
}
@@ -118,6 +116,8 @@
bo = bo_from_handle(dev, size, handle);
+ VG_BO_ALLOC(bo);
+
out_unlock:
pthread_mutex_unlock(&table_lock);
@@ -134,6 +134,7 @@
pthread_mutex_lock(&table_lock);
ret = drmPrimeFDToHandle(dev->fd, fd, &handle);
if (ret) {
+ pthread_mutex_unlock(&table_lock);
return NULL;
}
@@ -147,6 +148,8 @@
bo = bo_from_handle(dev, size, handle);
+ VG_BO_ALLOC(bo);
+
out_unlock:
pthread_mutex_unlock(&table_lock);
@@ -177,8 +180,10 @@
goto out_unlock;
bo = bo_from_handle(dev, req.size, req.handle);
- if (bo)
+ if (bo) {
set_name(bo, name);
+ VG_BO_ALLOC(bo);
+ }
out_unlock:
pthread_mutex_unlock(&table_lock);
@@ -186,6 +191,16 @@
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);
@@ -213,6 +228,8 @@
/* Called under table_lock */
drm_private void bo_del(struct fd_bo *bo)
{
+ VG_BO_FREE(bo);
+
if (bo->map)
drm_munmap(bo->map, bo->size);
@@ -315,7 +332,7 @@
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/freedreno/freedreno_bo_cache.c b/freedreno/freedreno_bo_cache.c
index 7becb0d..3b73715 100644
--- a/freedreno/freedreno_bo_cache.c
+++ b/freedreno/freedreno_bo_cache.c
@@ -26,14 +26,9 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "freedreno_drmif.h"
#include "freedreno_priv.h"
-
drm_private void bo_del(struct fd_bo *bo);
drm_private extern pthread_mutex_t table_lock;
@@ -102,6 +97,7 @@
if (time && ((time - bo->free_time) <= 1))
break;
+ VG_BO_OBTAIN(bo);
list_del(&bo->list);
bo_del(bo);
}
@@ -177,6 +173,7 @@
*size = bucket->size;
bo = find_in_bucket(bucket, flags);
if (bo) {
+ VG_BO_OBTAIN(bo);
if (bo->funcs->madvise(bo, TRUE) <= 0) {
/* we've lost the backing pages, delete and try again: */
pthread_mutex_lock(&table_lock);
@@ -207,6 +204,7 @@
clock_gettime(CLOCK_MONOTONIC, &time);
bo->free_time = time.tv_sec;
+ VG_BO_RELEASE(bo);
list_addtail(&bo->list, &bucket->list);
fd_bo_cache_cleanup(cache, time.tv_sec);
diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c
index fcbf140..0b42561 100644
--- a/freedreno/freedreno_device.c
+++ b/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 @@
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);
@@ -112,12 +108,13 @@
static void fd_device_del_impl(struct fd_device *dev)
{
+ int close_fd = dev->closefd ? dev->fd : -1;
fd_bo_cache_cleanup(&dev->bo_cache, 0);
drmHashDestroy(dev->handle_table);
drmHashDestroy(dev->name_table);
- if (dev->closefd)
- close(dev->fd);
dev->funcs->destroy(dev);
+ if (close_fd >= 0)
+ close(close_fd);
}
drm_private void fd_device_del_locked(struct fd_device *dev)
diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h
index 7a8073f..2711518 100644
--- a/freedreno/freedreno_drmif.h
+++ b/freedreno/freedreno_drmif.h
@@ -61,6 +61,7 @@
FD_CHIP_ID,
FD_MAX_FREQ,
FD_TIMESTAMP,
+ FD_NR_RINGS, /* # of rings == # of distinct priority levels */
};
/* bo flags: */
@@ -93,6 +94,8 @@
FD_VERSION_MADVISE = 1, /* kernel supports madvise */
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);
@@ -100,6 +103,7 @@
*/
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);
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);
@@ -120,6 +124,8 @@
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/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c
index 3f8c834..77b160e 100644
--- a/freedreno/freedreno_pipe.c
+++ b/freedreno/freedreno_pipe.c
@@ -26,28 +26,33 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "freedreno_drmif.h"
#include "freedreno_priv.h"
+/**
+ * priority of zero is highest priority, and higher numeric values are
+ * lower priorities
+ */
struct fd_pipe *
-fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
+fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio)
{
- struct fd_pipe *pipe = NULL;
+ struct fd_pipe *pipe;
uint64_t val;
if (id > FD_PIPE_MAX) {
ERROR_MSG("invalid pipe id: %d", id);
- goto fail;
+ return NULL;
}
- pipe = dev->funcs->pipe_new(dev, id);
+ if ((prio != 1) && (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)) {
+ ERROR_MSG("invalid priority!");
+ return NULL;
+ }
+
+ pipe = dev->funcs->pipe_new(dev, id, prio);
if (!pipe) {
ERROR_MSG("allocation failed");
- goto fail;
+ return NULL;
}
pipe->dev = dev;
@@ -57,10 +62,12 @@
pipe->gpu_id = val;
return pipe;
-fail:
- if (pipe)
- fd_pipe_del(pipe);
- return NULL;
+}
+
+struct fd_pipe *
+fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
+{
+ return fd_pipe_new2(dev, id, 1);
}
void fd_pipe_del(struct fd_pipe *pipe)
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 3217039..6c9e509 100644
--- a/freedreno/freedreno_priv.h
+++ b/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"
@@ -66,7 +63,8 @@
uint32_t flags, uint32_t *handle);
struct fd_bo * (*bo_from_handle)(struct fd_device *dev,
uint32_t size, uint32_t handle);
- struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id);
+ struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id,
+ unsigned prio);
void (*destroy)(struct fd_device *dev);
};
@@ -102,6 +100,9 @@
struct fd_bo_cache bo_cache;
int closefd; /* call close(fd) upon destruction */
+
+ /* just for valgrind: */
+ int bo_size;
};
drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse);
@@ -152,6 +153,7 @@
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);
};
@@ -169,7 +171,6 @@
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 */
@@ -196,4 +197,57 @@
return ((char *)end) - ((char *)start);
}
+#if HAVE_VALGRIND
+# include <memcheck.h>
+
+/*
+ * For tracking the backing memory (if valgrind enabled, we force a mmap
+ * for the purposes of tracking)
+ */
+static inline void VG_BO_ALLOC(struct fd_bo *bo)
+{
+ if (bo && RUNNING_ON_VALGRIND) {
+ VALGRIND_MALLOCLIKE_BLOCK(fd_bo_map(bo), bo->size, 0, 1);
+ }
+}
+
+static inline void VG_BO_FREE(struct fd_bo *bo)
+{
+ VALGRIND_FREELIKE_BLOCK(bo->map, 0);
+}
+
+/*
+ * For tracking bo structs that are in the buffer-cache, so that valgrind
+ * doesn't attribute ownership to the first one to allocate the recycled
+ * bo.
+ *
+ * Note that the list_head in fd_bo is used to track the buffers in cache
+ * so disable error reporting on the range while they are in cache so
+ * valgrind doesn't squawk about list traversal.
+ *
+ */
+static inline void VG_BO_RELEASE(struct fd_bo *bo)
+{
+ if (RUNNING_ON_VALGRIND) {
+ VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size);
+ VALGRIND_MAKE_MEM_NOACCESS(bo, bo->dev->bo_size);
+ VALGRIND_FREELIKE_BLOCK(bo->map, 0);
+ }
+}
+static inline void VG_BO_OBTAIN(struct fd_bo *bo)
+{
+ if (RUNNING_ON_VALGRIND) {
+ VALGRIND_MAKE_MEM_DEFINED(bo, bo->dev->bo_size);
+ VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size);
+ VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1);
+ }
+}
+#else
+static inline void VG_BO_ALLOC(struct fd_bo *bo) {}
+static inline void VG_BO_FREE(struct fd_bo *bo) {}
+static inline void VG_BO_RELEASE(struct fd_bo *bo) {}
+static inline void VG_BO_OBTAIN(struct fd_bo *bo) {}
+#endif
+
+
#endif /* FREEDRENO_PRIV_H_ */
diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c
index 7310f1f..3834b51 100644
--- a/freedreno/freedreno_ringbuffer.c
+++ b/freedreno/freedreno_ringbuffer.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <assert.h>
#include "freedreno_drmif.h"
diff --git a/freedreno/kgsl/kgsl_bo.c b/freedreno/kgsl/kgsl_bo.c
index ab3485e..c6d2d49 100644
--- a/freedreno/kgsl/kgsl_bo.c
+++ b/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/freedreno/kgsl/kgsl_device.c b/freedreno/kgsl/kgsl_device.c
index 175e837..914f341 100644
--- a/freedreno/kgsl/kgsl_device.c
+++ b/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>
@@ -61,5 +57,7 @@
dev = &kgsl_dev->base;
dev->funcs = &funcs;
+ dev->bo_size = sizeof(struct kgsl_bo);
+
return dev;
}
diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c
index 8a39eb4..0a8b658 100644
--- a/freedreno/kgsl/kgsl_pipe.c
+++ b/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"
@@ -52,6 +48,7 @@
return 0;
case FD_MAX_FREQ:
case FD_TIMESTAMP:
+ case FD_NR_RINGS:
/* unsupported on kgsl */
return -1;
default:
@@ -210,7 +207,7 @@
drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id)
+ enum fd_pipe_id id, uint32_t prio)
{
static const char *paths[] = {
[FD_PIPE_3D] = "/dev/kgsl-3d0",
diff --git a/freedreno/kgsl/kgsl_priv.h b/freedreno/kgsl/kgsl_priv.h
index 6ab6496..41b1392 100644
--- a/freedreno/kgsl/kgsl_priv.h
+++ b/freedreno/kgsl/kgsl_priv.h
@@ -103,7 +103,7 @@
drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe,
uint32_t timestamp);
drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id);
+ enum fd_pipe_id id, uint32_t prio);
drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size);
diff --git a/freedreno/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c
index e4696b1..a756ded 100644
--- a/freedreno/kgsl/kgsl_ringbuffer.c
+++ b/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"
@@ -146,7 +142,7 @@
ibdesc.gpuaddr = kgsl_ring->bo->gpuaddr;
ibdesc.hostptr = kgsl_ring->bo->hostptr;
ibdesc.sizedwords = 0x145;
- req.timestamp = (uint32_t)kgsl_ring->bo->hostptr;
+ req.timestamp = (uintptr_t)kgsl_ring->bo->hostptr;
}
do {
diff --git a/freedreno/meson.build b/freedreno/meson.build
new file mode 100644
index 0000000..015b7fb
--- /dev/null
+++ b/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/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c
index 72471df..8b3d0bc 100644
--- a/freedreno/msm/msm_bo.c
+++ b/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 @@
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 @@
.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/freedreno/msm/msm_device.c b/freedreno/msm/msm_device.c
index 727baa4..7bb5767 100644
--- a/freedreno/msm/msm_device.c
+++ b/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>
@@ -64,5 +60,7 @@
fd_bo_cache_init(&msm_dev->ring_cache, TRUE);
+ dev->bo_size = sizeof(struct msm_bo);
+
return dev;
}
diff --git a/freedreno/msm/msm_drm.h b/freedreno/msm/msm_drm.h
index ed4c8d4..dac49e5 100644
--- a/freedreno/msm/msm_drm.h
+++ b/freedreno/msm/msm_drm.h
@@ -73,6 +73,8 @@
#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 */
@@ -104,10 +106,14 @@
__u32 handle; /* out */
};
+#define MSM_INFO_IOVA 0x01
+
+#define MSM_INFO_FLAGS (MSM_INFO_IOVA)
+
struct drm_msm_gem_info {
__u32 handle; /* in */
- __u32 pad;
- __u64 offset; /* out, offset to pass to mmap() */
+ __u32 flags; /* in - combination of MSM_INFO_* flags */
+ __u64 offset; /* out, mmap() offset or iova */
};
#define MSM_PREP_READ 0x01
@@ -167,7 +173,7 @@
__u32 size; /* in, cmdstream size */
__u32 pad;
__u32 nr_relocs; /* in, number of submit_reloc's */
- __u64 __user relocs; /* in, ptr to array of submit_reloc's */
+ __u64 relocs; /* in, ptr to array of submit_reloc's */
};
/* Each buffer referenced elsewhere in the cmdstream submit (ie. the
@@ -211,9 +217,10 @@
__u32 fence; /* out */
__u32 nr_bos; /* in, number of submit_bo's */
__u32 nr_cmds; /* in, number of submit_cmd's */
- __u64 __user bos; /* in, ptr to array of submit_bo's */
- __u64 __user cmds; /* in, ptr to array 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
@@ -227,6 +234,7 @@
__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
@@ -250,6 +258,20 @@
__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
@@ -261,7 +283,11 @@
#define DRM_MSM_GEM_SUBMIT 0x06
#define DRM_MSM_WAIT_FENCE 0x07
#define DRM_MSM_GEM_MADVISE 0x08
-#define DRM_MSM_NUM_IOCTLS 0x09
+/* 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)
@@ -271,6 +297,8 @@
#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)
}
diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c
index f872e24..f28778e 100644
--- a/freedreno/msm/msm_pipe.c
+++ b/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,
@@ -71,6 +67,8 @@
return query_param(pipe, MSM_PARAM_MAX_FREQ, value);
case FD_TIMESTAMP:
return query_param(pipe, MSM_PARAM_TIMESTAMP, value);
+ case FD_NR_RINGS:
+ return query_param(pipe, MSM_PARAM_NR_RINGS, value);
default:
ERROR_MSG("invalid param id: %d", param);
return -1;
@@ -83,6 +81,7 @@
struct fd_device *dev = pipe->dev;
struct drm_msm_wait_fence req = {
.fence = timestamp,
+ .queueid = to_msm_pipe(pipe)->queue_id,
};
int ret;
@@ -97,9 +96,48 @@
return 0;
}
+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(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) {
+ to_msm_pipe(pipe)->queue_id = 0;
+ return 0;
+ }
+
+ 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;
+ }
+
+ to_msm_pipe(pipe)->queue_id = req.id;
+ return 0;
+}
+
+static void close_submitqueue(struct fd_pipe *pipe, uint32_t queue_id)
+{
+ if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES)
+ return;
+
+ 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, msm_pipe->queue_id);
free(msm_pipe);
}
@@ -122,7 +160,7 @@
}
drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id)
+ enum fd_pipe_id id, uint32_t prio)
{
static const uint32_t pipe_id[] = {
[FD_PIPE_3D] = MSM_PIPE_3D0,
@@ -157,6 +195,9 @@
INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id);
INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem);
+ if (open_submitqueue(pipe, prio))
+ goto fail;
+
return pipe;
fail:
if (pipe)
diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 6d670aa..88ac3aa 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -56,6 +56,7 @@
uint32_t gpu_id;
uint32_t gmem;
uint32_t chip_id;
+ uint32_t queue_id;
};
static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x)
@@ -64,7 +65,7 @@
}
drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id);
+ enum fd_pipe_id id, uint32_t prio);
drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size);
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 17194f4..a87e1b9 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/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>
@@ -401,6 +397,7 @@
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
struct drm_msm_gem_submit req = {
.flags = to_msm_pipe(ring->pipe)->pipe,
+ .queueid = to_msm_pipe(ring->pipe)->queue_id,
};
uint32_t i;
int ret;
@@ -496,11 +493,16 @@
if (ring->pipe->gpu_id >= 500) {
struct drm_msm_gem_submit_reloc *reloc_hi;
+ /* NOTE: grab reloc_idx *before* APPEND() since that could
+ * realloc() meaning that 'reloc' ptr is no longer valid:
+ */
+ uint32_t reloc_idx = reloc->reloc_idx;
+
idx = APPEND(cmd, relocs);
reloc_hi = &cmd->relocs[idx];
- reloc_hi->reloc_idx = reloc->reloc_idx;
+ reloc_hi->reloc_idx = reloc_idx;
reloc_hi->reloc_offset = r->offset;
reloc_hi->or = r->orhi;
reloc_hi->shift = r->shift - 32;
@@ -584,12 +586,12 @@
uint32_t size)
{
struct msm_ringbuffer *msm_ring;
- struct fd_ringbuffer *ring = NULL;
+ struct fd_ringbuffer *ring;
msm_ring = calloc(1, sizeof(*msm_ring));
if (!msm_ring) {
ERROR_MSG("allocation failed");
- goto fail;
+ return NULL;
}
if (size == 0) {
@@ -609,8 +611,4 @@
ring_cmd_new(ring, size);
return ring;
-fail:
- if (ring)
- fd_ringbuffer_del(ring);
- return NULL;
}
diff --git a/include/drm/README b/include/drm/README
index a50b02c..b4658dd 100644
--- a/include/drm/README
+++ b/include/drm/README
@@ -67,6 +67,8 @@
When and how to update these files
----------------------------------
+Note: One should not do _any_ changes to the files apart from the steps below.
+
In order to update the files do the following:
- Switch to a Linux kernel tree/branch which is not rebased.
For example: airlied/drm-next
@@ -84,47 +86,21 @@
This section contains a list of headers and the respective "issues" they might
have relative to their kernel equivalent.
-Nearly all headers:
- - Missing extern C notation.
-Status: Trivial.
-
Most UMS headers:
- Not using fixed size integers - compat ioctls are broken.
Status: ?
Promote to fixed size ints, which match the current (32bit) ones.
-
-amdgpu_drm.h
- - Using the stdint.h uint*_t over the respective __u* ones
-Status: Trivial.
-
-drm_mode.h
- - Missing DPI encode/connector pair.
-Status: Trivial.
-
-i915_drm.h
- - Missing PARAMS - HAS_POOLED_EU, MIN_EU_IN_POOL CONTEXT_PARAM_NO_ERROR_CAPTURE
-Status: Trivial.
-
-mga_drm.h
- - Typo fix, use struct over typedef.
-Status: Trivial.
-
nouveau_drm.h
- Missing macros NOUVEAU_GETPARAM*, NOUVEAU_DRM_HEADER_PATCHLEVEL, structs,
-enums, using stdint.h over the __u* types.
-Status: ?
-
-qxl_drm.h
- - Using the stdint.h uint*_t over the respective __u* ones
-Status: Trivial.
+enums
+Status: Deliberate UABI choice; nouveau hides the exact kernel ABI behind libdrm
r128_drm.h
- Broken compat ioctls.
radeon_drm.h
- - Missing RADEON_TILING_R600_NO_SCANOUT, CIK_TILE_MODE_*, broken UMS ioctls,
-using stdint types.
+ - Missing RADEON_TILING_R600_NO_SCANOUT, CIK_TILE_MODE_*, broken UMS ioctls
- Both kernel and libdrm: missing padding -
drm_radeon_gem_{create,{g,s}et_tiling,set_domain} others ?
Status: ?
diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index d8f2497..c363b67 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -50,6 +50,10 @@
#define DRM_AMDGPU_WAIT_CS 0x09
#define DRM_AMDGPU_GEM_OP 0x10
#define DRM_AMDGPU_GEM_USERPTR 0x11
+#define DRM_AMDGPU_WAIT_FENCES 0x12
+#define DRM_AMDGPU_VM 0x13
+#define DRM_AMDGPU_FENCE_TO_HANDLE 0x14
+#define DRM_AMDGPU_SCHED 0x15
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
@@ -63,6 +67,10 @@
#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
+#define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences)
+#define DRM_IOCTL_AMDGPU_VM DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
+#define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
+#define DRM_IOCTL_AMDGPU_SCHED DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched)
#define AMDGPU_GEM_DOMAIN_CPU 0x1
#define AMDGPU_GEM_DOMAIN_GTT 0x2
@@ -79,22 +87,30 @@
#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
/* Flag that the memory should be in VRAM and cleared */
#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
+/* Flag that create shadow bo(GTT) while allocating vram bo */
+#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
+/* Flag that allocating the BO should use linear VRAM */
+#define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS (1 << 5)
+/* Flag that BO is always valid in this VM */
+#define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID (1 << 6)
+/* Flag that BO sharing will be explicitly synchronized */
+#define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7)
struct drm_amdgpu_gem_create_in {
/** the requested memory size */
- uint64_t bo_size;
+ __u64 bo_size;
/** physical start_addr alignment in bytes for some HW requirements */
- uint64_t alignment;
+ __u64 alignment;
/** the requested memory domains */
- uint64_t domains;
+ __u64 domains;
/** allocation flags */
- uint64_t domain_flags;
+ __u64 domain_flags;
};
struct drm_amdgpu_gem_create_out {
/** returned GEM object handle */
- uint32_t handle;
- uint32_t _pad;
+ __u32 handle;
+ __u32 _pad;
};
union drm_amdgpu_gem_create {
@@ -111,28 +127,28 @@
struct drm_amdgpu_bo_list_in {
/** Type of operation */
- uint32_t operation;
+ __u32 operation;
/** Handle of list or 0 if we want to create one */
- uint32_t list_handle;
+ __u32 list_handle;
/** Number of BOs in list */
- uint32_t bo_number;
+ __u32 bo_number;
/** Size of each element describing BO */
- uint32_t bo_info_size;
+ __u32 bo_info_size;
/** Pointer to array describing BOs */
- uint64_t bo_info_ptr;
+ __u64 bo_info_ptr;
};
struct drm_amdgpu_bo_list_entry {
/** Handle of BO */
- uint32_t bo_handle;
+ __u32 bo_handle;
/** New (if specified) BO priority to be used during migration */
- uint32_t bo_priority;
+ __u32 bo_priority;
};
struct drm_amdgpu_bo_list_out {
/** Handle of resource list */
- uint32_t list_handle;
- uint32_t _pad;
+ __u32 list_handle;
+ __u32 _pad;
};
union drm_amdgpu_bo_list {
@@ -144,6 +160,7 @@
#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
@@ -154,28 +171,44 @@
/* 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
+#define AMDGPU_CTX_PRIORITY_LOW -512
+#define AMDGPU_CTX_PRIORITY_NORMAL 0
+/* Selecting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER */
+#define AMDGPU_CTX_PRIORITY_HIGH 512
+#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023
+
struct drm_amdgpu_ctx_in {
/** AMDGPU_CTX_OP_* */
- uint32_t op;
+ __u32 op;
/** For future use, no flags defined so far */
- uint32_t flags;
- uint32_t ctx_id;
- uint32_t _pad;
+ __u32 flags;
+ __u32 ctx_id;
+ __s32 priority;
};
union drm_amdgpu_ctx_out {
struct {
- uint32_t ctx_id;
- uint32_t _pad;
+ __u32 ctx_id;
+ __u32 _pad;
} alloc;
struct {
/** For future use, no flags defined so far */
- uint64_t flags;
+ __u64 flags;
/** Number of resets caused by this context so far. */
- uint32_t hangs;
+ __u32 hangs;
/** Reset status since the last call of the ioctl. */
- uint32_t reset_status;
+ __u32 reset_status;
} state;
};
@@ -184,6 +217,41 @@
union drm_amdgpu_ctx_out out;
};
+/* vm ioctl */
+#define AMDGPU_VM_OP_RESERVE_VMID 1
+#define AMDGPU_VM_OP_UNRESERVE_VMID 2
+
+struct drm_amdgpu_vm_in {
+ /** AMDGPU_VM_OP_* */
+ __u32 op;
+ __u32 flags;
+};
+
+struct drm_amdgpu_vm_out {
+ /** For future use, no flags defined so far */
+ __u64 flags;
+};
+
+union drm_amdgpu_vm {
+ struct drm_amdgpu_vm_in in;
+ struct drm_amdgpu_vm_out out;
+};
+
+/* sched ioctl */
+#define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1
+
+struct drm_amdgpu_sched_in {
+ /* AMDGPU_SCHED_OP_* */
+ __u32 op;
+ __u32 fd;
+ __s32 priority;
+ __u32 flags;
+};
+
+union drm_amdgpu_sched {
+ struct drm_amdgpu_sched_in in;
+};
+
/*
* This is not a reliable API and you should expect it to fail for any
* number of reasons and have fallback path that do not use userptr to
@@ -195,14 +263,15 @@
#define AMDGPU_GEM_USERPTR_REGISTER (1 << 3)
struct drm_amdgpu_gem_userptr {
- uint64_t addr;
- uint64_t size;
+ __u64 addr;
+ __u64 size;
/* AMDGPU_GEM_USERPTR_* */
- uint32_t flags;
+ __u32 flags;
/* Resulting GEM handle */
- uint32_t handle;
+ __u32 handle;
};
+/* SI-CI-VI: */
/* same meaning as the GB_TILE_MODE and GL_MACRO_TILE_MODE fields */
#define AMDGPU_TILING_ARRAY_MODE_SHIFT 0
#define AMDGPU_TILING_ARRAY_MODE_MASK 0xf
@@ -221,10 +290,15 @@
#define AMDGPU_TILING_NUM_BANKS_SHIFT 21
#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
+/* GFX9 and later: */
+#define AMDGPU_TILING_SWIZZLE_MODE_SHIFT 0
+#define AMDGPU_TILING_SWIZZLE_MODE_MASK 0x1f
+
+/* Set/Get helpers for tiling flags. */
#define AMDGPU_TILING_SET(field, value) \
- (((value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT)
+ (((__u64)(value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT)
#define AMDGPU_TILING_GET(value, field) \
- (((value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK)
+ (((__u64)(value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK)
#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
#define AMDGPU_GEM_METADATA_OP_GET_METADATA 2
@@ -232,28 +306,28 @@
/** The same structure is shared for input/output */
struct drm_amdgpu_gem_metadata {
/** GEM Object handle */
- uint32_t handle;
+ __u32 handle;
/** Do we want get or set metadata */
- uint32_t op;
+ __u32 op;
struct {
/** For future use, no flags defined so far */
- uint64_t flags;
+ __u64 flags;
/** family specific tiling info */
- uint64_t tiling_info;
- uint32_t data_size_bytes;
- uint32_t data[64];
+ __u64 tiling_info;
+ __u32 data_size_bytes;
+ __u32 data[64];
} data;
};
struct drm_amdgpu_gem_mmap_in {
/** the GEM object handle */
- uint32_t handle;
- uint32_t _pad;
+ __u32 handle;
+ __u32 _pad;
};
struct drm_amdgpu_gem_mmap_out {
/** mmap offset from the vma offset manager */
- uint64_t addr_ptr;
+ __u64 addr_ptr;
};
union drm_amdgpu_gem_mmap {
@@ -263,18 +337,18 @@
struct drm_amdgpu_gem_wait_idle_in {
/** GEM object handle */
- uint32_t handle;
+ __u32 handle;
/** For future use, no flags defined so far */
- uint32_t flags;
+ __u32 flags;
/** Absolute timeout to wait */
- uint64_t timeout;
+ __u64 timeout;
};
struct drm_amdgpu_gem_wait_idle_out {
/** BO status: 0 - BO is idle, 1 - BO is busy */
- uint32_t status;
+ __u32 status;
/** Returned current memory domain */
- uint32_t domain;
+ __u32 domain;
};
union drm_amdgpu_gem_wait_idle {
@@ -283,19 +357,22 @@
};
struct drm_amdgpu_wait_cs_in {
- /** Command submission handle */
- uint64_t handle;
+ /* Command submission handle
+ * handle equals 0 means none to wait for
+ * handle equals ~0ull means wait for the latest sequence number
+ */
+ __u64 handle;
/** Absolute timeout to wait */
- uint64_t timeout;
- uint32_t ip_type;
- uint32_t ip_instance;
- uint32_t ring;
- uint32_t ctx_id;
+ __u64 timeout;
+ __u32 ip_type;
+ __u32 ip_instance;
+ __u32 ring;
+ __u32 ctx_id;
};
struct drm_amdgpu_wait_cs_out {
/** CS status: 0 - CS completed, 1 - CS still busy */
- uint64_t status;
+ __u64 status;
};
union drm_amdgpu_wait_cs {
@@ -303,21 +380,49 @@
struct drm_amdgpu_wait_cs_out out;
};
+struct drm_amdgpu_fence {
+ __u32 ctx_id;
+ __u32 ip_type;
+ __u32 ip_instance;
+ __u32 ring;
+ __u64 seq_no;
+};
+
+struct drm_amdgpu_wait_fences_in {
+ /** This points to uint64_t * which points to fences */
+ __u64 fences;
+ __u32 fence_count;
+ __u32 wait_all;
+ __u64 timeout_ns;
+};
+
+struct drm_amdgpu_wait_fences_out {
+ __u32 status;
+ __u32 first_signaled;
+};
+
+union drm_amdgpu_wait_fences {
+ struct drm_amdgpu_wait_fences_in in;
+ struct drm_amdgpu_wait_fences_out out;
+};
+
#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
#define AMDGPU_GEM_OP_SET_PLACEMENT 1
/* Sets or returns a value associated with a buffer. */
struct drm_amdgpu_gem_op {
/** GEM object handle */
- uint32_t handle;
+ __u32 handle;
/** AMDGPU_GEM_OP_* */
- uint32_t op;
+ __u32 op;
/** Input or return value */
- uint64_t value;
+ __u64 value;
};
#define AMDGPU_VA_OP_MAP 1
#define AMDGPU_VA_OP_UNMAP 2
+#define AMDGPU_VA_OP_CLEAR 3
+#define AMDGPU_VA_OP_REPLACE 4
/* Delay the page table update till the next CS */
#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
@@ -329,21 +434,35 @@
#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
/* executable mapping, new for VI */
#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
+/* partially resident texture */
+#define AMDGPU_VM_PAGE_PRT (1 << 4)
+/* MTYPE flags use bit 5 to 8 */
+#define AMDGPU_VM_MTYPE_MASK (0xf << 5)
+/* Default MTYPE. Pre-AI must use this. Recommended for newer ASICs. */
+#define AMDGPU_VM_MTYPE_DEFAULT (0 << 5)
+/* Use NC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_NC (1 << 5)
+/* Use WC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_WC (2 << 5)
+/* Use CC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_CC (3 << 5)
+/* Use UC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_UC (4 << 5)
struct drm_amdgpu_gem_va {
/** GEM object handle */
- uint32_t handle;
- uint32_t _pad;
+ __u32 handle;
+ __u32 _pad;
/** AMDGPU_VA_OP_* */
- uint32_t operation;
+ __u32 operation;
/** AMDGPU_VM_PAGE_* */
- uint32_t flags;
+ __u32 flags;
/** va address to assign . Must be correctly aligned.*/
- uint64_t va_address;
+ __u64 va_address;
/** Specify offset inside of BO to assign. Must be correctly aligned.*/
- uint64_t offset_in_bo;
+ __u64 offset_in_bo;
/** Specify mapping size. Must be correctly aligned. */
- uint64_t map_size;
+ __u64 map_size;
};
#define AMDGPU_HW_IP_GFX 0
@@ -351,33 +470,38 @@
#define AMDGPU_HW_IP_DMA 2
#define AMDGPU_HW_IP_UVD 3
#define AMDGPU_HW_IP_VCE 4
-#define AMDGPU_HW_IP_NUM 5
+#define AMDGPU_HW_IP_UVD_ENC 5
+#define AMDGPU_HW_IP_VCN_DEC 6
+#define AMDGPU_HW_IP_VCN_ENC 7
+#define AMDGPU_HW_IP_NUM 8
#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
#define AMDGPU_CHUNK_ID_IB 0x01
#define AMDGPU_CHUNK_ID_FENCE 0x02
#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
+#define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04
+#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
struct drm_amdgpu_cs_chunk {
- uint32_t chunk_id;
- uint32_t length_dw;
- uint64_t chunk_data;
+ __u32 chunk_id;
+ __u32 length_dw;
+ __u64 chunk_data;
};
struct drm_amdgpu_cs_in {
/** Rendering context id */
- uint32_t ctx_id;
+ __u32 ctx_id;
/** Handle of resource list associated with CS */
- uint32_t bo_list_handle;
- uint32_t num_chunks;
- uint32_t _pad;
- /** this points to uint64_t * which point to cs chunks */
- uint64_t chunks;
+ __u32 bo_list_handle;
+ __u32 num_chunks;
+ __u32 _pad;
+ /** this points to __u64 * which point to cs chunks */
+ __u64 chunks;
};
struct drm_amdgpu_cs_out {
- uint64_t handle;
+ __u64 handle;
};
union drm_amdgpu_cs {
@@ -390,36 +514,58 @@
/* This IB should be submitted to CE */
#define AMDGPU_IB_FLAG_CE (1<<0)
-/* CE Preamble */
+/* Preamble flag, which means the IB could be dropped if no context switch */
#define AMDGPU_IB_FLAG_PREAMBLE (1<<1)
+/* Preempt flag, IB should set Pre_enb bit if PREEMPT flag detected */
+#define AMDGPU_IB_FLAG_PREEMPT (1<<2)
+
struct drm_amdgpu_cs_chunk_ib {
- uint32_t _pad;
+ __u32 _pad;
/** AMDGPU_IB_FLAG_* */
- uint32_t flags;
+ __u32 flags;
/** Virtual address to begin IB execution */
- uint64_t va_start;
+ __u64 va_start;
/** Size of submission */
- uint32_t ib_bytes;
+ __u32 ib_bytes;
/** HW IP to submit to */
- uint32_t ip_type;
+ __u32 ip_type;
/** HW IP index of the same type to submit to */
- uint32_t ip_instance;
+ __u32 ip_instance;
/** Ring index to submit to */
- uint32_t ring;
+ __u32 ring;
};
struct drm_amdgpu_cs_chunk_dep {
- uint32_t ip_type;
- uint32_t ip_instance;
- uint32_t ring;
- uint32_t ctx_id;
- uint64_t handle;
+ __u32 ip_type;
+ __u32 ip_instance;
+ __u32 ring;
+ __u32 ctx_id;
+ __u64 handle;
};
struct drm_amdgpu_cs_chunk_fence {
- uint32_t handle;
- uint32_t offset;
+ __u32 handle;
+ __u32 offset;
+};
+
+struct drm_amdgpu_cs_chunk_sem {
+ __u32 handle;
+};
+
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2
+
+union drm_amdgpu_fence_to_handle {
+ struct {
+ struct drm_amdgpu_fence fence;
+ __u32 what;
+ __u32 pad;
+ } in;
+ struct {
+ __u32 handle;
+ } out;
};
struct drm_amdgpu_cs_chunk_data {
@@ -434,6 +580,7 @@
*
*/
#define AMDGPU_IDS_FLAGS_FUSION 0x1
+#define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
/* indicate if acceleration can be working */
#define AMDGPU_INFO_ACCEL_WORKING 0x00
@@ -467,6 +614,12 @@
#define AMDGPU_INFO_FW_SMC 0x0a
/* Subquery id: Query SDMA firmware version */
#define AMDGPU_INFO_FW_SDMA 0x0b
+ /* Subquery id: Query PSP SOS firmware version */
+ #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 */
@@ -483,6 +636,43 @@
#define AMDGPU_INFO_DEV_INFO 0x16
/* visible vram usage */
#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17
+/* number of TTM buffer evictions */
+#define AMDGPU_INFO_NUM_EVICTIONS 0x18
+/* Query memory about VRAM and GTT domains */
+#define AMDGPU_INFO_MEMORY 0x19
+/* Query vce clock table */
+#define AMDGPU_INFO_VCE_CLOCK_TABLE 0x1A
+/* Query vbios related information */
+#define AMDGPU_INFO_VBIOS 0x1B
+ /* Subquery id: Query vbios size */
+ #define AMDGPU_INFO_VBIOS_SIZE 0x1
+ /* Subquery id: Query vbios image */
+ #define AMDGPU_INFO_VBIOS_IMAGE 0x2
+/* Query UVD handles */
+#define AMDGPU_INFO_NUM_HANDLES 0x1C
+/* Query sensor related information */
+#define AMDGPU_INFO_SENSOR 0x1D
+ /* Subquery id: Query GPU shader clock */
+ #define AMDGPU_INFO_SENSOR_GFX_SCLK 0x1
+ /* Subquery id: Query GPU memory clock */
+ #define AMDGPU_INFO_SENSOR_GFX_MCLK 0x2
+ /* Subquery id: Query GPU temperature */
+ #define AMDGPU_INFO_SENSOR_GPU_TEMP 0x3
+ /* Subquery id: Query GPU load */
+ #define AMDGPU_INFO_SENSOR_GPU_LOAD 0x4
+ /* Subquery id: Query average GPU power */
+ #define AMDGPU_INFO_SENSOR_GPU_AVG_POWER 0x5
+ /* Subquery id: Query northbridge voltage */
+ #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
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
@@ -491,86 +681,123 @@
struct drm_amdgpu_query_fw {
/** AMDGPU_INFO_FW_* */
- uint32_t fw_type;
+ __u32 fw_type;
/**
* Index of the IP if there are more IPs of
* the same type.
*/
- uint32_t ip_instance;
+ __u32 ip_instance;
/**
* Index of the engine. Whether this is used depends
* on the firmware type. (e.g. MEC, SDMA)
*/
- uint32_t index;
- uint32_t _pad;
+ __u32 index;
+ __u32 _pad;
};
/* Input structure for the INFO ioctl */
struct drm_amdgpu_info {
/* Where the return value will be stored */
- uint64_t return_pointer;
+ __u64 return_pointer;
/* The size of the return value. Just like "size" in "snprintf",
* it limits how many bytes the kernel can write. */
- uint32_t return_size;
+ __u32 return_size;
/* The query request id. */
- uint32_t query;
+ __u32 query;
union {
struct {
- uint32_t id;
- uint32_t _pad;
+ __u32 id;
+ __u32 _pad;
} mode_crtc;
struct {
/** AMDGPU_HW_IP_* */
- uint32_t type;
+ __u32 type;
/**
* Index of the IP if there are more IPs of the same
* type. Ignored by AMDGPU_INFO_HW_IP_COUNT.
*/
- uint32_t ip_instance;
+ __u32 ip_instance;
} query_hw_ip;
struct {
- uint32_t dword_offset;
+ __u32 dword_offset;
/** number of registers to read */
- uint32_t count;
- uint32_t instance;
+ __u32 count;
+ __u32 instance;
/** For future use, no flags defined so far */
- uint32_t flags;
+ __u32 flags;
} read_mmr_reg;
struct drm_amdgpu_query_fw query_fw;
+
+ struct {
+ __u32 type;
+ __u32 offset;
+ } vbios_info;
+
+ struct {
+ __u32 type;
+ } sensor_info;
};
};
struct drm_amdgpu_info_gds {
/** GDS GFX partition size */
- uint32_t gds_gfx_partition_size;
+ __u32 gds_gfx_partition_size;
/** GDS compute partition size */
- uint32_t compute_partition_size;
+ __u32 compute_partition_size;
/** total GDS memory size */
- uint32_t gds_total_size;
+ __u32 gds_total_size;
/** GWS size per GFX partition */
- uint32_t gws_per_gfx_partition;
+ __u32 gws_per_gfx_partition;
/** GSW size per compute partition */
- uint32_t gws_per_compute_partition;
+ __u32 gws_per_compute_partition;
/** OA size per GFX partition */
- uint32_t oa_per_gfx_partition;
+ __u32 oa_per_gfx_partition;
/** OA size per compute partition */
- uint32_t oa_per_compute_partition;
- uint32_t _pad;
+ __u32 oa_per_compute_partition;
+ __u32 _pad;
};
struct drm_amdgpu_info_vram_gtt {
- uint64_t vram_size;
- uint64_t vram_cpu_accessible_size;
- uint64_t gtt_size;
+ __u64 vram_size;
+ __u64 vram_cpu_accessible_size;
+ __u64 gtt_size;
+};
+
+struct drm_amdgpu_heap_info {
+ /** max. physical memory */
+ __u64 total_heap_size;
+
+ /** Theoretical max. available memory in the given heap */
+ __u64 usable_heap_size;
+
+ /**
+ * Number of bytes allocated in the heap. This includes all processes
+ * and private allocations in the kernel. It changes when new buffers
+ * are allocated, freed, and moved. It cannot be larger than
+ * heap_size.
+ */
+ __u64 heap_usage;
+
+ /**
+ * Theoretical possible max. size of buffer which
+ * could be allocated in the given heap
+ */
+ __u64 max_allocation;
+};
+
+struct drm_amdgpu_memory_info {
+ struct drm_amdgpu_heap_info vram;
+ struct drm_amdgpu_heap_info cpu_accessible_vram;
+ struct drm_amdgpu_heap_info gtt;
};
struct drm_amdgpu_info_firmware {
- uint32_t ver;
- uint32_t feature;
+ __u32 ver;
+ __u32 feature;
};
#define AMDGPU_VRAM_TYPE_UNKNOWN 0
@@ -581,74 +808,139 @@
#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 */
- uint32_t device_id;
+ __u32 device_id;
/** Internal chip revision: A0, A1, etc.) */
- uint32_t chip_rev;
- uint32_t external_rev;
+ __u32 chip_rev;
+ __u32 external_rev;
/** Revision id in PCI Config space */
- uint32_t pci_rev;
- uint32_t family;
- uint32_t num_shader_engines;
- uint32_t num_shader_arrays_per_engine;
+ __u32 pci_rev;
+ __u32 family;
+ __u32 num_shader_engines;
+ __u32 num_shader_arrays_per_engine;
/* in KHz */
- uint32_t gpu_counter_freq;
- uint64_t max_engine_clock;
- uint64_t max_memory_clock;
+ __u32 gpu_counter_freq;
+ __u64 max_engine_clock;
+ __u64 max_memory_clock;
/* cu information */
- uint32_t cu_active_number;
- uint32_t cu_ao_mask;
- uint32_t cu_bitmap[4][4];
+ __u32 cu_active_number;
+ /* NOTE: cu_ao_mask is INVALID, DON'T use it */
+ __u32 cu_ao_mask;
+ __u32 cu_bitmap[4][4];
/** Render backend pipe mask. One render backend is CB+DB. */
- uint32_t enabled_rb_pipes_mask;
- uint32_t num_rb_pipes;
- uint32_t num_hw_gfx_contexts;
- uint32_t _pad;
- uint64_t ids_flags;
+ __u32 enabled_rb_pipes_mask;
+ __u32 num_rb_pipes;
+ __u32 num_hw_gfx_contexts;
+ __u32 _pad;
+ __u64 ids_flags;
/** Starting virtual address for UMDs. */
- uint64_t virtual_address_offset;
+ __u64 virtual_address_offset;
/** The maximum virtual address */
- uint64_t virtual_address_max;
+ __u64 virtual_address_max;
/** Required alignment of virtual addresses. */
- uint32_t virtual_address_alignment;
+ __u32 virtual_address_alignment;
/** Page table entry - fragment size */
- uint32_t pte_fragment_size;
- uint32_t gart_page_size;
+ __u32 pte_fragment_size;
+ __u32 gart_page_size;
/** constant engine ram size*/
- uint32_t ce_ram_size;
+ __u32 ce_ram_size;
/** video memory type info*/
- uint32_t vram_type;
+ __u32 vram_type;
/** video memory bit width*/
- uint32_t vram_bit_width;
+ __u32 vram_bit_width;
/* vce harvesting instance */
- uint32_t vce_harvest_config;
+ __u32 vce_harvest_config;
+ /* gfx double offchip LDS buffers */
+ __u32 gc_double_offchip_lds_buf;
+ /* NGG Primitive Buffer */
+ __u64 prim_buf_gpu_addr;
+ /* NGG Position Buffer */
+ __u64 pos_buf_gpu_addr;
+ /* NGG Control Sideband */
+ __u64 cntl_sb_buf_gpu_addr;
+ /* NGG Parameter Cache */
+ __u64 param_buf_gpu_addr;
+ __u32 prim_buf_size;
+ __u32 pos_buf_size;
+ __u32 cntl_sb_buf_size;
+ __u32 param_buf_size;
+ /* wavefront size*/
+ __u32 wave_front_size;
+ /* shader visible vgprs*/
+ __u32 num_shader_visible_vgprs;
+ /* CU per shader array*/
+ __u32 num_cu_per_sh;
+ /* number of tcc blocks*/
+ __u32 num_tcc_blocks;
+ /* gs vgt table depth*/
+ __u32 gs_vgt_table_depth;
+ /* gs primitive buffer depth*/
+ __u32 gs_prim_buffer_depth;
+ /* max gs wavefront per vgt*/
+ __u32 max_gs_waves_per_vgt;
+ __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 {
/** Version of h/w IP */
- uint32_t hw_ip_version_major;
- uint32_t hw_ip_version_minor;
+ __u32 hw_ip_version_major;
+ __u32 hw_ip_version_minor;
/** Capabilities */
- uint64_t capabilities_flags;
+ __u64 capabilities_flags;
/** command buffer address start alignment*/
- uint32_t ib_start_alignment;
+ __u32 ib_start_alignment;
/** command buffer size alignment*/
- uint32_t ib_size_alignment;
+ __u32 ib_size_alignment;
/** Bitmask of available rings. Bit 0 means ring 0, etc. */
- uint32_t available_rings;
- uint32_t _pad;
+ __u32 available_rings;
+ __u32 _pad;
+};
+
+struct drm_amdgpu_info_num_handles {
+ /** Max handles as supported by firmware for UVD */
+ __u32 uvd_max_handles;
+ /** Handles currently in use for UVD */
+ __u32 uvd_used_handles;
+};
+
+#define AMDGPU_VCE_CLOCK_TABLE_ENTRIES 6
+
+struct drm_amdgpu_info_vce_clock_table_entry {
+ /** System clock */
+ __u32 sclk;
+ /** Memory clock */
+ __u32 mclk;
+ /** VCE clock */
+ __u32 eclk;
+ __u32 pad;
+};
+
+struct drm_amdgpu_info_vce_clock_table {
+ struct drm_amdgpu_info_vce_clock_table_entry entries[AMDGPU_VCE_CLOCK_TABLE_ENTRIES];
+ __u32 num_valid_entries;
+ __u32 pad;
};
/*
* Supported GPU families
*/
#define AMDGPU_FAMILY_UNKNOWN 0
+#define AMDGPU_FAMILY_SI 110 /* Hainan, Oland, Verde, Pitcairn, Tahiti */
#define AMDGPU_FAMILY_CI 120 /* Bonaire, Hawaii */
#define AMDGPU_FAMILY_KV 125 /* Kaveri, Kabini, Mullins */
#define AMDGPU_FAMILY_VI 130 /* Iceland, Tonga */
#define AMDGPU_FAMILY_CZ 135 /* Carrizo, Stoney */
+#define AMDGPU_FAMILY_AI 141 /* Vega10 */
+#define AMDGPU_FAMILY_RV 142 /* Raven */
#if defined(__cplusplus)
}
diff --git a/include/drm/drm.h b/include/drm/drm.h
index f6fd5c2..f0bd91d 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -641,6 +641,8 @@
#define DRM_CAP_CURSOR_HEIGHT 0x9
#define DRM_CAP_ADDFB2_MODIFIERS 0x10
#define DRM_CAP_PAGE_FLIP_TARGET 0x11
+#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
+#define DRM_CAP_SYNCOBJ 0x13
/** DRM_IOCTL_GET_CAP ioctl argument type */
struct drm_get_cap {
@@ -690,6 +692,67 @@
__s32 fd;
};
+struct drm_syncobj_create {
+ __u32 handle;
+#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0)
+ __u32 flags;
+};
+
+struct drm_syncobj_destroy {
+ __u32 handle;
+ __u32 pad;
+};
+
+#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0)
+#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0)
+struct drm_syncobj_handle {
+ __u32 handle;
+ __u32 flags;
+
+ __s32 fd;
+ __u32 pad;
+};
+
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+struct drm_syncobj_wait {
+ __u64 handles;
+ /* absolute timeout */
+ __s64 timeout_nsec;
+ __u32 count_handles;
+ __u32 flags;
+ __u32 first_signaled; /* only valid when not waiting all */
+ __u32 pad;
+};
+
+struct drm_syncobj_array {
+ __u64 handles;
+ __u32 count_handles;
+ __u32 pad;
+};
+
+/* Query current scanout sequence number */
+struct drm_crtc_get_sequence {
+ __u32 crtc_id; /* requested crtc_id */
+ __u32 active; /* return: crtc output is active */
+ __u64 sequence; /* return: most recent vblank sequence */
+ __s64 sequence_ns; /* return: most recent time of first pixel out */
+};
+
+/* Queue event to be delivered at specified sequence. Time stamp marks
+ * when the first pixel of the refresh cycle leaves the display engine
+ * for the display
+ */
+#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */
+#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */
+
+struct drm_crtc_queue_sequence {
+ __u32 crtc_id;
+ __u32 flags;
+ __u64 sequence; /* on input, target sequence. on output, actual sequence */
+ __u64 user_data; /* user data passed to event */
+};
+
#if defined(__cplusplus)
}
#endif
@@ -772,6 +835,9 @@
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
+#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence)
+#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence)
+
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
@@ -808,6 +874,19 @@
#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob)
#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
+#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create)
+#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
+#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
+#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
+#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
+
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
@@ -838,6 +917,7 @@
#define DRM_EVENT_VBLANK 0x01
#define DRM_EVENT_FLIP_COMPLETE 0x02
+#define DRM_EVENT_CRTC_SEQUENCE 0x03
struct drm_event_vblank {
struct drm_event base;
@@ -845,7 +925,17 @@
__u32 tv_sec;
__u32 tv_usec;
__u32 sequence;
- __u32 reserved;
+ __u32 crtc_id; /* 0 on older kernels that do not support this */
+};
+
+/* Event delivered at sequence. Time stamp marks when the first pixel
+ * of the refresh cycle leaves the display engine for the display
+ */
+struct drm_event_crtc_sequence {
+ struct drm_event base;
+ __u64 user_data;
+ __s64 time_ns;
+ __u64 sequence;
};
/* typedef area */
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 4d8da69..e04613d 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -26,6 +26,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
((__u32)(c) << 16) | ((__u32)(d) << 24))
@@ -37,10 +41,17 @@
/* 8 bpp Red */
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
+/* 16 bpp Red */
+#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */
+
/* 16 bpp RG */
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */
+/* 32 bpp RG */
+#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2') /* [31:0] R:G 16:16 little endian */
+#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] G:R 16:16 little endian */
+
/* 8 bpp RGB */
#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */
#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */
@@ -103,6 +114,20 @@
#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
/*
+ * 2 plane RGB + A
+ * index 0 = RGB plane, same format as the corresponding non _A8 format has
+ * index 1 = A plane, [7:0] A
+ */
+#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8')
+#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8')
+#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8')
+#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8')
+#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8')
+#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8')
+#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8')
+#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8')
+
+/*
* 2 plane YCbCr
* index 0 = Y plane, [7:0] Y
* index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
@@ -150,15 +175,20 @@
/* Vendor Ids: */
#define DRM_FORMAT_MOD_NONE 0
+#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
+#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
/* add more to the end as needed */
+#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:
@@ -168,6 +198,25 @@
* authoritative source for all of these.
*/
+/*
+ * Invalid Modifier
+ *
+ * This modifier can be used as a sentinel to terminate the format modifiers
+ * list, or to initialize a variable with an invalid modifier. It might also be
+ * used to report an error back to userspace for certain APIs.
+ */
+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
+
+/*
+ * Linear Layout
+ *
+ * Just plain linear layout. Note that this is different from no specifying any
+ * modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl),
+ * which tells the driver to also take driver-internal information into account
+ * and so might actually result in a tiled framebuffer.
+ */
+#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
+
/* Intel framebuffer modifiers */
/*
@@ -215,6 +264,26 @@
#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
/*
+ * Intel color control surface (CCS) for render compression
+ *
+ * The framebuffer format must be one of the 8:8:8:8 RGB formats.
+ * The main surface will be plane index 0 and must be Y/Yf-tiled,
+ * the CCS will be plane index 1.
+ *
+ * Each CCS tile matches a 1024x512 pixel area of the main surface.
+ * To match certain aspects of the 3D hardware the CCS is
+ * considered to be made up of normal 128Bx32 Y tiles, Thus
+ * the CCS pitch must be specified in multiples of 128 bytes.
+ *
+ * In reality the CCS tile appears to be a 64Bx64 Y tile, composed
+ * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks.
+ * But that fact is not relevant unless the memory is accessed
+ * directly.
+ */
+#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
+#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
+
+/*
* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
*
* Macroblocks are laid in a Z-shape, and each pixel data is following the
@@ -229,4 +298,115 @@
*/
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+/* Vivante framebuffer modifiers */
+
+/*
+ * Vivante 4x4 tiling layout
+ *
+ * This is a simple tiled layout using tiles of 4x4 pixels in a row-major
+ * layout.
+ */
+#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1)
+
+/*
+ * Vivante 64x64 super-tiling layout
+ *
+ * This is a tiled layout using 64x64 pixel super-tiles, where each super-tile
+ * contains 8x4 groups of 2x4 tiles of 4x4 pixels (like above) each, all in row-
+ * major layout.
+ *
+ * For more information: see
+ * https://github.com/etnaviv/etna_viv/blob/master/doc/hardware.md#texture-tiling
+ */
+#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2)
+
+/*
+ * Vivante 4x4 tiling layout for dual-pipe
+ *
+ * Same as the 4x4 tiling layout, except every second 4x4 pixel tile starts at a
+ * different base address. Offsets from the base addresses are therefore halved
+ * compared to the non-split tiled layout.
+ */
+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3)
+
+/*
+ * Vivante 64x64 super-tiling layout for dual-pipe
+ *
+ * Same as the 64x64 super-tiling layout, except every second 4x4 pixel tile
+ * starts at a different base address. Offsets from the base addresses are
+ * therefore halved compared to the non-split super-tiled layout.
+ */
+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4)
+
+/* 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 DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1)
+
+/*
+ * 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.
+ *
+ * Within a GOB, data is ordered as 16B x 2 lines sectors laid in Z-shape.
+ *
+ * Parameter 'v' is the log2 encoding of the number of GOBs stacked vertically.
+ * Valid values are:
+ *
+ * 0 == ONE_GOB
+ * 1 == TWO_GOBS
+ * 2 == FOUR_GOBS
+ * 3 == EIGHT_GOBS
+ * 4 == SIXTEEN_GOBS
+ * 5 == THIRTYTWO_GOBS
+ *
+ * Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format
+ * in full detail.
+ */
+#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
+ *
+ * This is the primary layout that the V3D GPU can texture from (it
+ * can't do linear). The T format has:
+ *
+ * - 64b utiles of pixels in a raster-order grid according to cpp. It's 4x4
+ * pixels at 32 bit depth.
+ *
+ * - 1k subtiles made of a 4x4 raster-order grid of 64b utiles (so usually
+ * 16x16 pixels).
+ *
+ * - 4k tiles made of a 2x2 grid of 1k subtiles (so usually 32x32 pixels). On
+ * even 4k tile rows, they're arranged as (BL, TL, TR, BR), and on odd rows
+ * they're (TR, BR, BL, TL), where bottom left is start of memory.
+ *
+ * - an image made of 4k tiles in rows either left-to-right (even rows of 4k
+ * tiles) or right-to-left (odd rows of 4k tiles).
+ */
+#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1)
+
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* DRM_FOURCC_H */
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 6708e2b..74368de 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -38,16 +38,24 @@
#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)
/* Video mode flags */
-/* bit compatible with the xorg definitions. */
+/* bit compatible with the xrandr RR_ definitions (bits 0-13)
+ *
+ * ABI warning: Existing userspace really expects
+ * the mode flags to match the xrandr definitions. Any
+ * changes that don't match the xrandr definitions will
+ * likely need a new client cap or some other mechanism
+ * to avoid breaking existing userspace. This includes
+ * allocating new flags in the previously unused bits!
+ */
#define DRM_MODE_FLAG_PHSYNC (1<<0)
#define DRM_MODE_FLAG_NHSYNC (1<<1)
#define DRM_MODE_FLAG_PVSYNC (1<<2)
@@ -58,8 +66,8 @@
#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)
/*
@@ -67,7 +75,7 @@
* (define not exposed to user space).
*/
#define DRM_MODE_FLAG_3D_MASK (0x1f<<14)
-#define DRM_MODE_FLAG_3D_NONE (0<<14)
+#define DRM_MODE_FLAG_3D_NONE (0<<14)
#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14)
#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14)
#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14)
@@ -77,6 +85,19 @@
#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14)
#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14)
+/* Picture aspect ratio options */
+#define DRM_MODE_PICTURE_ASPECT_NONE 0
+#define DRM_MODE_PICTURE_ASPECT_4_3 1
+#define DRM_MODE_PICTURE_ASPECT_16_9 2
+
+/* Aspect ratio flag bitmask (4 bits 22:19) */
+#define DRM_MODE_FLAG_PIC_AR_MASK (0x0F<<19)
+#define DRM_MODE_FLAG_PIC_AR_NONE \
+ (DRM_MODE_PICTURE_ASPECT_NONE<<19)
+#define DRM_MODE_FLAG_PIC_AR_4_3 \
+ (DRM_MODE_PICTURE_ASPECT_4_3<<19)
+#define DRM_MODE_FLAG_PIC_AR_16_9 \
+ (DRM_MODE_PICTURE_ASPECT_16_9<<19)
/* DPMS flags */
/* bit compatible with the xorg definitions. */
@@ -92,11 +113,6 @@
#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */
#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */
-/* Picture aspect ratio options */
-#define DRM_MODE_PICTURE_ASPECT_NONE 0
-#define DRM_MODE_PICTURE_ASPECT_4_3 1
-#define DRM_MODE_PICTURE_ASPECT_16_9 2
-
/* Dithering mode options */
#define DRM_MODE_DITHERING_OFF 0
#define DRM_MODE_DITHERING_ON 1
@@ -107,13 +123,73 @@
#define DRM_MODE_DIRTY_ON 1
#define DRM_MODE_DIRTY_ANNOTATE 2
+/* Link Status options */
+#define DRM_MODE_LINK_STATUS_GOOD 0
+#define DRM_MODE_LINK_STATUS_BAD 1
+
+/*
+ * DRM_MODE_ROTATE_<degrees>
+ *
+ * Signals that a drm plane is been rotated <degrees> degrees in counter
+ * clockwise direction.
+ *
+ * This define is provided as a convenience, looking up the property id
+ * using the name->prop id lookup is the preferred method.
+ */
+#define DRM_MODE_ROTATE_0 (1<<0)
+#define DRM_MODE_ROTATE_90 (1<<1)
+#define DRM_MODE_ROTATE_180 (1<<2)
+#define DRM_MODE_ROTATE_270 (1<<3)
+
+/*
+ * DRM_MODE_ROTATE_MASK
+ *
+ * Bitmask used to look for drm plane rotations.
+ */
+#define DRM_MODE_ROTATE_MASK (\
+ DRM_MODE_ROTATE_0 | \
+ DRM_MODE_ROTATE_90 | \
+ DRM_MODE_ROTATE_180 | \
+ DRM_MODE_ROTATE_270)
+
+/*
+ * DRM_MODE_REFLECT_<axis>
+ *
+ * Signals that the contents of a drm plane is reflected in the <axis> axis,
+ * in the same way as mirroring.
+ *
+ * This define is provided as a convenience, looking up the property id
+ * using the name->prop id lookup is the preferred method.
+ */
+#define DRM_MODE_REFLECT_X (1<<4)
+#define DRM_MODE_REFLECT_Y (1<<5)
+
+/*
+ * DRM_MODE_REFLECT_MASK
+ *
+ * Bitmask used to look for drm plane reflections.
+ */
+#define DRM_MODE_REFLECT_MASK (\
+ DRM_MODE_REFLECT_X | \
+ DRM_MODE_REFLECT_Y)
+
+
+/*
+ * Legacy definitions for old code that doesn't use
+ * the above mask definitions. Don't use in future code.
+ */
/* rotation property bits */
-#define DRM_ROTATE_0 0
-#define DRM_ROTATE_90 1
-#define DRM_ROTATE_180 2
-#define DRM_ROTATE_270 3
-#define DRM_REFLECT_X 4
-#define DRM_REFLECT_Y 5
+#define DRM_ROTATE_0 0
+#define DRM_ROTATE_90 1
+#define DRM_ROTATE_180 2
+#define DRM_ROTATE_270 3
+#define DRM_REFLECT_X 4
+#define DRM_REFLECT_Y 5
+
+/* 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;
@@ -228,14 +304,16 @@
/* This is for connectors with multiple signal types. */
/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
-#define DRM_MODE_SUBCONNECTOR_Automatic 0
-#define DRM_MODE_SUBCONNECTOR_Unknown 0
-#define DRM_MODE_SUBCONNECTOR_DVID 3
-#define DRM_MODE_SUBCONNECTOR_DVIA 4
-#define DRM_MODE_SUBCONNECTOR_Composite 5
-#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
-#define DRM_MODE_SUBCONNECTOR_Component 8
-#define DRM_MODE_SUBCONNECTOR_SCART 9
+enum drm_mode_subconnector {
+ DRM_MODE_SUBCONNECTOR_Automatic = 0,
+ DRM_MODE_SUBCONNECTOR_Unknown = 0,
+ DRM_MODE_SUBCONNECTOR_DVID = 3,
+ DRM_MODE_SUBCONNECTOR_DVIA = 4,
+ DRM_MODE_SUBCONNECTOR_Composite = 5,
+ DRM_MODE_SUBCONNECTOR_SVIDEO = 6,
+ DRM_MODE_SUBCONNECTOR_Component = 8,
+ DRM_MODE_SUBCONNECTOR_SCART = 9,
+};
#define DRM_MODE_CONNECTOR_Unknown 0
#define DRM_MODE_CONNECTOR_VGA 1
@@ -280,7 +358,7 @@
__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 */
@@ -400,17 +478,20 @@
* offsets[1]. Note that offsets[0] will generally
* be 0 (but this is not required).
*
- * To accommodate tiled, compressed, etc formats, a per-plane
+ * To accommodate tiled, compressed, etc formats, a
* modifier can be specified. The default value of zero
* indicates "native" format as specified by the fourcc.
- * Vendor specific modifier token. This allows, for example,
- * different tiling/swizzling pattern on different planes.
- * See discussion above of DRM_FORMAT_MOD_xxx.
+ * Vendor specific modifier token. Note that even though
+ * it looks like we have a modifier per-plane, we in fact
+ * do not. The modifier for each plane must be identical.
+ * Thus all combinations of different data layouts for
+ * multi plane formats must be enumerated as separate
+ * modifiers.
*/
__u32 handles[4];
__u32 pitches[4]; /* pitch for each plane */
__u32 offsets[4]; /* offset of each plane */
- __u64 modifier[4]; /* ie, tiling, compressed (per plane) */
+ __u64 modifier[4]; /* ie, tiling, compress */
};
#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
@@ -512,8 +593,11 @@
};
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 {
@@ -637,13 +721,6 @@
DRM_MODE_ATOMIC_NONBLOCK |\
DRM_MODE_ATOMIC_ALLOW_MODESET)
-#define DRM_MODE_ATOMIC_FLAGS (\
- DRM_MODE_PAGE_FLIP_EVENT |\
- DRM_MODE_PAGE_FLIP_ASYNC |\
- DRM_MODE_ATOMIC_TEST_ONLY |\
- DRM_MODE_ATOMIC_NONBLOCK |\
- DRM_MODE_ATOMIC_ALLOW_MODESET)
-
struct drm_mode_atomic {
__u32 flags;
__u32 count_objs;
@@ -655,6 +732,56 @@
__u64 user_data;
};
+struct drm_format_modifier_blob {
+#define FORMAT_BLOB_CURRENT 1
+ /* Version of this blob format */
+ __u32 version;
+
+ /* Flags */
+ __u32 flags;
+
+ /* Number of fourcc formats supported */
+ __u32 count_formats;
+
+ /* Where in this blob the formats exist (in bytes) */
+ __u32 formats_offset;
+
+ /* Number of drm_format_modifiers */
+ __u32 count_modifiers;
+
+ /* Where in this blob the modifiers exist (in bytes) */
+ __u32 modifiers_offset;
+
+ /* __u32 formats[] */
+ /* struct drm_format_modifier modifiers[] */
+};
+
+struct drm_format_modifier {
+ /* Bitmask of formats in get_plane format list this info applies to. The
+ * offset allows a sliding window of which 64 formats (bits).
+ *
+ * Some examples:
+ * In today's world with < 65 formats, and formats 0, and 2 are
+ * supported
+ * 0x0000000000000005
+ * ^-offset = 0, formats = 5
+ *
+ * If the number formats grew to 128, and formats 98-102 are
+ * supported with the modifier:
+ *
+ * 0x0000007c00000000 0000000000000000
+ * ^
+ * |__offset = 64, formats = 0x7c00000000
+ *
+ */
+ __u64 formats;
+ __u32 offset;
+ __u32 pad;
+
+ /* The modifier that applies to the >get_plane format list bitmask. */
+ __u64 modifier;
+};
+
/**
* Create a new 'blob' data property, copying length bytes from data pointer,
* and returning new blob ID.
@@ -675,6 +802,72 @@
__u32 blob_id;
};
+/**
+ * Lease mode resources, creating another drm_master.
+ */
+struct drm_mode_create_lease {
+ /** Pointer to array of object ids (__u32) */
+ __u64 object_ids;
+ /** Number of object ids */
+ __u32 object_count;
+ /** flags for new FD (O_CLOEXEC, etc) */
+ __u32 flags;
+
+ /** Return: unique identifier for lessee. */
+ __u32 lessee_id;
+ /** Return: file descriptor to new drm_master file */
+ __u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+ /** Number of lessees.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_lessees;
+ __u32 pad;
+
+ /** Pointer to lessees.
+ * pointer to __u64 array of lessee ids
+ */
+ __u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects
+ */
+struct drm_mode_get_lease {
+ /** Number of leased objects.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_objects;
+ __u32 pad;
+
+ /** Pointer to objects.
+ * pointer to __u32 array of object ids
+ */
+ __u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+ /** Unique ID of lessee
+ */
+ __u32 lessee_id;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/drm/drm_sarea.h b/include/drm/drm_sarea.h
index 502934e..93025be 100644
--- a/include/drm/drm_sarea.h
+++ b/include/drm/drm_sarea.h
@@ -34,6 +34,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* SAREA area needs to be at least a page */
#if defined(__alpha__)
#define SAREA_MAX 0x2000U
@@ -81,4 +85,8 @@
typedef struct drm_sarea_frame drm_sarea_frame_t;
typedef struct drm_sarea drm_sarea_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* _DRM_SAREA_H_ */
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 5ebe046..16e452a 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -86,6 +86,62 @@
I915_MOCS_CACHED,
};
+/*
+ * Different engines serve different roles, and there may be more than one
+ * engine serving each role. enum drm_i915_gem_engine_class provides a
+ * classification of the role of the engine, which may be used when requesting
+ * operations to be performed on a certain subset of engines, or for providing
+ * information about that group.
+ */
+enum drm_i915_gem_engine_class {
+ I915_ENGINE_CLASS_RENDER = 0,
+ I915_ENGINE_CLASS_COPY = 1,
+ I915_ENGINE_CLASS_VIDEO = 2,
+ I915_ENGINE_CLASS_VIDEO_ENHANCE = 3,
+
+ I915_ENGINE_CLASS_INVALID = -1
+};
+
+/**
+ * DOC: perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915
+ *
+ */
+
+enum drm_i915_pmu_engine_sample {
+ I915_SAMPLE_BUSY = 0,
+ I915_SAMPLE_WAIT = 1,
+ I915_SAMPLE_SEMA = 2
+};
+
+#define I915_PMU_SAMPLE_BITS (4)
+#define I915_PMU_SAMPLE_MASK (0xf)
+#define I915_PMU_SAMPLE_INSTANCE_BITS (8)
+#define I915_PMU_CLASS_SHIFT \
+ (I915_PMU_SAMPLE_BITS + I915_PMU_SAMPLE_INSTANCE_BITS)
+
+#define __I915_PMU_ENGINE(class, instance, sample) \
+ ((class) << I915_PMU_CLASS_SHIFT | \
+ (instance) << I915_PMU_SAMPLE_BITS | \
+ (sample))
+
+#define I915_PMU_ENGINE_BUSY(class, instance) \
+ __I915_PMU_ENGINE(class, instance, I915_SAMPLE_BUSY)
+
+#define I915_PMU_ENGINE_WAIT(class, instance) \
+ __I915_PMU_ENGINE(class, instance, I915_SAMPLE_WAIT)
+
+#define I915_PMU_ENGINE_SEMA(class, instance) \
+ __I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA)
+
+#define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x))
+
+#define I915_PMU_ACTUAL_FREQUENCY __I915_PMU_OTHER(0)
+#define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1)
+#define I915_PMU_INTERRUPTS __I915_PMU_OTHER(2)
+#define I915_PMU_RC6_RESIDENCY __I915_PMU_OTHER(3)
+
+#define I915_PMU_LAST I915_PMU_RC6_RESIDENCY
+
/* Each region is a minimum of 16k, and there are at most 255 of them.
*/
#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use
@@ -260,6 +316,9 @@
#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
#define DRM_I915_PERF_OPEN 0x36
+#define DRM_I915_PERF_ADD_CONFIG 0x37
+#define DRM_I915_PERF_REMOVE_CONFIG 0x38
+#define DRM_I915_QUERY 0x39
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -315,6 +374,9 @@
#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
+#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
+#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
+#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -393,10 +455,20 @@
#define I915_PARAM_MIN_EU_IN_POOL 39
#define I915_PARAM_MMAP_GTT_VERSION 40
-/* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution
+/*
+ * Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution
* priorities and the driver will attempt to execute batches in priority order.
+ * The param returns a capability bitmask, nonzero implies that the scheduler
+ * is enabled, with different features present according to the mask.
+ *
+ * The initial priority for each batch is supplied by the context and is
+ * controlled via I915_CONTEXT_PARAM_PRIORITY.
*/
#define I915_PARAM_HAS_SCHEDULER 41
+#define I915_SCHEDULER_CAP_ENABLED (1ul << 0)
+#define I915_SCHEDULER_CAP_PRIORITY (1ul << 1)
+#define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2)
+
#define I915_PARAM_HUC_STATUS 42
/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to opt-out of
@@ -412,6 +484,51 @@
*/
#define I915_PARAM_HAS_EXEC_FENCE 44
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to capture
+ * user specified bufffers for post-mortem debugging of GPU hangs. See
+ * EXEC_OBJECT_CAPTURE.
+ */
+#define I915_PARAM_HAS_EXEC_CAPTURE 45
+
+#define I915_PARAM_SLICE_MASK 46
+
+/* Assuming it's uniform for each slice, this queries the mask of subslices
+ * per-slice for this system.
+ */
+#define I915_PARAM_SUBSLICE_MASK 47
+
+/*
+ * Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying the batch buffer
+ * as the first execobject as opposed to the last. See I915_EXEC_BATCH_FIRST.
+ */
+#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48
+
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY.
+ */
+#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
+
+/*
+ * Query whether every context (both per-file default and user created) is
+ * isolated (insofar as HW supports). If this parameter is not true, then
+ * freshly created contexts may inherit values from an existing context,
+ * rather than default HW values. If true, it also ensures (insofar as HW
+ * supports) that all state set by this context will not leak to any other
+ * context.
+ *
+ * As not every engine across every gen support contexts, the returned
+ * value reports the support of context isolation for individual engines by
+ * returning a bitmask of each engine class set to true if that class supports
+ * isolation.
+ */
+#define I915_PARAM_HAS_CONTEXT_ISOLATION 50
+
+/* Frequency of the command streamer timestamps given by the *_TIMESTAMP
+ * registers. This used to be fixed per platform but from CNL onwards, this
+ * might vary depending on the parts.
+ */
+#define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51
+
typedef struct drm_i915_getparam {
__s32 param;
/*
@@ -666,6 +783,8 @@
#define I915_GEM_DOMAIN_VERTEX 0x00000020
/** GTT domain - aperture and scanout */
#define I915_GEM_DOMAIN_GTT 0x00000040
+/** WC domain - uncached access */
+#define I915_GEM_DOMAIN_WC 0x00000080
/** @} */
struct drm_i915_gem_exec_object {
@@ -773,8 +892,15 @@
* I915_PARAM_HAS_EXEC_FENCE to order execbufs and execute them asynchronously.
*/
#define EXEC_OBJECT_ASYNC (1<<6)
+/* Request that the contents of this execobject be copied into the error
+ * state upon a GPU hang involving this batch for post-mortem debugging.
+ * These buffers are recorded in no particular order as "user" in
+ * /sys/class/drm/cardN/error. Query I915_PARAM_HAS_EXEC_CAPTURE to see
+ * if the kernel supports this flag.
+ */
+#define EXEC_OBJECT_CAPTURE (1<<7)
/* All remaining bits are MBZ and RESERVED FOR FUTURE USE */
-#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_ASYNC<<1)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_CAPTURE<<1)
__u64 flags;
union {
@@ -784,6 +910,18 @@
__u64 rsvd2;
};
+struct drm_i915_gem_exec_fence {
+ /**
+ * User's handle for a drm_syncobj to wait on or signal.
+ */
+ __u32 handle;
+
+#define I915_EXEC_FENCE_WAIT (1<<0)
+#define I915_EXEC_FENCE_SIGNAL (1<<1)
+#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
+ __u32 flags;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -798,7 +936,11 @@
__u32 DR1;
__u32 DR4;
__u32 num_cliprects;
- /** This is a struct drm_clip_rect *cliprects */
+ /**
+ * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
+ * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
+ * struct drm_i915_gem_exec_fence *fences.
+ */
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (7<<0)
#define I915_EXEC_DEFAULT (0<<0)
@@ -889,7 +1031,24 @@
*/
#define I915_EXEC_FENCE_OUT (1<<17)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_OUT<<1))
+/*
+ * Traditionally the execbuf ioctl has only considered the final element in
+ * the execobject[] to be the executable batch. Often though, the client
+ * will known the batch object prior to construction and being able to place
+ * it into the execobject[] array first can simplify the relocation tracking.
+ * Setting I915_EXEC_BATCH_FIRST tells execbuf to use element 0 of the
+ * execobject[] as the * batch instead (the default is to use the last
+ * element).
+ */
+#define I915_EXEC_BATCH_FIRST (1<<18)
+
+/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr
+ * define an array of i915_gem_exec_fence structures which specify a set of
+ * dma fences to wait upon or signal.
+ */
+#define I915_EXEC_FENCE_ARRAY (1<<19)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
@@ -1201,7 +1360,9 @@
* active on a given plane.
*/
-#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */
+#define I915_SET_COLORKEY_NONE (1<<0) /* Deprecated. Instead set
+ * flags==0 to disable colorkeying.
+ */
#define I915_SET_COLORKEY_DESTINATION (1<<1)
#define I915_SET_COLORKEY_SOURCE (1<<2)
struct drm_intel_sprite_colorkey {
@@ -1239,14 +1400,16 @@
* be specified
*/
__u64 offset;
+#define I915_REG_READ_8B_WA (1ul << 0)
+
__u64 val; /* Return value */
};
/* Known registers:
*
* Render engine timestamp - 0x2358 + 64bit - gen7+
* - Note this register returns an invalid value if using the default
- * single instruction 8byte read, in order to workaround that use
- * offset (0x2538 | 1) instead.
+ * single instruction 8byte read, in order to workaround that pass
+ * flag I915_REG_READ_8B_WA in offset field.
*
*/
@@ -1289,17 +1452,26 @@
#define I915_CONTEXT_PARAM_GTT_SIZE 0x3
#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
#define I915_CONTEXT_PARAM_BANNABLE 0x5
+#define I915_CONTEXT_PARAM_PRIORITY 0x6
+#define I915_CONTEXT_MAX_USER_PRIORITY 1023 /* inclusive */
+#define I915_CONTEXT_DEFAULT_PRIORITY 0
+#define I915_CONTEXT_MIN_USER_PRIORITY -1023 /* inclusive */
__u64 value;
};
enum drm_i915_oa_format {
- I915_OA_FORMAT_A13 = 1,
- I915_OA_FORMAT_A29,
- I915_OA_FORMAT_A13_B8_C8,
- I915_OA_FORMAT_B4_C8,
- I915_OA_FORMAT_A45_B8_C8,
- I915_OA_FORMAT_B4_C8_A16,
- I915_OA_FORMAT_C4_B8,
+ I915_OA_FORMAT_A13 = 1, /* HSW only */
+ I915_OA_FORMAT_A29, /* HSW only */
+ I915_OA_FORMAT_A13_B8_C8, /* HSW only */
+ I915_OA_FORMAT_B4_C8, /* HSW only */
+ I915_OA_FORMAT_A45_B8_C8, /* HSW only */
+ I915_OA_FORMAT_B4_C8_A16, /* HSW only */
+ I915_OA_FORMAT_C4_B8, /* HSW+ */
+
+ /* Gen8+ */
+ I915_OA_FORMAT_A12,
+ I915_OA_FORMAT_A12_B8_C8,
+ I915_OA_FORMAT_A32u40_A4u32_B8_C8,
I915_OA_FORMAT_MAX /* non-ABI */
};
@@ -1424,6 +1596,127 @@
DRM_I915_PERF_RECORD_MAX /* non-ABI */
};
+/**
+ * Structure to upload perf dynamic configuration into the kernel.
+ */
+struct drm_i915_perf_oa_config {
+ /** String formatted like "%08x-%04x-%04x-%04x-%012x" */
+ char uuid[36];
+
+ __u32 n_mux_regs;
+ __u32 n_boolean_regs;
+ __u32 n_flex_regs;
+
+ /*
+ * These fields are pointers to tuples of u32 values (register address,
+ * value). For example the expected length of the buffer pointed by
+ * mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
+ */
+ __u64 mux_regs_ptr;
+ __u64 boolean_regs_ptr;
+ __u64 flex_regs_ptr;
+};
+
+struct drm_i915_query_item {
+ __u64 query_id;
+#define DRM_I915_QUERY_TOPOLOGY_INFO 1
+
+ /*
+ * When set to zero by userspace, this is filled with the size of the
+ * data to be written at the data_ptr pointer. The kernel sets this
+ * value to a negative value to signal an error on a particular query
+ * item.
+ */
+ __s32 length;
+
+ /*
+ * Unused for now. Must be cleared to zero.
+ */
+ __u32 flags;
+
+ /*
+ * Data will be written at the location pointed by data_ptr when the
+ * value of length matches the length of the data to be written by the
+ * kernel.
+ */
+ __u64 data_ptr;
+};
+
+struct drm_i915_query {
+ __u32 num_items;
+
+ /*
+ * Unused for now. Must be cleared to zero.
+ */
+ __u32 flags;
+
+ /*
+ * This points to an array of num_items drm_i915_query_item structures.
+ */
+ __u64 items_ptr;
+};
+
+/*
+ * Data written by the kernel with query DRM_I915_QUERY_TOPOLOGY_INFO :
+ *
+ * data: contains the 3 pieces of information :
+ *
+ * - the slice mask with one bit per slice telling whether a slice is
+ * available. The availability of slice X can be queried with the following
+ * formula :
+ *
+ * (data[X / 8] >> (X % 8)) & 1
+ *
+ * - the subslice mask for each slice with one bit per subslice telling
+ * whether a subslice is available. The availability of subslice Y in slice
+ * X can be queried with the following formula :
+ *
+ * (data[subslice_offset +
+ * X * subslice_stride +
+ * Y / 8] >> (Y % 8)) & 1
+ *
+ * - the EU mask for each subslice in each slice with one bit per EU telling
+ * whether an EU is available. The availability of EU Z in subslice Y in
+ * slice X can be queried with the following formula :
+ *
+ * (data[eu_offset +
+ * (X * max_subslices + Y) * eu_stride +
+ * Z / 8] >> (Z % 8)) & 1
+ */
+struct drm_i915_query_topology_info {
+ /*
+ * Unused for now. Must be cleared to zero.
+ */
+ __u16 flags;
+
+ __u16 max_slices;
+ __u16 max_subslices;
+ __u16 max_eus_per_subslice;
+
+ /*
+ * Offset in data[] at which the subslice masks are stored.
+ */
+ __u16 subslice_offset;
+
+ /*
+ * Stride at which each of the subslice masks for each slice are
+ * stored.
+ */
+ __u16 subslice_stride;
+
+ /*
+ * Offset in data[] at which the EU masks are stored.
+ */
+ __u16 eu_offset;
+
+ /*
+ * Stride at which each of the EU masks for each subslice are stored.
+ */
+ __u16 eu_stride;
+
+ __u8 data[];
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h
index b630e8f..7930011 100644
--- a/include/drm/mga_drm.h
+++ b/include/drm/mga_drm.h
@@ -37,6 +37,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (mga_sarea.h)
*/
@@ -107,7 +111,7 @@
*/
#define MGA_NR_SAREA_CLIPRECTS 8
-/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+/* 2 heaps (1 for card, 1 for agp), each divided into up to 128
* regions, subject to a minimum region size of (1<<16) == 64k.
*
* Clients may subdivide regions internally, but when sharing between
@@ -248,7 +252,7 @@
#define DRM_MGA_DMA_BOOTSTRAP 0x0c
#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
-#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock)
#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t)
@@ -416,4 +420,8 @@
void *value;
} drm_mga_getparam_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h
index 1372f53..91d2f31 100644
--- a/include/drm/nouveau_drm.h
+++ b/include/drm/nouveau_drm.h
@@ -27,6 +27,12 @@
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 16
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* reserved object handles when using deprecated object APIs - these
* are here so that libdrm can allow interoperability with the new
* object APIs
@@ -106,6 +112,7 @@
#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
@@ -113,13 +120,13 @@
#define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008
struct drm_nouveau_gem_info {
- uint32_t handle;
- uint32_t domain;
- uint64_t size;
- uint64_t offset;
- uint64_t map_handle;
- uint32_t tile_mode;
- uint32_t tile_flags;
+ __u32 handle;
+ __u32 domain;
+ __u64 size;
+ __u64 offset;
+ __u64 map_handle;
+ __u32 tile_mode;
+ __u32 tile_flags;
};
struct drm_nouveau_gem_set_tiling {
@@ -130,23 +137,23 @@
struct drm_nouveau_gem_new {
struct drm_nouveau_gem_info info;
- uint32_t channel_hint;
- uint32_t align;
+ __u32 channel_hint;
+ __u32 align;
};
#define NOUVEAU_GEM_MAX_BUFFERS 1024
struct drm_nouveau_gem_pushbuf_bo_presumed {
- uint32_t valid;
- uint32_t domain;
- uint64_t offset;
+ __u32 valid;
+ __u32 domain;
+ __u64 offset;
};
struct drm_nouveau_gem_pushbuf_bo {
- uint64_t user_priv;
- uint32_t handle;
- uint32_t read_domains;
- uint32_t write_domains;
- uint32_t valid_domains;
+ __u64 user_priv;
+ __u32 handle;
+ __u32 read_domains;
+ __u32 write_domains;
+ __u32 valid_domains;
struct drm_nouveau_gem_pushbuf_bo_presumed presumed;
};
@@ -155,35 +162,35 @@
#define NOUVEAU_GEM_RELOC_OR (1 << 2)
#define NOUVEAU_GEM_MAX_RELOCS 1024
struct drm_nouveau_gem_pushbuf_reloc {
- uint32_t reloc_bo_index;
- uint32_t reloc_bo_offset;
- uint32_t bo_index;
- uint32_t flags;
- uint32_t data;
- uint32_t vor;
- uint32_t tor;
+ __u32 reloc_bo_index;
+ __u32 reloc_bo_offset;
+ __u32 bo_index;
+ __u32 flags;
+ __u32 data;
+ __u32 vor;
+ __u32 tor;
};
#define NOUVEAU_GEM_MAX_PUSH 512
struct drm_nouveau_gem_pushbuf_push {
- uint32_t bo_index;
- uint32_t pad;
- uint64_t offset;
- uint64_t length;
+ __u32 bo_index;
+ __u32 pad;
+ __u64 offset;
+ __u64 length;
};
struct drm_nouveau_gem_pushbuf {
- uint32_t channel;
- uint32_t nr_buffers;
- uint64_t buffers;
- uint32_t nr_relocs;
- uint32_t nr_push;
- uint64_t relocs;
- uint64_t push;
- uint32_t suffix0;
- uint32_t suffix1;
- uint64_t vram_available;
- uint64_t gart_available;
+ __u32 channel;
+ __u32 nr_buffers;
+ __u64 buffers;
+ __u32 nr_relocs;
+ __u32 nr_push;
+ __u64 relocs;
+ __u64 push;
+ __u32 suffix0;
+ __u32 suffix1;
+ __u64 vram_available;
+ __u64 gart_available;
};
#define NOUVEAU_GEM_PUSHBUF_2_FENCE_WAIT 0x00000001
@@ -205,12 +212,12 @@
#define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002
#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004
struct drm_nouveau_gem_cpu_prep {
- uint32_t handle;
- uint32_t flags;
+ __u32 handle;
+ __u32 flags;
};
struct drm_nouveau_gem_cpu_fini {
- uint32_t handle;
+ __u32 handle;
};
#define NOUVEAU_GEM_AS_SPARSE 0x00000001
@@ -287,4 +294,7 @@
#define DRM_NOUVEAU_GEM_MAP 0x56
#define DRM_NOUVEAU_GEM_UNMAP 0x57
+#if defined(__cplusplus)
+}
+#endif
#endif /* __NOUVEAU_DRM_H__ */
diff --git a/include/drm/qxl_drm.h b/include/drm/qxl_drm.h
index 1e331a8..38a0dbd 100644
--- a/include/drm/qxl_drm.h
+++ b/include/drm/qxl_drm.h
@@ -27,10 +27,14 @@
#include <stddef.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.
*
- * Do not use pointers, use uint64_t instead for 32 bit / 64 bit user/kernel
+ * Do not use pointers, use __u64 instead for 32 bit / 64 bit user/kernel
* compatibility Keep fields aligned to their size
*/
@@ -48,14 +52,14 @@
#define DRM_QXL_ALLOC_SURF 0x06
struct drm_qxl_alloc {
- uint32_t size;
- uint32_t handle; /* 0 is an invalid handle */
+ __u32 size;
+ __u32 handle; /* 0 is an invalid handle */
};
struct drm_qxl_map {
- uint64_t offset; /* use for mmap system call */
- uint32_t handle;
- uint32_t pad;
+ __u64 offset; /* use for mmap system call */
+ __u32 handle;
+ __u32 pad;
};
/*
@@ -68,59 +72,59 @@
#define QXL_RELOC_TYPE_SURF 2
struct drm_qxl_reloc {
- uint64_t src_offset; /* offset into src_handle or src buffer */
- uint64_t dst_offset; /* offset in dest handle */
- uint32_t src_handle; /* dest handle to compute address from */
- uint32_t dst_handle; /* 0 if to command buffer */
- uint32_t reloc_type;
- uint32_t pad;
+ __u64 src_offset; /* offset into src_handle or src buffer */
+ __u64 dst_offset; /* offset in dest handle */
+ __u32 src_handle; /* dest handle to compute address from */
+ __u32 dst_handle; /* 0 if to command buffer */
+ __u32 reloc_type;
+ __u32 pad;
};
struct drm_qxl_command {
- uint64_t command; /* void* */
- uint64_t relocs; /* struct drm_qxl_reloc* */
- uint32_t type;
- uint32_t command_size;
- uint32_t relocs_num;
- uint32_t pad;
+ __u64 command; /* void* */
+ __u64 relocs; /* struct drm_qxl_reloc* */
+ __u32 type;
+ __u32 command_size;
+ __u32 relocs_num;
+ __u32 pad;
};
/* XXX: call it drm_qxl_commands? */
struct drm_qxl_execbuffer {
- uint32_t flags; /* for future use */
- uint32_t commands_num;
- uint64_t commands; /* struct drm_qxl_command* */
+ __u32 flags; /* for future use */
+ __u32 commands_num;
+ __u64 commands; /* struct drm_qxl_command* */
};
struct drm_qxl_update_area {
- uint32_t handle;
- uint32_t top;
- uint32_t left;
- uint32_t bottom;
- uint32_t right;
- uint32_t pad;
+ __u32 handle;
+ __u32 top;
+ __u32 left;
+ __u32 bottom;
+ __u32 right;
+ __u32 pad;
};
#define QXL_PARAM_NUM_SURFACES 1 /* rom->n_surfaces */
#define QXL_PARAM_MAX_RELOCS 2
struct drm_qxl_getparam {
- uint64_t param;
- uint64_t value;
+ __u64 param;
+ __u64 value;
};
/* these are one bit values */
struct drm_qxl_clientcap {
- uint32_t index;
- uint32_t pad;
+ __u32 index;
+ __u32 pad;
};
struct drm_qxl_alloc_surf {
- uint32_t format;
- uint32_t width;
- uint32_t height;
- int32_t stride;
- uint32_t handle;
- uint32_t pad;
+ __u32 format;
+ __u32 width;
+ __u32 height;
+ __s32 stride;
+ __u32 handle;
+ __u32 pad;
};
#define DRM_IOCTL_QXL_ALLOC \
@@ -149,4 +153,8 @@
DRM_IOWR(DRM_COMMAND_BASE + DRM_QXL_ALLOC_SURF,\
struct drm_qxl_alloc_surf)
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/r128_drm.h b/include/drm/r128_drm.h
index ede78ff..bf431a0 100644
--- a/include/drm/r128_drm.h
+++ b/include/drm/r128_drm.h
@@ -33,6 +33,12 @@
#ifndef __R128_DRM_H__
#define __R128_DRM_H__
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* WARNING: If you change any of these defines, make sure to change the
* defines in the X server file (r128_sarea.h)
*/
@@ -323,4 +329,8 @@
void *value;
} drm_r128_getparam_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index f09cc04..a1e385d 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -797,9 +797,9 @@
#define RADEON_GEM_DOMAIN_VRAM 0x4
struct drm_radeon_gem_info {
- uint64_t gart_size;
- uint64_t vram_size;
- uint64_t vram_visible;
+ __u64 gart_size;
+ __u64 vram_size;
+ __u64 vram_visible;
};
#define RADEON_GEM_NO_BACKING_STORE (1 << 0)
@@ -811,11 +811,11 @@
#define RADEON_GEM_NO_CPU_ACCESS (1 << 4)
struct drm_radeon_gem_create {
- uint64_t size;
- uint64_t alignment;
- uint32_t handle;
- uint32_t initial_domain;
- uint32_t flags;
+ __u64 size;
+ __u64 alignment;
+ __u32 handle;
+ __u32 initial_domain;
+ __u32 flags;
};
/*
@@ -829,10 +829,10 @@
#define RADEON_GEM_USERPTR_REGISTER (1 << 3)
struct drm_radeon_gem_userptr {
- uint64_t addr;
- uint64_t size;
- uint32_t flags;
- uint32_t handle;
+ __u64 addr;
+ __u64 size;
+ __u32 flags;
+ __u32 handle;
};
#define RADEON_TILING_MACRO 0x1
@@ -855,72 +855,72 @@
#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK 0xf
struct drm_radeon_gem_set_tiling {
- uint32_t handle;
- uint32_t tiling_flags;
- uint32_t pitch;
+ __u32 handle;
+ __u32 tiling_flags;
+ __u32 pitch;
};
struct drm_radeon_gem_get_tiling {
- uint32_t handle;
- uint32_t tiling_flags;
- uint32_t pitch;
+ __u32 handle;
+ __u32 tiling_flags;
+ __u32 pitch;
};
struct drm_radeon_gem_mmap {
- uint32_t handle;
- uint32_t pad;
- uint64_t offset;
- uint64_t size;
- uint64_t addr_ptr;
+ __u32 handle;
+ __u32 pad;
+ __u64 offset;
+ __u64 size;
+ __u64 addr_ptr;
};
struct drm_radeon_gem_set_domain {
- uint32_t handle;
- uint32_t read_domains;
- uint32_t write_domain;
+ __u32 handle;
+ __u32 read_domains;
+ __u32 write_domain;
};
struct drm_radeon_gem_wait_idle {
- uint32_t handle;
- uint32_t pad;
+ __u32 handle;
+ __u32 pad;
};
struct drm_radeon_gem_busy {
- uint32_t handle;
- uint32_t domain;
+ __u32 handle;
+ __u32 domain;
};
struct drm_radeon_gem_pread {
/** Handle for the object being read. */
- uint32_t handle;
- uint32_t pad;
+ __u32 handle;
+ __u32 pad;
/** Offset into the object to read from */
- uint64_t offset;
+ __u64 offset;
/** Length of data to read */
- uint64_t size;
+ __u64 size;
/** Pointer to write the data into. */
/* void *, but pointers are not 32/64 compatible */
- uint64_t data_ptr;
+ __u64 data_ptr;
};
struct drm_radeon_gem_pwrite {
/** Handle for the object being written to. */
- uint32_t handle;
- uint32_t pad;
+ __u32 handle;
+ __u32 pad;
/** Offset into the object to write to */
- uint64_t offset;
+ __u64 offset;
/** Length of data to write */
- uint64_t size;
+ __u64 size;
/** Pointer to read the data from. */
/* void *, but pointers are not 32/64 compatible */
- uint64_t data_ptr;
+ __u64 data_ptr;
};
/* Sets or returns a value associated with a buffer. */
struct drm_radeon_gem_op {
- uint32_t handle; /* buffer */
- uint32_t op; /* RADEON_GEM_OP_* */
- uint64_t value; /* input or return value */
+ __u32 handle; /* buffer */
+ __u32 op; /* RADEON_GEM_OP_* */
+ __u64 value; /* input or return value */
};
#define RADEON_GEM_OP_GET_INITIAL_DOMAIN 0
@@ -940,11 +940,11 @@
#define RADEON_VM_PAGE_SNOOPED (1 << 4)
struct drm_radeon_gem_va {
- uint32_t handle;
- uint32_t operation;
- uint32_t vm_id;
- uint32_t flags;
- uint64_t offset;
+ __u32 handle;
+ __u32 operation;
+ __u32 vm_id;
+ __u32 flags;
+ __u64 offset;
};
#define RADEON_CHUNK_ID_RELOCS 0x01
@@ -966,29 +966,29 @@
/* 0 = normal, + = higher priority, - = lower priority */
struct drm_radeon_cs_chunk {
- uint32_t chunk_id;
- uint32_t length_dw;
- uint64_t chunk_data;
+ __u32 chunk_id;
+ __u32 length_dw;
+ __u64 chunk_data;
};
/* drm_radeon_cs_reloc.flags */
#define RADEON_RELOC_PRIO_MASK (0xf << 0)
struct drm_radeon_cs_reloc {
- uint32_t handle;
- uint32_t read_domains;
- uint32_t write_domain;
- uint32_t flags;
+ __u32 handle;
+ __u32 read_domains;
+ __u32 write_domain;
+ __u32 flags;
};
struct drm_radeon_cs {
- uint32_t num_chunks;
- uint32_t cs_id;
- /* this points to uint64_t * which point to cs chunks */
- uint64_t chunks;
+ __u32 num_chunks;
+ __u32 cs_id;
+ /* this points to __u64 * which point to cs chunks */
+ __u64 chunks;
/* updates to the limits after this CS ioctl */
- uint64_t gart_limit;
- uint64_t vram_limit;
+ __u64 gart_limit;
+ __u64 vram_limit;
};
#define RADEON_INFO_DEVICE_ID 0x00
@@ -1047,9 +1047,9 @@
#define RADEON_INFO_GPU_RESET_COUNTER 0x26
struct drm_radeon_info {
- uint32_t request;
- uint32_t pad;
- uint64_t value;
+ __u32 request;
+ __u32 pad;
+ __u64 value;
};
/* Those correspond to the tile index to use, this is to explicitly state
diff --git a/include/drm/savage_drm.h b/include/drm/savage_drm.h
index f7a75ef..1a91234 100644
--- a/include/drm/savage_drm.h
+++ b/include/drm/savage_drm.h
@@ -26,10 +26,16 @@
#ifndef __SAVAGE_DRM_H__
#define __SAVAGE_DRM_H__
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
#ifndef __SAVAGE_SAREA_DEFINES__
#define __SAVAGE_SAREA_DEFINES__
-/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+/* 2 heaps (1 for card, 1 for agp), each divided into up to 128
* regions, subject to a minimum region size of (1<<16) == 64k.
*
* Clients may subdivide regions internally, but when sharing between
@@ -63,10 +69,10 @@
#define DRM_SAVAGE_BCI_EVENT_EMIT 0x02
#define DRM_SAVAGE_BCI_EVENT_WAIT 0x03
-#define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
-#define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
-#define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
-#define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
+#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
+#define DRM_IOCTL_SAVAGE_BCI_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
+#define DRM_IOCTL_SAVAGE_BCI_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
+#define DRM_IOCTL_SAVAGE_BCI_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
#define SAVAGE_DMA_PCI 1
#define SAVAGE_DMA_AGP 3
@@ -207,4 +213,8 @@
} clear1; /* SAVAGE_CMD_CLEAR data */
};
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/sis_drm.h b/include/drm/sis_drm.h
index 30f7b38..8e51bb9 100644
--- a/include/drm/sis_drm.h
+++ b/include/drm/sis_drm.h
@@ -27,6 +27,12 @@
#ifndef __SIS_DRM_H__
#define __SIS_DRM_H__
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* SiS specific ioctls */
#define NOT_USED_0_3
#define DRM_SIS_FB_ALLOC 0x04
@@ -64,4 +70,8 @@
unsigned int offset, size;
} drm_sis_fb_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* __SIS_DRM_H__ */
diff --git a/include/drm/tegra_drm.h b/include/drm/tegra_drm.h
index 1be09c4..f01f7a1 100644
--- a/include/drm/tegra_drm.h
+++ b/include/drm/tegra_drm.h
@@ -1,23 +1,33 @@
/*
* Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
+ * 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:
*
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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 _UAPI_TEGRA_DRM_H_
-#define _UAPI_TEGRA_DRM_H_
+#ifndef _TEGRA_DRM_H_
+#define _TEGRA_DRM_H_
-#include <drm/drm.h>
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
#define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1)
@@ -229,4 +239,8 @@
#define DRM_IOCTL_TEGRA_START_KEEPON DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_START_KEEPON, struct drm_tegra_keepon)
#define DRM_IOCTL_TEGRA_STOP_KEEPON DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_STOP_KEEPON, struct drm_tegra_keepon)
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/vc4_drm.h b/include/drm/vc4_drm.h
index 319881d..4117117 100644
--- a/include/drm/vc4_drm.h
+++ b/include/drm/vc4_drm.h
@@ -38,6 +38,13 @@
#define DRM_VC4_CREATE_SHADER_BO 0x05
#define DRM_VC4_GET_HANG_STATE 0x06
#define DRM_VC4_GET_PARAM 0x07
+#define DRM_VC4_SET_TILING 0x08
+#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)
@@ -47,6 +54,13 @@
#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
+#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
+#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. */
@@ -149,12 +163,31 @@
__u32 pad:24;
#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0)
+/* By default, the kernel gets to choose the order that the tiles are
+ * rendered in. If this is set, then the tiles will be rendered in a
+ * raster order, with the right-to-left vs left-to-right and
+ * top-to-bottom vs bottom-to-top dictated by
+ * VC4_SUBMIT_CL_RCL_ORDER_INCREASING_*. This allows overlapping
+ * blits to be implemented using the 3D engine.
+ */
+#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3)
__u32 flags;
/* Returned value of the seqno of this render job (for the
* 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;
};
/**
@@ -288,6 +321,9 @@
#define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
#define DRM_VC4_PARAM_SUPPORTS_ETC1 4
#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;
@@ -295,6 +331,103 @@
__u64 value;
};
+struct drm_vc4_get_tiling {
+ __u32 handle;
+ __u32 flags;
+ __u64 modifier;
+};
+
+struct drm_vc4_set_tiling {
+ __u32 handle;
+ __u32 flags;
+ __u64 modifier;
+};
+
+/**
+ * struct drm_vc4_label_bo - Attach a name to a BO for debug purposes.
+ */
+struct drm_vc4_label_bo {
+ __u32 handle;
+ __u32 len;
+ __u64 name;
+};
+
+/*
+ * States prefixed with '__' are internal states and cannot be passed to the
+ * DRM_IOCTL_VC4_GEM_MADVISE ioctl.
+ */
+#define VC4_MADV_WILLNEED 0
+#define VC4_MADV_DONTNEED 1
+#define __VC4_MADV_PURGED 2
+#define __VC4_MADV_NOTSUPP 3
+
+struct drm_vc4_gem_madvise {
+ __u32 handle;
+ __u32 madv;
+ __u32 retained;
+ __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/include/drm/via_drm.h b/include/drm/via_drm.h
index 182f879..8b69e81 100644
--- a/include/drm/via_drm.h
+++ b/include/drm/via_drm.h
@@ -26,6 +26,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* WARNING: These defines must be the same as what the Xserver uses.
* if you change them, you must change the defines in the Xserver.
*/
@@ -272,4 +276,8 @@
drm_via_blitsync_t sync;
} drm_via_dmablit_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* _VIA_DRM_H_ */
diff --git a/include/drm/virtgpu_drm.h b/include/drm/virtgpu_drm.h
index 91a31ff..9a781f0 100644
--- a/include/drm/virtgpu_drm.h
+++ b/include/drm/virtgpu_drm.h
@@ -63,6 +63,7 @@
};
#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/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h
index 5b68b4d..0bc784f 100644
--- a/include/drm/vmwgfx_drm.h
+++ b/include/drm/vmwgfx_drm.h
@@ -30,6 +30,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
#define DRM_VMW_MAX_SURFACE_FACES 6
#define DRM_VMW_MAX_MIP_LEVELS 24
@@ -37,6 +41,7 @@
#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
@@ -292,13 +297,17 @@
* @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;
@@ -307,7 +316,7 @@
__u32 version;
__u32 flags;
__u32 context_handle;
- __u32 pad64;
+ __s32 imported_fence_fd;
};
/**
@@ -323,6 +332,7 @@
* @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.
@@ -340,7 +350,7 @@
__u32 mask;
__u32 seqno;
__u32 passed_seqno;
- __u32 pad64;
+ __s32 fd;
__s32 error;
};
@@ -1087,4 +1097,32 @@
enum drm_vmw_extended_context req;
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
+
#endif
diff --git a/intel/intel-symbol-check b/intel/intel-symbol-check
index 2aa2d81..4d30a4b 100755
--- a/intel/intel-symbol-check
+++ b/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/intel/intel_bufmgr.c b/intel/intel_bufmgr.c
index 5bad93f..192de09 100644
--- a/intel/intel_bufmgr.c
+++ b/intel/intel_bufmgr.c
@@ -25,10 +25,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
diff --git a/intel/intel_bufmgr_fake.c b/intel/intel_bufmgr_fake.c
index 641df6a..3b24b81 100644
--- a/intel/intel_bufmgr_fake.c
+++ b/intel/intel_bufmgr_fake.c
@@ -34,10 +34,6 @@
* the bugs in the old texture manager.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index a665600..5c47a46 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -34,10 +34,6 @@
* Dave Airlie <airlied@linux.ie>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <xf86drm.h>
#include <xf86atomic.h>
#include <fcntl.h>
@@ -66,7 +62,7 @@
#include "i915_drm.h"
#include "uthash.h"
-#ifdef HAVE_VALGRIND
+#if HAVE_VALGRIND
#include <valgrind.h>
#include <memcheck.h>
#define VG(x) x
@@ -270,20 +266,6 @@
bool is_userptr;
/**
- * Boolean of whether this buffer can be placed in the full 48-bit
- * address range on gen8+.
- *
- * By default, buffers will be keep in a 32-bit range, unless this
- * flag is explicitly set.
- */
- bool use_48b_address_range;
-
- /**
- * Whether this buffer is softpinned at offset specified by the user
- */
- bool is_softpin;
-
- /**
* Size in bytes of this buffer and its relocation descendents.
*
* Used to avoid costly tree walking in
@@ -438,7 +420,7 @@
if (bo_gem->relocs == NULL && bo_gem->softpin_target == NULL) {
DBG("%2d: %d %s(%s)\n", i, bo_gem->gem_handle,
- bo_gem->is_softpin ? "*" : "",
+ bo_gem->kflags & EXEC_OBJECT_PINNED ? "*" : "",
bo_gem->name);
continue;
}
@@ -452,7 +434,7 @@
"%d (%s)@0x%08x %08x + 0x%08x\n",
i,
bo_gem->gem_handle,
- bo_gem->is_softpin ? "*" : "",
+ bo_gem->kflags & EXEC_OBJECT_PINNED ? "*" : "",
bo_gem->name,
upper_32_bits(bo_gem->relocs[j].offset),
lower_32_bits(bo_gem->relocs[j].offset),
@@ -471,7 +453,7 @@
"%d *(%s)@0x%08x %08x\n",
i,
bo_gem->gem_handle,
- bo_gem->is_softpin ? "*" : "",
+ bo_gem->kflags & EXEC_OBJECT_PINNED ? "*" : "",
bo_gem->name,
target_gem->gem_handle,
target_gem->name,
@@ -541,14 +523,11 @@
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
int index;
- int flags = 0;
+ unsigned long flags;
+ flags = 0;
if (need_fence)
flags |= EXEC_OBJECT_NEEDS_FENCE;
- if (bo_gem->use_48b_address_range)
- flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
- if (bo_gem->is_softpin)
- flags |= EXEC_OBJECT_PINNED;
if (bo_gem->validate_index != -1) {
bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |= flags;
@@ -579,7 +558,7 @@
bufmgr_gem->exec2_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
bufmgr_gem->exec2_objects[index].alignment = bo->align;
bufmgr_gem->exec2_objects[index].offset = bo->offset64;
- bufmgr_gem->exec2_objects[index].flags = flags | bo_gem->kflags;
+ bufmgr_gem->exec2_objects[index].flags = bo_gem->kflags | flags;
bufmgr_gem->exec2_objects[index].rsvd1 = 0;
bufmgr_gem->exec2_objects[index].rsvd2 = 0;
bufmgr_gem->exec_bos[index] = bo;
@@ -676,7 +655,6 @@
} else {
return false;
}
- return (ret == 0 && busy.busy);
}
static int
@@ -832,6 +810,10 @@
}
bo_gem->gem_handle = create.handle;
+ HASH_ADD(handle_hh, bufmgr_gem->handle_table,
+ gem_handle, sizeof(bo_gem->gem_handle),
+ bo_gem);
+
bo_gem->bo.handle = bo_gem->gem_handle;
bo_gem->bo.bufmgr = bufmgr;
bo_gem->bo.align = alignment;
@@ -844,10 +826,6 @@
tiling_mode,
stride))
goto err_free;
-
- HASH_ADD(handle_hh, bufmgr_gem->handle_table,
- gem_handle, sizeof(bo_gem->gem_handle),
- bo_gem);
}
bo_gem->name = name;
@@ -857,7 +835,6 @@
bo_gem->used_as_reloc_target = false;
bo_gem->has_error = false;
bo_gem->reusable = true;
- bo_gem->use_48b_address_range = false;
drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, alignment);
pthread_mutex_unlock(&bufmgr_gem->lock);
@@ -1016,7 +993,6 @@
bo_gem->used_as_reloc_target = false;
bo_gem->has_error = false;
bo_gem->reusable = false;
- bo_gem->use_48b_address_range = false;
drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
pthread_mutex_unlock(&bufmgr_gem->lock);
@@ -1164,7 +1140,6 @@
bo_gem->bo.handle = open_arg.handle;
bo_gem->global_name = handle;
bo_gem->reusable = false;
- bo_gem->use_48b_address_range = false;
HASH_ADD(handle_hh, bufmgr_gem->handle_table,
gem_handle, sizeof(bo_gem->gem_handle), bo_gem);
@@ -1411,8 +1386,6 @@
bo_gem->name = NULL;
bo_gem->validate_index = -1;
- bo_gem->kflags = 0;
-
DRMLISTADDTAIL(&bo_gem->head, &bucket->head);
} else {
drm_intel_gem_bo_free(bo);
@@ -1652,7 +1625,7 @@
drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
-#ifdef HAVE_VALGRIND
+#if HAVE_VALGRIND
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
#endif
int ret;
@@ -2054,7 +2027,11 @@
drm_intel_gem_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
- bo_gem->use_48b_address_range = enable;
+
+ if (enable)
+ bo_gem->kflags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+ else
+ bo_gem->kflags &= ~EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
}
static int
@@ -2071,7 +2048,7 @@
return -ENOMEM;
}
- if (!target_bo_gem->is_softpin)
+ if (!(target_bo_gem->kflags & EXEC_OBJECT_PINNED))
return -EINVAL;
if (target_bo_gem == bo_gem)
return -EINVAL;
@@ -2103,7 +2080,7 @@
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *)target_bo;
- if (target_bo_gem->is_softpin)
+ if (target_bo_gem->kflags & EXEC_OBJECT_PINNED)
return drm_intel_gem_bo_add_softpin_target(bo, target_bo);
else
return do_bo_emit_reloc(bo, offset, target_bo, target_offset,
@@ -2287,7 +2264,7 @@
/* If we're seeing softpinned object here it means that the kernel
* has relocated our object... Indicating a programming error
*/
- assert(!bo_gem->is_softpin);
+ assert(!(bo_gem->kflags & EXEC_OBJECT_PINNED));
DBG("BO %d (%s) migrated: 0x%08x %08x -> 0x%08x %08x\n",
bo_gem->gem_handle, bo_gem->name,
upper_32_bits(bo->offset64),
@@ -2643,9 +2620,10 @@
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
- bo_gem->is_softpin = true;
bo->offset64 = offset;
bo->offset = offset;
+ bo_gem->kflags |= EXEC_OBJECT_PINNED;
+
return 0;
}
@@ -2709,7 +2687,6 @@
bo_gem->used_as_reloc_target = false;
bo_gem->has_error = false;
bo_gem->reusable = false;
- bo_gem->use_48b_address_range = false;
memclear(get_tiling);
get_tiling.handle = bo_gem->gem_handle;
@@ -3681,6 +3658,8 @@
bufmgr_gem->gen = 8;
else if (IS_GEN9(bufmgr_gem->pci_device))
bufmgr_gem->gen = 9;
+ else if (IS_GEN10(bufmgr_gem->pci_device))
+ bufmgr_gem->gen = 10;
else {
free(bufmgr_gem);
bufmgr_gem = NULL;
diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
index 41fc0da..01d250e 100644
--- a/intel/intel_chipset.h
+++ b/intel/intel_chipset.h
@@ -202,7 +202,7 @@
#define PCI_CHIP_KABYLAKE_ULX_GT1 0x590E
#define PCI_CHIP_KABYLAKE_ULX_GT2 0x591E
#define PCI_CHIP_KABYLAKE_DT_GT2 0x5912
-#define PCI_CHIP_KABYLAKE_DT_GT1_5 0x5917
+#define PCI_CHIP_KABYLAKE_M_GT2 0x5917
#define PCI_CHIP_KABYLAKE_DT_GT1 0x5902
#define PCI_CHIP_KABYLAKE_HALO_GT2 0x591B
#define PCI_CHIP_KABYLAKE_HALO_GT4 0x593B
@@ -221,6 +221,41 @@
#define PCI_CHIP_GLK 0x3184
#define PCI_CHIP_GLK_2X6 0x3185
+#define PCI_CHIP_COFFEELAKE_S_GT1_1 0x3E90
+#define PCI_CHIP_COFFEELAKE_S_GT1_2 0x3E93
+#define PCI_CHIP_COFFEELAKE_S_GT1_3 0x3E99
+#define PCI_CHIP_COFFEELAKE_S_GT2_1 0x3E91
+#define PCI_CHIP_COFFEELAKE_S_GT2_2 0x3E92
+#define PCI_CHIP_COFFEELAKE_S_GT2_3 0x3E96
+#define PCI_CHIP_COFFEELAKE_S_GT2_4 0x3E9A
+#define PCI_CHIP_COFFEELAKE_H_GT2_1 0x3E9B
+#define PCI_CHIP_COFFEELAKE_H_GT2_2 0x3E94
+#define PCI_CHIP_COFFEELAKE_U_GT1_1 0x3EA1
+#define PCI_CHIP_COFFEELAKE_U_GT1_2 0x3EA4
+#define PCI_CHIP_COFFEELAKE_U_GT2_1 0x3EA0
+#define PCI_CHIP_COFFEELAKE_U_GT2_2 0x3EA3
+#define PCI_CHIP_COFFEELAKE_U_GT2_3 0x3EA9
+#define PCI_CHIP_COFFEELAKE_U_GT3_1 0x3EA2
+#define PCI_CHIP_COFFEELAKE_U_GT3_2 0x3EA5
+#define PCI_CHIP_COFFEELAKE_U_GT3_3 0x3EA6
+#define PCI_CHIP_COFFEELAKE_U_GT3_4 0x3EA7
+#define PCI_CHIP_COFFEELAKE_U_GT3_5 0x3EA8
+
+#define PCI_CHIP_CANNONLAKE_0 0x5A51
+#define PCI_CHIP_CANNONLAKE_1 0x5A59
+#define PCI_CHIP_CANNONLAKE_2 0x5A41
+#define PCI_CHIP_CANNONLAKE_3 0x5A49
+#define PCI_CHIP_CANNONLAKE_4 0x5A52
+#define PCI_CHIP_CANNONLAKE_5 0x5A5A
+#define PCI_CHIP_CANNONLAKE_6 0x5A42
+#define PCI_CHIP_CANNONLAKE_7 0x5A4A
+#define PCI_CHIP_CANNONLAKE_8 0x5A50
+#define PCI_CHIP_CANNONLAKE_9 0x5A40
+#define PCI_CHIP_CANNONLAKE_10 0x5A54
+#define PCI_CHIP_CANNONLAKE_11 0x5A5C
+#define PCI_CHIP_CANNONLAKE_12 0x5A44
+#define PCI_CHIP_CANNONLAKE_13 0x5A4C
+
#define IS_MOBILE(devid) ((devid) == PCI_CHIP_I855_GM || \
(devid) == PCI_CHIP_I915_GM || \
(devid) == PCI_CHIP_I945_GM || \
@@ -411,7 +446,6 @@
#define IS_KBL_GT1(devid) ((devid) == PCI_CHIP_KABYLAKE_ULT_GT1_5 || \
(devid) == PCI_CHIP_KABYLAKE_ULX_GT1_5 || \
- (devid) == PCI_CHIP_KABYLAKE_DT_GT1_5 || \
(devid) == PCI_CHIP_KABYLAKE_ULT_GT1 || \
(devid) == PCI_CHIP_KABYLAKE_ULX_GT1 || \
(devid) == PCI_CHIP_KABYLAKE_DT_GT1 || \
@@ -423,6 +457,7 @@
(devid) == PCI_CHIP_KABYLAKE_ULT_GT2F || \
(devid) == PCI_CHIP_KABYLAKE_ULX_GT2 || \
(devid) == PCI_CHIP_KABYLAKE_DT_GT2 || \
+ (devid) == PCI_CHIP_KABYLAKE_M_GT2 || \
(devid) == PCI_CHIP_KABYLAKE_HALO_GT2 || \
(devid) == PCI_CHIP_KABYLAKE_SRV_GT2 || \
(devid) == PCI_CHIP_KABYLAKE_WKS_GT2)
@@ -452,10 +487,54 @@
#define IS_GEMINILAKE(devid) ((devid) == PCI_CHIP_GLK || \
(devid) == PCI_CHIP_GLK_2X6)
+#define IS_CFL_S(devid) ((devid) == PCI_CHIP_COFFEELAKE_S_GT1_1 || \
+ (devid) == PCI_CHIP_COFFEELAKE_S_GT1_2 || \
+ (devid) == PCI_CHIP_COFFEELAKE_S_GT1_3 || \
+ (devid) == PCI_CHIP_COFFEELAKE_S_GT2_1 || \
+ (devid) == PCI_CHIP_COFFEELAKE_S_GT2_2 || \
+ (devid) == PCI_CHIP_COFFEELAKE_S_GT2_3 || \
+ (devid) == PCI_CHIP_COFFEELAKE_S_GT2_4)
+
+#define IS_CFL_H(devid) ((devid) == PCI_CHIP_COFFEELAKE_H_GT2_1 || \
+ (devid) == PCI_CHIP_COFFEELAKE_H_GT2_2)
+
+#define IS_CFL_U(devid) ((devid) == PCI_CHIP_COFFEELAKE_U_GT1_1 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT1_2 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT2_1 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT2_2 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT2_3 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT3_1 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT3_2 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT3_3 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT3_4 || \
+ (devid) == PCI_CHIP_COFFEELAKE_U_GT3_5)
+
+#define IS_COFFEELAKE(devid) (IS_CFL_S(devid) || \
+ IS_CFL_H(devid) || \
+ IS_CFL_U(devid))
+
#define IS_GEN9(devid) (IS_SKYLAKE(devid) || \
IS_BROXTON(devid) || \
IS_KABYLAKE(devid) || \
- IS_GEMINILAKE(devid))
+ IS_GEMINILAKE(devid) || \
+ IS_COFFEELAKE(devid))
+
+#define IS_CANNONLAKE(devid) ((devid) == PCI_CHIP_CANNONLAKE_0 || \
+ (devid) == PCI_CHIP_CANNONLAKE_1 || \
+ (devid) == PCI_CHIP_CANNONLAKE_2 || \
+ (devid) == PCI_CHIP_CANNONLAKE_3 || \
+ (devid) == PCI_CHIP_CANNONLAKE_4 || \
+ (devid) == PCI_CHIP_CANNONLAKE_5 || \
+ (devid) == PCI_CHIP_CANNONLAKE_6 || \
+ (devid) == PCI_CHIP_CANNONLAKE_7 || \
+ (devid) == PCI_CHIP_CANNONLAKE_8 || \
+ (devid) == PCI_CHIP_CANNONLAKE_9 || \
+ (devid) == PCI_CHIP_CANNONLAKE_10 || \
+ (devid) == PCI_CHIP_CANNONLAKE_11 || \
+ (devid) == PCI_CHIP_CANNONLAKE_12 || \
+ (devid) == PCI_CHIP_CANNONLAKE_13)
+
+#define IS_GEN10(devid) (IS_CANNONLAKE(devid))
#define IS_9XX(dev) (IS_GEN3(dev) || \
IS_GEN4(dev) || \
@@ -463,7 +542,7 @@
IS_GEN6(dev) || \
IS_GEN7(dev) || \
IS_GEN8(dev) || \
- IS_GEN9(dev))
-
+ IS_GEN9(dev) || \
+ IS_GEN10(dev))
#endif /* _INTEL_CHIPSET_H */
diff --git a/intel/intel_decode.c b/intel/intel_decode.c
index 803d202..bc7b04b 100644
--- a/intel/intel_decode.c
+++ b/intel/intel_decode.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
@@ -3827,7 +3823,9 @@
ctx->devid = devid;
ctx->out = stdout;
- if (IS_GEN9(devid))
+ if (IS_GEN10(devid))
+ ctx->gen = 10;
+ else if (IS_GEN9(devid))
ctx->gen = 9;
else if (IS_GEN8(devid))
ctx->gen = 8;
@@ -3899,7 +3897,7 @@
int ret;
unsigned int index = 0;
uint32_t devid;
- int size = ctx->base_count * 4;
+ int size;
void *temp;
if (!ctx)
@@ -3909,6 +3907,7 @@
* the batchbuffer. This lets us avoid a bunch of length
* checking in statically sized packets.
*/
+ size = ctx->base_count * 4;
temp = malloc(size + 4096);
memcpy(temp, ctx->base_data, size);
memset((char *)temp + size, 0xd0, 4096);
diff --git a/intel/meson.build b/intel/meson.build
new file mode 100644
index 0000000..53c7fce
--- /dev/null
+++ b/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/intel/mm.c b/intel/mm.c
index 954e9dc..79d8719 100644
--- a/intel/mm.c
+++ b/intel/mm.c
@@ -22,10 +22,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <assert.h>
diff --git a/intel/mm.h b/intel/mm.h
index 8d83743..1b0f84f 100644
--- a/intel/mm.h
+++ b/intel/mm.h
@@ -29,10 +29,6 @@
#ifndef MM_H
#define MM_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "libdrm_macros.h"
struct mem_block {
diff --git a/intel/test_decode.c b/intel/test_decode.c
index b4eddcd..b9f5b92 100644
--- a/intel/test_decode.c
+++ b/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 @@
{
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 @@
* 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/libdrm_macros.h b/libdrm_macros.h
index b88fdce..3134ae9 100644
--- a/libdrm_macros.h
+++ b/libdrm_macros.h
@@ -23,7 +23,7 @@
#ifndef LIBDRM_LIBDRM_H
#define LIBDRM_LIBDRM_H
-#if defined(HAVE_VISIBILITY)
+#if HAVE_VISIBILITY
# define drm_private __attribute__((visibility("hidden")))
#else
# define drm_private
diff --git a/libkms/api.c b/libkms/api.c
index 354d8a2..22dd32d 100644
--- a/libkms/api.c
+++ b/libkms/api.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdlib.h>
#include <string.h>
diff --git a/libkms/dumb.c b/libkms/dumb.c
index b95a072..17efc10 100644
--- a/libkms/dumb.c
+++ b/libkms/dumb.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/exynos.c b/libkms/exynos.c
index 0e97fb5..ef64a66 100644
--- a/libkms/exynos.c
+++ b/libkms/exynos.c
@@ -5,16 +5,26 @@
* SooChan Lim <sc1.lim@samsung.com>
* Sangjin LEE <lsj119@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/intel.c b/libkms/intel.c
index 3d8ca05..859e7a0 100644
--- a/libkms/intel.c
+++ b/libkms/intel.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/internal.h b/libkms/internal.h
index 905f5b1..8b386db 100644
--- a/libkms/internal.h
+++ b/libkms/internal.h
@@ -29,10 +29,6 @@
#ifndef INTERNAL_H_
#define INTERNAL_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "libdrm_macros.h"
#include "libkms.h"
diff --git a/libkms/kms-symbol-check b/libkms/kms-symbol-check
index 658b269..a5c2120 100755
--- a/libkms/kms-symbol-check
+++ b/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/libkms/linux.c b/libkms/linux.c
index 0b50777..5620505 100644
--- a/libkms/linux.c
+++ b/libkms/linux.c
@@ -29,10 +29,6 @@
* going from fd to pci id via fstat and udev.
*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -110,27 +106,27 @@
if (ret)
return ret;
-#ifdef HAVE_INTEL
+#if HAVE_INTEL
if (!strcmp(name, "intel"))
ret = intel_create(fd, out);
else
#endif
-#ifdef HAVE_VMWGFX
+#if HAVE_VMWGFX
if (!strcmp(name, "vmwgfx"))
ret = vmwgfx_create(fd, out);
else
#endif
-#ifdef HAVE_NOUVEAU
+#if HAVE_NOUVEAU
if (!strcmp(name, "nouveau"))
ret = nouveau_create(fd, out);
else
#endif
-#ifdef HAVE_RADEON
+#if HAVE_RADEON
if (!strcmp(name, "radeon"))
ret = radeon_create(fd, out);
else
#endif
-#ifdef HAVE_EXYNOS
+#if HAVE_EXYNOS
if (!strcmp(name, "exynos"))
ret = exynos_create(fd, out);
else
diff --git a/libkms/meson.build b/libkms/meson.build
new file mode 100644
index 0000000..86d1a4e
--- /dev/null
+++ b/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/libkms/nouveau.c b/libkms/nouveau.c
index d10e0fd..7fe23db 100644
--- a/libkms/nouveau.c
+++ b/libkms/nouveau.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/radeon.c b/libkms/radeon.c
index aaeeaf3..2cb2b11 100644
--- a/libkms/radeon.c
+++ b/libkms/radeon.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/vmwgfx.c b/libkms/vmwgfx.c
index 6a24fd4..f0e40be 100644
--- a/libkms/vmwgfx.c
+++ b/libkms/vmwgfx.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdlib.h>
#include <string.h>
diff --git a/man/drm-kms.xml b/man/drm-kms.xml
index ae38dc8..eb04c26 100644
--- a/man/drm-kms.xml
+++ b/man/drm-kms.xml
@@ -309,8 +309,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drm-memory.xml b/man/drm-memory.xml
index 6b4f075..3aa7cf2 100644
--- a/man/drm-memory.xml
+++ b/man/drm-memory.xml
@@ -410,8 +410,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drm.xml b/man/drm.xml
index 5a49fe1..1f55966 100644
--- a/man/drm.xml
+++ b/man/drm.xml
@@ -50,7 +50,7 @@
<para>In earlier days, the kernel framework was solely used to provide raw
hardware access to priviledged user-space processes which implement
- all the hardware abstraction layers. But more and more tasks where
+ all the hardware abstraction layers. But more and more tasks were
moved into the kernel. All these interfaces are based on
<citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
commands on the DRM character device. The <emphasis>libdrm</emphasis>
@@ -119,8 +119,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drmAvailable.xml b/man/drmAvailable.xml
index 55bef94..1e5d787 100644
--- a/man/drmAvailable.xml
+++ b/man/drmAvailable.xml
@@ -61,8 +61,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drmHandleEvent.xml b/man/drmHandleEvent.xml
index b1006e5..8330442 100644
--- a/man/drmHandleEvent.xml
+++ b/man/drmHandleEvent.xml
@@ -86,8 +86,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drmModeGetResources.xml b/man/drmModeGetResources.xml
index 2f5e8c2..0ab6a68 100644
--- a/man/drmModeGetResources.xml
+++ b/man/drmModeGetResources.xml
@@ -116,8 +116,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/meson.build b/man/meson.build
new file mode 100644
index 0000000..45eaeda
--- /dev/null
+++ b/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/meson.build b/meson.build
new file mode 100644
index 0000000..961ee59
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,382 @@
+# 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.91',
+ 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/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/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..8af33f1
--- /dev/null
+++ b/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/nouveau/abi16.c b/nouveau/abi16.c
index ee38c0c..ba2501e 100644
--- a/nouveau/abi16.c
+++ b/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/nouveau/bufctx.c b/nouveau/bufctx.c
index 4f76e5d..67b7570 100644
--- a/nouveau/bufctx.c
+++ b/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/nouveau/meson.build b/nouveau/meson.build
new file mode 100644
index 0000000..51c9a71
--- /dev/null
+++ b/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/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index b265cea..b3a2410 100755
--- a/nouveau/nouveau-symbol-check
+++ b/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/nouveau/nouveau.c b/nouveau/nouveau.c
index e113a8f..5559351 100644
--- a/nouveau/nouveau.c
+++ b/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/nouveau/pushbuf.c b/nouveau/pushbuf.c
index 035e301..445c966 100644
--- a/nouveau/pushbuf.c
+++ b/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/omap/Android.bp b/omap/Android.bp
new file mode 100644
index 0000000..05ca7d2
--- /dev/null
+++ b/omap/Android.bp
@@ -0,0 +1,12 @@
+build = ["Android.sources.bp"]
+
+cc_library_shared {
+ name: "libdrm_omap",
+ defaults: [
+ "libdrm_defaults",
+ "libdrm_omap_sources",
+ ],
+ vendor: true,
+
+ shared_libs: ["libdrm"],
+}
diff --git a/omap/Android.sources.bp b/omap/Android.sources.bp
new file mode 100644
index 0000000..3c7da94
--- /dev/null
+++ b/omap/Android.sources.bp
@@ -0,0 +1,8 @@
+// Autogenerated with Android.sources.bp.mk
+
+cc_defaults {
+ name: "libdrm_omap_sources",
+ srcs: [
+ "omap_drm.c",
+ ],
+}
diff --git a/omap/meson.build b/omap/meson.build
new file mode 100644
index 0000000..e57b8f5
--- /dev/null
+++ b/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/omap/omap-symbol-check b/omap/omap-symbol-check
index 759c84b..0fb4a0f 100755
--- a/omap/omap-symbol-check
+++ b/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/omap/omap_drm.c b/omap/omap_drm.c
index 08ba64e..65275ec 100644
--- a/omap/omap_drm.c
+++ b/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>
@@ -418,7 +414,7 @@
if (bo->fd < 0) {
struct drm_prime_handle req = {
.handle = bo->handle,
- .flags = DRM_CLOEXEC,
+ .flags = DRM_CLOEXEC | DRM_RDWR,
};
int ret;
diff --git a/radeon/meson.build b/radeon/meson.build
new file mode 100644
index 0000000..b08c744
--- /dev/null
+++ b/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/radeon/radeon-symbol-check b/radeon/radeon-symbol-check
index 0bf2ffc..7d79d90 100755
--- a/radeon/radeon-symbol-check
+++ b/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/radeon/radeon_bo.c b/radeon/radeon_bo.c
index 447f928..821807b 100644
--- a/radeon/radeon_bo.c
+++ b/radeon/radeon_bo.c
@@ -29,9 +29,6 @@
* Dave Airlie
* Jérôme Glisse <glisse@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <libdrm_macros.h>
#include <radeon_bo.h>
#include <radeon_bo_int.h>
diff --git a/radeon/radeon_bo_gem.c b/radeon/radeon_bo_gem.c
index fbd453d..774b26e 100644
--- a/radeon/radeon_bo_gem.c
+++ b/radeon/radeon_bo_gem.c
@@ -29,9 +29,6 @@
* Dave Airlie
* Jérôme Glisse <glisse@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/radeon/radeon_cs.c b/radeon/radeon_cs.c
index dffb869..eb7859e 100644
--- a/radeon/radeon_cs.c
+++ b/radeon/radeon_cs.c
@@ -1,6 +1,3 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include "libdrm_macros.h"
#include <stdio.h>
#include "radeon_cs.h"
diff --git a/radeon/radeon_cs_gem.c b/radeon/radeon_cs_gem.c
index f3dccb6..4d5fc13 100644
--- a/radeon/radeon_cs_gem.c
+++ b/radeon/radeon_cs_gem.c
@@ -29,9 +29,6 @@
* Nicolai Haehnle <prefect_@gmx.net>
* Jérôme Glisse <glisse@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
diff --git a/radeon/radeon_cs_space.c b/radeon/radeon_cs_space.c
index 69287be..8531c34 100644
--- a/radeon/radeon_cs_space.c
+++ b/radeon/radeon_cs_space.c
@@ -25,9 +25,6 @@
*/
/*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
diff --git a/radeon/radeon_surface.c b/radeon/radeon_surface.c
index 965be24..3cafcfc 100644
--- a/radeon/radeon_surface.c
+++ b/radeon/radeon_surface.c
@@ -26,9 +26,6 @@
* Authors:
* Jérôme Glisse <jglisse@redhat.com>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
@@ -2503,6 +2500,7 @@
if (surf->npix_y > 1) {
return -EINVAL;
}
+ /* fallthrough */
case RADEON_SURF_TYPE_2D:
if (surf->npix_z > 1) {
return -EINVAL;
diff --git a/tegra/meson.build b/tegra/meson.build
new file mode 100644
index 0000000..1f5c74b
--- /dev/null
+++ b/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/tegra/tegra-symbol-check b/tegra/tegra-symbol-check
index 4020831..509b678 100755
--- a/tegra/tegra-symbol-check
+++ b/tegra/tegra-symbol-check
@@ -1,11 +1,14 @@
#!/bin/bash
-# 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
+# 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__
__bss_start
+__end__
+_bss_end__
_edata
_end
_fini
diff --git a/tegra/tegra.c b/tegra/tegra.c
index 66f19e9..0c86987 100644
--- a/tegra/tegra.c
+++ b/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/tests/amdgpu/.editorconfig b/tests/amdgpu/.editorconfig
new file mode 120000
index 0000000..70734e4
--- /dev/null
+++ b/tests/amdgpu/.editorconfig
@@ -0,0 +1 @@
+../../amdgpu/.editorconfig
\ No newline at end of file
diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
index c1c3a32..e79c1bd 100644
--- a/tests/amdgpu/Makefile.am
+++ b/tests/amdgpu/Makefile.am
@@ -1,7 +1,8 @@
AM_CFLAGS = \
-I $(top_srcdir)/include/drm \
-I $(top_srcdir)/amdgpu \
- -I $(top_srcdir)
+ -I $(top_srcdir) \
+ -pthread
LDADD = $(top_builddir)/libdrm.la \
$(top_builddir)/amdgpu/libdrm_amdgpu.la \
@@ -23,7 +24,12 @@
basic_tests.c \
bo_tests.c \
cs_tests.c \
- uvd_messages.h \
+ decode_messages.h \
vce_tests.c \
vce_ib.h \
- frame.h
+ frame.h \
+ uvd_enc_tests.c \
+ vcn_tests.c \
+ uve_ib.h \
+ deadlock_tests.c \
+ vm_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 3fd6820..96fcd68 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/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>
@@ -49,6 +45,17 @@
#include "CUnit/Basic.h"
#include "amdgpu_test.h"
+#include "amdgpu_internal.h"
+
+/* Test suite names */
+#define BASIC_TESTS_STR "Basic Tests"
+#define BO_TESTS_STR "BO Tests"
+#define CS_TESTS_STR "CS Tests"
+#define VCE_TESTS_STR "VCE Tests"
+#define VCN_TESTS_STR "VCN Tests"
+#define UVD_ENC_TESTS_STR "UVD ENC Tests"
+#define DEADLOCK_TESTS_STR "Deadlock Tests"
+#define VM_TESTS_STR "VM Tests"
/**
* Open handles for amdgpu devices
@@ -62,49 +69,150 @@
/** The table of all known test suites to run */
static CU_SuiteInfo suites[] = {
{
- .pName = "Basic Tests",
+ .pName = BASIC_TESTS_STR,
.pInitFunc = suite_basic_tests_init,
.pCleanupFunc = suite_basic_tests_clean,
.pTests = basic_tests,
},
{
- .pName = "BO Tests",
+ .pName = BO_TESTS_STR,
.pInitFunc = suite_bo_tests_init,
.pCleanupFunc = suite_bo_tests_clean,
.pTests = bo_tests,
},
{
- .pName = "CS Tests",
+ .pName = CS_TESTS_STR,
.pInitFunc = suite_cs_tests_init,
.pCleanupFunc = suite_cs_tests_clean,
.pTests = cs_tests,
},
{
- .pName = "VCE Tests",
+ .pName = VCE_TESTS_STR,
.pInitFunc = suite_vce_tests_init,
.pCleanupFunc = suite_vce_tests_clean,
.pTests = vce_tests,
},
+ {
+ .pName = VCN_TESTS_STR,
+ .pInitFunc = suite_vcn_tests_init,
+ .pCleanupFunc = suite_vcn_tests_clean,
+ .pTests = vcn_tests,
+ },
+ {
+ .pName = UVD_ENC_TESTS_STR,
+ .pInitFunc = suite_uvd_enc_tests_init,
+ .pCleanupFunc = suite_uvd_enc_tests_clean,
+ .pTests = uvd_enc_tests,
+ },
+ {
+ .pName = DEADLOCK_TESTS_STR,
+ .pInitFunc = suite_deadlock_tests_init,
+ .pCleanupFunc = suite_deadlock_tests_clean,
+ .pTests = deadlock_tests,
+ },
+ {
+ .pName = VM_TESTS_STR,
+ .pInitFunc = suite_vm_tests_init,
+ .pCleanupFunc = suite_vm_tests_clean,
+ .pTests = vm_tests,
+ },
+
CU_SUITE_INFO_NULL,
};
+typedef CU_BOOL (*active__stat_func)(void);
-/** Display information about all suites and their tests */
+typedef struct Suites_Active_Status {
+ char* pName;
+ active__stat_func pActive;
+}Suites_Active_Status;
+
+static CU_BOOL always_active()
+{
+ return CU_TRUE;
+}
+
+static Suites_Active_Status suites_active_stat[] = {
+ {
+ .pName = BASIC_TESTS_STR,
+ .pActive = always_active,
+ },
+ {
+ .pName = BO_TESTS_STR,
+ .pActive = always_active,
+ },
+ {
+ .pName = CS_TESTS_STR,
+ .pActive = suite_cs_tests_enable,
+ },
+ {
+ .pName = VCE_TESTS_STR,
+ .pActive = suite_vce_tests_enable,
+ },
+ {
+ .pName = VCN_TESTS_STR,
+ .pActive = suite_vcn_tests_enable,
+ },
+ {
+ .pName = UVD_ENC_TESTS_STR,
+ .pActive = suite_uvd_enc_tests_enable,
+ },
+ {
+ .pName = DEADLOCK_TESTS_STR,
+ .pActive = suite_deadlock_tests_enable,
+ },
+ {
+ .pName = VM_TESTS_STR,
+ .pActive = suite_vm_tests_enable,
+ },
+};
+
+
+/*
+ * Display information about all suites and their tests
+ *
+ * NOTE: Must be run after registry is initialized and suites registered.
+ */
static void display_test_suites(void)
{
int iSuite;
int iTest;
+ CU_pSuite pSuite = NULL;
+ CU_pTest pTest = NULL;
printf("Suites\n");
for (iSuite = 0; suites[iSuite].pName != NULL; iSuite++) {
- printf("Suite id = %d: Name '%s'\n",
- iSuite + 1, suites[iSuite].pName);
+
+ pSuite = CU_get_suite_by_index((unsigned int) iSuite + 1,
+ CU_get_registry());
+
+ if (!pSuite) {
+ fprintf(stderr, "Invalid suite id : %d\n", iSuite + 1);
+ continue;
+ }
+
+ printf("Suite id = %d: Name '%s status: %s'\n",
+ iSuite + 1, suites[iSuite].pName,
+ pSuite->fActive ? "ENABLED" : "DISABLED");
+
+
for (iTest = 0; suites[iSuite].pTests[iTest].pName != NULL;
iTest++) {
- printf(" Test id %d: Name: '%s'\n", iTest + 1,
- suites[iSuite].pTests[iTest].pName);
+
+ pTest = CU_get_test_by_index((unsigned int) iTest + 1,
+ pSuite);
+
+ if (!pTest) {
+ fprintf(stderr, "Invalid test id : %d\n", iTest + 1);
+ continue;
+ }
+
+ printf("Test id %d: Name: '%s status: %s'\n", iTest + 1,
+ suites[iSuite].pTests[iTest].pName,
+ pSuite->fActive && pTest->fActive ?
+ "ENABLED" : "DISABLED");
}
}
}
@@ -112,7 +220,7 @@
/** Help string for command line parameters */
static const char usage[] =
- "Usage: %s [-hlpr] [<-s <suite id>> [-t <test id>]] "
+ "Usage: %s [-hlpr] [<-s <suite id>> [-t <test id>] [-f]] "
"[-b <pci_bus_id> [-d <pci_device_id>]]\n"
"where:\n"
" l - Display all suites and their tests\n"
@@ -120,9 +228,10 @@
" b - Specify device's PCI bus id to run tests\n"
" d - Specify device's PCI device id to run tests (optional)\n"
" p - Display information of AMDGPU devices in system\n"
+ " f - Force executing inactive suite or test\n"
" h - Display this help\n";
/** Specified options strings for getopt */
-static const char options[] = "hlrps:t:b:d:";
+static const char options[] = "hlrps:t:b:d:f";
/* Open AMD devices.
* Return the number of AMD device openned.
@@ -130,7 +239,6 @@
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;
@@ -264,29 +372,71 @@
/* Find a match AMD device in PCI bus
* Return the index of the device or -1 if not found
*/
-static int amdgpu_find_device(uint8_t bus, uint8_t dev)
+static int amdgpu_find_device(uint8_t bus, uint16_t dev)
{
int i;
drmDevicePtr device;
- for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++)
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
if (drmGetDevice2(drm_amdgpu[i],
DRM_DEVICE_GET_PCI_REVISION,
&device) == 0) {
if (device->bustype == DRM_BUS_PCI)
- if (device->businfo.pci->bus == bus &&
- device->businfo.pci->dev == dev) {
-
+ if ((bus == 0xFF || device->businfo.pci->bus == bus) &&
+ device->deviceinfo.pci->device_id == dev) {
drmFreeDevice(&device);
return i;
}
drmFreeDevice(&device);
}
+ }
return -1;
}
+static void amdgpu_disable_suites()
+{
+ amdgpu_device_handle device_handle;
+ uint32_t major_version, minor_version, family_id;
+ int i;
+ int size = sizeof(suites_active_stat) / sizeof(suites_active_stat[0]);
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return;
+
+ family_id = device_handle->info.family_id;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return;
+
+ /* 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, "suite deactivation failed - %s\n", CU_get_error_msg());
+
+ /* Explicitly disable specific tests due to known bugs or preferences */
+ /*
+ * BUG: Compute ring stalls and never recovers when the address is
+ * written after the command already submitted
+ */
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, "compute ring block test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ 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)
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Sync dependency Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+}
+
/* The main() function for setting up and running the tests.
* Returns a CUE_SUCCESS on successful running, another
* CUnit error code on failure.
@@ -303,6 +453,8 @@
CU_pSuite pSuite = NULL;
CU_pTest pTest = NULL;
int test_device_index;
+ int display_list = 0;
+ int force_run = 0;
for (i = 0; i < MAX_CARDS_SUPPORTED; i++)
drm_amdgpu[i] = -1;
@@ -313,8 +465,8 @@
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'l':
- display_test_suites();
- exit(EXIT_SUCCESS);
+ display_list = 1;
+ break;
case 's':
suite_id = atoi(optarg);
break;
@@ -325,7 +477,7 @@
pci_bus_id = atoi(optarg);
break;
case 'd':
- pci_device_id = atoi(optarg);
+ sscanf(optarg, "%x", &pci_device_id);
break;
case 'p':
display_devices = 1;
@@ -333,6 +485,9 @@
case 'r':
open_render_node = 1;
break;
+ case 'f':
+ force_run = 1;
+ break;
case '?':
case 'h':
fprintf(stderr, usage, argv[0]);
@@ -359,10 +514,10 @@
exit(EXIT_SUCCESS);
}
- if (pci_bus_id > 0) {
+ if (pci_bus_id > 0 || pci_device_id) {
/* A device was specified to run the test */
- test_device_index = amdgpu_find_device((uint8_t)pci_bus_id,
- (uint8_t)pci_device_id);
+ test_device_index = amdgpu_find_device(pci_bus_id,
+ pci_device_id);
if (test_device_index >= 0) {
/* Most tests run on device of drm_amdgpu[0].
@@ -398,17 +553,33 @@
/* Run tests using the CUnit Basic interface */
CU_basic_set_mode(CU_BRM_VERBOSE);
+ /* Disable suites and individual tests based on misc. conditions */
+ amdgpu_disable_suites();
+
+ if (display_list) {
+ display_test_suites();
+ goto end;
+ }
+
if (suite_id != -1) { /* If user specify particular suite? */
pSuite = CU_get_suite_by_index((unsigned int) suite_id,
CU_get_registry());
if (pSuite) {
+
+ if (force_run)
+ CU_set_suite_active(pSuite, CU_TRUE);
+
if (test_id != -1) { /* If user specify test id */
pTest = CU_get_test_by_index(
(unsigned int) test_id,
pSuite);
- if (pTest)
+ if (pTest) {
+ if (force_run)
+ CU_set_test_active(pTest, CU_TRUE);
+
CU_basic_run_test(pSuite, pTest);
+ }
else {
fprintf(stderr, "Invalid test id: %d\n",
test_id);
@@ -428,6 +599,7 @@
} else
CU_basic_run_tests();
+end:
CU_cleanup_registry();
amdgpu_close_devices();
return CU_get_error();
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index e30e231..6287573 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -85,6 +85,11 @@
int suite_cs_tests_clean();
/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_cs_tests_enable(void);
+
+/**
* Tests in cs test suite
*/
extern CU_TestInfo cs_tests[];
@@ -100,11 +105,96 @@
int suite_vce_tests_clean();
/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vce_tests_enable(void);
+
+/**
* Tests in vce test suite
*/
extern CU_TestInfo vce_tests[];
/**
++ * Initialize vcn test suite
++ */
+int suite_vcn_tests_init();
+
+/**
++ * Deinitialize vcn test suite
++ */
+int suite_vcn_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vcn_tests_enable(void);
+
+/**
++ * Tests in vcn test suite
++ */
+extern CU_TestInfo vcn_tests[];
+
+/**
+ * Initialize uvd enc test suite
+ */
+int suite_uvd_enc_tests_init();
+
+/**
+ * Deinitialize uvd enc test suite
+ */
+int suite_uvd_enc_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_uvd_enc_tests_enable(void);
+
+/**
+ * Tests in uvd enc test suite
+ */
+extern CU_TestInfo uvd_enc_tests[];
+
+/**
+ * Initialize deadlock test suite
+ */
+int suite_deadlock_tests_init();
+
+/**
+ * Deinitialize deadlock test suite
+ */
+int suite_deadlock_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_deadlock_tests_enable(void);
+
+/**
+ * Tests in uvd enc test suite
+ */
+extern CU_TestInfo deadlock_tests[];
+
+/**
+ * Initialize vm test suite
+ */
+int suite_vm_tests_init();
+
+/**
+ * Deinitialize deadlock test suite
+ */
+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[];
+
+/**
* Helper functions
*/
static inline amdgpu_bo_handle gpu_mem_alloc(
@@ -162,6 +252,29 @@
}
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,
@@ -236,4 +349,35 @@
return amdgpu_bo_list_create(dev, bo2 ? 2 : 1, resources, NULL, list);
}
+
+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(suite_name), active);
+
+ if (r != CUE_SUCCESS)
+ fprintf(stderr, "Failed to obtain suite %s\n", suite_name);
+
+ return r;
+}
+
+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(suite_name);
+
+ if (!pSuite) {
+ fprintf(stderr, "Failed to obtain suite %s\n",
+ suite_name);
+ return CUE_NOSUITE;
+ }
+
+ r = CU_set_test_active(CU_get_test(pSuite, test_name), active);
+ if (r != CUE_SUCCESS)
+ fprintf(stderr, "Failed to obtain test %s\n", test_name);
+
+ return r;
+}
+
#endif /* #ifdef _AMDGPU_TEST_H_ */
diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c
index bfda21b..1adbddd 100644
--- a/tests/amdgpu/basic_tests.c
+++ b/tests/amdgpu/basic_tests.c
@@ -21,16 +21,13 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
+#include <sys/wait.h>
#include "CUnit/Basic.h"
@@ -40,27 +37,38 @@
static amdgpu_device_handle device_handle;
static uint32_t major_version;
static uint32_t minor_version;
+static uint32_t family_id;
static void amdgpu_query_info_test(void);
-static void amdgpu_memory_alloc(void);
static void amdgpu_command_submission_gfx(void);
static void amdgpu_command_submission_compute(void);
+static void amdgpu_command_submission_multi_fence(void);
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 },
- { "Memory alloc Test", amdgpu_memory_alloc },
{ "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 },
{ "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
{ "SW semaphore Test", amdgpu_semaphore_test },
+ { "Sync dependency Test", amdgpu_sync_dependency_test },
CU_TEST_INFO_NULL,
};
#define BUFFER_SIZE (8 * 1024)
@@ -197,22 +205,110 @@
# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
+#define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \
+ (((b) & 0x1) << 26) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((cnt) & 0xFFFFF) << 0))
+#define SDMA_OPCODE_COPY_SI 3
+#define SDMA_OPCODE_CONSTANT_FILL_SI 13
+#define SDMA_NOP_SI 0xf
+#define GFX_COMPUTE_NOP_SI 0x80000000
+#define PACKET3_DMA_DATA_SI 0x41
+# define PACKET3_DMA_DATA_SI_ENGINE(x) ((x) << 27)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_DMA_DATA_SI_DST_SEL(x) ((x) << 20)
+ /* 0 - DST_ADDR using DAS
+ * 1 - GDS
+ * 3 - DST_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR using SAS
+ * 1 - GDS
+ * 2 - DATA
+ * 3 - SRC_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_CP_SYNC (1 << 31)
+
+
+#define PKT3_CONTEXT_CONTROL 0x28
+#define CONTEXT_CONTROL_LOAD_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+#define CONTEXT_CONTROL_LOAD_CE_RAM(x) (((unsigned)(x) & 0x1) << 28)
+#define CONTEXT_CONTROL_SHADOW_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+
+#define PKT3_CLEAR_STATE 0x12
+
+#define PKT3_SET_SH_REG 0x76
+#define PACKET3_SET_SH_REG_START 0x00002c00
+
+#define PACKET3_DISPATCH_DIRECT 0x15
+
+
+/* gfx 8 */
+#define mmCOMPUTE_PGM_LO 0x2e0c
+#define mmCOMPUTE_PGM_RSRC1 0x2e12
+#define mmCOMPUTE_TMPRING_SIZE 0x2e18
+#define mmCOMPUTE_USER_DATA_0 0x2e40
+#define mmCOMPUTE_USER_DATA_1 0x2e41
+#define mmCOMPUTE_RESOURCE_LIMITS 0x2e15
+#define mmCOMPUTE_NUM_THREAD_X 0x2e07
+
+
+
+#define SWAP_32(num) (((num & 0xff000000) >> 24) | \
+ ((num & 0x0000ff00) << 8) | \
+ ((num & 0x00ff0000) >> 8) | \
+ ((num & 0x000000ff) << 24))
+
+
+/* Shader code
+ * void main()
+{
+
+ float x = some_input;
+ for (unsigned i = 0; i < 1000000; i++)
+ x = sin(x);
+
+ u[0] = 42u;
+}
+*/
+
+static uint32_t shader_bin[] = {
+ SWAP_32(0x800082be), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0x040085bf),
+ SWAP_32(0x02810281), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0xfcff84bf),
+ SWAP_32(0xff0083be), SWAP_32(0x00f00000), SWAP_32(0xc10082be), SWAP_32(0xaa02007e),
+ SWAP_32(0x000070e0), SWAP_32(0x00000080), SWAP_32(0x000081bf)
+};
+
+#define CODE_OFFSET 512
+#define DATA_OFFSET 1024
+
+
int suite_basic_tests_init(void)
{
+ struct amdgpu_gpu_info gpu_info = {0};
int r;
r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
&minor_version, &device_handle);
- if (r == 0)
- return CUE_SUCCESS;
- else {
+ if (r) {
if ((r == -EACCES) && (errno == EACCES))
printf("\n\nError:%s. "
"Hint:Try to run this test program as root.",
strerror(errno));
return CUE_SINIT_FAILED;
}
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = gpu_info.family_id;
+
+ return CUE_SUCCESS;
}
int suite_basic_tests_clean(void)
@@ -239,53 +335,6 @@
CU_ASSERT_EQUAL(r, 0);
}
-static void amdgpu_memory_alloc(void)
-{
- amdgpu_bo_handle bo;
- amdgpu_va_handle va_handle;
- uint64_t bo_mc;
- int r;
-
- /* Test visible VRAM */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
- &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-
- /* Test invisible VRAM */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
- &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-
- /* Test GART Cacheable */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- 0, &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-
- /* Test GART USWC */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- AMDGPU_GEM_CREATE_CPU_GTT_USWC,
- &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-}
-
static void amdgpu_command_submission_gfx_separate_ibs(void)
{
amdgpu_context_handle context_handle;
@@ -299,7 +348,7 @@
uint32_t expired;
amdgpu_bo_list_handle bo_list;
amdgpu_va_handle va_handle, va_handle_ce;
- int r;
+ int r, i = 0;
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -324,12 +373,14 @@
/* IT_SET_CE_DE_COUNTERS */
ptr = ib_result_ce_cpu;
- ptr[0] = 0xc0008900;
- ptr[1] = 0;
- ptr[2] = 0xc0008400;
- ptr[3] = 1;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
ib_info[0].ib_mc_address = ib_result_ce_mc_address;
- ib_info[0].size = 4;
+ ib_info[0].size = i;
ib_info[0].flags = AMDGPU_IB_FLAG_CE;
/* IT_WAIT_ON_CE_COUNTER */
@@ -388,7 +439,7 @@
uint32_t expired;
amdgpu_bo_list_handle bo_list;
amdgpu_va_handle va_handle;
- int r;
+ int r, i = 0;
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -407,12 +458,14 @@
/* IT_SET_CE_DE_COUNTERS */
ptr = ib_result_cpu;
- ptr[0] = 0xc0008900;
- ptr[1] = 0;
- ptr[2] = 0xc0008400;
- ptr[3] = 1;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
ib_info[0].ib_mc_address = ib_result_mc_address;
- ib_info[0].size = 4;
+ ib_info[0].size = i;
ib_info[0].flags = AMDGPU_IB_FLAG_CE;
ptr = (uint32_t *)ib_result_cpu + 4;
@@ -467,6 +520,156 @@
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 */
@@ -493,10 +696,19 @@
struct amdgpu_cs_fence fence_status = {0};
uint32_t *ptr;
uint32_t expired;
+ uint32_t sdma_nop, gfx_nop;
amdgpu_bo_list_handle bo_list[2];
amdgpu_va_handle va_handle[2];
int r, i;
+ if (family_id == AMDGPU_FAMILY_SI) {
+ sdma_nop = SDMA_PACKET_SI(SDMA_NOP_SI, 0, 0, 0, 0);
+ gfx_nop = GFX_COMPUTE_NOP_SI;
+ } else {
+ sdma_nop = SDMA_PKT_HEADER_OP(SDMA_NOP);
+ gfx_nop = GFX_COMPUTE_NOP;
+ }
+
r = amdgpu_cs_create_semaphore(&sem);
CU_ASSERT_EQUAL(r, 0);
for (i = 0; i < 2; i++) {
@@ -516,7 +728,7 @@
/* 1. same context different engine */
ptr = ib_result_cpu[0];
- ptr[0] = SDMA_NOP;
+ ptr[0] = sdma_nop;
ib_info[0].ib_mc_address = ib_result_mc_address[0];
ib_info[0].size = 1;
@@ -533,7 +745,7 @@
r = amdgpu_cs_wait_semaphore(context_handle[0], AMDGPU_HW_IP_GFX, 0, 0, sem);
CU_ASSERT_EQUAL(r, 0);
ptr = ib_result_cpu[1];
- ptr[0] = GFX_COMPUTE_NOP;
+ ptr[0] = gfx_nop;
ib_info[1].ib_mc_address = ib_result_mc_address[1];
ib_info[1].size = 1;
@@ -557,7 +769,7 @@
/* 2. same engine different context */
ptr = ib_result_cpu[0];
- ptr[0] = GFX_COMPUTE_NOP;
+ ptr[0] = gfx_nop;
ib_info[0].ib_mc_address = ib_result_mc_address[0];
ib_info[0].size = 1;
@@ -574,7 +786,7 @@
r = amdgpu_cs_wait_semaphore(context_handle[1], AMDGPU_HW_IP_GFX, 0, 0, sem);
CU_ASSERT_EQUAL(r, 0);
ptr = ib_result_cpu[1];
- ptr[0] = GFX_COMPUTE_NOP;
+ ptr[0] = gfx_nop;
ib_info[1].ib_mc_address = ib_result_mc_address[1];
ib_info[1].size = 1;
@@ -595,6 +807,7 @@
500000000, 0, &expired);
CU_ASSERT_EQUAL(r, 0);
CU_ASSERT_EQUAL(expired, true);
+
for (i = 0; i < 2; i++) {
r = amdgpu_bo_unmap_and_free(ib_result_handle[i], va_handle[i],
ib_result_mc_address[i], 4096);
@@ -622,14 +835,18 @@
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;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_COMPUTE, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
- for (instance = 0; instance < 8; instance++) {
+ for (instance = 0; (1 << instance) & info.available_rings; instance++) {
r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
AMDGPU_GEM_DOMAIN_GTT, 0,
&ib_result_handle, &ib_result_cpu,
@@ -641,8 +858,8 @@
CU_ASSERT_EQUAL(r, 0);
ptr = ib_result_cpu;
- for (i = 0; i < 16; ++i)
- ptr[i] = 0xffff1000;
+ memset(ptr, 0, 16);
+ ptr[0]=PACKET3(PACKET3_NOP, 14);
memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
ib_info.ib_mc_address = ib_result_mc_address;
@@ -805,9 +1022,10 @@
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);
@@ -818,6 +1036,9 @@
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);
@@ -825,58 +1046,66 @@
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) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
- SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
- pm4[i++] = 0xffffffff & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- 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);
+
+ /* 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++;
}
-
- 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);
- }
-
- 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);
@@ -906,9 +1135,10 @@
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);
@@ -919,6 +1149,9 @@
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);
@@ -926,60 +1159,86 @@
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) {
- 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;
- pm4[i++] = sdma_write_length;
- } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
- (ip_type == AMDGPU_HW_IP_COMPUTE)) {
- 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;
+ /* 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;
+ }
+ }
+
+ 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);
+ }
+
+ r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+ loop++;
}
-
- 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 / 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++;
}
/* clean resources */
free(resources);
@@ -1009,9 +1268,10 @@
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);
@@ -1022,6 +1282,9 @@
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);
@@ -1029,81 +1292,111 @@
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);
+ 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);
+ /* 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);
+ /* 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);
+ /* clear bo2 */
+ memset((void*)bo2_cpu, 0, sdma_write_length);
- resources[0] = bo1;
- resources[1] = bo2;
+ resources[0] = bo1;
+ resources[1] = bo2;
- /* fulfill PM4: test DMA copy linear */
- i = j = 0;
- if (ip_type == AMDGPU_HW_IP_DMA) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
- 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)) {
- 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;
+ /* 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;
+ } 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);
+
+ /* 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++;
}
-
- 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);
- }
- 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);
@@ -1128,6 +1421,106 @@
amdgpu_command_submission_sdma_copy_linear();
}
+static void amdgpu_command_submission_multi_fence_wait_all(bool wait_all)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
+ void *ib_result_cpu, *ib_result_ce_cpu;
+ uint64_t ib_result_mc_address, ib_result_ce_mc_address;
+ struct amdgpu_cs_request ibs_request[2] = {0};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status[2] = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle, va_handle_ce;
+ int r;
+ int i = 0, ib_cs_num = 2;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_ce_handle, &ib_result_ce_cpu,
+ &ib_result_ce_mc_address, &va_handle_ce);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle,
+ ib_result_ce_handle, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_ce_cpu;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
+ ib_info[0].ib_mc_address = ib_result_ce_mc_address;
+ ib_info[0].size = i;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ /* IT_WAIT_ON_CE_COUNTER */
+ ptr = ib_result_cpu;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address;
+ ib_info[1].size = 2;
+
+ for (i = 0; i < ib_cs_num; i++) {
+ ibs_request[i].ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request[i].number_of_ibs = 2;
+ ibs_request[i].ibs = ib_info;
+ ibs_request[i].resources = bo_list;
+ ibs_request[i].fence_info.handle = NULL;
+ }
+
+ r = amdgpu_cs_submit(context_handle, 0,ibs_request, ib_cs_num);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (i = 0; i < ib_cs_num; i++) {
+ fence_status[i].context = context_handle;
+ fence_status[i].ip_type = AMDGPU_HW_IP_GFX;
+ fence_status[i].fence = ibs_request[i].seq_no;
+ }
+
+ r = amdgpu_cs_wait_fences(fence_status, ib_cs_num, wait_all,
+ AMDGPU_TIMEOUT_INFINITE,
+ &expired, NULL);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
+ ib_result_ce_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_multi_fence(void)
+{
+ amdgpu_command_submission_multi_fence_wait_all(true);
+ amdgpu_command_submission_multi_fence_wait_all(false);
+}
+
static void amdgpu_userptr_test(void)
{
int i, r, j;
@@ -1175,15 +1568,28 @@
handle = buf_handle;
j = i = 0;
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
- SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+
+ 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;
- pm4[i++] = sdma_write_length;
+ 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;
+ if (!fork()) {
+ pm4[0] = 0x0;
+ exit(0);
+ }
+
amdgpu_test_exec_cs_helper(context_handle,
AMDGPU_HW_IP_DMA, 0,
i, pm4,
@@ -1207,4 +1613,212 @@
r = amdgpu_cs_ctx_free(context_handle);
CU_ASSERT_EQUAL(r, 0);
+
+ wait(NULL);
+}
+
+static void amdgpu_sync_dependency_test(void)
+{
+ amdgpu_context_handle context_handle[2];
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, j, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ static uint32_t *ptr;
+ uint64_t seq_no;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 8192, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ i = 0;
+
+ memcpy(ptr + CODE_OFFSET , shader_bin, sizeof(shader_bin));
+
+ /* Dispatch minimal init config and verify it's executed */
+ ptr[i++] = PACKET3(PKT3_CONTEXT_CONTROL, 1);
+ ptr[i++] = 0x80000000;
+ ptr[i++] = 0x80000000;
+
+ ptr[i++] = PACKET3(PKT3_CLEAR_STATE, 0);
+ ptr[i++] = 0x80000000;
+
+
+ /* Program compute regs */
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START;
+ ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 8;
+ ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 40;
+
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_PGM_RSRC1 - PACKET3_SET_SH_REG_START;
+ /*
+ * 002c0040 COMPUTE_PGM_RSRC1 <- VGPRS = 0
+ SGPRS = 1
+ PRIORITY = 0
+ FLOAT_MODE = 192 (0xc0)
+ PRIV = 0
+ DX10_CLAMP = 1
+ DEBUG_MODE = 0
+ IEEE_MODE = 0
+ BULKY = 0
+ CDBG_USER = 0
+ *
+ */
+ ptr[i++] = 0x002c0040;
+
+
+ /*
+ * 00000010 COMPUTE_PGM_RSRC2 <- SCRATCH_EN = 0
+ USER_SGPR = 8
+ TRAP_PRESENT = 0
+ TGID_X_EN = 0
+ TGID_Y_EN = 0
+ TGID_Z_EN = 0
+ TG_SIZE_EN = 0
+ TIDIG_COMP_CNT = 0
+ EXCP_EN_MSB = 0
+ LDS_SIZE = 0
+ EXCP_EN = 0
+ *
+ */
+ ptr[i++] = 0x00000010;
+
+
+/*
+ * 00000100 COMPUTE_TMPRING_SIZE <- WAVES = 256 (0x100)
+ WAVESIZE = 0
+ *
+ */
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr[i++] = mmCOMPUTE_TMPRING_SIZE - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0x00000100;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_USER_DATA_0 - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0xffffffff & (ib_result_mc_address + DATA_OFFSET * 4);
+ ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr[i++] = mmCOMPUTE_RESOURCE_LIMITS - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 3);
+ ptr[i++] = mmCOMPUTE_NUM_THREAD_X - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+
+
+ /* Dispatch */
+ ptr[i++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 0x00000045; /* DISPATCH DIRECT field */
+
+
+ while (i & 7)
+ ptr[i++] = 0xffff1000; /* type3 nop packet */
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = i;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle[1], 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ seq_no = ibs_request.seq_no;
+
+
+
+ /* Prepare second command with dependency on the first */
+ 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++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
+ ptr[i++] = 99;
+
+ while (i & 7)
+ ptr[i++] = 0xffff1000; /* type3 nop packet */
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address + j * 4;
+ ib_info.size = i - j;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ ibs_request.number_of_dependencies = 1;
+
+ ibs_request.dependencies = calloc(1, sizeof(*ibs_request.dependencies));
+ ibs_request.dependencies[0].context = context_handle[1];
+ ibs_request.dependencies[0].ip_instance = 0;
+ ibs_request.dependencies[0].ring = 0;
+ ibs_request.dependencies[0].fence = seq_no;
+
+
+ r = amdgpu_cs_submit(context_handle[0], 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle[0];
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Expect the second command to wait for shader to complete */
+ CU_ASSERT_EQUAL(ptr[DATA_OFFSET], 99);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_ctx_free(context_handle[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free(ibs_request.dependencies);
}
diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c
index 74b5e77..9d4da4a 100644
--- a/tests/amdgpu/bo_tests.c
+++ b/tests/amdgpu/bo_tests.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include "CUnit/Basic.h"
@@ -46,13 +42,15 @@
static void amdgpu_bo_export_import(void);
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);
CU_TestInfo bo_tests[] = {
{ "Export/Import", amdgpu_bo_export_import },
-#if 0
{ "Metadata", amdgpu_bo_metadata },
-#endif
{ "CPU map/unmap", amdgpu_bo_map_unmap },
+ { "Memory alloc Test", amdgpu_memory_alloc },
+ { "Memory fail alloc Test", amdgpu_mem_fail_alloc },
CU_TEST_INFO_NULL,
};
@@ -195,3 +193,72 @@
r = amdgpu_bo_cpu_unmap(buffer_handle);
CU_ASSERT_EQUAL(r, 0);
}
+
+static void amdgpu_memory_alloc(void)
+{
+ amdgpu_bo_handle bo;
+ amdgpu_va_handle va_handle;
+ uint64_t bo_mc;
+ int r;
+
+ /* Test visible VRAM */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test invisible VRAM */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GART Cacheable */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ 0, &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GART USWC */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_CREATE_CPU_GTT_USWC,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_mem_fail_alloc(void)
+{
+ amdgpu_bo_handle bo;
+ int r;
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+
+ /* Test impossible mem allocation, 1TB */
+ req.alloc_size = 0xE8D4A51000;
+ req.phys_alignment = 4096;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;
+ req.flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, -ENOMEM);
+
+ if (!r) {
+ r = amdgpu_bo_free(bo);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+}
diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c
index 82c55aa..7ad0f0d 100644
--- a/tests/amdgpu/cs_tests.c
+++ b/tests/amdgpu/cs_tests.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include "CUnit/Basic.h"
@@ -32,7 +28,7 @@
#include "util_math.h"
#include "amdgpu_test.h"
-#include "uvd_messages.h"
+#include "decode_messages.h"
#include "amdgpu_drm.h"
#include "amdgpu_internal.h"
@@ -66,6 +62,26 @@
CU_TEST_INFO_NULL,
};
+CU_BOOL suite_cs_tests_enable(void)
+{
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+
+ 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 UVD, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ return CU_TRUE;
+}
+
int suite_cs_tests_init(void)
{
amdgpu_bo_handle ib_result_handle;
@@ -175,11 +191,11 @@
static void uvd_cmd(uint64_t addr, unsigned cmd, int *idx)
{
- ib_cpu[(*idx)++] = 0x3BC4;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC4 : 0x81C4;
ib_cpu[(*idx)++] = addr;
- ib_cpu[(*idx)++] = 0x3BC5;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC5 : 0x81C5;
ib_cpu[(*idx)++] = addr >> 32;
- ib_cpu[(*idx)++] = 0x3BC3;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC3 : 0x81C3;
ib_cpu[(*idx)++] = cmd << 1;
}
@@ -211,10 +227,13 @@
CU_ASSERT_EQUAL(r, 0);
memcpy(msg, uvd_create_msg, sizeof(uvd_create_msg));
+
if (family_id >= AMDGPU_FAMILY_VI) {
((uint8_t*)msg)[0x10] = 7;
- /* chip polaris 10/11 */
- if (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A) {
+ /* chip beyond polaris 10/11 */
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
/* dpb size */
((uint8_t*)msg)[0x28] = 0x00;
((uint8_t*)msg)[0x29] = 0x94;
@@ -250,7 +269,7 @@
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;
@@ -286,14 +305,18 @@
r = amdgpu_bo_cpu_map(buf_handle, (void **)&ptr);
CU_ASSERT_EQUAL(r, 0);
- memcpy(ptr, uvd_decode_msg, sizeof(uvd_create_msg));
+ memcpy(ptr, uvd_decode_msg, sizeof(uvd_decode_msg));
+ memcpy(ptr + sizeof(uvd_decode_msg), avc_decode_msg, sizeof(avc_decode_msg));
+
if (family_id >= AMDGPU_FAMILY_VI) {
ptr[0x10] = 7;
ptr[0x98] = 0x00;
ptr[0x99] = 0x02;
- /* chip polaris10/11 */
- if (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A) {
- /*dpb size */
+ /* chip beyond polaris10/11 */
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
+ /* dpb size */
ptr[0x24] = 0x00;
ptr[0x25] = 0x94;
ptr[0x26] = 0x6B;
@@ -335,9 +358,12 @@
bs_addr = fb_addr + 4*1024;
dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
- if ((family_id >= AMDGPU_FAMILY_VI) &&
- (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A)) {
- ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
+ ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ }
}
dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
@@ -348,12 +374,16 @@
uvd_cmd(dt_addr, 0x2, &i);
uvd_cmd(fb_addr, 0x3, &i);
uvd_cmd(bs_addr, 0x100, &i);
+
if (family_id >= AMDGPU_FAMILY_VI) {
uvd_cmd(it_addr, 0x204, &i);
- if (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A)
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64))
uvd_cmd(ctx_addr, 0x206, &i);
-}
- ib_cpu[i++] = 0x3BC6;
+ }
+
+ ib_cpu[i++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC6 : 0x81C6;
ib_cpu[i++] = 0x1;
for (; i % 16; ++i)
ib_cpu[i] = 0x80000000;
@@ -364,7 +394,7 @@
/* TODO: use a real CRC32 */
for (i = 0, sum = 0; i < dt_size; ++i)
sum += ptr[i];
- CU_ASSERT_EQUAL(sum, 0x20345d8);
+ CU_ASSERT_EQUAL(sum, SUM_DECODE);
r = amdgpu_bo_cpu_unmap(buf_handle);
CU_ASSERT_EQUAL(r, 0);
diff --git a/tests/amdgpu/deadlock_tests.c b/tests/amdgpu/deadlock_tests.c
new file mode 100644
index 0000000..1eb5761
--- /dev/null
+++ b/tests/amdgpu/deadlock_tests.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2017 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#include <pthread.h>
+
+
+/*
+ * This defines the delay in MS after which memory location designated for
+ * compression against reference value is written to, unblocking command
+ * processor
+ */
+#define WRITE_MEM_ADDRESS_DELAY_MS 100
+
+#define PACKET_TYPE3 3
+
+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
+ (((op) & 0xFF) << 8) | \
+ ((n) & 0x3FFF) << 16)
+
+#define PACKET3_WAIT_REG_MEM 0x3C
+#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0)
+ /* 0 - always
+ * 1 - <
+ * 2 - <=
+ * 3 - ==
+ * 4 - !=
+ * 5 - >=
+ * 6 - >
+ */
+#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4)
+ /* 0 - reg
+ * 1 - mem
+ */
+#define WAIT_REG_MEM_OPERATION(x) ((x) << 6)
+ /* 0 - wait_reg_mem
+ * 1 - wr_wait_wr_reg
+ */
+#define WAIT_REG_MEM_ENGINE(x) ((x) << 8)
+ /* 0 - me
+ * 1 - pfp
+ */
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static pthread_t stress_thread;
+static uint32_t *ptr;
+
+static void amdgpu_deadlock_helper(unsigned ip_type);
+static void amdgpu_deadlock_gfx(void);
+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 (device_handle->info.family_id == AMDGPU_FAMILY_AI ||
+ device_handle->info.family_id == AMDGPU_FAMILY_SI) {
+ printf("\n\nCurrently hangs the CP on this ASIC, deadlock suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_deadlock_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_deadlock_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo deadlock_tests[] = {
+ { "gfx ring block test", amdgpu_deadlock_gfx },
+ { "compute ring block test", amdgpu_deadlock_compute },
+ CU_TEST_INFO_NULL,
+};
+
+static void *write_mem_address(void *data)
+{
+ int i;
+
+ /* useconds_t range is [0, 1,000,000] so use loop for waits > 1s */
+ for (i = 0; i < WRITE_MEM_ADDRESS_DELAY_MS; i++)
+ usleep(1000);
+
+ ptr[256] = 0x1;
+
+ return 0;
+}
+
+static void amdgpu_deadlock_gfx(void)
+{
+ amdgpu_deadlock_helper(AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_deadlock_compute(void)
+{
+ amdgpu_deadlock_helper(AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_deadlock_helper(unsigned ip_type)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+
+ r = pthread_create(&stress_thread, NULL, write_mem_address, NULL);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+
+ ptr[0] = PACKET3(PACKET3_WAIT_REG_MEM, 5);
+ ptr[1] = (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
+ WAIT_REG_MEM_FUNCTION(4) | /* != */
+ WAIT_REG_MEM_ENGINE(0)); /* me */
+ ptr[2] = (ib_result_mc_address + 256*4) & 0xfffffffc;
+ ptr[3] = ((ib_result_mc_address + 256*4) >> 32) & 0xffffffff;
+ ptr[4] = 0x00000000; /* reference value */
+ ptr[5] = 0xffffffff; /* and mask */
+ ptr[6] = 0x00000004; /* poll interval */
+
+ for (i = 7; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+
+ ptr[256] = 0x0; /* the memory we wait on to change */
+
+
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = ip_type;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ for (i = 0; i < 200; i++) {
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ }
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ 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);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
diff --git a/tests/amdgpu/uvd_messages.h b/tests/amdgpu/decode_messages.h
similarity index 96%
rename from tests/amdgpu/uvd_messages.h
rename to tests/amdgpu/decode_messages.h
index 00235cb..bd6fe4b 100644
--- a/tests/amdgpu/uvd_messages.h
+++ b/tests/amdgpu/decode_messages.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2017 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"),
@@ -21,8 +21,10 @@
*
*/
-#ifndef _UVD_MESSAGES_H_
-#define _UVD_MESSAGES_H_
+#ifndef _DECODE_MESSAGES_H_
+#define _DECODE_MESSAGES_H_
+
+#define SUM_DECODE 0x20345d8
static const uint8_t uvd_create_msg[] = {
0xe4,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
@@ -356,6 +358,9 @@
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t avc_decode_msg[] = {
0x02,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x88,0x00,0x00,0x00,
0x01,0x00,0x00,0x01,0x00,0x03,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
@@ -810,4 +815,34 @@
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
};
-#endif /* _UVD_MESSAGES_H_ */
+static const uint8_t vcn_dec_create_msg[] = {
+ 0x28,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x28,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,
+};
+
+static const uint8_t vcn_dec_decode_msg[] = {
+ 0x28,0x00,0x00,0x00,0x90,0x06,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
+ 0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xec,0x00,0x00,0x00,
+ 0x5c,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x94,0x6b,0x00,
+ 0x96,0x4e,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x50,0x00,
+ 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,
+ 0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0x80,0x07,0x00,0x00,0x60,0x09,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t vcn_dec_destroy_msg[] = {
+ 0x28,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
+};
+
+#endif /* _DECODE_MESSAGES_H_ */
diff --git a/tests/amdgpu/frame.h b/tests/amdgpu/frame.h
index 4c946c2..335401c 100644
--- a/tests/amdgpu/frame.h
+++ b/tests/amdgpu/frame.h
@@ -24,7 +24,7 @@
#ifndef _frame_h_
#define _frame_h_
-const uint8_t frame[] = {
+static const uint8_t frame[] = {
0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
new file mode 100644
index 0000000..4c1237c
--- /dev/null
+++ b/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/tests/amdgpu/uvd_enc_tests.c b/tests/amdgpu/uvd_enc_tests.c
new file mode 100644
index 0000000..b4251bc
--- /dev/null
+++ b/tests/amdgpu/uvd_enc_tests.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2017 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 <stdio.h>
+#include <inttypes.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "frame.h"
+#include "uve_ib.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+struct amdgpu_uvd_enc_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+struct amdgpu_uvd_enc {
+ unsigned width;
+ unsigned height;
+ struct amdgpu_uvd_enc_bo session;
+ struct amdgpu_uvd_enc_bo vbuf;
+ struct amdgpu_uvd_enc_bo bs;
+ struct amdgpu_uvd_enc_bo fb;
+ struct amdgpu_uvd_enc_bo cpb;
+};
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static amdgpu_va_handle ib_va_handle;
+static uint64_t ib_mc_address;
+static uint32_t *ib_cpu;
+
+static struct amdgpu_uvd_enc enc;
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static void amdgpu_cs_uvd_enc_create(void);
+static void amdgpu_cs_uvd_enc_session_init(void);
+static void amdgpu_cs_uvd_enc_encode(void);
+static void amdgpu_cs_uvd_enc_destroy(void);
+
+
+CU_TestInfo uvd_enc_tests[] = {
+ { "UVD ENC create", amdgpu_cs_uvd_enc_create },
+ { "UVD ENC session init", amdgpu_cs_uvd_enc_session_init },
+ { "UVD ENC encode", amdgpu_cs_uvd_enc_encode },
+ { "UVD ENC destroy", amdgpu_cs_uvd_enc_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_uvd_enc_tests_enable(void)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_UVD_ENC, 0, &info);
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ if (!info.available_rings)
+ printf("\n\nThe ASIC NOT support UVD ENC, suite disabled.\n");
+
+ return (r == 0 && (info.available_rings ? CU_TRUE : CU_FALSE));
+}
+
+
+int suite_uvd_enc_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = device_handle->info.family_id;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_handle, (void**)&ib_cpu,
+ &ib_mc_address, &ib_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+int suite_uvd_enc_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
+ ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void alloc_resource(struct amdgpu_uvd_enc_bo *uvd_enc_bo,
+ unsigned size, unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ uvd_enc_bo->addr = va;
+ uvd_enc_bo->handle = buf_handle;
+ uvd_enc_bo->size = req.alloc_size;
+ uvd_enc_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(uvd_enc_bo->handle, (void **)&uvd_enc_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(uvd_enc_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(uvd_enc_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_uvd_enc_bo *uvd_enc_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(uvd_enc_bo->handle, 0, uvd_enc_bo->size,
+ uvd_enc_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(uvd_enc_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(uvd_enc_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(uvd_enc_bo, 0, sizeof(*uvd_enc_bo));
+}
+
+static void amdgpu_cs_uvd_enc_create(void)
+{
+ enc.width = 160;
+ enc.height = 128;
+
+ num_resources = 0;
+ alloc_resource(&enc.session, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.session.handle;
+ resources[num_resources++] = ib_handle;
+}
+
+static void check_result(struct amdgpu_uvd_enc *enc)
+{
+ uint64_t sum;
+ uint32_t s = 175602;
+ uint32_t *ptr, size;
+ int j, r;
+
+ r = amdgpu_bo_cpu_map(enc->fb.handle, (void **)&enc->fb.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr = (uint32_t *)enc->fb.ptr;
+ size = ptr[6];
+ r = amdgpu_bo_cpu_unmap(enc->fb.handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_map(enc->bs.handle, (void **)&enc->bs.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ for (j = 0, sum = 0; j < size; ++j)
+ sum += enc->bs.ptr[j];
+ CU_ASSERT_EQUAL(sum, s);
+ r = amdgpu_bo_cpu_unmap(enc->bs.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+}
+
+static void amdgpu_cs_uvd_enc_session_init(void)
+{
+ int len, r;
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0x000000d8;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_op_init, sizeof(uve_op_init));
+ len += sizeof(uve_op_init) / 4;
+
+ memcpy((ib_cpu + len), uve_session_init, sizeof(uve_session_init));
+ len += sizeof(uve_session_init) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_ctrl, sizeof(uve_layer_ctrl));
+ len += sizeof(uve_layer_ctrl) / 4;
+
+ memcpy((ib_cpu + len), uve_slice_ctrl, sizeof(uve_slice_ctrl));
+ len += sizeof(uve_slice_ctrl) / 4;
+
+ memcpy((ib_cpu + len), uve_spec_misc, sizeof(uve_spec_misc));
+ len += sizeof(uve_spec_misc) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_session_init, sizeof(uve_rc_session_init));
+ len += sizeof(uve_rc_session_init) / 4;
+
+ memcpy((ib_cpu + len), uve_deblocking_filter, sizeof(uve_deblocking_filter));
+ len += sizeof(uve_deblocking_filter) / 4;
+
+ memcpy((ib_cpu + len), uve_quality_params, sizeof(uve_quality_params));
+ len += sizeof(uve_quality_params) / 4;
+
+ memcpy((ib_cpu + len), uve_op_init_rc, sizeof(uve_op_init_rc));
+ len += sizeof(uve_op_init_rc) / 4;
+
+ memcpy((ib_cpu + len), uve_op_init_rc_vbv_level, sizeof(uve_op_init_rc_vbv_level));
+ len += sizeof(uve_op_init_rc_vbv_level) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_uvd_enc_encode(void)
+{
+ int len, r, i;
+ uint64_t luma_offset, chroma_offset;
+ uint32_t vbuf_size, bs_size = 0x003f4800, cpb_size;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
+ cpb_size = vbuf_size * 10;
+
+
+ num_resources = 0;
+ alloc_resource(&enc.fb, 4096, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.fb.handle;
+ alloc_resource(&enc.bs, bs_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.bs.handle;
+ alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.vbuf.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);
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0x000005e0;
+ ib_cpu[len++] = 0x00000001;
+ ib_cpu[len++] = 0x00000001;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_1, sizeof(uve_nalu_buffer_1));
+ len += sizeof(uve_nalu_buffer_1) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_2, sizeof(uve_nalu_buffer_2));
+ len += sizeof(uve_nalu_buffer_2) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_3, sizeof(uve_nalu_buffer_3));
+ len += sizeof(uve_nalu_buffer_3) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_4, sizeof(uve_nalu_buffer_4));
+ len += sizeof(uve_nalu_buffer_4) / 4;
+
+ memcpy((ib_cpu + len), uve_slice_header, sizeof(uve_slice_header));
+ len += sizeof(uve_slice_header) / 4;
+
+ ib_cpu[len++] = 0x00000254;
+ ib_cpu[len++] = 0x00000010;
+ ib_cpu[len++] = enc.cpb.addr >> 32;
+ ib_cpu[len++] = enc.cpb.addr;
+ memcpy((ib_cpu + len), uve_ctx_buffer, sizeof(uve_ctx_buffer));
+ len += sizeof(uve_ctx_buffer) / 4;
+
+ memcpy((ib_cpu + len), uve_bitstream_buffer, sizeof(uve_bitstream_buffer));
+ len += sizeof(uve_bitstream_buffer) / 4;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = enc.bs.addr >> 32;
+ ib_cpu[len++] = enc.bs.addr;
+ ib_cpu[len++] = 0x003f4800;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_feedback_buffer, sizeof(uve_feedback_buffer));
+ len += sizeof(uve_feedback_buffer) / 4;
+ ib_cpu[len++] = enc.fb.addr >> 32;
+ ib_cpu[len++] = enc.fb.addr;
+ ib_cpu[len++] = 0x00000010;
+ ib_cpu[len++] = 0x00000028;
+
+ memcpy((ib_cpu + len), uve_feedback_buffer_additional, sizeof(uve_feedback_buffer_additional));
+ len += sizeof(uve_feedback_buffer_additional) / 4;
+
+ memcpy((ib_cpu + len), uve_intra_refresh, sizeof(uve_intra_refresh));
+ len += sizeof(uve_intra_refresh) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_select, sizeof(uve_layer_select));
+ len += sizeof(uve_layer_select) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_layer_init, sizeof(uve_rc_layer_init));
+ len += sizeof(uve_rc_layer_init) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_select, sizeof(uve_layer_select));
+ len += sizeof(uve_layer_select) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_per_pic, sizeof(uve_rc_per_pic));
+ len += sizeof(uve_rc_per_pic) / 4;
+
+ unsigned luma_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16);
+ luma_offset = enc.vbuf.addr;
+ chroma_offset = luma_offset + luma_size;
+ ib_cpu[len++] = 0x00000054;
+ ib_cpu[len++] = 0x0000000c;
+ ib_cpu[len++] = 0x00000002;
+ ib_cpu[len++] = 0x003f4800;
+ ib_cpu[len++] = luma_offset >> 32;
+ ib_cpu[len++] = luma_offset;
+ ib_cpu[len++] = chroma_offset >> 32;
+ ib_cpu[len++] = chroma_offset;
+ memcpy((ib_cpu + len), uve_encode_param, sizeof(uve_encode_param));
+ ib_cpu[len] = ALIGN(enc.width, align);
+ ib_cpu[len + 1] = ALIGN(enc.width, align);
+ len += sizeof(uve_encode_param) / 4;
+
+ memcpy((ib_cpu + len), uve_op_speed_enc_mode, sizeof(uve_op_speed_enc_mode));
+ len += sizeof(uve_op_speed_enc_mode) / 4;
+
+ memcpy((ib_cpu + len), uve_op_encode, sizeof(uve_op_encode));
+ len += sizeof(uve_op_encode) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ check_result(&enc);
+
+ free_resource(&enc.fb);
+ free_resource(&enc.bs);
+ free_resource(&enc.vbuf);
+ free_resource(&enc.cpb);
+}
+
+static void amdgpu_cs_uvd_enc_destroy(void)
+{
+ int len, r;
+
+ num_resources = 0;
+ resources[num_resources++] = ib_handle;
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0xffffffff;
+ ib_cpu[len++] = 0x00000002;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_op_close, sizeof(uve_op_close));
+ len += sizeof(uve_op_close) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&enc.session);
+}
diff --git a/tests/amdgpu/uve_ib.h b/tests/amdgpu/uve_ib.h
new file mode 100644
index 0000000..cb72be2
--- /dev/null
+++ b/tests/amdgpu/uve_ib.h
@@ -0,0 +1,527 @@
+/*
+ * Copyright 2017 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 _uve_ib_h_
+#define _uve_ib_h_
+
+static const uint32_t uve_session_info[] = {
+ 0x00000018,
+ 0x00000001,
+ 0x00000000,
+ 0x00010000,
+};
+
+static const uint32_t uve_task_info[] = {
+ 0x00000014,
+ 0x00000002,
+};
+
+static const uint32_t uve_session_init[] = {
+ 0x00000020,
+ 0x00000003,
+ 0x000000c0,
+ 0x00000080,
+ 0x00000020,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_layer_ctrl[] = {
+ 0x00000010,
+ 0x00000004,
+ 0x00000001,
+ 0x00000001,
+};
+
+static const uint32_t uve_layer_select[] = {
+ 0x0000000c,
+ 0x00000005,
+ 0x00000000,
+};
+
+static const uint32_t uve_slice_ctrl[] = {
+ 0x00000014,
+ 0x00000006,
+ 0x00000000,
+ 0x00000006,
+ 0x00000006,
+};
+
+static const uint32_t uve_spec_misc[] = {
+ 0x00000024,
+ 0x00000007,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+ 0x00000001,
+};
+
+static const uint32_t uve_rc_session_init[] = {
+ 0x00000010,
+ 0x00000008,
+ 0x00000000,
+ 0x00000040,
+};
+
+static const uint32_t uve_rc_layer_init[] = {
+ 0x00000028,
+ 0x00000009,
+ 0x001e8480,
+ 0x001e8480,
+ 0x0000001e,
+ 0x00000001,
+ 0x0001046a,
+ 0x0001046a,
+ 0x0001046a,
+ 0xaaaaaaaa,
+};
+
+static const uint32_t uve_deblocking_filter[] = {
+ 0x00000020,
+ 0x0000000e,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_quality_params[] = {
+ 0x00000014,
+ 0x0000000d,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_feedback_buffer[] = {
+ 0x0000001c,
+ 0x00000012,
+ 0x00000000,
+};
+
+static const uint32_t uve_feedback_buffer_additional[] = {
+ 0x00000108,
+ 0x00000014,
+ 0x00000001,
+ 0x00000010,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_nalu_buffer_1[] = {
+ 0x00000018,
+ 0x00000013,
+ 0x00000001,
+ 0x00000007,
+ 0x00000001,
+ 0x46011000,
+};
+
+static const uint32_t uve_nalu_buffer_2[] = {
+ 0x0000002c,
+ 0x00000013,
+ 0x00000002,
+ 0x0000001b,
+ 0x00000001,
+ 0x40010c01,
+ 0xffff0160,
+ 0x00000300,
+ 0xb0000003,
+ 0x00000300,
+ 0x962c0900,
+};
+
+static const uint32_t uve_nalu_buffer_3[] = {
+ 0x00000034,
+ 0x00000013,
+ 0x00000003,
+ 0x00000023,
+ 0x00000001,
+ 0x42010101,
+ 0x60000003,
+ 0x00b00000,
+ 0x03000003,
+ 0x0096a018,
+ 0x2020708f,
+ 0xcb924295,
+ 0x12e08000,
+};
+
+static const uint32_t uve_nalu_buffer_4[] = {
+ 0x0000001c,
+ 0x00000013,
+ 0x00000004,
+ 0x0000000b,
+ 0x00000001,
+ 0x4401e0f1,
+ 0x80992000,
+};
+
+static const uint32_t uve_slice_header[] = {
+ 0x000000c8,
+ 0x0000000b,
+ 0x28010000,
+ 0x40000000,
+ 0x60000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000002,
+ 0x00000010,
+ 0x00000003,
+ 0x00000000,
+ 0x00000002,
+ 0x00000002,
+ 0x00000004,
+ 0x00000000,
+ 0x00000001,
+ 0x00000000,
+ 0x00000002,
+ 0x00000003,
+ 0x00000005,
+ 0x00000000,
+ 0x00000002,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_encode_param[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xffffffff,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_intra_refresh[] = {
+ 0x00000014,
+ 0x0000000f,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+};
+
+static const uint32_t uve_ctx_buffer[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x000000a0,
+ 0x000000a0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_bitstream_buffer[] = {
+ 0x0000001c,
+ 0x00000011,
+};
+
+static const uint32_t uve_rc_per_pic[] = {
+ 0x00000024,
+ 0x0000000a,
+ 0x0000001a,
+ 0x00000000,
+ 0x00000033,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+};
+
+static const uint32_t uve_op_init[] = {
+ 0x00000008,
+ 0x08000001,
+};
+
+static const uint32_t uve_op_close[] = {
+ 0x00000008,
+ 0x08000002,
+};
+
+static const uint32_t uve_op_encode[] = {
+ 0x00000008,
+ 0x08000003,
+};
+
+static const uint32_t uve_op_init_rc[] = {
+ 0x00000008,
+ 0x08000004,
+};
+
+static const uint32_t uve_op_init_rc_vbv_level[] = {
+ 0x00000008,
+ 0x08000005,
+};
+
+static const uint32_t uve_op_speed_enc_mode[] = {
+ 0x00000008,
+ 0x08000006,
+};
+
+static const uint32_t uve_op_balance_enc_mode[] = {
+ 0x00000008,
+ 0x08000007,
+};
+
+static const uint32_t uve_op_quality_enc_mode[] = {
+ 0x00000008,
+ 0x08000008,
+};
+#endif /*_uve_ib_h*/
diff --git a/tests/amdgpu/vce_tests.c b/tests/amdgpu/vce_tests.c
index de63aa1..25c0b1f 100644
--- a/tests/amdgpu/vce_tests.c
+++ b/tests/amdgpu/vce_tests.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include <inttypes.h>
@@ -88,6 +84,27 @@
CU_TEST_INFO_NULL,
};
+
+CU_BOOL suite_vce_tests_enable(void)
+{
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+
+ 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;
+ }
+
+ return CU_TRUE;
+}
+
int suite_vce_tests_init(void)
{
int r;
@@ -234,6 +251,7 @@
static void amdgpu_cs_vce_create(void)
{
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
int len, r;
enc.width = vce_create[6];
@@ -250,6 +268,8 @@
memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
len += sizeof(vce_taskinfo) / 4;
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);
len += sizeof(vce_create) / 4;
memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
ib_cpu[len + 2] = enc.fb[0].addr >> 32;
@@ -291,10 +311,12 @@
{
uint64_t luma_offset, chroma_offset;
- int len = 0, r;
+ 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 + enc->width * enc->height;
+ chroma_offset = luma_offset + luma_size;
memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
len += sizeof(vce_session) / 4;
@@ -309,6 +331,10 @@
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;
@@ -319,8 +345,10 @@
ib_cpu[len + 10] = luma_offset;
ib_cpu[len + 11] = chroma_offset >> 32;
ib_cpu[len + 12] = chroma_offset;
- ib_cpu[len + 73] = 0x7800;
- ib_cpu[len + 74] = 0x7800 + 0x5000;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
+ ib_cpu[len + 73] = luma_size * 1.5;
+ ib_cpu[len + 74] = luma_size * 2.5;
len += sizeof(vce_encode) / 4;
enc->ib_len = len;
if (!enc->two_instance) {
@@ -332,11 +360,13 @@
static void amdgpu_cs_vce_encode_p(struct amdgpu_vce_encode *enc)
{
uint64_t luma_offset, chroma_offset;
- int len, r;
+ int len, i, r;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16);
len = (enc->two_instance) ? enc->ib_len : 0;
luma_offset = enc->vbuf.addr;
- chroma_offset = luma_offset + enc->width * enc->height;
+ chroma_offset = luma_offset + luma_size;
if (!enc->two_instance) {
memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
@@ -353,6 +383,10 @@
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[1].addr >> 32;
@@ -364,15 +398,17 @@
ib_cpu[len + 10] = luma_offset;
ib_cpu[len + 11] = chroma_offset >> 32;
ib_cpu[len + 12] = chroma_offset;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
ib_cpu[len + 18] = 0;
ib_cpu[len + 19] = 0;
ib_cpu[len + 56] = 3;
ib_cpu[len + 57] = 0;
ib_cpu[len + 58] = 0;
- ib_cpu[len + 59] = 0x7800;
- ib_cpu[len + 60] = 0x7800 + 0x5000;
+ ib_cpu[len + 59] = luma_size * 1.5;
+ ib_cpu[len + 60] = luma_size * 2.5;
ib_cpu[len + 73] = 0;
- ib_cpu[len + 74] = 0x5000;
+ ib_cpu[len + 74] = luma_size;
ib_cpu[len + 81] = 1;
ib_cpu[len + 82] = 1;
len += sizeof(vce_encode) / 4;
@@ -408,9 +444,10 @@
static void amdgpu_cs_vce_encode(void)
{
uint32_t vbuf_size, bs_size = 0x154000, cpb_size;
- int r;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ int i, r;
- vbuf_size = enc.width * enc.height * 1.5;
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
cpb_size = vbuf_size * 10;
num_resources = 0;
alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
@@ -429,7 +466,17 @@
r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
CU_ASSERT_EQUAL(r, 0);
- memcpy(enc.vbuf.ptr, frame, sizeof(frame));
+
+ 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);
diff --git a/tests/amdgpu/vcn_tests.c b/tests/amdgpu/vcn_tests.c
new file mode 100644
index 0000000..d9f05af
--- /dev/null
+++ b/tests/amdgpu/vcn_tests.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2017 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 <stdio.h>
+#include <inttypes.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "decode_messages.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+struct amdgpu_vcn_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static amdgpu_va_handle ib_va_handle;
+static uint64_t ib_mc_address;
+static uint32_t *ib_cpu;
+
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static void amdgpu_cs_vcn_dec_create(void);
+static void amdgpu_cs_vcn_dec_decode(void);
+static void amdgpu_cs_vcn_dec_destroy(void);
+
+static void amdgpu_cs_vcn_enc_create(void);
+static void amdgpu_cs_vcn_enc_encode(void);
+static void amdgpu_cs_vcn_enc_destroy(void);
+
+CU_TestInfo vcn_tests[] = {
+
+ { "VCN DEC create", amdgpu_cs_vcn_dec_create },
+ { "VCN DEC decode", amdgpu_cs_vcn_dec_decode },
+ { "VCN DEC destroy", amdgpu_cs_vcn_dec_destroy },
+
+ { "VCN ENC create", amdgpu_cs_vcn_enc_create },
+ { "VCN ENC decode", amdgpu_cs_vcn_enc_encode },
+ { "VCN ENC destroy", amdgpu_cs_vcn_enc_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_vcn_tests_enable(void)
+{
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+
+ if (family_id < AMDGPU_FAMILY_RV) {
+ printf("\n\nThe ASIC NOT support VCN, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ return CU_TRUE;
+}
+
+int suite_vcn_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = device_handle->info.family_id;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_handle, (void**)&ib_cpu,
+ &ib_mc_address, &ib_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+int suite_vcn_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
+ ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void alloc_resource(struct amdgpu_vcn_bo *vcn_bo,
+ unsigned size, unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ vcn_bo->addr = va;
+ vcn_bo->handle = buf_handle;
+ vcn_bo->size = req.alloc_size;
+ vcn_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(vcn_bo->handle, (void **)&vcn_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vcn_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(vcn_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_vcn_bo *vcn_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(vcn_bo->handle, 0, vcn_bo->size,
+ vcn_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(vcn_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(vcn_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vcn_bo, 0, sizeof(*vcn_bo));
+}
+
+static void vcn_dec_cmd(uint64_t addr, unsigned cmd, int *idx)
+{
+ ib_cpu[(*idx)++] = 0x81C4;
+ ib_cpu[(*idx)++] = addr;
+ ib_cpu[(*idx)++] = 0x81C5;
+ ib_cpu[(*idx)++] = addr >> 32;
+ ib_cpu[(*idx)++] = 0x81C3;
+ ib_cpu[(*idx)++] = cmd << 1;
+}
+
+static void amdgpu_cs_vcn_dec_create(void)
+{
+ struct amdgpu_vcn_bo msg_buf;
+ int len, r;
+
+ num_resources = 0;
+ alloc_resource(&msg_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = msg_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(msg_buf.ptr, 0, 4096);
+ memcpy(msg_buf.ptr, vcn_dec_create_msg, sizeof(vcn_dec_create_msg));
+
+ len = 0;
+ ib_cpu[len++] = 0x81C4;
+ ib_cpu[len++] = msg_buf.addr;
+ ib_cpu[len++] = 0x81C5;
+ ib_cpu[len++] = msg_buf.addr >> 32;
+ ib_cpu[len++] = 0x81C3;
+ ib_cpu[len++] = 0;
+ for (; len % 16; ++len)
+ ib_cpu[len] = 0x81ff;
+
+ r = submit(len, AMDGPU_HW_IP_VCN_DEC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&msg_buf);
+}
+
+static void amdgpu_cs_vcn_dec_decode(void)
+{
+ 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;
+ uint8_t *dec;
+
+ size = 4*1024; /* msg */
+ size += 4*1024; /* fb */
+ size += 4096; /*it_scaling_table*/
+ size += ALIGN(sizeof(uvd_bitstream), 4*1024);
+ size += ALIGN(dpb_size, 4*1024);
+ size += ALIGN(dt_size, 4*1024);
+
+ num_resources = 0;
+ alloc_resource(&dec_buf, size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = dec_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(dec_buf.handle, (void **)&dec_buf.ptr);
+ dec = dec_buf.ptr;
+
+ CU_ASSERT_EQUAL(r, 0);
+ memset(dec_buf.ptr, 0, size);
+ memcpy(dec_buf.ptr, vcn_dec_decode_msg, sizeof(vcn_dec_decode_msg));
+ memcpy(dec_buf.ptr + sizeof(vcn_dec_decode_msg),
+ avc_decode_msg, sizeof(avc_decode_msg));
+
+ dec += 4*1024;
+ dec += 4*1024;
+ memcpy(dec, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
+
+ dec += 4*1024;
+ memcpy(dec, uvd_bitstream, sizeof(uvd_bitstream));
+
+ dec += ALIGN(sizeof(uvd_bitstream), 4*1024);
+
+ dec += ALIGN(dpb_size, 4*1024);
+
+ msg_addr = dec_buf.addr;
+ fb_addr = msg_addr + 4*1024;
+ it_addr = fb_addr + 4*1024;
+ bs_addr = it_addr + 4*1024;
+ dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
+ ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
+
+ len = 0;
+ vcn_dec_cmd(msg_addr, 0x0, &len);
+ vcn_dec_cmd(dpb_addr, 0x1, &len);
+ vcn_dec_cmd(dt_addr, 0x2, &len);
+ vcn_dec_cmd(fb_addr, 0x3, &len);
+ vcn_dec_cmd(bs_addr, 0x100, &len);
+ vcn_dec_cmd(it_addr, 0x204, &len);
+ vcn_dec_cmd(ctx_addr, 0x206, &len);
+
+ ib_cpu[len++] = 0x81C6;
+ ib_cpu[len++] = 0x1;
+ for (; len % 16; ++len)
+ ib_cpu[len] = 0x80000000;
+
+ r = submit(len, AMDGPU_HW_IP_VCN_DEC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (i = 0, sum = 0; i < dt_size; ++i)
+ sum += dec[i];
+
+ CU_ASSERT_EQUAL(sum, SUM_DECODE);
+
+ free_resource(&dec_buf);
+}
+
+static void amdgpu_cs_vcn_dec_destroy(void)
+{
+ struct amdgpu_vcn_bo msg_buf;
+ int len, r;
+
+ num_resources = 0;
+ alloc_resource(&msg_buf, 1024, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = msg_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(msg_buf.ptr, 0, 1024);
+ memcpy(msg_buf.ptr, vcn_dec_destroy_msg, sizeof(vcn_dec_destroy_msg));
+
+ len = 0;
+ ib_cpu[len++] = 0x81C4;
+ ib_cpu[len++] = msg_buf.addr;
+ ib_cpu[len++] = 0x81C5;
+ ib_cpu[len++] = msg_buf.addr >> 32;
+ ib_cpu[len++] = 0x81C3;
+ ib_cpu[len++] = 0;
+ for (; len % 16; ++len)
+ ib_cpu[len] = 0x80000000;
+
+ r = submit(len, AMDGPU_HW_IP_VCN_DEC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&msg_buf);
+}
+
+static void amdgpu_cs_vcn_enc_create(void)
+{
+ /* TODO */
+}
+
+static void amdgpu_cs_vcn_enc_encode(void)
+{
+ /* TODO */
+}
+
+static void amdgpu_cs_vcn_enc_destroy(void)
+{
+ /* TODO */
+}
diff --git a/tests/amdgpu/vm_tests.c b/tests/amdgpu/vm_tests.c
new file mode 100644
index 0000000..7b6dc5d
--- /dev/null
+++ b/tests/amdgpu/vm_tests.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2017 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 "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+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)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_vm_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo vm_tests[] = {
+ { "resere vmid test", amdgpu_vmid_reserve_test },
+ CU_TEST_INFO_NULL,
+};
+
+static void amdgpu_vmid_reserve_test(void)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired, flags;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ static uint32_t *ptr;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ flags = 0;
+ r = amdgpu_vm_reserve_vmid(device_handle, flags);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+
+ for (i = 0; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ flags = 0;
+ r = amdgpu_vm_unreserve_vmid(device_handle, flags);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
diff --git a/tests/drmsl.c b/tests/drmsl.c
index d0ac0ef..d1b59a8 100644
--- a/tests/drmsl.c
+++ b/tests/drmsl.c
@@ -106,7 +106,9 @@
return usec;
}
-static void print_neighbors(void *list, unsigned long key)
+static void print_neighbors(void *list, unsigned long key,
+ unsigned long expected_prev,
+ unsigned long expected_next)
{
unsigned long prev_key = 0;
unsigned long next_key = 0;
@@ -119,6 +121,16 @@
&next_key, &next_value);
printf("Neighbors of %5lu: %d %5lu %5lu\n",
key, retval, prev_key, next_key);
+ if (prev_key != expected_prev) {
+ fprintf(stderr, "Unexpected neighbor: %5lu. Expected: %5lu\n",
+ prev_key, expected_prev);
+ exit(1);
+ }
+ if (next_key != expected_next) {
+ fprintf(stderr, "Unexpected neighbor: %5lu. Expected: %5lu\n",
+ next_key, expected_next);
+ exit(1);
+ }
}
int main(void)
@@ -138,13 +150,13 @@
print(list);
printf("\n==============================\n\n");
- print_neighbors(list, 0);
- print_neighbors(list, 50);
- print_neighbors(list, 51);
- print_neighbors(list, 123);
- print_neighbors(list, 200);
- print_neighbors(list, 213);
- print_neighbors(list, 256);
+ print_neighbors(list, 0, 0, 50);
+ print_neighbors(list, 50, 0, 50);
+ print_neighbors(list, 51, 50, 123);
+ print_neighbors(list, 123, 50, 123);
+ print_neighbors(list, 200, 123, 213);
+ print_neighbors(list, 213, 123, 213);
+ print_neighbors(list, 256, 213, 256);
printf("\n==============================\n\n");
drmSLDelete(list, 50);
diff --git a/tests/drmstat.c b/tests/drmstat.c
deleted file mode 100644
index 023aa06..0000000
--- a/tests/drmstat.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* drmstat.c -- DRM device status and testing program
- * Created: Tue Jan 5 08:19:24 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * 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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
- *
- * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <getopt.h>
-#include <strings.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
-#include "xf86drm.h"
-
-int sigio_fd;
-
-static double usec(struct timeval *end, struct timeval *start)
-{
- double e = end->tv_sec * 1000000 + end->tv_usec;
- double s = start->tv_sec * 1000000 + start->tv_usec;
-
- return e - s;
-}
-
-static void getversion(int fd)
-{
- drmVersionPtr version;
-
- version = drmGetVersion(fd);
- if (version) {
- printf( "Name: %s\n", version->name ? version->name : "?" );
- printf( " Version: %d.%d.%d\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel );
- printf( " Date: %s\n", version->date ? version->date : "?" );
- printf( " Desc: %s\n", version->desc ? version->desc : "?" );
- drmFreeVersion(version);
- } else {
- printf( "No driver available\n" );
- }
-}
-
-static void process_sigio(char *device)
-{
- int fd;
-
- if ((fd = open(device, 0)) < 0) {
- drmError(-errno, __func__);
- exit(1);
- }
-
- sigio_fd = fd;
- for (;;) sleep(60);
-}
-
-int main(int argc, char **argv)
-{
- int c;
- int r = 0;
- int fd = -1;
- drm_handle_t handle;
- void *address;
- char *pt;
- unsigned long count;
- unsigned long offset;
- unsigned long size;
- drm_context_t context;
- int loops;
- char buf[1024];
- int i;
- drmBufInfoPtr info;
- drmBufMapPtr bufs;
- drmLockPtr lock;
- int secs;
-
- while ((c = getopt(argc, argv,
- "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF)
- switch (c) {
- case 'F':
- count = strtoul(optarg, NULL, 0);
- if (!fork()) {
- dup(fd);
- sleep(count);
- }
- close(fd);
- break;
- case 'v': getversion(fd); break;
- case 'X':
- if ((r = drmCreateContext(fd, &context))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf( "Got %d\n", context);
- break;
- case 'S':
- process_sigio(optarg);
- break;
- case 'C':
- if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) {
- drmError(r, argv[0]);
- return 1;
- }
- break;
- case 'c':
- if ((r = drmSetBusid(fd,optarg))) {
- drmError(r, argv[0]);
- return 1;
- }
- break;
- case 'o':
- if ((fd = drmOpen(optarg, NULL)) < 0) {
- drmError(fd, argv[0]);
- return 1;
- }
- break;
- case 'O':
- if ((fd = drmOpen(NULL, optarg)) < 0) {
- drmError(fd, argv[0]);
- return 1;
- }
- break;
- case 'B': /* Test buffer allocation */
- count = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, &pt, 0);
- secs = strtoul(pt+1, NULL, 0);
- {
- drmDMAReq dma;
- int *indices, *sizes;
-
- indices = alloca(sizeof(*indices) * count);
- sizes = alloca(sizeof(*sizes) * count);
- dma.context = context;
- dma.send_count = 0;
- dma.request_count = count;
- dma.request_size = size;
- dma.request_list = indices;
- dma.request_sizes = sizes;
- dma.flags = DRM_DMA_WAIT;
- if ((r = drmDMA(fd, &dma))) {
- drmError(r, argv[0]);
- return 1;
- }
- for (i = 0; i < dma.granted_count; i++) {
- printf("%5d: index = %d, size = %d\n",
- i, dma.request_list[i], dma.request_sizes[i]);
- }
- sleep(secs);
- drmFreeBufs(fd, dma.granted_count, indices);
- }
- break;
- case 'b':
- count = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) {
- drmError(r, argv[0]);
- return 1;
- }
- if (!(info = drmGetBufInfo(fd))) {
- drmError(0, argv[0]);
- return 1;
- }
- for (i = 0; i < info->count; i++) {
- printf("%5d buffers of size %6d (low = %d, high = %d)\n",
- info->list[i].count,
- info->list[i].size,
- info->list[i].low_mark,
- info->list[i].high_mark);
- }
- if ((r = drmMarkBufs(fd, 0.50, 0.80))) {
- drmError(r, argv[0]);
- return 1;
- }
- if (!(info = drmGetBufInfo(fd))) {
- drmError(0, argv[0]);
- return 1;
- }
- for (i = 0; i < info->count; i++) {
- printf("%5d buffers of size %6d (low = %d, high = %d)\n",
- info->list[i].count,
- info->list[i].size,
- info->list[i].low_mark,
- info->list[i].high_mark);
- }
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
-#if 1
- if (!(bufs = drmMapBufs(fd))) {
- drmError(0, argv[0]);
- return 1;
- }
- printf("===============================\n");
- printf( "%d bufs\n", bufs->count);
- for (i = 0; i < bufs->count; i++) {
- printf( " %4d: %8d bytes at %p\n",
- i,
- bufs->list[i].total,
- bufs->list[i].address);
- }
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
-#endif
- break;
- case 'f':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- handle = 0;
- if ((r = drmAddMap(fd, offset, size,
- DRM_FRAME_BUFFER, 0, &handle))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx added\n", offset, size);
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
- break;
- case 'r':
- case 'R':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- handle = 0;
- if ((r = drmAddMap(fd, offset, size,
- DRM_REGISTERS,
- c == 'R' ? DRM_READ_ONLY : 0,
- &handle))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx added\n", offset, size);
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
- break;
- case 's':
- size = strtoul(optarg, &pt, 0);
- handle = 0;
- if ((r = drmAddMap(fd, 0, size,
- DRM_SHM, DRM_CONTAINS_LOCK,
- &handle))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%04lx byte shm added at 0x%08lx\n", size, handle);
- sprintf(buf, "cat /proc/dri/0/vm");
- system(buf);
- break;
- case 'P':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- address = NULL;
- if ((r = drmMap(fd, offset, size, &address))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
- offset, size, address, getpid());
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- mprotect((void *)offset, size, PROT_READ);
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- break;
- case 'w':
- case 'W':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- address = NULL;
- if ((r = drmMap(fd, offset, size, &address))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
- offset, size, address, getpid());
- printf("===== /proc/%d/maps =====\n", getpid());
- sprintf(buf, "cat /proc/%d/maps", getpid());
- system(buf);
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- printf("===== READING =====\n");
- for (i = 0; i < 0x10; i++)
- printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
- printf("\n");
- if (c == 'w') {
- printf("===== WRITING =====\n");
- for (i = 0; i < size; i+=2) {
- ((char *)address)[i] = i & 0xff;
- ((char *)address)[i+1] = i & 0xff;
- }
- }
- printf("===== READING =====\n");
- for (i = 0; i < 0x10; i++)
- printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
- printf("\n");
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- break;
- case 'L':
- context = strtoul(optarg, &pt, 0);
- offset = strtoul(pt+1, &pt, 0);
- size = strtoul(pt+1, &pt, 0);
- loops = strtoul(pt+1, NULL, 0);
- address = NULL;
- if ((r = drmMap(fd, offset, size, &address))) {
- drmError(r, argv[0]);
- return 1;
- }
- lock = address;
-#if 1
- {
- int counter = 0;
- struct timeval loop_start, loop_end;
- struct timeval lock_start, lock_end;
- double wt;
-#define HISTOSIZE 9
- int histo[HISTOSIZE];
- int output = 0;
- int fast = 0;
-
- if (loops < 0) {
- loops = -loops;
- ++output;
- }
-
- for (i = 0; i < HISTOSIZE; i++) histo[i] = 0;
-
- gettimeofday(&loop_start, NULL);
- for (i = 0; i < loops; i++) {
- gettimeofday(&lock_start, NULL);
- DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast);
- gettimeofday(&lock_end, NULL);
- DRM_UNLOCK(fd,lock,context);
- ++counter;
- wt = usec(&lock_end, &lock_start);
- if (wt <= 2.5) ++histo[8];
- if (wt < 5.0) ++histo[0];
- else if (wt < 50.0) ++histo[1];
- else if (wt < 500.0) ++histo[2];
- else if (wt < 5000.0) ++histo[3];
- else if (wt < 50000.0) ++histo[4];
- else if (wt < 500000.0) ++histo[5];
- else if (wt < 5000000.0) ++histo[6];
- else ++histo[7];
- if (output) printf( "%.2f uSec, %d fast\n", wt, fast);
- }
- gettimeofday(&loop_end, NULL);
- printf( "Average wait time = %.2f usec, %d fast\n",
- usec(&loop_end, &loop_start) / counter, fast);
- printf( "%9d <= 2.5 uS\n", histo[8]);
- printf( "%9d < 5 uS\n", histo[0]);
- printf( "%9d < 50 uS\n", histo[1]);
- printf( "%9d < 500 uS\n", histo[2]);
- printf( "%9d < 5000 uS\n", histo[3]);
- printf( "%9d < 50000 uS\n", histo[4]);
- printf( "%9d < 500000 uS\n", histo[5]);
- printf( "%9d < 5000000 uS\n", histo[6]);
- printf( "%9d >= 5000000 uS\n", histo[7]);
- }
-#else
- printf( "before lock: 0x%08x\n", lock->lock);
- printf( "lock: 0x%08x\n", lock->lock);
- sleep(5);
- printf( "unlock: 0x%08x\n", lock->lock);
-#endif
- break;
- default:
- fprintf( stderr, "Usage: drmstat [options]\n" );
- return 1;
- }
-
- return r;
-}
-
-int xf86ConfigDRI[10];
diff --git a/tests/etnaviv/Makefile.am b/tests/etnaviv/Makefile.am
index 0631864..226baee 100644
--- a/tests/etnaviv/Makefile.am
+++ b/tests/etnaviv/Makefile.am
@@ -28,6 +28,7 @@
write_bmp.h
etnaviv_cmd_stream_test_LDADD = \
+ $(top_builddir)/libdrm.la \
$(top_builddir)/etnaviv/libdrm_etnaviv.la
etnaviv_cmd_stream_test_SOURCES = \
diff --git a/tests/etnaviv/etnaviv_2d_test.c b/tests/etnaviv/etnaviv_2d_test.c
index 10751c7..8dd77b6 100644
--- a/tests/etnaviv/etnaviv_2d_test.c
+++ b/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/tests/etnaviv/etnaviv_bo_cache_test.c b/tests/etnaviv/etnaviv_bo_cache_test.c
index fb01f8d..7fb0629 100644
--- a/tests/etnaviv/etnaviv_bo_cache_test.c
+++ b/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/tests/etnaviv/meson.build b/tests/etnaviv/meson.build
new file mode 100644
index 0000000..8b4a3cf
--- /dev/null
+++ b/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/tests/etnaviv/write_bmp.c b/tests/etnaviv/write_bmp.c
index 7ae0646..f7b6bc6 100644
--- a/tests/etnaviv/write_bmp.c
+++ b/tests/etnaviv/write_bmp.c
@@ -63,7 +63,7 @@
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 @@
write(fd, &bmp_header, sizeof(struct bmp_header));
write(fd, &dib_header, sizeof(struct dib_header));
-
- return 0;
}
void
diff --git a/tests/exynos/exynos_fimg2d_event.c b/tests/exynos/exynos_fimg2d_event.c
index 9ed5a30..353e087 100644
--- a/tests/exynos/exynos_fimg2d_event.c
+++ b/tests/exynos/exynos_fimg2d_event.c
@@ -1,17 +1,24 @@
/*
* Copyright (C) 2015 - Tobias Jakobi
*
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
+ * 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:
*
- * It is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with it. If not, see <http://www.gnu.org/licenses/>.
+ * 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 <unistd.h>
diff --git a/tests/exynos/exynos_fimg2d_perf.c b/tests/exynos/exynos_fimg2d_perf.c
index 1699bba..97691a7 100644
--- a/tests/exynos/exynos_fimg2d_perf.c
+++ b/tests/exynos/exynos_fimg2d_perf.c
@@ -1,17 +1,24 @@
/*
* Copyright (C) 2015 - Tobias Jakobi
*
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
+ * 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:
*
- * It is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with it. If not, see <http://www.gnu.org/licenses/>.
+ * 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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>
@@ -267,13 +274,6 @@
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/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c
index 797fb6e..99bb923 100644
--- a/tests/exynos/exynos_fimg2d_test.c
+++ b/tests/exynos/exynos_fimg2d_test.c
@@ -3,17 +3,26 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -59,7 +68,6 @@
if (!connector) {
fprintf(stderr, "could not get connector %i: %s\n",
resources->connectors[i], strerror(errno));
- drmModeFreeConnector(connector);
continue;
}
@@ -98,7 +106,6 @@
if (!c->encoder) {
fprintf(stderr, "could not get encoder %i: %s\n",
resources->encoders[i], strerror(errno));
- drmModeFreeEncoder(c->encoder);
continue;
}
@@ -264,7 +271,8 @@
userptr = (unsigned long)malloc(size);
if (!userptr) {
fprintf(stderr, "failed to allocate userptr.\n");
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
src_img.user_ptr[0].userptr = userptr;
@@ -469,7 +477,8 @@
userptr = (unsigned long)malloc(size);
if (!userptr) {
fprintf(stderr, "failed to allocate userptr.\n");
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
src_img.user_ptr[0].userptr = userptr;
@@ -520,9 +529,10 @@
fail:
g2d_fini(ctx);
- return 0;
+ return ret;
}
+#ifdef EXYNOS_G2D_USERPTR_TEST
static int g2d_blend_test(struct exynos_device *dev,
struct exynos_bo *src,
struct exynos_bo *dst,
@@ -557,7 +567,8 @@
userptr = (unsigned long)malloc(size);
if (!userptr) {
fprintf(stderr, "failed to allocate userptr.\n");
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
src_img.user_ptr[0].userptr = userptr;
@@ -619,8 +630,9 @@
fail:
g2d_fini(ctx);
- return 0;
+ return ret;
}
+#endif
static int g2d_checkerboard_test(struct exynos_device *dev,
struct exynos_bo *src,
@@ -645,8 +657,8 @@
dst_y = 0;
checkerboard = create_checkerboard_pattern(screen_width / 32, screen_height / 32, 32);
- if (checkerboard == NULL) {
- ret = -1;
+ if (!checkerboard) {
+ ret = -EFAULT;
goto fail;
}
@@ -755,8 +767,8 @@
dev = exynos_device_create(fd);
if (!dev) {
- drmClose(dev->fd);
- return -EFAULT;
+ ret = -EFAULT;
+ goto err_drm_close;
}
resources = drmModeGetResources(dev->fd);
@@ -764,7 +776,7 @@
fprintf(stderr, "drmModeGetResources failed: %s\n",
strerror(errno));
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
connector_find_mode(dev->fd, &con, resources);
@@ -773,7 +785,7 @@
if (!con.mode) {
fprintf(stderr, "failed to find usable connector\n");
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
screen_width = con.mode->hdisplay;
@@ -782,7 +794,7 @@
if (screen_width == 0 || screen_height == 0) {
fprintf(stderr, "failed to find sane resolution on connector\n");
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
printf("screen width = %d, screen height = %d\n", screen_width,
@@ -791,7 +803,7 @@
bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
if (!bo) {
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
handles[0] = bo->handle;
@@ -864,7 +876,7 @@
*
* Disable the test for now, until the kernel code has been sanitized.
*/
-#if 0
+#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");
@@ -882,9 +894,11 @@
err_destroy_buffer:
exynos_destroy_buffer(bo);
-err_drm_close:
- drmClose(dev->fd);
+err_dev_destory:
exynos_device_destroy(dev);
- return 0;
+err_drm_close:
+ drmClose(fd);
+
+ return ret;
}
diff --git a/tests/exynos/meson.build b/tests/exynos/meson.build
new file mode 100644
index 0000000..940c3ce
--- /dev/null
+++ b/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/tests/kms/kms-steal-crtc.c b/tests/kms/kms-steal-crtc.c
index 4b830d2..cd40758 100644
--- a/tests/kms/kms-steal-crtc.c
+++ b/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/tests/kms/kms-universal-planes.c b/tests/kms/kms-universal-planes.c
index 89057bb..2163c98 100644
--- a/tests/kms/kms-universal-planes.c
+++ b/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/tests/kms/libkms-test-crtc.c b/tests/kms/libkms-test-crtc.c
index 3adb490..2c28fac 100644
--- a/tests/kms/libkms-test-crtc.c
+++ b/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/tests/kms/libkms-test-device.c b/tests/kms/libkms-test-device.c
index 53c7349..d3bb11c 100644
--- a/tests/kms/libkms-test-device.c
+++ b/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 @@
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 @@
device->num_screens++;
}
+err_free_resources:
drmModeFreeResources(res);
}
@@ -112,7 +109,7 @@
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 @@
device->num_crtcs++;
}
+err_free_resources:
drmModeFreeResources(res);
}
@@ -138,7 +136,7 @@
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 @@
device->num_planes++;
}
+err_free_resources:
drmModeFreePlaneResources(res);
}
diff --git a/tests/kms/libkms-test-framebuffer.c b/tests/kms/libkms-test-framebuffer.c
index c9e5ad3..9bb2d95 100644
--- a/tests/kms/libkms-test-framebuffer.c
+++ b/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/tests/kms/libkms-test-plane.c b/tests/kms/libkms-test-plane.c
index 8eb78af..6c40a3c 100644
--- a/tests/kms/libkms-test-plane.c
+++ b/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/tests/kms/libkms-test-screen.c b/tests/kms/libkms-test-screen.c
index 3369022..bbe972a 100644
--- a/tests/kms/libkms-test-screen.c
+++ b/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/tests/kms/meson.build b/tests/kms/meson.build
new file mode 100644
index 0000000..1f7f724
--- /dev/null
+++ b/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/tests/kmstest/meson.build b/tests/kmstest/meson.build
new file mode 100644
index 0000000..a47d495
--- /dev/null
+++ b/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/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000..fdf950b
--- /dev/null
+++ b/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/tests/modeprint/meson.build b/tests/modeprint/meson.build
new file mode 100644
index 0000000..5f0eb24
--- /dev/null
+++ b/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/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c
index 0d85410..c81dd91 100644
--- a/tests/modeprint/modeprint.c
+++ b/tests/modeprint/modeprint.c
@@ -244,7 +244,7 @@
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/tests/modetest/buffers.c b/tests/modetest/buffers.c
index 4fd310b..9b635c0 100644
--- a/tests/modetest/buffers.c
+++ b/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/tests/modetest/cursor.c b/tests/modetest/cursor.c
index 6de82a4..829bced 100644
--- a/tests/modetest/cursor.c
+++ b/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/tests/modetest/meson.build b/tests/modetest/meson.build
new file mode 100644
index 0000000..2a08184
--- /dev/null
+++ b/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/tests/modetest/modetest.c b/tests/modetest/modetest.c
index cd91119..62957d8 100644
--- a/tests/modetest/modetest.c
+++ b/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>
@@ -174,6 +170,15 @@
static bit_name_fn(mode_flag)
+static void dump_fourcc(uint32_t fourcc)
+{
+ printf(" %c%c%c%c",
+ fourcc,
+ fourcc >> 8,
+ fourcc >> 16,
+ fourcc >> 24);
+}
+
static void dump_encoders(struct device *dev)
{
drmModeEncoder *encoder;
@@ -242,6 +247,89 @@
drmModeFreePropertyBlob(blob);
}
+static const char *modifier_to_string(uint64_t modifier)
+{
+ switch (modifier) {
+ case DRM_FORMAT_MOD_INVALID:
+ return "INVALID";
+ case DRM_FORMAT_MOD_LINEAR:
+ return "LINEAR";
+ case I915_FORMAT_MOD_X_TILED:
+ return "X_TILED";
+ case I915_FORMAT_MOD_Y_TILED:
+ return "Y_TILED";
+ case I915_FORMAT_MOD_Yf_TILED:
+ return "Yf_TILED";
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ return "Y_TILED_CCS";
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ return "Yf_TILED_CCS";
+ case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
+ return "SAMSUNG_64_32_TILE";
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ return "VIVANTE_TILED";
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ return "VIVANTE_SUPER_TILED";
+ case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED:
+ return "VIVANTE_SPLIT_TILED";
+ case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED:
+ return "VIVANTE_SPLIT_SUPER_TILED";
+ 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:
+ return "(UNKNOWN MODIFIER)";
+ }
+}
+
+static void dump_in_formats(struct device *dev, uint32_t blob_id)
+{
+ uint32_t i, j;
+ drmModePropertyBlobPtr blob;
+ struct drm_format_modifier_blob *header;
+ uint32_t *formats;
+ struct drm_format_modifier *modifiers;
+
+ printf("\t\tin_formats blob decoded:\n");
+ blob = drmModeGetPropertyBlob(dev->fd, blob_id);
+ if (!blob) {
+ printf("\n");
+ return;
+ }
+
+ header = blob->data;
+ formats = (uint32_t *) ((char *) header + header->formats_offset);
+ modifiers = (struct drm_format_modifier *)
+ ((char *) header + header->modifiers_offset);
+
+ for (i = 0; i < header->count_formats; i++) {
+ printf("\t\t\t");
+ dump_fourcc(formats[i]);
+ printf(": ");
+ for (j = 0; j < header->count_modifiers; j++) {
+ uint64_t mask = 1ULL << i;
+ if (modifiers[j].formats & mask)
+ printf(" %s", modifier_to_string(modifiers[j].modifier));
+ }
+ printf("\n");
+ }
+
+ drmModeFreePropertyBlob(blob);
+}
+
static void dump_prop(struct device *dev, drmModePropertyPtr prop,
uint32_t prop_id, uint64_t value)
{
@@ -319,6 +407,9 @@
printf(" %"PRId64"\n", value);
else
printf(" %"PRIu64"\n", value);
+
+ if (strcmp(prop->name, "IN_FORMATS") == 0)
+ dump_in_formats(dev, value);
}
static void dump_connectors(struct device *dev)
@@ -443,7 +534,7 @@
printf(" formats:");
for (j = 0; j < ovr->count_formats; j++)
- printf(" %4.4s", (char *)&ovr->formats[j]);
+ dump_fourcc(ovr->formats[j]);
printf("\n");
if (plane->props) {
@@ -524,7 +615,6 @@
return NULL;
drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
- drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1);
res->res = drmModeGetResources(dev->fd);
if (!res->res) {
@@ -562,10 +652,13 @@
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) \
@@ -997,7 +1090,8 @@
if (!format_support(ovr, p->fourcc))
continue;
- if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id) {
+ if ((ovr->possible_crtcs & (1 << pipe)) &&
+ (ovr->crtc_id == 0 || ovr->crtc_id == p->crtc_id)) {
plane_id = ovr->plane_id;
break;
}
diff --git a/tests/nouveau/meson.build b/tests/nouveau/meson.build
new file mode 100644
index 0000000..f5d73c1
--- /dev/null
+++ b/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/tests/nouveau/threaded.c b/tests/nouveau/threaded.c
index 281af46..3669bcd 100644
--- a/tests/nouveau/threaded.c
+++ b/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/tests/planetest/atomictest.c b/tests/planetest/atomictest.c
index 5fec911..891d242 100644
--- a/tests/planetest/atomictest.c
+++ b/tests/planetest/atomictest.c
@@ -47,7 +47,7 @@
struct sp_plane **plane = NULL;
struct sp_crtc *test_crtc;
fd_set fds;
- drmModePropertySetPtr pset;
+ drmModeAtomicReqPtr pset;
drmEventContext event_context = {
.version = DRM_EVENT_CONTEXT_VERSION,
.page_flip_handler = page_flip_handler,
@@ -100,7 +100,7 @@
fill_bo(plane[i]->bo, 0xFF, 0xFF, 0xFF, 0xFF);
}
- pset = drmModePropertySetAlloc();
+ pset = drmModeAtomicAlloc();
if (!pset) {
printf("Failed to allocate the property set\n");
goto out;
@@ -124,8 +124,8 @@
}
}
- ret = drmModePropertySetCommit(dev->fd,
- DRM_MODE_PAGE_FLIP_EVENT, NULL, pset);
+ ret = drmModeAtomicCommit(dev->fd, pset,
+ DRM_MODE_PAGE_FLIP_EVENT, NULL);
if (ret) {
printf("failed to commit properties ret=%d\n", ret);
goto out;
@@ -139,7 +139,7 @@
drmHandleEvent(dev->fd, &event_context);
}
- drmModePropertySetFree(pset);
+ drmModeAtomicFree(pset);
for (i = 0; i < num_test_planes; i++)
put_sp_plane(plane[i]);
diff --git a/tests/planetest/modeset.c b/tests/planetest/modeset.c
index 037814e..b8f6690 100644
--- a/tests/planetest/modeset.c
+++ b/tests/planetest/modeset.c
@@ -15,7 +15,7 @@
{
int ret;
struct drm_mode_create_blob create_blob;
- drmModePropertySetPtr pset;
+ drmModeAtomicReqPtr pset;
memset(&create_blob, 0, sizeof(create_blob));
create_blob.length = sizeof(struct drm_mode_modeinfo);
@@ -27,28 +27,28 @@
return ret;
}
- pset = drmModePropertySetAlloc();
+ pset = drmModeAtomicAlloc();
if (!pset) {
printf("Failed to allocate property set");
return -1;
}
- ret = drmModePropertySetAdd(pset, crtc->crtc->crtc_id,
+ ret = drmModeAtomicAddProperty(pset, crtc->crtc->crtc_id,
crtc->mode_pid, create_blob.blob_id) ||
- drmModePropertySetAdd(pset, crtc->crtc->crtc_id,
+ drmModeAtomicAddProperty(pset, crtc->crtc->crtc_id,
crtc->active_pid, 1) ||
- drmModePropertySetAdd(pset, conn->conn->connector_id,
+ drmModeAtomicAddProperty(pset, conn->conn->connector_id,
conn->crtc_id_pid, crtc->crtc->crtc_id);
if (ret) {
printf("Failed to add blob %d to pset", create_blob.blob_id);
- drmModePropertySetFree(pset);
+ drmModeAtomicFree(pset);
return ret;
}
- ret = drmModePropertySetCommit(dev->fd, DRM_MODE_ATOMIC_ALLOW_MODESET,
- NULL, pset);
+ ret = drmModeAtomicCommit(dev->fd, pset, DRM_MODE_ATOMIC_ALLOW_MODESET,
+ NULL);
- drmModePropertySetFree(pset);
+ drmModeAtomicFree(pset);
if (ret) {
printf("Failed to commit pset ret=%d\n", ret);
@@ -190,7 +190,7 @@
return ret;
}
int set_sp_plane_pset(struct sp_dev *dev, struct sp_plane *plane,
- drmModePropertySetPtr pset, struct sp_crtc *crtc, int x, int y)
+ drmModeAtomicReqPtr pset, struct sp_crtc *crtc, int x, int y)
{
int ret;
uint32_t w, h;
@@ -203,25 +203,25 @@
if ((h + y) > crtc->crtc->mode.vdisplay)
h = crtc->crtc->mode.vdisplay - y;
- ret = drmModePropertySetAdd(pset, plane->plane->plane_id,
+ ret = drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->crtc_pid, crtc->crtc->crtc_id)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->fb_pid, plane->bo->fb_id)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->crtc_x_pid, x)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->crtc_y_pid, y)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->crtc_w_pid, w)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->crtc_h_pid, h)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->src_x_pid, 0)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->src_y_pid, 0)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->src_w_pid, w << 16)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
+ || drmModeAtomicAddProperty(pset, plane->plane->plane_id,
plane->src_h_pid, h << 16);
if (ret) {
printf("failed to add properties to the set\n");
diff --git a/tests/planetest/modeset.h b/tests/planetest/modeset.h
index 7e96574..5499959 100644
--- a/tests/planetest/modeset.h
+++ b/tests/planetest/modeset.h
@@ -14,6 +14,6 @@
struct sp_crtc *crtc, int x, int y);
int set_sp_plane_pset(struct sp_dev *dev, struct sp_plane *plane,
- drmModePropertySetPtr pset, struct sp_crtc *crtc, int x, int y);
+ drmModeAtomicReqPtr pset, struct sp_crtc *crtc, int x, int y);
#endif /* __MODESET_H_INCLUDED__ */
diff --git a/tests/proptest/meson.build b/tests/proptest/meson.build
new file mode 100644
index 0000000..22d7473
--- /dev/null
+++ b/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/tests/radeon/meson.build b/tests/radeon/meson.build
new file mode 100644
index 0000000..9e4f916
--- /dev/null
+++ b/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/tests/tegra/meson.build b/tests/tegra/meson.build
new file mode 100644
index 0000000..9c74ac4
--- /dev/null
+++ b/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/tests/tegra/openclose.c b/tests/tegra/openclose.c
index 881d8aa..f80f52d 100644
--- a/tests/tegra/openclose.c
+++ b/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/tests/util/format.c b/tests/util/format.c
index 043cfe7..15ac5e1 100644
--- a/tests/util/format.c
+++ b/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/tests/util/kms.c b/tests/util/kms.c
index 959b688..8b3e787 100644
--- a/tests/util/kms.c
+++ b/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>
@@ -79,6 +75,7 @@
{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
{ DRM_MODE_ENCODER_DSI, "DSI" },
{ DRM_MODE_ENCODER_DPMST, "DPMST" },
+ { DRM_MODE_ENCODER_DPI, "DPI" },
};
const char *util_lookup_encoder_type_name(unsigned int type)
@@ -117,6 +114,7 @@
{ DRM_MODE_CONNECTOR_eDP, "eDP" },
{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
{ DRM_MODE_CONNECTOR_DSI, "DSI" },
+ { DRM_MODE_CONNECTOR_DPI, "DPI" },
};
const char *util_lookup_connector_type_name(unsigned int type)
@@ -145,6 +143,7 @@
"virtio_gpu",
"mediatek",
"meson",
+ "pl111",
};
int util_open(const char *device, const char *module)
diff --git a/tests/util/meson.build b/tests/util/meson.build
new file mode 100644
index 0000000..7fa1a4b
--- /dev/null
+++ b/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/tests/util/pattern.c b/tests/util/pattern.c
index 00b08a8..9fa0a41 100644
--- a/tests/util/pattern.c
+++ b/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 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 @@
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_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 @@
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/tests/vbltest/meson.build b/tests/vbltest/meson.build
new file mode 100644
index 0000000..ae52ab8
--- /dev/null
+++ b/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/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c
index 3f6b803..48708d2 100644
--- a/tests/vbltest/vbltest.c
+++ b/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/vc4/meson.build b/vc4/meson.build
new file mode 100644
index 0000000..0136987
--- /dev/null
+++ b/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',
+)
diff --git a/xf86atomic.h b/xf86atomic.h
index 922b37d..2d733bd 100644
--- a/xf86atomic.h
+++ b/xf86atomic.h
@@ -34,10 +34,6 @@
#ifndef LIBDRM_ATOMICS_H
#define LIBDRM_ATOMICS_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#if HAVE_LIBDRM_ATOMIC_PRIMITIVES
#define HAS_ATOMIC_OPS 1
@@ -101,7 +97,7 @@
#endif
-#if ! HAS_ATOMIC_OPS
+#if !defined(HAS_ATOMIC_OPS)
#error libdrm requires atomic operations, please define them for your CPU/compiler.
#endif
diff --git a/xf86drm.c b/xf86drm.c
index 82fb0e2..390e1eb 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -31,9 +31,6 @@
* DEALINGS IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -293,7 +290,7 @@
* If any other failure happened then it will output error mesage using
* drmMsg() call.
*/
-#if !defined(UDEV)
+#if !UDEV
static int chown_check_return(const char *path, uid_t owner, gid_t group)
{
int rv;
@@ -332,7 +329,7 @@
int fd;
mode_t devmode = DRM_DEV_MODE, serv_mode;
gid_t serv_group;
-#if !defined(UDEV)
+#if !UDEV
int isroot = !geteuid();
uid_t user = DRM_DEV_UID;
gid_t group = DRM_DEV_GID;
@@ -361,7 +358,7 @@
devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
}
-#if !defined(UDEV)
+#if !UDEV
if (stat(DRM_DIR_NAME, &st)) {
if (!isroot)
return DRM_ERR_NOT_ROOT;
@@ -414,7 +411,7 @@
if (fd >= 0)
return fd;
-#if !defined(UDEV)
+#if !UDEV
/* Check if the device node is not what we expect it to be, and recreate it
* and try again if so.
*/
@@ -866,8 +863,6 @@
drmVersionPtr retval;
drm_version_t *version = drmMalloc(sizeof(*version));
- memclear(*version);
-
if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
drmFreeKernelVersion(version);
return NULL;
@@ -994,8 +989,10 @@
if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
return NULL;
u.unique = drmMalloc(u.unique_len + 1);
- if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
+ if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) {
+ drmFree(u.unique);
return NULL;
+ }
u.unique[u.unique_len] = '\0';
return u.unique;
@@ -1523,14 +1520,12 @@
if (!(list = drmMalloc(res.count * sizeof(*list))))
return NULL;
- if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
- drmFree(list);
- return NULL;
- }
+ if (!(retval = drmMalloc(res.count * sizeof(*retval))))
+ goto err_free_list;
res.contexts = list;
if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
- return NULL;
+ goto err_free_context;
for (i = 0; i < res.count; i++)
retval[i] = list[i].handle;
@@ -1538,6 +1533,12 @@
*count = res.count;
return retval;
+
+err_free_list:
+ drmFree(list);
+err_free_context:
+ drmFree(retval);
+ return NULL;
}
void drmFreeReservedContextList(drm_context_t *pt)
@@ -1691,6 +1692,43 @@
return 0;
}
+int drmCrtcGetSequence(int fd, uint32_t crtcId, uint64_t *sequence, uint64_t *ns)
+{
+ struct drm_crtc_get_sequence get_seq;
+ int ret;
+
+ memclear(get_seq);
+ get_seq.crtc_id = crtcId;
+ ret = drmIoctl(fd, DRM_IOCTL_CRTC_GET_SEQUENCE, &get_seq);
+ if (ret)
+ return ret;
+
+ if (sequence)
+ *sequence = get_seq.sequence;
+ if (ns)
+ *ns = get_seq.sequence_ns;
+ return 0;
+}
+
+int drmCrtcQueueSequence(int fd, uint32_t crtcId, uint32_t flags, uint64_t sequence,
+ uint64_t *sequence_queued, uint64_t user_data)
+{
+ struct drm_crtc_queue_sequence queue_seq;
+ int ret;
+
+ memclear(queue_seq);
+ queue_seq.crtc_id = crtcId;
+ queue_seq.flags = flags;
+ queue_seq.sequence = sequence;
+ queue_seq.user_data = user_data;
+
+ ret = drmIoctl(fd, DRM_IOCTL_CRTC_QUEUE_SEQUENCE, &queue_seq);
+ if (ret == 0 && sequence_queued)
+ *sequence_queued = queue_seq.sequence;
+
+ return ret;
+}
+
/**
* Acquire the AGP device.
*
@@ -2781,12 +2819,11 @@
{
#ifdef __linux__
DIR *sysdir;
- struct dirent *pent, *ent;
+ struct dirent *ent;
struct stat sbuf;
const char *name = drmGetMinorName(type);
int len;
char dev_name[64], buf[64];
- long name_max;
int maj, min;
if (!name)
@@ -2809,30 +2846,16 @@
if (!sysdir)
return NULL;
- name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
- if (name_max == -1)
- goto out_close_dir;
-
- pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
- if (pent == NULL)
- goto out_close_dir;
-
- while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
+ while ((ent = readdir(sysdir))) {
if (strncmp(ent->d_name, name, len) == 0) {
snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
ent->d_name);
- free(pent);
closedir(sysdir);
-
return strdup(dev_name);
}
}
-
- free(pent);
-
-out_close_dir:
- closedir(sysdir);
+ return NULL;
#else
struct stat sbuf;
char buf[PATH_MAX + 1];
@@ -2873,7 +2896,6 @@
return strdup(buf);
#endif
- return NULL;
}
char *drmGetPrimaryDeviceNameFromFd(int fd)
@@ -3023,32 +3045,32 @@
#endif
}
-static int drmCompareBusInfo(drmDevicePtr a, drmDevicePtr b)
+int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b)
{
if (a == NULL || b == NULL)
- return -1;
+ return 0;
if (a->bustype != b->bustype)
- return -1;
+ return 0;
switch (a->bustype) {
case DRM_BUS_PCI:
- return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo));
+ return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)) == 0;
case DRM_BUS_USB:
- return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo));
+ return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo)) == 0;
case DRM_BUS_PLATFORM:
- return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo));
+ return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo)) == 0;
case DRM_BUS_HOST1X:
- return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo));
+ return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo)) == 0;
default:
break;
}
- return -1;
+ return 0;
}
static int drmGetNodeType(const char *name)
@@ -3663,7 +3685,7 @@
for (i = 0; i < count; i++) {
for (j = i + 1; j < count; j++) {
- if (drmCompareBusInfo(local_devices[i], local_devices[j]) == 0) {
+ if (drmDevicesEqual(local_devices[i], local_devices[j])) {
local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
node_type = log2(local_devices[j]->available_nodes);
memcpy(local_devices[i]->nodes[node_type],
@@ -3985,7 +4007,7 @@
ret = drmProcessUsbDevice(&device, node, node_type, maj, min,
devices != NULL, flags);
if (ret)
- goto free_devices;
+ continue;
break;
@@ -3993,7 +4015,7 @@
ret = drmProcessPlatformDevice(&device, node, node_type, maj, min,
devices != NULL, flags);
if (ret)
- goto free_devices;
+ continue;
break;
@@ -4001,7 +4023,7 @@
ret = drmProcessHost1xDevice(&device, node, node_type, maj, min,
devices != NULL, flags);
if (ret)
- goto free_devices;
+ continue;
break;
@@ -4140,3 +4162,132 @@
return strdup(node);
#endif
}
+
+int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle)
+{
+ struct drm_syncobj_create args;
+ int ret;
+
+ memclear(args);
+ args.flags = flags;
+ args.handle = 0;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &args);
+ if (ret)
+ return ret;
+ *handle = args.handle;
+ return 0;
+}
+
+int drmSyncobjDestroy(int fd, uint32_t handle)
+{
+ struct drm_syncobj_destroy args;
+
+ memclear(args);
+ args.handle = handle;
+ return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &args);
+}
+
+int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd)
+{
+ struct drm_syncobj_handle args;
+ int ret;
+
+ memclear(args);
+ args.fd = -1;
+ args.handle = handle;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
+ if (ret)
+ return ret;
+ *obj_fd = args.fd;
+ return 0;
+}
+
+int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle)
+{
+ struct drm_syncobj_handle args;
+ int ret;
+
+ memclear(args);
+ args.fd = obj_fd;
+ args.handle = 0;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &args);
+ if (ret)
+ return ret;
+ *handle = args.handle;
+ return 0;
+}
+
+int drmSyncobjImportSyncFile(int fd, uint32_t handle, int sync_file_fd)
+{
+ struct drm_syncobj_handle args;
+
+ memclear(args);
+ args.fd = sync_file_fd;
+ args.handle = handle;
+ args.flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE;
+ return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &args);
+}
+
+int drmSyncobjExportSyncFile(int fd, uint32_t handle, int *sync_file_fd)
+{
+ struct drm_syncobj_handle args;
+ int ret;
+
+ memclear(args);
+ args.fd = -1;
+ args.handle = handle;
+ args.flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
+ if (ret)
+ return ret;
+ *sync_file_fd = args.fd;
+ return 0;
+}
+
+int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+ struct drm_syncobj_wait args;
+ int ret;
+
+ memclear(args);
+ args.handles = (uintptr_t)handles;
+ args.timeout_nsec = timeout_nsec;
+ args.count_handles = num_handles;
+ args.flags = flags;
+
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &args);
+ if (ret < 0)
+ return -errno;
+
+ if (first_signaled)
+ *first_signaled = args.first_signaled;
+ return ret;
+}
+
+int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t handle_count)
+{
+ struct drm_syncobj_array args;
+ int ret;
+
+ memclear(args);
+ args.handles = (uintptr_t)handles;
+ args.count_handles = handle_count;
+
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &args);
+ return ret;
+}
+
+int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t handle_count)
+{
+ struct drm_syncobj_array args;
+ int ret;
+
+ memclear(args);
+ args.handles = (uintptr_t)handles;
+ args.count_handles = handle_count;
+
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &args);
+ return ret;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 0d92701..7773d71 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -636,6 +636,12 @@
extern int drmSetClientCap(int fd, uint64_t capability,
uint64_t value);
+extern int drmCrtcGetSequence(int fd, uint32_t crtcId,
+ uint64_t *sequence, uint64_t *ns);
+extern int drmCrtcQueueSequence(int fd, uint32_t crtcId,
+ uint32_t flags, uint64_t sequence,
+ uint64_t *sequence_queued,
+ uint64_t user_data);
/* General user-level programmer's API: authenticated client and/or X */
extern int drmMap(int fd,
drm_handle_t handle,
@@ -728,7 +734,7 @@
extern int drmSetMaster(int fd);
extern int drmDropMaster(int fd);
-#define DRM_EVENT_CONTEXT_VERSION 2
+#define DRM_EVENT_CONTEXT_VERSION 4
typedef struct _drmEventContext {
@@ -748,6 +754,17 @@
unsigned int tv_usec,
void *user_data);
+ void (*page_flip_handler2)(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ unsigned int crtc_id,
+ void *user_data);
+
+ void (*sequence_handler)(int fd,
+ uint64_t sequence,
+ uint64_t ns,
+ uint64_t user_data);
} drmEventContext, *drmEventContextPtr;
extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
@@ -844,6 +861,21 @@
extern int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device);
extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices);
+extern int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b);
+
+extern int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle);
+extern int drmSyncobjDestroy(int fd, uint32_t handle);
+extern int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd);
+extern int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle);
+
+extern int drmSyncobjImportSyncFile(int fd, uint32_t handle, int sync_file_fd);
+extern int drmSyncobjExportSyncFile(int fd, uint32_t handle, int *sync_file_fd);
+extern int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t handle_count);
+extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t handle_count);
+
#if defined(__cplusplus)
}
#endif
diff --git a/xf86drmHash.c b/xf86drmHash.c
index f287e61..b2fa414 100644
--- a/xf86drmHash.c
+++ b/xf86drmHash.c
@@ -98,9 +98,6 @@
}
hash %= HASH_SIZE;
-#if DEBUG
- printf( "Hash(%lu) = %lu\n", key, hash);
-#endif
return hash;
}
@@ -201,9 +198,6 @@
bucket->value = value;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
-#if DEBUG
- printf("Inserted %lu at %lu/%p\n", key, hash, bucket);
-#endif
return 0; /* Added to table */
}
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 2876b42..b0ec609 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -38,10 +38,6 @@
* platforms find which headers to include to get uint32_t
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
@@ -271,9 +267,9 @@
}
int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
- uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
+ const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)
{
struct drm_mode_fb_cmd2 f;
int ret;
@@ -297,8 +293,8 @@
}
int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
uint32_t *buf_id, uint32_t flags)
{
return drmModeAddFB2WithModifiers(fd, width, height,
@@ -831,8 +827,7 @@
}
#elif defined(__DragonFly__)
return 0;
-#endif
-#ifdef __OpenBSD__
+#elif defined(__OpenBSD__)
int fd;
struct drm_mode_card_res res;
drmModeResPtr r = 0;
@@ -889,6 +884,8 @@
int len, i;
struct drm_event *e;
struct drm_event_vblank *vblank;
+ struct drm_event_crtc_sequence *seq;
+ void *user_data;
/* The DRM read semantics guarantees that we always get only
* complete events. */
@@ -915,15 +912,30 @@
U642VOID (vblank->user_data));
break;
case DRM_EVENT_FLIP_COMPLETE:
- if (evctx->version < 2 ||
- evctx->page_flip_handler == NULL)
- break;
vblank = (struct drm_event_vblank *) e;
- evctx->page_flip_handler(fd,
- vblank->sequence,
- vblank->tv_sec,
- vblank->tv_usec,
- U642VOID (vblank->user_data));
+ user_data = U642VOID (vblank->user_data);
+
+ if (evctx->version >= 3 && evctx->page_flip_handler2)
+ evctx->page_flip_handler2(fd,
+ vblank->sequence,
+ vblank->tv_sec,
+ vblank->tv_usec,
+ vblank->crtc_id,
+ user_data);
+ else if (evctx->version >= 2 && evctx->page_flip_handler)
+ evctx->page_flip_handler(fd,
+ vblank->sequence,
+ vblank->tv_sec,
+ vblank->tv_usec,
+ user_data);
+ break;
+ case DRM_EVENT_CRTC_SEQUENCE:
+ seq = (struct drm_event_crtc_sequence *) e;
+ if (evctx->version >= 4 && evctx->sequence_handler)
+ evctx->sequence_handler(fd,
+ seq->sequence,
+ seq->time_ns,
+ seq->user_data);
break;
default:
break;
@@ -1188,275 +1200,6 @@
return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop);
}
-typedef struct _drmModePropertySetItem drmModePropertySetItem, *drmModePropertySetItemPtr;
-
-struct _drmModePropertySetItem {
- uint32_t object_id;
- uint32_t property_id;
- bool is_blob;
- uint64_t value;
- void *blob;
- drmModePropertySetItemPtr next;
-};
-
-struct _drmModePropertySet {
- unsigned int count_objs;
- unsigned int count_props;
- unsigned int count_blobs;
- drmModePropertySetItem list;
-};
-
-drmModePropertySetPtr drmModePropertySetAlloc(void)
-{
- drmModePropertySetPtr set;
-
- set = drmMalloc(sizeof *set);
- if (!set)
- return NULL;
-
- set->list.next = NULL;
- set->count_props = 0;
- set->count_objs = 0;
-
- return set;
-}
-
-int drmModePropertySetAdd(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t value)
-{
- drmModePropertySetItemPtr prev = &set->list;
- bool new_obj = false;
-
- /* keep it sorted by object_id and property_id */
- while (prev->next) {
- if (prev->next->object_id > object_id)
- break;
-
- if (prev->next->object_id == object_id &&
- prev->next->property_id >= property_id)
- break;
-
- prev = prev->next;
- }
-
- if ((prev == &set->list || prev->object_id != object_id) &&
- (!prev->next || prev->next->object_id != object_id))
- new_obj = true;
-
- /* replace or add? */
- if (prev->next &&
- prev->next->object_id == object_id &&
- prev->next->property_id == property_id) {
- drmModePropertySetItemPtr item = prev->next;
-
- if (item->is_blob)
- return -EINVAL;
-
- item->value = value;
- } else {
- drmModePropertySetItemPtr item;
-
- item = drmMalloc(sizeof *item);
- if (!item)
- return -1;
-
- item->object_id = object_id;
- item->property_id = property_id;
- item->value = value;
- item->is_blob = false;
- item->blob = NULL;
-
- item->next = prev->next;
- prev->next = item;
-
- set->count_props++;
- }
-
- if (new_obj)
- set->count_objs++;
-
- return 0;
-}
-
-int drmModePropertySetAddBlob(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t length,
- void *data)
-{
- drmModePropertySetItemPtr prev = &set->list;
- bool new_obj = false;
-
- /* keep it sorted by object_id and property_id */
- while (prev->next) {
- if (prev->next->object_id > object_id)
- break;
-
- if (prev->next->object_id == object_id &&
- prev->next->property_id >= property_id)
- break;
-
- prev = prev->next;
- }
-
- if ((prev == &set->list || prev->object_id != object_id) &&
- (!prev->next || prev->next->object_id != object_id))
- new_obj = true;
-
- /* replace or add? */
- if (prev->next &&
- prev->next->object_id == object_id &&
- prev->next->property_id == property_id) {
- drmModePropertySetItemPtr item = prev->next;
-
- if (!item->is_blob)
- return -EINVAL;
-
- item->value = length;
- item->blob = data;
- } else {
- drmModePropertySetItemPtr item;
-
- item = drmMalloc(sizeof *item);
- if (!item)
- return -1;
-
- item->object_id = object_id;
- item->property_id = property_id;
- item->is_blob = true;
- item->value = length;
- item->blob = data;
-
- item->next = prev->next;
- prev->next = item;
-
- set->count_props++;
- set->count_blobs++;
- }
-
- if (new_obj)
- set->count_objs++;
-
- return 0;
-}
-
-void drmModePropertySetFree(drmModePropertySetPtr set)
-{
- drmModePropertySetItemPtr item;
-
- if (!set)
- return;
-
- item = set->list.next;
-
- while (item) {
- drmModePropertySetItemPtr next = item->next;
-
- drmFree(item);
-
- item = next;
- }
-
- drmFree(set);
-}
-
-int drmModePropertySetCommit(int fd, uint32_t flags, void *user_data,
- drmModePropertySetPtr set)
-{
- drmModePropertySetItemPtr item;
- uint32_t *objs_ptr = NULL;
- uint32_t *count_props_ptr = NULL;
- uint32_t *props_ptr = NULL;
- uint64_t *prop_values_ptr = NULL;
- uint64_t *blob_values_ptr = NULL;
- struct drm_mode_atomic atomic = { 0 };
- unsigned int obj_idx = 0;
- unsigned int prop_idx = 0;
- unsigned int blob_idx = 0;
- int ret = -1;
-
- if (!set)
- return -1;
-
- objs_ptr = drmMalloc(set->count_objs * sizeof objs_ptr[0]);
- if (!objs_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- count_props_ptr = drmMalloc(set->count_objs * sizeof count_props_ptr[0]);
- if (!count_props_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- props_ptr = drmMalloc(set->count_props * sizeof props_ptr[0]);
- if (!props_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- prop_values_ptr = drmMalloc(set->count_props * sizeof prop_values_ptr[0]);
- if (!prop_values_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- blob_values_ptr = drmMalloc(set->count_blobs * sizeof blob_values_ptr[0]);
- if (!blob_values_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- item = set->list.next;
-
- while (item) {
- int count_props = 0;
- drmModePropertySetItemPtr next = item;
-
- objs_ptr[obj_idx] = item->object_id;
-
- while (next && next->object_id == item->object_id) {
- props_ptr[prop_idx] = next->property_id;
- prop_values_ptr[prop_idx] = next->value;
- prop_idx++;
-
- if (next->is_blob)
- blob_values_ptr[blob_idx++] = VOID2U64(next->blob);
-
- count_props++;
-
- next = next->next;
- }
-
- count_props_ptr[obj_idx++] = count_props;
-
- item = next;
- }
-
- atomic.count_objs = set->count_objs;
- atomic.flags = flags;
- atomic.objs_ptr = VOID2U64(objs_ptr);
- atomic.count_props_ptr = VOID2U64(count_props_ptr);
- atomic.props_ptr = VOID2U64(props_ptr);
- atomic.prop_values_ptr = VOID2U64(prop_values_ptr);
-// TODO:
-// atomic.blob_values_ptr = VOID2U64(blob_values_ptr);
- atomic.user_data = VOID2U64(user_data);
-
- ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
-
-out:
- drmFree(objs_ptr);
- drmFree(count_props_ptr);
- drmFree(props_ptr);
- drmFree(prop_values_ptr);
-
- return ret;
-}
-
typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr;
struct _drmModeAtomicReqItem {
@@ -1565,6 +1308,9 @@
if (!req)
return -EINVAL;
+ if (object_id == 0 || property_id == 0)
+ return -EINVAL;
+
if (req->cursor >= req->size_items) {
const uint32_t item_size_inc = getpagesize() / sizeof(*req->items);
drmModeAtomicReqItemPtr new;
@@ -1747,3 +1493,92 @@
destroy.blob_id = id;
return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
}
+
+int
+drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags, uint32_t *lessee_id)
+{
+ struct drm_mode_create_lease create;
+ int ret;
+
+ memclear(create);
+ create.object_ids = (uintptr_t) objects;
+ create.object_count = num_objects;
+ create.flags = flags;
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATE_LEASE, &create);
+ if (ret == 0) {
+ *lessee_id = create.lessee_id;
+ return create.fd;
+ }
+ return -errno;
+}
+
+drmModeLesseeListPtr
+drmModeListLessees(int fd)
+{
+ struct drm_mode_list_lessees list;
+ uint32_t count;
+ drmModeLesseeListPtr ret;
+
+ memclear(list);
+
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list))
+ return NULL;
+
+ count = list.count_lessees;
+ ret = drmMalloc(sizeof (drmModeLesseeListRes) + count * sizeof (ret->lessees[0]));
+ if (!ret)
+ return NULL;
+
+ list.lessees_ptr = VOID2U64(&ret->lessees[0]);
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list)) {
+ drmFree(ret);
+ return NULL;
+ }
+
+ ret->count = count;
+ return ret;
+}
+
+drmModeObjectListPtr
+drmModeGetLease(int fd)
+{
+ struct drm_mode_get_lease get;
+ uint32_t count;
+ drmModeObjectListPtr ret;
+
+ memclear(get);
+
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get))
+ return NULL;
+
+ count = get.count_objects;
+ ret = drmMalloc(sizeof (drmModeObjectListRes) + count * sizeof (ret->objects[0]));
+ if (!ret)
+ return NULL;
+
+ get.objects_ptr = VOID2U64(&ret->objects[0]);
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get)) {
+ drmFree(ret);
+ return NULL;
+ }
+
+ ret->count = count;
+ return ret;
+}
+
+int
+drmModeRevokeLease(int fd, uint32_t lessee_id)
+{
+ struct drm_mode_revoke_lease revoke;
+ int ret;
+
+ memclear(revoke);
+
+ revoke.lessee_id = lessee_id;
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_REVOKE_LEASE, &revoke);
+ if (ret == 0)
+ return 0;
+ return -errno;
+}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 9d73be9..3cd27ae 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -369,15 +369,16 @@
uint32_t *buf_id);
/* ...with a specific pixel format */
extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
uint32_t *buf_id, uint32_t flags);
/* ...with format modifiers */
int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
- uint64_t modifier[4], uint32_t *buf_id, uint32_t flags);
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
+ const uint64_t modifier[4], uint32_t *buf_id,
+ uint32_t flags);
/**
* Destroies the given framebuffer.
@@ -498,25 +499,6 @@
uint64_t value);
-typedef struct _drmModePropertySet drmModePropertySet, *drmModePropertySetPtr;
-
-extern drmModePropertySetPtr drmModePropertySetAlloc(void);
-
-extern int drmModePropertySetAdd(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t value);
-extern int drmModePropertySetAddBlob(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t length,
- void *blob);
-
-extern int drmModePropertySetCommit(int fd, uint32_t flags,
- void *user_data, drmModePropertySetPtr set);
-
-extern void drmModePropertySetFree(drmModePropertySetPtr set);
-
typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr;
extern drmModeAtomicReqPtr drmModeAtomicAlloc(void);
@@ -539,6 +521,28 @@
uint32_t *id);
extern int drmModeDestroyPropertyBlob(int fd, uint32_t id);
+/*
+ * DRM mode lease APIs. These create and manage new drm_masters with
+ * access to a subset of the available DRM resources
+ */
+
+extern int drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags, uint32_t *lessee_id);
+
+typedef struct drmModeLesseeList {
+ uint32_t count;
+ uint32_t lessees[0];
+} drmModeLesseeListRes, *drmModeLesseeListPtr;
+
+extern drmModeLesseeListPtr drmModeListLessees(int fd);
+
+typedef struct drmModeObjectList {
+ uint32_t count;
+ uint32_t objects[0];
+} drmModeObjectListRes, *drmModeObjectListPtr;
+
+extern drmModeObjectListPtr drmModeGetLease(int fd);
+
+extern int drmModeRevokeLease(int fd, uint32_t lessee_id);
#if defined(__cplusplus)
}