intel: Conditionally compile mcs-related code for i965 only.
[mesa.git] / src / mesa / drivers / dri / intel / intel_blit.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "main/mtypes.h"
30 #include "main/context.h"
31 #include "main/enums.h"
32 #include "main/colormac.h"
33 #include "main/fbobject.h"
34
35 #include "intel_blit.h"
36 #include "intel_buffers.h"
37 #include "intel_context.h"
38 #include "intel_fbo.h"
39 #include "intel_reg.h"
40 #include "intel_regions.h"
41 #include "intel_batchbuffer.h"
42 #include "intel_mipmap_tree.h"
43
44 #define FILE_DEBUG_FLAG DEBUG_BLIT
45
46 static GLuint translate_raster_op(GLenum logicop)
47 {
48 switch(logicop) {
49 case GL_CLEAR: return 0x00;
50 case GL_AND: return 0x88;
51 case GL_AND_REVERSE: return 0x44;
52 case GL_COPY: return 0xCC;
53 case GL_AND_INVERTED: return 0x22;
54 case GL_NOOP: return 0xAA;
55 case GL_XOR: return 0x66;
56 case GL_OR: return 0xEE;
57 case GL_NOR: return 0x11;
58 case GL_EQUIV: return 0x99;
59 case GL_INVERT: return 0x55;
60 case GL_OR_REVERSE: return 0xDD;
61 case GL_COPY_INVERTED: return 0x33;
62 case GL_OR_INVERTED: return 0xBB;
63 case GL_NAND: return 0x77;
64 case GL_SET: return 0xFF;
65 default: return 0;
66 }
67 }
68
69 static uint32_t
70 br13_for_cpp(int cpp)
71 {
72 switch (cpp) {
73 case 4:
74 return BR13_8888;
75 break;
76 case 2:
77 return BR13_565;
78 break;
79 case 1:
80 return BR13_8;
81 break;
82 default:
83 assert(0);
84 return 0;
85 }
86 }
87
88 /**
89 * Implements a rectangular block transfer (blit) of pixels between two
90 * miptrees.
91 *
92 * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous,
93 * but limited, pitches and sizes allowed.
94 *
95 * The src/dst coordinates are relative to the given level/slice of the
96 * miptree.
97 *
98 * If @src_flip or @dst_flip is set, then the rectangle within that miptree
99 * will be inverted (including scanline order) when copying. This is common
100 * in GL when copying between window system and user-created
101 * renderbuffers/textures.
102 */
103 bool
104 intel_miptree_blit(struct intel_context *intel,
105 struct intel_mipmap_tree *src_mt,
106 int src_level, int src_slice,
107 uint32_t src_x, uint32_t src_y, bool src_flip,
108 struct intel_mipmap_tree *dst_mt,
109 int dst_level, int dst_slice,
110 uint32_t dst_x, uint32_t dst_y, bool dst_flip,
111 uint32_t width, uint32_t height,
112 GLenum logicop)
113 {
114 /* We don't assert on format because we may blit from ARGB8888 to XRGB8888,
115 * for example.
116 */
117 assert(src_mt->cpp == dst_mt->cpp);
118
119 /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
120 * Data Size Limitations):
121 *
122 * The BLT engine is capable of transferring very large quantities of
123 * graphics data. Any graphics data read from and written to the
124 * destination is permitted to represent a number of pixels that
125 * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line
126 * at the destination. The maximum number of pixels that may be
127 * represented per scan line’s worth of graphics data depends on the
128 * color depth.
129 *
130 * Furthermore, intelEmitCopyBlit (which is called below) uses a signed
131 * 16-bit integer to represent buffer pitch, so it can only handle buffer
132 * pitches < 32k.
133 *
134 * As a result of these two limitations, we can only use the blitter to do
135 * this copy when the region's pitch is less than 32k.
136 */
137 if (src_mt->region->pitch > 32768 ||
138 dst_mt->region->pitch > 32768) {
139 perf_debug("Falling back due to >32k pitch\n");
140 return false;
141 }
142
143 /* The blitter has no idea about HiZ, so we need to get the real depth
144 * data into the two miptrees before we do anything.
145 */
146 intel_miptree_slice_resolve_depth(intel, src_mt, src_level, src_slice);
147 intel_miptree_slice_resolve_depth(intel, dst_mt, dst_level, dst_slice);
148
149 if (src_flip)
150 src_y = src_mt->level[src_level].height - src_y - height;
151
152 if (dst_flip)
153 dst_y = dst_mt->level[dst_level].height - dst_y - height;
154
155 int src_pitch = src_mt->region->pitch;
156 if (src_flip != dst_flip)
157 src_pitch = -src_pitch;
158
159 uint32_t src_image_x, src_image_y;
160 intel_miptree_get_image_offset(src_mt, src_level, src_slice,
161 &src_image_x, &src_image_y);
162 src_x += src_image_x;
163 src_y += src_image_y;
164
165 uint32_t dst_image_x, dst_image_y;
166 intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice,
167 &dst_image_x, &dst_image_y);
168 dst_x += dst_image_x;
169 dst_y += dst_image_y;
170
171 return intelEmitCopyBlit(intel,
172 src_mt->cpp,
173 src_pitch,
174 src_mt->region->bo, src_mt->offset,
175 src_mt->region->tiling,
176 dst_mt->region->pitch,
177 dst_mt->region->bo, dst_mt->offset,
178 dst_mt->region->tiling,
179 src_x, src_y,
180 dst_x, dst_y,
181 width, height,
182 logicop);
183 }
184
185 /* Copy BitBlt
186 */
187 bool
188 intelEmitCopyBlit(struct intel_context *intel,
189 GLuint cpp,
190 GLshort src_pitch,
191 drm_intel_bo *src_buffer,
192 GLuint src_offset,
193 uint32_t src_tiling,
194 GLshort dst_pitch,
195 drm_intel_bo *dst_buffer,
196 GLuint dst_offset,
197 uint32_t dst_tiling,
198 GLshort src_x, GLshort src_y,
199 GLshort dst_x, GLshort dst_y,
200 GLshort w, GLshort h,
201 GLenum logic_op)
202 {
203 GLuint CMD, BR13, pass = 0;
204 int dst_y2 = dst_y + h;
205 int dst_x2 = dst_x + w;
206 drm_intel_bo *aper_array[3];
207 uint32_t bcs_swctrl = 0;
208 BATCH_LOCALS;
209
210 if (dst_tiling != I915_TILING_NONE) {
211 if (dst_offset & 4095)
212 return false;
213 if (dst_tiling == I915_TILING_Y && intel->gen < 6)
214 return false;
215 }
216 if (src_tiling != I915_TILING_NONE) {
217 if (src_offset & 4095)
218 return false;
219 if (src_tiling == I915_TILING_Y && intel->gen < 6)
220 return false;
221 }
222
223 /* do space check before going any further */
224 do {
225 aper_array[0] = intel->batch.bo;
226 aper_array[1] = dst_buffer;
227 aper_array[2] = src_buffer;
228
229 if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
230 intel_batchbuffer_flush(intel);
231 pass++;
232 } else
233 break;
234 } while (pass < 2);
235
236 if (pass >= 2)
237 return false;
238
239 intel_batchbuffer_require_space(intel, 8 * 4, true);
240 DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
241 __FUNCTION__,
242 src_buffer, src_pitch, src_offset, src_x, src_y,
243 dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
244
245 /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop
246 * the low bits.
247 */
248 if (src_pitch % 4 != 0 || dst_pitch % 4 != 0)
249 return false;
250
251 /* For big formats (such as floating point), do the copy using 16 or 32bpp
252 * and multiply the coordinates.
253 */
254 if (cpp > 4) {
255 if (cpp % 4 == 2) {
256 dst_x *= cpp / 2;
257 dst_x2 *= cpp / 2;
258 src_x *= cpp / 2;
259 cpp = 2;
260 } else {
261 assert(cpp % 4 == 0);
262 dst_x *= cpp / 4;
263 dst_x2 *= cpp / 4;
264 src_x *= cpp / 4;
265 cpp = 4;
266 }
267 }
268
269 BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
270
271 switch (cpp) {
272 case 1:
273 case 2:
274 CMD = XY_SRC_COPY_BLT_CMD;
275 break;
276 case 4:
277 CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
278 break;
279 default:
280 return false;
281 }
282
283 #ifndef I915
284 if (dst_tiling != I915_TILING_NONE) {
285 CMD |= XY_DST_TILED;
286 dst_pitch /= 4;
287
288 if (dst_tiling == I915_TILING_Y)
289 bcs_swctrl |= BCS_SWCTRL_DST_Y;
290 }
291 if (src_tiling != I915_TILING_NONE) {
292 CMD |= XY_SRC_TILED;
293 src_pitch /= 4;
294
295 if (src_tiling == I915_TILING_Y)
296 bcs_swctrl |= BCS_SWCTRL_SRC_Y;
297 }
298 #endif
299
300 if (dst_y2 <= dst_y || dst_x2 <= dst_x) {
301 return true;
302 }
303
304 assert(dst_x < dst_x2);
305 assert(dst_y < dst_y2);
306
307 BEGIN_BATCH_BLT(8 + ((bcs_swctrl != 0) ? 14 : 0));
308
309 if (bcs_swctrl != 0) {
310 /* Idle the blitter before we update how tiling is interpreted. */
311 OUT_BATCH(MI_FLUSH_DW);
312 OUT_BATCH(0);
313 OUT_BATCH(0);
314 OUT_BATCH(0);
315
316 OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
317 OUT_BATCH(BCS_SWCTRL);
318 OUT_BATCH((BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y) << 16 |
319 bcs_swctrl);
320 }
321
322 OUT_BATCH(CMD | (8 - 2));
323 OUT_BATCH(BR13 | (uint16_t)dst_pitch);
324 OUT_BATCH((dst_y << 16) | dst_x);
325 OUT_BATCH((dst_y2 << 16) | dst_x2);
326 OUT_RELOC_FENCED(dst_buffer,
327 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
328 dst_offset);
329 OUT_BATCH((src_y << 16) | src_x);
330 OUT_BATCH((uint16_t)src_pitch);
331 OUT_RELOC_FENCED(src_buffer,
332 I915_GEM_DOMAIN_RENDER, 0,
333 src_offset);
334
335 if (bcs_swctrl != 0) {
336 OUT_BATCH(MI_FLUSH_DW);
337 OUT_BATCH(0);
338 OUT_BATCH(0);
339 OUT_BATCH(0);
340
341 OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
342 OUT_BATCH(BCS_SWCTRL);
343 OUT_BATCH((BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y) << 16);
344 }
345
346 ADVANCE_BATCH();
347
348 intel_batchbuffer_emit_mi_flush(intel);
349
350 return true;
351 }
352
353
354 /**
355 * Use blitting to clear the renderbuffers named by 'flags'.
356 * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
357 * since that might include software renderbuffers or renderbuffers
358 * which we're clearing with triangles.
359 * \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear
360 */
361 GLbitfield
362 intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
363 {
364 struct intel_context *intel = intel_context(ctx);
365 struct gl_framebuffer *fb = ctx->DrawBuffer;
366 GLuint clear_depth_value, clear_depth_mask;
367 GLint cx, cy, cw, ch;
368 GLbitfield fail_mask = 0;
369 BATCH_LOCALS;
370
371 /*
372 * Compute values for clearing the buffers.
373 */
374 clear_depth_value = 0;
375 clear_depth_mask = 0;
376 if (mask & BUFFER_BIT_DEPTH) {
377 clear_depth_value = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
378 clear_depth_mask = XY_BLT_WRITE_RGB;
379 }
380 if (mask & BUFFER_BIT_STENCIL) {
381 clear_depth_value |= (ctx->Stencil.Clear & 0xff) << 24;
382 clear_depth_mask |= XY_BLT_WRITE_ALPHA;
383 }
384
385 cx = fb->_Xmin;
386 if (_mesa_is_winsys_fbo(fb))
387 cy = ctx->DrawBuffer->Height - fb->_Ymax;
388 else
389 cy = fb->_Ymin;
390 cw = fb->_Xmax - fb->_Xmin;
391 ch = fb->_Ymax - fb->_Ymin;
392
393 if (cw == 0 || ch == 0)
394 return 0;
395
396 /* Loop over all renderbuffers */
397 mask &= (1 << BUFFER_COUNT) - 1;
398 while (mask) {
399 GLuint buf = ffs(mask) - 1;
400 bool is_depth_stencil = buf == BUFFER_DEPTH || buf == BUFFER_STENCIL;
401 struct intel_renderbuffer *irb;
402 int x1, y1, x2, y2;
403 uint32_t clear_val;
404 uint32_t BR13, CMD;
405 struct intel_region *region;
406 int pitch, cpp;
407 drm_intel_bo *aper_array[2];
408
409 mask &= ~(1 << buf);
410
411 irb = intel_get_renderbuffer(fb, buf);
412 if (irb && irb->mt) {
413 region = irb->mt->region;
414 assert(region);
415 assert(region->bo);
416 } else {
417 fail_mask |= 1 << buf;
418 continue;
419 }
420
421 /* OK, clear this renderbuffer */
422 x1 = cx + irb->draw_x;
423 y1 = cy + irb->draw_y;
424 x2 = cx + cw + irb->draw_x;
425 y2 = cy + ch + irb->draw_y;
426
427 pitch = region->pitch;
428 cpp = region->cpp;
429
430 DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
431 __FUNCTION__,
432 region->bo, pitch,
433 x1, y1, x2 - x1, y2 - y1);
434
435 BR13 = 0xf0 << 16;
436 CMD = XY_COLOR_BLT_CMD;
437
438 /* Setup the blit command */
439 if (cpp == 4) {
440 if (is_depth_stencil) {
441 CMD |= clear_depth_mask;
442 } else {
443 /* clearing RGBA */
444 CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
445 }
446 }
447
448 assert(region->tiling != I915_TILING_Y);
449
450 #ifndef I915
451 if (region->tiling != I915_TILING_NONE) {
452 CMD |= XY_DST_TILED;
453 pitch /= 4;
454 }
455 #endif
456 BR13 |= pitch;
457
458 if (is_depth_stencil) {
459 clear_val = clear_depth_value;
460 } else {
461 uint8_t clear[4];
462 GLfloat *color = ctx->Color.ClearColor.f;
463
464 _mesa_unclamped_float_rgba_to_ubyte(clear, color);
465
466 switch (intel_rb_format(irb)) {
467 case MESA_FORMAT_ARGB8888:
468 case MESA_FORMAT_XRGB8888:
469 clear_val = PACK_COLOR_8888(clear[3], clear[0],
470 clear[1], clear[2]);
471 break;
472 case MESA_FORMAT_RGB565:
473 clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]);
474 break;
475 case MESA_FORMAT_ARGB4444:
476 clear_val = PACK_COLOR_4444(clear[3], clear[0],
477 clear[1], clear[2]);
478 break;
479 case MESA_FORMAT_ARGB1555:
480 clear_val = PACK_COLOR_1555(clear[3], clear[0],
481 clear[1], clear[2]);
482 break;
483 case MESA_FORMAT_A8:
484 clear_val = PACK_COLOR_8888(clear[3], clear[3],
485 clear[3], clear[3]);
486 break;
487 default:
488 fail_mask |= 1 << buf;
489 continue;
490 }
491 }
492
493 BR13 |= br13_for_cpp(cpp);
494
495 assert(x1 < x2);
496 assert(y1 < y2);
497
498 /* do space check before going any further */
499 aper_array[0] = intel->batch.bo;
500 aper_array[1] = region->bo;
501
502 if (drm_intel_bufmgr_check_aperture_space(aper_array,
503 ARRAY_SIZE(aper_array)) != 0) {
504 intel_batchbuffer_flush(intel);
505 }
506
507 BEGIN_BATCH_BLT(6);
508 OUT_BATCH(CMD | (6 - 2));
509 OUT_BATCH(BR13);
510 OUT_BATCH((y1 << 16) | x1);
511 OUT_BATCH((y2 << 16) | x2);
512 OUT_RELOC_FENCED(region->bo,
513 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
514 0);
515 OUT_BATCH(clear_val);
516 ADVANCE_BATCH();
517
518 if (intel->always_flush_cache)
519 intel_batchbuffer_emit_mi_flush(intel);
520
521 if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
522 mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
523 }
524
525 return fail_mask;
526 }
527
528 bool
529 intelEmitImmediateColorExpandBlit(struct intel_context *intel,
530 GLuint cpp,
531 GLubyte *src_bits, GLuint src_size,
532 GLuint fg_color,
533 GLshort dst_pitch,
534 drm_intel_bo *dst_buffer,
535 GLuint dst_offset,
536 uint32_t dst_tiling,
537 GLshort x, GLshort y,
538 GLshort w, GLshort h,
539 GLenum logic_op)
540 {
541 int dwords = ALIGN(src_size, 8) / 4;
542 uint32_t opcode, br13, blit_cmd;
543
544 if (dst_tiling != I915_TILING_NONE) {
545 if (dst_offset & 4095)
546 return false;
547 if (dst_tiling == I915_TILING_Y)
548 return false;
549 }
550
551 assert( logic_op - GL_CLEAR >= 0 );
552 assert( logic_op - GL_CLEAR < 0x10 );
553 assert(dst_pitch > 0);
554
555 if (w < 0 || h < 0)
556 return true;
557
558 DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
559 __FUNCTION__,
560 dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
561
562 intel_batchbuffer_require_space(intel,
563 (8 * 4) +
564 (3 * 4) +
565 dwords * 4, true);
566
567 opcode = XY_SETUP_BLT_CMD;
568 if (cpp == 4)
569 opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
570 #ifndef I915
571 if (dst_tiling != I915_TILING_NONE) {
572 opcode |= XY_DST_TILED;
573 dst_pitch /= 4;
574 }
575 #endif
576
577 br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
578 br13 |= br13_for_cpp(cpp);
579
580 blit_cmd = XY_TEXT_IMMEDIATE_BLIT_CMD | XY_TEXT_BYTE_PACKED; /* packing? */
581 if (dst_tiling != I915_TILING_NONE)
582 blit_cmd |= XY_DST_TILED;
583
584 BEGIN_BATCH_BLT(8 + 3);
585 OUT_BATCH(opcode | (8 - 2));
586 OUT_BATCH(br13);
587 OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
588 OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
589 OUT_RELOC_FENCED(dst_buffer,
590 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
591 dst_offset);
592 OUT_BATCH(0); /* bg */
593 OUT_BATCH(fg_color); /* fg */
594 OUT_BATCH(0); /* pattern base addr */
595
596 OUT_BATCH(blit_cmd | ((3 - 2) + dwords));
597 OUT_BATCH((y << 16) | x);
598 OUT_BATCH(((y + h) << 16) | (x + w));
599 ADVANCE_BATCH();
600
601 intel_batchbuffer_data(intel, src_bits, dwords * 4, true);
602
603 intel_batchbuffer_emit_mi_flush(intel);
604
605 return true;
606 }
607
608 /* We don't have a memmove-type blit like some other hardware, so we'll do a
609 * rectangular blit covering a large space, then emit 1-scanline blit at the
610 * end to cover the last if we need.
611 */
612 void
613 intel_emit_linear_blit(struct intel_context *intel,
614 drm_intel_bo *dst_bo,
615 unsigned int dst_offset,
616 drm_intel_bo *src_bo,
617 unsigned int src_offset,
618 unsigned int size)
619 {
620 struct gl_context *ctx = &intel->ctx;
621 GLuint pitch, height;
622 bool ok;
623
624 /* The pitch given to the GPU must be DWORD aligned, and
625 * we want width to match pitch. Max width is (1 << 15 - 1),
626 * rounding that down to the nearest DWORD is 1 << 15 - 4
627 */
628 pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4);
629 height = (pitch == 0) ? 1 : size / pitch;
630 ok = intelEmitCopyBlit(intel, 1,
631 pitch, src_bo, src_offset, I915_TILING_NONE,
632 pitch, dst_bo, dst_offset, I915_TILING_NONE,
633 0, 0, /* src x/y */
634 0, 0, /* dst x/y */
635 pitch, height, /* w, h */
636 GL_COPY);
637 if (!ok)
638 _mesa_problem(ctx, "Failed to linear blit %dx%d\n", pitch, height);
639
640 src_offset += pitch * height;
641 dst_offset += pitch * height;
642 size -= pitch * height;
643 assert (size < (1 << 15));
644 pitch = ALIGN(size, 4);
645 if (size != 0) {
646 ok = intelEmitCopyBlit(intel, 1,
647 pitch, src_bo, src_offset, I915_TILING_NONE,
648 pitch, dst_bo, dst_offset, I915_TILING_NONE,
649 0, 0, /* src x/y */
650 0, 0, /* dst x/y */
651 size, 1, /* w, h */
652 GL_COPY);
653 if (!ok)
654 _mesa_problem(ctx, "Failed to linear blit %dx%d\n", size, 1);
655 }
656 }
657
658 /**
659 * Used to initialize the alpha value of an ARGB8888 teximage after
660 * loading it from an XRGB8888 source.
661 *
662 * This is very common with glCopyTexImage2D().
663 */
664 void
665 intel_set_teximage_alpha_to_one(struct gl_context *ctx,
666 struct intel_texture_image *intel_image)
667 {
668 struct intel_context *intel = intel_context(ctx);
669 unsigned int image_x, image_y;
670 uint32_t x1, y1, x2, y2;
671 uint32_t BR13, CMD;
672 int pitch, cpp;
673 drm_intel_bo *aper_array[2];
674 struct intel_region *region = intel_image->mt->region;
675 int width, height, depth;
676 BATCH_LOCALS;
677
678 /* This target would require iterating over the slices, which we don't do */
679 assert(intel_image->base.Base.TexObject->Target != GL_TEXTURE_1D_ARRAY);
680
681 intel_miptree_get_dimensions_for_image(&intel_image->base.Base,
682 &width, &height, &depth);
683 assert(depth == 1);
684
685 assert(intel_image->base.Base.TexFormat == MESA_FORMAT_ARGB8888);
686
687 /* get dest x/y in destination texture */
688 intel_miptree_get_image_offset(intel_image->mt,
689 intel_image->base.Base.Level,
690 intel_image->base.Base.Face,
691 &image_x, &image_y);
692
693 x1 = image_x;
694 y1 = image_y;
695 x2 = image_x + width;
696 y2 = image_y + height;
697
698 pitch = region->pitch;
699 cpp = region->cpp;
700
701 DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
702 __FUNCTION__,
703 intel_image->mt->region->bo, pitch,
704 x1, y1, x2 - x1, y2 - y1);
705
706 BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
707 CMD = XY_COLOR_BLT_CMD;
708 CMD |= XY_BLT_WRITE_ALPHA;
709
710 assert(region->tiling != I915_TILING_Y);
711
712 #ifndef I915
713 if (region->tiling != I915_TILING_NONE) {
714 CMD |= XY_DST_TILED;
715 pitch /= 4;
716 }
717 #endif
718 BR13 |= pitch;
719
720 /* do space check before going any further */
721 aper_array[0] = intel->batch.bo;
722 aper_array[1] = region->bo;
723
724 if (drm_intel_bufmgr_check_aperture_space(aper_array,
725 ARRAY_SIZE(aper_array)) != 0) {
726 intel_batchbuffer_flush(intel);
727 }
728
729 BEGIN_BATCH_BLT(6);
730 OUT_BATCH(CMD | (6 - 2));
731 OUT_BATCH(BR13);
732 OUT_BATCH((y1 << 16) | x1);
733 OUT_BATCH((y2 << 16) | x2);
734 OUT_RELOC_FENCED(region->bo,
735 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
736 0);
737 OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
738 ADVANCE_BATCH();
739
740 intel_batchbuffer_emit_mi_flush(intel);
741 }