Subversion Repositories Kolibri OS

Rev

Rev 3769 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3769 Rev 4251
Line 49... Line 49...
49
 * after every rectangle... So until that is resolved, prefer
49
 * after every rectangle... So until that is resolved, prefer
50
 * the BLT engine.
50
 * the BLT engine.
51
 */
51
 */
52
#define FORCE_SPANS 0
52
#define FORCE_SPANS 0
53
#define FORCE_NONRECTILINEAR_SPANS -1
53
#define FORCE_NONRECTILINEAR_SPANS -1
-
 
54
#define FORCE_FLUSH 1 /* https://bugs.freedesktop.org/show_bug.cgi?id=55500 */
Line 54... Line 55...
54
 
55
 
55
#define NO_COMPOSITE 0
56
#define NO_COMPOSITE 0
56
#define NO_COMPOSITE_SPANS 0
57
#define NO_COMPOSITE_SPANS 0
57
#define NO_COPY 0
58
#define NO_COPY 0
58
#define NO_COPY_BOXES 0
59
#define NO_COPY_BOXES 0
59
#define NO_FILL 0
60
#define NO_FILL 0
60
#define NO_FILL_ONE 0
61
#define NO_FILL_ONE 0
61
#define NO_FILL_BOXES 0
62
#define NO_FILL_BOXES 0
Line -... Line 63...
-
 
63
#define NO_VIDEO 0
-
 
64
 
62
#define NO_VIDEO 0
65
#define MAX_FLUSH_VERTICES 6
Line 63... Line 66...
63
 
66
 
64
#define GEN4_GRF_BLOCKS(nreg)    ((nreg + 15) / 16 - 1)
67
#define GEN4_GRF_BLOCKS(nreg)    ((nreg + 15) / 16 - 1)
65
 
68
 
Line 284... Line 287...
284
        return -1;
287
        return -1;
285
    case PICT_a8r8g8b8:
288
    case PICT_a8r8g8b8:
286
        return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
289
        return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
287
    case PICT_x8r8g8b8:
290
    case PICT_x8r8g8b8:
288
        return GEN4_SURFACEFORMAT_B8G8R8X8_UNORM;
291
        return GEN4_SURFACEFORMAT_B8G8R8X8_UNORM;
-
 
292
	case PICT_a8b8g8r8:
-
 
293
		return GEN4_SURFACEFORMAT_R8G8B8A8_UNORM;
-
 
294
	case PICT_x8b8g8r8:
-
 
295
		return GEN4_SURFACEFORMAT_R8G8B8X8_UNORM;
-
 
296
	case PICT_a2r10g10b10:
-
 
297
		return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM;
-
 
298
	case PICT_x2r10g10b10:
-
 
299
		return GEN4_SURFACEFORMAT_B10G10R10X2_UNORM;
-
 
300
	case PICT_r8g8b8:
-
 
301
		return GEN4_SURFACEFORMAT_R8G8B8_UNORM;
-
 
302
	case PICT_r5g6b5:
-
 
303
		return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
-
 
304
	case PICT_a1r5g5b5:
-
 
305
		return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM;
289
    case PICT_a8:
306
    case PICT_a8:
290
        return GEN4_SURFACEFORMAT_A8_UNORM;
307
        return GEN4_SURFACEFORMAT_A8_UNORM;
-
 
308
	case PICT_a4r4g4b4:
-
 
309
		return GEN4_SURFACEFORMAT_B4G4R4A4_UNORM;
291
    }
310
    }
292
}
311
}
Line 293... Line 312...
293
 
312
 
294
static uint32_t gen4_get_dest_format(PictFormat format)
313
static uint32_t gen4_get_dest_format(PictFormat format)
Line 297... Line 316...
297
    default:
316
    default:
298
        return -1;
317
        return -1;
299
    case PICT_a8r8g8b8:
318
    case PICT_a8r8g8b8:
300
    case PICT_x8r8g8b8:
319
    case PICT_x8r8g8b8:
301
        return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
320
        return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
-
 
321
	case PICT_a8b8g8r8:
-
 
322
	case PICT_x8b8g8r8:
-
 
323
		return GEN4_SURFACEFORMAT_R8G8B8A8_UNORM;
-
 
324
	case PICT_a2r10g10b10:
-
 
325
	case PICT_x2r10g10b10:
-
 
326
		return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM;
-
 
327
	case PICT_r5g6b5:
-
 
328
		return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
-
 
329
	case PICT_x1r5g5b5:
-
 
330
	case PICT_a1r5g5b5:
-
 
331
		return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM;
302
    case PICT_a8:
332
    case PICT_a8:
303
        return GEN4_SURFACEFORMAT_A8_UNORM;
333
        return GEN4_SURFACEFORMAT_A8_UNORM;
-
 
334
	case PICT_a4r4g4b4:
-
 
335
	case PICT_x4r4g4b4:
-
 
336
		return GEN4_SURFACEFORMAT_B4G4R4A4_UNORM;
304
    }
337
    }
305
}
338
}
Line 306... Line 339...
306
 
339
 
307
typedef struct gen4_surface_state_padded {
340
typedef struct gen4_surface_state_padded {
Line 391... Line 424...
391
	uint32_t *ss;
424
	uint32_t *ss;
Line 392... Line 425...
392
 
425
 
Line 393... Line 426...
393
	assert(sna->kgem.gen != 040 || !kgem_bo_is_snoop(bo));
426
	assert(sna->kgem.gen != 040 || !kgem_bo_is_snoop(bo));
394
 
427
 
395
	/* After the first bind, we manage the cache domains within the batch */
428
	/* After the first bind, we manage the cache domains within the batch */
396
	offset = kgem_bo_get_binding(bo, format);
429
	offset = kgem_bo_get_binding(bo, format | is_dst << 31);
397
	if (offset) {
430
	if (offset) {
398
		if (is_dst)
431
		if (is_dst)
399
			kgem_bo_mark_dirty(bo);
432
			kgem_bo_mark_dirty(bo);
Line 406... Line 439...
406
 
439
 
407
	ss[0] = (GEN4_SURFACE_2D << GEN4_SURFACE_TYPE_SHIFT |
440
	ss[0] = (GEN4_SURFACE_2D << GEN4_SURFACE_TYPE_SHIFT |
408
		 GEN4_SURFACE_BLEND_ENABLED |
441
		 GEN4_SURFACE_BLEND_ENABLED |
Line 409... Line 442...
409
		 format << GEN4_SURFACE_FORMAT_SHIFT);
442
		 format << GEN4_SURFACE_FORMAT_SHIFT);
-
 
443
 
410
 
444
	if (is_dst) {
411
	if (is_dst)
445
		ss[0] |= GEN4_SURFACE_RC_READ_WRITE;
412
		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
446
		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
413
	else
447
	} else
Line 414... Line 448...
414
		domains = I915_GEM_DOMAIN_SAMPLER << 16;
448
		domains = I915_GEM_DOMAIN_SAMPLER << 16;
415
	ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
449
	ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
416
 
450
 
417
	ss[2] = ((width - 1)  << GEN4_SURFACE_WIDTH_SHIFT |
451
	ss[2] = ((width - 1)  << GEN4_SURFACE_WIDTH_SHIFT |
418
		 (height - 1) << GEN4_SURFACE_HEIGHT_SHIFT);
452
		 (height - 1) << GEN4_SURFACE_HEIGHT_SHIFT);
419
	ss[3] = (gen4_tiling_bits(bo->tiling) |
453
	ss[3] = (gen4_tiling_bits(bo->tiling) |
Line 420... Line 454...
420
		 (bo->pitch - 1) << GEN4_SURFACE_PITCH_SHIFT);
454
		 (bo->pitch - 1) << GEN4_SURFACE_PITCH_SHIFT);
Line 421... Line 455...
421
	ss[4] = 0;
455
	ss[4] = 0;
422
	ss[5] = 0;
456
	ss[5] = 0;
423
 
457
 
424
	kgem_bo_set_binding(bo, format, offset);
458
	kgem_bo_set_binding(bo, format | is_dst << 31, offset);
Line 474... Line 508...
474
}
508
}
Line 475... Line 509...
475
 
509
 
476
static bool gen4_rectangle_begin(struct sna *sna,
510
static bool gen4_rectangle_begin(struct sna *sna,
477
				 const struct sna_composite_op *op)
511
				 const struct sna_composite_op *op)
478
{
512
{
479
	int id = op->u.gen4.ve_id;
513
	unsigned int id = 1 << op->u.gen4.ve_id;
Line 480... Line 514...
480
	int ndwords;
514
	int ndwords;
481
 
515
 
Line 482... Line 516...
482
	if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
516
	if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
483
		return true;
517
		return true;
484
 
518
 
485
	/* 7xpipelined pointers + 6xprimitive + 1xflush */
519
	/* 7xpipelined pointers + 6xprimitive + 1xflush */
-
 
520
	ndwords = op->need_magic_ca_pass? 20 : 6;
Line 486... Line 521...
486
	ndwords = op->need_magic_ca_pass? 20 : 6;
521
	if ((sna->render.vb_id & id) == 0)
487
	if ((sna->render.vb_id & (1 << id)) == 0)
522
		ndwords += 5;
Line 488... Line 523...
488
		ndwords += 5;
523
	ndwords += 2*FORCE_FLUSH;
489
 
524
 
490
	if (!kgem_check_batch(&sna->kgem, ndwords))
525
	if (!kgem_check_batch(&sna->kgem, ndwords))
491
		return false;
526
		return false;
Line 492... Line 527...
492
 
527
 
Line 506... Line 541...
506
		int rem = vertex_space(sna);
541
		int rem = vertex_space(sna);
507
		if (rem > op->floats_per_rect)
542
		if (rem > op->floats_per_rect)
508
			return rem;
543
			return rem;
509
	}
544
	}
Line -... Line 545...
-
 
545
 
510
 
546
	if (!kgem_check_batch(&sna->kgem,
511
	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 25 : 6))
547
			      2*FORCE_FLUSH + (op->need_magic_ca_pass ? 25 : 6)))
512
		return 0;
548
		return 0;
513
	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
549
	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
Line 514... Line 550...
514
		return 0;
550
		return 0;
Line 532... Line 568...
532
				      void (*emit_state)(struct sna *sna, const struct sna_composite_op *op))
568
				      void (*emit_state)(struct sna *sna, const struct sna_composite_op *op))
533
{
569
{
534
	int rem;
570
	int rem;
Line 535... Line 571...
535
 
571
 
-
 
572
	assert(want);
-
 
573
#if FORCE_FLUSH
-
 
574
	rem = sna->render.vertex_offset;
-
 
575
	if (sna->kgem.nbatch == sna->render_state.gen4.last_primitive)
-
 
576
		rem = sna->kgem.nbatch - 5;
-
 
577
	if (rem) {
-
 
578
		rem = MAX_FLUSH_VERTICES - (sna->render.vertex_index - sna->render.vertex_start) / 3;
-
 
579
		if (rem <= 0) {
-
 
580
			if (sna->render.vertex_offset) {
-
 
581
				gen4_vertex_flush(sna);
-
 
582
				if (gen4_magic_ca_pass(sna, op))
-
 
583
					gen4_emit_pipelined_pointers(sna, op, op->op,
-
 
584
								     op->u.gen4.wm_kernel);
-
 
585
			}
-
 
586
			OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH);
-
 
587
			rem = MAX_FLUSH_VERTICES;
-
 
588
		}
-
 
589
	} else
-
 
590
		rem = MAX_FLUSH_VERTICES;
-
 
591
	if (want > rem)
-
 
592
		want = rem;
Line 536... Line 593...
536
	assert(want);
593
#endif
537
 
594
 
538
start:
595
start:
539
	rem = vertex_space(sna);
596
	rem = vertex_space(sna);
Line 550... Line 607...
550
			goto flush;
607
			goto flush;
551
		else
608
		else
552
			goto start;
609
			goto start;
553
	}
610
	}
Line 554... Line -...
554
 
-
 
555
	assert(op->floats_per_rect >= vertex_space(sna));
611
 
-
 
612
	assert(rem <= vertex_space(sna));
556
	assert(rem <= vertex_space(sna));
613
	assert(op->floats_per_rect <= rem);
557
	if (want > 1 && want * op->floats_per_rect > rem)
614
	if (want > 1 && want * op->floats_per_rect > rem)
Line 558... Line 615...
558
		want = rem / op->floats_per_rect;
615
		want = rem / op->floats_per_rect;
559
 
616
 
Line 671... Line 728...
671
static void
728
static void
672
gen4_get_batch(struct sna *sna, const struct sna_composite_op *op)
729
gen4_get_batch(struct sna *sna, const struct sna_composite_op *op)
673
{
730
{
674
	kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
731
	kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
Line 675... Line 732...
675
 
732
 
676
	if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) {
733
	if (!kgem_check_batch_with_surfaces(&sna->kgem, 150 + 50*FORCE_FLUSH, 4)) {
677
		DBG(("%s: flushing batch: %d < %d+%d\n",
734
		DBG(("%s: flushing batch: %d < %d+%d\n",
678
		     __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
735
		     __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
679
		     150, 4*8));
736
		     150, 4*8));
680
		kgem_submit(&sna->kgem);
737
		kgem_submit(&sna->kgem);
Line 902... Line 959...
902
		const struct sna_composite_op *op,
959
		const struct sna_composite_op *op,
903
		uint16_t wm_binding_table)
960
		uint16_t wm_binding_table)
904
{
961
{
905
	bool flush;
962
	bool flush;
Line -... Line 963...
-
 
963
 
-
 
964
	assert(op->dst.bo->exec);
906
 
965
 
907
	flush = wm_binding_table & 1;
966
	flush = wm_binding_table & 1;
908
	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
967
	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
909
		DBG(("%s: flushing dirty (%d, %d), forced? %d\n", __FUNCTION__,
968
		DBG(("%s: flushing dirty (%d, %d), forced? %d\n", __FUNCTION__,
910
		     kgem_bo_is_dirty(op->src.bo),
969
		     kgem_bo_is_dirty(op->src.bo),
Line 982... Line 1041...
982
 
1041
 
983
	gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces);
1042
	gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces);
984
	op->prim_emit(sna, op, r);
1043
	op->prim_emit(sna, op, r);
Line -... Line 1044...
-
 
1044
}
-
 
1045
 
-
 
1046
#if 0
-
 
1047
fastcall static void
-
 
1048
gen4_render_composite_box(struct sna *sna,
-
 
1049
			  const struct sna_composite_op *op,
-
 
1050
			  const BoxRec *box)
-
 
1051
{
-
 
1052
	struct sna_composite_rectangles r;
-
 
1053
 
-
 
1054
	DBG(("  %s: (%d, %d), (%d, %d)\n",
-
 
1055
	     __FUNCTION__,
-
 
1056
	     box->x1, box->y1, box->x2, box->y2));
-
 
1057
 
-
 
1058
	gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces);
-
 
1059
 
-
 
1060
	r.dst.x = box->x1;
-
 
1061
	r.dst.y = box->y1;
-
 
1062
	r.width  = box->x2 - box->x1;
-
 
1063
	r.height = box->y2 - box->y1;
-
 
1064
	r.mask = r.src = r.dst;
-
 
1065
 
-
 
1066
	op->prim_emit(sna, op, &r);
-
 
1067
}
-
 
1068
 
-
 
1069
static void
-
 
1070
gen4_render_composite_boxes__blt(struct sna *sna,
-
 
1071
				 const struct sna_composite_op *op,
-
 
1072
				 const BoxRec *box, int nbox)
-
 
1073
{
-
 
1074
	DBG(("%s(%d) delta=(%d, %d), src=(%d, %d)/(%d, %d), mask=(%d, %d)/(%d, %d)\n",
-
 
1075
	     __FUNCTION__, nbox, op->dst.x, op->dst.y,
-
 
1076
	     op->src.offset[0], op->src.offset[1],
-
 
1077
	     op->src.width, op->src.height,
-
 
1078
	     op->mask.offset[0], op->mask.offset[1],
-
 
1079
	     op->mask.width, op->mask.height));
-
 
1080
 
-
 
1081
	do {
-
 
1082
		int nbox_this_time;
-
 
1083
 
-
 
1084
		nbox_this_time = gen4_get_rectangles(sna, op, nbox,
-
 
1085
						     gen4_bind_surfaces);
-
 
1086
		nbox -= nbox_this_time;
-
 
1087
 
-
 
1088
		do {
-
 
1089
			struct sna_composite_rectangles r;
-
 
1090
 
-
 
1091
			DBG(("  %s: (%d, %d), (%d, %d)\n",
-
 
1092
			     __FUNCTION__,
-
 
1093
			     box->x1, box->y1, box->x2, box->y2));
-
 
1094
 
-
 
1095
			r.dst.x = box->x1;
-
 
1096
			r.dst.y = box->y1;
-
 
1097
			r.width  = box->x2 - box->x1;
-
 
1098
			r.height = box->y2 - box->y1;
-
 
1099
			r.mask = r.src = r.dst;
-
 
1100
			op->prim_emit(sna, op, &r);
-
 
1101
			box++;
-
 
1102
		} while (--nbox_this_time);
-
 
1103
	} while (nbox);
-
 
1104
}
-
 
1105
 
-
 
1106
static void
-
 
1107
gen4_render_composite_boxes(struct sna *sna,
-
 
1108
			    const struct sna_composite_op *op,
-
 
1109
			    const BoxRec *box, int nbox)
-
 
1110
{
-
 
1111
	DBG(("%s: nbox=%d\n", __FUNCTION__, nbox));
-
 
1112
 
-
 
1113
	do {
-
 
1114
		int nbox_this_time;
-
 
1115
		float *v;
-
 
1116
 
-
 
1117
		nbox_this_time = gen4_get_rectangles(sna, op, nbox,
-
 
1118
						     gen4_bind_surfaces);
-
 
1119
		assert(nbox_this_time);
-
 
1120
		nbox -= nbox_this_time;
-
 
1121
 
-
 
1122
		v = sna->render.vertices + sna->render.vertex_used;
-
 
1123
		sna->render.vertex_used += nbox_this_time * op->floats_per_rect;
-
 
1124
 
-
 
1125
		op->emit_boxes(op, box, nbox_this_time, v);
-
 
1126
		box += nbox_this_time;
-
 
1127
	} while (nbox);
-
 
1128
}
-
 
1129
 
-
 
1130
#if !FORCE_FLUSH
-
 
1131
static void
-
 
1132
gen4_render_composite_boxes__thread(struct sna *sna,
-
 
1133
				    const struct sna_composite_op *op,
-
 
1134
				    const BoxRec *box, int nbox)
-
 
1135
{
-
 
1136
	DBG(("%s: nbox=%d\n", __FUNCTION__, nbox));
-
 
1137
 
-
 
1138
	sna_vertex_lock(&sna->render);
-
 
1139
	do {
-
 
1140
		int nbox_this_time;
-
 
1141
		float *v;
-
 
1142
 
-
 
1143
		nbox_this_time = gen4_get_rectangles(sna, op, nbox,
-
 
1144
						     gen4_bind_surfaces);
-
 
1145
		assert(nbox_this_time);
-
 
1146
		nbox -= nbox_this_time;
-
 
1147
 
-
 
1148
		v = sna->render.vertices + sna->render.vertex_used;
-
 
1149
		sna->render.vertex_used += nbox_this_time * op->floats_per_rect;
-
 
1150
 
-
 
1151
		sna_vertex_acquire__locked(&sna->render);
-
 
1152
		sna_vertex_unlock(&sna->render);
-
 
1153
 
-
 
1154
		op->emit_boxes(op, box, nbox_this_time, v);
-
 
1155
		box += nbox_this_time;
-
 
1156
 
-
 
1157
		sna_vertex_lock(&sna->render);
-
 
1158
		sna_vertex_release__locked(&sna->render);
-
 
1159
	} while (nbox);
-
 
1160
	sna_vertex_unlock(&sna->render);
-
 
1161
}
-
 
1162
#endif
-
 
1163
 
-
 
1164
#ifndef MAX
-
 
1165
#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
 
1166
#endif
-
 
1167
 
-
 
1168
static uint32_t gen4_bind_video_source(struct sna *sna,
-
 
1169
				       struct kgem_bo *src_bo,
-
 
1170
				       uint32_t src_offset,
-
 
1171
				       int src_width,
-
 
1172
				       int src_height,
-
 
1173
				       int src_pitch,
-
 
1174
				       uint32_t src_surf_format)
-
 
1175
{
-
 
1176
	struct gen4_surface_state *ss;
-
 
1177
 
-
 
1178
	sna->kgem.surface -= sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
-
 
1179
 
-
 
1180
	ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss));
-
 
1181
	ss->ss0.surface_type = GEN4_SURFACE_2D;
-
 
1182
	ss->ss0.surface_format = src_surf_format;
-
 
1183
	ss->ss0.color_blend = 1;
-
 
1184
 
-
 
1185
	ss->ss1.base_addr =
-
 
1186
		kgem_add_reloc(&sna->kgem,
-
 
1187
			       sna->kgem.surface + 1,
-
 
1188
			       src_bo,
-
 
1189
			       I915_GEM_DOMAIN_SAMPLER << 16,
-
 
1190
			       src_offset);
-
 
1191
 
-
 
1192
	ss->ss2.width  = src_width - 1;
-
 
1193
	ss->ss2.height = src_height - 1;
-
 
1194
	ss->ss3.pitch  = src_pitch - 1;
-
 
1195
 
-
 
1196
	return sna->kgem.surface * sizeof(uint32_t);
-
 
1197
}
-
 
1198
 
-
 
1199
static void gen4_video_bind_surfaces(struct sna *sna,
-
 
1200
				     const struct sna_composite_op *op)
-
 
1201
{
-
 
1202
	bool dirty = kgem_bo_is_dirty(op->dst.bo);
-
 
1203
	struct sna_video_frame *frame = op->priv;
-
 
1204
	uint32_t src_surf_format;
-
 
1205
	uint32_t src_surf_base[6];
-
 
1206
	int src_width[6];
-
 
1207
	int src_height[6];
-
 
1208
	int src_pitch[6];
-
 
1209
	uint32_t *binding_table;
-
 
1210
	uint16_t offset;
-
 
1211
	int n_src, n;
-
 
1212
 
-
 
1213
	src_surf_base[0] = 0;
-
 
1214
	src_surf_base[1] = 0;
-
 
1215
	src_surf_base[2] = frame->VBufOffset;
-
 
1216
	src_surf_base[3] = frame->VBufOffset;
-
 
1217
	src_surf_base[4] = frame->UBufOffset;
-
 
1218
	src_surf_base[5] = frame->UBufOffset;
-
 
1219
 
-
 
1220
	if (is_planar_fourcc(frame->id)) {
-
 
1221
		src_surf_format = GEN4_SURFACEFORMAT_R8_UNORM;
-
 
1222
		src_width[1]  = src_width[0]  = frame->width;
-
 
1223
		src_height[1] = src_height[0] = frame->height;
-
 
1224
		src_pitch[1]  = src_pitch[0]  = frame->pitch[1];
-
 
1225
		src_width[4]  = src_width[5]  = src_width[2]  = src_width[3] =
-
 
1226
			frame->width / 2;
-
 
1227
		src_height[4] = src_height[5] = src_height[2] = src_height[3] =
-
 
1228
			frame->height / 2;
-
 
1229
		src_pitch[4]  = src_pitch[5]  = src_pitch[2]  = src_pitch[3] =
-
 
1230
			frame->pitch[0];
-
 
1231
		n_src = 6;
-
 
1232
	} else {
-
 
1233
		if (frame->id == FOURCC_UYVY)
-
 
1234
			src_surf_format = GEN4_SURFACEFORMAT_YCRCB_SWAPY;
-
 
1235
		else
-
 
1236
			src_surf_format = GEN4_SURFACEFORMAT_YCRCB_NORMAL;
-
 
1237
 
-
 
1238
		src_width[0]  = frame->width;
-
 
1239
		src_height[0] = frame->height;
-
 
1240
		src_pitch[0]  = frame->pitch[0];
-
 
1241
		n_src = 1;
-
 
1242
	}
-
 
1243
 
-
 
1244
	gen4_get_batch(sna, op);
-
 
1245
 
-
 
1246
	binding_table = gen4_composite_get_binding_table(sna, &offset);
-
 
1247
	binding_table[0] =
-
 
1248
		gen4_bind_bo(sna,
-
 
1249
			     op->dst.bo, op->dst.width, op->dst.height,
-
 
1250
			     gen4_get_dest_format(op->dst.format),
-
 
1251
			     true);
-
 
1252
	for (n = 0; n < n_src; n++) {
-
 
1253
		binding_table[1+n] =
-
 
1254
			gen4_bind_video_source(sna,
-
 
1255
					       frame->bo,
-
 
1256
					       src_surf_base[n],
-
 
1257
					       src_width[n],
-
 
1258
					       src_height[n],
-
 
1259
					       src_pitch[n],
-
 
1260
					       src_surf_format);
-
 
1261
	}
-
 
1262
 
-
 
1263
	gen4_emit_state(sna, op, offset | dirty);
-
 
1264
}
-
 
1265
 
-
 
1266
static bool
-
 
1267
gen4_render_video(struct sna *sna,
-
 
1268
		  struct sna_video *video,
-
 
1269
		  struct sna_video_frame *frame,
-
 
1270
		  RegionPtr dstRegion,
-
 
1271
		  PixmapPtr pixmap)
-
 
1272
{
-
 
1273
	struct sna_composite_op tmp;
-
 
1274
	int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1;
-
 
1275
	int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1;
-
 
1276
	int src_width = frame->src.x2 - frame->src.x1;
-
 
1277
	int src_height = frame->src.y2 - frame->src.y1;
-
 
1278
	float src_offset_x, src_offset_y;
-
 
1279
	float src_scale_x, src_scale_y;
-
 
1280
	int nbox, pix_xoff, pix_yoff;
Line -... Line 1281...
-
 
1281
	struct sna_pixmap *priv;
-
 
1282
	BoxPtr box;
Line -... Line 1283...
-
 
1283
 
-
 
1284
	DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__,
-
 
1285
	     src_width, src_height, dst_width, dst_height));
-
 
1286
 
-
 
1287
	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
Line -... Line 1288...
-
 
1288
	if (priv == NULL)
-
 
1289
		return false;
-
 
1290
 
-
 
1291
	memset(&tmp, 0, sizeof(tmp));
-
 
1292
 
-
 
1293
	tmp.op = PictOpSrc;
Line -... Line 1294...
-
 
1294
	tmp.dst.pixmap = pixmap;
-
 
1295
	tmp.dst.width  = pixmap->drawable.width;
-
 
1296
	tmp.dst.height = pixmap->drawable.height;
-
 
1297
	tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth);
-
 
1298
	tmp.dst.bo = priv->gpu_bo;
-
 
1299
 
-
 
1300
	if (src_width == dst_width && src_height == dst_height)
-
 
1301
		tmp.src.filter = SAMPLER_FILTER_NEAREST;
-
 
1302
	else
-
 
1303
		tmp.src.filter = SAMPLER_FILTER_BILINEAR;
-
 
1304
	tmp.src.repeat = SAMPLER_EXTEND_PAD;
-
 
1305
	tmp.src.bo = frame->bo;
-
 
1306
	tmp.mask.bo = NULL;
-
 
1307
	tmp.u.gen4.wm_kernel =
Line -... Line 1308...
-
 
1308
		is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED;
-
 
1309
	tmp.u.gen4.ve_id = 2;
-
 
1310
	tmp.is_affine = true;
-
 
1311
	tmp.floats_per_vertex = 3;
Line -... Line 1312...
-
 
1312
	tmp.floats_per_rect = 9;
-
 
1313
	tmp.priv = frame;
Line -... Line 1314...
-
 
1314
 
-
 
1315
	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) {
-
 
1316
		kgem_submit(&sna->kgem);
-
 
1317
		assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL));
-
 
1318
	}
-
 
1319
 
-
 
1320
	gen4_video_bind_surfaces(sna, &tmp);
-
 
1321
	gen4_align_vertex(sna, &tmp);
-
 
1322
 
-
 
1323
	/* Set up the offset for translating from the given region (in screen
Line -... Line 1324...
-
 
1324
	 * coordinates) to the backing pixmap.
-
 
1325
	 */
Line -... Line 1326...
-
 
1326
#ifdef COMPOSITE
-
 
1327
	pix_xoff = -pixmap->screen_x + pixmap->drawable.x;
Line -... Line 1328...
-
 
1328
	pix_yoff = -pixmap->screen_y + pixmap->drawable.y;
-
 
1329
#else
-
 
1330
	pix_xoff = 0;
-
 
1331
	pix_yoff = 0;
-
 
1332
#endif
-
 
1333
 
-
 
1334
	src_scale_x = (float)src_width / dst_width / frame->width;
-
 
1335
	src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x;
-
 
1336
 
-
 
1337
	src_scale_y = (float)src_height / dst_height / frame->height;
-
 
1338
	src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y;
-
 
1339
 
-
 
1340
	box = REGION_RECTS(dstRegion);
-
 
1341
	nbox = REGION_NUM_RECTS(dstRegion);
-
 
1342
	do {
-
 
1343
		int n;
-
 
1344
 
-
 
1345
		n = gen4_get_rectangles(sna, &tmp, nbox,
-
 
1346
					gen4_video_bind_surfaces);
-
 
1347
		assert(n);
-
 
1348
		nbox -= n;
-
 
1349
 
-
 
1350
		do {
-
 
1351
			BoxRec r;
-
 
1352
 
-
 
1353
			r.x1 = box->x1 + pix_xoff;
-
 
1354
			r.x2 = box->x2 + pix_xoff;
-
 
1355
			r.y1 = box->y1 + pix_yoff;
-
 
1356
			r.y2 = box->y2 + pix_yoff;
-
 
1357
 
-
 
1358
			OUT_VERTEX(r.x2, r.y2);
-
 
1359
			OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x);
-
 
1360
			OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y);
-
 
1361
 
-
 
1362
			OUT_VERTEX(r.x1, r.y2);
-
 
1363
			OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x);
-
 
1364
			OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y);
-
 
1365
 
Line -... Line 1366...
-
 
1366
			OUT_VERTEX(r.x1, r.y1);
-
 
1367
			OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x);
Line -... Line 1368...
-
 
1368
			OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y);
-
 
1369
 
-
 
1370
			if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
-
 
1371
				sna_damage_add_box(&priv->gpu_damage, &r);
-
 
1372
				sna_damage_subtract_box(&priv->cpu_damage, &r);
-
 
1373
			}
-
 
1374
			box++;
-
 
1375
		} while (--n);
-
 
1376
	} while (nbox);
-
 
1377
	gen4_vertex_flush(sna);
-
 
1378
 
-
 
1379
	return true;
-
 
1380
}
-
 
1381
 
-
 
1382
static int
-
 
1383
gen4_composite_picture(struct sna *sna,
-
 
1384
		       PicturePtr picture,
-
 
1385
		       struct sna_composite_channel *channel,
-
 
1386
		       int x, int y,
-
 
1387
		       int w, int h,
-
 
1388
		       int dst_x, int dst_y,
-
 
1389
		       bool precise)
-
 
1390
{
-
 
1391
	PixmapPtr pixmap;
-
 
1392
	uint32_t color;
-
 
1393
	int16_t dx, dy;
-
 
1394
 
-
 
1395
	DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
-
 
1396
	     __FUNCTION__, x, y, w, h, dst_x, dst_y));
-
 
1397
 
-
 
1398
	channel->is_solid = false;
-
 
1399
	channel->card_format = -1;
-
 
1400
 
-
 
1401
	if (sna_picture_is_solid(picture, &color))
-
 
1402
		return gen4_channel_init_solid(sna, channel, color);
-
 
1403
 
-
 
1404
	if (picture->pDrawable == NULL) {
-
 
1405
		int ret;
-
 
1406
 
-
 
1407
		if (picture->pSourcePict->type == SourcePictTypeLinear)
-
 
1408
			return gen4_channel_init_linear(sna, picture, channel,
-
 
1409
							x, y,
-
 
1410
							w, h,
-
 
1411
							dst_x, dst_y);
-
 
1412
 
-
 
1413
		DBG(("%s -- fixup, gradient\n", __FUNCTION__));
-
 
1414
		ret = -1;
-
 
1415
		if (!precise)
-
 
1416
			ret = sna_render_picture_approximate_gradient(sna, picture, channel,
-
 
1417
								      x, y, w, h, dst_x, dst_y);
-
 
1418
		if (ret == -1)
-
 
1419
			ret = sna_render_picture_fixup(sna, picture, channel,
-
 
1420
						       x, y, w, h, dst_x, dst_y);
-
 
1421
		return ret;
-
 
1422
	}
-
 
1423
 
-
 
1424
	if (picture->alphaMap) {
-
 
1425
		DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
-
 
1426
		return sna_render_picture_fixup(sna, picture, channel,
-
 
1427
						x, y, w, h, dst_x, dst_y);
-
 
1428
	}
-
 
1429
 
-
 
1430
	if (!gen4_check_repeat(picture)) {
-
 
1431
		DBG(("%s: unknown repeat mode fixup\n", __FUNCTION__));
-
 
1432
		return sna_render_picture_fixup(sna, picture, channel,
-
 
1433
						x, y, w, h, dst_x, dst_y);
-
 
1434
	}
-
 
1435
 
-
 
1436
	if (!gen4_check_filter(picture)) {
-
 
1437
		DBG(("%s: unhandled filter fixup\n", __FUNCTION__));
-
 
1438
		return sna_render_picture_fixup(sna, picture, channel,
-
 
1439
						x, y, w, h, dst_x, dst_y);
-
 
1440
	}
-
 
1441
 
-
 
1442
	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
-
 
1443
	channel->filter = picture->filter;
-
 
1444
 
-
 
1445
	pixmap = get_drawable_pixmap(picture->pDrawable);
-
 
1446
	get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy);
Line -... Line 1447...
-
 
1447
 
-
 
1448
	x += dx + picture->pDrawable->x;
-
 
1449
	y += dy + picture->pDrawable->y;
-
 
1450
 
-
 
1451
	channel->is_affine = sna_transform_is_affine(picture->transform);
-
 
1452
	if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
Line -... Line 1453...
-
 
1453
		DBG(("%s: integer translation (%d, %d), removing\n",
-
 
1454
		     __FUNCTION__, dx, dy));
-
 
1455
		x += dx;
Line -... Line 1456...
-
 
1456
		y += dy;
-
 
1457
		channel->transform = NULL;
-
 
1458
		channel->filter = PictFilterNearest;
Line -... Line 1459...
-
 
1459
	} else
-
 
1460
		channel->transform = picture->transform;
-
 
1461
 
-
 
1462
	channel->pict_format = picture->format;
-
 
1463
	channel->card_format = gen4_get_card_format(picture->format);
-
 
1464
	if (channel->card_format == -1)
-
 
1465
		return sna_render_picture_convert(sna, picture, channel, pixmap,
-
 
1466
						  x, y, w, h, dst_x, dst_y,
-
 
1467
						  false);
-
 
1468
 
-
 
1469
	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
-
 
1470
		return sna_render_picture_extract(sna, picture, channel,
Line 985... Line 1471...
985
}
1471
						  x, y, w, h, dst_x, dst_y);
986
 
1472
 
987
 
1473
	return sna_render_pixmap_bo(sna, channel, pixmap,
988
 
1474
				    x, y, w, h, dst_x, dst_y);
Line 1012... Line 1498...
1012
		gen4_magic_ca_pass(sna, op);
1498
		gen4_magic_ca_pass(sna, op);
1013
	}
1499
	}
Line 1014... Line 1500...
1014
 
1500
 
Line -... Line 1501...
-
 
1501
}
-
 
1502
 
-
 
1503
#if 0
-
 
1504
static bool
-
 
1505
gen4_composite_set_target(struct sna *sna,
-
 
1506
			  struct sna_composite_op *op,
-
 
1507
			  PicturePtr dst,
-
 
1508
			  int x, int y, int w, int h,
-
 
1509
			  bool partial)
-
 
1510
{
-
 
1511
	BoxRec box;
-
 
1512
 
-
 
1513
	op->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
-
 
1514
	op->dst.width  = op->dst.pixmap->drawable.width;
-
 
1515
	op->dst.height = op->dst.pixmap->drawable.height;
-
 
1516
	op->dst.format = dst->format;
-
 
1517
	if (w && h) {
-
 
1518
		box.x1 = x;
-
 
1519
		box.y1 = y;
-
 
1520
		box.x2 = x + w;
-
 
1521
		box.y2 = y + h;
-
 
1522
	} else
-
 
1523
		sna_render_picture_extents(dst, &box);
-
 
1524
 
-
 
1525
	op->dst.bo = sna_drawable_use_bo (dst->pDrawable,
-
 
1526
					  PREFER_GPU | FORCE_GPU | RENDER_GPU,
-
 
1527
					  &box, &op->damage);
-
 
1528
	if (op->dst.bo == NULL)
-
 
1529
		return false;
-
 
1530
 
-
 
1531
	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
-
 
1532
			    &op->dst.x, &op->dst.y);
-
 
1533
 
-
 
1534
	DBG(("%s: pixmap=%p, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n",
-
 
1535
	     __FUNCTION__,
-
 
1536
	     op->dst.pixmap, (int)op->dst.format,
-
 
1537
	     op->dst.width, op->dst.height,
-
 
1538
	     op->dst.bo->pitch,
-
 
1539
	     op->dst.x, op->dst.y,
-
 
1540
	     op->damage ? *op->damage : (void *)-1));
-
 
1541
 
-
 
1542
	assert(op->dst.bo->proxy == NULL);
-
 
1543
 
-
 
1544
	if (too_large(op->dst.width, op->dst.height) &&
-
 
1545
	    !sna_render_composite_redirect(sna, op, x, y, w, h, partial))
-
 
1546
		return false;
-
 
1547
 
-
 
1548
	return true;
-
 
1549
}
-
 
1550
 
-
 
1551
static bool
-
 
1552
try_blt(struct sna *sna,
-
 
1553
	PicturePtr dst, PicturePtr src,
-
 
1554
	int width, int height)
-
 
1555
{
-
 
1556
	if (sna->kgem.mode != KGEM_RENDER) {
-
 
1557
		DBG(("%s: already performing BLT\n", __FUNCTION__));
-
 
1558
		return true;
-
 
1559
	}
-
 
1560
 
-
 
1561
	if (too_large(width, height)) {
-
 
1562
		DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
-
 
1563
		     __FUNCTION__, width, height));
-
 
1564
		return true;
-
 
1565
	}
-
 
1566
 
Line -... Line 1567...
-
 
1567
	if (too_large(dst->pDrawable->width, dst->pDrawable->height))
-
 
1568
		return true;
-
 
1569
 
Line -... Line 1570...
-
 
1570
	/* The blitter is much faster for solids */
-
 
1571
	if (sna_picture_is_solid(src, NULL))
-
 
1572
		return true;
Line -... Line 1573...
-
 
1573
 
-
 
1574
	/* is the source picture only in cpu memory e.g. a shm pixmap? */
-
 
1575
	return picture_is_cpu(sna, src);
-
 
1576
}
-
 
1577
 
-
 
1578
static bool
-
 
1579
check_gradient(PicturePtr picture, bool precise)
-
 
1580
{
-
 
1581
	switch (picture->pSourcePict->type) {
-
 
1582
	case SourcePictTypeSolidFill:
-
 
1583
	case SourcePictTypeLinear:
Line -... Line 1584...
-
 
1584
		return false;
-
 
1585
	default:
-
 
1586
		return precise;
-
 
1587
	}
-
 
1588
}
Line -... Line 1589...
-
 
1589
 
-
 
1590
static bool
-
 
1591
has_alphamap(PicturePtr p)
-
 
1592
{
-
 
1593
	return p->alphaMap != NULL;
-
 
1594
}
Line -... Line 1595...
-
 
1595
 
-
 
1596
static bool
-
 
1597
need_upload(struct sna *sna, PicturePtr p)
-
 
1598
{
-
 
1599
	return p->pDrawable && untransformed(p) &&
-
 
1600
		!is_gpu(sna, p->pDrawable, PREFER_GPU_RENDER);
Line -... Line 1601...
-
 
1601
}
-
 
1602
 
Line -... Line 1603...
-
 
1603
static bool
-
 
1604
source_is_busy(PixmapPtr pixmap)
Line -... Line 1605...
-
 
1605
{
-
 
1606
	struct sna_pixmap *priv = sna_pixmap(pixmap);
Line -... Line 1607...
-
 
1607
	if (priv == NULL)
-
 
1608
		return false;
Line -... Line 1609...
-
 
1609
 
-
 
1610
	if (priv->clear)
-
 
1611
		return false;
-
 
1612
 
-
 
1613
	if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo))
Line -... Line 1614...
-
 
1614
		return true;
-
 
1615
 
Line -... Line 1616...
-
 
1616
	if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo))
-
 
1617
		return true;
Line -... Line 1618...
-
 
1618
 
-
 
1619
	return priv->gpu_damage && !priv->cpu_damage;
-
 
1620
}
Line -... Line 1621...
-
 
1621
 
-
 
1622
static bool
Line -... Line 1623...
-
 
1623
source_fallback(struct sna *sna, PicturePtr p, PixmapPtr pixmap, bool precise)
-
 
1624
{
-
 
1625
	if (sna_picture_is_solid(p, NULL))
-
 
1626
		return false;
-
 
1627
 
-
 
1628
	if (p->pSourcePict)
-
 
1629
		return check_gradient(p, precise);
-
 
1630
 
-
 
1631
	if (!gen4_check_repeat(p) || !gen4_check_format(p->format))
-
 
1632
		return true;
-
 
1633
 
-
 
1634
	/* soft errors: perfer to upload/compute rather than readback */
-
 
1635
	if (pixmap && source_is_busy(pixmap))
-
 
1636
		return false;
-
 
1637
 
-
 
1638
	return has_alphamap(p) || !gen4_check_filter(p) || need_upload(sna, p);
Line -... Line 1639...
-
 
1639
}
Line -... Line 1640...
-
 
1640
 
-
 
1641
static bool
-
 
1642
gen4_composite_fallback(struct sna *sna,
-
 
1643
			PicturePtr src,
-
 
1644
			PicturePtr mask,
-
 
1645
			PicturePtr dst)
-
 
1646
{
-
 
1647
	PixmapPtr src_pixmap;
-
 
1648
	PixmapPtr mask_pixmap;
-
 
1649
	PixmapPtr dst_pixmap;
-
 
1650
	bool src_fallback, mask_fallback;
-
 
1651
 
Line -... Line 1652...
-
 
1652
	if (!gen4_check_dst_format(dst->format)) {
-
 
1653
		DBG(("%s: unknown destination format: %d\n",
-
 
1654
		     __FUNCTION__, dst->format));
-
 
1655
		return true;
-
 
1656
	}
-
 
1657
 
-
 
1658
	dst_pixmap = get_drawable_pixmap(dst->pDrawable);
-
 
1659
 
-
 
1660
	src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
-
 
1661
	src_fallback = source_fallback(sna, src, src_pixmap,
-
 
1662
				       dst->polyMode == PolyModePrecise);
-
 
1663
 
Line -... Line 1664...
-
 
1664
	if (mask) {
-
 
1665
		mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL;
-
 
1666
		mask_fallback = source_fallback(sna, mask, mask_pixmap,
-
 
1667
						dst->polyMode == PolyModePrecise);
-
 
1668
	} else {
-
 
1669
		mask_pixmap = NULL;
Line -... Line 1670...
-
 
1670
		mask_fallback = false;
-
 
1671
	}
-
 
1672
 
-
 
1673
	/* If we are using the destination as a source and need to
-
 
1674
	 * readback in order to upload the source, do it all
-
 
1675
	 * on the cpu.
-
 
1676
	 */
-
 
1677
	if (src_pixmap == dst_pixmap && src_fallback) {
-
 
1678
		DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
-
 
1679
		return true;
Line -... Line 1680...
-
 
1680
	}
-
 
1681
	if (mask_pixmap == dst_pixmap && mask_fallback) {
-
 
1682
		DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
-
 
1683
		return true;
-
 
1684
	}
-
 
1685
 
-
 
1686
	/* If anything is on the GPU, push everything out to the GPU */
-
 
1687
	if (dst_use_gpu(dst_pixmap)) {
-
 
1688
		DBG(("%s: dst is already on the GPU, try to use GPU\n",
Line -... Line 1689...
-
 
1689
		     __FUNCTION__));
-
 
1690
		return false;
-
 
1691
	}
-
 
1692
 
-
 
1693
	if (src_pixmap && !src_fallback) {
Line -... Line 1694...
-
 
1694
		DBG(("%s: src is already on the GPU, try to use GPU\n",
-
 
1695
		     __FUNCTION__));
-
 
1696
		return false;
-
 
1697
	}
-
 
1698
	if (mask_pixmap && !mask_fallback) {
-
 
1699
		DBG(("%s: mask is already on the GPU, try to use GPU\n",
Line -... Line 1700...
-
 
1700
		     __FUNCTION__));
-
 
1701
		return false;
-
 
1702
	}
-
 
1703
 
Line -... Line 1704...
-
 
1704
	/* However if the dst is not on the GPU and we need to
-
 
1705
	 * render one of the sources using the CPU, we may
-
 
1706
	 * as well do the entire operation in place onthe CPU.
-
 
1707
	 */
-
 
1708
	if (src_fallback) {
-
 
1709
		DBG(("%s: dst is on the CPU and src will fallback\n",
Line -... Line 1710...
-
 
1710
		     __FUNCTION__));
-
 
1711
		return true;
Line -... Line 1712...
-
 
1712
	}
-
 
1713
 
-
 
1714
	if (mask_fallback) {
-
 
1715
		DBG(("%s: dst is on the CPU and mask will fallback\n",
-
 
1716
		     __FUNCTION__));
-
 
1717
		return true;
Line -... Line 1718...
-
 
1718
	}
-
 
1719
 
Line -... Line 1720...
-
 
1720
	if (too_large(dst_pixmap->drawable.width,
-
 
1721
		      dst_pixmap->drawable.height) &&
Line -... Line 1722...
-
 
1722
	    dst_is_cpu(dst_pixmap)) {
-
 
1723
		DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__));
Line -... Line 1724...
-
 
1724
		return true;
Line -... Line 1725...
-
 
1725
	}
-
 
1726
 
Line -... Line 1727...
-
 
1727
	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
-
 
1728
	     __FUNCTION__));
Line -... Line 1729...
-
 
1729
	return dst_use_cpu(dst_pixmap);
-
 
1730
}
Line -... Line 1731...
-
 
1731
 
-
 
1732
static int
Line -... Line 1733...
-
 
1733
reuse_source(struct sna *sna,
-
 
1734
	     PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
Line -... Line 1735...
-
 
1735
	     PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
-
 
1736
{
Line -... Line 1737...
-
 
1737
	uint32_t color;
-
 
1738
 
-
 
1739
	if (src_x != msk_x || src_y != msk_y)
-
 
1740
		return false;
-
 
1741
 
-
 
1742
	if (src == mask) {
-
 
1743
		DBG(("%s: mask is source\n", __FUNCTION__));
-
 
1744
		*mc = *sc;
Line 1015... Line 1745...
1015
}
1745
		mc->bo = kgem_bo_reference(mc->bo);
1016
 
1746
		return true;
1017
 
1747
	}
1018
 
1748
 
1019
 
1749
	if (sna_picture_is_solid(mask, &color))
1020
 
1750
		return gen4_channel_init_solid(sna, mc, color);
1021
 
1751
 
1022
 
1752
	if (sc->is_solid)
1023
 
1753
		return false;
1024
 
1754
 
1025
 
1755
	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
1026
 
1756
		return false;
1027
 
-
 
1028
 
1757
 
1029
 
1758
	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
Line -... Line 1759...
-
 
1759
 
1030
 
1760
	if (!sna_transform_equal(src->transform, mask->transform))
Line 1031... Line 1761...
1031
 
1761
		return false;
-
 
1762
 
1032
 
1763
	if (!sna_picture_alphamap_equal(src, mask))
-
 
1764
		return false;
-
 
1765
 
1033
 
1766
	if (!gen4_check_repeat(mask))
1034
 
1767
		return false;
1035
 
1768
 
-
 
1769
	if (!gen4_check_filter(mask))
Line -... Line 1770...
-
 
1770
		return false;
-
 
1771
 
Line -... Line 1772...
-
 
1772
	if (!gen4_check_format(mask->format))
-
 
1773
		return false;
-
 
1774
 
-
 
1775
	DBG(("%s: reusing source channel for mask with a twist\n",
-
 
1776
	     __FUNCTION__));
1036
 
1777
 
-
 
1778
	*mc = *sc;
-
 
1779
	mc->repeat = gen4_repeat(mask->repeat ? mask->repeatType : RepeatNone);
1037
 
1780
	mc->filter = gen4_filter(mask->filter);
1038
 
1781
	mc->pict_format = mask->format;
-
 
1782
	mc->card_format = gen4_get_card_format(mask->format);
-
 
1783
	mc->bo = kgem_bo_reference(mc->bo);
-
 
1784
	return true;
-
 
1785
}
Line -... Line 1786...
-
 
1786
 
-
 
1787
static bool
1039
 
1788
gen4_render_composite(struct sna *sna,
-
 
1789
		      uint8_t op,
-
 
1790
		      PicturePtr src,
1040
 
1791
		      PicturePtr mask,
-
 
1792
		      PicturePtr dst,
-
 
1793
		      int16_t src_x, int16_t src_y,
-
 
1794
		      int16_t msk_x, int16_t msk_y,
-
 
1795
		      int16_t dst_x, int16_t dst_y,
1041
 
1796
		      int16_t width, int16_t height,
-
 
1797
		      struct sna_composite_op *tmp)
-
 
1798
{
-
 
1799
	DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
-
 
1800
	     width, height, sna->kgem.mode));
1042
 
1801
 
1043
 
1802
	if (op >= ARRAY_SIZE(gen4_blend_op))
-
 
1803
		return false;
-
 
1804
 
-
 
1805
	if (mask == NULL &&
-
 
1806
	    try_blt(sna, dst, src, width, height) &&
-
 
1807
	    sna_blt_composite(sna, op,
-
 
1808
			      src, dst,
Line 1044... Line 1809...
1044
 
1809
			      src_x, src_y,
1045
 
1810
			      dst_x, dst_y,
1046
 
1811
			      width, height,
Line 1047... Line 1812...
1047
 
1812
			      tmp, false))
1048
 
1813
		return true;
1049
 
1814
 
1050
 
1815
	if (gen4_composite_fallback(sna, src, mask, dst))
-
 
1816
		return false;
-
 
1817
 
1051
 
1818
	if (need_tiling(sna, width, height))
-
 
1819
		return sna_tiling_composite(op, src, mask, dst,
1052
 
1820
					    src_x, src_y,
1053
 
1821
					    msk_x, msk_y,
1054
 
1822
					    dst_x, dst_y,
1055
 
1823
					    width, height,
-
 
1824
					    tmp);
1056
 
1825
 
1057
static bool
1826
	if (!gen4_composite_set_target(sna, tmp, dst,
1058
gen4_blit_tex(struct sna *sna,
1827
				       dst_x, dst_y, width, height,
-
 
1828
				       op > PictOpSrc || dst->pCompositeClip->data)) {
1059
              uint8_t op, bool scale,
1829
		DBG(("%s: failed to set composite target\n", __FUNCTION__));
1060
		      PixmapPtr src, struct kgem_bo *src_bo,
1830
		return false;
1061
		      PixmapPtr mask,struct kgem_bo *mask_bo,
1831
	}
1062
		      PixmapPtr dst, struct kgem_bo *dst_bo, 
-
 
1063
              int32_t src_x, int32_t src_y,
-
 
1064
              int32_t msk_x, int32_t msk_y,
-
 
1065
              int32_t dst_x, int32_t dst_y,
-
 
1066
              int32_t width, int32_t height,
1832
 
1067
              struct sna_composite_op *tmp)
-
 
1068
{
-
 
Line -... Line 1833...
-
 
1833
	tmp->op = op;
-
 
1834
	switch (gen4_composite_picture(sna, src, &tmp->src,
-
 
1835
				       src_x, src_y,
-
 
1836
				       width, height,
-
 
1837
				       dst_x, dst_y,
-
 
1838
				       dst->polyMode == PolyModePrecise)) {
-
 
1839
	case -1:
-
 
1840
		DBG(("%s: failed to prepare source\n", __FUNCTION__));
-
 
1841
		goto cleanup_dst;
-
 
1842
	case 0:
-
 
1843
		if (!gen4_channel_init_solid(sna, &tmp->src, 0))
-
 
1844
			goto cleanup_dst;
-
 
1845
		/* fall through to fixup */
-
 
1846
	case 1:
-
 
1847
		if (mask == NULL &&
-
 
1848
		    sna_blt_composite__convert(sna,
-
 
1849
					       dst_x, dst_y, width, height,
-
 
1850
					       tmp))
-
 
1851
			return true;
-
 
1852
 
Line 1069... Line 1853...
1069
 
1853
		gen4_composite_channel_convert(&tmp->src);
1070
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
-
 
1071
         width, height, sna->kgem.ring));
-
 
1072
 
-
 
-
 
1854
		break;
Line 1073... Line 1855...
1073
    tmp->op = PictOpSrc;
1855
	}
1074
 
1856
 
1075
    tmp->dst.pixmap = dst;
1857
	tmp->is_affine = tmp->src.is_affine;
1076
    tmp->dst.bo     = dst_bo;
1858
	tmp->has_component_alpha = false;
1077
    tmp->dst.width  = dst->drawable.width;
1859
	tmp->need_magic_ca_pass = false;
1078
    tmp->dst.height = dst->drawable.height;
1860
 
Line 1079... Line 1861...
1079
    tmp->dst.format = PICT_x8r8g8b8;
1861
	if (mask) {
-
 
1862
		if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
-
 
1863
			tmp->has_component_alpha = true;
-
 
1864
 
-
 
1865
			/* Check if it's component alpha that relies on a source alpha and on
-
 
1866
			 * the source value.  We can only get one of those into the single
-
 
1867
			 * source value that we get to blend with.
-
 
1868
			 */
-
 
1869
			if (gen4_blend_op[op].src_alpha &&
1080
 
1870
			    (gen4_blend_op[op].src_blend != GEN4_BLENDFACTOR_ZERO)) {
Line 1081... Line 1871...
1081
 
1871
				if (op != PictOpOver) {
1082
	tmp->src.repeat = RepeatNone;
1872
					DBG(("%s -- fallback: unhandled component alpha blend\n",
1083
	tmp->src.filter = PictFilterNearest;
1873
					     __FUNCTION__));
1084
    tmp->src.is_affine = true;
1874
 
-
 
1875
					goto cleanup_src;
-
 
1876
				}
-
 
1877
 
-
 
1878
				tmp->need_magic_ca_pass = true;
1085
 
1879
				tmp->op = PictOpOutReverse;
Line 1086... Line 1880...
1086
    tmp->src.bo = src_bo;
1880
			}
1087
	tmp->src.pict_format = PICT_x8r8g8b8;
1881
		}
1088
    tmp->src.card_format = gen4_get_card_format(tmp->src.pict_format);
1882
 
-
 
1883
		if (!reuse_source(sna,
-
 
1884
				  src, &tmp->src, src_x, src_y,
-
 
1885
				  mask, &tmp->mask, msk_x, msk_y)) {
-
 
1886
			switch (gen4_composite_picture(sna, mask, &tmp->mask,
-
 
1887
						       msk_x, msk_y,
-
 
1888
						       width, height,
-
 
1889
						       dst_x, dst_y,
-
 
1890
						       dst->polyMode == PolyModePrecise)) {
-
 
1891
			case -1:
-
 
1892
				DBG(("%s: failed to prepare mask\n", __FUNCTION__));
-
 
1893
				goto cleanup_src;
1089
    tmp->src.width  = src->drawable.width;
1894
			case 0:
Line -... Line 1895...
-
 
1895
				if (!gen4_channel_init_solid(sna, &tmp->mask, 0))
-
 
1896
					goto cleanup_src;
-
 
1897
				/* fall through to fixup */
-
 
1898
			case 1:
-
 
1899
				gen4_composite_channel_convert(&tmp->mask);
-
 
1900
				break;
-
 
1901
			}
-
 
1902
		}
-
 
1903
 
-
 
1904
		tmp->is_affine &= tmp->mask.is_affine;
-
 
1905
	}
-
 
1906
 
-
 
1907
	tmp->u.gen4.wm_kernel =
-
 
1908
		gen4_choose_composite_kernel(tmp->op,
-
 
1909
					     tmp->mask.bo != NULL,
-
 
1910
					     tmp->has_component_alpha,
-
 
1911
					     tmp->is_affine);
-
 
1912
	tmp->u.gen4.ve_id = gen4_choose_composite_emitter(sna, tmp);
-
 
1913
 
-
 
1914
	tmp->blt   = gen4_render_composite_blt;
-
 
1915
	tmp->box   = gen4_render_composite_box;
-
 
1916
	tmp->boxes = gen4_render_composite_boxes__blt;
-
 
1917
	if (tmp->emit_boxes) {
-
 
1918
		tmp->boxes = gen4_render_composite_boxes;
-
 
1919
#if !FORCE_FLUSH
-
 
1920
		tmp->thread_boxes = gen4_render_composite_boxes__thread;
-
 
1921
#endif
-
 
1922
	}
-
 
1923
	tmp->done  = gen4_render_composite_done;
-
 
1924
 
-
 
1925
	if (!kgem_check_bo(&sna->kgem,
-
 
1926
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
-
 
1927
			   NULL)) {
-
 
1928
		kgem_submit(&sna->kgem);
-
 
1929
		if (!kgem_check_bo(&sna->kgem,
-
 
1930
				     tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
-
 
1931
				     NULL))
-
 
1932
			goto cleanup_mask;
-
 
1933
	}
-
 
1934
 
-
 
1935
	gen4_bind_surfaces(sna, tmp);
-
 
1936
	gen4_align_vertex(sna, tmp);
1090
    tmp->src.height = src->drawable.height;
1937
	return true;
1091
 
1938
 
1092
	tmp->is_affine = tmp->src.is_affine;
1939
cleanup_mask:
1093
	tmp->has_component_alpha = false;
1940
	if (tmp->mask.bo)
Line 1228... Line 2075...
1228
 
2075
 
1229
	return sna_static_stream_offsetof(stream, vs);
2076
	return sna_static_stream_offsetof(stream, vs);
Line 1230... Line 2077...
1230
}
2077
}
1231
 
2078
 
1232
static uint32_t gen4_create_sf_state(struct sna_static_stream *stream,
2079
static uint32_t gen4_create_sf_state(struct sna_static_stream *stream,
1233
				     int gen, uint32_t kernel)
2080
				     uint32_t kernel)
Line 1234... Line 2081...
1234
{
2081
{
Line 1382... Line 2229...
1382
							     16);
2229
							     16);
1383
		}
2230
		}
1384
	}
2231
	}
Line 1385... Line 2232...
1385
 
2232
 
1386
	state->vs = gen4_create_vs_unit_state(&general);
2233
	state->vs = gen4_create_vs_unit_state(&general);
Line 1387... Line 2234...
1387
	state->sf = gen4_create_sf_state(&general, sna->kgem.gen, sf);
2234
	state->sf = gen4_create_sf_state(&general, sf);
1388
 
2235
 
1389
	wm_state = sna_static_stream_map(&general,
2236
	wm_state = sna_static_stream_map(&general,
1390
					  sizeof(*wm_state) * KERNEL_COUNT *
2237
					  sizeof(*wm_state) * KERNEL_COUNT *
Line 1419... Line 2266...
1419
 
2266
 
1420
	state->general_bo = sna_static_stream_fini(sna, &general);
2267
	state->general_bo = sna_static_stream_fini(sna, &general);
1421
	return state->general_bo != NULL;
2268
	return state->general_bo != NULL;
Line 1422... Line -...
1422
}
-
 
1423
 
2269
}
1424
 
2270
 
1425
bool gen4_render_init(struct sna *sna)
2271
const char *gen4_render_init(struct sna *sna, const char *backend)
1426
{
2272
{
Line 1427... Line 2273...
1427
	if (!gen4_render_setup(sna))
2273
	if (!gen4_render_setup(sna))
1428
		return false;
2274
		return backend;
Line -... Line 2275...
-
 
2275
 
-
 
2276
	sna->kgem.retire = gen4_render_retire;
-
 
2277
	sna->kgem.expire = gen4_render_expire;
1429
 
2278
 
-
 
2279
#if 0
-
 
2280
#if !NO_COMPOSITE
-
 
2281
	sna->render.composite = gen4_render_composite;
-
 
2282
	sna->render.prefer_gpu |= PREFER_GPU_RENDER;
-
 
2283
#endif
-
 
2284
#if !NO_COMPOSITE_SPANS
-
 
2285
	sna->render.check_composite_spans = gen4_check_composite_spans;
Line -... Line 2286...
-
 
2286
	sna->render.composite_spans = gen4_render_composite_spans;
1430
	sna->kgem.retire = gen4_render_retire;
2287
	if (0)
-
 
2288
		sna->render.prefer_gpu |= PREFER_GPU_SPANS;
-
 
2289
#endif
-
 
2290
 
-
 
2291
#if !NO_VIDEO
-
 
2292
	sna->render.video = gen4_render_video;
-
 
2293
#endif
-
 
2294
 
-
 
2295
#if !NO_COPY_BOXES
-
 
2296
	sna->render.copy_boxes = gen4_render_copy_boxes;
-
 
2297
#endif
-
 
2298
#if !NO_COPY
-
 
2299
	sna->render.copy = gen4_render_copy;
-
 
2300
#endif
-
 
2301
 
-
 
2302
#if !NO_FILL_BOXES
-
 
2303
	sna->render.fill_boxes = gen4_render_fill_boxes;
-
 
2304
#endif
-
 
2305
#if !NO_FILL
-
 
2306
	sna->render.fill = gen4_render_fill;
-
 
2307
#endif
Line -... Line 2308...
-
 
2308
#if !NO_FILL_ONE
-
 
2309
	sna->render.fill_one = gen4_render_fill_one;
Line 1431... Line 2310...
1431
	sna->kgem.expire = gen4_render_expire;
2310
#endif
1432
 
2311
 
1433
	sna->render.prefer_gpu |= PREFER_GPU_RENDER;
2312
#endif
Line 1434... Line 2313...
1434
 
2313
 
1435
    sna->render.blit_tex = gen4_blit_tex;
2314
    sna->render.blit_tex = gen4_blit_tex;
-
 
2315
    sna->render.caps = HW_BIT_BLIT | HW_TEX_BLIT;
-
 
2316
 
-
 
2317
	sna->render.flush = gen4_render_flush;
-
 
2318
	sna->render.reset = gen4_render_reset;
-
 
2319
	sna->render.fini = gen4_render_fini;
-
 
2320
 
-
 
2321
	sna->render.max_3d_size = GEN4_MAX_3D_SIZE;
-
 
2322
	sna->render.max_3d_pitch = 1 << 18;
-
 
2323
	return sna->kgem.gen >= 045 ? "Eaglelake (gen4.5)" : "Broadwater (gen4)";
-
 
2324
}
-
 
2325
 
-
 
2326
static bool
-
 
2327
gen4_blit_tex(struct sna *sna,
-
 
2328
              uint8_t op, bool scale,
-
 
2329
		      PixmapPtr src, struct kgem_bo *src_bo,
-
 
2330
		      PixmapPtr mask,struct kgem_bo *mask_bo,
-
 
2331
		      PixmapPtr dst, struct kgem_bo *dst_bo,
-
 
2332
              int32_t src_x, int32_t src_y,
-
 
2333
              int32_t msk_x, int32_t msk_y,
-
 
2334
              int32_t dst_x, int32_t dst_y,
-
 
2335
              int32_t width, int32_t height,
-
 
2336
              struct sna_composite_op *tmp)
-
 
2337
{
-
 
2338
 
-
 
2339
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
1436
 
2340
         width, height, sna->kgem.ring));
-
 
2341
 
Line -... Line 2342...
-
 
2342
    tmp->op = PictOpSrc;
-
 
2343
 
-
 
2344
    tmp->dst.pixmap = dst;
-
 
2345
    tmp->dst.bo     = dst_bo;
-
 
2346
    tmp->dst.width  = dst->drawable.width;
-
 
2347
    tmp->dst.height = dst->drawable.height;
-
 
2348
    tmp->dst.format = PICT_x8r8g8b8;
-
 
2349
 
-
 
2350
 
-
 
2351
	tmp->src.repeat = RepeatNone;
-
 
2352
	tmp->src.filter = PictFilterNearest;
-
 
2353
    tmp->src.is_affine = true;
-
 
2354
 
-
 
2355
    tmp->src.bo = src_bo;
-
 
2356
	tmp->src.pict_format = PICT_x8r8g8b8;
-
 
2357
    tmp->src.card_format = gen4_get_card_format(tmp->src.pict_format);
-
 
2358
    tmp->src.width  = src->drawable.width;
-
 
2359
    tmp->src.height = src->drawable.height;
-
 
2360
 
-
 
2361
	tmp->is_affine = tmp->src.is_affine;
-
 
2362
	tmp->has_component_alpha = false;
-
 
2363
	tmp->need_magic_ca_pass = false;
-
 
2364
 
-
 
2365
 	tmp->mask.repeat = SAMPLER_EXTEND_NONE;
-
 
2366
	tmp->mask.filter = SAMPLER_FILTER_NEAREST;
-
 
2367
    tmp->mask.is_affine = true;
-
 
2368
 
-
 
2369
    tmp->mask.bo = mask_bo;
-
 
2370
    tmp->mask.pict_format = PIXMAN_a8;
-
 
2371
    tmp->mask.card_format = gen4_get_card_format(tmp->mask.pict_format);
-
 
2372
    tmp->mask.width  = mask->drawable.width;
-
 
2373
    tmp->mask.height = mask->drawable.height;
-
 
2374
 
-
 
2375
    if( scale )
-
 
2376
    {
-
 
2377
        tmp->src.scale[0] = 1.f/width;
-
 
2378
        tmp->src.scale[1] = 1.f/height;
-
 
2379
    }
-
 
2380
    else
-
 
2381
    {
-
 
2382
        tmp->src.scale[0] = 1.f/src->drawable.width;
-
 
2383
        tmp->src.scale[1] = 1.f/src->drawable.height;
-
 
2384
    }
-
 
2385
//    tmp->src.offset[0] = -dst_x;
-
 
2386
//    tmp->src.offset[1] = -dst_y;
-
 
2387
 
-
 
2388
 
-
 
2389
    tmp->mask.scale[0] = 1.f/mask->drawable.width;
-
 
2390
    tmp->mask.scale[1] = 1.f/mask->drawable.height;
-
 
2391
//    tmp->mask.offset[0] = -dst_x;
-
 
2392
//    tmp->mask.offset[1] = -dst_y;
-
 
2393
 
-
 
2394
	tmp->u.gen4.wm_kernel =
-
 
2395
		gen4_choose_composite_kernel(tmp->op,
-
 
2396
					     tmp->mask.bo != NULL,
-
 
2397
					     tmp->has_component_alpha,
-
 
2398
					     tmp->is_affine);
-
 
2399
	tmp->u.gen4.ve_id = gen4_choose_composite_emitter(sna, tmp);
-
 
2400
 
-
 
2401
	tmp->blt   = gen4_render_composite_blt;
-
 
2402
	tmp->done  = gen4_render_composite_done;
1437
 
2403
 
1438
	sna->render.flush = gen4_render_flush;
2404
	if (!kgem_check_bo(&sna->kgem,