[PATCH i-g-t v5 05/10] tests/imagination: Add DEV_QUERY heap info tests
Robert Mazur <[email protected]> Tue, 28 Jul 2026 09:19:00 +0200
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <20260728-test-imagination-add-support-v5-5-33049f0d1937@imgtec.com> |
From: Sarah Walker <[email protected]> Add subtests for DRM_IOCTL_PVR_DEV_QUERY heap info queries. Signed-off-by: Sarah Walker <[email protected]> Signed-off-by: Robert Mazur <[email protected]> Acked-by: Kamil Konieczny <[email protected]> --- lib/igt_pvr.c | 31 +++++++++ lib/igt_pvr.h | 2 + tests/imagination/meson.build | 1 + tests/imagination/pvr_heap_info.c | 130 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+) diff --git a/lib/igt_pvr.c b/lib/igt_pvr.c index 2e6c4ade3..40a68d4e6 100644 --- a/lib/igt_pvr.c +++ b/lib/igt_pvr.c @@ -104,3 +104,34 @@ igt_pvr_ioctl_dev_query(int fd, enum drm_pvr_dev_query type, uint64_t size, return args; } +/** + * igt_pvr_get_heap_info: + * @fd: The file descriptor of the DRM device. + * @array_len_out: Pointer to store the number of heaps. + * + * Function to get information about the device heaps. + * + * Returns: An array of drm_pvr_heap structures. The caller is responsible + * for freeing the array. + */ +struct drm_pvr_heap * +igt_pvr_get_heap_info(int fd, uint32_t *array_len_out) +{ + struct drm_pvr_heap *heaps = + calloc(DRM_PVR_HEAP_COUNT, sizeof(*heaps)); + struct drm_pvr_dev_query_heap_info heap_info_get = { + .heaps = DRM_PVR_OBJ_ARRAY(DRM_PVR_HEAP_COUNT, heaps), + }; + + if (!heaps) + return NULL; + + igt_pvr_ioctl_dev_query(fd, DRM_PVR_DEV_QUERY_HEAP_INFO_GET, + sizeof(heap_info_get), &heap_info_get, 0); + + if (array_len_out) + *array_len_out = heap_info_get.heaps.count; + + return heaps; +} + diff --git a/lib/igt_pvr.h b/lib/igt_pvr.h index b25fb1867..ca09f39e1 100644 --- a/lib/igt_pvr.h +++ b/lib/igt_pvr.h @@ -16,5 +16,7 @@ off_t igt_pvr_ioctl_get_bo_mmap_offset(int fd, uint32_t handle); struct drm_pvr_ioctl_dev_query_args igt_pvr_ioctl_dev_query(int fd, enum drm_pvr_dev_query type, uint64_t size, void *pointer, int expect_err); +struct drm_pvr_heap * +igt_pvr_get_heap_info(int fd, uint32_t *array_len_out); #endif /* IGT_PVR_H */ diff --git a/tests/imagination/meson.build b/tests/imagination/meson.build index c5899972b..fc24d0220 100644 --- a/tests/imagination/meson.build +++ b/tests/imagination/meson.build @@ -1,6 +1,7 @@ pvr_progs = [ 'pvr_dev_query', 'pvr_gem', 'pvr_gpu_info', + 'pvr_heap_info', ] pvr_deps = test_deps diff --git a/tests/imagination/pvr_heap_info.c b/tests/imagination/pvr_heap_info.c new file mode 100644 index 000000000..7d953044e --- /dev/null +++ b/tests/imagination/pvr_heap_info.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0 or MIT +/* Copyright (c) 2026 Imagination Technologies Ltd. All Rights Reserved */ + +#include <errno.h> +#include <stdbool.h> +#include <stdint.h> + +#include "igt.h" +#include "igt_pvr.h" + +#include "pvr_drm.h" + +enum pvr_page_size { + PVR_PAGE_SIZE_4K = 12, + PVR_PAGE_SIZE_16K = 14, + PVR_PAGE_SIZE_64K = 16, + PVR_PAGE_SIZE_256K = 18, + PVR_PAGE_SIZE_1M = 20, + PVR_PAGE_SIZE_2M = 21 +}; + +int igt_main() +{ + int fd; + + igt_fixture() + { + fd = drm_open_driver(DRIVER_POWERVR); + } + + igt_describe("Test getting the size of an array from the kernel"); + igt_subtest("heap-info-get-size") + { + /* Check we can get the size of the array kernel side. */ + struct drm_pvr_dev_query_heap_info heap_info_get = {0}; + + igt_pvr_ioctl_dev_query(fd, DRM_PVR_DEV_QUERY_HEAP_INFO_GET, + sizeof(heap_info_get), &heap_info_get, 0); + igt_assert_neq(heap_info_get.heaps.count, 0); + igt_assert_neq(heap_info_get.heaps.stride, 0); + } + + igt_describe("Test copying a single heap info from the kernel"); + igt_subtest("heap-info-copy-single") + { + struct drm_pvr_heap *heaps = + calloc(DRM_PVR_HEAP_COUNT, sizeof(*heaps)); + + /* Try copying a single heap. */ + struct drm_pvr_dev_query_heap_info heap_info_get = { + .heaps = DRM_PVR_OBJ_ARRAY(1, heaps), + }; + + igt_pvr_ioctl_dev_query(fd, DRM_PVR_DEV_QUERY_HEAP_INFO_GET, + sizeof(heap_info_get), &heap_info_get, 0); + + /* Kernel should stop copying after a single heap. */ + igt_assert_eq(heap_info_get.heaps.count, 1); + igt_assert_eq(heaps[1].size, 0); + + /* Kernel should respect the user side array stride. */ + igt_assert_eq(heap_info_get.heaps.stride, sizeof(*heaps)); + } + + igt_describe("Test copying all heaps info from the kernel"); + igt_subtest("heap-info-copy-all") + { + struct drm_pvr_dev_query_heap_info heap_info_get = {0}; + struct drm_pvr_heap *heaps = + calloc(DRM_PVR_HEAP_COUNT, sizeof(*heaps)); + uint32_t kernel_array_size = 0; + + igt_pvr_ioctl_dev_query(fd, DRM_PVR_DEV_QUERY_HEAP_INFO_GET, + sizeof(heap_info_get), &heap_info_get, 0); + + kernel_array_size = heap_info_get.heaps.count; + + heap_info_get.heaps = + (struct drm_pvr_obj_array)DRM_PVR_OBJ_ARRAY(DRM_PVR_HEAP_COUNT, + heaps); + + igt_pvr_ioctl_dev_query(fd, DRM_PVR_DEV_QUERY_HEAP_INFO_GET, + sizeof(heap_info_get), &heap_info_get, 0); + + igt_assert(heap_info_get.heaps.count == DRM_PVR_HEAP_COUNT || + heap_info_get.heaps.count == kernel_array_size); + + /* Kernel should respect the user side array stride. */ + igt_assert_eq(heap_info_get.heaps.stride, sizeof(*heaps)); + } + + igt_describe("Test validity of all heaps"); + igt_subtest("heap-info-heaps-valid") + { + uint32_t heaps_count = 0; + struct drm_pvr_heap *heaps = + igt_pvr_get_heap_info(fd, &heaps_count); + + igt_assert(heaps); + + for (int heap_id = 0; heap_id < heaps_count; heap_id++) { + const uint64_t page_mask = + (1ull << heaps[heap_id].page_size_log2) - 1; + + /* This heap isn't present for all devices. */ + if (heap_id == (int)DRM_PVR_HEAP_RGNHDR) + continue; + + igt_assert(heaps[heap_id].page_size_log2 == PVR_PAGE_SIZE_4K || + heaps[heap_id].page_size_log2 == PVR_PAGE_SIZE_16K || + heaps[heap_id].page_size_log2 == PVR_PAGE_SIZE_64K || + heaps[heap_id].page_size_log2 == PVR_PAGE_SIZE_256K || + heaps[heap_id].page_size_log2 == PVR_PAGE_SIZE_1M || + heaps[heap_id].page_size_log2 == PVR_PAGE_SIZE_2M); + + igt_assert_neq_u64(heaps[heap_id].size, 0); + igt_assert(!(heaps[heap_id].size & page_mask)); + igt_assert(!(heaps[heap_id].base & page_mask)); + + igt_assert(heaps[heap_id].flags == 0); + } + + free(heaps); + } + + igt_fixture() + { + drm_close_driver(fd); + } +} -- 2.43.0