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