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