xref: /aosp_15_r20/external/igt-gpu-tools/lib/igt_vc4.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2016 Broadcom
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  */
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker #include <assert.h>
25*d83cc019SAndroid Build Coastguard Worker #include <string.h>
26*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
27*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
28*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
29*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
30*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
32*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
33*d83cc019SAndroid Build Coastguard Worker 
34*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
35*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
36*d83cc019SAndroid Build Coastguard Worker #include "igt_core.h"
37*d83cc019SAndroid Build Coastguard Worker #include "igt_fb.h"
38*d83cc019SAndroid Build Coastguard Worker #include "igt_vc4.h"
39*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
40*d83cc019SAndroid Build Coastguard Worker #include "intel_reg.h"
41*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
42*d83cc019SAndroid Build Coastguard Worker #include "vc4_drm.h"
43*d83cc019SAndroid Build Coastguard Worker #include "vc4_packet.h"
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker #if NEW_CONTEXT_PARAM_NO_ERROR_CAPTURE_API
46*d83cc019SAndroid Build Coastguard Worker #define LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
47*d83cc019SAndroid Build Coastguard Worker #endif
48*d83cc019SAndroid Build Coastguard Worker 
49*d83cc019SAndroid Build Coastguard Worker /**
50*d83cc019SAndroid Build Coastguard Worker  * SECTION:igt_vc4
51*d83cc019SAndroid Build Coastguard Worker  * @short_description: VC4 support library
52*d83cc019SAndroid Build Coastguard Worker  * @title: VC4
53*d83cc019SAndroid Build Coastguard Worker  * @include: igt.h
54*d83cc019SAndroid Build Coastguard Worker  *
55*d83cc019SAndroid Build Coastguard Worker  * This library provides various auxiliary helper functions for writing VC4
56*d83cc019SAndroid Build Coastguard Worker  * tests.
57*d83cc019SAndroid Build Coastguard Worker  */
58*d83cc019SAndroid Build Coastguard Worker 
igt_vc4_is_tiled(uint64_t modifier)59*d83cc019SAndroid Build Coastguard Worker bool igt_vc4_is_tiled(uint64_t modifier)
60*d83cc019SAndroid Build Coastguard Worker {
61*d83cc019SAndroid Build Coastguard Worker 	if (modifier >> 56ULL != DRM_FORMAT_MOD_VENDOR_BROADCOM)
62*d83cc019SAndroid Build Coastguard Worker 		return false;
63*d83cc019SAndroid Build Coastguard Worker 
64*d83cc019SAndroid Build Coastguard Worker 	switch (fourcc_mod_broadcom_mod(modifier)) {
65*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND32:
66*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND64:
67*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND128:
68*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND256:
69*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
70*d83cc019SAndroid Build Coastguard Worker 		return true;
71*d83cc019SAndroid Build Coastguard Worker 	default:
72*d83cc019SAndroid Build Coastguard Worker 		return false;
73*d83cc019SAndroid Build Coastguard Worker 	}
74*d83cc019SAndroid Build Coastguard Worker }
75*d83cc019SAndroid Build Coastguard Worker 
76*d83cc019SAndroid Build Coastguard Worker /**
77*d83cc019SAndroid Build Coastguard Worker  * igt_vc4_get_cleared_bo:
78*d83cc019SAndroid Build Coastguard Worker  * @fd: device file descriptor
79*d83cc019SAndroid Build Coastguard Worker  * @size: size of the BO in bytes
80*d83cc019SAndroid Build Coastguard Worker  * @clearval: u32 value that the buffer should be completely cleared with
81*d83cc019SAndroid Build Coastguard Worker  *
82*d83cc019SAndroid Build Coastguard Worker  * This helper returns a new BO with the given size, which has just been
83*d83cc019SAndroid Build Coastguard Worker  * cleared using the render engine.
84*d83cc019SAndroid Build Coastguard Worker  */
igt_vc4_get_cleared_bo(int fd,size_t size,uint32_t clearval)85*d83cc019SAndroid Build Coastguard Worker uint32_t igt_vc4_get_cleared_bo(int fd, size_t size, uint32_t clearval)
86*d83cc019SAndroid Build Coastguard Worker {
87*d83cc019SAndroid Build Coastguard Worker 	/* A single row will be a page. */
88*d83cc019SAndroid Build Coastguard Worker 	uint32_t width = 1024;
89*d83cc019SAndroid Build Coastguard Worker 	uint32_t height = size / (width * 4);
90*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = igt_vc4_create_bo(fd, size);
91*d83cc019SAndroid Build Coastguard Worker 	struct drm_vc4_submit_cl submit = {
92*d83cc019SAndroid Build Coastguard Worker 		.color_write = {
93*d83cc019SAndroid Build Coastguard Worker 			.hindex = 0,
94*d83cc019SAndroid Build Coastguard Worker 			.bits = VC4_SET_FIELD(VC4_RENDER_CONFIG_FORMAT_RGBA8888,
95*d83cc019SAndroid Build Coastguard Worker 					      VC4_RENDER_CONFIG_FORMAT),
96*d83cc019SAndroid Build Coastguard Worker 		},
97*d83cc019SAndroid Build Coastguard Worker 
98*d83cc019SAndroid Build Coastguard Worker 		.color_read = { .hindex = ~0 },
99*d83cc019SAndroid Build Coastguard Worker 		.zs_read = { .hindex = ~0 },
100*d83cc019SAndroid Build Coastguard Worker 		.zs_write = { .hindex = ~0 },
101*d83cc019SAndroid Build Coastguard Worker 		.msaa_color_write = { .hindex = ~0 },
102*d83cc019SAndroid Build Coastguard Worker 		.msaa_zs_write = { .hindex = ~0 },
103*d83cc019SAndroid Build Coastguard Worker 
104*d83cc019SAndroid Build Coastguard Worker 		.bo_handles = to_user_pointer(&handle),
105*d83cc019SAndroid Build Coastguard Worker 		.bo_handle_count = 1,
106*d83cc019SAndroid Build Coastguard Worker 		.width = width,
107*d83cc019SAndroid Build Coastguard Worker 		.height = height,
108*d83cc019SAndroid Build Coastguard Worker 		.max_x_tile = ALIGN(width, 64) / 64 - 1,
109*d83cc019SAndroid Build Coastguard Worker 		.max_y_tile = ALIGN(height, 64) / 64 - 1,
110*d83cc019SAndroid Build Coastguard Worker 		.clear_color = { clearval, clearval },
111*d83cc019SAndroid Build Coastguard Worker 		.flags = VC4_SUBMIT_CL_USE_CLEAR_COLOR,
112*d83cc019SAndroid Build Coastguard Worker 	};
113*d83cc019SAndroid Build Coastguard Worker 
114*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32(width * height * 4, size);
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
117*d83cc019SAndroid Build Coastguard Worker 
118*d83cc019SAndroid Build Coastguard Worker 	return handle;
119*d83cc019SAndroid Build Coastguard Worker }
120*d83cc019SAndroid Build Coastguard Worker 
121*d83cc019SAndroid Build Coastguard Worker int
igt_vc4_create_bo(int fd,size_t size)122*d83cc019SAndroid Build Coastguard Worker igt_vc4_create_bo(int fd, size_t size)
123*d83cc019SAndroid Build Coastguard Worker {
124*d83cc019SAndroid Build Coastguard Worker 	struct drm_vc4_create_bo create = {
125*d83cc019SAndroid Build Coastguard Worker 		.size = size,
126*d83cc019SAndroid Build Coastguard Worker 	};
127*d83cc019SAndroid Build Coastguard Worker 
128*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_VC4_CREATE_BO, &create);
129*d83cc019SAndroid Build Coastguard Worker 
130*d83cc019SAndroid Build Coastguard Worker 	return create.handle;
131*d83cc019SAndroid Build Coastguard Worker }
132*d83cc019SAndroid Build Coastguard Worker 
133*d83cc019SAndroid Build Coastguard Worker void *
igt_vc4_mmap_bo(int fd,uint32_t handle,uint32_t size,unsigned prot)134*d83cc019SAndroid Build Coastguard Worker igt_vc4_mmap_bo(int fd, uint32_t handle, uint32_t size, unsigned prot)
135*d83cc019SAndroid Build Coastguard Worker {
136*d83cc019SAndroid Build Coastguard Worker 	struct drm_vc4_mmap_bo mmap_bo = {
137*d83cc019SAndroid Build Coastguard Worker 		.handle = handle,
138*d83cc019SAndroid Build Coastguard Worker 	};
139*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_VC4_MMAP_BO, &mmap_bo);
142*d83cc019SAndroid Build Coastguard Worker 
143*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap(0, size, prot, MAP_SHARED, fd, mmap_bo.offset);
144*d83cc019SAndroid Build Coastguard Worker 	if (ptr == MAP_FAILED)
145*d83cc019SAndroid Build Coastguard Worker 		return NULL;
146*d83cc019SAndroid Build Coastguard Worker 	else
147*d83cc019SAndroid Build Coastguard Worker 		return ptr;
148*d83cc019SAndroid Build Coastguard Worker }
149*d83cc019SAndroid Build Coastguard Worker 
igt_vc4_set_tiling(int fd,uint32_t handle,uint64_t modifier)150*d83cc019SAndroid Build Coastguard Worker void igt_vc4_set_tiling(int fd, uint32_t handle, uint64_t modifier)
151*d83cc019SAndroid Build Coastguard Worker {
152*d83cc019SAndroid Build Coastguard Worker 	struct drm_vc4_set_tiling set = {
153*d83cc019SAndroid Build Coastguard Worker 		.handle = handle,
154*d83cc019SAndroid Build Coastguard Worker 		.modifier = modifier,
155*d83cc019SAndroid Build Coastguard Worker 	};
156*d83cc019SAndroid Build Coastguard Worker 
157*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_VC4_SET_TILING, &set);
158*d83cc019SAndroid Build Coastguard Worker }
159*d83cc019SAndroid Build Coastguard Worker 
igt_vc4_get_tiling(int fd,uint32_t handle)160*d83cc019SAndroid Build Coastguard Worker uint64_t igt_vc4_get_tiling(int fd, uint32_t handle)
161*d83cc019SAndroid Build Coastguard Worker {
162*d83cc019SAndroid Build Coastguard Worker 	struct drm_vc4_get_tiling get = {
163*d83cc019SAndroid Build Coastguard Worker 		.handle = handle,
164*d83cc019SAndroid Build Coastguard Worker 	};
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_VC4_GET_TILING, &get);
167*d83cc019SAndroid Build Coastguard Worker 
168*d83cc019SAndroid Build Coastguard Worker 	return get.modifier;
169*d83cc019SAndroid Build Coastguard Worker }
170*d83cc019SAndroid Build Coastguard Worker 
igt_vc4_get_param(int fd,uint32_t param,uint64_t * val)171*d83cc019SAndroid Build Coastguard Worker int igt_vc4_get_param(int fd, uint32_t param, uint64_t *val)
172*d83cc019SAndroid Build Coastguard Worker {
173*d83cc019SAndroid Build Coastguard Worker 	struct drm_vc4_get_param arg = {
174*d83cc019SAndroid Build Coastguard Worker 		.param = param,
175*d83cc019SAndroid Build Coastguard Worker 	};
176*d83cc019SAndroid Build Coastguard Worker 	int ret;
177*d83cc019SAndroid Build Coastguard Worker 
178*d83cc019SAndroid Build Coastguard Worker 	ret = igt_ioctl(fd, DRM_IOCTL_VC4_GET_PARAM, &arg);
179*d83cc019SAndroid Build Coastguard Worker 	if (ret)
180*d83cc019SAndroid Build Coastguard Worker 		return ret;
181*d83cc019SAndroid Build Coastguard Worker 
182*d83cc019SAndroid Build Coastguard Worker 	*val = arg.value;
183*d83cc019SAndroid Build Coastguard Worker 	return 0;
184*d83cc019SAndroid Build Coastguard Worker }
185*d83cc019SAndroid Build Coastguard Worker 
igt_vc4_purgeable_bo(int fd,int handle,bool purgeable)186*d83cc019SAndroid Build Coastguard Worker bool igt_vc4_purgeable_bo(int fd, int handle, bool purgeable)
187*d83cc019SAndroid Build Coastguard Worker {
188*d83cc019SAndroid Build Coastguard Worker 	struct drm_vc4_gem_madvise arg = {
189*d83cc019SAndroid Build Coastguard Worker 		.handle = handle,
190*d83cc019SAndroid Build Coastguard Worker 		.madv = purgeable ? VC4_MADV_DONTNEED : VC4_MADV_WILLNEED,
191*d83cc019SAndroid Build Coastguard Worker 	};
192*d83cc019SAndroid Build Coastguard Worker 
193*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_VC4_GEM_MADVISE, &arg);
194*d83cc019SAndroid Build Coastguard Worker 
195*d83cc019SAndroid Build Coastguard Worker 	return arg.retained;
196*d83cc019SAndroid Build Coastguard Worker }
197*d83cc019SAndroid Build Coastguard Worker 
198*d83cc019SAndroid Build Coastguard Worker 
199*d83cc019SAndroid Build Coastguard Worker /* Calculate the t-tile width so that size = width * height * bpp / 8. */
200*d83cc019SAndroid Build Coastguard Worker #define VC4_T_TILE_W(size, height, bpp) ((size) / (height) / ((bpp) / 8))
201*d83cc019SAndroid Build Coastguard Worker 
igt_vc4_t_tiled_offset(size_t stride,size_t height,size_t bpp,size_t x,size_t y)202*d83cc019SAndroid Build Coastguard Worker static size_t igt_vc4_t_tiled_offset(size_t stride, size_t height, size_t bpp,
203*d83cc019SAndroid Build Coastguard Worker 				     size_t x, size_t y)
204*d83cc019SAndroid Build Coastguard Worker {
205*d83cc019SAndroid Build Coastguard Worker 	const size_t t1k_map_even[] = { 0, 3, 1, 2 };
206*d83cc019SAndroid Build Coastguard Worker 	const size_t t1k_map_odd[] = { 2, 1, 3, 0 };
207*d83cc019SAndroid Build Coastguard Worker 	const size_t t4k_t_h = 32;
208*d83cc019SAndroid Build Coastguard Worker 	const size_t t1k_t_h = 16;
209*d83cc019SAndroid Build Coastguard Worker 	const size_t t64_t_h = 4;
210*d83cc019SAndroid Build Coastguard Worker 	size_t offset = 0;
211*d83cc019SAndroid Build Coastguard Worker 	size_t t4k_t_w, t4k_w, t4k_x, t4k_y;
212*d83cc019SAndroid Build Coastguard Worker 	size_t t1k_t_w, t1k_x, t1k_y;
213*d83cc019SAndroid Build Coastguard Worker 	size_t t64_t_w, t64_x, t64_y;
214*d83cc019SAndroid Build Coastguard Worker 	size_t pix_x, pix_y;
215*d83cc019SAndroid Build Coastguard Worker 	unsigned int index;
216*d83cc019SAndroid Build Coastguard Worker 
217*d83cc019SAndroid Build Coastguard Worker 	/* T-tiling is only supported for 16 and 32 bpp. */
218*d83cc019SAndroid Build Coastguard Worker 	igt_assert(bpp == 16 || bpp == 32);
219*d83cc019SAndroid Build Coastguard Worker 
220*d83cc019SAndroid Build Coastguard Worker 	/* T-tiling stride must be aligned to the 4K tiles strides. */
221*d83cc019SAndroid Build Coastguard Worker 	igt_assert((stride % (4096 / t4k_t_h)) == 0);
222*d83cc019SAndroid Build Coastguard Worker 
223*d83cc019SAndroid Build Coastguard Worker 	/* Calculate the tile width for the bpp. */
224*d83cc019SAndroid Build Coastguard Worker 	t4k_t_w = VC4_T_TILE_W(4096, t4k_t_h, bpp);
225*d83cc019SAndroid Build Coastguard Worker 	t1k_t_w = VC4_T_TILE_W(1024, t1k_t_h, bpp);
226*d83cc019SAndroid Build Coastguard Worker 	t64_t_w = VC4_T_TILE_W(64, t64_t_h, bpp);
227*d83cc019SAndroid Build Coastguard Worker 
228*d83cc019SAndroid Build Coastguard Worker 	/* Aligned total width in number of 4K tiles. */
229*d83cc019SAndroid Build Coastguard Worker 	t4k_w = (stride / (bpp / 8)) / t4k_t_w;
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker 	/* X and y coordinates in number of 4K tiles. */
232*d83cc019SAndroid Build Coastguard Worker 	t4k_x = x / t4k_t_w;
233*d83cc019SAndroid Build Coastguard Worker 	t4k_y = y / t4k_t_h;
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 	/* Increase offset to the beginning of the 4K tile row. */
236*d83cc019SAndroid Build Coastguard Worker 	offset += t4k_y * t4k_w * 4096;
237*d83cc019SAndroid Build Coastguard Worker 
238*d83cc019SAndroid Build Coastguard Worker 	/* X and Y coordinates in number of 1K tiles within the 4K tile. */
239*d83cc019SAndroid Build Coastguard Worker 	t1k_x = (x % t4k_t_w) / t1k_t_w;
240*d83cc019SAndroid Build Coastguard Worker 	t1k_y = (y % t4k_t_h) / t1k_t_h;
241*d83cc019SAndroid Build Coastguard Worker 
242*d83cc019SAndroid Build Coastguard Worker 	/* Index for 1K tile map lookup. */
243*d83cc019SAndroid Build Coastguard Worker 	index = 2 * t1k_y + t1k_x;
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	/* Odd rows start from the right, even rows from the left. */
246*d83cc019SAndroid Build Coastguard Worker 	if (t4k_y % 2) {
247*d83cc019SAndroid Build Coastguard Worker 		/* Increase offset to the 4K tile (starting from the right). */
248*d83cc019SAndroid Build Coastguard Worker 		offset += (t4k_w - t4k_x - 1) * 4096;
249*d83cc019SAndroid Build Coastguard Worker 
250*d83cc019SAndroid Build Coastguard Worker 		/* Incrase offset to the beginning of the (odd) 1K tile. */
251*d83cc019SAndroid Build Coastguard Worker 		offset += t1k_map_odd[index] * 1024;
252*d83cc019SAndroid Build Coastguard Worker 	} else {
253*d83cc019SAndroid Build Coastguard Worker 		/* Increase offset to the 4K tile (starting from the left). */
254*d83cc019SAndroid Build Coastguard Worker 		offset += t4k_x * 4096;
255*d83cc019SAndroid Build Coastguard Worker 
256*d83cc019SAndroid Build Coastguard Worker 		/* Incrase offset to the beginning of the (even) 1K tile. */
257*d83cc019SAndroid Build Coastguard Worker 		offset += t1k_map_even[index] * 1024;
258*d83cc019SAndroid Build Coastguard Worker 	}
259*d83cc019SAndroid Build Coastguard Worker 
260*d83cc019SAndroid Build Coastguard Worker 	/* X and Y coordinates in number of 64 byte tiles within the 1K tile. */
261*d83cc019SAndroid Build Coastguard Worker 	t64_x = (x % t1k_t_w) / t64_t_w;
262*d83cc019SAndroid Build Coastguard Worker 	t64_y = (y % t1k_t_h) / t64_t_h;
263*d83cc019SAndroid Build Coastguard Worker 
264*d83cc019SAndroid Build Coastguard Worker 	/* Increase offset to the beginning of the 64-byte tile. */
265*d83cc019SAndroid Build Coastguard Worker 	offset += (t64_y * (t1k_t_w / t64_t_w) + t64_x) * 64;
266*d83cc019SAndroid Build Coastguard Worker 
267*d83cc019SAndroid Build Coastguard Worker 	/* X and Y coordinates in number of pixels within the 64-byte tile. */
268*d83cc019SAndroid Build Coastguard Worker 	pix_x = x % t64_t_w;
269*d83cc019SAndroid Build Coastguard Worker 	pix_y = y % t64_t_h;
270*d83cc019SAndroid Build Coastguard Worker 
271*d83cc019SAndroid Build Coastguard Worker 	/* Increase offset to the correct pixel. */
272*d83cc019SAndroid Build Coastguard Worker 	offset += (pix_y * t64_t_w + pix_x) * bpp / 8;
273*d83cc019SAndroid Build Coastguard Worker 
274*d83cc019SAndroid Build Coastguard Worker 	return offset;
275*d83cc019SAndroid Build Coastguard Worker }
276*d83cc019SAndroid Build Coastguard Worker 
vc4_fb_convert_plane_to_t_tiled(struct igt_fb * dst,void * dst_buf,struct igt_fb * src,void * src_buf,unsigned int plane)277*d83cc019SAndroid Build Coastguard Worker static void vc4_fb_convert_plane_to_t_tiled(struct igt_fb *dst, void *dst_buf,
278*d83cc019SAndroid Build Coastguard Worker 					    struct igt_fb *src, void *src_buf,
279*d83cc019SAndroid Build Coastguard Worker 					    unsigned int plane)
280*d83cc019SAndroid Build Coastguard Worker {
281*d83cc019SAndroid Build Coastguard Worker 	size_t bpp = src->plane_bpp[plane];
282*d83cc019SAndroid Build Coastguard Worker 	unsigned int i, j;
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < src->height; i++) {
285*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < src->width; j++) {
286*d83cc019SAndroid Build Coastguard Worker 			size_t src_offset = src->offsets[plane];
287*d83cc019SAndroid Build Coastguard Worker 			size_t dst_offset = dst->offsets[plane];
288*d83cc019SAndroid Build Coastguard Worker 
289*d83cc019SAndroid Build Coastguard Worker 			src_offset += src->strides[plane] * i + j * bpp / 8;
290*d83cc019SAndroid Build Coastguard Worker 			dst_offset += igt_vc4_t_tiled_offset(dst->strides[plane],
291*d83cc019SAndroid Build Coastguard Worker 							     dst->height,
292*d83cc019SAndroid Build Coastguard Worker 							     bpp, j, i);
293*d83cc019SAndroid Build Coastguard Worker 
294*d83cc019SAndroid Build Coastguard Worker 			switch (bpp) {
295*d83cc019SAndroid Build Coastguard Worker 			case 16:
296*d83cc019SAndroid Build Coastguard Worker 				*(uint16_t *)(dst_buf + dst_offset) =
297*d83cc019SAndroid Build Coastguard Worker 					*(uint16_t *)(src_buf + src_offset);
298*d83cc019SAndroid Build Coastguard Worker 				break;
299*d83cc019SAndroid Build Coastguard Worker 			case 32:
300*d83cc019SAndroid Build Coastguard Worker 				*(uint32_t *)(dst_buf + dst_offset) =
301*d83cc019SAndroid Build Coastguard Worker 					*(uint32_t *)(src_buf + src_offset);
302*d83cc019SAndroid Build Coastguard Worker 				break;
303*d83cc019SAndroid Build Coastguard Worker 			}
304*d83cc019SAndroid Build Coastguard Worker 		}
305*d83cc019SAndroid Build Coastguard Worker 	}
306*d83cc019SAndroid Build Coastguard Worker }
307*d83cc019SAndroid Build Coastguard Worker 
vc4_fb_convert_plane_from_t_tiled(struct igt_fb * dst,void * dst_buf,struct igt_fb * src,void * src_buf,unsigned int plane)308*d83cc019SAndroid Build Coastguard Worker static void vc4_fb_convert_plane_from_t_tiled(struct igt_fb *dst, void *dst_buf,
309*d83cc019SAndroid Build Coastguard Worker 					      struct igt_fb *src, void *src_buf,
310*d83cc019SAndroid Build Coastguard Worker 					      unsigned int plane)
311*d83cc019SAndroid Build Coastguard Worker {
312*d83cc019SAndroid Build Coastguard Worker 	size_t bpp = src->plane_bpp[plane];
313*d83cc019SAndroid Build Coastguard Worker 	unsigned int i, j;
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < src->height; i++) {
316*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < src->width; j++) {
317*d83cc019SAndroid Build Coastguard Worker 			size_t src_offset = src->offsets[plane];
318*d83cc019SAndroid Build Coastguard Worker 			size_t dst_offset = dst->offsets[plane];
319*d83cc019SAndroid Build Coastguard Worker 
320*d83cc019SAndroid Build Coastguard Worker 			src_offset += igt_vc4_t_tiled_offset(src->strides[plane],
321*d83cc019SAndroid Build Coastguard Worker 							     src->height,
322*d83cc019SAndroid Build Coastguard Worker 							     bpp, j, i);
323*d83cc019SAndroid Build Coastguard Worker 			src_offset += dst->strides[plane] * i + j * bpp / 8;
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 			switch (bpp) {
326*d83cc019SAndroid Build Coastguard Worker 			case 16:
327*d83cc019SAndroid Build Coastguard Worker 				*(uint16_t *)(dst_buf + dst_offset) =
328*d83cc019SAndroid Build Coastguard Worker 					*(uint16_t *)(src_buf + src_offset);
329*d83cc019SAndroid Build Coastguard Worker 				break;
330*d83cc019SAndroid Build Coastguard Worker 			case 32:
331*d83cc019SAndroid Build Coastguard Worker 				*(uint32_t *)(dst_buf + dst_offset) =
332*d83cc019SAndroid Build Coastguard Worker 					*(uint32_t *)(src_buf + src_offset);
333*d83cc019SAndroid Build Coastguard Worker 				break;
334*d83cc019SAndroid Build Coastguard Worker 			}
335*d83cc019SAndroid Build Coastguard Worker 		}
336*d83cc019SAndroid Build Coastguard Worker 	}
337*d83cc019SAndroid Build Coastguard Worker }
338*d83cc019SAndroid Build Coastguard Worker 
vc4_sand_tiled_offset(size_t column_width,size_t column_size,size_t x,size_t y,size_t bpp)339*d83cc019SAndroid Build Coastguard Worker static size_t vc4_sand_tiled_offset(size_t column_width, size_t column_size, size_t x,
340*d83cc019SAndroid Build Coastguard Worker 				    size_t y, size_t bpp)
341*d83cc019SAndroid Build Coastguard Worker {
342*d83cc019SAndroid Build Coastguard Worker 	size_t offset = 0;
343*d83cc019SAndroid Build Coastguard Worker 	size_t cols_x;
344*d83cc019SAndroid Build Coastguard Worker 	size_t pix_x;
345*d83cc019SAndroid Build Coastguard Worker 
346*d83cc019SAndroid Build Coastguard Worker 	/* Offset to the beginning of the relevant column. */
347*d83cc019SAndroid Build Coastguard Worker 	cols_x = x / column_width;
348*d83cc019SAndroid Build Coastguard Worker 	offset += cols_x * column_size;
349*d83cc019SAndroid Build Coastguard Worker 
350*d83cc019SAndroid Build Coastguard Worker 	/* Offset to the relevant pixel. */
351*d83cc019SAndroid Build Coastguard Worker 	pix_x = x % column_width;
352*d83cc019SAndroid Build Coastguard Worker 	offset += (column_width * y + pix_x) * bpp / 8;
353*d83cc019SAndroid Build Coastguard Worker 
354*d83cc019SAndroid Build Coastguard Worker 	return offset;
355*d83cc019SAndroid Build Coastguard Worker }
356*d83cc019SAndroid Build Coastguard Worker 
vc4_fb_convert_plane_to_sand_tiled(struct igt_fb * dst,void * dst_buf,struct igt_fb * src,void * src_buf,unsigned int plane)357*d83cc019SAndroid Build Coastguard Worker static void vc4_fb_convert_plane_to_sand_tiled(struct igt_fb *dst, void *dst_buf,
358*d83cc019SAndroid Build Coastguard Worker 					       struct igt_fb *src, void *src_buf,
359*d83cc019SAndroid Build Coastguard Worker 					       unsigned int plane)
360*d83cc019SAndroid Build Coastguard Worker {
361*d83cc019SAndroid Build Coastguard Worker 	uint64_t modifier_base = fourcc_mod_broadcom_mod(dst->modifier);
362*d83cc019SAndroid Build Coastguard Worker 	uint32_t column_height = fourcc_mod_broadcom_param(dst->modifier);
363*d83cc019SAndroid Build Coastguard Worker 	uint32_t column_width_bytes, column_width, column_size;
364*d83cc019SAndroid Build Coastguard Worker 	size_t bpp = dst->plane_bpp[plane];
365*d83cc019SAndroid Build Coastguard Worker 	unsigned int i, j;
366*d83cc019SAndroid Build Coastguard Worker 
367*d83cc019SAndroid Build Coastguard Worker 	switch (modifier_base) {
368*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND32:
369*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 32;
370*d83cc019SAndroid Build Coastguard Worker 		break;
371*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND64:
372*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 64;
373*d83cc019SAndroid Build Coastguard Worker 		break;
374*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND128:
375*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 128;
376*d83cc019SAndroid Build Coastguard Worker 		break;
377*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND256:
378*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 256;
379*d83cc019SAndroid Build Coastguard Worker 		break;
380*d83cc019SAndroid Build Coastguard Worker 	default:
381*d83cc019SAndroid Build Coastguard Worker 		igt_assert(false);
382*d83cc019SAndroid Build Coastguard Worker 	}
383*d83cc019SAndroid Build Coastguard Worker 
384*d83cc019SAndroid Build Coastguard Worker 	column_width = column_width_bytes * dst->plane_width[plane] / dst->width;
385*d83cc019SAndroid Build Coastguard Worker 	column_size = column_width_bytes * column_height;
386*d83cc019SAndroid Build Coastguard Worker 
387*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < dst->plane_height[plane]; i++) {
388*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < src->plane_width[plane]; j++) {
389*d83cc019SAndroid Build Coastguard Worker 			size_t src_offset = src->offsets[plane];
390*d83cc019SAndroid Build Coastguard Worker 			size_t dst_offset = dst->offsets[plane];
391*d83cc019SAndroid Build Coastguard Worker 
392*d83cc019SAndroid Build Coastguard Worker 			src_offset += src->strides[plane] * i + j * bpp / 8;
393*d83cc019SAndroid Build Coastguard Worker 			dst_offset += vc4_sand_tiled_offset(column_width,
394*d83cc019SAndroid Build Coastguard Worker 							    column_size, j, i,
395*d83cc019SAndroid Build Coastguard Worker 							    bpp);
396*d83cc019SAndroid Build Coastguard Worker 
397*d83cc019SAndroid Build Coastguard Worker 			switch (bpp) {
398*d83cc019SAndroid Build Coastguard Worker 			case 8:
399*d83cc019SAndroid Build Coastguard Worker 				*(uint8_t *)(dst_buf + dst_offset) =
400*d83cc019SAndroid Build Coastguard Worker 					*(uint8_t *)(src_buf + src_offset);
401*d83cc019SAndroid Build Coastguard Worker 				break;
402*d83cc019SAndroid Build Coastguard Worker 			case 16:
403*d83cc019SAndroid Build Coastguard Worker 				*(uint16_t *)(dst_buf + dst_offset) =
404*d83cc019SAndroid Build Coastguard Worker 					*(uint16_t *)(src_buf + src_offset);
405*d83cc019SAndroid Build Coastguard Worker 				break;
406*d83cc019SAndroid Build Coastguard Worker 			default:
407*d83cc019SAndroid Build Coastguard Worker 				igt_assert(false);
408*d83cc019SAndroid Build Coastguard Worker 			}
409*d83cc019SAndroid Build Coastguard Worker 		}
410*d83cc019SAndroid Build Coastguard Worker 	}
411*d83cc019SAndroid Build Coastguard Worker }
412*d83cc019SAndroid Build Coastguard Worker 
vc4_fb_convert_plane_from_sand_tiled(struct igt_fb * dst,void * dst_buf,struct igt_fb * src,void * src_buf,unsigned int plane)413*d83cc019SAndroid Build Coastguard Worker static void vc4_fb_convert_plane_from_sand_tiled(struct igt_fb *dst, void *dst_buf,
414*d83cc019SAndroid Build Coastguard Worker 						 struct igt_fb *src, void *src_buf,
415*d83cc019SAndroid Build Coastguard Worker 						 unsigned int plane)
416*d83cc019SAndroid Build Coastguard Worker {
417*d83cc019SAndroid Build Coastguard Worker 	uint64_t modifier_base = fourcc_mod_broadcom_mod(src->modifier);
418*d83cc019SAndroid Build Coastguard Worker 	uint32_t column_height = fourcc_mod_broadcom_param(src->modifier);
419*d83cc019SAndroid Build Coastguard Worker 	uint32_t column_width_bytes, column_width, column_size;
420*d83cc019SAndroid Build Coastguard Worker 	size_t bpp = src->plane_bpp[plane];
421*d83cc019SAndroid Build Coastguard Worker 	unsigned int i, j;
422*d83cc019SAndroid Build Coastguard Worker 
423*d83cc019SAndroid Build Coastguard Worker 	switch (modifier_base) {
424*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND32:
425*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 32;
426*d83cc019SAndroid Build Coastguard Worker 		break;
427*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND64:
428*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 64;
429*d83cc019SAndroid Build Coastguard Worker 		break;
430*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND128:
431*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 128;
432*d83cc019SAndroid Build Coastguard Worker 		break;
433*d83cc019SAndroid Build Coastguard Worker 	case DRM_FORMAT_MOD_BROADCOM_SAND256:
434*d83cc019SAndroid Build Coastguard Worker 		column_width_bytes = 256;
435*d83cc019SAndroid Build Coastguard Worker 		break;
436*d83cc019SAndroid Build Coastguard Worker 	default:
437*d83cc019SAndroid Build Coastguard Worker 		igt_assert(false);
438*d83cc019SAndroid Build Coastguard Worker 	}
439*d83cc019SAndroid Build Coastguard Worker 
440*d83cc019SAndroid Build Coastguard Worker 	column_width = column_width_bytes * src->plane_width[plane] / src->width;
441*d83cc019SAndroid Build Coastguard Worker 	column_size = column_width_bytes * column_height;
442*d83cc019SAndroid Build Coastguard Worker 
443*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < dst->plane_height[plane]; i++) {
444*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < src->plane_width[plane]; j++) {
445*d83cc019SAndroid Build Coastguard Worker 			size_t src_offset = src->offsets[plane];
446*d83cc019SAndroid Build Coastguard Worker 			size_t dst_offset = dst->offsets[plane];
447*d83cc019SAndroid Build Coastguard Worker 
448*d83cc019SAndroid Build Coastguard Worker 			src_offset += vc4_sand_tiled_offset(column_width,
449*d83cc019SAndroid Build Coastguard Worker 							    column_size, j, i,
450*d83cc019SAndroid Build Coastguard Worker 							    bpp);
451*d83cc019SAndroid Build Coastguard Worker 			dst_offset += dst->strides[plane] * i + j * bpp / 8;
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 			switch (bpp) {
454*d83cc019SAndroid Build Coastguard Worker 			case 8:
455*d83cc019SAndroid Build Coastguard Worker 				*(uint8_t *)(dst_buf + dst_offset) =
456*d83cc019SAndroid Build Coastguard Worker 					*(uint8_t *)(src_buf + src_offset);
457*d83cc019SAndroid Build Coastguard Worker 				break;
458*d83cc019SAndroid Build Coastguard Worker 			case 16:
459*d83cc019SAndroid Build Coastguard Worker 				*(uint16_t *)(dst_buf + dst_offset) =
460*d83cc019SAndroid Build Coastguard Worker 					*(uint16_t *)(src_buf + src_offset);
461*d83cc019SAndroid Build Coastguard Worker 				break;
462*d83cc019SAndroid Build Coastguard Worker 			default:
463*d83cc019SAndroid Build Coastguard Worker 				igt_assert(false);
464*d83cc019SAndroid Build Coastguard Worker 			}
465*d83cc019SAndroid Build Coastguard Worker 		}
466*d83cc019SAndroid Build Coastguard Worker 	}
467*d83cc019SAndroid Build Coastguard Worker }
468*d83cc019SAndroid Build Coastguard Worker 
vc4_fb_convert_plane_to_tiled(struct igt_fb * dst,void * dst_buf,struct igt_fb * src,void * src_buf)469*d83cc019SAndroid Build Coastguard Worker void vc4_fb_convert_plane_to_tiled(struct igt_fb *dst, void *dst_buf,
470*d83cc019SAndroid Build Coastguard Worker 				     struct igt_fb *src, void *src_buf)
471*d83cc019SAndroid Build Coastguard Worker {
472*d83cc019SAndroid Build Coastguard Worker 	unsigned int plane;
473*d83cc019SAndroid Build Coastguard Worker 
474*d83cc019SAndroid Build Coastguard Worker 	igt_assert(src->modifier == DRM_FORMAT_MOD_LINEAR);
475*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_vc4_is_tiled(dst->modifier));
476*d83cc019SAndroid Build Coastguard Worker 
477*d83cc019SAndroid Build Coastguard Worker 	for (plane = 0; plane < src->num_planes; plane++) {
478*d83cc019SAndroid Build Coastguard Worker 		if (dst->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
479*d83cc019SAndroid Build Coastguard Worker 			vc4_fb_convert_plane_to_t_tiled(dst, dst_buf, src, src_buf, plane);
480*d83cc019SAndroid Build Coastguard Worker 		else
481*d83cc019SAndroid Build Coastguard Worker 			vc4_fb_convert_plane_to_sand_tiled(dst, dst_buf, src, src_buf, plane);
482*d83cc019SAndroid Build Coastguard Worker 	}
483*d83cc019SAndroid Build Coastguard Worker }
484*d83cc019SAndroid Build Coastguard Worker 
vc4_fb_convert_plane_from_tiled(struct igt_fb * dst,void * dst_buf,struct igt_fb * src,void * src_buf)485*d83cc019SAndroid Build Coastguard Worker void vc4_fb_convert_plane_from_tiled(struct igt_fb *dst, void *dst_buf,
486*d83cc019SAndroid Build Coastguard Worker 				       struct igt_fb *src, void *src_buf)
487*d83cc019SAndroid Build Coastguard Worker {
488*d83cc019SAndroid Build Coastguard Worker 	unsigned int plane;
489*d83cc019SAndroid Build Coastguard Worker 
490*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_vc4_is_tiled(src->modifier));
491*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dst->modifier == DRM_FORMAT_MOD_LINEAR);
492*d83cc019SAndroid Build Coastguard Worker 
493*d83cc019SAndroid Build Coastguard Worker 	for (plane = 0; plane < src->num_planes; plane++) {
494*d83cc019SAndroid Build Coastguard Worker 		if (src->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
495*d83cc019SAndroid Build Coastguard Worker 			vc4_fb_convert_plane_from_t_tiled(dst, dst_buf, src, src_buf, plane);
496*d83cc019SAndroid Build Coastguard Worker 		else
497*d83cc019SAndroid Build Coastguard Worker 			vc4_fb_convert_plane_from_sand_tiled(dst, dst_buf, src, src_buf, plane);
498*d83cc019SAndroid Build Coastguard Worker 	}
499*d83cc019SAndroid Build Coastguard Worker }
500