1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2015 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 */
24*d83cc019SAndroid Build Coastguard Worker
25*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
26*d83cc019SAndroid Build Coastguard Worker
27*d83cc019SAndroid Build Coastguard Worker #include "igt_draw.h"
28*d83cc019SAndroid Build Coastguard Worker
29*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
30*d83cc019SAndroid Build Coastguard Worker #include "intel_batchbuffer.h"
31*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
32*d83cc019SAndroid Build Coastguard Worker #include "igt_core.h"
33*d83cc019SAndroid Build Coastguard Worker #include "igt_fb.h"
34*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
35*d83cc019SAndroid Build Coastguard Worker #include "i830_reg.h"
36*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_mman.h"
37*d83cc019SAndroid Build Coastguard Worker
38*d83cc019SAndroid Build Coastguard Worker #ifndef PAGE_ALIGN
39*d83cc019SAndroid Build Coastguard Worker #ifndef PAGE_SIZE
40*d83cc019SAndroid Build Coastguard Worker #define PAGE_SIZE 4096
41*d83cc019SAndroid Build Coastguard Worker #endif
42*d83cc019SAndroid Build Coastguard Worker #define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
43*d83cc019SAndroid Build Coastguard Worker #endif
44*d83cc019SAndroid Build Coastguard Worker
45*d83cc019SAndroid Build Coastguard Worker /**
46*d83cc019SAndroid Build Coastguard Worker * SECTION:igt_draw
47*d83cc019SAndroid Build Coastguard Worker * @short_description: drawing helpers for tests
48*d83cc019SAndroid Build Coastguard Worker * @title: Draw
49*d83cc019SAndroid Build Coastguard Worker * @include: igt.h
50*d83cc019SAndroid Build Coastguard Worker *
51*d83cc019SAndroid Build Coastguard Worker * This library contains some functions for drawing rectangles on buffers using
52*d83cc019SAndroid Build Coastguard Worker * the many different drawing methods we have. It also contains some wrappers
53*d83cc019SAndroid Build Coastguard Worker * that make the process easier if you have the abstract objects in hand.
54*d83cc019SAndroid Build Coastguard Worker *
55*d83cc019SAndroid Build Coastguard Worker * This library only claims support for some pixel formats, but adding support
56*d83cc019SAndroid Build Coastguard Worker * for more formats should be faily easy now that we support both 16bpp and
57*d83cc019SAndroid Build Coastguard Worker * 32bpp. If you need a new pixel format, make sure you update both this file
58*d83cc019SAndroid Build Coastguard Worker * and tests/kms_draw_crc.c.
59*d83cc019SAndroid Build Coastguard Worker */
60*d83cc019SAndroid Build Coastguard Worker
61*d83cc019SAndroid Build Coastguard Worker /* Some internal data structures to avoid having to pass tons of parameters
62*d83cc019SAndroid Build Coastguard Worker * around everything. */
63*d83cc019SAndroid Build Coastguard Worker struct cmd_data {
64*d83cc019SAndroid Build Coastguard Worker drm_intel_bufmgr *bufmgr;
65*d83cc019SAndroid Build Coastguard Worker drm_intel_context *context;
66*d83cc019SAndroid Build Coastguard Worker };
67*d83cc019SAndroid Build Coastguard Worker
68*d83cc019SAndroid Build Coastguard Worker struct buf_data {
69*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
70*d83cc019SAndroid Build Coastguard Worker uint32_t size;
71*d83cc019SAndroid Build Coastguard Worker uint32_t stride;
72*d83cc019SAndroid Build Coastguard Worker int bpp;
73*d83cc019SAndroid Build Coastguard Worker };
74*d83cc019SAndroid Build Coastguard Worker
75*d83cc019SAndroid Build Coastguard Worker struct rect {
76*d83cc019SAndroid Build Coastguard Worker int x;
77*d83cc019SAndroid Build Coastguard Worker int y;
78*d83cc019SAndroid Build Coastguard Worker int w;
79*d83cc019SAndroid Build Coastguard Worker int h;
80*d83cc019SAndroid Build Coastguard Worker };
81*d83cc019SAndroid Build Coastguard Worker
82*d83cc019SAndroid Build Coastguard Worker /**
83*d83cc019SAndroid Build Coastguard Worker * igt_draw_get_method_name:
84*d83cc019SAndroid Build Coastguard Worker * @method: draw method
85*d83cc019SAndroid Build Coastguard Worker *
86*d83cc019SAndroid Build Coastguard Worker * Simple function to transform the enum into a string. Useful when naming
87*d83cc019SAndroid Build Coastguard Worker * subtests and printing debug messages.
88*d83cc019SAndroid Build Coastguard Worker */
igt_draw_get_method_name(enum igt_draw_method method)89*d83cc019SAndroid Build Coastguard Worker const char *igt_draw_get_method_name(enum igt_draw_method method)
90*d83cc019SAndroid Build Coastguard Worker {
91*d83cc019SAndroid Build Coastguard Worker switch (method) {
92*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_MMAP_CPU:
93*d83cc019SAndroid Build Coastguard Worker return "mmap-cpu";
94*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_MMAP_GTT:
95*d83cc019SAndroid Build Coastguard Worker return "mmap-gtt";
96*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_MMAP_WC:
97*d83cc019SAndroid Build Coastguard Worker return "mmap-wc";
98*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_PWRITE:
99*d83cc019SAndroid Build Coastguard Worker return "pwrite";
100*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_BLT:
101*d83cc019SAndroid Build Coastguard Worker return "blt";
102*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_RENDER:
103*d83cc019SAndroid Build Coastguard Worker return "render";
104*d83cc019SAndroid Build Coastguard Worker default:
105*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
106*d83cc019SAndroid Build Coastguard Worker }
107*d83cc019SAndroid Build Coastguard Worker }
108*d83cc019SAndroid Build Coastguard Worker
swizzle_bit(unsigned int bit,unsigned long offset)109*d83cc019SAndroid Build Coastguard Worker static unsigned long swizzle_bit(unsigned int bit, unsigned long offset)
110*d83cc019SAndroid Build Coastguard Worker {
111*d83cc019SAndroid Build Coastguard Worker return (offset & (1ul << bit)) >> (bit - 6);
112*d83cc019SAndroid Build Coastguard Worker }
113*d83cc019SAndroid Build Coastguard Worker
swizzle_addr(unsigned long addr,int swizzle)114*d83cc019SAndroid Build Coastguard Worker static int swizzle_addr(unsigned long addr, int swizzle)
115*d83cc019SAndroid Build Coastguard Worker {
116*d83cc019SAndroid Build Coastguard Worker switch (swizzle) {
117*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_NONE:
118*d83cc019SAndroid Build Coastguard Worker return addr;
119*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_9:
120*d83cc019SAndroid Build Coastguard Worker return addr ^ swizzle_bit(9, addr);
121*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_9_10:
122*d83cc019SAndroid Build Coastguard Worker return addr ^ swizzle_bit(9, addr) ^ swizzle_bit(10, addr);
123*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_9_11:
124*d83cc019SAndroid Build Coastguard Worker return addr ^ swizzle_bit(9, addr) ^ swizzle_bit(11, addr);
125*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_9_10_11:
126*d83cc019SAndroid Build Coastguard Worker return (addr ^
127*d83cc019SAndroid Build Coastguard Worker swizzle_bit(9, addr) ^
128*d83cc019SAndroid Build Coastguard Worker swizzle_bit(10, addr) ^
129*d83cc019SAndroid Build Coastguard Worker swizzle_bit(11, addr));
130*d83cc019SAndroid Build Coastguard Worker
131*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_UNKNOWN:
132*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_9_17:
133*d83cc019SAndroid Build Coastguard Worker case I915_BIT_6_SWIZZLE_9_10_17:
134*d83cc019SAndroid Build Coastguard Worker default:
135*d83cc019SAndroid Build Coastguard Worker /* If we hit this case, we need to implement support for the
136*d83cc019SAndroid Build Coastguard Worker * appropriate swizzling method. */
137*d83cc019SAndroid Build Coastguard Worker igt_require(false);
138*d83cc019SAndroid Build Coastguard Worker return addr;
139*d83cc019SAndroid Build Coastguard Worker }
140*d83cc019SAndroid Build Coastguard Worker }
141*d83cc019SAndroid Build Coastguard Worker
tile(int x,int y,uint32_t x_tile_size,uint32_t y_tile_size,uint32_t line_size,bool xmajor)142*d83cc019SAndroid Build Coastguard Worker static int tile(int x, int y, uint32_t x_tile_size, uint32_t y_tile_size,
143*d83cc019SAndroid Build Coastguard Worker uint32_t line_size, bool xmajor)
144*d83cc019SAndroid Build Coastguard Worker {
145*d83cc019SAndroid Build Coastguard Worker int tile_size, tiles_per_line, x_tile_n, y_tile_n, tile_off, pos;
146*d83cc019SAndroid Build Coastguard Worker int tile_n, x_tile_off, y_tile_off;
147*d83cc019SAndroid Build Coastguard Worker
148*d83cc019SAndroid Build Coastguard Worker tiles_per_line = line_size / x_tile_size;
149*d83cc019SAndroid Build Coastguard Worker tile_size = x_tile_size * y_tile_size;
150*d83cc019SAndroid Build Coastguard Worker
151*d83cc019SAndroid Build Coastguard Worker x_tile_n = x / x_tile_size;
152*d83cc019SAndroid Build Coastguard Worker y_tile_n = y / y_tile_size;
153*d83cc019SAndroid Build Coastguard Worker tile_n = y_tile_n * tiles_per_line + x_tile_n;
154*d83cc019SAndroid Build Coastguard Worker
155*d83cc019SAndroid Build Coastguard Worker x_tile_off = x % x_tile_size;
156*d83cc019SAndroid Build Coastguard Worker y_tile_off = y % y_tile_size;
157*d83cc019SAndroid Build Coastguard Worker
158*d83cc019SAndroid Build Coastguard Worker if (xmajor)
159*d83cc019SAndroid Build Coastguard Worker tile_off = y_tile_off * x_tile_size + x_tile_off;
160*d83cc019SAndroid Build Coastguard Worker else
161*d83cc019SAndroid Build Coastguard Worker tile_off = x_tile_off * y_tile_size + y_tile_off;
162*d83cc019SAndroid Build Coastguard Worker
163*d83cc019SAndroid Build Coastguard Worker pos = tile_n * tile_size + tile_off;
164*d83cc019SAndroid Build Coastguard Worker
165*d83cc019SAndroid Build Coastguard Worker return pos;
166*d83cc019SAndroid Build Coastguard Worker }
167*d83cc019SAndroid Build Coastguard Worker
untile(int tiled_pos,int x_tile_size,int y_tile_size,uint32_t line_size,bool xmajor,int * x,int * y)168*d83cc019SAndroid Build Coastguard Worker static void untile(int tiled_pos, int x_tile_size, int y_tile_size,
169*d83cc019SAndroid Build Coastguard Worker uint32_t line_size, bool xmajor, int *x, int *y)
170*d83cc019SAndroid Build Coastguard Worker {
171*d83cc019SAndroid Build Coastguard Worker int tile_n, tile_off, tiles_per_line;
172*d83cc019SAndroid Build Coastguard Worker int x_tile_off, y_tile_off;
173*d83cc019SAndroid Build Coastguard Worker int x_tile_n, y_tile_n;
174*d83cc019SAndroid Build Coastguard Worker int tile_size;
175*d83cc019SAndroid Build Coastguard Worker
176*d83cc019SAndroid Build Coastguard Worker tile_size = x_tile_size * y_tile_size;
177*d83cc019SAndroid Build Coastguard Worker tiles_per_line = line_size / x_tile_size;
178*d83cc019SAndroid Build Coastguard Worker
179*d83cc019SAndroid Build Coastguard Worker tile_n = tiled_pos / tile_size;
180*d83cc019SAndroid Build Coastguard Worker tile_off = tiled_pos % tile_size;
181*d83cc019SAndroid Build Coastguard Worker
182*d83cc019SAndroid Build Coastguard Worker if (xmajor) {
183*d83cc019SAndroid Build Coastguard Worker y_tile_off = tile_off / x_tile_size;
184*d83cc019SAndroid Build Coastguard Worker x_tile_off = tile_off % x_tile_size;
185*d83cc019SAndroid Build Coastguard Worker } else {
186*d83cc019SAndroid Build Coastguard Worker y_tile_off = tile_off % y_tile_size;
187*d83cc019SAndroid Build Coastguard Worker x_tile_off = tile_off / y_tile_size;
188*d83cc019SAndroid Build Coastguard Worker }
189*d83cc019SAndroid Build Coastguard Worker
190*d83cc019SAndroid Build Coastguard Worker x_tile_n = tile_n % tiles_per_line;
191*d83cc019SAndroid Build Coastguard Worker y_tile_n = tile_n / tiles_per_line;
192*d83cc019SAndroid Build Coastguard Worker
193*d83cc019SAndroid Build Coastguard Worker *x = (x_tile_n * x_tile_size + x_tile_off);
194*d83cc019SAndroid Build Coastguard Worker *y = y_tile_n * y_tile_size + y_tile_off;
195*d83cc019SAndroid Build Coastguard Worker }
196*d83cc019SAndroid Build Coastguard Worker
linear_x_y_to_xtiled_pos(int x,int y,uint32_t stride,int swizzle,int bpp)197*d83cc019SAndroid Build Coastguard Worker static int linear_x_y_to_xtiled_pos(int x, int y, uint32_t stride, int swizzle,
198*d83cc019SAndroid Build Coastguard Worker int bpp)
199*d83cc019SAndroid Build Coastguard Worker {
200*d83cc019SAndroid Build Coastguard Worker int pos;
201*d83cc019SAndroid Build Coastguard Worker int pixel_size = bpp / 8;
202*d83cc019SAndroid Build Coastguard Worker
203*d83cc019SAndroid Build Coastguard Worker x *= pixel_size;
204*d83cc019SAndroid Build Coastguard Worker pos = tile(x, y, 512, 8, stride, true);
205*d83cc019SAndroid Build Coastguard Worker pos = swizzle_addr(pos, swizzle);
206*d83cc019SAndroid Build Coastguard Worker return pos / pixel_size;
207*d83cc019SAndroid Build Coastguard Worker }
208*d83cc019SAndroid Build Coastguard Worker
linear_x_y_to_ytiled_pos(int x,int y,uint32_t stride,int swizzle,int bpp)209*d83cc019SAndroid Build Coastguard Worker static int linear_x_y_to_ytiled_pos(int x, int y, uint32_t stride, int swizzle,
210*d83cc019SAndroid Build Coastguard Worker int bpp)
211*d83cc019SAndroid Build Coastguard Worker {
212*d83cc019SAndroid Build Coastguard Worker int ow_tile_n, pos;
213*d83cc019SAndroid Build Coastguard Worker int ow_size = 16;
214*d83cc019SAndroid Build Coastguard Worker int pixel_size = bpp / 8;
215*d83cc019SAndroid Build Coastguard Worker
216*d83cc019SAndroid Build Coastguard Worker /* We have an Y tiling of OWords, so use the tile() function to get the
217*d83cc019SAndroid Build Coastguard Worker * OW number, then adjust to the fact that the OW may have more than one
218*d83cc019SAndroid Build Coastguard Worker * pixel. */
219*d83cc019SAndroid Build Coastguard Worker x *= pixel_size;
220*d83cc019SAndroid Build Coastguard Worker ow_tile_n = tile(x / ow_size, y, 128 / ow_size, 32,
221*d83cc019SAndroid Build Coastguard Worker stride / ow_size, false);
222*d83cc019SAndroid Build Coastguard Worker pos = ow_tile_n * ow_size + (x % ow_size);
223*d83cc019SAndroid Build Coastguard Worker pos = swizzle_addr(pos, swizzle);
224*d83cc019SAndroid Build Coastguard Worker return pos / pixel_size;
225*d83cc019SAndroid Build Coastguard Worker }
226*d83cc019SAndroid Build Coastguard Worker
xtiled_pos_to_x_y_linear(int tiled_pos,uint32_t stride,int swizzle,int bpp,int * x,int * y)227*d83cc019SAndroid Build Coastguard Worker static void xtiled_pos_to_x_y_linear(int tiled_pos, uint32_t stride,
228*d83cc019SAndroid Build Coastguard Worker int swizzle, int bpp, int *x, int *y)
229*d83cc019SAndroid Build Coastguard Worker {
230*d83cc019SAndroid Build Coastguard Worker int pixel_size = bpp / 8;
231*d83cc019SAndroid Build Coastguard Worker
232*d83cc019SAndroid Build Coastguard Worker tiled_pos = swizzle_addr(tiled_pos, swizzle);
233*d83cc019SAndroid Build Coastguard Worker
234*d83cc019SAndroid Build Coastguard Worker untile(tiled_pos, 512, 8, stride, true, x, y);
235*d83cc019SAndroid Build Coastguard Worker *x /= pixel_size;
236*d83cc019SAndroid Build Coastguard Worker }
237*d83cc019SAndroid Build Coastguard Worker
ytiled_pos_to_x_y_linear(int tiled_pos,uint32_t stride,int swizzle,int bpp,int * x,int * y)238*d83cc019SAndroid Build Coastguard Worker static void ytiled_pos_to_x_y_linear(int tiled_pos, uint32_t stride,
239*d83cc019SAndroid Build Coastguard Worker int swizzle, int bpp, int *x, int *y)
240*d83cc019SAndroid Build Coastguard Worker {
241*d83cc019SAndroid Build Coastguard Worker int ow_tile_n;
242*d83cc019SAndroid Build Coastguard Worker int ow_size = 16;
243*d83cc019SAndroid Build Coastguard Worker int pixel_size = bpp / 8;
244*d83cc019SAndroid Build Coastguard Worker
245*d83cc019SAndroid Build Coastguard Worker tiled_pos = swizzle_addr(tiled_pos, swizzle);
246*d83cc019SAndroid Build Coastguard Worker
247*d83cc019SAndroid Build Coastguard Worker ow_tile_n = tiled_pos / ow_size;
248*d83cc019SAndroid Build Coastguard Worker untile(ow_tile_n, 128 / ow_size, 32, stride / ow_size, false, x, y);
249*d83cc019SAndroid Build Coastguard Worker *x *= ow_size;
250*d83cc019SAndroid Build Coastguard Worker *x += tiled_pos % ow_size;
251*d83cc019SAndroid Build Coastguard Worker *x /= pixel_size;
252*d83cc019SAndroid Build Coastguard Worker }
253*d83cc019SAndroid Build Coastguard Worker
set_pixel(void * _ptr,int index,uint32_t color,int bpp)254*d83cc019SAndroid Build Coastguard Worker static void set_pixel(void *_ptr, int index, uint32_t color, int bpp)
255*d83cc019SAndroid Build Coastguard Worker {
256*d83cc019SAndroid Build Coastguard Worker if (bpp == 16) {
257*d83cc019SAndroid Build Coastguard Worker uint16_t *ptr = _ptr;
258*d83cc019SAndroid Build Coastguard Worker ptr[index] = color;
259*d83cc019SAndroid Build Coastguard Worker } else if (bpp == 32) {
260*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr = _ptr;
261*d83cc019SAndroid Build Coastguard Worker ptr[index] = color;
262*d83cc019SAndroid Build Coastguard Worker } else {
263*d83cc019SAndroid Build Coastguard Worker igt_assert_f(false, "bpp: %d\n", bpp);
264*d83cc019SAndroid Build Coastguard Worker }
265*d83cc019SAndroid Build Coastguard Worker }
266*d83cc019SAndroid Build Coastguard Worker
switch_blt_tiling(struct intel_batchbuffer * batch,uint32_t tiling,bool on)267*d83cc019SAndroid Build Coastguard Worker static void switch_blt_tiling(struct intel_batchbuffer *batch, uint32_t tiling,
268*d83cc019SAndroid Build Coastguard Worker bool on)
269*d83cc019SAndroid Build Coastguard Worker {
270*d83cc019SAndroid Build Coastguard Worker uint32_t bcs_swctrl;
271*d83cc019SAndroid Build Coastguard Worker
272*d83cc019SAndroid Build Coastguard Worker /* Default is X-tile */
273*d83cc019SAndroid Build Coastguard Worker if (tiling != I915_TILING_Y)
274*d83cc019SAndroid Build Coastguard Worker return;
275*d83cc019SAndroid Build Coastguard Worker
276*d83cc019SAndroid Build Coastguard Worker bcs_swctrl = (0x3 << 16) | (on ? 0x3 : 0x0);
277*d83cc019SAndroid Build Coastguard Worker
278*d83cc019SAndroid Build Coastguard Worker /* To change the tile register, insert an MI_FLUSH_DW followed by an
279*d83cc019SAndroid Build Coastguard Worker * MI_LOAD_REGISTER_IMM
280*d83cc019SAndroid Build Coastguard Worker */
281*d83cc019SAndroid Build Coastguard Worker BEGIN_BATCH(4, 0);
282*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(MI_FLUSH_DW | 2);
283*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(0x0);
284*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(0x0);
285*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(0x0);
286*d83cc019SAndroid Build Coastguard Worker ADVANCE_BATCH();
287*d83cc019SAndroid Build Coastguard Worker
288*d83cc019SAndroid Build Coastguard Worker BEGIN_BATCH(4, 0);
289*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(MI_LOAD_REGISTER_IMM);
290*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(0x22200); /* BCS_SWCTRL */
291*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(bcs_swctrl);
292*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(MI_NOOP);
293*d83cc019SAndroid Build Coastguard Worker ADVANCE_BATCH();
294*d83cc019SAndroid Build Coastguard Worker }
295*d83cc019SAndroid Build Coastguard Worker
draw_rect_ptr_linear(void * ptr,uint32_t stride,struct rect * rect,uint32_t color,int bpp)296*d83cc019SAndroid Build Coastguard Worker static void draw_rect_ptr_linear(void *ptr, uint32_t stride,
297*d83cc019SAndroid Build Coastguard Worker struct rect *rect, uint32_t color, int bpp)
298*d83cc019SAndroid Build Coastguard Worker {
299*d83cc019SAndroid Build Coastguard Worker int x, y, line_begin;
300*d83cc019SAndroid Build Coastguard Worker
301*d83cc019SAndroid Build Coastguard Worker for (y = rect->y; y < rect->y + rect->h; y++) {
302*d83cc019SAndroid Build Coastguard Worker line_begin = y * stride / (bpp / 8);
303*d83cc019SAndroid Build Coastguard Worker for (x = rect->x; x < rect->x + rect->w; x++)
304*d83cc019SAndroid Build Coastguard Worker set_pixel(ptr, line_begin + x, color, bpp);
305*d83cc019SAndroid Build Coastguard Worker }
306*d83cc019SAndroid Build Coastguard Worker }
307*d83cc019SAndroid Build Coastguard Worker
draw_rect_ptr_tiled(void * ptr,uint32_t stride,uint32_t tiling,int swizzle,struct rect * rect,uint32_t color,int bpp)308*d83cc019SAndroid Build Coastguard Worker static void draw_rect_ptr_tiled(void *ptr, uint32_t stride, uint32_t tiling,
309*d83cc019SAndroid Build Coastguard Worker int swizzle, struct rect *rect, uint32_t color,
310*d83cc019SAndroid Build Coastguard Worker int bpp)
311*d83cc019SAndroid Build Coastguard Worker {
312*d83cc019SAndroid Build Coastguard Worker int x, y, pos;
313*d83cc019SAndroid Build Coastguard Worker
314*d83cc019SAndroid Build Coastguard Worker for (y = rect->y; y < rect->y + rect->h; y++) {
315*d83cc019SAndroid Build Coastguard Worker for (x = rect->x; x < rect->x + rect->w; x++) {
316*d83cc019SAndroid Build Coastguard Worker switch (tiling) {
317*d83cc019SAndroid Build Coastguard Worker case I915_TILING_X:
318*d83cc019SAndroid Build Coastguard Worker pos = linear_x_y_to_xtiled_pos(x, y, stride,
319*d83cc019SAndroid Build Coastguard Worker swizzle, bpp);
320*d83cc019SAndroid Build Coastguard Worker break;
321*d83cc019SAndroid Build Coastguard Worker case I915_TILING_Y:
322*d83cc019SAndroid Build Coastguard Worker pos = linear_x_y_to_ytiled_pos(x, y, stride,
323*d83cc019SAndroid Build Coastguard Worker swizzle, bpp);
324*d83cc019SAndroid Build Coastguard Worker break;
325*d83cc019SAndroid Build Coastguard Worker default:
326*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
327*d83cc019SAndroid Build Coastguard Worker }
328*d83cc019SAndroid Build Coastguard Worker set_pixel(ptr, pos, color, bpp);
329*d83cc019SAndroid Build Coastguard Worker }
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker }
332*d83cc019SAndroid Build Coastguard Worker
draw_rect_mmap_cpu(int fd,struct buf_data * buf,struct rect * rect,uint32_t color)333*d83cc019SAndroid Build Coastguard Worker static void draw_rect_mmap_cpu(int fd, struct buf_data *buf, struct rect *rect,
334*d83cc019SAndroid Build Coastguard Worker uint32_t color)
335*d83cc019SAndroid Build Coastguard Worker {
336*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr;
337*d83cc019SAndroid Build Coastguard Worker uint32_t tiling, swizzle;
338*d83cc019SAndroid Build Coastguard Worker
339*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, buf->handle, I915_GEM_DOMAIN_CPU,
340*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU);
341*d83cc019SAndroid Build Coastguard Worker igt_require(gem_get_tiling(fd, buf->handle, &tiling, &swizzle));
342*d83cc019SAndroid Build Coastguard Worker
343*d83cc019SAndroid Build Coastguard Worker /* We didn't implement suport for the older tiling methods yet. */
344*d83cc019SAndroid Build Coastguard Worker if (tiling != I915_TILING_NONE)
345*d83cc019SAndroid Build Coastguard Worker igt_require(intel_gen(intel_get_drm_devid(fd)) >= 5);
346*d83cc019SAndroid Build Coastguard Worker
347*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__cpu(fd, buf->handle, 0, PAGE_ALIGN(buf->size), 0);
348*d83cc019SAndroid Build Coastguard Worker
349*d83cc019SAndroid Build Coastguard Worker switch (tiling) {
350*d83cc019SAndroid Build Coastguard Worker case I915_TILING_NONE:
351*d83cc019SAndroid Build Coastguard Worker draw_rect_ptr_linear(ptr, buf->stride, rect, color, buf->bpp);
352*d83cc019SAndroid Build Coastguard Worker break;
353*d83cc019SAndroid Build Coastguard Worker case I915_TILING_X:
354*d83cc019SAndroid Build Coastguard Worker case I915_TILING_Y:
355*d83cc019SAndroid Build Coastguard Worker draw_rect_ptr_tiled(ptr, buf->stride, tiling, swizzle, rect,
356*d83cc019SAndroid Build Coastguard Worker color, buf->bpp);
357*d83cc019SAndroid Build Coastguard Worker break;
358*d83cc019SAndroid Build Coastguard Worker default:
359*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
360*d83cc019SAndroid Build Coastguard Worker break;
361*d83cc019SAndroid Build Coastguard Worker }
362*d83cc019SAndroid Build Coastguard Worker
363*d83cc019SAndroid Build Coastguard Worker gem_sw_finish(fd, buf->handle);
364*d83cc019SAndroid Build Coastguard Worker
365*d83cc019SAndroid Build Coastguard Worker igt_assert(gem_munmap(ptr, buf->size) == 0);
366*d83cc019SAndroid Build Coastguard Worker }
367*d83cc019SAndroid Build Coastguard Worker
draw_rect_mmap_gtt(int fd,struct buf_data * buf,struct rect * rect,uint32_t color)368*d83cc019SAndroid Build Coastguard Worker static void draw_rect_mmap_gtt(int fd, struct buf_data *buf, struct rect *rect,
369*d83cc019SAndroid Build Coastguard Worker uint32_t color)
370*d83cc019SAndroid Build Coastguard Worker {
371*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr;
372*d83cc019SAndroid Build Coastguard Worker
373*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, buf->handle, I915_GEM_DOMAIN_GTT,
374*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT);
375*d83cc019SAndroid Build Coastguard Worker
376*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__gtt(fd, buf->handle, PAGE_ALIGN(buf->size),
377*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
378*d83cc019SAndroid Build Coastguard Worker
379*d83cc019SAndroid Build Coastguard Worker draw_rect_ptr_linear(ptr, buf->stride, rect, color, buf->bpp);
380*d83cc019SAndroid Build Coastguard Worker
381*d83cc019SAndroid Build Coastguard Worker igt_assert(gem_munmap(ptr, buf->size) == 0);
382*d83cc019SAndroid Build Coastguard Worker }
383*d83cc019SAndroid Build Coastguard Worker
draw_rect_mmap_wc(int fd,struct buf_data * buf,struct rect * rect,uint32_t color)384*d83cc019SAndroid Build Coastguard Worker static void draw_rect_mmap_wc(int fd, struct buf_data *buf, struct rect *rect,
385*d83cc019SAndroid Build Coastguard Worker uint32_t color)
386*d83cc019SAndroid Build Coastguard Worker {
387*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr;
388*d83cc019SAndroid Build Coastguard Worker uint32_t tiling, swizzle;
389*d83cc019SAndroid Build Coastguard Worker
390*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, buf->handle, I915_GEM_DOMAIN_GTT,
391*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT);
392*d83cc019SAndroid Build Coastguard Worker igt_require(gem_get_tiling(fd, buf->handle, &tiling, &swizzle));
393*d83cc019SAndroid Build Coastguard Worker
394*d83cc019SAndroid Build Coastguard Worker /* We didn't implement suport for the older tiling methods yet. */
395*d83cc019SAndroid Build Coastguard Worker if (tiling != I915_TILING_NONE)
396*d83cc019SAndroid Build Coastguard Worker igt_require(intel_gen(intel_get_drm_devid(fd)) >= 5);
397*d83cc019SAndroid Build Coastguard Worker
398*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__wc(fd, buf->handle, 0, PAGE_ALIGN(buf->size),
399*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
400*d83cc019SAndroid Build Coastguard Worker
401*d83cc019SAndroid Build Coastguard Worker switch (tiling) {
402*d83cc019SAndroid Build Coastguard Worker case I915_TILING_NONE:
403*d83cc019SAndroid Build Coastguard Worker draw_rect_ptr_linear(ptr, buf->stride, rect, color, buf->bpp);
404*d83cc019SAndroid Build Coastguard Worker break;
405*d83cc019SAndroid Build Coastguard Worker case I915_TILING_X:
406*d83cc019SAndroid Build Coastguard Worker case I915_TILING_Y:
407*d83cc019SAndroid Build Coastguard Worker draw_rect_ptr_tiled(ptr, buf->stride, tiling, swizzle, rect,
408*d83cc019SAndroid Build Coastguard Worker color, buf->bpp);
409*d83cc019SAndroid Build Coastguard Worker break;
410*d83cc019SAndroid Build Coastguard Worker default:
411*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
412*d83cc019SAndroid Build Coastguard Worker break;
413*d83cc019SAndroid Build Coastguard Worker }
414*d83cc019SAndroid Build Coastguard Worker
415*d83cc019SAndroid Build Coastguard Worker igt_assert(gem_munmap(ptr, buf->size) == 0);
416*d83cc019SAndroid Build Coastguard Worker }
417*d83cc019SAndroid Build Coastguard Worker
draw_rect_pwrite_untiled(int fd,struct buf_data * buf,struct rect * rect,uint32_t color)418*d83cc019SAndroid Build Coastguard Worker static void draw_rect_pwrite_untiled(int fd, struct buf_data *buf,
419*d83cc019SAndroid Build Coastguard Worker struct rect *rect, uint32_t color)
420*d83cc019SAndroid Build Coastguard Worker {
421*d83cc019SAndroid Build Coastguard Worker int i, y, offset;
422*d83cc019SAndroid Build Coastguard Worker int pixel_size = buf->bpp / 8;
423*d83cc019SAndroid Build Coastguard Worker uint8_t tmp[rect->w * pixel_size];
424*d83cc019SAndroid Build Coastguard Worker
425*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < rect->w; i++)
426*d83cc019SAndroid Build Coastguard Worker set_pixel(tmp, i, color, buf->bpp);
427*d83cc019SAndroid Build Coastguard Worker
428*d83cc019SAndroid Build Coastguard Worker for (y = rect->y; y < rect->y + rect->h; y++) {
429*d83cc019SAndroid Build Coastguard Worker offset = (y * buf->stride) + (rect->x * pixel_size);
430*d83cc019SAndroid Build Coastguard Worker gem_write(fd, buf->handle, offset, tmp, rect->w * pixel_size);
431*d83cc019SAndroid Build Coastguard Worker }
432*d83cc019SAndroid Build Coastguard Worker }
433*d83cc019SAndroid Build Coastguard Worker
draw_rect_pwrite_tiled(int fd,struct buf_data * buf,uint32_t tiling,struct rect * rect,uint32_t color,uint32_t swizzle)434*d83cc019SAndroid Build Coastguard Worker static void draw_rect_pwrite_tiled(int fd, struct buf_data *buf,
435*d83cc019SAndroid Build Coastguard Worker uint32_t tiling, struct rect *rect,
436*d83cc019SAndroid Build Coastguard Worker uint32_t color, uint32_t swizzle)
437*d83cc019SAndroid Build Coastguard Worker {
438*d83cc019SAndroid Build Coastguard Worker int i;
439*d83cc019SAndroid Build Coastguard Worker int tiled_pos, x, y, pixel_size;
440*d83cc019SAndroid Build Coastguard Worker uint8_t tmp[4096];
441*d83cc019SAndroid Build Coastguard Worker int tmp_used = 0, tmp_size;
442*d83cc019SAndroid Build Coastguard Worker bool flush_tmp = false;
443*d83cc019SAndroid Build Coastguard Worker int tmp_start_pos = 0;
444*d83cc019SAndroid Build Coastguard Worker int pixels_written = 0;
445*d83cc019SAndroid Build Coastguard Worker
446*d83cc019SAndroid Build Coastguard Worker /* We didn't implement suport for the older tiling methods yet. */
447*d83cc019SAndroid Build Coastguard Worker igt_require(intel_gen(intel_get_drm_devid(fd)) >= 5);
448*d83cc019SAndroid Build Coastguard Worker
449*d83cc019SAndroid Build Coastguard Worker pixel_size = buf->bpp / 8;
450*d83cc019SAndroid Build Coastguard Worker tmp_size = sizeof(tmp) / pixel_size;
451*d83cc019SAndroid Build Coastguard Worker
452*d83cc019SAndroid Build Coastguard Worker /* Instead of doing one pwrite per pixel, we try to group the maximum
453*d83cc019SAndroid Build Coastguard Worker * amount of consecutive pixels we can in a single pwrite: that's why we
454*d83cc019SAndroid Build Coastguard Worker * use the "tmp" variables. */
455*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < tmp_size; i++)
456*d83cc019SAndroid Build Coastguard Worker set_pixel(tmp, i, color, buf->bpp);
457*d83cc019SAndroid Build Coastguard Worker
458*d83cc019SAndroid Build Coastguard Worker for (tiled_pos = 0; tiled_pos < buf->size; tiled_pos += pixel_size) {
459*d83cc019SAndroid Build Coastguard Worker switch (tiling) {
460*d83cc019SAndroid Build Coastguard Worker case I915_TILING_X:
461*d83cc019SAndroid Build Coastguard Worker xtiled_pos_to_x_y_linear(tiled_pos, buf->stride,
462*d83cc019SAndroid Build Coastguard Worker swizzle, buf->bpp, &x, &y);
463*d83cc019SAndroid Build Coastguard Worker break;
464*d83cc019SAndroid Build Coastguard Worker case I915_TILING_Y:
465*d83cc019SAndroid Build Coastguard Worker ytiled_pos_to_x_y_linear(tiled_pos, buf->stride,
466*d83cc019SAndroid Build Coastguard Worker swizzle, buf->bpp, &x, &y);
467*d83cc019SAndroid Build Coastguard Worker break;
468*d83cc019SAndroid Build Coastguard Worker default:
469*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
470*d83cc019SAndroid Build Coastguard Worker }
471*d83cc019SAndroid Build Coastguard Worker
472*d83cc019SAndroid Build Coastguard Worker if (x >= rect->x && x < rect->x + rect->w &&
473*d83cc019SAndroid Build Coastguard Worker y >= rect->y && y < rect->y + rect->h) {
474*d83cc019SAndroid Build Coastguard Worker if (tmp_used == 0)
475*d83cc019SAndroid Build Coastguard Worker tmp_start_pos = tiled_pos;
476*d83cc019SAndroid Build Coastguard Worker tmp_used++;
477*d83cc019SAndroid Build Coastguard Worker } else {
478*d83cc019SAndroid Build Coastguard Worker flush_tmp = true;
479*d83cc019SAndroid Build Coastguard Worker }
480*d83cc019SAndroid Build Coastguard Worker
481*d83cc019SAndroid Build Coastguard Worker if (tmp_used == tmp_size || (flush_tmp && tmp_used > 0) ||
482*d83cc019SAndroid Build Coastguard Worker tiled_pos + pixel_size >= buf->size) {
483*d83cc019SAndroid Build Coastguard Worker gem_write(fd, buf->handle, tmp_start_pos, tmp,
484*d83cc019SAndroid Build Coastguard Worker tmp_used * pixel_size);
485*d83cc019SAndroid Build Coastguard Worker flush_tmp = false;
486*d83cc019SAndroid Build Coastguard Worker pixels_written += tmp_used;
487*d83cc019SAndroid Build Coastguard Worker tmp_used = 0;
488*d83cc019SAndroid Build Coastguard Worker
489*d83cc019SAndroid Build Coastguard Worker if (pixels_written == rect->w * rect->h)
490*d83cc019SAndroid Build Coastguard Worker break;
491*d83cc019SAndroid Build Coastguard Worker }
492*d83cc019SAndroid Build Coastguard Worker }
493*d83cc019SAndroid Build Coastguard Worker }
494*d83cc019SAndroid Build Coastguard Worker
draw_rect_pwrite(int fd,struct buf_data * buf,struct rect * rect,uint32_t color)495*d83cc019SAndroid Build Coastguard Worker static void draw_rect_pwrite(int fd, struct buf_data *buf,
496*d83cc019SAndroid Build Coastguard Worker struct rect *rect, uint32_t color)
497*d83cc019SAndroid Build Coastguard Worker {
498*d83cc019SAndroid Build Coastguard Worker uint32_t tiling, swizzle;
499*d83cc019SAndroid Build Coastguard Worker
500*d83cc019SAndroid Build Coastguard Worker igt_require(gem_get_tiling(fd, buf->handle, &tiling, &swizzle));
501*d83cc019SAndroid Build Coastguard Worker
502*d83cc019SAndroid Build Coastguard Worker switch (tiling) {
503*d83cc019SAndroid Build Coastguard Worker case I915_TILING_NONE:
504*d83cc019SAndroid Build Coastguard Worker draw_rect_pwrite_untiled(fd, buf, rect, color);
505*d83cc019SAndroid Build Coastguard Worker break;
506*d83cc019SAndroid Build Coastguard Worker case I915_TILING_X:
507*d83cc019SAndroid Build Coastguard Worker case I915_TILING_Y:
508*d83cc019SAndroid Build Coastguard Worker draw_rect_pwrite_tiled(fd, buf, tiling, rect, color, swizzle);
509*d83cc019SAndroid Build Coastguard Worker break;
510*d83cc019SAndroid Build Coastguard Worker default:
511*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
512*d83cc019SAndroid Build Coastguard Worker break;
513*d83cc019SAndroid Build Coastguard Worker }
514*d83cc019SAndroid Build Coastguard Worker }
515*d83cc019SAndroid Build Coastguard Worker
draw_rect_blt(int fd,struct cmd_data * cmd_data,struct buf_data * buf,struct rect * rect,uint32_t color)516*d83cc019SAndroid Build Coastguard Worker static void draw_rect_blt(int fd, struct cmd_data *cmd_data,
517*d83cc019SAndroid Build Coastguard Worker struct buf_data *buf, struct rect *rect,
518*d83cc019SAndroid Build Coastguard Worker uint32_t color)
519*d83cc019SAndroid Build Coastguard Worker {
520*d83cc019SAndroid Build Coastguard Worker drm_intel_bo *dst;
521*d83cc019SAndroid Build Coastguard Worker struct intel_batchbuffer *batch;
522*d83cc019SAndroid Build Coastguard Worker int blt_cmd_len, blt_cmd_tiling, blt_cmd_depth;
523*d83cc019SAndroid Build Coastguard Worker uint32_t devid = intel_get_drm_devid(fd);
524*d83cc019SAndroid Build Coastguard Worker int gen = intel_gen(devid);
525*d83cc019SAndroid Build Coastguard Worker uint32_t tiling, swizzle;
526*d83cc019SAndroid Build Coastguard Worker int pitch;
527*d83cc019SAndroid Build Coastguard Worker
528*d83cc019SAndroid Build Coastguard Worker igt_require(gem_get_tiling(fd, buf->handle, &tiling, &swizzle));
529*d83cc019SAndroid Build Coastguard Worker
530*d83cc019SAndroid Build Coastguard Worker dst = gem_handle_to_libdrm_bo(cmd_data->bufmgr, fd, "", buf->handle);
531*d83cc019SAndroid Build Coastguard Worker igt_assert(dst);
532*d83cc019SAndroid Build Coastguard Worker
533*d83cc019SAndroid Build Coastguard Worker batch = intel_batchbuffer_alloc(cmd_data->bufmgr, devid);
534*d83cc019SAndroid Build Coastguard Worker igt_assert(batch);
535*d83cc019SAndroid Build Coastguard Worker
536*d83cc019SAndroid Build Coastguard Worker switch (buf->bpp) {
537*d83cc019SAndroid Build Coastguard Worker case 8:
538*d83cc019SAndroid Build Coastguard Worker blt_cmd_depth = 0;
539*d83cc019SAndroid Build Coastguard Worker break;
540*d83cc019SAndroid Build Coastguard Worker case 16: /* we're assuming 565 */
541*d83cc019SAndroid Build Coastguard Worker blt_cmd_depth = 1 << 24;
542*d83cc019SAndroid Build Coastguard Worker break;
543*d83cc019SAndroid Build Coastguard Worker case 32:
544*d83cc019SAndroid Build Coastguard Worker blt_cmd_depth = 3 << 24;
545*d83cc019SAndroid Build Coastguard Worker break;
546*d83cc019SAndroid Build Coastguard Worker default:
547*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
548*d83cc019SAndroid Build Coastguard Worker }
549*d83cc019SAndroid Build Coastguard Worker
550*d83cc019SAndroid Build Coastguard Worker blt_cmd_len = (gen >= 8) ? 0x5 : 0x4;
551*d83cc019SAndroid Build Coastguard Worker blt_cmd_tiling = (tiling) ? XY_COLOR_BLT_TILED : 0;
552*d83cc019SAndroid Build Coastguard Worker pitch = (tiling) ? buf->stride / 4 : buf->stride;
553*d83cc019SAndroid Build Coastguard Worker
554*d83cc019SAndroid Build Coastguard Worker switch_blt_tiling(batch, tiling, true);
555*d83cc019SAndroid Build Coastguard Worker
556*d83cc019SAndroid Build Coastguard Worker BEGIN_BATCH(6, 1);
557*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | XY_COLOR_BLT_WRITE_ALPHA |
558*d83cc019SAndroid Build Coastguard Worker XY_COLOR_BLT_WRITE_RGB | blt_cmd_tiling | blt_cmd_len);
559*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(blt_cmd_depth | (0xF0 << 16) | pitch);
560*d83cc019SAndroid Build Coastguard Worker OUT_BATCH((rect->y << 16) | rect->x);
561*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(((rect->y + rect->h) << 16) | (rect->x + rect->w));
562*d83cc019SAndroid Build Coastguard Worker OUT_RELOC_FENCED(dst, 0, I915_GEM_DOMAIN_RENDER, 0);
563*d83cc019SAndroid Build Coastguard Worker OUT_BATCH(color);
564*d83cc019SAndroid Build Coastguard Worker ADVANCE_BATCH();
565*d83cc019SAndroid Build Coastguard Worker
566*d83cc019SAndroid Build Coastguard Worker switch_blt_tiling(batch, tiling, false);
567*d83cc019SAndroid Build Coastguard Worker
568*d83cc019SAndroid Build Coastguard Worker intel_batchbuffer_flush(batch);
569*d83cc019SAndroid Build Coastguard Worker intel_batchbuffer_free(batch);
570*d83cc019SAndroid Build Coastguard Worker drm_intel_bo_unreference(dst);
571*d83cc019SAndroid Build Coastguard Worker }
572*d83cc019SAndroid Build Coastguard Worker
draw_rect_render(int fd,struct cmd_data * cmd_data,struct buf_data * buf,struct rect * rect,uint32_t color)573*d83cc019SAndroid Build Coastguard Worker static void draw_rect_render(int fd, struct cmd_data *cmd_data,
574*d83cc019SAndroid Build Coastguard Worker struct buf_data *buf, struct rect *rect,
575*d83cc019SAndroid Build Coastguard Worker uint32_t color)
576*d83cc019SAndroid Build Coastguard Worker {
577*d83cc019SAndroid Build Coastguard Worker drm_intel_bo *src, *dst;
578*d83cc019SAndroid Build Coastguard Worker uint32_t devid = intel_get_drm_devid(fd);
579*d83cc019SAndroid Build Coastguard Worker igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(devid);
580*d83cc019SAndroid Build Coastguard Worker struct igt_buf src_buf = {}, dst_buf = {};
581*d83cc019SAndroid Build Coastguard Worker struct intel_batchbuffer *batch;
582*d83cc019SAndroid Build Coastguard Worker uint32_t tiling, swizzle;
583*d83cc019SAndroid Build Coastguard Worker struct buf_data tmp;
584*d83cc019SAndroid Build Coastguard Worker int pixel_size = buf->bpp / 8;
585*d83cc019SAndroid Build Coastguard Worker
586*d83cc019SAndroid Build Coastguard Worker igt_skip_on(!rendercopy);
587*d83cc019SAndroid Build Coastguard Worker
588*d83cc019SAndroid Build Coastguard Worker igt_require(gem_get_tiling(fd, buf->handle, &tiling, &swizzle));
589*d83cc019SAndroid Build Coastguard Worker
590*d83cc019SAndroid Build Coastguard Worker /* We create a temporary buffer and copy from it using rendercopy. */
591*d83cc019SAndroid Build Coastguard Worker tmp.size = rect->w * rect->h * pixel_size;
592*d83cc019SAndroid Build Coastguard Worker tmp.handle = gem_create(fd, tmp.size);
593*d83cc019SAndroid Build Coastguard Worker tmp.stride = rect->w * pixel_size;
594*d83cc019SAndroid Build Coastguard Worker tmp.bpp = buf->bpp;
595*d83cc019SAndroid Build Coastguard Worker draw_rect_mmap_cpu(fd, &tmp, &(struct rect){0, 0, rect->w, rect->h},
596*d83cc019SAndroid Build Coastguard Worker color);
597*d83cc019SAndroid Build Coastguard Worker
598*d83cc019SAndroid Build Coastguard Worker src = gem_handle_to_libdrm_bo(cmd_data->bufmgr, fd, "", tmp.handle);
599*d83cc019SAndroid Build Coastguard Worker igt_assert(src);
600*d83cc019SAndroid Build Coastguard Worker dst = gem_handle_to_libdrm_bo(cmd_data->bufmgr, fd, "", buf->handle);
601*d83cc019SAndroid Build Coastguard Worker igt_assert(dst);
602*d83cc019SAndroid Build Coastguard Worker
603*d83cc019SAndroid Build Coastguard Worker src_buf.bo = src;
604*d83cc019SAndroid Build Coastguard Worker src_buf.stride = tmp.stride;
605*d83cc019SAndroid Build Coastguard Worker src_buf.tiling = I915_TILING_NONE;
606*d83cc019SAndroid Build Coastguard Worker src_buf.size = tmp.size;
607*d83cc019SAndroid Build Coastguard Worker src_buf.bpp = tmp.bpp;
608*d83cc019SAndroid Build Coastguard Worker dst_buf.bo = dst;
609*d83cc019SAndroid Build Coastguard Worker dst_buf.stride = buf->stride;
610*d83cc019SAndroid Build Coastguard Worker dst_buf.tiling = tiling;
611*d83cc019SAndroid Build Coastguard Worker dst_buf.size = buf->size;
612*d83cc019SAndroid Build Coastguard Worker dst_buf.bpp = buf->bpp;
613*d83cc019SAndroid Build Coastguard Worker
614*d83cc019SAndroid Build Coastguard Worker batch = intel_batchbuffer_alloc(cmd_data->bufmgr, devid);
615*d83cc019SAndroid Build Coastguard Worker igt_assert(batch);
616*d83cc019SAndroid Build Coastguard Worker
617*d83cc019SAndroid Build Coastguard Worker rendercopy(batch, cmd_data->context, &src_buf, 0, 0, rect->w,
618*d83cc019SAndroid Build Coastguard Worker rect->h, &dst_buf, rect->x, rect->y);
619*d83cc019SAndroid Build Coastguard Worker
620*d83cc019SAndroid Build Coastguard Worker intel_batchbuffer_free(batch);
621*d83cc019SAndroid Build Coastguard Worker drm_intel_bo_unreference(src);
622*d83cc019SAndroid Build Coastguard Worker drm_intel_bo_unreference(dst);
623*d83cc019SAndroid Build Coastguard Worker gem_close(fd, tmp.handle);
624*d83cc019SAndroid Build Coastguard Worker }
625*d83cc019SAndroid Build Coastguard Worker
626*d83cc019SAndroid Build Coastguard Worker /**
627*d83cc019SAndroid Build Coastguard Worker * igt_draw_rect:
628*d83cc019SAndroid Build Coastguard Worker * @fd: the DRM file descriptor
629*d83cc019SAndroid Build Coastguard Worker * @bufmgr: the libdrm bufmgr, only required for IGT_DRAW_BLT and
630*d83cc019SAndroid Build Coastguard Worker * IGT_DRAW_RENDER
631*d83cc019SAndroid Build Coastguard Worker * @context: the context, can be NULL if you don't want to think about it
632*d83cc019SAndroid Build Coastguard Worker * @buf_handle: the handle of the buffer where you're going to draw to
633*d83cc019SAndroid Build Coastguard Worker * @buf_size: the size of the buffer
634*d83cc019SAndroid Build Coastguard Worker * @buf_stride: the stride of the buffer
635*d83cc019SAndroid Build Coastguard Worker * @method: method you're going to use to write to the buffer
636*d83cc019SAndroid Build Coastguard Worker * @rect_x: horizontal position on the buffer where your rectangle starts
637*d83cc019SAndroid Build Coastguard Worker * @rect_y: vertical position on the buffer where your rectangle starts
638*d83cc019SAndroid Build Coastguard Worker * @rect_w: width of the rectangle
639*d83cc019SAndroid Build Coastguard Worker * @rect_h: height of the rectangle
640*d83cc019SAndroid Build Coastguard Worker * @color: color of the rectangle
641*d83cc019SAndroid Build Coastguard Worker * @bpp: bits per pixel
642*d83cc019SAndroid Build Coastguard Worker *
643*d83cc019SAndroid Build Coastguard Worker * This function draws a colored rectangle on the destination buffer, allowing
644*d83cc019SAndroid Build Coastguard Worker * you to specify the method used to draw the rectangle.
645*d83cc019SAndroid Build Coastguard Worker */
igt_draw_rect(int fd,drm_intel_bufmgr * bufmgr,drm_intel_context * context,uint32_t buf_handle,uint32_t buf_size,uint32_t buf_stride,enum igt_draw_method method,int rect_x,int rect_y,int rect_w,int rect_h,uint32_t color,int bpp)646*d83cc019SAndroid Build Coastguard Worker void igt_draw_rect(int fd, drm_intel_bufmgr *bufmgr, drm_intel_context *context,
647*d83cc019SAndroid Build Coastguard Worker uint32_t buf_handle, uint32_t buf_size, uint32_t buf_stride,
648*d83cc019SAndroid Build Coastguard Worker enum igt_draw_method method, int rect_x, int rect_y,
649*d83cc019SAndroid Build Coastguard Worker int rect_w, int rect_h, uint32_t color, int bpp)
650*d83cc019SAndroid Build Coastguard Worker {
651*d83cc019SAndroid Build Coastguard Worker struct cmd_data cmd_data = {
652*d83cc019SAndroid Build Coastguard Worker .bufmgr = bufmgr,
653*d83cc019SAndroid Build Coastguard Worker .context = context,
654*d83cc019SAndroid Build Coastguard Worker };
655*d83cc019SAndroid Build Coastguard Worker struct buf_data buf = {
656*d83cc019SAndroid Build Coastguard Worker .handle = buf_handle,
657*d83cc019SAndroid Build Coastguard Worker .size = buf_size,
658*d83cc019SAndroid Build Coastguard Worker .stride = buf_stride,
659*d83cc019SAndroid Build Coastguard Worker .bpp = bpp,
660*d83cc019SAndroid Build Coastguard Worker };
661*d83cc019SAndroid Build Coastguard Worker struct rect rect = {
662*d83cc019SAndroid Build Coastguard Worker .x = rect_x,
663*d83cc019SAndroid Build Coastguard Worker .y = rect_y,
664*d83cc019SAndroid Build Coastguard Worker .w = rect_w,
665*d83cc019SAndroid Build Coastguard Worker .h = rect_h,
666*d83cc019SAndroid Build Coastguard Worker };
667*d83cc019SAndroid Build Coastguard Worker
668*d83cc019SAndroid Build Coastguard Worker switch (method) {
669*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_MMAP_CPU:
670*d83cc019SAndroid Build Coastguard Worker draw_rect_mmap_cpu(fd, &buf, &rect, color);
671*d83cc019SAndroid Build Coastguard Worker break;
672*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_MMAP_GTT:
673*d83cc019SAndroid Build Coastguard Worker draw_rect_mmap_gtt(fd, &buf, &rect, color);
674*d83cc019SAndroid Build Coastguard Worker break;
675*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_MMAP_WC:
676*d83cc019SAndroid Build Coastguard Worker draw_rect_mmap_wc(fd, &buf, &rect, color);
677*d83cc019SAndroid Build Coastguard Worker break;
678*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_PWRITE:
679*d83cc019SAndroid Build Coastguard Worker draw_rect_pwrite(fd, &buf, &rect, color);
680*d83cc019SAndroid Build Coastguard Worker break;
681*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_BLT:
682*d83cc019SAndroid Build Coastguard Worker draw_rect_blt(fd, &cmd_data, &buf, &rect, color);
683*d83cc019SAndroid Build Coastguard Worker break;
684*d83cc019SAndroid Build Coastguard Worker case IGT_DRAW_RENDER:
685*d83cc019SAndroid Build Coastguard Worker draw_rect_render(fd, &cmd_data, &buf, &rect, color);
686*d83cc019SAndroid Build Coastguard Worker break;
687*d83cc019SAndroid Build Coastguard Worker default:
688*d83cc019SAndroid Build Coastguard Worker igt_assert(false);
689*d83cc019SAndroid Build Coastguard Worker break;
690*d83cc019SAndroid Build Coastguard Worker }
691*d83cc019SAndroid Build Coastguard Worker }
692*d83cc019SAndroid Build Coastguard Worker
693*d83cc019SAndroid Build Coastguard Worker /**
694*d83cc019SAndroid Build Coastguard Worker * igt_draw_rect_fb:
695*d83cc019SAndroid Build Coastguard Worker * @fd: the DRM file descriptor
696*d83cc019SAndroid Build Coastguard Worker * @bufmgr: the libdrm bufmgr, only required for IGT_DRAW_BLT and
697*d83cc019SAndroid Build Coastguard Worker * IGT_DRAW_RENDER
698*d83cc019SAndroid Build Coastguard Worker * @context: the context, can be NULL if you don't want to think about it
699*d83cc019SAndroid Build Coastguard Worker * @fb: framebuffer
700*d83cc019SAndroid Build Coastguard Worker * @method: method you're going to use to write to the buffer
701*d83cc019SAndroid Build Coastguard Worker * @rect_x: horizontal position on the buffer where your rectangle starts
702*d83cc019SAndroid Build Coastguard Worker * @rect_y: vertical position on the buffer where your rectangle starts
703*d83cc019SAndroid Build Coastguard Worker * @rect_w: width of the rectangle
704*d83cc019SAndroid Build Coastguard Worker * @rect_h: height of the rectangle
705*d83cc019SAndroid Build Coastguard Worker * @color: color of the rectangle
706*d83cc019SAndroid Build Coastguard Worker *
707*d83cc019SAndroid Build Coastguard Worker * This is exactly the same as igt_draw_rect, but you can pass an igt_fb instead
708*d83cc019SAndroid Build Coastguard Worker * of manually providing its details. See igt_draw_rect.
709*d83cc019SAndroid Build Coastguard Worker */
igt_draw_rect_fb(int fd,drm_intel_bufmgr * bufmgr,drm_intel_context * context,struct igt_fb * fb,enum igt_draw_method method,int rect_x,int rect_y,int rect_w,int rect_h,uint32_t color)710*d83cc019SAndroid Build Coastguard Worker void igt_draw_rect_fb(int fd, drm_intel_bufmgr *bufmgr,
711*d83cc019SAndroid Build Coastguard Worker drm_intel_context *context, struct igt_fb *fb,
712*d83cc019SAndroid Build Coastguard Worker enum igt_draw_method method, int rect_x, int rect_y,
713*d83cc019SAndroid Build Coastguard Worker int rect_w, int rect_h, uint32_t color)
714*d83cc019SAndroid Build Coastguard Worker {
715*d83cc019SAndroid Build Coastguard Worker igt_draw_rect(fd, bufmgr, context, fb->gem_handle, fb->size, fb->strides[0],
716*d83cc019SAndroid Build Coastguard Worker method, rect_x, rect_y, rect_w, rect_h, color,
717*d83cc019SAndroid Build Coastguard Worker igt_drm_format_to_bpp(fb->drm_format));
718*d83cc019SAndroid Build Coastguard Worker }
719*d83cc019SAndroid Build Coastguard Worker
720*d83cc019SAndroid Build Coastguard Worker /**
721*d83cc019SAndroid Build Coastguard Worker * igt_draw_fill_fb:
722*d83cc019SAndroid Build Coastguard Worker * @fd: the DRM file descriptor
723*d83cc019SAndroid Build Coastguard Worker * @fb: the FB that is going to be filled
724*d83cc019SAndroid Build Coastguard Worker * @color: the color you're going to paint it
725*d83cc019SAndroid Build Coastguard Worker *
726*d83cc019SAndroid Build Coastguard Worker * This function just paints an igt_fb using the provided color.
727*d83cc019SAndroid Build Coastguard Worker */
igt_draw_fill_fb(int fd,struct igt_fb * fb,uint32_t color)728*d83cc019SAndroid Build Coastguard Worker void igt_draw_fill_fb(int fd, struct igt_fb *fb, uint32_t color)
729*d83cc019SAndroid Build Coastguard Worker {
730*d83cc019SAndroid Build Coastguard Worker igt_draw_rect_fb(fd, NULL, NULL, fb, IGT_DRAW_MMAP_GTT,
731*d83cc019SAndroid Build Coastguard Worker 0, 0, fb->width, fb->height, color);
732*d83cc019SAndroid Build Coastguard Worker }
733