xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_render_copy.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2013 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  *    Damien Lespiau <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  */
26*d83cc019SAndroid Build Coastguard Worker 
27*d83cc019SAndroid Build Coastguard Worker /*
28*d83cc019SAndroid Build Coastguard Worker  * This file is a basic test for the render_copy() function, a very simple
29*d83cc019SAndroid Build Coastguard Worker  * workload for the 3D engine.
30*d83cc019SAndroid Build Coastguard Worker  */
31*d83cc019SAndroid Build Coastguard Worker 
32*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
33*d83cc019SAndroid Build Coastguard Worker #include "igt_x86.h"
34*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
35*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
36*d83cc019SAndroid Build Coastguard Worker #include <cairo.h>
37*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
38*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
39*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
40*d83cc019SAndroid Build Coastguard Worker #include <string.h>
41*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
42*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
43*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
44*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
45*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
48*d83cc019SAndroid Build Coastguard Worker 
49*d83cc019SAndroid Build Coastguard Worker #include "intel_bufmgr.h"
50*d83cc019SAndroid Build Coastguard Worker 
51*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Basic test for the render_copy() function.");
52*d83cc019SAndroid Build Coastguard Worker 
53*d83cc019SAndroid Build Coastguard Worker #define WIDTH 512
54*d83cc019SAndroid Build Coastguard Worker #define HEIGHT 512
55*d83cc019SAndroid Build Coastguard Worker 
56*d83cc019SAndroid Build Coastguard Worker typedef struct {
57*d83cc019SAndroid Build Coastguard Worker 	int drm_fd;
58*d83cc019SAndroid Build Coastguard Worker 	uint32_t devid;
59*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr *bufmgr;
60*d83cc019SAndroid Build Coastguard Worker 	struct intel_batchbuffer *batch;
61*d83cc019SAndroid Build Coastguard Worker 	igt_render_copyfunc_t render_copy;
62*d83cc019SAndroid Build Coastguard Worker } data_t;
63*d83cc019SAndroid Build Coastguard Worker static int opt_dump_png = false;
64*d83cc019SAndroid Build Coastguard Worker static int check_all_pixels = false;
65*d83cc019SAndroid Build Coastguard Worker 
make_filename(const char * filename)66*d83cc019SAndroid Build Coastguard Worker static const char *make_filename(const char *filename)
67*d83cc019SAndroid Build Coastguard Worker {
68*d83cc019SAndroid Build Coastguard Worker 	static char buf[64];
69*d83cc019SAndroid Build Coastguard Worker 
70*d83cc019SAndroid Build Coastguard Worker 	snprintf(buf, sizeof(buf), "%s_%s", igt_subtest_name(), filename);
71*d83cc019SAndroid Build Coastguard Worker 
72*d83cc019SAndroid Build Coastguard Worker 	return buf;
73*d83cc019SAndroid Build Coastguard Worker }
74*d83cc019SAndroid Build Coastguard Worker 
yf_ptr(void * ptr,unsigned int x,unsigned int y,unsigned int stride,unsigned int cpp)75*d83cc019SAndroid Build Coastguard Worker static void *yf_ptr(void *ptr,
76*d83cc019SAndroid Build Coastguard Worker 		    unsigned int x, unsigned int y,
77*d83cc019SAndroid Build Coastguard Worker 		    unsigned int stride, unsigned int cpp)
78*d83cc019SAndroid Build Coastguard Worker {
79*d83cc019SAndroid Build Coastguard Worker 	const int tile_size = 4 * 1024;
80*d83cc019SAndroid Build Coastguard Worker 	const int tile_width = 128;
81*d83cc019SAndroid Build Coastguard Worker 	int row_size = (stride / tile_width) * tile_size;
82*d83cc019SAndroid Build Coastguard Worker 
83*d83cc019SAndroid Build Coastguard Worker 	x *= cpp; /* convert to Byte offset */
84*d83cc019SAndroid Build Coastguard Worker 
85*d83cc019SAndroid Build Coastguard Worker 
86*d83cc019SAndroid Build Coastguard Worker 	/*
87*d83cc019SAndroid Build Coastguard Worker 	 * Within a 4k Yf tile, the byte swizzling pattern is
88*d83cc019SAndroid Build Coastguard Worker 	 * msb......lsb
89*d83cc019SAndroid Build Coastguard Worker 	 * xyxyxyyyxxxx
90*d83cc019SAndroid Build Coastguard Worker 	 * The tiles themselves are laid out in row major order.
91*d83cc019SAndroid Build Coastguard Worker 	 */
92*d83cc019SAndroid Build Coastguard Worker 	return ptr +
93*d83cc019SAndroid Build Coastguard Worker 		((x & 0xf) * 1) + /* 4x1 pixels(32bpp) = 16B */
94*d83cc019SAndroid Build Coastguard Worker 		((y & 0x3) * 16) + /* 4x4 pixels = 64B */
95*d83cc019SAndroid Build Coastguard Worker 		(((y & 0x4) >> 2) * 64) + /* 1x2 64B blocks */
96*d83cc019SAndroid Build Coastguard Worker 		(((x & 0x10) >> 4) * 128) + /* 2x2 64B blocks = 256B block */
97*d83cc019SAndroid Build Coastguard Worker 		(((y & 0x8) >> 3) * 256) + /* 2x1 256B blocks */
98*d83cc019SAndroid Build Coastguard Worker 		(((x & 0x20) >> 5) * 512) + /* 2x2 256B blocks */
99*d83cc019SAndroid Build Coastguard Worker 		(((y & 0x10) >> 4) * 1024) + /* 4x2 256 blocks */
100*d83cc019SAndroid Build Coastguard Worker 		(((x & 0x40) >> 6) * 2048) + /* 4x4 256B blocks = 4k tile */
101*d83cc019SAndroid Build Coastguard Worker 		(((x & ~0x7f) >> 7) * tile_size) + /* row of tiles */
102*d83cc019SAndroid Build Coastguard Worker 		(((y & ~0x1f) >> 5) * row_size);
103*d83cc019SAndroid Build Coastguard Worker }
104*d83cc019SAndroid Build Coastguard Worker 
copy_linear_to_yf(data_t * data,struct igt_buf * buf,const uint32_t * linear)105*d83cc019SAndroid Build Coastguard Worker static void copy_linear_to_yf(data_t *data, struct igt_buf *buf,
106*d83cc019SAndroid Build Coastguard Worker 			      const uint32_t *linear)
107*d83cc019SAndroid Build Coastguard Worker {
108*d83cc019SAndroid Build Coastguard Worker 	int height = igt_buf_height(buf);
109*d83cc019SAndroid Build Coastguard Worker 	int width = igt_buf_width(buf);
110*d83cc019SAndroid Build Coastguard Worker 	void *map;
111*d83cc019SAndroid Build Coastguard Worker 
112*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(data->drm_fd, buf->bo->handle,
113*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
114*d83cc019SAndroid Build Coastguard Worker 	map = gem_mmap__cpu(data->drm_fd, buf->bo->handle, 0,
115*d83cc019SAndroid Build Coastguard Worker 			    buf->bo->size, PROT_READ | PROT_WRITE);
116*d83cc019SAndroid Build Coastguard Worker 
117*d83cc019SAndroid Build Coastguard Worker 	for (int y = 0; y < height; y++) {
118*d83cc019SAndroid Build Coastguard Worker 		for (int x = 0; x < width; x++) {
119*d83cc019SAndroid Build Coastguard Worker 			uint32_t *ptr = yf_ptr(map, x, y,
120*d83cc019SAndroid Build Coastguard Worker 					       buf->stride, buf->bpp / 8);
121*d83cc019SAndroid Build Coastguard Worker 
122*d83cc019SAndroid Build Coastguard Worker 			*ptr = linear[y * width + x];
123*d83cc019SAndroid Build Coastguard Worker 		}
124*d83cc019SAndroid Build Coastguard Worker 	}
125*d83cc019SAndroid Build Coastguard Worker 
126*d83cc019SAndroid Build Coastguard Worker 	munmap(map, buf->bo->size);
127*d83cc019SAndroid Build Coastguard Worker }
128*d83cc019SAndroid Build Coastguard Worker 
copy_yf_to_linear(data_t * data,struct igt_buf * buf,uint32_t * linear)129*d83cc019SAndroid Build Coastguard Worker static void copy_yf_to_linear(data_t *data, struct igt_buf *buf,
130*d83cc019SAndroid Build Coastguard Worker 			      uint32_t *linear)
131*d83cc019SAndroid Build Coastguard Worker {
132*d83cc019SAndroid Build Coastguard Worker 	int height = igt_buf_height(buf);
133*d83cc019SAndroid Build Coastguard Worker 	int width = igt_buf_width(buf);
134*d83cc019SAndroid Build Coastguard Worker 	void *map;
135*d83cc019SAndroid Build Coastguard Worker 
136*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(data->drm_fd, buf->bo->handle,
137*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_CPU, 0);
138*d83cc019SAndroid Build Coastguard Worker 	map = gem_mmap__cpu(data->drm_fd, buf->bo->handle, 0,
139*d83cc019SAndroid Build Coastguard Worker 			    buf->bo->size, PROT_READ);
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 	for (int y = 0; y < height; y++) {
142*d83cc019SAndroid Build Coastguard Worker 		for (int x = 0; x < width; x++) {
143*d83cc019SAndroid Build Coastguard Worker 			uint32_t *ptr = yf_ptr(map, x, y,
144*d83cc019SAndroid Build Coastguard Worker 					       buf->stride, buf->bpp / 8);
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 			linear[y * width + x] = *ptr;
147*d83cc019SAndroid Build Coastguard Worker 		}
148*d83cc019SAndroid Build Coastguard Worker 	}
149*d83cc019SAndroid Build Coastguard Worker 
150*d83cc019SAndroid Build Coastguard Worker 	munmap(map, buf->bo->size);
151*d83cc019SAndroid Build Coastguard Worker }
152*d83cc019SAndroid Build Coastguard Worker 
copy_linear_to_gtt(data_t * data,struct igt_buf * buf,const uint32_t * linear)153*d83cc019SAndroid Build Coastguard Worker static void copy_linear_to_gtt(data_t *data, struct igt_buf *buf,
154*d83cc019SAndroid Build Coastguard Worker 			       const uint32_t *linear)
155*d83cc019SAndroid Build Coastguard Worker {
156*d83cc019SAndroid Build Coastguard Worker 	void *map;
157*d83cc019SAndroid Build Coastguard Worker 
158*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(data->drm_fd, buf->bo->handle,
159*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
160*d83cc019SAndroid Build Coastguard Worker 
161*d83cc019SAndroid Build Coastguard Worker 	map = gem_mmap__gtt(data->drm_fd, buf->bo->handle,
162*d83cc019SAndroid Build Coastguard Worker 			    buf->bo->size, PROT_READ | PROT_WRITE);
163*d83cc019SAndroid Build Coastguard Worker 
164*d83cc019SAndroid Build Coastguard Worker 	memcpy(map, linear, buf->bo->size);
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 	munmap(map, buf->bo->size);
167*d83cc019SAndroid Build Coastguard Worker }
168*d83cc019SAndroid Build Coastguard Worker 
copy_gtt_to_linear(data_t * data,struct igt_buf * buf,uint32_t * linear)169*d83cc019SAndroid Build Coastguard Worker static void copy_gtt_to_linear(data_t *data, struct igt_buf *buf,
170*d83cc019SAndroid Build Coastguard Worker 			       uint32_t *linear)
171*d83cc019SAndroid Build Coastguard Worker {
172*d83cc019SAndroid Build Coastguard Worker 	void *map;
173*d83cc019SAndroid Build Coastguard Worker 
174*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(data->drm_fd, buf->bo->handle,
175*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, 0);
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker 	map = gem_mmap__gtt(data->drm_fd, buf->bo->handle,
178*d83cc019SAndroid Build Coastguard Worker 			    buf->bo->size, PROT_READ);
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 	igt_memcpy_from_wc(linear, map, buf->bo->size);
181*d83cc019SAndroid Build Coastguard Worker 
182*d83cc019SAndroid Build Coastguard Worker 	munmap(map, buf->bo->size);
183*d83cc019SAndroid Build Coastguard Worker }
184*d83cc019SAndroid Build Coastguard Worker 
linear_copy(data_t * data,struct igt_buf * buf)185*d83cc019SAndroid Build Coastguard Worker static void *linear_copy(data_t *data, struct igt_buf *buf)
186*d83cc019SAndroid Build Coastguard Worker {
187*d83cc019SAndroid Build Coastguard Worker 	void *linear;
188*d83cc019SAndroid Build Coastguard Worker 
189*d83cc019SAndroid Build Coastguard Worker 	/* 16B alignment allows to potentially make use of SSE4 for copying */
190*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(posix_memalign(&linear, 16, buf->bo->size), 0);
191*d83cc019SAndroid Build Coastguard Worker 
192*d83cc019SAndroid Build Coastguard Worker 	if (buf->tiling == I915_TILING_Yf)
193*d83cc019SAndroid Build Coastguard Worker 		copy_yf_to_linear(data, buf, linear);
194*d83cc019SAndroid Build Coastguard Worker 	else
195*d83cc019SAndroid Build Coastguard Worker 		copy_gtt_to_linear(data, buf, linear);
196*d83cc019SAndroid Build Coastguard Worker 
197*d83cc019SAndroid Build Coastguard Worker 	return linear;
198*d83cc019SAndroid Build Coastguard Worker }
199*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_write_to_png(data_t * data,struct igt_buf * buf,const char * filename)200*d83cc019SAndroid Build Coastguard Worker static void scratch_buf_write_to_png(data_t *data, struct igt_buf *buf,
201*d83cc019SAndroid Build Coastguard Worker 				     const char *filename)
202*d83cc019SAndroid Build Coastguard Worker {
203*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_t *surface;
204*d83cc019SAndroid Build Coastguard Worker 	cairo_status_t ret;
205*d83cc019SAndroid Build Coastguard Worker 	void *linear;
206*d83cc019SAndroid Build Coastguard Worker 
207*d83cc019SAndroid Build Coastguard Worker 	linear = linear_copy(data, buf);
208*d83cc019SAndroid Build Coastguard Worker 
209*d83cc019SAndroid Build Coastguard Worker 	surface = cairo_image_surface_create_for_data(linear,
210*d83cc019SAndroid Build Coastguard Worker 						      CAIRO_FORMAT_RGB24,
211*d83cc019SAndroid Build Coastguard Worker 						      igt_buf_width(buf),
212*d83cc019SAndroid Build Coastguard Worker 						      igt_buf_height(buf),
213*d83cc019SAndroid Build Coastguard Worker 						      buf->stride);
214*d83cc019SAndroid Build Coastguard Worker 	ret = cairo_surface_write_to_png(surface, make_filename(filename));
215*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == CAIRO_STATUS_SUCCESS);
216*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_destroy(surface);
217*d83cc019SAndroid Build Coastguard Worker 
218*d83cc019SAndroid Build Coastguard Worker 	free(linear);
219*d83cc019SAndroid Build Coastguard Worker }
220*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_aux_width(const struct igt_buf * buf)221*d83cc019SAndroid Build Coastguard Worker static int scratch_buf_aux_width(const struct igt_buf *buf)
222*d83cc019SAndroid Build Coastguard Worker {
223*d83cc019SAndroid Build Coastguard Worker 	return DIV_ROUND_UP(igt_buf_width(buf), 1024) * 128;
224*d83cc019SAndroid Build Coastguard Worker }
225*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_aux_height(const struct igt_buf * buf)226*d83cc019SAndroid Build Coastguard Worker static int scratch_buf_aux_height(const struct igt_buf *buf)
227*d83cc019SAndroid Build Coastguard Worker {
228*d83cc019SAndroid Build Coastguard Worker 	return DIV_ROUND_UP(igt_buf_height(buf), 512) * 32;
229*d83cc019SAndroid Build Coastguard Worker }
230*d83cc019SAndroid Build Coastguard Worker 
linear_copy_aux(data_t * data,struct igt_buf * buf)231*d83cc019SAndroid Build Coastguard Worker static void *linear_copy_aux(data_t *data, struct igt_buf *buf)
232*d83cc019SAndroid Build Coastguard Worker {
233*d83cc019SAndroid Build Coastguard Worker 	void *map, *linear;
234*d83cc019SAndroid Build Coastguard Worker 	int aux_size = scratch_buf_aux_width(buf) *
235*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_aux_height(buf);
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(posix_memalign(&linear, 16, aux_size), 0);
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(data->drm_fd, buf->bo->handle,
240*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, 0);
241*d83cc019SAndroid Build Coastguard Worker 
242*d83cc019SAndroid Build Coastguard Worker 	map = gem_mmap__gtt(data->drm_fd, buf->bo->handle,
243*d83cc019SAndroid Build Coastguard Worker 			    buf->bo->size, PROT_READ);
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	igt_memcpy_from_wc(linear, map + buf->aux.offset, aux_size);
246*d83cc019SAndroid Build Coastguard Worker 
247*d83cc019SAndroid Build Coastguard Worker 	munmap(map, buf->bo->size);
248*d83cc019SAndroid Build Coastguard Worker 
249*d83cc019SAndroid Build Coastguard Worker 	return linear;
250*d83cc019SAndroid Build Coastguard Worker }
251*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_aux_write_to_png(data_t * data,struct igt_buf * buf,const char * filename)252*d83cc019SAndroid Build Coastguard Worker static void scratch_buf_aux_write_to_png(data_t *data,
253*d83cc019SAndroid Build Coastguard Worker 					 struct igt_buf *buf,
254*d83cc019SAndroid Build Coastguard Worker 					 const char *filename)
255*d83cc019SAndroid Build Coastguard Worker {
256*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_t *surface;
257*d83cc019SAndroid Build Coastguard Worker 	cairo_status_t ret;
258*d83cc019SAndroid Build Coastguard Worker 	void *linear;
259*d83cc019SAndroid Build Coastguard Worker 
260*d83cc019SAndroid Build Coastguard Worker 	linear = linear_copy_aux(data, buf);
261*d83cc019SAndroid Build Coastguard Worker 
262*d83cc019SAndroid Build Coastguard Worker 	surface = cairo_image_surface_create_for_data(linear,
263*d83cc019SAndroid Build Coastguard Worker 						      CAIRO_FORMAT_A8,
264*d83cc019SAndroid Build Coastguard Worker 						      scratch_buf_aux_width(buf),
265*d83cc019SAndroid Build Coastguard Worker 						      scratch_buf_aux_height(buf),
266*d83cc019SAndroid Build Coastguard Worker 						      buf->aux.stride);
267*d83cc019SAndroid Build Coastguard Worker 	ret = cairo_surface_write_to_png(surface, make_filename(filename));
268*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == CAIRO_STATUS_SUCCESS);
269*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_destroy(surface);
270*d83cc019SAndroid Build Coastguard Worker 
271*d83cc019SAndroid Build Coastguard Worker 	free(linear);
272*d83cc019SAndroid Build Coastguard Worker }
273*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_draw_pattern(data_t * data,struct igt_buf * buf,int x,int y,int w,int h,int cx,int cy,int cw,int ch,bool use_alternate_colors)274*d83cc019SAndroid Build Coastguard Worker static void scratch_buf_draw_pattern(data_t *data, struct igt_buf *buf,
275*d83cc019SAndroid Build Coastguard Worker 				     int x, int y, int w, int h,
276*d83cc019SAndroid Build Coastguard Worker 				     int cx, int cy, int cw, int ch,
277*d83cc019SAndroid Build Coastguard Worker 				     bool use_alternate_colors)
278*d83cc019SAndroid Build Coastguard Worker {
279*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_t *surface;
280*d83cc019SAndroid Build Coastguard Worker 	cairo_pattern_t *pat;
281*d83cc019SAndroid Build Coastguard Worker 	cairo_t *cr;
282*d83cc019SAndroid Build Coastguard Worker 	void *linear;
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	linear = linear_copy(data, buf);
285*d83cc019SAndroid Build Coastguard Worker 
286*d83cc019SAndroid Build Coastguard Worker 	surface = cairo_image_surface_create_for_data(linear,
287*d83cc019SAndroid Build Coastguard Worker 						      CAIRO_FORMAT_RGB24,
288*d83cc019SAndroid Build Coastguard Worker 						      igt_buf_width(buf),
289*d83cc019SAndroid Build Coastguard Worker 						      igt_buf_height(buf),
290*d83cc019SAndroid Build Coastguard Worker 						      buf->stride);
291*d83cc019SAndroid Build Coastguard Worker 
292*d83cc019SAndroid Build Coastguard Worker 	cr = cairo_create(surface);
293*d83cc019SAndroid Build Coastguard Worker 
294*d83cc019SAndroid Build Coastguard Worker 	cairo_rectangle(cr, cx, cy, cw, ch);
295*d83cc019SAndroid Build Coastguard Worker 	cairo_clip(cr);
296*d83cc019SAndroid Build Coastguard Worker 
297*d83cc019SAndroid Build Coastguard Worker 	pat = cairo_pattern_create_mesh();
298*d83cc019SAndroid Build Coastguard Worker 	cairo_mesh_pattern_begin_patch(pat);
299*d83cc019SAndroid Build Coastguard Worker 	cairo_mesh_pattern_move_to(pat, x,   y);
300*d83cc019SAndroid Build Coastguard Worker 	cairo_mesh_pattern_line_to(pat, x+w, y);
301*d83cc019SAndroid Build Coastguard Worker 	cairo_mesh_pattern_line_to(pat, x+w, y+h);
302*d83cc019SAndroid Build Coastguard Worker 	cairo_mesh_pattern_line_to(pat, x,   y+h);
303*d83cc019SAndroid Build Coastguard Worker 	if (use_alternate_colors) {
304*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 0, 0.0, 1.0, 1.0);
305*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 1, 1.0, 0.0, 1.0);
306*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 2, 1.0, 1.0, 0.0);
307*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 3, 0.0, 0.0, 0.0);
308*d83cc019SAndroid Build Coastguard Worker 	} else {
309*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 0, 1.0, 0.0, 0.0);
310*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 1, 0.0, 1.0, 0.0);
311*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 2, 0.0, 0.0, 1.0);
312*d83cc019SAndroid Build Coastguard Worker 		cairo_mesh_pattern_set_corner_color_rgb(pat, 3, 1.0, 1.0, 1.0);
313*d83cc019SAndroid Build Coastguard Worker 	}
314*d83cc019SAndroid Build Coastguard Worker 	cairo_mesh_pattern_end_patch(pat);
315*d83cc019SAndroid Build Coastguard Worker 
316*d83cc019SAndroid Build Coastguard Worker 	cairo_rectangle(cr, x, y, w, h);
317*d83cc019SAndroid Build Coastguard Worker 	cairo_set_source(cr, pat);
318*d83cc019SAndroid Build Coastguard Worker 	cairo_fill(cr);
319*d83cc019SAndroid Build Coastguard Worker 	cairo_pattern_destroy(pat);
320*d83cc019SAndroid Build Coastguard Worker 
321*d83cc019SAndroid Build Coastguard Worker 	cairo_destroy(cr);
322*d83cc019SAndroid Build Coastguard Worker 
323*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_destroy(surface);
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 	if (buf->tiling == I915_TILING_Yf)
326*d83cc019SAndroid Build Coastguard Worker 		copy_linear_to_yf(data, buf, linear);
327*d83cc019SAndroid Build Coastguard Worker 	else
328*d83cc019SAndroid Build Coastguard Worker 		copy_linear_to_gtt(data, buf, linear);
329*d83cc019SAndroid Build Coastguard Worker 
330*d83cc019SAndroid Build Coastguard Worker 	free(linear);
331*d83cc019SAndroid Build Coastguard Worker }
332*d83cc019SAndroid Build Coastguard Worker 
333*d83cc019SAndroid Build Coastguard Worker static void
scratch_buf_copy(data_t * data,struct igt_buf * src,int sx,int sy,int w,int h,struct igt_buf * dst,int dx,int dy)334*d83cc019SAndroid Build Coastguard Worker scratch_buf_copy(data_t *data,
335*d83cc019SAndroid Build Coastguard Worker 		 struct igt_buf *src, int sx, int sy, int w, int h,
336*d83cc019SAndroid Build Coastguard Worker 		 struct igt_buf *dst, int dx, int dy)
337*d83cc019SAndroid Build Coastguard Worker {
338*d83cc019SAndroid Build Coastguard Worker 	int width = igt_buf_width(dst);
339*d83cc019SAndroid Build Coastguard Worker 	int height  = igt_buf_height(dst);
340*d83cc019SAndroid Build Coastguard Worker 	uint32_t *linear_dst;
341*d83cc019SAndroid Build Coastguard Worker 
342*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(igt_buf_width(dst), igt_buf_width(src));
343*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(igt_buf_height(dst), igt_buf_height(src));
344*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(dst->bo->size, src->bo->size);
345*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(dst->bpp, src->bpp);
346*d83cc019SAndroid Build Coastguard Worker 
347*d83cc019SAndroid Build Coastguard Worker 	w = min(w, width - sx);
348*d83cc019SAndroid Build Coastguard Worker 	w = min(w, width - dx);
349*d83cc019SAndroid Build Coastguard Worker 
350*d83cc019SAndroid Build Coastguard Worker 	h = min(h, height - sy);
351*d83cc019SAndroid Build Coastguard Worker 	h = min(h, height - dy);
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(data->drm_fd, dst->bo->handle,
354*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
355*d83cc019SAndroid Build Coastguard Worker 	linear_dst = gem_mmap__gtt(data->drm_fd, dst->bo->handle,
356*d83cc019SAndroid Build Coastguard Worker 				   dst->bo->size, PROT_WRITE);
357*d83cc019SAndroid Build Coastguard Worker 
358*d83cc019SAndroid Build Coastguard Worker 	if (src->tiling == I915_TILING_Yf) {
359*d83cc019SAndroid Build Coastguard Worker 		void *map;
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker 		gem_set_domain(data->drm_fd, src->bo->handle,
362*d83cc019SAndroid Build Coastguard Worker 			       I915_GEM_DOMAIN_CPU, 0);
363*d83cc019SAndroid Build Coastguard Worker 		map = gem_mmap__cpu(data->drm_fd, src->bo->handle, 0,
364*d83cc019SAndroid Build Coastguard Worker 				    src->bo->size, PROT_READ);
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker 		for (int y = 0; y < h; y++) {
367*d83cc019SAndroid Build Coastguard Worker 			for (int x = 0; x < w; x++) {
368*d83cc019SAndroid Build Coastguard Worker 				const uint32_t *ptr = yf_ptr(map, sx+x, sy+y,
369*d83cc019SAndroid Build Coastguard Worker 							     src->stride,
370*d83cc019SAndroid Build Coastguard Worker 							     src->bpp / 8);
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 				linear_dst[(dy+y) * width + dx+x] = *ptr;
373*d83cc019SAndroid Build Coastguard Worker 			}
374*d83cc019SAndroid Build Coastguard Worker 		}
375*d83cc019SAndroid Build Coastguard Worker 
376*d83cc019SAndroid Build Coastguard Worker 		munmap(map, src->bo->size);
377*d83cc019SAndroid Build Coastguard Worker 	} else {
378*d83cc019SAndroid Build Coastguard Worker 		uint32_t *linear_src;
379*d83cc019SAndroid Build Coastguard Worker 
380*d83cc019SAndroid Build Coastguard Worker 		gem_set_domain(data->drm_fd, src->bo->handle,
381*d83cc019SAndroid Build Coastguard Worker 			       I915_GEM_DOMAIN_GTT, 0);
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 		linear_src = gem_mmap__gtt(data->drm_fd, src->bo->handle,
384*d83cc019SAndroid Build Coastguard Worker 					   src->bo->size, PROT_READ);
385*d83cc019SAndroid Build Coastguard Worker 
386*d83cc019SAndroid Build Coastguard Worker 		for (int y = 0; y < h; y++) {
387*d83cc019SAndroid Build Coastguard Worker 			igt_memcpy_from_wc(&linear_dst[(dy+y) * width + dx],
388*d83cc019SAndroid Build Coastguard Worker 					   &linear_src[(sy+y) * width + sx],
389*d83cc019SAndroid Build Coastguard Worker 					   w * (src->bpp / 8));
390*d83cc019SAndroid Build Coastguard Worker 		}
391*d83cc019SAndroid Build Coastguard Worker 
392*d83cc019SAndroid Build Coastguard Worker 		munmap(linear_src, src->bo->size);
393*d83cc019SAndroid Build Coastguard Worker 	}
394*d83cc019SAndroid Build Coastguard Worker 
395*d83cc019SAndroid Build Coastguard Worker 	munmap(linear_dst, dst->bo->size);
396*d83cc019SAndroid Build Coastguard Worker }
397*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_init(data_t * data,struct igt_buf * buf,int width,int height,uint32_t req_tiling,bool ccs)398*d83cc019SAndroid Build Coastguard Worker static void scratch_buf_init(data_t *data, struct igt_buf *buf,
399*d83cc019SAndroid Build Coastguard Worker 			     int width, int height,
400*d83cc019SAndroid Build Coastguard Worker 			     uint32_t req_tiling, bool ccs)
401*d83cc019SAndroid Build Coastguard Worker {
402*d83cc019SAndroid Build Coastguard Worker 	uint32_t tiling = req_tiling;
403*d83cc019SAndroid Build Coastguard Worker 	unsigned long pitch;
404*d83cc019SAndroid Build Coastguard Worker 	int bpp = 32;
405*d83cc019SAndroid Build Coastguard Worker 
406*d83cc019SAndroid Build Coastguard Worker 	memset(buf, 0, sizeof(*buf));
407*d83cc019SAndroid Build Coastguard Worker 
408*d83cc019SAndroid Build Coastguard Worker 	if (ccs) {
409*d83cc019SAndroid Build Coastguard Worker 		int aux_width, aux_height;
410*d83cc019SAndroid Build Coastguard Worker 		int size;
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker 		igt_require(intel_gen(data->devid) >= 9);
413*d83cc019SAndroid Build Coastguard Worker 		igt_assert(tiling == I915_TILING_Y ||
414*d83cc019SAndroid Build Coastguard Worker 			   tiling == I915_TILING_Yf);
415*d83cc019SAndroid Build Coastguard Worker 
416*d83cc019SAndroid Build Coastguard Worker 		buf->stride = ALIGN(width * (bpp / 8), 128);
417*d83cc019SAndroid Build Coastguard Worker 		buf->size = buf->stride * height;
418*d83cc019SAndroid Build Coastguard Worker 		buf->tiling = tiling;
419*d83cc019SAndroid Build Coastguard Worker 		buf->bpp = bpp;
420*d83cc019SAndroid Build Coastguard Worker 
421*d83cc019SAndroid Build Coastguard Worker 		aux_width = scratch_buf_aux_width(buf);
422*d83cc019SAndroid Build Coastguard Worker 		aux_height = scratch_buf_aux_height(buf);
423*d83cc019SAndroid Build Coastguard Worker 
424*d83cc019SAndroid Build Coastguard Worker 		buf->aux.offset = buf->stride * ALIGN(height, 32);
425*d83cc019SAndroid Build Coastguard Worker 		buf->aux.stride = aux_width;
426*d83cc019SAndroid Build Coastguard Worker 
427*d83cc019SAndroid Build Coastguard Worker 		size = buf->aux.offset + aux_width * aux_height;
428*d83cc019SAndroid Build Coastguard Worker 
429*d83cc019SAndroid Build Coastguard Worker 		buf->bo = drm_intel_bo_alloc(data->bufmgr, "", size, 4096);
430*d83cc019SAndroid Build Coastguard Worker 
431*d83cc019SAndroid Build Coastguard Worker 		if (tiling == I915_TILING_Y) {
432*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_set_tiling(buf->bo, &tiling, buf->stride);
433*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(tiling, req_tiling);
434*d83cc019SAndroid Build Coastguard Worker 		}
435*d83cc019SAndroid Build Coastguard Worker 	} else if (req_tiling == I915_TILING_Yf) {
436*d83cc019SAndroid Build Coastguard Worker 		int size;
437*d83cc019SAndroid Build Coastguard Worker 
438*d83cc019SAndroid Build Coastguard Worker 		buf->stride = ALIGN(width * (bpp / 8), 128);
439*d83cc019SAndroid Build Coastguard Worker 		buf->size = buf->stride * height;
440*d83cc019SAndroid Build Coastguard Worker 		buf->tiling = tiling;
441*d83cc019SAndroid Build Coastguard Worker 		buf->bpp = bpp;
442*d83cc019SAndroid Build Coastguard Worker 
443*d83cc019SAndroid Build Coastguard Worker 		size = buf->stride * ALIGN(height, 32);
444*d83cc019SAndroid Build Coastguard Worker 
445*d83cc019SAndroid Build Coastguard Worker 		buf->bo = drm_intel_bo_alloc(data->bufmgr, "", size, 4096);
446*d83cc019SAndroid Build Coastguard Worker 	} else {
447*d83cc019SAndroid Build Coastguard Worker 		buf->bo = drm_intel_bo_alloc_tiled(data->bufmgr, "",
448*d83cc019SAndroid Build Coastguard Worker 						   width, height, bpp / 8,
449*d83cc019SAndroid Build Coastguard Worker 						   &tiling, &pitch, 0);
450*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(tiling, req_tiling);
451*d83cc019SAndroid Build Coastguard Worker 
452*d83cc019SAndroid Build Coastguard Worker 		buf->stride = pitch;
453*d83cc019SAndroid Build Coastguard Worker 		buf->tiling = tiling;
454*d83cc019SAndroid Build Coastguard Worker 		buf->size = pitch * height;
455*d83cc019SAndroid Build Coastguard Worker 		buf->bpp = bpp;
456*d83cc019SAndroid Build Coastguard Worker 	}
457*d83cc019SAndroid Build Coastguard Worker 
458*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_buf_width(buf) == width);
459*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_buf_height(buf) == height);
460*d83cc019SAndroid Build Coastguard Worker }
461*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_fini(struct igt_buf * buf)462*d83cc019SAndroid Build Coastguard Worker static void scratch_buf_fini(struct igt_buf *buf)
463*d83cc019SAndroid Build Coastguard Worker {
464*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(buf->bo);
465*d83cc019SAndroid Build Coastguard Worker }
466*d83cc019SAndroid Build Coastguard Worker 
467*d83cc019SAndroid Build Coastguard Worker static void
scratch_buf_check(data_t * data,struct igt_buf * buf,struct igt_buf * ref,int x,int y)468*d83cc019SAndroid Build Coastguard Worker scratch_buf_check(data_t *data,
469*d83cc019SAndroid Build Coastguard Worker 		  struct igt_buf *buf,
470*d83cc019SAndroid Build Coastguard Worker 		  struct igt_buf *ref,
471*d83cc019SAndroid Build Coastguard Worker 		  int x, int y)
472*d83cc019SAndroid Build Coastguard Worker {
473*d83cc019SAndroid Build Coastguard Worker 	int width = igt_buf_width(buf);
474*d83cc019SAndroid Build Coastguard Worker 	uint32_t buf_val, ref_val;
475*d83cc019SAndroid Build Coastguard Worker 	uint32_t *linear;
476*d83cc019SAndroid Build Coastguard Worker 
477*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(igt_buf_width(buf), igt_buf_width(ref));
478*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(igt_buf_height(buf), igt_buf_height(ref));
479*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(buf->bo->size, ref->bo->size);
480*d83cc019SAndroid Build Coastguard Worker 
481*d83cc019SAndroid Build Coastguard Worker 	linear = linear_copy(data, buf);
482*d83cc019SAndroid Build Coastguard Worker 	buf_val = linear[y * width + x];
483*d83cc019SAndroid Build Coastguard Worker 	free(linear);
484*d83cc019SAndroid Build Coastguard Worker 
485*d83cc019SAndroid Build Coastguard Worker 	linear = linear_copy(data, ref);
486*d83cc019SAndroid Build Coastguard Worker 	ref_val = linear[y * width + x];
487*d83cc019SAndroid Build Coastguard Worker 	free(linear);
488*d83cc019SAndroid Build Coastguard Worker 
489*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(buf_val == ref_val,
490*d83cc019SAndroid Build Coastguard Worker 		     "Expected 0x%08x, found 0x%08x at (%d,%d)\n",
491*d83cc019SAndroid Build Coastguard Worker 		     ref_val, buf_val, x, y);
492*d83cc019SAndroid Build Coastguard Worker }
493*d83cc019SAndroid Build Coastguard Worker 
494*d83cc019SAndroid Build Coastguard Worker static void
scratch_buf_check_all(data_t * data,struct igt_buf * buf,struct igt_buf * ref)495*d83cc019SAndroid Build Coastguard Worker scratch_buf_check_all(data_t *data,
496*d83cc019SAndroid Build Coastguard Worker 		      struct igt_buf *buf,
497*d83cc019SAndroid Build Coastguard Worker 		      struct igt_buf *ref)
498*d83cc019SAndroid Build Coastguard Worker {
499*d83cc019SAndroid Build Coastguard Worker 	int width = igt_buf_width(buf);
500*d83cc019SAndroid Build Coastguard Worker 	int height  = igt_buf_height(buf);
501*d83cc019SAndroid Build Coastguard Worker 	uint32_t *linear_buf, *linear_ref;
502*d83cc019SAndroid Build Coastguard Worker 
503*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(igt_buf_width(buf), igt_buf_width(ref));
504*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(igt_buf_height(buf), igt_buf_height(ref));
505*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(buf->bo->size, ref->bo->size);
506*d83cc019SAndroid Build Coastguard Worker 
507*d83cc019SAndroid Build Coastguard Worker 	linear_buf = linear_copy(data, buf);
508*d83cc019SAndroid Build Coastguard Worker 	linear_ref = linear_copy(data, ref);
509*d83cc019SAndroid Build Coastguard Worker 
510*d83cc019SAndroid Build Coastguard Worker 	for (int y = 0; y < height; y++) {
511*d83cc019SAndroid Build Coastguard Worker 		for (int x = 0; x < width; x++) {
512*d83cc019SAndroid Build Coastguard Worker 			uint32_t buf_val = linear_buf[y * width + x];
513*d83cc019SAndroid Build Coastguard Worker 			uint32_t ref_val = linear_ref[y * width + x];
514*d83cc019SAndroid Build Coastguard Worker 
515*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(buf_val == ref_val,
516*d83cc019SAndroid Build Coastguard Worker 				     "Expected 0x%08x, found 0x%08x at (%d,%d)\n",
517*d83cc019SAndroid Build Coastguard Worker 				     ref_val, buf_val, x, y);
518*d83cc019SAndroid Build Coastguard Worker 		}
519*d83cc019SAndroid Build Coastguard Worker 	}
520*d83cc019SAndroid Build Coastguard Worker 
521*d83cc019SAndroid Build Coastguard Worker 	free(linear_ref);
522*d83cc019SAndroid Build Coastguard Worker 	free(linear_buf);
523*d83cc019SAndroid Build Coastguard Worker }
524*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_aux_check(data_t * data,struct igt_buf * buf)525*d83cc019SAndroid Build Coastguard Worker static void scratch_buf_aux_check(data_t *data,
526*d83cc019SAndroid Build Coastguard Worker 				  struct igt_buf *buf)
527*d83cc019SAndroid Build Coastguard Worker {
528*d83cc019SAndroid Build Coastguard Worker 	int aux_size = scratch_buf_aux_width(buf) *
529*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_aux_height(buf);
530*d83cc019SAndroid Build Coastguard Worker 	uint8_t *linear;
531*d83cc019SAndroid Build Coastguard Worker 	int i;
532*d83cc019SAndroid Build Coastguard Worker 
533*d83cc019SAndroid Build Coastguard Worker 	linear = linear_copy_aux(data, buf);
534*d83cc019SAndroid Build Coastguard Worker 
535*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < aux_size; i++) {
536*d83cc019SAndroid Build Coastguard Worker 		if (linear[i])
537*d83cc019SAndroid Build Coastguard Worker 			break;
538*d83cc019SAndroid Build Coastguard Worker 	}
539*d83cc019SAndroid Build Coastguard Worker 
540*d83cc019SAndroid Build Coastguard Worker 	free(linear);
541*d83cc019SAndroid Build Coastguard Worker 
542*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(i < aux_size,
543*d83cc019SAndroid Build Coastguard Worker 		     "Aux surface indicates that nothing was compressed\n");
544*d83cc019SAndroid Build Coastguard Worker }
545*d83cc019SAndroid Build Coastguard Worker 
test(data_t * data,uint32_t tiling,uint64_t ccs_modifier)546*d83cc019SAndroid Build Coastguard Worker static void test(data_t *data, uint32_t tiling, uint64_t ccs_modifier)
547*d83cc019SAndroid Build Coastguard Worker {
548*d83cc019SAndroid Build Coastguard Worker 	struct igt_buf dst, ccs, ref;
549*d83cc019SAndroid Build Coastguard Worker 	struct {
550*d83cc019SAndroid Build Coastguard Worker 		struct igt_buf buf;
551*d83cc019SAndroid Build Coastguard Worker 		const char *filename;
552*d83cc019SAndroid Build Coastguard Worker 		uint32_t tiling;
553*d83cc019SAndroid Build Coastguard Worker 		int x, y;
554*d83cc019SAndroid Build Coastguard Worker 	} src[] = {
555*d83cc019SAndroid Build Coastguard Worker 		{
556*d83cc019SAndroid Build Coastguard Worker 			.filename = "source-linear.png",
557*d83cc019SAndroid Build Coastguard Worker 			.tiling = I915_TILING_NONE,
558*d83cc019SAndroid Build Coastguard Worker 			.x = 1, .y = HEIGHT/2+1,
559*d83cc019SAndroid Build Coastguard Worker 		},
560*d83cc019SAndroid Build Coastguard Worker 		{
561*d83cc019SAndroid Build Coastguard Worker 			.filename = "source-x-tiled.png",
562*d83cc019SAndroid Build Coastguard Worker 			.tiling = I915_TILING_X,
563*d83cc019SAndroid Build Coastguard Worker 			.x = WIDTH/2+1, .y = HEIGHT/2+1,
564*d83cc019SAndroid Build Coastguard Worker 		},
565*d83cc019SAndroid Build Coastguard Worker 		{
566*d83cc019SAndroid Build Coastguard Worker 			.filename = "source-y-tiled.png",
567*d83cc019SAndroid Build Coastguard Worker 			.tiling = I915_TILING_Y,
568*d83cc019SAndroid Build Coastguard Worker 			.x = WIDTH/2+1, .y = 1,
569*d83cc019SAndroid Build Coastguard Worker 		},
570*d83cc019SAndroid Build Coastguard Worker 		{
571*d83cc019SAndroid Build Coastguard Worker 			.filename = "source-yf-tiled.png",
572*d83cc019SAndroid Build Coastguard Worker 			.tiling = I915_TILING_Yf,
573*d83cc019SAndroid Build Coastguard Worker 			.x = 1, .y = 1,
574*d83cc019SAndroid Build Coastguard Worker 		},
575*d83cc019SAndroid Build Coastguard Worker 	};
576*d83cc019SAndroid Build Coastguard Worker 
577*d83cc019SAndroid Build Coastguard Worker 	int opt_dump_aub = igt_aub_dump_enabled();
578*d83cc019SAndroid Build Coastguard Worker 	int num_src = ARRAY_SIZE(src);
579*d83cc019SAndroid Build Coastguard Worker 
580*d83cc019SAndroid Build Coastguard Worker 	/* no Yf before gen9 */
581*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(data->devid) < 9)
582*d83cc019SAndroid Build Coastguard Worker 		num_src--;
583*d83cc019SAndroid Build Coastguard Worker 
584*d83cc019SAndroid Build Coastguard Worker 	if (tiling == I915_TILING_Yf || ccs_modifier)
585*d83cc019SAndroid Build Coastguard Worker 		igt_require(intel_gen(data->devid) >= 9);
586*d83cc019SAndroid Build Coastguard Worker 
587*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < num_src; i++)
588*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_init(data, &src[i].buf, WIDTH, HEIGHT, src[i].tiling, false);
589*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_init(data, &dst, WIDTH, HEIGHT, tiling, false);
590*d83cc019SAndroid Build Coastguard Worker 	if (ccs_modifier)
591*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_init(data, &ccs, WIDTH, HEIGHT, ccs_modifier, true);
592*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_init(data, &ref, WIDTH, HEIGHT, I915_TILING_NONE, false);
593*d83cc019SAndroid Build Coastguard Worker 
594*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < num_src; i++)
595*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_draw_pattern(data, &src[i].buf,
596*d83cc019SAndroid Build Coastguard Worker 					 0, 0, WIDTH, HEIGHT,
597*d83cc019SAndroid Build Coastguard Worker 					 0, 0, WIDTH, HEIGHT, true);
598*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_draw_pattern(data, &dst,
599*d83cc019SAndroid Build Coastguard Worker 				 0, 0, WIDTH, HEIGHT,
600*d83cc019SAndroid Build Coastguard Worker 				 0, 0, WIDTH, HEIGHT, false);
601*d83cc019SAndroid Build Coastguard Worker 
602*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_copy(data,
603*d83cc019SAndroid Build Coastguard Worker 			 &dst, 0, 0, WIDTH, HEIGHT,
604*d83cc019SAndroid Build Coastguard Worker 			 &ref, 0, 0);
605*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < num_src; i++)
606*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_copy(data,
607*d83cc019SAndroid Build Coastguard Worker 				 &src[i].buf, WIDTH/4, HEIGHT/4, WIDTH/2-2, HEIGHT/2-2,
608*d83cc019SAndroid Build Coastguard Worker 				 &ref, src[i].x, src[i].y);
609*d83cc019SAndroid Build Coastguard Worker 
610*d83cc019SAndroid Build Coastguard Worker 	if (opt_dump_png) {
611*d83cc019SAndroid Build Coastguard Worker 		for (int i = 0; i < num_src; i++)
612*d83cc019SAndroid Build Coastguard Worker 			scratch_buf_write_to_png(data, &src[i].buf, src[i].filename);
613*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_write_to_png(data, &dst, "destination.png");
614*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_write_to_png(data, &ref, "reference.png");
615*d83cc019SAndroid Build Coastguard Worker 	}
616*d83cc019SAndroid Build Coastguard Worker 
617*d83cc019SAndroid Build Coastguard Worker 	if (opt_dump_aub) {
618*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_gem_set_aub_filename(data->bufmgr,
619*d83cc019SAndroid Build Coastguard Worker 						      "rendercopy.aub");
620*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_gem_set_aub_dump(data->bufmgr, true);
621*d83cc019SAndroid Build Coastguard Worker 	}
622*d83cc019SAndroid Build Coastguard Worker 
623*d83cc019SAndroid Build Coastguard Worker 	/* This will copy the src to the mid point of the dst buffer. Presumably
624*d83cc019SAndroid Build Coastguard Worker 	 * the out of bounds accesses will get clipped.
625*d83cc019SAndroid Build Coastguard Worker 	 * Resulting buffer should look like:
626*d83cc019SAndroid Build Coastguard Worker 	 *	  _______
627*d83cc019SAndroid Build Coastguard Worker 	 *	 |dst|dst|
628*d83cc019SAndroid Build Coastguard Worker 	 *	 |dst|src|
629*d83cc019SAndroid Build Coastguard Worker 	 *	  -------
630*d83cc019SAndroid Build Coastguard Worker 	 */
631*d83cc019SAndroid Build Coastguard Worker 	if (ccs_modifier)
632*d83cc019SAndroid Build Coastguard Worker 		data->render_copy(data->batch, NULL,
633*d83cc019SAndroid Build Coastguard Worker 				  &dst, 0, 0, WIDTH, HEIGHT,
634*d83cc019SAndroid Build Coastguard Worker 				  &ccs, 0, 0);
635*d83cc019SAndroid Build Coastguard Worker 
636*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < num_src; i++)
637*d83cc019SAndroid Build Coastguard Worker 		data->render_copy(data->batch, NULL,
638*d83cc019SAndroid Build Coastguard Worker 				  &src[i].buf, WIDTH/4, HEIGHT/4, WIDTH/2-2, HEIGHT/2-2,
639*d83cc019SAndroid Build Coastguard Worker 				  ccs_modifier ? &ccs : &dst, src[i].x, src[i].y);
640*d83cc019SAndroid Build Coastguard Worker 
641*d83cc019SAndroid Build Coastguard Worker 	if (ccs_modifier)
642*d83cc019SAndroid Build Coastguard Worker 		data->render_copy(data->batch, NULL,
643*d83cc019SAndroid Build Coastguard Worker 				  &ccs, 0, 0, WIDTH, HEIGHT,
644*d83cc019SAndroid Build Coastguard Worker 				  &dst, 0, 0);
645*d83cc019SAndroid Build Coastguard Worker 
646*d83cc019SAndroid Build Coastguard Worker 	if (opt_dump_png){
647*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_write_to_png(data, &dst, "result.png");
648*d83cc019SAndroid Build Coastguard Worker 		if (ccs_modifier) {
649*d83cc019SAndroid Build Coastguard Worker 			scratch_buf_write_to_png(data, &ccs, "compressed.png");
650*d83cc019SAndroid Build Coastguard Worker 			scratch_buf_aux_write_to_png(data, &ccs, "compressed-aux.png");
651*d83cc019SAndroid Build Coastguard Worker 		}
652*d83cc019SAndroid Build Coastguard Worker 	}
653*d83cc019SAndroid Build Coastguard Worker 
654*d83cc019SAndroid Build Coastguard Worker 	if (opt_dump_aub) {
655*d83cc019SAndroid Build Coastguard Worker 		drm_intel_gem_bo_aub_dump_bmp(dst.bo,
656*d83cc019SAndroid Build Coastguard Worker 					      0, 0, igt_buf_width(&dst),
657*d83cc019SAndroid Build Coastguard Worker 					      igt_buf_height(&dst),
658*d83cc019SAndroid Build Coastguard Worker 					      AUB_DUMP_BMP_FORMAT_ARGB_8888,
659*d83cc019SAndroid Build Coastguard Worker 					      dst.stride, 0);
660*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_gem_set_aub_dump(data->bufmgr, false);
661*d83cc019SAndroid Build Coastguard Worker 	} else if (check_all_pixels) {
662*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_check_all(data, &dst, &ref);
663*d83cc019SAndroid Build Coastguard Worker 	} else {
664*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_check(data, &dst, &ref, 10, 10);
665*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_check(data, &dst, &ref, WIDTH - 10, HEIGHT - 10);
666*d83cc019SAndroid Build Coastguard Worker 	}
667*d83cc019SAndroid Build Coastguard Worker 
668*d83cc019SAndroid Build Coastguard Worker 	if (ccs_modifier)
669*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_aux_check(data, &ccs);
670*d83cc019SAndroid Build Coastguard Worker 
671*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_fini(&ref);
672*d83cc019SAndroid Build Coastguard Worker 	if (ccs_modifier)
673*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_fini(&ccs);
674*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_fini(&dst);
675*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < num_src; i++)
676*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_fini(&src[i].buf);
677*d83cc019SAndroid Build Coastguard Worker }
678*d83cc019SAndroid Build Coastguard Worker 
opt_handler(int opt,int opt_index,void * data)679*d83cc019SAndroid Build Coastguard Worker static int opt_handler(int opt, int opt_index, void *data)
680*d83cc019SAndroid Build Coastguard Worker {
681*d83cc019SAndroid Build Coastguard Worker 	switch (opt) {
682*d83cc019SAndroid Build Coastguard Worker 	case 'd':
683*d83cc019SAndroid Build Coastguard Worker 		opt_dump_png = true;
684*d83cc019SAndroid Build Coastguard Worker 		break;
685*d83cc019SAndroid Build Coastguard Worker 	case 'a':
686*d83cc019SAndroid Build Coastguard Worker 		check_all_pixels = true;
687*d83cc019SAndroid Build Coastguard Worker 		break;
688*d83cc019SAndroid Build Coastguard Worker 	default:
689*d83cc019SAndroid Build Coastguard Worker 		return IGT_OPT_HANDLER_ERROR;
690*d83cc019SAndroid Build Coastguard Worker 	}
691*d83cc019SAndroid Build Coastguard Worker 
692*d83cc019SAndroid Build Coastguard Worker 	return IGT_OPT_HANDLER_SUCCESS;
693*d83cc019SAndroid Build Coastguard Worker }
694*d83cc019SAndroid Build Coastguard Worker 
695*d83cc019SAndroid Build Coastguard Worker const char *help_str =
696*d83cc019SAndroid Build Coastguard Worker 	"  -d\tDump PNG\n"
697*d83cc019SAndroid Build Coastguard Worker 	"  -a\tCheck all pixels\n"
698*d83cc019SAndroid Build Coastguard Worker 	;
699*d83cc019SAndroid Build Coastguard Worker 
700*d83cc019SAndroid Build Coastguard Worker igt_main_args("da", NULL, help_str, opt_handler, NULL)
701*d83cc019SAndroid Build Coastguard Worker {
702*d83cc019SAndroid Build Coastguard Worker 	data_t data = {0, };
703*d83cc019SAndroid Build Coastguard Worker 
704*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
705*d83cc019SAndroid Build Coastguard Worker 		data.drm_fd = drm_open_driver_render(DRIVER_INTEL);
706*d83cc019SAndroid Build Coastguard Worker 		data.devid = intel_get_drm_devid(data.drm_fd);
707*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(data.drm_fd);
708*d83cc019SAndroid Build Coastguard Worker 
709*d83cc019SAndroid Build Coastguard Worker 		data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);
710*d83cc019SAndroid Build Coastguard Worker 		igt_assert(data.bufmgr);
711*d83cc019SAndroid Build Coastguard Worker 
712*d83cc019SAndroid Build Coastguard Worker 		data.render_copy = igt_get_render_copyfunc(data.devid);
713*d83cc019SAndroid Build Coastguard Worker 		igt_require_f(data.render_copy,
714*d83cc019SAndroid Build Coastguard Worker 			      "no render-copy function\n");
715*d83cc019SAndroid Build Coastguard Worker 
716*d83cc019SAndroid Build Coastguard Worker 		data.batch = intel_batchbuffer_alloc(data.bufmgr, data.devid);
717*d83cc019SAndroid Build Coastguard Worker 		igt_assert(data.batch);
718*d83cc019SAndroid Build Coastguard Worker 	}
719*d83cc019SAndroid Build Coastguard Worker 
720*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("linear")
721*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_NONE, 0);
722*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("x-tiled")
723*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_X, 0);
724*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("y-tiled")
725*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_Y, 0);
726*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("yf-tiled")
727*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_Yf, 0);
728*d83cc019SAndroid Build Coastguard Worker 
729*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("y-tiled-ccs-to-linear")
730*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_NONE, I915_TILING_Y);
731*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("y-tiled-ccs-to-x-tiled")
732*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_X, I915_TILING_Y);
733*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("y-tiled-ccs-to-y-tiled")
734*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_Y, I915_TILING_Y);
735*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("y-tiled-ccs-to-yf-tiled")
736*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_Yf, I915_TILING_Y);
737*d83cc019SAndroid Build Coastguard Worker 
738*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("yf-tiled-ccs-to-linear")
739*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_NONE, I915_TILING_Yf);
740*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("yf-tiled-ccs-to-x-tiled")
741*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_X, I915_TILING_Yf);
742*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("yf-tiled-ccs-to-y-tiled")
743*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_Y, I915_TILING_Yf);
744*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("yf-tiled-ccs-to-yf-tiled")
745*d83cc019SAndroid Build Coastguard Worker 		test(&data, I915_TILING_Yf, I915_TILING_Yf);
746*d83cc019SAndroid Build Coastguard Worker 
747*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
748*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_free(data.batch);
749*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_destroy(data.bufmgr);
750*d83cc019SAndroid Build Coastguard Worker 	}
751*d83cc019SAndroid Build Coastguard Worker }
752