Re: [PATCH i-g-t v3 05/10] tests/imagination: Add DEV_QUERY heap info tests

Kamil Konieczny <[email protected]>
Newsgroups org.freedesktop.lists.igt-dev
Message-ID <[email protected]>
Hi Robert,
On 2026-07-17 at 16:21:37 +0200, Robert Mazur wrote:
> 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]>

LGTM
Acked-by: Kamil Konieczny <[email protected]>

Regards,
Kamil

> ---
>  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 421cbc24c..a26b4edad 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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.