Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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