1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2013,2014 Intel Corporation
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 * Authors:
24*d83cc019SAndroid Build Coastguard Worker * Daniel Vetter <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker * Damien Lespiau <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker */
27*d83cc019SAndroid Build Coastguard Worker
28*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
29*d83cc019SAndroid Build Coastguard Worker #include <math.h>
30*d83cc019SAndroid Build Coastguard Worker #include <wchar.h>
31*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
32*d83cc019SAndroid Build Coastguard Worker
33*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
34*d83cc019SAndroid Build Coastguard Worker #include <pixman.h>
35*d83cc019SAndroid Build Coastguard Worker #endif
36*d83cc019SAndroid Build Coastguard Worker
37*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
38*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
39*d83cc019SAndroid Build Coastguard Worker #include "igt_color_encoding.h"
40*d83cc019SAndroid Build Coastguard Worker #include "igt_fb.h"
41*d83cc019SAndroid Build Coastguard Worker #include "igt_halffloat.h"
42*d83cc019SAndroid Build Coastguard Worker #include "igt_kms.h"
43*d83cc019SAndroid Build Coastguard Worker #include "igt_matrix.h"
44*d83cc019SAndroid Build Coastguard Worker #if defined(USE_VC4)
45*d83cc019SAndroid Build Coastguard Worker #include "igt_vc4.h"
46*d83cc019SAndroid Build Coastguard Worker #endif
47*d83cc019SAndroid Build Coastguard Worker #include "igt_amd.h"
48*d83cc019SAndroid Build Coastguard Worker #include "igt_x86.h"
49*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
50*d83cc019SAndroid Build Coastguard Worker #include "intel_batchbuffer.h"
51*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
52*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_mman.h"
53*d83cc019SAndroid Build Coastguard Worker
54*d83cc019SAndroid Build Coastguard Worker /**
55*d83cc019SAndroid Build Coastguard Worker * SECTION:igt_fb
56*d83cc019SAndroid Build Coastguard Worker * @short_description: Framebuffer handling and drawing library
57*d83cc019SAndroid Build Coastguard Worker * @title: Framebuffer
58*d83cc019SAndroid Build Coastguard Worker * @include: igt.h
59*d83cc019SAndroid Build Coastguard Worker *
60*d83cc019SAndroid Build Coastguard Worker * This library contains helper functions for handling kms framebuffer objects
61*d83cc019SAndroid Build Coastguard Worker * using #igt_fb structures to track all the metadata. igt_create_fb() creates
62*d83cc019SAndroid Build Coastguard Worker * a basic framebuffer and igt_remove_fb() cleans everything up again.
63*d83cc019SAndroid Build Coastguard Worker *
64*d83cc019SAndroid Build Coastguard Worker * It also supports drawing using the cairo library and provides some simplified
65*d83cc019SAndroid Build Coastguard Worker * helper functions to easily draw test patterns. The main function to create a
66*d83cc019SAndroid Build Coastguard Worker * cairo drawing context for a framebuffer object is igt_get_cairo_ctx().
67*d83cc019SAndroid Build Coastguard Worker *
68*d83cc019SAndroid Build Coastguard Worker * Finally it also pulls in the drm fourcc headers and provides some helper
69*d83cc019SAndroid Build Coastguard Worker * functions to work with these pixel format codes.
70*d83cc019SAndroid Build Coastguard Worker */
71*d83cc019SAndroid Build Coastguard Worker
72*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
73*d83cc019SAndroid Build Coastguard Worker #define PIXMAN_invalid 0
74*d83cc019SAndroid Build Coastguard Worker
75*d83cc019SAndroid Build Coastguard Worker #if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 17, 2)
76*d83cc019SAndroid Build Coastguard Worker /*
77*d83cc019SAndroid Build Coastguard Worker * We need cairo 1.17.2 to use HDR formats, but the only thing added is a value
78*d83cc019SAndroid Build Coastguard Worker * to cairo_format_t.
79*d83cc019SAndroid Build Coastguard Worker *
80*d83cc019SAndroid Build Coastguard Worker * To prevent going outside the enum, make cairo_format_t an int and define
81*d83cc019SAndroid Build Coastguard Worker * ourselves.
82*d83cc019SAndroid Build Coastguard Worker */
83*d83cc019SAndroid Build Coastguard Worker
84*d83cc019SAndroid Build Coastguard Worker #define CAIRO_FORMAT_RGB96F (6)
85*d83cc019SAndroid Build Coastguard Worker #define CAIRO_FORMAT_RGBA128F (7)
86*d83cc019SAndroid Build Coastguard Worker #define cairo_format_t int
87*d83cc019SAndroid Build Coastguard Worker #endif
88*d83cc019SAndroid Build Coastguard Worker #endif /*defined(USE_CAIRO_PIXMAN)*/
89*d83cc019SAndroid Build Coastguard Worker
90*d83cc019SAndroid Build Coastguard Worker /* drm fourcc/cairo format maps */
91*d83cc019SAndroid Build Coastguard Worker static const struct format_desc_struct {
92*d83cc019SAndroid Build Coastguard Worker const char *name;
93*d83cc019SAndroid Build Coastguard Worker uint32_t drm_id;
94*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
95*d83cc019SAndroid Build Coastguard Worker cairo_format_t cairo_id;
96*d83cc019SAndroid Build Coastguard Worker pixman_format_code_t pixman_id;
97*d83cc019SAndroid Build Coastguard Worker #endif
98*d83cc019SAndroid Build Coastguard Worker int depth;
99*d83cc019SAndroid Build Coastguard Worker int num_planes;
100*d83cc019SAndroid Build Coastguard Worker int plane_bpp[4];
101*d83cc019SAndroid Build Coastguard Worker uint8_t hsub;
102*d83cc019SAndroid Build Coastguard Worker uint8_t vsub;
103*d83cc019SAndroid Build Coastguard Worker } format_desc[] = {
104*d83cc019SAndroid Build Coastguard Worker { .name = "ARGB1555", .depth = -1, .drm_id = DRM_FORMAT_ARGB1555,
105*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
106*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
107*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_a1r5g5b5,
108*d83cc019SAndroid Build Coastguard Worker #endif
109*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
110*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
111*d83cc019SAndroid Build Coastguard Worker },
112*d83cc019SAndroid Build Coastguard Worker { .name = "C8", .depth = -1, .drm_id = DRM_FORMAT_C8,
113*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
114*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
115*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_r3g3b2,
116*d83cc019SAndroid Build Coastguard Worker #endif
117*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 8, },
118*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
119*d83cc019SAndroid Build Coastguard Worker },
120*d83cc019SAndroid Build Coastguard Worker { .name = "XRGB1555", .depth = -1, .drm_id = DRM_FORMAT_XRGB1555,
121*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
122*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
123*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_x1r5g5b5,
124*d83cc019SAndroid Build Coastguard Worker #endif
125*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
126*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
127*d83cc019SAndroid Build Coastguard Worker },
128*d83cc019SAndroid Build Coastguard Worker { .name = "RGB565", .depth = 16, .drm_id = DRM_FORMAT_RGB565,
129*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
130*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB16_565,
131*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_r5g6b5,
132*d83cc019SAndroid Build Coastguard Worker #endif
133*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
134*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
135*d83cc019SAndroid Build Coastguard Worker },
136*d83cc019SAndroid Build Coastguard Worker { .name = "BGR565", .depth = -1, .drm_id = DRM_FORMAT_BGR565,
137*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
138*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
139*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_b5g6r5,
140*d83cc019SAndroid Build Coastguard Worker #endif
141*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
142*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
143*d83cc019SAndroid Build Coastguard Worker },
144*d83cc019SAndroid Build Coastguard Worker { .name = "BGR888", .depth = -1, .drm_id = DRM_FORMAT_BGR888,
145*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
146*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
147*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_b8g8r8,
148*d83cc019SAndroid Build Coastguard Worker #endif
149*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 24, },
150*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
151*d83cc019SAndroid Build Coastguard Worker },
152*d83cc019SAndroid Build Coastguard Worker { .name = "RGB888", .depth = -1, .drm_id = DRM_FORMAT_RGB888,
153*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
154*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
155*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_r8g8b8,
156*d83cc019SAndroid Build Coastguard Worker #endif
157*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 24, },
158*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
159*d83cc019SAndroid Build Coastguard Worker },
160*d83cc019SAndroid Build Coastguard Worker { .name = "XYUV8888", .depth = -1, .drm_id = DRM_FORMAT_XYUV8888,
161*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
162*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
163*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
164*d83cc019SAndroid Build Coastguard Worker #endif
165*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
166*d83cc019SAndroid Build Coastguard Worker },
167*d83cc019SAndroid Build Coastguard Worker { .name = "XRGB8888", .depth = 24, .drm_id = DRM_FORMAT_XRGB8888,
168*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
169*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
170*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_x8r8g8b8,
171*d83cc019SAndroid Build Coastguard Worker #endif
172*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
173*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
174*d83cc019SAndroid Build Coastguard Worker },
175*d83cc019SAndroid Build Coastguard Worker { .name = "XBGR8888", .depth = -1, .drm_id = DRM_FORMAT_XBGR8888,
176*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
177*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
178*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_x8b8g8r8,
179*d83cc019SAndroid Build Coastguard Worker #endif
180*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
181*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
182*d83cc019SAndroid Build Coastguard Worker },
183*d83cc019SAndroid Build Coastguard Worker { .name = "XRGB2101010", .depth = 30, .drm_id = DRM_FORMAT_XRGB2101010,
184*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
185*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB30,
186*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_x2r10g10b10,
187*d83cc019SAndroid Build Coastguard Worker #endif
188*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
189*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
190*d83cc019SAndroid Build Coastguard Worker },
191*d83cc019SAndroid Build Coastguard Worker { .name = "ARGB8888", .depth = 32, .drm_id = DRM_FORMAT_ARGB8888,
192*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
193*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_ARGB32,
194*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_a8r8g8b8,
195*d83cc019SAndroid Build Coastguard Worker #endif
196*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
197*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
198*d83cc019SAndroid Build Coastguard Worker },
199*d83cc019SAndroid Build Coastguard Worker { .name = "ABGR8888", .depth = -1, .drm_id = DRM_FORMAT_ABGR8888,
200*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
201*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
202*d83cc019SAndroid Build Coastguard Worker .pixman_id = PIXMAN_a8b8g8r8,
203*d83cc019SAndroid Build Coastguard Worker #endif
204*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
205*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
206*d83cc019SAndroid Build Coastguard Worker },
207*d83cc019SAndroid Build Coastguard Worker { .name = "XRGB16161616F", .depth = -1, .drm_id = DRM_FORMAT_XRGB16161616F,
208*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
209*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGBA128F,
210*d83cc019SAndroid Build Coastguard Worker #endif
211*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
212*d83cc019SAndroid Build Coastguard Worker },
213*d83cc019SAndroid Build Coastguard Worker { .name = "ARGB16161616F", .depth = -1, .drm_id = DRM_FORMAT_ARGB16161616F,
214*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
215*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGBA128F,
216*d83cc019SAndroid Build Coastguard Worker #endif
217*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
218*d83cc019SAndroid Build Coastguard Worker },
219*d83cc019SAndroid Build Coastguard Worker { .name = "XBGR16161616F", .depth = -1, .drm_id = DRM_FORMAT_XBGR16161616F,
220*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
221*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGBA128F,
222*d83cc019SAndroid Build Coastguard Worker #endif
223*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
224*d83cc019SAndroid Build Coastguard Worker },
225*d83cc019SAndroid Build Coastguard Worker { .name = "ABGR16161616F", .depth = -1, .drm_id = DRM_FORMAT_ABGR16161616F,
226*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
227*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGBA128F,
228*d83cc019SAndroid Build Coastguard Worker #endif
229*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
230*d83cc019SAndroid Build Coastguard Worker },
231*d83cc019SAndroid Build Coastguard Worker { .name = "NV12", .depth = -1, .drm_id = DRM_FORMAT_NV12,
232*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
233*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
234*d83cc019SAndroid Build Coastguard Worker #endif
235*d83cc019SAndroid Build Coastguard Worker .num_planes = 2, .plane_bpp = { 8, 16, },
236*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 2,
237*d83cc019SAndroid Build Coastguard Worker },
238*d83cc019SAndroid Build Coastguard Worker { .name = "NV16", .depth = -1, .drm_id = DRM_FORMAT_NV16,
239*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
240*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
241*d83cc019SAndroid Build Coastguard Worker #endif
242*d83cc019SAndroid Build Coastguard Worker .num_planes = 2, .plane_bpp = { 8, 16, },
243*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
244*d83cc019SAndroid Build Coastguard Worker },
245*d83cc019SAndroid Build Coastguard Worker { .name = "NV21", .depth = -1, .drm_id = DRM_FORMAT_NV21,
246*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
247*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
248*d83cc019SAndroid Build Coastguard Worker #endif
249*d83cc019SAndroid Build Coastguard Worker .num_planes = 2, .plane_bpp = { 8, 16, },
250*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 2,
251*d83cc019SAndroid Build Coastguard Worker },
252*d83cc019SAndroid Build Coastguard Worker { .name = "NV61", .depth = -1, .drm_id = DRM_FORMAT_NV61,
253*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
254*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
255*d83cc019SAndroid Build Coastguard Worker #endif
256*d83cc019SAndroid Build Coastguard Worker .num_planes = 2, .plane_bpp = { 8, 16, },
257*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
258*d83cc019SAndroid Build Coastguard Worker },
259*d83cc019SAndroid Build Coastguard Worker { .name = "YUYV", .depth = -1, .drm_id = DRM_FORMAT_YUYV,
260*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
261*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
262*d83cc019SAndroid Build Coastguard Worker #endif
263*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
264*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
265*d83cc019SAndroid Build Coastguard Worker },
266*d83cc019SAndroid Build Coastguard Worker { .name = "YVYU", .depth = -1, .drm_id = DRM_FORMAT_YVYU,
267*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
268*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
269*d83cc019SAndroid Build Coastguard Worker #endif
270*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
271*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
272*d83cc019SAndroid Build Coastguard Worker },
273*d83cc019SAndroid Build Coastguard Worker { .name = "UYVY", .depth = -1, .drm_id = DRM_FORMAT_UYVY,
274*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
275*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
276*d83cc019SAndroid Build Coastguard Worker #endif
277*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
278*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
279*d83cc019SAndroid Build Coastguard Worker },
280*d83cc019SAndroid Build Coastguard Worker { .name = "VYUY", .depth = -1, .drm_id = DRM_FORMAT_VYUY,
281*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
282*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
283*d83cc019SAndroid Build Coastguard Worker #endif
284*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 16, },
285*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
286*d83cc019SAndroid Build Coastguard Worker },
287*d83cc019SAndroid Build Coastguard Worker { .name = "YU12", .depth = -1, .drm_id = DRM_FORMAT_YUV420,
288*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
289*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
290*d83cc019SAndroid Build Coastguard Worker #endif
291*d83cc019SAndroid Build Coastguard Worker .num_planes = 3, .plane_bpp = { 8, 8, 8, },
292*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 2,
293*d83cc019SAndroid Build Coastguard Worker },
294*d83cc019SAndroid Build Coastguard Worker { .name = "YU16", .depth = -1, .drm_id = DRM_FORMAT_YUV422,
295*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
296*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
297*d83cc019SAndroid Build Coastguard Worker #endif
298*d83cc019SAndroid Build Coastguard Worker .num_planes = 3, .plane_bpp = { 8, 8, 8, },
299*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
300*d83cc019SAndroid Build Coastguard Worker },
301*d83cc019SAndroid Build Coastguard Worker { .name = "YV12", .depth = -1, .drm_id = DRM_FORMAT_YVU420,
302*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
303*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
304*d83cc019SAndroid Build Coastguard Worker #endif
305*d83cc019SAndroid Build Coastguard Worker .num_planes = 3, .plane_bpp = { 8, 8, 8, },
306*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 2,
307*d83cc019SAndroid Build Coastguard Worker },
308*d83cc019SAndroid Build Coastguard Worker { .name = "YV16", .depth = -1, .drm_id = DRM_FORMAT_YVU422,
309*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
310*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB24,
311*d83cc019SAndroid Build Coastguard Worker #endif
312*d83cc019SAndroid Build Coastguard Worker .num_planes = 3, .plane_bpp = { 8, 8, 8, },
313*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
314*d83cc019SAndroid Build Coastguard Worker },
315*d83cc019SAndroid Build Coastguard Worker { .name = "Y410", .depth = -1, .drm_id = DRM_FORMAT_Y410,
316*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
317*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGBA128F,
318*d83cc019SAndroid Build Coastguard Worker #endif
319*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
320*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
321*d83cc019SAndroid Build Coastguard Worker },
322*d83cc019SAndroid Build Coastguard Worker { .name = "Y412", .depth = -1, .drm_id = DRM_FORMAT_Y412,
323*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
324*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGBA128F,
325*d83cc019SAndroid Build Coastguard Worker #endif
326*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
327*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
328*d83cc019SAndroid Build Coastguard Worker },
329*d83cc019SAndroid Build Coastguard Worker { .name = "Y416", .depth = -1, .drm_id = DRM_FORMAT_Y416,
330*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
331*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGBA128F,
332*d83cc019SAndroid Build Coastguard Worker #endif
333*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
334*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
335*d83cc019SAndroid Build Coastguard Worker },
336*d83cc019SAndroid Build Coastguard Worker { .name = "XV30", .depth = -1, .drm_id = DRM_FORMAT_XVYU2101010,
337*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
338*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
339*d83cc019SAndroid Build Coastguard Worker #endif
340*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
341*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
342*d83cc019SAndroid Build Coastguard Worker },
343*d83cc019SAndroid Build Coastguard Worker { .name = "XV36", .depth = -1, .drm_id = DRM_FORMAT_XVYU12_16161616,
344*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
345*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
346*d83cc019SAndroid Build Coastguard Worker #endif
347*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
348*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
349*d83cc019SAndroid Build Coastguard Worker },
350*d83cc019SAndroid Build Coastguard Worker { .name = "XV48", .depth = -1, .drm_id = DRM_FORMAT_XVYU16161616,
351*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
352*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
353*d83cc019SAndroid Build Coastguard Worker #endif
354*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 64, },
355*d83cc019SAndroid Build Coastguard Worker .hsub = 1, .vsub = 1,
356*d83cc019SAndroid Build Coastguard Worker },
357*d83cc019SAndroid Build Coastguard Worker { .name = "P010", .depth = -1, .drm_id = DRM_FORMAT_P010,
358*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
359*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
360*d83cc019SAndroid Build Coastguard Worker #endif
361*d83cc019SAndroid Build Coastguard Worker .num_planes = 2, .plane_bpp = { 16, 32 },
362*d83cc019SAndroid Build Coastguard Worker .vsub = 2, .hsub = 2,
363*d83cc019SAndroid Build Coastguard Worker },
364*d83cc019SAndroid Build Coastguard Worker { .name = "P012", .depth = -1, .drm_id = DRM_FORMAT_P012,
365*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
366*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
367*d83cc019SAndroid Build Coastguard Worker #endif
368*d83cc019SAndroid Build Coastguard Worker .num_planes = 2, .plane_bpp = { 16, 32 },
369*d83cc019SAndroid Build Coastguard Worker .vsub = 2, .hsub = 2,
370*d83cc019SAndroid Build Coastguard Worker },
371*d83cc019SAndroid Build Coastguard Worker { .name = "P016", .depth = -1, .drm_id = DRM_FORMAT_P016,
372*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
373*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
374*d83cc019SAndroid Build Coastguard Worker #endif
375*d83cc019SAndroid Build Coastguard Worker .num_planes = 2, .plane_bpp = { 16, 32 },
376*d83cc019SAndroid Build Coastguard Worker .vsub = 2, .hsub = 2,
377*d83cc019SAndroid Build Coastguard Worker },
378*d83cc019SAndroid Build Coastguard Worker { .name = "Y210", .depth = -1, .drm_id = DRM_FORMAT_Y210,
379*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
380*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
381*d83cc019SAndroid Build Coastguard Worker #endif
382*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
383*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
384*d83cc019SAndroid Build Coastguard Worker },
385*d83cc019SAndroid Build Coastguard Worker { .name = "Y212", .depth = -1, .drm_id = DRM_FORMAT_Y212,
386*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
387*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
388*d83cc019SAndroid Build Coastguard Worker #endif
389*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
390*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
391*d83cc019SAndroid Build Coastguard Worker },
392*d83cc019SAndroid Build Coastguard Worker { .name = "Y216", .depth = -1, .drm_id = DRM_FORMAT_Y216,
393*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
394*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_RGB96F,
395*d83cc019SAndroid Build Coastguard Worker #endif
396*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 32, },
397*d83cc019SAndroid Build Coastguard Worker .hsub = 2, .vsub = 1,
398*d83cc019SAndroid Build Coastguard Worker },
399*d83cc019SAndroid Build Coastguard Worker { .name = "IGT-FLOAT", .depth = -1, .drm_id = IGT_FORMAT_FLOAT,
400*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
401*d83cc019SAndroid Build Coastguard Worker .cairo_id = CAIRO_FORMAT_INVALID,
402*d83cc019SAndroid Build Coastguard Worker #endif
403*d83cc019SAndroid Build Coastguard Worker .num_planes = 1, .plane_bpp = { 128 },
404*d83cc019SAndroid Build Coastguard Worker },
405*d83cc019SAndroid Build Coastguard Worker };
406*d83cc019SAndroid Build Coastguard Worker #define for_each_format(f) \
407*d83cc019SAndroid Build Coastguard Worker for (f = format_desc; f - format_desc < ARRAY_SIZE(format_desc); f++)
408*d83cc019SAndroid Build Coastguard Worker
lookup_drm_format(uint32_t drm_format)409*d83cc019SAndroid Build Coastguard Worker static const struct format_desc_struct *lookup_drm_format(uint32_t drm_format)
410*d83cc019SAndroid Build Coastguard Worker {
411*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *format;
412*d83cc019SAndroid Build Coastguard Worker
413*d83cc019SAndroid Build Coastguard Worker for_each_format(format) {
414*d83cc019SAndroid Build Coastguard Worker if (format->drm_id != drm_format)
415*d83cc019SAndroid Build Coastguard Worker continue;
416*d83cc019SAndroid Build Coastguard Worker
417*d83cc019SAndroid Build Coastguard Worker return format;
418*d83cc019SAndroid Build Coastguard Worker }
419*d83cc019SAndroid Build Coastguard Worker
420*d83cc019SAndroid Build Coastguard Worker return NULL;
421*d83cc019SAndroid Build Coastguard Worker }
422*d83cc019SAndroid Build Coastguard Worker
423*d83cc019SAndroid Build Coastguard Worker /**
424*d83cc019SAndroid Build Coastguard Worker * igt_get_fb_tile_size:
425*d83cc019SAndroid Build Coastguard Worker * @fd: the DRM file descriptor
426*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer (as framebuffer modifier)
427*d83cc019SAndroid Build Coastguard Worker * @fb_bpp: bits per pixel of the framebuffer
428*d83cc019SAndroid Build Coastguard Worker * @width_ret: width of the tile in bytes
429*d83cc019SAndroid Build Coastguard Worker * @height_ret: height of the tile in lines
430*d83cc019SAndroid Build Coastguard Worker *
431*d83cc019SAndroid Build Coastguard Worker * This function returns width and height of a tile based on the given tiling
432*d83cc019SAndroid Build Coastguard Worker * format.
433*d83cc019SAndroid Build Coastguard Worker */
igt_get_fb_tile_size(int fd,uint64_t modifier,int fb_bpp,unsigned * width_ret,unsigned * height_ret)434*d83cc019SAndroid Build Coastguard Worker void igt_get_fb_tile_size(int fd, uint64_t modifier, int fb_bpp,
435*d83cc019SAndroid Build Coastguard Worker unsigned *width_ret, unsigned *height_ret)
436*d83cc019SAndroid Build Coastguard Worker {
437*d83cc019SAndroid Build Coastguard Worker uint32_t vc4_modifier_param = 0;
438*d83cc019SAndroid Build Coastguard Worker
439*d83cc019SAndroid Build Coastguard Worker if (is_vc4_device(fd)) {
440*d83cc019SAndroid Build Coastguard Worker vc4_modifier_param = fourcc_mod_broadcom_param(modifier);
441*d83cc019SAndroid Build Coastguard Worker modifier = fourcc_mod_broadcom_mod(modifier);
442*d83cc019SAndroid Build Coastguard Worker }
443*d83cc019SAndroid Build Coastguard Worker
444*d83cc019SAndroid Build Coastguard Worker switch (modifier) {
445*d83cc019SAndroid Build Coastguard Worker case LOCAL_DRM_FORMAT_MOD_NONE:
446*d83cc019SAndroid Build Coastguard Worker if (is_i915_device(fd))
447*d83cc019SAndroid Build Coastguard Worker *width_ret = 64;
448*d83cc019SAndroid Build Coastguard Worker else
449*d83cc019SAndroid Build Coastguard Worker *width_ret = 1;
450*d83cc019SAndroid Build Coastguard Worker
451*d83cc019SAndroid Build Coastguard Worker *height_ret = 1;
452*d83cc019SAndroid Build Coastguard Worker break;
453*d83cc019SAndroid Build Coastguard Worker #if defined(USE_INTEL)
454*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_X_TILED:
455*d83cc019SAndroid Build Coastguard Worker igt_require_intel(fd);
456*d83cc019SAndroid Build Coastguard Worker if (intel_gen(intel_get_drm_devid(fd)) == 2) {
457*d83cc019SAndroid Build Coastguard Worker *width_ret = 128;
458*d83cc019SAndroid Build Coastguard Worker *height_ret = 16;
459*d83cc019SAndroid Build Coastguard Worker } else {
460*d83cc019SAndroid Build Coastguard Worker *width_ret = 512;
461*d83cc019SAndroid Build Coastguard Worker *height_ret = 8;
462*d83cc019SAndroid Build Coastguard Worker }
463*d83cc019SAndroid Build Coastguard Worker break;
464*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Y_TILED:
465*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Y_TILED_CCS:
466*d83cc019SAndroid Build Coastguard Worker igt_require_intel(fd);
467*d83cc019SAndroid Build Coastguard Worker if (intel_gen(intel_get_drm_devid(fd)) == 2) {
468*d83cc019SAndroid Build Coastguard Worker *width_ret = 128;
469*d83cc019SAndroid Build Coastguard Worker *height_ret = 16;
470*d83cc019SAndroid Build Coastguard Worker } else if (IS_915(intel_get_drm_devid(fd))) {
471*d83cc019SAndroid Build Coastguard Worker *width_ret = 512;
472*d83cc019SAndroid Build Coastguard Worker *height_ret = 8;
473*d83cc019SAndroid Build Coastguard Worker } else {
474*d83cc019SAndroid Build Coastguard Worker *width_ret = 128;
475*d83cc019SAndroid Build Coastguard Worker *height_ret = 32;
476*d83cc019SAndroid Build Coastguard Worker }
477*d83cc019SAndroid Build Coastguard Worker break;
478*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Yf_TILED:
479*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Yf_TILED_CCS:
480*d83cc019SAndroid Build Coastguard Worker igt_require_intel(fd);
481*d83cc019SAndroid Build Coastguard Worker switch (fb_bpp) {
482*d83cc019SAndroid Build Coastguard Worker case 8:
483*d83cc019SAndroid Build Coastguard Worker *width_ret = 64;
484*d83cc019SAndroid Build Coastguard Worker *height_ret = 64;
485*d83cc019SAndroid Build Coastguard Worker break;
486*d83cc019SAndroid Build Coastguard Worker case 16:
487*d83cc019SAndroid Build Coastguard Worker case 32:
488*d83cc019SAndroid Build Coastguard Worker *width_ret = 128;
489*d83cc019SAndroid Build Coastguard Worker *height_ret = 32;
490*d83cc019SAndroid Build Coastguard Worker break;
491*d83cc019SAndroid Build Coastguard Worker case 64:
492*d83cc019SAndroid Build Coastguard Worker case 128:
493*d83cc019SAndroid Build Coastguard Worker *width_ret = 256;
494*d83cc019SAndroid Build Coastguard Worker *height_ret = 16;
495*d83cc019SAndroid Build Coastguard Worker break;
496*d83cc019SAndroid Build Coastguard Worker default:
497*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
498*d83cc019SAndroid Build Coastguard Worker }
499*d83cc019SAndroid Build Coastguard Worker break;
500*d83cc019SAndroid Build Coastguard Worker #endif
501*d83cc019SAndroid Build Coastguard Worker #if defined(USE_VC4)
502*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
503*d83cc019SAndroid Build Coastguard Worker igt_require_vc4(fd);
504*d83cc019SAndroid Build Coastguard Worker *width_ret = 128;
505*d83cc019SAndroid Build Coastguard Worker *height_ret = 32;
506*d83cc019SAndroid Build Coastguard Worker break;
507*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_BROADCOM_SAND32:
508*d83cc019SAndroid Build Coastguard Worker igt_require_vc4(fd);
509*d83cc019SAndroid Build Coastguard Worker *width_ret = 32;
510*d83cc019SAndroid Build Coastguard Worker *height_ret = vc4_modifier_param;
511*d83cc019SAndroid Build Coastguard Worker break;
512*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_BROADCOM_SAND64:
513*d83cc019SAndroid Build Coastguard Worker igt_require_vc4(fd);
514*d83cc019SAndroid Build Coastguard Worker *width_ret = 64;
515*d83cc019SAndroid Build Coastguard Worker *height_ret = vc4_modifier_param;
516*d83cc019SAndroid Build Coastguard Worker break;
517*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_BROADCOM_SAND128:
518*d83cc019SAndroid Build Coastguard Worker igt_require_vc4(fd);
519*d83cc019SAndroid Build Coastguard Worker *width_ret = 128;
520*d83cc019SAndroid Build Coastguard Worker *height_ret = vc4_modifier_param;
521*d83cc019SAndroid Build Coastguard Worker break;
522*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_BROADCOM_SAND256:
523*d83cc019SAndroid Build Coastguard Worker igt_require_vc4(fd);
524*d83cc019SAndroid Build Coastguard Worker *width_ret = 256;
525*d83cc019SAndroid Build Coastguard Worker *height_ret = vc4_modifier_param;
526*d83cc019SAndroid Build Coastguard Worker break;
527*d83cc019SAndroid Build Coastguard Worker #endif
528*d83cc019SAndroid Build Coastguard Worker default:
529*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
530*d83cc019SAndroid Build Coastguard Worker }
531*d83cc019SAndroid Build Coastguard Worker }
532*d83cc019SAndroid Build Coastguard Worker
is_ccs_modifier(uint64_t modifier)533*d83cc019SAndroid Build Coastguard Worker static bool is_ccs_modifier(uint64_t modifier)
534*d83cc019SAndroid Build Coastguard Worker {
535*d83cc019SAndroid Build Coastguard Worker return modifier == LOCAL_I915_FORMAT_MOD_Y_TILED_CCS ||
536*d83cc019SAndroid Build Coastguard Worker modifier == LOCAL_I915_FORMAT_MOD_Yf_TILED_CCS;
537*d83cc019SAndroid Build Coastguard Worker }
538*d83cc019SAndroid Build Coastguard Worker
fb_plane_width(const struct igt_fb * fb,int plane)539*d83cc019SAndroid Build Coastguard Worker static unsigned fb_plane_width(const struct igt_fb *fb, int plane)
540*d83cc019SAndroid Build Coastguard Worker {
541*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
542*d83cc019SAndroid Build Coastguard Worker
543*d83cc019SAndroid Build Coastguard Worker if (is_ccs_modifier(fb->modifier) && plane == 1)
544*d83cc019SAndroid Build Coastguard Worker return DIV_ROUND_UP(fb->width, 1024) * 128;
545*d83cc019SAndroid Build Coastguard Worker
546*d83cc019SAndroid Build Coastguard Worker if (plane == 0)
547*d83cc019SAndroid Build Coastguard Worker return fb->width;
548*d83cc019SAndroid Build Coastguard Worker
549*d83cc019SAndroid Build Coastguard Worker return DIV_ROUND_UP(fb->width, format->hsub);
550*d83cc019SAndroid Build Coastguard Worker }
551*d83cc019SAndroid Build Coastguard Worker
fb_plane_bpp(const struct igt_fb * fb,int plane)552*d83cc019SAndroid Build Coastguard Worker static unsigned fb_plane_bpp(const struct igt_fb *fb, int plane)
553*d83cc019SAndroid Build Coastguard Worker {
554*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
555*d83cc019SAndroid Build Coastguard Worker
556*d83cc019SAndroid Build Coastguard Worker if (is_ccs_modifier(fb->modifier) && plane == 1)
557*d83cc019SAndroid Build Coastguard Worker return 8;
558*d83cc019SAndroid Build Coastguard Worker else
559*d83cc019SAndroid Build Coastguard Worker return format->plane_bpp[plane];
560*d83cc019SAndroid Build Coastguard Worker }
561*d83cc019SAndroid Build Coastguard Worker
fb_plane_height(const struct igt_fb * fb,int plane)562*d83cc019SAndroid Build Coastguard Worker static unsigned fb_plane_height(const struct igt_fb *fb, int plane)
563*d83cc019SAndroid Build Coastguard Worker {
564*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
565*d83cc019SAndroid Build Coastguard Worker
566*d83cc019SAndroid Build Coastguard Worker if (is_ccs_modifier(fb->modifier) && plane == 1)
567*d83cc019SAndroid Build Coastguard Worker return DIV_ROUND_UP(fb->height, 512) * 32;
568*d83cc019SAndroid Build Coastguard Worker
569*d83cc019SAndroid Build Coastguard Worker if (plane == 0)
570*d83cc019SAndroid Build Coastguard Worker return fb->height;
571*d83cc019SAndroid Build Coastguard Worker
572*d83cc019SAndroid Build Coastguard Worker return DIV_ROUND_UP(fb->height, format->vsub);
573*d83cc019SAndroid Build Coastguard Worker }
574*d83cc019SAndroid Build Coastguard Worker
fb_num_planes(const struct igt_fb * fb)575*d83cc019SAndroid Build Coastguard Worker static int fb_num_planes(const struct igt_fb *fb)
576*d83cc019SAndroid Build Coastguard Worker {
577*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
578*d83cc019SAndroid Build Coastguard Worker
579*d83cc019SAndroid Build Coastguard Worker if (is_ccs_modifier(fb->modifier))
580*d83cc019SAndroid Build Coastguard Worker return 2;
581*d83cc019SAndroid Build Coastguard Worker else
582*d83cc019SAndroid Build Coastguard Worker return format->num_planes;
583*d83cc019SAndroid Build Coastguard Worker }
584*d83cc019SAndroid Build Coastguard Worker
igt_init_fb(struct igt_fb * fb,int fd,int width,int height,uint32_t drm_format,uint64_t modifier,enum igt_color_encoding color_encoding,enum igt_color_range color_range)585*d83cc019SAndroid Build Coastguard Worker void igt_init_fb(struct igt_fb *fb, int fd, int width, int height,
586*d83cc019SAndroid Build Coastguard Worker uint32_t drm_format, uint64_t modifier,
587*d83cc019SAndroid Build Coastguard Worker enum igt_color_encoding color_encoding,
588*d83cc019SAndroid Build Coastguard Worker enum igt_color_range color_range)
589*d83cc019SAndroid Build Coastguard Worker {
590*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f = lookup_drm_format(drm_format);
591*d83cc019SAndroid Build Coastguard Worker
592*d83cc019SAndroid Build Coastguard Worker igt_assert_f(f, "DRM format %08x not found\n", drm_format);
593*d83cc019SAndroid Build Coastguard Worker
594*d83cc019SAndroid Build Coastguard Worker memset(fb, 0, sizeof(*fb));
595*d83cc019SAndroid Build Coastguard Worker
596*d83cc019SAndroid Build Coastguard Worker fb->width = width;
597*d83cc019SAndroid Build Coastguard Worker fb->height = height;
598*d83cc019SAndroid Build Coastguard Worker fb->modifier = modifier;
599*d83cc019SAndroid Build Coastguard Worker fb->drm_format = drm_format;
600*d83cc019SAndroid Build Coastguard Worker fb->fd = fd;
601*d83cc019SAndroid Build Coastguard Worker fb->num_planes = fb_num_planes(fb);
602*d83cc019SAndroid Build Coastguard Worker fb->color_encoding = color_encoding;
603*d83cc019SAndroid Build Coastguard Worker fb->color_range = color_range;
604*d83cc019SAndroid Build Coastguard Worker
605*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < fb->num_planes; i++) {
606*d83cc019SAndroid Build Coastguard Worker fb->plane_bpp[i] = fb_plane_bpp(fb, i);
607*d83cc019SAndroid Build Coastguard Worker fb->plane_height[i] = fb_plane_height(fb, i);
608*d83cc019SAndroid Build Coastguard Worker fb->plane_width[i] = fb_plane_width(fb, i);
609*d83cc019SAndroid Build Coastguard Worker }
610*d83cc019SAndroid Build Coastguard Worker }
611*d83cc019SAndroid Build Coastguard Worker
calc_plane_stride(struct igt_fb * fb,int plane)612*d83cc019SAndroid Build Coastguard Worker static uint32_t calc_plane_stride(struct igt_fb *fb, int plane)
613*d83cc019SAndroid Build Coastguard Worker {
614*d83cc019SAndroid Build Coastguard Worker uint32_t min_stride = fb->plane_width[plane] *
615*d83cc019SAndroid Build Coastguard Worker (fb->plane_bpp[plane] / 8);
616*d83cc019SAndroid Build Coastguard Worker
617*d83cc019SAndroid Build Coastguard Worker if (fb->modifier != LOCAL_DRM_FORMAT_MOD_NONE &&
618*d83cc019SAndroid Build Coastguard Worker is_i915_device(fb->fd) &&
619*d83cc019SAndroid Build Coastguard Worker intel_gen(intel_get_drm_devid(fb->fd)) <= 3) {
620*d83cc019SAndroid Build Coastguard Worker uint32_t stride;
621*d83cc019SAndroid Build Coastguard Worker
622*d83cc019SAndroid Build Coastguard Worker /* Round the tiling up to the next power-of-two and the region
623*d83cc019SAndroid Build Coastguard Worker * up to the next pot fence size so that this works on all
624*d83cc019SAndroid Build Coastguard Worker * generations.
625*d83cc019SAndroid Build Coastguard Worker *
626*d83cc019SAndroid Build Coastguard Worker * This can still fail if the framebuffer is too large to be
627*d83cc019SAndroid Build Coastguard Worker * tiled. But then that failure is expected.
628*d83cc019SAndroid Build Coastguard Worker */
629*d83cc019SAndroid Build Coastguard Worker
630*d83cc019SAndroid Build Coastguard Worker stride = max(min_stride, 512);
631*d83cc019SAndroid Build Coastguard Worker stride = roundup_power_of_two(stride);
632*d83cc019SAndroid Build Coastguard Worker
633*d83cc019SAndroid Build Coastguard Worker return stride;
634*d83cc019SAndroid Build Coastguard Worker } else if (igt_format_is_yuv(fb->drm_format) && is_amdgpu_device(fb->fd)) {
635*d83cc019SAndroid Build Coastguard Worker /*
636*d83cc019SAndroid Build Coastguard Worker * Chroma address needs to be aligned to 256 bytes on AMDGPU
637*d83cc019SAndroid Build Coastguard Worker * so the easiest way is to align the luma stride to 256.
638*d83cc019SAndroid Build Coastguard Worker */
639*d83cc019SAndroid Build Coastguard Worker return ALIGN(min_stride, 256);
640*d83cc019SAndroid Build Coastguard Worker } else {
641*d83cc019SAndroid Build Coastguard Worker unsigned int tile_width, tile_height;
642*d83cc019SAndroid Build Coastguard Worker
643*d83cc019SAndroid Build Coastguard Worker igt_get_fb_tile_size(fb->fd, fb->modifier, fb->plane_bpp[plane],
644*d83cc019SAndroid Build Coastguard Worker &tile_width, &tile_height);
645*d83cc019SAndroid Build Coastguard Worker
646*d83cc019SAndroid Build Coastguard Worker return ALIGN(min_stride, tile_width);
647*d83cc019SAndroid Build Coastguard Worker }
648*d83cc019SAndroid Build Coastguard Worker }
649*d83cc019SAndroid Build Coastguard Worker
calc_plane_size(struct igt_fb * fb,int plane)650*d83cc019SAndroid Build Coastguard Worker static uint64_t calc_plane_size(struct igt_fb *fb, int plane)
651*d83cc019SAndroid Build Coastguard Worker {
652*d83cc019SAndroid Build Coastguard Worker if (fb->modifier != LOCAL_DRM_FORMAT_MOD_NONE &&
653*d83cc019SAndroid Build Coastguard Worker is_i915_device(fb->fd) &&
654*d83cc019SAndroid Build Coastguard Worker intel_gen(intel_get_drm_devid(fb->fd)) <= 3) {
655*d83cc019SAndroid Build Coastguard Worker uint64_t min_size = (uint64_t) fb->strides[plane] *
656*d83cc019SAndroid Build Coastguard Worker fb->plane_height[plane];
657*d83cc019SAndroid Build Coastguard Worker uint64_t size;
658*d83cc019SAndroid Build Coastguard Worker
659*d83cc019SAndroid Build Coastguard Worker /* Round the tiling up to the next power-of-two and the region
660*d83cc019SAndroid Build Coastguard Worker * up to the next pot fence size so that this works on all
661*d83cc019SAndroid Build Coastguard Worker * generations.
662*d83cc019SAndroid Build Coastguard Worker *
663*d83cc019SAndroid Build Coastguard Worker * This can still fail if the framebuffer is too large to be
664*d83cc019SAndroid Build Coastguard Worker * tiled. But then that failure is expected.
665*d83cc019SAndroid Build Coastguard Worker */
666*d83cc019SAndroid Build Coastguard Worker
667*d83cc019SAndroid Build Coastguard Worker size = max(min_size, 1024*1024);
668*d83cc019SAndroid Build Coastguard Worker size = roundup_power_of_two(size);
669*d83cc019SAndroid Build Coastguard Worker
670*d83cc019SAndroid Build Coastguard Worker return size;
671*d83cc019SAndroid Build Coastguard Worker } else {
672*d83cc019SAndroid Build Coastguard Worker unsigned int tile_width, tile_height;
673*d83cc019SAndroid Build Coastguard Worker
674*d83cc019SAndroid Build Coastguard Worker igt_get_fb_tile_size(fb->fd, fb->modifier, fb->plane_bpp[plane],
675*d83cc019SAndroid Build Coastguard Worker &tile_width, &tile_height);
676*d83cc019SAndroid Build Coastguard Worker
677*d83cc019SAndroid Build Coastguard Worker /* Special case where the "tile height" represents a
678*d83cc019SAndroid Build Coastguard Worker * height-based stride, such as with VC4 SAND tiling modes.
679*d83cc019SAndroid Build Coastguard Worker */
680*d83cc019SAndroid Build Coastguard Worker
681*d83cc019SAndroid Build Coastguard Worker if (tile_height > fb->plane_height[plane])
682*d83cc019SAndroid Build Coastguard Worker return fb->strides[plane] * tile_height;
683*d83cc019SAndroid Build Coastguard Worker
684*d83cc019SAndroid Build Coastguard Worker return (uint64_t) fb->strides[plane] *
685*d83cc019SAndroid Build Coastguard Worker ALIGN(fb->plane_height[plane], tile_height);
686*d83cc019SAndroid Build Coastguard Worker }
687*d83cc019SAndroid Build Coastguard Worker }
688*d83cc019SAndroid Build Coastguard Worker
calc_fb_size(struct igt_fb * fb)689*d83cc019SAndroid Build Coastguard Worker static uint64_t calc_fb_size(struct igt_fb *fb)
690*d83cc019SAndroid Build Coastguard Worker {
691*d83cc019SAndroid Build Coastguard Worker uint64_t size = 0;
692*d83cc019SAndroid Build Coastguard Worker int plane;
693*d83cc019SAndroid Build Coastguard Worker
694*d83cc019SAndroid Build Coastguard Worker for (plane = 0; plane < fb->num_planes; plane++) {
695*d83cc019SAndroid Build Coastguard Worker /* respect the stride requested by the caller */
696*d83cc019SAndroid Build Coastguard Worker if (!fb->strides[plane])
697*d83cc019SAndroid Build Coastguard Worker fb->strides[plane] = calc_plane_stride(fb, plane);
698*d83cc019SAndroid Build Coastguard Worker
699*d83cc019SAndroid Build Coastguard Worker fb->offsets[plane] = size;
700*d83cc019SAndroid Build Coastguard Worker
701*d83cc019SAndroid Build Coastguard Worker size += calc_plane_size(fb, plane);
702*d83cc019SAndroid Build Coastguard Worker }
703*d83cc019SAndroid Build Coastguard Worker
704*d83cc019SAndroid Build Coastguard Worker return size;
705*d83cc019SAndroid Build Coastguard Worker }
706*d83cc019SAndroid Build Coastguard Worker
707*d83cc019SAndroid Build Coastguard Worker /**
708*d83cc019SAndroid Build Coastguard Worker * igt_calc_fb_size:
709*d83cc019SAndroid Build Coastguard Worker * @fd: the DRM file descriptor
710*d83cc019SAndroid Build Coastguard Worker * @width: width of the framebuffer in pixels
711*d83cc019SAndroid Build Coastguard Worker * @height: height of the framebuffer in pixels
712*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
713*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer (as framebuffer modifier)
714*d83cc019SAndroid Build Coastguard Worker * @size_ret: returned size for the framebuffer
715*d83cc019SAndroid Build Coastguard Worker * @stride_ret: returned stride for the framebuffer
716*d83cc019SAndroid Build Coastguard Worker *
717*d83cc019SAndroid Build Coastguard Worker * This function returns valid stride and size values for a framebuffer with the
718*d83cc019SAndroid Build Coastguard Worker * specified parameters.
719*d83cc019SAndroid Build Coastguard Worker */
igt_calc_fb_size(int fd,int width,int height,uint32_t drm_format,uint64_t modifier,uint64_t * size_ret,unsigned * stride_ret)720*d83cc019SAndroid Build Coastguard Worker void igt_calc_fb_size(int fd, int width, int height, uint32_t drm_format, uint64_t modifier,
721*d83cc019SAndroid Build Coastguard Worker uint64_t *size_ret, unsigned *stride_ret)
722*d83cc019SAndroid Build Coastguard Worker {
723*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb;
724*d83cc019SAndroid Build Coastguard Worker
725*d83cc019SAndroid Build Coastguard Worker igt_init_fb(&fb, fd, width, height, drm_format, modifier,
726*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_BT709, IGT_COLOR_YCBCR_LIMITED_RANGE);
727*d83cc019SAndroid Build Coastguard Worker
728*d83cc019SAndroid Build Coastguard Worker fb.size = calc_fb_size(&fb);
729*d83cc019SAndroid Build Coastguard Worker
730*d83cc019SAndroid Build Coastguard Worker if (size_ret)
731*d83cc019SAndroid Build Coastguard Worker *size_ret = fb.size;
732*d83cc019SAndroid Build Coastguard Worker if (stride_ret)
733*d83cc019SAndroid Build Coastguard Worker *stride_ret = fb.strides[0];
734*d83cc019SAndroid Build Coastguard Worker }
735*d83cc019SAndroid Build Coastguard Worker
736*d83cc019SAndroid Build Coastguard Worker /**
737*d83cc019SAndroid Build Coastguard Worker * igt_fb_mod_to_tiling:
738*d83cc019SAndroid Build Coastguard Worker * @modifier: DRM framebuffer modifier
739*d83cc019SAndroid Build Coastguard Worker *
740*d83cc019SAndroid Build Coastguard Worker * This function converts a DRM framebuffer modifier to its corresponding
741*d83cc019SAndroid Build Coastguard Worker * tiling constant.
742*d83cc019SAndroid Build Coastguard Worker *
743*d83cc019SAndroid Build Coastguard Worker * Returns:
744*d83cc019SAndroid Build Coastguard Worker * A tiling constant
745*d83cc019SAndroid Build Coastguard Worker */
igt_fb_mod_to_tiling(uint64_t modifier)746*d83cc019SAndroid Build Coastguard Worker uint64_t igt_fb_mod_to_tiling(uint64_t modifier)
747*d83cc019SAndroid Build Coastguard Worker {
748*d83cc019SAndroid Build Coastguard Worker switch (modifier) {
749*d83cc019SAndroid Build Coastguard Worker case LOCAL_DRM_FORMAT_MOD_NONE:
750*d83cc019SAndroid Build Coastguard Worker return I915_TILING_NONE;
751*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_X_TILED:
752*d83cc019SAndroid Build Coastguard Worker return I915_TILING_X;
753*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Y_TILED:
754*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Y_TILED_CCS:
755*d83cc019SAndroid Build Coastguard Worker return I915_TILING_Y;
756*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Yf_TILED:
757*d83cc019SAndroid Build Coastguard Worker case LOCAL_I915_FORMAT_MOD_Yf_TILED_CCS:
758*d83cc019SAndroid Build Coastguard Worker return I915_TILING_Yf;
759*d83cc019SAndroid Build Coastguard Worker default:
760*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
761*d83cc019SAndroid Build Coastguard Worker }
762*d83cc019SAndroid Build Coastguard Worker }
763*d83cc019SAndroid Build Coastguard Worker
764*d83cc019SAndroid Build Coastguard Worker /**
765*d83cc019SAndroid Build Coastguard Worker * igt_fb_tiling_to_mod:
766*d83cc019SAndroid Build Coastguard Worker * @tiling: DRM framebuffer tiling
767*d83cc019SAndroid Build Coastguard Worker *
768*d83cc019SAndroid Build Coastguard Worker * This function converts a DRM framebuffer tiling to its corresponding
769*d83cc019SAndroid Build Coastguard Worker * modifier constant.
770*d83cc019SAndroid Build Coastguard Worker *
771*d83cc019SAndroid Build Coastguard Worker * Returns:
772*d83cc019SAndroid Build Coastguard Worker * A modifier constant
773*d83cc019SAndroid Build Coastguard Worker */
igt_fb_tiling_to_mod(uint64_t tiling)774*d83cc019SAndroid Build Coastguard Worker uint64_t igt_fb_tiling_to_mod(uint64_t tiling)
775*d83cc019SAndroid Build Coastguard Worker {
776*d83cc019SAndroid Build Coastguard Worker switch (tiling) {
777*d83cc019SAndroid Build Coastguard Worker case I915_TILING_NONE:
778*d83cc019SAndroid Build Coastguard Worker return LOCAL_DRM_FORMAT_MOD_NONE;
779*d83cc019SAndroid Build Coastguard Worker case I915_TILING_X:
780*d83cc019SAndroid Build Coastguard Worker return LOCAL_I915_FORMAT_MOD_X_TILED;
781*d83cc019SAndroid Build Coastguard Worker case I915_TILING_Y:
782*d83cc019SAndroid Build Coastguard Worker return LOCAL_I915_FORMAT_MOD_Y_TILED;
783*d83cc019SAndroid Build Coastguard Worker case I915_TILING_Yf:
784*d83cc019SAndroid Build Coastguard Worker return LOCAL_I915_FORMAT_MOD_Yf_TILED;
785*d83cc019SAndroid Build Coastguard Worker default:
786*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
787*d83cc019SAndroid Build Coastguard Worker }
788*d83cc019SAndroid Build Coastguard Worker }
789*d83cc019SAndroid Build Coastguard Worker
memset64(uint64_t * s,uint64_t c,size_t n)790*d83cc019SAndroid Build Coastguard Worker static void memset64(uint64_t *s, uint64_t c, size_t n)
791*d83cc019SAndroid Build Coastguard Worker {
792*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < n; i++)
793*d83cc019SAndroid Build Coastguard Worker s[i] = c;
794*d83cc019SAndroid Build Coastguard Worker }
795*d83cc019SAndroid Build Coastguard Worker
clear_yuv_buffer(struct igt_fb * fb)796*d83cc019SAndroid Build Coastguard Worker static void clear_yuv_buffer(struct igt_fb *fb)
797*d83cc019SAndroid Build Coastguard Worker {
798*d83cc019SAndroid Build Coastguard Worker bool full_range = fb->color_range == IGT_COLOR_YCBCR_FULL_RANGE;
799*d83cc019SAndroid Build Coastguard Worker uint8_t *ptr;
800*d83cc019SAndroid Build Coastguard Worker
801*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_format_is_yuv(fb->drm_format));
802*d83cc019SAndroid Build Coastguard Worker
803*d83cc019SAndroid Build Coastguard Worker /* Ensure the framebuffer is preallocated */
804*d83cc019SAndroid Build Coastguard Worker ptr = igt_fb_map_buffer(fb->fd, fb);
805*d83cc019SAndroid Build Coastguard Worker igt_assert(*(uint32_t *)ptr == 0);
806*d83cc019SAndroid Build Coastguard Worker
807*d83cc019SAndroid Build Coastguard Worker switch (fb->drm_format) {
808*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
809*d83cc019SAndroid Build Coastguard Worker memset(ptr + fb->offsets[0],
810*d83cc019SAndroid Build Coastguard Worker full_range ? 0x00 : 0x10,
811*d83cc019SAndroid Build Coastguard Worker fb->strides[0] * fb->plane_height[0]);
812*d83cc019SAndroid Build Coastguard Worker memset(ptr + fb->offsets[1],
813*d83cc019SAndroid Build Coastguard Worker 0x80,
814*d83cc019SAndroid Build Coastguard Worker fb->strides[1] * fb->plane_height[1]);
815*d83cc019SAndroid Build Coastguard Worker break;
816*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XYUV8888:
817*d83cc019SAndroid Build Coastguard Worker wmemset((wchar_t*)(ptr + fb->offsets[0]), full_range ? 0x00008080 : 0x00108080,
818*d83cc019SAndroid Build Coastguard Worker fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
819*d83cc019SAndroid Build Coastguard Worker break;
820*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUYV:
821*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVYU:
822*d83cc019SAndroid Build Coastguard Worker wmemset((wchar_t*)(ptr + fb->offsets[0]),
823*d83cc019SAndroid Build Coastguard Worker full_range ? 0x80008000 : 0x80108010,
824*d83cc019SAndroid Build Coastguard Worker fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
825*d83cc019SAndroid Build Coastguard Worker break;
826*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_UYVY:
827*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_VYUY:
828*d83cc019SAndroid Build Coastguard Worker wmemset((wchar_t*)(ptr + fb->offsets[0]),
829*d83cc019SAndroid Build Coastguard Worker full_range ? 0x00800080 : 0x10801080,
830*d83cc019SAndroid Build Coastguard Worker fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
831*d83cc019SAndroid Build Coastguard Worker break;
832*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P010:
833*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P012:
834*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P016:
835*d83cc019SAndroid Build Coastguard Worker wmemset((wchar_t*)ptr, full_range ? 0 : 0x10001000,
836*d83cc019SAndroid Build Coastguard Worker fb->offsets[1] / sizeof(wchar_t));
837*d83cc019SAndroid Build Coastguard Worker wmemset((wchar_t*)(ptr + fb->offsets[1]), 0x80008000,
838*d83cc019SAndroid Build Coastguard Worker fb->strides[1] * fb->plane_height[1] / sizeof(wchar_t));
839*d83cc019SAndroid Build Coastguard Worker break;
840*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y210:
841*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y212:
842*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y216:
843*d83cc019SAndroid Build Coastguard Worker wmemset((wchar_t*)(ptr + fb->offsets[0]),
844*d83cc019SAndroid Build Coastguard Worker full_range ? 0x80000000 : 0x80001000,
845*d83cc019SAndroid Build Coastguard Worker fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
846*d83cc019SAndroid Build Coastguard Worker break;
847*d83cc019SAndroid Build Coastguard Worker
848*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU2101010:
849*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y410:
850*d83cc019SAndroid Build Coastguard Worker wmemset((wchar_t*)(ptr + fb->offsets[0]),
851*d83cc019SAndroid Build Coastguard Worker full_range ? 0x20000200 : 0x20010200,
852*d83cc019SAndroid Build Coastguard Worker fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
853*d83cc019SAndroid Build Coastguard Worker break;
854*d83cc019SAndroid Build Coastguard Worker
855*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU12_16161616:
856*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU16161616:
857*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y412:
858*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y416:
859*d83cc019SAndroid Build Coastguard Worker memset64((uint64_t*)(ptr + fb->offsets[0]),
860*d83cc019SAndroid Build Coastguard Worker full_range ? 0x800000008000ULL : 0x800010008000ULL,
861*d83cc019SAndroid Build Coastguard Worker fb->strides[0] * fb->plane_height[0] / sizeof(uint64_t));
862*d83cc019SAndroid Build Coastguard Worker break;
863*d83cc019SAndroid Build Coastguard Worker }
864*d83cc019SAndroid Build Coastguard Worker
865*d83cc019SAndroid Build Coastguard Worker igt_fb_unmap_buffer(fb, ptr);
866*d83cc019SAndroid Build Coastguard Worker }
867*d83cc019SAndroid Build Coastguard Worker
868*d83cc019SAndroid Build Coastguard Worker /* helpers to create nice-looking framebuffers */
create_bo_for_fb(struct igt_fb * fb)869*d83cc019SAndroid Build Coastguard Worker static int create_bo_for_fb(struct igt_fb *fb)
870*d83cc019SAndroid Build Coastguard Worker {
871*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *fmt = lookup_drm_format(fb->drm_format);
872*d83cc019SAndroid Build Coastguard Worker unsigned int bpp = 0;
873*d83cc019SAndroid Build Coastguard Worker unsigned int plane;
874*d83cc019SAndroid Build Coastguard Worker unsigned *strides = &fb->strides[0];
875*d83cc019SAndroid Build Coastguard Worker bool device_bo = false;
876*d83cc019SAndroid Build Coastguard Worker int fd = fb->fd;
877*d83cc019SAndroid Build Coastguard Worker uint64_t size;
878*d83cc019SAndroid Build Coastguard Worker
879*d83cc019SAndroid Build Coastguard Worker /*
880*d83cc019SAndroid Build Coastguard Worker * The current dumb buffer allocation API doesn't really allow to
881*d83cc019SAndroid Build Coastguard Worker * specify a custom size or stride. Yet the caller is free to specify
882*d83cc019SAndroid Build Coastguard Worker * them, so we need to make sure to use a device BO then.
883*d83cc019SAndroid Build Coastguard Worker */
884*d83cc019SAndroid Build Coastguard Worker if (fb->modifier || fb->size || fb->strides[0] ||
885*d83cc019SAndroid Build Coastguard Worker (is_i915_device(fd) && igt_format_is_yuv(fb->drm_format)) ||
886*d83cc019SAndroid Build Coastguard Worker (is_i915_device(fd) && igt_format_is_fp16(fb->drm_format)) ||
887*d83cc019SAndroid Build Coastguard Worker (is_amdgpu_device(fd) && igt_format_is_yuv(fb->drm_format)))
888*d83cc019SAndroid Build Coastguard Worker device_bo = true;
889*d83cc019SAndroid Build Coastguard Worker
890*d83cc019SAndroid Build Coastguard Worker /* Sets offets and stride if necessary. */
891*d83cc019SAndroid Build Coastguard Worker size = calc_fb_size(fb);
892*d83cc019SAndroid Build Coastguard Worker
893*d83cc019SAndroid Build Coastguard Worker /* Respect the size requested by the caller. */
894*d83cc019SAndroid Build Coastguard Worker if (fb->size == 0)
895*d83cc019SAndroid Build Coastguard Worker fb->size = size;
896*d83cc019SAndroid Build Coastguard Worker
897*d83cc019SAndroid Build Coastguard Worker if (device_bo) {
898*d83cc019SAndroid Build Coastguard Worker fb->is_dumb = false;
899*d83cc019SAndroid Build Coastguard Worker
900*d83cc019SAndroid Build Coastguard Worker if (is_i915_device(fd)) {
901*d83cc019SAndroid Build Coastguard Worker fb->gem_handle = gem_create(fd, fb->size);
902*d83cc019SAndroid Build Coastguard Worker gem_set_tiling(fd, fb->gem_handle,
903*d83cc019SAndroid Build Coastguard Worker igt_fb_mod_to_tiling(fb->modifier),
904*d83cc019SAndroid Build Coastguard Worker fb->strides[0]);
905*d83cc019SAndroid Build Coastguard Worker #if defined(USE_VC4)
906*d83cc019SAndroid Build Coastguard Worker } else if (is_vc4_device(fd)) {
907*d83cc019SAndroid Build Coastguard Worker fb->gem_handle = igt_vc4_create_bo(fd, fb->size);
908*d83cc019SAndroid Build Coastguard Worker
909*d83cc019SAndroid Build Coastguard Worker if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
910*d83cc019SAndroid Build Coastguard Worker igt_vc4_set_tiling(fd, fb->gem_handle,
911*d83cc019SAndroid Build Coastguard Worker fb->modifier);
912*d83cc019SAndroid Build Coastguard Worker #endif
913*d83cc019SAndroid Build Coastguard Worker #if defined(USE_AMD)
914*d83cc019SAndroid Build Coastguard Worker } else if (is_amdgpu_device(fd)) {
915*d83cc019SAndroid Build Coastguard Worker fb->gem_handle = igt_amd_create_bo(fd, fb->size);
916*d83cc019SAndroid Build Coastguard Worker #endif
917*d83cc019SAndroid Build Coastguard Worker } else {
918*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
919*d83cc019SAndroid Build Coastguard Worker }
920*d83cc019SAndroid Build Coastguard Worker
921*d83cc019SAndroid Build Coastguard Worker goto out;
922*d83cc019SAndroid Build Coastguard Worker }
923*d83cc019SAndroid Build Coastguard Worker
924*d83cc019SAndroid Build Coastguard Worker for (plane = 0; plane < fb->num_planes; plane++)
925*d83cc019SAndroid Build Coastguard Worker bpp += DIV_ROUND_UP(fb->plane_bpp[plane],
926*d83cc019SAndroid Build Coastguard Worker plane ? fmt->hsub * fmt->vsub : 1);
927*d83cc019SAndroid Build Coastguard Worker
928*d83cc019SAndroid Build Coastguard Worker fb->is_dumb = true;
929*d83cc019SAndroid Build Coastguard Worker
930*d83cc019SAndroid Build Coastguard Worker /*
931*d83cc019SAndroid Build Coastguard Worker * We can't really pass the stride array here since the dumb
932*d83cc019SAndroid Build Coastguard Worker * buffer allocation is assuming that it operates on one
933*d83cc019SAndroid Build Coastguard Worker * plane, and therefore will calculate the stride as if each
934*d83cc019SAndroid Build Coastguard Worker * pixel was stored on a single plane.
935*d83cc019SAndroid Build Coastguard Worker *
936*d83cc019SAndroid Build Coastguard Worker * This might cause issues at some point on drivers that would
937*d83cc019SAndroid Build Coastguard Worker * change the stride of YUV buffers, but we haven't
938*d83cc019SAndroid Build Coastguard Worker * encountered any yet.
939*d83cc019SAndroid Build Coastguard Worker */
940*d83cc019SAndroid Build Coastguard Worker if (fb->num_planes > 1)
941*d83cc019SAndroid Build Coastguard Worker strides = NULL;
942*d83cc019SAndroid Build Coastguard Worker
943*d83cc019SAndroid Build Coastguard Worker fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
944*d83cc019SAndroid Build Coastguard Worker bpp, strides, &fb->size);
945*d83cc019SAndroid Build Coastguard Worker
946*d83cc019SAndroid Build Coastguard Worker out:
947*d83cc019SAndroid Build Coastguard Worker if (igt_format_is_yuv(fb->drm_format))
948*d83cc019SAndroid Build Coastguard Worker clear_yuv_buffer(fb);
949*d83cc019SAndroid Build Coastguard Worker
950*d83cc019SAndroid Build Coastguard Worker return fb->gem_handle;
951*d83cc019SAndroid Build Coastguard Worker }
952*d83cc019SAndroid Build Coastguard Worker
igt_create_bo_for_fb(int fd,int width,int height,uint32_t format,uint64_t modifier,struct igt_fb * fb)953*d83cc019SAndroid Build Coastguard Worker void igt_create_bo_for_fb(int fd, int width, int height,
954*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier,
955*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb /* out */)
956*d83cc019SAndroid Build Coastguard Worker {
957*d83cc019SAndroid Build Coastguard Worker igt_init_fb(fb, fd, width, height, format, modifier,
958*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_BT709, IGT_COLOR_YCBCR_LIMITED_RANGE);
959*d83cc019SAndroid Build Coastguard Worker create_bo_for_fb(fb);
960*d83cc019SAndroid Build Coastguard Worker }
961*d83cc019SAndroid Build Coastguard Worker
962*d83cc019SAndroid Build Coastguard Worker /**
963*d83cc019SAndroid Build Coastguard Worker * igt_create_bo_with_dimensions:
964*d83cc019SAndroid Build Coastguard Worker * @fd: open drm file descriptor
965*d83cc019SAndroid Build Coastguard Worker * @width: width of the buffer object in pixels
966*d83cc019SAndroid Build Coastguard Worker * @height: height of the buffer object in pixels
967*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
968*d83cc019SAndroid Build Coastguard Worker * @modifier: modifier corresponding to the tiling layout of the buffer object
969*d83cc019SAndroid Build Coastguard Worker * @stride: stride of the buffer object in bytes (0 for automatic stride)
970*d83cc019SAndroid Build Coastguard Worker * @size_ret: size of the buffer object as created by the kernel
971*d83cc019SAndroid Build Coastguard Worker * @stride_ret: stride of the buffer object as created by the kernel
972*d83cc019SAndroid Build Coastguard Worker * @is_dumb: whether the created buffer object is a dumb buffer or not
973*d83cc019SAndroid Build Coastguard Worker *
974*d83cc019SAndroid Build Coastguard Worker * This function allocates a gem buffer object matching the requested
975*d83cc019SAndroid Build Coastguard Worker * properties.
976*d83cc019SAndroid Build Coastguard Worker *
977*d83cc019SAndroid Build Coastguard Worker * Returns:
978*d83cc019SAndroid Build Coastguard Worker * The kms id of the created buffer object.
979*d83cc019SAndroid Build Coastguard Worker */
igt_create_bo_with_dimensions(int fd,int width,int height,uint32_t format,uint64_t modifier,unsigned stride,uint64_t * size_ret,unsigned * stride_ret,bool * is_dumb)980*d83cc019SAndroid Build Coastguard Worker int igt_create_bo_with_dimensions(int fd, int width, int height,
981*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier,
982*d83cc019SAndroid Build Coastguard Worker unsigned stride, uint64_t *size_ret,
983*d83cc019SAndroid Build Coastguard Worker unsigned *stride_ret, bool *is_dumb)
984*d83cc019SAndroid Build Coastguard Worker {
985*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb;
986*d83cc019SAndroid Build Coastguard Worker
987*d83cc019SAndroid Build Coastguard Worker igt_init_fb(&fb, fd, width, height, format, modifier,
988*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_BT709, IGT_COLOR_YCBCR_LIMITED_RANGE);
989*d83cc019SAndroid Build Coastguard Worker
990*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < fb.num_planes; i++)
991*d83cc019SAndroid Build Coastguard Worker fb.strides[i] = stride;
992*d83cc019SAndroid Build Coastguard Worker
993*d83cc019SAndroid Build Coastguard Worker create_bo_for_fb(&fb);
994*d83cc019SAndroid Build Coastguard Worker
995*d83cc019SAndroid Build Coastguard Worker if (size_ret)
996*d83cc019SAndroid Build Coastguard Worker *size_ret = fb.size;
997*d83cc019SAndroid Build Coastguard Worker if (stride_ret)
998*d83cc019SAndroid Build Coastguard Worker *stride_ret = fb.strides[0];
999*d83cc019SAndroid Build Coastguard Worker if (is_dumb)
1000*d83cc019SAndroid Build Coastguard Worker *is_dumb = fb.is_dumb;
1001*d83cc019SAndroid Build Coastguard Worker
1002*d83cc019SAndroid Build Coastguard Worker return fb.gem_handle;
1003*d83cc019SAndroid Build Coastguard Worker }
1004*d83cc019SAndroid Build Coastguard Worker
1005*d83cc019SAndroid Build Coastguard Worker #define get_u16_bit(x, n) ((x & (1 << n)) >> n )
1006*d83cc019SAndroid Build Coastguard Worker #define set_u16_bit(x, n, val) ((x & ~(1 << n)) | (val << n))
1007*d83cc019SAndroid Build Coastguard Worker /*
1008*d83cc019SAndroid Build Coastguard Worker * update_crc16_dp:
1009*d83cc019SAndroid Build Coastguard Worker * @crc_old: old 16-bit CRC value to be updated
1010*d83cc019SAndroid Build Coastguard Worker * @d: input 16-bit data on which to calculate 16-bit CRC
1011*d83cc019SAndroid Build Coastguard Worker *
1012*d83cc019SAndroid Build Coastguard Worker * CRC algorithm implementation described in DP 1.4 spec Appendix J
1013*d83cc019SAndroid Build Coastguard Worker * the 16-bit CRC IBM is applied, with the following polynomial:
1014*d83cc019SAndroid Build Coastguard Worker *
1015*d83cc019SAndroid Build Coastguard Worker * f(x) = x ^ 16 + x ^ 15 + x ^ 2 + 1
1016*d83cc019SAndroid Build Coastguard Worker *
1017*d83cc019SAndroid Build Coastguard Worker * the MSB is shifted in first, for any color format that is less than 16 bits
1018*d83cc019SAndroid Build Coastguard Worker * per component, the LSB is zero-padded.
1019*d83cc019SAndroid Build Coastguard Worker *
1020*d83cc019SAndroid Build Coastguard Worker * The following implementation is based on the hardware parallel 16-bit CRC
1021*d83cc019SAndroid Build Coastguard Worker * generation and ported to C code.
1022*d83cc019SAndroid Build Coastguard Worker *
1023*d83cc019SAndroid Build Coastguard Worker * Reference: VESA DisplayPort Standard v1.4, appendix J
1024*d83cc019SAndroid Build Coastguard Worker *
1025*d83cc019SAndroid Build Coastguard Worker * Returns:
1026*d83cc019SAndroid Build Coastguard Worker * updated 16-bit CRC value.
1027*d83cc019SAndroid Build Coastguard Worker */
update_crc16_dp(uint16_t crc_old,uint16_t d)1028*d83cc019SAndroid Build Coastguard Worker static uint16_t update_crc16_dp(uint16_t crc_old, uint16_t d)
1029*d83cc019SAndroid Build Coastguard Worker {
1030*d83cc019SAndroid Build Coastguard Worker uint16_t crc_new = 0; /* 16-bit CRC output */
1031*d83cc019SAndroid Build Coastguard Worker
1032*d83cc019SAndroid Build Coastguard Worker /* internal use */
1033*d83cc019SAndroid Build Coastguard Worker uint16_t b = crc_old;
1034*d83cc019SAndroid Build Coastguard Worker uint8_t val;
1035*d83cc019SAndroid Build Coastguard Worker
1036*d83cc019SAndroid Build Coastguard Worker /* b[15] */
1037*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 0) ^ get_u16_bit(b, 1) ^ get_u16_bit(b, 2) ^
1038*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 3) ^ get_u16_bit(b, 4) ^ get_u16_bit(b, 5) ^
1039*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 6) ^ get_u16_bit(b, 7) ^ get_u16_bit(b, 8) ^
1040*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 9) ^ get_u16_bit(b, 10) ^ get_u16_bit(b, 11) ^
1041*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 12) ^ get_u16_bit(b, 14) ^ get_u16_bit(b, 15) ^
1042*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 0) ^ get_u16_bit(d, 1) ^ get_u16_bit(d, 2) ^
1043*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 3) ^ get_u16_bit(d, 4) ^ get_u16_bit(d, 5) ^
1044*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 6) ^ get_u16_bit(d, 7) ^ get_u16_bit(d, 8) ^
1045*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 9) ^ get_u16_bit(d, 10) ^ get_u16_bit(d, 11) ^
1046*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 12) ^ get_u16_bit(d, 14) ^ get_u16_bit(d, 15);
1047*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 15, val);
1048*d83cc019SAndroid Build Coastguard Worker
1049*d83cc019SAndroid Build Coastguard Worker /* b[14] */
1050*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 12) ^ get_u16_bit(b, 13) ^
1051*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 12) ^ get_u16_bit(d, 13);
1052*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 14, val);
1053*d83cc019SAndroid Build Coastguard Worker
1054*d83cc019SAndroid Build Coastguard Worker /* b[13] */
1055*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 11) ^ get_u16_bit(b, 12) ^
1056*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 11) ^ get_u16_bit(d, 12);
1057*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 13, val);
1058*d83cc019SAndroid Build Coastguard Worker
1059*d83cc019SAndroid Build Coastguard Worker /* b[12] */
1060*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 10) ^ get_u16_bit(b, 11) ^
1061*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 10) ^ get_u16_bit(d, 11);
1062*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 12, val);
1063*d83cc019SAndroid Build Coastguard Worker
1064*d83cc019SAndroid Build Coastguard Worker /* b[11] */
1065*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 9) ^ get_u16_bit(b, 10) ^
1066*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 9) ^ get_u16_bit(d, 10);
1067*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 11, val);
1068*d83cc019SAndroid Build Coastguard Worker
1069*d83cc019SAndroid Build Coastguard Worker /* b[10] */
1070*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 8) ^ get_u16_bit(b, 9) ^
1071*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 8) ^ get_u16_bit(d, 9);
1072*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 10, val);
1073*d83cc019SAndroid Build Coastguard Worker
1074*d83cc019SAndroid Build Coastguard Worker /* b[9] */
1075*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 7) ^ get_u16_bit(b, 8) ^
1076*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 7) ^ get_u16_bit(d, 8);
1077*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 9, val);
1078*d83cc019SAndroid Build Coastguard Worker
1079*d83cc019SAndroid Build Coastguard Worker /* b[8] */
1080*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 6) ^ get_u16_bit(b, 7) ^
1081*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 6) ^ get_u16_bit(d, 7);
1082*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 8, val);
1083*d83cc019SAndroid Build Coastguard Worker
1084*d83cc019SAndroid Build Coastguard Worker /* b[7] */
1085*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 5) ^ get_u16_bit(b, 6) ^
1086*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 5) ^ get_u16_bit(d, 6);
1087*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 7, val);
1088*d83cc019SAndroid Build Coastguard Worker
1089*d83cc019SAndroid Build Coastguard Worker /* b[6] */
1090*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 4) ^ get_u16_bit(b, 5) ^
1091*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 4) ^ get_u16_bit(d, 5);
1092*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 6, val);
1093*d83cc019SAndroid Build Coastguard Worker
1094*d83cc019SAndroid Build Coastguard Worker /* b[5] */
1095*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 3) ^ get_u16_bit(b, 4) ^
1096*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 3) ^ get_u16_bit(d, 4);
1097*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 5, val);
1098*d83cc019SAndroid Build Coastguard Worker
1099*d83cc019SAndroid Build Coastguard Worker /* b[4] */
1100*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 2) ^ get_u16_bit(b, 3) ^
1101*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 2) ^ get_u16_bit(d, 3);
1102*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 4, val);
1103*d83cc019SAndroid Build Coastguard Worker
1104*d83cc019SAndroid Build Coastguard Worker /* b[3] */
1105*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 1) ^ get_u16_bit(b, 2) ^ get_u16_bit(b, 15) ^
1106*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 1) ^ get_u16_bit(d, 2) ^ get_u16_bit(d, 15);
1107*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 3, val);
1108*d83cc019SAndroid Build Coastguard Worker
1109*d83cc019SAndroid Build Coastguard Worker /* b[2] */
1110*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 0) ^ get_u16_bit(b, 1) ^ get_u16_bit(b, 14) ^
1111*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 0) ^ get_u16_bit(d, 1) ^ get_u16_bit(d, 14);
1112*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 2, val);
1113*d83cc019SAndroid Build Coastguard Worker
1114*d83cc019SAndroid Build Coastguard Worker /* b[1] */
1115*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 1) ^ get_u16_bit(b, 2) ^ get_u16_bit(b, 3) ^
1116*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 4) ^ get_u16_bit(b, 5) ^ get_u16_bit(b, 6) ^
1117*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 7) ^ get_u16_bit(b, 8) ^ get_u16_bit(b, 9) ^
1118*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 10) ^ get_u16_bit(b, 11) ^ get_u16_bit(b, 12) ^
1119*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 13) ^ get_u16_bit(b, 14) ^
1120*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 1) ^ get_u16_bit(d, 2) ^ get_u16_bit(d, 3) ^
1121*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 4) ^ get_u16_bit(d, 5) ^ get_u16_bit(d, 6) ^
1122*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 7) ^ get_u16_bit(d, 8) ^ get_u16_bit(d, 9) ^
1123*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 10) ^ get_u16_bit(d, 11) ^ get_u16_bit(d, 12) ^
1124*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 13) ^ get_u16_bit(d, 14);
1125*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 1, val);
1126*d83cc019SAndroid Build Coastguard Worker
1127*d83cc019SAndroid Build Coastguard Worker /* b[0] */
1128*d83cc019SAndroid Build Coastguard Worker val = get_u16_bit(b, 0) ^ get_u16_bit(b, 1) ^ get_u16_bit(b, 2) ^
1129*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 3) ^ get_u16_bit(b, 4) ^ get_u16_bit(b, 5) ^
1130*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 6) ^ get_u16_bit(b, 7) ^ get_u16_bit(b, 8) ^
1131*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 9) ^ get_u16_bit(b, 10) ^ get_u16_bit(b, 11) ^
1132*d83cc019SAndroid Build Coastguard Worker get_u16_bit(b, 12) ^ get_u16_bit(b, 13) ^ get_u16_bit(b, 15) ^
1133*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 0) ^ get_u16_bit(d, 1) ^ get_u16_bit(d, 2) ^
1134*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 3) ^ get_u16_bit(d, 4) ^ get_u16_bit(d, 5) ^
1135*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 6) ^ get_u16_bit(d, 7) ^ get_u16_bit(d, 8) ^
1136*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 9) ^ get_u16_bit(d, 10) ^ get_u16_bit(d, 11) ^
1137*d83cc019SAndroid Build Coastguard Worker get_u16_bit(d, 12) ^ get_u16_bit(d, 13) ^ get_u16_bit(d, 15);
1138*d83cc019SAndroid Build Coastguard Worker crc_new = set_u16_bit(crc_new, 0, val);
1139*d83cc019SAndroid Build Coastguard Worker
1140*d83cc019SAndroid Build Coastguard Worker return crc_new;
1141*d83cc019SAndroid Build Coastguard Worker }
1142*d83cc019SAndroid Build Coastguard Worker
1143*d83cc019SAndroid Build Coastguard Worker /**
1144*d83cc019SAndroid Build Coastguard Worker * igt_fb_calc_crc:
1145*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
1146*d83cc019SAndroid Build Coastguard Worker * @crc: pointer to an #igt_crc_t structure
1147*d83cc019SAndroid Build Coastguard Worker *
1148*d83cc019SAndroid Build Coastguard Worker * This function calculate the 16-bit frame CRC of RGB components over all
1149*d83cc019SAndroid Build Coastguard Worker * the active pixels.
1150*d83cc019SAndroid Build Coastguard Worker */
igt_fb_calc_crc(struct igt_fb * fb,igt_crc_t * crc)1151*d83cc019SAndroid Build Coastguard Worker void igt_fb_calc_crc(struct igt_fb *fb, igt_crc_t *crc)
1152*d83cc019SAndroid Build Coastguard Worker {
1153*d83cc019SAndroid Build Coastguard Worker int x, y, i;
1154*d83cc019SAndroid Build Coastguard Worker uint8_t *ptr;
1155*d83cc019SAndroid Build Coastguard Worker uint8_t *data;
1156*d83cc019SAndroid Build Coastguard Worker uint16_t din;
1157*d83cc019SAndroid Build Coastguard Worker
1158*d83cc019SAndroid Build Coastguard Worker igt_assert(fb && crc);
1159*d83cc019SAndroid Build Coastguard Worker
1160*d83cc019SAndroid Build Coastguard Worker ptr = igt_fb_map_buffer(fb->fd, fb);
1161*d83cc019SAndroid Build Coastguard Worker igt_assert(ptr);
1162*d83cc019SAndroid Build Coastguard Worker
1163*d83cc019SAndroid Build Coastguard Worker /* set for later CRC comparison */
1164*d83cc019SAndroid Build Coastguard Worker crc->has_valid_frame = true;
1165*d83cc019SAndroid Build Coastguard Worker crc->frame = 0;
1166*d83cc019SAndroid Build Coastguard Worker crc->n_words = 3;
1167*d83cc019SAndroid Build Coastguard Worker crc->crc[0] = 0; /* R */
1168*d83cc019SAndroid Build Coastguard Worker crc->crc[1] = 0; /* G */
1169*d83cc019SAndroid Build Coastguard Worker crc->crc[2] = 0; /* B */
1170*d83cc019SAndroid Build Coastguard Worker
1171*d83cc019SAndroid Build Coastguard Worker data = ptr + fb->offsets[0];
1172*d83cc019SAndroid Build Coastguard Worker for (y = 0; y < fb->height; ++y) {
1173*d83cc019SAndroid Build Coastguard Worker for (x = 0; x < fb->width; ++x) {
1174*d83cc019SAndroid Build Coastguard Worker switch (fb->drm_format) {
1175*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XRGB8888:
1176*d83cc019SAndroid Build Coastguard Worker i = x * 4 + y * fb->strides[0];
1177*d83cc019SAndroid Build Coastguard Worker
1178*d83cc019SAndroid Build Coastguard Worker din = data[i + 2] << 8; /* padding-zeros */
1179*d83cc019SAndroid Build Coastguard Worker crc->crc[0] = update_crc16_dp(crc->crc[0], din);
1180*d83cc019SAndroid Build Coastguard Worker
1181*d83cc019SAndroid Build Coastguard Worker /* Green-component */
1182*d83cc019SAndroid Build Coastguard Worker din = data[i + 1] << 8;
1183*d83cc019SAndroid Build Coastguard Worker crc->crc[1] = update_crc16_dp(crc->crc[1], din);
1184*d83cc019SAndroid Build Coastguard Worker
1185*d83cc019SAndroid Build Coastguard Worker /* Blue-component */
1186*d83cc019SAndroid Build Coastguard Worker din = data[i] << 8;
1187*d83cc019SAndroid Build Coastguard Worker crc->crc[2] = update_crc16_dp(crc->crc[2], din);
1188*d83cc019SAndroid Build Coastguard Worker break;
1189*d83cc019SAndroid Build Coastguard Worker default:
1190*d83cc019SAndroid Build Coastguard Worker igt_assert_f(0, "DRM Format Invalid");
1191*d83cc019SAndroid Build Coastguard Worker break;
1192*d83cc019SAndroid Build Coastguard Worker }
1193*d83cc019SAndroid Build Coastguard Worker }
1194*d83cc019SAndroid Build Coastguard Worker }
1195*d83cc019SAndroid Build Coastguard Worker
1196*d83cc019SAndroid Build Coastguard Worker igt_fb_unmap_buffer(fb, ptr);
1197*d83cc019SAndroid Build Coastguard Worker }
1198*d83cc019SAndroid Build Coastguard Worker
1199*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
1200*d83cc019SAndroid Build Coastguard Worker /**
1201*d83cc019SAndroid Build Coastguard Worker * igt_paint_color:
1202*d83cc019SAndroid Build Coastguard Worker * @cr: cairo drawing context
1203*d83cc019SAndroid Build Coastguard Worker * @x: pixel x-coordination of the fill rectangle
1204*d83cc019SAndroid Build Coastguard Worker * @y: pixel y-coordination of the fill rectangle
1205*d83cc019SAndroid Build Coastguard Worker * @w: width of the fill rectangle
1206*d83cc019SAndroid Build Coastguard Worker * @h: height of the fill rectangle
1207*d83cc019SAndroid Build Coastguard Worker * @r: red value to use as fill color
1208*d83cc019SAndroid Build Coastguard Worker * @g: green value to use as fill color
1209*d83cc019SAndroid Build Coastguard Worker * @b: blue value to use as fill color
1210*d83cc019SAndroid Build Coastguard Worker *
1211*d83cc019SAndroid Build Coastguard Worker * This functions draws a solid rectangle with the given color using the drawing
1212*d83cc019SAndroid Build Coastguard Worker * context @cr.
1213*d83cc019SAndroid Build Coastguard Worker */
igt_paint_color(cairo_t * cr,int x,int y,int w,int h,double r,double g,double b)1214*d83cc019SAndroid Build Coastguard Worker void igt_paint_color(cairo_t *cr, int x, int y, int w, int h,
1215*d83cc019SAndroid Build Coastguard Worker double r, double g, double b)
1216*d83cc019SAndroid Build Coastguard Worker {
1217*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(cr, x, y, w, h);
1218*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(cr, r, g, b);
1219*d83cc019SAndroid Build Coastguard Worker cairo_fill(cr);
1220*d83cc019SAndroid Build Coastguard Worker }
1221*d83cc019SAndroid Build Coastguard Worker
1222*d83cc019SAndroid Build Coastguard Worker /**
1223*d83cc019SAndroid Build Coastguard Worker * igt_paint_color_alpha:
1224*d83cc019SAndroid Build Coastguard Worker * @cr: cairo drawing context
1225*d83cc019SAndroid Build Coastguard Worker * @x: pixel x-coordination of the fill rectangle
1226*d83cc019SAndroid Build Coastguard Worker * @y: pixel y-coordination of the fill rectangle
1227*d83cc019SAndroid Build Coastguard Worker * @w: width of the fill rectangle
1228*d83cc019SAndroid Build Coastguard Worker * @h: height of the fill rectangle
1229*d83cc019SAndroid Build Coastguard Worker * @r: red value to use as fill color
1230*d83cc019SAndroid Build Coastguard Worker * @g: green value to use as fill color
1231*d83cc019SAndroid Build Coastguard Worker * @b: blue value to use as fill color
1232*d83cc019SAndroid Build Coastguard Worker * @a: alpha value to use as fill color
1233*d83cc019SAndroid Build Coastguard Worker *
1234*d83cc019SAndroid Build Coastguard Worker * This functions draws a rectangle with the given color and alpha values using
1235*d83cc019SAndroid Build Coastguard Worker * the drawing context @cr.
1236*d83cc019SAndroid Build Coastguard Worker */
igt_paint_color_alpha(cairo_t * cr,int x,int y,int w,int h,double r,double g,double b,double a)1237*d83cc019SAndroid Build Coastguard Worker void igt_paint_color_alpha(cairo_t *cr, int x, int y, int w, int h,
1238*d83cc019SAndroid Build Coastguard Worker double r, double g, double b, double a)
1239*d83cc019SAndroid Build Coastguard Worker {
1240*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(cr, x, y, w, h);
1241*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgba(cr, r, g, b, a);
1242*d83cc019SAndroid Build Coastguard Worker cairo_fill(cr);
1243*d83cc019SAndroid Build Coastguard Worker }
1244*d83cc019SAndroid Build Coastguard Worker
1245*d83cc019SAndroid Build Coastguard Worker /**
1246*d83cc019SAndroid Build Coastguard Worker * igt_paint_color_gradient:
1247*d83cc019SAndroid Build Coastguard Worker * @cr: cairo drawing context
1248*d83cc019SAndroid Build Coastguard Worker * @x: pixel x-coordination of the fill rectangle
1249*d83cc019SAndroid Build Coastguard Worker * @y: pixel y-coordination of the fill rectangle
1250*d83cc019SAndroid Build Coastguard Worker * @w: width of the fill rectangle
1251*d83cc019SAndroid Build Coastguard Worker * @h: height of the fill rectangle
1252*d83cc019SAndroid Build Coastguard Worker * @r: red value to use as fill color
1253*d83cc019SAndroid Build Coastguard Worker * @g: green value to use as fill color
1254*d83cc019SAndroid Build Coastguard Worker * @b: blue value to use as fill color
1255*d83cc019SAndroid Build Coastguard Worker *
1256*d83cc019SAndroid Build Coastguard Worker * This functions draws a gradient into the rectangle which fades in from black
1257*d83cc019SAndroid Build Coastguard Worker * to the given values using the drawing context @cr.
1258*d83cc019SAndroid Build Coastguard Worker */
1259*d83cc019SAndroid Build Coastguard Worker void
igt_paint_color_gradient(cairo_t * cr,int x,int y,int w,int h,int r,int g,int b)1260*d83cc019SAndroid Build Coastguard Worker igt_paint_color_gradient(cairo_t *cr, int x, int y, int w, int h,
1261*d83cc019SAndroid Build Coastguard Worker int r, int g, int b)
1262*d83cc019SAndroid Build Coastguard Worker {
1263*d83cc019SAndroid Build Coastguard Worker cairo_pattern_t *pat;
1264*d83cc019SAndroid Build Coastguard Worker
1265*d83cc019SAndroid Build Coastguard Worker pat = cairo_pattern_create_linear(x, y, x + w, y + h);
1266*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(pat, 1, 0, 0, 0, 1);
1267*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(pat, 0, r, g, b, 1);
1268*d83cc019SAndroid Build Coastguard Worker
1269*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(cr, x, y, w, h);
1270*d83cc019SAndroid Build Coastguard Worker cairo_set_source(cr, pat);
1271*d83cc019SAndroid Build Coastguard Worker cairo_fill(cr);
1272*d83cc019SAndroid Build Coastguard Worker cairo_pattern_destroy(pat);
1273*d83cc019SAndroid Build Coastguard Worker }
1274*d83cc019SAndroid Build Coastguard Worker
1275*d83cc019SAndroid Build Coastguard Worker /**
1276*d83cc019SAndroid Build Coastguard Worker * igt_paint_color_gradient_range:
1277*d83cc019SAndroid Build Coastguard Worker * @cr: cairo drawing context
1278*d83cc019SAndroid Build Coastguard Worker * @x: pixel x-coordination of the fill rectangle
1279*d83cc019SAndroid Build Coastguard Worker * @y: pixel y-coordination of the fill rectangle
1280*d83cc019SAndroid Build Coastguard Worker * @w: width of the fill rectangle
1281*d83cc019SAndroid Build Coastguard Worker * @h: height of the fill rectangle
1282*d83cc019SAndroid Build Coastguard Worker * @sr: red value to use as start gradient color
1283*d83cc019SAndroid Build Coastguard Worker * @sg: green value to use as start gradient color
1284*d83cc019SAndroid Build Coastguard Worker * @sb: blue value to use as start gradient color
1285*d83cc019SAndroid Build Coastguard Worker * @er: red value to use as end gradient color
1286*d83cc019SAndroid Build Coastguard Worker * @eg: green value to use as end gradient color
1287*d83cc019SAndroid Build Coastguard Worker * @eb: blue value to use as end gradient color
1288*d83cc019SAndroid Build Coastguard Worker *
1289*d83cc019SAndroid Build Coastguard Worker * This functions draws a gradient into the rectangle which fades in
1290*d83cc019SAndroid Build Coastguard Worker * from one color to the other using the drawing context @cr.
1291*d83cc019SAndroid Build Coastguard Worker */
1292*d83cc019SAndroid Build Coastguard Worker void
igt_paint_color_gradient_range(cairo_t * cr,int x,int y,int w,int h,double sr,double sg,double sb,double er,double eg,double eb)1293*d83cc019SAndroid Build Coastguard Worker igt_paint_color_gradient_range(cairo_t *cr, int x, int y, int w, int h,
1294*d83cc019SAndroid Build Coastguard Worker double sr, double sg, double sb,
1295*d83cc019SAndroid Build Coastguard Worker double er, double eg, double eb)
1296*d83cc019SAndroid Build Coastguard Worker {
1297*d83cc019SAndroid Build Coastguard Worker cairo_pattern_t *pat;
1298*d83cc019SAndroid Build Coastguard Worker
1299*d83cc019SAndroid Build Coastguard Worker pat = cairo_pattern_create_linear(x, y, x + w, y + h);
1300*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(pat, 1, sr, sg, sb, 1);
1301*d83cc019SAndroid Build Coastguard Worker cairo_pattern_add_color_stop_rgba(pat, 0, er, eg, eb, 1);
1302*d83cc019SAndroid Build Coastguard Worker
1303*d83cc019SAndroid Build Coastguard Worker cairo_rectangle(cr, x, y, w, h);
1304*d83cc019SAndroid Build Coastguard Worker cairo_set_source(cr, pat);
1305*d83cc019SAndroid Build Coastguard Worker cairo_fill(cr);
1306*d83cc019SAndroid Build Coastguard Worker cairo_pattern_destroy(pat);
1307*d83cc019SAndroid Build Coastguard Worker }
1308*d83cc019SAndroid Build Coastguard Worker
1309*d83cc019SAndroid Build Coastguard Worker static void
paint_test_patterns(cairo_t * cr,int width,int height)1310*d83cc019SAndroid Build Coastguard Worker paint_test_patterns(cairo_t *cr, int width, int height)
1311*d83cc019SAndroid Build Coastguard Worker {
1312*d83cc019SAndroid Build Coastguard Worker double gr_height, gr_width;
1313*d83cc019SAndroid Build Coastguard Worker int x, y;
1314*d83cc019SAndroid Build Coastguard Worker
1315*d83cc019SAndroid Build Coastguard Worker y = height * 0.10;
1316*d83cc019SAndroid Build Coastguard Worker gr_width = width * 0.75;
1317*d83cc019SAndroid Build Coastguard Worker gr_height = height * 0.08;
1318*d83cc019SAndroid Build Coastguard Worker x = (width / 2) - (gr_width / 2);
1319*d83cc019SAndroid Build Coastguard Worker
1320*d83cc019SAndroid Build Coastguard Worker igt_paint_color_gradient(cr, x, y, gr_width, gr_height, 1, 0, 0);
1321*d83cc019SAndroid Build Coastguard Worker
1322*d83cc019SAndroid Build Coastguard Worker y += gr_height;
1323*d83cc019SAndroid Build Coastguard Worker igt_paint_color_gradient(cr, x, y, gr_width, gr_height, 0, 1, 0);
1324*d83cc019SAndroid Build Coastguard Worker
1325*d83cc019SAndroid Build Coastguard Worker y += gr_height;
1326*d83cc019SAndroid Build Coastguard Worker igt_paint_color_gradient(cr, x, y, gr_width, gr_height, 0, 0, 1);
1327*d83cc019SAndroid Build Coastguard Worker
1328*d83cc019SAndroid Build Coastguard Worker y += gr_height;
1329*d83cc019SAndroid Build Coastguard Worker igt_paint_color_gradient(cr, x, y, gr_width, gr_height, 1, 1, 1);
1330*d83cc019SAndroid Build Coastguard Worker }
1331*d83cc019SAndroid Build Coastguard Worker
1332*d83cc019SAndroid Build Coastguard Worker /**
1333*d83cc019SAndroid Build Coastguard Worker * igt_cairo_printf_line:
1334*d83cc019SAndroid Build Coastguard Worker * @cr: cairo drawing context
1335*d83cc019SAndroid Build Coastguard Worker * @align: text alignment
1336*d83cc019SAndroid Build Coastguard Worker * @yspacing: additional y-direction feed after this line
1337*d83cc019SAndroid Build Coastguard Worker * @fmt: format string
1338*d83cc019SAndroid Build Coastguard Worker * @...: optional arguments used in the format string
1339*d83cc019SAndroid Build Coastguard Worker *
1340*d83cc019SAndroid Build Coastguard Worker * This is a little helper to draw text onto framebuffers. All the initial setup
1341*d83cc019SAndroid Build Coastguard Worker * (like setting the font size and the moving to the starting position) still
1342*d83cc019SAndroid Build Coastguard Worker * needs to be done manually with explicit cairo calls on @cr.
1343*d83cc019SAndroid Build Coastguard Worker *
1344*d83cc019SAndroid Build Coastguard Worker * Returns:
1345*d83cc019SAndroid Build Coastguard Worker * The width of the drawn text.
1346*d83cc019SAndroid Build Coastguard Worker */
igt_cairo_printf_line(cairo_t * cr,enum igt_text_align align,double yspacing,const char * fmt,...)1347*d83cc019SAndroid Build Coastguard Worker int igt_cairo_printf_line(cairo_t *cr, enum igt_text_align align,
1348*d83cc019SAndroid Build Coastguard Worker double yspacing, const char *fmt, ...)
1349*d83cc019SAndroid Build Coastguard Worker {
1350*d83cc019SAndroid Build Coastguard Worker double x, y, xofs, yofs;
1351*d83cc019SAndroid Build Coastguard Worker cairo_text_extents_t extents;
1352*d83cc019SAndroid Build Coastguard Worker char *text;
1353*d83cc019SAndroid Build Coastguard Worker va_list ap;
1354*d83cc019SAndroid Build Coastguard Worker int ret;
1355*d83cc019SAndroid Build Coastguard Worker
1356*d83cc019SAndroid Build Coastguard Worker va_start(ap, fmt);
1357*d83cc019SAndroid Build Coastguard Worker ret = vasprintf(&text, fmt, ap);
1358*d83cc019SAndroid Build Coastguard Worker igt_assert(ret >= 0);
1359*d83cc019SAndroid Build Coastguard Worker va_end(ap);
1360*d83cc019SAndroid Build Coastguard Worker
1361*d83cc019SAndroid Build Coastguard Worker cairo_text_extents(cr, text, &extents);
1362*d83cc019SAndroid Build Coastguard Worker
1363*d83cc019SAndroid Build Coastguard Worker xofs = yofs = 0;
1364*d83cc019SAndroid Build Coastguard Worker if (align & align_right)
1365*d83cc019SAndroid Build Coastguard Worker xofs = -extents.width;
1366*d83cc019SAndroid Build Coastguard Worker else if (align & align_hcenter)
1367*d83cc019SAndroid Build Coastguard Worker xofs = -extents.width / 2;
1368*d83cc019SAndroid Build Coastguard Worker
1369*d83cc019SAndroid Build Coastguard Worker if (align & align_top)
1370*d83cc019SAndroid Build Coastguard Worker yofs = extents.height;
1371*d83cc019SAndroid Build Coastguard Worker else if (align & align_vcenter)
1372*d83cc019SAndroid Build Coastguard Worker yofs = extents.height / 2;
1373*d83cc019SAndroid Build Coastguard Worker
1374*d83cc019SAndroid Build Coastguard Worker cairo_get_current_point(cr, &x, &y);
1375*d83cc019SAndroid Build Coastguard Worker if (xofs || yofs)
1376*d83cc019SAndroid Build Coastguard Worker cairo_rel_move_to(cr, xofs, yofs);
1377*d83cc019SAndroid Build Coastguard Worker
1378*d83cc019SAndroid Build Coastguard Worker cairo_text_path(cr, text);
1379*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(cr, 0, 0, 0);
1380*d83cc019SAndroid Build Coastguard Worker cairo_stroke_preserve(cr);
1381*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(cr, 1, 1, 1);
1382*d83cc019SAndroid Build Coastguard Worker cairo_fill(cr);
1383*d83cc019SAndroid Build Coastguard Worker
1384*d83cc019SAndroid Build Coastguard Worker cairo_move_to(cr, x, y + extents.height + yspacing);
1385*d83cc019SAndroid Build Coastguard Worker
1386*d83cc019SAndroid Build Coastguard Worker free(text);
1387*d83cc019SAndroid Build Coastguard Worker
1388*d83cc019SAndroid Build Coastguard Worker return extents.width;
1389*d83cc019SAndroid Build Coastguard Worker }
1390*d83cc019SAndroid Build Coastguard Worker
1391*d83cc019SAndroid Build Coastguard Worker static void
paint_marker(cairo_t * cr,int x,int y)1392*d83cc019SAndroid Build Coastguard Worker paint_marker(cairo_t *cr, int x, int y)
1393*d83cc019SAndroid Build Coastguard Worker {
1394*d83cc019SAndroid Build Coastguard Worker enum igt_text_align align;
1395*d83cc019SAndroid Build Coastguard Worker int xoff, yoff;
1396*d83cc019SAndroid Build Coastguard Worker
1397*d83cc019SAndroid Build Coastguard Worker cairo_move_to(cr, x, y - 20);
1398*d83cc019SAndroid Build Coastguard Worker cairo_line_to(cr, x, y + 20);
1399*d83cc019SAndroid Build Coastguard Worker cairo_move_to(cr, x - 20, y);
1400*d83cc019SAndroid Build Coastguard Worker cairo_line_to(cr, x + 20, y);
1401*d83cc019SAndroid Build Coastguard Worker cairo_new_sub_path(cr);
1402*d83cc019SAndroid Build Coastguard Worker cairo_arc(cr, x, y, 10, 0, M_PI * 2);
1403*d83cc019SAndroid Build Coastguard Worker cairo_set_line_width(cr, 4);
1404*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(cr, 0, 0, 0);
1405*d83cc019SAndroid Build Coastguard Worker cairo_stroke_preserve(cr);
1406*d83cc019SAndroid Build Coastguard Worker cairo_set_source_rgb(cr, 1, 1, 1);
1407*d83cc019SAndroid Build Coastguard Worker cairo_set_line_width(cr, 2);
1408*d83cc019SAndroid Build Coastguard Worker cairo_stroke(cr);
1409*d83cc019SAndroid Build Coastguard Worker
1410*d83cc019SAndroid Build Coastguard Worker xoff = x ? -20 : 20;
1411*d83cc019SAndroid Build Coastguard Worker align = x ? align_right : align_left;
1412*d83cc019SAndroid Build Coastguard Worker
1413*d83cc019SAndroid Build Coastguard Worker yoff = y ? -20 : 20;
1414*d83cc019SAndroid Build Coastguard Worker align |= y ? align_bottom : align_top;
1415*d83cc019SAndroid Build Coastguard Worker
1416*d83cc019SAndroid Build Coastguard Worker cairo_move_to(cr, x + xoff, y + yoff);
1417*d83cc019SAndroid Build Coastguard Worker cairo_set_font_size(cr, 18);
1418*d83cc019SAndroid Build Coastguard Worker igt_cairo_printf_line(cr, align, 0, "(%d, %d)", x, y);
1419*d83cc019SAndroid Build Coastguard Worker }
1420*d83cc019SAndroid Build Coastguard Worker
1421*d83cc019SAndroid Build Coastguard Worker /**
1422*d83cc019SAndroid Build Coastguard Worker * igt_paint_test_pattern:
1423*d83cc019SAndroid Build Coastguard Worker * @cr: cairo drawing context
1424*d83cc019SAndroid Build Coastguard Worker * @width: width of the visible area
1425*d83cc019SAndroid Build Coastguard Worker * @height: height of the visible area
1426*d83cc019SAndroid Build Coastguard Worker *
1427*d83cc019SAndroid Build Coastguard Worker * This functions draws an entire set of test patterns for the given visible
1428*d83cc019SAndroid Build Coastguard Worker * area using the drawing context @cr. This is useful for manual visual
1429*d83cc019SAndroid Build Coastguard Worker * inspection of displayed framebuffers.
1430*d83cc019SAndroid Build Coastguard Worker *
1431*d83cc019SAndroid Build Coastguard Worker * The test patterns include
1432*d83cc019SAndroid Build Coastguard Worker * - corner markers to check for over/underscan and
1433*d83cc019SAndroid Build Coastguard Worker * - a set of color and b/w gradients.
1434*d83cc019SAndroid Build Coastguard Worker */
igt_paint_test_pattern(cairo_t * cr,int width,int height)1435*d83cc019SAndroid Build Coastguard Worker void igt_paint_test_pattern(cairo_t *cr, int width, int height)
1436*d83cc019SAndroid Build Coastguard Worker {
1437*d83cc019SAndroid Build Coastguard Worker paint_test_patterns(cr, width, height);
1438*d83cc019SAndroid Build Coastguard Worker
1439*d83cc019SAndroid Build Coastguard Worker cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
1440*d83cc019SAndroid Build Coastguard Worker
1441*d83cc019SAndroid Build Coastguard Worker /* Paint corner markers */
1442*d83cc019SAndroid Build Coastguard Worker paint_marker(cr, 0, 0);
1443*d83cc019SAndroid Build Coastguard Worker paint_marker(cr, width, 0);
1444*d83cc019SAndroid Build Coastguard Worker paint_marker(cr, 0, height);
1445*d83cc019SAndroid Build Coastguard Worker paint_marker(cr, width, height);
1446*d83cc019SAndroid Build Coastguard Worker
1447*d83cc019SAndroid Build Coastguard Worker igt_assert(!cairo_status(cr));
1448*d83cc019SAndroid Build Coastguard Worker }
1449*d83cc019SAndroid Build Coastguard Worker
1450*d83cc019SAndroid Build Coastguard Worker static cairo_status_t
stdio_read_func(void * closure,unsigned char * data,unsigned int size)1451*d83cc019SAndroid Build Coastguard Worker stdio_read_func(void *closure, unsigned char* data, unsigned int size)
1452*d83cc019SAndroid Build Coastguard Worker {
1453*d83cc019SAndroid Build Coastguard Worker if (fread(data, 1, size, (FILE*)closure) != size)
1454*d83cc019SAndroid Build Coastguard Worker return CAIRO_STATUS_READ_ERROR;
1455*d83cc019SAndroid Build Coastguard Worker
1456*d83cc019SAndroid Build Coastguard Worker return CAIRO_STATUS_SUCCESS;
1457*d83cc019SAndroid Build Coastguard Worker }
1458*d83cc019SAndroid Build Coastguard Worker
igt_cairo_image_surface_create_from_png(const char * filename)1459*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *igt_cairo_image_surface_create_from_png(const char *filename)
1460*d83cc019SAndroid Build Coastguard Worker {
1461*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *image;
1462*d83cc019SAndroid Build Coastguard Worker FILE *f;
1463*d83cc019SAndroid Build Coastguard Worker
1464*d83cc019SAndroid Build Coastguard Worker f = igt_fopen_data(filename);
1465*d83cc019SAndroid Build Coastguard Worker image = cairo_image_surface_create_from_png_stream(&stdio_read_func, f);
1466*d83cc019SAndroid Build Coastguard Worker fclose(f);
1467*d83cc019SAndroid Build Coastguard Worker
1468*d83cc019SAndroid Build Coastguard Worker return image;
1469*d83cc019SAndroid Build Coastguard Worker }
1470*d83cc019SAndroid Build Coastguard Worker
1471*d83cc019SAndroid Build Coastguard Worker /**
1472*d83cc019SAndroid Build Coastguard Worker * igt_paint_image:
1473*d83cc019SAndroid Build Coastguard Worker * @cr: cairo drawing context
1474*d83cc019SAndroid Build Coastguard Worker * @filename: filename of the png image to draw
1475*d83cc019SAndroid Build Coastguard Worker * @dst_x: pixel x-coordination of the destination rectangle
1476*d83cc019SAndroid Build Coastguard Worker * @dst_y: pixel y-coordination of the destination rectangle
1477*d83cc019SAndroid Build Coastguard Worker * @dst_width: width of the destination rectangle
1478*d83cc019SAndroid Build Coastguard Worker * @dst_height: height of the destination rectangle
1479*d83cc019SAndroid Build Coastguard Worker *
1480*d83cc019SAndroid Build Coastguard Worker * This function can be used to draw a scaled version of the supplied png image,
1481*d83cc019SAndroid Build Coastguard Worker * which is loaded from the package data directory.
1482*d83cc019SAndroid Build Coastguard Worker */
igt_paint_image(cairo_t * cr,const char * filename,int dst_x,int dst_y,int dst_width,int dst_height)1483*d83cc019SAndroid Build Coastguard Worker void igt_paint_image(cairo_t *cr, const char *filename,
1484*d83cc019SAndroid Build Coastguard Worker int dst_x, int dst_y, int dst_width, int dst_height)
1485*d83cc019SAndroid Build Coastguard Worker {
1486*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *image;
1487*d83cc019SAndroid Build Coastguard Worker int img_width, img_height;
1488*d83cc019SAndroid Build Coastguard Worker double scale_x, scale_y;
1489*d83cc019SAndroid Build Coastguard Worker
1490*d83cc019SAndroid Build Coastguard Worker image = igt_cairo_image_surface_create_from_png(filename);
1491*d83cc019SAndroid Build Coastguard Worker igt_assert(cairo_surface_status(image) == CAIRO_STATUS_SUCCESS);
1492*d83cc019SAndroid Build Coastguard Worker
1493*d83cc019SAndroid Build Coastguard Worker img_width = cairo_image_surface_get_width(image);
1494*d83cc019SAndroid Build Coastguard Worker img_height = cairo_image_surface_get_height(image);
1495*d83cc019SAndroid Build Coastguard Worker
1496*d83cc019SAndroid Build Coastguard Worker scale_x = (double)dst_width / img_width;
1497*d83cc019SAndroid Build Coastguard Worker scale_y = (double)dst_height / img_height;
1498*d83cc019SAndroid Build Coastguard Worker
1499*d83cc019SAndroid Build Coastguard Worker cairo_save(cr);
1500*d83cc019SAndroid Build Coastguard Worker
1501*d83cc019SAndroid Build Coastguard Worker cairo_translate(cr, dst_x, dst_y);
1502*d83cc019SAndroid Build Coastguard Worker cairo_scale(cr, scale_x, scale_y);
1503*d83cc019SAndroid Build Coastguard Worker cairo_set_source_surface(cr, image, 0, 0);
1504*d83cc019SAndroid Build Coastguard Worker cairo_paint(cr);
1505*d83cc019SAndroid Build Coastguard Worker
1506*d83cc019SAndroid Build Coastguard Worker cairo_surface_destroy(image);
1507*d83cc019SAndroid Build Coastguard Worker
1508*d83cc019SAndroid Build Coastguard Worker cairo_restore(cr);
1509*d83cc019SAndroid Build Coastguard Worker }
1510*d83cc019SAndroid Build Coastguard Worker #endif /*defined(USE_CAIRO_PIXMAN)*/
1511*d83cc019SAndroid Build Coastguard Worker
1512*d83cc019SAndroid Build Coastguard Worker /**
1513*d83cc019SAndroid Build Coastguard Worker * igt_create_fb_with_bo_size:
1514*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
1515*d83cc019SAndroid Build Coastguard Worker * @width: width of the framebuffer in pixel
1516*d83cc019SAndroid Build Coastguard Worker * @height: height of the framebuffer in pixel
1517*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
1518*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer (as framebuffer modifier)
1519*d83cc019SAndroid Build Coastguard Worker * @color_encoding: color encoding for YCbCr formats (ignored otherwise)
1520*d83cc019SAndroid Build Coastguard Worker * @color_range: color range for YCbCr formats (ignored otherwise)
1521*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
1522*d83cc019SAndroid Build Coastguard Worker * @bo_size: size of the backing bo (0 for automatic size)
1523*d83cc019SAndroid Build Coastguard Worker * @bo_stride: stride of the backing bo (0 for automatic stride)
1524*d83cc019SAndroid Build Coastguard Worker *
1525*d83cc019SAndroid Build Coastguard Worker * This function allocates a gem buffer object suitable to back a framebuffer
1526*d83cc019SAndroid Build Coastguard Worker * with the requested properties and then wraps it up in a drm framebuffer
1527*d83cc019SAndroid Build Coastguard Worker * object of the requested size. All metadata is stored in @fb.
1528*d83cc019SAndroid Build Coastguard Worker *
1529*d83cc019SAndroid Build Coastguard Worker * The backing storage of the framebuffer is filled with all zeros, i.e. black
1530*d83cc019SAndroid Build Coastguard Worker * for rgb pixel formats.
1531*d83cc019SAndroid Build Coastguard Worker *
1532*d83cc019SAndroid Build Coastguard Worker * Returns:
1533*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer.
1534*d83cc019SAndroid Build Coastguard Worker */
1535*d83cc019SAndroid Build Coastguard Worker unsigned int
igt_create_fb_with_bo_size(int fd,int width,int height,uint32_t format,uint64_t modifier,enum igt_color_encoding color_encoding,enum igt_color_range color_range,struct igt_fb * fb,uint64_t bo_size,unsigned bo_stride)1536*d83cc019SAndroid Build Coastguard Worker igt_create_fb_with_bo_size(int fd, int width, int height,
1537*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier,
1538*d83cc019SAndroid Build Coastguard Worker enum igt_color_encoding color_encoding,
1539*d83cc019SAndroid Build Coastguard Worker enum igt_color_range color_range,
1540*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb, uint64_t bo_size,
1541*d83cc019SAndroid Build Coastguard Worker unsigned bo_stride)
1542*d83cc019SAndroid Build Coastguard Worker {
1543*d83cc019SAndroid Build Coastguard Worker uint32_t flags = 0;
1544*d83cc019SAndroid Build Coastguard Worker
1545*d83cc019SAndroid Build Coastguard Worker igt_init_fb(fb, fd, width, height, format, modifier,
1546*d83cc019SAndroid Build Coastguard Worker color_encoding, color_range);
1547*d83cc019SAndroid Build Coastguard Worker
1548*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < fb->num_planes; i++)
1549*d83cc019SAndroid Build Coastguard Worker fb->strides[i] = bo_stride;
1550*d83cc019SAndroid Build Coastguard Worker
1551*d83cc019SAndroid Build Coastguard Worker fb->size = bo_size;
1552*d83cc019SAndroid Build Coastguard Worker
1553*d83cc019SAndroid Build Coastguard Worker igt_debug("%s(width=%d, height=%d, format=" IGT_FORMAT_FMT
1554*d83cc019SAndroid Build Coastguard Worker ", modifier=0x%"PRIx64", size=%"PRIu64")\n",
1555*d83cc019SAndroid Build Coastguard Worker __func__, width, height, IGT_FORMAT_ARGS(format), modifier,
1556*d83cc019SAndroid Build Coastguard Worker bo_size);
1557*d83cc019SAndroid Build Coastguard Worker
1558*d83cc019SAndroid Build Coastguard Worker create_bo_for_fb(fb);
1559*d83cc019SAndroid Build Coastguard Worker igt_assert(fb->gem_handle > 0);
1560*d83cc019SAndroid Build Coastguard Worker
1561*d83cc019SAndroid Build Coastguard Worker igt_debug("%s(handle=%d, pitch=%d)\n",
1562*d83cc019SAndroid Build Coastguard Worker __func__, fb->gem_handle, fb->strides[0]);
1563*d83cc019SAndroid Build Coastguard Worker
1564*d83cc019SAndroid Build Coastguard Worker if (fb->modifier || igt_has_fb_modifiers(fd))
1565*d83cc019SAndroid Build Coastguard Worker flags = LOCAL_DRM_MODE_FB_MODIFIERS;
1566*d83cc019SAndroid Build Coastguard Worker
1567*d83cc019SAndroid Build Coastguard Worker do_or_die(__kms_addfb(fb->fd, fb->gem_handle,
1568*d83cc019SAndroid Build Coastguard Worker fb->width, fb->height,
1569*d83cc019SAndroid Build Coastguard Worker fb->drm_format, fb->modifier,
1570*d83cc019SAndroid Build Coastguard Worker fb->strides, fb->offsets, fb->num_planes, flags,
1571*d83cc019SAndroid Build Coastguard Worker &fb->fb_id));
1572*d83cc019SAndroid Build Coastguard Worker
1573*d83cc019SAndroid Build Coastguard Worker return fb->fb_id;
1574*d83cc019SAndroid Build Coastguard Worker }
1575*d83cc019SAndroid Build Coastguard Worker
1576*d83cc019SAndroid Build Coastguard Worker /**
1577*d83cc019SAndroid Build Coastguard Worker * igt_create_fb:
1578*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
1579*d83cc019SAndroid Build Coastguard Worker * @width: width of the framebuffer in pixel
1580*d83cc019SAndroid Build Coastguard Worker * @height: height of the framebuffer in pixel
1581*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
1582*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer
1583*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
1584*d83cc019SAndroid Build Coastguard Worker *
1585*d83cc019SAndroid Build Coastguard Worker * This function allocates a gem buffer object suitable to back a framebuffer
1586*d83cc019SAndroid Build Coastguard Worker * with the requested properties and then wraps it up in a drm framebuffer
1587*d83cc019SAndroid Build Coastguard Worker * object. All metadata is stored in @fb.
1588*d83cc019SAndroid Build Coastguard Worker *
1589*d83cc019SAndroid Build Coastguard Worker * The backing storage of the framebuffer is filled with all zeros, i.e. black
1590*d83cc019SAndroid Build Coastguard Worker * for rgb pixel formats.
1591*d83cc019SAndroid Build Coastguard Worker *
1592*d83cc019SAndroid Build Coastguard Worker * Returns:
1593*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer.
1594*d83cc019SAndroid Build Coastguard Worker */
igt_create_fb(int fd,int width,int height,uint32_t format,uint64_t modifier,struct igt_fb * fb)1595*d83cc019SAndroid Build Coastguard Worker unsigned int igt_create_fb(int fd, int width, int height, uint32_t format,
1596*d83cc019SAndroid Build Coastguard Worker uint64_t modifier, struct igt_fb *fb)
1597*d83cc019SAndroid Build Coastguard Worker {
1598*d83cc019SAndroid Build Coastguard Worker return igt_create_fb_with_bo_size(fd, width, height, format, modifier,
1599*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_BT709,
1600*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_LIMITED_RANGE,
1601*d83cc019SAndroid Build Coastguard Worker fb, 0, 0);
1602*d83cc019SAndroid Build Coastguard Worker }
1603*d83cc019SAndroid Build Coastguard Worker
1604*d83cc019SAndroid Build Coastguard Worker /**
1605*d83cc019SAndroid Build Coastguard Worker * igt_create_color_fb:
1606*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
1607*d83cc019SAndroid Build Coastguard Worker * @width: width of the framebuffer in pixel
1608*d83cc019SAndroid Build Coastguard Worker * @height: height of the framebuffer in pixel
1609*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
1610*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer
1611*d83cc019SAndroid Build Coastguard Worker * @r: red value to use as fill color
1612*d83cc019SAndroid Build Coastguard Worker * @g: green value to use as fill color
1613*d83cc019SAndroid Build Coastguard Worker * @b: blue value to use as fill color
1614*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
1615*d83cc019SAndroid Build Coastguard Worker *
1616*d83cc019SAndroid Build Coastguard Worker * This function allocates a gem buffer object suitable to back a framebuffer
1617*d83cc019SAndroid Build Coastguard Worker * with the requested properties and then wraps it up in a drm framebuffer
1618*d83cc019SAndroid Build Coastguard Worker * object. All metadata is stored in @fb.
1619*d83cc019SAndroid Build Coastguard Worker *
1620*d83cc019SAndroid Build Coastguard Worker * Compared to igt_create_fb() this function also fills the entire framebuffer
1621*d83cc019SAndroid Build Coastguard Worker * with the given color, which is useful for some simple pipe crc based tests.
1622*d83cc019SAndroid Build Coastguard Worker *
1623*d83cc019SAndroid Build Coastguard Worker * Returns:
1624*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer on success or a negative error code on
1625*d83cc019SAndroid Build Coastguard Worker * failure.
1626*d83cc019SAndroid Build Coastguard Worker */
igt_create_color_fb(int fd,int width,int height,uint32_t format,uint64_t modifier,double r,double g,double b,struct igt_fb * fb)1627*d83cc019SAndroid Build Coastguard Worker unsigned int igt_create_color_fb(int fd, int width, int height,
1628*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier,
1629*d83cc019SAndroid Build Coastguard Worker double r, double g, double b,
1630*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb /* out */)
1631*d83cc019SAndroid Build Coastguard Worker {
1632*d83cc019SAndroid Build Coastguard Worker unsigned int fb_id;
1633*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
1634*d83cc019SAndroid Build Coastguard Worker
1635*d83cc019SAndroid Build Coastguard Worker fb_id = igt_create_fb(fd, width, height, format, modifier, fb);
1636*d83cc019SAndroid Build Coastguard Worker igt_assert(fb_id);
1637*d83cc019SAndroid Build Coastguard Worker
1638*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
1639*d83cc019SAndroid Build Coastguard Worker cr = igt_get_cairo_ctx(fd, fb);
1640*d83cc019SAndroid Build Coastguard Worker igt_paint_color(cr, 0, 0, width, height, r, g, b);
1641*d83cc019SAndroid Build Coastguard Worker igt_put_cairo_ctx(fd, fb, cr);
1642*d83cc019SAndroid Build Coastguard Worker #endif
1643*d83cc019SAndroid Build Coastguard Worker
1644*d83cc019SAndroid Build Coastguard Worker return fb_id;
1645*d83cc019SAndroid Build Coastguard Worker }
1646*d83cc019SAndroid Build Coastguard Worker
1647*d83cc019SAndroid Build Coastguard Worker /**
1648*d83cc019SAndroid Build Coastguard Worker * igt_create_pattern_fb:
1649*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
1650*d83cc019SAndroid Build Coastguard Worker * @width: width of the framebuffer in pixel
1651*d83cc019SAndroid Build Coastguard Worker * @height: height of the framebuffer in pixel
1652*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
1653*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer
1654*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
1655*d83cc019SAndroid Build Coastguard Worker *
1656*d83cc019SAndroid Build Coastguard Worker * This function allocates a gem buffer object suitable to back a framebuffer
1657*d83cc019SAndroid Build Coastguard Worker * with the requested properties and then wraps it up in a drm framebuffer
1658*d83cc019SAndroid Build Coastguard Worker * object. All metadata is stored in @fb.
1659*d83cc019SAndroid Build Coastguard Worker *
1660*d83cc019SAndroid Build Coastguard Worker * Compared to igt_create_fb() this function also draws the standard test pattern
1661*d83cc019SAndroid Build Coastguard Worker * into the framebuffer.
1662*d83cc019SAndroid Build Coastguard Worker *
1663*d83cc019SAndroid Build Coastguard Worker * Returns:
1664*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer on success or a negative error code on
1665*d83cc019SAndroid Build Coastguard Worker * failure.
1666*d83cc019SAndroid Build Coastguard Worker */
igt_create_pattern_fb(int fd,int width,int height,uint32_t format,uint64_t modifier,struct igt_fb * fb)1667*d83cc019SAndroid Build Coastguard Worker unsigned int igt_create_pattern_fb(int fd, int width, int height,
1668*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier,
1669*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb /* out */)
1670*d83cc019SAndroid Build Coastguard Worker {
1671*d83cc019SAndroid Build Coastguard Worker unsigned int fb_id;
1672*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
1673*d83cc019SAndroid Build Coastguard Worker
1674*d83cc019SAndroid Build Coastguard Worker fb_id = igt_create_fb(fd, width, height, format, modifier, fb);
1675*d83cc019SAndroid Build Coastguard Worker igt_assert(fb_id);
1676*d83cc019SAndroid Build Coastguard Worker
1677*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
1678*d83cc019SAndroid Build Coastguard Worker cr = igt_get_cairo_ctx(fd, fb);
1679*d83cc019SAndroid Build Coastguard Worker igt_paint_test_pattern(cr, width, height);
1680*d83cc019SAndroid Build Coastguard Worker igt_put_cairo_ctx(fd, fb, cr);
1681*d83cc019SAndroid Build Coastguard Worker #endif
1682*d83cc019SAndroid Build Coastguard Worker
1683*d83cc019SAndroid Build Coastguard Worker return fb_id;
1684*d83cc019SAndroid Build Coastguard Worker }
1685*d83cc019SAndroid Build Coastguard Worker
1686*d83cc019SAndroid Build Coastguard Worker /**
1687*d83cc019SAndroid Build Coastguard Worker * igt_create_color_pattern_fb:
1688*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
1689*d83cc019SAndroid Build Coastguard Worker * @width: width of the framebuffer in pixel
1690*d83cc019SAndroid Build Coastguard Worker * @height: height of the framebuffer in pixel
1691*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
1692*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer
1693*d83cc019SAndroid Build Coastguard Worker * @r: red value to use as fill color
1694*d83cc019SAndroid Build Coastguard Worker * @g: green value to use as fill color
1695*d83cc019SAndroid Build Coastguard Worker * @b: blue value to use as fill color
1696*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
1697*d83cc019SAndroid Build Coastguard Worker *
1698*d83cc019SAndroid Build Coastguard Worker * This function allocates a gem buffer object suitable to back a framebuffer
1699*d83cc019SAndroid Build Coastguard Worker * with the requested properties and then wraps it up in a drm framebuffer
1700*d83cc019SAndroid Build Coastguard Worker * object. All metadata is stored in @fb.
1701*d83cc019SAndroid Build Coastguard Worker *
1702*d83cc019SAndroid Build Coastguard Worker * Compared to igt_create_fb() this function also fills the entire framebuffer
1703*d83cc019SAndroid Build Coastguard Worker * with the given color, and then draws the standard test pattern into the
1704*d83cc019SAndroid Build Coastguard Worker * framebuffer.
1705*d83cc019SAndroid Build Coastguard Worker *
1706*d83cc019SAndroid Build Coastguard Worker * Returns:
1707*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer on success or a negative error code on
1708*d83cc019SAndroid Build Coastguard Worker * failure.
1709*d83cc019SAndroid Build Coastguard Worker */
igt_create_color_pattern_fb(int fd,int width,int height,uint32_t format,uint64_t modifier,double r,double g,double b,struct igt_fb * fb)1710*d83cc019SAndroid Build Coastguard Worker unsigned int igt_create_color_pattern_fb(int fd, int width, int height,
1711*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier,
1712*d83cc019SAndroid Build Coastguard Worker double r, double g, double b,
1713*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb /* out */)
1714*d83cc019SAndroid Build Coastguard Worker {
1715*d83cc019SAndroid Build Coastguard Worker unsigned int fb_id;
1716*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
1717*d83cc019SAndroid Build Coastguard Worker
1718*d83cc019SAndroid Build Coastguard Worker fb_id = igt_create_fb(fd, width, height, format, modifier, fb);
1719*d83cc019SAndroid Build Coastguard Worker igt_assert(fb_id);
1720*d83cc019SAndroid Build Coastguard Worker
1721*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
1722*d83cc019SAndroid Build Coastguard Worker cr = igt_get_cairo_ctx(fd, fb);
1723*d83cc019SAndroid Build Coastguard Worker igt_paint_color(cr, 0, 0, width, height, r, g, b);
1724*d83cc019SAndroid Build Coastguard Worker igt_paint_test_pattern(cr, width, height);
1725*d83cc019SAndroid Build Coastguard Worker igt_put_cairo_ctx(fd, fb, cr);
1726*d83cc019SAndroid Build Coastguard Worker #endif
1727*d83cc019SAndroid Build Coastguard Worker
1728*d83cc019SAndroid Build Coastguard Worker return fb_id;
1729*d83cc019SAndroid Build Coastguard Worker }
1730*d83cc019SAndroid Build Coastguard Worker
1731*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
1732*d83cc019SAndroid Build Coastguard Worker /**
1733*d83cc019SAndroid Build Coastguard Worker * igt_create_image_fb:
1734*d83cc019SAndroid Build Coastguard Worker * @drm_fd: open i915 drm file descriptor
1735*d83cc019SAndroid Build Coastguard Worker * @width: width of the framebuffer in pixel or 0
1736*d83cc019SAndroid Build Coastguard Worker * @height: height of the framebuffer in pixel or 0
1737*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
1738*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer
1739*d83cc019SAndroid Build Coastguard Worker * @filename: filename of the png image to draw
1740*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
1741*d83cc019SAndroid Build Coastguard Worker *
1742*d83cc019SAndroid Build Coastguard Worker * Create a framebuffer with the specified image. If @width is zero the
1743*d83cc019SAndroid Build Coastguard Worker * image width will be used. If @height is zero the image height will be used.
1744*d83cc019SAndroid Build Coastguard Worker *
1745*d83cc019SAndroid Build Coastguard Worker * Returns:
1746*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer on success or a negative error code on
1747*d83cc019SAndroid Build Coastguard Worker * failure.
1748*d83cc019SAndroid Build Coastguard Worker */
igt_create_image_fb(int fd,int width,int height,uint32_t format,uint64_t modifier,const char * filename,struct igt_fb * fb)1749*d83cc019SAndroid Build Coastguard Worker unsigned int igt_create_image_fb(int fd, int width, int height,
1750*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier,
1751*d83cc019SAndroid Build Coastguard Worker const char *filename,
1752*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb /* out */)
1753*d83cc019SAndroid Build Coastguard Worker {
1754*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *image;
1755*d83cc019SAndroid Build Coastguard Worker uint32_t fb_id;
1756*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
1757*d83cc019SAndroid Build Coastguard Worker
1758*d83cc019SAndroid Build Coastguard Worker image = igt_cairo_image_surface_create_from_png(filename);
1759*d83cc019SAndroid Build Coastguard Worker igt_assert(cairo_surface_status(image) == CAIRO_STATUS_SUCCESS);
1760*d83cc019SAndroid Build Coastguard Worker if (width == 0)
1761*d83cc019SAndroid Build Coastguard Worker width = cairo_image_surface_get_width(image);
1762*d83cc019SAndroid Build Coastguard Worker if (height == 0)
1763*d83cc019SAndroid Build Coastguard Worker height = cairo_image_surface_get_height(image);
1764*d83cc019SAndroid Build Coastguard Worker cairo_surface_destroy(image);
1765*d83cc019SAndroid Build Coastguard Worker
1766*d83cc019SAndroid Build Coastguard Worker fb_id = igt_create_fb(fd, width, height, format, modifier, fb);
1767*d83cc019SAndroid Build Coastguard Worker
1768*d83cc019SAndroid Build Coastguard Worker cr = igt_get_cairo_ctx(fd, fb);
1769*d83cc019SAndroid Build Coastguard Worker igt_paint_image(cr, filename, 0, 0, width, height);
1770*d83cc019SAndroid Build Coastguard Worker igt_put_cairo_ctx(fd, fb, cr);
1771*d83cc019SAndroid Build Coastguard Worker
1772*d83cc019SAndroid Build Coastguard Worker return fb_id;
1773*d83cc019SAndroid Build Coastguard Worker }
1774*d83cc019SAndroid Build Coastguard Worker #endif
1775*d83cc019SAndroid Build Coastguard Worker
1776*d83cc019SAndroid Build Coastguard Worker struct box {
1777*d83cc019SAndroid Build Coastguard Worker int x, y, width, height;
1778*d83cc019SAndroid Build Coastguard Worker };
1779*d83cc019SAndroid Build Coastguard Worker
1780*d83cc019SAndroid Build Coastguard Worker struct stereo_fb_layout {
1781*d83cc019SAndroid Build Coastguard Worker int fb_width, fb_height;
1782*d83cc019SAndroid Build Coastguard Worker struct box left, right;
1783*d83cc019SAndroid Build Coastguard Worker };
1784*d83cc019SAndroid Build Coastguard Worker
box_init(struct box * box,int x,int y,int bwidth,int bheight)1785*d83cc019SAndroid Build Coastguard Worker static void box_init(struct box *box, int x, int y, int bwidth, int bheight)
1786*d83cc019SAndroid Build Coastguard Worker {
1787*d83cc019SAndroid Build Coastguard Worker box->x = x;
1788*d83cc019SAndroid Build Coastguard Worker box->y = y;
1789*d83cc019SAndroid Build Coastguard Worker box->width = bwidth;
1790*d83cc019SAndroid Build Coastguard Worker box->height = bheight;
1791*d83cc019SAndroid Build Coastguard Worker }
1792*d83cc019SAndroid Build Coastguard Worker
1793*d83cc019SAndroid Build Coastguard Worker
stereo_fb_layout_from_mode(struct stereo_fb_layout * layout,drmModeModeInfo * mode)1794*d83cc019SAndroid Build Coastguard Worker static void stereo_fb_layout_from_mode(struct stereo_fb_layout *layout,
1795*d83cc019SAndroid Build Coastguard Worker drmModeModeInfo *mode)
1796*d83cc019SAndroid Build Coastguard Worker {
1797*d83cc019SAndroid Build Coastguard Worker unsigned int format = mode->flags & DRM_MODE_FLAG_3D_MASK;
1798*d83cc019SAndroid Build Coastguard Worker const int hdisplay = mode->hdisplay, vdisplay = mode->vdisplay;
1799*d83cc019SAndroid Build Coastguard Worker int middle;
1800*d83cc019SAndroid Build Coastguard Worker
1801*d83cc019SAndroid Build Coastguard Worker switch (format) {
1802*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
1803*d83cc019SAndroid Build Coastguard Worker layout->fb_width = hdisplay;
1804*d83cc019SAndroid Build Coastguard Worker layout->fb_height = vdisplay;
1805*d83cc019SAndroid Build Coastguard Worker
1806*d83cc019SAndroid Build Coastguard Worker middle = vdisplay / 2;
1807*d83cc019SAndroid Build Coastguard Worker box_init(&layout->left, 0, 0, hdisplay, middle);
1808*d83cc019SAndroid Build Coastguard Worker box_init(&layout->right,
1809*d83cc019SAndroid Build Coastguard Worker 0, middle, hdisplay, vdisplay - middle);
1810*d83cc019SAndroid Build Coastguard Worker break;
1811*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
1812*d83cc019SAndroid Build Coastguard Worker layout->fb_width = hdisplay;
1813*d83cc019SAndroid Build Coastguard Worker layout->fb_height = vdisplay;
1814*d83cc019SAndroid Build Coastguard Worker
1815*d83cc019SAndroid Build Coastguard Worker middle = hdisplay / 2;
1816*d83cc019SAndroid Build Coastguard Worker box_init(&layout->left, 0, 0, middle, vdisplay);
1817*d83cc019SAndroid Build Coastguard Worker box_init(&layout->right,
1818*d83cc019SAndroid Build Coastguard Worker middle, 0, hdisplay - middle, vdisplay);
1819*d83cc019SAndroid Build Coastguard Worker break;
1820*d83cc019SAndroid Build Coastguard Worker case DRM_MODE_FLAG_3D_FRAME_PACKING:
1821*d83cc019SAndroid Build Coastguard Worker {
1822*d83cc019SAndroid Build Coastguard Worker int vactive_space = mode->vtotal - vdisplay;
1823*d83cc019SAndroid Build Coastguard Worker
1824*d83cc019SAndroid Build Coastguard Worker layout->fb_width = hdisplay;
1825*d83cc019SAndroid Build Coastguard Worker layout->fb_height = 2 * vdisplay + vactive_space;
1826*d83cc019SAndroid Build Coastguard Worker
1827*d83cc019SAndroid Build Coastguard Worker box_init(&layout->left,
1828*d83cc019SAndroid Build Coastguard Worker 0, 0, hdisplay, vdisplay);
1829*d83cc019SAndroid Build Coastguard Worker box_init(&layout->right,
1830*d83cc019SAndroid Build Coastguard Worker 0, vdisplay + vactive_space, hdisplay, vdisplay);
1831*d83cc019SAndroid Build Coastguard Worker break;
1832*d83cc019SAndroid Build Coastguard Worker }
1833*d83cc019SAndroid Build Coastguard Worker default:
1834*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
1835*d83cc019SAndroid Build Coastguard Worker }
1836*d83cc019SAndroid Build Coastguard Worker }
1837*d83cc019SAndroid Build Coastguard Worker
1838*d83cc019SAndroid Build Coastguard Worker /**
1839*d83cc019SAndroid Build Coastguard Worker * igt_create_stereo_fb:
1840*d83cc019SAndroid Build Coastguard Worker * @drm_fd: open i915 drm file descriptor
1841*d83cc019SAndroid Build Coastguard Worker * @mode: A stereo 3D mode.
1842*d83cc019SAndroid Build Coastguard Worker * @format: drm fourcc pixel format code
1843*d83cc019SAndroid Build Coastguard Worker * @modifier: tiling layout of the framebuffer
1844*d83cc019SAndroid Build Coastguard Worker *
1845*d83cc019SAndroid Build Coastguard Worker * Create a framebuffer for use with the stereo 3D mode specified by @mode.
1846*d83cc019SAndroid Build Coastguard Worker *
1847*d83cc019SAndroid Build Coastguard Worker * Returns:
1848*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer on success or a negative error code on
1849*d83cc019SAndroid Build Coastguard Worker * failure.
1850*d83cc019SAndroid Build Coastguard Worker */
igt_create_stereo_fb(int drm_fd,drmModeModeInfo * mode,uint32_t format,uint64_t modifier)1851*d83cc019SAndroid Build Coastguard Worker unsigned int igt_create_stereo_fb(int drm_fd, drmModeModeInfo *mode,
1852*d83cc019SAndroid Build Coastguard Worker uint32_t format, uint64_t modifier)
1853*d83cc019SAndroid Build Coastguard Worker {
1854*d83cc019SAndroid Build Coastguard Worker struct stereo_fb_layout layout;
1855*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
1856*d83cc019SAndroid Build Coastguard Worker uint32_t fb_id;
1857*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb;
1858*d83cc019SAndroid Build Coastguard Worker
1859*d83cc019SAndroid Build Coastguard Worker stereo_fb_layout_from_mode(&layout, mode);
1860*d83cc019SAndroid Build Coastguard Worker fb_id = igt_create_fb(drm_fd, layout.fb_width, layout.fb_height, format,
1861*d83cc019SAndroid Build Coastguard Worker modifier, &fb);
1862*d83cc019SAndroid Build Coastguard Worker cr = igt_get_cairo_ctx(drm_fd, &fb);
1863*d83cc019SAndroid Build Coastguard Worker
1864*d83cc019SAndroid Build Coastguard Worker igt_paint_image(cr, "1080p-left.png",
1865*d83cc019SAndroid Build Coastguard Worker layout.left.x, layout.left.y,
1866*d83cc019SAndroid Build Coastguard Worker layout.left.width, layout.left.height);
1867*d83cc019SAndroid Build Coastguard Worker igt_paint_image(cr, "1080p-right.png",
1868*d83cc019SAndroid Build Coastguard Worker layout.right.x, layout.right.y,
1869*d83cc019SAndroid Build Coastguard Worker layout.right.width, layout.right.height);
1870*d83cc019SAndroid Build Coastguard Worker
1871*d83cc019SAndroid Build Coastguard Worker igt_put_cairo_ctx(drm_fd, &fb, cr);
1872*d83cc019SAndroid Build Coastguard Worker
1873*d83cc019SAndroid Build Coastguard Worker return fb_id;
1874*d83cc019SAndroid Build Coastguard Worker }
1875*d83cc019SAndroid Build Coastguard Worker
1876*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
drm_format_to_pixman(uint32_t drm_format)1877*d83cc019SAndroid Build Coastguard Worker static pixman_format_code_t drm_format_to_pixman(uint32_t drm_format)
1878*d83cc019SAndroid Build Coastguard Worker {
1879*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f;
1880*d83cc019SAndroid Build Coastguard Worker
1881*d83cc019SAndroid Build Coastguard Worker for_each_format(f)
1882*d83cc019SAndroid Build Coastguard Worker if (f->drm_id == drm_format)
1883*d83cc019SAndroid Build Coastguard Worker return f->pixman_id;
1884*d83cc019SAndroid Build Coastguard Worker
1885*d83cc019SAndroid Build Coastguard Worker igt_assert_f(0, "can't find a pixman format for %08x (%s)\n",
1886*d83cc019SAndroid Build Coastguard Worker drm_format, igt_format_str(drm_format));
1887*d83cc019SAndroid Build Coastguard Worker }
1888*d83cc019SAndroid Build Coastguard Worker
drm_format_to_cairo(uint32_t drm_format)1889*d83cc019SAndroid Build Coastguard Worker static cairo_format_t drm_format_to_cairo(uint32_t drm_format)
1890*d83cc019SAndroid Build Coastguard Worker {
1891*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f;
1892*d83cc019SAndroid Build Coastguard Worker
1893*d83cc019SAndroid Build Coastguard Worker for_each_format(f)
1894*d83cc019SAndroid Build Coastguard Worker if (f->drm_id == drm_format)
1895*d83cc019SAndroid Build Coastguard Worker return f->cairo_id;
1896*d83cc019SAndroid Build Coastguard Worker
1897*d83cc019SAndroid Build Coastguard Worker igt_assert_f(0, "can't find a cairo format for %08x (%s)\n",
1898*d83cc019SAndroid Build Coastguard Worker drm_format, igt_format_str(drm_format));
1899*d83cc019SAndroid Build Coastguard Worker }
1900*d83cc019SAndroid Build Coastguard Worker #endif
1901*d83cc019SAndroid Build Coastguard Worker
1902*d83cc019SAndroid Build Coastguard Worker struct fb_blit_linear {
1903*d83cc019SAndroid Build Coastguard Worker struct igt_fb fb;
1904*d83cc019SAndroid Build Coastguard Worker uint8_t *map;
1905*d83cc019SAndroid Build Coastguard Worker };
1906*d83cc019SAndroid Build Coastguard Worker
1907*d83cc019SAndroid Build Coastguard Worker struct fb_blit_upload {
1908*d83cc019SAndroid Build Coastguard Worker int fd;
1909*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb;
1910*d83cc019SAndroid Build Coastguard Worker struct fb_blit_linear linear;
1911*d83cc019SAndroid Build Coastguard Worker drm_intel_bufmgr *bufmgr;
1912*d83cc019SAndroid Build Coastguard Worker struct intel_batchbuffer *batch;
1913*d83cc019SAndroid Build Coastguard Worker };
1914*d83cc019SAndroid Build Coastguard Worker
1915*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
blitter_ok(const struct igt_fb * fb)1916*d83cc019SAndroid Build Coastguard Worker static bool blitter_ok(const struct igt_fb *fb)
1917*d83cc019SAndroid Build Coastguard Worker {
1918*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < fb->num_planes; i++) {
1919*d83cc019SAndroid Build Coastguard Worker /*
1920*d83cc019SAndroid Build Coastguard Worker * gen4+ stride limit is 4x this with tiling,
1921*d83cc019SAndroid Build Coastguard Worker * but since our blits are always between tiled
1922*d83cc019SAndroid Build Coastguard Worker * and linear surfaces (and we do this check just
1923*d83cc019SAndroid Build Coastguard Worker * for the tiled surface) we must use the lower
1924*d83cc019SAndroid Build Coastguard Worker * linear stride limit here.
1925*d83cc019SAndroid Build Coastguard Worker */
1926*d83cc019SAndroid Build Coastguard Worker if (fb->plane_width[i] > 32767 ||
1927*d83cc019SAndroid Build Coastguard Worker fb->plane_height[i] > 32767 ||
1928*d83cc019SAndroid Build Coastguard Worker fb->strides[i] > 32767)
1929*d83cc019SAndroid Build Coastguard Worker return false;
1930*d83cc019SAndroid Build Coastguard Worker }
1931*d83cc019SAndroid Build Coastguard Worker
1932*d83cc019SAndroid Build Coastguard Worker return true;
1933*d83cc019SAndroid Build Coastguard Worker }
1934*d83cc019SAndroid Build Coastguard Worker
use_rendercopy(const struct igt_fb * fb)1935*d83cc019SAndroid Build Coastguard Worker static bool use_rendercopy(const struct igt_fb *fb)
1936*d83cc019SAndroid Build Coastguard Worker {
1937*d83cc019SAndroid Build Coastguard Worker return is_ccs_modifier(fb->modifier) ||
1938*d83cc019SAndroid Build Coastguard Worker (fb->modifier == I915_FORMAT_MOD_Yf_TILED &&
1939*d83cc019SAndroid Build Coastguard Worker !blitter_ok(fb));
1940*d83cc019SAndroid Build Coastguard Worker }
1941*d83cc019SAndroid Build Coastguard Worker
use_blitter(const struct igt_fb * fb)1942*d83cc019SAndroid Build Coastguard Worker static bool use_blitter(const struct igt_fb *fb)
1943*d83cc019SAndroid Build Coastguard Worker {
1944*d83cc019SAndroid Build Coastguard Worker return (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1945*d83cc019SAndroid Build Coastguard Worker fb->modifier == I915_FORMAT_MOD_Yf_TILED) &&
1946*d83cc019SAndroid Build Coastguard Worker blitter_ok(fb);
1947*d83cc019SAndroid Build Coastguard Worker }
1948*d83cc019SAndroid Build Coastguard Worker
init_buf(struct fb_blit_upload * blit,struct igt_buf * buf,const struct igt_fb * fb,const char * name)1949*d83cc019SAndroid Build Coastguard Worker static void init_buf(struct fb_blit_upload *blit,
1950*d83cc019SAndroid Build Coastguard Worker struct igt_buf *buf,
1951*d83cc019SAndroid Build Coastguard Worker const struct igt_fb *fb,
1952*d83cc019SAndroid Build Coastguard Worker const char *name)
1953*d83cc019SAndroid Build Coastguard Worker {
1954*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(fb->offsets[0], 0);
1955*d83cc019SAndroid Build Coastguard Worker
1956*d83cc019SAndroid Build Coastguard Worker buf->bo = gem_handle_to_libdrm_bo(blit->bufmgr, blit->fd,
1957*d83cc019SAndroid Build Coastguard Worker name, fb->gem_handle);
1958*d83cc019SAndroid Build Coastguard Worker buf->tiling = igt_fb_mod_to_tiling(fb->modifier);
1959*d83cc019SAndroid Build Coastguard Worker buf->stride = fb->strides[0];
1960*d83cc019SAndroid Build Coastguard Worker buf->bpp = fb->plane_bpp[0];
1961*d83cc019SAndroid Build Coastguard Worker buf->size = fb->size;
1962*d83cc019SAndroid Build Coastguard Worker
1963*d83cc019SAndroid Build Coastguard Worker if (is_ccs_modifier(fb->modifier)) {
1964*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(fb->strides[0] & 127, 0);
1965*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(fb->strides[1] & 127, 0);
1966*d83cc019SAndroid Build Coastguard Worker
1967*d83cc019SAndroid Build Coastguard Worker buf->aux.offset = fb->offsets[1];
1968*d83cc019SAndroid Build Coastguard Worker buf->aux.stride = fb->strides[1];
1969*d83cc019SAndroid Build Coastguard Worker }
1970*d83cc019SAndroid Build Coastguard Worker }
1971*d83cc019SAndroid Build Coastguard Worker
fini_buf(struct igt_buf * buf)1972*d83cc019SAndroid Build Coastguard Worker static void fini_buf(struct igt_buf *buf)
1973*d83cc019SAndroid Build Coastguard Worker {
1974*d83cc019SAndroid Build Coastguard Worker drm_intel_bo_unreference(buf->bo);
1975*d83cc019SAndroid Build Coastguard Worker }
1976*d83cc019SAndroid Build Coastguard Worker
rendercopy(struct fb_blit_upload * blit,const struct igt_fb * dst_fb,const struct igt_fb * src_fb)1977*d83cc019SAndroid Build Coastguard Worker static void rendercopy(struct fb_blit_upload *blit,
1978*d83cc019SAndroid Build Coastguard Worker const struct igt_fb *dst_fb,
1979*d83cc019SAndroid Build Coastguard Worker const struct igt_fb *src_fb)
1980*d83cc019SAndroid Build Coastguard Worker {
1981*d83cc019SAndroid Build Coastguard Worker struct igt_buf src = {}, dst = {};
1982*d83cc019SAndroid Build Coastguard Worker igt_render_copyfunc_t render_copy =
1983*d83cc019SAndroid Build Coastguard Worker igt_get_render_copyfunc(intel_get_drm_devid(blit->fd));
1984*d83cc019SAndroid Build Coastguard Worker
1985*d83cc019SAndroid Build Coastguard Worker igt_require(render_copy);
1986*d83cc019SAndroid Build Coastguard Worker
1987*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(dst_fb->offsets[0], 0);
1988*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(src_fb->offsets[0], 0);
1989*d83cc019SAndroid Build Coastguard Worker
1990*d83cc019SAndroid Build Coastguard Worker init_buf(blit, &src, src_fb, "cairo rendercopy src");
1991*d83cc019SAndroid Build Coastguard Worker init_buf(blit, &dst, dst_fb, "cairo rendercopy dst");
1992*d83cc019SAndroid Build Coastguard Worker
1993*d83cc019SAndroid Build Coastguard Worker render_copy(blit->batch, NULL,
1994*d83cc019SAndroid Build Coastguard Worker &src, 0, 0, dst_fb->plane_width[0], dst_fb->plane_height[0],
1995*d83cc019SAndroid Build Coastguard Worker &dst, 0, 0);
1996*d83cc019SAndroid Build Coastguard Worker
1997*d83cc019SAndroid Build Coastguard Worker fini_buf(&dst);
1998*d83cc019SAndroid Build Coastguard Worker fini_buf(&src);
1999*d83cc019SAndroid Build Coastguard Worker }
2000*d83cc019SAndroid Build Coastguard Worker
blitcopy(const struct igt_fb * dst_fb,const struct igt_fb * src_fb)2001*d83cc019SAndroid Build Coastguard Worker static void blitcopy(const struct igt_fb *dst_fb,
2002*d83cc019SAndroid Build Coastguard Worker const struct igt_fb *src_fb)
2003*d83cc019SAndroid Build Coastguard Worker {
2004*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(dst_fb->fd, src_fb->fd);
2005*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(dst_fb->num_planes, src_fb->num_planes);
2006*d83cc019SAndroid Build Coastguard Worker
2007*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < dst_fb->num_planes; i++) {
2008*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(dst_fb->plane_bpp[i], src_fb->plane_bpp[i]);
2009*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(dst_fb->plane_width[i], src_fb->plane_width[i]);
2010*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(dst_fb->plane_height[i], src_fb->plane_height[i]);
2011*d83cc019SAndroid Build Coastguard Worker
2012*d83cc019SAndroid Build Coastguard Worker igt_blitter_fast_copy__raw(dst_fb->fd,
2013*d83cc019SAndroid Build Coastguard Worker src_fb->gem_handle,
2014*d83cc019SAndroid Build Coastguard Worker src_fb->offsets[i],
2015*d83cc019SAndroid Build Coastguard Worker src_fb->strides[i],
2016*d83cc019SAndroid Build Coastguard Worker igt_fb_mod_to_tiling(src_fb->modifier),
2017*d83cc019SAndroid Build Coastguard Worker 0, 0, /* src_x, src_y */
2018*d83cc019SAndroid Build Coastguard Worker dst_fb->plane_width[i], dst_fb->plane_height[i],
2019*d83cc019SAndroid Build Coastguard Worker dst_fb->plane_bpp[i],
2020*d83cc019SAndroid Build Coastguard Worker dst_fb->gem_handle,
2021*d83cc019SAndroid Build Coastguard Worker dst_fb->offsets[i],
2022*d83cc019SAndroid Build Coastguard Worker dst_fb->strides[i],
2023*d83cc019SAndroid Build Coastguard Worker igt_fb_mod_to_tiling(dst_fb->modifier),
2024*d83cc019SAndroid Build Coastguard Worker 0, 0 /* dst_x, dst_y */);
2025*d83cc019SAndroid Build Coastguard Worker }
2026*d83cc019SAndroid Build Coastguard Worker }
2027*d83cc019SAndroid Build Coastguard Worker
free_linear_mapping(struct fb_blit_upload * blit)2028*d83cc019SAndroid Build Coastguard Worker static void free_linear_mapping(struct fb_blit_upload *blit)
2029*d83cc019SAndroid Build Coastguard Worker {
2030*d83cc019SAndroid Build Coastguard Worker int fd = blit->fd;
2031*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb = blit->fb;
2032*d83cc019SAndroid Build Coastguard Worker struct fb_blit_linear *linear = &blit->linear;
2033*d83cc019SAndroid Build Coastguard Worker
2034*d83cc019SAndroid Build Coastguard Worker if (igt_vc4_is_tiled(fb->modifier)) {
2035*d83cc019SAndroid Build Coastguard Worker void *map = igt_vc4_mmap_bo(fd, fb->gem_handle, fb->size, PROT_WRITE);
2036*d83cc019SAndroid Build Coastguard Worker
2037*d83cc019SAndroid Build Coastguard Worker vc4_fb_convert_plane_to_tiled(fb, map, &linear->fb, &linear->map);
2038*d83cc019SAndroid Build Coastguard Worker
2039*d83cc019SAndroid Build Coastguard Worker munmap(map, fb->size);
2040*d83cc019SAndroid Build Coastguard Worker } else {
2041*d83cc019SAndroid Build Coastguard Worker gem_munmap(linear->map, linear->fb.size);
2042*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, linear->fb.gem_handle,
2043*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, 0);
2044*d83cc019SAndroid Build Coastguard Worker
2045*d83cc019SAndroid Build Coastguard Worker if (blit->batch)
2046*d83cc019SAndroid Build Coastguard Worker rendercopy(blit, fb, &linear->fb);
2047*d83cc019SAndroid Build Coastguard Worker else
2048*d83cc019SAndroid Build Coastguard Worker blitcopy(fb, &linear->fb);
2049*d83cc019SAndroid Build Coastguard Worker
2050*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, linear->fb.gem_handle);
2051*d83cc019SAndroid Build Coastguard Worker gem_close(fd, linear->fb.gem_handle);
2052*d83cc019SAndroid Build Coastguard Worker }
2053*d83cc019SAndroid Build Coastguard Worker
2054*d83cc019SAndroid Build Coastguard Worker if (blit->batch) {
2055*d83cc019SAndroid Build Coastguard Worker intel_batchbuffer_free(blit->batch);
2056*d83cc019SAndroid Build Coastguard Worker drm_intel_bufmgr_destroy(blit->bufmgr);
2057*d83cc019SAndroid Build Coastguard Worker }
2058*d83cc019SAndroid Build Coastguard Worker }
2059*d83cc019SAndroid Build Coastguard Worker
destroy_cairo_surface__gpu(void * arg)2060*d83cc019SAndroid Build Coastguard Worker static void destroy_cairo_surface__gpu(void *arg)
2061*d83cc019SAndroid Build Coastguard Worker {
2062*d83cc019SAndroid Build Coastguard Worker struct fb_blit_upload *blit = arg;
2063*d83cc019SAndroid Build Coastguard Worker
2064*d83cc019SAndroid Build Coastguard Worker blit->fb->cairo_surface = NULL;
2065*d83cc019SAndroid Build Coastguard Worker
2066*d83cc019SAndroid Build Coastguard Worker free_linear_mapping(blit);
2067*d83cc019SAndroid Build Coastguard Worker
2068*d83cc019SAndroid Build Coastguard Worker free(blit);
2069*d83cc019SAndroid Build Coastguard Worker }
2070*d83cc019SAndroid Build Coastguard Worker
setup_linear_mapping(struct fb_blit_upload * blit)2071*d83cc019SAndroid Build Coastguard Worker static void setup_linear_mapping(struct fb_blit_upload *blit)
2072*d83cc019SAndroid Build Coastguard Worker {
2073*d83cc019SAndroid Build Coastguard Worker int fd = blit->fd;
2074*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb = blit->fb;
2075*d83cc019SAndroid Build Coastguard Worker struct fb_blit_linear *linear = &blit->linear;
2076*d83cc019SAndroid Build Coastguard Worker
2077*d83cc019SAndroid Build Coastguard Worker if (!igt_vc4_is_tiled(fb->modifier) && use_rendercopy(fb)) {
2078*d83cc019SAndroid Build Coastguard Worker blit->bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
2079*d83cc019SAndroid Build Coastguard Worker blit->batch = intel_batchbuffer_alloc(blit->bufmgr,
2080*d83cc019SAndroid Build Coastguard Worker intel_get_drm_devid(fd));
2081*d83cc019SAndroid Build Coastguard Worker }
2082*d83cc019SAndroid Build Coastguard Worker
2083*d83cc019SAndroid Build Coastguard Worker /*
2084*d83cc019SAndroid Build Coastguard Worker * We create a linear BO that we'll map for the CPU to write to (using
2085*d83cc019SAndroid Build Coastguard Worker * cairo). This linear bo will be then blitted to its final
2086*d83cc019SAndroid Build Coastguard Worker * destination, tiling it at the same time.
2087*d83cc019SAndroid Build Coastguard Worker */
2088*d83cc019SAndroid Build Coastguard Worker
2089*d83cc019SAndroid Build Coastguard Worker igt_init_fb(&linear->fb, fb->fd, fb->width, fb->height,
2090*d83cc019SAndroid Build Coastguard Worker fb->drm_format, LOCAL_DRM_FORMAT_MOD_NONE,
2091*d83cc019SAndroid Build Coastguard Worker fb->color_encoding, fb->color_range);
2092*d83cc019SAndroid Build Coastguard Worker
2093*d83cc019SAndroid Build Coastguard Worker create_bo_for_fb(&linear->fb);
2094*d83cc019SAndroid Build Coastguard Worker
2095*d83cc019SAndroid Build Coastguard Worker igt_assert(linear->fb.gem_handle > 0);
2096*d83cc019SAndroid Build Coastguard Worker
2097*d83cc019SAndroid Build Coastguard Worker if (igt_vc4_is_tiled(fb->modifier)) {
2098*d83cc019SAndroid Build Coastguard Worker void *map = igt_vc4_mmap_bo(fd, fb->gem_handle, fb->size, PROT_READ);
2099*d83cc019SAndroid Build Coastguard Worker
2100*d83cc019SAndroid Build Coastguard Worker linear->map = igt_vc4_mmap_bo(fd, linear->fb.gem_handle,
2101*d83cc019SAndroid Build Coastguard Worker linear->fb.size,
2102*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
2103*d83cc019SAndroid Build Coastguard Worker
2104*d83cc019SAndroid Build Coastguard Worker vc4_fb_convert_plane_from_tiled(&linear->fb, &linear->map, fb, map);
2105*d83cc019SAndroid Build Coastguard Worker
2106*d83cc019SAndroid Build Coastguard Worker munmap(map, fb->size);
2107*d83cc019SAndroid Build Coastguard Worker } else {
2108*d83cc019SAndroid Build Coastguard Worker /* Copy fb content to linear BO */
2109*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, linear->fb.gem_handle,
2110*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, 0);
2111*d83cc019SAndroid Build Coastguard Worker
2112*d83cc019SAndroid Build Coastguard Worker if (blit->batch)
2113*d83cc019SAndroid Build Coastguard Worker rendercopy(blit, &linear->fb, fb);
2114*d83cc019SAndroid Build Coastguard Worker else
2115*d83cc019SAndroid Build Coastguard Worker blitcopy(&linear->fb, fb);
2116*d83cc019SAndroid Build Coastguard Worker
2117*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, linear->fb.gem_handle);
2118*d83cc019SAndroid Build Coastguard Worker
2119*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, linear->fb.gem_handle,
2120*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
2121*d83cc019SAndroid Build Coastguard Worker
2122*d83cc019SAndroid Build Coastguard Worker /* Setup cairo context */
2123*d83cc019SAndroid Build Coastguard Worker linear->map = gem_mmap__cpu(fd, linear->fb.gem_handle,
2124*d83cc019SAndroid Build Coastguard Worker 0, linear->fb.size, PROT_READ | PROT_WRITE);
2125*d83cc019SAndroid Build Coastguard Worker }
2126*d83cc019SAndroid Build Coastguard Worker }
2127*d83cc019SAndroid Build Coastguard Worker
create_cairo_surface__gpu(int fd,struct igt_fb * fb)2128*d83cc019SAndroid Build Coastguard Worker static void create_cairo_surface__gpu(int fd, struct igt_fb *fb)
2129*d83cc019SAndroid Build Coastguard Worker {
2130*d83cc019SAndroid Build Coastguard Worker struct fb_blit_upload *blit;
2131*d83cc019SAndroid Build Coastguard Worker cairo_format_t cairo_format;
2132*d83cc019SAndroid Build Coastguard Worker
2133*d83cc019SAndroid Build Coastguard Worker blit = calloc(1, sizeof(*blit));
2134*d83cc019SAndroid Build Coastguard Worker igt_assert(blit);
2135*d83cc019SAndroid Build Coastguard Worker
2136*d83cc019SAndroid Build Coastguard Worker blit->fd = fd;
2137*d83cc019SAndroid Build Coastguard Worker blit->fb = fb;
2138*d83cc019SAndroid Build Coastguard Worker setup_linear_mapping(blit);
2139*d83cc019SAndroid Build Coastguard Worker
2140*d83cc019SAndroid Build Coastguard Worker cairo_format = drm_format_to_cairo(fb->drm_format);
2141*d83cc019SAndroid Build Coastguard Worker fb->cairo_surface =
2142*d83cc019SAndroid Build Coastguard Worker cairo_image_surface_create_for_data(blit->linear.map,
2143*d83cc019SAndroid Build Coastguard Worker cairo_format,
2144*d83cc019SAndroid Build Coastguard Worker fb->width, fb->height,
2145*d83cc019SAndroid Build Coastguard Worker blit->linear.fb.strides[0]);
2146*d83cc019SAndroid Build Coastguard Worker fb->domain = I915_GEM_DOMAIN_GTT;
2147*d83cc019SAndroid Build Coastguard Worker
2148*d83cc019SAndroid Build Coastguard Worker cairo_surface_set_user_data(fb->cairo_surface,
2149*d83cc019SAndroid Build Coastguard Worker (cairo_user_data_key_t *)create_cairo_surface__gpu,
2150*d83cc019SAndroid Build Coastguard Worker blit, destroy_cairo_surface__gpu);
2151*d83cc019SAndroid Build Coastguard Worker }
2152*d83cc019SAndroid Build Coastguard Worker #endif /*defined(USE_CAIRO_PIXMAN)*/
2153*d83cc019SAndroid Build Coastguard Worker
2154*d83cc019SAndroid Build Coastguard Worker /**
2155*d83cc019SAndroid Build Coastguard Worker * igt_dirty_fb:
2156*d83cc019SAndroid Build Coastguard Worker * @fd: open drm file descriptor
2157*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
2158*d83cc019SAndroid Build Coastguard Worker *
2159*d83cc019SAndroid Build Coastguard Worker * Flushes out the whole framebuffer.
2160*d83cc019SAndroid Build Coastguard Worker *
2161*d83cc019SAndroid Build Coastguard Worker * Returns: 0 upon success.
2162*d83cc019SAndroid Build Coastguard Worker */
igt_dirty_fb(int fd,struct igt_fb * fb)2163*d83cc019SAndroid Build Coastguard Worker int igt_dirty_fb(int fd, struct igt_fb *fb)
2164*d83cc019SAndroid Build Coastguard Worker {
2165*d83cc019SAndroid Build Coastguard Worker return drmModeDirtyFB(fb->fd, fb->fb_id, NULL, 0);
2166*d83cc019SAndroid Build Coastguard Worker }
2167*d83cc019SAndroid Build Coastguard Worker
unmap_bo(struct igt_fb * fb,void * ptr)2168*d83cc019SAndroid Build Coastguard Worker static void unmap_bo(struct igt_fb *fb, void *ptr)
2169*d83cc019SAndroid Build Coastguard Worker {
2170*d83cc019SAndroid Build Coastguard Worker gem_munmap(ptr, fb->size);
2171*d83cc019SAndroid Build Coastguard Worker
2172*d83cc019SAndroid Build Coastguard Worker if (fb->is_dumb)
2173*d83cc019SAndroid Build Coastguard Worker igt_dirty_fb(fb->fd, fb);
2174*d83cc019SAndroid Build Coastguard Worker }
2175*d83cc019SAndroid Build Coastguard Worker
2176*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
destroy_cairo_surface__gtt(void * arg)2177*d83cc019SAndroid Build Coastguard Worker static void destroy_cairo_surface__gtt(void *arg)
2178*d83cc019SAndroid Build Coastguard Worker {
2179*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb = arg;
2180*d83cc019SAndroid Build Coastguard Worker
2181*d83cc019SAndroid Build Coastguard Worker unmap_bo(fb, cairo_image_surface_get_data(fb->cairo_surface));
2182*d83cc019SAndroid Build Coastguard Worker fb->cairo_surface = NULL;
2183*d83cc019SAndroid Build Coastguard Worker }
2184*d83cc019SAndroid Build Coastguard Worker #endif
2185*d83cc019SAndroid Build Coastguard Worker
map_bo(int fd,struct igt_fb * fb)2186*d83cc019SAndroid Build Coastguard Worker static void *map_bo(int fd, struct igt_fb *fb)
2187*d83cc019SAndroid Build Coastguard Worker {
2188*d83cc019SAndroid Build Coastguard Worker void *ptr;
2189*d83cc019SAndroid Build Coastguard Worker
2190*d83cc019SAndroid Build Coastguard Worker if (is_i915_device(fd))
2191*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, fb->gem_handle,
2192*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
2193*d83cc019SAndroid Build Coastguard Worker
2194*d83cc019SAndroid Build Coastguard Worker if (fb->is_dumb)
2195*d83cc019SAndroid Build Coastguard Worker ptr = kmstest_dumb_map_buffer(fd, fb->gem_handle, fb->size,
2196*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
2197*d83cc019SAndroid Build Coastguard Worker else if (is_i915_device(fd))
2198*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__gtt(fd, fb->gem_handle, fb->size,
2199*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
2200*d83cc019SAndroid Build Coastguard Worker #if defined(USE_VC4)
2201*d83cc019SAndroid Build Coastguard Worker else if (is_vc4_device(fd))
2202*d83cc019SAndroid Build Coastguard Worker ptr = igt_vc4_mmap_bo(fd, fb->gem_handle, fb->size,
2203*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
2204*d83cc019SAndroid Build Coastguard Worker #endif
2205*d83cc019SAndroid Build Coastguard Worker #if defined(USE_AMD)
2206*d83cc019SAndroid Build Coastguard Worker else if (is_amdgpu_device(fd))
2207*d83cc019SAndroid Build Coastguard Worker ptr = igt_amd_mmap_bo(fd, fb->gem_handle, fb->size,
2208*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
2209*d83cc019SAndroid Build Coastguard Worker #endif
2210*d83cc019SAndroid Build Coastguard Worker else
2211*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
2212*d83cc019SAndroid Build Coastguard Worker
2213*d83cc019SAndroid Build Coastguard Worker return ptr;
2214*d83cc019SAndroid Build Coastguard Worker }
2215*d83cc019SAndroid Build Coastguard Worker
2216*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
create_cairo_surface__gtt(int fd,struct igt_fb * fb)2217*d83cc019SAndroid Build Coastguard Worker static void create_cairo_surface__gtt(int fd, struct igt_fb *fb)
2218*d83cc019SAndroid Build Coastguard Worker {
2219*d83cc019SAndroid Build Coastguard Worker void *ptr = map_bo(fd, fb);
2220*d83cc019SAndroid Build Coastguard Worker
2221*d83cc019SAndroid Build Coastguard Worker fb->cairo_surface =
2222*d83cc019SAndroid Build Coastguard Worker cairo_image_surface_create_for_data(ptr,
2223*d83cc019SAndroid Build Coastguard Worker drm_format_to_cairo(fb->drm_format),
2224*d83cc019SAndroid Build Coastguard Worker fb->width, fb->height, fb->strides[0]);
2225*d83cc019SAndroid Build Coastguard Worker igt_require_f(cairo_surface_status(fb->cairo_surface) == CAIRO_STATUS_SUCCESS,
2226*d83cc019SAndroid Build Coastguard Worker "Unable to create a cairo surface: %s\n",
2227*d83cc019SAndroid Build Coastguard Worker cairo_status_to_string(cairo_surface_status(fb->cairo_surface)));
2228*d83cc019SAndroid Build Coastguard Worker
2229*d83cc019SAndroid Build Coastguard Worker fb->domain = I915_GEM_DOMAIN_GTT;
2230*d83cc019SAndroid Build Coastguard Worker
2231*d83cc019SAndroid Build Coastguard Worker cairo_surface_set_user_data(fb->cairo_surface,
2232*d83cc019SAndroid Build Coastguard Worker (cairo_user_data_key_t *)create_cairo_surface__gtt,
2233*d83cc019SAndroid Build Coastguard Worker fb, destroy_cairo_surface__gtt);
2234*d83cc019SAndroid Build Coastguard Worker }
2235*d83cc019SAndroid Build Coastguard Worker #endif
2236*d83cc019SAndroid Build Coastguard Worker
2237*d83cc019SAndroid Build Coastguard Worker struct fb_convert_blit_upload {
2238*d83cc019SAndroid Build Coastguard Worker struct fb_blit_upload base;
2239*d83cc019SAndroid Build Coastguard Worker
2240*d83cc019SAndroid Build Coastguard Worker struct igt_fb shadow_fb;
2241*d83cc019SAndroid Build Coastguard Worker uint8_t *shadow_ptr;
2242*d83cc019SAndroid Build Coastguard Worker };
2243*d83cc019SAndroid Build Coastguard Worker
2244*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
igt_fb_create_cairo_shadow_buffer(int fd,unsigned drm_format,unsigned int width,unsigned int height,struct igt_fb * shadow)2245*d83cc019SAndroid Build Coastguard Worker static void *igt_fb_create_cairo_shadow_buffer(int fd,
2246*d83cc019SAndroid Build Coastguard Worker unsigned drm_format,
2247*d83cc019SAndroid Build Coastguard Worker unsigned int width,
2248*d83cc019SAndroid Build Coastguard Worker unsigned int height,
2249*d83cc019SAndroid Build Coastguard Worker struct igt_fb *shadow)
2250*d83cc019SAndroid Build Coastguard Worker {
2251*d83cc019SAndroid Build Coastguard Worker void *ptr;
2252*d83cc019SAndroid Build Coastguard Worker
2253*d83cc019SAndroid Build Coastguard Worker igt_assert(shadow);
2254*d83cc019SAndroid Build Coastguard Worker
2255*d83cc019SAndroid Build Coastguard Worker igt_init_fb(shadow, fd, width, height,
2256*d83cc019SAndroid Build Coastguard Worker drm_format, LOCAL_DRM_FORMAT_MOD_NONE,
2257*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_BT709, IGT_COLOR_YCBCR_LIMITED_RANGE);
2258*d83cc019SAndroid Build Coastguard Worker
2259*d83cc019SAndroid Build Coastguard Worker shadow->strides[0] = ALIGN(width * (shadow->plane_bpp[0] / 8), 16);
2260*d83cc019SAndroid Build Coastguard Worker shadow->size = ALIGN((uint64_t)shadow->strides[0] * height,
2261*d83cc019SAndroid Build Coastguard Worker sysconf(_SC_PAGESIZE));
2262*d83cc019SAndroid Build Coastguard Worker ptr = mmap(NULL, shadow->size, PROT_READ | PROT_WRITE,
2263*d83cc019SAndroid Build Coastguard Worker MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2264*d83cc019SAndroid Build Coastguard Worker igt_assert(ptr != MAP_FAILED);
2265*d83cc019SAndroid Build Coastguard Worker
2266*d83cc019SAndroid Build Coastguard Worker return ptr;
2267*d83cc019SAndroid Build Coastguard Worker }
2268*d83cc019SAndroid Build Coastguard Worker
igt_fb_destroy_cairo_shadow_buffer(struct igt_fb * shadow,void * ptr)2269*d83cc019SAndroid Build Coastguard Worker static void igt_fb_destroy_cairo_shadow_buffer(struct igt_fb *shadow,
2270*d83cc019SAndroid Build Coastguard Worker void *ptr)
2271*d83cc019SAndroid Build Coastguard Worker {
2272*d83cc019SAndroid Build Coastguard Worker munmap(ptr, shadow->size);
2273*d83cc019SAndroid Build Coastguard Worker }
2274*d83cc019SAndroid Build Coastguard Worker
clamprgb(float val)2275*d83cc019SAndroid Build Coastguard Worker static uint8_t clamprgb(float val)
2276*d83cc019SAndroid Build Coastguard Worker {
2277*d83cc019SAndroid Build Coastguard Worker return clamp((int)(val + 0.5f), 0, 255);
2278*d83cc019SAndroid Build Coastguard Worker }
2279*d83cc019SAndroid Build Coastguard Worker
read_rgb(struct igt_vec4 * rgb,const uint8_t * rgb24)2280*d83cc019SAndroid Build Coastguard Worker static void read_rgb(struct igt_vec4 *rgb, const uint8_t *rgb24)
2281*d83cc019SAndroid Build Coastguard Worker {
2282*d83cc019SAndroid Build Coastguard Worker rgb->d[0] = rgb24[2];
2283*d83cc019SAndroid Build Coastguard Worker rgb->d[1] = rgb24[1];
2284*d83cc019SAndroid Build Coastguard Worker rgb->d[2] = rgb24[0];
2285*d83cc019SAndroid Build Coastguard Worker rgb->d[3] = 1.0f;
2286*d83cc019SAndroid Build Coastguard Worker }
2287*d83cc019SAndroid Build Coastguard Worker
write_rgb(uint8_t * rgb24,const struct igt_vec4 * rgb)2288*d83cc019SAndroid Build Coastguard Worker static void write_rgb(uint8_t *rgb24, const struct igt_vec4 *rgb)
2289*d83cc019SAndroid Build Coastguard Worker {
2290*d83cc019SAndroid Build Coastguard Worker rgb24[2] = clamprgb(rgb->d[0]);
2291*d83cc019SAndroid Build Coastguard Worker rgb24[1] = clamprgb(rgb->d[1]);
2292*d83cc019SAndroid Build Coastguard Worker rgb24[0] = clamprgb(rgb->d[2]);
2293*d83cc019SAndroid Build Coastguard Worker }
2294*d83cc019SAndroid Build Coastguard Worker
2295*d83cc019SAndroid Build Coastguard Worker struct fb_convert_buf {
2296*d83cc019SAndroid Build Coastguard Worker void *ptr;
2297*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb;
2298*d83cc019SAndroid Build Coastguard Worker bool slow_reads;
2299*d83cc019SAndroid Build Coastguard Worker };
2300*d83cc019SAndroid Build Coastguard Worker
2301*d83cc019SAndroid Build Coastguard Worker struct fb_convert {
2302*d83cc019SAndroid Build Coastguard Worker struct fb_convert_buf dst;
2303*d83cc019SAndroid Build Coastguard Worker struct fb_convert_buf src;
2304*d83cc019SAndroid Build Coastguard Worker };
2305*d83cc019SAndroid Build Coastguard Worker
convert_src_get(const struct fb_convert * cvt)2306*d83cc019SAndroid Build Coastguard Worker static void *convert_src_get(const struct fb_convert *cvt)
2307*d83cc019SAndroid Build Coastguard Worker {
2308*d83cc019SAndroid Build Coastguard Worker void *buf;
2309*d83cc019SAndroid Build Coastguard Worker
2310*d83cc019SAndroid Build Coastguard Worker if (!cvt->src.slow_reads)
2311*d83cc019SAndroid Build Coastguard Worker return cvt->src.ptr;
2312*d83cc019SAndroid Build Coastguard Worker
2313*d83cc019SAndroid Build Coastguard Worker /*
2314*d83cc019SAndroid Build Coastguard Worker * Reading from the BO is awfully slow because of lack of read caching,
2315*d83cc019SAndroid Build Coastguard Worker * it's faster to copy the whole BO to a temporary buffer and convert
2316*d83cc019SAndroid Build Coastguard Worker * from there.
2317*d83cc019SAndroid Build Coastguard Worker */
2318*d83cc019SAndroid Build Coastguard Worker buf = malloc(cvt->src.fb->size);
2319*d83cc019SAndroid Build Coastguard Worker if (!buf)
2320*d83cc019SAndroid Build Coastguard Worker return cvt->src.ptr;
2321*d83cc019SAndroid Build Coastguard Worker
2322*d83cc019SAndroid Build Coastguard Worker igt_memcpy_from_wc(buf, cvt->src.ptr, cvt->src.fb->size);
2323*d83cc019SAndroid Build Coastguard Worker
2324*d83cc019SAndroid Build Coastguard Worker return buf;
2325*d83cc019SAndroid Build Coastguard Worker }
2326*d83cc019SAndroid Build Coastguard Worker
convert_src_put(const struct fb_convert * cvt,void * src_buf)2327*d83cc019SAndroid Build Coastguard Worker static void convert_src_put(const struct fb_convert *cvt,
2328*d83cc019SAndroid Build Coastguard Worker void *src_buf)
2329*d83cc019SAndroid Build Coastguard Worker {
2330*d83cc019SAndroid Build Coastguard Worker if (src_buf != cvt->src.ptr)
2331*d83cc019SAndroid Build Coastguard Worker free(src_buf);
2332*d83cc019SAndroid Build Coastguard Worker }
2333*d83cc019SAndroid Build Coastguard Worker
2334*d83cc019SAndroid Build Coastguard Worker struct yuv_parameters {
2335*d83cc019SAndroid Build Coastguard Worker unsigned ay_inc;
2336*d83cc019SAndroid Build Coastguard Worker unsigned uv_inc;
2337*d83cc019SAndroid Build Coastguard Worker unsigned ay_stride;
2338*d83cc019SAndroid Build Coastguard Worker unsigned uv_stride;
2339*d83cc019SAndroid Build Coastguard Worker unsigned a_offset;
2340*d83cc019SAndroid Build Coastguard Worker unsigned y_offset;
2341*d83cc019SAndroid Build Coastguard Worker unsigned u_offset;
2342*d83cc019SAndroid Build Coastguard Worker unsigned v_offset;
2343*d83cc019SAndroid Build Coastguard Worker };
2344*d83cc019SAndroid Build Coastguard Worker
get_yuv_parameters(struct igt_fb * fb,struct yuv_parameters * params)2345*d83cc019SAndroid Build Coastguard Worker static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
2346*d83cc019SAndroid Build Coastguard Worker {
2347*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_format_is_yuv(fb->drm_format));
2348*d83cc019SAndroid Build Coastguard Worker
2349*d83cc019SAndroid Build Coastguard Worker switch (fb->drm_format) {
2350*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
2351*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV16:
2352*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV21:
2353*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV61:
2354*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P010:
2355*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P012:
2356*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P016:
2357*d83cc019SAndroid Build Coastguard Worker params->ay_inc = 1;
2358*d83cc019SAndroid Build Coastguard Worker params->uv_inc = 2;
2359*d83cc019SAndroid Build Coastguard Worker break;
2360*d83cc019SAndroid Build Coastguard Worker
2361*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV420:
2362*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV422:
2363*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
2364*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU422:
2365*d83cc019SAndroid Build Coastguard Worker params->ay_inc = 1;
2366*d83cc019SAndroid Build Coastguard Worker params->uv_inc = 1;
2367*d83cc019SAndroid Build Coastguard Worker break;
2368*d83cc019SAndroid Build Coastguard Worker
2369*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUYV:
2370*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVYU:
2371*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_UYVY:
2372*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_VYUY:
2373*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y210:
2374*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y212:
2375*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y216:
2376*d83cc019SAndroid Build Coastguard Worker params->ay_inc = 2;
2377*d83cc019SAndroid Build Coastguard Worker params->uv_inc = 4;
2378*d83cc019SAndroid Build Coastguard Worker break;
2379*d83cc019SAndroid Build Coastguard Worker
2380*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU12_16161616:
2381*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU16161616:
2382*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y412:
2383*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y416:
2384*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XYUV8888:
2385*d83cc019SAndroid Build Coastguard Worker params->ay_inc = 4;
2386*d83cc019SAndroid Build Coastguard Worker params->uv_inc = 4;
2387*d83cc019SAndroid Build Coastguard Worker break;
2388*d83cc019SAndroid Build Coastguard Worker }
2389*d83cc019SAndroid Build Coastguard Worker
2390*d83cc019SAndroid Build Coastguard Worker switch (fb->drm_format) {
2391*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
2392*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV16:
2393*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV21:
2394*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV61:
2395*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV420:
2396*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV422:
2397*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
2398*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU422:
2399*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P010:
2400*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P012:
2401*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P016:
2402*d83cc019SAndroid Build Coastguard Worker params->ay_stride = fb->strides[0];
2403*d83cc019SAndroid Build Coastguard Worker params->uv_stride = fb->strides[1];
2404*d83cc019SAndroid Build Coastguard Worker break;
2405*d83cc019SAndroid Build Coastguard Worker
2406*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUYV:
2407*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVYU:
2408*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_UYVY:
2409*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_VYUY:
2410*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y210:
2411*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y212:
2412*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y216:
2413*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XYUV8888:
2414*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU12_16161616:
2415*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU16161616:
2416*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y412:
2417*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y416:
2418*d83cc019SAndroid Build Coastguard Worker params->ay_stride = fb->strides[0];
2419*d83cc019SAndroid Build Coastguard Worker params->uv_stride = fb->strides[0];
2420*d83cc019SAndroid Build Coastguard Worker break;
2421*d83cc019SAndroid Build Coastguard Worker }
2422*d83cc019SAndroid Build Coastguard Worker
2423*d83cc019SAndroid Build Coastguard Worker switch (fb->drm_format) {
2424*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
2425*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV16:
2426*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2427*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[1];
2428*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[1] + 1;
2429*d83cc019SAndroid Build Coastguard Worker break;
2430*d83cc019SAndroid Build Coastguard Worker
2431*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV21:
2432*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV61:
2433*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2434*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[1] + 1;
2435*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[1];
2436*d83cc019SAndroid Build Coastguard Worker break;
2437*d83cc019SAndroid Build Coastguard Worker
2438*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV420:
2439*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV422:
2440*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2441*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[1];
2442*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[2];
2443*d83cc019SAndroid Build Coastguard Worker break;
2444*d83cc019SAndroid Build Coastguard Worker
2445*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
2446*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU422:
2447*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2448*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[2];
2449*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[1];
2450*d83cc019SAndroid Build Coastguard Worker break;
2451*d83cc019SAndroid Build Coastguard Worker
2452*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P010:
2453*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P012:
2454*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P016:
2455*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2456*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[1];
2457*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[1] + 2;
2458*d83cc019SAndroid Build Coastguard Worker break;
2459*d83cc019SAndroid Build Coastguard Worker
2460*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUYV:
2461*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2462*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[0] + 1;
2463*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[0] + 3;
2464*d83cc019SAndroid Build Coastguard Worker break;
2465*d83cc019SAndroid Build Coastguard Worker
2466*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVYU:
2467*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2468*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[0] + 3;
2469*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[0] + 1;
2470*d83cc019SAndroid Build Coastguard Worker break;
2471*d83cc019SAndroid Build Coastguard Worker
2472*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_UYVY:
2473*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0] + 1;
2474*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[0];
2475*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[0] + 2;
2476*d83cc019SAndroid Build Coastguard Worker break;
2477*d83cc019SAndroid Build Coastguard Worker
2478*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_VYUY:
2479*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0] + 1;
2480*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[0] + 2;
2481*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[0];
2482*d83cc019SAndroid Build Coastguard Worker break;
2483*d83cc019SAndroid Build Coastguard Worker
2484*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y210:
2485*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y212:
2486*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y216:
2487*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0];
2488*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[0] + 2;
2489*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[0] + 6;
2490*d83cc019SAndroid Build Coastguard Worker break;
2491*d83cc019SAndroid Build Coastguard Worker
2492*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU12_16161616:
2493*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU16161616:
2494*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y412:
2495*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y416:
2496*d83cc019SAndroid Build Coastguard Worker params->a_offset = fb->offsets[0] + 6;
2497*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0] + 2;
2498*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[0];
2499*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[0] + 4;
2500*d83cc019SAndroid Build Coastguard Worker break;
2501*d83cc019SAndroid Build Coastguard Worker
2502*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XYUV8888:
2503*d83cc019SAndroid Build Coastguard Worker params->y_offset = fb->offsets[0] + 1;
2504*d83cc019SAndroid Build Coastguard Worker params->u_offset = fb->offsets[0] + 2;
2505*d83cc019SAndroid Build Coastguard Worker params->v_offset = fb->offsets[0] + 3;
2506*d83cc019SAndroid Build Coastguard Worker break;
2507*d83cc019SAndroid Build Coastguard Worker }
2508*d83cc019SAndroid Build Coastguard Worker }
2509*d83cc019SAndroid Build Coastguard Worker
convert_yuv_to_rgb24(struct fb_convert * cvt)2510*d83cc019SAndroid Build Coastguard Worker static void convert_yuv_to_rgb24(struct fb_convert *cvt)
2511*d83cc019SAndroid Build Coastguard Worker {
2512*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *src_fmt =
2513*d83cc019SAndroid Build Coastguard Worker lookup_drm_format(cvt->src.fb->drm_format);
2514*d83cc019SAndroid Build Coastguard Worker int i, j;
2515*d83cc019SAndroid Build Coastguard Worker uint8_t bpp = 4;
2516*d83cc019SAndroid Build Coastguard Worker uint8_t *y, *u, *v;
2517*d83cc019SAndroid Build Coastguard Worker uint8_t *rgb24 = cvt->dst.ptr;
2518*d83cc019SAndroid Build Coastguard Worker unsigned int rgb24_stride = cvt->dst.fb->strides[0];
2519*d83cc019SAndroid Build Coastguard Worker struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
2520*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format,
2521*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->color_encoding,
2522*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->color_range);
2523*d83cc019SAndroid Build Coastguard Worker uint8_t *buf;
2524*d83cc019SAndroid Build Coastguard Worker struct yuv_parameters params = { };
2525*d83cc019SAndroid Build Coastguard Worker
2526*d83cc019SAndroid Build Coastguard Worker igt_assert(cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888 &&
2527*d83cc019SAndroid Build Coastguard Worker igt_format_is_yuv(cvt->src.fb->drm_format));
2528*d83cc019SAndroid Build Coastguard Worker
2529*d83cc019SAndroid Build Coastguard Worker buf = convert_src_get(cvt);
2530*d83cc019SAndroid Build Coastguard Worker get_yuv_parameters(cvt->src.fb, ¶ms);
2531*d83cc019SAndroid Build Coastguard Worker y = buf + params.y_offset;
2532*d83cc019SAndroid Build Coastguard Worker u = buf + params.u_offset;
2533*d83cc019SAndroid Build Coastguard Worker v = buf + params.v_offset;
2534*d83cc019SAndroid Build Coastguard Worker
2535*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
2536*d83cc019SAndroid Build Coastguard Worker const uint8_t *y_tmp = y;
2537*d83cc019SAndroid Build Coastguard Worker const uint8_t *u_tmp = u;
2538*d83cc019SAndroid Build Coastguard Worker const uint8_t *v_tmp = v;
2539*d83cc019SAndroid Build Coastguard Worker uint8_t *rgb_tmp = rgb24;
2540*d83cc019SAndroid Build Coastguard Worker
2541*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
2542*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 rgb, yuv;
2543*d83cc019SAndroid Build Coastguard Worker
2544*d83cc019SAndroid Build Coastguard Worker yuv.d[0] = *y_tmp;
2545*d83cc019SAndroid Build Coastguard Worker yuv.d[1] = *u_tmp;
2546*d83cc019SAndroid Build Coastguard Worker yuv.d[2] = *v_tmp;
2547*d83cc019SAndroid Build Coastguard Worker yuv.d[3] = 1.0f;
2548*d83cc019SAndroid Build Coastguard Worker
2549*d83cc019SAndroid Build Coastguard Worker rgb = igt_matrix_transform(&m, &yuv);
2550*d83cc019SAndroid Build Coastguard Worker write_rgb(rgb_tmp, &rgb);
2551*d83cc019SAndroid Build Coastguard Worker
2552*d83cc019SAndroid Build Coastguard Worker rgb_tmp += bpp;
2553*d83cc019SAndroid Build Coastguard Worker y_tmp += params.ay_inc;
2554*d83cc019SAndroid Build Coastguard Worker
2555*d83cc019SAndroid Build Coastguard Worker if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
2556*d83cc019SAndroid Build Coastguard Worker u_tmp += params.uv_inc;
2557*d83cc019SAndroid Build Coastguard Worker v_tmp += params.uv_inc;
2558*d83cc019SAndroid Build Coastguard Worker }
2559*d83cc019SAndroid Build Coastguard Worker }
2560*d83cc019SAndroid Build Coastguard Worker
2561*d83cc019SAndroid Build Coastguard Worker rgb24 += rgb24_stride;
2562*d83cc019SAndroid Build Coastguard Worker y += params.ay_stride;
2563*d83cc019SAndroid Build Coastguard Worker
2564*d83cc019SAndroid Build Coastguard Worker if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
2565*d83cc019SAndroid Build Coastguard Worker u += params.uv_stride;
2566*d83cc019SAndroid Build Coastguard Worker v += params.uv_stride;
2567*d83cc019SAndroid Build Coastguard Worker }
2568*d83cc019SAndroid Build Coastguard Worker }
2569*d83cc019SAndroid Build Coastguard Worker
2570*d83cc019SAndroid Build Coastguard Worker convert_src_put(cvt, buf);
2571*d83cc019SAndroid Build Coastguard Worker }
2572*d83cc019SAndroid Build Coastguard Worker
convert_rgb24_to_yuv(struct fb_convert * cvt)2573*d83cc019SAndroid Build Coastguard Worker static void convert_rgb24_to_yuv(struct fb_convert *cvt)
2574*d83cc019SAndroid Build Coastguard Worker {
2575*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *dst_fmt =
2576*d83cc019SAndroid Build Coastguard Worker lookup_drm_format(cvt->dst.fb->drm_format);
2577*d83cc019SAndroid Build Coastguard Worker int i, j;
2578*d83cc019SAndroid Build Coastguard Worker uint8_t *y, *u, *v;
2579*d83cc019SAndroid Build Coastguard Worker const uint8_t *rgb24 = cvt->src.ptr;
2580*d83cc019SAndroid Build Coastguard Worker uint8_t bpp = 4;
2581*d83cc019SAndroid Build Coastguard Worker unsigned rgb24_stride = cvt->src.fb->strides[0];
2582*d83cc019SAndroid Build Coastguard Worker struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
2583*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format,
2584*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->color_encoding,
2585*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->color_range);
2586*d83cc019SAndroid Build Coastguard Worker struct yuv_parameters params = { };
2587*d83cc019SAndroid Build Coastguard Worker
2588*d83cc019SAndroid Build Coastguard Worker igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
2589*d83cc019SAndroid Build Coastguard Worker igt_format_is_yuv(cvt->dst.fb->drm_format));
2590*d83cc019SAndroid Build Coastguard Worker
2591*d83cc019SAndroid Build Coastguard Worker get_yuv_parameters(cvt->dst.fb, ¶ms);
2592*d83cc019SAndroid Build Coastguard Worker y = (uint8_t*)cvt->dst.ptr + params.y_offset;
2593*d83cc019SAndroid Build Coastguard Worker u = (uint8_t*)cvt->dst.ptr + params.u_offset;
2594*d83cc019SAndroid Build Coastguard Worker v = (uint8_t*)cvt->dst.ptr + params.v_offset;
2595*d83cc019SAndroid Build Coastguard Worker
2596*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
2597*d83cc019SAndroid Build Coastguard Worker const uint8_t *rgb_tmp = rgb24;
2598*d83cc019SAndroid Build Coastguard Worker uint8_t *y_tmp = y;
2599*d83cc019SAndroid Build Coastguard Worker uint8_t *u_tmp = u;
2600*d83cc019SAndroid Build Coastguard Worker uint8_t *v_tmp = v;
2601*d83cc019SAndroid Build Coastguard Worker
2602*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
2603*d83cc019SAndroid Build Coastguard Worker const uint8_t *pair_rgb24 = rgb_tmp;
2604*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 pair_rgb, rgb;
2605*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 pair_yuv, yuv;
2606*d83cc019SAndroid Build Coastguard Worker
2607*d83cc019SAndroid Build Coastguard Worker read_rgb(&rgb, rgb_tmp);
2608*d83cc019SAndroid Build Coastguard Worker yuv = igt_matrix_transform(&m, &rgb);
2609*d83cc019SAndroid Build Coastguard Worker
2610*d83cc019SAndroid Build Coastguard Worker rgb_tmp += bpp;
2611*d83cc019SAndroid Build Coastguard Worker
2612*d83cc019SAndroid Build Coastguard Worker *y_tmp = yuv.d[0];
2613*d83cc019SAndroid Build Coastguard Worker y_tmp += params.ay_inc;
2614*d83cc019SAndroid Build Coastguard Worker
2615*d83cc019SAndroid Build Coastguard Worker if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
2616*d83cc019SAndroid Build Coastguard Worker continue;
2617*d83cc019SAndroid Build Coastguard Worker
2618*d83cc019SAndroid Build Coastguard Worker /*
2619*d83cc019SAndroid Build Coastguard Worker * We assume the MPEG2 chroma siting convention, where
2620*d83cc019SAndroid Build Coastguard Worker * pixel center for Cb'Cr' is between the left top and
2621*d83cc019SAndroid Build Coastguard Worker * bottom pixel in a 2x2 block, so take the average.
2622*d83cc019SAndroid Build Coastguard Worker *
2623*d83cc019SAndroid Build Coastguard Worker * Therefore, if we use subsampling, we only really care
2624*d83cc019SAndroid Build Coastguard Worker * about two pixels all the time, either the two
2625*d83cc019SAndroid Build Coastguard Worker * subsequent pixels horizontally, vertically, or the
2626*d83cc019SAndroid Build Coastguard Worker * two corners in a 2x2 block.
2627*d83cc019SAndroid Build Coastguard Worker *
2628*d83cc019SAndroid Build Coastguard Worker * The only corner case is when we have an odd number of
2629*d83cc019SAndroid Build Coastguard Worker * pixels, but this can be handled pretty easily by not
2630*d83cc019SAndroid Build Coastguard Worker * incrementing the paired pixel pointer in the
2631*d83cc019SAndroid Build Coastguard Worker * direction it's odd in.
2632*d83cc019SAndroid Build Coastguard Worker */
2633*d83cc019SAndroid Build Coastguard Worker if (j != (cvt->dst.fb->width - 1))
2634*d83cc019SAndroid Build Coastguard Worker pair_rgb24 += (dst_fmt->hsub - 1) * bpp;
2635*d83cc019SAndroid Build Coastguard Worker
2636*d83cc019SAndroid Build Coastguard Worker if (i != (cvt->dst.fb->height - 1))
2637*d83cc019SAndroid Build Coastguard Worker pair_rgb24 += rgb24_stride * (dst_fmt->vsub - 1);
2638*d83cc019SAndroid Build Coastguard Worker
2639*d83cc019SAndroid Build Coastguard Worker read_rgb(&pair_rgb, pair_rgb24);
2640*d83cc019SAndroid Build Coastguard Worker pair_yuv = igt_matrix_transform(&m, &pair_rgb);
2641*d83cc019SAndroid Build Coastguard Worker
2642*d83cc019SAndroid Build Coastguard Worker *u_tmp = (yuv.d[1] + pair_yuv.d[1]) / 2.0f;
2643*d83cc019SAndroid Build Coastguard Worker *v_tmp = (yuv.d[2] + pair_yuv.d[2]) / 2.0f;
2644*d83cc019SAndroid Build Coastguard Worker
2645*d83cc019SAndroid Build Coastguard Worker u_tmp += params.uv_inc;
2646*d83cc019SAndroid Build Coastguard Worker v_tmp += params.uv_inc;
2647*d83cc019SAndroid Build Coastguard Worker }
2648*d83cc019SAndroid Build Coastguard Worker
2649*d83cc019SAndroid Build Coastguard Worker rgb24 += rgb24_stride;
2650*d83cc019SAndroid Build Coastguard Worker y += params.ay_stride;
2651*d83cc019SAndroid Build Coastguard Worker
2652*d83cc019SAndroid Build Coastguard Worker if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
2653*d83cc019SAndroid Build Coastguard Worker u += params.uv_stride;
2654*d83cc019SAndroid Build Coastguard Worker v += params.uv_stride;
2655*d83cc019SAndroid Build Coastguard Worker }
2656*d83cc019SAndroid Build Coastguard Worker }
2657*d83cc019SAndroid Build Coastguard Worker }
2658*d83cc019SAndroid Build Coastguard Worker
read_rgbf(struct igt_vec4 * rgb,const float * rgb24)2659*d83cc019SAndroid Build Coastguard Worker static void read_rgbf(struct igt_vec4 *rgb, const float *rgb24)
2660*d83cc019SAndroid Build Coastguard Worker {
2661*d83cc019SAndroid Build Coastguard Worker rgb->d[0] = rgb24[0];
2662*d83cc019SAndroid Build Coastguard Worker rgb->d[1] = rgb24[1];
2663*d83cc019SAndroid Build Coastguard Worker rgb->d[2] = rgb24[2];
2664*d83cc019SAndroid Build Coastguard Worker rgb->d[3] = 1.0f;
2665*d83cc019SAndroid Build Coastguard Worker }
2666*d83cc019SAndroid Build Coastguard Worker
write_rgbf(float * rgb24,const struct igt_vec4 * rgb)2667*d83cc019SAndroid Build Coastguard Worker static void write_rgbf(float *rgb24, const struct igt_vec4 *rgb)
2668*d83cc019SAndroid Build Coastguard Worker {
2669*d83cc019SAndroid Build Coastguard Worker rgb24[0] = rgb->d[0];
2670*d83cc019SAndroid Build Coastguard Worker rgb24[1] = rgb->d[1];
2671*d83cc019SAndroid Build Coastguard Worker rgb24[2] = rgb->d[2];
2672*d83cc019SAndroid Build Coastguard Worker }
2673*d83cc019SAndroid Build Coastguard Worker
convert_yuv16_to_float(struct fb_convert * cvt,bool alpha)2674*d83cc019SAndroid Build Coastguard Worker static void convert_yuv16_to_float(struct fb_convert *cvt, bool alpha)
2675*d83cc019SAndroid Build Coastguard Worker {
2676*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *src_fmt =
2677*d83cc019SAndroid Build Coastguard Worker lookup_drm_format(cvt->src.fb->drm_format);
2678*d83cc019SAndroid Build Coastguard Worker int i, j;
2679*d83cc019SAndroid Build Coastguard Worker uint8_t fpp = alpha ? 4 : 3;
2680*d83cc019SAndroid Build Coastguard Worker uint16_t *a, *y, *u, *v;
2681*d83cc019SAndroid Build Coastguard Worker float *ptr = cvt->dst.ptr;
2682*d83cc019SAndroid Build Coastguard Worker unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
2683*d83cc019SAndroid Build Coastguard Worker struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
2684*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format,
2685*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->color_encoding,
2686*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->color_range);
2687*d83cc019SAndroid Build Coastguard Worker uint16_t *buf;
2688*d83cc019SAndroid Build Coastguard Worker struct yuv_parameters params = { };
2689*d83cc019SAndroid Build Coastguard Worker
2690*d83cc019SAndroid Build Coastguard Worker igt_assert(cvt->dst.fb->drm_format == IGT_FORMAT_FLOAT &&
2691*d83cc019SAndroid Build Coastguard Worker igt_format_is_yuv(cvt->src.fb->drm_format));
2692*d83cc019SAndroid Build Coastguard Worker
2693*d83cc019SAndroid Build Coastguard Worker buf = convert_src_get(cvt);
2694*d83cc019SAndroid Build Coastguard Worker get_yuv_parameters(cvt->src.fb, ¶ms);
2695*d83cc019SAndroid Build Coastguard Worker igt_assert(!(params.y_offset % sizeof(*buf)) &&
2696*d83cc019SAndroid Build Coastguard Worker !(params.u_offset % sizeof(*buf)) &&
2697*d83cc019SAndroid Build Coastguard Worker !(params.v_offset % sizeof(*buf)));
2698*d83cc019SAndroid Build Coastguard Worker
2699*d83cc019SAndroid Build Coastguard Worker a = buf + params.a_offset / sizeof(*buf);
2700*d83cc019SAndroid Build Coastguard Worker y = buf + params.y_offset / sizeof(*buf);
2701*d83cc019SAndroid Build Coastguard Worker u = buf + params.u_offset / sizeof(*buf);
2702*d83cc019SAndroid Build Coastguard Worker v = buf + params.v_offset / sizeof(*buf);
2703*d83cc019SAndroid Build Coastguard Worker
2704*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
2705*d83cc019SAndroid Build Coastguard Worker const uint16_t *a_tmp = a;
2706*d83cc019SAndroid Build Coastguard Worker const uint16_t *y_tmp = y;
2707*d83cc019SAndroid Build Coastguard Worker const uint16_t *u_tmp = u;
2708*d83cc019SAndroid Build Coastguard Worker const uint16_t *v_tmp = v;
2709*d83cc019SAndroid Build Coastguard Worker float *rgb_tmp = ptr;
2710*d83cc019SAndroid Build Coastguard Worker
2711*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
2712*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 rgb, yuv;
2713*d83cc019SAndroid Build Coastguard Worker
2714*d83cc019SAndroid Build Coastguard Worker yuv.d[0] = *y_tmp;
2715*d83cc019SAndroid Build Coastguard Worker yuv.d[1] = *u_tmp;
2716*d83cc019SAndroid Build Coastguard Worker yuv.d[2] = *v_tmp;
2717*d83cc019SAndroid Build Coastguard Worker yuv.d[3] = 1.0f;
2718*d83cc019SAndroid Build Coastguard Worker
2719*d83cc019SAndroid Build Coastguard Worker rgb = igt_matrix_transform(&m, &yuv);
2720*d83cc019SAndroid Build Coastguard Worker write_rgbf(rgb_tmp, &rgb);
2721*d83cc019SAndroid Build Coastguard Worker
2722*d83cc019SAndroid Build Coastguard Worker if (alpha) {
2723*d83cc019SAndroid Build Coastguard Worker rgb_tmp[3] = ((float)*a_tmp) / 65535.f;
2724*d83cc019SAndroid Build Coastguard Worker a_tmp += params.ay_inc;
2725*d83cc019SAndroid Build Coastguard Worker }
2726*d83cc019SAndroid Build Coastguard Worker
2727*d83cc019SAndroid Build Coastguard Worker rgb_tmp += fpp;
2728*d83cc019SAndroid Build Coastguard Worker y_tmp += params.ay_inc;
2729*d83cc019SAndroid Build Coastguard Worker
2730*d83cc019SAndroid Build Coastguard Worker if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
2731*d83cc019SAndroid Build Coastguard Worker u_tmp += params.uv_inc;
2732*d83cc019SAndroid Build Coastguard Worker v_tmp += params.uv_inc;
2733*d83cc019SAndroid Build Coastguard Worker }
2734*d83cc019SAndroid Build Coastguard Worker }
2735*d83cc019SAndroid Build Coastguard Worker
2736*d83cc019SAndroid Build Coastguard Worker ptr += float_stride;
2737*d83cc019SAndroid Build Coastguard Worker
2738*d83cc019SAndroid Build Coastguard Worker a += params.ay_stride / sizeof(*a);
2739*d83cc019SAndroid Build Coastguard Worker y += params.ay_stride / sizeof(*y);
2740*d83cc019SAndroid Build Coastguard Worker
2741*d83cc019SAndroid Build Coastguard Worker if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
2742*d83cc019SAndroid Build Coastguard Worker u += params.uv_stride / sizeof(*u);
2743*d83cc019SAndroid Build Coastguard Worker v += params.uv_stride / sizeof(*v);
2744*d83cc019SAndroid Build Coastguard Worker }
2745*d83cc019SAndroid Build Coastguard Worker }
2746*d83cc019SAndroid Build Coastguard Worker
2747*d83cc019SAndroid Build Coastguard Worker convert_src_put(cvt, buf);
2748*d83cc019SAndroid Build Coastguard Worker }
2749*d83cc019SAndroid Build Coastguard Worker
convert_float_to_yuv16(struct fb_convert * cvt,bool alpha)2750*d83cc019SAndroid Build Coastguard Worker static void convert_float_to_yuv16(struct fb_convert *cvt, bool alpha)
2751*d83cc019SAndroid Build Coastguard Worker {
2752*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *dst_fmt =
2753*d83cc019SAndroid Build Coastguard Worker lookup_drm_format(cvt->dst.fb->drm_format);
2754*d83cc019SAndroid Build Coastguard Worker int i, j;
2755*d83cc019SAndroid Build Coastguard Worker uint16_t *a, *y, *u, *v;
2756*d83cc019SAndroid Build Coastguard Worker const float *ptr = cvt->src.ptr;
2757*d83cc019SAndroid Build Coastguard Worker uint8_t fpp = alpha ? 4 : 3;
2758*d83cc019SAndroid Build Coastguard Worker unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
2759*d83cc019SAndroid Build Coastguard Worker struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
2760*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format,
2761*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->color_encoding,
2762*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->color_range);
2763*d83cc019SAndroid Build Coastguard Worker struct yuv_parameters params = { };
2764*d83cc019SAndroid Build Coastguard Worker
2765*d83cc019SAndroid Build Coastguard Worker igt_assert(cvt->src.fb->drm_format == IGT_FORMAT_FLOAT &&
2766*d83cc019SAndroid Build Coastguard Worker igt_format_is_yuv(cvt->dst.fb->drm_format));
2767*d83cc019SAndroid Build Coastguard Worker
2768*d83cc019SAndroid Build Coastguard Worker get_yuv_parameters(cvt->dst.fb, ¶ms);
2769*d83cc019SAndroid Build Coastguard Worker igt_assert(!(params.a_offset % sizeof(*a)) &&
2770*d83cc019SAndroid Build Coastguard Worker !(params.y_offset % sizeof(*y)) &&
2771*d83cc019SAndroid Build Coastguard Worker !(params.u_offset % sizeof(*u)) &&
2772*d83cc019SAndroid Build Coastguard Worker !(params.v_offset % sizeof(*v)));
2773*d83cc019SAndroid Build Coastguard Worker
2774*d83cc019SAndroid Build Coastguard Worker a = (uint16_t*)((uint8_t*)cvt->dst.ptr + params.a_offset);
2775*d83cc019SAndroid Build Coastguard Worker y = (uint16_t*)((uint8_t*)cvt->dst.ptr + params.y_offset);
2776*d83cc019SAndroid Build Coastguard Worker u = (uint16_t*)((uint8_t*)cvt->dst.ptr + params.u_offset);
2777*d83cc019SAndroid Build Coastguard Worker v = (uint16_t*)((uint8_t*)cvt->dst.ptr + params.v_offset);
2778*d83cc019SAndroid Build Coastguard Worker
2779*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
2780*d83cc019SAndroid Build Coastguard Worker const float *rgb_tmp = ptr;
2781*d83cc019SAndroid Build Coastguard Worker uint16_t *a_tmp = a;
2782*d83cc019SAndroid Build Coastguard Worker uint16_t *y_tmp = y;
2783*d83cc019SAndroid Build Coastguard Worker uint16_t *u_tmp = u;
2784*d83cc019SAndroid Build Coastguard Worker uint16_t *v_tmp = v;
2785*d83cc019SAndroid Build Coastguard Worker
2786*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
2787*d83cc019SAndroid Build Coastguard Worker const float *pair_float = rgb_tmp;
2788*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 pair_rgb, rgb;
2789*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 pair_yuv, yuv;
2790*d83cc019SAndroid Build Coastguard Worker
2791*d83cc019SAndroid Build Coastguard Worker read_rgbf(&rgb, rgb_tmp);
2792*d83cc019SAndroid Build Coastguard Worker yuv = igt_matrix_transform(&m, &rgb);
2793*d83cc019SAndroid Build Coastguard Worker
2794*d83cc019SAndroid Build Coastguard Worker if (alpha) {
2795*d83cc019SAndroid Build Coastguard Worker *a_tmp = rgb_tmp[3] * 65535.f + .5f;
2796*d83cc019SAndroid Build Coastguard Worker a_tmp += params.ay_inc;
2797*d83cc019SAndroid Build Coastguard Worker }
2798*d83cc019SAndroid Build Coastguard Worker
2799*d83cc019SAndroid Build Coastguard Worker rgb_tmp += fpp;
2800*d83cc019SAndroid Build Coastguard Worker
2801*d83cc019SAndroid Build Coastguard Worker *y_tmp = yuv.d[0];
2802*d83cc019SAndroid Build Coastguard Worker y_tmp += params.ay_inc;
2803*d83cc019SAndroid Build Coastguard Worker
2804*d83cc019SAndroid Build Coastguard Worker if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
2805*d83cc019SAndroid Build Coastguard Worker continue;
2806*d83cc019SAndroid Build Coastguard Worker
2807*d83cc019SAndroid Build Coastguard Worker /*
2808*d83cc019SAndroid Build Coastguard Worker * We assume the MPEG2 chroma siting convention, where
2809*d83cc019SAndroid Build Coastguard Worker * pixel center for Cb'Cr' is between the left top and
2810*d83cc019SAndroid Build Coastguard Worker * bottom pixel in a 2x2 block, so take the average.
2811*d83cc019SAndroid Build Coastguard Worker *
2812*d83cc019SAndroid Build Coastguard Worker * Therefore, if we use subsampling, we only really care
2813*d83cc019SAndroid Build Coastguard Worker * about two pixels all the time, either the two
2814*d83cc019SAndroid Build Coastguard Worker * subsequent pixels horizontally, vertically, or the
2815*d83cc019SAndroid Build Coastguard Worker * two corners in a 2x2 block.
2816*d83cc019SAndroid Build Coastguard Worker *
2817*d83cc019SAndroid Build Coastguard Worker * The only corner case is when we have an odd number of
2818*d83cc019SAndroid Build Coastguard Worker * pixels, but this can be handled pretty easily by not
2819*d83cc019SAndroid Build Coastguard Worker * incrementing the paired pixel pointer in the
2820*d83cc019SAndroid Build Coastguard Worker * direction it's odd in.
2821*d83cc019SAndroid Build Coastguard Worker */
2822*d83cc019SAndroid Build Coastguard Worker if (j != (cvt->dst.fb->width - 1))
2823*d83cc019SAndroid Build Coastguard Worker pair_float += (dst_fmt->hsub - 1) * fpp;
2824*d83cc019SAndroid Build Coastguard Worker
2825*d83cc019SAndroid Build Coastguard Worker if (i != (cvt->dst.fb->height - 1))
2826*d83cc019SAndroid Build Coastguard Worker pair_float += float_stride * (dst_fmt->vsub - 1);
2827*d83cc019SAndroid Build Coastguard Worker
2828*d83cc019SAndroid Build Coastguard Worker read_rgbf(&pair_rgb, pair_float);
2829*d83cc019SAndroid Build Coastguard Worker pair_yuv = igt_matrix_transform(&m, &pair_rgb);
2830*d83cc019SAndroid Build Coastguard Worker
2831*d83cc019SAndroid Build Coastguard Worker *u_tmp = (yuv.d[1] + pair_yuv.d[1]) / 2.0f;
2832*d83cc019SAndroid Build Coastguard Worker *v_tmp = (yuv.d[2] + pair_yuv.d[2]) / 2.0f;
2833*d83cc019SAndroid Build Coastguard Worker
2834*d83cc019SAndroid Build Coastguard Worker u_tmp += params.uv_inc;
2835*d83cc019SAndroid Build Coastguard Worker v_tmp += params.uv_inc;
2836*d83cc019SAndroid Build Coastguard Worker }
2837*d83cc019SAndroid Build Coastguard Worker
2838*d83cc019SAndroid Build Coastguard Worker ptr += float_stride;
2839*d83cc019SAndroid Build Coastguard Worker a += params.ay_stride / sizeof(*a);
2840*d83cc019SAndroid Build Coastguard Worker y += params.ay_stride / sizeof(*y);
2841*d83cc019SAndroid Build Coastguard Worker
2842*d83cc019SAndroid Build Coastguard Worker if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
2843*d83cc019SAndroid Build Coastguard Worker u += params.uv_stride / sizeof(*u);
2844*d83cc019SAndroid Build Coastguard Worker v += params.uv_stride / sizeof(*v);
2845*d83cc019SAndroid Build Coastguard Worker }
2846*d83cc019SAndroid Build Coastguard Worker }
2847*d83cc019SAndroid Build Coastguard Worker }
2848*d83cc019SAndroid Build Coastguard Worker
convert_Y410_to_float(struct fb_convert * cvt,bool alpha)2849*d83cc019SAndroid Build Coastguard Worker static void convert_Y410_to_float(struct fb_convert *cvt, bool alpha)
2850*d83cc019SAndroid Build Coastguard Worker {
2851*d83cc019SAndroid Build Coastguard Worker int i, j;
2852*d83cc019SAndroid Build Coastguard Worker const uint32_t *uyv;
2853*d83cc019SAndroid Build Coastguard Worker uint32_t *buf;
2854*d83cc019SAndroid Build Coastguard Worker float *ptr = cvt->dst.ptr;
2855*d83cc019SAndroid Build Coastguard Worker unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
2856*d83cc019SAndroid Build Coastguard Worker unsigned int uyv_stride = cvt->src.fb->strides[0] / sizeof(*uyv);
2857*d83cc019SAndroid Build Coastguard Worker struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
2858*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format,
2859*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->color_encoding,
2860*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->color_range);
2861*d83cc019SAndroid Build Coastguard Worker unsigned bpp = alpha ? 4 : 3;
2862*d83cc019SAndroid Build Coastguard Worker
2863*d83cc019SAndroid Build Coastguard Worker igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_Y410 ||
2864*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->drm_format == DRM_FORMAT_XVYU2101010) &&
2865*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format == IGT_FORMAT_FLOAT);
2866*d83cc019SAndroid Build Coastguard Worker
2867*d83cc019SAndroid Build Coastguard Worker uyv = buf = convert_src_get(cvt);
2868*d83cc019SAndroid Build Coastguard Worker
2869*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
2870*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
2871*d83cc019SAndroid Build Coastguard Worker /* Convert 2x1 pixel blocks */
2872*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 yuv;
2873*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 rgb;
2874*d83cc019SAndroid Build Coastguard Worker
2875*d83cc019SAndroid Build Coastguard Worker yuv.d[0] = (uyv[j] >> 10) & 0x3ff;
2876*d83cc019SAndroid Build Coastguard Worker yuv.d[1] = uyv[j] & 0x3ff;
2877*d83cc019SAndroid Build Coastguard Worker yuv.d[2] = (uyv[j] >> 20) & 0x3ff;
2878*d83cc019SAndroid Build Coastguard Worker yuv.d[3] = 1.f;
2879*d83cc019SAndroid Build Coastguard Worker
2880*d83cc019SAndroid Build Coastguard Worker rgb = igt_matrix_transform(&m, &yuv);
2881*d83cc019SAndroid Build Coastguard Worker
2882*d83cc019SAndroid Build Coastguard Worker write_rgbf(&ptr[j * bpp], &rgb);
2883*d83cc019SAndroid Build Coastguard Worker if (alpha)
2884*d83cc019SAndroid Build Coastguard Worker ptr[j * bpp + 3] = (float)(uyv[j] >> 30) / 3.f;
2885*d83cc019SAndroid Build Coastguard Worker }
2886*d83cc019SAndroid Build Coastguard Worker
2887*d83cc019SAndroid Build Coastguard Worker ptr += float_stride;
2888*d83cc019SAndroid Build Coastguard Worker uyv += uyv_stride;
2889*d83cc019SAndroid Build Coastguard Worker }
2890*d83cc019SAndroid Build Coastguard Worker
2891*d83cc019SAndroid Build Coastguard Worker convert_src_put(cvt, buf);
2892*d83cc019SAndroid Build Coastguard Worker }
2893*d83cc019SAndroid Build Coastguard Worker
convert_float_to_Y410(struct fb_convert * cvt,bool alpha)2894*d83cc019SAndroid Build Coastguard Worker static void convert_float_to_Y410(struct fb_convert *cvt, bool alpha)
2895*d83cc019SAndroid Build Coastguard Worker {
2896*d83cc019SAndroid Build Coastguard Worker int i, j;
2897*d83cc019SAndroid Build Coastguard Worker uint32_t *uyv = cvt->dst.ptr;
2898*d83cc019SAndroid Build Coastguard Worker const float *ptr = cvt->src.ptr;
2899*d83cc019SAndroid Build Coastguard Worker unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
2900*d83cc019SAndroid Build Coastguard Worker unsigned uyv_stride = cvt->dst.fb->strides[0] / sizeof(*uyv);
2901*d83cc019SAndroid Build Coastguard Worker struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
2902*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format,
2903*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->color_encoding,
2904*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->color_range);
2905*d83cc019SAndroid Build Coastguard Worker unsigned bpp = alpha ? 4 : 3;
2906*d83cc019SAndroid Build Coastguard Worker
2907*d83cc019SAndroid Build Coastguard Worker igt_assert(cvt->src.fb->drm_format == IGT_FORMAT_FLOAT &&
2908*d83cc019SAndroid Build Coastguard Worker (cvt->dst.fb->drm_format == DRM_FORMAT_Y410 ||
2909*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->drm_format == DRM_FORMAT_XVYU2101010));
2910*d83cc019SAndroid Build Coastguard Worker
2911*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
2912*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
2913*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 rgb;
2914*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 yuv;
2915*d83cc019SAndroid Build Coastguard Worker uint8_t a = 0;
2916*d83cc019SAndroid Build Coastguard Worker uint16_t y, cb, cr;
2917*d83cc019SAndroid Build Coastguard Worker
2918*d83cc019SAndroid Build Coastguard Worker read_rgbf(&rgb, &ptr[j * bpp]);
2919*d83cc019SAndroid Build Coastguard Worker if (alpha)
2920*d83cc019SAndroid Build Coastguard Worker a = ptr[j * bpp + 3] * 3.f + .5f;
2921*d83cc019SAndroid Build Coastguard Worker
2922*d83cc019SAndroid Build Coastguard Worker yuv = igt_matrix_transform(&m, &rgb);
2923*d83cc019SAndroid Build Coastguard Worker y = yuv.d[0];
2924*d83cc019SAndroid Build Coastguard Worker cb = yuv.d[1];
2925*d83cc019SAndroid Build Coastguard Worker cr = yuv.d[2];
2926*d83cc019SAndroid Build Coastguard Worker
2927*d83cc019SAndroid Build Coastguard Worker uyv[j] = ((cb & 0x3ff) << 0) |
2928*d83cc019SAndroid Build Coastguard Worker ((y & 0x3ff) << 10) |
2929*d83cc019SAndroid Build Coastguard Worker ((cr & 0x3ff) << 20) |
2930*d83cc019SAndroid Build Coastguard Worker (a << 30);
2931*d83cc019SAndroid Build Coastguard Worker }
2932*d83cc019SAndroid Build Coastguard Worker
2933*d83cc019SAndroid Build Coastguard Worker ptr += float_stride;
2934*d83cc019SAndroid Build Coastguard Worker uyv += uyv_stride;
2935*d83cc019SAndroid Build Coastguard Worker }
2936*d83cc019SAndroid Build Coastguard Worker }
2937*d83cc019SAndroid Build Coastguard Worker
2938*d83cc019SAndroid Build Coastguard Worker /* { R, G, B, X } */
2939*d83cc019SAndroid Build Coastguard Worker static const unsigned char swizzle_rgbx[] = { 0, 1, 2, 3 };
2940*d83cc019SAndroid Build Coastguard Worker static const unsigned char swizzle_bgrx[] = { 2, 1, 0, 3 };
2941*d83cc019SAndroid Build Coastguard Worker
rgbx_swizzle(uint32_t format)2942*d83cc019SAndroid Build Coastguard Worker static const unsigned char *rgbx_swizzle(uint32_t format)
2943*d83cc019SAndroid Build Coastguard Worker {
2944*d83cc019SAndroid Build Coastguard Worker switch (format) {
2945*d83cc019SAndroid Build Coastguard Worker default:
2946*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XRGB16161616F:
2947*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ARGB16161616F:
2948*d83cc019SAndroid Build Coastguard Worker return swizzle_bgrx;
2949*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XBGR16161616F:
2950*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ABGR16161616F:
2951*d83cc019SAndroid Build Coastguard Worker return swizzle_rgbx;
2952*d83cc019SAndroid Build Coastguard Worker }
2953*d83cc019SAndroid Build Coastguard Worker }
2954*d83cc019SAndroid Build Coastguard Worker
convert_fp16_to_float(struct fb_convert * cvt)2955*d83cc019SAndroid Build Coastguard Worker static void convert_fp16_to_float(struct fb_convert *cvt)
2956*d83cc019SAndroid Build Coastguard Worker {
2957*d83cc019SAndroid Build Coastguard Worker int i, j;
2958*d83cc019SAndroid Build Coastguard Worker uint16_t *fp16;
2959*d83cc019SAndroid Build Coastguard Worker float *ptr = cvt->dst.ptr;
2960*d83cc019SAndroid Build Coastguard Worker unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
2961*d83cc019SAndroid Build Coastguard Worker unsigned int fp16_stride = cvt->src.fb->strides[0] / sizeof(*fp16);
2962*d83cc019SAndroid Build Coastguard Worker const unsigned char *swz = rgbx_swizzle(cvt->src.fb->drm_format);
2963*d83cc019SAndroid Build Coastguard Worker bool needs_reswizzle = swz != swizzle_rgbx;
2964*d83cc019SAndroid Build Coastguard Worker
2965*d83cc019SAndroid Build Coastguard Worker uint16_t *buf = convert_src_get(cvt);
2966*d83cc019SAndroid Build Coastguard Worker fp16 = buf + cvt->src.fb->offsets[0] / sizeof(*buf);
2967*d83cc019SAndroid Build Coastguard Worker
2968*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
2969*d83cc019SAndroid Build Coastguard Worker if (needs_reswizzle) {
2970*d83cc019SAndroid Build Coastguard Worker const uint16_t *fp16_tmp = fp16;
2971*d83cc019SAndroid Build Coastguard Worker float *rgb_tmp = ptr;
2972*d83cc019SAndroid Build Coastguard Worker
2973*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
2974*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 rgb;
2975*d83cc019SAndroid Build Coastguard Worker
2976*d83cc019SAndroid Build Coastguard Worker igt_half_to_float(fp16_tmp, rgb.d, 4);
2977*d83cc019SAndroid Build Coastguard Worker
2978*d83cc019SAndroid Build Coastguard Worker rgb_tmp[0] = rgb.d[swz[0]];
2979*d83cc019SAndroid Build Coastguard Worker rgb_tmp[1] = rgb.d[swz[1]];
2980*d83cc019SAndroid Build Coastguard Worker rgb_tmp[2] = rgb.d[swz[2]];
2981*d83cc019SAndroid Build Coastguard Worker rgb_tmp[3] = rgb.d[swz[3]];
2982*d83cc019SAndroid Build Coastguard Worker
2983*d83cc019SAndroid Build Coastguard Worker rgb_tmp += 4;
2984*d83cc019SAndroid Build Coastguard Worker fp16_tmp += 4;
2985*d83cc019SAndroid Build Coastguard Worker }
2986*d83cc019SAndroid Build Coastguard Worker } else {
2987*d83cc019SAndroid Build Coastguard Worker igt_half_to_float(fp16, ptr, cvt->dst.fb->width * 4);
2988*d83cc019SAndroid Build Coastguard Worker }
2989*d83cc019SAndroid Build Coastguard Worker
2990*d83cc019SAndroid Build Coastguard Worker ptr += float_stride;
2991*d83cc019SAndroid Build Coastguard Worker fp16 += fp16_stride;
2992*d83cc019SAndroid Build Coastguard Worker }
2993*d83cc019SAndroid Build Coastguard Worker
2994*d83cc019SAndroid Build Coastguard Worker convert_src_put(cvt, buf);
2995*d83cc019SAndroid Build Coastguard Worker }
2996*d83cc019SAndroid Build Coastguard Worker
convert_float_to_fp16(struct fb_convert * cvt)2997*d83cc019SAndroid Build Coastguard Worker static void convert_float_to_fp16(struct fb_convert *cvt)
2998*d83cc019SAndroid Build Coastguard Worker {
2999*d83cc019SAndroid Build Coastguard Worker int i, j;
3000*d83cc019SAndroid Build Coastguard Worker uint16_t *fp16 = (uint16_t*)((uint8_t*)cvt->dst.ptr + cvt->dst.fb->offsets[0]);
3001*d83cc019SAndroid Build Coastguard Worker const float *ptr = cvt->src.ptr;
3002*d83cc019SAndroid Build Coastguard Worker unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
3003*d83cc019SAndroid Build Coastguard Worker unsigned fp16_stride = cvt->dst.fb->strides[0] / sizeof(*fp16);
3004*d83cc019SAndroid Build Coastguard Worker const unsigned char *swz = rgbx_swizzle(cvt->dst.fb->drm_format);
3005*d83cc019SAndroid Build Coastguard Worker bool needs_reswizzle = swz != swizzle_rgbx;
3006*d83cc019SAndroid Build Coastguard Worker
3007*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < cvt->dst.fb->height; i++) {
3008*d83cc019SAndroid Build Coastguard Worker if (needs_reswizzle) {
3009*d83cc019SAndroid Build Coastguard Worker const float *rgb_tmp = ptr;
3010*d83cc019SAndroid Build Coastguard Worker uint16_t *fp16_tmp = fp16;
3011*d83cc019SAndroid Build Coastguard Worker
3012*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < cvt->dst.fb->width; j++) {
3013*d83cc019SAndroid Build Coastguard Worker struct igt_vec4 rgb;
3014*d83cc019SAndroid Build Coastguard Worker
3015*d83cc019SAndroid Build Coastguard Worker rgb.d[0] = rgb_tmp[swz[0]];
3016*d83cc019SAndroid Build Coastguard Worker rgb.d[1] = rgb_tmp[swz[1]];
3017*d83cc019SAndroid Build Coastguard Worker rgb.d[2] = rgb_tmp[swz[2]];
3018*d83cc019SAndroid Build Coastguard Worker rgb.d[3] = rgb_tmp[swz[3]];
3019*d83cc019SAndroid Build Coastguard Worker
3020*d83cc019SAndroid Build Coastguard Worker igt_float_to_half(rgb.d, fp16_tmp, 4);
3021*d83cc019SAndroid Build Coastguard Worker
3022*d83cc019SAndroid Build Coastguard Worker rgb_tmp += 4;
3023*d83cc019SAndroid Build Coastguard Worker fp16_tmp += 4;
3024*d83cc019SAndroid Build Coastguard Worker }
3025*d83cc019SAndroid Build Coastguard Worker } else {
3026*d83cc019SAndroid Build Coastguard Worker igt_float_to_half(ptr, fp16, cvt->dst.fb->width * 4);
3027*d83cc019SAndroid Build Coastguard Worker }
3028*d83cc019SAndroid Build Coastguard Worker
3029*d83cc019SAndroid Build Coastguard Worker ptr += float_stride;
3030*d83cc019SAndroid Build Coastguard Worker fp16 += fp16_stride;
3031*d83cc019SAndroid Build Coastguard Worker }
3032*d83cc019SAndroid Build Coastguard Worker }
3033*d83cc019SAndroid Build Coastguard Worker
convert_pixman(struct fb_convert * cvt)3034*d83cc019SAndroid Build Coastguard Worker static void convert_pixman(struct fb_convert *cvt)
3035*d83cc019SAndroid Build Coastguard Worker {
3036*d83cc019SAndroid Build Coastguard Worker pixman_format_code_t src_pixman = drm_format_to_pixman(cvt->src.fb->drm_format);
3037*d83cc019SAndroid Build Coastguard Worker pixman_format_code_t dst_pixman = drm_format_to_pixman(cvt->dst.fb->drm_format);
3038*d83cc019SAndroid Build Coastguard Worker pixman_image_t *dst_image, *src_image;
3039*d83cc019SAndroid Build Coastguard Worker void *src_ptr;
3040*d83cc019SAndroid Build Coastguard Worker
3041*d83cc019SAndroid Build Coastguard Worker igt_assert((src_pixman != PIXMAN_invalid) &&
3042*d83cc019SAndroid Build Coastguard Worker (dst_pixman != PIXMAN_invalid));
3043*d83cc019SAndroid Build Coastguard Worker
3044*d83cc019SAndroid Build Coastguard Worker /* Pixman requires the stride to be aligned to 32 bits. */
3045*d83cc019SAndroid Build Coastguard Worker igt_assert((cvt->src.fb->strides[0] % sizeof(uint32_t)) == 0);
3046*d83cc019SAndroid Build Coastguard Worker igt_assert((cvt->dst.fb->strides[0] % sizeof(uint32_t)) == 0);
3047*d83cc019SAndroid Build Coastguard Worker
3048*d83cc019SAndroid Build Coastguard Worker src_ptr = convert_src_get(cvt);
3049*d83cc019SAndroid Build Coastguard Worker
3050*d83cc019SAndroid Build Coastguard Worker src_image = pixman_image_create_bits(src_pixman,
3051*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->width,
3052*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->height,
3053*d83cc019SAndroid Build Coastguard Worker src_ptr,
3054*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->strides[0]);
3055*d83cc019SAndroid Build Coastguard Worker igt_assert(src_image);
3056*d83cc019SAndroid Build Coastguard Worker
3057*d83cc019SAndroid Build Coastguard Worker dst_image = pixman_image_create_bits(dst_pixman,
3058*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->width,
3059*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->height,
3060*d83cc019SAndroid Build Coastguard Worker cvt->dst.ptr,
3061*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->strides[0]);
3062*d83cc019SAndroid Build Coastguard Worker igt_assert(dst_image);
3063*d83cc019SAndroid Build Coastguard Worker
3064*d83cc019SAndroid Build Coastguard Worker pixman_image_composite(PIXMAN_OP_SRC, src_image, NULL, dst_image,
3065*d83cc019SAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0,
3066*d83cc019SAndroid Build Coastguard Worker cvt->dst.fb->width, cvt->dst.fb->height);
3067*d83cc019SAndroid Build Coastguard Worker pixman_image_unref(dst_image);
3068*d83cc019SAndroid Build Coastguard Worker pixman_image_unref(src_image);
3069*d83cc019SAndroid Build Coastguard Worker
3070*d83cc019SAndroid Build Coastguard Worker convert_src_put(cvt, src_ptr);
3071*d83cc019SAndroid Build Coastguard Worker }
3072*d83cc019SAndroid Build Coastguard Worker
fb_convert(struct fb_convert * cvt)3073*d83cc019SAndroid Build Coastguard Worker static void fb_convert(struct fb_convert *cvt)
3074*d83cc019SAndroid Build Coastguard Worker {
3075*d83cc019SAndroid Build Coastguard Worker if ((drm_format_to_pixman(cvt->src.fb->drm_format) != PIXMAN_invalid) &&
3076*d83cc019SAndroid Build Coastguard Worker (drm_format_to_pixman(cvt->dst.fb->drm_format) != PIXMAN_invalid)) {
3077*d83cc019SAndroid Build Coastguard Worker convert_pixman(cvt);
3078*d83cc019SAndroid Build Coastguard Worker return;
3079*d83cc019SAndroid Build Coastguard Worker } else if (cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888) {
3080*d83cc019SAndroid Build Coastguard Worker switch (cvt->src.fb->drm_format) {
3081*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XYUV8888:
3082*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
3083*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV16:
3084*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV21:
3085*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV61:
3086*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_UYVY:
3087*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_VYUY:
3088*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV420:
3089*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV422:
3090*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUYV:
3091*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
3092*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU422:
3093*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVYU:
3094*d83cc019SAndroid Build Coastguard Worker convert_yuv_to_rgb24(cvt);
3095*d83cc019SAndroid Build Coastguard Worker return;
3096*d83cc019SAndroid Build Coastguard Worker }
3097*d83cc019SAndroid Build Coastguard Worker } else if (cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888) {
3098*d83cc019SAndroid Build Coastguard Worker switch (cvt->dst.fb->drm_format) {
3099*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XYUV8888:
3100*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
3101*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV16:
3102*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV21:
3103*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV61:
3104*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_UYVY:
3105*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_VYUY:
3106*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV420:
3107*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV422:
3108*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUYV:
3109*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
3110*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU422:
3111*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVYU:
3112*d83cc019SAndroid Build Coastguard Worker convert_rgb24_to_yuv(cvt);
3113*d83cc019SAndroid Build Coastguard Worker return;
3114*d83cc019SAndroid Build Coastguard Worker }
3115*d83cc019SAndroid Build Coastguard Worker } else if (cvt->dst.fb->drm_format == IGT_FORMAT_FLOAT) {
3116*d83cc019SAndroid Build Coastguard Worker switch (cvt->src.fb->drm_format) {
3117*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P010:
3118*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P012:
3119*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P016:
3120*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y210:
3121*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y212:
3122*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y216:
3123*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU12_16161616:
3124*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU16161616:
3125*d83cc019SAndroid Build Coastguard Worker convert_yuv16_to_float(cvt, false);
3126*d83cc019SAndroid Build Coastguard Worker return;
3127*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y410:
3128*d83cc019SAndroid Build Coastguard Worker convert_Y410_to_float(cvt, true);
3129*d83cc019SAndroid Build Coastguard Worker return;
3130*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU2101010:
3131*d83cc019SAndroid Build Coastguard Worker convert_Y410_to_float(cvt, false);
3132*d83cc019SAndroid Build Coastguard Worker return;
3133*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y412:
3134*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y416:
3135*d83cc019SAndroid Build Coastguard Worker convert_yuv16_to_float(cvt, true);
3136*d83cc019SAndroid Build Coastguard Worker return;
3137*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XRGB16161616F:
3138*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XBGR16161616F:
3139*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ARGB16161616F:
3140*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ABGR16161616F:
3141*d83cc019SAndroid Build Coastguard Worker convert_fp16_to_float(cvt);
3142*d83cc019SAndroid Build Coastguard Worker return;
3143*d83cc019SAndroid Build Coastguard Worker }
3144*d83cc019SAndroid Build Coastguard Worker } else if (cvt->src.fb->drm_format == IGT_FORMAT_FLOAT) {
3145*d83cc019SAndroid Build Coastguard Worker switch (cvt->dst.fb->drm_format) {
3146*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P010:
3147*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P012:
3148*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P016:
3149*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y210:
3150*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y212:
3151*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y216:
3152*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU12_16161616:
3153*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU16161616:
3154*d83cc019SAndroid Build Coastguard Worker convert_float_to_yuv16(cvt, false);
3155*d83cc019SAndroid Build Coastguard Worker return;
3156*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y410:
3157*d83cc019SAndroid Build Coastguard Worker convert_float_to_Y410(cvt, true);
3158*d83cc019SAndroid Build Coastguard Worker return;
3159*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU2101010:
3160*d83cc019SAndroid Build Coastguard Worker convert_float_to_Y410(cvt, false);
3161*d83cc019SAndroid Build Coastguard Worker return;
3162*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y412:
3163*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y416:
3164*d83cc019SAndroid Build Coastguard Worker convert_float_to_yuv16(cvt, true);
3165*d83cc019SAndroid Build Coastguard Worker return;
3166*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XRGB16161616F:
3167*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XBGR16161616F:
3168*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ARGB16161616F:
3169*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ABGR16161616F:
3170*d83cc019SAndroid Build Coastguard Worker convert_float_to_fp16(cvt);
3171*d83cc019SAndroid Build Coastguard Worker return;
3172*d83cc019SAndroid Build Coastguard Worker }
3173*d83cc019SAndroid Build Coastguard Worker }
3174*d83cc019SAndroid Build Coastguard Worker
3175*d83cc019SAndroid Build Coastguard Worker igt_assert_f(false,
3176*d83cc019SAndroid Build Coastguard Worker "Conversion not implemented (from format 0x%x to 0x%x)\n",
3177*d83cc019SAndroid Build Coastguard Worker cvt->src.fb->drm_format, cvt->dst.fb->drm_format);
3178*d83cc019SAndroid Build Coastguard Worker }
3179*d83cc019SAndroid Build Coastguard Worker
destroy_cairo_surface__convert(void * arg)3180*d83cc019SAndroid Build Coastguard Worker static void destroy_cairo_surface__convert(void *arg)
3181*d83cc019SAndroid Build Coastguard Worker {
3182*d83cc019SAndroid Build Coastguard Worker struct fb_convert_blit_upload *blit = arg;
3183*d83cc019SAndroid Build Coastguard Worker struct igt_fb *fb = blit->base.fb;
3184*d83cc019SAndroid Build Coastguard Worker struct fb_convert cvt = {
3185*d83cc019SAndroid Build Coastguard Worker .dst = {
3186*d83cc019SAndroid Build Coastguard Worker .ptr = blit->base.linear.map,
3187*d83cc019SAndroid Build Coastguard Worker .fb = &blit->base.linear.fb,
3188*d83cc019SAndroid Build Coastguard Worker },
3189*d83cc019SAndroid Build Coastguard Worker
3190*d83cc019SAndroid Build Coastguard Worker .src = {
3191*d83cc019SAndroid Build Coastguard Worker .ptr = blit->shadow_ptr,
3192*d83cc019SAndroid Build Coastguard Worker .fb = &blit->shadow_fb,
3193*d83cc019SAndroid Build Coastguard Worker },
3194*d83cc019SAndroid Build Coastguard Worker };
3195*d83cc019SAndroid Build Coastguard Worker
3196*d83cc019SAndroid Build Coastguard Worker fb_convert(&cvt);
3197*d83cc019SAndroid Build Coastguard Worker igt_fb_destroy_cairo_shadow_buffer(&blit->shadow_fb, blit->shadow_ptr);
3198*d83cc019SAndroid Build Coastguard Worker
3199*d83cc019SAndroid Build Coastguard Worker if (blit->base.linear.fb.gem_handle)
3200*d83cc019SAndroid Build Coastguard Worker free_linear_mapping(&blit->base);
3201*d83cc019SAndroid Build Coastguard Worker else
3202*d83cc019SAndroid Build Coastguard Worker unmap_bo(fb, blit->base.linear.map);
3203*d83cc019SAndroid Build Coastguard Worker
3204*d83cc019SAndroid Build Coastguard Worker free(blit);
3205*d83cc019SAndroid Build Coastguard Worker
3206*d83cc019SAndroid Build Coastguard Worker fb->cairo_surface = NULL;
3207*d83cc019SAndroid Build Coastguard Worker }
3208*d83cc019SAndroid Build Coastguard Worker
create_cairo_surface__convert(int fd,struct igt_fb * fb)3209*d83cc019SAndroid Build Coastguard Worker static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
3210*d83cc019SAndroid Build Coastguard Worker {
3211*d83cc019SAndroid Build Coastguard Worker struct fb_convert_blit_upload *blit = calloc(1, sizeof(*blit));
3212*d83cc019SAndroid Build Coastguard Worker struct fb_convert cvt = { };
3213*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f = lookup_drm_format(fb->drm_format);
3214*d83cc019SAndroid Build Coastguard Worker unsigned drm_format;
3215*d83cc019SAndroid Build Coastguard Worker cairo_format_t cairo_id;
3216*d83cc019SAndroid Build Coastguard Worker
3217*d83cc019SAndroid Build Coastguard Worker if (f->cairo_id != CAIRO_FORMAT_INVALID) {
3218*d83cc019SAndroid Build Coastguard Worker cairo_id = f->cairo_id;
3219*d83cc019SAndroid Build Coastguard Worker
3220*d83cc019SAndroid Build Coastguard Worker switch (f->cairo_id) {
3221*d83cc019SAndroid Build Coastguard Worker case CAIRO_FORMAT_RGB96F:
3222*d83cc019SAndroid Build Coastguard Worker case CAIRO_FORMAT_RGBA128F:
3223*d83cc019SAndroid Build Coastguard Worker drm_format = IGT_FORMAT_FLOAT;
3224*d83cc019SAndroid Build Coastguard Worker break;
3225*d83cc019SAndroid Build Coastguard Worker case CAIRO_FORMAT_RGB24:
3226*d83cc019SAndroid Build Coastguard Worker drm_format = DRM_FORMAT_XRGB8888;
3227*d83cc019SAndroid Build Coastguard Worker break;
3228*d83cc019SAndroid Build Coastguard Worker default:
3229*d83cc019SAndroid Build Coastguard Worker igt_assert_f(0, "Unsupported format %u", f->cairo_id);
3230*d83cc019SAndroid Build Coastguard Worker }
3231*d83cc019SAndroid Build Coastguard Worker } else if (PIXMAN_FORMAT_A(f->pixman_id)) {
3232*d83cc019SAndroid Build Coastguard Worker cairo_id = CAIRO_FORMAT_ARGB32;
3233*d83cc019SAndroid Build Coastguard Worker drm_format = DRM_FORMAT_ARGB8888;
3234*d83cc019SAndroid Build Coastguard Worker } else {
3235*d83cc019SAndroid Build Coastguard Worker cairo_id = CAIRO_FORMAT_RGB24;
3236*d83cc019SAndroid Build Coastguard Worker drm_format = DRM_FORMAT_XRGB8888;
3237*d83cc019SAndroid Build Coastguard Worker }
3238*d83cc019SAndroid Build Coastguard Worker
3239*d83cc019SAndroid Build Coastguard Worker igt_assert(blit);
3240*d83cc019SAndroid Build Coastguard Worker
3241*d83cc019SAndroid Build Coastguard Worker blit->base.fd = fd;
3242*d83cc019SAndroid Build Coastguard Worker blit->base.fb = fb;
3243*d83cc019SAndroid Build Coastguard Worker
3244*d83cc019SAndroid Build Coastguard Worker blit->shadow_ptr = igt_fb_create_cairo_shadow_buffer(fd, drm_format,
3245*d83cc019SAndroid Build Coastguard Worker fb->width,
3246*d83cc019SAndroid Build Coastguard Worker fb->height,
3247*d83cc019SAndroid Build Coastguard Worker &blit->shadow_fb);
3248*d83cc019SAndroid Build Coastguard Worker igt_assert(blit->shadow_ptr);
3249*d83cc019SAndroid Build Coastguard Worker
3250*d83cc019SAndroid Build Coastguard Worker if (use_rendercopy(fb) || use_blitter(fb) || igt_vc4_is_tiled(fb->modifier)) {
3251*d83cc019SAndroid Build Coastguard Worker setup_linear_mapping(&blit->base);
3252*d83cc019SAndroid Build Coastguard Worker } else {
3253*d83cc019SAndroid Build Coastguard Worker blit->base.linear.fb = *fb;
3254*d83cc019SAndroid Build Coastguard Worker blit->base.linear.fb.gem_handle = 0;
3255*d83cc019SAndroid Build Coastguard Worker blit->base.linear.map = map_bo(fd, fb);
3256*d83cc019SAndroid Build Coastguard Worker igt_assert(blit->base.linear.map);
3257*d83cc019SAndroid Build Coastguard Worker
3258*d83cc019SAndroid Build Coastguard Worker /* reading via gtt mmap is slow */
3259*d83cc019SAndroid Build Coastguard Worker cvt.src.slow_reads = is_i915_device(fd);
3260*d83cc019SAndroid Build Coastguard Worker }
3261*d83cc019SAndroid Build Coastguard Worker
3262*d83cc019SAndroid Build Coastguard Worker cvt.dst.ptr = blit->shadow_ptr;
3263*d83cc019SAndroid Build Coastguard Worker cvt.dst.fb = &blit->shadow_fb;
3264*d83cc019SAndroid Build Coastguard Worker cvt.src.ptr = blit->base.linear.map;
3265*d83cc019SAndroid Build Coastguard Worker cvt.src.fb = &blit->base.linear.fb;
3266*d83cc019SAndroid Build Coastguard Worker fb_convert(&cvt);
3267*d83cc019SAndroid Build Coastguard Worker
3268*d83cc019SAndroid Build Coastguard Worker fb->cairo_surface =
3269*d83cc019SAndroid Build Coastguard Worker cairo_image_surface_create_for_data(blit->shadow_ptr,
3270*d83cc019SAndroid Build Coastguard Worker cairo_id,
3271*d83cc019SAndroid Build Coastguard Worker fb->width, fb->height,
3272*d83cc019SAndroid Build Coastguard Worker blit->shadow_fb.strides[0]);
3273*d83cc019SAndroid Build Coastguard Worker
3274*d83cc019SAndroid Build Coastguard Worker cairo_surface_set_user_data(fb->cairo_surface,
3275*d83cc019SAndroid Build Coastguard Worker (cairo_user_data_key_t *)create_cairo_surface__convert,
3276*d83cc019SAndroid Build Coastguard Worker blit, destroy_cairo_surface__convert);
3277*d83cc019SAndroid Build Coastguard Worker }
3278*d83cc019SAndroid Build Coastguard Worker #endif /*defined(USE_CAIRO_PIXMAN)*/
3279*d83cc019SAndroid Build Coastguard Worker
3280*d83cc019SAndroid Build Coastguard Worker
3281*d83cc019SAndroid Build Coastguard Worker /**
3282*d83cc019SAndroid Build Coastguard Worker * igt_fb_map_buffer:
3283*d83cc019SAndroid Build Coastguard Worker * @fd: open drm file descriptor
3284*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
3285*d83cc019SAndroid Build Coastguard Worker *
3286*d83cc019SAndroid Build Coastguard Worker * This function will creating a new mapping of the buffer and return a pointer
3287*d83cc019SAndroid Build Coastguard Worker * to the content of the supplied framebuffer's plane. This mapping needs to be
3288*d83cc019SAndroid Build Coastguard Worker * deleted using igt_fb_unmap_buffer().
3289*d83cc019SAndroid Build Coastguard Worker *
3290*d83cc019SAndroid Build Coastguard Worker * Returns:
3291*d83cc019SAndroid Build Coastguard Worker * A pointer to a buffer with the contents of the framebuffer
3292*d83cc019SAndroid Build Coastguard Worker */
igt_fb_map_buffer(int fd,struct igt_fb * fb)3293*d83cc019SAndroid Build Coastguard Worker void *igt_fb_map_buffer(int fd, struct igt_fb *fb)
3294*d83cc019SAndroid Build Coastguard Worker {
3295*d83cc019SAndroid Build Coastguard Worker return map_bo(fd, fb);
3296*d83cc019SAndroid Build Coastguard Worker }
3297*d83cc019SAndroid Build Coastguard Worker
3298*d83cc019SAndroid Build Coastguard Worker /**
3299*d83cc019SAndroid Build Coastguard Worker * igt_fb_unmap_buffer:
3300*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to the backing igt_fb structure
3301*d83cc019SAndroid Build Coastguard Worker * @buffer: pointer to the buffer previously mappped
3302*d83cc019SAndroid Build Coastguard Worker *
3303*d83cc019SAndroid Build Coastguard Worker * This function will unmap a buffer mapped previously with
3304*d83cc019SAndroid Build Coastguard Worker * igt_fb_map_buffer().
3305*d83cc019SAndroid Build Coastguard Worker */
igt_fb_unmap_buffer(struct igt_fb * fb,void * buffer)3306*d83cc019SAndroid Build Coastguard Worker void igt_fb_unmap_buffer(struct igt_fb *fb, void *buffer)
3307*d83cc019SAndroid Build Coastguard Worker {
3308*d83cc019SAndroid Build Coastguard Worker return unmap_bo(fb, buffer);
3309*d83cc019SAndroid Build Coastguard Worker }
3310*d83cc019SAndroid Build Coastguard Worker
3311*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
3312*d83cc019SAndroid Build Coastguard Worker /**
3313*d83cc019SAndroid Build Coastguard Worker * igt_get_cairo_surface:
3314*d83cc019SAndroid Build Coastguard Worker * @fd: open drm file descriptor
3315*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
3316*d83cc019SAndroid Build Coastguard Worker *
3317*d83cc019SAndroid Build Coastguard Worker * This function stores the contents of the supplied framebuffer's plane
3318*d83cc019SAndroid Build Coastguard Worker * into a cairo surface and returns it.
3319*d83cc019SAndroid Build Coastguard Worker *
3320*d83cc019SAndroid Build Coastguard Worker * Returns:
3321*d83cc019SAndroid Build Coastguard Worker * A pointer to a cairo surface with the contents of the framebuffer.
3322*d83cc019SAndroid Build Coastguard Worker */
igt_get_cairo_surface(int fd,struct igt_fb * fb)3323*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *igt_get_cairo_surface(int fd, struct igt_fb *fb)
3324*d83cc019SAndroid Build Coastguard Worker {
3325*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f = lookup_drm_format(fb->drm_format);
3326*d83cc019SAndroid Build Coastguard Worker
3327*d83cc019SAndroid Build Coastguard Worker if (fb->cairo_surface == NULL) {
3328*d83cc019SAndroid Build Coastguard Worker if (igt_format_is_yuv(fb->drm_format) ||
3329*d83cc019SAndroid Build Coastguard Worker igt_format_is_fp16(fb->drm_format) ||
3330*d83cc019SAndroid Build Coastguard Worker ((f->cairo_id == CAIRO_FORMAT_INVALID) &&
3331*d83cc019SAndroid Build Coastguard Worker (f->pixman_id != PIXMAN_invalid)))
3332*d83cc019SAndroid Build Coastguard Worker create_cairo_surface__convert(fd, fb);
3333*d83cc019SAndroid Build Coastguard Worker else if (use_blitter(fb) || use_rendercopy(fb) || igt_vc4_is_tiled(fb->modifier))
3334*d83cc019SAndroid Build Coastguard Worker create_cairo_surface__gpu(fd, fb);
3335*d83cc019SAndroid Build Coastguard Worker else
3336*d83cc019SAndroid Build Coastguard Worker create_cairo_surface__gtt(fd, fb);
3337*d83cc019SAndroid Build Coastguard Worker
3338*d83cc019SAndroid Build Coastguard Worker if (f->cairo_id == CAIRO_FORMAT_RGB96F ||
3339*d83cc019SAndroid Build Coastguard Worker f->cairo_id == CAIRO_FORMAT_RGBA128F) {
3340*d83cc019SAndroid Build Coastguard Worker cairo_status_t status = cairo_surface_status(fb->cairo_surface);
3341*d83cc019SAndroid Build Coastguard Worker
3342*d83cc019SAndroid Build Coastguard Worker igt_skip_on_f(status == CAIRO_STATUS_INVALID_FORMAT &&
3343*d83cc019SAndroid Build Coastguard Worker cairo_version() < CAIRO_VERSION_ENCODE(1, 17, 2),
3344*d83cc019SAndroid Build Coastguard Worker "Cairo version too old, need 1.17.2, have %s\n",
3345*d83cc019SAndroid Build Coastguard Worker cairo_version_string());
3346*d83cc019SAndroid Build Coastguard Worker
3347*d83cc019SAndroid Build Coastguard Worker igt_skip_on_f(status == CAIRO_STATUS_NO_MEMORY &&
3348*d83cc019SAndroid Build Coastguard Worker pixman_version() < PIXMAN_VERSION_ENCODE(0, 36, 0),
3349*d83cc019SAndroid Build Coastguard Worker "Pixman version too old, need 0.36.0, have %s\n",
3350*d83cc019SAndroid Build Coastguard Worker pixman_version_string());
3351*d83cc019SAndroid Build Coastguard Worker }
3352*d83cc019SAndroid Build Coastguard Worker }
3353*d83cc019SAndroid Build Coastguard Worker
3354*d83cc019SAndroid Build Coastguard Worker igt_assert(cairo_surface_status(fb->cairo_surface) == CAIRO_STATUS_SUCCESS);
3355*d83cc019SAndroid Build Coastguard Worker return fb->cairo_surface;
3356*d83cc019SAndroid Build Coastguard Worker }
3357*d83cc019SAndroid Build Coastguard Worker
3358*d83cc019SAndroid Build Coastguard Worker /**
3359*d83cc019SAndroid Build Coastguard Worker * igt_get_cairo_ctx:
3360*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
3361*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
3362*d83cc019SAndroid Build Coastguard Worker *
3363*d83cc019SAndroid Build Coastguard Worker * This initializes a cairo surface for @fb and then allocates a drawing context
3364*d83cc019SAndroid Build Coastguard Worker * for it. The return cairo drawing context should be released by calling
3365*d83cc019SAndroid Build Coastguard Worker * igt_put_cairo_ctx(). This also sets a default font for drawing text on
3366*d83cc019SAndroid Build Coastguard Worker * framebuffers.
3367*d83cc019SAndroid Build Coastguard Worker *
3368*d83cc019SAndroid Build Coastguard Worker * Returns:
3369*d83cc019SAndroid Build Coastguard Worker * The created cairo drawing context.
3370*d83cc019SAndroid Build Coastguard Worker */
igt_get_cairo_ctx(int fd,struct igt_fb * fb)3371*d83cc019SAndroid Build Coastguard Worker cairo_t *igt_get_cairo_ctx(int fd, struct igt_fb *fb)
3372*d83cc019SAndroid Build Coastguard Worker {
3373*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *surface;
3374*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
3375*d83cc019SAndroid Build Coastguard Worker
3376*d83cc019SAndroid Build Coastguard Worker surface = igt_get_cairo_surface(fd, fb);
3377*d83cc019SAndroid Build Coastguard Worker cr = cairo_create(surface);
3378*d83cc019SAndroid Build Coastguard Worker cairo_surface_destroy(surface);
3379*d83cc019SAndroid Build Coastguard Worker igt_assert(cairo_status(cr) == CAIRO_STATUS_SUCCESS);
3380*d83cc019SAndroid Build Coastguard Worker
3381*d83cc019SAndroid Build Coastguard Worker cairo_select_font_face(cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL,
3382*d83cc019SAndroid Build Coastguard Worker CAIRO_FONT_WEIGHT_NORMAL);
3383*d83cc019SAndroid Build Coastguard Worker igt_assert(cairo_status(cr) == CAIRO_STATUS_SUCCESS);
3384*d83cc019SAndroid Build Coastguard Worker
3385*d83cc019SAndroid Build Coastguard Worker return cr;
3386*d83cc019SAndroid Build Coastguard Worker }
3387*d83cc019SAndroid Build Coastguard Worker
3388*d83cc019SAndroid Build Coastguard Worker /**
3389*d83cc019SAndroid Build Coastguard Worker * igt_put_cairo_ctx:
3390*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
3391*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
3392*d83cc019SAndroid Build Coastguard Worker * @cr: the cairo context returned by igt_get_cairo_ctx.
3393*d83cc019SAndroid Build Coastguard Worker *
3394*d83cc019SAndroid Build Coastguard Worker * This releases the cairo surface @cr returned by igt_get_cairo_ctx()
3395*d83cc019SAndroid Build Coastguard Worker * for @fb, and writes the changes out to the framebuffer if cairo doesn't
3396*d83cc019SAndroid Build Coastguard Worker * have native support for the format.
3397*d83cc019SAndroid Build Coastguard Worker */
igt_put_cairo_ctx(int fd,struct igt_fb * fb,cairo_t * cr)3398*d83cc019SAndroid Build Coastguard Worker void igt_put_cairo_ctx(int fd, struct igt_fb *fb, cairo_t *cr)
3399*d83cc019SAndroid Build Coastguard Worker {
3400*d83cc019SAndroid Build Coastguard Worker cairo_status_t ret = cairo_status(cr);
3401*d83cc019SAndroid Build Coastguard Worker igt_assert_f(ret == CAIRO_STATUS_SUCCESS, "Cairo failed to draw with %s\n", cairo_status_to_string(ret));
3402*d83cc019SAndroid Build Coastguard Worker
3403*d83cc019SAndroid Build Coastguard Worker cairo_destroy(cr);
3404*d83cc019SAndroid Build Coastguard Worker }
3405*d83cc019SAndroid Build Coastguard Worker #endif /*defined(USE_CAIRO_PIXMAN)*/
3406*d83cc019SAndroid Build Coastguard Worker
3407*d83cc019SAndroid Build Coastguard Worker /**
3408*d83cc019SAndroid Build Coastguard Worker * igt_remove_fb:
3409*d83cc019SAndroid Build Coastguard Worker * @fd: open i915 drm file descriptor
3410*d83cc019SAndroid Build Coastguard Worker * @fb: pointer to an #igt_fb structure
3411*d83cc019SAndroid Build Coastguard Worker *
3412*d83cc019SAndroid Build Coastguard Worker * This function releases all resources allocated in igt_create_fb() for @fb.
3413*d83cc019SAndroid Build Coastguard Worker * Note that if this framebuffer is still in use on a primary plane the kernel
3414*d83cc019SAndroid Build Coastguard Worker * will disable the corresponding crtc.
3415*d83cc019SAndroid Build Coastguard Worker */
igt_remove_fb(int fd,struct igt_fb * fb)3416*d83cc019SAndroid Build Coastguard Worker void igt_remove_fb(int fd, struct igt_fb *fb)
3417*d83cc019SAndroid Build Coastguard Worker {
3418*d83cc019SAndroid Build Coastguard Worker if (!fb || !fb->fb_id)
3419*d83cc019SAndroid Build Coastguard Worker return;
3420*d83cc019SAndroid Build Coastguard Worker
3421*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
3422*d83cc019SAndroid Build Coastguard Worker cairo_surface_destroy(fb->cairo_surface);
3423*d83cc019SAndroid Build Coastguard Worker #endif
3424*d83cc019SAndroid Build Coastguard Worker do_or_die(drmModeRmFB(fd, fb->fb_id));
3425*d83cc019SAndroid Build Coastguard Worker if (fb->is_dumb)
3426*d83cc019SAndroid Build Coastguard Worker kmstest_dumb_destroy(fd, fb->gem_handle);
3427*d83cc019SAndroid Build Coastguard Worker else
3428*d83cc019SAndroid Build Coastguard Worker gem_close(fd, fb->gem_handle);
3429*d83cc019SAndroid Build Coastguard Worker fb->fb_id = 0;
3430*d83cc019SAndroid Build Coastguard Worker }
3431*d83cc019SAndroid Build Coastguard Worker
3432*d83cc019SAndroid Build Coastguard Worker #if defined(USE_CAIRO_PIXMAN)
3433*d83cc019SAndroid Build Coastguard Worker /**
3434*d83cc019SAndroid Build Coastguard Worker * igt_fb_convert_with_stride:
3435*d83cc019SAndroid Build Coastguard Worker * @dst: pointer to the #igt_fb structure that will store the conversion result
3436*d83cc019SAndroid Build Coastguard Worker * @src: pointer to the #igt_fb structure that stores the frame we convert
3437*d83cc019SAndroid Build Coastguard Worker * @dst_fourcc: DRM format specifier to convert to
3438*d83cc019SAndroid Build Coastguard Worker * @dst_modifier: DRM format modifier to convert to
3439*d83cc019SAndroid Build Coastguard Worker * @dst_stride: Stride for the resulting framebuffer (0 for automatic stride)
3440*d83cc019SAndroid Build Coastguard Worker *
3441*d83cc019SAndroid Build Coastguard Worker * This will convert a given @src content to the @dst_fourcc format,
3442*d83cc019SAndroid Build Coastguard Worker * storing the result in the @dst fb, allocating the @dst fb
3443*d83cc019SAndroid Build Coastguard Worker * underlying buffer with a stride of @dst_stride stride.
3444*d83cc019SAndroid Build Coastguard Worker *
3445*d83cc019SAndroid Build Coastguard Worker * Once done with @dst, the caller will have to call igt_remove_fb()
3446*d83cc019SAndroid Build Coastguard Worker * on it to free the associated resources.
3447*d83cc019SAndroid Build Coastguard Worker *
3448*d83cc019SAndroid Build Coastguard Worker * Returns:
3449*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer.
3450*d83cc019SAndroid Build Coastguard Worker */
igt_fb_convert_with_stride(struct igt_fb * dst,struct igt_fb * src,uint32_t dst_fourcc,uint64_t dst_modifier,unsigned int dst_stride)3451*d83cc019SAndroid Build Coastguard Worker unsigned int igt_fb_convert_with_stride(struct igt_fb *dst, struct igt_fb *src,
3452*d83cc019SAndroid Build Coastguard Worker uint32_t dst_fourcc,
3453*d83cc019SAndroid Build Coastguard Worker uint64_t dst_modifier,
3454*d83cc019SAndroid Build Coastguard Worker unsigned int dst_stride)
3455*d83cc019SAndroid Build Coastguard Worker {
3456*d83cc019SAndroid Build Coastguard Worker /* Use the cairo api to convert */
3457*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *surf = igt_get_cairo_surface(src->fd, src);
3458*d83cc019SAndroid Build Coastguard Worker cairo_t *cr;
3459*d83cc019SAndroid Build Coastguard Worker int fb_id;
3460*d83cc019SAndroid Build Coastguard Worker
3461*d83cc019SAndroid Build Coastguard Worker fb_id = igt_create_fb_with_bo_size(src->fd, src->width,
3462*d83cc019SAndroid Build Coastguard Worker src->height, dst_fourcc,
3463*d83cc019SAndroid Build Coastguard Worker dst_modifier,
3464*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_BT709,
3465*d83cc019SAndroid Build Coastguard Worker IGT_COLOR_YCBCR_LIMITED_RANGE,
3466*d83cc019SAndroid Build Coastguard Worker dst, 0,
3467*d83cc019SAndroid Build Coastguard Worker dst_stride);
3468*d83cc019SAndroid Build Coastguard Worker igt_assert(fb_id > 0);
3469*d83cc019SAndroid Build Coastguard Worker
3470*d83cc019SAndroid Build Coastguard Worker cr = igt_get_cairo_ctx(dst->fd, dst);
3471*d83cc019SAndroid Build Coastguard Worker cairo_set_source_surface(cr, surf, 0, 0);
3472*d83cc019SAndroid Build Coastguard Worker cairo_paint(cr);
3473*d83cc019SAndroid Build Coastguard Worker igt_put_cairo_ctx(dst->fd, dst, cr);
3474*d83cc019SAndroid Build Coastguard Worker
3475*d83cc019SAndroid Build Coastguard Worker cairo_surface_destroy(surf);
3476*d83cc019SAndroid Build Coastguard Worker
3477*d83cc019SAndroid Build Coastguard Worker return fb_id;
3478*d83cc019SAndroid Build Coastguard Worker }
3479*d83cc019SAndroid Build Coastguard Worker
3480*d83cc019SAndroid Build Coastguard Worker /**
3481*d83cc019SAndroid Build Coastguard Worker * igt_fb_convert:
3482*d83cc019SAndroid Build Coastguard Worker * @dst: pointer to the #igt_fb structure that will store the conversion result
3483*d83cc019SAndroid Build Coastguard Worker * @src: pointer to the #igt_fb structure that stores the frame we convert
3484*d83cc019SAndroid Build Coastguard Worker * @dst_fourcc: DRM format specifier to convert to
3485*d83cc019SAndroid Build Coastguard Worker * @dst_modifier: DRM format modifier to convert to
3486*d83cc019SAndroid Build Coastguard Worker *
3487*d83cc019SAndroid Build Coastguard Worker * This will convert a given @src content to the @dst_fourcc format,
3488*d83cc019SAndroid Build Coastguard Worker * storing the result in the @dst fb, allocating the @dst fb
3489*d83cc019SAndroid Build Coastguard Worker * underlying buffer.
3490*d83cc019SAndroid Build Coastguard Worker *
3491*d83cc019SAndroid Build Coastguard Worker * Once done with @dst, the caller will have to call igt_remove_fb()
3492*d83cc019SAndroid Build Coastguard Worker * on it to free the associated resources.
3493*d83cc019SAndroid Build Coastguard Worker *
3494*d83cc019SAndroid Build Coastguard Worker * Returns:
3495*d83cc019SAndroid Build Coastguard Worker * The kms id of the created framebuffer.
3496*d83cc019SAndroid Build Coastguard Worker */
igt_fb_convert(struct igt_fb * dst,struct igt_fb * src,uint32_t dst_fourcc,uint64_t dst_modifier)3497*d83cc019SAndroid Build Coastguard Worker unsigned int igt_fb_convert(struct igt_fb *dst, struct igt_fb *src,
3498*d83cc019SAndroid Build Coastguard Worker uint32_t dst_fourcc, uint64_t dst_modifier)
3499*d83cc019SAndroid Build Coastguard Worker {
3500*d83cc019SAndroid Build Coastguard Worker return igt_fb_convert_with_stride(dst, src, dst_fourcc, dst_modifier,
3501*d83cc019SAndroid Build Coastguard Worker 0);
3502*d83cc019SAndroid Build Coastguard Worker }
3503*d83cc019SAndroid Build Coastguard Worker #endif /*defined(USE_CAIRO_PIXMAN)*/
3504*d83cc019SAndroid Build Coastguard Worker
3505*d83cc019SAndroid Build Coastguard Worker /**
3506*d83cc019SAndroid Build Coastguard Worker * igt_bpp_depth_to_drm_format:
3507*d83cc019SAndroid Build Coastguard Worker * @bpp: desired bits per pixel
3508*d83cc019SAndroid Build Coastguard Worker * @depth: desired depth
3509*d83cc019SAndroid Build Coastguard Worker *
3510*d83cc019SAndroid Build Coastguard Worker * Returns:
3511*d83cc019SAndroid Build Coastguard Worker * The rgb drm fourcc pixel format code corresponding to the given @bpp and
3512*d83cc019SAndroid Build Coastguard Worker * @depth values. Fails hard if no match was found.
3513*d83cc019SAndroid Build Coastguard Worker */
igt_bpp_depth_to_drm_format(int bpp,int depth)3514*d83cc019SAndroid Build Coastguard Worker uint32_t igt_bpp_depth_to_drm_format(int bpp, int depth)
3515*d83cc019SAndroid Build Coastguard Worker {
3516*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f;
3517*d83cc019SAndroid Build Coastguard Worker
3518*d83cc019SAndroid Build Coastguard Worker for_each_format(f)
3519*d83cc019SAndroid Build Coastguard Worker if (f->plane_bpp[0] == bpp && f->depth == depth)
3520*d83cc019SAndroid Build Coastguard Worker return f->drm_id;
3521*d83cc019SAndroid Build Coastguard Worker
3522*d83cc019SAndroid Build Coastguard Worker
3523*d83cc019SAndroid Build Coastguard Worker igt_assert_f(0, "can't find drm format with bpp=%d, depth=%d\n", bpp,
3524*d83cc019SAndroid Build Coastguard Worker depth);
3525*d83cc019SAndroid Build Coastguard Worker }
3526*d83cc019SAndroid Build Coastguard Worker
3527*d83cc019SAndroid Build Coastguard Worker /**
3528*d83cc019SAndroid Build Coastguard Worker * igt_drm_format_to_bpp:
3529*d83cc019SAndroid Build Coastguard Worker * @drm_format: drm fourcc pixel format code
3530*d83cc019SAndroid Build Coastguard Worker *
3531*d83cc019SAndroid Build Coastguard Worker * Returns:
3532*d83cc019SAndroid Build Coastguard Worker * The bits per pixel for the given drm fourcc pixel format code. Fails hard if
3533*d83cc019SAndroid Build Coastguard Worker * no match was found.
3534*d83cc019SAndroid Build Coastguard Worker */
igt_drm_format_to_bpp(uint32_t drm_format)3535*d83cc019SAndroid Build Coastguard Worker uint32_t igt_drm_format_to_bpp(uint32_t drm_format)
3536*d83cc019SAndroid Build Coastguard Worker {
3537*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f = lookup_drm_format(drm_format);
3538*d83cc019SAndroid Build Coastguard Worker
3539*d83cc019SAndroid Build Coastguard Worker igt_assert_f(f, "can't find a bpp format for %08x (%s)\n",
3540*d83cc019SAndroid Build Coastguard Worker drm_format, igt_format_str(drm_format));
3541*d83cc019SAndroid Build Coastguard Worker
3542*d83cc019SAndroid Build Coastguard Worker return f->plane_bpp[0];
3543*d83cc019SAndroid Build Coastguard Worker }
3544*d83cc019SAndroid Build Coastguard Worker
3545*d83cc019SAndroid Build Coastguard Worker /**
3546*d83cc019SAndroid Build Coastguard Worker * igt_format_str:
3547*d83cc019SAndroid Build Coastguard Worker * @drm_format: drm fourcc pixel format code
3548*d83cc019SAndroid Build Coastguard Worker *
3549*d83cc019SAndroid Build Coastguard Worker * Returns:
3550*d83cc019SAndroid Build Coastguard Worker * Human-readable fourcc pixel format code for @drm_format or "invalid" no match
3551*d83cc019SAndroid Build Coastguard Worker * was found.
3552*d83cc019SAndroid Build Coastguard Worker */
igt_format_str(uint32_t drm_format)3553*d83cc019SAndroid Build Coastguard Worker const char *igt_format_str(uint32_t drm_format)
3554*d83cc019SAndroid Build Coastguard Worker {
3555*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f = lookup_drm_format(drm_format);
3556*d83cc019SAndroid Build Coastguard Worker
3557*d83cc019SAndroid Build Coastguard Worker return f ? f->name : "invalid";
3558*d83cc019SAndroid Build Coastguard Worker }
3559*d83cc019SAndroid Build Coastguard Worker
3560*d83cc019SAndroid Build Coastguard Worker /**
3561*d83cc019SAndroid Build Coastguard Worker * igt_fb_supported_format:
3562*d83cc019SAndroid Build Coastguard Worker * @drm_format: drm fourcc to test.
3563*d83cc019SAndroid Build Coastguard Worker *
3564*d83cc019SAndroid Build Coastguard Worker * This functions returns whether @drm_format can be succesfully created by
3565*d83cc019SAndroid Build Coastguard Worker * igt_create_fb() and drawn to by igt_get_cairo_ctx().
3566*d83cc019SAndroid Build Coastguard Worker */
igt_fb_supported_format(uint32_t drm_format)3567*d83cc019SAndroid Build Coastguard Worker bool igt_fb_supported_format(uint32_t drm_format)
3568*d83cc019SAndroid Build Coastguard Worker {
3569*d83cc019SAndroid Build Coastguard Worker #if defined (USE_CAIRO_PIXMAN)
3570*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *f;
3571*d83cc019SAndroid Build Coastguard Worker
3572*d83cc019SAndroid Build Coastguard Worker /*
3573*d83cc019SAndroid Build Coastguard Worker * C8 needs a LUT which (at least for the time being)
3574*d83cc019SAndroid Build Coastguard Worker * is the responsibility of each test. Not all tests
3575*d83cc019SAndroid Build Coastguard Worker * have the required code so let's keep C8 hidden from
3576*d83cc019SAndroid Build Coastguard Worker * most eyes.
3577*d83cc019SAndroid Build Coastguard Worker */
3578*d83cc019SAndroid Build Coastguard Worker if (drm_format == DRM_FORMAT_C8)
3579*d83cc019SAndroid Build Coastguard Worker return false;
3580*d83cc019SAndroid Build Coastguard Worker
3581*d83cc019SAndroid Build Coastguard Worker for_each_format(f)
3582*d83cc019SAndroid Build Coastguard Worker if (f->drm_id == drm_format)
3583*d83cc019SAndroid Build Coastguard Worker return (f->cairo_id != CAIRO_FORMAT_INVALID) ||
3584*d83cc019SAndroid Build Coastguard Worker (f->pixman_id != PIXMAN_invalid);
3585*d83cc019SAndroid Build Coastguard Worker
3586*d83cc019SAndroid Build Coastguard Worker return false;
3587*d83cc019SAndroid Build Coastguard Worker #else
3588*d83cc019SAndroid Build Coastguard Worker /* If we don't use Cairo/Pixman, all formats are equally good */
3589*d83cc019SAndroid Build Coastguard Worker return true;
3590*d83cc019SAndroid Build Coastguard Worker #endif
3591*d83cc019SAndroid Build Coastguard Worker }
3592*d83cc019SAndroid Build Coastguard Worker
3593*d83cc019SAndroid Build Coastguard Worker /**
3594*d83cc019SAndroid Build Coastguard Worker * igt_format_is_yuv:
3595*d83cc019SAndroid Build Coastguard Worker * @drm_format: drm fourcc
3596*d83cc019SAndroid Build Coastguard Worker *
3597*d83cc019SAndroid Build Coastguard Worker * This functions returns whether @drm_format is YUV (as opposed to RGB).
3598*d83cc019SAndroid Build Coastguard Worker */
igt_format_is_yuv(uint32_t drm_format)3599*d83cc019SAndroid Build Coastguard Worker bool igt_format_is_yuv(uint32_t drm_format)
3600*d83cc019SAndroid Build Coastguard Worker {
3601*d83cc019SAndroid Build Coastguard Worker switch (drm_format) {
3602*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
3603*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV16:
3604*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV21:
3605*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_NV61:
3606*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV420:
3607*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUV422:
3608*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
3609*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVU422:
3610*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P010:
3611*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P012:
3612*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_P016:
3613*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y210:
3614*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y212:
3615*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y216:
3616*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU2101010:
3617*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU12_16161616:
3618*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XVYU16161616:
3619*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y410:
3620*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y412:
3621*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_Y416:
3622*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YUYV:
3623*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_YVYU:
3624*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_UYVY:
3625*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_VYUY:
3626*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XYUV8888:
3627*d83cc019SAndroid Build Coastguard Worker return true;
3628*d83cc019SAndroid Build Coastguard Worker default:
3629*d83cc019SAndroid Build Coastguard Worker return false;
3630*d83cc019SAndroid Build Coastguard Worker }
3631*d83cc019SAndroid Build Coastguard Worker }
3632*d83cc019SAndroid Build Coastguard Worker
3633*d83cc019SAndroid Build Coastguard Worker /**
3634*d83cc019SAndroid Build Coastguard Worker * igt_format_is_fp16
3635*d83cc019SAndroid Build Coastguard Worker * @drm_format: drm fourcc
3636*d83cc019SAndroid Build Coastguard Worker *
3637*d83cc019SAndroid Build Coastguard Worker * Check if the format is fp16.
3638*d83cc019SAndroid Build Coastguard Worker */
igt_format_is_fp16(uint32_t drm_format)3639*d83cc019SAndroid Build Coastguard Worker bool igt_format_is_fp16(uint32_t drm_format)
3640*d83cc019SAndroid Build Coastguard Worker {
3641*d83cc019SAndroid Build Coastguard Worker switch (drm_format) {
3642*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XRGB16161616F:
3643*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ARGB16161616F:
3644*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_XBGR16161616F:
3645*d83cc019SAndroid Build Coastguard Worker case DRM_FORMAT_ABGR16161616F:
3646*d83cc019SAndroid Build Coastguard Worker return true;
3647*d83cc019SAndroid Build Coastguard Worker default:
3648*d83cc019SAndroid Build Coastguard Worker return false;
3649*d83cc019SAndroid Build Coastguard Worker }
3650*d83cc019SAndroid Build Coastguard Worker }
3651*d83cc019SAndroid Build Coastguard Worker
3652*d83cc019SAndroid Build Coastguard Worker /**
3653*d83cc019SAndroid Build Coastguard Worker * igt_format_plane_bpp:
3654*d83cc019SAndroid Build Coastguard Worker * @drm_format: drm fourcc
3655*d83cc019SAndroid Build Coastguard Worker * @plane: format plane index
3656*d83cc019SAndroid Build Coastguard Worker *
3657*d83cc019SAndroid Build Coastguard Worker * This functions returns the number of bits per pixel for the given @plane
3658*d83cc019SAndroid Build Coastguard Worker * index of the @drm_format.
3659*d83cc019SAndroid Build Coastguard Worker */
igt_format_plane_bpp(uint32_t drm_format,int plane)3660*d83cc019SAndroid Build Coastguard Worker int igt_format_plane_bpp(uint32_t drm_format, int plane)
3661*d83cc019SAndroid Build Coastguard Worker {
3662*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *format =
3663*d83cc019SAndroid Build Coastguard Worker lookup_drm_format(drm_format);
3664*d83cc019SAndroid Build Coastguard Worker
3665*d83cc019SAndroid Build Coastguard Worker return format->plane_bpp[plane];
3666*d83cc019SAndroid Build Coastguard Worker }
3667*d83cc019SAndroid Build Coastguard Worker
3668*d83cc019SAndroid Build Coastguard Worker /**
3669*d83cc019SAndroid Build Coastguard Worker * igt_format_array_fill:
3670*d83cc019SAndroid Build Coastguard Worker * @formats_array: a pointer to the formats array pointer to be allocated
3671*d83cc019SAndroid Build Coastguard Worker * @count: a pointer to the number of elements contained in the allocated array
3672*d83cc019SAndroid Build Coastguard Worker * @allow_yuv: a boolean indicating whether YUV formats should be included
3673*d83cc019SAndroid Build Coastguard Worker *
3674*d83cc019SAndroid Build Coastguard Worker * This functions allocates and fills a @formats_array that lists the DRM
3675*d83cc019SAndroid Build Coastguard Worker * formats current available.
3676*d83cc019SAndroid Build Coastguard Worker */
igt_format_array_fill(uint32_t ** formats_array,unsigned int * count,bool allow_yuv)3677*d83cc019SAndroid Build Coastguard Worker void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
3678*d83cc019SAndroid Build Coastguard Worker bool allow_yuv)
3679*d83cc019SAndroid Build Coastguard Worker {
3680*d83cc019SAndroid Build Coastguard Worker const struct format_desc_struct *format;
3681*d83cc019SAndroid Build Coastguard Worker unsigned int index = 0;
3682*d83cc019SAndroid Build Coastguard Worker
3683*d83cc019SAndroid Build Coastguard Worker *count = 0;
3684*d83cc019SAndroid Build Coastguard Worker
3685*d83cc019SAndroid Build Coastguard Worker for_each_format(format) {
3686*d83cc019SAndroid Build Coastguard Worker if (!allow_yuv && igt_format_is_yuv(format->drm_id))
3687*d83cc019SAndroid Build Coastguard Worker continue;
3688*d83cc019SAndroid Build Coastguard Worker
3689*d83cc019SAndroid Build Coastguard Worker (*count)++;
3690*d83cc019SAndroid Build Coastguard Worker }
3691*d83cc019SAndroid Build Coastguard Worker
3692*d83cc019SAndroid Build Coastguard Worker *formats_array = calloc(*count, sizeof(uint32_t));
3693*d83cc019SAndroid Build Coastguard Worker igt_assert(*formats_array);
3694*d83cc019SAndroid Build Coastguard Worker
3695*d83cc019SAndroid Build Coastguard Worker for_each_format(format) {
3696*d83cc019SAndroid Build Coastguard Worker if (!allow_yuv && igt_format_is_yuv(format->drm_id))
3697*d83cc019SAndroid Build Coastguard Worker continue;
3698*d83cc019SAndroid Build Coastguard Worker
3699*d83cc019SAndroid Build Coastguard Worker (*formats_array)[index++] = format->drm_id;
3700*d83cc019SAndroid Build Coastguard Worker }
3701*d83cc019SAndroid Build Coastguard Worker }
3702