summaryrefslogtreecommitdiff
path: root/tests/v3d/v3d_perfmon.c
blob: 4d6ea465f48e89588e60e5c183a0c6529c05e2b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Igalia S.L.
 */

#include "igt.h"
#include "igt_v3d.h"

IGT_TEST_DESCRIPTION("Tests for the V3D's performance monitors");

igt_main
{
	int fd;

	igt_fixture {
		fd = drm_open_driver(DRIVER_V3D);
		igt_require(igt_v3d_get_param(fd, DRM_V3D_PARAM_SUPPORTS_PERFMON));
	}

	igt_describe("Make sure a perfmon cannot be created with zero counters.");
	igt_subtest("create-perfmon-0") {
		struct drm_v3d_perfmon_create create = {
			.ncounters = 0,
		};
		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_CREATE, &create, EINVAL);
	}

	igt_describe("Make sure a perfmon cannot be created with more counters than the maximum allowed.");
	igt_subtest("create-perfmon-exceed") {
		struct drm_v3d_perfmon_create create = {
			.ncounters = DRM_V3D_MAX_PERF_COUNTERS + 1,
		};
		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_CREATE, &create, EINVAL);
	}

	igt_describe("Make sure a perfmon cannot be created with invalid counters identifiers.");
	igt_subtest("create-perfmon-invalid-counters") {
		struct drm_v3d_perfmon_create create = {
			.ncounters = 1,
			.counters = { V3D_PERFCNT_NUM },
		};
		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_CREATE, &create, EINVAL);
	}

	igt_describe("Make sure a perfmon with 1 counter can be created.");
	igt_subtest("create-single-perfmon") {
		uint8_t counters[] = { V3D_PERFCNT_FEP_VALID_PRIMTS_NO_PIXELS };
		uint32_t id = igt_v3d_perfmon_create(fd, 1, counters);

		igt_v3d_perfmon_destroy(fd, id);
	}

	igt_describe("Make sure that two perfmons can be created simultaneously.");
	igt_subtest("create-two-perfmon") {
		uint8_t counters_perfmon1[] = { V3D_PERFCNT_AXI_WRITE_STALLS_WATCH_0 };
		uint8_t counters_perfmon2[] = { V3D_PERFCNT_L2T_TMUCFG_READS, V3D_PERFCNT_CORE_MEM_WRITES };

		/* Create two different performance monitors */
		uint32_t id1 = igt_v3d_perfmon_create(fd, 1, counters_perfmon1);
		uint32_t id2 = igt_v3d_perfmon_create(fd, 2, counters_perfmon2);

		/* Make sure that the id's of the performance monitors are different */
		igt_assert_neq(id1, id2);

		igt_v3d_perfmon_destroy(fd, id1);

		/* Make sure that the second perfmon it is still acessible */
		igt_v3d_perfmon_get_values(fd, id2);

		igt_v3d_perfmon_destroy(fd, id2);
	}

	igt_describe("Make sure that getting the values from perfmon fails for non-zero pad.");
	igt_subtest("get-values-invalid-pad") {
		struct drm_v3d_perfmon_get_values get = {
			.pad = 1,
		};
		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_GET_VALUES, &get, EINVAL);
	}

	igt_describe("Make sure that getting the values from perfmon fails for invalid identifier.");
	igt_subtest("get-values-invalid-perfmon") {
		struct drm_v3d_perfmon_get_values get = {
			.id = 1,
		};
		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_GET_VALUES, &get, EINVAL);
	}

	igt_describe("Make sure that getting the values from perfmon fails for invalid memory pointer.");
	igt_subtest("get-values-invalid-pointer") {
		uint8_t counters[] = { V3D_PERFCNT_TLB_QUADS_STENCIL_FAIL,
				       V3D_PERFCNT_PTB_PRIM_VIEWPOINT_DISCARD,
				       V3D_PERFCNT_QPU_UC_HIT };
		uint32_t id = igt_v3d_perfmon_create(fd, 3, counters);

		struct drm_v3d_perfmon_get_values get = {
			.id = id,
			.values_ptr = 0ULL
		};

		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_GET_VALUES, &get, EFAULT);

		igt_v3d_perfmon_destroy(fd, id);
	}

	igt_describe("Sanity check for getting the values from a valid perfmon.");
	igt_subtest("get-values-valid-perfmon") {
		uint8_t counters[] = { V3D_PERFCNT_COMPUTE_ACTIVE,
				       V3D_PERFCNT_PTB_MEM_READS,
				       V3D_PERFCNT_CLE_ACTIVE };
		uint32_t id = igt_v3d_perfmon_create(fd, 3, counters);

		igt_v3d_perfmon_get_values(fd, id);
		igt_v3d_perfmon_destroy(fd, id);
	}

	igt_describe("Make sure that destroying a non-existent perfmon fails.");
	igt_subtest("destroy-invalid-perfmon") {
		struct drm_v3d_perfmon_destroy destroy = {
			.id = 1,
		};
		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_DESTROY, &destroy, EINVAL);
	}

	igt_describe("Make sure that a perfmon is not accessible after being destroyed.");
	igt_subtest("destroy-valid-perfmon") {
		uint8_t counters[] = { V3D_PERFCNT_AXI_WRITE_STALLS_WATCH_1,
				       V3D_PERFCNT_TMU_CONFIG_ACCESSES,
				       V3D_PERFCNT_TLB_PARTIAL_QUADS,
				       V3D_PERFCNT_L2T_SLC0_READS };
		uint32_t id = igt_v3d_perfmon_create(fd, 4, counters);
		struct drm_v3d_perfmon_get_values get = {
			.id = id,
		};

		igt_v3d_perfmon_get_values(fd, id);

		igt_v3d_perfmon_destroy(fd, id);

		/* Make sure that the id is no longer allocate */
		do_ioctl_err(fd, DRM_IOCTL_V3D_PERFMON_GET_VALUES, &get, EINVAL);
	}

	igt_fixture
		drm_close_driver(fd);
}