1#include "brw.h"
2
3#define X16 8
4#define Y16 10
5
6static void brw_wm_xy(struct brw_compile *p, int dw)
7{
8	struct brw_reg r1 = brw_vec1_grf(1, 0);
9	struct brw_reg r1_uw = __retype_uw(r1);
10	struct brw_reg x_uw, y_uw;
11
12	brw_set_compression_control(p, BRW_COMPRESSION_NONE);
13
14	if (dw == 16) {
15		x_uw = brw_uw16_grf(30, 0);
16		y_uw = brw_uw16_grf(28, 0);
17	} else {
18		x_uw = brw_uw8_grf(30, 0);
19		y_uw = brw_uw8_grf(28, 0);
20	}
21
22	brw_ADD(p,
23		x_uw,
24		__stride(__suboffset(r1_uw, 4), 2, 4, 0),
25		brw_imm_v(0x10101010));
26	brw_ADD(p,
27		y_uw,
28		__stride(__suboffset(r1_uw, 5), 2, 4, 0),
29		brw_imm_v(0x11001100));
30
31	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
32
33	brw_ADD(p, brw_vec8_grf(X16, 0), vec8(x_uw), brw_negate(r1));
34	brw_ADD(p, brw_vec8_grf(Y16, 0), vec8(y_uw), brw_negate(__suboffset(r1, 1)));
35}
36
37static void brw_wm_affine_st(struct brw_compile *p, int dw,
38			     int channel, int msg)
39{
40	int uv;
41
42	if (dw == 16) {
43		brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
44		uv = p->gen >= 060 ? 6 : 3;
45	} else {
46		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
47		uv = p->gen >= 060 ? 4 : 3;
48	}
49	uv += 2*channel;
50
51	msg++;
52	if (p->gen >= 060) {
53		brw_PLN(p,
54			brw_message_reg(msg),
55			brw_vec1_grf(uv, 0),
56			brw_vec8_grf(2, 0));
57		msg += dw/8;
58
59		brw_PLN(p,
60			brw_message_reg(msg),
61			brw_vec1_grf(uv, 4),
62			brw_vec8_grf(2, 0));
63	} else {
64		struct brw_reg r = brw_vec1_grf(uv, 0);
65
66		brw_LINE(p, brw_null_reg(), __suboffset(r, 0), brw_vec8_grf(X16, 0));
67		brw_MAC(p, brw_message_reg(msg), __suboffset(r, 1), brw_vec8_grf(Y16, 0));
68		msg += dw/8;
69
70		brw_LINE(p, brw_null_reg(), __suboffset(r, 4), brw_vec8_grf(X16, 0));
71		brw_MAC(p, brw_message_reg(msg), __suboffset(r, 5), brw_vec8_grf(Y16, 0));
72	}
73}
74
75static inline unsigned simd(int dw)
76{
77	return dw == 16 ? BRW_SAMPLER_SIMD_MODE_SIMD16 : BRW_SAMPLER_SIMD_MODE_SIMD8;
78}
79
80static inline struct brw_reg sample_result(int dw, int result)
81{
82	return brw_reg(BRW_GENERAL_REGISTER_FILE, result, 0,
83		       BRW_REGISTER_TYPE_UW,
84		       dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8,
85		       dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8,
86		       BRW_HORIZONTAL_STRIDE_1,
87		       BRW_SWIZZLE_XYZW,
88		       WRITEMASK_XYZW);
89}
90
91static int brw_wm_sample(struct brw_compile *p, int dw,
92			 int channel, int msg, int result)
93{
94	struct brw_reg src0;
95	bool header;
96	int len;
97
98	len = dw == 16 ? 4 : 2;
99	if (p->gen >= 060) {
100		header = false;
101		src0 = brw_message_reg(++msg);
102	} else {
103		header = true;
104		src0 = brw_vec8_grf(0, 0);
105	}
106
107	brw_SAMPLE(p, sample_result(dw, result), msg, src0,
108		   channel+1, channel, WRITEMASK_XYZW, 0,
109		   2*len, len+header, header, simd(dw));
110	return result;
111}
112
113static int brw_wm_sample__alpha(struct brw_compile *p, int dw,
114				int channel, int msg, int result)
115{
116	struct brw_reg src0;
117	int mlen, rlen;
118
119	if (dw == 8) {
120		/* SIMD8 sample return is not masked */
121		mlen = 3;
122		rlen = 4;
123	} else {
124		mlen = 5;
125		rlen = 2;
126	}
127
128	if (p->gen >= 060)
129		src0 = brw_message_reg(msg);
130	else
131		src0 = brw_vec8_grf(0, 0);
132
133	brw_SAMPLE(p, sample_result(dw, result), msg, src0,
134		   channel+1, channel, WRITEMASK_W, 0,
135		   rlen, mlen, true, simd(dw));
136
137	if (dw == 8)
138		result += 3;
139
140	return result;
141}
142
143static int brw_wm_affine(struct brw_compile *p, int dw,
144			 int channel, int msg, int result)
145{
146	brw_wm_affine_st(p, dw, channel, msg);
147	return brw_wm_sample(p, dw, channel, msg, result);
148}
149
150static int brw_wm_affine__alpha(struct brw_compile *p, int dw,
151				int channel, int msg, int result)
152{
153	brw_wm_affine_st(p, dw, channel, msg);
154	return brw_wm_sample__alpha(p, dw, channel, msg, result);
155}
156
157static inline struct brw_reg null_result(int dw)
158{
159	return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0,
160		       BRW_REGISTER_TYPE_UW,
161		       dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8,
162		       dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8,
163		       BRW_HORIZONTAL_STRIDE_1,
164		       BRW_SWIZZLE_XYZW,
165		       WRITEMASK_XYZW);
166}
167
168static void brw_fb_write(struct brw_compile *p, int dw)
169{
170	struct brw_instruction *insn;
171	unsigned msg_control, msg_type, msg_len;
172	struct brw_reg src0;
173	bool header;
174
175	if (dw == 16) {
176		brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
177		msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE;
178		msg_len = 8;
179	} else {
180		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
181		msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01;
182		msg_len = 4;
183	}
184
185	if (p->gen < 060) {
186		brw_push_insn_state(p);
187		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
188		brw_set_mask_control(p, BRW_MASK_DISABLE);
189		brw_MOV(p, brw_message_reg(1), brw_vec8_grf(1, 0));
190		brw_pop_insn_state(p);
191
192		msg_len += 2;
193	}
194
195	/* The execution mask is ignored for render target writes. */
196	insn = brw_next_insn(p, BRW_OPCODE_SEND);
197	insn->header.predicate_control = 0;
198	insn->header.compression_control = BRW_COMPRESSION_NONE;
199
200	if (p->gen >= 060) {
201		msg_type = GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE;
202		src0 = brw_message_reg(2);
203		header = false;
204	} else {
205		insn->header.destreg__conditionalmod = 0;
206		msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE;
207		src0 = __retype_uw(brw_vec8_grf(0, 0));
208		header = true;
209	}
210
211	brw_set_dest(p, insn, null_result(dw));
212	brw_set_src0(p, insn, src0);
213	brw_set_dp_write_message(p, insn, 0,
214				 msg_control, msg_type, msg_len,
215				 header, true, 0, true, false);
216}
217
218static void brw_wm_write(struct brw_compile *p, int dw, int src)
219{
220	int n;
221
222	if (dw == 8 && p->gen >= 060) {
223		/* XXX pixel execution mask? */
224		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
225
226		brw_MOV(p, brw_message_reg(2), brw_vec8_grf(src+0, 0));
227		brw_MOV(p, brw_message_reg(3), brw_vec8_grf(src+1, 0));
228		brw_MOV(p, brw_message_reg(4), brw_vec8_grf(src+2, 0));
229		brw_MOV(p, brw_message_reg(5), brw_vec8_grf(src+3, 0));
230		goto done;
231	}
232
233	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
234
235	for (n = 0; n < 4; n++) {
236		if (p->gen >= 060) {
237			brw_MOV(p,
238				brw_message_reg(2 + 2*n),
239				brw_vec8_grf(src + 2*n, 0));
240		} else if (p->gen >= 045 && dw == 16) {
241			brw_MOV(p,
242				brw_message_reg(2 + n + BRW_MRF_COMPR4),
243				brw_vec8_grf(src + 2*n, 0));
244		} else {
245			brw_set_compression_control(p, BRW_COMPRESSION_NONE);
246			brw_MOV(p,
247				brw_message_reg(2 + n),
248				brw_vec8_grf(src + 2*n, 0));
249
250			if (dw == 16) {
251				brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
252				brw_MOV(p,
253					brw_message_reg(2 + n + 4),
254					brw_vec8_grf(src + 2*n+1, 0));
255			}
256		}
257	}
258
259done:
260	brw_fb_write(p, dw);
261}
262
263static void brw_wm_write__mask(struct brw_compile *p, int dw,
264			       int src, int mask)
265{
266	int n;
267
268	if (dw == 8 && p->gen >= 060) {
269		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
270
271		brw_MUL(p,
272			brw_message_reg(2),
273			brw_vec8_grf(src+0, 0),
274			brw_vec8_grf(mask, 0));
275		brw_MUL(p,
276			brw_message_reg(3),
277			brw_vec8_grf(src+1, 0),
278			brw_vec8_grf(mask, 0));
279		brw_MUL(p,
280			brw_message_reg(4),
281			brw_vec8_grf(src+2, 0),
282			brw_vec8_grf(mask, 0));
283		brw_MUL(p,
284			brw_message_reg(5),
285			brw_vec8_grf(src+3, 0),
286			brw_vec8_grf(mask, 0));
287
288		goto done;
289	}
290
291	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
292
293	for (n = 0; n < 4; n++) {
294		if (p->gen >= 060) {
295			brw_MUL(p,
296				brw_message_reg(2 + 2*n),
297				brw_vec8_grf(src + 2*n, 0),
298				brw_vec8_grf(mask, 0));
299		} else if (p->gen >= 045 && dw == 16) {
300			brw_MUL(p,
301				brw_message_reg(2 + n + BRW_MRF_COMPR4),
302				brw_vec8_grf(src + 2*n, 0),
303				brw_vec8_grf(mask, 0));
304		} else {
305			brw_set_compression_control(p, BRW_COMPRESSION_NONE);
306			brw_MUL(p,
307				brw_message_reg(2 + n),
308				brw_vec8_grf(src + 2*n, 0),
309				brw_vec8_grf(mask, 0));
310
311			if (dw == 16) {
312				brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
313				brw_MUL(p,
314					brw_message_reg(2 + n + 4),
315					brw_vec8_grf(src + 2*n+1, 0),
316					brw_vec8_grf(mask+1, 0));
317			}
318		}
319	}
320
321done:
322	brw_fb_write(p, dw);
323}
324
325static void brw_wm_write__opacity(struct brw_compile *p, int dw,
326				  int src, int mask)
327{
328	int n;
329
330	if (dw == 8 && p->gen >= 060) {
331		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
332
333		brw_MUL(p,
334			brw_message_reg(2),
335			brw_vec8_grf(src+0, 0),
336			brw_vec1_grf(mask, 3));
337		brw_MUL(p,
338			brw_message_reg(3),
339			brw_vec8_grf(src+1, 0),
340			brw_vec1_grf(mask, 3));
341		brw_MUL(p,
342			brw_message_reg(4),
343			brw_vec8_grf(src+2, 0),
344			brw_vec1_grf(mask, 3));
345		brw_MUL(p,
346			brw_message_reg(5),
347			brw_vec8_grf(src+3, 0),
348			brw_vec1_grf(mask, 3));
349
350		goto done;
351	}
352
353	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
354
355	for (n = 0; n < 4; n++) {
356		if (p->gen >= 060) {
357			brw_MUL(p,
358				brw_message_reg(2 + 2*n),
359				brw_vec8_grf(src + 2*n, 0),
360				brw_vec1_grf(mask, 3));
361		} else if (p->gen >= 045 && dw == 16) {
362			brw_MUL(p,
363				brw_message_reg(2 + n + BRW_MRF_COMPR4),
364				brw_vec8_grf(src + 2*n, 0),
365				brw_vec1_grf(mask, 3));
366		} else {
367			brw_set_compression_control(p, BRW_COMPRESSION_NONE);
368			brw_MUL(p,
369				brw_message_reg(2 + n),
370				brw_vec8_grf(src + 2*n, 0),
371				brw_vec1_grf(mask, 3));
372
373			if (dw == 16) {
374				brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
375				brw_MUL(p,
376					brw_message_reg(2 + n + 4),
377					brw_vec8_grf(src + 2*n+1, 0),
378					brw_vec1_grf(mask, 3));
379			}
380		}
381	}
382
383done:
384	brw_fb_write(p, dw);
385}
386
387static void brw_wm_write__mask_ca(struct brw_compile *p, int dw,
388				  int src, int mask)
389{
390	int n;
391
392	if (dw == 8 && p->gen >= 060) {
393		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
394
395		brw_MUL(p,
396			brw_message_reg(2),
397			brw_vec8_grf(src  + 0, 0),
398			brw_vec8_grf(mask + 0, 0));
399		brw_MUL(p,
400			brw_message_reg(3),
401			brw_vec8_grf(src  + 1, 0),
402			brw_vec8_grf(mask + 1, 0));
403		brw_MUL(p,
404			brw_message_reg(4),
405			brw_vec8_grf(src  + 2, 0),
406			brw_vec8_grf(mask + 2, 0));
407		brw_MUL(p,
408			brw_message_reg(5),
409			brw_vec8_grf(src  + 3, 0),
410			brw_vec8_grf(mask + 3, 0));
411
412		goto done;
413	}
414
415	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
416
417	for (n = 0; n < 4; n++) {
418		if (p->gen >= 060) {
419			brw_MUL(p,
420				brw_message_reg(2 + 2*n),
421				brw_vec8_grf(src + 2*n, 0),
422				brw_vec8_grf(mask + 2*n, 0));
423		} else if (p->gen >= 045 && dw == 16) {
424			brw_MUL(p,
425				brw_message_reg(2 + n + BRW_MRF_COMPR4),
426				brw_vec8_grf(src + 2*n, 0),
427				brw_vec8_grf(mask + 2*n, 0));
428		} else {
429			brw_set_compression_control(p, BRW_COMPRESSION_NONE);
430			brw_MUL(p,
431				brw_message_reg(2 + n),
432				brw_vec8_grf(src + 2*n, 0),
433				brw_vec8_grf(mask + 2*n, 0));
434
435			if (dw == 16) {
436				brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
437				brw_MUL(p,
438					brw_message_reg(2 + n + 4),
439					brw_vec8_grf(src + 2*n + 1, 0),
440					brw_vec8_grf(mask + 2*n + 1, 0));
441			}
442		}
443	}
444
445done:
446	brw_fb_write(p, dw);
447}
448
449bool
450brw_wm_kernel__affine(struct brw_compile *p, int dispatch)
451{
452	if (p->gen < 060)
453		brw_wm_xy(p, dispatch);
454	brw_wm_write(p, dispatch, brw_wm_affine(p, dispatch, 0, 1, 12));
455
456	return true;
457}
458
459bool
460brw_wm_kernel__affine_mask(struct brw_compile *p, int dispatch)
461{
462	int src, mask;
463
464	if (p->gen < 060)
465		brw_wm_xy(p, dispatch);
466
467	src = brw_wm_affine(p, dispatch, 0, 1, 12);
468	mask = brw_wm_affine__alpha(p, dispatch, 1, 6, 20);
469	brw_wm_write__mask(p, dispatch, src, mask);
470
471	return true;
472}
473
474bool
475brw_wm_kernel__affine_mask_ca(struct brw_compile *p, int dispatch)
476{
477	int src, mask;
478
479	if (p->gen < 060)
480		brw_wm_xy(p, dispatch);
481
482	src = brw_wm_affine(p, dispatch, 0, 1, 12);
483	mask = brw_wm_affine(p, dispatch, 1, 6, 20);
484	brw_wm_write__mask_ca(p, dispatch, src, mask);
485
486	return true;
487}
488
489bool
490brw_wm_kernel__affine_mask_sa(struct brw_compile *p, int dispatch)
491{
492	int src, mask;
493
494	if (p->gen < 060)
495		brw_wm_xy(p, dispatch);
496
497	src = brw_wm_affine__alpha(p, dispatch, 0, 1, 12);
498	mask = brw_wm_affine(p, dispatch, 1, 6, 16);
499	brw_wm_write__mask(p, dispatch, mask, src);
500
501	return true;
502}
503
504/* Projective variants */
505
506static void brw_wm_projective_st(struct brw_compile *p, int dw,
507				 int channel, int msg)
508{
509	int uv;
510
511	if (dw == 16) {
512		brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
513		uv = p->gen >= 060 ? 6 : 3;
514	} else {
515		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
516		uv = p->gen >= 060 ? 4 : 3;
517	}
518	uv += 2*channel;
519
520	msg++;
521	if (p->gen >= 060) {
522		/* First compute 1/z */
523		brw_PLN(p,
524			brw_vec8_grf(30, 0),
525			brw_vec1_grf(uv+1, 0),
526			brw_vec8_grf(2, 0));
527
528		if (dw == 16) {
529			brw_set_compression_control(p, BRW_COMPRESSION_NONE);
530			brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0));
531			brw_math_invert(p, brw_vec8_grf(31, 0), brw_vec8_grf(31, 0));
532			brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
533		} else
534			brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0));
535
536		brw_PLN(p,
537			brw_vec8_grf(26, 0),
538			brw_vec1_grf(uv, 0),
539			brw_vec8_grf(2, 0));
540		brw_PLN(p,
541			brw_vec8_grf(28, 0),
542			brw_vec1_grf(uv, 4),
543			brw_vec8_grf(2, 0));
544
545		brw_MUL(p,
546			brw_message_reg(msg),
547			brw_vec8_grf(26, 0),
548			brw_vec8_grf(30, 0));
549		brw_MUL(p,
550			brw_message_reg(msg + dw/8),
551			brw_vec8_grf(28, 0),
552			brw_vec8_grf(30, 0));
553	} else {
554		struct brw_reg r = brw_vec1_grf(uv, 0);
555
556		/* First compute 1/z */
557		brw_LINE(p, brw_null_reg(), brw_vec1_grf(uv+1, 0), brw_vec8_grf(X16, 0));
558		brw_MAC(p, brw_vec8_grf(30, 0), brw_vec1_grf(uv+1, 1), brw_vec8_grf(Y16, 0));
559
560		if (dw == 16) {
561			brw_set_compression_control(p, BRW_COMPRESSION_NONE);
562			brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0));
563			brw_math_invert(p, brw_vec8_grf(31, 0), brw_vec8_grf(31, 0));
564			brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
565		} else
566			brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0));
567
568		/* Now compute the output s,t values */
569		brw_LINE(p, brw_null_reg(), __suboffset(r, 0), brw_vec8_grf(X16, 0));
570		brw_MAC(p, brw_vec8_grf(28, 0), __suboffset(r, 1), brw_vec8_grf(Y16, 0));
571		brw_MUL(p, brw_message_reg(msg), brw_vec8_grf(28, 0), brw_vec8_grf(30, 0));
572		msg += dw/8;
573
574		brw_LINE(p, brw_null_reg(), __suboffset(r, 4), brw_vec8_grf(X16, 0));
575		brw_MAC(p, brw_vec8_grf(28, 0), __suboffset(r, 5), brw_vec8_grf(Y16, 0));
576		brw_MUL(p, brw_message_reg(msg), brw_vec8_grf(28, 0), brw_vec8_grf(30, 0));
577	}
578}
579
580static int brw_wm_projective(struct brw_compile *p, int dw,
581			     int channel, int msg, int result)
582{
583	brw_wm_projective_st(p, dw, channel, msg);
584	return brw_wm_sample(p, dw, channel, msg, result);
585}
586
587static int brw_wm_projective__alpha(struct brw_compile *p, int dw,
588				     int channel, int msg, int result)
589{
590	brw_wm_projective_st(p, dw, channel, msg);
591	return brw_wm_sample__alpha(p, dw, channel, msg, result);
592}
593
594bool
595brw_wm_kernel__projective(struct brw_compile *p, int dispatch)
596{
597	if (p->gen < 060)
598		brw_wm_xy(p, dispatch);
599	brw_wm_write(p, dispatch, brw_wm_projective(p, dispatch, 0, 1, 12));
600
601	return true;
602}
603
604bool
605brw_wm_kernel__projective_mask(struct brw_compile *p, int dispatch)
606{
607	int src, mask;
608
609	if (p->gen < 060)
610		brw_wm_xy(p, dispatch);
611
612	src = brw_wm_projective(p, dispatch, 0, 1, 12);
613	mask = brw_wm_projective__alpha(p, dispatch, 1, 6, 20);
614	brw_wm_write__mask(p, dispatch, src, mask);
615
616	return true;
617}
618
619bool
620brw_wm_kernel__projective_mask_ca(struct brw_compile *p, int dispatch)
621{
622	int src, mask;
623
624	if (p->gen < 060)
625		brw_wm_xy(p, dispatch);
626
627	src = brw_wm_projective(p, dispatch, 0, 1, 12);
628	mask = brw_wm_projective(p, dispatch, 1, 6, 20);
629	brw_wm_write__mask_ca(p, dispatch, src, mask);
630
631	return true;
632}
633
634bool
635brw_wm_kernel__projective_mask_sa(struct brw_compile *p, int dispatch)
636{
637	int src, mask;
638
639	if (p->gen < 060)
640		brw_wm_xy(p, dispatch);
641
642	src = brw_wm_projective__alpha(p, dispatch, 0, 1, 12);
643	mask = brw_wm_projective(p, dispatch, 1, 6, 16);
644	brw_wm_write__mask(p, dispatch, mask, src);
645
646	return true;
647}
648
649bool
650brw_wm_kernel__affine_opacity(struct brw_compile *p, int dispatch)
651{
652	int src, mask;
653
654	if (p->gen < 060) {
655		brw_wm_xy(p, dispatch);
656		mask = 5;
657	} else
658		mask = dispatch == 16 ? 8 : 6;
659
660	src = brw_wm_affine(p, dispatch, 0, 1, 12);
661	brw_wm_write__opacity(p, dispatch, src, mask);
662
663	return true;
664}
665
666bool
667brw_wm_kernel__projective_opacity(struct brw_compile *p, int dispatch)
668{
669	int src, mask;
670
671	if (p->gen < 060) {
672		brw_wm_xy(p, dispatch);
673		mask = 5;
674	} else
675		mask = dispatch == 16 ? 8 : 6;
676
677	src = brw_wm_projective(p, dispatch, 0, 1, 12);
678	brw_wm_write__opacity(p, dispatch, src, mask);
679
680	return true;
681}
682