Subversion Repositories Kolibri OS

Rev

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

Rev 4251 Rev 4281
1
/*
1
/*
2
 * Copyright © 2006,2008,2011 Intel Corporation
2
 * Copyright © 2006,2008,2011 Intel Corporation
3
 * Copyright © 2007 Red Hat, Inc.
3
 * Copyright © 2007 Red Hat, Inc.
4
 *
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
11
 *
12
 * The above copyright notice and this permission notice (including the next
12
 * The above copyright notice and this permission notice (including the next
13
 * paragraph) shall be included in all copies or substantial portions of the
13
 * paragraph) shall be included in all copies or substantial portions of the
14
 * Software.
14
 * Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 * SOFTWARE.
22
 * SOFTWARE.
23
 *
23
 *
24
 * Authors:
24
 * Authors:
25
 *    Wang Zhenyu 
25
 *    Wang Zhenyu 
26
 *    Eric Anholt 
26
 *    Eric Anholt 
27
 *    Carl Worth 
27
 *    Carl Worth 
28
 *    Keith Packard 
28
 *    Keith Packard 
29
 *    Chris Wilson 
29
 *    Chris Wilson 
30
 *
30
 *
31
 */
31
 */
32
 
32
 
33
 
33
 
34
#include "sna.h"
34
#include "sna.h"
35
#include "sna_reg.h"
35
#include "sna_reg.h"
36
#include "sna_render.h"
36
#include "sna_render.h"
37
#include "sna_render_inline.h"
37
#include "sna_render_inline.h"
38
//#include "sna_video.h"
38
//#include "sna_video.h"
39
 
39
 
40
#include "brw/brw.h"
40
#include "brw/brw.h"
41
#include "gen6_render.h"
41
#include "gen6_render.h"
42
#include "gen4_source.h"
42
#include "gen4_source.h"
43
#include "gen4_vertex.h"
43
#include "gen4_vertex.h"
44
 
44
 
45
#define NO_COMPOSITE 0
45
#define NO_COMPOSITE 0
46
#define NO_COMPOSITE_SPANS 0
46
#define NO_COMPOSITE_SPANS 0
47
#define NO_COPY 0
47
#define NO_COPY 0
48
#define NO_COPY_BOXES 0
48
#define NO_COPY_BOXES 0
49
#define NO_FILL 0
49
#define NO_FILL 0
50
#define NO_FILL_BOXES 0
50
#define NO_FILL_BOXES 0
51
#define NO_FILL_ONE 0
51
#define NO_FILL_ONE 0
52
#define NO_FILL_CLEAR 0
52
#define NO_FILL_CLEAR 0
53
 
53
 
54
#define NO_RING_SWITCH 0
54
#define NO_RING_SWITCH 0
55
#define PREFER_RENDER 0
55
#define PREFER_RENDER 0
56
 
56
 
57
#define USE_8_PIXEL_DISPATCH 1
57
#define USE_8_PIXEL_DISPATCH 1
58
#define USE_16_PIXEL_DISPATCH 1
58
#define USE_16_PIXEL_DISPATCH 1
59
#define USE_32_PIXEL_DISPATCH 0
59
#define USE_32_PIXEL_DISPATCH 0
60
 
60
 
61
#if !USE_8_PIXEL_DISPATCH && !USE_16_PIXEL_DISPATCH && !USE_32_PIXEL_DISPATCH
61
#if !USE_8_PIXEL_DISPATCH && !USE_16_PIXEL_DISPATCH && !USE_32_PIXEL_DISPATCH
62
#error "Must select at least 8, 16 or 32 pixel dispatch"
62
#error "Must select at least 8, 16 or 32 pixel dispatch"
63
#endif
63
#endif
64
 
64
 
65
#define GEN6_MAX_SIZE 8192
65
#define GEN6_MAX_SIZE 8192
66
 
66
 
67
struct gt_info {
67
struct gt_info {
68
	const char *name;
68
	const char *name;
69
	int max_vs_threads;
69
	int max_vs_threads;
70
	int max_gs_threads;
70
	int max_gs_threads;
71
	int max_wm_threads;
71
	int max_wm_threads;
72
	struct {
72
	struct {
73
		int size;
73
		int size;
74
		int max_vs_entries;
74
		int max_vs_entries;
75
		int max_gs_entries;
75
		int max_gs_entries;
76
	} urb;
76
	} urb;
77
};
77
};
78
 
78
 
79
static const struct gt_info gt1_info = {
79
static const struct gt_info gt1_info = {
80
	.name = "Sandybridge (gen6, gt1)",
80
	.name = "Sandybridge (gen6, gt1)",
81
	.max_vs_threads = 24,
81
	.max_vs_threads = 24,
82
	.max_gs_threads = 21,
82
	.max_gs_threads = 21,
83
	.max_wm_threads = 40,
83
	.max_wm_threads = 40,
84
	.urb = { 32, 256, 256 },
84
	.urb = { 32, 256, 256 },
85
};
85
};
86
 
86
 
87
static const struct gt_info gt2_info = {
87
static const struct gt_info gt2_info = {
88
	.name = "Sandybridge (gen6, gt2)",
88
	.name = "Sandybridge (gen6, gt2)",
89
	.max_vs_threads = 60,
89
	.max_vs_threads = 60,
90
	.max_gs_threads = 60,
90
	.max_gs_threads = 60,
91
	.max_wm_threads = 80,
91
	.max_wm_threads = 80,
92
	.urb = { 64, 256, 256 },
92
	.urb = { 64, 256, 256 },
93
};
93
};
94
 
94
 
95
static const uint32_t ps_kernel_packed[][4] = {
95
static const uint32_t ps_kernel_packed[][4] = {
96
#include "exa_wm_src_affine.g6b"
96
#include "exa_wm_src_affine.g6b"
97
#include "exa_wm_src_sample_argb.g6b"
97
#include "exa_wm_src_sample_argb.g6b"
98
#include "exa_wm_yuv_rgb.g6b"
98
#include "exa_wm_yuv_rgb.g6b"
99
#include "exa_wm_write.g6b"
99
#include "exa_wm_write.g6b"
100
};
100
};
101
 
101
 
102
static const uint32_t ps_kernel_planar[][4] = {
102
static const uint32_t ps_kernel_planar[][4] = {
103
#include "exa_wm_src_affine.g6b"
103
#include "exa_wm_src_affine.g6b"
104
#include "exa_wm_src_sample_planar.g6b"
104
#include "exa_wm_src_sample_planar.g6b"
105
#include "exa_wm_yuv_rgb.g6b"
105
#include "exa_wm_yuv_rgb.g6b"
106
#include "exa_wm_write.g6b"
106
#include "exa_wm_write.g6b"
107
};
107
};
108
 
108
 
109
#define NOKERNEL(kernel_enum, func, ns) \
109
#define NOKERNEL(kernel_enum, func, ns) \
110
    [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, func, 0, ns}
110
    [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, func, 0, ns}
111
#define KERNEL(kernel_enum, kernel, ns) \
111
#define KERNEL(kernel_enum, kernel, ns) \
112
    [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), ns}
112
    [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), ns}
113
 
113
 
114
static const struct wm_kernel_info {
114
static const struct wm_kernel_info {
115
	const char *name;
115
	const char *name;
116
	const void *data;
116
	const void *data;
117
	unsigned int size;
117
	unsigned int size;
118
	unsigned int num_surfaces;
118
	unsigned int num_surfaces;
119
} wm_kernels[] = {
119
} wm_kernels[] = {
120
	NOKERNEL(NOMASK, brw_wm_kernel__affine, 2),
120
	NOKERNEL(NOMASK, brw_wm_kernel__affine, 2),
121
	NOKERNEL(NOMASK_P, brw_wm_kernel__projective, 2),
121
	NOKERNEL(NOMASK_P, brw_wm_kernel__projective, 2),
122
 
122
 
123
	NOKERNEL(MASK, brw_wm_kernel__affine_mask, 3),
123
	NOKERNEL(MASK, brw_wm_kernel__affine_mask, 3),
124
	NOKERNEL(MASK_P, brw_wm_kernel__projective_mask, 3),
124
	NOKERNEL(MASK_P, brw_wm_kernel__projective_mask, 3),
125
 
125
 
126
	NOKERNEL(MASKCA, brw_wm_kernel__affine_mask_ca, 3),
126
	NOKERNEL(MASKCA, brw_wm_kernel__affine_mask_ca, 3),
127
	NOKERNEL(MASKCA_P, brw_wm_kernel__projective_mask_ca, 3),
127
	NOKERNEL(MASKCA_P, brw_wm_kernel__projective_mask_ca, 3),
128
 
128
 
129
	NOKERNEL(MASKSA, brw_wm_kernel__affine_mask_sa, 3),
129
	NOKERNEL(MASKSA, brw_wm_kernel__affine_mask_sa, 3),
130
	NOKERNEL(MASKSA_P, brw_wm_kernel__projective_mask_sa, 3),
130
	NOKERNEL(MASKSA_P, brw_wm_kernel__projective_mask_sa, 3),
131
 
131
 
132
	NOKERNEL(OPACITY, brw_wm_kernel__affine_opacity, 2),
132
	NOKERNEL(OPACITY, brw_wm_kernel__affine_opacity, 2),
133
	NOKERNEL(OPACITY_P, brw_wm_kernel__projective_opacity, 2),
133
	NOKERNEL(OPACITY_P, brw_wm_kernel__projective_opacity, 2),
134
 
134
 
135
	KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7),
135
	KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7),
136
	KERNEL(VIDEO_PACKED, ps_kernel_packed, 2),
136
	KERNEL(VIDEO_PACKED, ps_kernel_packed, 2),
137
};
137
};
138
#undef KERNEL
138
#undef KERNEL
139
 
139
 
140
static const struct blendinfo {
140
static const struct blendinfo {
141
	bool src_alpha;
141
	bool src_alpha;
142
	uint32_t src_blend;
142
	uint32_t src_blend;
143
	uint32_t dst_blend;
143
	uint32_t dst_blend;
144
} gen6_blend_op[] = {
144
} gen6_blend_op[] = {
145
	/* Clear */	{0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO},
145
	/* Clear */	{0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO},
146
	/* Src */	{0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO},
146
	/* Src */	{0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO},
147
	/* Dst */	{0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ONE},
147
	/* Dst */	{0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ONE},
148
	/* Over */	{1, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
148
	/* Over */	{1, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
149
	/* OverReverse */ {0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ONE},
149
	/* OverReverse */ {0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ONE},
150
	/* In */	{0, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
150
	/* In */	{0, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
151
	/* InReverse */	{1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_SRC_ALPHA},
151
	/* InReverse */	{1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_SRC_ALPHA},
152
	/* Out */	{0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
152
	/* Out */	{0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
153
	/* OutReverse */ {1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
153
	/* OutReverse */ {1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
154
	/* Atop */	{1, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
154
	/* Atop */	{1, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
155
	/* AtopReverse */ {1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_SRC_ALPHA},
155
	/* AtopReverse */ {1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_SRC_ALPHA},
156
	/* Xor */	{1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
156
	/* Xor */	{1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
157
	/* Add */	{0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ONE},
157
	/* Add */	{0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ONE},
158
};
158
};
159
 
159
 
160
/**
160
/**
161
 * Highest-valued BLENDFACTOR used in gen6_blend_op.
161
 * Highest-valued BLENDFACTOR used in gen6_blend_op.
162
 *
162
 *
163
 * This leaves out GEN6_BLENDFACTOR_INV_DST_COLOR,
163
 * This leaves out GEN6_BLENDFACTOR_INV_DST_COLOR,
164
 * GEN6_BLENDFACTOR_INV_CONST_{COLOR,ALPHA},
164
 * GEN6_BLENDFACTOR_INV_CONST_{COLOR,ALPHA},
165
 * GEN6_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA}
165
 * GEN6_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA}
166
 */
166
 */
167
#define GEN6_BLENDFACTOR_COUNT (GEN6_BLENDFACTOR_INV_DST_ALPHA + 1)
167
#define GEN6_BLENDFACTOR_COUNT (GEN6_BLENDFACTOR_INV_DST_ALPHA + 1)
168
 
168
 
169
#define GEN6_BLEND_STATE_PADDED_SIZE	ALIGN(sizeof(struct gen6_blend_state), 64)
169
#define GEN6_BLEND_STATE_PADDED_SIZE	ALIGN(sizeof(struct gen6_blend_state), 64)
170
 
170
 
171
#define BLEND_OFFSET(s, d) \
171
#define BLEND_OFFSET(s, d) \
172
	(((s) * GEN6_BLENDFACTOR_COUNT + (d)) * GEN6_BLEND_STATE_PADDED_SIZE)
172
	(((s) * GEN6_BLENDFACTOR_COUNT + (d)) * GEN6_BLEND_STATE_PADDED_SIZE)
173
 
173
 
174
#define NO_BLEND BLEND_OFFSET(GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO)
174
#define NO_BLEND BLEND_OFFSET(GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO)
175
#define CLEAR BLEND_OFFSET(GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO)
175
#define CLEAR BLEND_OFFSET(GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO)
176
 
176
 
177
#define SAMPLER_OFFSET(sf, se, mf, me) \
177
#define SAMPLER_OFFSET(sf, se, mf, me) \
178
	(((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me) + 2) * 2 * sizeof(struct gen6_sampler_state))
178
	(((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me) + 2) * 2 * sizeof(struct gen6_sampler_state))
179
 
179
 
180
#define VERTEX_2s2s 0
180
#define VERTEX_2s2s 0
181
 
181
 
182
#define COPY_SAMPLER 0
182
#define COPY_SAMPLER 0
183
#define COPY_VERTEX VERTEX_2s2s
183
#define COPY_VERTEX VERTEX_2s2s
184
#define COPY_FLAGS(a) GEN6_SET_FLAGS(COPY_SAMPLER, (a) == GXcopy ? NO_BLEND : CLEAR, GEN6_WM_KERNEL_NOMASK, COPY_VERTEX)
184
#define COPY_FLAGS(a) GEN6_SET_FLAGS(COPY_SAMPLER, (a) == GXcopy ? NO_BLEND : CLEAR, GEN6_WM_KERNEL_NOMASK, COPY_VERTEX)
185
 
185
 
186
#define FILL_SAMPLER (2 * sizeof(struct gen6_sampler_state))
186
#define FILL_SAMPLER (2 * sizeof(struct gen6_sampler_state))
187
#define FILL_VERTEX VERTEX_2s2s
187
#define FILL_VERTEX VERTEX_2s2s
188
#define FILL_FLAGS(op, format) GEN6_SET_FLAGS(FILL_SAMPLER, gen6_get_blend((op), false, (format)), GEN6_WM_KERNEL_NOMASK, FILL_VERTEX)
188
#define FILL_FLAGS(op, format) GEN6_SET_FLAGS(FILL_SAMPLER, gen6_get_blend((op), false, (format)), GEN6_WM_KERNEL_NOMASK, FILL_VERTEX)
189
#define FILL_FLAGS_NOBLEND GEN6_SET_FLAGS(FILL_SAMPLER, NO_BLEND, GEN6_WM_KERNEL_NOMASK, FILL_VERTEX)
189
#define FILL_FLAGS_NOBLEND GEN6_SET_FLAGS(FILL_SAMPLER, NO_BLEND, GEN6_WM_KERNEL_NOMASK, FILL_VERTEX)
190
 
190
 
191
#define GEN6_SAMPLER(f) (((f) >> 16) & 0xfff0)
191
#define GEN6_SAMPLER(f) (((f) >> 16) & 0xfff0)
192
#define GEN6_BLEND(f) (((f) >> 0) & 0xfff0)
192
#define GEN6_BLEND(f) (((f) >> 0) & 0xfff0)
193
#define GEN6_KERNEL(f) (((f) >> 16) & 0xf)
193
#define GEN6_KERNEL(f) (((f) >> 16) & 0xf)
194
#define GEN6_VERTEX(f) (((f) >> 0) & 0xf)
194
#define GEN6_VERTEX(f) (((f) >> 0) & 0xf)
195
#define GEN6_SET_FLAGS(S, B, K, V)  (((S) | (K)) << 16 | ((B) | (V)))
195
#define GEN6_SET_FLAGS(S, B, K, V)  (((S) | (K)) << 16 | ((B) | (V)))
196
 
196
 
197
#define OUT_BATCH(v) batch_emit(sna, v)
197
#define OUT_BATCH(v) batch_emit(sna, v)
198
#define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y)
198
#define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y)
199
#define OUT_VERTEX_F(v) vertex_emit(sna, v)
199
#define OUT_VERTEX_F(v) vertex_emit(sna, v)
200
 
200
 
201
static inline bool too_large(int width, int height)
201
static inline bool too_large(int width, int height)
202
{
202
{
203
	return width > GEN6_MAX_SIZE || height > GEN6_MAX_SIZE;
203
	return width > GEN6_MAX_SIZE || height > GEN6_MAX_SIZE;
204
}
204
}
205
 
205
 
206
static uint32_t gen6_get_blend(int op,
206
static uint32_t gen6_get_blend(int op,
207
			       bool has_component_alpha,
207
			       bool has_component_alpha,
208
			       uint32_t dst_format)
208
			       uint32_t dst_format)
209
{
209
{
210
	uint32_t src, dst;
210
	uint32_t src, dst;
211
 
211
 
212
 
212
 
213
    src = GEN6_BLENDFACTOR_ONE; //gen6_blend_op[op].src_blend;
213
    src = GEN6_BLENDFACTOR_ONE; //gen6_blend_op[op].src_blend;
214
    dst = GEN6_BLENDFACTOR_INV_SRC_ALPHA; //gen6_blend_op[op].dst_blend;
214
    dst = GEN6_BLENDFACTOR_INV_SRC_ALPHA; //gen6_blend_op[op].dst_blend;
215
 
215
 
216
//    dst = GEN6_BLENDFACTOR_ZERO; //gen6_blend_op[op].dst_blend;
216
//    dst = GEN6_BLENDFACTOR_ZERO; //gen6_blend_op[op].dst_blend;
217
 
217
 
218
#if 0
218
#if 0
219
	/* If there's no dst alpha channel, adjust the blend op so that
219
	/* If there's no dst alpha channel, adjust the blend op so that
220
	 * we'll treat it always as 1.
220
	 * we'll treat it always as 1.
221
	 */
221
	 */
222
	if (PICT_FORMAT_A(dst_format) == 0) {
222
	if (PICT_FORMAT_A(dst_format) == 0) {
223
		if (src == GEN6_BLENDFACTOR_DST_ALPHA)
223
		if (src == GEN6_BLENDFACTOR_DST_ALPHA)
224
			src = GEN6_BLENDFACTOR_ONE;
224
			src = GEN6_BLENDFACTOR_ONE;
225
		else if (src == GEN6_BLENDFACTOR_INV_DST_ALPHA)
225
		else if (src == GEN6_BLENDFACTOR_INV_DST_ALPHA)
226
			src = GEN6_BLENDFACTOR_ZERO;
226
			src = GEN6_BLENDFACTOR_ZERO;
227
	}
227
	}
228
 
228
 
229
	/* If the source alpha is being used, then we should only be in a
229
	/* If the source alpha is being used, then we should only be in a
230
	 * case where the source blend factor is 0, and the source blend
230
	 * case where the source blend factor is 0, and the source blend
231
	 * value is the mask channels multiplied by the source picture's alpha.
231
	 * value is the mask channels multiplied by the source picture's alpha.
232
	 */
232
	 */
233
	if (has_component_alpha && gen6_blend_op[op].src_alpha) {
233
	if (has_component_alpha && gen6_blend_op[op].src_alpha) {
234
		if (dst == GEN6_BLENDFACTOR_SRC_ALPHA)
234
		if (dst == GEN6_BLENDFACTOR_SRC_ALPHA)
235
			dst = GEN6_BLENDFACTOR_SRC_COLOR;
235
			dst = GEN6_BLENDFACTOR_SRC_COLOR;
236
		else if (dst == GEN6_BLENDFACTOR_INV_SRC_ALPHA)
236
		else if (dst == GEN6_BLENDFACTOR_INV_SRC_ALPHA)
237
			dst = GEN6_BLENDFACTOR_INV_SRC_COLOR;
237
			dst = GEN6_BLENDFACTOR_INV_SRC_COLOR;
238
	}
238
	}
239
 
239
 
240
	DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n",
240
	DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n",
241
	     op, dst_format, PICT_FORMAT_A(dst_format),
241
	     op, dst_format, PICT_FORMAT_A(dst_format),
242
	     src, dst, (int)BLEND_OFFSET(src, dst)));
242
	     src, dst, (int)BLEND_OFFSET(src, dst)));
243
#endif
243
#endif
244
 
244
 
245
	return BLEND_OFFSET(src, dst);
245
	return BLEND_OFFSET(src, dst);
246
}
246
}
247
 
247
 
248
static uint32_t gen6_get_card_format(PictFormat format)
248
static uint32_t gen6_get_card_format(PictFormat format)
249
{
249
{
250
	switch (format) {
250
	switch (format) {
251
	default:
251
	default:
252
		return -1;
252
		return -1;
253
	case PICT_a8r8g8b8:
253
	case PICT_a8r8g8b8:
254
    return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
254
    return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
255
	case PICT_x8r8g8b8:
255
	case PICT_x8r8g8b8:
256
		return GEN6_SURFACEFORMAT_B8G8R8X8_UNORM;
256
		return GEN6_SURFACEFORMAT_B8G8R8X8_UNORM;
257
	case PICT_a8b8g8r8:
257
	case PICT_a8b8g8r8:
258
		return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM;
258
		return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM;
259
	case PICT_x8b8g8r8:
259
	case PICT_x8b8g8r8:
260
		return GEN6_SURFACEFORMAT_R8G8B8X8_UNORM;
260
		return GEN6_SURFACEFORMAT_R8G8B8X8_UNORM;
261
	case PICT_a2r10g10b10:
261
	case PICT_a2r10g10b10:
262
		return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
262
		return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
263
	case PICT_x2r10g10b10:
263
	case PICT_x2r10g10b10:
264
		return GEN6_SURFACEFORMAT_B10G10R10X2_UNORM;
264
		return GEN6_SURFACEFORMAT_B10G10R10X2_UNORM;
265
	case PICT_r8g8b8:
265
	case PICT_r8g8b8:
266
		return GEN6_SURFACEFORMAT_R8G8B8_UNORM;
266
		return GEN6_SURFACEFORMAT_R8G8B8_UNORM;
267
	case PICT_r5g6b5:
267
	case PICT_r5g6b5:
268
		return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
268
		return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
269
	case PICT_a1r5g5b5:
269
	case PICT_a1r5g5b5:
270
		return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
270
		return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
271
	case PICT_a8:
271
	case PICT_a8:
272
		return GEN6_SURFACEFORMAT_A8_UNORM;
272
		return GEN6_SURFACEFORMAT_A8_UNORM;
273
	case PICT_a4r4g4b4:
273
	case PICT_a4r4g4b4:
274
		return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM;
274
		return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM;
275
	}
275
	}
276
}
276
}
277
 
277
 
278
static uint32_t gen6_get_dest_format(PictFormat format)
278
static uint32_t gen6_get_dest_format(PictFormat format)
279
{
279
{
280
    return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
280
    return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
281
 
281
 
282
#if 0
282
#if 0
283
 
283
 
284
	switch (format) {
284
	switch (format) {
285
	default:
285
	default:
286
		return -1;
286
		return -1;
287
	case PICT_a8r8g8b8:
287
	case PICT_a8r8g8b8:
288
	case PICT_x8r8g8b8:
288
	case PICT_x8r8g8b8:
289
		return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
289
		return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
290
	case PICT_a8b8g8r8:
290
	case PICT_a8b8g8r8:
291
	case PICT_x8b8g8r8:
291
	case PICT_x8b8g8r8:
292
		return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM;
292
		return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM;
293
	case PICT_a2r10g10b10:
293
	case PICT_a2r10g10b10:
294
	case PICT_x2r10g10b10:
294
	case PICT_x2r10g10b10:
295
		return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
295
		return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
296
	case PICT_r5g6b5:
296
	case PICT_r5g6b5:
297
		return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
297
		return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
298
	case PICT_x1r5g5b5:
298
	case PICT_x1r5g5b5:
299
	case PICT_a1r5g5b5:
299
	case PICT_a1r5g5b5:
300
		return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
300
		return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
301
	case PICT_a8:
301
	case PICT_a8:
302
		return GEN6_SURFACEFORMAT_A8_UNORM;
302
		return GEN6_SURFACEFORMAT_A8_UNORM;
303
	case PICT_a4r4g4b4:
303
	case PICT_a4r4g4b4:
304
	case PICT_x4r4g4b4:
304
	case PICT_x4r4g4b4:
305
		return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM;
305
		return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM;
306
	}
306
	}
307
#endif
307
#endif
308
 
308
 
309
}
309
}
310
 
310
 
311
#if 0
311
#if 0
312
 
312
 
313
static bool gen6_check_dst_format(PictFormat format)
313
static bool gen6_check_dst_format(PictFormat format)
314
{
314
{
315
	if (gen6_get_dest_format(format) != -1)
315
	if (gen6_get_dest_format(format) != -1)
316
		return true;
316
		return true;
317
 
317
 
318
	DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format));
318
	DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format));
319
	return false;
319
	return false;
320
}
320
}
321
 
321
 
322
static bool gen6_check_format(uint32_t format)
322
static bool gen6_check_format(uint32_t format)
323
{
323
{
324
	if (gen6_get_card_format(format) != -1)
324
	if (gen6_get_card_format(format) != -1)
325
		return true;
325
		return true;
326
 
326
 
327
	DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format));
327
	DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format));
328
		return false;
328
		return false;
329
}
329
}
330
 
330
 
331
static uint32_t gen6_filter(uint32_t filter)
331
static uint32_t gen6_filter(uint32_t filter)
332
{
332
{
333
	switch (filter) {
333
	switch (filter) {
334
	default:
334
	default:
335
		assert(0);
335
		assert(0);
336
	case PictFilterNearest:
336
	case PictFilterNearest:
337
		return SAMPLER_FILTER_NEAREST;
337
		return SAMPLER_FILTER_NEAREST;
338
	case PictFilterBilinear:
338
	case PictFilterBilinear:
339
		return SAMPLER_FILTER_BILINEAR;
339
		return SAMPLER_FILTER_BILINEAR;
340
	}
340
	}
341
}
341
}
342
 
342
 
343
static uint32_t gen6_check_filter(PicturePtr picture)
343
static uint32_t gen6_check_filter(PicturePtr picture)
344
{
344
{
345
	switch (picture->filter) {
345
	switch (picture->filter) {
346
	case PictFilterNearest:
346
	case PictFilterNearest:
347
	case PictFilterBilinear:
347
	case PictFilterBilinear:
348
		return true;
348
		return true;
349
	default:
349
	default:
350
		return false;
350
		return false;
351
	}
351
	}
352
}
352
}
353
 
353
 
354
static uint32_t gen6_repeat(uint32_t repeat)
354
static uint32_t gen6_repeat(uint32_t repeat)
355
{
355
{
356
	switch (repeat) {
356
	switch (repeat) {
357
	default:
357
	default:
358
		assert(0);
358
		assert(0);
359
	case RepeatNone:
359
	case RepeatNone:
360
		return SAMPLER_EXTEND_NONE;
360
		return SAMPLER_EXTEND_NONE;
361
	case RepeatNormal:
361
	case RepeatNormal:
362
		return SAMPLER_EXTEND_REPEAT;
362
		return SAMPLER_EXTEND_REPEAT;
363
	case RepeatPad:
363
	case RepeatPad:
364
		return SAMPLER_EXTEND_PAD;
364
		return SAMPLER_EXTEND_PAD;
365
	case RepeatReflect:
365
	case RepeatReflect:
366
		return SAMPLER_EXTEND_REFLECT;
366
		return SAMPLER_EXTEND_REFLECT;
367
	}
367
	}
368
}
368
}
369
 
369
 
370
static bool gen6_check_repeat(PicturePtr picture)
370
static bool gen6_check_repeat(PicturePtr picture)
371
{
371
{
372
	if (!picture->repeat)
372
	if (!picture->repeat)
373
		return true;
373
		return true;
374
 
374
 
375
	switch (picture->repeatType) {
375
	switch (picture->repeatType) {
376
	case RepeatNone:
376
	case RepeatNone:
377
	case RepeatNormal:
377
	case RepeatNormal:
378
	case RepeatPad:
378
	case RepeatPad:
379
	case RepeatReflect:
379
	case RepeatReflect:
380
		return true;
380
		return true;
381
	default:
381
	default:
382
		return false;
382
		return false;
383
	}
383
	}
384
}
384
}
385
#endif
385
#endif
386
 
386
 
387
static int
387
static int
388
gen6_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine)
388
gen6_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine)
389
{
389
{
390
	int base;
390
	int base;
391
 
391
 
392
	if (has_mask) {
392
	if (has_mask) {
393
		if (is_ca) {
393
		if (is_ca) {
394
			if (gen6_blend_op[op].src_alpha)
394
			if (gen6_blend_op[op].src_alpha)
395
				base = GEN6_WM_KERNEL_MASKSA;
395
				base = GEN6_WM_KERNEL_MASKSA;
396
			else
396
			else
397
				base = GEN6_WM_KERNEL_MASKCA;
397
				base = GEN6_WM_KERNEL_MASKCA;
398
		} else
398
		} else
399
			base = GEN6_WM_KERNEL_MASK;
399
			base = GEN6_WM_KERNEL_MASK;
400
	} else
400
	} else
401
		base = GEN6_WM_KERNEL_NOMASK;
401
		base = GEN6_WM_KERNEL_NOMASK;
402
 
402
 
403
	return base + !is_affine;
403
	return base + !is_affine;
404
}
404
}
405
 
405
 
406
static void
406
static void
407
gen6_emit_urb(struct sna *sna)
407
gen6_emit_urb(struct sna *sna)
408
{
408
{
409
	OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2));
409
	OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2));
410
	OUT_BATCH(((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT) |
410
	OUT_BATCH(((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT) |
411
		  (sna->render_state.gen6.info->urb.max_vs_entries << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT)); /* at least 24 on GEN6 */
411
		  (sna->render_state.gen6.info->urb.max_vs_entries << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT)); /* at least 24 on GEN6 */
412
	OUT_BATCH((0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT) |
412
	OUT_BATCH((0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT) |
413
		  (0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT)); /* no GS thread */
413
		  (0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT)); /* no GS thread */
414
}
414
}
415
 
415
 
416
static void
416
static void
417
gen6_emit_state_base_address(struct sna *sna)
417
gen6_emit_state_base_address(struct sna *sna)
418
{
418
{
419
	OUT_BATCH(GEN6_STATE_BASE_ADDRESS | (10 - 2));
419
	OUT_BATCH(GEN6_STATE_BASE_ADDRESS | (10 - 2));
420
	OUT_BATCH(0); /* general */
420
	OUT_BATCH(0); /* general */
421
	OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */
421
	OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */
422
				 sna->kgem.nbatch,
422
				 sna->kgem.nbatch,
423
				 NULL,
423
				 NULL,
424
				 I915_GEM_DOMAIN_INSTRUCTION << 16,
424
				 I915_GEM_DOMAIN_INSTRUCTION << 16,
425
				 BASE_ADDRESS_MODIFY));
425
				 BASE_ADDRESS_MODIFY));
426
	OUT_BATCH(kgem_add_reloc(&sna->kgem, /* instruction */
426
	OUT_BATCH(kgem_add_reloc(&sna->kgem, /* instruction */
427
				 sna->kgem.nbatch,
427
				 sna->kgem.nbatch,
428
				 sna->render_state.gen6.general_bo,
428
				 sna->render_state.gen6.general_bo,
429
				 I915_GEM_DOMAIN_INSTRUCTION << 16,
429
				 I915_GEM_DOMAIN_INSTRUCTION << 16,
430
				 BASE_ADDRESS_MODIFY));
430
				 BASE_ADDRESS_MODIFY));
431
	OUT_BATCH(0); /* indirect */
431
	OUT_BATCH(0); /* indirect */
432
	OUT_BATCH(kgem_add_reloc(&sna->kgem,
432
	OUT_BATCH(kgem_add_reloc(&sna->kgem,
433
				 sna->kgem.nbatch,
433
				 sna->kgem.nbatch,
434
				 sna->render_state.gen6.general_bo,
434
				 sna->render_state.gen6.general_bo,
435
				 I915_GEM_DOMAIN_INSTRUCTION << 16,
435
				 I915_GEM_DOMAIN_INSTRUCTION << 16,
436
				 BASE_ADDRESS_MODIFY));
436
				 BASE_ADDRESS_MODIFY));
437
 
437
 
438
	/* upper bounds, disable */
438
	/* upper bounds, disable */
439
	OUT_BATCH(0);
439
	OUT_BATCH(0);
440
	OUT_BATCH(BASE_ADDRESS_MODIFY);
440
	OUT_BATCH(BASE_ADDRESS_MODIFY);
441
	OUT_BATCH(0);
441
	OUT_BATCH(0);
442
	OUT_BATCH(BASE_ADDRESS_MODIFY);
442
	OUT_BATCH(BASE_ADDRESS_MODIFY);
443
}
443
}
444
 
444
 
445
static void
445
static void
446
gen6_emit_viewports(struct sna *sna)
446
gen6_emit_viewports(struct sna *sna)
447
{
447
{
448
	OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS |
448
	OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS |
449
		  GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC |
449
		  GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC |
450
		  (4 - 2));
450
		  (4 - 2));
451
	OUT_BATCH(0);
451
	OUT_BATCH(0);
452
	OUT_BATCH(0);
452
	OUT_BATCH(0);
453
	OUT_BATCH(0);
453
	OUT_BATCH(0);
454
}
454
}
455
 
455
 
456
static void
456
static void
457
gen6_emit_vs(struct sna *sna)
457
gen6_emit_vs(struct sna *sna)
458
{
458
{
459
	/* disable VS constant buffer */
459
	/* disable VS constant buffer */
460
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | (5 - 2));
460
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | (5 - 2));
461
	OUT_BATCH(0);
461
	OUT_BATCH(0);
462
	OUT_BATCH(0);
462
	OUT_BATCH(0);
463
	OUT_BATCH(0);
463
	OUT_BATCH(0);
464
	OUT_BATCH(0);
464
	OUT_BATCH(0);
465
 
465
 
466
	OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2));
466
	OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2));
467
	OUT_BATCH(0); /* no VS kernel */
467
	OUT_BATCH(0); /* no VS kernel */
468
	OUT_BATCH(0);
468
	OUT_BATCH(0);
469
	OUT_BATCH(0);
469
	OUT_BATCH(0);
470
	OUT_BATCH(0);
470
	OUT_BATCH(0);
471
	OUT_BATCH(0); /* pass-through */
471
	OUT_BATCH(0); /* pass-through */
472
}
472
}
473
 
473
 
474
static void
474
static void
475
gen6_emit_gs(struct sna *sna)
475
gen6_emit_gs(struct sna *sna)
476
{
476
{
477
	/* disable GS constant buffer */
477
	/* disable GS constant buffer */
478
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2));
478
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2));
479
	OUT_BATCH(0);
479
	OUT_BATCH(0);
480
	OUT_BATCH(0);
480
	OUT_BATCH(0);
481
	OUT_BATCH(0);
481
	OUT_BATCH(0);
482
	OUT_BATCH(0);
482
	OUT_BATCH(0);
483
 
483
 
484
	OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2));
484
	OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2));
485
	OUT_BATCH(0); /* no GS kernel */
485
	OUT_BATCH(0); /* no GS kernel */
486
	OUT_BATCH(0);
486
	OUT_BATCH(0);
487
	OUT_BATCH(0);
487
	OUT_BATCH(0);
488
	OUT_BATCH(0);
488
	OUT_BATCH(0);
489
	OUT_BATCH(0);
489
	OUT_BATCH(0);
490
	OUT_BATCH(0); /* pass-through */
490
	OUT_BATCH(0); /* pass-through */
491
}
491
}
492
 
492
 
493
static void
493
static void
494
gen6_emit_clip(struct sna *sna)
494
gen6_emit_clip(struct sna *sna)
495
{
495
{
496
	OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2));
496
	OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2));
497
	OUT_BATCH(0);
497
	OUT_BATCH(0);
498
	OUT_BATCH(0); /* pass-through */
498
	OUT_BATCH(0); /* pass-through */
499
	OUT_BATCH(0);
499
	OUT_BATCH(0);
500
}
500
}
501
 
501
 
502
static void
502
static void
503
gen6_emit_wm_constants(struct sna *sna)
503
gen6_emit_wm_constants(struct sna *sna)
504
{
504
{
505
	/* disable WM constant buffer */
505
	/* disable WM constant buffer */
506
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2));
506
	OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2));
507
	OUT_BATCH(0);
507
	OUT_BATCH(0);
508
	OUT_BATCH(0);
508
	OUT_BATCH(0);
509
	OUT_BATCH(0);
509
	OUT_BATCH(0);
510
	OUT_BATCH(0);
510
	OUT_BATCH(0);
511
}
511
}
512
 
512
 
513
static void
513
static void
514
gen6_emit_null_depth_buffer(struct sna *sna)
514
gen6_emit_null_depth_buffer(struct sna *sna)
515
{
515
{
516
	OUT_BATCH(GEN6_3DSTATE_DEPTH_BUFFER | (7 - 2));
516
	OUT_BATCH(GEN6_3DSTATE_DEPTH_BUFFER | (7 - 2));
517
	OUT_BATCH(GEN6_SURFACE_NULL << GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT |
517
	OUT_BATCH(GEN6_SURFACE_NULL << GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT |
518
		  GEN6_DEPTHFORMAT_D32_FLOAT << GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT);
518
		  GEN6_DEPTHFORMAT_D32_FLOAT << GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT);
519
	OUT_BATCH(0);
519
	OUT_BATCH(0);
520
	OUT_BATCH(0);
520
	OUT_BATCH(0);
521
	OUT_BATCH(0);
521
	OUT_BATCH(0);
522
	OUT_BATCH(0);
522
	OUT_BATCH(0);
523
	OUT_BATCH(0);
523
	OUT_BATCH(0);
524
 
524
 
525
	OUT_BATCH(GEN6_3DSTATE_CLEAR_PARAMS | (2 - 2));
525
	OUT_BATCH(GEN6_3DSTATE_CLEAR_PARAMS | (2 - 2));
526
	OUT_BATCH(0);
526
	OUT_BATCH(0);
527
}
527
}
528
 
528
 
529
static void
529
static void
530
gen6_emit_invariant(struct sna *sna)
530
gen6_emit_invariant(struct sna *sna)
531
{
531
{
532
	OUT_BATCH(GEN6_PIPELINE_SELECT | PIPELINE_SELECT_3D);
532
	OUT_BATCH(GEN6_PIPELINE_SELECT | PIPELINE_SELECT_3D);
533
 
533
 
534
	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | (3 - 2));
534
	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | (3 - 2));
535
	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
535
	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
536
              GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
536
              GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
537
	OUT_BATCH(0);
537
	OUT_BATCH(0);
538
 
538
 
539
	OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2));
539
	OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2));
540
	OUT_BATCH(1);
540
	OUT_BATCH(1);
541
 
541
 
542
	gen6_emit_urb(sna);
542
	gen6_emit_urb(sna);
543
 
543
 
544
	gen6_emit_state_base_address(sna);
544
	gen6_emit_state_base_address(sna);
545
 
545
 
546
	gen6_emit_viewports(sna);
546
	gen6_emit_viewports(sna);
547
	gen6_emit_vs(sna);
547
	gen6_emit_vs(sna);
548
	gen6_emit_gs(sna);
548
	gen6_emit_gs(sna);
549
	gen6_emit_clip(sna);
549
	gen6_emit_clip(sna);
550
	gen6_emit_wm_constants(sna);
550
	gen6_emit_wm_constants(sna);
551
	gen6_emit_null_depth_buffer(sna);
551
	gen6_emit_null_depth_buffer(sna);
552
 
552
 
553
	sna->render_state.gen6.needs_invariant = false;
553
	sna->render_state.gen6.needs_invariant = false;
554
}
554
}
555
 
555
 
556
static bool
556
static bool
557
gen6_emit_cc(struct sna *sna, int blend)
557
gen6_emit_cc(struct sna *sna, int blend)
558
{
558
{
559
	struct gen6_render_state *render = &sna->render_state.gen6;
559
	struct gen6_render_state *render = &sna->render_state.gen6;
560
 
560
 
561
	if (render->blend == blend)
561
	if (render->blend == blend)
562
		return blend != NO_BLEND;
562
		return blend != NO_BLEND;
563
 
563
 
564
	DBG(("%s: blend = %x\n", __FUNCTION__, blend));
564
	DBG(("%s: blend = %x\n", __FUNCTION__, blend));
565
 
565
 
566
	OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2));
566
	OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2));
567
	OUT_BATCH((render->cc_blend + blend) | 1);
567
	OUT_BATCH((render->cc_blend + blend) | 1);
568
	if (render->blend == (unsigned)-1) {
568
	if (render->blend == (unsigned)-1) {
569
		OUT_BATCH(1);
569
		OUT_BATCH(1);
570
		OUT_BATCH(1);
570
		OUT_BATCH(1);
571
	} else {
571
	} else {
572
		OUT_BATCH(0);
572
		OUT_BATCH(0);
573
		OUT_BATCH(0);
573
		OUT_BATCH(0);
574
	}
574
	}
575
 
575
 
576
	render->blend = blend;
576
	render->blend = blend;
577
	return blend != NO_BLEND;
577
	return blend != NO_BLEND;
578
}
578
}
579
 
579
 
580
static void
580
static void
581
gen6_emit_sampler(struct sna *sna, uint32_t state)
581
gen6_emit_sampler(struct sna *sna, uint32_t state)
582
{
582
{
583
	if (sna->render_state.gen6.samplers == state)
583
	if (sna->render_state.gen6.samplers == state)
584
		return;
584
		return;
585
 
585
 
586
	sna->render_state.gen6.samplers = state;
586
	sna->render_state.gen6.samplers = state;
587
 
587
 
588
	DBG(("%s: sampler = %x\n", __FUNCTION__, state));
588
	DBG(("%s: sampler = %x\n", __FUNCTION__, state));
589
 
589
 
590
	OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS |
590
	OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS |
591
		  GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS |
591
		  GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS |
592
		  (4 - 2));
592
		  (4 - 2));
593
	OUT_BATCH(0); /* VS */
593
	OUT_BATCH(0); /* VS */
594
	OUT_BATCH(0); /* GS */
594
	OUT_BATCH(0); /* GS */
595
	OUT_BATCH(sna->render_state.gen6.wm_state + state);
595
	OUT_BATCH(sna->render_state.gen6.wm_state + state);
596
}
596
}
597
 
597
 
598
static void
598
static void
599
gen6_emit_sf(struct sna *sna, bool has_mask)
599
gen6_emit_sf(struct sna *sna, bool has_mask)
600
{
600
{
601
	int num_sf_outputs = has_mask ? 2 : 1;
601
	int num_sf_outputs = has_mask ? 2 : 1;
602
 
602
 
603
	if (sna->render_state.gen6.num_sf_outputs == num_sf_outputs)
603
	if (sna->render_state.gen6.num_sf_outputs == num_sf_outputs)
604
		return;
604
		return;
605
 
605
 
606
	DBG(("%s: num_sf_outputs=%d, read_length=%d, read_offset=%d\n",
606
	DBG(("%s: num_sf_outputs=%d, read_length=%d, read_offset=%d\n",
607
	     __FUNCTION__, num_sf_outputs, 1, 0));
607
	     __FUNCTION__, num_sf_outputs, 1, 0));
608
 
608
 
609
	sna->render_state.gen6.num_sf_outputs = num_sf_outputs;
609
	sna->render_state.gen6.num_sf_outputs = num_sf_outputs;
610
 
610
 
611
	OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2));
611
	OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2));
612
	OUT_BATCH(num_sf_outputs << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT |
612
	OUT_BATCH(num_sf_outputs << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT |
613
		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT |
613
		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT |
614
		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT);
614
		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT);
615
	OUT_BATCH(0);
615
	OUT_BATCH(0);
616
	OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE);
616
	OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE);
617
	OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */
617
	OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */
618
	OUT_BATCH(0);
618
	OUT_BATCH(0);
619
	OUT_BATCH(0);
619
	OUT_BATCH(0);
620
	OUT_BATCH(0);
620
	OUT_BATCH(0);
621
	OUT_BATCH(0);
621
	OUT_BATCH(0);
622
	OUT_BATCH(0); /* DW9 */
622
	OUT_BATCH(0); /* DW9 */
623
	OUT_BATCH(0);
623
	OUT_BATCH(0);
624
	OUT_BATCH(0);
624
	OUT_BATCH(0);
625
	OUT_BATCH(0);
625
	OUT_BATCH(0);
626
	OUT_BATCH(0);
626
	OUT_BATCH(0);
627
	OUT_BATCH(0); /* DW14 */
627
	OUT_BATCH(0); /* DW14 */
628
	OUT_BATCH(0);
628
	OUT_BATCH(0);
629
	OUT_BATCH(0);
629
	OUT_BATCH(0);
630
	OUT_BATCH(0);
630
	OUT_BATCH(0);
631
	OUT_BATCH(0);
631
	OUT_BATCH(0);
632
	OUT_BATCH(0); /* DW19 */
632
	OUT_BATCH(0); /* DW19 */
633
}
633
}
634
 
634
 
635
static void
635
static void
636
gen6_emit_wm(struct sna *sna, unsigned int kernel, bool has_mask)
636
gen6_emit_wm(struct sna *sna, unsigned int kernel, bool has_mask)
637
{
637
{
638
	const uint32_t *kernels;
638
	const uint32_t *kernels;
639
 
639
 
640
	if (sna->render_state.gen6.kernel == kernel)
640
	if (sna->render_state.gen6.kernel == kernel)
641
		return;
641
		return;
642
 
642
 
643
	sna->render_state.gen6.kernel = kernel;
643
	sna->render_state.gen6.kernel = kernel;
644
	kernels = sna->render_state.gen6.wm_kernel[kernel];
644
	kernels = sna->render_state.gen6.wm_kernel[kernel];
645
 
645
 
646
	DBG(("%s: switching to %s, num_surfaces=%d (8-pixel? %d, 16-pixel? %d,32-pixel? %d)\n",
646
	DBG(("%s: switching to %s, num_surfaces=%d (8-pixel? %d, 16-pixel? %d,32-pixel? %d)\n",
647
	     __FUNCTION__,
647
	     __FUNCTION__,
648
	     wm_kernels[kernel].name, wm_kernels[kernel].num_surfaces,
648
	     wm_kernels[kernel].name, wm_kernels[kernel].num_surfaces,
649
	    kernels[0], kernels[1], kernels[2]));
649
	    kernels[0], kernels[1], kernels[2]));
650
 
650
 
651
	OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2));
651
	OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2));
652
	OUT_BATCH(kernels[0] ?: kernels[1] ?: kernels[2]);
652
	OUT_BATCH(kernels[0] ?: kernels[1] ?: kernels[2]);
653
	OUT_BATCH(1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT |
653
	OUT_BATCH(1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT |
654
		  wm_kernels[kernel].num_surfaces << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT);
654
		  wm_kernels[kernel].num_surfaces << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT);
655
	OUT_BATCH(0); /* scratch space */
655
	OUT_BATCH(0); /* scratch space */
656
	OUT_BATCH((kernels[0] ? 4 : kernels[1] ? 6 : 8) << GEN6_3DSTATE_WM_DISPATCH_0_START_GRF_SHIFT |
656
	OUT_BATCH((kernels[0] ? 4 : kernels[1] ? 6 : 8) << GEN6_3DSTATE_WM_DISPATCH_0_START_GRF_SHIFT |
657
		  8 << GEN6_3DSTATE_WM_DISPATCH_1_START_GRF_SHIFT |
657
		  8 << GEN6_3DSTATE_WM_DISPATCH_1_START_GRF_SHIFT |
658
		  6 << GEN6_3DSTATE_WM_DISPATCH_2_START_GRF_SHIFT);
658
		  6 << GEN6_3DSTATE_WM_DISPATCH_2_START_GRF_SHIFT);
659
	OUT_BATCH((sna->render_state.gen6.info->max_wm_threads - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT |
659
	OUT_BATCH((sna->render_state.gen6.info->max_wm_threads - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT |
660
		  (kernels[0] ? GEN6_3DSTATE_WM_8_DISPATCH_ENABLE : 0) |
660
		  (kernels[0] ? GEN6_3DSTATE_WM_8_DISPATCH_ENABLE : 0) |
661
		  (kernels[1] ? GEN6_3DSTATE_WM_16_DISPATCH_ENABLE : 0) |
661
		  (kernels[1] ? GEN6_3DSTATE_WM_16_DISPATCH_ENABLE : 0) |
662
		  (kernels[2] ? GEN6_3DSTATE_WM_32_DISPATCH_ENABLE : 0) |
662
		  (kernels[2] ? GEN6_3DSTATE_WM_32_DISPATCH_ENABLE : 0) |
663
		  GEN6_3DSTATE_WM_DISPATCH_ENABLE);
663
		  GEN6_3DSTATE_WM_DISPATCH_ENABLE);
664
	OUT_BATCH((1 + has_mask) << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT |
664
	OUT_BATCH((1 + has_mask) << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT |
665
		  GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
665
		  GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
666
	OUT_BATCH(kernels[2]);
666
	OUT_BATCH(kernels[2]);
667
	OUT_BATCH(kernels[1]);
667
	OUT_BATCH(kernels[1]);
668
}
668
}
669
 
669
 
670
static bool
670
static bool
671
gen6_emit_binding_table(struct sna *sna, uint16_t offset)
671
gen6_emit_binding_table(struct sna *sna, uint16_t offset)
672
{
672
{
673
	if (sna->render_state.gen6.surface_table == offset)
673
	if (sna->render_state.gen6.surface_table == offset)
674
		return false;
674
		return false;
675
 
675
 
676
	/* Binding table pointers */
676
	/* Binding table pointers */
677
	OUT_BATCH(GEN6_3DSTATE_BINDING_TABLE_POINTERS |
677
	OUT_BATCH(GEN6_3DSTATE_BINDING_TABLE_POINTERS |
678
		  GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS |
678
		  GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS |
679
		  (4 - 2));
679
		  (4 - 2));
680
	OUT_BATCH(0);		/* vs */
680
	OUT_BATCH(0);		/* vs */
681
	OUT_BATCH(0);		/* gs */
681
	OUT_BATCH(0);		/* gs */
682
	/* Only the PS uses the binding table */
682
	/* Only the PS uses the binding table */
683
	OUT_BATCH(offset*4);
683
	OUT_BATCH(offset*4);
684
 
684
 
685
	sna->render_state.gen6.surface_table = offset;
685
	sna->render_state.gen6.surface_table = offset;
686
	return true;
686
	return true;
687
}
687
}
688
 
688
 
689
static bool
689
static bool
690
gen6_emit_drawing_rectangle(struct sna *sna,
690
gen6_emit_drawing_rectangle(struct sna *sna,
691
			    const struct sna_composite_op *op)
691
			    const struct sna_composite_op *op)
692
{
692
{
693
	uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
693
	uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
694
	uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
694
	uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
695
 
695
 
696
	assert(!too_large(op->dst.x, op->dst.y));
696
	assert(!too_large(op->dst.x, op->dst.y));
697
	assert(!too_large(op->dst.width, op->dst.height));
697
	assert(!too_large(op->dst.width, op->dst.height));
698
 
698
 
699
	if (sna->render_state.gen6.drawrect_limit  == limit &&
699
	if (sna->render_state.gen6.drawrect_limit  == limit &&
700
	    sna->render_state.gen6.drawrect_offset == offset)
700
	    sna->render_state.gen6.drawrect_offset == offset)
701
		return false;
701
		return false;
702
 
702
 
703
	/* [DevSNB-C+{W/A}] Before any depth stall flush (including those
703
	/* [DevSNB-C+{W/A}] Before any depth stall flush (including those
704
	 * produced by non-pipelined state commands), software needs to first
704
	 * produced by non-pipelined state commands), software needs to first
705
	 * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
705
	 * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
706
	 * 0.
706
	 * 0.
707
	 *
707
	 *
708
	 * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
708
	 * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
709
	 * BEFORE the pipe-control with a post-sync op and no write-cache
709
	 * BEFORE the pipe-control with a post-sync op and no write-cache
710
	 * flushes.
710
	 * flushes.
711
	 */
711
	 */
712
	if (!sna->render_state.gen6.first_state_packet) {
712
	if (!sna->render_state.gen6.first_state_packet) {
713
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
713
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
714
	OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
714
	OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
715
		  GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
715
		  GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
716
	OUT_BATCH(0);
716
	OUT_BATCH(0);
717
	OUT_BATCH(0);
717
	OUT_BATCH(0);
718
	}
718
	}
719
 
719
 
720
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
720
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
721
	OUT_BATCH(GEN6_PIPE_CONTROL_WRITE_TIME);
721
	OUT_BATCH(GEN6_PIPE_CONTROL_WRITE_TIME);
722
	OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
722
	OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
723
				 sna->render_state.gen6.general_bo,
723
				 sna->render_state.gen6.general_bo,
724
				 I915_GEM_DOMAIN_INSTRUCTION << 16 |
724
				 I915_GEM_DOMAIN_INSTRUCTION << 16 |
725
				 I915_GEM_DOMAIN_INSTRUCTION,
725
				 I915_GEM_DOMAIN_INSTRUCTION,
726
				 64));
726
				 64));
727
	OUT_BATCH(0);
727
	OUT_BATCH(0);
728
 
728
 
729
	OUT_BATCH(GEN6_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
729
	OUT_BATCH(GEN6_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
730
	OUT_BATCH(0);
730
	OUT_BATCH(0);
731
	OUT_BATCH(limit);
731
	OUT_BATCH(limit);
732
	OUT_BATCH(offset);
732
	OUT_BATCH(offset);
733
 
733
 
734
	sna->render_state.gen6.drawrect_offset = offset;
734
	sna->render_state.gen6.drawrect_offset = offset;
735
	sna->render_state.gen6.drawrect_limit = limit;
735
	sna->render_state.gen6.drawrect_limit = limit;
736
	return true;
736
	return true;
737
}
737
}
738
 
738
 
739
static void
739
static void
740
gen6_emit_vertex_elements(struct sna *sna,
740
gen6_emit_vertex_elements(struct sna *sna,
741
			  const struct sna_composite_op *op)
741
			  const struct sna_composite_op *op)
742
{
742
{
743
	/*
743
	/*
744
	 * vertex data in vertex buffer
744
	 * vertex data in vertex buffer
745
	 *    position: (x, y)
745
	 *    position: (x, y)
746
	 *    texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0)
746
	 *    texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0)
747
	 *    texture coordinate 1 if (has_mask is true): same as above
747
	 *    texture coordinate 1 if (has_mask is true): same as above
748
	 */
748
	 */
749
	struct gen6_render_state *render = &sna->render_state.gen6;
749
	struct gen6_render_state *render = &sna->render_state.gen6;
750
	uint32_t src_format, dw;
750
	uint32_t src_format, dw;
751
	int id = GEN6_VERTEX(op->u.gen6.flags);
751
	int id = GEN6_VERTEX(op->u.gen6.flags);
752
	bool has_mask;
752
	bool has_mask;
753
 
753
 
754
	DBG(("%s: setup id=%d\n", __FUNCTION__, id));
754
	DBG(("%s: setup id=%d\n", __FUNCTION__, id));
755
 
755
 
756
	if (render->ve_id == id)
756
	if (render->ve_id == id)
757
		return;
757
		return;
758
	render->ve_id = id;
758
	render->ve_id = id;
759
 
759
 
760
	/* The VUE layout
760
	/* The VUE layout
761
	 *    dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
761
	 *    dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
762
	 *    dword 4-7: position (x, y, 1.0, 1.0),
762
	 *    dword 4-7: position (x, y, 1.0, 1.0),
763
	 *    dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0)
763
	 *    dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0)
764
	 *    dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0)
764
	 *    dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0)
765
	 *
765
	 *
766
	 * dword 4-15 are fetched from vertex buffer
766
	 * dword 4-15 are fetched from vertex buffer
767
	 */
767
	 */
768
	has_mask = (id >> 2) != 0;
768
	has_mask = (id >> 2) != 0;
769
	OUT_BATCH(GEN6_3DSTATE_VERTEX_ELEMENTS |
769
	OUT_BATCH(GEN6_3DSTATE_VERTEX_ELEMENTS |
770
		((2 * (3 + has_mask)) + 1 - 2));
770
		((2 * (3 + has_mask)) + 1 - 2));
771
 
771
 
772
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
772
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
773
		  GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT |
773
		  GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT |
774
		  0 << VE0_OFFSET_SHIFT);
774
		  0 << VE0_OFFSET_SHIFT);
775
	OUT_BATCH(GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
775
	OUT_BATCH(GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
776
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
776
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
777
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
777
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
778
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
778
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
779
 
779
 
780
	/* x,y */
780
	/* x,y */
781
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
781
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
782
		  GEN6_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
782
		  GEN6_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
783
		  0 << VE0_OFFSET_SHIFT);
783
		  0 << VE0_OFFSET_SHIFT);
784
	OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
784
	OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
785
		  GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
785
		  GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
786
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
786
		  GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
787
		  GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
787
		  GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
788
 
788
 
789
	/* u0, v0, w0 */
789
	/* u0, v0, w0 */
790
	DBG(("%s: first channel %d floats, offset=4b\n", __FUNCTION__, id & 3));
790
	DBG(("%s: first channel %d floats, offset=4b\n", __FUNCTION__, id & 3));
791
	dw = GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
791
	dw = GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
792
	switch (id & 3) {
792
	switch (id & 3) {
793
	default:
793
	default:
794
		assert(0);
794
		assert(0);
795
	case 0:
795
	case 0:
796
		src_format = GEN6_SURFACEFORMAT_R16G16_SSCALED;
796
		src_format = GEN6_SURFACEFORMAT_R16G16_SSCALED;
797
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
797
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
798
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
798
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
799
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
799
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
800
		break;
800
		break;
801
	case 1:
801
	case 1:
802
		src_format = GEN6_SURFACEFORMAT_R32_FLOAT;
802
		src_format = GEN6_SURFACEFORMAT_R32_FLOAT;
803
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
803
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
804
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
804
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
805
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
805
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
806
		break;
806
		break;
807
	case 2:
807
	case 2:
808
		src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT;
808
		src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT;
809
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
809
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
810
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
810
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
811
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
811
		dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
812
		break;
812
		break;
813
	case 3:
813
	case 3:
814
		src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT;
814
		src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT;
815
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
815
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
816
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
816
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
817
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
817
		dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
818
		break;
818
		break;
819
	}
819
	}
820
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
820
	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
821
		  src_format << VE0_FORMAT_SHIFT |
821
		  src_format << VE0_FORMAT_SHIFT |
822
		  4 << VE0_OFFSET_SHIFT);
822
		  4 << VE0_OFFSET_SHIFT);
823
	OUT_BATCH(dw);
823
	OUT_BATCH(dw);
824
 
824
 
825
	/* u1, v1, w1 */
825
	/* u1, v1, w1 */
826
	if (has_mask) {
826
	if (has_mask) {
827
		unsigned offset = 4 + ((id & 3) ?: 1) * sizeof(float);
827
		unsigned offset = 4 + ((id & 3) ?: 1) * sizeof(float);
828
		DBG(("%s: second channel %d floats, offset=%db\n", __FUNCTION__, id >> 2, offset));
828
		DBG(("%s: second channel %d floats, offset=%db\n", __FUNCTION__, id >> 2, offset));
829
		dw = GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
829
		dw = GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
830
		switch (id >> 2) {
830
		switch (id >> 2) {
831
		case 1:
831
		case 1:
832
			src_format = GEN6_SURFACEFORMAT_R32_FLOAT;
832
			src_format = GEN6_SURFACEFORMAT_R32_FLOAT;
833
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
833
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
834
			dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
834
			dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
835
			dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
835
			dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
836
			break;
836
			break;
837
		default:
837
		default:
838
			assert(0);
838
			assert(0);
839
		case 2:
839
		case 2:
840
			src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT;
840
			src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT;
841
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
841
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
842
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
842
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
843
			dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
843
			dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
844
			break;
844
			break;
845
		case 3:
845
		case 3:
846
			src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT;
846
			src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT;
847
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
847
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
848
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
848
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
849
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
849
			dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
850
			break;
850
			break;
851
		}
851
		}
852
		OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
852
		OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
853
			  src_format << VE0_FORMAT_SHIFT |
853
			  src_format << VE0_FORMAT_SHIFT |
854
			  offset << VE0_OFFSET_SHIFT);
854
			  offset << VE0_OFFSET_SHIFT);
855
		OUT_BATCH(dw);
855
		OUT_BATCH(dw);
856
	}
856
	}
857
}
857
}
858
 
858
 
859
static void
859
static void
860
gen6_emit_flush(struct sna *sna)
860
gen6_emit_flush(struct sna *sna)
861
{
861
{
862
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
862
	OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
863
	OUT_BATCH(GEN6_PIPE_CONTROL_WC_FLUSH |
863
	OUT_BATCH(GEN6_PIPE_CONTROL_WC_FLUSH |
864
		  GEN6_PIPE_CONTROL_TC_FLUSH |
864
		  GEN6_PIPE_CONTROL_TC_FLUSH |
865
		  GEN6_PIPE_CONTROL_CS_STALL);
865
		  GEN6_PIPE_CONTROL_CS_STALL);
866
	OUT_BATCH(0);
866
	OUT_BATCH(0);
867
	OUT_BATCH(0);
867
	OUT_BATCH(0);
868
}
868
}
869
 
869
 
870
static void
870
static void
871
gen6_emit_state(struct sna *sna,
871
gen6_emit_state(struct sna *sna,
872
		const struct sna_composite_op *op,
872
		const struct sna_composite_op *op,
873
		uint16_t wm_binding_table)
873
		uint16_t wm_binding_table)
874
{
874
{
875
	bool need_stall = wm_binding_table & 1;
875
	bool need_stall = wm_binding_table & 1;
876
 
876
 
877
	assert(op->dst.bo->exec);
877
	assert(op->dst.bo->exec);
878
 
878
 
879
	if (gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags)))
879
	if (gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags)))
880
		need_stall = false;
880
		need_stall = false;
881
	gen6_emit_sampler(sna, GEN6_SAMPLER(op->u.gen6.flags));
881
	gen6_emit_sampler(sna, GEN6_SAMPLER(op->u.gen6.flags));
882
	gen6_emit_sf(sna, GEN6_VERTEX(op->u.gen6.flags) >> 2);
882
	gen6_emit_sf(sna, GEN6_VERTEX(op->u.gen6.flags) >> 2);
883
	gen6_emit_wm(sna, GEN6_KERNEL(op->u.gen6.flags), GEN6_VERTEX(op->u.gen6.flags) >> 2);
883
	gen6_emit_wm(sna, GEN6_KERNEL(op->u.gen6.flags), GEN6_VERTEX(op->u.gen6.flags) >> 2);
884
	gen6_emit_vertex_elements(sna, op);
884
	gen6_emit_vertex_elements(sna, op);
885
 
885
 
886
	need_stall |= gen6_emit_binding_table(sna, wm_binding_table & ~1);
886
	need_stall |= gen6_emit_binding_table(sna, wm_binding_table & ~1);
887
	if (gen6_emit_drawing_rectangle(sna, op))
887
	if (gen6_emit_drawing_rectangle(sna, op))
888
		need_stall = false;
888
		need_stall = false;
889
	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
889
	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
890
        gen6_emit_flush(sna);
890
        gen6_emit_flush(sna);
891
        kgem_clear_dirty(&sna->kgem);
891
        kgem_clear_dirty(&sna->kgem);
892
		assert(op->dst.bo->exec);
892
		assert(op->dst.bo->exec);
893
		kgem_bo_mark_dirty(op->dst.bo);
893
		kgem_bo_mark_dirty(op->dst.bo);
894
		need_stall = false;
894
		need_stall = false;
895
	}
895
	}
896
	if (need_stall) {
896
	if (need_stall) {
897
		OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
897
		OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
898
		OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
898
		OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
899
			  GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
899
			  GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
900
		OUT_BATCH(0);
900
		OUT_BATCH(0);
901
		OUT_BATCH(0);
901
		OUT_BATCH(0);
902
	}
902
	}
903
	sna->render_state.gen6.first_state_packet = false;
903
	sna->render_state.gen6.first_state_packet = false;
904
}
904
}
905
 
905
 
906
static bool gen6_magic_ca_pass(struct sna *sna,
906
static bool gen6_magic_ca_pass(struct sna *sna,
907
			       const struct sna_composite_op *op)
907
			       const struct sna_composite_op *op)
908
{
908
{
909
	struct gen6_render_state *state = &sna->render_state.gen6;
909
	struct gen6_render_state *state = &sna->render_state.gen6;
910
 
910
 
911
	if (!op->need_magic_ca_pass)
911
	if (!op->need_magic_ca_pass)
912
		return false;
912
		return false;
913
 
913
 
914
	DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__,
914
	DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__,
915
	     sna->render.vertex_start, sna->render.vertex_index));
915
	     sna->render.vertex_start, sna->render.vertex_index));
916
 
916
 
917
	gen6_emit_flush(sna);
917
	gen6_emit_flush(sna);
918
 
918
 
919
	gen6_emit_cc(sna, gen6_get_blend(PictOpAdd, true, op->dst.format));
919
	gen6_emit_cc(sna, gen6_get_blend(PictOpAdd, true, op->dst.format));
920
	gen6_emit_wm(sna,
920
	gen6_emit_wm(sna,
921
		     gen6_choose_composite_kernel(PictOpAdd,
921
		     gen6_choose_composite_kernel(PictOpAdd,
922
						  true, true,
922
						  true, true,
923
						  op->is_affine),
923
						  op->is_affine),
924
		     true);
924
		     true);
925
 
925
 
926
	OUT_BATCH(GEN6_3DPRIMITIVE |
926
	OUT_BATCH(GEN6_3DPRIMITIVE |
927
		  GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
927
		  GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
928
		  _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
928
		  _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
929
		  0 << 9 |
929
		  0 << 9 |
930
		  4);
930
		  4);
931
	OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start);
931
	OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start);
932
	OUT_BATCH(sna->render.vertex_start);
932
	OUT_BATCH(sna->render.vertex_start);
933
	OUT_BATCH(1);	/* single instance */
933
	OUT_BATCH(1);	/* single instance */
934
	OUT_BATCH(0);	/* start instance location */
934
	OUT_BATCH(0);	/* start instance location */
935
	OUT_BATCH(0);	/* index buffer offset, ignored */
935
	OUT_BATCH(0);	/* index buffer offset, ignored */
936
 
936
 
937
	state->last_primitive = sna->kgem.nbatch;
937
	state->last_primitive = sna->kgem.nbatch;
938
	return true;
938
	return true;
939
}
939
}
940
 
940
 
941
typedef struct gen6_surface_state_padded {
941
typedef struct gen6_surface_state_padded {
942
	struct gen6_surface_state state;
942
	struct gen6_surface_state state;
943
	char pad[32 - sizeof(struct gen6_surface_state)];
943
	char pad[32 - sizeof(struct gen6_surface_state)];
944
} gen6_surface_state_padded;
944
} gen6_surface_state_padded;
945
 
945
 
946
static void null_create(struct sna_static_stream *stream)
946
static void null_create(struct sna_static_stream *stream)
947
{
947
{
948
	/* A bunch of zeros useful for legacy border color and depth-stencil */
948
	/* A bunch of zeros useful for legacy border color and depth-stencil */
949
	sna_static_stream_map(stream, 64, 64);
949
	sna_static_stream_map(stream, 64, 64);
950
}
950
}
951
 
951
 
952
static void scratch_create(struct sna_static_stream *stream)
952
static void scratch_create(struct sna_static_stream *stream)
953
{
953
{
954
	/* 64 bytes of scratch space for random writes, such as
954
	/* 64 bytes of scratch space for random writes, such as
955
	 * the pipe-control w/a.
955
	 * the pipe-control w/a.
956
	 */
956
	 */
957
	sna_static_stream_map(stream, 64, 64);
957
	sna_static_stream_map(stream, 64, 64);
958
}
958
}
959
 
959
 
960
static void
960
static void
961
sampler_state_init(struct gen6_sampler_state *sampler_state,
961
sampler_state_init(struct gen6_sampler_state *sampler_state,
962
		   sampler_filter_t filter,
962
		   sampler_filter_t filter,
963
		   sampler_extend_t extend)
963
		   sampler_extend_t extend)
964
{
964
{
965
	sampler_state->ss0.lod_preclamp = 1;	/* GL mode */
965
	sampler_state->ss0.lod_preclamp = 1;	/* GL mode */
966
 
966
 
967
	/* We use the legacy mode to get the semantics specified by
967
	/* We use the legacy mode to get the semantics specified by
968
	 * the Render extension. */
968
	 * the Render extension. */
969
	sampler_state->ss0.border_color_mode = GEN6_BORDER_COLOR_MODE_LEGACY;
969
	sampler_state->ss0.border_color_mode = GEN6_BORDER_COLOR_MODE_LEGACY;
970
 
970
 
971
	switch (filter) {
971
	switch (filter) {
972
	default:
972
	default:
973
	case SAMPLER_FILTER_NEAREST:
973
	case SAMPLER_FILTER_NEAREST:
974
		sampler_state->ss0.min_filter = GEN6_MAPFILTER_NEAREST;
974
		sampler_state->ss0.min_filter = GEN6_MAPFILTER_NEAREST;
975
		sampler_state->ss0.mag_filter = GEN6_MAPFILTER_NEAREST;
975
		sampler_state->ss0.mag_filter = GEN6_MAPFILTER_NEAREST;
976
		break;
976
		break;
977
	case SAMPLER_FILTER_BILINEAR:
977
	case SAMPLER_FILTER_BILINEAR:
978
		sampler_state->ss0.min_filter = GEN6_MAPFILTER_LINEAR;
978
		sampler_state->ss0.min_filter = GEN6_MAPFILTER_LINEAR;
979
		sampler_state->ss0.mag_filter = GEN6_MAPFILTER_LINEAR;
979
		sampler_state->ss0.mag_filter = GEN6_MAPFILTER_LINEAR;
980
		break;
980
		break;
981
	}
981
	}
982
 
982
 
983
	switch (extend) {
983
	switch (extend) {
984
	default:
984
	default:
985
	case SAMPLER_EXTEND_NONE:
985
	case SAMPLER_EXTEND_NONE:
986
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
986
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
987
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
987
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
988
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
988
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
989
		break;
989
		break;
990
	case SAMPLER_EXTEND_REPEAT:
990
	case SAMPLER_EXTEND_REPEAT:
991
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
991
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
992
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
992
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
993
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
993
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
994
		break;
994
		break;
995
	case SAMPLER_EXTEND_PAD:
995
	case SAMPLER_EXTEND_PAD:
996
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
996
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
997
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
997
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
998
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
998
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
999
		break;
999
		break;
1000
	case SAMPLER_EXTEND_REFLECT:
1000
	case SAMPLER_EXTEND_REFLECT:
1001
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1001
		sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1002
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1002
		sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1003
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1003
		sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
1004
		break;
1004
		break;
1005
	}
1005
	}
1006
}
1006
}
1007
 
1007
 
1008
static void
1008
static void
1009
sampler_copy_init(struct gen6_sampler_state *ss)
1009
sampler_copy_init(struct gen6_sampler_state *ss)
1010
{
1010
{
1011
	sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
1011
	sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
1012
	ss->ss3.non_normalized_coord = 1;
1012
	ss->ss3.non_normalized_coord = 1;
1013
 
1013
 
1014
	sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
1014
	sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
1015
}
1015
}
1016
 
1016
 
1017
static void
1017
static void
1018
sampler_fill_init(struct gen6_sampler_state *ss)
1018
sampler_fill_init(struct gen6_sampler_state *ss)
1019
{
1019
{
1020
	sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_REPEAT);
1020
	sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_REPEAT);
1021
	ss->ss3.non_normalized_coord = 1;
1021
	ss->ss3.non_normalized_coord = 1;
1022
 
1022
 
1023
	sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
1023
	sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
1024
}
1024
}
1025
 
1025
 
1026
static uint32_t
1026
static uint32_t
1027
gen6_tiling_bits(uint32_t tiling)
1027
gen6_tiling_bits(uint32_t tiling)
1028
{
1028
{
1029
	switch (tiling) {
1029
	switch (tiling) {
1030
	default: assert(0);
1030
	default: assert(0);
1031
	case I915_TILING_NONE: return 0;
1031
	case I915_TILING_NONE: return 0;
1032
	case I915_TILING_X: return GEN6_SURFACE_TILED;
1032
	case I915_TILING_X: return GEN6_SURFACE_TILED;
1033
	case I915_TILING_Y: return GEN6_SURFACE_TILED | GEN6_SURFACE_TILED_Y;
1033
	case I915_TILING_Y: return GEN6_SURFACE_TILED | GEN6_SURFACE_TILED_Y;
1034
	}
1034
	}
1035
}
1035
}
1036
 
1036
 
1037
/**
1037
/**
1038
 * Sets up the common fields for a surface state buffer for the given
1038
 * Sets up the common fields for a surface state buffer for the given
1039
 * picture in the given surface state buffer.
1039
 * picture in the given surface state buffer.
1040
 */
1040
 */
1041
static int
1041
static int
1042
gen6_bind_bo(struct sna *sna,
1042
gen6_bind_bo(struct sna *sna,
1043
         struct kgem_bo *bo,
1043
         struct kgem_bo *bo,
1044
	     uint32_t width,
1044
	     uint32_t width,
1045
	     uint32_t height,
1045
	     uint32_t height,
1046
	     uint32_t format,
1046
	     uint32_t format,
1047
	     bool is_dst)
1047
	     bool is_dst)
1048
{
1048
{
1049
	uint32_t *ss;
1049
	uint32_t *ss;
1050
	uint32_t domains;
1050
	uint32_t domains;
1051
	uint16_t offset;
1051
	uint16_t offset;
1052
	uint32_t is_scanout = is_dst && bo->scanout;
1052
	uint32_t is_scanout = is_dst && bo->scanout;
1053
 
1053
 
1054
	/* After the first bind, we manage the cache domains within the batch */
1054
	/* After the first bind, we manage the cache domains within the batch */
1055
	offset = kgem_bo_get_binding(bo, format | is_dst << 30 | is_scanout << 31);
1055
	offset = kgem_bo_get_binding(bo, format | is_dst << 30 | is_scanout << 31);
1056
	if (offset) {
1056
	if (offset) {
1057
		DBG(("[%x]  bo(handle=%d), format=%d, reuse %s binding\n",
1057
		DBG(("[%x]  bo(handle=%d), format=%d, reuse %s binding\n",
1058
		     offset, bo->handle, format,
1058
		     offset, bo->handle, format,
1059
		     is_dst ? "render" : "sampler"));
1059
		     is_dst ? "render" : "sampler"));
1060
		if (is_dst)
1060
		if (is_dst)
1061
			kgem_bo_mark_dirty(bo);
1061
			kgem_bo_mark_dirty(bo);
1062
		return offset * sizeof(uint32_t);
1062
		return offset * sizeof(uint32_t);
1063
	}
1063
	}
1064
 
1064
 
1065
	offset = sna->kgem.surface -=
1065
	offset = sna->kgem.surface -=
1066
		sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1066
		sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1067
	ss = sna->kgem.batch + offset;
1067
	ss = sna->kgem.batch + offset;
1068
	ss[0] = (GEN6_SURFACE_2D << GEN6_SURFACE_TYPE_SHIFT |
1068
	ss[0] = (GEN6_SURFACE_2D << GEN6_SURFACE_TYPE_SHIFT |
1069
		 GEN6_SURFACE_BLEND_ENABLED |
1069
		 GEN6_SURFACE_BLEND_ENABLED |
1070
		 format << GEN6_SURFACE_FORMAT_SHIFT);
1070
		 format << GEN6_SURFACE_FORMAT_SHIFT);
1071
	if (is_dst) {
1071
	if (is_dst) {
1072
		ss[0] |= GEN6_SURFACE_RC_READ_WRITE;
1072
		ss[0] |= GEN6_SURFACE_RC_READ_WRITE;
1073
		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
1073
		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
1074
	} else
1074
	} else
1075
		domains = I915_GEM_DOMAIN_SAMPLER << 16;
1075
		domains = I915_GEM_DOMAIN_SAMPLER << 16;
1076
	ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
1076
	ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
1077
	ss[2] = ((width - 1)  << GEN6_SURFACE_WIDTH_SHIFT |
1077
	ss[2] = ((width - 1)  << GEN6_SURFACE_WIDTH_SHIFT |
1078
		 (height - 1) << GEN6_SURFACE_HEIGHT_SHIFT);
1078
		 (height - 1) << GEN6_SURFACE_HEIGHT_SHIFT);
1079
	assert(bo->pitch <= (1 << 18));
1079
	assert(bo->pitch <= (1 << 18));
1080
	ss[3] = (gen6_tiling_bits(bo->tiling) |
1080
	ss[3] = (gen6_tiling_bits(bo->tiling) |
1081
		 (bo->pitch - 1) << GEN6_SURFACE_PITCH_SHIFT);
1081
		 (bo->pitch - 1) << GEN6_SURFACE_PITCH_SHIFT);
1082
	ss[4] = 0;
1082
	ss[4] = 0;
1083
	ss[5] = (is_scanout || bo->io) ? 0 : 3 << 16;
1083
	ss[5] = (is_scanout || bo->io) ? 0 : 3 << 16;
1084
 
1084
 
1085
	kgem_bo_set_binding(bo, format | is_dst << 30 | is_scanout << 31, offset);
1085
	kgem_bo_set_binding(bo, format | is_dst << 30 | is_scanout << 31, offset);
1086
 
1086
 
1087
	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
1087
	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
1088
	     offset, bo->handle, ss[1],
1088
	     offset, bo->handle, ss[1],
1089
	     format, width, height, bo->pitch, bo->tiling,
1089
	     format, width, height, bo->pitch, bo->tiling,
1090
	     domains & 0xffff ? "render" : "sampler"));
1090
	     domains & 0xffff ? "render" : "sampler"));
1091
 
1091
 
1092
	return offset * sizeof(uint32_t);
1092
	return offset * sizeof(uint32_t);
1093
}
1093
}
1094
 
1094
 
1095
static void gen6_emit_vertex_buffer(struct sna *sna,
1095
static void gen6_emit_vertex_buffer(struct sna *sna,
1096
				    const struct sna_composite_op *op)
1096
				    const struct sna_composite_op *op)
1097
{
1097
{
1098
	int id = GEN6_VERTEX(op->u.gen6.flags);
1098
	int id = GEN6_VERTEX(op->u.gen6.flags);
1099
 
1099
 
1100
	OUT_BATCH(GEN6_3DSTATE_VERTEX_BUFFERS | 3);
1100
	OUT_BATCH(GEN6_3DSTATE_VERTEX_BUFFERS | 3);
1101
	OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA |
1101
	OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA |
1102
		  4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT);
1102
		  4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT);
1103
	sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch;
1103
	sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch;
1104
	OUT_BATCH(0);
1104
	OUT_BATCH(0);
1105
	OUT_BATCH(~0); /* max address: disabled */
1105
	OUT_BATCH(~0); /* max address: disabled */
1106
	OUT_BATCH(0);
1106
	OUT_BATCH(0);
1107
 
1107
 
1108
	sna->render.vb_id |= 1 << id;
1108
	sna->render.vb_id |= 1 << id;
1109
}
1109
}
1110
 
1110
 
1111
static void gen6_emit_primitive(struct sna *sna)
1111
static void gen6_emit_primitive(struct sna *sna)
1112
{
1112
{
1113
	if (sna->kgem.nbatch == sna->render_state.gen6.last_primitive) {
1113
	if (sna->kgem.nbatch == sna->render_state.gen6.last_primitive) {
1114
		DBG(("%s: continuing previous primitive, start=%d, index=%d\n",
1114
		DBG(("%s: continuing previous primitive, start=%d, index=%d\n",
1115
		     __FUNCTION__,
1115
		     __FUNCTION__,
1116
		     sna->render.vertex_start,
1116
		     sna->render.vertex_start,
1117
		     sna->render.vertex_index));
1117
		     sna->render.vertex_index));
1118
		sna->render.vertex_offset = sna->kgem.nbatch - 5;
1118
		sna->render.vertex_offset = sna->kgem.nbatch - 5;
1119
		return;
1119
		return;
1120
	}
1120
	}
1121
 
1121
 
1122
	OUT_BATCH(GEN6_3DPRIMITIVE |
1122
	OUT_BATCH(GEN6_3DPRIMITIVE |
1123
		  GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
1123
		  GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
1124
		  _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
1124
		  _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
1125
		  0 << 9 |
1125
		  0 << 9 |
1126
		  4);
1126
		  4);
1127
	sna->render.vertex_offset = sna->kgem.nbatch;
1127
	sna->render.vertex_offset = sna->kgem.nbatch;
1128
	OUT_BATCH(0);	/* vertex count, to be filled in later */
1128
	OUT_BATCH(0);	/* vertex count, to be filled in later */
1129
	OUT_BATCH(sna->render.vertex_index);
1129
	OUT_BATCH(sna->render.vertex_index);
1130
	OUT_BATCH(1);	/* single instance */
1130
	OUT_BATCH(1);	/* single instance */
1131
	OUT_BATCH(0);	/* start instance location */
1131
	OUT_BATCH(0);	/* start instance location */
1132
	OUT_BATCH(0);	/* index buffer offset, ignored */
1132
	OUT_BATCH(0);	/* index buffer offset, ignored */
1133
	sna->render.vertex_start = sna->render.vertex_index;
1133
	sna->render.vertex_start = sna->render.vertex_index;
1134
	DBG(("%s: started new primitive: index=%d\n",
1134
	DBG(("%s: started new primitive: index=%d\n",
1135
	     __FUNCTION__, sna->render.vertex_start));
1135
	     __FUNCTION__, sna->render.vertex_start));
1136
 
1136
 
1137
	sna->render_state.gen6.last_primitive = sna->kgem.nbatch;
1137
	sna->render_state.gen6.last_primitive = sna->kgem.nbatch;
1138
}
1138
}
1139
 
1139
 
1140
static bool gen6_rectangle_begin(struct sna *sna,
1140
static bool gen6_rectangle_begin(struct sna *sna,
1141
				 const struct sna_composite_op *op)
1141
				 const struct sna_composite_op *op)
1142
{
1142
{
1143
	int id = 1 << GEN6_VERTEX(op->u.gen6.flags);
1143
	int id = 1 << GEN6_VERTEX(op->u.gen6.flags);
1144
	int ndwords;
1144
	int ndwords;
1145
 
1145
 
1146
	if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
1146
	if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
1147
		return true;
1147
		return true;
1148
 
1148
 
1149
	ndwords = op->need_magic_ca_pass ? 60 : 6;
1149
	ndwords = op->need_magic_ca_pass ? 60 : 6;
1150
	if ((sna->render.vb_id & id) == 0)
1150
	if ((sna->render.vb_id & id) == 0)
1151
		ndwords += 5;
1151
		ndwords += 5;
1152
	if (!kgem_check_batch(&sna->kgem, ndwords))
1152
	if (!kgem_check_batch(&sna->kgem, ndwords))
1153
		return false;
1153
		return false;
1154
 
1154
 
1155
	if ((sna->render.vb_id & id) == 0)
1155
	if ((sna->render.vb_id & id) == 0)
1156
		gen6_emit_vertex_buffer(sna, op);
1156
		gen6_emit_vertex_buffer(sna, op);
1157
 
1157
 
1158
	gen6_emit_primitive(sna);
1158
	gen6_emit_primitive(sna);
1159
	return true;
1159
	return true;
1160
}
1160
}
1161
 
1161
 
1162
static int gen6_get_rectangles__flush(struct sna *sna,
1162
static int gen6_get_rectangles__flush(struct sna *sna,
1163
				      const struct sna_composite_op *op)
1163
				      const struct sna_composite_op *op)
1164
{
1164
{
1165
	/* Preventing discarding new vbo after lock contention */
1165
	/* Preventing discarding new vbo after lock contention */
1166
	if (sna_vertex_wait__locked(&sna->render)) {
1166
	if (sna_vertex_wait__locked(&sna->render)) {
1167
		int rem = vertex_space(sna);
1167
		int rem = vertex_space(sna);
1168
		if (rem > op->floats_per_rect)
1168
		if (rem > op->floats_per_rect)
1169
			return rem;
1169
			return rem;
1170
	}
1170
	}
1171
 
1171
 
1172
	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5))
1172
	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5))
1173
		return 0;
1173
		return 0;
1174
	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
1174
	if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
1175
		return 0;
1175
		return 0;
1176
 
1176
 
1177
	if (sna->render.vertex_offset) {
1177
	if (sna->render.vertex_offset) {
1178
		gen4_vertex_flush(sna);
1178
		gen4_vertex_flush(sna);
1179
		if (gen6_magic_ca_pass(sna, op)) {
1179
		if (gen6_magic_ca_pass(sna, op)) {
1180
			gen6_emit_flush(sna);
1180
			gen6_emit_flush(sna);
1181
			gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags));
1181
			gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags));
1182
			gen6_emit_wm(sna,
1182
			gen6_emit_wm(sna,
1183
				     GEN6_KERNEL(op->u.gen6.flags),
1183
				     GEN6_KERNEL(op->u.gen6.flags),
1184
				     GEN6_VERTEX(op->u.gen6.flags) >> 2);
1184
				     GEN6_VERTEX(op->u.gen6.flags) >> 2);
1185
		}
1185
		}
1186
	}
1186
	}
1187
 
1187
 
1188
	return gen4_vertex_finish(sna);
1188
	return gen4_vertex_finish(sna);
1189
}
1189
}
1190
 
1190
 
1191
inline static int gen6_get_rectangles(struct sna *sna,
1191
inline static int gen6_get_rectangles(struct sna *sna,
1192
				      const struct sna_composite_op *op,
1192
				      const struct sna_composite_op *op,
1193
				      int want,
1193
				      int want,
1194
				      void (*emit_state)(struct sna *, const struct sna_composite_op *op))
1194
				      void (*emit_state)(struct sna *, const struct sna_composite_op *op))
1195
{
1195
{
1196
	int rem;
1196
	int rem;
1197
 
1197
 
1198
	assert(want);
1198
	assert(want);
1199
 
1199
 
1200
start:
1200
start:
1201
	rem = vertex_space(sna);
1201
	rem = vertex_space(sna);
1202
	if (unlikely(rem < op->floats_per_rect)) {
1202
	if (unlikely(rem < op->floats_per_rect)) {
1203
		DBG(("flushing vbo for %s: %d < %d\n",
1203
		DBG(("flushing vbo for %s: %d < %d\n",
1204
		     __FUNCTION__, rem, op->floats_per_rect));
1204
		     __FUNCTION__, rem, op->floats_per_rect));
1205
		rem = gen6_get_rectangles__flush(sna, op);
1205
		rem = gen6_get_rectangles__flush(sna, op);
1206
		if (unlikely(rem == 0))
1206
		if (unlikely(rem == 0))
1207
			goto flush;
1207
			goto flush;
1208
	}
1208
	}
1209
 
1209
 
1210
	if (unlikely(sna->render.vertex_offset == 0)) {
1210
	if (unlikely(sna->render.vertex_offset == 0)) {
1211
		if (!gen6_rectangle_begin(sna, op))
1211
		if (!gen6_rectangle_begin(sna, op))
1212
		goto flush;
1212
		goto flush;
1213
		else
1213
		else
1214
			goto start;
1214
			goto start;
1215
	}
1215
	}
1216
 
1216
 
1217
	assert(rem <= vertex_space(sna));
1217
	assert(rem <= vertex_space(sna));
1218
	assert(op->floats_per_rect <= rem);
1218
	assert(op->floats_per_rect <= rem);
1219
	if (want > 1 && want * op->floats_per_rect > rem)
1219
	if (want > 1 && want * op->floats_per_rect > rem)
1220
		want = rem / op->floats_per_rect;
1220
		want = rem / op->floats_per_rect;
1221
 
1221
 
1222
	assert(want > 0);
1222
	assert(want > 0);
1223
	sna->render.vertex_index += 3*want;
1223
	sna->render.vertex_index += 3*want;
1224
	return want;
1224
	return want;
1225
 
1225
 
1226
flush:
1226
flush:
1227
	if (sna->render.vertex_offset) {
1227
	if (sna->render.vertex_offset) {
1228
		gen4_vertex_flush(sna);
1228
		gen4_vertex_flush(sna);
1229
		gen6_magic_ca_pass(sna, op);
1229
		gen6_magic_ca_pass(sna, op);
1230
	}
1230
	}
1231
	sna_vertex_wait__locked(&sna->render);
1231
	sna_vertex_wait__locked(&sna->render);
1232
	_kgem_submit(&sna->kgem);
1232
	_kgem_submit(&sna->kgem);
1233
	emit_state(sna, op);
1233
	emit_state(sna, op);
1234
	goto start;
1234
	goto start;
1235
}
1235
}
1236
 
1236
 
1237
inline static uint32_t *gen6_composite_get_binding_table(struct sna *sna,
1237
inline static uint32_t *gen6_composite_get_binding_table(struct sna *sna,
1238
							 uint16_t *offset)
1238
							 uint16_t *offset)
1239
{
1239
{
1240
	uint32_t *table;
1240
	uint32_t *table;
1241
 
1241
 
1242
	sna->kgem.surface -=
1242
	sna->kgem.surface -=
1243
		sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1243
		sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1244
	/* Clear all surplus entries to zero in case of prefetch */
1244
	/* Clear all surplus entries to zero in case of prefetch */
1245
	table = memset(sna->kgem.batch + sna->kgem.surface,
1245
	table = memset(sna->kgem.batch + sna->kgem.surface,
1246
		       0, sizeof(struct gen6_surface_state_padded));
1246
		       0, sizeof(struct gen6_surface_state_padded));
1247
 
1247
 
1248
	DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
1248
	DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
1249
 
1249
 
1250
	*offset = sna->kgem.surface;
1250
	*offset = sna->kgem.surface;
1251
	return table;
1251
	return table;
1252
}
1252
}
1253
 
1253
 
1254
static bool
1254
static bool
1255
gen6_get_batch(struct sna *sna, const struct sna_composite_op *op)
1255
gen6_get_batch(struct sna *sna, const struct sna_composite_op *op)
1256
{
1256
{
1257
	kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
1257
	kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
1258
 
1258
 
1259
	if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) {
1259
	if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) {
1260
		DBG(("%s: flushing batch: %d < %d+%d\n",
1260
		DBG(("%s: flushing batch: %d < %d+%d\n",
1261
		     __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
1261
		     __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
1262
		     150, 4*8));
1262
		     150, 4*8));
1263
		kgem_submit(&sna->kgem);
1263
		kgem_submit(&sna->kgem);
1264
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1264
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1265
	}
1265
	}
1266
 
1266
 
1267
	if (sna->render_state.gen6.needs_invariant)
1267
	if (sna->render_state.gen6.needs_invariant)
1268
		gen6_emit_invariant(sna);
1268
		gen6_emit_invariant(sna);
1269
 
1269
 
1270
	return kgem_bo_is_dirty(op->dst.bo);
1270
	return kgem_bo_is_dirty(op->dst.bo);
1271
}
1271
}
1272
 
1272
 
1273
static void gen6_emit_composite_state(struct sna *sna,
1273
static void gen6_emit_composite_state(struct sna *sna,
1274
                      const struct sna_composite_op *op)
1274
                      const struct sna_composite_op *op)
1275
{
1275
{
1276
    uint32_t *binding_table;
1276
    uint32_t *binding_table;
1277
    uint16_t offset;
1277
    uint16_t offset;
1278
    bool dirty;
1278
    bool dirty;
1279
 
1279
 
1280
	dirty = gen6_get_batch(sna, op);
1280
	dirty = gen6_get_batch(sna, op);
1281
 
1281
 
1282
    binding_table = gen6_composite_get_binding_table(sna, &offset);
1282
    binding_table = gen6_composite_get_binding_table(sna, &offset);
1283
 
1283
 
1284
    binding_table[0] =
1284
    binding_table[0] =
1285
        gen6_bind_bo(sna,
1285
        gen6_bind_bo(sna,
1286
                op->dst.bo, op->dst.width, op->dst.height,
1286
                op->dst.bo, op->dst.width, op->dst.height,
1287
			    gen6_get_dest_format(op->dst.format),
1287
			    gen6_get_dest_format(op->dst.format),
1288
			    true);
1288
			    true);
1289
    binding_table[1] =
1289
    binding_table[1] =
1290
        gen6_bind_bo(sna,
1290
        gen6_bind_bo(sna,
1291
                 op->src.bo, op->src.width, op->src.height,
1291
                 op->src.bo, op->src.width, op->src.height,
1292
                 op->src.card_format,
1292
                 op->src.card_format,
1293
			     false);
1293
			     false);
1294
    if (op->mask.bo) {
1294
    if (op->mask.bo) {
1295
        binding_table[2] =
1295
        binding_table[2] =
1296
            gen6_bind_bo(sna,
1296
            gen6_bind_bo(sna,
1297
                     op->mask.bo,
1297
                     op->mask.bo,
1298
                     op->mask.width,
1298
                     op->mask.width,
1299
                     op->mask.height,
1299
                     op->mask.height,
1300
                     op->mask.card_format,
1300
                     op->mask.card_format,
1301
				     false);
1301
				     false);
1302
    }
1302
    }
1303
 
1303
 
1304
    if (sna->kgem.surface == offset &&
1304
    if (sna->kgem.surface == offset &&
1305
        *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table &&
1305
        *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table &&
1306
        (op->mask.bo == NULL ||
1306
        (op->mask.bo == NULL ||
1307
         sna->kgem.batch[sna->render_state.gen6.surface_table+2] == binding_table[2])) {
1307
         sna->kgem.batch[sna->render_state.gen6.surface_table+2] == binding_table[2])) {
1308
        sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1308
        sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1309
        offset = sna->render_state.gen6.surface_table;
1309
        offset = sna->render_state.gen6.surface_table;
1310
    }
1310
    }
1311
 
1311
 
1312
    gen6_emit_state(sna, op, offset | dirty);
1312
    gen6_emit_state(sna, op, offset | dirty);
1313
}
1313
}
1314
 
1314
 
1315
static void
1315
static void
1316
gen6_align_vertex(struct sna *sna, const struct sna_composite_op *op)
1316
gen6_align_vertex(struct sna *sna, const struct sna_composite_op *op)
1317
{
1317
{
1318
	assert (sna->render.vertex_offset == 0);
1318
	assert (sna->render.vertex_offset == 0);
1319
	if (op->floats_per_vertex != sna->render_state.gen6.floats_per_vertex) {
1319
	if (op->floats_per_vertex != sna->render_state.gen6.floats_per_vertex) {
1320
		if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
1320
		if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
1321
			gen4_vertex_finish(sna);
1321
			gen4_vertex_finish(sna);
1322
 
1322
 
1323
		DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
1323
		DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
1324
		     sna->render_state.gen6.floats_per_vertex,
1324
		     sna->render_state.gen6.floats_per_vertex,
1325
		     op->floats_per_vertex,
1325
		     op->floats_per_vertex,
1326
		     sna->render.vertex_index,
1326
		     sna->render.vertex_index,
1327
		     (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
1327
		     (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
1328
		sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
1328
		sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
1329
		sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
1329
		sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
1330
		sna->render_state.gen6.floats_per_vertex = op->floats_per_vertex;
1330
		sna->render_state.gen6.floats_per_vertex = op->floats_per_vertex;
1331
	}
1331
	}
1332
	assert((sna->render.vertex_used % op->floats_per_vertex) == 0);
1332
	assert((sna->render.vertex_used % op->floats_per_vertex) == 0);
1333
}
1333
}
1334
 
1334
 
1335
fastcall static void
1335
fastcall static void
1336
gen6_render_composite_blt(struct sna *sna,
1336
gen6_render_composite_blt(struct sna *sna,
1337
			  const struct sna_composite_op *op,
1337
			  const struct sna_composite_op *op,
1338
			  const struct sna_composite_rectangles *r)
1338
			  const struct sna_composite_rectangles *r)
1339
{
1339
{
1340
	gen6_get_rectangles(sna, op, 1, gen6_emit_composite_state);
1340
	gen6_get_rectangles(sna, op, 1, gen6_emit_composite_state);
1341
	op->prim_emit(sna, op, r);
1341
	op->prim_emit(sna, op, r);
1342
}
1342
}
1343
 
1343
 
1344
#if 0
1344
#if 0
1345
fastcall static void
1345
fastcall static void
1346
gen6_render_composite_box(struct sna *sna,
1346
gen6_render_composite_box(struct sna *sna,
1347
			  const struct sna_composite_op *op,
1347
			  const struct sna_composite_op *op,
1348
			  const BoxRec *box)
1348
			  const BoxRec *box)
1349
{
1349
{
1350
	struct sna_composite_rectangles r;
1350
	struct sna_composite_rectangles r;
1351
 
1351
 
1352
	gen6_get_rectangles(sna, op, 1, gen6_emit_composite_state);
1352
	gen6_get_rectangles(sna, op, 1, gen6_emit_composite_state);
1353
 
1353
 
1354
	DBG(("  %s: (%d, %d), (%d, %d)\n",
1354
	DBG(("  %s: (%d, %d), (%d, %d)\n",
1355
	     __FUNCTION__,
1355
	     __FUNCTION__,
1356
	     box->x1, box->y1, box->x2, box->y2));
1356
	     box->x1, box->y1, box->x2, box->y2));
1357
 
1357
 
1358
	r.dst.x = box->x1;
1358
	r.dst.x = box->x1;
1359
	r.dst.y = box->y1;
1359
	r.dst.y = box->y1;
1360
	r.width  = box->x2 - box->x1;
1360
	r.width  = box->x2 - box->x1;
1361
	r.height = box->y2 - box->y1;
1361
	r.height = box->y2 - box->y1;
1362
	r.src = r.mask = r.dst;
1362
	r.src = r.mask = r.dst;
1363
 
1363
 
1364
	op->prim_emit(sna, op, &r);
1364
	op->prim_emit(sna, op, &r);
1365
}
1365
}
1366
 
1366
 
1367
static void
1367
static void
1368
gen6_render_composite_boxes__blt(struct sna *sna,
1368
gen6_render_composite_boxes__blt(struct sna *sna,
1369
				 const struct sna_composite_op *op,
1369
				 const struct sna_composite_op *op,
1370
				 const BoxRec *box, int nbox)
1370
				 const BoxRec *box, int nbox)
1371
{
1371
{
1372
	DBG(("composite_boxes(%d)\n", nbox));
1372
	DBG(("composite_boxes(%d)\n", nbox));
1373
 
1373
 
1374
	do {
1374
	do {
1375
		int nbox_this_time;
1375
		int nbox_this_time;
1376
 
1376
 
1377
		nbox_this_time = gen6_get_rectangles(sna, op, nbox,
1377
		nbox_this_time = gen6_get_rectangles(sna, op, nbox,
1378
						     gen6_emit_composite_state);
1378
						     gen6_emit_composite_state);
1379
		nbox -= nbox_this_time;
1379
		nbox -= nbox_this_time;
1380
 
1380
 
1381
		do {
1381
		do {
1382
			struct sna_composite_rectangles r;
1382
			struct sna_composite_rectangles r;
1383
 
1383
 
1384
			DBG(("  %s: (%d, %d), (%d, %d)\n",
1384
			DBG(("  %s: (%d, %d), (%d, %d)\n",
1385
			     __FUNCTION__,
1385
			     __FUNCTION__,
1386
			     box->x1, box->y1, box->x2, box->y2));
1386
			     box->x1, box->y1, box->x2, box->y2));
1387
 
1387
 
1388
			r.dst.x = box->x1;
1388
			r.dst.x = box->x1;
1389
			r.dst.y = box->y1;
1389
			r.dst.y = box->y1;
1390
			r.width  = box->x2 - box->x1;
1390
			r.width  = box->x2 - box->x1;
1391
			r.height = box->y2 - box->y1;
1391
			r.height = box->y2 - box->y1;
1392
			r.src = r.mask = r.dst;
1392
			r.src = r.mask = r.dst;
1393
 
1393
 
1394
			op->prim_emit(sna, op, &r);
1394
			op->prim_emit(sna, op, &r);
1395
			box++;
1395
			box++;
1396
		} while (--nbox_this_time);
1396
		} while (--nbox_this_time);
1397
	} while (nbox);
1397
	} while (nbox);
1398
}
1398
}
1399
 
1399
 
1400
static void
1400
static void
1401
gen6_render_composite_boxes(struct sna *sna,
1401
gen6_render_composite_boxes(struct sna *sna,
1402
			    const struct sna_composite_op *op,
1402
			    const struct sna_composite_op *op,
1403
			    const BoxRec *box, int nbox)
1403
			    const BoxRec *box, int nbox)
1404
{
1404
{
1405
	DBG(("%s: nbox=%d\n", __FUNCTION__, nbox));
1405
	DBG(("%s: nbox=%d\n", __FUNCTION__, nbox));
1406
 
1406
 
1407
	do {
1407
	do {
1408
		int nbox_this_time;
1408
		int nbox_this_time;
1409
		float *v;
1409
		float *v;
1410
 
1410
 
1411
		nbox_this_time = gen6_get_rectangles(sna, op, nbox,
1411
		nbox_this_time = gen6_get_rectangles(sna, op, nbox,
1412
						     gen6_emit_composite_state);
1412
						     gen6_emit_composite_state);
1413
		assert(nbox_this_time);
1413
		assert(nbox_this_time);
1414
		nbox -= nbox_this_time;
1414
		nbox -= nbox_this_time;
1415
 
1415
 
1416
		v = sna->render.vertices + sna->render.vertex_used;
1416
		v = sna->render.vertices + sna->render.vertex_used;
1417
		sna->render.vertex_used += nbox_this_time * op->floats_per_rect;
1417
		sna->render.vertex_used += nbox_this_time * op->floats_per_rect;
1418
 
1418
 
1419
		op->emit_boxes(op, box, nbox_this_time, v);
1419
		op->emit_boxes(op, box, nbox_this_time, v);
1420
		box += nbox_this_time;
1420
		box += nbox_this_time;
1421
	} while (nbox);
1421
	} while (nbox);
1422
}
1422
}
1423
 
1423
 
1424
static void
1424
static void
1425
gen6_render_composite_boxes__thread(struct sna *sna,
1425
gen6_render_composite_boxes__thread(struct sna *sna,
1426
				    const struct sna_composite_op *op,
1426
				    const struct sna_composite_op *op,
1427
				    const BoxRec *box, int nbox)
1427
				    const BoxRec *box, int nbox)
1428
{
1428
{
1429
	DBG(("%s: nbox=%d\n", __FUNCTION__, nbox));
1429
	DBG(("%s: nbox=%d\n", __FUNCTION__, nbox));
1430
 
1430
 
1431
	sna_vertex_lock(&sna->render);
1431
	sna_vertex_lock(&sna->render);
1432
	do {
1432
	do {
1433
		int nbox_this_time;
1433
		int nbox_this_time;
1434
		float *v;
1434
		float *v;
1435
 
1435
 
1436
		nbox_this_time = gen6_get_rectangles(sna, op, nbox,
1436
		nbox_this_time = gen6_get_rectangles(sna, op, nbox,
1437
						     gen6_emit_composite_state);
1437
						     gen6_emit_composite_state);
1438
		assert(nbox_this_time);
1438
		assert(nbox_this_time);
1439
		nbox -= nbox_this_time;
1439
		nbox -= nbox_this_time;
1440
 
1440
 
1441
		v = sna->render.vertices + sna->render.vertex_used;
1441
		v = sna->render.vertices + sna->render.vertex_used;
1442
		sna->render.vertex_used += nbox_this_time * op->floats_per_rect;
1442
		sna->render.vertex_used += nbox_this_time * op->floats_per_rect;
1443
 
1443
 
1444
		sna_vertex_acquire__locked(&sna->render);
1444
		sna_vertex_acquire__locked(&sna->render);
1445
		sna_vertex_unlock(&sna->render);
1445
		sna_vertex_unlock(&sna->render);
1446
 
1446
 
1447
		op->emit_boxes(op, box, nbox_this_time, v);
1447
		op->emit_boxes(op, box, nbox_this_time, v);
1448
		box += nbox_this_time;
1448
		box += nbox_this_time;
1449
 
1449
 
1450
		sna_vertex_lock(&sna->render);
1450
		sna_vertex_lock(&sna->render);
1451
		sna_vertex_release__locked(&sna->render);
1451
		sna_vertex_release__locked(&sna->render);
1452
	} while (nbox);
1452
	} while (nbox);
1453
	sna_vertex_unlock(&sna->render);
1453
	sna_vertex_unlock(&sna->render);
1454
}
1454
}
1455
#endif
1455
#endif
1456
 
1456
 
1457
#ifndef MAX
1457
#ifndef MAX
1458
#define MAX(a,b) ((a) > (b) ? (a) : (b))
1458
#define MAX(a,b) ((a) > (b) ? (a) : (b))
1459
#endif
1459
#endif
1460
 
1460
 
1461
static uint32_t
1461
static uint32_t
1462
gen6_composite_create_blend_state(struct sna_static_stream *stream)
1462
gen6_composite_create_blend_state(struct sna_static_stream *stream)
1463
{
1463
{
1464
	char *base, *ptr;
1464
	char *base, *ptr;
1465
	int src, dst;
1465
	int src, dst;
1466
 
1466
 
1467
	base = sna_static_stream_map(stream,
1467
	base = sna_static_stream_map(stream,
1468
				     GEN6_BLENDFACTOR_COUNT * GEN6_BLENDFACTOR_COUNT * GEN6_BLEND_STATE_PADDED_SIZE,
1468
				     GEN6_BLENDFACTOR_COUNT * GEN6_BLENDFACTOR_COUNT * GEN6_BLEND_STATE_PADDED_SIZE,
1469
				     64);
1469
				     64);
1470
 
1470
 
1471
	ptr = base;
1471
	ptr = base;
1472
	for (src = 0; src < GEN6_BLENDFACTOR_COUNT; src++) {
1472
	for (src = 0; src < GEN6_BLENDFACTOR_COUNT; src++) {
1473
		for (dst= 0; dst < GEN6_BLENDFACTOR_COUNT; dst++) {
1473
		for (dst= 0; dst < GEN6_BLENDFACTOR_COUNT; dst++) {
1474
			struct gen6_blend_state *blend =
1474
			struct gen6_blend_state *blend =
1475
				(struct gen6_blend_state *)ptr;
1475
				(struct gen6_blend_state *)ptr;
1476
 
1476
 
1477
			blend->blend0.dest_blend_factor = dst;
1477
			blend->blend0.dest_blend_factor = dst;
1478
			blend->blend0.source_blend_factor = src;
1478
			blend->blend0.source_blend_factor = src;
1479
			blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD;
1479
			blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD;
1480
			blend->blend0.blend_enable =
1480
			blend->blend0.blend_enable =
1481
				!(dst == GEN6_BLENDFACTOR_ZERO && src == GEN6_BLENDFACTOR_ONE);
1481
				!(dst == GEN6_BLENDFACTOR_ZERO && src == GEN6_BLENDFACTOR_ONE);
1482
 
1482
 
1483
			blend->blend1.post_blend_clamp_enable = 1;
1483
			blend->blend1.post_blend_clamp_enable = 1;
1484
			blend->blend1.pre_blend_clamp_enable = 1;
1484
			blend->blend1.pre_blend_clamp_enable = 1;
1485
 
1485
 
1486
			ptr += GEN6_BLEND_STATE_PADDED_SIZE;
1486
			ptr += GEN6_BLEND_STATE_PADDED_SIZE;
1487
		}
1487
		}
1488
	}
1488
	}
1489
 
1489
 
1490
	return sna_static_stream_offsetof(stream, base);
1490
	return sna_static_stream_offsetof(stream, base);
1491
}
1491
}
1492
 
1492
 
1493
#if 0
1493
#if 0
1494
static uint32_t gen6_bind_video_source(struct sna *sna,
1494
static uint32_t gen6_bind_video_source(struct sna *sna,
1495
				       struct kgem_bo *src_bo,
1495
				       struct kgem_bo *src_bo,
1496
				       uint32_t src_offset,
1496
				       uint32_t src_offset,
1497
				       int src_width,
1497
				       int src_width,
1498
				       int src_height,
1498
				       int src_height,
1499
				       int src_pitch,
1499
				       int src_pitch,
1500
				       uint32_t src_surf_format)
1500
				       uint32_t src_surf_format)
1501
{
1501
{
1502
	struct gen6_surface_state *ss;
1502
	struct gen6_surface_state *ss;
1503
 
1503
 
1504
	sna->kgem.surface -= sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1504
	sna->kgem.surface -= sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
1505
 
1505
 
1506
	ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss));
1506
	ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss));
1507
	ss->ss0.surface_type = GEN6_SURFACE_2D;
1507
	ss->ss0.surface_type = GEN6_SURFACE_2D;
1508
	ss->ss0.surface_format = src_surf_format;
1508
	ss->ss0.surface_format = src_surf_format;
1509
 
1509
 
1510
	ss->ss1.base_addr =
1510
	ss->ss1.base_addr =
1511
		kgem_add_reloc(&sna->kgem,
1511
		kgem_add_reloc(&sna->kgem,
1512
			       sna->kgem.surface + 1,
1512
			       sna->kgem.surface + 1,
1513
			       src_bo,
1513
			       src_bo,
1514
			       I915_GEM_DOMAIN_SAMPLER << 16,
1514
			       I915_GEM_DOMAIN_SAMPLER << 16,
1515
			       src_offset);
1515
			       src_offset);
1516
 
1516
 
1517
	ss->ss2.width  = src_width - 1;
1517
	ss->ss2.width  = src_width - 1;
1518
	ss->ss2.height = src_height - 1;
1518
	ss->ss2.height = src_height - 1;
1519
	ss->ss3.pitch  = src_pitch - 1;
1519
	ss->ss3.pitch  = src_pitch - 1;
1520
 
1520
 
1521
	return sna->kgem.surface * sizeof(uint32_t);
1521
	return sna->kgem.surface * sizeof(uint32_t);
1522
}
1522
}
1523
 
1523
 
1524
static void gen6_emit_video_state(struct sna *sna,
1524
static void gen6_emit_video_state(struct sna *sna,
1525
				  const struct sna_composite_op *op)
1525
				  const struct sna_composite_op *op)
1526
{
1526
{
1527
	struct sna_video_frame *frame = op->priv;
1527
	struct sna_video_frame *frame = op->priv;
1528
	uint32_t src_surf_format;
1528
	uint32_t src_surf_format;
1529
	uint32_t src_surf_base[6];
1529
	uint32_t src_surf_base[6];
1530
	int src_width[6];
1530
	int src_width[6];
1531
	int src_height[6];
1531
	int src_height[6];
1532
	int src_pitch[6];
1532
	int src_pitch[6];
1533
	uint32_t *binding_table;
1533
	uint32_t *binding_table;
1534
	uint16_t offset;
1534
	uint16_t offset;
1535
	bool dirty;
1535
	bool dirty;
1536
	int n_src, n;
1536
	int n_src, n;
1537
 
1537
 
1538
	dirty = gen6_get_batch(sna, op);
1538
	dirty = gen6_get_batch(sna, op);
1539
 
1539
 
1540
	src_surf_base[0] = 0;
1540
	src_surf_base[0] = 0;
1541
	src_surf_base[1] = 0;
1541
	src_surf_base[1] = 0;
1542
	src_surf_base[2] = frame->VBufOffset;
1542
	src_surf_base[2] = frame->VBufOffset;
1543
	src_surf_base[3] = frame->VBufOffset;
1543
	src_surf_base[3] = frame->VBufOffset;
1544
	src_surf_base[4] = frame->UBufOffset;
1544
	src_surf_base[4] = frame->UBufOffset;
1545
	src_surf_base[5] = frame->UBufOffset;
1545
	src_surf_base[5] = frame->UBufOffset;
1546
 
1546
 
1547
	if (is_planar_fourcc(frame->id)) {
1547
	if (is_planar_fourcc(frame->id)) {
1548
		src_surf_format = GEN6_SURFACEFORMAT_R8_UNORM;
1548
		src_surf_format = GEN6_SURFACEFORMAT_R8_UNORM;
1549
		src_width[1]  = src_width[0]  = frame->width;
1549
		src_width[1]  = src_width[0]  = frame->width;
1550
		src_height[1] = src_height[0] = frame->height;
1550
		src_height[1] = src_height[0] = frame->height;
1551
		src_pitch[1]  = src_pitch[0]  = frame->pitch[1];
1551
		src_pitch[1]  = src_pitch[0]  = frame->pitch[1];
1552
		src_width[4]  = src_width[5]  = src_width[2]  = src_width[3] =
1552
		src_width[4]  = src_width[5]  = src_width[2]  = src_width[3] =
1553
			frame->width / 2;
1553
			frame->width / 2;
1554
		src_height[4] = src_height[5] = src_height[2] = src_height[3] =
1554
		src_height[4] = src_height[5] = src_height[2] = src_height[3] =
1555
			frame->height / 2;
1555
			frame->height / 2;
1556
		src_pitch[4]  = src_pitch[5]  = src_pitch[2]  = src_pitch[3] =
1556
		src_pitch[4]  = src_pitch[5]  = src_pitch[2]  = src_pitch[3] =
1557
			frame->pitch[0];
1557
			frame->pitch[0];
1558
		n_src = 6;
1558
		n_src = 6;
1559
	} else {
1559
	} else {
1560
		if (frame->id == FOURCC_UYVY)
1560
		if (frame->id == FOURCC_UYVY)
1561
			src_surf_format = GEN6_SURFACEFORMAT_YCRCB_SWAPY;
1561
			src_surf_format = GEN6_SURFACEFORMAT_YCRCB_SWAPY;
1562
		else
1562
		else
1563
			src_surf_format = GEN6_SURFACEFORMAT_YCRCB_NORMAL;
1563
			src_surf_format = GEN6_SURFACEFORMAT_YCRCB_NORMAL;
1564
 
1564
 
1565
		src_width[0]  = frame->width;
1565
		src_width[0]  = frame->width;
1566
		src_height[0] = frame->height;
1566
		src_height[0] = frame->height;
1567
		src_pitch[0]  = frame->pitch[0];
1567
		src_pitch[0]  = frame->pitch[0];
1568
		n_src = 1;
1568
		n_src = 1;
1569
	}
1569
	}
1570
 
1570
 
1571
	binding_table = gen6_composite_get_binding_table(sna, &offset);
1571
	binding_table = gen6_composite_get_binding_table(sna, &offset);
1572
 
1572
 
1573
	binding_table[0] =
1573
	binding_table[0] =
1574
		gen6_bind_bo(sna,
1574
		gen6_bind_bo(sna,
1575
			     op->dst.bo, op->dst.width, op->dst.height,
1575
			     op->dst.bo, op->dst.width, op->dst.height,
1576
			     gen6_get_dest_format(op->dst.format),
1576
			     gen6_get_dest_format(op->dst.format),
1577
			     true);
1577
			     true);
1578
	for (n = 0; n < n_src; n++) {
1578
	for (n = 0; n < n_src; n++) {
1579
		binding_table[1+n] =
1579
		binding_table[1+n] =
1580
			gen6_bind_video_source(sna,
1580
			gen6_bind_video_source(sna,
1581
					       frame->bo,
1581
					       frame->bo,
1582
					       src_surf_base[n],
1582
					       src_surf_base[n],
1583
					       src_width[n],
1583
					       src_width[n],
1584
					       src_height[n],
1584
					       src_height[n],
1585
					       src_pitch[n],
1585
					       src_pitch[n],
1586
					       src_surf_format);
1586
					       src_surf_format);
1587
	}
1587
	}
1588
 
1588
 
1589
	gen6_emit_state(sna, op, offset | dirty);
1589
	gen6_emit_state(sna, op, offset | dirty);
1590
}
1590
}
1591
 
1591
 
1592
static bool
1592
static bool
1593
gen6_render_video(struct sna *sna,
1593
gen6_render_video(struct sna *sna,
1594
		  struct sna_video *video,
1594
		  struct sna_video *video,
1595
		  struct sna_video_frame *frame,
1595
		  struct sna_video_frame *frame,
1596
		  RegionPtr dstRegion,
1596
		  RegionPtr dstRegion,
1597
		  PixmapPtr pixmap)
1597
		  PixmapPtr pixmap)
1598
{
1598
{
1599
	struct sna_composite_op tmp;
1599
	struct sna_composite_op tmp;
1600
	int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1;
1600
	int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1;
1601
	int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1;
1601
	int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1;
1602
	int src_width = frame->src.x2 - frame->src.x1;
1602
	int src_width = frame->src.x2 - frame->src.x1;
1603
	int src_height = frame->src.y2 - frame->src.y1;
1603
	int src_height = frame->src.y2 - frame->src.y1;
1604
	float src_offset_x, src_offset_y;
1604
	float src_offset_x, src_offset_y;
1605
	float src_scale_x, src_scale_y;
1605
	float src_scale_x, src_scale_y;
1606
	int nbox, pix_xoff, pix_yoff;
1606
	int nbox, pix_xoff, pix_yoff;
1607
	struct sna_pixmap *priv;
1607
	struct sna_pixmap *priv;
1608
	unsigned filter;
1608
	unsigned filter;
1609
	BoxPtr box;
1609
	BoxPtr box;
1610
 
1610
 
1611
	DBG(("%s: src=(%d, %d), dst=(%d, %d), %ldx[(%d, %d), (%d, %d)...]\n",
1611
	DBG(("%s: src=(%d, %d), dst=(%d, %d), %ldx[(%d, %d), (%d, %d)...]\n",
1612
	     __FUNCTION__,
1612
	     __FUNCTION__,
1613
	     src_width, src_height, dst_width, dst_height,
1613
	     src_width, src_height, dst_width, dst_height,
1614
	     (long)REGION_NUM_RECTS(dstRegion),
1614
	     (long)REGION_NUM_RECTS(dstRegion),
1615
	     REGION_EXTENTS(NULL, dstRegion)->x1,
1615
	     REGION_EXTENTS(NULL, dstRegion)->x1,
1616
	     REGION_EXTENTS(NULL, dstRegion)->y1,
1616
	     REGION_EXTENTS(NULL, dstRegion)->y1,
1617
	     REGION_EXTENTS(NULL, dstRegion)->x2,
1617
	     REGION_EXTENTS(NULL, dstRegion)->x2,
1618
	     REGION_EXTENTS(NULL, dstRegion)->y2));
1618
	     REGION_EXTENTS(NULL, dstRegion)->y2));
1619
 
1619
 
1620
	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
1620
	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
1621
	if (priv == NULL)
1621
	if (priv == NULL)
1622
		return false;
1622
		return false;
1623
 
1623
 
1624
	memset(&tmp, 0, sizeof(tmp));
1624
	memset(&tmp, 0, sizeof(tmp));
1625
 
1625
 
1626
	tmp.dst.pixmap = pixmap;
1626
	tmp.dst.pixmap = pixmap;
1627
	tmp.dst.width  = pixmap->drawable.width;
1627
	tmp.dst.width  = pixmap->drawable.width;
1628
	tmp.dst.height = pixmap->drawable.height;
1628
	tmp.dst.height = pixmap->drawable.height;
1629
	tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth);
1629
	tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth);
1630
	tmp.dst.bo = priv->gpu_bo;
1630
	tmp.dst.bo = priv->gpu_bo;
1631
 
1631
 
1632
	tmp.src.bo = frame->bo;
1632
	tmp.src.bo = frame->bo;
1633
	tmp.mask.bo = NULL;
1633
	tmp.mask.bo = NULL;
1634
 
1634
 
1635
	tmp.floats_per_vertex = 3;
1635
	tmp.floats_per_vertex = 3;
1636
	tmp.floats_per_rect = 9;
1636
	tmp.floats_per_rect = 9;
1637
 
1637
 
1638
	if (src_width == dst_width && src_height == dst_height)
1638
	if (src_width == dst_width && src_height == dst_height)
1639
		filter = SAMPLER_FILTER_NEAREST;
1639
		filter = SAMPLER_FILTER_NEAREST;
1640
	else
1640
	else
1641
		filter = SAMPLER_FILTER_BILINEAR;
1641
		filter = SAMPLER_FILTER_BILINEAR;
1642
 
1642
 
1643
	tmp.u.gen6.flags =
1643
	tmp.u.gen6.flags =
1644
		GEN6_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD,
1644
		GEN6_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD,
1645
					       SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE),
1645
					       SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE),
1646
			       NO_BLEND,
1646
			       NO_BLEND,
1647
			       is_planar_fourcc(frame->id) ?
1647
			       is_planar_fourcc(frame->id) ?
1648
			       GEN6_WM_KERNEL_VIDEO_PLANAR :
1648
			       GEN6_WM_KERNEL_VIDEO_PLANAR :
1649
			       GEN6_WM_KERNEL_VIDEO_PACKED,
1649
			       GEN6_WM_KERNEL_VIDEO_PACKED,
1650
			       2);
1650
			       2);
1651
	tmp.priv = frame;
1651
	tmp.priv = frame;
1652
 
1652
 
1653
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo);
1653
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo);
1654
	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) {
1654
	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) {
1655
		kgem_submit(&sna->kgem);
1655
		kgem_submit(&sna->kgem);
1656
		assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL));
1656
		assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL));
1657
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1657
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
1658
	}
1658
	}
1659
 
1659
 
1660
	gen6_emit_video_state(sna, &tmp);
1660
	gen6_emit_video_state(sna, &tmp);
1661
	gen6_align_vertex(sna, &tmp);
1661
	gen6_align_vertex(sna, &tmp);
1662
 
1662
 
1663
	/* Set up the offset for translating from the given region (in screen
1663
	/* Set up the offset for translating from the given region (in screen
1664
	 * coordinates) to the backing pixmap.
1664
	 * coordinates) to the backing pixmap.
1665
	 */
1665
	 */
1666
#ifdef COMPOSITE
1666
#ifdef COMPOSITE
1667
	pix_xoff = -pixmap->screen_x + pixmap->drawable.x;
1667
	pix_xoff = -pixmap->screen_x + pixmap->drawable.x;
1668
	pix_yoff = -pixmap->screen_y + pixmap->drawable.y;
1668
	pix_yoff = -pixmap->screen_y + pixmap->drawable.y;
1669
#else
1669
#else
1670
	pix_xoff = 0;
1670
	pix_xoff = 0;
1671
	pix_yoff = 0;
1671
	pix_yoff = 0;
1672
#endif
1672
#endif
1673
 
1673
 
1674
	src_scale_x = (float)src_width / dst_width / frame->width;
1674
	src_scale_x = (float)src_width / dst_width / frame->width;
1675
	src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x;
1675
	src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x;
1676
 
1676
 
1677
	src_scale_y = (float)src_height / dst_height / frame->height;
1677
	src_scale_y = (float)src_height / dst_height / frame->height;
1678
	src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y;
1678
	src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y;
1679
 
1679
 
1680
	box = REGION_RECTS(dstRegion);
1680
	box = REGION_RECTS(dstRegion);
1681
	nbox = REGION_NUM_RECTS(dstRegion);
1681
	nbox = REGION_NUM_RECTS(dstRegion);
1682
	while (nbox--) {
1682
	while (nbox--) {
1683
		BoxRec r;
1683
		BoxRec r;
1684
 
1684
 
1685
		r.x1 = box->x1 + pix_xoff;
1685
		r.x1 = box->x1 + pix_xoff;
1686
		r.x2 = box->x2 + pix_xoff;
1686
		r.x2 = box->x2 + pix_xoff;
1687
		r.y1 = box->y1 + pix_yoff;
1687
		r.y1 = box->y1 + pix_yoff;
1688
		r.y2 = box->y2 + pix_yoff;
1688
		r.y2 = box->y2 + pix_yoff;
1689
 
1689
 
1690
		gen6_get_rectangles(sna, &tmp, 1, gen6_emit_video_state);
1690
		gen6_get_rectangles(sna, &tmp, 1, gen6_emit_video_state);
1691
 
1691
 
1692
		OUT_VERTEX(r.x2, r.y2);
1692
		OUT_VERTEX(r.x2, r.y2);
1693
		OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x);
1693
		OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x);
1694
		OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y);
1694
		OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y);
1695
 
1695
 
1696
		OUT_VERTEX(r.x1, r.y2);
1696
		OUT_VERTEX(r.x1, r.y2);
1697
		OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x);
1697
		OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x);
1698
		OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y);
1698
		OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y);
1699
 
1699
 
1700
		OUT_VERTEX(r.x1, r.y1);
1700
		OUT_VERTEX(r.x1, r.y1);
1701
		OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x);
1701
		OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x);
1702
		OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y);
1702
		OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y);
1703
 
1703
 
1704
		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
1704
		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
1705
			sna_damage_add_box(&priv->gpu_damage, &r);
1705
			sna_damage_add_box(&priv->gpu_damage, &r);
1706
			sna_damage_subtract_box(&priv->cpu_damage, &r);
1706
			sna_damage_subtract_box(&priv->cpu_damage, &r);
1707
		}
1707
		}
1708
		box++;
1708
		box++;
1709
	}
1709
	}
1710
 
1710
 
1711
	gen4_vertex_flush(sna);
1711
	gen4_vertex_flush(sna);
1712
	return true;
1712
	return true;
1713
}
1713
}
1714
 
1714
 
1715
static int
1715
static int
1716
gen6_composite_picture(struct sna *sna,
1716
gen6_composite_picture(struct sna *sna,
1717
		       PicturePtr picture,
1717
		       PicturePtr picture,
1718
		       struct sna_composite_channel *channel,
1718
		       struct sna_composite_channel *channel,
1719
		       int x, int y,
1719
		       int x, int y,
1720
		       int w, int h,
1720
		       int w, int h,
1721
		       int dst_x, int dst_y,
1721
		       int dst_x, int dst_y,
1722
		       bool precise)
1722
		       bool precise)
1723
{
1723
{
1724
	PixmapPtr pixmap;
1724
	PixmapPtr pixmap;
1725
	uint32_t color;
1725
	uint32_t color;
1726
	int16_t dx, dy;
1726
	int16_t dx, dy;
1727
 
1727
 
1728
	DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
1728
	DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
1729
	     __FUNCTION__, x, y, w, h, dst_x, dst_y));
1729
	     __FUNCTION__, x, y, w, h, dst_x, dst_y));
1730
 
1730
 
1731
	channel->is_solid = false;
1731
	channel->is_solid = false;
1732
	channel->card_format = -1;
1732
	channel->card_format = -1;
1733
 
1733
 
1734
	if (sna_picture_is_solid(picture, &color))
1734
	if (sna_picture_is_solid(picture, &color))
1735
		return gen4_channel_init_solid(sna, channel, color);
1735
		return gen4_channel_init_solid(sna, channel, color);
1736
 
1736
 
1737
	if (picture->pDrawable == NULL) {
1737
	if (picture->pDrawable == NULL) {
1738
		int ret;
1738
		int ret;
1739
 
1739
 
1740
		if (picture->pSourcePict->type == SourcePictTypeLinear)
1740
		if (picture->pSourcePict->type == SourcePictTypeLinear)
1741
			return gen4_channel_init_linear(sna, picture, channel,
1741
			return gen4_channel_init_linear(sna, picture, channel,
1742
							x, y,
1742
							x, y,
1743
							w, h,
1743
							w, h,
1744
							dst_x, dst_y);
1744
							dst_x, dst_y);
1745
 
1745
 
1746
		DBG(("%s -- fixup, gradient\n", __FUNCTION__));
1746
		DBG(("%s -- fixup, gradient\n", __FUNCTION__));
1747
		ret = -1;
1747
		ret = -1;
1748
		if (!precise)
1748
		if (!precise)
1749
			ret = sna_render_picture_approximate_gradient(sna, picture, channel,
1749
			ret = sna_render_picture_approximate_gradient(sna, picture, channel,
1750
								      x, y, w, h, dst_x, dst_y);
1750
								      x, y, w, h, dst_x, dst_y);
1751
		if (ret == -1)
1751
		if (ret == -1)
1752
			ret = sna_render_picture_fixup(sna, picture, channel,
1752
			ret = sna_render_picture_fixup(sna, picture, channel,
1753
						       x, y, w, h, dst_x, dst_y);
1753
						       x, y, w, h, dst_x, dst_y);
1754
		return ret;
1754
		return ret;
1755
	}
1755
	}
1756
 
1756
 
1757
	if (picture->alphaMap) {
1757
	if (picture->alphaMap) {
1758
		DBG(("%s -- fixup, alphamap\n", __FUNCTION__));
1758
		DBG(("%s -- fixup, alphamap\n", __FUNCTION__));
1759
		return sna_render_picture_fixup(sna, picture, channel,
1759
		return sna_render_picture_fixup(sna, picture, channel,
1760
						x, y, w, h, dst_x, dst_y);
1760
						x, y, w, h, dst_x, dst_y);
1761
	}
1761
	}
1762
 
1762
 
1763
	if (!gen6_check_repeat(picture))
1763
	if (!gen6_check_repeat(picture))
1764
		return sna_render_picture_fixup(sna, picture, channel,
1764
		return sna_render_picture_fixup(sna, picture, channel,
1765
						x, y, w, h, dst_x, dst_y);
1765
						x, y, w, h, dst_x, dst_y);
1766
 
1766
 
1767
	if (!gen6_check_filter(picture))
1767
	if (!gen6_check_filter(picture))
1768
		return sna_render_picture_fixup(sna, picture, channel,
1768
		return sna_render_picture_fixup(sna, picture, channel,
1769
						x, y, w, h, dst_x, dst_y);
1769
						x, y, w, h, dst_x, dst_y);
1770
 
1770
 
1771
	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
1771
	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
1772
	channel->filter = picture->filter;
1772
	channel->filter = picture->filter;
1773
 
1773
 
1774
	pixmap = get_drawable_pixmap(picture->pDrawable);
1774
	pixmap = get_drawable_pixmap(picture->pDrawable);
1775
	get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy);
1775
	get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy);
1776
 
1776
 
1777
	x += dx + picture->pDrawable->x;
1777
	x += dx + picture->pDrawable->x;
1778
	y += dy + picture->pDrawable->y;
1778
	y += dy + picture->pDrawable->y;
1779
 
1779
 
1780
	channel->is_affine = sna_transform_is_affine(picture->transform);
1780
	channel->is_affine = sna_transform_is_affine(picture->transform);
1781
	if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
1781
	if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
1782
		DBG(("%s: integer translation (%d, %d), removing\n",
1782
		DBG(("%s: integer translation (%d, %d), removing\n",
1783
		     __FUNCTION__, dx, dy));
1783
		     __FUNCTION__, dx, dy));
1784
		x += dx;
1784
		x += dx;
1785
		y += dy;
1785
		y += dy;
1786
		channel->transform = NULL;
1786
		channel->transform = NULL;
1787
		channel->filter = PictFilterNearest;
1787
		channel->filter = PictFilterNearest;
1788
	} else
1788
	} else
1789
		channel->transform = picture->transform;
1789
		channel->transform = picture->transform;
1790
 
1790
 
1791
	channel->pict_format = picture->format;
1791
	channel->pict_format = picture->format;
1792
	channel->card_format = gen6_get_card_format(picture->format);
1792
	channel->card_format = gen6_get_card_format(picture->format);
1793
	if (channel->card_format == (unsigned)-1)
1793
	if (channel->card_format == (unsigned)-1)
1794
		return sna_render_picture_convert(sna, picture, channel, pixmap,
1794
		return sna_render_picture_convert(sna, picture, channel, pixmap,
1795
						  x, y, w, h, dst_x, dst_y,
1795
						  x, y, w, h, dst_x, dst_y,
1796
						  false);
1796
						  false);
1797
 
1797
 
1798
	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
1798
	if (too_large(pixmap->drawable.width, pixmap->drawable.height)) {
1799
		DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
1799
		DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__,
1800
		     pixmap->drawable.width, pixmap->drawable.height));
1800
		     pixmap->drawable.width, pixmap->drawable.height));
1801
		return sna_render_picture_extract(sna, picture, channel,
1801
		return sna_render_picture_extract(sna, picture, channel,
1802
						  x, y, w, h, dst_x, dst_y);
1802
						  x, y, w, h, dst_x, dst_y);
1803
	}
1803
	}
1804
 
1804
 
1805
	return sna_render_pixmap_bo(sna, channel, pixmap,
1805
	return sna_render_pixmap_bo(sna, channel, pixmap,
1806
				    x, y, w, h, dst_x, dst_y);
1806
				    x, y, w, h, dst_x, dst_y);
1807
}
1807
}
1808
 
1808
 
1809
inline static void gen6_composite_channel_convert(struct sna_composite_channel *channel)
1809
inline static void gen6_composite_channel_convert(struct sna_composite_channel *channel)
1810
{
1810
{
1811
	channel->repeat = gen6_repeat(channel->repeat);
1811
	channel->repeat = gen6_repeat(channel->repeat);
1812
	channel->filter = gen6_filter(channel->filter);
1812
	channel->filter = gen6_filter(channel->filter);
1813
	if (channel->card_format == (unsigned)-1)
1813
	if (channel->card_format == (unsigned)-1)
1814
		channel->card_format = gen6_get_card_format(channel->pict_format);
1814
		channel->card_format = gen6_get_card_format(channel->pict_format);
1815
	assert(channel->card_format != (unsigned)-1);
1815
	assert(channel->card_format != (unsigned)-1);
1816
}
1816
}
1817
#endif
1817
#endif
1818
 
1818
 
1819
static void gen6_render_composite_done(struct sna *sna,
1819
static void gen6_render_composite_done(struct sna *sna,
1820
                       const struct sna_composite_op *op)
1820
                       const struct sna_composite_op *op)
1821
{
1821
{
1822
    DBG(("%s\n", __FUNCTION__));
1822
    DBG(("%s\n", __FUNCTION__));
1823
 
1823
 
1824
	assert(!sna->render.active);
1824
	assert(!sna->render.active);
1825
	if (sna->render.vertex_offset) {
1825
	if (sna->render.vertex_offset) {
1826
		gen4_vertex_flush(sna);
1826
		gen4_vertex_flush(sna);
1827
        gen6_magic_ca_pass(sna, op);
1827
        gen6_magic_ca_pass(sna, op);
1828
    }
1828
    }
1829
 
1829
 
1830
 
1830
 
1831
}
1831
}
1832
 
1832
 
1833
#if 0
1833
#if 0
1834
static bool
1834
static bool
1835
gen6_composite_set_target(struct sna *sna,
1835
gen6_composite_set_target(struct sna *sna,
1836
			  struct sna_composite_op *op,
1836
			  struct sna_composite_op *op,
1837
			  PicturePtr dst,
1837
			  PicturePtr dst,
1838
			  int x, int y, int w, int h,
1838
			  int x, int y, int w, int h,
1839
			  bool partial)
1839
			  bool partial)
1840
{
1840
{
1841
	BoxRec box;
1841
	BoxRec box;
1842
 
1842
 
1843
	op->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
1843
	op->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
1844
	op->dst.format = dst->format;
1844
	op->dst.format = dst->format;
1845
	op->dst.width = op->dst.pixmap->drawable.width;
1845
	op->dst.width = op->dst.pixmap->drawable.width;
1846
	op->dst.height = op->dst.pixmap->drawable.height;
1846
	op->dst.height = op->dst.pixmap->drawable.height;
1847
 
1847
 
1848
	if (w && h) {
1848
	if (w && h) {
1849
		box.x1 = x;
1849
		box.x1 = x;
1850
		box.y1 = y;
1850
		box.y1 = y;
1851
		box.x2 = x + w;
1851
		box.x2 = x + w;
1852
		box.y2 = y + h;
1852
		box.y2 = y + h;
1853
	} else
1853
	} else
1854
		sna_render_picture_extents(dst, &box);
1854
		sna_render_picture_extents(dst, &box);
1855
 
1855
 
1856
//	op->dst.bo = sna_drawable_use_bo (dst->pDrawable,
1856
//	op->dst.bo = sna_drawable_use_bo (dst->pDrawable,
1857
//					  PREFER_GPU | FORCE_GPU | RENDER_GPU,
1857
//					  PREFER_GPU | FORCE_GPU | RENDER_GPU,
1858
//					  &box, &op->damage);
1858
//					  &box, &op->damage);
1859
	if (op->dst.bo == NULL)
1859
	if (op->dst.bo == NULL)
1860
		return false;
1860
		return false;
1861
 
1861
 
1862
	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
1862
	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
1863
			    &op->dst.x, &op->dst.y);
1863
			    &op->dst.x, &op->dst.y);
1864
 
1864
 
1865
	DBG(("%s: pixmap=%p, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n",
1865
	DBG(("%s: pixmap=%p, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n",
1866
	     __FUNCTION__,
1866
	     __FUNCTION__,
1867
	     op->dst.pixmap, (int)op->dst.format,
1867
	     op->dst.pixmap, (int)op->dst.format,
1868
	     op->dst.width, op->dst.height,
1868
	     op->dst.width, op->dst.height,
1869
	     op->dst.bo->pitch,
1869
	     op->dst.bo->pitch,
1870
	     op->dst.x, op->dst.y,
1870
	     op->dst.x, op->dst.y,
1871
	     op->damage ? *op->damage : (void *)-1));
1871
	     op->damage ? *op->damage : (void *)-1));
1872
 
1872
 
1873
	assert(op->dst.bo->proxy == NULL);
1873
	assert(op->dst.bo->proxy == NULL);
1874
 
1874
 
1875
	if (too_large(op->dst.width, op->dst.height) &&
1875
	if (too_large(op->dst.width, op->dst.height) &&
1876
	    !sna_render_composite_redirect(sna, op, x, y, w, h))
1876
	    !sna_render_composite_redirect(sna, op, x, y, w, h))
1877
		return false;
1877
		return false;
1878
 
1878
 
1879
	return true;
1879
	return true;
1880
}
1880
}
1881
 
1881
 
1882
static bool
1882
static bool
1883
prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
1883
prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
1884
{
1884
{
1885
	if (untiled_tlb_miss(tmp->dst.bo) ||
1885
	if (untiled_tlb_miss(tmp->dst.bo) ||
1886
	    untiled_tlb_miss(tmp->src.bo))
1886
	    untiled_tlb_miss(tmp->src.bo))
1887
		return true;
1887
		return true;
1888
 
1888
 
1889
	if (kgem_bo_is_render(tmp->dst.bo) ||
1889
	if (kgem_bo_is_render(tmp->dst.bo) ||
1890
	    kgem_bo_is_render(tmp->src.bo))
1890
	    kgem_bo_is_render(tmp->src.bo))
1891
		return false;
1891
		return false;
1892
 
1892
 
1893
	if (!prefer_blt_ring(sna, tmp->dst.bo, 0))
1893
	if (!prefer_blt_ring(sna, tmp->dst.bo, 0))
1894
		return false;
1894
		return false;
1895
 
1895
 
1896
	return prefer_blt_bo(sna, tmp->dst.bo) || prefer_blt_bo(sna, tmp->src.bo);
1896
	return prefer_blt_bo(sna, tmp->dst.bo) || prefer_blt_bo(sna, tmp->src.bo);
1897
}
1897
}
1898
 
1898
 
1899
static bool
1899
static bool
1900
gen6_render_composite(struct sna *sna,
1900
gen6_render_composite(struct sna *sna,
1901
              uint8_t op,
1901
              uint8_t op,
1902
		      PicturePtr src,
1902
		      PicturePtr src,
1903
		      PicturePtr mask,
1903
		      PicturePtr mask,
1904
		      PicturePtr dst,
1904
		      PicturePtr dst,
1905
              int16_t src_x, int16_t src_y,
1905
              int16_t src_x, int16_t src_y,
1906
              int16_t msk_x, int16_t msk_y,
1906
              int16_t msk_x, int16_t msk_y,
1907
              int16_t dst_x, int16_t dst_y,
1907
              int16_t dst_x, int16_t dst_y,
1908
              int16_t width, int16_t height,
1908
              int16_t width, int16_t height,
1909
              struct sna_composite_op *tmp)
1909
              struct sna_composite_op *tmp)
1910
{
1910
{
1911
	if (op >= ARRAY_SIZE(gen6_blend_op))
1911
	if (op >= ARRAY_SIZE(gen6_blend_op))
1912
		return false;
1912
		return false;
1913
 
1913
 
1914
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
1914
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
1915
         width, height, sna->kgem.ring));
1915
         width, height, sna->kgem.ring));
1916
 
1916
 
1917
	if (mask == NULL &&
1917
	if (mask == NULL &&
1918
	    try_blt(sna, dst, src, width, height) &&
1918
	    try_blt(sna, dst, src, width, height) &&
1919
	    sna_blt_composite(sna, op,
1919
	    sna_blt_composite(sna, op,
1920
			      src, dst,
1920
			      src, dst,
1921
			      src_x, src_y,
1921
			      src_x, src_y,
1922
			      dst_x, dst_y,
1922
			      dst_x, dst_y,
1923
			      width, height,
1923
			      width, height,
1924
			      tmp, false))
1924
			      tmp, false))
1925
		return true;
1925
		return true;
1926
 
1926
 
1927
	if (gen6_composite_fallback(sna, src, mask, dst))
1927
	if (gen6_composite_fallback(sna, src, mask, dst))
1928
		return false;
1928
		return false;
1929
 
1929
 
1930
	if (need_tiling(sna, width, height))
1930
	if (need_tiling(sna, width, height))
1931
		return sna_tiling_composite(op, src, mask, dst,
1931
		return sna_tiling_composite(op, src, mask, dst,
1932
					    src_x, src_y,
1932
					    src_x, src_y,
1933
					    msk_x, msk_y,
1933
					    msk_x, msk_y,
1934
					    dst_x, dst_y,
1934
					    dst_x, dst_y,
1935
					    width, height,
1935
					    width, height,
1936
					    tmp);
1936
					    tmp);
1937
 
1937
 
1938
	if (op == PictOpClear)
1938
	if (op == PictOpClear)
1939
		op = PictOpSrc;
1939
		op = PictOpSrc;
1940
	tmp->op = op;
1940
	tmp->op = op;
1941
	if (!gen6_composite_set_target(sna, tmp, dst,
1941
	if (!gen6_composite_set_target(sna, tmp, dst,
1942
				       dst_x, dst_y, width, height,
1942
				       dst_x, dst_y, width, height,
1943
				       op > PictOpSrc || dst->pCompositeClip->data))
1943
				       op > PictOpSrc || dst->pCompositeClip->data))
1944
		return false;
1944
		return false;
1945
 
1945
 
1946
	switch (gen6_composite_picture(sna, src, &tmp->src,
1946
	switch (gen6_composite_picture(sna, src, &tmp->src,
1947
				       src_x, src_y,
1947
				       src_x, src_y,
1948
				       width, height,
1948
				       width, height,
1949
				       dst_x, dst_y,
1949
				       dst_x, dst_y,
1950
				       dst->polyMode == PolyModePrecise)) {
1950
				       dst->polyMode == PolyModePrecise)) {
1951
	case -1:
1951
	case -1:
1952
		goto cleanup_dst;
1952
		goto cleanup_dst;
1953
	case 0:
1953
	case 0:
1954
		if (!gen4_channel_init_solid(sna, &tmp->src, 0))
1954
		if (!gen4_channel_init_solid(sna, &tmp->src, 0))
1955
			goto cleanup_dst;
1955
			goto cleanup_dst;
1956
		/* fall through to fixup */
1956
		/* fall through to fixup */
1957
	case 1:
1957
	case 1:
1958
		/* Did we just switch rings to prepare the source? */
1958
		/* Did we just switch rings to prepare the source? */
1959
		if (mask == NULL &&
1959
		if (mask == NULL &&
1960
		    prefer_blt_composite(sna, tmp) &&
1960
		    prefer_blt_composite(sna, tmp) &&
1961
		    sna_blt_composite__convert(sna,
1961
		    sna_blt_composite__convert(sna,
1962
					       dst_x, dst_y, width, height,
1962
					       dst_x, dst_y, width, height,
1963
					       tmp))
1963
					       tmp))
1964
			return true;
1964
			return true;
1965
 
1965
 
1966
		gen6_composite_channel_convert(&tmp->src);
1966
		gen6_composite_channel_convert(&tmp->src);
1967
		break;
1967
		break;
1968
	}
1968
	}
1969
 
1969
 
1970
	tmp->is_affine = tmp->src.is_affine;
1970
	tmp->is_affine = tmp->src.is_affine;
1971
	tmp->has_component_alpha = false;
1971
	tmp->has_component_alpha = false;
1972
	tmp->need_magic_ca_pass = false;
1972
	tmp->need_magic_ca_pass = false;
1973
 
1973
 
1974
	tmp->mask.bo = NULL;
1974
	tmp->mask.bo = NULL;
1975
    tmp->mask.filter = SAMPLER_FILTER_NEAREST;
1975
    tmp->mask.filter = SAMPLER_FILTER_NEAREST;
1976
    tmp->mask.repeat = SAMPLER_EXTEND_NONE;
1976
    tmp->mask.repeat = SAMPLER_EXTEND_NONE;
1977
 
1977
 
1978
	if (mask) {
1978
	if (mask) {
1979
		if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
1979
		if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
1980
			tmp->has_component_alpha = true;
1980
			tmp->has_component_alpha = true;
1981
 
1981
 
1982
			/* Check if it's component alpha that relies on a source alpha and on
1982
			/* Check if it's component alpha that relies on a source alpha and on
1983
			 * the source value.  We can only get one of those into the single
1983
			 * the source value.  We can only get one of those into the single
1984
			 * source value that we get to blend with.
1984
			 * source value that we get to blend with.
1985
			 */
1985
			 */
1986
			if (gen6_blend_op[op].src_alpha &&
1986
			if (gen6_blend_op[op].src_alpha &&
1987
			    (gen6_blend_op[op].src_blend != GEN6_BLENDFACTOR_ZERO)) {
1987
			    (gen6_blend_op[op].src_blend != GEN6_BLENDFACTOR_ZERO)) {
1988
				if (op != PictOpOver)
1988
				if (op != PictOpOver)
1989
					goto cleanup_src;
1989
					goto cleanup_src;
1990
 
1990
 
1991
				tmp->need_magic_ca_pass = true;
1991
				tmp->need_magic_ca_pass = true;
1992
				tmp->op = PictOpOutReverse;
1992
				tmp->op = PictOpOutReverse;
1993
			}
1993
			}
1994
		}
1994
		}
1995
 
1995
 
1996
		if (!reuse_source(sna,
1996
		if (!reuse_source(sna,
1997
				  src, &tmp->src, src_x, src_y,
1997
				  src, &tmp->src, src_x, src_y,
1998
				  mask, &tmp->mask, msk_x, msk_y)) {
1998
				  mask, &tmp->mask, msk_x, msk_y)) {
1999
			switch (gen6_composite_picture(sna, mask, &tmp->mask,
1999
			switch (gen6_composite_picture(sna, mask, &tmp->mask,
2000
						       msk_x, msk_y,
2000
						       msk_x, msk_y,
2001
						       width, height,
2001
						       width, height,
2002
						       dst_x, dst_y,
2002
						       dst_x, dst_y,
2003
						       dst->polyMode == PolyModePrecise)) {
2003
						       dst->polyMode == PolyModePrecise)) {
2004
			case -1:
2004
			case -1:
2005
				goto cleanup_src;
2005
				goto cleanup_src;
2006
			case 0:
2006
			case 0:
2007
				if (!gen4_channel_init_solid(sna, &tmp->mask, 0))
2007
				if (!gen4_channel_init_solid(sna, &tmp->mask, 0))
2008
					goto cleanup_src;
2008
					goto cleanup_src;
2009
				/* fall through to fixup */
2009
				/* fall through to fixup */
2010
			case 1:
2010
			case 1:
2011
				gen6_composite_channel_convert(&tmp->mask);
2011
				gen6_composite_channel_convert(&tmp->mask);
2012
				break;
2012
				break;
2013
			}
2013
			}
2014
		}
2014
		}
2015
 
2015
 
2016
		tmp->is_affine &= tmp->mask.is_affine;
2016
		tmp->is_affine &= tmp->mask.is_affine;
2017
	}
2017
	}
2018
 
2018
 
2019
	tmp->u.gen6.flags =
2019
	tmp->u.gen6.flags =
2020
		GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter,
2020
		GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter,
2021
					      tmp->src.repeat,
2021
					      tmp->src.repeat,
2022
					      tmp->mask.filter,
2022
					      tmp->mask.filter,
2023
					      tmp->mask.repeat),
2023
					      tmp->mask.repeat),
2024
			       gen6_get_blend(tmp->op,
2024
			       gen6_get_blend(tmp->op,
2025
					      tmp->has_component_alpha,
2025
					      tmp->has_component_alpha,
2026
					      tmp->dst.format),
2026
					      tmp->dst.format),
2027
			       gen6_choose_composite_kernel(tmp->op,
2027
			       gen6_choose_composite_kernel(tmp->op,
2028
							    tmp->mask.bo != NULL,
2028
							    tmp->mask.bo != NULL,
2029
							    tmp->has_component_alpha,
2029
							    tmp->has_component_alpha,
2030
							    tmp->is_affine),
2030
							    tmp->is_affine),
2031
			       gen4_choose_composite_emitter(sna, tmp));
2031
			       gen4_choose_composite_emitter(sna, tmp));
2032
 
2032
 
2033
	tmp->blt   = gen6_render_composite_blt;
2033
	tmp->blt   = gen6_render_composite_blt;
2034
	tmp->box   = gen6_render_composite_box;
2034
	tmp->box   = gen6_render_composite_box;
2035
	tmp->boxes = gen6_render_composite_boxes__blt;
2035
	tmp->boxes = gen6_render_composite_boxes__blt;
2036
	if (tmp->emit_boxes) {
2036
	if (tmp->emit_boxes) {
2037
		tmp->boxes = gen6_render_composite_boxes;
2037
		tmp->boxes = gen6_render_composite_boxes;
2038
		tmp->thread_boxes = gen6_render_composite_boxes__thread;
2038
		tmp->thread_boxes = gen6_render_composite_boxes__thread;
2039
	}
2039
	}
2040
	tmp->done  = gen6_render_composite_done;
2040
	tmp->done  = gen6_render_composite_done;
2041
 
2041
 
2042
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo);
2042
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo);
2043
	if (!kgem_check_bo(&sna->kgem,
2043
	if (!kgem_check_bo(&sna->kgem,
2044
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
2044
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
2045
			   NULL)) {
2045
			   NULL)) {
2046
		kgem_submit(&sna->kgem);
2046
		kgem_submit(&sna->kgem);
2047
		if (!kgem_check_bo(&sna->kgem,
2047
		if (!kgem_check_bo(&sna->kgem,
2048
				   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
2048
				   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
2049
				   NULL))
2049
				   NULL))
2050
			goto cleanup_mask;
2050
			goto cleanup_mask;
2051
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2051
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2052
	}
2052
	}
2053
 
2053
 
2054
    gen6_emit_composite_state(sna, tmp);
2054
    gen6_emit_composite_state(sna, tmp);
2055
    gen6_align_vertex(sna, tmp);
2055
    gen6_align_vertex(sna, tmp);
2056
	return true;
2056
	return true;
2057
 
2057
 
2058
cleanup_mask:
2058
cleanup_mask:
2059
	if (tmp->mask.bo)
2059
	if (tmp->mask.bo)
2060
		kgem_bo_destroy(&sna->kgem, tmp->mask.bo);
2060
		kgem_bo_destroy(&sna->kgem, tmp->mask.bo);
2061
cleanup_src:
2061
cleanup_src:
2062
	if (tmp->src.bo)
2062
	if (tmp->src.bo)
2063
		kgem_bo_destroy(&sna->kgem, tmp->src.bo);
2063
		kgem_bo_destroy(&sna->kgem, tmp->src.bo);
2064
cleanup_dst:
2064
cleanup_dst:
2065
	if (tmp->redirect.real_bo)
2065
	if (tmp->redirect.real_bo)
2066
		kgem_bo_destroy(&sna->kgem, tmp->dst.bo);
2066
		kgem_bo_destroy(&sna->kgem, tmp->dst.bo);
2067
	return false;
2067
	return false;
2068
}
2068
}
2069
 
2069
 
2070
#if !NO_COMPOSITE_SPANS
2070
#if !NO_COMPOSITE_SPANS
2071
fastcall static void
2071
fastcall static void
2072
gen6_render_composite_spans_box(struct sna *sna,
2072
gen6_render_composite_spans_box(struct sna *sna,
2073
				const struct sna_composite_spans_op *op,
2073
				const struct sna_composite_spans_op *op,
2074
				const BoxRec *box, float opacity)
2074
				const BoxRec *box, float opacity)
2075
{
2075
{
2076
	DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n",
2076
	DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n",
2077
	     __FUNCTION__,
2077
	     __FUNCTION__,
2078
	     op->base.src.offset[0], op->base.src.offset[1],
2078
	     op->base.src.offset[0], op->base.src.offset[1],
2079
	     opacity,
2079
	     opacity,
2080
	     op->base.dst.x, op->base.dst.y,
2080
	     op->base.dst.x, op->base.dst.y,
2081
	     box->x1, box->y1,
2081
	     box->x1, box->y1,
2082
	     box->x2 - box->x1,
2082
	     box->x2 - box->x1,
2083
	     box->y2 - box->y1));
2083
	     box->y2 - box->y1));
2084
 
2084
 
2085
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_composite_state);
2085
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_composite_state);
2086
	op->prim_emit(sna, op, box, opacity);
2086
	op->prim_emit(sna, op, box, opacity);
2087
}
2087
}
2088
 
2088
 
2089
static void
2089
static void
2090
gen6_render_composite_spans_boxes(struct sna *sna,
2090
gen6_render_composite_spans_boxes(struct sna *sna,
2091
				  const struct sna_composite_spans_op *op,
2091
				  const struct sna_composite_spans_op *op,
2092
				  const BoxRec *box, int nbox,
2092
				  const BoxRec *box, int nbox,
2093
				  float opacity)
2093
				  float opacity)
2094
{
2094
{
2095
	DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n",
2095
	DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n",
2096
	     __FUNCTION__, nbox,
2096
	     __FUNCTION__, nbox,
2097
	     op->base.src.offset[0], op->base.src.offset[1],
2097
	     op->base.src.offset[0], op->base.src.offset[1],
2098
	     opacity,
2098
	     opacity,
2099
	     op->base.dst.x, op->base.dst.y));
2099
	     op->base.dst.x, op->base.dst.y));
2100
 
2100
 
2101
	do {
2101
	do {
2102
		int nbox_this_time;
2102
		int nbox_this_time;
2103
 
2103
 
2104
		nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox,
2104
		nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox,
2105
						     gen6_emit_composite_state);
2105
						     gen6_emit_composite_state);
2106
		nbox -= nbox_this_time;
2106
		nbox -= nbox_this_time;
2107
 
2107
 
2108
		do {
2108
		do {
2109
			DBG(("  %s: (%d, %d) x (%d, %d)\n", __FUNCTION__,
2109
			DBG(("  %s: (%d, %d) x (%d, %d)\n", __FUNCTION__,
2110
			     box->x1, box->y1,
2110
			     box->x1, box->y1,
2111
			     box->x2 - box->x1,
2111
			     box->x2 - box->x1,
2112
			     box->y2 - box->y1));
2112
			     box->y2 - box->y1));
2113
 
2113
 
2114
			op->prim_emit(sna, op, box++, opacity);
2114
			op->prim_emit(sna, op, box++, opacity);
2115
		} while (--nbox_this_time);
2115
		} while (--nbox_this_time);
2116
	} while (nbox);
2116
	} while (nbox);
2117
}
2117
}
2118
 
2118
 
2119
fastcall static void
2119
fastcall static void
2120
gen6_render_composite_spans_boxes__thread(struct sna *sna,
2120
gen6_render_composite_spans_boxes__thread(struct sna *sna,
2121
					  const struct sna_composite_spans_op *op,
2121
					  const struct sna_composite_spans_op *op,
2122
					  const struct sna_opacity_box *box,
2122
					  const struct sna_opacity_box *box,
2123
					  int nbox)
2123
					  int nbox)
2124
{
2124
{
2125
	DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n",
2125
	DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n",
2126
	     __FUNCTION__, nbox,
2126
	     __FUNCTION__, nbox,
2127
	     op->base.src.offset[0], op->base.src.offset[1],
2127
	     op->base.src.offset[0], op->base.src.offset[1],
2128
	     op->base.dst.x, op->base.dst.y));
2128
	     op->base.dst.x, op->base.dst.y));
2129
 
2129
 
2130
	sna_vertex_lock(&sna->render);
2130
	sna_vertex_lock(&sna->render);
2131
	do {
2131
	do {
2132
		int nbox_this_time;
2132
		int nbox_this_time;
2133
		float *v;
2133
		float *v;
2134
 
2134
 
2135
		nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox,
2135
		nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox,
2136
						     gen6_emit_composite_state);
2136
						     gen6_emit_composite_state);
2137
		assert(nbox_this_time);
2137
		assert(nbox_this_time);
2138
		nbox -= nbox_this_time;
2138
		nbox -= nbox_this_time;
2139
 
2139
 
2140
		v = sna->render.vertices + sna->render.vertex_used;
2140
		v = sna->render.vertices + sna->render.vertex_used;
2141
		sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect;
2141
		sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect;
2142
 
2142
 
2143
		sna_vertex_acquire__locked(&sna->render);
2143
		sna_vertex_acquire__locked(&sna->render);
2144
		sna_vertex_unlock(&sna->render);
2144
		sna_vertex_unlock(&sna->render);
2145
 
2145
 
2146
		op->emit_boxes(op, box, nbox_this_time, v);
2146
		op->emit_boxes(op, box, nbox_this_time, v);
2147
		box += nbox_this_time;
2147
		box += nbox_this_time;
2148
 
2148
 
2149
		sna_vertex_lock(&sna->render);
2149
		sna_vertex_lock(&sna->render);
2150
		sna_vertex_release__locked(&sna->render);
2150
		sna_vertex_release__locked(&sna->render);
2151
	} while (nbox);
2151
	} while (nbox);
2152
	sna_vertex_unlock(&sna->render);
2152
	sna_vertex_unlock(&sna->render);
2153
}
2153
}
2154
 
2154
 
2155
fastcall static void
2155
fastcall static void
2156
gen6_render_composite_spans_done(struct sna *sna,
2156
gen6_render_composite_spans_done(struct sna *sna,
2157
				 const struct sna_composite_spans_op *op)
2157
				 const struct sna_composite_spans_op *op)
2158
{
2158
{
2159
	DBG(("%s()\n", __FUNCTION__));
2159
	DBG(("%s()\n", __FUNCTION__));
2160
	assert(!sna->render.active);
2160
	assert(!sna->render.active);
2161
 
2161
 
2162
	if (sna->render.vertex_offset)
2162
	if (sna->render.vertex_offset)
2163
		gen4_vertex_flush(sna);
2163
		gen4_vertex_flush(sna);
2164
 
2164
 
2165
	if (op->base.src.bo)
2165
	if (op->base.src.bo)
2166
		kgem_bo_destroy(&sna->kgem, op->base.src.bo);
2166
		kgem_bo_destroy(&sna->kgem, op->base.src.bo);
2167
 
2167
 
2168
	sna_render_composite_redirect_done(sna, &op->base);
2168
	sna_render_composite_redirect_done(sna, &op->base);
2169
}
2169
}
2170
 
2170
 
2171
static bool
2171
static bool
2172
gen6_check_composite_spans(struct sna *sna,
2172
gen6_check_composite_spans(struct sna *sna,
2173
			   uint8_t op, PicturePtr src, PicturePtr dst,
2173
			   uint8_t op, PicturePtr src, PicturePtr dst,
2174
			   int16_t width, int16_t height,
2174
			   int16_t width, int16_t height,
2175
			   unsigned flags)
2175
			   unsigned flags)
2176
{
2176
{
2177
	DBG(("%s: op=%d, width=%d, height=%d, flags=%x\n",
2177
	DBG(("%s: op=%d, width=%d, height=%d, flags=%x\n",
2178
	     __FUNCTION__, op, width, height, flags));
2178
	     __FUNCTION__, op, width, height, flags));
2179
 
2179
 
2180
	if (op >= ARRAY_SIZE(gen6_blend_op))
2180
	if (op >= ARRAY_SIZE(gen6_blend_op))
2181
		return false;
2181
		return false;
2182
 
2182
 
2183
	if (gen6_composite_fallback(sna, src, NULL, dst)) {
2183
	if (gen6_composite_fallback(sna, src, NULL, dst)) {
2184
		DBG(("%s: operation would fallback\n", __FUNCTION__));
2184
		DBG(("%s: operation would fallback\n", __FUNCTION__));
2185
		return false;
2185
		return false;
2186
	}
2186
	}
2187
 
2187
 
2188
	if (need_tiling(sna, width, height) &&
2188
	if (need_tiling(sna, width, height) &&
2189
	    !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) {
2189
	    !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) {
2190
		DBG(("%s: fallback, tiled operation not on GPU\n",
2190
		DBG(("%s: fallback, tiled operation not on GPU\n",
2191
		     __FUNCTION__));
2191
		     __FUNCTION__));
2192
		return false;
2192
		return false;
2193
	}
2193
	}
2194
 
2194
 
2195
	if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) {
2195
	if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) {
2196
		struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable);
2196
		struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable);
2197
		assert(priv);
2197
		assert(priv);
2198
 
2198
 
2199
		if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo))
2199
		if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo))
2200
			return true;
2200
			return true;
2201
 
2201
 
2202
		if (flags & COMPOSITE_SPANS_INPLACE_HINT)
2202
		if (flags & COMPOSITE_SPANS_INPLACE_HINT)
2203
			return false;
2203
			return false;
2204
 
2204
 
2205
		return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo);
2205
		return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo);
2206
	}
2206
	}
2207
 
2207
 
2208
	return true;
2208
	return true;
2209
}
2209
}
2210
 
2210
 
2211
static bool
2211
static bool
2212
gen6_render_composite_spans(struct sna *sna,
2212
gen6_render_composite_spans(struct sna *sna,
2213
			    uint8_t op,
2213
			    uint8_t op,
2214
			    PicturePtr src,
2214
			    PicturePtr src,
2215
			    PicturePtr dst,
2215
			    PicturePtr dst,
2216
			    int16_t src_x,  int16_t src_y,
2216
			    int16_t src_x,  int16_t src_y,
2217
			    int16_t dst_x,  int16_t dst_y,
2217
			    int16_t dst_x,  int16_t dst_y,
2218
			    int16_t width,  int16_t height,
2218
			    int16_t width,  int16_t height,
2219
			    unsigned flags,
2219
			    unsigned flags,
2220
			    struct sna_composite_spans_op *tmp)
2220
			    struct sna_composite_spans_op *tmp)
2221
{
2221
{
2222
	DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__,
2222
	DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__,
2223
	     width, height, flags, sna->kgem.ring));
2223
	     width, height, flags, sna->kgem.ring));
2224
 
2224
 
2225
	assert(gen6_check_composite_spans(sna, op, src, dst, width, height, flags));
2225
	assert(gen6_check_composite_spans(sna, op, src, dst, width, height, flags));
2226
 
2226
 
2227
	if (need_tiling(sna, width, height)) {
2227
	if (need_tiling(sna, width, height)) {
2228
		DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n",
2228
		DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n",
2229
		     __FUNCTION__, width, height));
2229
		     __FUNCTION__, width, height));
2230
		return sna_tiling_composite_spans(op, src, dst,
2230
		return sna_tiling_composite_spans(op, src, dst,
2231
						  src_x, src_y, dst_x, dst_y,
2231
						  src_x, src_y, dst_x, dst_y,
2232
						  width, height, flags, tmp);
2232
						  width, height, flags, tmp);
2233
	}
2233
	}
2234
 
2234
 
2235
	tmp->base.op = op;
2235
	tmp->base.op = op;
2236
	if (!gen6_composite_set_target(sna, &tmp->base, dst,
2236
	if (!gen6_composite_set_target(sna, &tmp->base, dst,
2237
				       dst_x, dst_y, width, height, true))
2237
				       dst_x, dst_y, width, height, true))
2238
		return false;
2238
		return false;
2239
 
2239
 
2240
	switch (gen6_composite_picture(sna, src, &tmp->base.src,
2240
	switch (gen6_composite_picture(sna, src, &tmp->base.src,
2241
				       src_x, src_y,
2241
				       src_x, src_y,
2242
				       width, height,
2242
				       width, height,
2243
				       dst_x, dst_y,
2243
				       dst_x, dst_y,
2244
				       dst->polyMode == PolyModePrecise)) {
2244
				       dst->polyMode == PolyModePrecise)) {
2245
	case -1:
2245
	case -1:
2246
		goto cleanup_dst;
2246
		goto cleanup_dst;
2247
	case 0:
2247
	case 0:
2248
		if (!gen4_channel_init_solid(sna, &tmp->base.src, 0))
2248
		if (!gen4_channel_init_solid(sna, &tmp->base.src, 0))
2249
			goto cleanup_dst;
2249
			goto cleanup_dst;
2250
		/* fall through to fixup */
2250
		/* fall through to fixup */
2251
	case 1:
2251
	case 1:
2252
		gen6_composite_channel_convert(&tmp->base.src);
2252
		gen6_composite_channel_convert(&tmp->base.src);
2253
		break;
2253
		break;
2254
	}
2254
	}
2255
	tmp->base.mask.bo = NULL;
2255
	tmp->base.mask.bo = NULL;
2256
 
2256
 
2257
	tmp->base.is_affine = tmp->base.src.is_affine;
2257
	tmp->base.is_affine = tmp->base.src.is_affine;
2258
	tmp->base.need_magic_ca_pass = false;
2258
	tmp->base.need_magic_ca_pass = false;
2259
 
2259
 
2260
	tmp->base.u.gen6.flags =
2260
	tmp->base.u.gen6.flags =
2261
		GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter,
2261
		GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter,
2262
					      tmp->base.src.repeat,
2262
					      tmp->base.src.repeat,
2263
					      SAMPLER_FILTER_NEAREST,
2263
					      SAMPLER_FILTER_NEAREST,
2264
					      SAMPLER_EXTEND_PAD),
2264
					      SAMPLER_EXTEND_PAD),
2265
			       gen6_get_blend(tmp->base.op, false, tmp->base.dst.format),
2265
			       gen6_get_blend(tmp->base.op, false, tmp->base.dst.format),
2266
			       GEN6_WM_KERNEL_OPACITY | !tmp->base.is_affine,
2266
			       GEN6_WM_KERNEL_OPACITY | !tmp->base.is_affine,
2267
			       gen4_choose_spans_emitter(sna, tmp));
2267
			       gen4_choose_spans_emitter(sna, tmp));
2268
 
2268
 
2269
	tmp->box   = gen6_render_composite_spans_box;
2269
	tmp->box   = gen6_render_composite_spans_box;
2270
	tmp->boxes = gen6_render_composite_spans_boxes;
2270
	tmp->boxes = gen6_render_composite_spans_boxes;
2271
	if (tmp->emit_boxes)
2271
	if (tmp->emit_boxes)
2272
		tmp->thread_boxes = gen6_render_composite_spans_boxes__thread;
2272
		tmp->thread_boxes = gen6_render_composite_spans_boxes__thread;
2273
	tmp->done  = gen6_render_composite_spans_done;
2273
	tmp->done  = gen6_render_composite_spans_done;
2274
 
2274
 
2275
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->base.dst.bo);
2275
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->base.dst.bo);
2276
	if (!kgem_check_bo(&sna->kgem,
2276
	if (!kgem_check_bo(&sna->kgem,
2277
			   tmp->base.dst.bo, tmp->base.src.bo,
2277
			   tmp->base.dst.bo, tmp->base.src.bo,
2278
			   NULL)) {
2278
			   NULL)) {
2279
		kgem_submit(&sna->kgem);
2279
		kgem_submit(&sna->kgem);
2280
		if (!kgem_check_bo(&sna->kgem,
2280
		if (!kgem_check_bo(&sna->kgem,
2281
				   tmp->base.dst.bo, tmp->base.src.bo,
2281
				   tmp->base.dst.bo, tmp->base.src.bo,
2282
				   NULL))
2282
				   NULL))
2283
			goto cleanup_src;
2283
			goto cleanup_src;
2284
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2284
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2285
	}
2285
	}
2286
 
2286
 
2287
	gen6_emit_composite_state(sna, &tmp->base);
2287
	gen6_emit_composite_state(sna, &tmp->base);
2288
	gen6_align_vertex(sna, &tmp->base);
2288
	gen6_align_vertex(sna, &tmp->base);
2289
	return true;
2289
	return true;
2290
 
2290
 
2291
cleanup_src:
2291
cleanup_src:
2292
	if (tmp->base.src.bo)
2292
	if (tmp->base.src.bo)
2293
		kgem_bo_destroy(&sna->kgem, tmp->base.src.bo);
2293
		kgem_bo_destroy(&sna->kgem, tmp->base.src.bo);
2294
cleanup_dst:
2294
cleanup_dst:
2295
	if (tmp->base.redirect.real_bo)
2295
	if (tmp->base.redirect.real_bo)
2296
		kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo);
2296
		kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo);
2297
	return false;
2297
	return false;
2298
}
2298
}
2299
#endif
2299
#endif
2300
 
2300
 
2301
static void
2301
static void
2302
gen6_emit_copy_state(struct sna *sna,
2302
gen6_emit_copy_state(struct sna *sna,
2303
		     const struct sna_composite_op *op)
2303
		     const struct sna_composite_op *op)
2304
{
2304
{
2305
	uint32_t *binding_table;
2305
	uint32_t *binding_table;
2306
	uint16_t offset;
2306
	uint16_t offset;
2307
	bool dirty;
2307
	bool dirty;
2308
 
2308
 
2309
	dirty = gen6_get_batch(sna, op);
2309
	dirty = gen6_get_batch(sna, op);
2310
 
2310
 
2311
	binding_table = gen6_composite_get_binding_table(sna, &offset);
2311
	binding_table = gen6_composite_get_binding_table(sna, &offset);
2312
 
2312
 
2313
	binding_table[0] =
2313
	binding_table[0] =
2314
		gen6_bind_bo(sna,
2314
		gen6_bind_bo(sna,
2315
			     op->dst.bo, op->dst.width, op->dst.height,
2315
			     op->dst.bo, op->dst.width, op->dst.height,
2316
			     gen6_get_dest_format(op->dst.format),
2316
			     gen6_get_dest_format(op->dst.format),
2317
			     true);
2317
			     true);
2318
	binding_table[1] =
2318
	binding_table[1] =
2319
		gen6_bind_bo(sna,
2319
		gen6_bind_bo(sna,
2320
			     op->src.bo, op->src.width, op->src.height,
2320
			     op->src.bo, op->src.width, op->src.height,
2321
			     op->src.card_format,
2321
			     op->src.card_format,
2322
			     false);
2322
			     false);
2323
 
2323
 
2324
	if (sna->kgem.surface == offset &&
2324
	if (sna->kgem.surface == offset &&
2325
	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
2325
	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
2326
		sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
2326
		sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
2327
		offset = sna->render_state.gen6.surface_table;
2327
		offset = sna->render_state.gen6.surface_table;
2328
	}
2328
	}
2329
 
2329
 
2330
	gen6_emit_state(sna, op, offset | dirty);
2330
	gen6_emit_state(sna, op, offset | dirty);
2331
}
2331
}
2332
 
2332
 
2333
static inline bool prefer_blt_copy(struct sna *sna,
2333
static inline bool prefer_blt_copy(struct sna *sna,
2334
				   struct kgem_bo *src_bo,
2334
				   struct kgem_bo *src_bo,
2335
				   struct kgem_bo *dst_bo,
2335
				   struct kgem_bo *dst_bo,
2336
				   unsigned flags)
2336
				   unsigned flags)
2337
{
2337
{
2338
	if (flags & COPY_SYNC)
2338
	if (flags & COPY_SYNC)
2339
		return false;
2339
		return false;
2340
 
2340
 
2341
	if (PREFER_RENDER)
2341
	if (PREFER_RENDER)
2342
		return PREFER_RENDER > 0;
2342
		return PREFER_RENDER > 0;
2343
 
2343
 
2344
	if (sna->kgem.ring == KGEM_BLT)
2344
	if (sna->kgem.ring == KGEM_BLT)
2345
		return true;
2345
		return true;
2346
 
2346
 
2347
	if (src_bo == dst_bo && can_switch_to_blt(sna, dst_bo, flags))
2347
	if (src_bo == dst_bo && can_switch_to_blt(sna, dst_bo, flags))
2348
		return true;
2348
		return true;
2349
 
2349
 
2350
	if (untiled_tlb_miss(src_bo) ||
2350
	if (untiled_tlb_miss(src_bo) ||
2351
	    untiled_tlb_miss(dst_bo))
2351
	    untiled_tlb_miss(dst_bo))
2352
		return true;
2352
		return true;
2353
 
2353
 
2354
	if (kgem_bo_is_render(dst_bo) ||
2354
	if (kgem_bo_is_render(dst_bo) ||
2355
	    kgem_bo_is_render(src_bo))
2355
	    kgem_bo_is_render(src_bo))
2356
		return false;
2356
		return false;
2357
 
2357
 
2358
	if (!prefer_blt_ring(sna, dst_bo, flags))
2358
	if (!prefer_blt_ring(sna, dst_bo, flags))
2359
		return false;
2359
		return false;
2360
 
2360
 
2361
	return prefer_blt_bo(sna, src_bo) || prefer_blt_bo(sna, dst_bo);
2361
	return prefer_blt_bo(sna, src_bo) || prefer_blt_bo(sna, dst_bo);
2362
}
2362
}
2363
 
2363
 
2364
inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents)
2364
inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents)
2365
{
2365
{
2366
	*extents = box[0];
2366
	*extents = box[0];
2367
	while (--n) {
2367
	while (--n) {
2368
		box++;
2368
		box++;
2369
 
2369
 
2370
		if (box->x1 < extents->x1)
2370
		if (box->x1 < extents->x1)
2371
			extents->x1 = box->x1;
2371
			extents->x1 = box->x1;
2372
		if (box->x2 > extents->x2)
2372
		if (box->x2 > extents->x2)
2373
			extents->x2 = box->x2;
2373
			extents->x2 = box->x2;
2374
 
2374
 
2375
		if (box->y1 < extents->y1)
2375
		if (box->y1 < extents->y1)
2376
			extents->y1 = box->y1;
2376
			extents->y1 = box->y1;
2377
		if (box->y2 > extents->y2)
2377
		if (box->y2 > extents->y2)
2378
			extents->y2 = box->y2;
2378
			extents->y2 = box->y2;
2379
	}
2379
	}
2380
}
2380
}
2381
 
2381
 
2382
static inline bool
2382
static inline bool
2383
overlaps(struct sna *sna,
2383
overlaps(struct sna *sna,
2384
	 struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
2384
	 struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
2385
	 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
2385
	 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
2386
	 const BoxRec *box, int n, BoxRec *extents)
2386
	 const BoxRec *box, int n, BoxRec *extents)
2387
{
2387
{
2388
	if (src_bo != dst_bo)
2388
	if (src_bo != dst_bo)
2389
		return false;
2389
		return false;
2390
 
2390
 
2391
	boxes_extents(box, n, extents);
2391
	boxes_extents(box, n, extents);
2392
	return (extents->x2 + src_dx > extents->x1 + dst_dx &&
2392
	return (extents->x2 + src_dx > extents->x1 + dst_dx &&
2393
		extents->x1 + src_dx < extents->x2 + dst_dx &&
2393
		extents->x1 + src_dx < extents->x2 + dst_dx &&
2394
		extents->y2 + src_dy > extents->y1 + dst_dy &&
2394
		extents->y2 + src_dy > extents->y1 + dst_dy &&
2395
		extents->y1 + src_dy < extents->y2 + dst_dy);
2395
		extents->y1 + src_dy < extents->y2 + dst_dy);
2396
}
2396
}
2397
 
2397
 
2398
static bool
2398
static bool
2399
gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
2399
gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
2400
		       PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
2400
		       PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
2401
		       PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
2401
		       PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
2402
		       const BoxRec *box, int n, unsigned flags)
2402
		       const BoxRec *box, int n, unsigned flags)
2403
{
2403
{
2404
	struct sna_composite_op tmp;
2404
	struct sna_composite_op tmp;
2405
	BoxRec extents;
2405
	BoxRec extents;
2406
 
2406
 
2407
	DBG(("%s (%d, %d)->(%d, %d) x %d, alu=%x, self-copy=%d, overlaps? %d\n",
2407
	DBG(("%s (%d, %d)->(%d, %d) x %d, alu=%x, self-copy=%d, overlaps? %d\n",
2408
	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n, alu,
2408
	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n, alu,
2409
	     src_bo == dst_bo,
2409
	     src_bo == dst_bo,
2410
	     overlaps(sna,
2410
	     overlaps(sna,
2411
		      src_bo, src_dx, src_dy,
2411
		      src_bo, src_dx, src_dy,
2412
		      dst_bo, dst_dx, dst_dy,
2412
		      dst_bo, dst_dx, dst_dy,
2413
		      box, n, &extents)));
2413
		      box, n, &extents)));
2414
 
2414
 
2415
	if (prefer_blt_copy(sna, src_bo, dst_bo, flags) &&
2415
	if (prefer_blt_copy(sna, src_bo, dst_bo, flags) &&
2416
	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2416
	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2417
	    sna_blt_copy_boxes(sna, alu,
2417
	    sna_blt_copy_boxes(sna, alu,
2418
			       src_bo, src_dx, src_dy,
2418
			       src_bo, src_dx, src_dy,
2419
			       dst_bo, dst_dx, dst_dy,
2419
			       dst_bo, dst_dx, dst_dy,
2420
			       dst->drawable.bitsPerPixel,
2420
			       dst->drawable.bitsPerPixel,
2421
			       box, n))
2421
			       box, n))
2422
		return true;
2422
		return true;
2423
 
2423
 
2424
	if (!(alu == GXcopy || alu == GXclear)) {
2424
	if (!(alu == GXcopy || alu == GXclear)) {
2425
fallback_blt:
2425
fallback_blt:
2426
		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
2426
		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
2427
			return false;
2427
			return false;
2428
 
2428
 
2429
		return sna_blt_copy_boxes_fallback(sna, alu,
2429
		return sna_blt_copy_boxes_fallback(sna, alu,
2430
						   src, src_bo, src_dx, src_dy,
2430
						   src, src_bo, src_dx, src_dy,
2431
						   dst, dst_bo, dst_dx, dst_dy,
2431
						   dst, dst_bo, dst_dx, dst_dy,
2432
						   box, n);
2432
						   box, n);
2433
	}
2433
	}
2434
 
2434
 
2435
	if (overlaps(sna,
2435
	if (overlaps(sna,
2436
		     src_bo, src_dx, src_dy,
2436
		     src_bo, src_dx, src_dy,
2437
		     dst_bo, dst_dx, dst_dy,
2437
		     dst_bo, dst_dx, dst_dy,
2438
		     box, n, &extents)) {
2438
		     box, n, &extents)) {
2439
		if (too_large(extents.x2-extents.x1, extents.y2-extents.y1))
2439
		if (too_large(extents.x2-extents.x1, extents.y2-extents.y1))
2440
			goto fallback_blt;
2440
			goto fallback_blt;
2441
 
2441
 
2442
		if (can_switch_to_blt(sna, dst_bo, flags) &&
2442
		if (can_switch_to_blt(sna, dst_bo, flags) &&
2443
		    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2443
		    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2444
		    sna_blt_copy_boxes(sna, alu,
2444
		    sna_blt_copy_boxes(sna, alu,
2445
				       src_bo, src_dx, src_dy,
2445
				       src_bo, src_dx, src_dy,
2446
				       dst_bo, dst_dx, dst_dy,
2446
				       dst_bo, dst_dx, dst_dy,
2447
				       dst->drawable.bitsPerPixel,
2447
				       dst->drawable.bitsPerPixel,
2448
				       box, n))
2448
				       box, n))
2449
			return true;
2449
			return true;
2450
 
2450
 
2451
		return sna_render_copy_boxes__overlap(sna, alu,
2451
		return sna_render_copy_boxes__overlap(sna, alu,
2452
						      src, src_bo, src_dx, src_dy,
2452
						      src, src_bo, src_dx, src_dy,
2453
						      dst, dst_bo, dst_dx, dst_dy,
2453
						      dst, dst_bo, dst_dx, dst_dy,
2454
						      box, n, &extents);
2454
						      box, n, &extents);
2455
	}
2455
	}
2456
 
2456
 
2457
	if (dst->drawable.depth == src->drawable.depth) {
2457
	if (dst->drawable.depth == src->drawable.depth) {
2458
		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
2458
		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
2459
		tmp.src.pict_format = tmp.dst.format;
2459
		tmp.src.pict_format = tmp.dst.format;
2460
	} else {
2460
	} else {
2461
		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
2461
		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
2462
		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
2462
		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
2463
	}
2463
	}
2464
	if (!gen6_check_format(tmp.src.pict_format))
2464
	if (!gen6_check_format(tmp.src.pict_format))
2465
		goto fallback_blt;
2465
		goto fallback_blt;
2466
 
2466
 
2467
	tmp.dst.pixmap = dst;
2467
	tmp.dst.pixmap = dst;
2468
	tmp.dst.width  = dst->drawable.width;
2468
	tmp.dst.width  = dst->drawable.width;
2469
	tmp.dst.height = dst->drawable.height;
2469
	tmp.dst.height = dst->drawable.height;
2470
	tmp.dst.bo = dst_bo;
2470
	tmp.dst.bo = dst_bo;
2471
	tmp.dst.x = tmp.dst.y = 0;
2471
	tmp.dst.x = tmp.dst.y = 0;
2472
	tmp.damage = NULL;
2472
	tmp.damage = NULL;
2473
 
2473
 
2474
	sna_render_composite_redirect_init(&tmp);
2474
	sna_render_composite_redirect_init(&tmp);
2475
	if (too_large(tmp.dst.width, tmp.dst.height)) {
2475
	if (too_large(tmp.dst.width, tmp.dst.height)) {
2476
		int i;
2476
		int i;
2477
 
2477
 
2478
		extents = box[0];
2478
		extents = box[0];
2479
		for (i = 1; i < n; i++) {
2479
		for (i = 1; i < n; i++) {
2480
			if (box[i].x1 < extents.x1)
2480
			if (box[i].x1 < extents.x1)
2481
				extents.x1 = box[i].x1;
2481
				extents.x1 = box[i].x1;
2482
			if (box[i].y1 < extents.y1)
2482
			if (box[i].y1 < extents.y1)
2483
				extents.y1 = box[i].y1;
2483
				extents.y1 = box[i].y1;
2484
 
2484
 
2485
			if (box[i].x2 > extents.x2)
2485
			if (box[i].x2 > extents.x2)
2486
				extents.x2 = box[i].x2;
2486
				extents.x2 = box[i].x2;
2487
			if (box[i].y2 > extents.y2)
2487
			if (box[i].y2 > extents.y2)
2488
				extents.y2 = box[i].y2;
2488
				extents.y2 = box[i].y2;
2489
		}
2489
		}
2490
 
2490
 
2491
		if (!sna_render_composite_redirect(sna, &tmp,
2491
		if (!sna_render_composite_redirect(sna, &tmp,
2492
						   extents.x1 + dst_dx,
2492
						   extents.x1 + dst_dx,
2493
						   extents.y1 + dst_dy,
2493
						   extents.y1 + dst_dy,
2494
						   extents.x2 - extents.x1,
2494
						   extents.x2 - extents.x1,
2495
						   extents.y2 - extents.y1,
2495
						   extents.y2 - extents.y1,
2496
						   n > 1))
2496
						   n > 1))
2497
			goto fallback_tiled;
2497
			goto fallback_tiled;
2498
 
2498
 
2499
		dst_dx += tmp.dst.x;
2499
		dst_dx += tmp.dst.x;
2500
		dst_dy += tmp.dst.y;
2500
		dst_dy += tmp.dst.y;
2501
 
2501
 
2502
		tmp.dst.x = tmp.dst.y = 0;
2502
		tmp.dst.x = tmp.dst.y = 0;
2503
	}
2503
	}
2504
 
2504
 
2505
	tmp.src.card_format = gen6_get_card_format(tmp.src.pict_format);
2505
	tmp.src.card_format = gen6_get_card_format(tmp.src.pict_format);
2506
	if (too_large(src->drawable.width, src->drawable.height)) {
2506
	if (too_large(src->drawable.width, src->drawable.height)) {
2507
		int i;
2507
		int i;
2508
 
2508
 
2509
		extents = box[0];
2509
		extents = box[0];
2510
		for (i = 1; i < n; i++) {
2510
		for (i = 1; i < n; i++) {
2511
			if (box[i].x1 < extents.x1)
2511
			if (box[i].x1 < extents.x1)
2512
				extents.x1 = box[i].x1;
2512
				extents.x1 = box[i].x1;
2513
			if (box[i].y1 < extents.y1)
2513
			if (box[i].y1 < extents.y1)
2514
				extents.y1 = box[i].y1;
2514
				extents.y1 = box[i].y1;
2515
 
2515
 
2516
			if (box[i].x2 > extents.x2)
2516
			if (box[i].x2 > extents.x2)
2517
				extents.x2 = box[i].x2;
2517
				extents.x2 = box[i].x2;
2518
			if (box[i].y2 > extents.y2)
2518
			if (box[i].y2 > extents.y2)
2519
				extents.y2 = box[i].y2;
2519
				extents.y2 = box[i].y2;
2520
		}
2520
		}
2521
 
2521
 
2522
		if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src,
2522
		if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src,
2523
					       extents.x1 + src_dx,
2523
					       extents.x1 + src_dx,
2524
					       extents.y1 + src_dy,
2524
					       extents.y1 + src_dy,
2525
					       extents.x2 - extents.x1,
2525
					       extents.x2 - extents.x1,
2526
					       extents.y2 - extents.y1)) {
2526
					       extents.y2 - extents.y1)) {
2527
			DBG(("%s: unable to extract partial pixmap\n", __FUNCTION__));
2527
			DBG(("%s: unable to extract partial pixmap\n", __FUNCTION__));
2528
			goto fallback_tiled_dst;
2528
			goto fallback_tiled_dst;
2529
		}
2529
		}
2530
 
2530
 
2531
		src_dx += tmp.src.offset[0];
2531
		src_dx += tmp.src.offset[0];
2532
		src_dy += tmp.src.offset[1];
2532
		src_dy += tmp.src.offset[1];
2533
	} else {
2533
	} else {
2534
		tmp.src.bo = src_bo;
2534
		tmp.src.bo = src_bo;
2535
		tmp.src.width  = src->drawable.width;
2535
		tmp.src.width  = src->drawable.width;
2536
		tmp.src.height = src->drawable.height;
2536
		tmp.src.height = src->drawable.height;
2537
	}
2537
	}
2538
 
2538
 
2539
	tmp.mask.bo = NULL;
2539
	tmp.mask.bo = NULL;
2540
 
2540
 
2541
	tmp.floats_per_vertex = 2;
2541
	tmp.floats_per_vertex = 2;
2542
	tmp.floats_per_rect = 6;
2542
	tmp.floats_per_rect = 6;
2543
	tmp.need_magic_ca_pass = 0;
2543
	tmp.need_magic_ca_pass = 0;
2544
 
2544
 
2545
	tmp.u.gen6.flags = COPY_FLAGS(alu);
2545
	tmp.u.gen6.flags = COPY_FLAGS(alu);
2546
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
2546
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
2547
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == COPY_SAMPLER);
2547
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == COPY_SAMPLER);
2548
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == COPY_VERTEX);
2548
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == COPY_VERTEX);
2549
 
2549
 
2550
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo);
2550
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo);
2551
	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) {
2551
	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) {
2552
		kgem_submit(&sna->kgem);
2552
		kgem_submit(&sna->kgem);
2553
		if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) {
2553
		if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) {
2554
			DBG(("%s: too large for a single operation\n",
2554
			DBG(("%s: too large for a single operation\n",
2555
			     __FUNCTION__));
2555
			     __FUNCTION__));
2556
			goto fallback_tiled_src;
2556
			goto fallback_tiled_src;
2557
		}
2557
		}
2558
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2558
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2559
	}
2559
	}
2560
 
2560
 
2561
	gen6_emit_copy_state(sna, &tmp);
2561
	gen6_emit_copy_state(sna, &tmp);
2562
	gen6_align_vertex(sna, &tmp);
2562
	gen6_align_vertex(sna, &tmp);
2563
 
2563
 
2564
	do {
2564
	do {
2565
		int16_t *v;
2565
		int16_t *v;
2566
		int n_this_time;
2566
		int n_this_time;
2567
 
2567
 
2568
		n_this_time = gen6_get_rectangles(sna, &tmp, n,
2568
		n_this_time = gen6_get_rectangles(sna, &tmp, n,
2569
						  gen6_emit_copy_state);
2569
						  gen6_emit_copy_state);
2570
		n -= n_this_time;
2570
		n -= n_this_time;
2571
 
2571
 
2572
		v = (int16_t *)(sna->render.vertices + sna->render.vertex_used);
2572
		v = (int16_t *)(sna->render.vertices + sna->render.vertex_used);
2573
		sna->render.vertex_used += 6 * n_this_time;
2573
		sna->render.vertex_used += 6 * n_this_time;
2574
		assert(sna->render.vertex_used <= sna->render.vertex_size);
2574
		assert(sna->render.vertex_used <= sna->render.vertex_size);
2575
		do {
2575
		do {
2576
 
2576
 
2577
			DBG(("	(%d, %d) -> (%d, %d) + (%d, %d)\n",
2577
			DBG(("	(%d, %d) -> (%d, %d) + (%d, %d)\n",
2578
			     box->x1 + src_dx, box->y1 + src_dy,
2578
			     box->x1 + src_dx, box->y1 + src_dy,
2579
			     box->x1 + dst_dx, box->y1 + dst_dy,
2579
			     box->x1 + dst_dx, box->y1 + dst_dy,
2580
			     box->x2 - box->x1, box->y2 - box->y1));
2580
			     box->x2 - box->x1, box->y2 - box->y1));
2581
			v[0] = box->x2 + dst_dx;
2581
			v[0] = box->x2 + dst_dx;
2582
			v[2] = box->x2 + src_dx;
2582
			v[2] = box->x2 + src_dx;
2583
			v[1]  = v[5] = box->y2 + dst_dy;
2583
			v[1]  = v[5] = box->y2 + dst_dy;
2584
			v[3]  = v[7] = box->y2 + src_dy;
2584
			v[3]  = v[7] = box->y2 + src_dy;
2585
			v[8]  = v[4] = box->x1 + dst_dx;
2585
			v[8]  = v[4] = box->x1 + dst_dx;
2586
			v[10] = v[6] = box->x1 + src_dx;
2586
			v[10] = v[6] = box->x1 + src_dx;
2587
			v[9]  = box->y1 + dst_dy;
2587
			v[9]  = box->y1 + dst_dy;
2588
			v[11] = box->y1 + src_dy;
2588
			v[11] = box->y1 + src_dy;
2589
			v += 12; box++;
2589
			v += 12; box++;
2590
		} while (--n_this_time);
2590
		} while (--n_this_time);
2591
	} while (n);
2591
	} while (n);
2592
 
2592
 
2593
	gen4_vertex_flush(sna);
2593
	gen4_vertex_flush(sna);
2594
	sna_render_composite_redirect_done(sna, &tmp);
2594
	sna_render_composite_redirect_done(sna, &tmp);
2595
	if (tmp.src.bo != src_bo)
2595
	if (tmp.src.bo != src_bo)
2596
		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
2596
		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
2597
	return true;
2597
	return true;
2598
 
2598
 
2599
fallback_tiled_src:
2599
fallback_tiled_src:
2600
	if (tmp.src.bo != src_bo)
2600
	if (tmp.src.bo != src_bo)
2601
		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
2601
		kgem_bo_destroy(&sna->kgem, tmp.src.bo);
2602
fallback_tiled_dst:
2602
fallback_tiled_dst:
2603
	if (tmp.redirect.real_bo)
2603
	if (tmp.redirect.real_bo)
2604
		kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
2604
		kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
2605
fallback_tiled:
2605
fallback_tiled:
2606
	if (sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2606
	if (sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2607
	    sna_blt_copy_boxes(sna, alu,
2607
	    sna_blt_copy_boxes(sna, alu,
2608
			       src_bo, src_dx, src_dy,
2608
			       src_bo, src_dx, src_dy,
2609
			       dst_bo, dst_dx, dst_dy,
2609
			       dst_bo, dst_dx, dst_dy,
2610
			       dst->drawable.bitsPerPixel,
2610
			       dst->drawable.bitsPerPixel,
2611
			       box, n))
2611
			       box, n))
2612
		return true;
2612
		return true;
2613
 
2613
 
2614
	return sna_tiling_copy_boxes(sna, alu,
2614
	return sna_tiling_copy_boxes(sna, alu,
2615
				     src, src_bo, src_dx, src_dy,
2615
				     src, src_bo, src_dx, src_dy,
2616
				     dst, dst_bo, dst_dx, dst_dy,
2616
				     dst, dst_bo, dst_dx, dst_dy,
2617
				     box, n);
2617
				     box, n);
2618
}
2618
}
2619
 
2619
 
2620
static void
2620
static void
2621
gen6_render_copy_blt(struct sna *sna,
2621
gen6_render_copy_blt(struct sna *sna,
2622
		     const struct sna_copy_op *op,
2622
		     const struct sna_copy_op *op,
2623
		     int16_t sx, int16_t sy,
2623
		     int16_t sx, int16_t sy,
2624
		     int16_t w,  int16_t h,
2624
		     int16_t w,  int16_t h,
2625
		     int16_t dx, int16_t dy)
2625
		     int16_t dx, int16_t dy)
2626
{
2626
{
2627
	int16_t *v;
2627
	int16_t *v;
2628
 
2628
 
2629
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_copy_state);
2629
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_copy_state);
2630
 
2630
 
2631
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2631
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2632
	sna->render.vertex_used += 6;
2632
	sna->render.vertex_used += 6;
2633
	assert(sna->render.vertex_used <= sna->render.vertex_size);
2633
	assert(sna->render.vertex_used <= sna->render.vertex_size);
2634
 
2634
 
2635
	v[0]  = dx+w; v[1]  = dy+h;
2635
	v[0]  = dx+w; v[1]  = dy+h;
2636
	v[2]  = sx+w; v[3]  = sy+h;
2636
	v[2]  = sx+w; v[3]  = sy+h;
2637
	v[4]  = dx;   v[5]  = dy+h;
2637
	v[4]  = dx;   v[5]  = dy+h;
2638
	v[6]  = sx;   v[7]  = sy+h;
2638
	v[6]  = sx;   v[7]  = sy+h;
2639
	v[8]  = dx;   v[9]  = dy;
2639
	v[8]  = dx;   v[9]  = dy;
2640
	v[10] = sx;   v[11] = sy;
2640
	v[10] = sx;   v[11] = sy;
2641
}
2641
}
2642
 
2642
 
2643
static void
2643
static void
2644
gen6_render_copy_done(struct sna *sna, const struct sna_copy_op *op)
2644
gen6_render_copy_done(struct sna *sna, const struct sna_copy_op *op)
2645
{
2645
{
2646
	DBG(("%s()\n", __FUNCTION__));
2646
	DBG(("%s()\n", __FUNCTION__));
2647
 
2647
 
2648
	assert(!sna->render.active);
2648
	assert(!sna->render.active);
2649
	if (sna->render.vertex_offset)
2649
	if (sna->render.vertex_offset)
2650
		gen4_vertex_flush(sna);
2650
		gen4_vertex_flush(sna);
2651
}
2651
}
2652
 
2652
 
2653
static bool
2653
static bool
2654
gen6_render_copy(struct sna *sna, uint8_t alu,
2654
gen6_render_copy(struct sna *sna, uint8_t alu,
2655
		 PixmapPtr src, struct kgem_bo *src_bo,
2655
		 PixmapPtr src, struct kgem_bo *src_bo,
2656
		 PixmapPtr dst, struct kgem_bo *dst_bo,
2656
		 PixmapPtr dst, struct kgem_bo *dst_bo,
2657
		 struct sna_copy_op *op)
2657
		 struct sna_copy_op *op)
2658
{
2658
{
2659
	DBG(("%s (alu=%d, src=(%dx%d), dst=(%dx%d))\n",
2659
	DBG(("%s (alu=%d, src=(%dx%d), dst=(%dx%d))\n",
2660
	     __FUNCTION__, alu,
2660
	     __FUNCTION__, alu,
2661
	     src->drawable.width, src->drawable.height,
2661
	     src->drawable.width, src->drawable.height,
2662
	     dst->drawable.width, dst->drawable.height));
2662
	     dst->drawable.width, dst->drawable.height));
2663
 
2663
 
2664
	if (prefer_blt_copy(sna, src_bo, dst_bo, 0) &&
2664
	if (prefer_blt_copy(sna, src_bo, dst_bo, 0) &&
2665
	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2665
	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
2666
	    sna_blt_copy(sna, alu,
2666
	    sna_blt_copy(sna, alu,
2667
			 src_bo, dst_bo,
2667
			 src_bo, dst_bo,
2668
			 dst->drawable.bitsPerPixel,
2668
			 dst->drawable.bitsPerPixel,
2669
			 op))
2669
			 op))
2670
		return true;
2670
		return true;
2671
 
2671
 
2672
	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
2672
	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
2673
	    too_large(src->drawable.width, src->drawable.height) ||
2673
	    too_large(src->drawable.width, src->drawable.height) ||
2674
	    too_large(dst->drawable.width, dst->drawable.height)) {
2674
	    too_large(dst->drawable.width, dst->drawable.height)) {
2675
fallback:
2675
fallback:
2676
		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
2676
		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
2677
			return false;
2677
			return false;
2678
 
2678
 
2679
		return sna_blt_copy(sna, alu, src_bo, dst_bo,
2679
		return sna_blt_copy(sna, alu, src_bo, dst_bo,
2680
				    dst->drawable.bitsPerPixel,
2680
				    dst->drawable.bitsPerPixel,
2681
				    op);
2681
				    op);
2682
	}
2682
	}
2683
 
2683
 
2684
	if (dst->drawable.depth == src->drawable.depth) {
2684
	if (dst->drawable.depth == src->drawable.depth) {
2685
		op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
2685
		op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
2686
	op->base.src.pict_format = op->base.dst.format;
2686
	op->base.src.pict_format = op->base.dst.format;
2687
	} else {
2687
	} else {
2688
		op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
2688
		op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
2689
		op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
2689
		op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
2690
	}
2690
	}
2691
	if (!gen6_check_format(op->base.src.pict_format))
2691
	if (!gen6_check_format(op->base.src.pict_format))
2692
		goto fallback;
2692
		goto fallback;
2693
 
2693
 
2694
	op->base.dst.pixmap = dst;
2694
	op->base.dst.pixmap = dst;
2695
	op->base.dst.width  = dst->drawable.width;
2695
	op->base.dst.width  = dst->drawable.width;
2696
	op->base.dst.height = dst->drawable.height;
2696
	op->base.dst.height = dst->drawable.height;
2697
	op->base.dst.bo = dst_bo;
2697
	op->base.dst.bo = dst_bo;
2698
 
2698
 
2699
	op->base.src.bo = src_bo;
2699
	op->base.src.bo = src_bo;
2700
	op->base.src.card_format =
2700
	op->base.src.card_format =
2701
		gen6_get_card_format(op->base.src.pict_format);
2701
		gen6_get_card_format(op->base.src.pict_format);
2702
	op->base.src.width  = src->drawable.width;
2702
	op->base.src.width  = src->drawable.width;
2703
	op->base.src.height = src->drawable.height;
2703
	op->base.src.height = src->drawable.height;
2704
 
2704
 
2705
	op->base.mask.bo = NULL;
2705
	op->base.mask.bo = NULL;
2706
 
2706
 
2707
	op->base.floats_per_vertex = 2;
2707
	op->base.floats_per_vertex = 2;
2708
	op->base.floats_per_rect = 6;
2708
	op->base.floats_per_rect = 6;
2709
 
2709
 
2710
	op->base.u.gen6.flags = COPY_FLAGS(alu);
2710
	op->base.u.gen6.flags = COPY_FLAGS(alu);
2711
	assert(GEN6_KERNEL(op->base.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
2711
	assert(GEN6_KERNEL(op->base.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
2712
	assert(GEN6_SAMPLER(op->base.u.gen6.flags) == COPY_SAMPLER);
2712
	assert(GEN6_SAMPLER(op->base.u.gen6.flags) == COPY_SAMPLER);
2713
	assert(GEN6_VERTEX(op->base.u.gen6.flags) == COPY_VERTEX);
2713
	assert(GEN6_VERTEX(op->base.u.gen6.flags) == COPY_VERTEX);
2714
 
2714
 
2715
	kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo);
2715
	kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo);
2716
	if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
2716
	if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
2717
		kgem_submit(&sna->kgem);
2717
		kgem_submit(&sna->kgem);
2718
		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))
2718
		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))
2719
			goto fallback;
2719
			goto fallback;
2720
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2720
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
2721
	}
2721
	}
2722
 
2722
 
2723
	gen6_emit_copy_state(sna, &op->base);
2723
	gen6_emit_copy_state(sna, &op->base);
2724
	gen6_align_vertex(sna, &op->base);
2724
	gen6_align_vertex(sna, &op->base);
2725
 
2725
 
2726
	op->blt  = gen6_render_copy_blt;
2726
	op->blt  = gen6_render_copy_blt;
2727
	op->done = gen6_render_copy_done;
2727
	op->done = gen6_render_copy_done;
2728
	return true;
2728
	return true;
2729
}
2729
}
2730
#endif
-
 
2731
 
-
 
2732
#if 0
2730
 
2733
static void
2731
static void
2734
gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op)
2732
gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op)
2735
{
2733
{
2736
	uint32_t *binding_table;
2734
	uint32_t *binding_table;
2737
	uint16_t offset;
2735
	uint16_t offset;
2738
	bool dirty;
2736
	bool dirty;
2739
 
2737
 
2740
	dirty = gen6_get_batch(sna, op);
2738
	dirty = gen6_get_batch(sna, op);
2741
 
2739
 
2742
	binding_table = gen6_composite_get_binding_table(sna, &offset);
2740
	binding_table = gen6_composite_get_binding_table(sna, &offset);
2743
 
2741
 
2744
	binding_table[0] =
2742
	binding_table[0] =
2745
		gen6_bind_bo(sna,
2743
		gen6_bind_bo(sna,
2746
			     op->dst.bo, op->dst.width, op->dst.height,
2744
			     op->dst.bo, op->dst.width, op->dst.height,
2747
			     gen6_get_dest_format(op->dst.format),
2745
			     gen6_get_dest_format(op->dst.format),
2748
			     true);
2746
			     true);
2749
	binding_table[1] =
2747
	binding_table[1] =
2750
		gen6_bind_bo(sna,
2748
		gen6_bind_bo(sna,
2751
			     op->src.bo, 1, 1,
2749
			     op->src.bo, 1, 1,
2752
			     GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
2750
			     GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
2753
			     false);
2751
			     false);
2754
 
2752
 
2755
	if (sna->kgem.surface == offset &&
2753
	if (sna->kgem.surface == offset &&
2756
	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
2754
	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
2757
		sna->kgem.surface +=
2755
		sna->kgem.surface +=
2758
			sizeof(struct gen6_surface_state_padded)/sizeof(uint32_t);
2756
			sizeof(struct gen6_surface_state_padded)/sizeof(uint32_t);
2759
		offset = sna->render_state.gen6.surface_table;
2757
		offset = sna->render_state.gen6.surface_table;
2760
	}
2758
	}
2761
 
2759
 
2762
	gen6_emit_state(sna, op, offset | dirty);
2760
	gen6_emit_state(sna, op, offset | dirty);
2763
}
2761
}
2764
 
2762
 
2765
static inline bool prefer_blt_fill(struct sna *sna,
2763
static inline bool prefer_blt_fill(struct sna *sna,
2766
				   struct kgem_bo *bo)
2764
				   struct kgem_bo *bo)
2767
{
2765
{
2768
	if (PREFER_RENDER)
2766
	if (PREFER_RENDER)
2769
		return PREFER_RENDER < 0;
2767
		return PREFER_RENDER < 0;
2770
 
2768
 
2771
	if (kgem_bo_is_render(bo))
2769
	if (kgem_bo_is_render(bo))
2772
		return false;
2770
		return false;
2773
 
2771
 
2774
	if (untiled_tlb_miss(bo))
2772
	if (untiled_tlb_miss(bo))
2775
		return true;
2773
		return true;
2776
 
2774
 
2777
	if (!prefer_blt_ring(sna, bo, 0))
2775
	if (!prefer_blt_ring(sna, bo, 0))
2778
		return false;
2776
		return false;
2779
 
2777
 
2780
	return prefer_blt_bo(sna, bo);
2778
	return prefer_blt_bo(sna, bo);
2781
}
2779
}
2782
 
2780
 
2783
static bool
2781
static bool
2784
gen6_render_fill_boxes(struct sna *sna,
2782
gen6_render_fill_boxes(struct sna *sna,
2785
		       CARD8 op,
2783
		       CARD8 op,
2786
		       PictFormat format,
2784
		       PictFormat format,
2787
		       const xRenderColor *color,
2785
		       const xRenderColor *color,
2788
		       PixmapPtr dst, struct kgem_bo *dst_bo,
2786
		       PixmapPtr dst, struct kgem_bo *dst_bo,
2789
		       const BoxRec *box, int n)
2787
		       const BoxRec *box, int n)
2790
{
2788
{
2791
	struct sna_composite_op tmp;
2789
	struct sna_composite_op tmp;
2792
	uint32_t pixel;
2790
	uint32_t pixel;
2793
 
2791
 
2794
	DBG(("%s (op=%d, color=(%04x, %04x, %04x, %04x) [%08x])\n",
2792
	DBG(("%s (op=%d, color=(%04x, %04x, %04x, %04x) [%08x])\n",
2795
	     __FUNCTION__, op,
2793
	     __FUNCTION__, op,
2796
	     color->red, color->green, color->blue, color->alpha, (int)format));
2794
	     color->red, color->green, color->blue, color->alpha, (int)format));
2797
 
2795
 
2798
	if (op >= ARRAY_SIZE(gen6_blend_op)) {
2796
	if (op >= ARRAY_SIZE(gen6_blend_op)) {
2799
		DBG(("%s: fallback due to unhandled blend op: %d\n",
2797
		DBG(("%s: fallback due to unhandled blend op: %d\n",
2800
		     __FUNCTION__, op));
2798
		     __FUNCTION__, op));
2801
		return false;
2799
		return false;
2802
	}
2800
	}
2803
 
2801
 
2804
	if (prefer_blt_fill(sna, dst_bo) || !gen6_check_dst_format(format)) {
2802
	if (prefer_blt_fill(sna, dst_bo) || !gen6_check_dst_format(format)) {
2805
		uint8_t alu = GXinvalid;
2803
		uint8_t alu = GXinvalid;
2806
 
2804
 
2807
		if (op <= PictOpSrc) {
2805
		if (op <= PictOpSrc) {
2808
			pixel = 0;
2806
			pixel = 0;
2809
			if (op == PictOpClear)
2807
			if (op == PictOpClear)
2810
				alu = GXclear;
2808
				alu = GXclear;
2811
			else if (sna_get_pixel_from_rgba(&pixel,
2809
			else if (sna_get_pixel_from_rgba(&pixel,
2812
							 color->red,
2810
							 color->red,
2813
							 color->green,
2811
							 color->green,
2814
							 color->blue,
2812
							 color->blue,
2815
							 color->alpha,
2813
							 color->alpha,
2816
							 format))
2814
							 format))
2817
				alu = GXcopy;
2815
				alu = GXcopy;
2818
		}
2816
		}
2819
 
2817
 
2820
		if (alu != GXinvalid &&
2818
		if (alu != GXinvalid &&
2821
		    sna_blt_fill_boxes(sna, alu,
2819
		    sna_blt_fill_boxes(sna, alu,
2822
				       dst_bo, dst->drawable.bitsPerPixel,
2820
				       dst_bo, dst->drawable.bitsPerPixel,
2823
				       pixel, box, n))
2821
				       pixel, box, n))
2824
			return true;
2822
			return true;
2825
 
2823
 
2826
		if (!gen6_check_dst_format(format))
2824
		if (!gen6_check_dst_format(format))
2827
			return false;
2825
			return false;
2828
	}
2826
	}
2829
 
2827
 
2830
	if (op == PictOpClear) {
2828
	if (op == PictOpClear) {
2831
		pixel = 0;
2829
		pixel = 0;
2832
		op = PictOpSrc;
2830
		op = PictOpSrc;
2833
	} else if (!sna_get_pixel_from_rgba(&pixel,
2831
	} else if (!sna_get_pixel_from_rgba(&pixel,
2834
					    color->red,
2832
					    color->red,
2835
					    color->green,
2833
					    color->green,
2836
					    color->blue,
2834
					    color->blue,
2837
					    color->alpha,
2835
					    color->alpha,
2838
					    PICT_a8r8g8b8))
2836
					    PICT_a8r8g8b8))
2839
		return false;
2837
		return false;
2840
 
2838
 
2841
	DBG(("%s(%08x x %d [(%d, %d), (%d, %d) ...])\n",
2839
	DBG(("%s(%08x x %d [(%d, %d), (%d, %d) ...])\n",
2842
	     __FUNCTION__, pixel, n,
2840
	     __FUNCTION__, pixel, n,
2843
	     box[0].x1, box[0].y1, box[0].x2, box[0].y2));
2841
	     box[0].x1, box[0].y1, box[0].x2, box[0].y2));
2844
 
2842
 
2845
	tmp.dst.pixmap = dst;
2843
	tmp.dst.pixmap = dst;
2846
	tmp.dst.width  = dst->drawable.width;
2844
	tmp.dst.width  = dst->drawable.width;
2847
	tmp.dst.height = dst->drawable.height;
2845
	tmp.dst.height = dst->drawable.height;
2848
	tmp.dst.format = format;
2846
	tmp.dst.format = format;
2849
	tmp.dst.bo = dst_bo;
2847
	tmp.dst.bo = dst_bo;
2850
	tmp.dst.x = tmp.dst.y = 0;
2848
	tmp.dst.x = tmp.dst.y = 0;
2851
	tmp.damage = NULL;
2849
	tmp.damage = NULL;
2852
 
2850
 
2853
	sna_render_composite_redirect_init(&tmp);
2851
	sna_render_composite_redirect_init(&tmp);
2854
	if (too_large(dst->drawable.width, dst->drawable.height)) {
2852
	if (too_large(dst->drawable.width, dst->drawable.height)) {
2855
		BoxRec extents;
2853
		BoxRec extents;
2856
 
2854
 
2857
		boxes_extents(box, n, &extents);
2855
		boxes_extents(box, n, &extents);
2858
		if (!sna_render_composite_redirect(sna, &tmp,
2856
		if (!sna_render_composite_redirect(sna, &tmp,
2859
						   extents.x1, extents.y1,
2857
						   extents.x1, extents.y1,
2860
						   extents.x2 - extents.x1,
2858
						   extents.x2 - extents.x1,
2861
						   extents.y2 - extents.y1,
2859
						   extents.y2 - extents.y1,
2862
						   n > 1))
2860
						   n > 1))
2863
			return sna_tiling_fill_boxes(sna, op, format, color,
2861
			return sna_tiling_fill_boxes(sna, op, format, color,
2864
						     dst, dst_bo, box, n);
2862
						     dst, dst_bo, box, n);
2865
	}
2863
	}
2866
 
2864
 
2867
	tmp.src.bo = sna_render_get_solid(sna, pixel);
2865
	tmp.src.bo = sna_render_get_solid(sna, pixel);
2868
	tmp.mask.bo = NULL;
2866
	tmp.mask.bo = NULL;
2869
 
2867
 
2870
	tmp.floats_per_vertex = 2;
2868
	tmp.floats_per_vertex = 2;
2871
	tmp.floats_per_rect = 6;
2869
	tmp.floats_per_rect = 6;
2872
	tmp.need_magic_ca_pass = false;
2870
	tmp.need_magic_ca_pass = false;
2873
 
2871
 
2874
	tmp.u.gen6.flags = FILL_FLAGS(op, format);
2872
	tmp.u.gen6.flags = FILL_FLAGS(op, format);
2875
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
2873
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
2876
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
2874
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
2877
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX);
2875
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX);
2878
 
2876
 
2879
	if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
2877
	if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
2880
		kgem_submit(&sna->kgem);
2878
		kgem_submit(&sna->kgem);
2881
		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
2879
		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
2882
	}
2880
	}
2883
 
2881
 
2884
	gen6_emit_fill_state(sna, &tmp);
2882
	gen6_emit_fill_state(sna, &tmp);
2885
	gen6_align_vertex(sna, &tmp);
2883
	gen6_align_vertex(sna, &tmp);
2886
 
2884
 
2887
	do {
2885
	do {
2888
		int n_this_time;
2886
		int n_this_time;
2889
		int16_t *v;
2887
		int16_t *v;
2890
 
2888
 
2891
		n_this_time = gen6_get_rectangles(sna, &tmp, n,
2889
		n_this_time = gen6_get_rectangles(sna, &tmp, n,
2892
						  gen6_emit_fill_state);
2890
						  gen6_emit_fill_state);
2893
		n -= n_this_time;
2891
		n -= n_this_time;
2894
 
2892
 
2895
		v = (int16_t *)(sna->render.vertices + sna->render.vertex_used);
2893
		v = (int16_t *)(sna->render.vertices + sna->render.vertex_used);
2896
		sna->render.vertex_used += 6 * n_this_time;
2894
		sna->render.vertex_used += 6 * n_this_time;
2897
		assert(sna->render.vertex_used <= sna->render.vertex_size);
2895
		assert(sna->render.vertex_used <= sna->render.vertex_size);
2898
		do {
2896
		do {
2899
			DBG(("	(%d, %d), (%d, %d)\n",
2897
			DBG(("	(%d, %d), (%d, %d)\n",
2900
			     box->x1, box->y1, box->x2, box->y2));
2898
			     box->x1, box->y1, box->x2, box->y2));
2901
 
2899
 
2902
			v[0] = box->x2;
2900
			v[0] = box->x2;
2903
			v[5] = v[1] = box->y2;
2901
			v[5] = v[1] = box->y2;
2904
			v[8] = v[4] = box->x1;
2902
			v[8] = v[4] = box->x1;
2905
			v[9] = box->y1;
2903
			v[9] = box->y1;
2906
			v[2] = v[3]  = v[7]  = 1;
2904
			v[2] = v[3]  = v[7]  = 1;
2907
			v[6] = v[10] = v[11] = 0;
2905
			v[6] = v[10] = v[11] = 0;
2908
			v += 12; box++;
2906
			v += 12; box++;
2909
		} while (--n_this_time);
2907
		} while (--n_this_time);
2910
	} while (n);
2908
	} while (n);
2911
 
2909
 
2912
	gen4_vertex_flush(sna);
2910
	gen4_vertex_flush(sna);
2913
	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
2911
	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
2914
	sna_render_composite_redirect_done(sna, &tmp);
2912
	sna_render_composite_redirect_done(sna, &tmp);
2915
	return true;
2913
	return true;
2916
}
2914
}
2917
 
2915
 
2918
static void
2916
static void
2919
gen6_render_op_fill_blt(struct sna *sna,
2917
gen6_render_op_fill_blt(struct sna *sna,
2920
			const struct sna_fill_op *op,
2918
			const struct sna_fill_op *op,
2921
			int16_t x, int16_t y, int16_t w, int16_t h)
2919
			int16_t x, int16_t y, int16_t w, int16_t h)
2922
{
2920
{
2923
	int16_t *v;
2921
	int16_t *v;
2924
 
2922
 
2925
	DBG(("%s: (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h));
2923
	DBG(("%s: (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h));
2926
 
2924
 
2927
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_fill_state);
2925
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_fill_state);
2928
 
2926
 
2929
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2927
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2930
	sna->render.vertex_used += 6;
2928
	sna->render.vertex_used += 6;
2931
	assert(sna->render.vertex_used <= sna->render.vertex_size);
2929
	assert(sna->render.vertex_used <= sna->render.vertex_size);
2932
 
2930
 
2933
	v[0] = x+w;
2931
	v[0] = x+w;
2934
	v[4] = v[8] = x;
2932
	v[4] = v[8] = x;
2935
	v[1] = v[5] = y+h;
2933
	v[1] = v[5] = y+h;
2936
	v[9] = y;
2934
	v[9] = y;
2937
 
2935
 
2938
	v[2] = v[3]  = v[7]  = 1;
2936
	v[2] = v[3]  = v[7]  = 1;
2939
	v[6] = v[10] = v[11] = 0;
2937
	v[6] = v[10] = v[11] = 0;
2940
}
2938
}
2941
 
2939
 
2942
fastcall static void
2940
fastcall static void
2943
gen6_render_op_fill_box(struct sna *sna,
2941
gen6_render_op_fill_box(struct sna *sna,
2944
			const struct sna_fill_op *op,
2942
			const struct sna_fill_op *op,
2945
			const BoxRec *box)
2943
			const BoxRec *box)
2946
{
2944
{
2947
	int16_t *v;
2945
	int16_t *v;
2948
 
2946
 
2949
	DBG(("%s: (%d, %d),(%d, %d)\n", __FUNCTION__,
2947
	DBG(("%s: (%d, %d),(%d, %d)\n", __FUNCTION__,
2950
	     box->x1, box->y1, box->x2, box->y2));
2948
	     box->x1, box->y1, box->x2, box->y2));
2951
 
2949
 
2952
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_fill_state);
2950
	gen6_get_rectangles(sna, &op->base, 1, gen6_emit_fill_state);
2953
 
2951
 
2954
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2952
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2955
	sna->render.vertex_used += 6;
2953
	sna->render.vertex_used += 6;
2956
	assert(sna->render.vertex_used <= sna->render.vertex_size);
2954
	assert(sna->render.vertex_used <= sna->render.vertex_size);
2957
 
2955
 
2958
	v[0] = box->x2;
2956
	v[0] = box->x2;
2959
	v[8] = v[4] = box->x1;
2957
	v[8] = v[4] = box->x1;
2960
	v[5] = v[1] = box->y2;
2958
	v[5] = v[1] = box->y2;
2961
	v[9] = box->y1;
2959
	v[9] = box->y1;
2962
 
2960
 
2963
	v[7] = v[2]  = v[3]  = 1;
2961
	v[7] = v[2]  = v[3]  = 1;
2964
	v[6] = v[10] = v[11] = 0;
2962
	v[6] = v[10] = v[11] = 0;
2965
}
2963
}
2966
 
2964
 
2967
fastcall static void
2965
fastcall static void
2968
gen6_render_op_fill_boxes(struct sna *sna,
2966
gen6_render_op_fill_boxes(struct sna *sna,
2969
			  const struct sna_fill_op *op,
2967
			  const struct sna_fill_op *op,
2970
			  const BoxRec *box,
2968
			  const BoxRec *box,
2971
			  int nbox)
2969
			  int nbox)
2972
{
2970
{
2973
	DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__,
2971
	DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__,
2974
	     box->x1, box->y1, box->x2, box->y2, nbox));
2972
	     box->x1, box->y1, box->x2, box->y2, nbox));
2975
 
2973
 
2976
	do {
2974
	do {
2977
		int nbox_this_time;
2975
		int nbox_this_time;
2978
		int16_t *v;
2976
		int16_t *v;
2979
 
2977
 
2980
		nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox,
2978
		nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox,
2981
						     gen6_emit_fill_state);
2979
						     gen6_emit_fill_state);
2982
		nbox -= nbox_this_time;
2980
		nbox -= nbox_this_time;
2983
 
2981
 
2984
		v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2982
		v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
2985
		sna->render.vertex_used += 6 * nbox_this_time;
2983
		sna->render.vertex_used += 6 * nbox_this_time;
2986
		assert(sna->render.vertex_used <= sna->render.vertex_size);
2984
		assert(sna->render.vertex_used <= sna->render.vertex_size);
2987
 
2985
 
2988
		do {
2986
		do {
2989
			v[0] = box->x2;
2987
			v[0] = box->x2;
2990
			v[8] = v[4] = box->x1;
2988
			v[8] = v[4] = box->x1;
2991
			v[5] = v[1] = box->y2;
2989
			v[5] = v[1] = box->y2;
2992
			v[9] = box->y1;
2990
			v[9] = box->y1;
2993
			v[7] = v[2]  = v[3]  = 1;
2991
			v[7] = v[2]  = v[3]  = 1;
2994
			v[6] = v[10] = v[11] = 0;
2992
			v[6] = v[10] = v[11] = 0;
2995
			box++; v += 12;
2993
			box++; v += 12;
2996
		} while (--nbox_this_time);
2994
		} while (--nbox_this_time);
2997
	} while (nbox);
2995
	} while (nbox);
2998
}
2996
}
2999
 
2997
 
3000
static void
2998
static void
3001
gen6_render_op_fill_done(struct sna *sna, const struct sna_fill_op *op)
2999
gen6_render_op_fill_done(struct sna *sna, const struct sna_fill_op *op)
3002
{
3000
{
3003
	DBG(("%s()\n", __FUNCTION__));
3001
	DBG(("%s()\n", __FUNCTION__));
3004
 
3002
 
3005
	assert(!sna->render.active);
3003
	assert(!sna->render.active);
3006
	if (sna->render.vertex_offset)
3004
	if (sna->render.vertex_offset)
3007
		gen4_vertex_flush(sna);
3005
		gen4_vertex_flush(sna);
3008
	kgem_bo_destroy(&sna->kgem, op->base.src.bo);
3006
	kgem_bo_destroy(&sna->kgem, op->base.src.bo);
3009
}
3007
}
3010
 
3008
 
3011
static bool
3009
static bool
3012
gen6_render_fill(struct sna *sna, uint8_t alu,
3010
gen6_render_fill(struct sna *sna, uint8_t alu,
3013
		 PixmapPtr dst, struct kgem_bo *dst_bo,
3011
		 PixmapPtr dst, struct kgem_bo *dst_bo,
3014
		 uint32_t color,
3012
		 uint32_t color,
3015
		 struct sna_fill_op *op)
3013
		 struct sna_fill_op *op)
3016
{
3014
{
3017
	DBG(("%s: (alu=%d, color=%x)\n", __FUNCTION__, alu, color));
3015
	DBG(("%s: (alu=%d, color=%x)\n", __FUNCTION__, alu, color));
3018
 
3016
 
3019
	if (prefer_blt_fill(sna, dst_bo) &&
3017
	if (prefer_blt_fill(sna, dst_bo) &&
3020
	    sna_blt_fill(sna, alu,
3018
	    sna_blt_fill(sna, alu,
3021
			 dst_bo, dst->drawable.bitsPerPixel,
3019
			 dst_bo, dst->drawable.bitsPerPixel,
3022
			 color,
3020
			 color,
3023
			 op))
3021
			 op))
3024
		return true;
3022
		return true;
3025
 
3023
 
3026
	if (!(alu == GXcopy || alu == GXclear) ||
3024
	if (!(alu == GXcopy || alu == GXclear) ||
3027
	    too_large(dst->drawable.width, dst->drawable.height))
3025
	    too_large(dst->drawable.width, dst->drawable.height))
3028
		return sna_blt_fill(sna, alu,
3026
		return sna_blt_fill(sna, alu,
3029
				    dst_bo, dst->drawable.bitsPerPixel,
3027
				    dst_bo, dst->drawable.bitsPerPixel,
3030
				    color,
3028
				    color,
3031
				    op);
3029
				    op);
3032
 
3030
 
3033
	if (alu == GXclear)
3031
	if (alu == GXclear)
3034
		color = 0;
3032
		color = 0;
3035
 
3033
 
3036
	op->base.dst.pixmap = dst;
3034
	op->base.dst.pixmap = dst;
3037
	op->base.dst.width  = dst->drawable.width;
3035
	op->base.dst.width  = dst->drawable.width;
3038
	op->base.dst.height = dst->drawable.height;
3036
	op->base.dst.height = dst->drawable.height;
3039
	op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
3037
	op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
3040
	op->base.dst.bo = dst_bo;
3038
	op->base.dst.bo = dst_bo;
3041
	op->base.dst.x = op->base.dst.y = 0;
3039
	op->base.dst.x = op->base.dst.y = 0;
3042
 
3040
 
3043
	op->base.src.bo =
3041
	op->base.src.bo =
3044
		sna_render_get_solid(sna,
3042
		sna_render_get_solid(sna,
3045
				     sna_rgba_for_color(color,
3043
				     sna_rgba_for_color(color,
3046
							dst->drawable.depth));
3044
							dst->drawable.depth));
3047
	op->base.mask.bo = NULL;
3045
	op->base.mask.bo = NULL;
3048
 
3046
 
3049
	op->base.need_magic_ca_pass = false;
3047
	op->base.need_magic_ca_pass = false;
3050
	op->base.floats_per_vertex = 2;
3048
	op->base.floats_per_vertex = 2;
3051
	op->base.floats_per_rect = 6;
3049
	op->base.floats_per_rect = 6;
3052
 
3050
 
3053
	op->base.u.gen6.flags = FILL_FLAGS_NOBLEND;
3051
	op->base.u.gen6.flags = FILL_FLAGS_NOBLEND;
3054
	assert(GEN6_KERNEL(op->base.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
3052
	assert(GEN6_KERNEL(op->base.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
3055
	assert(GEN6_SAMPLER(op->base.u.gen6.flags) == FILL_SAMPLER);
3053
	assert(GEN6_SAMPLER(op->base.u.gen6.flags) == FILL_SAMPLER);
3056
	assert(GEN6_VERTEX(op->base.u.gen6.flags) == FILL_VERTEX);
3054
	assert(GEN6_VERTEX(op->base.u.gen6.flags) == FILL_VERTEX);
3057
 
3055
 
3058
	if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
3056
	if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
3059
		kgem_submit(&sna->kgem);
3057
		kgem_submit(&sna->kgem);
3060
		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
3058
		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
3061
	}
3059
	}
3062
 
3060
 
3063
	gen6_emit_fill_state(sna, &op->base);
3061
	gen6_emit_fill_state(sna, &op->base);
3064
	gen6_align_vertex(sna, &op->base);
3062
	gen6_align_vertex(sna, &op->base);
3065
 
3063
 
3066
	op->blt  = gen6_render_op_fill_blt;
3064
	op->blt  = gen6_render_op_fill_blt;
3067
	op->box  = gen6_render_op_fill_box;
3065
	op->box  = gen6_render_op_fill_box;
3068
	op->boxes = gen6_render_op_fill_boxes;
3066
	op->boxes = gen6_render_op_fill_boxes;
3069
	op->done = gen6_render_op_fill_done;
3067
	op->done = gen6_render_op_fill_done;
3070
	return true;
3068
	return true;
3071
}
3069
}
3072
 
3070
 
3073
static bool
3071
static bool
3074
gen6_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
3072
gen6_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
3075
			     uint32_t color,
3073
			     uint32_t color,
3076
			     int16_t x1, int16_t y1, int16_t x2, int16_t y2,
3074
			     int16_t x1, int16_t y1, int16_t x2, int16_t y2,
3077
			     uint8_t alu)
3075
			     uint8_t alu)
3078
{
3076
{
3079
	BoxRec box;
3077
	BoxRec box;
3080
 
3078
 
3081
	box.x1 = x1;
3079
	box.x1 = x1;
3082
	box.y1 = y1;
3080
	box.y1 = y1;
3083
	box.x2 = x2;
3081
	box.x2 = x2;
3084
	box.y2 = y2;
3082
	box.y2 = y2;
3085
 
3083
 
3086
	return sna_blt_fill_boxes(sna, alu,
3084
	return sna_blt_fill_boxes(sna, alu,
3087
				  bo, dst->drawable.bitsPerPixel,
3085
				  bo, dst->drawable.bitsPerPixel,
3088
				  color, &box, 1);
3086
				  color, &box, 1);
3089
}
3087
}
3090
 
3088
 
3091
static bool
3089
static bool
3092
gen6_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
3090
gen6_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
3093
		     uint32_t color,
3091
		     uint32_t color,
3094
		     int16_t x1, int16_t y1,
3092
		     int16_t x1, int16_t y1,
3095
		     int16_t x2, int16_t y2,
3093
		     int16_t x2, int16_t y2,
3096
		     uint8_t alu)
3094
		     uint8_t alu)
3097
{
3095
{
3098
	struct sna_composite_op tmp;
3096
	struct sna_composite_op tmp;
3099
	int16_t *v;
3097
	int16_t *v;
3100
 
3098
 
3101
	/* Prefer to use the BLT if already engaged */
3099
	/* Prefer to use the BLT if already engaged */
3102
	if (prefer_blt_fill(sna, bo) &&
3100
	if (prefer_blt_fill(sna, bo) &&
3103
	    gen6_render_fill_one_try_blt(sna, dst, bo, color,
3101
	    gen6_render_fill_one_try_blt(sna, dst, bo, color,
3104
					 x1, y1, x2, y2, alu))
3102
					 x1, y1, x2, y2, alu))
3105
		return true;
3103
		return true;
3106
 
3104
 
3107
	/* Must use the BLT if we can't RENDER... */
3105
	/* Must use the BLT if we can't RENDER... */
3108
	if (!(alu == GXcopy || alu == GXclear) ||
3106
	if (!(alu == GXcopy || alu == GXclear) ||
3109
	    too_large(dst->drawable.width, dst->drawable.height))
3107
	    too_large(dst->drawable.width, dst->drawable.height))
3110
		return gen6_render_fill_one_try_blt(sna, dst, bo, color,
3108
		return gen6_render_fill_one_try_blt(sna, dst, bo, color,
3111
						    x1, y1, x2, y2, alu);
3109
						    x1, y1, x2, y2, alu);
3112
 
3110
 
3113
	if (alu == GXclear)
3111
	if (alu == GXclear)
3114
		color = 0;
3112
		color = 0;
3115
 
3113
 
3116
	tmp.dst.pixmap = dst;
3114
	tmp.dst.pixmap = dst;
3117
	tmp.dst.width  = dst->drawable.width;
3115
	tmp.dst.width  = dst->drawable.width;
3118
	tmp.dst.height = dst->drawable.height;
3116
	tmp.dst.height = dst->drawable.height;
3119
	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
3117
	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
3120
	tmp.dst.bo = bo;
3118
	tmp.dst.bo = bo;
3121
	tmp.dst.x = tmp.dst.y = 0;
3119
	tmp.dst.x = tmp.dst.y = 0;
3122
 
3120
 
3123
	tmp.src.bo =
3121
	tmp.src.bo =
3124
		sna_render_get_solid(sna,
3122
		sna_render_get_solid(sna,
3125
				     sna_rgba_for_color(color,
3123
				     sna_rgba_for_color(color,
3126
							dst->drawable.depth));
3124
							dst->drawable.depth));
3127
	tmp.mask.bo = NULL;
3125
	tmp.mask.bo = NULL;
3128
 
3126
 
3129
	tmp.floats_per_vertex = 2;
3127
	tmp.floats_per_vertex = 2;
3130
	tmp.floats_per_rect = 6;
3128
	tmp.floats_per_rect = 6;
3131
	tmp.need_magic_ca_pass = false;
3129
	tmp.need_magic_ca_pass = false;
3132
 
3130
 
3133
	tmp.u.gen6.flags = FILL_FLAGS_NOBLEND;
3131
	tmp.u.gen6.flags = FILL_FLAGS_NOBLEND;
3134
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
3132
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
3135
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
3133
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
3136
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX);
3134
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX);
3137
 
3135
 
3138
	if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3136
	if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3139
		kgem_submit(&sna->kgem);
3137
		kgem_submit(&sna->kgem);
3140
		if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3138
		if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3141
			kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3139
			kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3142
			return false;
3140
			return false;
3143
		}
3141
		}
3144
	}
3142
	}
3145
 
3143
 
3146
	gen6_emit_fill_state(sna, &tmp);
3144
	gen6_emit_fill_state(sna, &tmp);
3147
	gen6_align_vertex(sna, &tmp);
3145
	gen6_align_vertex(sna, &tmp);
3148
 
3146
 
3149
	gen6_get_rectangles(sna, &tmp, 1, gen6_emit_fill_state);
3147
	gen6_get_rectangles(sna, &tmp, 1, gen6_emit_fill_state);
3150
 
3148
 
3151
	DBG(("	(%d, %d), (%d, %d)\n", x1, y1, x2, y2));
3149
	DBG(("	(%d, %d), (%d, %d)\n", x1, y1, x2, y2));
3152
 
3150
 
3153
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
3151
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
3154
	sna->render.vertex_used += 6;
3152
	sna->render.vertex_used += 6;
3155
	assert(sna->render.vertex_used <= sna->render.vertex_size);
3153
	assert(sna->render.vertex_used <= sna->render.vertex_size);
3156
 
3154
 
3157
	v[0] = x2;
3155
	v[0] = x2;
3158
	v[8] = v[4] = x1;
3156
	v[8] = v[4] = x1;
3159
	v[5] = v[1] = y2;
3157
	v[5] = v[1] = y2;
3160
	v[9] = y1;
3158
	v[9] = y1;
3161
	v[7] = v[2]  = v[3]  = 1;
3159
	v[7] = v[2]  = v[3]  = 1;
3162
	v[6] = v[10] = v[11] = 0;
3160
	v[6] = v[10] = v[11] = 0;
3163
 
3161
 
3164
	gen4_vertex_flush(sna);
3162
	gen4_vertex_flush(sna);
3165
	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3163
	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3166
 
3164
 
3167
	return true;
3165
	return true;
3168
}
3166
}
3169
 
3167
 
3170
static bool
3168
static bool
3171
gen6_render_clear_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
3169
gen6_render_clear_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
3172
{
3170
{
3173
	BoxRec box;
3171
	BoxRec box;
3174
 
3172
 
3175
	box.x1 = 0;
3173
	box.x1 = 0;
3176
	box.y1 = 0;
3174
	box.y1 = 0;
3177
	box.x2 = dst->drawable.width;
3175
	box.x2 = dst->drawable.width;
3178
	box.y2 = dst->drawable.height;
3176
	box.y2 = dst->drawable.height;
3179
 
3177
 
3180
	return sna_blt_fill_boxes(sna, GXclear,
3178
	return sna_blt_fill_boxes(sna, GXclear,
3181
				  bo, dst->drawable.bitsPerPixel,
3179
				  bo, dst->drawable.bitsPerPixel,
3182
				  0, &box, 1);
3180
				  0, &box, 1);
3183
}
3181
}
3184
 
3182
 
3185
static bool
3183
static bool
3186
gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
3184
gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
3187
{
3185
{
3188
	struct sna_composite_op tmp;
3186
	struct sna_composite_op tmp;
3189
	int16_t *v;
3187
	int16_t *v;
3190
 
3188
 
3191
	DBG(("%s: %dx%d\n",
3189
	DBG(("%s: %dx%d\n",
3192
	     __FUNCTION__,
3190
	     __FUNCTION__,
3193
	     dst->drawable.width,
3191
	     dst->drawable.width,
3194
	     dst->drawable.height));
3192
	     dst->drawable.height));
3195
 
3193
 
3196
	/* Prefer to use the BLT if, and only if, already engaged */
3194
	/* Prefer to use the BLT if, and only if, already engaged */
3197
	if (sna->kgem.ring == KGEM_BLT &&
3195
	if (sna->kgem.ring == KGEM_BLT &&
3198
	    gen6_render_clear_try_blt(sna, dst, bo))
3196
	    gen6_render_clear_try_blt(sna, dst, bo))
3199
		return true;
3197
		return true;
3200
 
3198
 
3201
	/* Must use the BLT if we can't RENDER... */
3199
	/* Must use the BLT if we can't RENDER... */
3202
	if (too_large(dst->drawable.width, dst->drawable.height))
3200
	if (too_large(dst->drawable.width, dst->drawable.height))
3203
		return gen6_render_clear_try_blt(sna, dst, bo);
3201
		return gen6_render_clear_try_blt(sna, dst, bo);
3204
 
3202
 
3205
	tmp.dst.pixmap = dst;
3203
	tmp.dst.pixmap = dst;
3206
	tmp.dst.width  = dst->drawable.width;
3204
	tmp.dst.width  = dst->drawable.width;
3207
	tmp.dst.height = dst->drawable.height;
3205
	tmp.dst.height = dst->drawable.height;
3208
	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
3206
	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
3209
	tmp.dst.bo = bo;
3207
	tmp.dst.bo = bo;
3210
	tmp.dst.x = tmp.dst.y = 0;
3208
	tmp.dst.x = tmp.dst.y = 0;
3211
 
3209
 
3212
	tmp.src.bo = sna_render_get_solid(sna, 0);
3210
	tmp.src.bo = sna_render_get_solid(sna, 0);
3213
	tmp.mask.bo = NULL;
3211
	tmp.mask.bo = NULL;
3214
 
3212
 
3215
	tmp.floats_per_vertex = 2;
3213
	tmp.floats_per_vertex = 2;
3216
	tmp.floats_per_rect = 6;
3214
	tmp.floats_per_rect = 6;
3217
	tmp.need_magic_ca_pass = false;
3215
	tmp.need_magic_ca_pass = false;
3218
 
3216
 
3219
	tmp.u.gen6.flags = FILL_FLAGS_NOBLEND;
3217
	tmp.u.gen6.flags = FILL_FLAGS_NOBLEND;
3220
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
3218
	assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK);
3221
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
3219
	assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
3222
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX);
3220
	assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX);
3223
 
3221
 
3224
	if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3222
	if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3225
		kgem_submit(&sna->kgem);
3223
		kgem_submit(&sna->kgem);
3226
		if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3224
		if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3227
			kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3225
			kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3228
			return false;
3226
			return false;
3229
		}
3227
		}
3230
	}
3228
	}
3231
 
3229
 
3232
	gen6_emit_fill_state(sna, &tmp);
3230
	gen6_emit_fill_state(sna, &tmp);
3233
	gen6_align_vertex(sna, &tmp);
3231
	gen6_align_vertex(sna, &tmp);
3234
 
3232
 
3235
	gen6_get_rectangles(sna, &tmp, 1, gen6_emit_fill_state);
3233
	gen6_get_rectangles(sna, &tmp, 1, gen6_emit_fill_state);
3236
 
3234
 
3237
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
3235
	v = (int16_t *)&sna->render.vertices[sna->render.vertex_used];
3238
	sna->render.vertex_used += 6;
3236
	sna->render.vertex_used += 6;
3239
	assert(sna->render.vertex_used <= sna->render.vertex_size);
3237
	assert(sna->render.vertex_used <= sna->render.vertex_size);
3240
 
3238
 
3241
	v[0] = dst->drawable.width;
3239
	v[0] = dst->drawable.width;
3242
	v[5] = v[1] = dst->drawable.height;
3240
	v[5] = v[1] = dst->drawable.height;
3243
	v[8] = v[4] = 0;
3241
	v[8] = v[4] = 0;
3244
	v[9] = 0;
3242
	v[9] = 0;
3245
 
3243
 
3246
	v[7] = v[2]  = v[3]  = 1;
3244
	v[7] = v[2]  = v[3]  = 1;
3247
	v[6] = v[10] = v[11] = 0;
3245
	v[6] = v[10] = v[11] = 0;
3248
 
3246
 
3249
	gen4_vertex_flush(sna);
3247
	gen4_vertex_flush(sna);
3250
	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3248
	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3251
 
3249
 
3252
	return true;
3250
	return true;
3253
}
3251
}
3254
#endif
3252
#endif
3255
 
3253
 
3256
static void gen6_render_flush(struct sna *sna)
3254
static void gen6_render_flush(struct sna *sna)
3257
{
3255
{
3258
	gen4_vertex_close(sna);
3256
	gen4_vertex_close(sna);
3259
 
3257
 
3260
	assert(sna->render.vb_id == 0);
3258
	assert(sna->render.vb_id == 0);
3261
	assert(sna->render.vertex_offset == 0);
3259
	assert(sna->render.vertex_offset == 0);
3262
}
3260
}
3263
 
3261
 
3264
static void
3262
static void
3265
gen6_render_context_switch(struct kgem *kgem,
3263
gen6_render_context_switch(struct kgem *kgem,
3266
			   int new_mode)
3264
			   int new_mode)
3267
{
3265
{
3268
	if (kgem->nbatch) {
3266
	if (kgem->nbatch) {
3269
		DBG(("%s: from %d to %d\n", __FUNCTION__, kgem->mode, new_mode));
3267
		DBG(("%s: from %d to %d\n", __FUNCTION__, kgem->mode, new_mode));
3270
		_kgem_submit(kgem);
3268
		_kgem_submit(kgem);
3271
	}
3269
	}
3272
 
3270
 
3273
	kgem->ring = new_mode;
3271
	kgem->ring = new_mode;
3274
}
3272
}
3275
 
3273
 
3276
static void
3274
static void
3277
gen6_render_retire(struct kgem *kgem)
3275
gen6_render_retire(struct kgem *kgem)
3278
{
3276
{
3279
	struct sna *sna;
3277
	struct sna *sna;
3280
 
3278
 
3281
	if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire))
3279
	if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire))
3282
		kgem->ring = kgem->mode;
3280
		kgem->ring = kgem->mode;
3283
 
3281
 
3284
	sna = container_of(kgem, struct sna, kgem);
3282
	sna = container_of(kgem, struct sna, kgem);
3285
	if (kgem->nbatch == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) {
3283
	if (kgem->nbatch == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) {
3286
		DBG(("%s: resetting idle vbo handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
3284
		DBG(("%s: resetting idle vbo handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
3287
		sna->render.vertex_used = 0;
3285
		sna->render.vertex_used = 0;
3288
		sna->render.vertex_index = 0;
3286
		sna->render.vertex_index = 0;
3289
	}
3287
	}
3290
}
3288
}
3291
 
3289
 
3292
static void
3290
static void
3293
gen6_render_expire(struct kgem *kgem)
3291
gen6_render_expire(struct kgem *kgem)
3294
{
3292
{
3295
	struct sna *sna;
3293
	struct sna *sna;
3296
 
3294
 
3297
	sna = container_of(kgem, struct sna, kgem);
3295
	sna = container_of(kgem, struct sna, kgem);
3298
	if (sna->render.vbo && !sna->render.vertex_used) {
3296
	if (sna->render.vbo && !sna->render.vertex_used) {
3299
		DBG(("%s: discarding vbo handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
3297
		DBG(("%s: discarding vbo handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
3300
		kgem_bo_destroy(kgem, sna->render.vbo);
3298
		kgem_bo_destroy(kgem, sna->render.vbo);
3301
		assert(!sna->render.active);
3299
		assert(!sna->render.active);
3302
		sna->render.vbo = NULL;
3300
		sna->render.vbo = NULL;
3303
		sna->render.vertices = sna->render.vertex_data;
3301
		sna->render.vertices = sna->render.vertex_data;
3304
		sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
3302
		sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
3305
		sna->render.vertex_used = 0;
3303
		sna->render.vertex_used = 0;
3306
		sna->render.vertex_index = 0;
3304
		sna->render.vertex_index = 0;
3307
	}
3305
	}
3308
}
3306
}
3309
 
3307
 
3310
static void gen6_render_reset(struct sna *sna)
3308
static void gen6_render_reset(struct sna *sna)
3311
{
3309
{
3312
	sna->render_state.gen6.needs_invariant = true;
3310
	sna->render_state.gen6.needs_invariant = true;
3313
	sna->render_state.gen6.first_state_packet = true;
3311
	sna->render_state.gen6.first_state_packet = true;
3314
	sna->render_state.gen6.ve_id = 3 << 2;
3312
	sna->render_state.gen6.ve_id = 3 << 2;
3315
	sna->render_state.gen6.last_primitive = -1;
3313
	sna->render_state.gen6.last_primitive = -1;
3316
 
3314
 
3317
	sna->render_state.gen6.num_sf_outputs = 0;
3315
	sna->render_state.gen6.num_sf_outputs = 0;
3318
	sna->render_state.gen6.samplers = -1;
3316
	sna->render_state.gen6.samplers = -1;
3319
	sna->render_state.gen6.blend = -1;
3317
	sna->render_state.gen6.blend = -1;
3320
	sna->render_state.gen6.kernel = -1;
3318
	sna->render_state.gen6.kernel = -1;
3321
	sna->render_state.gen6.drawrect_offset = -1;
3319
	sna->render_state.gen6.drawrect_offset = -1;
3322
	sna->render_state.gen6.drawrect_limit = -1;
3320
	sna->render_state.gen6.drawrect_limit = -1;
3323
	sna->render_state.gen6.surface_table = -1;
3321
	sna->render_state.gen6.surface_table = -1;
3324
 
3322
 
3325
	sna->render.vertex_offset = 0;
3323
	sna->render.vertex_offset = 0;
3326
	sna->render.nvertex_reloc = 0;
3324
	sna->render.nvertex_reloc = 0;
3327
	sna->render.vb_id = 0;
3325
	sna->render.vb_id = 0;
3328
}
3326
}
3329
 
3327
 
3330
static void gen6_render_fini(struct sna *sna)
3328
static void gen6_render_fini(struct sna *sna)
3331
{
3329
{
3332
    kgem_bo_destroy(&sna->kgem, sna->render_state.gen6.general_bo);
3330
    kgem_bo_destroy(&sna->kgem, sna->render_state.gen6.general_bo);
3333
}
3331
}
3334
 
3332
 
3335
static bool is_gt2(struct sna *sna)
3333
static bool is_gt2(struct sna *sna)
3336
{
3334
{
3337
	return sna->PciInfo->device_id & 0x30;
3335
	return sna->PciInfo->device_id & 0x30;
3338
}
3336
}
3339
 
3337
 
3340
static bool is_mobile(struct sna *sna)
3338
static bool is_mobile(struct sna *sna)
3341
{
3339
{
3342
	return (sna->PciInfo->device_id & 0xf) == 0x6;
3340
	return (sna->PciInfo->device_id & 0xf) == 0x6;
3343
}
3341
}
3344
 
3342
 
3345
static bool gen6_render_setup(struct sna *sna)
3343
static bool gen6_render_setup(struct sna *sna)
3346
{
3344
{
3347
	struct gen6_render_state *state = &sna->render_state.gen6;
3345
	struct gen6_render_state *state = &sna->render_state.gen6;
3348
	struct sna_static_stream general;
3346
	struct sna_static_stream general;
3349
	struct gen6_sampler_state *ss;
3347
	struct gen6_sampler_state *ss;
3350
	int i, j, k, l, m;
3348
	int i, j, k, l, m;
3351
 
3349
 
3352
	state->info = >1_info;
3350
	state->info = >1_info;
3353
	if (is_gt2(sna))
3351
	if (is_gt2(sna))
3354
		state->info = >2_info; /* XXX requires GT_MODE WiZ disabled */
3352
		state->info = >2_info; /* XXX requires GT_MODE WiZ disabled */
3355
 
3353
 
3356
    sna_static_stream_init(&general);
3354
    sna_static_stream_init(&general);
3357
 
3355
 
3358
	/* Zero pad the start. If you see an offset of 0x0 in the batchbuffer
3356
	/* Zero pad the start. If you see an offset of 0x0 in the batchbuffer
3359
	 * dumps, you know it points to zero.
3357
	 * dumps, you know it points to zero.
3360
	 */
3358
	 */
3361
    null_create(&general);
3359
    null_create(&general);
3362
    scratch_create(&general);
3360
    scratch_create(&general);
3363
 
3361
 
3364
	for (m = 0; m < GEN6_KERNEL_COUNT; m++) {
3362
	for (m = 0; m < GEN6_KERNEL_COUNT; m++) {
3365
		if (wm_kernels[m].size) {
3363
		if (wm_kernels[m].size) {
3366
			state->wm_kernel[m][1] =
3364
			state->wm_kernel[m][1] =
3367
			sna_static_stream_add(&general,
3365
			sna_static_stream_add(&general,
3368
					       wm_kernels[m].data,
3366
					       wm_kernels[m].data,
3369
					       wm_kernels[m].size,
3367
					       wm_kernels[m].size,
3370
					       64);
3368
					       64);
3371
		} else {
3369
		} else {
3372
			if (USE_8_PIXEL_DISPATCH) {
3370
			if (USE_8_PIXEL_DISPATCH) {
3373
				state->wm_kernel[m][0] =
3371
				state->wm_kernel[m][0] =
3374
					sna_static_stream_compile_wm(sna, &general,
3372
					sna_static_stream_compile_wm(sna, &general,
3375
								     wm_kernels[m].data, 8);
3373
								     wm_kernels[m].data, 8);
3376
			}
3374
			}
3377
 
3375
 
3378
			if (USE_16_PIXEL_DISPATCH) {
3376
			if (USE_16_PIXEL_DISPATCH) {
3379
				state->wm_kernel[m][1] =
3377
				state->wm_kernel[m][1] =
3380
					sna_static_stream_compile_wm(sna, &general,
3378
					sna_static_stream_compile_wm(sna, &general,
3381
								     wm_kernels[m].data, 16);
3379
								     wm_kernels[m].data, 16);
3382
			}
3380
			}
3383
 
3381
 
3384
			if (USE_32_PIXEL_DISPATCH) {
3382
			if (USE_32_PIXEL_DISPATCH) {
3385
				state->wm_kernel[m][2] =
3383
				state->wm_kernel[m][2] =
3386
					sna_static_stream_compile_wm(sna, &general,
3384
					sna_static_stream_compile_wm(sna, &general,
3387
								     wm_kernels[m].data, 32);
3385
								     wm_kernels[m].data, 32);
3388
			}
3386
			}
3389
		}
3387
		}
3390
		if ((state->wm_kernel[m][0]|state->wm_kernel[m][1]|state->wm_kernel[m][2]) == 0) {
3388
		if ((state->wm_kernel[m][0]|state->wm_kernel[m][1]|state->wm_kernel[m][2]) == 0) {
3391
			state->wm_kernel[m][1] =
3389
			state->wm_kernel[m][1] =
3392
				sna_static_stream_compile_wm(sna, &general,
3390
				sna_static_stream_compile_wm(sna, &general,
3393
							     wm_kernels[m].data, 16);
3391
							     wm_kernels[m].data, 16);
3394
		}
3392
		}
3395
	}
3393
	}
3396
 
3394
 
3397
	ss = sna_static_stream_map(&general,
3395
	ss = sna_static_stream_map(&general,
3398
				   2 * sizeof(*ss) *
3396
				   2 * sizeof(*ss) *
3399
				   (2 +
3397
				   (2 +
3400
				   FILTER_COUNT * EXTEND_COUNT *
3398
				   FILTER_COUNT * EXTEND_COUNT *
3401
				    FILTER_COUNT * EXTEND_COUNT),
3399
				    FILTER_COUNT * EXTEND_COUNT),
3402
				   32);
3400
				   32);
3403
	state->wm_state = sna_static_stream_offsetof(&general, ss);
3401
	state->wm_state = sna_static_stream_offsetof(&general, ss);
3404
	sampler_copy_init(ss); ss += 2;
3402
	sampler_copy_init(ss); ss += 2;
3405
	sampler_fill_init(ss); ss += 2;
3403
	sampler_fill_init(ss); ss += 2;
3406
	for (i = 0; i < FILTER_COUNT; i++) {
3404
	for (i = 0; i < FILTER_COUNT; i++) {
3407
		for (j = 0; j < EXTEND_COUNT; j++) {
3405
		for (j = 0; j < EXTEND_COUNT; j++) {
3408
			for (k = 0; k < FILTER_COUNT; k++) {
3406
			for (k = 0; k < FILTER_COUNT; k++) {
3409
				for (l = 0; l < EXTEND_COUNT; l++) {
3407
				for (l = 0; l < EXTEND_COUNT; l++) {
3410
					sampler_state_init(ss++, i, j);
3408
					sampler_state_init(ss++, i, j);
3411
					sampler_state_init(ss++, k, l);
3409
					sampler_state_init(ss++, k, l);
3412
				}
3410
				}
3413
			}
3411
			}
3414
		}
3412
		}
3415
	}
3413
	}
3416
 
3414
 
3417
    state->cc_blend = gen6_composite_create_blend_state(&general);
3415
    state->cc_blend = gen6_composite_create_blend_state(&general);
3418
 
3416
 
3419
    state->general_bo = sna_static_stream_fini(sna, &general);
3417
    state->general_bo = sna_static_stream_fini(sna, &general);
3420
    return state->general_bo != NULL;
3418
    return state->general_bo != NULL;
3421
}
3419
}
3422
 
3420
 
3423
const char *gen6_render_init(struct sna *sna, const char *backend)
3421
const char *gen6_render_init(struct sna *sna, const char *backend)
3424
{
3422
{
3425
    if (!gen6_render_setup(sna))
3423
    if (!gen6_render_setup(sna))
3426
		return backend;
3424
		return backend;
3427
 
3425
 
3428
	sna->kgem.context_switch = gen6_render_context_switch;
3426
	sna->kgem.context_switch = gen6_render_context_switch;
3429
	sna->kgem.retire = gen6_render_retire;
3427
	sna->kgem.retire = gen6_render_retire;
3430
	sna->kgem.expire = gen6_render_expire;
3428
	sna->kgem.expire = gen6_render_expire;
3431
 
3429
 
3432
#if 0
3430
#if 0
3433
#if !NO_COMPOSITE
3431
#if !NO_COMPOSITE
3434
	sna->render.composite = gen6_render_composite;
3432
	sna->render.composite = gen6_render_composite;
3435
	sna->render.prefer_gpu |= PREFER_GPU_RENDER;
3433
	sna->render.prefer_gpu |= PREFER_GPU_RENDER;
3436
#endif
3434
#endif
3437
 
3435
 
3438
#if !NO_COMPOSITE_SPANS
3436
#if !NO_COMPOSITE_SPANS
3439
	sna->render.check_composite_spans = gen6_check_composite_spans;
3437
	sna->render.check_composite_spans = gen6_check_composite_spans;
3440
	sna->render.composite_spans = gen6_render_composite_spans;
3438
	sna->render.composite_spans = gen6_render_composite_spans;
3441
	if (is_mobile(sna))
3439
	if (is_mobile(sna))
3442
		sna->render.prefer_gpu |= PREFER_GPU_SPANS;
3440
		sna->render.prefer_gpu |= PREFER_GPU_SPANS;
3443
#endif
3441
#endif
3444
	sna->render.video = gen6_render_video;
3442
	sna->render.video = gen6_render_video;
3445
 
3443
 
3446
#if !NO_COPY_BOXES
3444
#if !NO_COPY_BOXES
3447
	sna->render.copy_boxes = gen6_render_copy_boxes;
3445
	sna->render.copy_boxes = gen6_render_copy_boxes;
3448
#endif
3446
#endif
3449
#if !NO_COPY
3447
#if !NO_COPY
3450
	sna->render.copy = gen6_render_copy;
3448
	sna->render.copy = gen6_render_copy;
3451
#endif
3449
#endif
3452
 
3450
 
3453
#if !NO_FILL_BOXES
3451
#if !NO_FILL_BOXES
3454
	sna->render.fill_boxes = gen6_render_fill_boxes;
3452
	sna->render.fill_boxes = gen6_render_fill_boxes;
3455
#endif
3453
#endif
3456
#if !NO_FILL
3454
#if !NO_FILL
3457
	sna->render.fill = gen6_render_fill;
3455
	sna->render.fill = gen6_render_fill;
3458
#endif
3456
#endif
3459
#if !NO_FILL_ONE
3457
#if !NO_FILL_ONE
3460
	sna->render.fill_one = gen6_render_fill_one;
3458
	sna->render.fill_one = gen6_render_fill_one;
3461
#endif
3459
#endif
3462
#if !NO_FILL_CLEAR
3460
#if !NO_FILL_CLEAR
3463
	sna->render.clear = gen6_render_clear;
3461
	sna->render.clear = gen6_render_clear;
3464
#endif
3462
#endif
3465
#endif
3463
#endif
3466
 
3464
 
3467
    sna->render.caps = HW_BIT_BLIT | HW_TEX_BLIT;
3465
    sna->render.caps = HW_BIT_BLIT | HW_TEX_BLIT;
3468
    sna->render.blit_tex = gen6_blit_tex;
3466
    sna->render.blit_tex = gen6_blit_tex;
3469
 
3467
 
3470
    sna->render.flush = gen6_render_flush;
3468
    sna->render.flush = gen6_render_flush;
3471
    sna->render.reset = gen6_render_reset;
3469
    sna->render.reset = gen6_render_reset;
3472
	sna->render.fini = gen6_render_fini;
3470
	sna->render.fini = gen6_render_fini;
3473
 
3471
 
3474
    sna->render.max_3d_size = GEN6_MAX_SIZE;
3472
    sna->render.max_3d_size = GEN6_MAX_SIZE;
3475
    sna->render.max_3d_pitch = 1 << 18;
3473
    sna->render.max_3d_pitch = 1 << 18;
3476
	return sna->render_state.gen6.info->name;
3474
	return sna->render_state.gen6.info->name;
3477
}
3475
}
3478
 
3476
 
3479
static bool
3477
static bool
3480
gen6_blit_tex(struct sna *sna,
3478
gen6_blit_tex(struct sna *sna,
3481
              uint8_t op, bool scale,
3479
              uint8_t op, bool scale,
3482
		      PixmapPtr src, struct kgem_bo *src_bo,
3480
		      PixmapPtr src, struct kgem_bo *src_bo,
3483
		      PixmapPtr mask,struct kgem_bo *mask_bo,
3481
		      PixmapPtr mask,struct kgem_bo *mask_bo,
3484
		      PixmapPtr dst, struct kgem_bo *dst_bo,
3482
		      PixmapPtr dst, struct kgem_bo *dst_bo,
3485
              int32_t src_x, int32_t src_y,
3483
              int32_t src_x, int32_t src_y,
3486
              int32_t msk_x, int32_t msk_y,
3484
              int32_t msk_x, int32_t msk_y,
3487
              int32_t dst_x, int32_t dst_y,
3485
              int32_t dst_x, int32_t dst_y,
3488
              int32_t width, int32_t height,
3486
              int32_t width, int32_t height,
3489
              struct sna_composite_op *tmp)
3487
              struct sna_composite_op *tmp)
3490
{
3488
{
3491
 
3489
 
3492
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
3490
    DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
3493
         width, height, sna->kgem.ring));
3491
         width, height, sna->kgem.ring));
3494
 
3492
 
3495
    tmp->op = PictOpSrc;
3493
    tmp->op = PictOpSrc;
3496
 
3494
 
3497
    tmp->dst.pixmap = dst;
3495
    tmp->dst.pixmap = dst;
3498
    tmp->dst.bo     = dst_bo;
3496
    tmp->dst.bo     = dst_bo;
3499
    tmp->dst.width  = dst->drawable.width;
3497
    tmp->dst.width  = dst->drawable.width;
3500
    tmp->dst.height = dst->drawable.height;
3498
    tmp->dst.height = dst->drawable.height;
3501
    tmp->dst.format = PICT_x8r8g8b8;
3499
    tmp->dst.format = PICT_x8r8g8b8;
3502
 
3500
 
3503
 
3501
 
3504
	tmp->src.repeat = SAMPLER_EXTEND_NONE;
3502
	tmp->src.repeat = SAMPLER_EXTEND_NONE;
3505
    tmp->src.is_affine = true;
3503
    tmp->src.is_affine = true;
3506
 
3504
 
3507
    tmp->src.bo = src_bo;
3505
    tmp->src.bo = src_bo;
3508
	tmp->src.pict_format = PICT_x8r8g8b8;
3506
	tmp->src.pict_format = PICT_x8r8g8b8;
3509
    tmp->src.card_format = gen6_get_card_format(tmp->src.pict_format);
3507
    tmp->src.card_format = gen6_get_card_format(tmp->src.pict_format);
3510
    tmp->src.width  = src->drawable.width;
3508
    tmp->src.width  = src->drawable.width;
3511
    tmp->src.height = src->drawable.height;
3509
    tmp->src.height = src->drawable.height;
3512
 
3510
 
3513
	if ( (tmp->src.width  == width) &&
3511
	if ( (tmp->src.width  == width) &&
3514
         (tmp->src.height == height) )
3512
         (tmp->src.height == height) )
3515
		tmp->src.filter = SAMPLER_FILTER_NEAREST;
3513
		tmp->src.filter = SAMPLER_FILTER_NEAREST;
3516
	else
3514
	else
3517
		tmp->src.filter = SAMPLER_FILTER_BILINEAR;
3515
		tmp->src.filter = SAMPLER_FILTER_BILINEAR;
3518
 
3516
 
3519
	tmp->is_affine = tmp->src.is_affine;
3517
	tmp->is_affine = tmp->src.is_affine;
3520
	tmp->has_component_alpha = false;
3518
	tmp->has_component_alpha = false;
3521
	tmp->need_magic_ca_pass = false;
3519
	tmp->need_magic_ca_pass = false;
3522
 
3520
 
3523
	tmp->mask.repeat = SAMPLER_EXTEND_NONE;
3521
	tmp->mask.repeat = SAMPLER_EXTEND_NONE;
3524
	tmp->mask.filter = SAMPLER_FILTER_NEAREST;
3522
	tmp->mask.filter = SAMPLER_FILTER_NEAREST;
3525
    tmp->mask.is_affine = true;
3523
    tmp->mask.is_affine = true;
3526
 
3524
 
3527
    tmp->mask.bo = mask_bo;
3525
    tmp->mask.bo = mask_bo;
3528
    tmp->mask.pict_format = PIXMAN_a8;
3526
    tmp->mask.pict_format = PIXMAN_a8;
3529
    tmp->mask.card_format = gen6_get_card_format(tmp->mask.pict_format);
3527
    tmp->mask.card_format = gen6_get_card_format(tmp->mask.pict_format);
3530
    tmp->mask.width  = mask->drawable.width;
3528
    tmp->mask.width  = mask->drawable.width;
3531
    tmp->mask.height = mask->drawable.height;
3529
    tmp->mask.height = mask->drawable.height;
3532
 
3530
 
3533
 
3531
 
3534
    if( scale )
3532
    if( scale )
3535
    {
3533
    {
3536
        tmp->src.scale[0] = 1.f/width;
3534
        tmp->src.scale[0] = 1.f/width;
3537
        tmp->src.scale[1] = 1.f/height;
3535
        tmp->src.scale[1] = 1.f/height;
3538
    }
3536
    }
3539
    else
3537
    else
3540
    {
3538
    {
3541
        tmp->src.scale[0] = 1.f/src->drawable.width;
3539
        tmp->src.scale[0] = 1.f/src->drawable.width;
3542
        tmp->src.scale[1] = 1.f/src->drawable.height;
3540
        tmp->src.scale[1] = 1.f/src->drawable.height;
3543
    }
3541
    }
3544
//    tmp->src.offset[0] = -dst_x;
3542
//    tmp->src.offset[0] = -dst_x;
3545
//    tmp->src.offset[1] = -dst_y;
3543
//    tmp->src.offset[1] = -dst_y;
3546
 
3544
 
3547
 
3545
 
3548
    tmp->mask.scale[0] = 1.f/mask->drawable.width;
3546
    tmp->mask.scale[0] = 1.f/mask->drawable.width;
3549
    tmp->mask.scale[1] = 1.f/mask->drawable.height;
3547
    tmp->mask.scale[1] = 1.f/mask->drawable.height;
3550
//    tmp->mask.offset[0] = -dst_x;
3548
//    tmp->mask.offset[0] = -dst_x;
3551
//    tmp->mask.offset[1] = -dst_y;
3549
//    tmp->mask.offset[1] = -dst_y;
3552
 
3550
 
3553
	tmp->u.gen6.flags =
3551
	tmp->u.gen6.flags =
3554
		GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter,
3552
		GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter,
3555
					      tmp->src.repeat,
3553
					      tmp->src.repeat,
3556
					      tmp->mask.filter,
3554
					      tmp->mask.filter,
3557
					      tmp->mask.repeat),
3555
					      tmp->mask.repeat),
3558
			       gen6_get_blend(tmp->op,
3556
			       gen6_get_blend(tmp->op,
3559
					      tmp->has_component_alpha,
3557
					      tmp->has_component_alpha,
3560
					      tmp->dst.format),
3558
					      tmp->dst.format),
3561
/*			       gen6_choose_composite_kernel(tmp->op,
3559
/*			       gen6_choose_composite_kernel(tmp->op,
3562
							    tmp->mask.bo != NULL,
3560
							    tmp->mask.bo != NULL,
3563
							    tmp->has_component_alpha,
3561
							    tmp->has_component_alpha,
3564
							    tmp->is_affine),
3562
							    tmp->is_affine),
3565
*/
3563
*/
3566
                   GEN6_WM_KERNEL_MASK,
3564
                   GEN6_WM_KERNEL_MASK,
3567
			       gen4_choose_composite_emitter(sna, tmp));
3565
			       gen4_choose_composite_emitter(sna, tmp));
3568
 
3566
 
3569
	tmp->blt   = gen6_render_composite_blt;
3567
	tmp->blt   = gen6_render_composite_blt;
3570
//    tmp->box   = gen6_render_composite_box;
3568
//    tmp->box   = gen6_render_composite_box;
3571
	tmp->done  = gen6_render_composite_done;
3569
	tmp->done  = gen6_render_composite_done;
3572
 
3570
 
3573
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo);
3571
	kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo);
3574
	if (!kgem_check_bo(&sna->kgem,
3572
	if (!kgem_check_bo(&sna->kgem,
3575
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
3573
			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
3576
			   NULL)) {
3574
			   NULL)) {
3577
		kgem_submit(&sna->kgem);
3575
		kgem_submit(&sna->kgem);
3578
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
3576
		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
3579
	}
3577
	}
3580
 
3578
 
3581
    gen6_emit_composite_state(sna, tmp);
3579
    gen6_emit_composite_state(sna, tmp);
3582
    gen6_align_vertex(sna, tmp);
3580
    gen6_align_vertex(sna, tmp);
3583
	return true;
3581
	return true;
3584
 
3582
 
3585
}
3583
}