ilo: make ilo_cp based on ilo_builder
[mesa.git] / src / gallium / drivers / ilo / ilo_blitter_blt.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2013 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "genhw/genhw.h"
29 #include "util/u_pack_color.h"
30
31 #include "ilo_3d.h"
32 #include "ilo_context.h"
33 #include "ilo_cp.h"
34 #include "ilo_blit.h"
35 #include "ilo_resource.h"
36 #include "ilo_blitter.h"
37
38 enum gen6_blt_mask {
39 GEN6_BLT_MASK_8,
40 GEN6_BLT_MASK_16,
41 GEN6_BLT_MASK_32,
42 GEN6_BLT_MASK_32_LO,
43 GEN6_BLT_MASK_32_HI,
44 };
45
46 /*
47 * From the Sandy Bridge PRM, volume 1 part 5, page 7:
48 *
49 * "The BLT engine is capable of transferring very large quantities of
50 * graphics data. Any graphics data read from and written to the
51 * destination is permitted to represent a number of pixels that occupies
52 * up to 65,536 scan lines and up to 32,768 bytes per scan line at the
53 * destination. The maximum number of pixels that may be represented per
54 * scan line's worth of graphics data depends on the color depth."
55 */
56 static const int gen6_max_bytes_per_scanline = 32768;
57 static const int gen6_max_scanlines = 65536;
58
59 static void
60 gen6_emit_MI_FLUSH_DW(struct ilo_dev_info *dev, struct ilo_cp *cp)
61 {
62 const uint8_t cmd_len = 4;
63 const uint32_t dw0 = GEN6_MI_CMD(MI_FLUSH_DW) | (cmd_len - 2);
64
65 ilo_cp_begin(cp, cmd_len);
66 ilo_cp_write(cp, dw0);
67 ilo_cp_write(cp, 0);
68 ilo_cp_write(cp, 0);
69 ilo_cp_write(cp, 0);
70 ilo_cp_end(cp);
71 }
72
73 static void
74 gen6_emit_MI_LOAD_REGISTER_IMM(struct ilo_dev_info *dev,
75 uint32_t reg, uint32_t val,
76 struct ilo_cp *cp)
77 {
78 const uint8_t cmd_len = 3;
79 const uint32_t dw0 = GEN6_MI_CMD(MI_LOAD_REGISTER_IMM) | (cmd_len - 2);
80
81 ilo_cp_begin(cp, cmd_len);
82 ilo_cp_write(cp, dw0);
83 ilo_cp_write(cp, reg);
84 ilo_cp_write(cp, val);
85 ilo_cp_end(cp);
86 }
87
88 static uint32_t
89 gen6_translate_blt_value_mask(enum gen6_blt_mask value_mask)
90 {
91 switch (value_mask) {
92 case GEN6_BLT_MASK_8: return GEN6_BLITTER_BR13_FORMAT_8;
93 case GEN6_BLT_MASK_16: return GEN6_BLITTER_BR13_FORMAT_565;
94 default: return GEN6_BLITTER_BR13_FORMAT_8888;
95 }
96 }
97
98 static uint32_t
99 gen6_translate_blt_write_mask(enum gen6_blt_mask write_mask)
100 {
101 switch (write_mask) {
102 case GEN6_BLT_MASK_32: return GEN6_BLITTER_BR00_WRITE_RGB |
103 GEN6_BLITTER_BR00_WRITE_A;
104 case GEN6_BLT_MASK_32_LO: return GEN6_BLITTER_BR00_WRITE_RGB;
105 case GEN6_BLT_MASK_32_HI: return GEN6_BLITTER_BR00_WRITE_A;
106 default: return 0;
107 }
108 }
109
110 static uint32_t
111 gen6_translate_blt_cpp(enum gen6_blt_mask mask)
112 {
113 switch (mask) {
114 case GEN6_BLT_MASK_8: return 1;
115 case GEN6_BLT_MASK_16: return 2;
116 default: return 4;
117 }
118 }
119
120 static void
121 gen6_emit_COLOR_BLT(struct ilo_dev_info *dev,
122 struct intel_bo *dst_bo,
123 int16_t dst_pitch, uint32_t dst_offset,
124 uint16_t width, uint16_t height,
125 uint32_t pattern, uint8_t rop,
126 enum gen6_blt_mask value_mask,
127 enum gen6_blt_mask write_mask,
128 struct ilo_cp *cp)
129 {
130 const uint8_t cmd_len = 5;
131 const int cpp = gen6_translate_blt_cpp(value_mask);
132 uint32_t dw0, dw1;
133
134 dw0 = GEN6_BLITTER_CMD(COLOR_BLT) |
135 gen6_translate_blt_write_mask(write_mask) |
136 (cmd_len - 2);
137
138 assert(width < gen6_max_bytes_per_scanline);
139 assert(height < gen6_max_scanlines);
140 /* offsets are naturally aligned and pitches are dword-aligned */
141 assert(dst_offset % cpp == 0 && dst_pitch % 4 == 0);
142
143 dw1 = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
144 gen6_translate_blt_value_mask(value_mask) |
145 dst_pitch;
146
147 ilo_cp_begin(cp, cmd_len);
148 ilo_cp_write(cp, dw0);
149 ilo_cp_write(cp, dw1);
150 ilo_cp_write(cp, height << 16 | width);
151 ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_RELOC_WRITE);
152 ilo_cp_write(cp, pattern);
153 ilo_cp_end(cp);
154 }
155
156 static void
157 gen6_emit_XY_COLOR_BLT(struct ilo_dev_info *dev,
158 struct intel_bo *dst_bo,
159 enum intel_tiling_mode dst_tiling,
160 int16_t dst_pitch, uint32_t dst_offset,
161 int16_t x1, int16_t y1, int16_t x2, int16_t y2,
162 uint32_t pattern, uint8_t rop,
163 enum gen6_blt_mask value_mask,
164 enum gen6_blt_mask write_mask,
165 struct ilo_cp *cp)
166 {
167 const uint8_t cmd_len = 6;
168 const int cpp = gen6_translate_blt_cpp(value_mask);
169 int dst_align, dst_pitch_shift;
170 uint32_t dw0, dw1;
171
172 dw0 = GEN6_BLITTER_CMD(XY_COLOR_BLT) |
173 gen6_translate_blt_write_mask(write_mask) |
174 (cmd_len - 2);
175
176 if (dst_tiling == INTEL_TILING_NONE) {
177 dst_align = 4;
178 dst_pitch_shift = 0;
179 }
180 else {
181 dw0 |= GEN6_BLITTER_BR00_DST_TILED;
182
183 dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
184 /* in dwords when tiled */
185 dst_pitch_shift = 2;
186 }
187
188 assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
189 assert(y2 - y1 < gen6_max_scanlines);
190 assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
191
192 dw1 = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
193 gen6_translate_blt_value_mask(value_mask) |
194 dst_pitch >> dst_pitch_shift;
195
196 ilo_cp_begin(cp, cmd_len);
197 ilo_cp_write(cp, dw0);
198 ilo_cp_write(cp, dw1);
199 ilo_cp_write(cp, y1 << 16 | x1);
200 ilo_cp_write(cp, y2 << 16 | x2);
201 ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_RELOC_WRITE);
202 ilo_cp_write(cp, pattern);
203 ilo_cp_end(cp);
204 }
205
206 static void
207 gen6_emit_SRC_COPY_BLT(struct ilo_dev_info *dev,
208 struct intel_bo *dst_bo,
209 int16_t dst_pitch, uint32_t dst_offset,
210 uint16_t width, uint16_t height,
211 struct intel_bo *src_bo,
212 int16_t src_pitch, uint32_t src_offset,
213 bool dir_rtl, uint8_t rop,
214 enum gen6_blt_mask value_mask,
215 enum gen6_blt_mask write_mask,
216 struct ilo_cp *cp)
217 {
218 const uint8_t cmd_len = 6;
219 const int cpp = gen6_translate_blt_cpp(value_mask);
220 uint32_t dw0, dw1;
221
222 dw0 = GEN6_BLITTER_CMD(SRC_COPY_BLT) |
223 gen6_translate_blt_write_mask(write_mask) |
224 (cmd_len - 2);
225
226 assert(width < gen6_max_bytes_per_scanline);
227 assert(height < gen6_max_scanlines);
228 /* offsets are naturally aligned and pitches are dword-aligned */
229 assert(dst_offset % cpp == 0 && dst_pitch % 4 == 0);
230 assert(src_offset % cpp == 0 && src_pitch % 4 == 0);
231
232 dw1 = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
233 gen6_translate_blt_value_mask(value_mask) |
234 dst_pitch;
235
236 if (dir_rtl)
237 dw1 |= GEN6_BLITTER_BR13_DIR_RTL;
238
239 ilo_cp_begin(cp, cmd_len);
240 ilo_cp_write(cp, dw0);
241 ilo_cp_write(cp, dw1);
242 ilo_cp_write(cp, height << 16 | width);
243 ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_RELOC_WRITE);
244 ilo_cp_write(cp, src_pitch);
245 ilo_cp_write_bo(cp, src_offset, src_bo, 0);
246 ilo_cp_end(cp);
247 }
248
249 static void
250 gen6_emit_XY_SRC_COPY_BLT(struct ilo_dev_info *dev,
251 struct intel_bo *dst_bo,
252 enum intel_tiling_mode dst_tiling,
253 int16_t dst_pitch, uint32_t dst_offset,
254 int16_t x1, int16_t y1, int16_t x2, int16_t y2,
255 struct intel_bo *src_bo,
256 enum intel_tiling_mode src_tiling,
257 int16_t src_pitch, uint32_t src_offset,
258 int16_t src_x, int16_t src_y, uint8_t rop,
259 enum gen6_blt_mask value_mask,
260 enum gen6_blt_mask write_mask,
261 struct ilo_cp *cp)
262 {
263 const uint8_t cmd_len = 8;
264 const int cpp = gen6_translate_blt_cpp(value_mask);
265 int dst_align, dst_pitch_shift;
266 int src_align, src_pitch_shift;
267 uint32_t dw0, dw1;
268
269 dw0 = GEN6_BLITTER_CMD(XY_SRC_COPY_BLT) |
270 gen6_translate_blt_write_mask(write_mask) |
271 (cmd_len - 2);
272
273 if (dst_tiling == INTEL_TILING_NONE) {
274 dst_align = 4;
275 dst_pitch_shift = 0;
276 }
277 else {
278 dw0 |= GEN6_BLITTER_BR00_DST_TILED;
279
280 dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
281 /* in dwords when tiled */
282 dst_pitch_shift = 2;
283 }
284
285 if (src_tiling == INTEL_TILING_NONE) {
286 src_align = 4;
287 src_pitch_shift = 0;
288 }
289 else {
290 dw0 |= GEN6_BLITTER_BR00_SRC_TILED;
291
292 src_align = (src_tiling == INTEL_TILING_Y) ? 128 : 512;
293 /* in dwords when tiled */
294 src_pitch_shift = 2;
295 }
296
297 assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
298 assert(y2 - y1 < gen6_max_scanlines);
299 assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
300 assert(src_offset % src_align == 0 && src_pitch % src_align == 0);
301
302 dw1 = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
303 gen6_translate_blt_value_mask(value_mask) |
304 dst_pitch >> dst_pitch_shift;
305
306 ilo_cp_begin(cp, cmd_len);
307 ilo_cp_write(cp, dw0);
308 ilo_cp_write(cp, dw1);
309 ilo_cp_write(cp, y1 << 16 | x1);
310 ilo_cp_write(cp, y2 << 16 | x2);
311 ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_RELOC_WRITE);
312 ilo_cp_write(cp, src_y << 16 | src_x);
313 ilo_cp_write(cp, src_pitch >> src_pitch_shift);
314 ilo_cp_write_bo(cp, src_offset, src_bo, 0);
315 ilo_cp_end(cp);
316 }
317
318 static uint32_t
319 ilo_blitter_blt_begin(struct ilo_blitter *blitter, int max_cmd_size,
320 struct intel_bo *dst, enum intel_tiling_mode dst_tiling,
321 struct intel_bo *src, enum intel_tiling_mode src_tiling)
322 {
323 struct ilo_context *ilo = blitter->ilo;
324 struct intel_bo *aper_check[2];
325 int count;
326 uint32_t swctrl;
327
328 /* change ring */
329 ilo_cp_set_ring(ilo->cp, INTEL_RING_BLT);
330 ilo_cp_set_owner(ilo->cp, NULL, 0);
331
332 /* check aperture space */
333 aper_check[0] = dst;
334 count = 1;
335
336 if (src) {
337 aper_check[1] = src;
338 count++;
339 }
340
341 if (!ilo_builder_validate(&ilo->cp->builder, count, aper_check))
342 ilo_cp_flush(ilo->cp, "out of aperture");
343
344 /* set BCS_SWCTRL */
345 swctrl = 0x0;
346
347 if (dst_tiling == INTEL_TILING_Y) {
348 swctrl |= GEN6_REG_BCS_SWCTRL_DST_TILING_Y << 16 |
349 GEN6_REG_BCS_SWCTRL_DST_TILING_Y;
350 }
351
352 if (src && src_tiling == INTEL_TILING_Y) {
353 swctrl |= GEN6_REG_BCS_SWCTRL_SRC_TILING_Y << 16 |
354 GEN6_REG_BCS_SWCTRL_SRC_TILING_Y;
355 }
356
357 if (swctrl) {
358 /*
359 * Most clients expect BLT engine to be stateless. If we have to set
360 * BCS_SWCTRL to a non-default value, we have to set it back in the same
361 * batch buffer.
362 */
363 if (ilo_cp_space(ilo->cp) < (4 + 3) * 2 + max_cmd_size)
364 ilo_cp_flush(ilo->cp, "out of space");
365
366 ilo_cp_assert_no_implicit_flush(ilo->cp, true);
367
368 /*
369 * From the Ivy Bridge PRM, volume 1 part 4, page 133:
370 *
371 * "SW is required to flush the HW before changing the polarity of
372 * this bit (Tile Y Destination/Source)."
373 */
374 gen6_emit_MI_FLUSH_DW(ilo->dev, ilo->cp);
375 gen6_emit_MI_LOAD_REGISTER_IMM(ilo->dev,
376 GEN6_REG_BCS_SWCTRL, swctrl, ilo->cp);
377
378 swctrl &= ~(GEN6_REG_BCS_SWCTRL_DST_TILING_Y |
379 GEN6_REG_BCS_SWCTRL_SRC_TILING_Y);
380 }
381
382 return swctrl;
383 }
384
385 static void
386 ilo_blitter_blt_end(struct ilo_blitter *blitter, uint32_t swctrl)
387 {
388 struct ilo_context *ilo = blitter->ilo;
389
390 /* set BCS_SWCTRL back */
391 if (swctrl) {
392 gen6_emit_MI_FLUSH_DW(ilo->dev, ilo->cp);
393 gen6_emit_MI_LOAD_REGISTER_IMM(ilo->dev, GEN6_REG_BCS_SWCTRL, swctrl, ilo->cp);
394
395 ilo_cp_assert_no_implicit_flush(ilo->cp, false);
396 }
397 }
398
399 static bool
400 buf_clear_region(struct ilo_blitter *blitter,
401 struct ilo_buffer *dst,
402 unsigned dst_offset, unsigned dst_size,
403 uint32_t val,
404 enum gen6_blt_mask value_mask,
405 enum gen6_blt_mask write_mask)
406 {
407 const uint8_t rop = 0xf0; /* PATCOPY */
408 const int cpp = gen6_translate_blt_cpp(value_mask);
409 struct ilo_context *ilo = blitter->ilo;
410 unsigned offset = 0;
411
412 if (dst_offset % cpp || dst_size % cpp)
413 return false;
414
415 ilo_blitter_blt_begin(blitter, 0,
416 dst->bo, INTEL_TILING_NONE, NULL, INTEL_TILING_NONE);
417
418 while (dst_size) {
419 unsigned width, height;
420 int16_t pitch;
421
422 width = dst_size;
423 height = 1;
424 pitch = 0;
425
426 if (width > gen6_max_bytes_per_scanline) {
427 /* less than INT16_MAX and dword-aligned */
428 pitch = 32764;
429
430 width = pitch;
431 height = dst_size / width;
432 if (height > gen6_max_scanlines)
433 height = gen6_max_scanlines;
434 }
435
436 gen6_emit_COLOR_BLT(ilo->dev, dst->bo, pitch, dst_offset + offset,
437 width, height, val, rop, value_mask, write_mask, ilo->cp);
438
439 offset += pitch * height;
440 dst_size -= width * height;
441 }
442
443 ilo_blitter_blt_end(blitter, 0);
444
445 return true;
446 }
447
448 static bool
449 buf_copy_region(struct ilo_blitter *blitter,
450 struct ilo_buffer *dst, unsigned dst_offset,
451 struct ilo_buffer *src, unsigned src_offset,
452 unsigned size)
453 {
454 const uint8_t rop = 0xcc; /* SRCCOPY */
455 struct ilo_context *ilo = blitter->ilo;
456 unsigned offset = 0;
457
458 ilo_blitter_blt_begin(blitter, 0,
459 dst->bo, INTEL_TILING_NONE, src->bo, INTEL_TILING_NONE);
460
461 while (size) {
462 unsigned width, height;
463 int16_t pitch;
464
465 width = size;
466 height = 1;
467 pitch = 0;
468
469 if (width > gen6_max_bytes_per_scanline) {
470 /* less than INT16_MAX and dword-aligned */
471 pitch = 32764;
472
473 width = pitch;
474 height = size / width;
475 if (height > gen6_max_scanlines)
476 height = gen6_max_scanlines;
477 }
478
479 gen6_emit_SRC_COPY_BLT(ilo->dev,
480 dst->bo, pitch, dst_offset + offset,
481 width, height,
482 src->bo, pitch, src_offset + offset,
483 false, rop, GEN6_BLT_MASK_8, GEN6_BLT_MASK_8,
484 ilo->cp);
485
486 offset += pitch * height;
487 size -= width * height;
488 }
489
490 ilo_blitter_blt_end(blitter, 0);
491
492 return true;
493 }
494
495 static bool
496 tex_clear_region(struct ilo_blitter *blitter,
497 struct ilo_texture *dst, unsigned dst_level,
498 const struct pipe_box *dst_box,
499 uint32_t val,
500 enum gen6_blt_mask value_mask,
501 enum gen6_blt_mask write_mask)
502 {
503 const int cpp = gen6_translate_blt_cpp(value_mask);
504 const unsigned max_extent = 32767; /* INT16_MAX */
505 const uint8_t rop = 0xf0; /* PATCOPY */
506 struct ilo_context *ilo = blitter->ilo;
507 uint32_t swctrl;
508 int slice;
509
510 /* no W-tiling support */
511 if (dst->separate_s8)
512 return false;
513
514 if (dst->layout.bo_stride > max_extent)
515 return false;
516
517 swctrl = ilo_blitter_blt_begin(blitter, dst_box->depth * 6,
518 dst->bo, dst->layout.tiling, NULL, INTEL_TILING_NONE);
519
520 for (slice = 0; slice < dst_box->depth; slice++) {
521 unsigned x1, y1, x2, y2;
522
523 ilo_layout_get_slice_pos(&dst->layout,
524 dst_level, dst_box->z + slice, &x1, &y1);
525
526 x1 += dst_box->x;
527 y1 += dst_box->y;
528 x2 = x1 + dst_box->width;
529 y2 = y1 + dst_box->height;
530
531 if (x2 > max_extent || y2 > max_extent ||
532 (x2 - x1) * cpp > gen6_max_bytes_per_scanline)
533 break;
534
535 gen6_emit_XY_COLOR_BLT(ilo->dev,
536 dst->bo, dst->layout.tiling, dst->layout.bo_stride, 0,
537 x1, y1, x2, y2, val, rop, value_mask, write_mask,
538 ilo->cp);
539 }
540
541 ilo_blitter_blt_end(blitter, swctrl);
542
543 return (slice == dst_box->depth);
544 }
545
546 static bool
547 tex_copy_region(struct ilo_blitter *blitter,
548 struct ilo_texture *dst,
549 unsigned dst_level,
550 unsigned dst_x, unsigned dst_y, unsigned dst_z,
551 struct ilo_texture *src,
552 unsigned src_level,
553 const struct pipe_box *src_box)
554 {
555 const struct util_format_description *desc =
556 util_format_description(dst->layout.format);
557 const unsigned max_extent = 32767; /* INT16_MAX */
558 const uint8_t rop = 0xcc; /* SRCCOPY */
559 struct ilo_context *ilo = blitter->ilo;
560 enum gen6_blt_mask mask;
561 uint32_t swctrl;
562 int cpp, xscale, slice;
563
564 /* no W-tiling support */
565 if (dst->separate_s8 || src->separate_s8)
566 return false;
567
568 if (dst->layout.bo_stride > max_extent ||
569 src->layout.bo_stride > max_extent)
570 return false;
571
572 cpp = desc->block.bits / 8;
573 xscale = 1;
574
575 /* accommodate for larger cpp */
576 if (cpp > 4) {
577 if (cpp % 2 == 1)
578 return false;
579
580 cpp = (cpp % 4 == 0) ? 4 : 2;
581 xscale = (desc->block.bits / 8) / cpp;
582 }
583
584 switch (cpp) {
585 case 1:
586 mask = GEN6_BLT_MASK_8;
587 break;
588 case 2:
589 mask = GEN6_BLT_MASK_16;
590 break;
591 case 4:
592 mask = GEN6_BLT_MASK_32;
593 break;
594 default:
595 return false;
596 break;
597 }
598
599 swctrl = ilo_blitter_blt_begin(blitter, src_box->depth * 8,
600 dst->bo, dst->layout.tiling, src->bo, src->layout.tiling);
601
602 for (slice = 0; slice < src_box->depth; slice++) {
603 unsigned x1, y1, x2, y2, src_x, src_y;
604
605 ilo_layout_get_slice_pos(&dst->layout,
606 dst_level, dst_z + slice, &x1, &y1);
607 x1 = (x1 + dst_x) * xscale;
608 y1 = y1 + dst_y;
609 x2 = (x1 + src_box->width) * xscale;
610 y2 = y1 + src_box->height;
611
612 ilo_layout_get_slice_pos(&src->layout,
613 src_level, src_box->z + slice, &src_x, &src_y);
614
615 src_x = (src_x + src_box->x) * xscale;
616 src_y += src_box->y;
617
618 /* in blocks */
619 x1 /= desc->block.width;
620 y1 /= desc->block.height;
621 x2 = (x2 + desc->block.width - 1) / desc->block.width;
622 y2 = (y2 + desc->block.height - 1) / desc->block.height;
623 src_x /= desc->block.width;
624 src_y /= desc->block.height;
625
626 if (x2 > max_extent || y2 > max_extent ||
627 src_x > max_extent || src_y > max_extent ||
628 (x2 - x1) * cpp > gen6_max_bytes_per_scanline)
629 break;
630
631 gen6_emit_XY_SRC_COPY_BLT(ilo->dev,
632 dst->bo, dst->layout.tiling, dst->layout.bo_stride, 0,
633 x1, y1, x2, y2,
634 src->bo, src->layout.tiling, src->layout.bo_stride, 0,
635 src_x, src_y, rop, mask, mask,
636 ilo->cp);
637 }
638
639 ilo_blitter_blt_end(blitter, swctrl);
640
641 return (slice == src_box->depth);
642 }
643
644 bool
645 ilo_blitter_blt_copy_resource(struct ilo_blitter *blitter,
646 struct pipe_resource *dst, unsigned dst_level,
647 unsigned dst_x, unsigned dst_y, unsigned dst_z,
648 struct pipe_resource *src, unsigned src_level,
649 const struct pipe_box *src_box)
650 {
651 bool success;
652
653 ilo_blit_resolve_slices(blitter->ilo, src, src_level,
654 src_box->z, src_box->depth, ILO_TEXTURE_BLT_READ);
655 ilo_blit_resolve_slices(blitter->ilo, dst, dst_level,
656 dst_z, src_box->depth, ILO_TEXTURE_BLT_WRITE);
657
658 if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
659 const unsigned dst_offset = dst_x;
660 const unsigned src_offset = src_box->x;
661 const unsigned size = src_box->width;
662
663 assert(dst_level == 0 && dst_y == 0 && dst_z == 0);
664 assert(src_level == 0 &&
665 src_box->y == 0 &&
666 src_box->z == 0 &&
667 src_box->height == 1 &&
668 src_box->depth == 1);
669
670 success = buf_copy_region(blitter,
671 ilo_buffer(dst), dst_offset, ilo_buffer(src), src_offset, size);
672 }
673 else if (dst->target != PIPE_BUFFER && src->target != PIPE_BUFFER) {
674 success = tex_copy_region(blitter,
675 ilo_texture(dst), dst_level, dst_x, dst_y, dst_z,
676 ilo_texture(src), src_level, src_box);
677 }
678 else {
679 success = false;
680 }
681
682 return success;
683 }
684
685 bool
686 ilo_blitter_blt_clear_rt(struct ilo_blitter *blitter,
687 struct pipe_surface *rt,
688 const union pipe_color_union *color,
689 unsigned x, unsigned y,
690 unsigned width, unsigned height)
691 {
692 const int cpp = util_format_get_blocksize(rt->format);
693 enum gen6_blt_mask mask;
694 union util_color packed;
695 bool success;
696
697 if (!ilo_3d_pass_render_condition(blitter->ilo))
698 return true;
699
700 switch (cpp) {
701 case 1:
702 mask = GEN6_BLT_MASK_8;
703 break;
704 case 2:
705 mask = GEN6_BLT_MASK_16;
706 break;
707 case 4:
708 mask = GEN6_BLT_MASK_32;
709 break;
710 default:
711 return false;
712 break;
713 }
714
715 if (util_format_is_pure_integer(rt->format) ||
716 util_format_is_compressed(rt->format))
717 return false;
718
719 ilo_blit_resolve_surface(blitter->ilo, rt, ILO_TEXTURE_BLT_WRITE);
720
721 util_pack_color(color->f, rt->format, &packed);
722
723 if (rt->texture->target == PIPE_BUFFER) {
724 unsigned offset, end, size;
725
726 assert(y == 0 && height == 1);
727
728 offset = (rt->u.buf.first_element + x) * cpp;
729 end = (rt->u.buf.last_element + 1) * cpp;
730
731 size = width * cpp;
732 if (offset + size > end)
733 size = end - offset;
734
735 success = buf_clear_region(blitter, ilo_buffer(rt->texture),
736 offset, size, packed.ui[0], mask, mask);
737 }
738 else {
739 struct pipe_box box;
740
741 u_box_3d(x, y, rt->u.tex.first_layer, width, height,
742 rt->u.tex.last_layer - rt->u.tex.first_layer + 1, &box);
743
744 success = tex_clear_region(blitter, ilo_texture(rt->texture),
745 rt->u.tex.level, &box, packed.ui[0], mask, mask);
746 }
747
748 return success;
749 }
750
751 bool
752 ilo_blitter_blt_clear_zs(struct ilo_blitter *blitter,
753 struct pipe_surface *zs,
754 unsigned clear_flags,
755 double depth, unsigned stencil,
756 unsigned x, unsigned y,
757 unsigned width, unsigned height)
758 {
759 enum gen6_blt_mask value_mask, write_mask;
760 struct pipe_box box;
761 uint32_t val;
762
763 if (!ilo_3d_pass_render_condition(blitter->ilo))
764 return true;
765
766 switch (zs->format) {
767 case PIPE_FORMAT_Z16_UNORM:
768 if (!(clear_flags & PIPE_CLEAR_DEPTH))
769 return true;
770
771 value_mask = GEN6_BLT_MASK_16;
772 write_mask = GEN6_BLT_MASK_16;
773 break;
774 case PIPE_FORMAT_Z32_FLOAT:
775 if (!(clear_flags & PIPE_CLEAR_DEPTH))
776 return true;
777
778 value_mask = GEN6_BLT_MASK_32;
779 write_mask = GEN6_BLT_MASK_32;
780 break;
781 case PIPE_FORMAT_Z24X8_UNORM:
782 if (!(clear_flags & PIPE_CLEAR_DEPTH))
783 return true;
784
785 value_mask = GEN6_BLT_MASK_32;
786 write_mask = GEN6_BLT_MASK_32_LO;
787 break;
788 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
789 if (!(clear_flags & PIPE_CLEAR_DEPTHSTENCIL))
790 return true;
791
792 value_mask = GEN6_BLT_MASK_32;
793
794 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL)
795 write_mask = GEN6_BLT_MASK_32;
796 else if (clear_flags & PIPE_CLEAR_DEPTH)
797 write_mask = GEN6_BLT_MASK_32_LO;
798 else
799 write_mask = GEN6_BLT_MASK_32_HI;
800 break;
801 default:
802 return false;
803 break;
804 }
805
806 ilo_blit_resolve_surface(blitter->ilo, zs, ILO_TEXTURE_BLT_WRITE);
807
808 val = util_pack_z_stencil(zs->format, depth, stencil);
809
810 u_box_3d(x, y, zs->u.tex.first_layer, width, height,
811 zs->u.tex.last_layer - zs->u.tex.first_layer + 1, &box);
812
813 assert(zs->texture->target != PIPE_BUFFER);
814
815 return tex_clear_region(blitter, ilo_texture(zs->texture),
816 zs->u.tex.level, &box, val, value_mask, write_mask);
817 }