[965] Replace our own depth constants in intel context with GL context ones.
[mesa.git] / src / mesa / drivers / dri / i965 / 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 <stdio.h>
30 #include <errno.h>
31
32 #include "mtypes.h"
33 #include "context.h"
34 #include "enums.h"
35 #include "vblank.h"
36
37 #include "intel_reg.h"
38 #include "intel_batchbuffer.h"
39 #include "intel_context.h"
40 #include "intel_blit.h"
41 #include "intel_regions.h"
42 #include "intel_structs.h"
43
44 #include "dri_bufmgr.h"
45
46 #define FILE_DEBUG_FLAG DEBUG_BLIT
47
48 /**
49 * Copy the back color buffer to the front color buffer.
50 * Used for SwapBuffers().
51 */
52 void
53 intelCopyBuffer(__DRIdrawablePrivate *dPriv,
54 const drm_clip_rect_t *rect)
55 {
56 struct intel_context *intel;
57 GLboolean missed_target;
58 int64_t ust;
59
60 DBG("%s\n", __FUNCTION__);
61
62 assert(dPriv);
63 assert(dPriv->driContextPriv);
64 assert(dPriv->driContextPriv->driverPrivate);
65
66 intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
67 intelFlush( &intel->ctx );
68
69 if (intel->last_swap_fence) {
70 dri_fence_wait(intel->last_swap_fence);
71 dri_fence_unreference(intel->last_swap_fence);
72 intel->last_swap_fence = NULL;
73 }
74 intel->last_swap_fence = intel->first_swap_fence;
75 intel->first_swap_fence = NULL;
76
77 /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
78 * should work regardless.
79 */
80 LOCK_HARDWARE(intel);
81
82 if (!rect)
83 {
84 UNLOCK_HARDWARE( intel );
85 driWaitForVBlank( dPriv, &missed_target );
86 LOCK_HARDWARE( intel );
87 }
88
89 {
90 intelScreenPrivate *intelScreen = intel->intelScreen;
91 __DRIdrawablePrivate *dPriv = intel->driDrawable;
92 struct intel_region *src, *dst;
93 int nbox = dPriv->numClipRects;
94 drm_clip_rect_t *pbox = dPriv->pClipRects;
95 int cpp = intelScreen->cpp;
96 int src_pitch, dst_pitch;
97 int BR13, CMD;
98 int i;
99
100 if (intel->sarea->pf_current_page == 0) {
101 dst = intel->front_region;
102 src = intel->back_region;
103 }
104 else {
105 assert(0);
106 src = intel->front_region;
107 dst = intel->back_region;
108 }
109
110 src_pitch = src->pitch * src->cpp;
111 dst_pitch = dst->pitch * dst->cpp;
112
113 if (cpp == 2) {
114 BR13 = (0xCC << 16) | (1 << 24);
115 CMD = XY_SRC_COPY_BLT_CMD;
116 }
117 else {
118 BR13 = (0xCC << 16) | (1 << 24) | (1 << 25);
119 CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
120 }
121
122 if (src->tiled) {
123 CMD |= XY_SRC_TILED;
124 src_pitch /= 4;
125 }
126 if (dst->tiled) {
127 CMD |= XY_DST_TILED;
128 dst_pitch /= 4;
129 }
130
131 for (i = 0; i < nbox; i++, pbox++) {
132 drm_clip_rect_t box = *pbox;
133
134 if (rect) {
135 if (!intel_intersect_cliprects(&box, &box, rect))
136 continue;
137 }
138
139 if (box.x1 > box.x2 ||
140 box.y1 > box.y2 ||
141 box.x2 > intelScreen->width ||
142 box.y2 > intelScreen->height)
143 continue;
144
145 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
146 OUT_BATCH(CMD);
147 OUT_BATCH(BR13 | dst_pitch);
148 OUT_BATCH((box.y1 << 16) | box.x1);
149 OUT_BATCH((box.y2 << 16) | box.x2);
150 OUT_RELOC(dst->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, 0);
151 OUT_BATCH((box.y1 << 16) | box.x1);
152 OUT_BATCH(src_pitch);
153 OUT_RELOC(src->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0);
154 ADVANCE_BATCH();
155 }
156
157 if (intel->first_swap_fence)
158 dri_fence_unreference(intel->first_swap_fence);
159 intel_batchbuffer_flush(intel->batch);
160 intel->first_swap_fence = intel->batch->last_fence;
161 if (intel->first_swap_fence)
162 dri_fence_reference(intel->first_swap_fence);
163 }
164 UNLOCK_HARDWARE(intel);
165
166 if (!rect)
167 {
168 intel->swap_count++;
169 (*dri_interface->getUST)(&ust);
170 if (missed_target) {
171 intel->swap_missed_count++;
172 intel->swap_missed_ust = ust - intel->swap_ust;
173 }
174
175 intel->swap_ust = ust;
176 }
177
178 }
179
180
181
182
183 void
184 intelEmitFillBlit(struct intel_context *intel,
185 GLuint cpp,
186 GLshort dst_pitch,
187 dri_bo *dst_buffer,
188 GLuint dst_offset,
189 GLboolean dst_tiled,
190 GLshort x, GLshort y,
191 GLshort w, GLshort h,
192 GLuint color)
193 {
194 GLuint BR13, CMD;
195 BATCH_LOCALS;
196
197 dst_pitch *= cpp;
198
199 switch (cpp) {
200 case 1:
201 case 2:
202 case 3:
203 BR13 = (0xF0 << 16) | (1 << 24);
204 CMD = XY_COLOR_BLT_CMD;
205 break;
206 case 4:
207 BR13 = (0xF0 << 16) | (1 << 24) | (1 << 25);
208 CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
209 break;
210 default:
211 return;
212 }
213
214 if (dst_tiled) {
215 CMD |= XY_DST_TILED;
216 dst_pitch /= 4;
217 }
218
219 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
220 OUT_BATCH(CMD);
221 OUT_BATCH(BR13 | dst_pitch);
222 OUT_BATCH((y << 16) | x);
223 OUT_BATCH(((y + h) << 16) | (x + w));
224 OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset);
225 OUT_BATCH(color);
226 ADVANCE_BATCH();
227 }
228
229 static GLuint translate_raster_op(GLenum logicop)
230 {
231 switch(logicop) {
232 case GL_CLEAR: return 0x00;
233 case GL_AND: return 0x88;
234 case GL_AND_REVERSE: return 0x44;
235 case GL_COPY: return 0xCC;
236 case GL_AND_INVERTED: return 0x22;
237 case GL_NOOP: return 0xAA;
238 case GL_XOR: return 0x66;
239 case GL_OR: return 0xEE;
240 case GL_NOR: return 0x11;
241 case GL_EQUIV: return 0x99;
242 case GL_INVERT: return 0x55;
243 case GL_OR_REVERSE: return 0xDD;
244 case GL_COPY_INVERTED: return 0x33;
245 case GL_OR_INVERTED: return 0xBB;
246 case GL_NAND: return 0x77;
247 case GL_SET: return 0xFF;
248 default: return 0;
249 }
250 }
251
252
253 /* Copy BitBlt
254 */
255 void
256 intelEmitCopyBlit(struct intel_context *intel,
257 GLuint cpp,
258 GLshort src_pitch,
259 dri_bo *src_buffer,
260 GLuint src_offset,
261 GLboolean src_tiled,
262 GLshort dst_pitch,
263 dri_bo *dst_buffer,
264 GLuint dst_offset,
265 GLboolean dst_tiled,
266 GLshort src_x, GLshort src_y,
267 GLshort dst_x, GLshort dst_y,
268 GLshort w, GLshort h,
269 GLenum logic_op)
270 {
271 GLuint CMD, BR13;
272 int dst_y2 = dst_y + h;
273 int dst_x2 = dst_x + w;
274 BATCH_LOCALS;
275
276
277 DBG("%s src:buf(%d)/%d+%d %d,%d dst:buf(%d)/%d+%d %d,%d sz:%dx%d op:%d\n",
278 __FUNCTION__,
279 src_buffer, src_pitch, src_offset, src_x, src_y,
280 dst_buffer, dst_pitch, dst_offset, dst_x, dst_y,
281 w, h, logic_op);
282
283 assert( logic_op - GL_CLEAR >= 0 );
284 assert( logic_op - GL_CLEAR < 0x10 );
285
286 src_pitch *= cpp;
287 dst_pitch *= cpp;
288
289 BR13 = translate_raster_op(logic_op) << 16;
290
291 switch (cpp) {
292 case 1:
293 case 2:
294 case 3:
295 BR13 |= (1 << 24);
296 CMD = XY_SRC_COPY_BLT_CMD;
297 break;
298 case 4:
299 BR13 |= (1 << 24) | (1 << 25);
300 CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
301 break;
302 default:
303 return;
304 }
305
306 if (dst_tiled) {
307 CMD |= XY_DST_TILED;
308 dst_pitch /= 4;
309 }
310 if (src_tiled) {
311 CMD |= XY_SRC_TILED;
312 src_pitch /= 4;
313 }
314
315 if (dst_y2 < dst_y || dst_x2 < dst_x) {
316 return;
317 }
318
319 dst_pitch &= 0xffff;
320 src_pitch &= 0xffff;
321
322 /* Initial y values don't seem to work with negative pitches. If
323 * we adjust the offsets manually (below), it seems to work fine.
324 *
325 * On the other hand, if we always adjust, the hardware doesn't
326 * know which blit directions to use, so overlapping copypixels get
327 * the wrong result.
328 */
329 if (dst_pitch > 0 && src_pitch > 0) {
330 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
331 OUT_BATCH(CMD);
332 OUT_BATCH(BR13 | dst_pitch);
333 OUT_BATCH((dst_y << 16) | dst_x);
334 OUT_BATCH((dst_y2 << 16) | dst_x2);
335 OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
336 dst_offset);
337 OUT_BATCH((src_y << 16) | src_x);
338 OUT_BATCH(src_pitch);
339 OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
340 src_offset);
341 ADVANCE_BATCH();
342 }
343 else {
344 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
345 OUT_BATCH(CMD);
346 OUT_BATCH(BR13 | dst_pitch);
347 OUT_BATCH((0 << 16) | dst_x);
348 OUT_BATCH((h << 16) | dst_x2);
349 OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
350 dst_offset + dst_y * dst_pitch);
351 OUT_BATCH((0 << 16) | src_x);
352 OUT_BATCH(src_pitch);
353 OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
354 src_offset + src_y * src_pitch);
355 ADVANCE_BATCH();
356 }
357 }
358
359
360
361 void
362 intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
363 {
364 struct intel_context *intel = intel_context(ctx);
365 struct gl_framebuffer *fb = ctx->DrawBuffer;
366 intelScreenPrivate *intelScreen = intel->intelScreen;
367 GLuint clear_depth, clear_color;
368 GLint cpp = intelScreen->cpp;
369 GLboolean all;
370 GLint i;
371 struct intel_region *front = intel->front_region;
372 struct intel_region *back = intel->back_region;
373 struct intel_region *depth = intel->depth_region;
374 GLuint BR13, FRONT_CMD, BACK_CMD, DEPTH_CMD;
375 GLuint front_pitch;
376 GLuint back_pitch;
377 GLuint depth_pitch;
378 BATCH_LOCALS;
379
380 clear_color = intel->ClearColor;
381 clear_depth = 0;
382
383 if (mask & BUFFER_BIT_DEPTH) {
384 clear_depth = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
385 }
386
387 if (mask & BUFFER_BIT_STENCIL) {
388 clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
389 }
390
391 switch (cpp) {
392 case 2:
393 BR13 = (0xF0 << 16) | (1 << 24);
394 BACK_CMD = FRONT_CMD = XY_COLOR_BLT_CMD;
395 DEPTH_CMD = XY_COLOR_BLT_CMD;
396 break;
397 case 4:
398 BR13 = (0xF0 << 16) | (1 << 24) | (1 << 25);
399 BACK_CMD = FRONT_CMD = XY_COLOR_BLT_CMD |
400 XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
401 DEPTH_CMD = XY_COLOR_BLT_CMD;
402 if (mask & BUFFER_BIT_DEPTH) DEPTH_CMD |= XY_BLT_WRITE_RGB;
403 if (mask & BUFFER_BIT_STENCIL) DEPTH_CMD |= XY_BLT_WRITE_ALPHA;
404 break;
405 default:
406 return;
407 }
408
409
410 intelFlush(&intel->ctx);
411 LOCK_HARDWARE( intel );
412 if (intel->numClipRects) {
413 GLint cx, cy, cw, ch;
414
415 /* Get clear bounds after locking */
416 cx = fb->_Xmin;
417 cy = fb->_Ymin;
418 cw = fb->_Xmax - cx;
419 ch = fb->_Ymax - cy;
420 all = (cw == fb->Width && ch == fb->Height);
421
422 /* flip top to bottom */
423 cy = intel->driDrawable->h - cy - ch;
424 cx = cx + intel->drawX;
425 cy += intel->drawY;
426
427 /* adjust for page flipping */
428 if ( intel->sarea->pf_current_page == 0 ) {
429 front = intel->front_region;
430 back = intel->back_region;
431 }
432 else {
433 back = intel->front_region;
434 front = intel->back_region;
435 }
436
437 front_pitch = front->pitch * front->cpp;
438 back_pitch = back->pitch * back->cpp;
439 depth_pitch = depth->pitch * depth->cpp;
440
441 if (front->tiled) {
442 FRONT_CMD |= XY_DST_TILED;
443 front_pitch /= 4;
444 }
445
446 if (back->tiled) {
447 BACK_CMD |= XY_DST_TILED;
448 back_pitch /= 4;
449 }
450
451 if (depth->tiled) {
452 DEPTH_CMD |= XY_DST_TILED;
453 depth_pitch /= 4;
454 }
455
456 for (i = 0 ; i < intel->numClipRects ; i++)
457 {
458 drm_clip_rect_t *box = &intel->pClipRects[i];
459 drm_clip_rect_t b;
460
461 if (!all) {
462 GLint x = box->x1;
463 GLint y = box->y1;
464 GLint w = box->x2 - x;
465 GLint h = box->y2 - y;
466
467 if (x < cx) w -= cx - x, x = cx;
468 if (y < cy) h -= cy - y, y = cy;
469 if (x + w > cx + cw) w = cx + cw - x;
470 if (y + h > cy + ch) h = cy + ch - y;
471 if (w <= 0) continue;
472 if (h <= 0) continue;
473
474 b.x1 = x;
475 b.y1 = y;
476 b.x2 = x + w;
477 b.y2 = y + h;
478 } else {
479 b = *box;
480 }
481
482
483 if (b.x1 > b.x2 ||
484 b.y1 > b.y2 ||
485 b.x2 > intelScreen->width ||
486 b.y2 > intelScreen->height)
487 continue;
488
489 if ( mask & BUFFER_BIT_FRONT_LEFT ) {
490 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
491 OUT_BATCH(FRONT_CMD);
492 OUT_BATCH(BR13 | front_pitch);
493 OUT_BATCH((b.y1 << 16) | b.x1);
494 OUT_BATCH((b.y2 << 16) | b.x2);
495 OUT_RELOC(front->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
496 0);
497 OUT_BATCH(clear_color);
498 ADVANCE_BATCH();
499 }
500
501 if ( mask & BUFFER_BIT_BACK_LEFT ) {
502 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
503 OUT_BATCH(BACK_CMD);
504 OUT_BATCH(BR13 | back_pitch);
505 OUT_BATCH((b.y1 << 16) | b.x1);
506 OUT_BATCH((b.y2 << 16) | b.x2);
507 OUT_RELOC(back->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
508 0);
509 OUT_BATCH(clear_color);
510 ADVANCE_BATCH();
511 }
512
513 if ( mask & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
514 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
515 OUT_BATCH(DEPTH_CMD);
516 OUT_BATCH(BR13 | depth_pitch);
517 OUT_BATCH((b.y1 << 16) | b.x1);
518 OUT_BATCH((b.y2 << 16) | b.x2);
519 OUT_RELOC(depth->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
520 0);
521 OUT_BATCH(clear_depth);
522 ADVANCE_BATCH();
523 }
524 }
525 intel_batchbuffer_flush(intel->batch);
526 }
527
528 UNLOCK_HARDWARE(intel);
529 }
530
531
532 void
533 intelEmitImmediateColorExpandBlit(struct intel_context *intel,
534 GLuint cpp,
535 GLubyte *src_bits, GLuint src_size,
536 GLuint fg_color,
537 GLshort dst_pitch,
538 dri_bo *dst_buffer,
539 GLuint dst_offset,
540 GLboolean dst_tiled,
541 GLshort x, GLshort y,
542 GLshort w, GLshort h,
543 GLenum logic_op)
544 {
545 struct xy_text_immediate_blit text;
546 int dwords = ALIGN(src_size, 8) / 4;
547 uint32_t opcode, br13;
548
549 assert( logic_op - GL_CLEAR >= 0 );
550 assert( logic_op - GL_CLEAR < 0x10 );
551
552 if (w < 0 || h < 0)
553 return;
554
555 dst_pitch *= cpp;
556
557 if (dst_tiled)
558 dst_pitch /= 4;
559
560 DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
561 __FUNCTION__,
562 dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
563
564 memset(&text, 0, sizeof(text));
565 text.dw0.client = CLIENT_2D;
566 text.dw0.opcode = OPCODE_XY_TEXT_IMMEDIATE_BLT;
567 text.dw0.pad0 = 0;
568 text.dw0.byte_packed = 1; /* ?maybe? */
569 text.dw0.pad1 = 0;
570 text.dw0.dst_tiled = dst_tiled;
571 text.dw0.pad2 = 0;
572 text.dw0.length = (sizeof(text)/sizeof(int)) - 2 + dwords;
573 text.dw1.dest_y1 = y; /* duplicates info in setup blit */
574 text.dw1.dest_x1 = x;
575 text.dw2.dest_y2 = y + h;
576 text.dw2.dest_x2 = x + w;
577
578 intel_batchbuffer_require_space( intel->batch,
579 (8 * 4) +
580 sizeof(text) +
581 dwords,
582 INTEL_BATCH_NO_CLIPRECTS );
583
584 opcode = XY_SETUP_BLT_CMD;
585 if (cpp == 4)
586 opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
587 if (dst_tiled)
588 opcode |= XY_DST_TILED;
589
590 br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
591 if (cpp == 2)
592 br13 |= BR13_565;
593 else
594 br13 |= BR13_8888;
595
596 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
597 OUT_BATCH(opcode);
598 OUT_BATCH(br13);
599 OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
600 OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
601 OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset);
602 OUT_BATCH(0); /* bg */
603 OUT_BATCH(fg_color); /* fg */
604 OUT_BATCH(0); /* pattern base addr */
605 ADVANCE_BATCH();
606
607 intel_batchbuffer_data( intel->batch,
608 &text,
609 sizeof(text),
610 INTEL_BATCH_NO_CLIPRECTS );
611
612 intel_batchbuffer_data( intel->batch,
613 src_bits,
614 dwords * 4,
615 INTEL_BATCH_NO_CLIPRECTS );
616 }
617