summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlib/libdrm/amdgpu/amdgpu-symbol-check9
-rw-r--r--lib/libdrm/amdgpu/amdgpu.h131
-rw-r--r--lib/libdrm/amdgpu/amdgpu_cs.c137
-rw-r--r--lib/libdrm/amdgpu/amdgpu_device.c30
-rw-r--r--lib/libdrm/amdgpu/meson.build4
-rwxr-xr-xlib/libdrm/build-aux/compile13
-rwxr-xr-xlib/libdrm/build-aux/test-driver10
-rwxr-xr-xlib/libdrm/etnaviv/etnaviv-symbol-check3
-rw-r--r--lib/libdrm/etnaviv/etnaviv_cmd_stream.c8
-rw-r--r--lib/libdrm/etnaviv/etnaviv_drmif.h2
-rw-r--r--lib/libdrm/etnaviv/meson.build5
-rwxr-xr-xlib/libdrm/exynos/exynos-symbol-check2
-rw-r--r--lib/libdrm/exynos/meson.build4
-rwxr-xr-xlib/libdrm/freedreno/freedreno-symbol-check2
-rw-r--r--lib/libdrm/freedreno/meson.build4
-rw-r--r--lib/libdrm/include/drm/amdgpu_drm.h29
-rwxr-xr-xlib/libdrm/intel/intel-symbol-check2
-rw-r--r--lib/libdrm/intel/intel_chipset.c2
-rw-r--r--lib/libdrm/intel/meson.build22
-rwxr-xr-xlib/libdrm/libkms/kms-symbol-check2
-rw-r--r--lib/libdrm/libkms/meson.build4
-rw-r--r--lib/libdrm/meson.build19
-rw-r--r--lib/libdrm/nouveau/meson.build4
-rwxr-xr-xlib/libdrm/nouveau/nouveau-symbol-check2
-rw-r--r--lib/libdrm/omap/meson.build4
-rwxr-xr-xlib/libdrm/omap/omap-symbol-check2
-rw-r--r--lib/libdrm/omap/omap_drm.c2
-rw-r--r--lib/libdrm/radeon/meson.build4
-rwxr-xr-xlib/libdrm/radeon/radeon-symbol-check2
-rw-r--r--lib/libdrm/tegra/meson.build4
-rwxr-xr-xlib/libdrm/tegra/tegra-symbol-check2
-rw-r--r--lib/libdrm/tests/amdgpu/Makefile.am3
-rw-r--r--lib/libdrm/tests/amdgpu/amdgpu_test.c23
-rw-r--r--lib/libdrm/tests/amdgpu/amdgpu_test.h21
-rw-r--r--lib/libdrm/tests/amdgpu/basic_tests.c94
-rw-r--r--lib/libdrm/tests/amdgpu/bo_tests.c3
-rw-r--r--lib/libdrm/tests/amdgpu/meson.build2
-rw-r--r--lib/libdrm/tests/amdgpu/ras_tests.c446
-rw-r--r--lib/libdrm/tests/amdgpu/syncobj_tests.c298
-rw-r--r--lib/libdrm/tests/amdgpu/vcn_tests.c50
-rw-r--r--lib/libdrm/tests/kms/libkms-test-plane.c4
-rw-r--r--lib/libdrm/tests/modetest/buffers.c13
-rw-r--r--lib/libdrm/tests/modetest/modetest.c109
-rw-r--r--lib/libdrm/tests/util/format.c7
-rw-r--r--lib/libdrm/tests/util/pattern.c432
-rw-r--r--lib/libdrm/tests/util/pattern.h7
46 files changed, 1785 insertions, 197 deletions
diff --git a/lib/libdrm/amdgpu/amdgpu-symbol-check b/lib/libdrm/amdgpu/amdgpu-symbol-check
index 4d8069223..7d748eedd 100755
--- a/lib/libdrm/amdgpu/amdgpu-symbol-check
+++ b/lib/libdrm/amdgpu/amdgpu-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
@@ -46,15 +46,22 @@ amdgpu_cs_fence_to_handle
amdgpu_cs_import_syncobj
amdgpu_cs_query_fence_status
amdgpu_cs_query_reset_state
+amdgpu_cs_query_reset_state2
amdgpu_query_sw_info
amdgpu_cs_signal_semaphore
amdgpu_cs_submit
amdgpu_cs_submit_raw
amdgpu_cs_submit_raw2
amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_export_sync_file2
amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_import_sync_file2
+amdgpu_cs_syncobj_query
amdgpu_cs_syncobj_reset
amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_signal
+amdgpu_cs_syncobj_timeline_wait
+amdgpu_cs_syncobj_transfer
amdgpu_cs_syncobj_wait
amdgpu_cs_wait_fences
amdgpu_cs_wait_semaphore
diff --git a/lib/libdrm/amdgpu/amdgpu.h b/lib/libdrm/amdgpu/amdgpu.h
index c44a495a2..bcac4cb77 100644
--- a/lib/libdrm/amdgpu/amdgpu.h
+++ b/lib/libdrm/amdgpu/amdgpu.h
@@ -87,8 +87,8 @@ enum amdgpu_bo_handle_type {
/** DMA-buf fd handle */
amdgpu_bo_handle_type_dma_buf_fd = 2,
- /** KMS handle, but re-importing as a DMABUF handle through
- * drmPrimeHandleToFD is forbidden. (Glamor does that)
+ /** Deprecated in favour of and same behaviour as
+ * amdgpu_bo_handle_type_kms, use that instead of this
*/
amdgpu_bo_handle_type_kms_noimport = 3,
};
@@ -942,6 +942,21 @@ int amdgpu_cs_ctx_override_priority(amdgpu_device_handle dev,
int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
uint32_t *state, uint32_t *hangs);
+/**
+ * Query reset state for the specific GPU Context.
+ *
+ * \param context - \c [in] GPU Context handle
+ * \param flags - \c [out] A combination of AMDGPU_CTX_QUERY2_FLAGS_*
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ * \sa amdgpu_cs_ctx_create()
+ *
+*/
+int amdgpu_cs_query_reset_state2(amdgpu_context_handle context,
+ uint64_t *flags);
+
/*
* Command Buffers Management
*
@@ -1517,6 +1532,23 @@ int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
const uint32_t *syncobjs, uint32_t syncobj_count);
/**
+ * Signal kernel timeline sync objects.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobjs - \c [in] array of sync object handles
+ * \param points - \c [in] array of timeline points
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint64_t *points,
+ uint32_t syncobj_count);
+
+/**
* Wait for one or all sync objects to signal.
*
* \param dev - \c [in] self-explanatory
@@ -1537,6 +1569,45 @@ int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
uint32_t *first_signaled);
/**
+ * Wait for one or all sync objects on their points to signal.
+ *
+ * \param dev - \c [in] self-explanatory
+ * \param handles - \c [in] array of sync object handles
+ * \param points - \c [in] array of sync points to wait
+ * \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_timeline_wait(amdgpu_device_handle dev,
+ uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+/**
+ * Query sync objects payloads.
+ *
+ * \param dev - \c [in] self-explanatory
+ * \param handles - \c [in] array of sync object handles
+ * \param points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param num_handles - \c [in] self-explanatory
+ *
+ * \return 0 on success\n
+ * -ETIME - Timeout
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+ uint32_t *handles, uint64_t *points,
+ unsigned num_handles);
+
+/**
* Export kernel sync object to shareable fd.
*
* \param dev - \c [in] device handle
@@ -1594,6 +1665,62 @@ int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
uint32_t syncobj,
int sync_file_fd);
+/**
+ * Export kernel timeline sync object to a sync_file.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param point - \c [in] timeline point
+ * \param flags - \c [in] flags
+ * \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_file2(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ uint64_t point,
+ uint32_t flags,
+ int *sync_file_fd);
+
+/**
+ * Import kernel timeline sync object from a sync_file.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param point - \c [in] timeline point
+ * \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_file2(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ uint64_t point,
+ int sync_file_fd);
+
+/**
+ * transfer between syncbojs.
+ *
+ * \param dev - \c [in] device handle
+ * \param dst_handle - \c [in] sync object handle
+ * \param dst_point - \c [in] timeline point, 0 presents dst is binary
+ * \param src_handle - \c [in] sync object handle
+ * \param src_point - \c [in] timeline point, 0 presents src is binary
+ * \param flags - \c [in] flags
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+ uint32_t dst_handle,
+ uint64_t dst_point,
+ uint32_t src_handle,
+ uint64_t src_point,
+ uint32_t flags);
/**
* Export an amdgpu fence as a handle (syncobj or fd).
diff --git a/lib/libdrm/amdgpu/amdgpu_cs.c b/lib/libdrm/amdgpu/amdgpu_cs.c
index 7ee844fb7..56502950b 100644
--- a/lib/libdrm/amdgpu/amdgpu_cs.c
+++ b/lib/libdrm/amdgpu/amdgpu_cs.c
@@ -147,12 +147,12 @@ drm_public int amdgpu_cs_ctx_override_priority(amdgpu_device_handle dev,
int master_fd,
unsigned priority)
{
+ union drm_amdgpu_sched args;
int r;
if (!dev || !context || master_fd < 0)
return -EINVAL;
- union drm_amdgpu_sched args;
memset(&args, 0, sizeof(args));
args.in.op = AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE;
@@ -188,6 +188,25 @@ drm_public int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
return r;
}
+drm_public int amdgpu_cs_query_reset_state2(amdgpu_context_handle context,
+ uint64_t *flags)
+{
+ union drm_amdgpu_ctx args;
+ int r;
+
+ if (!context)
+ return -EINVAL;
+
+ memset(&args, 0, sizeof(args));
+ args.in.op = AMDGPU_CTX_OP_QUERY_STATE2;
+ args.in.ctx_id = context->id;
+ r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX,
+ &args, sizeof(args));
+ if (!r)
+ *flags = args.out.state.flags;
+ return r;
+}
+
/**
* Submit command to kernel DRM
* \param dev - \c [in] Device handle
@@ -674,6 +693,18 @@ drm_public int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
}
+drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint64_t *points,
+ uint32_t syncobj_count)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjTimelineSignal(dev->fd, syncobjs,
+ points, syncobj_count);
+}
+
drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
uint32_t *handles, unsigned num_handles,
int64_t timeout_nsec, unsigned flags,
@@ -686,6 +717,29 @@ drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
flags, first_signaled);
}
+drm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+ uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles,
+ timeout_nsec, flags, first_signaled);
+}
+
+drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+ uint32_t *handles, uint64_t *points,
+ unsigned num_handles)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjQuery(dev->fd, handles, points, num_handles);
+}
+
drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
@@ -726,6 +780,78 @@ drm_public int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
}
+drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ uint64_t point,
+ uint32_t flags,
+ int *sync_file_fd)
+{
+ uint32_t binary_handle;
+ int ret;
+
+ if (NULL == dev)
+ return -EINVAL;
+
+ if (!point)
+ return drmSyncobjExportSyncFile(dev->fd, syncobj, sync_file_fd);
+
+ ret = drmSyncobjCreate(dev->fd, 0, &binary_handle);
+ if (ret)
+ return ret;
+
+ ret = drmSyncobjTransfer(dev->fd, binary_handle, 0,
+ syncobj, point, flags);
+ if (ret)
+ goto out;
+ ret = drmSyncobjExportSyncFile(dev->fd, binary_handle, sync_file_fd);
+out:
+ drmSyncobjDestroy(dev->fd, binary_handle);
+ return ret;
+}
+
+drm_public int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ uint64_t point,
+ int sync_file_fd)
+{
+ uint32_t binary_handle;
+ int ret;
+
+ if (NULL == dev)
+ return -EINVAL;
+
+ if (!point)
+ return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
+
+ ret = drmSyncobjCreate(dev->fd, 0, &binary_handle);
+ if (ret)
+ return ret;
+ ret = drmSyncobjImportSyncFile(dev->fd, binary_handle, sync_file_fd);
+ if (ret)
+ goto out;
+ ret = drmSyncobjTransfer(dev->fd, syncobj, point,
+ binary_handle, 0, 0);
+out:
+ drmSyncobjDestroy(dev->fd, binary_handle);
+ return ret;
+}
+
+drm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+ uint32_t dst_handle,
+ uint64_t dst_point,
+ uint32_t src_handle,
+ uint64_t src_point,
+ uint32_t flags)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjTransfer(dev->fd,
+ dst_handle, dst_point,
+ src_handle, src_point,
+ flags);
+}
+
drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
amdgpu_context_handle context,
amdgpu_bo_list_handle bo_list_handle,
@@ -733,12 +859,13 @@ drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
struct drm_amdgpu_cs_chunk *chunks,
uint64_t *seq_no)
{
- union drm_amdgpu_cs cs = {0};
+ 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];
@@ -763,10 +890,11 @@ drm_public int amdgpu_cs_submit_raw2(amdgpu_device_handle dev,
struct drm_amdgpu_cs_chunk *chunks,
uint64_t *seq_no)
{
- union drm_amdgpu_cs cs = {0};
+ union drm_amdgpu_cs cs;
uint64_t *chunk_array;
int i, r;
+ 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];
@@ -803,9 +931,10 @@ drm_public int amdgpu_cs_fence_to_handle(amdgpu_device_handle dev,
uint32_t what,
uint32_t *out_handle)
{
- union drm_amdgpu_fence_to_handle fth = {0};
+ 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;
diff --git a/lib/libdrm/amdgpu/amdgpu_device.c b/lib/libdrm/amdgpu/amdgpu_device.c
index 362494b16..76b4e5ebc 100644
--- a/lib/libdrm/amdgpu/amdgpu_device.c
+++ b/lib/libdrm/amdgpu/amdgpu_device.c
@@ -43,8 +43,8 @@
#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
-static pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER;
-static amdgpu_device_handle fd_list;
+static pthread_mutex_t dev_mutex = PTHREAD_MUTEX_INITIALIZER;
+static amdgpu_device_handle dev_list;
static int fd_compare(int fd1, int fd2)
{
@@ -95,13 +95,13 @@ static int amdgpu_get_auth(int fd, int *auth)
static void amdgpu_device_free_internal(amdgpu_device_handle dev)
{
- amdgpu_device_handle *node = &fd_list;
+ amdgpu_device_handle *node = &dev_list;
- pthread_mutex_lock(&fd_mutex);
+ pthread_mutex_lock(&dev_mutex);
while (*node != dev && (*node)->next)
node = &(*node)->next;
*node = (*node)->next;
- pthread_mutex_unlock(&fd_mutex);
+ pthread_mutex_unlock(&dev_mutex);
close(dev->fd);
if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
@@ -155,16 +155,16 @@ drm_public int amdgpu_device_initialize(int fd,
*device_handle = NULL;
- pthread_mutex_lock(&fd_mutex);
+ pthread_mutex_lock(&dev_mutex);
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);
+ pthread_mutex_unlock(&dev_mutex);
return r;
}
- for (dev = fd_list; dev; dev = dev->next)
+ for (dev = dev_list; dev; dev = dev->next)
if (fd_compare(dev->fd, fd) == 0)
break;
@@ -173,7 +173,7 @@ drm_public int amdgpu_device_initialize(int fd,
if (r) {
fprintf(stderr, "%s: amdgpu_get_auth (2) failed (%i)\n",
__func__, r);
- pthread_mutex_unlock(&fd_mutex);
+ pthread_mutex_unlock(&dev_mutex);
return r;
}
if ((flag_auth) && (!flag_authexist)) {
@@ -182,14 +182,14 @@ drm_public int amdgpu_device_initialize(int fd,
*major_version = dev->major_version;
*minor_version = dev->minor_version;
amdgpu_device_reference(device_handle, dev);
- pthread_mutex_unlock(&fd_mutex);
+ pthread_mutex_unlock(&dev_mutex);
return 0;
}
dev = calloc(1, sizeof(struct amdgpu_device));
if (!dev) {
fprintf(stderr, "%s: calloc failed\n", __func__);
- pthread_mutex_unlock(&fd_mutex);
+ pthread_mutex_unlock(&dev_mutex);
return -ENOMEM;
}
@@ -265,9 +265,9 @@ drm_public int amdgpu_device_initialize(int fd,
*major_version = dev->major_version;
*minor_version = dev->minor_version;
*device_handle = dev;
- dev->next = fd_list;
- fd_list = dev;
- pthread_mutex_unlock(&fd_mutex);
+ dev->next = dev_list;
+ dev_list = dev;
+ pthread_mutex_unlock(&dev_mutex);
return 0;
@@ -275,7 +275,7 @@ cleanup:
if (dev->fd >= 0)
close(dev->fd);
free(dev);
- pthread_mutex_unlock(&fd_mutex);
+ pthread_mutex_unlock(&dev_mutex);
return r;
}
diff --git a/lib/libdrm/amdgpu/meson.build b/lib/libdrm/amdgpu/meson.build
index 7c8ccc7e4..8168993a7 100644
--- a/lib/libdrm/amdgpu/meson.build
+++ b/lib/libdrm/amdgpu/meson.build
@@ -59,7 +59,7 @@ ext_libdrm_amdgpu = declare_dependency(
test(
'amdgpu-symbol-check',
- prog_bash,
+ find_program('amdgpu-symbol-check'),
env : env_test,
- args : [files('amdgpu-symbol-check'), libdrm_amdgpu]
+ args : libdrm_amdgpu,
)
diff --git a/lib/libdrm/build-aux/compile b/lib/libdrm/build-aux/compile
index 99e50524b..a85b723c7 100755
--- a/lib/libdrm/build-aux/compile
+++ b/lib/libdrm/build-aux/compile
@@ -1,9 +1,9 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
-scriptversion=2018-03-07.03; # UTC
+scriptversion=2012-10-14.11; # UTC
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2018-03-07.03; # UTC
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -255,8 +255,7 @@ EOF
echo "compile $scriptversion"
exit $?
;;
- cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
- icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
@@ -340,9 +339,9 @@ exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC0"
+# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
diff --git a/lib/libdrm/build-aux/test-driver b/lib/libdrm/build-aux/test-driver
index b8521a482..8e575b017 100755
--- a/lib/libdrm/build-aux/test-driver
+++ b/lib/libdrm/build-aux/test-driver
@@ -1,9 +1,9 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
-scriptversion=2018-03-07.03; # UTC
+scriptversion=2013-07-13.22; # UTC
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
#
# 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
@@ -16,7 +16,7 @@ scriptversion=2018-03-07.03; # UTC
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -140,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
# Local Variables:
# mode: shell-script
# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC0"
+# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
diff --git a/lib/libdrm/etnaviv/etnaviv-symbol-check b/lib/libdrm/etnaviv/etnaviv-symbol-check
index 189106889..b3f3dda7f 100755
--- a/lib/libdrm/etnaviv/etnaviv-symbol-check
+++ b/lib/libdrm/etnaviv/etnaviv-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
@@ -25,7 +25,6 @@ etna_pipe_del
etna_pipe_wait
etna_pipe_wait_ns
etna_bo_new
-etna_bo_from_handle
etna_bo_from_name
etna_bo_from_dmabuf
etna_bo_ref
diff --git a/lib/libdrm/etnaviv/etnaviv_cmd_stream.c b/lib/libdrm/etnaviv/etnaviv_cmd_stream.c
index 7139c3245..261777b00 100644
--- a/lib/libdrm/etnaviv/etnaviv_cmd_stream.c
+++ b/lib/libdrm/etnaviv/etnaviv_cmd_stream.c
@@ -150,11 +150,7 @@ static uint32_t bo2idx(struct etna_cmd_stream *stream, struct etna_bo *bo,
pthread_mutex_lock(&idx_lock);
- if (!bo->current_stream) {
- idx = append_bo(stream, bo);
- bo->current_stream = stream;
- bo->idx = idx;
- } else if (bo->current_stream == stream) {
+ if (bo->current_stream == stream) {
idx = bo->idx;
} else {
/* slow-path: */
@@ -165,6 +161,8 @@ static uint32_t bo2idx(struct etna_cmd_stream *stream, struct etna_bo *bo,
/* not found */
idx = append_bo(stream, bo);
}
+ bo->current_stream = stream;
+ bo->idx = idx;
}
pthread_mutex_unlock(&idx_lock);
diff --git a/lib/libdrm/etnaviv/etnaviv_drmif.h b/lib/libdrm/etnaviv/etnaviv_drmif.h
index 5a6bef8d1..80aedc1cf 100644
--- a/lib/libdrm/etnaviv/etnaviv_drmif.h
+++ b/lib/libdrm/etnaviv/etnaviv_drmif.h
@@ -115,8 +115,6 @@ int etna_pipe_wait_ns(struct etna_pipe *pipe, uint32_t timestamp, uint64_t ns);
struct etna_bo *etna_bo_new(struct etna_device *dev,
uint32_t size, uint32_t flags);
-struct etna_bo *etna_bo_from_handle(struct etna_device *dev,
- uint32_t handle, uint32_t size);
struct etna_bo *etna_bo_from_name(struct etna_device *dev, uint32_t name);
struct etna_bo *etna_bo_from_dmabuf(struct etna_device *dev, int fd);
struct etna_bo *etna_bo_ref(struct etna_bo *bo);
diff --git a/lib/libdrm/etnaviv/meson.build b/lib/libdrm/etnaviv/meson.build
index 515a4ed07..1ecf29404 100644
--- a/lib/libdrm/etnaviv/meson.build
+++ b/lib/libdrm/etnaviv/meson.build
@@ -54,6 +54,7 @@ ext_libdrm_etnaviv = declare_dependency(
test(
'etnaviv-symbol-check',
- prog_bash,
- args : [files('etnaviv-symbol-check'), libdrm_etnaviv]
+ find_program('etnaviv-symbol-check'),
+ env : env_test,
+ args : libdrm_etnaviv,
)
diff --git a/lib/libdrm/exynos/exynos-symbol-check b/lib/libdrm/exynos/exynos-symbol-check
index 49d611e6b..d2c362e1f 100755
--- a/lib/libdrm/exynos/exynos-symbol-check
+++ b/lib/libdrm/exynos/exynos-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/exynos/meson.build b/lib/libdrm/exynos/meson.build
index bdfc3fc6d..0136cb2a8 100644
--- a/lib/libdrm/exynos/meson.build
+++ b/lib/libdrm/exynos/meson.build
@@ -48,7 +48,7 @@ pkg.generate(
test(
'exynos-symbol-check',
- prog_bash,
+ find_program('exynos-symbol-check'),
env : env_test,
- args : [files('exynos-symbol-check'), libdrm_exynos]
+ args : libdrm_exynos,
)
diff --git a/lib/libdrm/freedreno/freedreno-symbol-check b/lib/libdrm/freedreno/freedreno-symbol-check
index 978026c09..987e38fa2 100755
--- a/lib/libdrm/freedreno/freedreno-symbol-check
+++ b/lib/libdrm/freedreno/freedreno-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/freedreno/meson.build b/lib/libdrm/freedreno/meson.build
index c9aba060a..5d8d8e9bb 100644
--- a/lib/libdrm/freedreno/meson.build
+++ b/lib/libdrm/freedreno/meson.build
@@ -71,7 +71,7 @@ pkg.generate(
test(
'freedreno-symbol-check',
- prog_bash,
+ find_program('freedreno-symbol-check'),
env : env_test,
- args : [files('freedreno-symbol-check'), libdrm_freedreno]
+ args : libdrm_freedreno,
)
diff --git a/lib/libdrm/include/drm/amdgpu_drm.h b/lib/libdrm/include/drm/amdgpu_drm.h
index d0701ffcb..4fe35d600 100644
--- a/lib/libdrm/include/drm/amdgpu_drm.h
+++ b/lib/libdrm/include/drm/amdgpu_drm.h
@@ -128,6 +128,10 @@ extern "C" {
* for the second page onward should be set to NC.
*/
#define AMDGPU_GEM_CREATE_MQD_GFX9 (1 << 8)
+/* Flag that BO may contain sensitive data that must be wiped before
+ * releasing the memory
+ */
+#define AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE (1 << 9)
struct drm_amdgpu_gem_create_in {
/** the requested memory size */
@@ -204,9 +208,9 @@ union drm_amdgpu_bo_list {
/* unknown cause */
#define AMDGPU_CTX_UNKNOWN_RESET 3
-/* indicate gpu reset occurred after ctx created */
+/* indicate gpu reset occured after ctx created */
#define AMDGPU_CTX_QUERY2_FLAGS_RESET (1<<0)
-/* indicate vram lost occurred after ctx created */
+/* 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)
@@ -219,7 +223,10 @@ union drm_amdgpu_bo_list {
#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 */
+/*
+ * When used in struct drm_amdgpu_ctx_in, a priority above NORMAL requires
+ * CAP_SYS_NICE or DRM_MASTER
+*/
#define AMDGPU_CTX_PRIORITY_HIGH 512
#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023
@@ -229,6 +236,7 @@ struct drm_amdgpu_ctx_in {
/** For future use, no flags defined so far */
__u32 flags;
__u32 ctx_id;
+ /** AMDGPU_CTX_PRIORITY_* */
__s32 priority;
};
@@ -281,6 +289,7 @@ struct drm_amdgpu_sched_in {
/* AMDGPU_SCHED_OP_* */
__u32 op;
__u32 fd;
+ /** AMDGPU_CTX_PRIORITY_* */
__s32 priority;
__u32 ctx_id;
};
@@ -528,6 +537,8 @@ struct drm_amdgpu_gem_va {
#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
#define AMDGPU_CHUNK_ID_BO_HANDLES 0x06
#define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT 0x08
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x09
struct drm_amdgpu_cs_chunk {
__u32 chunk_id;
@@ -608,6 +619,12 @@ struct drm_amdgpu_cs_chunk_sem {
__u32 handle;
};
+struct drm_amdgpu_cs_chunk_syncobj {
+ __u32 handle;
+ __u32 flags;
+ __u64 point;
+};
+
#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
@@ -904,6 +921,7 @@ struct drm_amdgpu_info_firmware {
#define AMDGPU_VRAM_TYPE_HBM 6
#define AMDGPU_VRAM_TYPE_DDR3 7
#define AMDGPU_VRAM_TYPE_DDR4 8
+#define AMDGPU_VRAM_TYPE_GDDR6 9
struct drm_amdgpu_info_device {
/** PCI Device ID */
@@ -983,6 +1001,10 @@ struct drm_amdgpu_info_device {
__u64 high_va_offset;
/** The maximum high virtual address */
__u64 high_va_max;
+ /* gfx10 pa_sc_tile_steering_override */
+ __u32 pa_sc_tile_steering_override;
+ /* disabled TCCs */
+ __u64 tcc_disabled_mask;
};
struct drm_amdgpu_info_hw_ip {
@@ -1036,6 +1058,7 @@ struct drm_amdgpu_info_vce_clock_table {
#define AMDGPU_FAMILY_CZ 135 /* Carrizo, Stoney */
#define AMDGPU_FAMILY_AI 141 /* Vega10 */
#define AMDGPU_FAMILY_RV 142 /* Raven */
+#define AMDGPU_FAMILY_NV 143 /* Navi10 */
#if defined(__cplusplus)
}
diff --git a/lib/libdrm/intel/intel-symbol-check b/lib/libdrm/intel/intel-symbol-check
index de377bef1..2f3553219 100755
--- a/lib/libdrm/intel/intel-symbol-check
+++ b/lib/libdrm/intel/intel-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/intel/intel_chipset.c b/lib/libdrm/intel/intel_chipset.c
index 5aa4a2f25..f6e37ee7f 100644
--- a/lib/libdrm/intel/intel_chipset.c
+++ b/lib/libdrm/intel/intel_chipset.c
@@ -35,6 +35,8 @@ static const struct pci_device {
uint16_t gen;
} pciids[] = {
/* Keep ids sorted by gen; latest gen first */
+ INTEL_TGL_12_IDS(12),
+ INTEL_EHL_IDS(11),
INTEL_ICL_11_IDS(11),
INTEL_CNL_IDS(10),
INTEL_CFL_IDS(9),
diff --git a/lib/libdrm/intel/meson.build b/lib/libdrm/intel/meson.build
index 3d6bbac62..355bf35d4 100644
--- a/lib/libdrm/intel/meson.build
+++ b/lib/libdrm/intel/meson.build
@@ -64,43 +64,37 @@ test_decode = executable(
test(
'gen4-3d.batch',
- prog_bash,
- args : files('tests/gen4-3d.batch.sh'),
+ find_program('tests/gen4-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen45-3d.batch',
- prog_bash,
- args : files('tests/gm45-3d.batch.sh'),
+ find_program('tests/gm45-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen5-3d.batch',
- prog_bash,
- args : files('tests/gen5-3d.batch.sh'),
+ find_program('tests/gen5-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen6-3d.batch',
- prog_bash,
- args : files('tests/gen6-3d.batch.sh'),
+ find_program('tests/gen6-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen7-3d.batch',
- prog_bash,
- args : files('tests/gen7-3d.batch.sh'),
+ find_program('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'),
+ find_program('tests/gen7-2d-copy.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'intel-symbol-check',
- prog_bash,
+ find_program('intel-symbol-check'),
env : env_test,
- args : [files('intel-symbol-check'), libdrm_intel]
+ args : libdrm_intel,
)
diff --git a/lib/libdrm/libkms/kms-symbol-check b/lib/libdrm/libkms/kms-symbol-check
index 30f444f7b..7d3426f6f 100755
--- a/lib/libdrm/libkms/kms-symbol-check
+++ b/lib/libdrm/libkms/kms-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/libkms/meson.build b/lib/libdrm/libkms/meson.build
index dc9316086..04f018af6 100644
--- a/lib/libdrm/libkms/meson.build
+++ b/lib/libdrm/libkms/meson.build
@@ -69,7 +69,7 @@ pkg.generate(
test(
'kms-symbol-check',
- prog_bash,
+ find_program('kms-symbol-check'),
env : env_test,
- args : [files('kms-symbol-check'), libkms]
+ args : libkms,
)
diff --git a/lib/libdrm/meson.build b/lib/libdrm/meson.build
index be768afa3..fc02f5527 100644
--- a/lib/libdrm/meson.build
+++ b/lib/libdrm/meson.build
@@ -21,7 +21,7 @@
project(
'libdrm',
['c'],
- version : '2.4.98',
+ version : '2.4.100',
license : 'MIT',
meson_version : '>= 0.43',
default_options : ['buildtype=debugoptimized', 'c_std=gnu99'],
@@ -179,13 +179,21 @@ else
dep_rt = []
endif
dep_m = cc.find_library('m', required : false)
+# From Niclas Zeising:
+# FreeBSD requires sys/types.h for sys/sysctl.h, add it as part of the
+# includes when checking for headers.
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)))
+ cc.compiles('#include <sys/types.h>\n#include <@0@>'.format(header), name : '@0@ works'.format(header)))
endforeach
-if cc.has_header_symbol('sys/sysmacros.h', 'major')
+if (cc.has_header_symbol('sys/sysmacros.h', 'major') and
+ cc.has_header_symbol('sys/sysmacros.h', 'minor') and
+ cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
config.set10('MAJOR_IN_SYSMACROS', true)
-elif cc.has_header_symbol('sys/mkdev.h', 'major')
+endif
+if (cc.has_header_symbol('sys/mkdev.h', 'major') and
+ cc.has_header_symbol('sys/mkdev.h', 'minor') and
+ cc.has_header_symbol('sys/mkdev.h', 'makedev'))
config.set10('MAJOR_IN_MKDEV', true)
endif
config.set10('HAVE_OPEN_MEMSTREAM', cc.has_function('open_memstream'))
@@ -248,9 +256,6 @@ if prog_xslt.found()
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"))'))
diff --git a/lib/libdrm/nouveau/meson.build b/lib/libdrm/nouveau/meson.build
index 0c1498d7e..56e952ca5 100644
--- a/lib/libdrm/nouveau/meson.build
+++ b/lib/libdrm/nouveau/meson.build
@@ -53,7 +53,7 @@ pkg.generate(
test(
'nouveau-symbol-check',
- prog_bash,
+ find_program('nouveau-symbol-check'),
env : env_test,
- args : [files('nouveau-symbol-check'), libdrm_nouveau]
+ args : libdrm_nouveau,
)
diff --git a/lib/libdrm/nouveau/nouveau-symbol-check b/lib/libdrm/nouveau/nouveau-symbol-check
index 6296244c1..36703a3e0 100755
--- a/lib/libdrm/nouveau/nouveau-symbol-check
+++ b/lib/libdrm/nouveau/nouveau-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/omap/meson.build b/lib/libdrm/omap/meson.build
index 54698c6a8..f3ea36dbf 100644
--- a/lib/libdrm/omap/meson.build
+++ b/lib/libdrm/omap/meson.build
@@ -48,7 +48,7 @@ pkg.generate(
test(
'omap-symbol-check',
- prog_bash,
+ find_program('omap-symbol-check'),
env : env_test,
- args : [files('omap-symbol-check'), libdrm_omap]
+ args : libdrm_omap,
)
diff --git a/lib/libdrm/omap/omap-symbol-check b/lib/libdrm/omap/omap-symbol-check
index 16da3c406..21522ba04 100755
--- a/lib/libdrm/omap/omap-symbol-check
+++ b/lib/libdrm/omap/omap-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/omap/omap_drm.c b/lib/libdrm/omap/omap_drm.c
index 3aed4e0a2..ffacea697 100644
--- a/lib/libdrm/omap/omap_drm.c
+++ b/lib/libdrm/omap/omap_drm.c
@@ -414,7 +414,7 @@ drm_public int omap_bo_dmabuf(struct omap_bo *bo)
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/lib/libdrm/radeon/meson.build b/lib/libdrm/radeon/meson.build
index 1fc5282cf..662b5bcef 100644
--- a/lib/libdrm/radeon/meson.build
+++ b/lib/libdrm/radeon/meson.build
@@ -58,7 +58,7 @@ pkg.generate(
test(
'radeon-symbol-check',
- prog_bash,
+ find_program('radeon-symbol-check'),
env : env_test,
- args : [files('radeon-symbol-check'), libdrm_radeon]
+ args : libdrm_radeon,
)
diff --git a/lib/libdrm/radeon/radeon-symbol-check b/lib/libdrm/radeon/radeon-symbol-check
index da605bb88..7b69f9a48 100755
--- a/lib/libdrm/radeon/radeon-symbol-check
+++ b/lib/libdrm/radeon/radeon-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/tegra/meson.build b/lib/libdrm/tegra/meson.build
index 4bc454b6e..ce56ddcfc 100644
--- a/lib/libdrm/tegra/meson.build
+++ b/lib/libdrm/tegra/meson.build
@@ -47,7 +47,7 @@ pkg.generate(
test(
'tegra-symbol-check',
- prog_bash,
+ find_program('tegra-symbol-check'),
env : env_test,
- args : [files('tegra-symbol-check'), libdrm_tegra]
+ args : libdrm_tegra,
)
diff --git a/lib/libdrm/tegra/tegra-symbol-check b/lib/libdrm/tegra/tegra-symbol-check
index 8539b95be..a74d97497 100755
--- a/lib/libdrm/tegra/tegra-symbol-check
+++ b/lib/libdrm/tegra/tegra-symbol-check
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
set -u
diff --git a/lib/libdrm/tests/amdgpu/Makefile.am b/lib/libdrm/tests/amdgpu/Makefile.am
index 48278848c..920882d02 100644
--- a/lib/libdrm/tests/amdgpu/Makefile.am
+++ b/lib/libdrm/tests/amdgpu/Makefile.am
@@ -34,4 +34,5 @@ amdgpu_test_SOURCES = \
uve_ib.h \
deadlock_tests.c \
vm_tests.c \
- ras_tests.c
+ ras_tests.c \
+ syncobj_tests.c
diff --git a/lib/libdrm/tests/amdgpu/amdgpu_test.c b/lib/libdrm/tests/amdgpu/amdgpu_test.c
index 35c8bf6cc..5aadd7e64 100644
--- a/lib/libdrm/tests/amdgpu/amdgpu_test.c
+++ b/lib/libdrm/tests/amdgpu/amdgpu_test.c
@@ -57,6 +57,7 @@
#define DEADLOCK_TESTS_STR "Deadlock Tests"
#define VM_TESTS_STR "VM Tests"
#define RAS_TESTS_STR "RAS Tests"
+#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
/**
* Open handles for amdgpu devices
@@ -123,6 +124,12 @@ static CU_SuiteInfo suites[] = {
.pCleanupFunc = suite_ras_tests_clean,
.pTests = ras_tests,
},
+ {
+ .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+ .pInitFunc = suite_syncobj_timeline_tests_init,
+ .pCleanupFunc = suite_syncobj_timeline_tests_clean,
+ .pTests = syncobj_timeline_tests,
+ },
CU_SUITE_INFO_NULL,
};
@@ -176,6 +183,10 @@ static Suites_Active_Status suites_active_stat[] = {
.pName = RAS_TESTS_STR,
.pActive = suite_ras_tests_enable,
},
+ {
+ .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+ .pActive = suite_syncobj_timeline_tests_enable,
+ },
};
@@ -453,14 +464,22 @@ static void amdgpu_disable_suites()
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
/* This test was ran on GFX9 only */
- if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
- if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test", CU_FALSE))
+ if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) {
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (GFX)", CU_FALSE))
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (Compute)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+ }
/* This test was ran on GFX9 only */
if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
if (amdgpu_set_test_active(BASIC_TESTS_STR, "Draw Test", CU_FALSE))
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "GPU reset Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
}
/* The main() function for setting up and running the tests.
diff --git a/lib/libdrm/tests/amdgpu/amdgpu_test.h b/lib/libdrm/tests/amdgpu/amdgpu_test.h
index bcd0bc7e6..36675ea3f 100644
--- a/lib/libdrm/tests/amdgpu/amdgpu_test.h
+++ b/lib/libdrm/tests/amdgpu/amdgpu_test.h
@@ -217,6 +217,27 @@ extern CU_TestInfo ras_tests[];
/**
+ * Initialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_init();
+
+/**
+ * Deinitialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_syncobj_timeline_tests_enable(void);
+
+/**
+ * Tests in syncobj timeline test suite
+ */
+extern CU_TestInfo syncobj_timeline_tests[];
+
+
+/**
* Helper functions
*/
static inline amdgpu_bo_handle gpu_mem_alloc(
diff --git a/lib/libdrm/tests/amdgpu/basic_tests.c b/lib/libdrm/tests/amdgpu/basic_tests.c
index 2d472691b..ab2a6728a 100644
--- a/lib/libdrm/tests/amdgpu/basic_tests.c
+++ b/lib/libdrm/tests/amdgpu/basic_tests.c
@@ -24,6 +24,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/types.h>
+#ifdef MAJOR_IN_SYSMACROS
+#include <sys/sysmacros.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
@@ -49,8 +55,10 @@ 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_dispatch_test(void);
+static void amdgpu_compute_dispatch_test(void);
+static void amdgpu_gfx_dispatch_test(void);
static void amdgpu_draw_test(void);
+static void amdgpu_gpu_reset_test(void);
static void amdgpu_command_submission_write_linear_helper(unsigned ip_type);
static void amdgpu_command_submission_const_fill_helper(unsigned ip_type);
@@ -72,8 +80,10 @@ CU_TestInfo basic_tests[] = {
{ "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
{ "SW semaphore Test", amdgpu_semaphore_test },
{ "Sync dependency Test", amdgpu_sync_dependency_test },
- { "Dispatch Test", amdgpu_dispatch_test },
+ { "Dispatch Test (Compute)", amdgpu_compute_dispatch_test },
+ { "Dispatch Test (GFX)", amdgpu_gfx_dispatch_test },
{ "Draw Test", amdgpu_draw_test },
+ { "GPU reset Test", amdgpu_gpu_reset_test },
CU_TEST_INFO_NULL,
};
#define BUFFER_SIZE (8 * 1024)
@@ -329,14 +339,15 @@ static const uint32_t preamblecache_gfx9[] = {
0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0,
0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0,
0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
- 0xc0026900, 0x311, 0x3, 0x0, 0xc0026900, 0x316, 0x1e, 0x20,
+ 0xc0036900, 0x311, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0x1e, 0x20,
0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0,
0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x19, 0x0,
0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0,
0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0,
0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff,
- 0xc0016900, 0x314, 0x0, 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1,
+ 0xc0016900, 0x314, 0x0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0,
+ 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1,
0xc0016900, 0x18, 0x2, 0xc0016900, 0x206, 0x300, 0xc0017900, 0x20000243, 0x0,
0xc0017900, 0x248, 0xffffffff, 0xc0017900, 0x249, 0x0, 0xc0017900, 0x24a, 0x0,
0xc0017900, 0x24b, 0x0
@@ -450,7 +461,7 @@ static const uint32_t cached_cmd_gfx9[] = {
0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0,
0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020,
0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf,
- 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x12,
+ 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x1a,
0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0,
0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011,
0xc0026900, 0x292, 0x20, 0x60201b8,
@@ -2094,10 +2105,7 @@ static int amdgpu_dispatch_init(uint32_t *ptr, uint32_t ip_type)
ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 3);
ptr[i++] = 0x204;
i += 3;
- /* clear mmCOMPUTE_RESOURCE_LIMITS */
- ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
- ptr[i++] = 0x215;
- ptr[i++] = 0;
+
/* clear mmCOMPUTE_TMPRING_SIZE */
ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
ptr[i++] = 0x218;
@@ -2184,6 +2192,7 @@ static void amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle,
&bo_shader, &ptr_shader,
&mc_address_shader, &va_shader);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader, 0, bo_shader_size);
r = amdgpu_dispatch_load_cs_shader(ptr_shader, CS_BUFFERCLEAR);
CU_ASSERT_EQUAL(r, 0);
@@ -2220,6 +2229,11 @@ static void amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle,
ptr_cmd[i++] = 0x22222222;
ptr_cmd[i++] = 0x22222222;
+ /* clear mmCOMPUTE_RESOURCE_LIMITS */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
+ ptr_cmd[i++] = 0x215;
+ ptr_cmd[i++] = 0;
+
/* dispatch direct command */
ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3);
ptr_cmd[i++] = 0x10;
@@ -2321,6 +2335,7 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
&bo_shader, &ptr_shader,
&mc_address_shader, &va_shader);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader, 0, bo_shader_size);
r = amdgpu_dispatch_load_cs_shader(ptr_shader, CS_BUFFERCOPY );
CU_ASSERT_EQUAL(r, 0);
@@ -2365,6 +2380,11 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
ptr_cmd[i++] = 0x400;
ptr_cmd[i++] = 0x74fac;
+ /* clear mmCOMPUTE_RESOURCE_LIMITS */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
+ ptr_cmd[i++] = 0x215;
+ ptr_cmd[i++] = 0;
+
/* dispatch direct command */
ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3);
ptr_cmd[i++] = 0x10;
@@ -2430,7 +2450,8 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
r = amdgpu_cs_ctx_free(context_handle);
CU_ASSERT_EQUAL(r, 0);
}
-static void amdgpu_dispatch_test(void)
+
+static void amdgpu_compute_dispatch_test(void)
{
int r;
struct drm_amdgpu_info_hw_ip info;
@@ -2438,14 +2459,25 @@ static void amdgpu_dispatch_test(void)
r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_COMPUTE, 0, &info);
CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no compute ring\n");
for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id);
amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id);
}
+}
+
+static void amdgpu_gfx_dispatch_test(void)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t ring_id;
r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no graphics ring\n");
for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id);
@@ -2901,12 +2933,14 @@ static void amdgpu_memset_draw_test(amdgpu_device_handle device_handle,
&bo_shader_ps, &ptr_shader_ps,
&mc_address_shader_ps, &va_shader_ps);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_ps, 0, bo_shader_size);
r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096,
AMDGPU_GEM_DOMAIN_VRAM, 0,
&bo_shader_vs, &ptr_shader_vs,
&mc_address_shader_vs, &va_shader_vs);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_vs, 0, bo_shader_size);
r = amdgpu_draw_load_ps_shader(ptr_shader_ps, PS_CONST);
CU_ASSERT_EQUAL(r, 0);
@@ -2996,7 +3030,7 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle,
ptr_cmd[i++] = 0x92;
i += 3;
- ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
ptr_cmd[i++] = 0x191;
ptr_cmd[i++] = 0;
@@ -3074,12 +3108,14 @@ static void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t
&bo_shader_ps, &ptr_shader_ps,
&mc_address_shader_ps, &va_shader_ps);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_ps, 0, bo_shader_size);
r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096,
AMDGPU_GEM_DOMAIN_VRAM, 0,
&bo_shader_vs, &ptr_shader_vs,
&mc_address_shader_vs, &va_shader_vs);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_vs, 0, bo_shader_size);
r = amdgpu_draw_load_ps_shader(ptr_shader_ps, PS_TEX);
CU_ASSERT_EQUAL(r, 0);
@@ -3105,9 +3141,45 @@ static void amdgpu_draw_test(void)
r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no graphics ring\n");
for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
amdgpu_memset_draw_test(device_handle, ring_id);
amdgpu_memcpy_draw_test(device_handle, ring_id);
}
}
+
+static void amdgpu_gpu_reset_test(void)
+{
+ int r;
+ char debugfs_path[256], tmp[10];
+ int fd;
+ struct stat sbuf;
+ amdgpu_context_handle context_handle;
+ uint32_t hang_state, hangs;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = fstat(drm_amdgpu[0], &sbuf);
+ CU_ASSERT_EQUAL(r, 0);
+
+ sprintf(debugfs_path, "/sys/kernel/debug/dri/%d/amdgpu_gpu_recover", minor(sbuf.st_rdev));
+ fd = open(debugfs_path, O_RDONLY);
+ CU_ASSERT(fd >= 0);
+
+ r = read(fd, tmp, sizeof(tmp)/sizeof(char));
+ CU_ASSERT(r > 0);
+
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
+
+ close(fd);
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_compute_dispatch_test();
+ amdgpu_gfx_dispatch_test();
+}
diff --git a/lib/libdrm/tests/amdgpu/bo_tests.c b/lib/libdrm/tests/amdgpu/bo_tests.c
index 7cff4cf73..4c11665a7 100644
--- a/lib/libdrm/tests/amdgpu/bo_tests.c
+++ b/lib/libdrm/tests/amdgpu/bo_tests.c
@@ -267,7 +267,6 @@ static void amdgpu_memory_alloc(void)
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;
@@ -282,7 +281,7 @@ static void amdgpu_mem_fail_alloc(void)
CU_ASSERT_EQUAL(r, -ENOMEM);
if (!r) {
- r = amdgpu_bo_free(bo);
+ r = amdgpu_bo_free(buf_handle);
CU_ASSERT_EQUAL(r, 0);
}
}
diff --git a/lib/libdrm/tests/amdgpu/meson.build b/lib/libdrm/tests/amdgpu/meson.build
index 95ed93052..1726cb438 100644
--- a/lib/libdrm/tests/amdgpu/meson.build
+++ b/lib/libdrm/tests/amdgpu/meson.build
@@ -24,7 +24,7 @@ if dep_cunit.found()
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', 'ras_tests.c',
+ 'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c',
),
dependencies : [dep_cunit, dep_threads],
include_directories : [inc_root, inc_drm, include_directories('../../amdgpu')],
diff --git a/lib/libdrm/tests/amdgpu/ras_tests.c b/lib/libdrm/tests/amdgpu/ras_tests.c
index 81c34ad62..c1c543c12 100644
--- a/lib/libdrm/tests/amdgpu/ras_tests.c
+++ b/lib/libdrm/tests/amdgpu/ras_tests.c
@@ -31,6 +31,8 @@
#include <stdio.h>
#include "xf86drm.h"
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
const char *ras_block_string[] = {
"umc",
"sdma",
@@ -72,11 +74,251 @@ enum amdgpu_ras_block {
#define AMDGPU_RAS_BLOCK_COUNT AMDGPU_RAS_BLOCK__LAST
#define AMDGPU_RAS_BLOCK_MASK ((1ULL << AMDGPU_RAS_BLOCK_COUNT) - 1)
+enum amdgpu_ras_gfx_subblock {
+ /* CPC */
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_START = 0,
+ AMDGPU_RAS_BLOCK__GFX_CPC_SCRATCH =
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPC_UCODE,
+ AMDGPU_RAS_BLOCK__GFX_DC_STATE_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_CSINVOC_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_STATE_ME2,
+ AMDGPU_RAS_BLOCK__GFX_DC_CSINVOC_ME2,
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME2,
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME2,
+ /* CPF */
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPF_ROQ_ME2 =
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPF_ROQ_ME1,
+ AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_END = AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ /* CPG */
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPG_DMA_ROQ =
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPG_DMA_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_END = AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ /* GDS */
+ AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_GDS_MEM = AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_GDS_INPUT_QUEUE,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PHY_CMD_RAM_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PHY_DATA_RAM_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PIPE_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PIPE_MEM,
+ /* SPI */
+ AMDGPU_RAS_BLOCK__GFX_SPI_SR_MEM,
+ /* SQ */
+ AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQ_SGPR = AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQ_LDS_D,
+ AMDGPU_RAS_BLOCK__GFX_SQ_LDS_I,
+ AMDGPU_RAS_BLOCK__GFX_SQ_VGPR,
+ AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_END = AMDGPU_RAS_BLOCK__GFX_SQ_VGPR,
+ /* SQC (3 ranges) */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_START,
+ /* SQC range 0 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_UTCL1_LFIFO =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU0_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU0_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_UTCL1_LFIFO,
+ /* SQC range 1 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_TAG_RAM =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_UTCL1_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_TAG_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_HIT_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_DIRTY_BIT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_BANK_RAM,
+ /* SQC range 2 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_TAG_RAM =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_UTCL1_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_TAG_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_HIT_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_DIRTY_BIT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_END,
+ /* TA */
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_DFIFO =
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_AFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FL_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FX_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_CFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_END = AMDGPU_RAS_BLOCK__GFX_TA_FS_CFIFO,
+ /* TCA */
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCA_HOLE_FIFO =
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCA_REQ_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCA_REQ_FIFO,
+ /* TCC (5 sub-ranges) */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_START,
+ /* TCC range 0 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_0_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_0,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DIRTY_BANK_0,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DIRTY_BANK_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_HIGH_RATE_TAG,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LOW_RATE_TAG,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_LOW_RATE_TAG,
+ /* TCC range 1 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_DEC =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_TRANSFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_TRANSFER,
+ /* TCC range 2 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_RETURN_DATA =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_RETURN_CONTROL,
+ AMDGPU_RAS_BLOCK__GFX_TCC_UC_ATOMIC_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRITE_RETURN,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRITE_CACHE_READ,
+ AMDGPU_RAS_BLOCK__GFX_TCC_SRC_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_SRC_FIFO_NEXT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_TAG_PROBE_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_TAG_PROBE_FIFO,
+ /* TCC range 3 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO_NEXT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO_NEXT_RAM,
+ /* TCC range 4 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRRET_TAG_WRITE_RETURN =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_ATOMIC_RETURN_BUFFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_ATOMIC_RETURN_BUFFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_END,
+ /* TCI */
+ AMDGPU_RAS_BLOCK__GFX_TCI_WRITE_RAM,
+ /* TCP */
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCP_CACHE_RAM =
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCP_LFIFO_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCP_CMD_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCP_VM_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCP_DB_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO0,
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO1,
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO1,
+ /* TD */
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_LO =
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_HI,
+ AMDGPU_RAS_BLOCK__GFX_TD_CS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_END = AMDGPU_RAS_BLOCK__GFX_TD_CS_FIFO,
+ /* EA (3 sub-ranges) */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_START,
+ /* EA range 0 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_CMDMEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_RRET_TAGMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_WRET_TAGMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIRD_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_DATAMEM,
+ /* EA range 1 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_PAGEMEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IORD_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IOWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IOWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIRD_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_PAGEMEM,
+ /* EA range 2 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D0MEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D1MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D2MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D3MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D3MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_END,
+ /* UTC VM L2 bank */
+ AMDGPU_RAS_BLOCK__UTC_VML2_BANK_CACHE,
+ /* UTC VM walker */
+ AMDGPU_RAS_BLOCK__UTC_VML2_WALKER,
+ /* UTC ATC L2 2MB cache */
+ AMDGPU_RAS_BLOCK__UTC_ATCL2_CACHE_2M_BANK,
+ /* UTC ATC L2 4KB cache */
+ AMDGPU_RAS_BLOCK__UTC_ATCL2_CACHE_4K_BANK,
+ AMDGPU_RAS_BLOCK__GFX_MAX
+};
+
enum amdgpu_ras_error_type {
- AMDGPU_RAS_ERROR__NONE = 0,
- AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE = 2,
- AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE = 4,
- AMDGPU_RAS_ERROR__POISON = 8,
+ AMDGPU_RAS_ERROR__NONE = 0,
+ AMDGPU_RAS_ERROR__PARITY = 1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE = 2,
+ AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE = 4,
+ AMDGPU_RAS_ERROR__POISON = 8,
+};
+
+struct ras_inject_test_config {
+ char name[64];
+ char block[32];
+ int sub_block;
+ enum amdgpu_ras_error_type type;
+ uint64_t address;
+ uint64_t value;
};
struct ras_common_if {
@@ -100,8 +342,10 @@ struct ras_debug_if {
int op;
};
/* for now, only umc, gfx, sdma has implemented. */
-#define DEFAULT_RAS_BLOCK_MASK_INJECT (1 << AMDGPU_RAS_BLOCK__UMC)
-#define DEFAULT_RAS_BLOCK_MASK_QUERY (1 << AMDGPU_RAS_BLOCK__UMC)
+#define DEFAULT_RAS_BLOCK_MASK_INJECT ((1 << AMDGPU_RAS_BLOCK__UMC) |\
+ (1 << AMDGPU_RAS_BLOCK__GFX))
+#define DEFAULT_RAS_BLOCK_MASK_QUERY ((1 << AMDGPU_RAS_BLOCK__UMC) |\
+ (1 << AMDGPU_RAS_BLOCK__GFX))
#define DEFAULT_RAS_BLOCK_MASK_BASIC (1 << AMDGPU_RAS_BLOCK__UMC |\
(1 << AMDGPU_RAS_BLOCK__SDMA) |\
(1 << AMDGPU_RAS_BLOCK__GFX))
@@ -146,12 +390,78 @@ struct ras_DID_test_mask{
DEFAULT_RAS_BLOCK_MASK_BASIC\
}
+static const struct ras_inject_test_config umc_ras_inject_test[] = {
+ {"ras_umc.1.0", "umc", 0, AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+};
+
+static const struct ras_inject_test_config gfx_ras_inject_test[] = {
+ {"ras_gfx.2.0", "gfx", AMDGPU_RAS_BLOCK__GFX_CPC_UCODE,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.1", "gfx", AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.2", "gfx", AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.3", "gfx", AMDGPU_RAS_BLOCK__GFX_SQ_LDS_D,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.4", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_UTCL1_LFIFO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.5", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_TAG_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.6", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_TAG_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.7", "gfx", AMDGPU_RAS_BLOCK__GFX_TA_FS_DFIFO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.8", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.9", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_0_1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.10", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_0,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.11", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.12", "gfx", AMDGPU_RAS_BLOCK__GFX_TCP_CACHE_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.13", "gfx", AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_LO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.14", "gfx", AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_CMDMEM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+};
+
static const struct ras_DID_test_mask ras_DID_array[] = {
{0x66a1, 0x00, RAS_BLOCK_MASK_ALL},
{0x66a1, 0x01, RAS_BLOCK_MASK_ALL},
{0x66a1, 0x04, RAS_BLOCK_MASK_ALL},
};
+static uint32_t amdgpu_ras_find_block_id_by_name(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) {
+ if (strcmp(name, ras_block_string[i]) == 0)
+ return i;
+ }
+
+ return ARRAY_SIZE(ras_block_string);
+}
+
+static char *amdgpu_ras_get_error_type_id(enum amdgpu_ras_error_type type)
+{
+ switch (type) {
+ case AMDGPU_RAS_ERROR__PARITY:
+ return "parity";
+ case AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE:
+ return "single_correctable";
+ case AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE:
+ return "multi_uncorrectable";
+ case AMDGPU_RAS_ERROR__POISON:
+ return "poison";
+ case AMDGPU_RAS_ERROR__NONE:
+ default:
+ return NULL;
+ }
+}
+
static struct ras_test_mask amdgpu_ras_get_test_mask(drmDevicePtr device)
{
int i;
@@ -453,6 +763,34 @@ static int amdgpu_ras_query_err_count(enum amdgpu_ras_block block,
return 0;
}
+static int amdgpu_ras_inject(enum amdgpu_ras_block block,
+ uint32_t sub_block, enum amdgpu_ras_error_type type,
+ uint64_t address, uint64_t value)
+{
+ struct ras_debug_if data = { .op = 2, };
+ struct ras_inject_if *inject = &data.inject;
+ int ret;
+
+ if (amdgpu_ras_is_feature_enabled(block) <= 0) {
+ fprintf(stderr, "block id(%d) is not valid\n", block);
+ return -1;
+ }
+
+ inject->head.block = block;
+ inject->head.type = type;
+ inject->head.sub_block_index = sub_block;
+ strncpy(inject->head.name, ras_block_str(block), 32);
+ inject->address = address;
+ inject->value = value;
+
+ ret = amdgpu_ras_invoke(&data);
+ CU_ASSERT_EQUAL(ret, 0);
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
//tests
static void amdgpu_ras_features_test(int enable)
{
@@ -503,69 +841,83 @@ static void amdgpu_ras_enable_test(void)
}
}
-static void __amdgpu_ras_inject_test(void)
+static void __amdgpu_ras_ip_inject_test(const struct ras_inject_test_config *ip_test,
+ uint32_t size)
{
- struct ras_debug_if data;
- int ret;
- int i;
- unsigned long ue, ce, ue_old, ce_old;
+ int i, ret;
+ unsigned long old_ue, old_ce;
+ unsigned long ue, ce;
+ uint32_t block;
+ int timeout;
+ bool pass;
- data.op = 2;
- for (i = 0; i < AMDGPU_RAS_BLOCK__LAST; i++) {
- int timeout = 3;
- struct ras_inject_if inject = {
- .head = {
- .block = i,
- .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
- .sub_block_index = 0,
- .name = "",
- },
- .address = 0,
- .value = 0,
- };
+ for (i = 0; i < size; i++) {
+ timeout = 3;
+ pass = false;
- if (amdgpu_ras_is_feature_enabled(i) <= 0)
- continue;
+ block = amdgpu_ras_find_block_id_by_name(ip_test[i].block);
- if (!((1 << i) & ras_block_mask_inject))
- continue;
+ /* Ensure one valid ip block */
+ if (block == ARRAY_SIZE(ras_block_string))
+ break;
- data.inject = inject;
+ /* Ensure RAS feature for the IP block is enabled by kernel */
+ if (amdgpu_ras_is_feature_supported(block) <= 0)
+ break;
- ret = amdgpu_ras_query_err_count(i, &ue_old, &ce_old);
+ ret = amdgpu_ras_query_err_count(block, &old_ue, &old_ce);
CU_ASSERT_EQUAL(ret, 0);
-
if (ret)
- continue;
+ break;
- ret = amdgpu_ras_invoke(&data);
+ ret = amdgpu_ras_inject(block,
+ ip_test[i].sub_block,
+ ip_test[i].type,
+ ip_test[i].address,
+ ip_test[i].value);
CU_ASSERT_EQUAL(ret, 0);
-
if (ret)
- continue;
+ break;
-loop:
while (timeout > 0) {
- ret = amdgpu_ras_query_err_count(i, &ue, &ce);
- CU_ASSERT_EQUAL(ret, 0);
+ sleep(5);
+ ret = amdgpu_ras_query_err_count(block, &ue, &ce);
+ CU_ASSERT_EQUAL(ret, 0);
if (ret)
- continue;
- if (ue_old != ue) {
- /*recovery takes ~10s*/
- sleep(10);
break;
- }
- sleep(1);
+ if (old_ue != ue || old_ce != ce) {
+ pass = true;
+ sleep(20);
+ break;
+ }
timeout -= 1;
}
-
- CU_ASSERT_EQUAL(ue_old + 1, ue);
- CU_ASSERT_EQUAL(ce_old, ce);
+ printf("\t Test %s@block %s, subblock %d, error_type %s, address %ld, value %ld: %s\n",
+ ip_test[i].name,
+ ip_test[i].block,
+ ip_test[i].sub_block,
+ amdgpu_ras_get_error_type_id(ip_test[i].type),
+ ip_test[i].address,
+ ip_test[i].value,
+ pass ? "Pass" : "Fail");
}
}
+static void __amdgpu_ras_inject_test(void)
+{
+ printf("...\n");
+
+ /* run UMC ras inject test */
+ __amdgpu_ras_ip_inject_test(umc_ras_inject_test,
+ ARRAY_SIZE(umc_ras_inject_test));
+
+ /* run GFX ras inject test */
+ __amdgpu_ras_ip_inject_test(gfx_ras_inject_test,
+ ARRAY_SIZE(gfx_ras_inject_test));
+}
+
static void amdgpu_ras_inject_test(void)
{
int i;
diff --git a/lib/libdrm/tests/amdgpu/syncobj_tests.c b/lib/libdrm/tests/amdgpu/syncobj_tests.c
new file mode 100644
index 000000000..869ed88ea
--- /dev/null
+++ b/lib/libdrm/tests/amdgpu/syncobj_tests.c
@@ -0,0 +1,298 @@
+/*
+ * 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 "xf86drm.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include <pthread.h>
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static void amdgpu_syncobj_timeline_test(void);
+
+CU_BOOL suite_syncobj_timeline_tests_enable(void)
+{
+ int r;
+ uint64_t cap = 0;
+
+ r = drmGetCap(drm_amdgpu[0], DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+ if (r || cap == 0)
+ return CU_FALSE;
+
+ return CU_TRUE;
+}
+
+int suite_syncobj_timeline_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_syncobj_timeline_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo syncobj_timeline_tests[] = {
+ { "syncobj timeline test", amdgpu_syncobj_timeline_test },
+ CU_TEST_INFO_NULL,
+};
+
+#define GFX_COMPUTE_NOP 0xffff1000
+#define SDMA_NOP 0x0
+static int syncobj_command_submission_helper(uint32_t syncobj_handle, bool
+ wait_or_signal, uint64_t point)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct drm_amdgpu_cs_chunk chunks[2];
+ struct drm_amdgpu_cs_chunk_data chunk_data;
+ struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
+ struct amdgpu_cs_fence fence_status;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ uint32_t expired, flags;
+ int i, r;
+ uint64_t seq_no;
+ static uint32_t *ptr;
+
+ 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;
+
+ for (i = 0; i < 16; ++i)
+ ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP: SDMA_NOP;
+
+ chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
+ chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
+ chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
+ chunk_data.ib_data._pad = 0;
+ chunk_data.ib_data.va_start = ib_result_mc_address;
+ chunk_data.ib_data.ib_bytes = 16 * 4;
+ chunk_data.ib_data.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX :
+ AMDGPU_HW_IP_DMA;
+ chunk_data.ib_data.ip_instance = 0;
+ chunk_data.ib_data.ring = 0;
+ chunk_data.ib_data.flags = 0;
+
+ chunks[1].chunk_id = wait_or_signal ?
+ AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
+ AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
+ chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
+ chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
+ syncobj_data.handle = syncobj_handle;
+ syncobj_data.point = point;
+ syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+ r = amdgpu_cs_submit_raw(device_handle,
+ context_handle,
+ bo_list,
+ 2,
+ chunks,
+ &seq_no);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = wait_or_signal ? AMDGPU_HW_IP_GFX:
+ AMDGPU_HW_IP_DMA;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = 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);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return r;
+}
+
+struct syncobj_point {
+ uint32_t syncobj_handle;
+ uint64_t point;
+};
+
+static void *syncobj_wait(void *data)
+{
+ struct syncobj_point *sp = (struct syncobj_point *)data;
+ int r;
+
+ r = syncobj_command_submission_helper(sp->syncobj_handle, true,
+ sp->point);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return (void *)(long)r;
+}
+
+static void *syncobj_signal(void *data)
+{
+ struct syncobj_point *sp = (struct syncobj_point *)data;
+ int r;
+
+ r = syncobj_command_submission_helper(sp->syncobj_handle, false,
+ sp->point);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return (void *)(long)r;
+}
+
+static void amdgpu_syncobj_timeline_test(void)
+{
+ static pthread_t wait_thread;
+ static pthread_t signal_thread;
+ static pthread_t c_thread;
+ struct syncobj_point sp1, sp2, sp3;
+ uint32_t syncobj_handle;
+ uint64_t payload;
+ uint64_t wait_point, signal_point;
+ uint64_t timeout;
+ struct timespec tp;
+ int r, sync_fd;
+ void *tmp;
+
+ r = amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ // wait on point 5
+ sp1.syncobj_handle = syncobj_handle;
+ sp1.point = 5;
+ r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ // signal on point 10
+ sp2.syncobj_handle = syncobj_handle;
+ sp2.point = 10;
+ r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = pthread_join(wait_thread, &tmp);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(tmp, 0);
+
+ r = pthread_join(signal_thread, &tmp);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(tmp, 0);
+
+ //query timeline payload
+ r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+ &payload, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(payload, 10);
+
+ //signal on point 16
+ sp3.syncobj_handle = syncobj_handle;
+ sp3.point = 16;
+ r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
+ CU_ASSERT_EQUAL(r, 0);
+ //CPU wait on point 16
+ wait_point = 16;
+ timeout = 0;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+ timeout += 0x10000000000; //10s
+ r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
+ &wait_point, 1, timeout,
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+ NULL);
+
+ CU_ASSERT_EQUAL(r, 0);
+ r = pthread_join(c_thread, &tmp);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(tmp, 0);
+
+ // export point 16 and import to point 18
+ r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
+ 16,
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+ &sync_fd);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
+ 18, sync_fd);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+ &payload, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(payload, 18);
+
+ // CPU signal on point 20
+ signal_point = 20;
+ r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
+ &signal_point, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+ &payload, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(payload, 20);
+
+ r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+}
diff --git a/lib/libdrm/tests/amdgpu/vcn_tests.c b/lib/libdrm/tests/amdgpu/vcn_tests.c
index 859ec4969..ad438f35c 100644
--- a/lib/libdrm/tests/amdgpu/vcn_tests.c
+++ b/lib/libdrm/tests/amdgpu/vcn_tests.c
@@ -44,6 +44,14 @@ struct amdgpu_vcn_bo {
uint8_t *ptr;
};
+struct amdgpu_vcn_reg {
+ uint32_t data0;
+ uint32_t data1;
+ uint32_t cmd;
+ uint32_t nop;
+ uint32_t cntl;
+};
+
static amdgpu_device_handle device_handle;
static uint32_t major_version;
static uint32_t minor_version;
@@ -57,6 +65,7 @@ static uint32_t *ib_cpu;
static amdgpu_bo_handle resources[MAX_RESOURCES];
static unsigned num_resources;
+static struct amdgpu_vcn_reg reg;
static void amdgpu_cs_vcn_dec_create(void);
static void amdgpu_cs_vcn_dec_decode(void);
@@ -96,6 +105,21 @@ CU_BOOL suite_vcn_tests_enable(void)
return CU_FALSE;
}
+ if (family_id == AMDGPU_FAMILY_RV) {
+ reg.data0 = 0x81c4;
+ reg.data1 = 0x81c5;
+ reg.cmd = 0x81c3;
+ reg.nop = 0x81ff;
+ reg.cntl = 0x81c6;
+ } else if (family_id == AMDGPU_FAMILY_NV) {
+ reg.data0 = 0x504;
+ reg.data1 = 0x505;
+ reg.cmd = 0x503;
+ reg.nop = 0x53f;
+ reg.cntl = 0x506;
+ } else
+ return CU_FALSE;
+
return CU_TRUE;
}
@@ -237,11 +261,11 @@ static void free_resource(struct amdgpu_vcn_bo *vcn_bo)
static void vcn_dec_cmd(uint64_t addr, unsigned cmd, int *idx)
{
- ib_cpu[(*idx)++] = 0x81C4;
+ ib_cpu[(*idx)++] = reg.data0;
ib_cpu[(*idx)++] = addr;
- ib_cpu[(*idx)++] = 0x81C5;
+ ib_cpu[(*idx)++] = reg.data1;
ib_cpu[(*idx)++] = addr >> 32;
- ib_cpu[(*idx)++] = 0x81C3;
+ ib_cpu[(*idx)++] = reg.cmd;
ib_cpu[(*idx)++] = cmd << 1;
}
@@ -262,14 +286,14 @@ static void amdgpu_cs_vcn_dec_create(void)
memcpy(msg_buf.ptr, vcn_dec_create_msg, sizeof(vcn_dec_create_msg));
len = 0;
- ib_cpu[len++] = 0x81C4;
+ ib_cpu[len++] = reg.data0;
ib_cpu[len++] = msg_buf.addr;
- ib_cpu[len++] = 0x81C5;
+ ib_cpu[len++] = reg.data1;
ib_cpu[len++] = msg_buf.addr >> 32;
- ib_cpu[len++] = 0x81C3;
+ ib_cpu[len++] = reg.cmd;
ib_cpu[len++] = 0;
for (; len % 16; ) {
- ib_cpu[len++] = 0x81ff;
+ ib_cpu[len++] = reg.nop;
ib_cpu[len++] = 0;
}
@@ -336,10 +360,10 @@ static void amdgpu_cs_vcn_dec_decode(void)
vcn_dec_cmd(it_addr, 0x204, &len);
vcn_dec_cmd(ctx_addr, 0x206, &len);
- ib_cpu[len++] = 0x81C6;
+ ib_cpu[len++] = reg.cntl;
ib_cpu[len++] = 0x1;
for (; len % 16; ) {
- ib_cpu[len++] = 0x81ff;
+ ib_cpu[len++] = reg.nop;
ib_cpu[len++] = 0;
}
@@ -371,14 +395,14 @@ static void amdgpu_cs_vcn_dec_destroy(void)
memcpy(msg_buf.ptr, vcn_dec_destroy_msg, sizeof(vcn_dec_destroy_msg));
len = 0;
- ib_cpu[len++] = 0x81C4;
+ ib_cpu[len++] = reg.data0;
ib_cpu[len++] = msg_buf.addr;
- ib_cpu[len++] = 0x81C5;
+ ib_cpu[len++] = reg.data1;
ib_cpu[len++] = msg_buf.addr >> 32;
- ib_cpu[len++] = 0x81C3;
+ ib_cpu[len++] = reg.cmd;
ib_cpu[len++] = 0;
for (; len % 16; ) {
- ib_cpu[len++] = 0x81ff;
+ ib_cpu[len++] = reg.nop;
ib_cpu[len++] = 0;
}
diff --git a/lib/libdrm/tests/kms/libkms-test-plane.c b/lib/libdrm/tests/kms/libkms-test-plane.c
index 6c40a3c9e..4cb27378a 100644
--- a/lib/libdrm/tests/kms/libkms-test-plane.c
+++ b/lib/libdrm/tests/kms/libkms-test-plane.c
@@ -55,8 +55,10 @@ static int kms_plane_probe(struct kms_plane *plane)
}
plane->formats = calloc(p->count_formats, sizeof(uint32_t));
- if (!plane->formats)
+ if (!plane->formats) {
+ drmModeFreePlane(p);
return -ENOMEM;
+ }
for (i = 0; i < p->count_formats; i++)
plane->formats[i] = p->formats[i];
diff --git a/lib/libdrm/tests/modetest/buffers.c b/lib/libdrm/tests/modetest/buffers.c
index 9b635c0ce..8a8d9e014 100644
--- a/lib/libdrm/tests/modetest/buffers.c
+++ b/lib/libdrm/tests/modetest/buffers.c
@@ -135,6 +135,7 @@ bo_create(int fd, unsigned int format,
int ret;
switch (format) {
+ case DRM_FORMAT_C8:
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
@@ -193,6 +194,13 @@ bo_create(int fd, unsigned int format,
bpp = 32;
break;
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_ABGR16161616F:
+ bpp = 64;
+ break;
+
default:
fprintf(stderr, "unsupported format 0x%08x\n", format);
return NULL;
@@ -275,6 +283,7 @@ bo_create(int fd, unsigned int format,
planes[2] = virtual + offsets[2];
break;
+ case DRM_FORMAT_C8:
case DRM_FORMAT_ARGB4444:
case DRM_FORMAT_XRGB4444:
case DRM_FORMAT_ABGR4444:
@@ -311,6 +320,10 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_RGBX1010102:
case DRM_FORMAT_BGRA1010102:
case DRM_FORMAT_BGRX1010102:
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_ABGR16161616F:
offsets[0] = 0;
handles[0] = bo->handle;
pitches[0] = bo->pitch;
diff --git a/lib/libdrm/tests/modetest/modetest.c b/lib/libdrm/tests/modetest/modetest.c
index 9c85c07be..e66be6607 100644
--- a/lib/libdrm/tests/modetest/modetest.c
+++ b/lib/libdrm/tests/modetest/modetest.c
@@ -67,6 +67,9 @@
#include "buffers.h"
#include "cursor.h"
+static enum util_fill_pattern primary_fill = UTIL_PATTERN_SMPTE;
+static enum util_fill_pattern secondary_fill = UTIL_PATTERN_TILES;
+
struct crtc {
drmModeCrtc *crtc;
drmModeObjectProperties *props;
@@ -948,9 +951,10 @@ struct property_arg {
char name[DRM_PROP_NAME_LEN+1];
uint32_t prop_id;
uint64_t value;
+ bool optional;
};
-static void set_property(struct device *dev, struct property_arg *p)
+static bool set_property(struct device *dev, struct property_arg *p)
{
drmModeObjectProperties *props = NULL;
drmModePropertyRes **props_info = NULL;
@@ -982,13 +986,13 @@ static void set_property(struct device *dev, struct property_arg *p)
if (p->obj_type == 0) {
fprintf(stderr, "Object %i not found, can't set property\n",
p->obj_id);
- return;
+ return false;
}
if (!props) {
fprintf(stderr, "%s %i has no properties\n",
obj_type, p->obj_id);
- return;
+ return false;
}
for (i = 0; i < (int)props->count_props; ++i) {
@@ -999,9 +1003,10 @@ static void set_property(struct device *dev, struct property_arg *p)
}
if (i == (int)props->count_props) {
- fprintf(stderr, "%s %i has no %s property\n",
- obj_type, p->obj_id, p->name);
- return;
+ if (!p->optional)
+ fprintf(stderr, "%s %i has no %s property\n",
+ obj_type, p->obj_id, p->name);
+ return false;
}
p->prop_id = props->props[i];
@@ -1015,6 +1020,8 @@ static void set_property(struct device *dev, struct property_arg *p)
if (ret < 0)
fprintf(stderr, "failed to set %s %i property %s to %" PRIu64 ": %s\n",
obj_type, p->obj_id, p->name, p->value, strerror(errno));
+
+ return true;
}
/* -------------------------------------------------------------------------- */
@@ -1072,6 +1079,55 @@ static void add_property(struct device *dev, uint32_t obj_id,
set_property(dev, &p);
}
+static bool add_property_optional(struct device *dev, uint32_t obj_id,
+ const char *name, uint64_t value)
+{
+ struct property_arg p;
+
+ p.obj_id = obj_id;
+ strcpy(p.name, name);
+ p.value = value;
+ p.optional = true;
+
+ return set_property(dev, &p);
+}
+
+static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
+{
+ unsigned blob_id = 0;
+ /* TODO: support 1024-sized LUTs, when the use-case arises */
+ struct drm_color_lut gamma_lut[256];
+ int i, ret;
+
+ if (fourcc == DRM_FORMAT_C8) {
+ /* TODO: Add C8 support for more patterns */
+ util_smpte_c8_gamma(256, gamma_lut);
+ drmModeCreatePropertyBlob(dev->fd, gamma_lut, sizeof(gamma_lut), &blob_id);
+ } else {
+ for (i = 0; i < 256; i++) {
+ gamma_lut[i].red =
+ gamma_lut[i].green =
+ gamma_lut[i].blue = i << 8;
+ }
+ }
+
+ add_property_optional(dev, crtc_id, "DEGAMMA_LUT", 0);
+ add_property_optional(dev, crtc_id, "CTM", 0);
+ if (!add_property_optional(dev, crtc_id, "GAMMA_LUT", blob_id)) {
+ uint16_t r[256], g[256], b[256];
+
+ for (i = 0; i < 256; i++) {
+ r[i] = gamma_lut[i].red;
+ g[i] = gamma_lut[i].green;
+ b[i] = gamma_lut[i].blue;
+ }
+
+ ret = drmModeCrtcSetGamma(dev->fd, crtc_id, 256, r, g, b);
+ if (ret)
+ fprintf(stderr, "failed to set gamma: %s\n", strerror(errno));
+ }
+}
+
static int atomic_set_plane(struct device *dev, struct plane_arg *p,
int pattern, bool update)
{
@@ -1206,7 +1262,7 @@ static int set_plane(struct device *dev, struct plane_arg *p)
p->w, p->h, p->format_str, plane_id);
plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, handles,
- pitches, offsets, UTIL_PATTERN_TILES);
+ pitches, offsets, secondary_fill);
if (plane_bo == NULL)
return -1;
@@ -1247,12 +1303,14 @@ static int set_plane(struct device *dev, struct plane_arg *p)
static void atomic_set_planes(struct device *dev, struct plane_arg *p,
unsigned int count, bool update)
{
- unsigned int i, pattern = UTIL_PATTERN_SMPTE;
+ unsigned int i, pattern = primary_fill;
/* set up planes */
for (i = 0; i < count; i++) {
if (i > 0)
- pattern = UTIL_PATTERN_TILES;
+ pattern = secondary_fill;
+ else
+ set_gamma(dev, p[i].crtc_id, p[i].fourcc);
if (atomic_set_plane(dev, &p[i], pattern, update))
return;
@@ -1335,8 +1393,8 @@ static void atomic_set_mode(struct device *dev, struct pipe_arg *pipes, unsigned
if (pipe->mode == NULL)
continue;
- printf("setting mode %s-%dHz@%s on connectors ",
- pipe->mode_str, pipe->mode->vrefresh, pipe->format_str);
+ printf("setting mode %s-%dHz on connectors ",
+ pipe->mode_str, pipe->mode->vrefresh);
for (j = 0; j < pipe->num_cons; ++j) {
printf("%s, ", pipe->cons[j]);
add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc->crtc->crtc_id);
@@ -1395,7 +1453,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width,
dev->mode.height, handles, pitches, offsets,
- UTIL_PATTERN_SMPTE);
+ primary_fill);
if (bo == NULL)
return;
@@ -1437,6 +1495,8 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
return;
}
+
+ set_gamma(dev, pipe->crtc->crtc->crtc_id, pipe->fourcc);
}
}
@@ -1711,11 +1771,8 @@ static int parse_plane(struct plane_arg *plane, const char *p)
}
if (*end == '@') {
- p = end + 1;
- if (strlen(p) != 4)
- return -EINVAL;
-
- strcpy(plane->format_str, p);
+ strncpy(plane->format_str, end + 1, 4);
+ plane->format_str[4] = '\0';
} else {
strcpy(plane->format_str, "XR24");
}
@@ -1740,6 +1797,18 @@ static int parse_property(struct property_arg *p, const char *arg)
return 0;
}
+static void parse_fill_patterns(char *arg)
+{
+ char *fill = strtok(arg, ",");
+ if (!fill)
+ return;
+ primary_fill = util_pattern_enum(fill);
+ fill = strtok(NULL, ",");
+ if (!fill)
+ return;
+ secondary_fill = util_pattern_enum(fill);
+}
+
static void usage(char *name)
{
fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
@@ -1757,6 +1826,7 @@ static void usage(char *name)
fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
fprintf(stderr, "\t-a \tuse atomic API\n");
+ fprintf(stderr, "\t-F pattern1,pattern2\tspecify fill patterns\n");
fprintf(stderr, "\n Generic options:\n\n");
fprintf(stderr, "\t-d\tdrop master after mode set\n");
@@ -1820,7 +1890,7 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
return 0;
}
-static char optstr[] = "acdD:efM:P:ps:Cvw:";
+static char optstr[] = "acdD:efF:M:P:ps:Cvw:";
int main(int argc, char **argv)
{
@@ -1869,6 +1939,9 @@ int main(int argc, char **argv)
case 'f':
framebuffers = 1;
break;
+ case 'F':
+ parse_fill_patterns(optarg);
+ break;
case 'M':
module = optarg;
/* Preserve the default behaviour of dumping all information. */
diff --git a/lib/libdrm/tests/util/format.c b/lib/libdrm/tests/util/format.c
index 15ac5e1e2..1ca1b82ce 100644
--- a/lib/libdrm/tests/util/format.c
+++ b/lib/libdrm/tests/util/format.c
@@ -39,6 +39,8 @@
.yuv = { (order), (xsub), (ysub), (chroma_stride) }
static const struct util_format_info format_info[] = {
+ /* Indexed */
+ { DRM_FORMAT_C8, "C8" },
/* YUV packed */
{ DRM_FORMAT_UYVY, "UYVY", MAKE_YUV_INFO(YUV_YCbCr | YUV_CY, 2, 2, 2) },
{ DRM_FORMAT_VYUY, "VYUY", MAKE_YUV_INFO(YUV_YCrCb | YUV_CY, 2, 2, 2) },
@@ -91,6 +93,11 @@ static const struct util_format_info format_info[] = {
{ DRM_FORMAT_RGBX1010102, "RX30", MAKE_RGB_INFO(10, 22, 10, 12, 10, 2, 0, 0) },
{ DRM_FORMAT_BGRA1010102, "BA30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 2, 0) },
{ DRM_FORMAT_BGRX1010102, "BX30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 0, 0) },
+ { DRM_FORMAT_XRGB16161616F, "XR4H", MAKE_RGB_INFO(16, 32, 16, 16, 16, 0, 0, 0) },
+ { DRM_FORMAT_XBGR16161616F, "XB4H", MAKE_RGB_INFO(16, 0, 16, 16, 16, 32, 0, 0) },
+ { DRM_FORMAT_ARGB16161616F, "AR4H", MAKE_RGB_INFO(16, 32, 16, 16, 16, 0, 16, 48) },
+ { DRM_FORMAT_ABGR16161616F, "AB4H", MAKE_RGB_INFO(16, 0, 16, 16, 16, 32, 16, 48) },
+
};
uint32_t util_format_fourcc(const char *name)
diff --git a/lib/libdrm/tests/util/pattern.c b/lib/libdrm/tests/util/pattern.c
index 9fa0a417b..bf1797d40 100644
--- a/lib/libdrm/tests/util/pattern.c
+++ b/lib/libdrm/tests/util/pattern.c
@@ -35,6 +35,7 @@
#include <math.h>
#endif
+#include "common.h"
#include "format.h"
#include "pattern.h"
@@ -60,15 +61,101 @@ struct color_yuv {
.u = MAKE_YUV_601_U(r, g, b), \
.v = MAKE_YUV_601_V(r, g, b) }
+/* This function takes 8-bit color values */
+static inline uint32_t shiftcolor8(const struct util_color_component *comp,
+ uint32_t value)
+{
+ value &= 0xff;
+ /* Fill the low bits with the high bits. */
+ value = (value << 8) | value;
+ /* Shift down to remove unwanted low bits */
+ value = value >> (16 - comp->length);
+ /* Shift back up to where the value should be */
+ return value << comp->offset;
+}
+
+/* This function takes 10-bit color values */
+static inline uint32_t shiftcolor10(const struct util_color_component *comp,
+ uint32_t value)
+{
+ value &= 0x3ff;
+ /* Fill the low bits with the high bits. */
+ value = (value << 6) | (value >> 4);
+ /* Shift down to remove unwanted low bits */
+ value = value >> (16 - comp->length);
+ /* Shift back up to where the value should be */
+ return value << comp->offset;
+}
+
+/* This function takes 16-bit color values */
+static inline uint64_t shiftcolor16(const struct util_color_component *comp,
+ uint64_t value)
+{
+ value &= 0xffff;
+ /* Shift down to remove unwanted low bits */
+ value = value >> (16 - comp->length);
+ /* Shift back up to where the value should be */
+ return value << comp->offset;
+}
+
+#define MAKE_RGBA10(rgb, r, g, b, a) \
+ (shiftcolor10(&(rgb)->red, (r)) | \
+ shiftcolor10(&(rgb)->green, (g)) | \
+ shiftcolor10(&(rgb)->blue, (b)) | \
+ shiftcolor10(&(rgb)->alpha, (a)))
+
#define MAKE_RGBA(rgb, r, g, b, a) \
- ((((r) >> (8 - (rgb)->red.length)) << (rgb)->red.offset) | \
- (((g) >> (8 - (rgb)->green.length)) << (rgb)->green.offset) | \
- (((b) >> (8 - (rgb)->blue.length)) << (rgb)->blue.offset) | \
- (((a) >> (8 - (rgb)->alpha.length)) << (rgb)->alpha.offset))
+ (shiftcolor8(&(rgb)->red, (r)) | \
+ shiftcolor8(&(rgb)->green, (g)) | \
+ shiftcolor8(&(rgb)->blue, (b)) | \
+ shiftcolor8(&(rgb)->alpha, (a)))
#define MAKE_RGB24(rgb, r, g, b) \
{ .value = MAKE_RGBA(rgb, r, g, b, 0) }
+
+/**
+ * Takes a uint16_t, divides by 65536, converts the infinite-precision
+ * result to fp16 with round-to-zero.
+ *
+ * Copied from mesa:src/util/half_float.c
+ */
+static uint16_t uint16_div_64k_to_half(uint16_t v)
+{
+ /* Zero or subnormal. Set the mantissa to (v << 8) and return. */
+ if (v < 4)
+ return v << 8;
+
+ /* Count the leading 0s in the uint16_t */
+ int n = __builtin_clz(v) - 16;
+
+ /* Shift the mantissa up so bit 16 is the hidden 1 bit,
+ * mask it off, then shift back down to 10 bits
+ */
+ int m = ( ((uint32_t)v << (n + 1)) & 0xffff ) >> 6;
+
+ /* (0{n} 1 X{15-n}) * 2^-16
+ * = 1.X * 2^(15-n-16)
+ * = 1.X * 2^(14-n - 15)
+ * which is the FP16 form with e = 14 - n
+ */
+ int e = 14 - n;
+
+ return (e << 10) | m;
+}
+
+#define MAKE_RGBA8FP16(rgb, r, g, b, a) \
+ (shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 8)) | \
+ shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 8)) | \
+ shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 8)) | \
+ shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 8)))
+
+#define MAKE_RGBA10FP16(rgb, r, g, b, a) \
+ (shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 6)) | \
+ shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 6)) | \
+ shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 6)) | \
+ shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 6)))
+
static void fill_smpte_yuv_planar(const struct util_yuv_info *yuv,
unsigned char *y_mem, unsigned char *u_mem,
unsigned char *v_mem, unsigned int width,
@@ -457,6 +544,140 @@ static void fill_smpte_rgb32(const struct util_rgb_info *rgb, void *mem,
}
}
+static void fill_smpte_rgb16fp(const struct util_rgb_info *rgb, void *mem,
+ unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ const uint64_t colors_top[] = {
+ MAKE_RGBA8FP16(rgb, 192, 192, 192, 255),/* grey */
+ MAKE_RGBA8FP16(rgb, 192, 192, 0, 255), /* yellow */
+ MAKE_RGBA8FP16(rgb, 0, 192, 192, 255), /* cyan */
+ MAKE_RGBA8FP16(rgb, 0, 192, 0, 255), /* green */
+ MAKE_RGBA8FP16(rgb, 192, 0, 192, 255), /* magenta */
+ MAKE_RGBA8FP16(rgb, 192, 0, 0, 255), /* red */
+ MAKE_RGBA8FP16(rgb, 0, 0, 192, 255), /* blue */
+ };
+ const uint64_t colors_middle[] = {
+ MAKE_RGBA8FP16(rgb, 0, 0, 192, 127), /* blue */
+ MAKE_RGBA8FP16(rgb, 19, 19, 19, 127), /* black */
+ MAKE_RGBA8FP16(rgb, 192, 0, 192, 127), /* magenta */
+ MAKE_RGBA8FP16(rgb, 19, 19, 19, 127), /* black */
+ MAKE_RGBA8FP16(rgb, 0, 192, 192, 127), /* cyan */
+ MAKE_RGBA8FP16(rgb, 19, 19, 19, 127), /* black */
+ MAKE_RGBA8FP16(rgb, 192, 192, 192, 127),/* grey */
+ };
+ const uint64_t colors_bottom[] = {
+ MAKE_RGBA8FP16(rgb, 0, 33, 76, 255), /* in-phase */
+ MAKE_RGBA8FP16(rgb, 255, 255, 255, 255),/* super white */
+ MAKE_RGBA8FP16(rgb, 50, 0, 106, 255), /* quadrature */
+ MAKE_RGBA8FP16(rgb, 19, 19, 19, 255), /* black */
+ MAKE_RGBA8FP16(rgb, 9, 9, 9, 255), /* 3.5% */
+ MAKE_RGBA8FP16(rgb, 19, 19, 19, 255), /* 7.5% */
+ MAKE_RGBA8FP16(rgb, 29, 29, 29, 255), /* 11.5% */
+ MAKE_RGBA8FP16(rgb, 19, 19, 19, 255), /* black */
+ };
+ unsigned int x;
+ unsigned int y;
+
+ for (y = 0; y < height * 6 / 9; ++y) {
+ for (x = 0; x < width; ++x)
+ ((uint64_t *)mem)[x] = colors_top[x * 7 / width];
+ mem += stride;
+ }
+
+ for (; y < height * 7 / 9; ++y) {
+ for (x = 0; x < width; ++x)
+ ((uint64_t *)mem)[x] = colors_middle[x * 7 / width];
+ mem += stride;
+ }
+
+ for (; y < height; ++y) {
+ for (x = 0; x < width * 5 / 7; ++x)
+ ((uint64_t *)mem)[x] =
+ colors_bottom[x * 4 / (width * 5 / 7)];
+ for (; x < width * 6 / 7; ++x)
+ ((uint64_t *)mem)[x] =
+ colors_bottom[(x - width * 5 / 7) * 3
+ / (width / 7) + 4];
+ for (; x < width; ++x)
+ ((uint64_t *)mem)[x] = colors_bottom[7];
+ mem += stride;
+ }
+}
+
+static void fill_smpte_c8(void *mem, unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ unsigned int x;
+ unsigned int y;
+
+ for (y = 0; y < height * 6 / 9; ++y) {
+ for (x = 0; x < width; ++x)
+ ((uint8_t *)mem)[x] = x * 7 / width;
+ mem += stride;
+ }
+
+ for (; y < height * 7 / 9; ++y) {
+ for (x = 0; x < width; ++x)
+ ((uint8_t *)mem)[x] = 7 + (x * 7 / width);
+ mem += stride;
+ }
+
+ for (; y < height; ++y) {
+ for (x = 0; x < width * 5 / 7; ++x)
+ ((uint8_t *)mem)[x] =
+ 14 + (x * 4 / (width * 5 / 7));
+ for (; x < width * 6 / 7; ++x)
+ ((uint8_t *)mem)[x] =
+ 14 + ((x - width * 5 / 7) * 3
+ / (width / 7) + 4);
+ for (; x < width; ++x)
+ ((uint8_t *)mem)[x] = 14 + 7;
+ mem += stride;
+ }
+}
+
+void util_smpte_c8_gamma(unsigned size, struct drm_color_lut *lut)
+{
+ if (size < 7 + 7 + 8) {
+ printf("Error: gamma too small: %d < %d\n", size, 7 + 7 + 8);
+ return;
+ }
+ memset(lut, 0, size * sizeof(struct drm_color_lut));
+
+#define FILL_COLOR(idx, r, g, b) \
+ lut[idx].red = (r) << 8; \
+ lut[idx].green = (g) << 8; \
+ lut[idx].blue = (b) << 8
+
+ FILL_COLOR( 0, 192, 192, 192); /* grey */
+ FILL_COLOR( 1, 192, 192, 0 ); /* yellow */
+ FILL_COLOR( 2, 0, 192, 192); /* cyan */
+ FILL_COLOR( 3, 0, 192, 0 ); /* green */
+ FILL_COLOR( 4, 192, 0, 192); /* magenta */
+ FILL_COLOR( 5, 192, 0, 0 ); /* red */
+ FILL_COLOR( 6, 0, 0, 192); /* blue */
+
+ FILL_COLOR( 7, 0, 0, 192); /* blue */
+ FILL_COLOR( 8, 19, 19, 19 ); /* black */
+ FILL_COLOR( 9, 192, 0, 192); /* magenta */
+ FILL_COLOR(10, 19, 19, 19 ); /* black */
+ FILL_COLOR(11, 0, 192, 192); /* cyan */
+ FILL_COLOR(12, 19, 19, 19 ); /* black */
+ FILL_COLOR(13, 192, 192, 192); /* grey */
+
+ FILL_COLOR(14, 0, 33, 76); /* in-phase */
+ FILL_COLOR(15, 255, 255, 255); /* super white */
+ FILL_COLOR(16, 50, 0, 106); /* quadrature */
+ FILL_COLOR(17, 19, 19, 19); /* black */
+ FILL_COLOR(18, 9, 9, 9); /* 3.5% */
+ FILL_COLOR(19, 19, 19, 19); /* 7.5% */
+ FILL_COLOR(20, 29, 29, 29); /* 11.5% */
+ FILL_COLOR(21, 19, 19, 19); /* black */
+
+#undef FILL_COLOR
+}
+
static void fill_smpte(const struct util_format_info *info, void *planes[3],
unsigned int width, unsigned int height,
unsigned int stride)
@@ -464,6 +685,8 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3],
unsigned char *u, *v;
switch (info->format) {
+ case DRM_FORMAT_C8:
+ return fill_smpte_c8(planes[0], width, height, stride);
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_YUYV:
@@ -531,6 +754,13 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3],
case DRM_FORMAT_BGRX1010102:
return fill_smpte_rgb32(&info->rgb, planes[0],
width, height, stride);
+
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_ABGR16161616F:
+ return fill_smpte_rgb16fp(&info->rgb, planes[0],
+ width, height, stride);
}
}
@@ -559,6 +789,14 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height,
case DRM_FORMAT_BGR565:
cairo_format = CAIRO_FORMAT_RGB16_565;
break;
+#if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 12)
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_XBGR2101010:
+ cairo_format = CAIRO_FORMAT_RGB30;
+ break;
+#endif
default:
return;
}
@@ -742,6 +980,32 @@ static void fill_tiles_rgb32(const struct util_format_info *info, void *mem,
make_pwetty(mem_base, width, height, stride, info->format);
}
+static void fill_tiles_rgb16fp(const struct util_format_info *info, void *mem,
+ unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ const struct util_rgb_info *rgb = &info->rgb;
+ void *mem_base = mem;
+ unsigned int x, y;
+
+ /* TODO: Give this actual fp16 precision */
+ for (y = 0; y < height; ++y) {
+ for (x = 0; x < width; ++x) {
+ div_t d = div(x+y, width);
+ uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
+ + 0x000a1120 * (d.rem >> 6);
+ uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
+ uint64_t color =
+ MAKE_RGBA8FP16(rgb, (rgb32 >> 16) & 0xff,
+ (rgb32 >> 8) & 0xff, rgb32 & 0xff,
+ alpha);
+
+ ((uint64_t *)mem)[x] = color;
+ }
+ mem += stride;
+ }
+}
+
static void fill_tiles(const struct util_format_info *info, void *planes[3],
unsigned int width, unsigned int height,
unsigned int stride)
@@ -816,14 +1080,146 @@ static void fill_tiles(const struct util_format_info *info, void *planes[3],
case DRM_FORMAT_BGRX1010102:
return fill_tiles_rgb32(info, planes[0],
width, height, stride);
+
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_ABGR16161616F:
+ return fill_tiles_rgb16fp(info, planes[0],
+ width, height, stride);
}
}
-static void fill_plain(void *planes[3],
+static void fill_plain(const struct util_format_info *info, void *planes[3],
unsigned int height,
unsigned int stride)
{
- memset(planes[0], 0x77, stride * height);
+ switch (info->format) {
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_ABGR16161616F:
+ /* 0x3838 = 0.5273 */
+ memset(planes[0], 0x38, stride * height);
+ break;
+ default:
+ memset(planes[0], 0x77, stride * height);
+ break;
+ }
+}
+
+static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
+ void *mem,
+ unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ int i, j;
+
+ for (i = 0; i < height / 2; i++) {
+ uint32_t *row = mem;
+
+ for (j = 0; j < width / 2; j++) {
+ uint32_t value = MAKE_RGBA10(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
+ row[2*j] = row[2*j+1] = value;
+ }
+ mem += stride;
+ }
+
+ for (; i < height; i++) {
+ uint32_t *row = mem;
+
+ for (j = 0; j < width / 2; j++) {
+ uint32_t value = MAKE_RGBA10(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
+ row[2*j] = row[2*j+1] = value;
+ }
+ mem += stride;
+ }
+}
+
+static void fill_gradient_rgb16fp(const struct util_rgb_info *rgb,
+ void *mem,
+ unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ int i, j;
+
+ for (i = 0; i < height / 2; i++) {
+ uint64_t *row = mem;
+
+ for (j = 0; j < width / 2; j++) {
+ uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
+ row[2*j] = row[2*j+1] = value;
+ }
+ mem += stride;
+ }
+
+ for (; i < height; i++) {
+ uint64_t *row = mem;
+
+ for (j = 0; j < width / 2; j++) {
+ uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
+ row[2*j] = row[2*j+1] = value;
+ }
+ mem += stride;
+ }
+}
+
+/* The gradient pattern creates two horizontal gray gradients, split
+ * into two halves. The top half has 10bpc precision, the bottom half
+ * has 8bpc precision. When using with a 10bpc fb format, there are 3
+ * possible outcomes:
+ *
+ * - Pixel data is encoded as 8bpc to the display, no dithering. This
+ * would lead to the top and bottom halves looking identical.
+ *
+ * - Pixel data is encoded as 8bpc to the display, with dithering. This
+ * would lead to there being a visible difference between the two halves,
+ * but the top half would look a little speck-y due to the dithering.
+ *
+ * - Pixel data is encoded at 10bpc+ to the display (which implies
+ * the display is able to show this level of depth). This should
+ * lead to the top half being a very clean gradient, and visibly different
+ * from the bottom half.
+ *
+ * Once we support additional fb formats, this approach could be extended
+ * to distinguish even higher bpc precisions.
+ *
+ * Note that due to practical size considerations, for the screens
+ * where this matters, the pattern actually emits stripes 2-pixels
+ * wide for each gradient color. Otherwise the difference may be a bit
+ * hard to notice.
+ */
+static void fill_gradient(const struct util_format_info *info, void *planes[3],
+ unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ switch (info->format) {
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_BGRX8888:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_RGBA1010102:
+ case DRM_FORMAT_RGBX1010102:
+ case DRM_FORMAT_BGRA1010102:
+ case DRM_FORMAT_BGRX1010102:
+ return fill_gradient_rgb32(&info->rgb, planes[0],
+ width, height, stride);
+
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_ABGR16161616F:
+ return fill_gradient_rgb16fp(&info->rgb, planes[0],
+ width, height, stride);
+ }
}
/*
@@ -856,10 +1252,32 @@ void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
return fill_smpte(info, planes, width, height, stride);
case UTIL_PATTERN_PLAIN:
- return fill_plain(planes, height, stride);
+ return fill_plain(info, planes, height, stride);
+
+ case UTIL_PATTERN_GRADIENT:
+ return fill_gradient(info, planes, width, height, stride);
default:
printf("Error: unsupported test pattern %u.\n", pattern);
break;
}
}
+
+static const char *pattern_names[] = {
+ [UTIL_PATTERN_TILES] = "tiles",
+ [UTIL_PATTERN_SMPTE] = "smpte",
+ [UTIL_PATTERN_PLAIN] = "plain",
+ [UTIL_PATTERN_GRADIENT] = "gradient",
+};
+
+enum util_fill_pattern util_pattern_enum(const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(pattern_names); i++)
+ if (!strcmp(pattern_names[i], name))
+ return (enum util_fill_pattern)i;
+
+ printf("Error: unsupported test pattern %s.\n", name);
+ return UTIL_PATTERN_SMPTE;
+}
diff --git a/lib/libdrm/tests/util/pattern.h b/lib/libdrm/tests/util/pattern.h
index d5c4260cc..ea38cafdc 100644
--- a/lib/libdrm/tests/util/pattern.h
+++ b/lib/libdrm/tests/util/pattern.h
@@ -26,14 +26,21 @@
#ifndef UTIL_PATTERN_H
#define UTIL_PATTERN_H
+#include <drm_mode.h>
+
enum util_fill_pattern {
UTIL_PATTERN_TILES,
UTIL_PATTERN_PLAIN,
UTIL_PATTERN_SMPTE,
+ UTIL_PATTERN_GRADIENT,
};
void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
void *planes[3], unsigned int width,
unsigned int height, unsigned int stride);
+void util_smpte_c8_gamma(unsigned size, struct drm_color_lut *lut);
+
+enum util_fill_pattern util_pattern_enum(const char *name);
+
#endif /* UTIL_PATTERN_H */