Subversion Repositories Kolibri OS

Rev

Rev 2352 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2351 Serge 1
/*
2
 * Copyright © 2006,2008,2011 Intel Corporation
3
 * Copyright © 2007 Red Hat, Inc.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the next
13
 * paragraph) shall be included in all copies or substantial portions of the
14
 * 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 FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 * SOFTWARE.
23
 *
24
 * Authors:
25
 *    Wang Zhenyu 
26
 *    Eric Anholt 
27
 *    Carl Worth 
28
 *    Keith Packard 
29
 *    Chris Wilson 
30
 *
31
 */
32
 
33
#include 
34
#include 
35
#include "i915_drm.h"
36
#include "i915_drv.h"
37
#include "intel_drv.h"
38
 
39
#include 
40
#include 
41
#include 
42
#include 
43
 
44
#include 
45
 
46
#include "../bitmap.h"
47
 
48
#include "sna.h"
49
//#include "sna_reg.h"
50
#include "sna_render.h"
51
//#include "sna_render_inline.h"
52
//#include "sna_video.h"
53
 
54
#include "gen6_render.h"
55
 
56
 
57
#define NO_COMPOSITE 0
58
#define NO_COMPOSITE_SPANS 0
59
#define NO_COPY 0
60
#define NO_COPY_BOXES 0
61
#define NO_FILL 0
62
#define NO_FILL_BOXES 0
63
#define NO_CLEAR 0
64
 
65
#define NO_RING_SWITCH 1
66
 
67
#define GEN6_MAX_SIZE 8192
68
 
69
static const uint32_t ps_kernel_nomask_affine[][4] = {
70
#include "exa_wm_src_affine.g6b"
71
#include "exa_wm_src_sample_argb.g6b"
72
#include "exa_wm_write.g6b"
73
};
74
 
2360 Serge 75
static const uint32_t ps_kernel_masknoca_affine[][4] = {
76
#include "exa_wm_src_affine.g6b"
2351 Serge 77
#include "exa_wm_src_sample_argb.g6b"
2360 Serge 78
#include "exa_wm_mask_affine.g6b"
79
#include "exa_wm_mask_sample_a.g6b"
80
#include "exa_wm_noca.g6b"
2351 Serge 81
#include "exa_wm_write.g6b"
82
};
83
 
84
 
85
#define KERNEL(kernel_enum, kernel, masked) \
86
    [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), masked}
87
static const struct wm_kernel_info {
88
	const char *name;
89
	const void *data;
90
	unsigned int size;
91
	Bool has_mask;
92
} wm_kernels[] = {
93
	KERNEL(NOMASK, ps_kernel_nomask_affine, FALSE),
2360 Serge 94
    KERNEL(MASK, ps_kernel_masknoca_affine, TRUE),
2351 Serge 95
};
96
#undef KERNEL
97
 
98
static const struct blendinfo {
99
	Bool src_alpha;
100
	uint32_t src_blend;
101
	uint32_t dst_blend;
102
} gen6_blend_op[] = {
103
	/* Clear */	{0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO},
104
	/* Src */	{0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO},
105
	/* Dst */	{0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ONE},
106
	/* Over */	{1, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
107
	/* OverReverse */ {0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ONE},
108
	/* In */	{0, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
109
	/* InReverse */	{1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_SRC_ALPHA},
110
	/* Out */	{0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
111
	/* OutReverse */ {1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
112
	/* Atop */	{1, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
113
	/* AtopReverse */ {1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_SRC_ALPHA},
114
	/* Xor */	{1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
115
	/* Add */	{0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ONE},
116
};
117
 
118
 
119
/**
120
 * Highest-valued BLENDFACTOR used in gen6_blend_op.
121
 *
122
 * This leaves out GEN6_BLENDFACTOR_INV_DST_COLOR,
123
 * GEN6_BLENDFACTOR_INV_CONST_{COLOR,ALPHA},
124
 * GEN6_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA}
125
 */
126
#define GEN6_BLENDFACTOR_COUNT (GEN6_BLENDFACTOR_INV_DST_ALPHA + 1)
127
 
128
/* FIXME: surface format defined in gen6_defines.h, shared Sampling engine
129
 * 1.7.2
130
 
131
static const struct formatinfo {
132
	CARD32 pict_fmt;
133
	uint32_t card_fmt;
134
} gen6_tex_formats[] = {
135
	{PICT_a8, GEN6_SURFACEFORMAT_A8_UNORM},
136
	{PICT_a8r8g8b8, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM},
137
	{PICT_x8r8g8b8, GEN6_SURFACEFORMAT_B8G8R8X8_UNORM},
138
	{PICT_a8b8g8r8, GEN6_SURFACEFORMAT_R8G8B8A8_UNORM},
139
	{PICT_x8b8g8r8, GEN6_SURFACEFORMAT_R8G8B8X8_UNORM},
140
	{PICT_r8g8b8, GEN6_SURFACEFORMAT_R8G8B8_UNORM},
141
	{PICT_r5g6b5, GEN6_SURFACEFORMAT_B5G6R5_UNORM},
142
	{PICT_a1r5g5b5, GEN6_SURFACEFORMAT_B5G5R5A1_UNORM},
143
	{PICT_a2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10A2_UNORM},
144
	{PICT_x2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10X2_UNORM},
145
	{PICT_a2b10g10r10, GEN6_SURFACEFORMAT_R10G10B10A2_UNORM},
146
	{PICT_x2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10X2_UNORM},
147
	{PICT_a4r4g4b4, GEN6_SURFACEFORMAT_B4G4R4A4_UNORM},
148
};
149
 */
150
 
151
#define GEN6_BLEND_STATE_PADDED_SIZE	ALIGN(sizeof(struct gen6_blend_state), 64)
152
 
153
#define BLEND_OFFSET(s, d) \
154
	(((s) * GEN6_BLENDFACTOR_COUNT + (d)) * GEN6_BLEND_STATE_PADDED_SIZE)
155
 
156
#define SAMPLER_OFFSET(sf, se, mf, me) \
157
	(((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) * 2 * sizeof(struct gen6_sampler_state))
158
 
159
#define OUT_BATCH(v) batch_emit(sna, v)
160
#define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y)
161
#define OUT_VERTEX_F(v) vertex_emit(sna, v)
162
 
163
static inline bool too_large(int width, int height)
164
{
165
	return width > GEN6_MAX_SIZE || height > GEN6_MAX_SIZE;
166
}
167
 
168
static uint32_t gen6_get_blend(int op,
169
			       bool has_component_alpha,
170
			       uint32_t dst_format)
171
{
172
	uint32_t src, dst;
173
 
174
    src = GEN6_BLENDFACTOR_ONE; //gen6_blend_op[op].src_blend;
175
    dst = GEN6_BLENDFACTOR_ZERO; //gen6_blend_op[op].dst_blend;
176
 
177
#if 0
178
	/* If there's no dst alpha channel, adjust the blend op so that
179
	 * we'll treat it always as 1.
180
	 */
181
	if (PICT_FORMAT_A(dst_format) == 0) {
182
		if (src == GEN6_BLENDFACTOR_DST_ALPHA)
183
			src = GEN6_BLENDFACTOR_ONE;
184
		else if (src == GEN6_BLENDFACTOR_INV_DST_ALPHA)
185
			src = GEN6_BLENDFACTOR_ZERO;
186
	}
187
 
188
	/* If the source alpha is being used, then we should only be in a
189
	 * case where the source blend factor is 0, and the source blend
190
	 * value is the mask channels multiplied by the source picture's alpha.
191
	 */
192
	if (has_component_alpha && gen6_blend_op[op].src_alpha) {
193
		if (dst == GEN6_BLENDFACTOR_SRC_ALPHA)
194
			dst = GEN6_BLENDFACTOR_SRC_COLOR;
195
		else if (dst == GEN6_BLENDFACTOR_INV_SRC_ALPHA)
196
			dst = GEN6_BLENDFACTOR_INV_SRC_COLOR;
197
	}
198
 
199
	DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n",
200
	     op, dst_format, PICT_FORMAT_A(dst_format),
201
	     src, dst, (int)BLEND_OFFSET(src, dst)));
202
#endif
203
 
204
	return BLEND_OFFSET(src, dst);
205
}
206
 
207
static uint32_t gen6_get_dest_format(CARD32 format)
208
{
209
    return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
210
 
211
/*
212
	switch (format) {
213
	default:
214
		assert(0);
215
	case PICT_a8r8g8b8:
216
	case PICT_x8r8g8b8:
217
		return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
218
	case PICT_a8b8g8r8:
219
	case PICT_x8b8g8r8:
220
		return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM;
221
	case PICT_a2r10g10b10:
222
	case PICT_x2r10g10b10:
223
		return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
224
	case PICT_r5g6b5:
225
		return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
226
	case PICT_x1r5g5b5:
227
	case PICT_a1r5g5b5:
228
		return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
229
	case PICT_a8:
230
		return GEN6_SURFACEFORMAT_A8_UNORM;
231
	case PICT_a4r4g4b4:
232
	case PICT_x4r4g4b4:
233
		return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM;
234
	}
235
 */
236
}
237
 
238
#if 0
239
static Bool gen6_check_dst_format(PictFormat format)
240
{
241
	switch (format) {
242
	case PICT_a8r8g8b8:
243
	case PICT_x8r8g8b8:
244
	case PICT_a8b8g8r8:
245
	case PICT_x8b8g8r8:
246
	case PICT_a2r10g10b10:
247
	case PICT_x2r10g10b10:
248
	case PICT_r5g6b5:
249
	case PICT_x1r5g5b5:
250
	case PICT_a1r5g5b5:
251
	case PICT_a8:
252
	case PICT_a4r4g4b4:
253
	case PICT_x4r4g4b4:
254
		return TRUE;
255
	}
256
	return FALSE;
257
}
258
 
259
static bool gen6_check_format(uint32_t format)
260
{
261
	switch (format) {
262
	case PICT_a8r8g8b8:
263
	case PICT_x8r8g8b8:
264
	case PICT_a8b8g8r8:
265
	case PICT_x8b8g8r8:
266
	case PICT_a2r10g10b10:
267
	case PICT_x2r10g10b10:
268
	case PICT_r8g8b8:
269
	case PICT_r5g6b5:
270
	case PICT_a1r5g5b5:
271
	case PICT_a8:
272
	case PICT_a4r4g4b4:
273
	case PICT_x4r4g4b4:
274
		return true;
275
	default:
276
		DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
277
		return false;
278
	}
279
}
280
 
281
static uint32_t gen6_filter(uint32_t filter)
282
{
283
	switch (filter) {
284
	default:
285
		assert(0);
286
	case PictFilterNearest:
287
		return SAMPLER_FILTER_NEAREST;
288
	case PictFilterBilinear:
289
		return SAMPLER_FILTER_BILINEAR;
290
	}
291
}
292
 
293
static uint32_t gen6_check_filter(PicturePtr picture)
294
{
295
	switch (picture->filter) {
296
	case PictFilterNearest:
297
	case PictFilterBilinear:
298
		return TRUE;
299
	default:
300
		return FALSE;
301
	}
302
}
303
 
304
static uint32_t gen6_repeat(uint32_t repeat)
305
{
306
	switch (repeat) {
307
	default:
308
		assert(0);
309
	case RepeatNone:
310
		return SAMPLER_EXTEND_NONE;
311
	case RepeatNormal:
312
		return SAMPLER_EXTEND_REPEAT;
313
	case RepeatPad:
314
		return SAMPLER_EXTEND_PAD;
315
	case RepeatReflect:
316
		return SAMPLER_EXTEND_REFLECT;
317
	}
318
}
319
 
320
static bool gen6_check_repeat(PicturePtr picture)
321
{
322
	if (!picture->repeat)
323
		return TRUE;
324
 
325
	switch (picture->repeatType) {
326
	case RepeatNone:
327
	case RepeatNormal:
328
	case RepeatPad:
329
	case RepeatReflect:
330
		return TRUE;
331
	default:
332
		return FALSE;
333
	}
334
}
335
#endif
336
 
337
static int
338
gen6_choose_composite_kernel(int op, Bool has_mask, Bool is_ca, Bool is_affine)
339
{
340
	int base;
341
 
342
	if (has_mask) {
343
/*
344
		if (is_ca) {
345
			if (gen6_blend_op[op].src_alpha)
346
				base = GEN6_WM_KERNEL_MASKCA_SRCALPHA;
347
			else
348
				base = GEN6_WM_KERNEL_MASKCA;
349
		} else
350
			base = GEN6_WM_KERNEL_MASK;
351
*/
352
	} else
353
		base = GEN6_WM_KERNEL_NOMASK;
354
 
355
	return base + !is_affine;
356
}
357
 
358
static void
359
gen6_emit_urb(struct sna *sna)
360
{
361
	OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2));
362
	OUT_BATCH(((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT) |
363
		  (24 << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT)); /* at least 24 on GEN6 */
364
	OUT_BATCH((0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT) |
365
		  (0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT)); /* no GS thread */
366
}
367
 
368
static void
369
gen6_emit_state_base_address(struct sna *sna)
370
{
371
	OUT_BATCH(GEN6_STATE_BASE_ADDRESS | (10 - 2));
372
	OUT_BATCH(0); /* general */
373
 
374
    OUT_BATCH((sna->kgem.batch_obj->gtt_offset+
375
              sna->kgem.batch_idx*4096)|BASE_ADDRESS_MODIFY);
376
 
377
    OUT_BATCH(sna->render_state.gen6.general_bo->gaddr|BASE_ADDRESS_MODIFY);
378
 
379
	OUT_BATCH(0); /* indirect */
380
 
381
    OUT_BATCH(sna->render_state.gen6.general_bo->gaddr|BASE_ADDRESS_MODIFY);
382
 
383
	/* upper bounds, disable */
384
	OUT_BATCH(0);
385
	OUT_BATCH(BASE_ADDRESS_MODIFY);
386
	OUT_BATCH(0);
387
	OUT_BATCH(BASE_ADDRESS_MODIFY);
388
}
389
 
390
static void
391
gen6_emit_viewports(struct sna *sna)
392
{
393
	OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS |
394
		  GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC |
395
		  (4 - 2));
396
	OUT_BATCH(0);
397
	OUT_BATCH(0);
398
	OUT_BATCH(sna->render_state.gen6.cc_vp);
399
}
400
 
401
static void
402
gen6_emit_vs(struct sna *sna)
403
{
404
	/* disable VS constant buffer */
405
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | (5 - 2));
406
	OUT_BATCH(0);
407
	OUT_BATCH(0);
408
	OUT_BATCH(0);
409
	OUT_BATCH(0);
410
 
411
	OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2));
412
	OUT_BATCH(0); /* no VS kernel */
413
	OUT_BATCH(0);
414
	OUT_BATCH(0);
415
	OUT_BATCH(0);
416
	OUT_BATCH(0); /* pass-through */
417
}
418
 
419
static void
420
gen6_emit_gs(struct sna *sna)
421
{
422
	/* disable GS constant buffer */
423
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2));
424
	OUT_BATCH(0);
425
	OUT_BATCH(0);
426
	OUT_BATCH(0);
427
	OUT_BATCH(0);
428
 
429
	OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2));
430
	OUT_BATCH(0); /* no GS kernel */
431
	OUT_BATCH(0);
432
	OUT_BATCH(0);
433
	OUT_BATCH(0);
434
	OUT_BATCH(0);
435
	OUT_BATCH(0); /* pass-through */
436
}
437
 
438
static void
439
gen6_emit_clip(struct sna *sna)
440
{
441
	OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2));
442
	OUT_BATCH(0);
443
	OUT_BATCH(0); /* pass-through */
444
	OUT_BATCH(0);
445
}
446
 
447
static void
448
gen6_emit_wm_constants(struct sna *sna)
449
{
450
	/* disable WM constant buffer */
451
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2));
452
	OUT_BATCH(0);
453
	OUT_BATCH(0);
454
	OUT_BATCH(0);
455
	OUT_BATCH(0);
456
}
457
 
458
static void
459
gen6_emit_null_depth_buffer(struct sna *sna)
460
{
461
	OUT_BATCH(GEN6_3DSTATE_DEPTH_BUFFER | (7 - 2));
462
	OUT_BATCH(GEN6_SURFACE_NULL << GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT |
463
		  GEN6_DEPTHFORMAT_D32_FLOAT << GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT);
464
	OUT_BATCH(0);
465
	OUT_BATCH(0);
466
	OUT_BATCH(0);
467
	OUT_BATCH(0);
468
	OUT_BATCH(0);
469
 
470
	OUT_BATCH(GEN6_3DSTATE_CLEAR_PARAMS | (2 - 2));
471
	OUT_BATCH(0);
472
}
473
 
474
static void
475
gen6_emit_invariant(struct sna *sna)
476
{
477
	OUT_BATCH(GEN6_PIPELINE_SELECT | PIPELINE_SELECT_3D);
478
 
479
	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | (3 - 2));
480
	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
2352 Serge 481
              GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
2351 Serge 482
	OUT_BATCH(0);
483
 
484
	OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2));
485
	OUT_BATCH(1);
486
 
487
	gen6_emit_urb(sna);
488
 
489
	gen6_emit_state_base_address(sna);
490
 
491
	gen6_emit_viewports(sna);
492
	gen6_emit_vs(sna);
493
	gen6_emit_gs(sna);
494
	gen6_emit_clip(sna);
495
	gen6_emit_wm_constants(sna);
496
	gen6_emit_null_depth_buffer(sna);
497
 
498
	sna->render_state.gen6.needs_invariant = FALSE;
499
}
500
 
501
static bool
502
gen6_emit_cc(struct sna *sna,
503
	     int op, bool has_component_alpha, uint32_t dst_format)
504
{
505
	struct gen6_render_state *render = &sna->render_state.gen6;
506
	uint32_t blend;
507
 
508
	blend = gen6_get_blend(op, has_component_alpha, dst_format);
509
 
510
	DBG(("%s(op=%d, ca=%d, format=%x): new=%x, current=%x\n",
511
	     __FUNCTION__,
512
	     op, has_component_alpha, dst_format,
513
	     blend, render->blend));
514
	if (render->blend == blend)
515
		return op <= PictOpSrc;
516
 
517
	OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2));
518
	OUT_BATCH((render->cc_blend + blend) | 1);
519
	if (render->blend == (unsigned)-1) {
520
		OUT_BATCH(1);
521
		OUT_BATCH(1);
522
	} else {
523
		OUT_BATCH(0);
524
		OUT_BATCH(0);
525
	}
526
 
527
	render->blend = blend;
528
	return op <= PictOpSrc;
529
}
530
 
531
static void
532
gen6_emit_sampler(struct sna *sna, uint32_t state)
533
{
534
	assert(state <
535
	       2 * sizeof(struct gen6_sampler_state) *
536
	       FILTER_COUNT * EXTEND_COUNT *
537
	       FILTER_COUNT * EXTEND_COUNT);
538
 
539
	if (sna->render_state.gen6.samplers == state)
540
		return;
541
 
542
	sna->render_state.gen6.samplers = state;
543
 
544
	OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS |
545
		  GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS |
546
		  (4 - 2));
547
	OUT_BATCH(0); /* VS */
548
	OUT_BATCH(0); /* GS */
549
	OUT_BATCH(sna->render_state.gen6.wm_state + state);
550
}
551
 
552
static void
553
gen6_emit_sf(struct sna *sna, Bool has_mask)
554
{
555
	int num_sf_outputs = has_mask ? 2 : 1;
556
 
557
	if (sna->render_state.gen6.num_sf_outputs == num_sf_outputs)
558
		return;
559
 
560
	DBG(("%s: num_sf_outputs=%d, read_length=%d, read_offset=%d\n",
561
	     __FUNCTION__, num_sf_outputs, 1, 0));
562
 
563
	sna->render_state.gen6.num_sf_outputs = num_sf_outputs;
564
 
565
	OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2));
566
	OUT_BATCH(num_sf_outputs << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT |
567
		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT |
568
		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT);
569
	OUT_BATCH(0);
570
	OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE);
571
	OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */
572
	OUT_BATCH(0);
573
	OUT_BATCH(0);
574
	OUT_BATCH(0);
575
	OUT_BATCH(0);
576
	OUT_BATCH(0); /* DW9 */
577
	OUT_BATCH(0);
578
	OUT_BATCH(0);
579
	OUT_BATCH(0);
580
	OUT_BATCH(0);
581
	OUT_BATCH(0); /* DW14 */
582
	OUT_BATCH(0);
583
	OUT_BATCH(0);
584
	OUT_BATCH(0);
585
	OUT_BATCH(0);
586
	OUT_BATCH(0); /* DW19 */
587
}
588
 
589
static void
590
gen6_emit_wm(struct sna *sna, unsigned int kernel, int nr_surfaces, int nr_inputs)
591
{
592
	if (sna->render_state.gen6.kernel == kernel)
593
		return;
594
 
595
	sna->render_state.gen6.kernel = kernel;
596
 
597
	DBG(("%s: switching to %s\n", __FUNCTION__, wm_kernels[kernel].name));
598
 
599
	OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2));
600
	OUT_BATCH(sna->render_state.gen6.wm_kernel[kernel]);
601
	OUT_BATCH(1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT |
602
		  nr_surfaces << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT);
603
	OUT_BATCH(0);
604
	OUT_BATCH(6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT); /* DW4 */
605
	OUT_BATCH((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT |
606
		  GEN6_3DSTATE_WM_DISPATCH_ENABLE |
607
		  GEN6_3DSTATE_WM_16_DISPATCH_ENABLE);
608
	OUT_BATCH(nr_inputs << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT |
609
		  GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
610
	OUT_BATCH(0);
611
	OUT_BATCH(0);
612
}
613
 
614
static bool
615
gen6_emit_binding_table(struct sna *sna, uint16_t offset)
616
{
617
	if (sna->render_state.gen6.surface_table == offset)
618
		return false;
619
 
620
	/* Binding table pointers */
621
	OUT_BATCH(GEN6_3DSTATE_BINDING_TABLE_POINTERS |
622
		  GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS |
623
		  (4 - 2));
624
	OUT_BATCH(0);		/* vs */
625
	OUT_BATCH(0);		/* gs */
626
	/* Only the PS uses the binding table */
627
	OUT_BATCH(offset*4);
628
 
629
	sna->render_state.gen6.surface_table = offset;
630
	return true;
631
}
632
 
633
static bool
634
gen6_emit_drawing_rectangle(struct sna *sna,
635
			    const struct sna_composite_op *op)
636
{
637
	uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
638
	uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
639
 
640
	assert(!too_large(op->dst.x, op->dst.y));
641
	assert(!too_large(op->dst.width, op->dst.height));
642
 
643
	if (sna->render_state.gen6.drawrect_limit  == limit &&
644
	    sna->render_state.gen6.drawrect_offset == offset)
645
		return false;
646
 
647
	/* [DevSNB-C+{W/A}] Before any depth stall flush (including those
648
	 * produced by non-pipelined state commands), software needs to first
649
	 * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
650
	 * 0.
651
	 *
652
	 * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
653
	 * BEFORE the pipe-control with a post-sync op and no write-cache
654
	 * flushes.
655
	 */
656
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
657
	OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
658
		  GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
659
	OUT_BATCH(0);
660
	OUT_BATCH(0);
661
 
662
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
663
	OUT_BATCH(GEN6_PIPE_CONTROL_WRITE_TIME);
664
 
665
    OUT_BATCH(sna->render_state.gen6.general_bo->gaddr+64);
666
 
667
	OUT_BATCH(0);
668
 
669
	OUT_BATCH(GEN6_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
670
	OUT_BATCH(0);
671
	OUT_BATCH(limit);
672
	OUT_BATCH(offset);
673
 
674
	sna->render_state.gen6.drawrect_offset = offset;
675
	sna->render_state.gen6.drawrect_limit = limit;
676
	return true;
677
}
678
 
679
static void
680
gen6_emit_vertex_elements(struct sna *sna,
681
			  const struct sna_composite_op *op)
682
{
683
	/*
684
	 * vertex data in vertex buffer
685
	 *    position: (x, y)
686
	 *    texture coordinate 0: (u0, v0) if (is_affine is TRUE) else (u0, v0, w0)
687
	 *    texture coordinate 1 if (has_mask is TRUE): same as above
688
	 */
689
	struct gen6_render_state *render = &sna->render_state.gen6;
690
	int nelem = op->mask.bo ? 2 : 1;
691
	int selem = op->is_affine ? 2 : 3;
692
	uint32_t w_component;
693
	uint32_t src_format;
694
	int id = op->u.gen6.ve_id;
695
 
696
	if (render->ve_id == id)
697
		return;
698
	render->ve_id = id;
699
 
700
	if (op->is_affine) {
701
		src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT;
702
		w_component = GEN6_VFCOMPONENT_STORE_1_FLT;
703
	} else {
704
		src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT;
705
		w_component = GEN6_VFCOMPONENT_STORE_SRC;
706
	}
707
 
708
	/* The VUE layout
709
	 *    dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
710
	 *    dword 4-7: position (x, y, 1.0, 1.0),
711
	 *    dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0)
712
	 *    dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0)
713
	 *
714
	 * dword 4-15 are fetched from vertex buffer
715
	 */
716
	OUT_BATCH(GEN6_3DSTATE_VERTEX_ELEMENTS |
717
		((2 * (2 + nelem)) + 1 - 2));
718
 
719
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
720
		  GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT |
721
 
722
	OUT_BATCH(GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
723
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
724
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
725
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
726
 
727
	/* x,y */
728
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
729
		  GEN6_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
730
 
731
	OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
732
		  GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
733
		  GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
734
		  GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
735
 
736
	/* u0, v0, w0 */
737
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
738
		  src_format << VE0_FORMAT_SHIFT |
739
		  4 << VE0_OFFSET_SHIFT);	/* offset vb in bytes */
740
	OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
741
		  GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
742
		  w_component << VE1_VFCOMPONENT_2_SHIFT |
743
		  GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
744
 
745
	/* u1, v1, w1 */
746
	if (op->mask.bo) {
747
		OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
748
			  src_format << VE0_FORMAT_SHIFT |
749
			  ((1 + selem) * 4) << VE0_OFFSET_SHIFT); /* vb offset in bytes */
750
		OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
751
			  GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
752
			  w_component << VE1_VFCOMPONENT_2_SHIFT |
753
			  GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
754
	}
755
}
756
 
757
static void
758
gen6_emit_flush(struct sna *sna)
759
{
760
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
761
	OUT_BATCH(GEN6_PIPE_CONTROL_WC_FLUSH |
762
		  GEN6_PIPE_CONTROL_TC_FLUSH |
763
		  GEN6_PIPE_CONTROL_CS_STALL);
764
	OUT_BATCH(0);
765
	OUT_BATCH(0);
766
}
767
 
768
static void
769
gen6_emit_state(struct sna *sna,
770
		const struct sna_composite_op *op,
771
		uint16_t wm_binding_table)
772
{
773
	bool need_stall = wm_binding_table & 1;
774
 
775
	if (gen6_emit_cc(sna, op->op, op->has_component_alpha, op->dst.format))
776
		need_stall = false;
777
	gen6_emit_sampler(sna,
778
			  SAMPLER_OFFSET(op->src.filter,
779
					 op->src.repeat,
780
					 op->mask.filter,
781
					 op->mask.repeat));
782
	gen6_emit_sf(sna, op->mask.bo != NULL);
783
	gen6_emit_wm(sna,
784
		     op->u.gen6.wm_kernel,
785
		     op->u.gen6.nr_surfaces,
786
		     op->u.gen6.nr_inputs);
787
	gen6_emit_vertex_elements(sna, op);
788
	need_stall |= gen6_emit_binding_table(sna, wm_binding_table & ~1);
789
	if (gen6_emit_drawing_rectangle(sna, op))
790
		need_stall = false;
791
//    if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
792
        gen6_emit_flush(sna);
793
        kgem_clear_dirty(&sna->kgem);
794
		kgem_bo_mark_dirty(op->dst.bo);
795
		need_stall = false;
796
//   }
797
	if (need_stall) {
798
		OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
799
		OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
800
			  GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
801
		OUT_BATCH(0);
802
		OUT_BATCH(0);
803
	}
804
}
805
 
806
static void gen6_magic_ca_pass(struct sna *sna,
807
			       const struct sna_composite_op *op)
808
{
809
	struct gen6_render_state *state = &sna->render_state.gen6;
810
 
811
	if (!op->need_magic_ca_pass)
812
		return;
813
 
814
	DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__,
815
	     sna->render.vertex_start, sna->render.vertex_index));
816
 
817
	gen6_emit_flush(sna);
818
 
819
	gen6_emit_cc(sna, PictOpAdd, TRUE, op->dst.format);
820
	gen6_emit_wm(sna,
821
		     gen6_choose_composite_kernel(PictOpAdd,
822
						  TRUE, TRUE,
823
						  op->is_affine),
824
		     3, 2);
825
 
826
	OUT_BATCH(GEN6_3DPRIMITIVE |
827
		  GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
828
		  _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
829
 
830
		  4);
831
	OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start);
832
	OUT_BATCH(sna->render.vertex_start);
833
	OUT_BATCH(1);	/* single instance */
834
	OUT_BATCH(0);	/* start instance location */
835
	OUT_BATCH(0);	/* index buffer offset, ignored */
836
 
837
	state->last_primitive = sna->kgem.nbatch;
838
}
839
 
840
static void gen6_vertex_flush(struct sna *sna)
841
{
842
	assert(sna->render_state.gen6.vertex_offset);
843
 
844
	DBG(("%s[%x] = %d\n", __FUNCTION__,
845
	     4*sna->render_state.gen6.vertex_offset,
846
	     sna->render.vertex_index - sna->render.vertex_start));
847
	sna->kgem.batch[sna->render_state.gen6.vertex_offset] =
848
		sna->render.vertex_index - sna->render.vertex_start;
849
	sna->render_state.gen6.vertex_offset = 0;
850
}
851
 
852
static int gen6_vertex_finish(struct sna *sna)
853
{
854
	struct kgem_bo *bo;
855
	unsigned int i;
856
 
857
	DBG(("%s: used=%d / %d\n", __FUNCTION__,
858
	     sna->render.vertex_used, sna->render.vertex_size));
859
	assert(sna->render.vertex_used);
860
 
861
	/* Note: we only need dword alignment (currently) */
862
/*
863
	bo = sna->render.vbo;
864
	if (bo) {
865
		for (i = 0; i < ARRAY_SIZE(sna->render.vertex_reloc); i++) {
866
			if (sna->render.vertex_reloc[i]) {
867
				DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
868
				     i, sna->render.vertex_reloc[i]));
869
 
870
				sna->kgem.batch[sna->render.vertex_reloc[i]] =
871
					kgem_add_reloc(&sna->kgem,
872
						       sna->render.vertex_reloc[i],
873
						       bo,
874
						       I915_GEM_DOMAIN_VERTEX << 16,
875
						       0);
876
				sna->kgem.batch[sna->render.vertex_reloc[i]+1] =
877
					kgem_add_reloc(&sna->kgem,
878
						       sna->render.vertex_reloc[i]+1,
879
						       bo,
880
						       I915_GEM_DOMAIN_VERTEX << 16,
881
 
882
				sna->render.vertex_reloc[i] = 0;
883
			}
884
		}
885
 
886
		sna->render.vertex_used = 0;
887
		sna->render.vertex_index = 0;
888
		sna->render_state.gen6.vb_id = 0;
889
 
890
		kgem_bo_destroy(&sna->kgem, bo);
891
	}
892
*/
893
	sna->render.vertices = NULL;
894
	sna->render.vbo = kgem_create_linear(&sna->kgem, 256*1024);
895
	if (sna->render.vbo)
896
		sna->render.vertices = kgem_bo_map__cpu(&sna->kgem, sna->render.vbo);
897
	if (sna->render.vertices == NULL) {
898
		kgem_bo_destroy(&sna->kgem, sna->render.vbo);
899
		sna->render.vbo = NULL;
900
		return 0;
901
	}
902
 
903
//   kgem_bo_sync__cpu(&sna->kgem, sna->render.vbo);
904
	if (sna->render.vertex_used) {
905
		DBG(("%s: copying initial buffer x %d to handle=%d\n",
906
		     __FUNCTION__,
907
		     sna->render.vertex_used,
908
		     sna->render.vbo->handle));
909
		memcpy(sna->render.vertices,
910
		       sna->render.vertex_data,
911
		       sizeof(float)*sna->render.vertex_used);
912
	}
913
	sna->render.vertex_size = 64 * 1024 - 1;
914
	return sna->render.vertex_size - sna->render.vertex_used;
915
}
916
 
917
static void gen6_vertex_close(struct sna *sna)
918
{
919
	struct kgem_bo *bo;
920
	unsigned int i, delta = 0;
921
 
922
	if (!sna->render.vertex_used) {
923
		assert(sna->render.vbo == NULL);
924
		assert(sna->render.vertices == sna->render.vertex_data);
925
		assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
926
		return;
927
	}
928
 
929
	DBG(("%s: used=%d / %d\n", __FUNCTION__,
930
	     sna->render.vertex_used, sna->render.vertex_size));
931
 
932
	bo = sna->render.vbo;
933
	if (bo == NULL) {
934
		assert(sna->render.vertices == sna->render.vertex_data);
935
		assert(sna->render.vertex_used < ARRAY_SIZE(sna->render.vertex_data));
936
		if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
937
			DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
938
			     sna->render.vertex_used, sna->kgem.nbatch));
939
			memcpy(sna->kgem.batch + sna->kgem.nbatch,
940
			       sna->render.vertex_data,
941
			       sna->render.vertex_used * 4);
942
			delta = sna->kgem.nbatch * 4;
943
			bo = NULL;
944
			sna->kgem.nbatch += sna->render.vertex_used;
945
		} else {
946
			bo = kgem_create_linear(&sna->kgem, 4*sna->render.vertex_used);
947
			if (bo && !kgem_bo_write(&sna->kgem, bo,
948
						 sna->render.vertex_data,
949
						 4*sna->render.vertex_used)) {
950
				kgem_bo_destroy(&sna->kgem, bo);
951
				goto reset;
952
			}
953
			DBG(("%s: new vbo: %d\n", __FUNCTION__,
954
			     sna->render.vertex_used));
955
		}
956
	}
957
 
958
	for (i = 0; i < ARRAY_SIZE(sna->render.vertex_reloc); i++) {
959
		if (sna->render.vertex_reloc[i]) {
960
			DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
961
			     i, sna->render.vertex_reloc[i]));
962
 
963
            sna->kgem.batch[sna->render.vertex_reloc[i]] =
964
                            sna->kgem.batch_obj->gtt_offset+delta+
965
                            sna->kgem.batch_idx*4096;
966
 
967
            sna->kgem.batch[sna->render.vertex_reloc[i]+1] =
968
                            sna->kgem.batch_obj->gtt_offset+delta+
969
                            sna->kgem.batch_idx*4096+
970
                            sna->render.vertex_used * 4 - 1;
971
 
972
			sna->render.vertex_reloc[i] = 0;
973
		}
974
	}
975
 
976
//   if (bo)
977
//       kgem_bo_destroy(&sna->kgem, bo);
978
 
979
reset:
980
	sna->render.vertex_used = 0;
981
	sna->render.vertex_index = 0;
982
	sna->render_state.gen6.vb_id = 0;
983
 
984
	sna->render.vbo = NULL;
985
	sna->render.vertices = sna->render.vertex_data;
986
	sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
987
}
988
 
989
typedef struct gen6_surface_state_padded {
990
	struct gen6_surface_state state;
991
	char pad[32 - sizeof(struct gen6_surface_state)];
992
} gen6_surface_state_padded;
993
 
994
static void null_create(struct sna_static_stream *stream)
995
{
996
	/* A bunch of zeros useful for legacy border color and depth-stencil */
997
	sna_static_stream_map(stream, 64, 64);
998
}
999
 
1000
static void scratch_create(struct sna_static_stream *stream)
1001
{
1002
	/* 64 bytes of scratch space for random writes, such as
1003
	 * the pipe-control w/a.
1004
	 */
1005
	sna_static_stream_map(stream, 64, 64);
1006
}
1007
 
1008
static void
1009
sampler_state_init(struct gen6_sampler_state *sampler_state,
1010
		   sampler_filter_t filter,
1011
		   sampler_extend_t extend)
1012
{
1013
	sampler_state->ss0.lod_preclamp = 1;	/* GL mode */
1014
 
1015
	/* We use the legacy mode to get the semantics specified by
1016
	 * the Render extension. */
1017
	sampler_state->ss0.border_color_mode = GEN6_BORDER_COLOR_MODE_LEGACY;
1018
 
1019
	switch (filter) {
1020
	default:
1021
	case SAMPLER_FILTER_NEAREST:
1022
		sampler_state->ss0.min_filter = GEN6_MAPFILTER_NEAREST;
1023
		sampler_state->ss0.mag_filter = GEN6_MAPFILTER_NEAREST;
1024
		break;
1025
	case SAMPLER_FILTER_BILINEAR:
1026
		sampler_state->ss0.min_filter = GEN6_MAPFILTER_LINEAR;
1027
		sampler_state->ss0.mag_filter = GEN6_MAPFILTER_LINEAR;
1028
		break;
1029
	}
1030
 
1031
	switch (extend) {
1032
	default:
1033
	case SAMPLER_EXTEND_NONE:
1034
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
1035
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
1036
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
1037
		break;
1038
	case SAMPLER_EXTEND_REPEAT:
1039
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
1040
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
1041
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
1042
		break;
1043
	case SAMPLER_EXTEND_PAD:
1044
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
1045
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
1046
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
1047
		break;
1048
	case SAMPLER_EXTEND_REFLECT:
1049
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1050
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1051
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1052
		break;
1053
	}
1054
}
1055
 
1056
static uint32_t gen6_create_cc_viewport(struct sna_static_stream *stream)
1057
{
1058
	struct gen6_cc_viewport vp;
1059
 
1060
	vp.min_depth = -1.e35;
1061
	vp.max_depth = 1.e35;
1062
 
1063
	return sna_static_stream_add(stream, &vp, sizeof(vp), 32);
1064
}
1065
 
1066
#if 0
1067
 
1068
static uint32_t gen6_get_card_format(PictFormat format)
1069
{
1070
	unsigned int i;
1071
 
1072
	for (i = 0; i < ARRAY_SIZE(gen6_tex_formats); i++) {
1073
		if (gen6_tex_formats[i].pict_fmt == format)
1074
			return gen6_tex_formats[i].card_fmt;
1075
	}
1076
	return -1;
1077
}
1078
#endif
1079
 
1080
static uint32_t
1081
gen6_tiling_bits(uint32_t tiling)
1082
{
1083
    return 0;
1084
/*
1085
	switch (tiling) {
1086
	default: assert(0);
1087
	case I915_TILING_NONE: return 0;
1088
	case I915_TILING_X: return GEN6_SURFACE_TILED;
1089
	case I915_TILING_Y: return GEN6_SURFACE_TILED | GEN6_SURFACE_TILED_Y;
1090
	}
1091
*/
1092
}
1093
 
1094
/**
1095
 * Sets up the common fields for a surface state buffer for the given
1096
 * picture in the given surface state buffer.
1097
 */
1098
static int
1099
gen6_bind_bo(struct sna *sna,
1100
         struct kgem_bo *bo,
1101
	     uint32_t width,
1102
	     uint32_t height,
1103
	     uint32_t format,
1104
	     Bool is_dst)
1105
{
1106
	uint32_t *ss;
1107
	uint32_t domains;
1108
	uint16_t offset;
1109
 
1110
	/* After the first bind, we manage the cache domains within the batch */
1111
	if (is_dst) {
1112
		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
1113
//       kgem_bo_mark_dirty(bo);
1114
	} else
1115
		domains = I915_GEM_DOMAIN_SAMPLER << 16;
1116
 
1117
//   offset = kgem_bo_get_binding(bo, format);
1118
//   if (offset) {
1119
//        DBG(("[%x]  bo(handle=%x), format=%d, reuse %s binding\n",
1120
//            offset, bo->handle, format,
1121
//            domains & 0xffff ? "render" : "sampler"));
1122
//       return offset;
1123
//   }
1124
 
1125
	offset = sna->kgem.surface - sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1126
	offset *= sizeof(uint32_t);
1127
 
1128
	sna->kgem.surface -=
1129
		sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1130
	ss = sna->kgem.batch + sna->kgem.surface;
1131
	ss[0] = (GEN6_SURFACE_2D << GEN6_SURFACE_TYPE_SHIFT |
1132
		 GEN6_SURFACE_BLEND_ENABLED |
1133
		 format << GEN6_SURFACE_FORMAT_SHIFT);
1134
    ss[1] = bo->gaddr;
1135
	ss[2] = ((width - 1)  << GEN6_SURFACE_WIDTH_SHIFT |
1136
		 (height - 1) << GEN6_SURFACE_HEIGHT_SHIFT);
1137
	assert(bo->pitch <= (1 << 18));
1138
    ss[3] = (gen6_tiling_bits(0) |
1139
		 (bo->pitch - 1) << GEN6_SURFACE_PITCH_SHIFT);
1140
	ss[4] = 0;
1141
	ss[5] = 0;
1142
 
1143
//   kgem_bo_set_binding(bo, format, offset);
1144
 
1145
	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
1146
	     offset, bo->handle, ss[1],
1147
	     format, width, height, bo->pitch, bo->tiling,
1148
	     domains & 0xffff ? "render" : "sampler"));
1149
 
1150
	return offset;
1151
}
1152
 
1153
 
1154
static void gen6_emit_vertex_buffer(struct sna *sna,
1155
				    const struct sna_composite_op *op)
1156
{
1157
	int id = op->u.gen6.ve_id;
1158
 
1159
	OUT_BATCH(GEN6_3DSTATE_VERTEX_BUFFERS | 3);
1160
	OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA |
1161
		  4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT);
1162
	sna->render.vertex_reloc[id] = sna->kgem.nbatch;
1163
	OUT_BATCH(0);
1164
	OUT_BATCH(0);
1165
	OUT_BATCH(0);
1166
 
1167
	sna->render_state.gen6.vb_id |= 1 << id;
1168
}
1169
 
1170
static void gen6_emit_primitive(struct sna *sna)
1171
{
1172
	if (sna->kgem.nbatch == sna->render_state.gen6.last_primitive) {
1173
		DBG(("%s: continuing previous primitive, start=%d, index=%d\n",
1174
		     __FUNCTION__,
1175
		     sna->render.vertex_start,
1176
		     sna->render.vertex_index));
1177
		sna->render_state.gen6.vertex_offset = sna->kgem.nbatch - 5;
1178
		return;
1179
	}
1180
 
1181
	OUT_BATCH(GEN6_3DPRIMITIVE |
1182
		  GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
1183
		  _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
1184
 
1185
		  4);
1186
	sna->render_state.gen6.vertex_offset = sna->kgem.nbatch;
1187
	OUT_BATCH(0);	/* vertex count, to be filled in later */
1188
	OUT_BATCH(sna->render.vertex_index);
1189
	OUT_BATCH(1);	/* single instance */
1190
	OUT_BATCH(0);	/* start instance location */
1191
	OUT_BATCH(0);	/* index buffer offset, ignored */
1192
	sna->render.vertex_start = sna->render.vertex_index;
1193
	DBG(("%s: started new primitive: index=%d\n",
1194
	     __FUNCTION__, sna->render.vertex_start));
1195
 
1196
	sna->render_state.gen6.last_primitive = sna->kgem.nbatch;
1197
}
1198
 
1199
static bool gen6_rectangle_begin(struct sna *sna,
1200
				 const struct sna_composite_op *op)
1201
{
1202
	int id = 1 << op->u.gen6.ve_id;
1203
	int ndwords;
1204
 
1205
	ndwords = op->need_magic_ca_pass ? 60 : 6;
1206
	if ((sna->render_state.gen6.vb_id & id) == 0)
1207
		ndwords += 5;
1208
	if (!kgem_check_batch(&sna->kgem, ndwords))
1209
		return false;
1210
 
1211
	if ((sna->render_state.gen6.vb_id & id) == 0)
1212
		gen6_emit_vertex_buffer(sna, op);
1213
 
1214
	gen6_emit_primitive(sna);
1215
	return true;
1216
}
1217
 
1218
static int gen6_get_rectangles__flush(struct sna *sna,
1219
				      const struct sna_composite_op *op)
1220
{
1221
	if (sna->render_state.gen6.vertex_offset) {
1222
		gen6_vertex_flush(sna);
1223
		gen6_magic_ca_pass(sna, op);
1224
	}
1225
 
1226
	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5))
1227
		return 0;
1228
	if (sna->kgem.nexec > KGEM_EXEC_SIZE(&sna->kgem) - 1)
1229
		return 0;
1230
	if (sna->kgem.nreloc > KGEM_RELOC_SIZE(&sna->kgem) - 2)
1231
		return 0;
1232
 
1233
	return gen6_vertex_finish(sna);
1234
}
1235
 
1236
inline static int gen6_get_rectangles(struct sna *sna,
1237
				      const struct sna_composite_op *op,
1238
				      int want)
1239
{
1240
	int rem = vertex_space(sna);
1241
 
1242
	if (rem < op->floats_per_rect) {
1243
		DBG(("flushing vbo for %s: %d < %d\n",
1244
		     __FUNCTION__, rem, op->floats_per_rect));
1245
		rem = gen6_get_rectangles__flush(sna, op);
1246
		if (rem == 0)
1247
			return 0;
1248
	}
1249
 
1250
	if (sna->render_state.gen6.vertex_offset == 0 &&
1251
	    !gen6_rectangle_begin(sna, op))
1252
		return 0;
1253
 
1254
	if (want > 1 && want * op->floats_per_rect > rem)
1255
		want = rem / op->floats_per_rect;
1256
 
1257
	assert(want > 0);
1258
	sna->render.vertex_index += 3*want;
1259
	return want;
1260
}
1261
 
1262
inline static uint32_t *gen6_composite_get_binding_table(struct sna *sna,
1263
							 uint16_t *offset)
1264
{
1265
	uint32_t *table;
1266
 
1267
	sna->kgem.surface -=
1268
		sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1269
	/* Clear all surplus entries to zero in case of prefetch */
1270
	table = memset(sna->kgem.batch + sna->kgem.surface,
1271
		       0, sizeof(struct gen6_surface_state_padded));
1272
 
1273
	DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
1274
 
1275
	*offset = sna->kgem.surface;
1276
	return table;
1277
}
1278
 
1279
static uint32_t
1280
gen6_choose_composite_vertex_buffer(const struct sna_composite_op *op)
1281
{
1282
	int has_mask = op->mask.bo != NULL;
1283
	int is_affine = op->is_affine;
1284
	return has_mask << 1 | is_affine;
1285
}
1286
 
1287
static void
1288
gen6_get_batch(struct sna *sna)
1289
{
1290
	kgem_set_mode(&sna->kgem, KGEM_RENDER);
1291
/*
1292
	if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) {
1293
		DBG(("%s: flushing batch: %d < %d+%d\n",
1294
		     __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
1295
		     150, 4*8));
1296
		kgem_submit(&sna->kgem);
1297
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1298
	}
1299
*/
1300
 
1301
	if (sna->render_state.gen6.needs_invariant)
1302
		gen6_emit_invariant(sna);
1303
}
1304
 
1305
 
1306
static void
1307
gen6_align_vertex(struct sna *sna, const struct sna_composite_op *op)
1308
{
1309
	assert (sna->render_state.gen6.vertex_offset == 0);
1310
	if (op->floats_per_vertex != sna->render_state.gen6.floats_per_vertex) {
1311
		if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
1312
			/* XXX propagate failure */
1313
			gen6_vertex_finish(sna);
1314
 
1315
		DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
1316
		     sna->render_state.gen6.floats_per_vertex,
1317
		     op->floats_per_vertex,
1318
		     sna->render.vertex_index,
1319
		     (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
1320
		sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
1321
		sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
1322
		sna->render_state.gen6.floats_per_vertex = op->floats_per_vertex;
1323
	}
1324
}
1325
 
1326
 
1327
#ifndef MAX
1328
#define MAX(a,b) ((a) > (b) ? (a) : (b))
1329
#endif
1330
 
1331
static uint32_t
1332
gen6_composite_create_blend_state(struct sna_static_stream *stream)
1333
{
1334
	char *base, *ptr;
1335
	int src, dst;
1336
 
1337
	base = sna_static_stream_map(stream,
1338
				     GEN6_BLENDFACTOR_COUNT * GEN6_BLENDFACTOR_COUNT * GEN6_BLEND_STATE_PADDED_SIZE,
1339
				     64);
1340
 
1341
	ptr = base;
1342
	for (src = 0; src < GEN6_BLENDFACTOR_COUNT; src++) {
1343
		for (dst= 0; dst < GEN6_BLENDFACTOR_COUNT; dst++) {
1344
			struct gen6_blend_state *blend =
1345
				(struct gen6_blend_state *)ptr;
1346
 
1347
			blend->blend0.dest_blend_factor = dst;
1348
			blend->blend0.source_blend_factor = src;
1349
			blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD;
1350
			blend->blend0.blend_enable =
1351
				!(dst == GEN6_BLENDFACTOR_ZERO && src == GEN6_BLENDFACTOR_ONE);
1352
 
1353
			blend->blend1.post_blend_clamp_enable = 1;
1354
			blend->blend1.pre_blend_clamp_enable = 1;
1355
 
1356
			ptr += GEN6_BLEND_STATE_PADDED_SIZE;
1357
		}
1358
	}
1359
 
1360
	return sna_static_stream_offsetof(stream, base);
1361
}
1362
 
1363
#if 0
1364
static uint32_t gen6_bind_video_source(struct sna *sna,
1365
				       struct kgem_bo *src_bo,
1366
				       uint32_t src_offset,
1367
				       int src_width,
1368
				       int src_height,
1369
				       int src_pitch,
1370
				       uint32_t src_surf_format)
1371
{
1372
	struct gen6_surface_state *ss;
1373
 
1374
	sna->kgem.surface -= sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1375
 
1376
	ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss));
1377
	ss->ss0.surface_type = GEN6_SURFACE_2D;
1378
	ss->ss0.surface_format = src_surf_format;
1379
 
1380
	ss->ss1.base_addr =
1381
		kgem_add_reloc(&sna->kgem,
1382
			       sna->kgem.surface + 1,
1383
			       src_bo,
1384
			       I915_GEM_DOMAIN_SAMPLER << 16,
1385
			       src_offset);
1386
 
1387
	ss->ss2.width  = src_width - 1;
1388
	ss->ss2.height = src_height - 1;
1389
	ss->ss3.pitch  = src_pitch - 1;
1390
 
1391
	return sna->kgem.surface * sizeof(uint32_t);
1392
}
1393
 
1394
static void gen6_emit_video_state(struct sna *sna,
1395
				  struct sna_composite_op *op,
1396
				  struct sna_video_frame *frame)
1397
{
1398
	uint32_t src_surf_format;
1399
	uint32_t src_surf_base[6];
1400
	int src_width[6];
1401
	int src_height[6];
1402
	int src_pitch[6];
1403
	uint32_t *binding_table;
1404
	uint16_t offset;
1405
	bool dirty;
1406
	int n_src, n;
1407
 
1408
	gen6_get_batch(sna);
1409
	dirty = kgem_bo_is_dirty(op->dst.bo);
1410
 
1411
	src_surf_base[0] = 0;
1412
	src_surf_base[1] = 0;
1413
	src_surf_base[2] = frame->VBufOffset;
1414
	src_surf_base[3] = frame->VBufOffset;
1415
	src_surf_base[4] = frame->UBufOffset;
1416
	src_surf_base[5] = frame->UBufOffset;
1417
 
1418
	if (is_planar_fourcc(frame->id)) {
1419
		src_surf_format = GEN6_SURFACEFORMAT_R8_UNORM;
1420
		src_width[1]  = src_width[0]  = frame->width;
1421
		src_height[1] = src_height[0] = frame->height;
1422
		src_pitch[1]  = src_pitch[0]  = frame->pitch[1];
1423
		src_width[4]  = src_width[5]  = src_width[2]  = src_width[3] =
1424
			frame->width / 2;
1425
		src_height[4] = src_height[5] = src_height[2] = src_height[3] =
1426
			frame->height / 2;
1427
		src_pitch[4]  = src_pitch[5]  = src_pitch[2]  = src_pitch[3] =
1428
			frame->pitch[0];
1429
		n_src = 6;
1430
	} else {
1431
		if (frame->id == FOURCC_UYVY)
1432
			src_surf_format = GEN6_SURFACEFORMAT_YCRCB_SWAPY;
1433
		else
1434
			src_surf_format = GEN6_SURFACEFORMAT_YCRCB_NORMAL;
1435
 
1436
		src_width[0]  = frame->width;
1437
		src_height[0] = frame->height;
1438
		src_pitch[0]  = frame->pitch[0];
1439
		n_src = 1;
1440
	}
1441
 
1442
	binding_table = gen6_composite_get_binding_table(sna, &offset);
1443
 
1444
	binding_table[0] =
1445
		gen6_bind_bo(sna,
1446
			     op->dst.bo, op->dst.width, op->dst.height,
1447
			     gen6_get_dest_format(op->dst.format),
1448
			     TRUE);
1449
	for (n = 0; n < n_src; n++) {
1450
		binding_table[1+n] =
1451
			gen6_bind_video_source(sna,
1452
					       frame->bo,
1453
					       src_surf_base[n],
1454
					       src_width[n],
1455
					       src_height[n],
1456
					       src_pitch[n],
1457
					       src_surf_format);
1458
	}
1459
 
1460
	gen6_emit_state(sna, op, offset | dirty);
1461
}
1462
 
1463
static Bool
1464
gen6_render_video(struct sna *sna,
1465
		  struct sna_video *video,
1466
		  struct sna_video_frame *frame,
1467
		  RegionPtr dstRegion,
1468
		  short src_w, short src_h,
1469
		  short drw_w, short drw_h,
1470
		  PixmapPtr pixmap)
1471
{
1472
	struct sna_composite_op tmp;
1473
	int nbox, dxo, dyo, pix_xoff, pix_yoff;
1474
	float src_scale_x, src_scale_y;
1475
	struct sna_pixmap *priv;
1476
	BoxPtr box;
1477
 
1478
	DBG(("%s: src=(%d, %d), dst=(%d, %d), %dx[(%d, %d), (%d, %d)...]\n",
1479
	     __FUNCTION__, src_w, src_h, drw_w, drw_h,
1480
	     REGION_NUM_RECTS(dstRegion),
1481
	     REGION_EXTENTS(NULL, dstRegion)->x1,
1482
	     REGION_EXTENTS(NULL, dstRegion)->y1,
1483
	     REGION_EXTENTS(NULL, dstRegion)->x2,
1484
	     REGION_EXTENTS(NULL, dstRegion)->y2));
1485
 
1486
	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
1487
	if (priv == NULL)
1488
		return FALSE;
1489
 
1490
	memset(&tmp, 0, sizeof(tmp));
1491
 
1492
	tmp.op = PictOpSrc;
1493
	tmp.dst.pixmap = pixmap;
1494
	tmp.dst.width  = pixmap->drawable.width;
1495
	tmp.dst.height = pixmap->drawable.height;
1496
	tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth);
1497
	tmp.dst.bo = priv->gpu_bo;
1498
 
1499
	tmp.src.bo = frame->bo;
1500
	tmp.src.filter = SAMPLER_FILTER_BILINEAR;
1501
	tmp.src.repeat = SAMPLER_EXTEND_PAD;
1502
 
1503
	tmp.mask.bo = NULL;
1504
 
1505
	tmp.is_affine = TRUE;
1506
	tmp.floats_per_vertex = 3;
1507
	tmp.floats_per_rect = 9;
1508
 
1509
	if (is_planar_fourcc(frame->id)) {
1510
		tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_VIDEO_PLANAR;
1511
		tmp.u.gen6.nr_surfaces = 7;
1512
	} else {
1513
		tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_VIDEO_PACKED;
1514
		tmp.u.gen6.nr_surfaces = 2;
1515
	}
1516
	tmp.u.gen6.nr_inputs = 1;
1517
	tmp.u.gen6.ve_id = 1;
1518
 
1519
	kgem_set_mode(&sna->kgem, KGEM_RENDER);
1520
	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) {
1521
		kgem_submit(&sna->kgem);
1522
		assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL));
1523
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1524
	}
1525
 
1526
	gen6_emit_video_state(sna, &tmp, frame);
1527
	gen6_align_vertex(sna, &tmp);
1528
 
1529
	/* Set up the offset for translating from the given region (in screen
1530
	 * coordinates) to the backing pixmap.
1531
	 */
1532
#ifdef COMPOSITE
1533
	pix_xoff = -pixmap->screen_x + pixmap->drawable.x;
1534
	pix_yoff = -pixmap->screen_y + pixmap->drawable.y;
1535
#else
1536
	pix_xoff = 0;
1537
	pix_yoff = 0;
1538
#endif
1539
 
1540
	dxo = dstRegion->extents.x1;
1541
	dyo = dstRegion->extents.y1;
1542
 
1543
	/* Use normalized texture coordinates */
1544
	src_scale_x = ((float)src_w / frame->width) / (float)drw_w;
1545
	src_scale_y = ((float)src_h / frame->height) / (float)drw_h;
1546
 
1547
	box = REGION_RECTS(dstRegion);
1548
	nbox = REGION_NUM_RECTS(dstRegion);
1549
	while (nbox--) {
1550
		BoxRec r;
1551
 
1552
		r.x1 = box->x1 + pix_xoff;
1553
		r.x2 = box->x2 + pix_xoff;
1554
		r.y1 = box->y1 + pix_yoff;
1555
		r.y2 = box->y2 + pix_yoff;
1556
 
1557
		if (unlikely(!gen6_get_rectangles(sna, &tmp, 1))) {
1558
			_kgem_submit(&sna->kgem);
1559
			gen6_emit_video_state(sna, &tmp, frame);
1560
			gen6_get_rectangles(sna, &tmp, 1);
1561
		}
1562
 
1563
		OUT_VERTEX(r.x2, r.y2);
1564
		OUT_VERTEX_F((box->x2 - dxo) * src_scale_x);
1565
		OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
1566
 
1567
		OUT_VERTEX(r.x1, r.y2);
1568
		OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
1569
		OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
1570
 
1571
		OUT_VERTEX(r.x1, r.y1);
1572
		OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
1573
		OUT_VERTEX_F((box->y1 - dyo) * src_scale_y);
1574
 
1575
		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
1576
			sna_damage_add_box(&priv->gpu_damage, &r);
1577
			sna_damage_subtract_box(&priv->cpu_damage, &r);
1578
		}
1579
		box++;
1580
	}
1581
	priv->clear = false;
1582
 
1583
	gen6_vertex_flush(sna);
1584
	return TRUE;
1585
}
1586
 
1587
#endif
1588
 
1589
static void gen6_render_composite_done(struct sna *sna,
1590
				       const struct sna_composite_op *op)
1591
{
1592
	DBG(("%s\n", __FUNCTION__));
1593
 
1594
	if (sna->render_state.gen6.vertex_offset) {
1595
		gen6_vertex_flush(sna);
1596
		gen6_magic_ca_pass(sna, op);
1597
	}
1598
 
1599
//   if (op->mask.bo)
1600
//       kgem_bo_destroy(&sna->kgem, op->mask.bo);
1601
//   if (op->src.bo)
1602
//       kgem_bo_destroy(&sna->kgem, op->src.bo);
1603
 
1604
//   sna_render_composite_redirect_done(sna, op);
1605
}
1606
 
1607
 
1608
 
1609
static void
1610
gen6_emit_copy_state(struct sna *sna,
1611
		     const struct sna_composite_op *op)
1612
{
1613
	uint32_t *binding_table;
1614
	uint16_t offset;
1615
	bool dirty;
1616
 
1617
	gen6_get_batch(sna);
1618
 
1619
	binding_table = gen6_composite_get_binding_table(sna, &offset);
1620
 
1621
	binding_table[0] =
1622
		gen6_bind_bo(sna,
1623
			     op->dst.bo, op->dst.width, op->dst.height,
1624
                 GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
1625
			     TRUE);
1626
	binding_table[1] =
1627
		gen6_bind_bo(sna,
1628
			     op->src.bo, op->src.width, op->src.height,
1629
                 GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
1630
			     FALSE);
1631
 
1632
	if (sna->kgem.surface == offset &&
1633
	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
1634
		sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1635
		offset = sna->render_state.gen6.surface_table;
1636
	}
1637
 
1638
	gen6_emit_state(sna, op, offset | dirty);
1639
}
1640
 
1641
 
1642
static void
1643
gen6_render_copy_blt(struct sna *sna,
1644
             const struct sna_composite_op *op,
1645
		     int16_t sx, int16_t sy,
1646
		     int16_t w,  int16_t h,
1647
		     int16_t dx, int16_t dy)
1648
{
1649
    if (unlikely(!gen6_get_rectangles(sna, op, 1))) {
2352 Serge 1650
//       _kgem_submit(&sna->kgem);
2351 Serge 1651
        gen6_emit_copy_state(sna, op);
1652
        gen6_get_rectangles(sna, op, 1);
1653
	}
1654
 
1655
	OUT_VERTEX(dx+w, dy+h);
1656
    OUT_VERTEX_F((sx+w)*op->src.scale[0]);
1657
    OUT_VERTEX_F((sy+h)*op->src.scale[1]);
1658
 
1659
	OUT_VERTEX(dx, dy+h);
1660
    OUT_VERTEX_F(sx*op->src.scale[0]);
1661
    OUT_VERTEX_F((sy+h)*op->src.scale[1]);
1662
 
1663
	OUT_VERTEX(dx, dy);
1664
    OUT_VERTEX_F(sx*op->src.scale[0]);
1665
    OUT_VERTEX_F(sy*op->src.scale[1]);
1666
}
1667
 
1668
static void
1669
gen6_render_copy_done(struct sna *sna)
1670
{
1671
	DBG(("%s()\n", __FUNCTION__));
1672
 
1673
	if (sna->render_state.gen6.vertex_offset)
1674
		gen6_vertex_flush(sna);
1675
}
1676
 
1677
static Bool
1678
gen6_render_copy(struct sna *sna, uint8_t alu,
1679
         bitmap_t *src, struct kgem_bo *src_bo,
1680
         bitmap_t *dst, struct kgem_bo *dst_bo,
1681
         int dst_x, int dst_y, int src_x, int src_y, int w, int h)
1682
{
1683
    struct sna_composite_op op;
1684
 
1685
    memset(&op, 0, sizeof(op));
1686
 
1687
	DBG(("%s (alu=%d, src=(%dx%d), dst=(%dx%d))\n",
1688
	     __FUNCTION__, alu,
1689
         src->width, src->height,
1690
         dst->width, dst->height));
1691
 
1692
//    printf("%s %dx%d  src=(%dx%d), dst=(%dx%d)\n",
1693
//         __FUNCTION__,dst_x, dst_y,
1694
//         src->width, src->height,
1695
//         dst->width, dst->height);
1696
 
1697
    op.dst.format = 0;
1698
    op.src.pict_format = 0;
1699
 
1700
    op.op = PictOpSrc;
1701
 
1702
    op.dst.pixmap = dst;
1703
    op.dst.width  = dst->width;
1704
    op.dst.height = dst->height;
1705
    op.dst.bo = dst_bo;
1706
 
1707
    op.src.bo = src_bo;
1708
    op.src.card_format = GEN6_SURFACEFORMAT_B8G8R8X8_UNORM;
1709
    op.src.width  = src->width;
1710
    op.src.height = src->height;
1711
 
1712
    op.src.scale[0] = 1.f/w;            //src->width;
1713
    op.src.scale[1] = 1.f/h;            //src->height;
1714
    op.src.filter = SAMPLER_FILTER_BILINEAR;
1715
    op.src.repeat = SAMPLER_EXTEND_NONE;
1716
 
1717
    op.mask.bo = NULL;
1718
 
1719
    op.is_affine = true;
1720
    op.floats_per_vertex = 3;
1721
    op.floats_per_rect = 9;
1722
 
1723
    op.u.gen6.wm_kernel = GEN6_WM_KERNEL_NOMASK;
1724
    op.u.gen6.nr_surfaces = 2;
1725
    op.u.gen6.nr_inputs = 1;
1726
    op.u.gen6.ve_id = 1;
1727
 
1728
    gen6_emit_copy_state(sna, &op);
1729
    gen6_align_vertex(sna, &op);
1730
 
1731
    gen6_render_copy_blt(sna, &op, src_x, src_y, w, h, dst_x, dst_y);
1732
    gen6_render_copy_done(sna);
1733
 
1734
	return TRUE;
1735
}
1736
 
1737
static void
1738
gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op)
1739
{
1740
	uint32_t *binding_table;
1741
	uint16_t offset;
1742
	bool dirty;
1743
 
1744
	gen6_get_batch(sna);
1745
//   dirty = kgem_bo_is_dirty(op->dst.bo);
1746
 
1747
	binding_table = gen6_composite_get_binding_table(sna, &offset);
1748
 
1749
	binding_table[0] =
1750
		gen6_bind_bo(sna,
1751
                 op->dst.bo, 1024, 768,
1752
                 GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
1753
			     TRUE);
1754
	binding_table[1] =
1755
		gen6_bind_bo(sna,
1756
			     op->src.bo, 1, 1,
1757
			     GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
1758
			     FALSE);
1759
 
1760
	if (sna->kgem.surface == offset &&
1761
	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
1762
		sna->kgem.surface +=
1763
			sizeof(struct gen6_surface_state_padded)/sizeof(uint32_t);
1764
		offset = sna->render_state.gen6.surface_table;
1765
	}
1766
 
1767
	gen6_emit_state(sna, op, offset | dirty);
1768
}
1769
 
1770
 
1771
static Bool
1772
gen6_render_clear(struct sna *sna, bitmap_t *dst, struct kgem_bo *bo)
1773
{
1774
	struct sna_composite_op tmp;
1775
 
1776
 
1777
	DBG(("%s: %dx%d\n",
1778
	     __FUNCTION__,
1779
         dst->width,
1780
         dst->height));
1781
 
1782
	tmp.op = PictOpSrc;
1783
 
1784
	tmp.dst.pixmap = dst;
1785
    tmp.dst.width  = dst->width;
1786
    tmp.dst.height = dst->height;
1787
    tmp.dst.format = 0; //PICT_a8r8g8b8;
1788
	tmp.dst.bo = bo;
1789
	tmp.dst.x = tmp.dst.y = 0;
1790
 
1791
//   tmp.src.bo = sna_render_get_solid(sna, 0);
1792
    tmp.src.bo     = bo;
1793
	tmp.src.filter = SAMPLER_FILTER_NEAREST;
1794
	tmp.src.repeat = SAMPLER_EXTEND_REPEAT;
1795
 
1796
	tmp.mask.bo = NULL;
1797
	tmp.mask.filter = SAMPLER_FILTER_NEAREST;
1798
	tmp.mask.repeat = SAMPLER_EXTEND_NONE;
1799
 
1800
	tmp.is_affine = TRUE;
1801
	tmp.floats_per_vertex = 3;
1802
	tmp.floats_per_rect = 9;
1803
	tmp.has_component_alpha = 0;
1804
	tmp.need_magic_ca_pass = FALSE;
1805
 
1806
	tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_NOMASK;
1807
	tmp.u.gen6.nr_surfaces = 2;
1808
	tmp.u.gen6.nr_inputs = 1;
1809
	tmp.u.gen6.ve_id = 1;
1810
 
1811
//   if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
1812
//       _kgem_submit(&sna->kgem);
1813
//       assert(kgem_check_bo(&sna->kgem, bo, NULL));
1814
//   }
1815
 
1816
	gen6_emit_fill_state(sna, &tmp);
1817
	gen6_align_vertex(sna, &tmp);
1818
 
1819
	if (unlikely(!gen6_get_rectangles(sna, &tmp, 1))) {
2352 Serge 1820
//       _kgem_submit(&sna->kgem);
2351 Serge 1821
		gen6_emit_fill_state(sna, &tmp);
1822
		gen6_get_rectangles(sna, &tmp, 1);
1823
	}
1824
 
1825
    OUT_VERTEX(dst->width, dst->height);
1826
	OUT_VERTEX_F(1);
1827
	OUT_VERTEX_F(1);
1828
 
1829
    OUT_VERTEX(0, dst->height);
1830
	OUT_VERTEX_F(0);
1831
	OUT_VERTEX_F(1);
1832
 
1833
	OUT_VERTEX(0, 0);
1834
	OUT_VERTEX_F(0);
1835
	OUT_VERTEX_F(0);
1836
 
1837
    gen6_vertex_flush(sna);
1838
//   kgem_bo_destroy(&sna->kgem, tmp.src.bo);
1839
//    gen6_render_composite_done(sna, &tmp);
2352 Serge 1840
//    _kgem_submit(&sna->kgem);
2351 Serge 1841
 
1842
	return TRUE;
1843
}
1844
 
1845
static void gen6_render_flush(struct sna *sna)
1846
{
1847
	gen6_vertex_close(sna);
1848
}
1849
 
1850
 
1851
static void
1852
gen6_render_retire(struct kgem *kgem)
1853
{
1854
	if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire))
1855
		kgem->ring = kgem->mode;
1856
}
1857
 
1858
static void gen6_render_reset(struct sna *sna)
1859
{
1860
	sna->render_state.gen6.needs_invariant = TRUE;
1861
	sna->render_state.gen6.vb_id = 0;
1862
	sna->render_state.gen6.ve_id = -1;
1863
	sna->render_state.gen6.last_primitive = -1;
1864
 
1865
	sna->render_state.gen6.num_sf_outputs = 0;
1866
	sna->render_state.gen6.samplers = -1;
1867
	sna->render_state.gen6.blend = -1;
1868
	sna->render_state.gen6.kernel = -1;
1869
	sna->render_state.gen6.drawrect_offset = -1;
1870
	sna->render_state.gen6.drawrect_limit = -1;
1871
	sna->render_state.gen6.surface_table = -1;
1872
}
1873
 
1874
static void gen6_render_fini(struct sna *sna)
1875
{
1876
//   kgem_bo_destroy(&sna->kgem, sna->render_state.gen6.general_bo);
1877
}
1878
 
1879
static Bool gen6_render_setup(struct sna *sna)
1880
{
1881
	struct gen6_render_state *state = &sna->render_state.gen6;
1882
	struct sna_static_stream general;
1883
	struct gen6_sampler_state *ss;
1884
	int i, j, k, l, m;
1885
 
1886
    sna_static_stream_init(&general);
1887
 
1888
	/* Zero pad the start. If you see an offset of 0x0 in the batchbuffer
1889
	 * dumps, you know it points to zero.
1890
	 */
1891
    null_create(&general);
1892
    scratch_create(&general);
1893
 
1894
	for (m = 0; m < GEN6_KERNEL_COUNT; m++)
1895
		state->wm_kernel[m] =
1896
			sna_static_stream_add(&general,
1897
					       wm_kernels[m].data,
1898
					       wm_kernels[m].size,
1899
					       64);
1900
 
1901
	ss = sna_static_stream_map(&general,
1902
				   2 * sizeof(*ss) *
1903
				   FILTER_COUNT * EXTEND_COUNT *
1904
				   FILTER_COUNT * EXTEND_COUNT,
1905
				   32);
1906
	state->wm_state = sna_static_stream_offsetof(&general, ss);
1907
	for (i = 0; i < FILTER_COUNT; i++) {
1908
		for (j = 0; j < EXTEND_COUNT; j++) {
1909
			for (k = 0; k < FILTER_COUNT; k++) {
1910
				for (l = 0; l < EXTEND_COUNT; l++) {
1911
					sampler_state_init(ss++, i, j);
1912
					sampler_state_init(ss++, k, l);
1913
				}
1914
			}
1915
		}
1916
	}
1917
 
1918
    state->cc_vp = gen6_create_cc_viewport(&general);
1919
    state->cc_blend = gen6_composite_create_blend_state(&general);
1920
 
1921
    state->general_bo = sna_static_stream_fini(sna, &general);
1922
    return state->general_bo != NULL;
1923
}
1924
 
1925
Bool gen6_render_init(struct sna *sna)
1926
{
1927
    if (!gen6_render_setup(sna))
1928
        return FALSE;
1929
 
1930
//    sna->kgem.context_switch = gen6_render_context_switch;
1931
      sna->kgem.retire = gen6_render_retire;
1932
 
1933
//    sna->render.composite = gen6_render_composite;
1934
//    sna->render.video = gen6_render_video;
1935
 
1936
//    sna->render.copy_boxes = gen6_render_copy_boxes;
1937
    sna->render.copy = gen6_render_copy;
1938
 
1939
//    sna->render.fill_boxes = gen6_render_fill_boxes;
1940
//    sna->render.fill = gen6_render_fill;
1941
//    sna->render.fill_one = gen6_render_fill_one;
1942
    sna->render.clear = gen6_render_clear;
1943
 
1944
    sna->render.flush = gen6_render_flush;
1945
    sna->render.reset = gen6_render_reset;
1946
//    sna->render.fini = gen6_render_fini;
1947
 
1948
    sna->render.max_3d_size = GEN6_MAX_SIZE;
1949
    sna->render.max_3d_pitch = 1 << 18;
1950
    return TRUE;
1951
}