Subversion Repositories Kolibri OS

Rev

Rev 4245 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4245 Rev 4251
1
/*
1
/*
2
 * Copyright © 2010-2011 Intel Corporation
2
 * Copyright © 2010-2011 Intel Corporation
3
 *
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
10
 *
11
 * The above copyright notice and this permission notice (including the next
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
13
 * Software.
14
 *
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
21
 * SOFTWARE.
22
 *
22
 *
23
 * Authors:
23
 * Authors:
24
 *    Chris Wilson 
24
 *    Chris Wilson 
25
 *
25
 *
26
 */
26
 */
27
 
27
 
28
#ifdef HAVE_CONFIG_H
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
29
#include "config.h"
30
#endif
30
#endif
31
 
31
 
32
#include "sna.h"
32
#include "sna.h"
33
#include "sna_render.h"
33
#include "sna_render.h"
34
#include "sna_render_inline.h"
34
#include "sna_render_inline.h"
35
#include "sna_reg.h"
35
#include "sna_reg.h"
36
//#include "sna_video.h"
36
//#include "sna_video.h"
37
 
37
 
38
#include "gen3_render.h"
38
#include "gen3_render.h"
39
 
39
 
40
#define NO_COMPOSITE 0
40
#define NO_COMPOSITE 0
41
#define NO_COMPOSITE_SPANS 0
41
#define NO_COMPOSITE_SPANS 0
42
#define NO_COPY 0
42
#define NO_COPY 0
43
#define NO_COPY_BOXES 0
43
#define NO_COPY_BOXES 0
44
#define NO_FILL 0
44
#define NO_FILL 0
45
#define NO_FILL_ONE 0
45
#define NO_FILL_ONE 0
46
#define NO_FILL_BOXES 0
46
#define NO_FILL_BOXES 0
47
 
47
 
48
#define PREFER_BLT_FILL 1
48
#define PREFER_BLT_FILL 1
49
 
49
 
50
enum {
50
enum {
51
	SHADER_NONE = 0,
51
	SHADER_NONE = 0,
52
	SHADER_ZERO,
52
	SHADER_ZERO,
53
	SHADER_BLACK,
53
	SHADER_BLACK,
54
	SHADER_WHITE,
54
	SHADER_WHITE,
55
	SHADER_CONSTANT,
55
	SHADER_CONSTANT,
56
	SHADER_LINEAR,
56
	SHADER_LINEAR,
57
	SHADER_RADIAL,
57
	SHADER_RADIAL,
58
	SHADER_TEXTURE,
58
	SHADER_TEXTURE,
59
	SHADER_OPACITY,
59
	SHADER_OPACITY,
60
};
60
};
61
 
61
 
62
#define MAX_3D_SIZE 2048
62
#define MAX_3D_SIZE 2048
63
#define MAX_3D_PITCH 8192
63
#define MAX_3D_PITCH 8192
64
 
64
 
65
#define OUT_BATCH(v) batch_emit(sna, v)
65
#define OUT_BATCH(v) batch_emit(sna, v)
66
#define OUT_BATCH_F(v) batch_emit_float(sna, v)
66
#define OUT_BATCH_F(v) batch_emit_float(sna, v)
67
#define OUT_VERTEX(v) vertex_emit(sna, v)
67
#define OUT_VERTEX(v) vertex_emit(sna, v)
68
 
68
 
69
enum gen3_radial_mode {
69
enum gen3_radial_mode {
70
	RADIAL_ONE,
70
	RADIAL_ONE,
71
	RADIAL_TWO
71
	RADIAL_TWO
72
};
72
};
73
 
73
 
74
static const struct blendinfo {
74
static const struct blendinfo {
75
	bool dst_alpha;
75
	bool dst_alpha;
76
	bool src_alpha;
76
	bool src_alpha;
77
	uint32_t src_blend;
77
	uint32_t src_blend;
78
	uint32_t dst_blend;
78
	uint32_t dst_blend;
79
} gen3_blend_op[] = {
79
} gen3_blend_op[] = {
80
	/* Clear */	{0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO},
80
	/* Clear */	{0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO},
81
	/* Src */	{0, 0, BLENDFACT_ONE, BLENDFACT_ZERO},
81
	/* Src */	{0, 0, BLENDFACT_ONE, BLENDFACT_ZERO},
82
	/* Dst */	{0, 0, BLENDFACT_ZERO, BLENDFACT_ONE},
82
	/* Dst */	{0, 0, BLENDFACT_ZERO, BLENDFACT_ONE},
83
	/* Over */	{0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA},
83
	/* Over */	{0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA},
84
	/* OverReverse */ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
84
	/* OverReverse */ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
85
	/* In */	{1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO},
85
	/* In */	{1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO},
86
	/* InReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA},
86
	/* InReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA},
87
	/* Out */	{1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
87
	/* Out */	{1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
88
	/* OutReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA},
88
	/* OutReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA},
89
	/* Atop */	{1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
89
	/* Atop */	{1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
90
	/* AtopReverse */ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
90
	/* AtopReverse */ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
91
	/* Xor */	{1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
91
	/* Xor */	{1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
92
	/* Add */	{0, 0, BLENDFACT_ONE, BLENDFACT_ONE},
92
	/* Add */	{0, 0, BLENDFACT_ONE, BLENDFACT_ONE},
93
};
93
};
94
 
94
 
95
#define S6_COLOR_WRITE_ONLY \
95
#define S6_COLOR_WRITE_ONLY \
96
	(S6_COLOR_WRITE_ENABLE | \
96
	(S6_COLOR_WRITE_ENABLE | \
97
	 BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | \
97
	 BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | \
98
	 BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | \
98
	 BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | \
99
	 BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT)
99
	 BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT)
100
 
100
 
101
static const struct formatinfo {
101
static const struct formatinfo {
102
	unsigned int fmt, xfmt;
102
	unsigned int fmt, xfmt;
103
	uint32_t card_fmt;
103
	uint32_t card_fmt;
104
	bool rb_reversed;
104
	bool rb_reversed;
105
} gen3_tex_formats[] = {
105
} gen3_tex_formats[] = {
106
	{PICT_a8, 0, MAPSURF_8BIT | MT_8BIT_A8, false},
106
	{PICT_a8, 0, MAPSURF_8BIT | MT_8BIT_A8, false},
107
	{PICT_a8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_ARGB8888, false},
107
	{PICT_a8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_ARGB8888, false},
108
	{PICT_x8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_XRGB8888, false},
108
	{PICT_x8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_XRGB8888, false},
109
	{PICT_a8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_ABGR8888, false},
109
	{PICT_a8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_ABGR8888, false},
110
	{PICT_x8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_XBGR8888, false}
110
	{PICT_x8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_XBGR8888, false},
-
 
111
	{PICT_a2r10g10b10, PICT_x2r10g10b10, MAPSURF_32BIT | MT_32BIT_ARGB2101010, false},
-
 
112
	{PICT_a2b10g10r10, PICT_x2b10g10r10, MAPSURF_32BIT | MT_32BIT_ABGR2101010, false},
-
 
113
	{PICT_r5g6b5, 0, MAPSURF_16BIT | MT_16BIT_RGB565, false},
-
 
114
	{PICT_b5g6r5, 0, MAPSURF_16BIT | MT_16BIT_RGB565, true},
-
 
115
	{PICT_a1r5g5b5, PICT_x1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555, false},
-
 
116
	{PICT_a1b5g5r5, PICT_x1b5g5r5, MAPSURF_16BIT | MT_16BIT_ARGB1555, true},
-
 
117
	{PICT_a4r4g4b4, PICT_x4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444, false},
-
 
118
	{PICT_a4b4g4r4, PICT_x4b4g4r4, MAPSURF_16BIT | MT_16BIT_ARGB4444, true},
111
};
119
};
112
 
120
 
113
#define xFixedToDouble(f) pixman_fixed_to_double(f)
121
#define xFixedToDouble(f) pixman_fixed_to_double(f)
114
 
122
 
115
static inline bool too_large(int width, int height)
123
static inline bool too_large(int width, int height)
116
{
124
{
117
	return width > MAX_3D_SIZE || height > MAX_3D_SIZE;
125
	return width > MAX_3D_SIZE || height > MAX_3D_SIZE;
118
}
126
}
119
 
127
 
120
static inline uint32_t gen3_buf_tiling(uint32_t tiling)
128
static inline uint32_t gen3_buf_tiling(uint32_t tiling)
121
{
129
{
122
	uint32_t v = 0;
130
	uint32_t v = 0;
123
	switch (tiling) {
131
	switch (tiling) {
124
	case I915_TILING_Y: v |= BUF_3D_TILE_WALK_Y;
132
	case I915_TILING_Y: v |= BUF_3D_TILE_WALK_Y;
125
	case I915_TILING_X: v |= BUF_3D_TILED_SURFACE;
133
	case I915_TILING_X: v |= BUF_3D_TILED_SURFACE;
126
	case I915_TILING_NONE: break;
134
	case I915_TILING_NONE: break;
127
	}
135
	}
128
	return v;
136
	return v;
129
}
137
}
130
static uint32_t gen3_get_blend_cntl(int op,
138
static uint32_t gen3_get_blend_cntl(int op,
131
				    bool has_component_alpha,
139
				    bool has_component_alpha,
132
				    uint32_t dst_format)
140
				    uint32_t dst_format)
133
{
141
{
134
	uint32_t sblend;
142
	uint32_t sblend;
135
	uint32_t dblend;
143
	uint32_t dblend;
136
 
144
 
137
    sblend = BLENDFACT_ONE;
145
    sblend = BLENDFACT_ONE;
138
    dblend = BLENDFACT_INV_SRC_ALPHA;
146
    dblend = BLENDFACT_INV_SRC_ALPHA;
139
 
147
 
140
#if 0
148
#if 0
141
	if (op <= PictOpSrc) /* for clear and src disable blending */
149
	if (op <= PictOpSrc) /* for clear and src disable blending */
142
		return S6_COLOR_WRITE_ONLY;
150
		return S6_COLOR_WRITE_ONLY;
143
 
151
 
144
	/* If there's no dst alpha channel, adjust the blend op so that we'll
152
	/* If there's no dst alpha channel, adjust the blend op so that we'll
145
	 * treat it as always 1.
153
	 * treat it as always 1.
146
	 */
154
	 */
147
	if (gen3_blend_op[op].dst_alpha) {
155
	if (gen3_blend_op[op].dst_alpha) {
148
		if (PICT_FORMAT_A(dst_format) == 0) {
156
		if (PICT_FORMAT_A(dst_format) == 0) {
149
			if (sblend == BLENDFACT_DST_ALPHA)
157
			if (sblend == BLENDFACT_DST_ALPHA)
150
				sblend = BLENDFACT_ONE;
158
				sblend = BLENDFACT_ONE;
151
			else if (sblend == BLENDFACT_INV_DST_ALPHA)
159
			else if (sblend == BLENDFACT_INV_DST_ALPHA)
152
				sblend = BLENDFACT_ZERO;
160
				sblend = BLENDFACT_ZERO;
153
		}
161
		}
154
 
162
 
155
		/* gen3 engine reads 8bit color buffer into green channel
163
		/* gen3 engine reads 8bit color buffer into green channel
156
		 * in cases like color buffer blending etc., and also writes
164
		 * in cases like color buffer blending etc., and also writes
157
		 * back green channel.  So with dst_alpha blend we should use
165
		 * back green channel.  So with dst_alpha blend we should use
158
		 * color factor. See spec on "8-bit rendering".
166
		 * color factor. See spec on "8-bit rendering".
159
		 */
167
		 */
160
		if (dst_format == PICT_a8) {
168
		if (dst_format == PICT_a8) {
161
			if (sblend == BLENDFACT_DST_ALPHA)
169
			if (sblend == BLENDFACT_DST_ALPHA)
162
				sblend = BLENDFACT_DST_COLR;
170
				sblend = BLENDFACT_DST_COLR;
163
			else if (sblend == BLENDFACT_INV_DST_ALPHA)
171
			else if (sblend == BLENDFACT_INV_DST_ALPHA)
164
				sblend = BLENDFACT_INV_DST_COLR;
172
				sblend = BLENDFACT_INV_DST_COLR;
165
		}
173
		}
166
	}
174
	}
167
 
175
 
168
	/* If the source alpha is being used, then we should only be in a case
176
	/* If the source alpha is being used, then we should only be in a case
169
	 * where the source blend factor is 0, and the source blend value is the
177
	 * where the source blend factor is 0, and the source blend value is the
170
	 * mask channels multiplied by the source picture's alpha.
178
	 * mask channels multiplied by the source picture's alpha.
171
	 */
179
	 */
172
	if (has_component_alpha && gen3_blend_op[op].src_alpha) {
180
	if (has_component_alpha && gen3_blend_op[op].src_alpha) {
173
		if (dblend == BLENDFACT_SRC_ALPHA)
181
		if (dblend == BLENDFACT_SRC_ALPHA)
174
			dblend = BLENDFACT_SRC_COLR;
182
			dblend = BLENDFACT_SRC_COLR;
175
		else if (dblend == BLENDFACT_INV_SRC_ALPHA)
183
		else if (dblend == BLENDFACT_INV_SRC_ALPHA)
176
			dblend = BLENDFACT_INV_SRC_COLR;
184
			dblend = BLENDFACT_INV_SRC_COLR;
177
	}
185
	}
178
#endif
186
#endif
179
 
187
 
180
	return (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
188
	return (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
181
		BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT |
189
		BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT |
182
		sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT |
190
		sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT |
183
		dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
191
		dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
184
}
192
}
185
static bool gen3_dst_rb_reversed(uint32_t format)
193
static bool gen3_dst_rb_reversed(uint32_t format)
186
{
194
{
187
	switch (format) {
195
	switch (format) {
188
	case PICT_a8r8g8b8:
196
	case PICT_a8r8g8b8:
189
	case PICT_x8r8g8b8:
197
	case PICT_x8r8g8b8:
-
 
198
	case PICT_r5g6b5:
-
 
199
	case PICT_a1r5g5b5:
-
 
200
	case PICT_x1r5g5b5:
-
 
201
	case PICT_a2r10g10b10:
-
 
202
	case PICT_x2r10g10b10:
190
	case PICT_a8:
203
	case PICT_a8:
-
 
204
	case PICT_a4r4g4b4:
-
 
205
	case PICT_x4r4g4b4:
191
		return false;
206
		return false;
192
	default:
207
	default:
193
		return true;
208
		return true;
194
	}
209
	}
195
}
210
}
196
 
211
 
197
#define DSTORG_HORT_BIAS(x)             ((x)<<20)
212
#define DSTORG_HORT_BIAS(x)             ((x)<<20)
198
#define DSTORG_VERT_BIAS(x)             ((x)<<16)
213
#define DSTORG_VERT_BIAS(x)             ((x)<<16)
199
 
214
 
200
static uint32_t gen3_get_dst_format(uint32_t format)
215
static uint32_t gen3_get_dst_format(uint32_t format)
201
{
216
{
202
#define BIAS (DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8))
217
#define BIAS (DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8))
203
	switch (format) {
218
	switch (format) {
204
	default:
219
	default:
205
	case PICT_a8r8g8b8:
220
	case PICT_a8r8g8b8:
206
	case PICT_x8r8g8b8:
221
	case PICT_x8r8g8b8:
207
	case PICT_a8b8g8r8:
222
	case PICT_a8b8g8r8:
208
	case PICT_x8b8g8r8:
223
	case PICT_x8b8g8r8:
209
		return BIAS | COLR_BUF_ARGB8888;
224
		return BIAS | COLR_BUF_ARGB8888;
-
 
225
	case PICT_r5g6b5:
-
 
226
	case PICT_b5g6r5:
-
 
227
		return BIAS | COLR_BUF_RGB565;
-
 
228
	case PICT_a1r5g5b5:
-
 
229
	case PICT_x1r5g5b5:
-
 
230
	case PICT_a1b5g5r5:
-
 
231
	case PICT_x1b5g5r5:
-
 
232
		return BIAS | COLR_BUF_ARGB1555;
-
 
233
	case PICT_a2r10g10b10:
-
 
234
	case PICT_x2r10g10b10:
-
 
235
	case PICT_a2b10g10r10:
-
 
236
	case PICT_x2b10g10r10:
-
 
237
		return BIAS | COLR_BUF_ARGB2AAA;
210
	case PICT_a8:
238
	case PICT_a8:
211
		return BIAS | COLR_BUF_8BIT;
239
		return BIAS | COLR_BUF_8BIT;
-
 
240
	case PICT_a4r4g4b4:
-
 
241
	case PICT_x4r4g4b4:
-
 
242
	case PICT_a4b4g4r4:
-
 
243
	case PICT_x4b4g4r4:
-
 
244
		return BIAS | COLR_BUF_ARGB4444;
212
	}
245
	}
213
#undef BIAS
246
#undef BIAS
214
}
247
}
215
 
248
 
-
 
249
 
-
 
250
#if 0
-
 
251
static bool gen3_check_repeat(PicturePtr p)
-
 
252
{
-
 
253
	if (!p->repeat)
-
 
254
		return true;
-
 
255
 
-
 
256
	switch (p->repeatType) {
-
 
257
	case RepeatNone:
-
 
258
	case RepeatNormal:
-
 
259
	case RepeatPad:
-
 
260
	case RepeatReflect:
-
 
261
		return true;
-
 
262
	default:
-
 
263
		return false;
-
 
264
	}
-
 
265
}
-
 
266
 
-
 
267
static uint32_t gen3_filter(uint32_t filter)
-
 
268
{
-
 
269
	switch (filter) {
-
 
270
	default:
-
 
271
		assert(0);
-
 
272
	case PictFilterNearest:
-
 
273
		return (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT |
-
 
274
			FILTER_NEAREST << SS2_MIN_FILTER_SHIFT |
-
 
275
			MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
-
 
276
	case PictFilterBilinear:
-
 
277
		return (FILTER_LINEAR  << SS2_MAG_FILTER_SHIFT |
-
 
278
			FILTER_LINEAR  << SS2_MIN_FILTER_SHIFT |
-
 
279
			MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
-
 
280
	}
-
 
281
}
-
 
282
 
-
 
283
static bool gen3_check_filter(PicturePtr p)
-
 
284
{
-
 
285
	switch (p->filter) {
-
 
286
	case PictFilterNearest:
-
 
287
	case PictFilterBilinear:
-
 
288
		return true;
-
 
289
	default:
-
 
290
		return false;
-
 
291
	}
-
 
292
}
-
 
293
fastcall static void
-
 
294
gen3_emit_composite_primitive_identity_gradient(struct sna *sna,
-
 
295
						const struct sna_composite_op *op,
-
 
296
						const struct sna_composite_rectangles *r)
-
 
297
{
-
 
298
	int16_t dst_x, dst_y;
-
 
299
	int16_t src_x, src_y;
-
 
300
 
-
 
301
	dst_x = r->dst.x + op->dst.x;
-
 
302
	dst_y = r->dst.y + op->dst.y;
-
 
303
	src_x = r->src.x + op->src.offset[0];
-
 
304
	src_y = r->src.y + op->src.offset[1];
-
 
305
 
-
 
306
	gen3_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height);
-
 
307
	OUT_VERTEX(src_x + r->width);
-
 
308
	OUT_VERTEX(src_y + r->height);
-
 
309
 
-
 
310
	gen3_emit_composite_dstcoord(sna, dst_x, dst_y + r->height);
-
 
311
	OUT_VERTEX(src_x);
-
 
312
	OUT_VERTEX(src_y + r->height);
-
 
313
 
-
 
314
	gen3_emit_composite_dstcoord(sna, dst_x, dst_y);
-
 
315
	OUT_VERTEX(src_x);
-
 
316
	OUT_VERTEX(src_y);
-
 
317
}
-
 
318
 
-
 
319
fastcall static void
-
 
320
gen3_emit_composite_boxes_identity_gradient(const struct sna_composite_op *op,
-
 
321
					    const BoxRec *box, int nbox,
-
 
322
					    float *v)
-
 
323
{
-
 
324
	do {
-
 
325
		v[0] = box->x2;
-
 
326
		v[1] = box->y2;
-
 
327
		v[2] = box->x2 + op->src.offset[0];
-
 
328
		v[3] = box->y2 + op->src.offset[1];
-
 
329
 
-
 
330
		v[4] = box->x1;
-
 
331
		v[5] = box->y2;
-
 
332
		v[6] = box->x1 + op->src.offset[0];
-
 
333
		v[7] = box->y2 + op->src.offset[1];
-
 
334
 
-
 
335
		v[8] = box->x1;
-
 
336
		v[9] = box->y1;
-
 
337
		v[10] = box->x1 + op->src.offset[0];
-
 
338
		v[11] = box->y1 + op->src.offset[1];
-
 
339
 
-
 
340
		v += 12;
-
 
341
		box++;
-
 
342
	} while (--nbox);
-
 
343
}
-
 
344
fastcall static void
-
 
345
gen3_emit_composite_boxes_affine_gradient(const struct sna_composite_op *op,
-
 
346
					  const BoxRec *box, int nbox,
-
 
347
					  float *v)
-
 
348
{
-
 
349
	const PictTransform *transform = op->src.transform;
-
 
350
 
-
 
351
	do {
-
 
352
		v[0] = box->x2;
-
 
353
		v[1] = box->y2;
-
 
354
		_sna_get_transformed_scaled(box->x2 + op->src.offset[0],
-
 
355
					    box->y2 + op->src.offset[1],
-
 
356
					    transform, op->src.scale,
-
 
357
					    &v[2], &v[3]);
-
 
358
 
-
 
359
		v[4] = box->x1;
-
 
360
		v[5] = box->y2;
-
 
361
		_sna_get_transformed_scaled(box->x1 + op->src.offset[0],
-
 
362
					    box->y2 + op->src.offset[1],
-
 
363
					    transform, op->src.scale,
-
 
364
					    &v[6], &v[7]);
-
 
365
 
-
 
366
		v[8] = box->x1;
-
 
367
		v[9] = box->y1;
-
 
368
		_sna_get_transformed_scaled(box->x1 + op->src.offset[0],
-
 
369
					    box->y1 + op->src.offset[1],
-
 
370
					    transform, op->src.scale,
-
 
371
					    &v[10], &v[11]);
-
 
372
 
-
 
373
		box++;
-
 
374
		v += 12;
-
 
375
	} while (--nbox);
-
 
376
}
-
 
377
 
-
 
378
fastcall static void
-
 
379
gen3_emit_composite_primitive_identity_source(struct sna *sna,
-
 
380
					      const struct sna_composite_op *op,
-
 
381
					      const struct sna_composite_rectangles *r)
-
 
382
{
-
 
383
	float w = r->width;
-
 
384
	float h = r->height;
-
 
385
	float *v;
-
 
386
 
-
 
387
	v = sna->render.vertices + sna->render.vertex_used;
-
 
388
	sna->render.vertex_used += 12;
-
 
389
 
-
 
390
	v[8] = v[4] = r->dst.x + op->dst.x;
-
 
391
	v[0] = v[4] + w;
-
 
392
 
-
 
393
	v[9] = r->dst.y + op->dst.y;
-
 
394
	v[5] = v[1] = v[9] + h;
-
 
395
 
-
 
396
	v[10] = v[6] = (r->src.x + op->src.offset[0]) * op->src.scale[0];
-
 
397
	v[2] = v[6] + w * op->src.scale[0];
-
 
398
 
-
 
399
	v[11] = (r->src.y + op->src.offset[1]) * op->src.scale[1];
-
 
400
	v[7] = v[3] = v[11] + h * op->src.scale[1];
-
 
401
}
-
 
402
 
-
 
403
fastcall static void
-
 
404
gen3_emit_composite_boxes_identity_source(const struct sna_composite_op *op,
-
 
405
					  const BoxRec *box, int nbox,
-
 
406
					  float *v)
-
 
407
{
-
 
408
	do {
-
 
409
		v[0] = box->x2 + op->dst.x;
-
 
410
		v[8] = v[4] = box->x1 + op->dst.x;
-
 
411
		v[5] = v[1] = box->y2 + op->dst.y;
-
 
412
		v[9] = box->y1 + op->dst.y;
-
 
413
 
-
 
414
		v[10] = v[6] = (box->x1 + op->src.offset[0]) * op->src.scale[0];
-
 
415
		v[2] = (box->x2 + op->src.offset[0]) * op->src.scale[0];
-
 
416
 
-
 
417
		v[11] = (box->y1 + op->src.offset[1]) * op->src.scale[1];
-
 
418
		v[7] = v[3] = (box->y2 + op->src.offset[1]) * op->src.scale[1];
-
 
419
 
-
 
420
		v += 12;
-
 
421
		box++;
-
 
422
	} while (--nbox);
-
 
423
}
-
 
424
 
-
 
425
fastcall static void
-
 
426
gen3_emit_composite_primitive_identity_source_no_offset(struct sna *sna,
-
 
427
							const struct sna_composite_op *op,
-
 
428
							const struct sna_composite_rectangles *r)
-
 
429
{
-
 
430
	float w = r->width;
-
 
431
	float h = r->height;
-
 
432
	float *v;
-
 
433
 
-
 
434
	v = sna->render.vertices + sna->render.vertex_used;
-
 
435
	sna->render.vertex_used += 12;
-
 
436
 
-
 
437
	v[8] = v[4] = r->dst.x;
-
 
438
	v[9] = r->dst.y;
-
 
439
 
-
 
440
	v[0] = v[4] + w;
-
 
441
	v[5] = v[1] = v[9] + h;
-
 
442
 
-
 
443
	v[10] = v[6] = r->src.x * op->src.scale[0];
-
 
444
	v[11] = r->src.y * op->src.scale[1];
-
 
445
 
-
 
446
	v[2] = v[6] + w * op->src.scale[0];
-
 
447
	v[7] = v[3] = v[11] + h * op->src.scale[1];
-
 
448
}
-
 
449
fastcall static void
-
 
450
gen3_emit_composite_primitive_constant_identity_mask(struct sna *sna,
-
 
451
						     const struct sna_composite_op *op,
-
 
452
						     const struct sna_composite_rectangles *r)
-
 
453
{
-
 
454
	float w = r->width;
-
 
455
	float h = r->height;
-
 
456
	float *v;
-
 
457
 
-
 
458
	v = sna->render.vertices + sna->render.vertex_used;
-
 
459
	sna->render.vertex_used += 12;
-
 
460
 
-
 
461
	v[8] = v[4] = r->dst.x + op->dst.x;
-
 
462
	v[0] = v[4] + w;
-
 
463
 
-
 
464
	v[9] = r->dst.y + op->dst.y;
-
 
465
	v[5] = v[1] = v[9] + h;
-
 
466
 
-
 
467
	v[10] = v[6] = (r->mask.x + op->mask.offset[0]) * op->mask.scale[0];
-
 
468
	v[2] = v[6] + w * op->mask.scale[0];
-
 
469
 
-
 
470
	v[11] = (r->mask.y + op->mask.offset[1]) * op->mask.scale[1];
-
 
471
	v[7] = v[3] = v[11] + h * op->mask.scale[1];
-
 
472
}
216
 
473
#endif
217
 
474
 
218
fastcall static void
475
fastcall static void
219
gen3_emit_composite_primitive_identity_source_mask(struct sna *sna,
476
gen3_emit_composite_primitive_identity_source_mask(struct sna *sna,
220
						   const struct sna_composite_op *op,
477
						   const struct sna_composite_op *op,
221
						   const struct sna_composite_rectangles *r)
478
						   const struct sna_composite_rectangles *r)
222
{
479
{
223
	float dst_x, dst_y;
480
	float dst_x, dst_y;
224
	float src_x, src_y;
481
	float src_x, src_y;
225
	float msk_x, msk_y;
482
	float msk_x, msk_y;
226
	float w, h;
483
	float w, h;
227
	float *v;
484
	float *v;
228
 
485
 
229
	dst_x = r->dst.x + op->dst.x;
486
	dst_x = r->dst.x + op->dst.x;
230
	dst_y = r->dst.y + op->dst.y;
487
	dst_y = r->dst.y + op->dst.y;
231
	src_x = r->src.x + op->src.offset[0];
488
	src_x = r->src.x + op->src.offset[0];
232
	src_y = r->src.y + op->src.offset[1];
489
	src_y = r->src.y + op->src.offset[1];
233
	msk_x = r->mask.x + op->mask.offset[0];
490
	msk_x = r->mask.x + op->mask.offset[0];
234
	msk_y = r->mask.y + op->mask.offset[1];
491
	msk_y = r->mask.y + op->mask.offset[1];
235
	w = r->width;
492
	w = r->width;
236
	h = r->height;
493
	h = r->height;
237
 
494
 
238
	v = sna->render.vertices + sna->render.vertex_used;
495
	v = sna->render.vertices + sna->render.vertex_used;
239
	sna->render.vertex_used += 18;
496
	sna->render.vertex_used += 18;
240
 
497
 
241
	v[0] = dst_x + w;
498
	v[0] = dst_x + w;
242
	v[1] = dst_y + h;
499
	v[1] = dst_y + h;
243
	v[2] = (src_x + w) * op->src.scale[0];
500
	v[2] = (src_x + w) * op->src.scale[0];
244
	v[3] = (src_y + h) * op->src.scale[1];
501
	v[3] = (src_y + h) * op->src.scale[1];
245
	v[4] = (msk_x + w) * op->mask.scale[0];
502
	v[4] = (msk_x + w) * op->mask.scale[0];
246
	v[5] = (msk_y + h) * op->mask.scale[1];
503
	v[5] = (msk_y + h) * op->mask.scale[1];
247
 
504
 
248
	v[6] = dst_x;
505
	v[6] = dst_x;
249
	v[7] = v[1];
506
	v[7] = v[1];
250
	v[8] = src_x * op->src.scale[0];
507
	v[8] = src_x * op->src.scale[0];
251
	v[9] = v[3];
508
	v[9] = v[3];
252
	v[10] = msk_x * op->mask.scale[0];
509
	v[10] = msk_x * op->mask.scale[0];
253
	v[11] =v[5];
510
	v[11] =v[5];
254
 
511
 
255
	v[12] = v[6];
512
	v[12] = v[6];
256
	v[13] = dst_y;
513
	v[13] = dst_y;
257
	v[14] = v[8];
514
	v[14] = v[8];
258
	v[15] = src_y * op->src.scale[1];
515
	v[15] = src_y * op->src.scale[1];
259
	v[16] = v[10];
516
	v[16] = v[10];
260
	v[17] = msk_y * op->mask.scale[1];
517
	v[17] = msk_y * op->mask.scale[1];
261
}
518
}
262
 
519
 
263
 
520
 
264
 
521
 
265
 
522
 
266
 
523
 
267
 
524
 
268
 
525
 
269
 
526
 
270
 
527
 
271
 
528
 
272
 
529
 
273
 
530
 
274
 
531
 
275
 
532
 
276
 
533
 
277
 
534
 
278
 
535
 
279
 
536
 
280
 
537
 
281
 
538
 
282
 
539
 
283
 
540
 
284
 
541
 
285
 
542
 
286
 
543
 
287
 
544
 
288
 
545
 
289
 
546
 
290
 
547
 
291
 
548
 
292
 
549
 
293
 
550
 
294
 
551
 
295
 
552
 
296
 
553
 
297
 
554
 
298
 
555
 
299
 
556
 
300
 
557
 
301
 
558
 
302
 
559
 
303
 
560
 
304
 
561
 
305
 
562
 
306
 
563
 
307
 
564
 
308
 
565
 
309
 
566
 
310
 
567
 
311
 
568
 
312
 
569
 
313
 
570
 
314
 
571
 
315
 
572
 
316
 
573
 
317
 
574
 
318
 
575
 
319
 
576
 
320
 
577
 
321
 
578
 
322
 
579
 
323
 
580
 
324
 
581
 
325
static inline void
582
static inline void
326
gen3_2d_perspective(struct sna *sna, int in, int out)
583
gen3_2d_perspective(struct sna *sna, int in, int out)
327
{
584
{
328
	gen3_fs_rcp(out, 0, gen3_fs_operand(in, W, W, W, W));
585
	gen3_fs_rcp(out, 0, gen3_fs_operand(in, W, W, W, W));
329
	gen3_fs_mul(out,
586
	gen3_fs_mul(out,
330
		    gen3_fs_operand(in, X, Y, ZERO, ONE),
587
		    gen3_fs_operand(in, X, Y, ZERO, ONE),
331
		    gen3_fs_operand_reg(out));
588
		    gen3_fs_operand_reg(out));
332
}
589
}
333
 
590
 
334
static inline void
591
static inline void
335
gen3_linear_coord(struct sna *sna,
592
gen3_linear_coord(struct sna *sna,
336
		  const struct sna_composite_channel *channel,
593
		  const struct sna_composite_channel *channel,
337
		  int in, int out)
594
		  int in, int out)
338
{
595
{
339
	int c = channel->u.gen3.constants;
596
	int c = channel->u.gen3.constants;
340
 
597
 
341
	if (!channel->is_affine) {
598
	if (!channel->is_affine) {
342
		gen3_2d_perspective(sna, in, FS_U0);
599
		gen3_2d_perspective(sna, in, FS_U0);
343
		in = FS_U0;
600
		in = FS_U0;
344
	}
601
	}
345
 
602
 
346
	gen3_fs_mov(out, gen3_fs_operand_zero());
603
	gen3_fs_mov(out, gen3_fs_operand_zero());
347
	gen3_fs_dp3(out, MASK_X,
604
	gen3_fs_dp3(out, MASK_X,
348
		    gen3_fs_operand(in, X, Y, ONE, ZERO),
605
		    gen3_fs_operand(in, X, Y, ONE, ZERO),
349
		    gen3_fs_operand_reg(c));
606
		    gen3_fs_operand_reg(c));
350
}
607
}
351
 
608
 
352
static void
609
static void
353
gen3_radial_coord(struct sna *sna,
610
gen3_radial_coord(struct sna *sna,
354
		  const struct sna_composite_channel *channel,
611
		  const struct sna_composite_channel *channel,
355
		  int in, int out)
612
		  int in, int out)
356
{
613
{
357
	int c = channel->u.gen3.constants;
614
	int c = channel->u.gen3.constants;
358
 
615
 
359
	if (!channel->is_affine) {
616
	if (!channel->is_affine) {
360
		gen3_2d_perspective(sna, in, FS_U0);
617
		gen3_2d_perspective(sna, in, FS_U0);
361
		in = FS_U0;
618
		in = FS_U0;
362
	}
619
	}
363
 
620
 
364
	switch (channel->u.gen3.mode) {
621
	switch (channel->u.gen3.mode) {
365
	case RADIAL_ONE:
622
	case RADIAL_ONE:
366
		/*
623
		/*
367
		   pdx = (x - c1x) / dr, pdy = (y - c1y) / dr;
624
		   pdx = (x - c1x) / dr, pdy = (y - c1y) / dr;
368
		   r? = pdx*pdx + pdy*pdy
625
		   r? = pdx*pdx + pdy*pdy
369
		   t = r?/sqrt(r?) - r1/dr;
626
		   t = r?/sqrt(r?) - r1/dr;
370
		   */
627
		   */
371
		gen3_fs_mad(FS_U0, MASK_X | MASK_Y,
628
		gen3_fs_mad(FS_U0, MASK_X | MASK_Y,
372
			    gen3_fs_operand(in, X, Y, ZERO, ZERO),
629
			    gen3_fs_operand(in, X, Y, ZERO, ZERO),
373
			    gen3_fs_operand(c, Z, Z, ZERO, ZERO),
630
			    gen3_fs_operand(c, Z, Z, ZERO, ZERO),
374
			    gen3_fs_operand(c, NEG_X, NEG_Y, ZERO, ZERO));
631
			    gen3_fs_operand(c, NEG_X, NEG_Y, ZERO, ZERO));
375
		gen3_fs_dp2add(FS_U0, MASK_X,
632
		gen3_fs_dp2add(FS_U0, MASK_X,
376
			       gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO),
633
			       gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO),
377
			       gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO),
634
			       gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO),
378
			       gen3_fs_operand_zero());
635
			       gen3_fs_operand_zero());
379
		gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U0, X, X, X, X));
636
		gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U0, X, X, X, X));
380
		gen3_fs_mad(out, 0,
637
		gen3_fs_mad(out, 0,
381
			    gen3_fs_operand(FS_U0, X, ZERO, ZERO, ZERO),
638
			    gen3_fs_operand(FS_U0, X, ZERO, ZERO, ZERO),
382
			    gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
639
			    gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
383
			    gen3_fs_operand(c, W, ZERO, ZERO, ZERO));
640
			    gen3_fs_operand(c, W, ZERO, ZERO, ZERO));
384
		break;
641
		break;
385
 
642
 
386
	case RADIAL_TWO:
643
	case RADIAL_TWO:
387
		/*
644
		/*
388
		   pdx = x - c1x, pdy = y - c1y;
645
		   pdx = x - c1x, pdy = y - c1y;
389
		   A = dx? + dy? - dr?
646
		   A = dx? + dy? - dr?
390
		   B = -2*(pdx*dx + pdy*dy + r1*dr);
647
		   B = -2*(pdx*dx + pdy*dy + r1*dr);
391
		   C = pdx? + pdy? - r1?;
648
		   C = pdx? + pdy? - r1?;
392
		   det = B*B - 4*A*C;
649
		   det = B*B - 4*A*C;
393
		   t = (-B + sqrt (det)) / (2 * A)
650
		   t = (-B + sqrt (det)) / (2 * A)
394
		   */
651
		   */
395
 
652
 
396
		/* u0.x = pdx, u0.y = pdy, u[0].z = r1; */
653
		/* u0.x = pdx, u0.y = pdy, u[0].z = r1; */
397
		gen3_fs_add(FS_U0,
654
		gen3_fs_add(FS_U0,
398
			    gen3_fs_operand(in, X, Y, ZERO, ZERO),
655
			    gen3_fs_operand(in, X, Y, ZERO, ZERO),
399
			    gen3_fs_operand(c, X, Y, Z, ZERO));
656
			    gen3_fs_operand(c, X, Y, Z, ZERO));
400
		/* u0.x = pdx, u0.y = pdy, u[0].z = r1, u[0].w = B; */
657
		/* u0.x = pdx, u0.y = pdy, u[0].z = r1, u[0].w = B; */
401
		gen3_fs_dp3(FS_U0, MASK_W,
658
		gen3_fs_dp3(FS_U0, MASK_W,
402
			    gen3_fs_operand(FS_U0, X, Y, ONE, ZERO),
659
			    gen3_fs_operand(FS_U0, X, Y, ONE, ZERO),
403
			    gen3_fs_operand(c+1, X, Y, Z, ZERO));
660
			    gen3_fs_operand(c+1, X, Y, Z, ZERO));
404
		/* u1.x = pdx? + pdy? - r1?; [C] */
661
		/* u1.x = pdx? + pdy? - r1?; [C] */
405
		gen3_fs_dp3(FS_U1, MASK_X,
662
		gen3_fs_dp3(FS_U1, MASK_X,
406
			    gen3_fs_operand(FS_U0, X, Y, Z, ZERO),
663
			    gen3_fs_operand(FS_U0, X, Y, Z, ZERO),
407
			    gen3_fs_operand(FS_U0, X, Y, NEG_Z, ZERO));
664
			    gen3_fs_operand(FS_U0, X, Y, NEG_Z, ZERO));
408
		/* u1.x = C, u1.y = B, u1.z=-4*A; */
665
		/* u1.x = C, u1.y = B, u1.z=-4*A; */
409
		gen3_fs_mov_masked(FS_U1, MASK_Y, gen3_fs_operand(FS_U0, W, W, W, W));
666
		gen3_fs_mov_masked(FS_U1, MASK_Y, gen3_fs_operand(FS_U0, W, W, W, W));
410
		gen3_fs_mov_masked(FS_U1, MASK_Z, gen3_fs_operand(c, W, W, W, W));
667
		gen3_fs_mov_masked(FS_U1, MASK_Z, gen3_fs_operand(c, W, W, W, W));
411
		/* u1.x = B? - 4*A*C */
668
		/* u1.x = B? - 4*A*C */
412
		gen3_fs_dp2add(FS_U1, MASK_X,
669
		gen3_fs_dp2add(FS_U1, MASK_X,
413
			       gen3_fs_operand(FS_U1, X, Y, ZERO, ZERO),
670
			       gen3_fs_operand(FS_U1, X, Y, ZERO, ZERO),
414
			       gen3_fs_operand(FS_U1, Z, Y, ZERO, ZERO),
671
			       gen3_fs_operand(FS_U1, Z, Y, ZERO, ZERO),
415
			       gen3_fs_operand_zero());
672
			       gen3_fs_operand_zero());
416
		/* out.x = -B + sqrt (B? - 4*A*C), */
673
		/* out.x = -B + sqrt (B? - 4*A*C), */
417
		gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U1, X, X, X, X));
674
		gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U1, X, X, X, X));
418
		gen3_fs_mad(out, MASK_X,
675
		gen3_fs_mad(out, MASK_X,
419
			    gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
676
			    gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
420
			    gen3_fs_operand(FS_U1, X, ZERO, ZERO, ZERO),
677
			    gen3_fs_operand(FS_U1, X, ZERO, ZERO, ZERO),
421
			    gen3_fs_operand(FS_U0, NEG_W, ZERO, ZERO, ZERO));
678
			    gen3_fs_operand(FS_U0, NEG_W, ZERO, ZERO, ZERO));
422
		/* out.x = (-B + sqrt (B? - 4*A*C)) / (2 * A), */
679
		/* out.x = (-B + sqrt (B? - 4*A*C)) / (2 * A), */
423
		gen3_fs_mul(out,
680
		gen3_fs_mul(out,
424
			    gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
681
			    gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
425
			    gen3_fs_operand(c+1, W, ZERO, ZERO, ZERO));
682
			    gen3_fs_operand(c+1, W, ZERO, ZERO, ZERO));
426
		break;
683
		break;
427
	}
684
	}
428
}
685
}
429
 
686
 
430
static void
687
static void
431
gen3_composite_emit_shader(struct sna *sna,
688
gen3_composite_emit_shader(struct sna *sna,
432
			   const struct sna_composite_op *op,
689
			   const struct sna_composite_op *op,
433
			   uint8_t blend)
690
			   uint8_t blend)
434
{
691
{
435
	bool dst_is_alpha = PIXMAN_FORMAT_RGB(op->dst.format) == 0;
692
	bool dst_is_alpha = PIXMAN_FORMAT_RGB(op->dst.format) == 0;
436
	const struct sna_composite_channel *src, *mask;
693
	const struct sna_composite_channel *src, *mask;
437
	struct gen3_render_state *state = &sna->render_state.gen3;
694
	struct gen3_render_state *state = &sna->render_state.gen3;
438
	uint32_t shader_offset, id;
695
	uint32_t shader_offset, id;
439
	int src_reg, mask_reg;
696
	int src_reg, mask_reg;
440
	int t, length;
697
	int t, length;
441
 
698
 
442
	src = &op->src;
699
	src = &op->src;
443
	mask = &op->mask;
700
	mask = &op->mask;
444
	if (mask->u.gen3.type == SHADER_NONE)
701
	if (mask->u.gen3.type == SHADER_NONE)
445
		mask = NULL;
702
		mask = NULL;
446
 
703
 
447
	id = (src->u.gen3.type |
704
	id = (src->u.gen3.type |
448
	      src->is_affine << 4 |
705
	      src->is_affine << 4 |
449
	      src->alpha_fixup << 5 |
706
	      src->alpha_fixup << 5 |
450
	      src->rb_reversed << 6);
707
	      src->rb_reversed << 6);
451
	if (mask) {
708
	if (mask) {
452
		id |= (mask->u.gen3.type << 8 |
709
		id |= (mask->u.gen3.type << 8 |
453
		       mask->is_affine << 12 |
710
		       mask->is_affine << 12 |
454
		       gen3_blend_op[blend].src_alpha << 13 |
711
		       gen3_blend_op[blend].src_alpha << 13 |
455
		       op->has_component_alpha << 14 |
712
		       op->has_component_alpha << 14 |
456
		       mask->alpha_fixup << 15 |
713
		       mask->alpha_fixup << 15 |
457
		       mask->rb_reversed << 16);
714
		       mask->rb_reversed << 16);
458
	}
715
	}
459
	id |= dst_is_alpha << 24;
716
	id |= dst_is_alpha << 24;
460
	id |= op->rb_reversed << 25;
717
	id |= op->rb_reversed << 25;
461
 
718
 
462
	if (id == state->last_shader)
719
	if (id == state->last_shader)
463
		return;
720
		return;
464
 
721
 
465
	state->last_shader = id;
722
	state->last_shader = id;
466
 
723
 
467
	shader_offset = sna->kgem.nbatch++;
724
	shader_offset = sna->kgem.nbatch++;
468
	t = 0;
725
	t = 0;
469
	switch (src->u.gen3.type) {
726
	switch (src->u.gen3.type) {
470
	case SHADER_NONE:
727
	case SHADER_NONE:
471
	case SHADER_OPACITY:
728
	case SHADER_OPACITY:
472
		assert(0);
729
		assert(0);
473
	case SHADER_ZERO:
730
	case SHADER_ZERO:
474
	case SHADER_BLACK:
731
	case SHADER_BLACK:
475
	case SHADER_WHITE:
732
	case SHADER_WHITE:
476
		break;
733
		break;
477
	case SHADER_CONSTANT:
734
	case SHADER_CONSTANT:
478
		gen3_fs_dcl(FS_T8);
735
		gen3_fs_dcl(FS_T8);
479
		src_reg = FS_T8;
736
		src_reg = FS_T8;
480
		break;
737
		break;
481
	case SHADER_TEXTURE:
738
	case SHADER_TEXTURE:
482
	case SHADER_RADIAL:
739
	case SHADER_RADIAL:
483
	case SHADER_LINEAR:
740
	case SHADER_LINEAR:
484
		gen3_fs_dcl(FS_S0);
741
		gen3_fs_dcl(FS_S0);
485
		gen3_fs_dcl(FS_T0);
742
		gen3_fs_dcl(FS_T0);
486
		t++;
743
		t++;
487
		break;
744
		break;
488
	}
745
	}
489
 
746
 
490
	if (mask == NULL) {
747
	if (mask == NULL) {
491
		switch (src->u.gen3.type) {
748
		switch (src->u.gen3.type) {
492
		case SHADER_ZERO:
749
		case SHADER_ZERO:
493
			gen3_fs_mov(FS_OC, gen3_fs_operand_zero());
750
			gen3_fs_mov(FS_OC, gen3_fs_operand_zero());
494
			goto done;
751
			goto done;
495
		case SHADER_BLACK:
752
		case SHADER_BLACK:
496
			if (dst_is_alpha)
753
			if (dst_is_alpha)
497
				gen3_fs_mov(FS_OC, gen3_fs_operand_one());
754
				gen3_fs_mov(FS_OC, gen3_fs_operand_one());
498
			else
755
			else
499
				gen3_fs_mov(FS_OC, gen3_fs_operand(FS_R0, ZERO, ZERO, ZERO, ONE));
756
				gen3_fs_mov(FS_OC, gen3_fs_operand(FS_R0, ZERO, ZERO, ZERO, ONE));
500
			goto done;
757
			goto done;
501
		case SHADER_WHITE:
758
		case SHADER_WHITE:
502
			gen3_fs_mov(FS_OC, gen3_fs_operand_one());
759
			gen3_fs_mov(FS_OC, gen3_fs_operand_one());
503
			goto done;
760
			goto done;
504
		}
761
		}
505
		if (src->alpha_fixup && dst_is_alpha) {
762
		if (src->alpha_fixup && dst_is_alpha) {
506
			gen3_fs_mov(FS_OC, gen3_fs_operand_one());
763
			gen3_fs_mov(FS_OC, gen3_fs_operand_one());
507
			goto done;
764
			goto done;
508
		}
765
		}
509
		/* No mask, so load directly to output color */
766
		/* No mask, so load directly to output color */
510
		if (src->u.gen3.type != SHADER_CONSTANT) {
767
		if (src->u.gen3.type != SHADER_CONSTANT) {
511
			if (dst_is_alpha || src->rb_reversed ^ op->rb_reversed)
768
			if (dst_is_alpha || src->rb_reversed ^ op->rb_reversed)
512
				src_reg = FS_R0;
769
				src_reg = FS_R0;
513
			else
770
			else
514
				src_reg = FS_OC;
771
				src_reg = FS_OC;
515
		}
772
		}
516
		switch (src->u.gen3.type) {
773
		switch (src->u.gen3.type) {
517
		case SHADER_LINEAR:
774
		case SHADER_LINEAR:
518
			gen3_linear_coord(sna, src, FS_T0, FS_R0);
775
			gen3_linear_coord(sna, src, FS_T0, FS_R0);
519
			gen3_fs_texld(src_reg, FS_S0, FS_R0);
776
			gen3_fs_texld(src_reg, FS_S0, FS_R0);
520
			break;
777
			break;
521
 
778
 
522
		case SHADER_RADIAL:
779
		case SHADER_RADIAL:
523
			gen3_radial_coord(sna, src, FS_T0, FS_R0);
780
			gen3_radial_coord(sna, src, FS_T0, FS_R0);
524
			gen3_fs_texld(src_reg, FS_S0, FS_R0);
781
			gen3_fs_texld(src_reg, FS_S0, FS_R0);
525
			break;
782
			break;
526
 
783
 
527
		case SHADER_TEXTURE:
784
		case SHADER_TEXTURE:
528
			if (src->is_affine)
785
			if (src->is_affine)
529
				gen3_fs_texld(src_reg, FS_S0, FS_T0);
786
				gen3_fs_texld(src_reg, FS_S0, FS_T0);
530
			else
787
			else
531
				gen3_fs_texldp(src_reg, FS_S0, FS_T0);
788
				gen3_fs_texldp(src_reg, FS_S0, FS_T0);
532
			break;
789
			break;
533
 
790
 
534
		case SHADER_NONE:
791
		case SHADER_NONE:
535
		case SHADER_WHITE:
792
		case SHADER_WHITE:
536
		case SHADER_BLACK:
793
		case SHADER_BLACK:
537
		case SHADER_ZERO:
794
		case SHADER_ZERO:
538
			assert(0);
795
			assert(0);
539
		case SHADER_CONSTANT:
796
		case SHADER_CONSTANT:
540
			break;
797
			break;
541
		}
798
		}
542
 
799
 
543
		if (src_reg != FS_OC) {
800
		if (src_reg != FS_OC) {
544
			if (src->alpha_fixup)
801
			if (src->alpha_fixup)
545
				gen3_fs_mov(FS_OC,
802
				gen3_fs_mov(FS_OC,
546
					    src->rb_reversed ^ op->rb_reversed ?
803
					    src->rb_reversed ^ op->rb_reversed ?
547
					    gen3_fs_operand(src_reg, Z, Y, X, ONE) :
804
					    gen3_fs_operand(src_reg, Z, Y, X, ONE) :
548
					    gen3_fs_operand(src_reg, X, Y, Z, ONE));
805
					    gen3_fs_operand(src_reg, X, Y, Z, ONE));
549
			else if (dst_is_alpha)
806
			else if (dst_is_alpha)
550
				gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, W, W, W, W));
807
				gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, W, W, W, W));
551
			else if (src->rb_reversed ^ op->rb_reversed)
808
			else if (src->rb_reversed ^ op->rb_reversed)
552
				gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, Z, Y, X, W));
809
				gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, Z, Y, X, W));
553
			else
810
			else
554
				gen3_fs_mov(FS_OC, gen3_fs_operand_reg(src_reg));
811
				gen3_fs_mov(FS_OC, gen3_fs_operand_reg(src_reg));
555
		} else if (src->alpha_fixup)
812
		} else if (src->alpha_fixup)
556
			gen3_fs_mov_masked(FS_OC, MASK_W, gen3_fs_operand_one());
813
			gen3_fs_mov_masked(FS_OC, MASK_W, gen3_fs_operand_one());
557
	} else {
814
	} else {
558
		int out_reg = FS_OC;
815
		int out_reg = FS_OC;
559
		if (op->rb_reversed)
816
		if (op->rb_reversed)
560
			out_reg = FS_U0;
817
			out_reg = FS_U0;
561
 
818
 
562
		switch (mask->u.gen3.type) {
819
		switch (mask->u.gen3.type) {
563
		case SHADER_CONSTANT:
820
		case SHADER_CONSTANT:
564
			gen3_fs_dcl(FS_T9);
821
			gen3_fs_dcl(FS_T9);
565
			mask_reg = FS_T9;
822
			mask_reg = FS_T9;
566
			break;
823
			break;
567
		case SHADER_TEXTURE:
824
		case SHADER_TEXTURE:
568
		case SHADER_LINEAR:
825
		case SHADER_LINEAR:
569
		case SHADER_RADIAL:
826
		case SHADER_RADIAL:
570
			gen3_fs_dcl(FS_S0 + t);
827
			gen3_fs_dcl(FS_S0 + t);
571
			/* fall through */
828
			/* fall through */
572
		case SHADER_OPACITY:
829
		case SHADER_OPACITY:
573
			gen3_fs_dcl(FS_T0 + t);
830
			gen3_fs_dcl(FS_T0 + t);
574
			break;
831
			break;
575
		case SHADER_ZERO:
832
		case SHADER_ZERO:
576
		case SHADER_BLACK:
833
		case SHADER_BLACK:
577
			assert(0);
834
			assert(0);
578
		case SHADER_NONE:
835
		case SHADER_NONE:
579
		case SHADER_WHITE:
836
		case SHADER_WHITE:
580
			break;
837
			break;
581
		}
838
		}
582
 
839
 
583
		t = 0;
840
		t = 0;
584
		switch (src->u.gen3.type) {
841
		switch (src->u.gen3.type) {
585
		case SHADER_LINEAR:
842
		case SHADER_LINEAR:
586
			gen3_linear_coord(sna, src, FS_T0, FS_R0);
843
			gen3_linear_coord(sna, src, FS_T0, FS_R0);
587
			gen3_fs_texld(FS_R0, FS_S0, FS_R0);
844
			gen3_fs_texld(FS_R0, FS_S0, FS_R0);
588
			src_reg = FS_R0;
845
			src_reg = FS_R0;
589
			t++;
846
			t++;
590
			break;
847
			break;
591
 
848
 
592
		case SHADER_RADIAL:
849
		case SHADER_RADIAL:
593
			gen3_radial_coord(sna, src, FS_T0, FS_R0);
850
			gen3_radial_coord(sna, src, FS_T0, FS_R0);
594
			gen3_fs_texld(FS_R0, FS_S0, FS_R0);
851
			gen3_fs_texld(FS_R0, FS_S0, FS_R0);
595
			src_reg = FS_R0;
852
			src_reg = FS_R0;
596
			t++;
853
			t++;
597
			break;
854
			break;
598
 
855
 
599
		case SHADER_TEXTURE:
856
		case SHADER_TEXTURE:
600
			if (src->is_affine)
857
			if (src->is_affine)
601
				gen3_fs_texld(FS_R0, FS_S0, FS_T0);
858
				gen3_fs_texld(FS_R0, FS_S0, FS_T0);
602
			else
859
			else
603
				gen3_fs_texldp(FS_R0, FS_S0, FS_T0);
860
				gen3_fs_texldp(FS_R0, FS_S0, FS_T0);
604
			src_reg = FS_R0;
861
			src_reg = FS_R0;
605
			t++;
862
			t++;
606
			break;
863
			break;
607
 
864
 
608
		case SHADER_CONSTANT:
865
		case SHADER_CONSTANT:
609
		case SHADER_NONE:
866
		case SHADER_NONE:
610
		case SHADER_ZERO:
867
		case SHADER_ZERO:
611
		case SHADER_BLACK:
868
		case SHADER_BLACK:
612
		case SHADER_WHITE:
869
		case SHADER_WHITE:
613
			break;
870
			break;
614
		}
871
		}
615
		if (src->alpha_fixup)
872
		if (src->alpha_fixup)
616
			gen3_fs_mov_masked(src_reg, MASK_W, gen3_fs_operand_one());
873
			gen3_fs_mov_masked(src_reg, MASK_W, gen3_fs_operand_one());
617
		if (src->rb_reversed)
874
		if (src->rb_reversed)
618
			gen3_fs_mov(src_reg, gen3_fs_operand(src_reg, Z, Y, X, W));
875
			gen3_fs_mov(src_reg, gen3_fs_operand(src_reg, Z, Y, X, W));
619
 
876
 
620
		switch (mask->u.gen3.type) {
877
		switch (mask->u.gen3.type) {
621
		case SHADER_LINEAR:
878
		case SHADER_LINEAR:
622
			gen3_linear_coord(sna, mask, FS_T0 + t, FS_R1);
879
			gen3_linear_coord(sna, mask, FS_T0 + t, FS_R1);
623
			gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1);
880
			gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1);
624
			mask_reg = FS_R1;
881
			mask_reg = FS_R1;
625
			break;
882
			break;
626
 
883
 
627
		case SHADER_RADIAL:
884
		case SHADER_RADIAL:
628
			gen3_radial_coord(sna, mask, FS_T0 + t, FS_R1);
885
			gen3_radial_coord(sna, mask, FS_T0 + t, FS_R1);
629
			gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1);
886
			gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1);
630
			mask_reg = FS_R1;
887
			mask_reg = FS_R1;
631
			break;
888
			break;
632
 
889
 
633
		case SHADER_TEXTURE:
890
		case SHADER_TEXTURE:
634
			if (mask->is_affine)
891
			if (mask->is_affine)
635
				gen3_fs_texld(FS_R1, FS_S0 + t, FS_T0 + t);
892
				gen3_fs_texld(FS_R1, FS_S0 + t, FS_T0 + t);
636
			else
893
			else
637
				gen3_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t);
894
				gen3_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t);
638
			mask_reg = FS_R1;
895
			mask_reg = FS_R1;
639
			break;
896
			break;
640
 
897
 
641
		case SHADER_OPACITY:
898
		case SHADER_OPACITY:
642
			switch (src->u.gen3.type) {
899
			switch (src->u.gen3.type) {
643
			case SHADER_BLACK:
900
			case SHADER_BLACK:
644
			case SHADER_WHITE:
901
			case SHADER_WHITE:
645
				if (dst_is_alpha || src->u.gen3.type == SHADER_WHITE) {
902
				if (dst_is_alpha || src->u.gen3.type == SHADER_WHITE) {
646
					gen3_fs_mov(out_reg,
903
					gen3_fs_mov(out_reg,
647
						    gen3_fs_operand(FS_T0 + t, X, X, X, X));
904
						    gen3_fs_operand(FS_T0 + t, X, X, X, X));
648
				} else {
905
				} else {
649
					gen3_fs_mov(out_reg,
906
					gen3_fs_mov(out_reg,
650
						    gen3_fs_operand(FS_T0 + t, ZERO, ZERO, ZERO, X));
907
						    gen3_fs_operand(FS_T0 + t, ZERO, ZERO, ZERO, X));
651
				}
908
				}
652
				break;
909
				break;
653
			default:
910
			default:
654
				if (dst_is_alpha) {
911
				if (dst_is_alpha) {
655
					gen3_fs_mul(out_reg,
912
					gen3_fs_mul(out_reg,
656
						    gen3_fs_operand(src_reg, W, W, W, W),
913
						    gen3_fs_operand(src_reg, W, W, W, W),
657
						    gen3_fs_operand(FS_T0 + t, X, X, X, X));
914
						    gen3_fs_operand(FS_T0 + t, X, X, X, X));
658
				} else {
915
				} else {
659
					gen3_fs_mul(out_reg,
916
					gen3_fs_mul(out_reg,
660
						    gen3_fs_operand(src_reg, X, Y, Z, W),
917
						    gen3_fs_operand(src_reg, X, Y, Z, W),
661
						    gen3_fs_operand(FS_T0 + t, X, X, X, X));
918
						    gen3_fs_operand(FS_T0 + t, X, X, X, X));
662
				}
919
				}
663
			}
920
			}
664
			goto mask_done;
921
			goto mask_done;
665
 
922
 
666
		case SHADER_CONSTANT:
923
		case SHADER_CONSTANT:
667
		case SHADER_ZERO:
924
		case SHADER_ZERO:
668
		case SHADER_BLACK:
925
		case SHADER_BLACK:
669
		case SHADER_WHITE:
926
		case SHADER_WHITE:
670
		case SHADER_NONE:
927
		case SHADER_NONE:
671
			break;
928
			break;
672
		}
929
		}
673
		if (mask->alpha_fixup)
930
		if (mask->alpha_fixup)
674
			gen3_fs_mov_masked(mask_reg, MASK_W, gen3_fs_operand_one());
931
			gen3_fs_mov_masked(mask_reg, MASK_W, gen3_fs_operand_one());
675
		if (mask->rb_reversed)
932
		if (mask->rb_reversed)
676
			gen3_fs_mov(mask_reg, gen3_fs_operand(mask_reg, Z, Y, X, W));
933
			gen3_fs_mov(mask_reg, gen3_fs_operand(mask_reg, Z, Y, X, W));
677
 
934
 
678
		if (dst_is_alpha) {
935
		if (dst_is_alpha) {
679
			switch (src->u.gen3.type) {
936
			switch (src->u.gen3.type) {
680
			case SHADER_BLACK:
937
			case SHADER_BLACK:
681
			case SHADER_WHITE:
938
			case SHADER_WHITE:
682
				gen3_fs_mov(out_reg,
939
				gen3_fs_mov(out_reg,
683
					    gen3_fs_operand(mask_reg, W, W, W, W));
940
					    gen3_fs_operand(mask_reg, W, W, W, W));
684
				break;
941
				break;
685
			default:
942
			default:
686
				gen3_fs_mul(out_reg,
943
				gen3_fs_mul(out_reg,
687
					    gen3_fs_operand(src_reg, W, W, W, W),
944
					    gen3_fs_operand(src_reg, W, W, W, W),
688
					    gen3_fs_operand(mask_reg, W, W, W, W));
945
					    gen3_fs_operand(mask_reg, W, W, W, W));
689
				break;
946
				break;
690
			}
947
			}
691
		} else {
948
		} else {
692
			/* If component alpha is active in the mask and the blend
949
			/* If component alpha is active in the mask and the blend
693
			 * operation uses the source alpha, then we know we don't
950
			 * operation uses the source alpha, then we know we don't
694
			 * need the source value (otherwise we would have hit a
951
			 * need the source value (otherwise we would have hit a
695
			 * fallback earlier), so we provide the source alpha (src.A *
952
			 * fallback earlier), so we provide the source alpha (src.A *
696
			 * mask.X) as output color.
953
			 * mask.X) as output color.
697
			 * Conversely, if CA is set and we don't need the source alpha,
954
			 * Conversely, if CA is set and we don't need the source alpha,
698
			 * then we produce the source value (src.X * mask.X) and the
955
			 * then we produce the source value (src.X * mask.X) and the
699
			 * source alpha is unused.  Otherwise, we provide the non-CA
956
			 * source alpha is unused.  Otherwise, we provide the non-CA
700
			 * source value (src.X * mask.A).
957
			 * source value (src.X * mask.A).
701
			 */
958
			 */
702
			if (op->has_component_alpha) {
959
			if (op->has_component_alpha) {
703
				switch (src->u.gen3.type) {
960
				switch (src->u.gen3.type) {
704
				case SHADER_BLACK:
961
				case SHADER_BLACK:
705
					if (gen3_blend_op[blend].src_alpha)
962
					if (gen3_blend_op[blend].src_alpha)
706
						gen3_fs_mov(out_reg,
963
						gen3_fs_mov(out_reg,
707
							    gen3_fs_operand_reg(mask_reg));
964
							    gen3_fs_operand_reg(mask_reg));
708
					else
965
					else
709
						gen3_fs_mov(out_reg,
966
						gen3_fs_mov(out_reg,
710
							    gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
967
							    gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
711
					break;
968
					break;
712
				case SHADER_WHITE:
969
				case SHADER_WHITE:
713
					gen3_fs_mov(out_reg,
970
					gen3_fs_mov(out_reg,
714
						    gen3_fs_operand_reg(mask_reg));
971
						    gen3_fs_operand_reg(mask_reg));
715
					break;
972
					break;
716
				default:
973
				default:
717
					if (gen3_blend_op[blend].src_alpha)
974
					if (gen3_blend_op[blend].src_alpha)
718
						gen3_fs_mul(out_reg,
975
						gen3_fs_mul(out_reg,
719
							    gen3_fs_operand(src_reg, W, W, W, W),
976
							    gen3_fs_operand(src_reg, W, W, W, W),
720
							    gen3_fs_operand_reg(mask_reg));
977
							    gen3_fs_operand_reg(mask_reg));
721
					else
978
					else
722
						gen3_fs_mul(out_reg,
979
						gen3_fs_mul(out_reg,
723
							    gen3_fs_operand_reg(src_reg),
980
							    gen3_fs_operand_reg(src_reg),
724
							    gen3_fs_operand_reg(mask_reg));
981
							    gen3_fs_operand_reg(mask_reg));
725
					break;
982
					break;
726
				}
983
				}
727
			} else {
984
			} else {
728
				switch (src->u.gen3.type) {
985
				switch (src->u.gen3.type) {
729
				case SHADER_WHITE:
986
				case SHADER_WHITE:
730
					gen3_fs_mov(out_reg,
987
					gen3_fs_mov(out_reg,
731
						    gen3_fs_operand(mask_reg, W, W, W, W));
988
						    gen3_fs_operand(mask_reg, W, W, W, W));
732
					break;
989
					break;
733
				case SHADER_BLACK:
990
				case SHADER_BLACK:
734
					gen3_fs_mov(out_reg,
991
					gen3_fs_mov(out_reg,
735
						    gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
992
						    gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
736
					break;
993
					break;
737
				default:
994
				default:
738
					gen3_fs_mul(out_reg,
995
					gen3_fs_mul(out_reg,
739
						    gen3_fs_operand_reg(src_reg),
996
						    gen3_fs_operand_reg(src_reg),
740
						    gen3_fs_operand(mask_reg, W, W, W, W));
997
						    gen3_fs_operand(mask_reg, W, W, W, W));
741
					break;
998
					break;
742
				}
999
				}
743
			}
1000
			}
744
		}
1001
		}
745
mask_done:
1002
mask_done:
746
		if (op->rb_reversed)
1003
		if (op->rb_reversed)
747
			gen3_fs_mov(FS_OC, gen3_fs_operand(FS_U0, Z, Y, X, W));
1004
			gen3_fs_mov(FS_OC, gen3_fs_operand(FS_U0, Z, Y, X, W));
748
	}
1005
	}
749
 
1006
 
750
done:
1007
done:
751
	length = sna->kgem.nbatch - shader_offset;
1008
	length = sna->kgem.nbatch - shader_offset;
752
	sna->kgem.batch[shader_offset] =
1009
	sna->kgem.batch[shader_offset] =
753
		_3DSTATE_PIXEL_SHADER_PROGRAM | (length - 2);
1010
		_3DSTATE_PIXEL_SHADER_PROGRAM | (length - 2);
754
}
1011
}
755
 
1012
 
756
static uint32_t gen3_ms_tiling(uint32_t tiling)
1013
static uint32_t gen3_ms_tiling(uint32_t tiling)
757
{
1014
{
758
	uint32_t v = 0;
1015
	uint32_t v = 0;
759
	switch (tiling) {
1016
	switch (tiling) {
760
	case I915_TILING_Y: v |= MS3_TILE_WALK;
1017
	case I915_TILING_Y: v |= MS3_TILE_WALK;
761
	case I915_TILING_X: v |= MS3_TILED_SURFACE;
1018
	case I915_TILING_X: v |= MS3_TILED_SURFACE;
762
	case I915_TILING_NONE: break;
1019
	case I915_TILING_NONE: break;
763
	}
1020
	}
764
	return v;
1021
	return v;
765
}
1022
}
766
 
1023
 
767
static void gen3_emit_invariant(struct sna *sna)
1024
static void gen3_emit_invariant(struct sna *sna)
768
{
1025
{
769
	/* Disable independent alpha blend */
1026
	/* Disable independent alpha blend */
770
	OUT_BATCH(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE |
1027
	OUT_BATCH(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE |
771
		  IAB_MODIFY_FUNC | BLENDFUNC_ADD << IAB_FUNC_SHIFT |
1028
		  IAB_MODIFY_FUNC | BLENDFUNC_ADD << IAB_FUNC_SHIFT |
772
		  IAB_MODIFY_SRC_FACTOR | BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT |
1029
		  IAB_MODIFY_SRC_FACTOR | BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT |
773
		  IAB_MODIFY_DST_FACTOR | BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT);
1030
		  IAB_MODIFY_DST_FACTOR | BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT);
774
 
1031
 
775
	OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
1032
	OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
776
		  CSB_TCB(0, 0) |
1033
		  CSB_TCB(0, 0) |
777
		  CSB_TCB(1, 1) |
1034
		  CSB_TCB(1, 1) |
778
		  CSB_TCB(2, 2) |
1035
		  CSB_TCB(2, 2) |
779
		  CSB_TCB(3, 3) |
1036
		  CSB_TCB(3, 3) |
780
		  CSB_TCB(4, 4) |
1037
		  CSB_TCB(4, 4) |
781
		  CSB_TCB(5, 5) |
1038
		  CSB_TCB(5, 5) |
782
		  CSB_TCB(6, 6) |
1039
		  CSB_TCB(6, 6) |
783
		  CSB_TCB(7, 7));
1040
		  CSB_TCB(7, 7));
784
 
1041
 
785
	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
1042
	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
786
	OUT_BATCH(0); /* Disable texture coordinate wrap-shortest */
1043
	OUT_BATCH(0); /* Disable texture coordinate wrap-shortest */
787
	OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) |
1044
	OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) |
788
		  S4_LINE_WIDTH_ONE |
1045
		  S4_LINE_WIDTH_ONE |
789
		  S4_CULLMODE_NONE |
1046
		  S4_CULLMODE_NONE |
790
		  S4_VFMT_XY);
1047
		  S4_VFMT_XY);
791
	OUT_BATCH(0); /* Disable fog/stencil. *Enable* write mask. */
1048
	OUT_BATCH(0); /* Disable fog/stencil. *Enable* write mask. */
792
	OUT_BATCH(S6_COLOR_WRITE_ONLY); /* Disable blending, depth */
1049
	OUT_BATCH(S6_COLOR_WRITE_ONLY); /* Disable blending, depth */
793
 
1050
 
794
	OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
1051
	OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
795
	OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
1052
	OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
796
 
1053
 
797
	OUT_BATCH(_3DSTATE_LOAD_INDIRECT);
1054
	OUT_BATCH(_3DSTATE_LOAD_INDIRECT);
798
	OUT_BATCH(0x00000000);
1055
	OUT_BATCH(0x00000000);
799
 
1056
 
800
	OUT_BATCH(_3DSTATE_STIPPLE);
1057
	OUT_BATCH(_3DSTATE_STIPPLE);
801
	OUT_BATCH(0x00000000);
1058
	OUT_BATCH(0x00000000);
802
 
1059
 
803
	sna->render_state.gen3.need_invariant = false;
1060
	sna->render_state.gen3.need_invariant = false;
804
}
1061
}
805
 
1062
 
806
#define MAX_OBJECTS 3 /* worst case: dst + src + mask  */
1063
#define MAX_OBJECTS 3 /* worst case: dst + src + mask  */
807
 
1064
 
808
static void
1065
static void
809
gen3_get_batch(struct sna *sna, const struct sna_composite_op *op)
1066
gen3_get_batch(struct sna *sna, const struct sna_composite_op *op)
810
{
1067
{
811
	kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
1068
	kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
812
 
1069
 
813
	if (!kgem_check_batch(&sna->kgem, 200)) {
1070
	if (!kgem_check_batch(&sna->kgem, 200)) {
814
		DBG(("%s: flushing batch: size %d > %d\n",
1071
		DBG(("%s: flushing batch: size %d > %d\n",
815
		     __FUNCTION__, 200,
1072
		     __FUNCTION__, 200,
816
		     sna->kgem.surface-sna->kgem.nbatch));
1073
		     sna->kgem.surface-sna->kgem.nbatch));
817
		kgem_submit(&sna->kgem);
1074
		kgem_submit(&sna->kgem);
818
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1075
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
819
	}
1076
	}
820
 
1077
 
821
	if (!kgem_check_reloc(&sna->kgem, MAX_OBJECTS)) {
1078
	if (!kgem_check_reloc(&sna->kgem, MAX_OBJECTS)) {
822
		DBG(("%s: flushing batch: reloc %d >= %d\n",
1079
		DBG(("%s: flushing batch: reloc %d >= %d\n",
823
		     __FUNCTION__,
1080
		     __FUNCTION__,
824
		     sna->kgem.nreloc,
1081
		     sna->kgem.nreloc,
825
		     (int)KGEM_RELOC_SIZE(&sna->kgem) - MAX_OBJECTS));
1082
		     (int)KGEM_RELOC_SIZE(&sna->kgem) - MAX_OBJECTS));
826
		kgem_submit(&sna->kgem);
1083
		kgem_submit(&sna->kgem);
827
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1084
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
828
	}
1085
	}
829
 
1086
 
830
	if (!kgem_check_exec(&sna->kgem, MAX_OBJECTS)) {
1087
	if (!kgem_check_exec(&sna->kgem, MAX_OBJECTS)) {
831
		DBG(("%s: flushing batch: exec %d >= %d\n",
1088
		DBG(("%s: flushing batch: exec %d >= %d\n",
832
		     __FUNCTION__,
1089
		     __FUNCTION__,
833
		     sna->kgem.nexec,
1090
		     sna->kgem.nexec,
834
		     (int)KGEM_EXEC_SIZE(&sna->kgem) - MAX_OBJECTS - 1));
1091
		     (int)KGEM_EXEC_SIZE(&sna->kgem) - MAX_OBJECTS - 1));
835
		kgem_submit(&sna->kgem);
1092
		kgem_submit(&sna->kgem);
836
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1093
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
837
	}
1094
	}
838
 
1095
 
839
	if (sna->render_state.gen3.need_invariant)
1096
	if (sna->render_state.gen3.need_invariant)
840
		gen3_emit_invariant(sna);
1097
		gen3_emit_invariant(sna);
841
#undef MAX_OBJECTS
1098
#undef MAX_OBJECTS
842
}
1099
}
843
 
1100
 
844
static void gen3_emit_target(struct sna *sna,
1101
static void gen3_emit_target(struct sna *sna,
845
			     struct kgem_bo *bo,
1102
			     struct kgem_bo *bo,
846
			     int width,
1103
			     int width,
847
			     int height,
1104
			     int height,
848
			     int format)
1105
			     int format)
849
{
1106
{
850
	struct gen3_render_state *state = &sna->render_state.gen3;
1107
	struct gen3_render_state *state = &sna->render_state.gen3;
851
 
1108
 
852
	assert(!too_large(width, height));
1109
	assert(!too_large(width, height));
853
 
1110
 
854
	/* BUF_INFO is an implicit flush, so skip if the target is unchanged. */
1111
	/* BUF_INFO is an implicit flush, so skip if the target is unchanged. */
855
	assert(bo->unique_id != 0);
1112
	assert(bo->unique_id != 0);
856
	if (bo->unique_id != state->current_dst) {
1113
	if (bo->unique_id != state->current_dst) {
857
		uint32_t v;
1114
		uint32_t v;
858
 
1115
 
859
		DBG(("%s: setting new target id=%d, handle=%d\n",
1116
		DBG(("%s: setting new target id=%d, handle=%d\n",
860
		     __FUNCTION__, bo->unique_id, bo->handle));
1117
		     __FUNCTION__, bo->unique_id, bo->handle));
861
 
1118
 
862
		OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
1119
		OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
863
		OUT_BATCH(BUF_3D_ID_COLOR_BACK |
1120
		OUT_BATCH(BUF_3D_ID_COLOR_BACK |
864
			  gen3_buf_tiling(bo->tiling) |
1121
			  gen3_buf_tiling(bo->tiling) |
865
			  bo->pitch);
1122
			  bo->pitch);
866
		OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
1123
		OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
867
					 bo,
1124
					 bo,
868
					 I915_GEM_DOMAIN_RENDER << 16 |
1125
					 I915_GEM_DOMAIN_RENDER << 16 |
869
					 I915_GEM_DOMAIN_RENDER,
1126
					 I915_GEM_DOMAIN_RENDER,
870
					 0));
1127
					 0));
871
 
1128
 
872
		OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
1129
		OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
873
		OUT_BATCH(gen3_get_dst_format(format));
1130
		OUT_BATCH(gen3_get_dst_format(format));
874
 
1131
 
875
		v = DRAW_YMAX(height - 1) | DRAW_XMAX(width - 1);
1132
		v = DRAW_YMAX(height - 1) | DRAW_XMAX(width - 1);
876
		if (v != state->last_drawrect_limit) {
1133
		if (v != state->last_drawrect_limit) {
877
			OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
1134
			OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
878
			OUT_BATCH(0); /* XXX dither origin? */
1135
			OUT_BATCH(0); /* XXX dither origin? */
879
			OUT_BATCH(0);
1136
			OUT_BATCH(0);
880
			OUT_BATCH(v);
1137
			OUT_BATCH(v);
881
			OUT_BATCH(0);
1138
			OUT_BATCH(0);
882
			state->last_drawrect_limit = v;
1139
			state->last_drawrect_limit = v;
883
		}
1140
		}
884
 
1141
 
885
		state->current_dst = bo->unique_id;
1142
		state->current_dst = bo->unique_id;
886
	}
1143
	}
-
 
1144
	assert(bo->exec);
887
	kgem_bo_mark_dirty(bo);
1145
	kgem_bo_mark_dirty(bo);
888
}
1146
}
889
 
1147
 
890
static void gen3_emit_composite_state(struct sna *sna,
1148
static void gen3_emit_composite_state(struct sna *sna,
891
				      const struct sna_composite_op *op)
1149
				      const struct sna_composite_op *op)
892
{
1150
{
893
	struct gen3_render_state *state = &sna->render_state.gen3;
1151
	struct gen3_render_state *state = &sna->render_state.gen3;
894
	uint32_t map[4];
1152
	uint32_t map[4];
895
	uint32_t sampler[4];
1153
	uint32_t sampler[4];
896
	struct kgem_bo *bo[2];
1154
	struct kgem_bo *bo[2];
897
	unsigned int tex_count, n;
1155
	unsigned int tex_count, n;
898
	uint32_t ss2;
1156
	uint32_t ss2;
899
 
1157
 
900
	gen3_get_batch(sna, op);
1158
	gen3_get_batch(sna, op);
901
 
1159
 
902
	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
1160
	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
903
		if (op->src.bo == op->dst.bo || op->mask.bo == op->dst.bo)
1161
		if (op->src.bo == op->dst.bo || op->mask.bo == op->dst.bo)
904
			OUT_BATCH(MI_FLUSH | MI_INVALIDATE_MAP_CACHE);
1162
			OUT_BATCH(MI_FLUSH | MI_INVALIDATE_MAP_CACHE);
905
		else
1163
		else
906
			OUT_BATCH(_3DSTATE_MODES_5_CMD |
1164
			OUT_BATCH(_3DSTATE_MODES_5_CMD |
907
				  PIPELINE_FLUSH_RENDER_CACHE |
1165
				  PIPELINE_FLUSH_RENDER_CACHE |
908
				  PIPELINE_FLUSH_TEXTURE_CACHE);
1166
				  PIPELINE_FLUSH_TEXTURE_CACHE);
909
		kgem_clear_dirty(&sna->kgem);
1167
		kgem_clear_dirty(&sna->kgem);
910
	}
1168
	}
911
 
1169
 
912
	gen3_emit_target(sna,
1170
	gen3_emit_target(sna,
913
			 op->dst.bo,
1171
			 op->dst.bo,
914
			 op->dst.width,
1172
			 op->dst.width,
915
			 op->dst.height,
1173
			 op->dst.height,
916
			 op->dst.format);
1174
			 op->dst.format);
917
 
1175
 
918
	ss2 = ~0;
1176
	ss2 = ~0;
919
	tex_count = 0;
1177
	tex_count = 0;
920
	switch (op->src.u.gen3.type) {
1178
	switch (op->src.u.gen3.type) {
921
	case SHADER_OPACITY:
1179
	case SHADER_OPACITY:
922
	case SHADER_NONE:
1180
	case SHADER_NONE:
923
		assert(0);
1181
		assert(0);
924
	case SHADER_ZERO:
1182
	case SHADER_ZERO:
925
	case SHADER_BLACK:
1183
	case SHADER_BLACK:
926
	case SHADER_WHITE:
1184
	case SHADER_WHITE:
927
		break;
1185
		break;
928
	case SHADER_CONSTANT:
1186
	case SHADER_CONSTANT:
929
		if (op->src.u.gen3.mode != state->last_diffuse) {
1187
		if (op->src.u.gen3.mode != state->last_diffuse) {
930
			OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
1188
			OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
931
			OUT_BATCH(op->src.u.gen3.mode);
1189
			OUT_BATCH(op->src.u.gen3.mode);
932
			state->last_diffuse = op->src.u.gen3.mode;
1190
			state->last_diffuse = op->src.u.gen3.mode;
933
		}
1191
		}
934
		break;
1192
		break;
935
	case SHADER_LINEAR:
1193
	case SHADER_LINEAR:
936
	case SHADER_RADIAL:
1194
	case SHADER_RADIAL:
937
	case SHADER_TEXTURE:
1195
	case SHADER_TEXTURE:
938
		ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
1196
		ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
939
		ss2 |= S2_TEXCOORD_FMT(tex_count,
1197
		ss2 |= S2_TEXCOORD_FMT(tex_count,
940
				       op->src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
1198
				       op->src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
-
 
1199
		assert(op->src.card_format);
941
		map[tex_count * 2 + 0] =
1200
		map[tex_count * 2 + 0] =
942
			op->src.card_format |
1201
			op->src.card_format |
943
			gen3_ms_tiling(op->src.bo->tiling) |
1202
			gen3_ms_tiling(op->src.bo->tiling) |
944
			(op->src.height - 1) << MS3_HEIGHT_SHIFT |
1203
			(op->src.height - 1) << MS3_HEIGHT_SHIFT |
945
			(op->src.width - 1) << MS3_WIDTH_SHIFT;
1204
			(op->src.width - 1) << MS3_WIDTH_SHIFT;
946
		map[tex_count * 2 + 1] =
1205
		map[tex_count * 2 + 1] =
947
			(op->src.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT;
1206
			(op->src.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT;
948
 
1207
 
949
		sampler[tex_count * 2 + 0] = op->src.filter;
1208
		sampler[tex_count * 2 + 0] = op->src.filter;
950
		sampler[tex_count * 2 + 1] =
1209
		sampler[tex_count * 2 + 1] =
951
			op->src.repeat |
1210
			op->src.repeat |
952
			tex_count << SS3_TEXTUREMAP_INDEX_SHIFT;
1211
			tex_count << SS3_TEXTUREMAP_INDEX_SHIFT;
953
		bo[tex_count] = op->src.bo;
1212
		bo[tex_count] = op->src.bo;
954
		tex_count++;
1213
		tex_count++;
955
		break;
1214
		break;
956
	}
1215
	}
957
	switch (op->mask.u.gen3.type) {
1216
	switch (op->mask.u.gen3.type) {
958
	case SHADER_NONE:
1217
	case SHADER_NONE:
959
	case SHADER_ZERO:
1218
	case SHADER_ZERO:
960
	case SHADER_BLACK:
1219
	case SHADER_BLACK:
961
	case SHADER_WHITE:
1220
	case SHADER_WHITE:
962
		break;
1221
		break;
963
	case SHADER_CONSTANT:
1222
	case SHADER_CONSTANT:
964
		if (op->mask.u.gen3.mode != state->last_specular) {
1223
		if (op->mask.u.gen3.mode != state->last_specular) {
965
			OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
1224
			OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
966
			OUT_BATCH(op->mask.u.gen3.mode);
1225
			OUT_BATCH(op->mask.u.gen3.mode);
967
			state->last_specular = op->mask.u.gen3.mode;
1226
			state->last_specular = op->mask.u.gen3.mode;
968
		}
1227
		}
969
		break;
1228
		break;
970
	case SHADER_LINEAR:
1229
	case SHADER_LINEAR:
971
	case SHADER_RADIAL:
1230
	case SHADER_RADIAL:
972
	case SHADER_TEXTURE:
1231
	case SHADER_TEXTURE:
973
		ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
1232
		ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
974
		ss2 |= S2_TEXCOORD_FMT(tex_count,
1233
		ss2 |= S2_TEXCOORD_FMT(tex_count,
975
				       op->mask.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
1234
				       op->mask.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
-
 
1235
		assert(op->mask.card_format);
976
		map[tex_count * 2 + 0] =
1236
		map[tex_count * 2 + 0] =
977
			op->mask.card_format |
1237
			op->mask.card_format |
978
			gen3_ms_tiling(op->mask.bo->tiling) |
1238
			gen3_ms_tiling(op->mask.bo->tiling) |
979
			(op->mask.height - 1) << MS3_HEIGHT_SHIFT |
1239
			(op->mask.height - 1) << MS3_HEIGHT_SHIFT |
980
			(op->mask.width - 1) << MS3_WIDTH_SHIFT;
1240
			(op->mask.width - 1) << MS3_WIDTH_SHIFT;
981
		map[tex_count * 2 + 1] =
1241
		map[tex_count * 2 + 1] =
982
			(op->mask.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT;
1242
			(op->mask.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT;
983
 
1243
 
984
		sampler[tex_count * 2 + 0] = op->mask.filter;
1244
		sampler[tex_count * 2 + 0] = op->mask.filter;
985
		sampler[tex_count * 2 + 1] =
1245
		sampler[tex_count * 2 + 1] =
986
			op->mask.repeat |
1246
			op->mask.repeat |
987
			tex_count << SS3_TEXTUREMAP_INDEX_SHIFT;
1247
			tex_count << SS3_TEXTUREMAP_INDEX_SHIFT;
988
		bo[tex_count] = op->mask.bo;
1248
		bo[tex_count] = op->mask.bo;
989
		tex_count++;
1249
		tex_count++;
990
		break;
1250
		break;
991
	case SHADER_OPACITY:
1251
	case SHADER_OPACITY:
992
		ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
1252
		ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
993
		ss2 |= S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_1D);
1253
		ss2 |= S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_1D);
994
		break;
1254
		break;
995
	}
1255
	}
996
 
1256
 
997
	{
1257
	{
998
		uint32_t blend_offset = sna->kgem.nbatch;
1258
		uint32_t blend_offset = sna->kgem.nbatch;
999
 
1259
 
1000
		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
1260
		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
1001
		OUT_BATCH(ss2);
1261
		OUT_BATCH(ss2);
1002
		OUT_BATCH(gen3_get_blend_cntl(op->op,
1262
		OUT_BATCH(gen3_get_blend_cntl(op->op,
1003
					      op->has_component_alpha,
1263
					      op->has_component_alpha,
1004
					      op->dst.format));
1264
					      op->dst.format));
1005
 
1265
 
1006
		if (memcmp(sna->kgem.batch + state->last_blend + 1,
1266
		if (memcmp(sna->kgem.batch + state->last_blend + 1,
1007
			   sna->kgem.batch + blend_offset + 1,
1267
			   sna->kgem.batch + blend_offset + 1,
1008
			   2 * 4) == 0)
1268
			   2 * 4) == 0)
1009
			sna->kgem.nbatch = blend_offset;
1269
			sna->kgem.nbatch = blend_offset;
1010
		else
1270
		else
1011
			state->last_blend = blend_offset;
1271
			state->last_blend = blend_offset;
1012
	}
1272
	}
1013
 
1273
 
1014
	if (op->u.gen3.num_constants) {
1274
	if (op->u.gen3.num_constants) {
1015
		int count = op->u.gen3.num_constants;
1275
		int count = op->u.gen3.num_constants;
1016
		if (state->last_constants) {
1276
		if (state->last_constants) {
1017
			int last = sna->kgem.batch[state->last_constants+1];
1277
			int last = sna->kgem.batch[state->last_constants+1];
1018
			if (last == (1 << (count >> 2)) - 1 &&
1278
			if (last == (1 << (count >> 2)) - 1 &&
1019
			    memcmp(&sna->kgem.batch[state->last_constants+2],
1279
			    memcmp(&sna->kgem.batch[state->last_constants+2],
1020
				   op->u.gen3.constants,
1280
				   op->u.gen3.constants,
1021
				   count * sizeof(uint32_t)) == 0)
1281
				   count * sizeof(uint32_t)) == 0)
1022
				count = 0;
1282
				count = 0;
1023
		}
1283
		}
1024
		if (count) {
1284
		if (count) {
1025
			state->last_constants = sna->kgem.nbatch;
1285
			state->last_constants = sna->kgem.nbatch;
1026
			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | count);
1286
			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | count);
1027
			OUT_BATCH((1 << (count >> 2)) - 1);
1287
			OUT_BATCH((1 << (count >> 2)) - 1);
1028
 
1288
 
1029
			memcpy(sna->kgem.batch + sna->kgem.nbatch,
1289
			memcpy(sna->kgem.batch + sna->kgem.nbatch,
1030
			       op->u.gen3.constants,
1290
			       op->u.gen3.constants,
1031
			       count * sizeof(uint32_t));
1291
			       count * sizeof(uint32_t));
1032
			sna->kgem.nbatch += count;
1292
			sna->kgem.nbatch += count;
1033
		}
1293
		}
1034
	}
1294
	}
1035
 
1295
 
1036
	if (tex_count != 0) {
1296
	if (tex_count != 0) {
1037
		uint32_t rewind;
1297
		uint32_t rewind;
1038
 
1298
 
1039
		n = 0;
1299
		n = 0;
1040
		if (tex_count == state->tex_count) {
1300
		if (tex_count == state->tex_count) {
1041
			for (; n < tex_count; n++) {
1301
			for (; n < tex_count; n++) {
1042
				if (map[2*n+0] != state->tex_map[2*n+0] ||
1302
				if (map[2*n+0] != state->tex_map[2*n+0] ||
1043
				    map[2*n+1] != state->tex_map[2*n+1] ||
1303
				    map[2*n+1] != state->tex_map[2*n+1] ||
1044
				    state->tex_handle[n] != bo[n]->handle ||
1304
				    state->tex_handle[n] != bo[n]->handle ||
1045
				    state->tex_delta[n] != bo[n]->delta)
1305
				    state->tex_delta[n] != bo[n]->delta)
1046
					break;
1306
					break;
1047
			}
1307
			}
1048
		}
1308
		}
1049
		if (n < tex_count) {
1309
		if (n < tex_count) {
1050
			OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count));
1310
			OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count));
1051
			OUT_BATCH((1 << tex_count) - 1);
1311
			OUT_BATCH((1 << tex_count) - 1);
1052
			for (n = 0; n < tex_count; n++) {
1312
			for (n = 0; n < tex_count; n++) {
1053
				OUT_BATCH(kgem_add_reloc(&sna->kgem,
1313
				OUT_BATCH(kgem_add_reloc(&sna->kgem,
1054
							 sna->kgem.nbatch,
1314
							 sna->kgem.nbatch,
1055
							 bo[n],
1315
							 bo[n],
1056
							 I915_GEM_DOMAIN_SAMPLER<< 16,
1316
							 I915_GEM_DOMAIN_SAMPLER<< 16,
1057
							 0));
1317
							 0));
1058
				OUT_BATCH(map[2*n + 0]);
1318
				OUT_BATCH(map[2*n + 0]);
1059
				OUT_BATCH(map[2*n + 1]);
1319
				OUT_BATCH(map[2*n + 1]);
1060
 
1320
 
1061
				state->tex_map[2*n+0] = map[2*n+0];
1321
				state->tex_map[2*n+0] = map[2*n+0];
1062
				state->tex_map[2*n+1] = map[2*n+1];
1322
				state->tex_map[2*n+1] = map[2*n+1];
1063
				state->tex_handle[n] = bo[n]->handle;
1323
				state->tex_handle[n] = bo[n]->handle;
1064
				state->tex_delta[n] = bo[n]->delta;
1324
				state->tex_delta[n] = bo[n]->delta;
1065
			}
1325
			}
1066
			state->tex_count = n;
1326
			state->tex_count = n;
1067
		}
1327
		}
1068
 
1328
 
1069
		rewind = sna->kgem.nbatch;
1329
		rewind = sna->kgem.nbatch;
1070
		OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count));
1330
		OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count));
1071
		OUT_BATCH((1 << tex_count) - 1);
1331
		OUT_BATCH((1 << tex_count) - 1);
1072
		for (n = 0; n < tex_count; n++) {
1332
		for (n = 0; n < tex_count; n++) {
1073
			OUT_BATCH(sampler[2*n + 0]);
1333
			OUT_BATCH(sampler[2*n + 0]);
1074
			OUT_BATCH(sampler[2*n + 1]);
1334
			OUT_BATCH(sampler[2*n + 1]);
1075
			OUT_BATCH(0);
1335
			OUT_BATCH(0);
1076
		}
1336
		}
1077
		if (state->last_sampler &&
1337
		if (state->last_sampler &&
1078
		    memcmp(&sna->kgem.batch[state->last_sampler+1],
1338
		    memcmp(&sna->kgem.batch[state->last_sampler+1],
1079
			   &sna->kgem.batch[rewind + 1],
1339
			   &sna->kgem.batch[rewind + 1],
1080
			   (3*tex_count + 1)*sizeof(uint32_t)) == 0)
1340
			   (3*tex_count + 1)*sizeof(uint32_t)) == 0)
1081
			sna->kgem.nbatch = rewind;
1341
			sna->kgem.nbatch = rewind;
1082
		else
1342
		else
1083
			state->last_sampler = rewind;
1343
			state->last_sampler = rewind;
1084
	}
1344
	}
1085
 
1345
 
1086
	gen3_composite_emit_shader(sna, op, op->op);
1346
	gen3_composite_emit_shader(sna, op, op->op);
1087
}
1347
}
1088
 
1348
 
1089
static bool gen3_magic_ca_pass(struct sna *sna,
1349
static bool gen3_magic_ca_pass(struct sna *sna,
1090
			       const struct sna_composite_op *op)
1350
			       const struct sna_composite_op *op)
1091
{
1351
{
1092
	if (!op->need_magic_ca_pass)
1352
	if (!op->need_magic_ca_pass)
1093
		return false;
1353
		return false;
1094
 
1354
 
1095
	DBG(("%s(%d)\n", __FUNCTION__,
1355
	DBG(("%s(%d)\n", __FUNCTION__,
1096
	     sna->render.vertex_index - sna->render.vertex_start));
1356
	     sna->render.vertex_index - sna->render.vertex_start));
1097
 
1357
 
1098
	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
1358
	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
1099
	OUT_BATCH(gen3_get_blend_cntl(PictOpAdd, true, op->dst.format));
1359
	OUT_BATCH(gen3_get_blend_cntl(PictOpAdd, true, op->dst.format));
1100
	gen3_composite_emit_shader(sna, op, PictOpAdd);
1360
	gen3_composite_emit_shader(sna, op, PictOpAdd);
1101
 
1361
 
1102
	OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL |
1362
	OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL |
1103
		  (sna->render.vertex_index - sna->render.vertex_start));
1363
		  (sna->render.vertex_index - sna->render.vertex_start));
1104
	OUT_BATCH(sna->render.vertex_start);
1364
	OUT_BATCH(sna->render.vertex_start);
1105
 
1365
 
1106
	sna->render_state.gen3.last_blend = 0;
1366
	sna->render_state.gen3.last_blend = 0;
1107
	return true;
1367
	return true;
1108
}
1368
}
1109
 
1369
 
1110
static void gen3_vertex_flush(struct sna *sna)
1370
static void gen3_vertex_flush(struct sna *sna)
1111
{
1371
{
1112
	assert(sna->render.vertex_offset);
1372
	assert(sna->render.vertex_offset);
1113
 
1373
 
1114
	DBG(("%s[%x] = %d\n", __FUNCTION__,
1374
	DBG(("%s[%x] = %d\n", __FUNCTION__,
1115
	     4*sna->render.vertex_offset,
1375
	     4*sna->render.vertex_offset,
1116
	     sna->render.vertex_index - sna->render.vertex_start));
1376
	     sna->render.vertex_index - sna->render.vertex_start));
1117
 
1377
 
1118
	sna->kgem.batch[sna->render.vertex_offset] =
1378
	sna->kgem.batch[sna->render.vertex_offset] =
1119
		PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL |
1379
		PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL |
1120
		(sna->render.vertex_index - sna->render.vertex_start);
1380
		(sna->render.vertex_index - sna->render.vertex_start);
1121
	sna->kgem.batch[sna->render.vertex_offset + 1] =
1381
	sna->kgem.batch[sna->render.vertex_offset + 1] =
1122
		sna->render.vertex_start;
1382
		sna->render.vertex_start;
1123
 
1383
 
1124
	sna->render.vertex_offset = 0;
1384
	sna->render.vertex_offset = 0;
1125
}
1385
}
1126
 
1386
 
1127
static int gen3_vertex_finish(struct sna *sna)
1387
static int gen3_vertex_finish(struct sna *sna)
1128
{
1388
{
1129
	struct kgem_bo *bo;
1389
	struct kgem_bo *bo;
1130
 
1390
 
1131
	DBG(("%s: used=%d/%d, vbo active? %d\n",
1391
	DBG(("%s: used=%d/%d, vbo active? %d\n",
1132
	     __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size,
1392
	     __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size,
1133
	     sna->render.vbo ? sna->render.vbo->handle : 0));
1393
	     sna->render.vbo ? sna->render.vbo->handle : 0));
1134
	assert(sna->render.vertex_offset == 0);
1394
	assert(sna->render.vertex_offset == 0);
1135
	assert(sna->render.vertex_used);
1395
	assert(sna->render.vertex_used);
1136
	assert(sna->render.vertex_used <= sna->render.vertex_size);
1396
	assert(sna->render.vertex_used <= sna->render.vertex_size);
1137
 
1397
 
1138
	sna_vertex_wait__locked(&sna->render);
1398
	sna_vertex_wait__locked(&sna->render);
1139
 
1399
 
1140
	bo = sna->render.vbo;
1400
	bo = sna->render.vbo;
1141
	if (bo) {
1401
	if (bo) {
1142
		DBG(("%s: reloc = %d\n", __FUNCTION__,
1402
		DBG(("%s: reloc = %d\n", __FUNCTION__,
1143
		     sna->render.vertex_reloc[0]));
1403
		     sna->render.vertex_reloc[0]));
1144
 
1404
 
1145
		if (sna->render.vertex_reloc[0]) {
1405
		if (sna->render.vertex_reloc[0]) {
1146
			sna->kgem.batch[sna->render.vertex_reloc[0]] =
1406
			sna->kgem.batch[sna->render.vertex_reloc[0]] =
1147
				kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0],
1407
				kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0],
1148
					       bo, I915_GEM_DOMAIN_VERTEX << 16, 0);
1408
					       bo, I915_GEM_DOMAIN_VERTEX << 16, 0);
1149
 
1409
 
1150
			sna->render.vertex_reloc[0] = 0;
1410
			sna->render.vertex_reloc[0] = 0;
1151
		}
1411
		}
1152
		sna->render.vertex_used = 0;
1412
		sna->render.vertex_used = 0;
1153
		sna->render.vertex_index = 0;
1413
		sna->render.vertex_index = 0;
1154
		sna->render.vbo = NULL;
1414
		sna->render.vbo = NULL;
1155
 
1415
 
1156
		kgem_bo_destroy(&sna->kgem, bo);
1416
		kgem_bo_destroy(&sna->kgem, bo);
1157
	}
1417
	}
1158
 
1418
 
1159
	sna->render.vertices = NULL;
1419
	sna->render.vertices = NULL;
1160
	sna->render.vbo = kgem_create_linear(&sna->kgem,
1420
	sna->render.vbo = kgem_create_linear(&sna->kgem,
1161
					     256*1024, CREATE_GTT_MAP);
1421
					     256*1024, CREATE_GTT_MAP);
1162
	if (sna->render.vbo)
1422
	if (sna->render.vbo)
1163
		sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
1423
		sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
1164
	if (sna->render.vertices == NULL) {
1424
	if (sna->render.vertices == NULL) {
1165
		if (sna->render.vbo)
1425
		if (sna->render.vbo)
1166
			kgem_bo_destroy(&sna->kgem, sna->render.vbo);
1426
			kgem_bo_destroy(&sna->kgem, sna->render.vbo);
1167
		sna->render.vbo = NULL;
1427
		sna->render.vbo = NULL;
1168
		return 0;
1428
		return 0;
1169
	}
1429
	}
1170
	assert(sna->render.vbo->snoop == false);
1430
	assert(sna->render.vbo->snoop == false);
1171
 
1431
 
1172
	if (sna->render.vertex_used) {
1432
	if (sna->render.vertex_used) {
1173
		memcpy(sna->render.vertices,
1433
		memcpy(sna->render.vertices,
1174
		       sna->render.vertex_data,
1434
		       sna->render.vertex_data,
1175
		       sizeof(float)*sna->render.vertex_used);
1435
		       sizeof(float)*sna->render.vertex_used);
1176
	}
1436
	}
1177
	sna->render.vertex_size = 64 * 1024 - 1;
1437
	sna->render.vertex_size = 64 * 1024 - 1;
1178
	return sna->render.vertex_size - sna->render.vertex_used;
1438
	return sna->render.vertex_size - sna->render.vertex_used;
1179
}
1439
}
1180
 
1440
 
1181
static void gen3_vertex_close(struct sna *sna)
1441
static void gen3_vertex_close(struct sna *sna)
1182
{
1442
{
1183
	struct kgem_bo *bo, *free_bo = NULL;
1443
	struct kgem_bo *bo, *free_bo = NULL;
1184
	unsigned int delta = 0;
1444
	unsigned int delta = 0;
1185
 
1445
 
1186
	assert(sna->render.vertex_offset == 0);
1446
	assert(sna->render.vertex_offset == 0);
1187
	if (sna->render.vertex_reloc[0] == 0)
1447
	if (sna->render.vertex_reloc[0] == 0)
1188
		return;
1448
		return;
1189
 
1449
 
1190
	DBG(("%s: used=%d/%d, vbo active? %d\n",
1450
	DBG(("%s: used=%d/%d, vbo active? %d\n",
1191
	     __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size,
1451
	     __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size,
1192
	     sna->render.vbo ? sna->render.vbo->handle : 0));
1452
	     sna->render.vbo ? sna->render.vbo->handle : 0));
1193
 
1453
 
1194
	bo = sna->render.vbo;
1454
	bo = sna->render.vbo;
1195
	if (bo) {
1455
	if (bo) {
1196
		if (sna->render.vertex_size - sna->render.vertex_used < 64) {
1456
		if (sna->render.vertex_size - sna->render.vertex_used < 64) {
1197
			DBG(("%s: discarding full vbo\n", __FUNCTION__));
1457
			DBG(("%s: discarding full vbo\n", __FUNCTION__));
1198
			sna->render.vbo = NULL;
1458
			sna->render.vbo = NULL;
1199
			sna->render.vertices = sna->render.vertex_data;
1459
			sna->render.vertices = sna->render.vertex_data;
1200
			sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
1460
			sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
1201
			free_bo = bo;
1461
			free_bo = bo;
1202
		} else if (IS_CPU_MAP(bo->map)) {
1462
		} else if (IS_CPU_MAP(bo->map)) {
1203
			DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
1463
			DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
1204
			sna->render.vertices = kgem_bo_map__gtt(&sna->kgem, bo);
1464
			sna->render.vertices = kgem_bo_map__gtt(&sna->kgem, bo);
1205
			if (sna->render.vertices == NULL) {
1465
			if (sna->render.vertices == NULL) {
1206
				DBG(("%s: discarding non-mappable vertices\n",__FUNCTION__));
1466
				DBG(("%s: discarding non-mappable vertices\n",__FUNCTION__));
1207
				sna->render.vbo = NULL;
1467
				sna->render.vbo = NULL;
1208
				sna->render.vertices = sna->render.vertex_data;
1468
				sna->render.vertices = sna->render.vertex_data;
1209
				sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
1469
				sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
1210
				free_bo = bo;
1470
				free_bo = bo;
1211
			}
1471
			}
1212
		}
1472
		}
1213
	} else {
1473
	} else {
1214
		if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
1474
		if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
1215
			DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
1475
			DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
1216
			     sna->render.vertex_used, sna->kgem.nbatch));
1476
			     sna->render.vertex_used, sna->kgem.nbatch));
1217
			memcpy(sna->kgem.batch + sna->kgem.nbatch,
1477
			memcpy(sna->kgem.batch + sna->kgem.nbatch,
1218
			       sna->render.vertex_data,
1478
			       sna->render.vertex_data,
1219
			       sna->render.vertex_used * 4);
1479
			       sna->render.vertex_used * 4);
1220
			delta = sna->kgem.nbatch * 4;
1480
			delta = sna->kgem.nbatch * 4;
1221
			bo = NULL;
1481
			bo = NULL;
1222
			sna->kgem.nbatch += sna->render.vertex_used;
1482
			sna->kgem.nbatch += sna->render.vertex_used;
1223
		} else {
1483
		} else {
1224
			DBG(("%s: new vbo: %d\n", __FUNCTION__,
1484
			DBG(("%s: new vbo: %d\n", __FUNCTION__,
1225
			     sna->render.vertex_used));
1485
			     sna->render.vertex_used));
1226
			bo = kgem_create_linear(&sna->kgem,
1486
			bo = kgem_create_linear(&sna->kgem,
1227
						4*sna->render.vertex_used,
1487
						4*sna->render.vertex_used,
1228
						CREATE_NO_THROTTLE);
1488
						CREATE_NO_THROTTLE);
1229
			if (bo) {
1489
			if (bo) {
1230
				assert(bo->snoop == false);
1490
				assert(bo->snoop == false);
1231
				kgem_bo_write(&sna->kgem, bo,
1491
				kgem_bo_write(&sna->kgem, bo,
1232
					      sna->render.vertex_data,
1492
					      sna->render.vertex_data,
1233
					      4*sna->render.vertex_used);
1493
					      4*sna->render.vertex_used);
1234
			}
1494
			}
1235
			free_bo = bo;
1495
			free_bo = bo;
1236
		}
1496
		}
1237
	}
1497
	}
1238
 
1498
 
1239
	DBG(("%s: reloc = %d\n", __FUNCTION__, sna->render.vertex_reloc[0]));
1499
	DBG(("%s: reloc = %d\n", __FUNCTION__, sna->render.vertex_reloc[0]));
1240
	sna->kgem.batch[sna->render.vertex_reloc[0]] =
1500
	sna->kgem.batch[sna->render.vertex_reloc[0]] =
1241
		kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0],
1501
		kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0],
1242
			       bo, I915_GEM_DOMAIN_VERTEX << 16, delta);
1502
			       bo, I915_GEM_DOMAIN_VERTEX << 16, delta);
1243
	sna->render.vertex_reloc[0] = 0;
1503
	sna->render.vertex_reloc[0] = 0;
1244
 
1504
 
1245
	if (sna->render.vbo == NULL) {
1505
	if (sna->render.vbo == NULL) {
1246
		DBG(("%s: resetting vbo\n", __FUNCTION__));
1506
		DBG(("%s: resetting vbo\n", __FUNCTION__));
1247
		sna->render.vertex_used = 0;
1507
		sna->render.vertex_used = 0;
1248
		sna->render.vertex_index = 0;
1508
		sna->render.vertex_index = 0;
1249
		assert(sna->render.vertices == sna->render.vertex_data);
1509
		assert(sna->render.vertices == sna->render.vertex_data);
1250
		assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
1510
		assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
1251
	}
1511
	}
1252
 
1512
 
1253
	if (free_bo)
1513
	if (free_bo)
1254
		kgem_bo_destroy(&sna->kgem, free_bo);
1514
		kgem_bo_destroy(&sna->kgem, free_bo);
1255
}
1515
}
1256
 
1516
 
1257
static bool gen3_rectangle_begin(struct sna *sna,
1517
static bool gen3_rectangle_begin(struct sna *sna,
1258
				 const struct sna_composite_op *op)
1518
				 const struct sna_composite_op *op)
1259
{
1519
{
1260
	struct gen3_render_state *state = &sna->render_state.gen3;
1520
	struct gen3_render_state *state = &sna->render_state.gen3;
1261
	int ndwords, i1_cmd = 0, i1_len = 0;
1521
	int ndwords, i1_cmd = 0, i1_len = 0;
1262
 
1522
 
1263
	if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
1523
	if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
1264
		return true;
1524
		return true;
1265
 
1525
 
1266
	ndwords = 2;
1526
	ndwords = 2;
1267
	if (op->need_magic_ca_pass)
1527
	if (op->need_magic_ca_pass)
1268
		ndwords += 100;
1528
		ndwords += 100;
1269
	if (sna->render.vertex_reloc[0] == 0)
1529
	if (sna->render.vertex_reloc[0] == 0)
1270
		i1_len++, i1_cmd |= I1_LOAD_S(0), ndwords++;
1530
		i1_len++, i1_cmd |= I1_LOAD_S(0), ndwords++;
1271
	if (state->floats_per_vertex != op->floats_per_vertex)
1531
	if (state->floats_per_vertex != op->floats_per_vertex)
1272
		i1_len++, i1_cmd |= I1_LOAD_S(1), ndwords++;
1532
		i1_len++, i1_cmd |= I1_LOAD_S(1), ndwords++;
1273
 
1533
 
1274
	if (!kgem_check_batch(&sna->kgem, ndwords+1))
1534
	if (!kgem_check_batch(&sna->kgem, ndwords+1))
1275
		return false;
1535
		return false;
1276
 
1536
 
1277
	if (i1_cmd) {
1537
	if (i1_cmd) {
1278
		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | i1_cmd | (i1_len - 1));
1538
		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | i1_cmd | (i1_len - 1));
1279
		if (sna->render.vertex_reloc[0] == 0)
1539
		if (sna->render.vertex_reloc[0] == 0)
1280
			sna->render.vertex_reloc[0] = sna->kgem.nbatch++;
1540
			sna->render.vertex_reloc[0] = sna->kgem.nbatch++;
1281
		if (state->floats_per_vertex != op->floats_per_vertex) {
1541
		if (state->floats_per_vertex != op->floats_per_vertex) {
1282
			state->floats_per_vertex = op->floats_per_vertex;
1542
			state->floats_per_vertex = op->floats_per_vertex;
1283
			OUT_BATCH(state->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT |
1543
			OUT_BATCH(state->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT |
1284
				  state->floats_per_vertex << S1_VERTEX_PITCH_SHIFT);
1544
				  state->floats_per_vertex << S1_VERTEX_PITCH_SHIFT);
1285
		}
1545
		}
1286
	}
1546
	}
1287
 
1547
 
1288
	if (sna->kgem.nbatch == 2 + state->last_vertex_offset &&
1548
	if (sna->kgem.nbatch == 2 + state->last_vertex_offset &&
1289
	    !op->need_magic_ca_pass) {
1549
	    !op->need_magic_ca_pass) {
1290
		sna->render.vertex_offset = state->last_vertex_offset;
1550
		sna->render.vertex_offset = state->last_vertex_offset;
1291
	} else {
1551
	} else {
1292
		sna->render.vertex_offset = sna->kgem.nbatch;
1552
		sna->render.vertex_offset = sna->kgem.nbatch;
1293
		OUT_BATCH(MI_NOOP); /* to be filled later */
1553
		OUT_BATCH(MI_NOOP); /* to be filled later */
1294
		OUT_BATCH(MI_NOOP);
1554
		OUT_BATCH(MI_NOOP);
1295
		sna->render.vertex_start = sna->render.vertex_index;
1555
		sna->render.vertex_start = sna->render.vertex_index;
1296
		state->last_vertex_offset = sna->render.vertex_offset;
1556
		state->last_vertex_offset = sna->render.vertex_offset;
1297
	}
1557
	}
1298
 
1558
 
1299
	return true;
1559
	return true;
1300
}
1560
}
1301
 
1561
 
1302
static int gen3_get_rectangles__flush(struct sna *sna,
1562
static int gen3_get_rectangles__flush(struct sna *sna,
1303
				      const struct sna_composite_op *op)
1563
				      const struct sna_composite_op *op)
1304
{
1564
{
1305
	/* Preventing discarding new vbo after lock contention */
1565
	/* Preventing discarding new vbo after lock contention */
1306
	if (sna_vertex_wait__locked(&sna->render)) {
1566
	if (sna_vertex_wait__locked(&sna->render)) {
1307
		int rem = vertex_space(sna);
1567
		int rem = vertex_space(sna);
1308
		if (rem > op->floats_per_rect)
1568
		if (rem > op->floats_per_rect)
1309
			return rem;
1569
			return rem;
1310
	}
1570
	}
1311
 
1571
 
1312
	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 105: 5))
1572
	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 105: 5))
1313
		return 0;
1573
		return 0;
1314
	if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
1574
	if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
1315
		return 0;
1575
		return 0;
1316
 
1576
 
1317
	if (sna->render.vertex_offset) {
1577
	if (sna->render.vertex_offset) {
1318
		gen3_vertex_flush(sna);
1578
		gen3_vertex_flush(sna);
1319
		if (gen3_magic_ca_pass(sna, op)) {
1579
		if (gen3_magic_ca_pass(sna, op)) {
1320
			OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
1580
			OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
1321
			OUT_BATCH(gen3_get_blend_cntl(op->op,
1581
			OUT_BATCH(gen3_get_blend_cntl(op->op,
1322
						      op->has_component_alpha,
1582
						      op->has_component_alpha,
1323
						      op->dst.format));
1583
						      op->dst.format));
1324
			gen3_composite_emit_shader(sna, op, op->op);
1584
			gen3_composite_emit_shader(sna, op, op->op);
1325
		}
1585
		}
1326
	}
1586
	}
1327
 
1587
 
1328
	return gen3_vertex_finish(sna);
1588
	return gen3_vertex_finish(sna);
1329
}
1589
}
1330
 
1590
 
1331
inline static int gen3_get_rectangles(struct sna *sna,
1591
inline static int gen3_get_rectangles(struct sna *sna,
1332
				      const struct sna_composite_op *op,
1592
				      const struct sna_composite_op *op,
1333
				      int want)
1593
				      int want)
1334
{
1594
{
1335
	int rem;
1595
	int rem;
1336
 
1596
 
1337
	DBG(("%s: want=%d, rem=%d\n",
1597
	DBG(("%s: want=%d, rem=%d\n",
1338
	     __FUNCTION__, want*op->floats_per_rect, vertex_space(sna)));
1598
	     __FUNCTION__, want*op->floats_per_rect, vertex_space(sna)));
1339
 
1599
 
1340
	assert(want);
1600
	assert(want);
1341
	assert(sna->render.vertex_index * op->floats_per_vertex == sna->render.vertex_used);
1601
	assert(sna->render.vertex_index * op->floats_per_vertex == sna->render.vertex_used);
1342
 
1602
 
1343
start:
1603
start:
1344
	rem = vertex_space(sna);
1604
	rem = vertex_space(sna);
1345
	if (unlikely(op->floats_per_rect > rem)) {
1605
	if (unlikely(op->floats_per_rect > rem)) {
1346
		DBG(("flushing vbo for %s: %d < %d\n",
1606
		DBG(("flushing vbo for %s: %d < %d\n",
1347
		     __FUNCTION__, rem, op->floats_per_rect));
1607
		     __FUNCTION__, rem, op->floats_per_rect));
1348
		rem = gen3_get_rectangles__flush(sna, op);
1608
		rem = gen3_get_rectangles__flush(sna, op);
1349
		if (unlikely(rem == 0))
1609
		if (unlikely(rem == 0))
1350
			goto flush;
1610
			goto flush;
1351
	}
1611
	}
1352
 
1612
 
1353
	if (unlikely(sna->render.vertex_offset == 0)) {
1613
	if (unlikely(sna->render.vertex_offset == 0)) {
1354
		if (!gen3_rectangle_begin(sna, op))
1614
		if (!gen3_rectangle_begin(sna, op))
1355
			goto flush;
1615
			goto flush;
1356
		else
1616
		else
1357
			goto start;
1617
			goto start;
1358
	}
1618
	}
1359
 
-
 
1360
	assert(op->floats_per_rect >= vertex_space(sna));
1619
 
-
 
1620
	assert(rem <= vertex_space(sna));
1361
	assert(rem <= vertex_space(sna));
1621
	assert(op->floats_per_rect <= rem);
1362
	if (want > 1 && want * op->floats_per_rect > rem)
1622
	if (want > 1 && want * op->floats_per_rect > rem)
1363
		want = rem / op->floats_per_rect;
1623
		want = rem / op->floats_per_rect;
1364
	sna->render.vertex_index += 3*want;
1624
	sna->render.vertex_index += 3*want;
1365
 
1625
 
1366
	assert(want);
1626
	assert(want);
1367
	assert(sna->render.vertex_index * op->floats_per_vertex <= sna->render.vertex_size);
1627
	assert(sna->render.vertex_index * op->floats_per_vertex <= sna->render.vertex_size);
1368
	return want;
1628
	return want;
1369
 
1629
 
1370
flush:
1630
flush:
1371
	DBG(("%s: flushing batch\n", __FUNCTION__));
1631
	DBG(("%s: flushing batch\n", __FUNCTION__));
1372
	if (sna->render.vertex_offset) {
1632
	if (sna->render.vertex_offset) {
1373
		gen3_vertex_flush(sna);
1633
		gen3_vertex_flush(sna);
1374
		gen3_magic_ca_pass(sna, op);
1634
		gen3_magic_ca_pass(sna, op);
1375
	}
1635
	}
1376
	sna_vertex_wait__locked(&sna->render);
1636
	sna_vertex_wait__locked(&sna->render);
1377
	_kgem_submit(&sna->kgem);
1637
	_kgem_submit(&sna->kgem);
1378
	gen3_emit_composite_state(sna, op);
1638
	gen3_emit_composite_state(sna, op);
1379
	assert(sna->render.vertex_offset == 0);
1639
	assert(sna->render.vertex_offset == 0);
1380
	assert(sna->render.vertex_reloc[0] == 0);
1640
	assert(sna->render.vertex_reloc[0] == 0);
1381
	goto start;
1641
	goto start;
1382
}
1642
}
1383
 
1643
 
1384
fastcall static void
1644
fastcall static void
1385
gen3_render_composite_blt(struct sna *sna,
1645
gen3_render_composite_blt(struct sna *sna,
1386
			  const struct sna_composite_op *op,
1646
			  const struct sna_composite_op *op,
1387
			  const struct sna_composite_rectangles *r)
1647
			  const struct sna_composite_rectangles *r)
1388
{
1648
{
1389
	DBG(("%s: src=(%d, %d)+(%d, %d), mask=(%d, %d)+(%d, %d), dst=(%d, %d)+(%d, %d), size=(%d, %d)\n", __FUNCTION__,
1649
	DBG(("%s: src=(%d, %d)+(%d, %d), mask=(%d, %d)+(%d, %d), dst=(%d, %d)+(%d, %d), size=(%d, %d)\n", __FUNCTION__,
1390
	     r->src.x, r->src.y, op->src.offset[0], op->src.offset[1],
1650
	     r->src.x, r->src.y, op->src.offset[0], op->src.offset[1],
1391
	     r->mask.x, r->mask.y, op->mask.offset[0], op->mask.offset[1],
1651
	     r->mask.x, r->mask.y, op->mask.offset[0], op->mask.offset[1],
1392
	     r->dst.x, r->dst.y, op->dst.x, op->dst.y,
1652
	     r->dst.x, r->dst.y, op->dst.x, op->dst.y,
1393
	     r->width, r->height));
1653
	     r->width, r->height));
1394
 
1654
 
1395
	gen3_get_rectangles(sna, op, 1);
1655
	gen3_get_rectangles(sna, op, 1);
1396
 
1656
 
1397
	op->prim_emit(sna, op, r);
1657
	op->prim_emit(sna, op, r);
1398
}
1658
}
1399
 
1659
 
1400
static void
1660
static void
1401
gen3_render_composite_done(struct sna *sna,
1661
gen3_render_composite_done(struct sna *sna,
1402
			   const struct sna_composite_op *op)
1662
			   const struct sna_composite_op *op)
1403
{
1663
{
1404
	DBG(("%s()\n", __FUNCTION__));
1664
	DBG(("%s()\n", __FUNCTION__));
1405
 
1665
 
1406
	if (sna->render.vertex_offset) {
1666
	if (sna->render.vertex_offset) {
1407
		gen3_vertex_flush(sna);
1667
		gen3_vertex_flush(sna);
1408
		gen3_magic_ca_pass(sna, op);
1668
		gen3_magic_ca_pass(sna, op);
1409
	}
1669
	}
1410
 
1670
 
1411
}
1671
}
1412
 
1672
 
1413
static void
1673
static void
1414
discard_vbo(struct sna *sna)
1674
discard_vbo(struct sna *sna)
1415
{
1675
{
1416
	kgem_bo_destroy(&sna->kgem, sna->render.vbo);
1676
	kgem_bo_destroy(&sna->kgem, sna->render.vbo);
1417
	sna->render.vbo = NULL;
1677
	sna->render.vbo = NULL;
1418
	sna->render.vertices = sna->render.vertex_data;
1678
	sna->render.vertices = sna->render.vertex_data;
1419
	sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
1679
	sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
1420
	sna->render.vertex_used = 0;
1680
	sna->render.vertex_used = 0;
1421
	sna->render.vertex_index = 0;
1681
	sna->render.vertex_index = 0;
1422
}
1682
}
1423
 
1683
 
1424
static void
1684
static void
1425
gen3_render_reset(struct sna *sna)
1685
gen3_render_reset(struct sna *sna)
1426
{
1686
{
1427
	struct gen3_render_state *state = &sna->render_state.gen3;
1687
	struct gen3_render_state *state = &sna->render_state.gen3;
1428
 
1688
 
1429
	state->need_invariant = true;
1689
	state->need_invariant = true;
1430
	state->current_dst = 0;
1690
	state->current_dst = 0;
1431
	state->tex_count = 0;
1691
	state->tex_count = 0;
1432
	state->last_drawrect_limit = ~0U;
1692
	state->last_drawrect_limit = ~0U;
1433
	state->last_target = 0;
1693
	state->last_target = 0;
1434
	state->last_blend = 0;
1694
	state->last_blend = 0;
1435
	state->last_constants = 0;
1695
	state->last_constants = 0;
1436
	state->last_sampler = 0;
1696
	state->last_sampler = 0;
1437
	state->last_shader = 0x7fffffff;
1697
	state->last_shader = 0x7fffffff;
1438
	state->last_diffuse = 0xcc00ffee;
1698
	state->last_diffuse = 0xcc00ffee;
1439
	state->last_specular = 0xcc00ffee;
1699
	state->last_specular = 0xcc00ffee;
1440
 
1700
 
1441
	state->floats_per_vertex = 0;
1701
	state->floats_per_vertex = 0;
1442
	state->last_floats_per_vertex = 0;
1702
	state->last_floats_per_vertex = 0;
1443
	state->last_vertex_offset = 0;
1703
	state->last_vertex_offset = 0;
1444
 
1704
 
1445
	if (sna->render.vbo != NULL &&
1705
	if (sna->render.vbo != NULL &&
1446
	    !kgem_bo_is_mappable(&sna->kgem, sna->render.vbo)) {
1706
	    !kgem_bo_is_mappable(&sna->kgem, sna->render.vbo)) {
1447
		DBG(("%s: discarding vbo as next access will stall: %d\n",
1707
		DBG(("%s: discarding vbo as next access will stall: %d\n",
1448
		     __FUNCTION__, sna->render.vbo->presumed_offset));
1708
		     __FUNCTION__, sna->render.vbo->presumed_offset));
1449
		discard_vbo(sna);
1709
		discard_vbo(sna);
1450
	}
1710
	}
1451
 
1711
 
1452
	sna->render.vertex_reloc[0] = 0;
1712
	sna->render.vertex_reloc[0] = 0;
1453
	sna->render.vertex_offset = 0;
1713
	sna->render.vertex_offset = 0;
1454
}
1714
}
1455
 
1715
 
1456
static void
1716
static void
1457
gen3_render_retire(struct kgem *kgem)
1717
gen3_render_retire(struct kgem *kgem)
1458
{
1718
{
1459
	struct sna *sna;
1719
	struct sna *sna;
1460
 
1720
 
1461
	sna = container_of(kgem, struct sna, kgem);
1721
	sna = container_of(kgem, struct sna, kgem);
1462
	if (sna->render.vertex_reloc[0] == 0 &&
1722
	if (sna->render.vertex_reloc[0] == 0 &&
1463
	    sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) {
1723
	    sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) {
1464
		DBG(("%s: resetting idle vbo\n", __FUNCTION__));
1724
		DBG(("%s: resetting idle vbo\n", __FUNCTION__));
1465
		sna->render.vertex_used = 0;
1725
		sna->render.vertex_used = 0;
1466
		sna->render.vertex_index = 0;
1726
		sna->render.vertex_index = 0;
1467
	}
1727
	}
1468
}
1728
}
1469
 
1729
 
1470
static void
1730
static void
1471
gen3_render_expire(struct kgem *kgem)
1731
gen3_render_expire(struct kgem *kgem)
1472
{
1732
{
1473
	struct sna *sna;
1733
	struct sna *sna;
1474
 
1734
 
1475
	sna = container_of(kgem, struct sna, kgem);
1735
	sna = container_of(kgem, struct sna, kgem);
1476
	if (sna->render.vbo && !sna->render.vertex_used) {
1736
	if (sna->render.vbo && !sna->render.vertex_used) {
1477
		DBG(("%s: discarding vbo\n", __FUNCTION__));
1737
		DBG(("%s: discarding vbo\n", __FUNCTION__));
1478
		discard_vbo(sna);
1738
		discard_vbo(sna);
1479
	}
1739
	}
1480
}
1740
}
1481
 
1741
 
1482
static bool gen3_composite_channel_set_format(struct sna_composite_channel *channel,
1742
static bool gen3_composite_channel_set_format(struct sna_composite_channel *channel,
1483
					      CARD32 format)
1743
					      CARD32 format)
1484
{
1744
{
1485
	unsigned int i;
1745
	unsigned int i;
1486
 
1746
 
1487
	for (i = 0; i < ARRAY_SIZE(gen3_tex_formats); i++) {
1747
	for (i = 0; i < ARRAY_SIZE(gen3_tex_formats); i++) {
1488
		if (gen3_tex_formats[i].fmt == format) {
1748
		if (gen3_tex_formats[i].fmt == format) {
1489
			channel->card_format = gen3_tex_formats[i].card_fmt;
1749
			channel->card_format = gen3_tex_formats[i].card_fmt;
1490
			channel->rb_reversed = gen3_tex_formats[i].rb_reversed;
1750
			channel->rb_reversed = gen3_tex_formats[i].rb_reversed;
1491
			return true;
1751
			return true;
1492
		}
1752
		}
1493
	}
1753
	}
1494
	return false;
1754
	return false;
1495
}
1755
}
-
 
1756
 
-
 
1757
#if 0
-
 
1758
static int
-
 
1759
gen3_composite_picture(struct sna *sna,
-
 
1760
		       PicturePtr picture,
-
 
1761
		       struct sna_composite_op *op,
-
 
1762
		       struct sna_composite_channel *channel,
-
 
1763
		       int16_t x, int16_t y,
-
 
1764
		       int16_t w, int16_t h,
-
 
1765
		       int16_t dst_x, int16_t dst_y,
-
 
1766
		       bool precise)
-
 
1767
{
-
 
1768
	PixmapPtr pixmap;
-
 
1769
	uint32_t color;
-
 
1770
	int16_t dx, dy;
-
 
1771
 
-
 
1772
	DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
-
 
1773
	     __FUNCTION__, x, y, w, h, dst_x, dst_y));
-
 
1774
 
-
 
1775
	channel->card_format = 0;
-
 
1776
 
-
 
1777
	if (picture->pDrawable == NULL) {
-
 
1778
		SourcePict *source = picture->pSourcePict;
-
 
1779
		int ret = -1;
-
 
1780
 
-
 
1781
		switch (source->type) {
-
 
1782
		case SourcePictTypeSolidFill:
-
 
1783
			DBG(("%s: solid fill [%08x], format %08x\n",
-
 
1784
			     __FUNCTION__,
-
 
1785
			     (unsigned)source->solidFill.color,
-
 
1786
			     (unsigned)picture->format));
-
 
1787
			ret = gen3_init_solid(channel, source->solidFill.color);
-
 
1788
			break;
-
 
1789
 
-
 
1790
		case SourcePictTypeLinear:
-
 
1791
			ret = gen3_init_linear(sna, picture, op, channel,
-
 
1792
					       x - dst_x, y - dst_y);
-
 
1793
			break;
-
 
1794
 
-
 
1795
		case SourcePictTypeRadial:
-
 
1796
			ret = gen3_init_radial(sna, picture, op, channel,
-
 
1797
					       x - dst_x, y - dst_y);
-
 
1798
			break;
-
 
1799
		}
-
 
1800
 
-
 
1801
		if (ret == -1) {
-
 
1802
			if (!precise)
-
 
1803
				ret = sna_render_picture_approximate_gradient(sna, picture, channel,
-
 
1804
									      x, y, w, h, dst_x, dst_y);
-
 
1805
			if (ret == -1)
-
 
1806
				ret = sna_render_picture_fixup(sna, picture, channel,
-
 
1807
							       x, y, w, h, dst_x, dst_y);
-
 
1808
		}
-
 
1809
		return ret;
-
 
1810
	}
-
 
1811
 
-
 
1812
	if (picture->alphaMap) {
-
 
1813
		DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
-
 
1814
		return sna_render_picture_fixup(sna, picture, channel,
-
 
1815
						x, y, w, h, dst_x, dst_y);
-
 
1816
	}
-
 
1817
 
-
 
1818
	if (sna_picture_is_solid(picture, &color)) {
-
 
1819
		DBG(("%s: solid drawable [%08x]\n", __FUNCTION__, color));
-
 
1820
		return gen3_init_solid(channel, color);
-
 
1821
	}
-
 
1822
 
-
 
1823
	if (sna_picture_is_clear(picture, x, y, w, h, &color)) {
-
 
1824
		DBG(("%s: clear drawable [%08x]\n", __FUNCTION__, color));
-
 
1825
		return gen3_init_solid(channel, color_convert(color, picture->format, PICT_a8r8g8b8));
-
 
1826
	}
-
 
1827
 
-
 
1828
	if (!gen3_check_repeat(picture))
-
 
1829
		return sna_render_picture_fixup(sna, picture, channel,
-
 
1830
						x, y, w, h, dst_x, dst_y);
-
 
1831
 
-
 
1832
	if (!gen3_check_filter(picture))
-
 
1833
		return sna_render_picture_fixup(sna, picture, channel,
-
 
1834
						x, y, w, h, dst_x, dst_y);
-
 
1835
 
-
 
1836
	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
-
 
1837
	channel->filter = picture->filter;
-
 
1838
	channel->pict_format = picture->format;
-
 
1839
 
-
 
1840
	pixmap = get_drawable_pixmap(picture->pDrawable);
-
 
1841
	get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy);
-
 
1842
 
-
 
1843
	x += dx + picture->pDrawable->x;
-
 
1844
	y += dy + picture->pDrawable->y;
-
 
1845
 
-
 
1846
	if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
-
 
1847
		DBG(("%s: integer translation (%d, %d), removing\n",
-
 
1848
		     __FUNCTION__, dx, dy));
-
 
1849
		x += dx;
-
 
1850
		y += dy;
-
 
1851
		channel->transform = NULL;
-
 
1852
		channel->filter = PictFilterNearest;
-
 
1853
	} else {
-
 
1854
		channel->transform = picture->transform;
-
 
1855
		channel->is_affine = sna_transform_is_affine(picture->transform);
-
 
1856
	}
-
 
1857
 
-
 
1858
	if (!gen3_composite_channel_set_format(channel, picture->format) &&
-
 
1859
	    !gen3_composite_channel_set_xformat(picture, channel, x, y, w, h))
-
 
1860
		return sna_render_picture_convert(sna, picture, channel, pixmap,
-
 
1861
						  x, y, w, h, dst_x, dst_y,
-
 
1862
						  false);
-
 
1863
	assert(channel->card_format);
-
 
1864
 
-
 
1865
	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
-
 
1866
		DBG(("%s: pixmap too large (%dx%d), extracting (%d, %d)x(%d,%d)\n",
-
 
1867
		     __FUNCTION__,
-
 
1868
		     pixmap->drawable.width, pixmap->drawable.height,
-
 
1869
		     x, y, w, h));
-
 
1870
		return sna_render_picture_extract(sna, picture, channel,
-
 
1871
						  x, y, w, h, dst_x, dst_y);
-
 
1872
	}
-
 
1873
 
-
 
1874
	return sna_render_pixmap_bo(sna, channel, pixmap,
-
 
1875
				    x, y, w, h, dst_x, dst_y);
-
 
1876
}
-
 
1877
 
-
 
1878
static inline bool
-
 
1879
source_use_blt(struct sna *sna, PicturePtr picture)
-
 
1880
{
-
 
1881
	/* If it is a solid, try to use the BLT paths */
-
 
1882
	if (!picture->pDrawable)
-
 
1883
		return picture->pSourcePict->type == SourcePictTypeSolidFill;
-
 
1884
 
-
 
1885
	if (picture->pDrawable->width  == 1 &&
-
 
1886
	    picture->pDrawable->height == 1 &&
-
 
1887
	    picture->repeat)
-
 
1888
		return true;
-
 
1889
 
-
 
1890
	if (too_large(picture->pDrawable->width, picture->pDrawable->height))
-
 
1891
		return true;
-
 
1892
 
-
 
1893
	return !is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER);
-
 
1894
}
-
 
1895
 
-
 
1896
static bool
-
 
1897
try_blt(struct sna *sna,
-
 
1898
	PicturePtr dst,
-
 
1899
	PicturePtr src,
-
 
1900
	int width, int height)
-
 
1901
{
-
 
1902
	if (sna->kgem.mode != KGEM_RENDER) {
-
 
1903
		DBG(("%s: already performing BLT\n", __FUNCTION__));
-
 
1904
		return true;
-
 
1905
	}
-
 
1906
 
-
 
1907
	if (too_large(width, height)) {
-
 
1908
		DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
-
 
1909
		     __FUNCTION__, width, height));
-
 
1910
		return true;
-
 
1911
	}
-
 
1912
 
-
 
1913
	if (too_large(dst->pDrawable->width, dst->pDrawable->height)) {
-
 
1914
		DBG(("%s: target too large for 3D pipe (%d, %d)\n",
-
 
1915
		     __FUNCTION__,
-
 
1916
		     dst->pDrawable->width, dst->pDrawable->height));
-
 
1917
		return true;
-
 
1918
	}
-
 
1919
 
-
 
1920
	/* is the source picture only in cpu memory e.g. a shm pixmap? */
-
 
1921
	return source_use_blt(sna, src);
-
 
1922
}
-
 
1923
#endif
-
 
1924
 
-
 
1925
static void
-
 
1926
gen3_align_vertex(struct sna *sna,
-
 
1927
		  const struct sna_composite_op *op)
-
 
1928
{
-
 
1929
	if (op->floats_per_vertex != sna->render_state.gen3.last_floats_per_vertex) {
-
 
1930
		if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
-
 
1931
			gen3_vertex_finish(sna);
-
 
1932
 
-
 
1933
		DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
-
 
1934
		     sna->render_state.gen3.last_floats_per_vertex,
-
 
1935
		     op->floats_per_vertex,
-
 
1936
		     sna->render.vertex_index,
-
 
1937
		     (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
-
 
1938
		sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
-
 
1939
		sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
-
 
1940
		assert(sna->render.vertex_used < sna->render.vertex_size - op->floats_per_rect);
-
 
1941
		sna->render_state.gen3.last_floats_per_vertex = op->floats_per_vertex;
-
 
1942
	}
-
 
1943
}
-
 
1944
 
-
 
1945
static inline bool is_constant_ps(uint32_t type)
-
 
1946
{
-
 
1947
	switch (type) {
-
 
1948
	case SHADER_NONE: /* be warned! */
-
 
1949
	case SHADER_ZERO:
-
 
1950
	case SHADER_BLACK:
-
 
1951
	case SHADER_WHITE:
-
 
1952
	case SHADER_CONSTANT:
-
 
1953
		return true;
-
 
1954
	default:
-
 
1955
		return false;
-
 
1956
	}
-
 
1957
}
-
 
1958
 
-
 
1959
#if 0
-
 
1960
static bool
-
 
1961
gen3_composite_fallback(struct sna *sna,
-
 
1962
			uint8_t op,
-
 
1963
			PicturePtr src,
-
 
1964
			PicturePtr mask,
-
 
1965
			PicturePtr dst)
-
 
1966
{
-
 
1967
	PixmapPtr src_pixmap;
-
 
1968
	PixmapPtr mask_pixmap;
-
 
1969
	PixmapPtr dst_pixmap;
-
 
1970
	bool src_fallback, mask_fallback;
-
 
1971
 
-
 
1972
	if (!gen3_check_dst_format(dst->format)) {
-
 
1973
		DBG(("%s: unknown destination format: %d\n",
-
 
1974
		     __FUNCTION__, dst->format));
-
 
1975
		return true;
-
 
1976
	}
-
 
1977
 
-
 
1978
	dst_pixmap = get_drawable_pixmap(dst->pDrawable);
-
 
1979
 
-
 
1980
	src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
-
 
1981
	src_fallback = source_fallback(src, src_pixmap,
-
 
1982
				       dst->polyMode == PolyModePrecise);
-
 
1983
 
-
 
1984
	if (mask) {
-
 
1985
		mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL;
-
 
1986
		mask_fallback = source_fallback(mask, mask_pixmap,
-
 
1987
						dst->polyMode == PolyModePrecise);
-
 
1988
	} else {
-
 
1989
		mask_pixmap = NULL;
-
 
1990
		mask_fallback = false;
-
 
1991
	}
-
 
1992
 
-
 
1993
	/* If we are using the destination as a source and need to
-
 
1994
	 * readback in order to upload the source, do it all
-
 
1995
	 * on the cpu.
-
 
1996
	 */
-
 
1997
	if (src_pixmap == dst_pixmap && src_fallback) {
-
 
1998
		DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
-
 
1999
		return true;
-
 
2000
	}
-
 
2001
	if (mask_pixmap == dst_pixmap && mask_fallback) {
-
 
2002
		DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
-
 
2003
		return true;
-
 
2004
	}
-
 
2005
 
-
 
2006
	if (mask &&
-
 
2007
	    mask->componentAlpha && PICT_FORMAT_RGB(mask->format) &&
-
 
2008
	    gen3_blend_op[op].src_alpha &&
-
 
2009
	    gen3_blend_op[op].src_blend != BLENDFACT_ZERO &&
-
 
2010
	    op != PictOpOver) {
-
 
2011
		DBG(("%s: component-alpha mask with op=%d, should fallback\n",
-
 
2012
		     __FUNCTION__, op));
-
 
2013
		return true;
-
 
2014
	}
-
 
2015
 
-
 
2016
	/* If anything is on the GPU, push everything out to the GPU */
-
 
2017
	if (dst_use_gpu(dst_pixmap)) {
-
 
2018
		DBG(("%s: dst is already on the GPU, try to use GPU\n",
-
 
2019
		     __FUNCTION__));
-
 
2020
		return false;
-
 
2021
	}
-
 
2022
 
-
 
2023
	if (src_pixmap && !src_fallback) {
-
 
2024
		DBG(("%s: src is already on the GPU, try to use GPU\n",
-
 
2025
		     __FUNCTION__));
-
 
2026
		return false;
-
 
2027
	}
-
 
2028
	if (mask_pixmap && !mask_fallback) {
-
 
2029
		DBG(("%s: mask is already on the GPU, try to use GPU\n",
-
 
2030
		     __FUNCTION__));
-
 
2031
		return false;
-
 
2032
	}
-
 
2033
 
-
 
2034
	/* However if the dst is not on the GPU and we need to
-
 
2035
	 * render one of the sources using the CPU, we may
-
 
2036
	 * as well do the entire operation in place onthe CPU.
-
 
2037
	 */
-
 
2038
	if (src_fallback) {
-
 
2039
		DBG(("%s: dst is on the CPU and src will fallback\n",
-
 
2040
		     __FUNCTION__));
-
 
2041
		return true;
-
 
2042
	}
-
 
2043
 
-
 
2044
	if (mask && mask_fallback) {
-
 
2045
		DBG(("%s: dst is on the CPU and mask will fallback\n",
-
 
2046
		     __FUNCTION__));
-
 
2047
		return true;
-
 
2048
	}
-
 
2049
 
-
 
2050
	if (too_large(dst_pixmap->drawable.width,
-
 
2051
		      dst_pixmap->drawable.height) &&
-
 
2052
	    dst_is_cpu(dst_pixmap)) {
-
 
2053
		DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__));
-
 
2054
		return true;
-
 
2055
	}
-
 
2056
 
-
 
2057
	DBG(("%s: dst is not on the GPU and the operation should not fallback: use-cpu? %d\n",
-
 
2058
	     __FUNCTION__, dst_use_cpu(dst_pixmap)));
-
 
2059
	return dst_use_cpu(dst_pixmap);
-
 
2060
}
-
 
2061
 
-
 
2062
static bool
-
 
2063
gen3_render_composite(struct sna *sna,
-
 
2064
		      uint8_t op,
-
 
2065
		      PicturePtr src,
-
 
2066
		      PicturePtr mask,
-
 
2067
		      PicturePtr dst,
-
 
2068
		      int16_t src_x,  int16_t src_y,
-
 
2069
		      int16_t mask_x, int16_t mask_y,
-
 
2070
		      int16_t dst_x,  int16_t dst_y,
-
 
2071
		      int16_t width,  int16_t height,
-
 
2072
		      struct sna_composite_op *tmp)
-
 
2073
{
-
 
2074
	DBG(("%s()\n", __FUNCTION__));
-
 
2075
 
-
 
2076
	if (op >= ARRAY_SIZE(gen3_blend_op)) {
-
 
2077
		DBG(("%s: fallback due to unhandled blend op: %d\n",
-
 
2078
		     __FUNCTION__, op));
-
 
2079
		return false;
-
 
2080
	}
-
 
2081
 
-
 
2082
	/* Try to use the BLT engine unless it implies a
-
 
2083
	 * 3D -> 2D context switch.
-
 
2084
	 */
-
 
2085
	if (mask == NULL &&
-
 
2086
	    try_blt(sna, dst, src, width, height) &&
-
 
2087
	    sna_blt_composite(sna,
-
 
2088
			      op, src, dst,
-
 
2089
			      src_x, src_y,
-
 
2090
			      dst_x, dst_y,
-
 
2091
			      width, height,
-
 
2092
			      tmp, false))
-
 
2093
		return true;
-
 
2094
 
-
 
2095
	if (gen3_composite_fallback(sna, op, src, mask, dst))
-
 
2096
		return false;
-
 
2097
 
-
 
2098
	if (need_tiling(sna, width, height))
-
 
2099
		return sna_tiling_composite(op, src, mask, dst,
-
 
2100
					    src_x,  src_y,
-
 
2101
					    mask_x, mask_y,
-
 
2102
					    dst_x,  dst_y,
-
 
2103
					    width,  height,
-
 
2104
					    tmp);
-
 
2105
 
-
 
2106
	if (!gen3_composite_set_target(sna, tmp, dst,
-
 
2107
				       dst_x, dst_y, width, height)) {
-
 
2108
		DBG(("%s: unable to set render target\n",
-
 
2109
		     __FUNCTION__));
-
 
2110
		return false;
-
 
2111
	}
-
 
2112
 
-
 
2113
	tmp->op = op;
-
 
2114
	tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format);
-
 
2115
	if (too_large(tmp->dst.width, tmp->dst.height) ||
-
 
2116
	    !gen3_check_pitch_3d(tmp->dst.bo)) {
-
 
2117
		if (!sna_render_composite_redirect(sna, tmp,
-
 
2118
						   dst_x, dst_y, width, height,
-
 
2119
						   op > PictOpSrc || dst->pCompositeClip->data))
-
 
2120
			return false;
-
 
2121
	}
-
 
2122
 
-
 
2123
	tmp->u.gen3.num_constants = 0;
-
 
2124
	tmp->src.u.gen3.type = SHADER_TEXTURE;
-
 
2125
	tmp->src.is_affine = true;
-
 
2126
	DBG(("%s: preparing source\n", __FUNCTION__));
-
 
2127
	switch (gen3_composite_picture(sna, src, tmp, &tmp->src,
-
 
2128
				       src_x, src_y,
-
 
2129
				       width, height,
-
 
2130
				       dst_x, dst_y,
-
 
2131
				       dst->polyMode == PolyModePrecise)) {
-
 
2132
	case -1:
-
 
2133
		goto cleanup_dst;
-
 
2134
	case 0:
-
 
2135
		tmp->src.u.gen3.type = SHADER_ZERO;
-
 
2136
		break;
-
 
2137
	case 1:
-
 
2138
		if (mask == NULL && tmp->src.bo &&
-
 
2139
		    sna_blt_composite__convert(sna,
-
 
2140
					       dst_x, dst_y, width, height,
-
 
2141
					       tmp))
-
 
2142
			return true;
-
 
2143
 
-
 
2144
		gen3_composite_channel_convert(&tmp->src);
-
 
2145
		break;
-
 
2146
	}
-
 
2147
	DBG(("%s: source type=%d\n", __FUNCTION__, tmp->src.u.gen3.type));
-
 
2148
 
-
 
2149
	tmp->mask.u.gen3.type = SHADER_NONE;
-
 
2150
	tmp->mask.is_affine = true;
-
 
2151
	tmp->need_magic_ca_pass = false;
-
 
2152
	tmp->has_component_alpha = false;
-
 
2153
	if (mask && tmp->src.u.gen3.type != SHADER_ZERO) {
-
 
2154
		if (!reuse_source(sna,
-
 
2155
				  src, &tmp->src, src_x, src_y,
-
 
2156
				  mask, &tmp->mask, mask_x, mask_y)) {
-
 
2157
			tmp->mask.u.gen3.type = SHADER_TEXTURE;
-
 
2158
			DBG(("%s: preparing mask\n", __FUNCTION__));
-
 
2159
			switch (gen3_composite_picture(sna, mask, tmp, &tmp->mask,
-
 
2160
						       mask_x, mask_y,
-
 
2161
						       width,  height,
-
 
2162
						       dst_x,  dst_y,
-
 
2163
						       dst->polyMode == PolyModePrecise)) {
-
 
2164
			case -1:
-
 
2165
				goto cleanup_src;
-
 
2166
			case 0:
-
 
2167
				tmp->mask.u.gen3.type = SHADER_ZERO;
-
 
2168
				break;
-
 
2169
			case 1:
-
 
2170
				gen3_composite_channel_convert(&tmp->mask);
-
 
2171
				break;
-
 
2172
			}
-
 
2173
		}
-
 
2174
		DBG(("%s: mask type=%d\n", __FUNCTION__, tmp->mask.u.gen3.type));
-
 
2175
		if (tmp->mask.u.gen3.type == SHADER_ZERO) {
-
 
2176
			if (tmp->src.bo) {
-
 
2177
				kgem_bo_destroy(&sna->kgem,
-
 
2178
						tmp->src.bo);
-
 
2179
				tmp->src.bo = NULL;
-
 
2180
			}
-
 
2181
			tmp->src.u.gen3.type = SHADER_ZERO;
-
 
2182
			tmp->mask.u.gen3.type = SHADER_NONE;
-
 
2183
		}
-
 
2184
 
-
 
2185
		if (tmp->mask.u.gen3.type != SHADER_NONE) {
-
 
2186
			if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
-
 
2187
				/* Check if it's component alpha that relies on a source alpha
-
 
2188
				 * and on the source value.  We can only get one of those
-
 
2189
				 * into the single source value that we get to blend with.
-
 
2190
				 */
-
 
2191
				DBG(("%s: component-alpha mask: %d\n",
-
 
2192
				     __FUNCTION__, tmp->mask.u.gen3.type));
-
 
2193
				tmp->has_component_alpha = true;
-
 
2194
				if (tmp->mask.u.gen3.type == SHADER_WHITE) {
-
 
2195
					tmp->mask.u.gen3.type = SHADER_NONE;
-
 
2196
					tmp->has_component_alpha = false;
-
 
2197
				} else if (gen3_blend_op[op].src_alpha &&
-
 
2198
					   gen3_blend_op[op].src_blend != BLENDFACT_ZERO) {
-
 
2199
					if (op != PictOpOver)
-
 
2200
						goto cleanup_mask;
-
 
2201
 
-
 
2202
					tmp->need_magic_ca_pass = true;
-
 
2203
					tmp->op = PictOpOutReverse;
-
 
2204
				}
-
 
2205
			} else {
-
 
2206
				if (tmp->mask.is_opaque) {
-
 
2207
					tmp->mask.u.gen3.type = SHADER_NONE;
-
 
2208
				} else if (is_constant_ps(tmp->src.u.gen3.type) &&
-
 
2209
					   is_constant_ps(tmp->mask.u.gen3.type)) {
-
 
2210
					uint32_t v;
-
 
2211
 
-
 
2212
					v = multa(tmp->src.u.gen3.mode,
-
 
2213
						  tmp->mask.u.gen3.mode,
-
 
2214
						  24);
-
 
2215
					v |= multa(tmp->src.u.gen3.mode,
-
 
2216
						   tmp->mask.u.gen3.mode,
-
 
2217
						   16);
-
 
2218
					v |= multa(tmp->src.u.gen3.mode,
-
 
2219
						   tmp->mask.u.gen3.mode,
-
 
2220
						   8);
-
 
2221
					v |= multa(tmp->src.u.gen3.mode,
-
 
2222
						   tmp->mask.u.gen3.mode,
-
 
2223
						   0);
-
 
2224
 
-
 
2225
					DBG(("%s: combining constant source/mask: %x x %x -> %x\n",
-
 
2226
					     __FUNCTION__,
-
 
2227
					     tmp->src.u.gen3.mode,
-
 
2228
					     tmp->mask.u.gen3.mode,
-
 
2229
					     v));
-
 
2230
 
-
 
2231
					tmp->src.u.gen3.type = SHADER_CONSTANT;
-
 
2232
					tmp->src.u.gen3.mode = v;
-
 
2233
					tmp->src.is_opaque = false;
-
 
2234
 
-
 
2235
					tmp->mask.u.gen3.type = SHADER_NONE;
-
 
2236
				}
-
 
2237
			}
-
 
2238
		}
-
 
2239
	}
-
 
2240
	DBG(("%s: final src/mask type=%d/%d, affine=%d/%d\n", __FUNCTION__,
-
 
2241
	     tmp->src.u.gen3.type, tmp->mask.u.gen3.type,
-
 
2242
	     tmp->src.is_affine, tmp->mask.is_affine));
-
 
2243
 
-
 
2244
	tmp->prim_emit = gen3_emit_composite_primitive;
-
 
2245
	if (is_constant_ps(tmp->mask.u.gen3.type)) {
-
 
2246
		switch (tmp->src.u.gen3.type) {
-
 
2247
		case SHADER_NONE:
-
 
2248
		case SHADER_ZERO:
-
 
2249
		case SHADER_BLACK:
-
 
2250
		case SHADER_WHITE:
-
 
2251
		case SHADER_CONSTANT:
-
 
2252
#if defined(sse2) && !defined(__x86_64__)
-
 
2253
			if (sna->cpu_features & SSE2) {
-
 
2254
				tmp->prim_emit = gen3_emit_composite_primitive_constant__sse2;
-
 
2255
				tmp->emit_boxes = gen3_emit_composite_boxes_constant__sse2;
-
 
2256
			} else
-
 
2257
#endif
-
 
2258
			{
-
 
2259
				tmp->prim_emit = gen3_emit_composite_primitive_constant;
-
 
2260
				tmp->emit_boxes = gen3_emit_composite_boxes_constant;
-
 
2261
			}
-
 
2262
 
-
 
2263
			break;
-
 
2264
		case SHADER_LINEAR:
-
 
2265
		case SHADER_RADIAL:
-
 
2266
			if (tmp->src.transform == NULL) {
-
 
2267
#if defined(sse2) && !defined(__x86_64__)
-
 
2268
				if (sna->cpu_features & SSE2) {
-
 
2269
					tmp->prim_emit = gen3_emit_composite_primitive_identity_gradient__sse2;
-
 
2270
					tmp->emit_boxes = gen3_emit_composite_boxes_identity_gradient__sse2;
-
 
2271
				} else
-
 
2272
#endif
-
 
2273
				{
-
 
2274
					tmp->prim_emit = gen3_emit_composite_primitive_identity_gradient;
-
 
2275
					tmp->emit_boxes = gen3_emit_composite_boxes_identity_gradient;
-
 
2276
				}
-
 
2277
			} else if (tmp->src.is_affine) {
-
 
2278
				tmp->src.scale[1] = tmp->src.scale[0] = 1. / tmp->src.transform->matrix[2][2];
-
 
2279
#if defined(sse2) && !defined(__x86_64__)
-
 
2280
				if (sna->cpu_features & SSE2) {
-
 
2281
					tmp->prim_emit = gen3_emit_composite_primitive_affine_gradient__sse2;
-
 
2282
					tmp->emit_boxes = gen3_emit_composite_boxes_affine_gradient__sse2;
-
 
2283
				} else
-
 
2284
#endif
-
 
2285
				{
-
 
2286
					tmp->prim_emit = gen3_emit_composite_primitive_affine_gradient;
-
 
2287
					tmp->emit_boxes = gen3_emit_composite_boxes_affine_gradient;
-
 
2288
				}
-
 
2289
			}
-
 
2290
			break;
-
 
2291
		case SHADER_TEXTURE:
-
 
2292
			if (tmp->src.transform == NULL) {
-
 
2293
				if ((tmp->src.offset[0]|tmp->src.offset[1]|tmp->dst.x|tmp->dst.y) == 0) {
-
 
2294
#if defined(sse2) && !defined(__x86_64__)
-
 
2295
					if (sna->cpu_features & SSE2) {
-
 
2296
						tmp->prim_emit = gen3_emit_composite_primitive_identity_source_no_offset__sse2;
-
 
2297
						tmp->emit_boxes = gen3_emit_composite_boxes_identity_source_no_offset__sse2;
-
 
2298
					} else
-
 
2299
#endif
-
 
2300
					{
-
 
2301
						tmp->prim_emit = gen3_emit_composite_primitive_identity_source_no_offset;
-
 
2302
						tmp->emit_boxes = gen3_emit_composite_boxes_identity_source_no_offset;
-
 
2303
					}
-
 
2304
				} else {
-
 
2305
#if defined(sse2) && !defined(__x86_64__)
-
 
2306
					if (sna->cpu_features & SSE2) {
-
 
2307
						tmp->prim_emit = gen3_emit_composite_primitive_identity_source__sse2;
-
 
2308
						tmp->emit_boxes = gen3_emit_composite_boxes_identity_source__sse2;
-
 
2309
					} else
-
 
2310
#endif
-
 
2311
					{
-
 
2312
						tmp->prim_emit = gen3_emit_composite_primitive_identity_source;
-
 
2313
						tmp->emit_boxes = gen3_emit_composite_boxes_identity_source;
-
 
2314
					}
-
 
2315
				}
-
 
2316
			} else if (tmp->src.is_affine) {
-
 
2317
				tmp->src.scale[0] /= tmp->src.transform->matrix[2][2];
-
 
2318
				tmp->src.scale[1] /= tmp->src.transform->matrix[2][2];
-
 
2319
#if defined(sse2) && !defined(__x86_64__)
-
 
2320
				if (sna->cpu_features & SSE2) {
-
 
2321
					tmp->prim_emit = gen3_emit_composite_primitive_affine_source__sse2;
-
 
2322
					tmp->emit_boxes = gen3_emit_composite_boxes_affine_source__sse2;
-
 
2323
				} else
-
 
2324
#endif
-
 
2325
				{
-
 
2326
					tmp->prim_emit = gen3_emit_composite_primitive_affine_source;
-
 
2327
					tmp->emit_boxes = gen3_emit_composite_boxes_affine_source;
-
 
2328
				}
-
 
2329
			}
-
 
2330
			break;
-
 
2331
		}
-
 
2332
	} else if (tmp->mask.u.gen3.type == SHADER_TEXTURE) {
-
 
2333
		if (tmp->mask.transform == NULL) {
-
 
2334
			if (is_constant_ps(tmp->src.u.gen3.type)) {
-
 
2335
				if ((tmp->mask.offset[0]|tmp->mask.offset[1]|tmp->dst.x|tmp->dst.y) == 0) {
-
 
2336
#if defined(sse2) && !defined(__x86_64__)
-
 
2337
					if (sna->cpu_features & SSE2) {
-
 
2338
						tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask_no_offset__sse2;
-
 
2339
					} else
-
 
2340
#endif
-
 
2341
					{
-
 
2342
						tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask_no_offset;
-
 
2343
					}
-
 
2344
				} else {
-
 
2345
#if defined(sse2) && !defined(__x86_64__)
-
 
2346
					if (sna->cpu_features & SSE2) {
-
 
2347
						tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask__sse2;
-
 
2348
					} else
-
 
2349
#endif
1496
 
-
 
1497
 
2350
					{
1498
 
2351
						tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask;
1499
 
-
 
1500
 
-
 
1501
 
-
 
1502
 
2352
					}
-
 
2353
				}
1503
 
2354
			} else if (tmp->src.transform == NULL) {
1504
 
2355
#if defined(sse2) && !defined(__x86_64__)
1505
 
2356
				if (sna->cpu_features & SSE2) {
1506
 
2357
					tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask__sse2;
1507
 
2358
				} else
1508
 
-
 
1509
 
2359
#endif
1510
 
2360
				{
1511
 
2361
					tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask;
1512
 
2362
				}
1513
 
2363
			} else if (tmp->src.is_affine) {
-
 
2364
				tmp->src.scale[0] /= tmp->src.transform->matrix[2][2];
1514
 
2365
				tmp->src.scale[1] /= tmp->src.transform->matrix[2][2];
1515
 
2366
#if defined(sse2) && !defined(__x86_64__)
1516
 
2367
				if (sna->cpu_features & SSE2) {
1517
 
2368
					tmp->prim_emit = gen3_emit_composite_primitive_affine_source_mask__sse2;
1518
 
2369
				} else
1519
 
2370
#endif
1520
 
2371
				{
1521
 
2372
					tmp->prim_emit = gen3_emit_composite_primitive_affine_source_mask;
1522
 
2373
				}
1523
 
2374
			}
1524
 
2375
		}
1525
 
2376
	}
1526
 
2377
 
1527
 
2378
	tmp->floats_per_vertex = 2;
1528
 
2379
	if (!is_constant_ps(tmp->src.u.gen3.type))
1529
 
2380
		tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 4;
1530
 
2381
	if (!is_constant_ps(tmp->mask.u.gen3.type))
1531
 
2382
		tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 4;
1532
 
2383
	DBG(("%s: floats_per_vertex = 2 + %d + %d = %d [specialised emitter? %d]\n", __FUNCTION__,
1533
 
2384
	     !is_constant_ps(tmp->src.u.gen3.type) ? tmp->src.is_affine ? 2 : 4 : 0,
1534
 
2385
	     !is_constant_ps(tmp->mask.u.gen3.type) ? tmp->mask.is_affine ? 2 : 4 : 0,
1535
 
2386
	     tmp->floats_per_vertex,
1536
 
2387
	     tmp->prim_emit != gen3_emit_composite_primitive));
1537
 
2388
	tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
1538
 
2389
 
1539
 
2390
	tmp->blt   = gen3_render_composite_blt;
1540
 
2391
	tmp->box   = gen3_render_composite_box;
1541
 
2392
	tmp->boxes = gen3_render_composite_boxes__blt;
1542
 
2393
	if (tmp->emit_boxes) {
1543
 
2394
		tmp->boxes = gen3_render_composite_boxes;
1544
 
2395
		tmp->thread_boxes = gen3_render_composite_boxes__thread;
1545
 
2396
	}
1546
 
2397
	tmp->done  = gen3_render_composite_done;
1547
 
2398
 
1548
 
2399
	if (!kgem_check_bo(&sna->kgem,
1549
 
2400
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
1550
 
2401
			   NULL)) {
1551
 
2402
		kgem_submit(&sna->kgem);
1552
 
2403
		if (!kgem_check_bo(&sna->kgem,
1553
 
2404
				   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
1554
 
2405
				   NULL))
1555
static void
2406
			goto cleanup_mask;
1556
gen3_align_vertex(struct sna *sna,
2407
	}
1557
		  const struct sna_composite_op *op)
2408
 
1558
{
2409
	gen3_emit_composite_state(sna, tmp);
1559
	if (op->floats_per_vertex != sna->render_state.gen3.last_floats_per_vertex) {
2410
	gen3_align_vertex(sna, tmp);
1560
		if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
2411
	return true;
1561
			gen3_vertex_finish(sna);
2412
 
1562
 
2413
cleanup_mask:
1563
		DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
2414
	if (tmp->mask.bo)
1564
		     sna->render_state.gen3.last_floats_per_vertex,
2415
		kgem_bo_destroy(&sna->kgem, tmp->mask.bo);
1565
		     op->floats_per_vertex,
2416
cleanup_src:
1566
		     sna->render.vertex_index,
2417
	if (tmp->src.bo)
1567
		     (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
2418
		kgem_bo_destroy(&sna->kgem, tmp->src.bo);
1568
		sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
2419
cleanup_dst:
1569
		sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
2420
	if (tmp->redirect.real_bo)
1570
		assert(sna->render.vertex_used < sna->render.vertex_size - op->floats_per_rect);
2421
		kgem_bo_destroy(&sna->kgem, tmp->dst.bo);
1571
		sna->render_state.gen3.last_floats_per_vertex = op->floats_per_vertex;
2422
	return false;
1572
	}
2423
}
1573
}
2424
#endif
1574
 
2425
 
1575
 
2426
 
1576
 
2427
 
1577
 
2428
 
1578
 
2429
 
1579
 
2430
 
1580
 
2431
 
1581
 
2432
 
1582
 
2433
 
1583
 
2434
 
1584
 
2435
 
1585
 
2436
 
1586
 
2437
 
1587
 
2438
 
1588
 
2439
 
1589
 
2440
 
1590
 
2441
 
1591
 
2442
 
1592
 
2443
 
1593
 
2444
 
1594
 
2445
 
1595
 
2446
 
1596
 
2447
 
1597
 
2448
 
1598
 
2449
 
1599
 
2450
 
1600
 
2451
 
1601
 
2452
 
1602
 
2453
 
1603
 
2454
 
1604
 
2455
 
1605
 
2456
 
1606
 
2457
 
1607
 
2458
 
1608
 
2459
 
1609
 
2460
 
1610
 
2461
 
1611
 
2462
 
1612
 
2463
 
1613
 
2464
 
1614
 
2465
 
1615
 
2466
 
1616
 
2467
 
1617
 
2468
 
1618
 
2469
 
1619
 
2470
 
1620
 
2471
 
1621
 
2472
 
1622
 
2473
 
1623
 
2474
 
1624
 
2475
 
1625
 
2476
 
1626
 
2477
 
1627
 
2478
 
1628
 
2479
 
1629
 
2480
 
1630
 
2481
 
1631
 
2482
 
1632
 
2483
 
1633
 
2484
 
1634
 
2485
 
1635
 
2486
 
1636
 
2487
 
1637
 
2488
 
1638
 
2489
 
1639
 
2490
 
1640
 
2491
 
1641
 
2492
 
1642
 
2493
 
1643
 
2494
 
1644
 
2495
 
1645
 
2496
 
1646
 
2497
 
1647
 
2498
 
1648
 
2499
 
1649
 
2500
 
1650
 
2501
 
1651
 
2502
 
1652
 
2503
 
1653
 
2504
 
1654
 
2505
 
1655
 
2506
 
1656
 
2507
 
1657
 
2508
 
1658
 
2509
 
1659
 
2510
 
1660
 
2511
 
1661
 
2512
 
1662
 
2513
 
1663
 
2514
 
1664
 
2515
 
1665
 
2516
 
1666
 
2517
 
1667
 
2518
 
1668
 
2519
 
1669
 
2520
 
1670
 
2521
 
1671
 
2522
 
1672
 
2523
 
1673
 
2524
 
1674
 
2525
 
1675
 
2526
 
1676
 
2527
 
1677
 
2528
 
1678
 
2529
 
1679
 
2530
 
1680
 
2531
 
1681
 
2532
 
1682
 
2533
 
1683
 
2534
 
1684
 
2535
 
1685
 
2536
 
1686
 
2537
 
1687
 
2538
 
1688
 
2539
 
1689
 
2540
 
1690
 
2541
 
1691
 
2542
 
1692
 
2543
 
1693
 
2544
 
1694
 
2545
 
1695
 
2546
 
1696
 
2547
 
1697
 
2548
 
1698
 
2549
 
1699
 
2550
 
1700
 
2551
 
1701
 
2552
 
1702
 
2553
 
1703
 
2554
 
1704
 
2555
 
1705
 
2556
 
1706
 
2557
 
1707
 
2558
 
1708
 
2559
 
1709
 
2560
 
1710
 
2561
 
1711
 
2562
 
1712
 
-
 
1713
static inline bool is_constant_ps(uint32_t type)
-
 
1714
{
-
 
1715
	switch (type) {
-
 
1716
	case SHADER_NONE: /* be warned! */
-
 
1717
	case SHADER_ZERO:
-
 
1718
	case SHADER_BLACK:
-
 
1719
	case SHADER_WHITE:
-
 
1720
	case SHADER_CONSTANT:
-
 
1721
		return true;
-
 
1722
	default:
-
 
1723
		return false;
-
 
1724
	}
-
 
1725
}
2563
 
1726
 
2564
 
1727
 
2565
 
1728
 
2566
 
1729
 
2567
 
1730
 
2568
 
1731
 
2569
 
1732
 
2570
 
1733
 
2571
 
1734
 
2572
 
1735
 
2573
 
1736
 
2574
 
1737
 
2575
 
1738
 
2576
 
1739
 
2577
 
1740
 
2578
 
1741
 
2579
 
1742
 
2580
 
1743
 
2581
 
1744
 
2582
 
1745
 
2583
 
1746
 
2584
 
1747
 
2585
 
1748
 
2586
 
1749
 
2587
 
1750
 
2588
 
1751
 
2589
 
1752
 
2590
 
1753
 
2591
 
1754
 
2592
 
1755
 
2593
 
1756
 
2594
 
1757
 
2595
 
1758
 
2596
 
1759
 
2597
 
1760
 
2598
 
1761
 
2599
 
1762
 
2600
 
1763
 
2601
 
1764
 
2602
 
1765
 
2603
 
1766
 
2604
 
1767
 
2605
 
1768
 
2606
 
1769
 
2607
 
1770
 
2608
 
1771
 
2609
 
1772
 
2610
 
1773
 
2611
 
1774
 
2612
 
1775
 
2613
 
1776
 
2614
 
1777
 
2615
 
1778
 
2616
 
1779
 
2617
 
1780
 
2618
 
1781
 
2619
 
1782
 
2620
 
1783
 
2621
 
1784
 
2622
 
1785
 
2623
 
1786
 
2624
 
1787
 
2625
 
1788
 
2626
 
1789
 
2627
 
1790
 
2628
 
1791
 
2629
 
1792
 
2630
 
1793
 
2631
 
1794
 
2632
 
1795
 
2633
 
1796
 
2634
 
1797
 
2635
 
1798
 
2636
 
1799
 
2637
 
1800
 
2638
 
1801
 
2639
 
1802
 
2640
 
1803
 
2641
 
1804
 
2642
 
1805
 
2643
 
1806
 
2644
 
1807
 
2645
 
1808
 
2646
 
1809
 
2647
 
1810
 
2648
 
1811
 
2649
 
1812
 
2650
 
1813
 
2651
 
1814
 
2652
 
1815
 
2653
 
1816
 
2654
 
1817
 
2655
 
1818
 
2656
 
1819
 
2657
 
1820
 
2658
 
1821
 
2659
 
-
 
2660
 
-
 
2661
static void gen3_render_flush(struct sna *sna)
-
 
2662
{
-
 
2663
	gen3_vertex_close(sna);
-
 
2664
 
-
 
2665
	assert(sna->render.vertex_reloc[0] == 0);
-
 
2666
	assert(sna->render.vertex_offset == 0);
-
 
2667
}
-
 
2668
 
-
 
2669
static void
-
 
2670
gen3_render_fini(struct sna *sna)
-
 
2671
{
-
 
2672
}
-
 
2673
 
-
 
2674
const char *gen3_render_init(struct sna *sna, const char *backend)
-
 
2675
{
-
 
2676
	struct sna_render *render = &sna->render;
-
 
2677
 
-
 
2678
#if 0
-
 
2679
#if !NO_COMPOSITE
-
 
2680
	render->composite = gen3_render_composite;
-
 
2681
	render->prefer_gpu |= PREFER_GPU_RENDER;
-
 
2682
#endif
-
 
2683
#if !NO_COMPOSITE_SPANS
-
 
2684
	render->check_composite_spans = gen3_check_composite_spans;
-
 
2685
	render->composite_spans = gen3_render_composite_spans;
-
 
2686
	render->prefer_gpu |= PREFER_GPU_SPANS;
-
 
2687
#endif
-
 
2688
 
-
 
2689
	render->video = gen3_render_video;
-
 
2690
 
-
 
2691
	render->copy_boxes = gen3_render_copy_boxes;
-
 
2692
	render->copy = gen3_render_copy;
-
 
2693
 
-
 
2694
	render->fill_boxes = gen3_render_fill_boxes;
-
 
2695
	render->fill = gen3_render_fill;
-
 
2696
	render->fill_one = gen3_render_fill_one;
-
 
2697
#endif
-
 
2698
 
-
 
2699
    render->blit_tex = gen3_blit_tex;
-
 
2700
    render->caps = HW_BIT_BLIT | HW_TEX_BLIT;
1822
 
2701
 
1823
 
2702
	render->reset = gen3_render_reset;
1824
 
2703
	render->flush = gen3_render_flush;
1825
 
2704
	render->fini = gen3_render_fini;
1826
 
2705
 
1827
 
2706
	render->max_3d_size = MAX_3D_SIZE;
1828
 
2707
	render->max_3d_pitch = MAX_3D_PITCH;
1829
 
2708
 
1830
 
2709
	sna->kgem.retire = gen3_render_retire;
1831
 
2710
	sna->kgem.expire = gen3_render_expire;
1832
 
2711
	return "Alviso (gen3)";
1833
 
2712
}
1834
 
2713
 
1835
static bool
2714
static bool
1836
gen3_blit_tex(struct sna *sna,
2715
gen3_blit_tex(struct sna *sna,
1837
              uint8_t op, bool scale,
2716
              uint8_t op, bool scale,
1838
		      PixmapPtr src, struct kgem_bo *src_bo,
2717
		      PixmapPtr src, struct kgem_bo *src_bo,
1839
		      PixmapPtr mask,struct kgem_bo *mask_bo,
2718
		      PixmapPtr mask,struct kgem_bo *mask_bo,
1840
		      PixmapPtr dst, struct kgem_bo *dst_bo,
2719
		      PixmapPtr dst, struct kgem_bo *dst_bo,
1841
              int32_t src_x, int32_t src_y,
2720
              int32_t src_x, int32_t src_y,
1842
              int32_t msk_x, int32_t msk_y,
2721
              int32_t msk_x, int32_t msk_y,
1843
              int32_t dst_x, int32_t dst_y,
2722
              int32_t dst_x, int32_t dst_y,
1844
              int32_t width, int32_t height,
2723
              int32_t width, int32_t height,
1845
              struct sna_composite_op *tmp)
2724
              struct sna_composite_op *tmp)
1846
{
2725
{
1847
 
2726
 
1848
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
2727
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
1849
         width, height, sna->kgem.ring));
2728
         width, height, sna->kgem.ring));
1850
 
2729
 
1851
    tmp->op = PictOpSrc;
2730
    tmp->op = PictOpSrc;
1852
 
2731
 
1853
    tmp->dst.pixmap = dst;
2732
    tmp->dst.pixmap = dst;
1854
    tmp->dst.bo     = dst_bo;
2733
    tmp->dst.bo     = dst_bo;
1855
    tmp->dst.width  = dst->drawable.width;
2734
    tmp->dst.width  = dst->drawable.width;
1856
    tmp->dst.height = dst->drawable.height;
2735
    tmp->dst.height = dst->drawable.height;
1857
    tmp->dst.format = PICT_x8r8g8b8;
2736
    tmp->dst.format = PICT_x8r8g8b8;
1858
 
2737
 
1859
	tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format);
2738
	tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format);
1860
 
2739
 
1861
	tmp->u.gen3.num_constants = 0;
2740
	tmp->u.gen3.num_constants = 0;
1862
	tmp->src.u.gen3.type = SHADER_TEXTURE;
2741
	tmp->src.u.gen3.type = SHADER_TEXTURE;
1863
	tmp->src.is_affine = true;
2742
	tmp->src.is_affine = true;
1864
 
2743
 
1865
 
2744
 
1866
	tmp->src.repeat = RepeatNone;
2745
	tmp->src.repeat = RepeatNone;
1867
	tmp->src.filter = PictFilterNearest;
2746
	tmp->src.filter = PictFilterNearest;
1868
 
2747
 
1869
    tmp->src.bo = src_bo;
2748
    tmp->src.bo = src_bo;
1870
	tmp->src.pict_format = PICT_x8r8g8b8;
2749
	tmp->src.pict_format = PICT_x8r8g8b8;
1871
 
2750
 
1872
	gen3_composite_channel_set_format(&tmp->src, tmp->src.pict_format);
2751
	gen3_composite_channel_set_format(&tmp->src, tmp->src.pict_format);
1873
 
2752
 
1874
    tmp->src.width  = src->drawable.width;
2753
    tmp->src.width  = src->drawable.width;
1875
    tmp->src.height = src->drawable.height;
2754
    tmp->src.height = src->drawable.height;
1876
 
2755
 
1877
	tmp->mask.u.gen3.type = SHADER_TEXTURE;
2756
	tmp->mask.u.gen3.type = SHADER_TEXTURE;
1878
	tmp->mask.is_affine = true;
2757
	tmp->mask.is_affine = true;
1879
	tmp->need_magic_ca_pass = false;
2758
	tmp->need_magic_ca_pass = false;
1880
	tmp->has_component_alpha = false;
2759
	tmp->has_component_alpha = false;
1881
 
2760
 
1882
 
2761
 
1883
 	tmp->mask.repeat = RepeatNone;
2762
 	tmp->mask.repeat = RepeatNone;
1884
	tmp->mask.filter = PictFilterNearest;
2763
	tmp->mask.filter = PictFilterNearest;
1885
    tmp->mask.is_affine = true;
2764
    tmp->mask.is_affine = true;
1886
 
2765
 
1887
    tmp->mask.bo = mask_bo;
2766
    tmp->mask.bo = mask_bo;
1888
    tmp->mask.pict_format = PIXMAN_a8;
2767
    tmp->mask.pict_format = PIXMAN_a8;
1889
	gen3_composite_channel_set_format(&tmp->mask, tmp->mask.pict_format);
2768
	gen3_composite_channel_set_format(&tmp->mask, tmp->mask.pict_format);
1890
    tmp->mask.width  = mask->drawable.width;
2769
    tmp->mask.width  = mask->drawable.width;
1891
    tmp->mask.height = mask->drawable.height;
2770
    tmp->mask.height = mask->drawable.height;
1892
 
2771
 
1893
    if( scale )
2772
    if( scale )
1894
    {
2773
    {
1895
        tmp->src.scale[0] = 1.f/width;
2774
        tmp->src.scale[0] = 1.f/width;
1896
        tmp->src.scale[1] = 1.f/height;
2775
        tmp->src.scale[1] = 1.f/height;
1897
    }
2776
    }
1898
    else
2777
    else
1899
    {
2778
    {
1900
        tmp->src.scale[0] = 1.f/src->drawable.width;
2779
        tmp->src.scale[0] = 1.f/src->drawable.width;
1901
        tmp->src.scale[1] = 1.f/src->drawable.height;
2780
        tmp->src.scale[1] = 1.f/src->drawable.height;
1902
    }
2781
    }
1903
 
2782
 
1904
    tmp->mask.scale[0] = 1.f/mask->drawable.width;
2783
    tmp->mask.scale[0] = 1.f/mask->drawable.width;
1905
    tmp->mask.scale[1] = 1.f/mask->drawable.height;
2784
    tmp->mask.scale[1] = 1.f/mask->drawable.height;
1906
 
2785
 
1907
	tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask;
2786
	tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask;
1908
 
2787
 
1909
 
2788
 
1910
	tmp->floats_per_vertex = 2;
2789
	tmp->floats_per_vertex = 2;
1911
	if (!is_constant_ps(tmp->src.u.gen3.type))
2790
	if (!is_constant_ps(tmp->src.u.gen3.type))
1912
		tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 4;
2791
		tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 4;
1913
	if (!is_constant_ps(tmp->mask.u.gen3.type))
2792
	if (!is_constant_ps(tmp->mask.u.gen3.type))
1914
		tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 4;
2793
		tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 4;
1915
//	DBG(("%s: floats_per_vertex = 2 + %d + %d = %d [specialised emitter? %d]\n", __FUNCTION__,
2794
//	DBG(("%s: floats_per_vertex = 2 + %d + %d = %d [specialised emitter? %d]\n", __FUNCTION__,
1916
//	     !is_constant_ps(tmp->src.u.gen3.type) ? tmp->src.is_affine ? 2 : 4 : 0,
2795
//	     !is_constant_ps(tmp->src.u.gen3.type) ? tmp->src.is_affine ? 2 : 4 : 0,
1917
//	     !is_constant_ps(tmp->mask.u.gen3.type) ? tmp->mask.is_affine ? 2 : 4 : 0,
2796
//	     !is_constant_ps(tmp->mask.u.gen3.type) ? tmp->mask.is_affine ? 2 : 4 : 0,
1918
//	     tmp->floats_per_vertex,
2797
//	     tmp->floats_per_vertex,
1919
//	     tmp->prim_emit != gen3_emit_composite_primitive));
2798
//	     tmp->prim_emit != gen3_emit_composite_primitive));
1920
	tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
2799
	tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
1921
 
2800
 
1922
	tmp->blt   = gen3_render_composite_blt;
2801
	tmp->blt   = gen3_render_composite_blt;
1923
 
2802
 
1924
	tmp->done  = gen3_render_composite_done;
2803
	tmp->done  = gen3_render_composite_done;
1925
 
2804
 
1926
	if (!kgem_check_bo(&sna->kgem,
2805
	if (!kgem_check_bo(&sna->kgem,
1927
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
2806
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
1928
			   NULL)) {
2807
			   NULL)) {
1929
		kgem_submit(&sna->kgem);
2808
		kgem_submit(&sna->kgem);
1930
	}
2809
	}
1931
 
2810
 
1932
	gen3_emit_composite_state(sna, tmp);
2811
	gen3_emit_composite_state(sna, tmp);
1933
	gen3_align_vertex(sna, tmp);
2812
	gen3_align_vertex(sna, tmp);
1934
	return true;
2813
	return true;
1935
}
-
 
1936
 
-
 
1937
static void gen3_render_flush(struct sna *sna)
-
 
1938
{
-
 
1939
	gen3_vertex_close(sna);
-
 
1940
 
-
 
1941
	assert(sna->render.vertex_reloc[0] == 0);
-
 
1942
	assert(sna->render.vertex_offset == 0);
-
 
1943
}
-
 
1944
 
-
 
1945
static void
-
 
1946
gen3_render_fini(struct sna *sna)
-
 
1947
{
-
 
1948
}
-
 
1949
 
-
 
1950
bool gen3_render_init(struct sna *sna)
-
 
1951
{
-
 
1952
	struct sna_render *render = &sna->render;
-
 
1953
 
-
 
1954
 
-
 
1955
//	render->video = gen3_render_video;
-
 
1956
 
-
 
1957
    render->blit_tex = gen3_blit_tex;
-
 
1958
 
-
 
1959
	render->reset = gen3_render_reset;
-
 
1960
	render->flush = gen3_render_flush;
-
 
1961
	render->fini = gen3_render_fini;
-
 
1962
 
-
 
1963
	render->max_3d_size = MAX_3D_SIZE;
-
 
1964
	render->max_3d_pitch = MAX_3D_PITCH;
-
 
1965
 
-
 
1966
    render->caps = HW_BIT_BLIT | HW_TEX_BLIT;
-
 
1967
 
-
 
1968
	sna->kgem.retire = gen3_render_retire;
-
 
1969
	sna->kgem.expire = gen3_render_expire;
-
 
1970
	return true;
-
 
1971
}
2814
}
1972
 
2815
 
1973
static>
2816
static>
1974
 
2817
 
1975
static>
2818
static>
1976
#define>
2819
#define>
1977
#define>
2820
#define>