ilo: switch to ilo states for CC stage
[mesa.git] / src / gallium / drivers / ilo / ilo_blit.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-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 "util/u_blitter.h"
29 #include "util/u_clear.h"
30 #include "util/u_pack_color.h"
31 #include "util/u_surface.h"
32 #include "intel_reg.h"
33
34 #include "ilo_context.h"
35 #include "ilo_cp.h"
36 #include "ilo_resource.h"
37 #include "ilo_screen.h"
38 #include "ilo_blit.h"
39
40 /*
41 * From the Sandy Bridge PRM, volume 1 part 5, page 7:
42 *
43 * "The BLT engine is capable of transferring very large quantities of
44 * graphics data. Any graphics data read from and written to the
45 * destination is permitted to represent a number of pixels that occupies
46 * up to 65,536 scan lines and up to 32,768 bytes per scan line at the
47 * destination. The maximum number of pixels that may be represented per
48 * scan line's worth of graphics data depends on the color depth."
49 */
50 static const int gen6_max_bytes_per_scanline = 32768;
51 static const int gen6_max_scanlines = 65536;
52
53 static void
54 ilo_blit_own_blt_ring(struct ilo_context *ilo)
55 {
56 ilo_cp_set_ring(ilo->cp, ILO_CP_RING_BLT);
57 ilo_cp_set_owner(ilo->cp, NULL, 0);
58 }
59
60 static void
61 gen6_MI_FLUSH_DW(struct ilo_context *ilo)
62 {
63 const uint8_t cmd_len = 4;
64 struct ilo_cp *cp = ilo->cp;
65
66 ilo_cp_begin(cp, cmd_len);
67 ilo_cp_write(cp, MI_FLUSH_DW | (cmd_len - 2));
68 ilo_cp_write(cp, 0);
69 ilo_cp_write(cp, 0);
70 ilo_cp_write(cp, 0);
71 ilo_cp_end(cp);
72 }
73
74 static void
75 gen6_MI_LOAD_REGISTER_IMM(struct ilo_context *ilo, uint32_t reg, uint32_t val)
76 {
77 const uint8_t cmd_len = 3;
78 struct ilo_cp *cp = ilo->cp;
79
80 ilo_cp_begin(cp, cmd_len);
81 ilo_cp_write(cp, MI_LOAD_REGISTER_IMM | (cmd_len - 2));
82 ilo_cp_write(cp, reg);
83 ilo_cp_write(cp, val);
84 ilo_cp_end(cp);
85 }
86
87 static void
88 gen6_XY_COLOR_BLT(struct ilo_context *ilo, struct intel_bo *dst_bo,
89 uint32_t dst_offset, int16_t dst_pitch,
90 enum intel_tiling_mode dst_tiling,
91 int16_t x1, int16_t y1, int16_t x2, int16_t y2,
92 uint32_t color,
93 uint8_t rop, int cpp, bool write_alpha)
94 {
95 const uint8_t cmd_len = 6;
96 struct ilo_cp *cp = ilo->cp;
97 int dst_align, dst_pitch_shift;
98 uint32_t dw0, dw1;
99
100 dw0 = XY_COLOR_BLT_CMD | (cmd_len - 2);
101
102 if (dst_tiling == INTEL_TILING_NONE) {
103 dst_align = 4;
104 dst_pitch_shift = 0;
105 }
106 else {
107 dw0 |= XY_DST_TILED;
108
109 dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
110 /* in dwords when tiled */
111 dst_pitch_shift = 2;
112 }
113
114 assert(cpp == 4 || cpp == 2 || cpp == 1);
115 assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
116 assert(y2 - y1 < gen6_max_scanlines);
117 assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
118
119 dw1 = rop << 16 |
120 dst_pitch >> dst_pitch_shift;
121
122 switch (cpp) {
123 case 4:
124 dw0 |= XY_BLT_WRITE_RGB;
125 if (write_alpha)
126 dw0 |= XY_BLT_WRITE_ALPHA;
127
128 dw1 |= BR13_8888;
129 break;
130 case 2:
131 dw1 |= BR13_565;
132 break;
133 case 1:
134 dw1 |= BR13_8;
135 break;
136 }
137
138 ilo_cp_begin(cp, cmd_len);
139 ilo_cp_write(cp, dw0);
140 ilo_cp_write(cp, dw1);
141 ilo_cp_write(cp, y1 << 16 | x1);
142 ilo_cp_write(cp, y2 << 16 | x2);
143 ilo_cp_write_bo(cp, dst_offset, dst_bo,
144 INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
145 ilo_cp_write(cp, color);
146 ilo_cp_end(cp);
147 }
148
149 static void
150 gen6_SRC_COPY_BLT(struct ilo_context *ilo, struct intel_bo *dst_bo,
151 uint32_t dst_offset, int16_t dst_pitch,
152 uint16_t width, uint16_t height,
153 struct intel_bo *src_bo,
154 uint32_t src_offset, int16_t src_pitch,
155 uint8_t rop, int cpp, bool write_alpha, bool dir_rtl)
156 {
157 const uint8_t cmd_len = 6;
158 struct ilo_cp *cp = ilo->cp;
159 uint32_t dw0, dw1;
160
161 assert(cpp == 4 || cpp == 2 || cpp == 1);
162 assert(width < gen6_max_bytes_per_scanline);
163 assert(height < gen6_max_scanlines);
164 /* offsets are naturally aligned and pitches are dword-aligned */
165 assert(dst_offset % cpp == 0 && dst_pitch % 4 == 0);
166 assert(src_offset % cpp == 0 && src_pitch % 4 == 0);
167
168 #ifndef SRC_COPY_BLT_CMD
169 #define SRC_COPY_BLT_CMD (CMD_2D | (0x43 << 22))
170 #endif
171 dw0 = SRC_COPY_BLT_CMD | (cmd_len - 2);
172 dw1 = rop << 16 | dst_pitch;
173
174 if (dir_rtl)
175 dw1 |= 1 << 30;
176
177 switch (cpp) {
178 case 4:
179 dw0 |= XY_BLT_WRITE_RGB;
180 if (write_alpha)
181 dw0 |= XY_BLT_WRITE_ALPHA;
182
183 dw1 |= BR13_8888;
184 break;
185 case 2:
186 dw1 |= BR13_565;
187 break;
188 case 1:
189 dw1 |= BR13_8;
190 break;
191 }
192
193 ilo_cp_begin(cp, cmd_len);
194 ilo_cp_write(cp, dw0);
195 ilo_cp_write(cp, dw1);
196 ilo_cp_write(cp, height << 16 | width);
197 ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
198 INTEL_DOMAIN_RENDER);
199 ilo_cp_write(cp, src_pitch);
200 ilo_cp_write_bo(cp, src_offset, src_bo, INTEL_DOMAIN_RENDER, 0);
201 ilo_cp_end(cp);
202 }
203
204 static void
205 gen6_XY_SRC_COPY_BLT(struct ilo_context *ilo, struct intel_bo *dst_bo,
206 uint32_t dst_offset, int16_t dst_pitch,
207 enum intel_tiling_mode dst_tiling,
208 int16_t x1, int16_t y1, int16_t x2, int16_t y2,
209 struct intel_bo *src_bo,
210 uint32_t src_offset, int16_t src_pitch,
211 enum intel_tiling_mode src_tiling,
212 int16_t src_x, int16_t src_y,
213 uint8_t rop, int cpp, bool write_alpha)
214 {
215 const uint8_t cmd_len = 8;
216 struct ilo_cp *cp = ilo->cp;
217 int dst_align, dst_pitch_shift;
218 int src_align, src_pitch_shift;
219 uint32_t dw0, dw1;
220
221 dw0 = XY_SRC_COPY_BLT_CMD | (cmd_len - 2);
222
223 if (dst_tiling == INTEL_TILING_NONE) {
224 dst_align = 4;
225 dst_pitch_shift = 0;
226 }
227 else {
228 dw0 |= XY_DST_TILED;
229
230 dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
231 /* in dwords when tiled */
232 dst_pitch_shift = 2;
233 }
234
235 if (src_tiling == INTEL_TILING_NONE) {
236 src_align = 4;
237 src_pitch_shift = 0;
238 }
239 else {
240 dw0 |= XY_SRC_TILED;
241
242 src_align = (src_tiling == INTEL_TILING_Y) ? 128 : 512;
243 /* in dwords when tiled */
244 src_pitch_shift = 2;
245 }
246
247 assert(cpp == 4 || cpp == 2 || cpp == 1);
248 assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
249 assert(y2 - y1 < gen6_max_scanlines);
250 assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
251 assert(src_offset % src_align == 0 && src_pitch % src_align == 0);
252
253 dw1 = rop << 16 |
254 dst_pitch >> dst_pitch_shift;
255
256 switch (cpp) {
257 case 4:
258 dw0 |= XY_BLT_WRITE_RGB;
259 if (write_alpha)
260 dw0 |= XY_BLT_WRITE_ALPHA;
261
262 dw1 |= BR13_8888;
263 break;
264 case 2:
265 dw1 |= BR13_565;
266 break;
267 case 1:
268 dw1 |= BR13_8;
269 break;
270 }
271
272 ilo_cp_begin(cp, cmd_len);
273 ilo_cp_write(cp, dw0);
274 ilo_cp_write(cp, dw1);
275 ilo_cp_write(cp, y1 << 16 | x1);
276 ilo_cp_write(cp, y2 << 16 | x2);
277 ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
278 INTEL_DOMAIN_RENDER);
279 ilo_cp_write(cp, src_y << 16 | src_x);
280 ilo_cp_write(cp, src_pitch >> src_pitch_shift);
281 ilo_cp_write_bo(cp, src_offset, src_bo, INTEL_DOMAIN_RENDER, 0);
282 ilo_cp_end(cp);
283 }
284
285 static bool
286 tex_copy_region(struct ilo_context *ilo,
287 struct ilo_texture *dst,
288 unsigned dst_level,
289 unsigned dst_x, unsigned dst_y, unsigned dst_z,
290 struct ilo_texture *src,
291 unsigned src_level,
292 const struct pipe_box *src_box)
293 {
294 const struct util_format_description *desc =
295 util_format_description(dst->bo_format);
296 const unsigned max_extent = 32767; /* INT16_MAX */
297 const uint8_t rop = 0xcc; /* SRCCOPY */
298 struct intel_bo *aper_check[3];
299 uint32_t swctrl;
300 int cpp, xscale, slice;
301
302 /* no W-tiling support */
303 if (dst->separate_s8 || src->separate_s8)
304 return false;
305
306 if (dst->bo_stride > max_extent || src->bo_stride > max_extent)
307 return false;
308
309 cpp = desc->block.bits / 8;
310 xscale = 1;
311
312 /* accommodate for larger cpp */
313 if (cpp > 4) {
314 if (cpp % 2 == 1)
315 return false;
316
317 cpp = (cpp % 4 == 0) ? 4 : 2;
318 xscale = (desc->block.bits / 8) / cpp;
319 }
320
321 ilo_blit_own_blt_ring(ilo);
322
323 /* make room if necessary */
324 aper_check[0] = ilo->cp->bo;
325 aper_check[1] = dst->bo;
326 aper_check[2] = src->bo;
327 if (ilo->winsys->check_aperture_space(ilo->winsys, aper_check, 3))
328 ilo_cp_flush(ilo->cp);
329
330 swctrl = 0x0;
331
332 if (dst->tiling == INTEL_TILING_Y) {
333 swctrl |= BCS_SWCTRL_DST_Y << 16 |
334 BCS_SWCTRL_DST_Y;
335 }
336
337 if (src->tiling == INTEL_TILING_Y) {
338 swctrl |= BCS_SWCTRL_SRC_Y << 16 |
339 BCS_SWCTRL_SRC_Y;
340 }
341
342 if (swctrl) {
343 /*
344 * Most clients expect BLT engine to be stateless. If we have to set
345 * BCS_SWCTRL to a non-default value, we have to set it back in the same
346 * batch buffer.
347 */
348 if (ilo_cp_space(ilo->cp) < (4 + 3) * 2 + src_box->depth * 8)
349 ilo_cp_flush(ilo->cp);
350
351 ilo_cp_assert_no_implicit_flush(ilo->cp, true);
352
353 /*
354 * From the Ivy Bridge PRM, volume 1 part 4, page 133:
355 *
356 * "SW is required to flush the HW before changing the polarity of
357 * this bit (Tile Y Destination/Source)."
358 */
359 gen6_MI_FLUSH_DW(ilo);
360 gen6_MI_LOAD_REGISTER_IMM(ilo, BCS_SWCTRL, swctrl);
361
362 swctrl &= ~(BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y);
363 }
364
365 for (slice = 0; slice < src_box->depth; slice++) {
366 const struct ilo_texture_slice *dst_slice =
367 &dst->slice_offsets[dst_level][dst_z + slice];
368 const struct ilo_texture_slice *src_slice =
369 &src->slice_offsets[src_level][src_box->z + slice];
370 unsigned x1, y1, x2, y2, src_x, src_y;
371
372 x1 = (dst_slice->x + dst_x) * xscale;
373 y1 = dst_slice->y + dst_y;
374 x2 = (x1 + src_box->width) * xscale;
375 y2 = y1 + src_box->height;
376 src_x = (src_slice->x + src_box->x) * xscale;
377 src_y = src_slice->y + src_box->y;
378
379 x1 /= desc->block.width;
380 y1 /= desc->block.height;
381 x2 = (x2 + desc->block.width - 1) / desc->block.width;
382 y2 = (y2 + desc->block.height - 1) / desc->block.height;
383 src_x /= desc->block.width;
384 src_y /= desc->block.height;
385
386 if (x2 > max_extent || y2 > max_extent ||
387 src_x > max_extent || src_y > max_extent ||
388 (x2 - x1) * cpp > gen6_max_bytes_per_scanline)
389 break;
390
391 gen6_XY_SRC_COPY_BLT(ilo,
392 dst->bo, 0, dst->bo_stride, dst->tiling,
393 x1, y1, x2, y2,
394 src->bo, 0, src->bo_stride, src->tiling,
395 src_x, src_y, rop, cpp, true);
396 }
397
398 if (swctrl) {
399 gen6_MI_FLUSH_DW(ilo);
400 gen6_MI_LOAD_REGISTER_IMM(ilo, BCS_SWCTRL, swctrl);
401
402 ilo_cp_assert_no_implicit_flush(ilo->cp, false);
403 }
404
405 return (slice == src_box->depth);
406 }
407
408 static bool
409 buf_copy_region(struct ilo_context *ilo,
410 struct ilo_buffer *dst, unsigned dst_offset,
411 struct ilo_buffer *src, unsigned src_offset,
412 unsigned size)
413 {
414 const uint8_t rop = 0xcc; /* SRCCOPY */
415 unsigned offset = 0;
416 struct intel_bo *aper_check[3];
417
418 ilo_blit_own_blt_ring(ilo);
419
420 /* make room if necessary */
421 aper_check[0] = ilo->cp->bo;
422 aper_check[1] = dst->bo;
423 aper_check[2] = src->bo;
424 if (ilo->winsys->check_aperture_space(ilo->winsys, aper_check, 3))
425 ilo_cp_flush(ilo->cp);
426
427 while (size) {
428 unsigned width, height;
429 int16_t pitch;
430
431 width = 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 = size / width;
441 if (height > gen6_max_scanlines)
442 height = gen6_max_scanlines;
443 }
444
445 gen6_SRC_COPY_BLT(ilo,
446 dst->bo, dst_offset + offset, pitch,
447 width, height,
448 src->bo, src_offset + offset, pitch,
449 rop, 1, true, false);
450
451 offset += pitch * height;
452 size -= width * height;
453 }
454
455 return true;
456 }
457
458 static void
459 ilo_resource_copy_region(struct pipe_context *pipe,
460 struct pipe_resource *dst,
461 unsigned dst_level,
462 unsigned dstx, unsigned dsty, unsigned dstz,
463 struct pipe_resource *src,
464 unsigned src_level,
465 const struct pipe_box *src_box)
466 {
467 bool success;
468
469 if (dst->target != PIPE_BUFFER && src->target != PIPE_BUFFER) {
470 success = tex_copy_region(ilo_context(pipe),
471 ilo_texture(dst), dst_level, dstx, dsty, dstz,
472 ilo_texture(src), src_level, src_box);
473 }
474 else if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
475 const unsigned dst_offset = dstx;
476 const unsigned src_offset = src_box->x;
477 const unsigned size = src_box->width;
478
479 assert(dst_level == 0 && dsty == 0 && dstz == 0);
480 assert(src_level == 0 &&
481 src_box->y == 0 &&
482 src_box->z == 0 &&
483 src_box->height == 1 &&
484 src_box->depth == 1);
485
486 success = buf_copy_region(ilo_context(pipe),
487 ilo_buffer(dst), dst_offset, ilo_buffer(src), src_offset, size);
488 }
489 else {
490 success = false;
491 }
492
493 if (!success) {
494 util_resource_copy_region(pipe, dst, dst_level,
495 dstx, dsty, dstz, src, src_level, src_box);
496 }
497 }
498
499 static bool
500 blitter_xy_color_blt(struct pipe_context *pipe,
501 struct pipe_resource *res,
502 int16_t x1, int16_t y1,
503 int16_t x2, int16_t y2,
504 uint32_t color)
505 {
506 struct ilo_context *ilo = ilo_context(pipe);
507 struct ilo_texture *tex = ilo_texture(res);
508 const int cpp = util_format_get_blocksize(tex->bo_format);
509 const uint8_t rop = 0xf0; /* PATCOPY */
510 struct intel_bo *aper_check[2];
511
512 /* how to support Y-tiling? */
513 if (tex->tiling == INTEL_TILING_Y)
514 return false;
515
516 /* nothing to clear */
517 if (x1 >= x2 || y1 >= y2)
518 return true;
519
520 ilo_blit_own_blt_ring(ilo);
521
522 /* make room if necessary */
523 aper_check[0] = ilo->cp->bo;
524 aper_check[1] = tex->bo;
525 if (ilo->winsys->check_aperture_space(ilo->winsys, aper_check, 2))
526 ilo_cp_flush(ilo->cp);
527
528 gen6_XY_COLOR_BLT(ilo,
529 tex->bo, 0, tex->bo_stride, tex->tiling,
530 x1, y1, x2, y2, color, rop, cpp, true);
531
532 return true;
533 }
534
535 enum ilo_blitter_op {
536 ILO_BLITTER_CLEAR,
537 ILO_BLITTER_CLEAR_SURFACE,
538 ILO_BLITTER_BLIT,
539 };
540
541 static void
542 ilo_blitter_begin(struct ilo_context *ilo, enum ilo_blitter_op op)
543 {
544 /* as documented in util/u_blitter.h */
545 util_blitter_save_vertex_buffer_slot(ilo->blitter, ilo->vb.states);
546 util_blitter_save_vertex_elements(ilo->blitter, (void *) ilo->ve);
547 util_blitter_save_vertex_shader(ilo->blitter, ilo->vs);
548 util_blitter_save_geometry_shader(ilo->blitter, ilo->gs);
549 util_blitter_save_so_targets(ilo->blitter, ilo->so.count, ilo->so.states);
550
551 util_blitter_save_fragment_shader(ilo->blitter, ilo->fs);
552 util_blitter_save_depth_stencil_alpha(ilo->blitter, (void *) ilo->dsa);
553 util_blitter_save_blend(ilo->blitter, (void *) ilo->blend);
554
555 /* undocumented? */
556 util_blitter_save_viewport(ilo->blitter, &ilo->viewport.states[0]);
557 util_blitter_save_stencil_ref(ilo->blitter, &ilo->stencil_ref);
558 util_blitter_save_sample_mask(ilo->blitter, ilo->sample_mask);
559
560 switch (op) {
561 case ILO_BLITTER_CLEAR:
562 util_blitter_save_rasterizer(ilo->blitter, (void *) ilo->rasterizer);
563 break;
564 case ILO_BLITTER_CLEAR_SURFACE:
565 util_blitter_save_framebuffer(ilo->blitter, &ilo->fb.state);
566 break;
567 case ILO_BLITTER_BLIT:
568 util_blitter_save_rasterizer(ilo->blitter, (void *) ilo->rasterizer);
569 util_blitter_save_framebuffer(ilo->blitter, &ilo->fb.state);
570
571 util_blitter_save_fragment_sampler_states(ilo->blitter,
572 ilo->samplers[PIPE_SHADER_FRAGMENT].num_samplers,
573 (void **) ilo->samplers[PIPE_SHADER_FRAGMENT].samplers);
574
575 util_blitter_save_fragment_sampler_views(ilo->blitter,
576 ilo->sampler_views[PIPE_SHADER_FRAGMENT].num_views,
577 ilo->sampler_views[PIPE_SHADER_FRAGMENT].views);
578
579 /* disable render condition? */
580 break;
581 default:
582 break;
583 }
584 }
585
586 static void
587 ilo_blitter_end(struct ilo_context *ilo)
588 {
589 }
590
591 static void
592 ilo_clear(struct pipe_context *pipe,
593 unsigned buffers,
594 const union pipe_color_union *color,
595 double depth,
596 unsigned stencil)
597 {
598 struct ilo_context *ilo = ilo_context(pipe);
599
600 /* TODO we should pause/resume some queries */
601 ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR);
602
603 util_blitter_clear(ilo->blitter,
604 ilo->fb.state.width, ilo->fb.state.height,
605 ilo->fb.state.nr_cbufs, buffers,
606 (ilo->fb.state.nr_cbufs) ? ilo->fb.state.cbufs[0]->format :
607 PIPE_FORMAT_NONE,
608 color, depth, stencil);
609
610 ilo_blitter_end(ilo);
611 }
612
613 static void
614 ilo_clear_render_target(struct pipe_context *pipe,
615 struct pipe_surface *dst,
616 const union pipe_color_union *color,
617 unsigned dstx, unsigned dsty,
618 unsigned width, unsigned height)
619 {
620 struct ilo_context *ilo = ilo_context(pipe);
621 union util_color packed;
622
623 if (!width || !height || dstx >= dst->width || dsty >= dst->height)
624 return;
625
626 if (dstx + width > dst->width)
627 width = dst->width - dstx;
628 if (dsty + height > dst->height)
629 height = dst->height - dsty;
630
631 util_pack_color(color->f, dst->format, &packed);
632
633 /* try HW blit first */
634 if (blitter_xy_color_blt(pipe, dst->texture,
635 dstx, dsty,
636 dstx + width, dsty + height,
637 packed.ui))
638 return;
639
640 ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE);
641 util_blitter_clear_render_target(ilo->blitter,
642 dst, color, dstx, dsty, width, height);
643 ilo_blitter_end(ilo);
644 }
645
646 static void
647 ilo_clear_depth_stencil(struct pipe_context *pipe,
648 struct pipe_surface *dst,
649 unsigned clear_flags,
650 double depth,
651 unsigned stencil,
652 unsigned dstx, unsigned dsty,
653 unsigned width, unsigned height)
654 {
655 struct ilo_context *ilo = ilo_context(pipe);
656
657 /*
658 * The PRM claims that HW blit supports Y-tiling since GEN6, but it does
659 * not tell us how to program it. Since depth buffers are always Y-tiled,
660 * HW blit will not work.
661 */
662 ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE);
663 util_blitter_clear_depth_stencil(ilo->blitter,
664 dst, clear_flags, depth, stencil, dstx, dsty, width, height);
665 ilo_blitter_end(ilo);
666 }
667
668 static void
669 ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
670 {
671 struct ilo_context *ilo = ilo_context(pipe);
672 struct pipe_blit_info skip_stencil;
673
674 if (util_try_blit_via_copy_region(pipe, info))
675 return;
676
677 if (!util_blitter_is_blit_supported(ilo->blitter, info)) {
678 /* try without stencil */
679 if (info->mask & PIPE_MASK_S) {
680 skip_stencil = *info;
681 skip_stencil.mask = info->mask & ~PIPE_MASK_S;
682
683 if (util_blitter_is_blit_supported(ilo->blitter, &skip_stencil))
684 info = &skip_stencil;
685 }
686
687 if (info == &skip_stencil) {
688 ilo_warn("ignore stencil buffer blitting\n");
689 }
690 else {
691 ilo_warn("failed to blit with the generic blitter\n");
692 return;
693 }
694 }
695
696 ilo_blitter_begin(ilo, ILO_BLITTER_BLIT);
697 util_blitter_blit(ilo->blitter, info);
698 ilo_blitter_end(ilo);
699 }
700
701 /**
702 * Initialize blit-related functions.
703 */
704 void
705 ilo_init_blit_functions(struct ilo_context *ilo)
706 {
707 ilo->base.resource_copy_region = ilo_resource_copy_region;
708 ilo->base.blit = ilo_blit;
709
710 ilo->base.clear = ilo_clear;
711 ilo->base.clear_render_target = ilo_clear_render_target;
712 ilo->base.clear_depth_stencil = ilo_clear_depth_stencil;
713 }