i965/gen7: Move SOL stage disable to gen7_sol_state.c
[mesa.git] / src / mesa / drivers / dri / i965 / brw_eu.h
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32
33 #ifndef BRW_EU_H
34 #define BRW_EU_H
35
36 #include <stdbool.h>
37 #include "brw_structs.h"
38 #include "brw_defines.h"
39 #include "program/prog_instruction.h"
40
41 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
42 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
43
44 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
45 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
46 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
47 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
48 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
49 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
50 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
51
52
53 #define REG_SIZE (8*4)
54
55
56 /* These aren't hardware structs, just something useful for us to pass around:
57 *
58 * Align1 operation has a lot of control over input ranges. Used in
59 * WM programs to implement shaders decomposed into "channel serial"
60 * or "structure of array" form:
61 */
62 struct brw_reg
63 {
64 GLuint type:4;
65 GLuint file:2;
66 GLuint nr:8;
67 GLuint subnr:5; /* :1 in align16 */
68 GLuint negate:1; /* source only */
69 GLuint abs:1; /* source only */
70 GLuint vstride:4; /* source only */
71 GLuint width:3; /* src only, align1 only */
72 GLuint hstride:2; /* align1 only */
73 GLuint address_mode:1; /* relative addressing, hopefully! */
74 GLuint pad0:1;
75
76 union {
77 struct {
78 GLuint swizzle:8; /* src only, align16 only */
79 GLuint writemask:4; /* dest only, align16 only */
80 GLint indirect_offset:10; /* relative addressing offset */
81 GLuint pad1:10; /* two dwords total */
82 } bits;
83
84 GLfloat f;
85 GLint d;
86 GLuint ud;
87 } dw1;
88 };
89
90
91 struct brw_indirect {
92 GLuint addr_subnr:4;
93 GLint addr_offset:10;
94 GLuint pad:18;
95 };
96
97
98 struct brw_glsl_label;
99 struct brw_glsl_call;
100
101
102
103 #define BRW_EU_MAX_INSN_STACK 5
104 #define BRW_EU_MAX_INSN 10000
105
106 struct brw_compile {
107 struct brw_instruction store[BRW_EU_MAX_INSN];
108 GLuint nr_insn;
109
110 void *mem_ctx;
111
112 /* Allow clients to push/pop instruction state:
113 */
114 struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
115 bool compressed_stack[BRW_EU_MAX_INSN_STACK];
116 struct brw_instruction *current;
117
118 GLuint flag_value;
119 bool single_program_flow;
120 bool compressed;
121 struct brw_context *brw;
122
123 /* Control flow stacks:
124 * - if_stack contains IF and ELSE instructions which must be patched
125 * (and popped) once the matching ENDIF instruction is encountered.
126 */
127 struct brw_instruction **if_stack;
128 int if_stack_depth;
129 int if_stack_array_size;
130
131 /**
132 * loop_stack contains the instruction pointers of the starts of loops which
133 * must be patched (and popped) once the matching WHILE instruction is
134 * encountered.
135 */
136 int *loop_stack;
137 /**
138 * pre-gen6, the BREAK and CONT instructions had to tell how many IF/ENDIF
139 * blocks they were popping out of, to fix up the mask stack. This tracks
140 * the IF/ENDIF nesting in each current nested loop level.
141 */
142 int *if_depth_in_loop;
143 int loop_stack_depth;
144 int loop_stack_array_size;
145
146 struct brw_glsl_label *first_label; /**< linked list of labels */
147 struct brw_glsl_call *first_call; /**< linked list of CALs */
148 };
149
150
151 void
152 brw_save_label(struct brw_compile *c, const char *name, GLuint position);
153
154 void
155 brw_save_call(struct brw_compile *c, const char *name, GLuint call_pos);
156
157 void
158 brw_resolve_cals(struct brw_compile *c);
159
160
161
162 static INLINE int type_sz( GLuint type )
163 {
164 switch( type ) {
165 case BRW_REGISTER_TYPE_UD:
166 case BRW_REGISTER_TYPE_D:
167 case BRW_REGISTER_TYPE_F:
168 return 4;
169 case BRW_REGISTER_TYPE_HF:
170 case BRW_REGISTER_TYPE_UW:
171 case BRW_REGISTER_TYPE_W:
172 return 2;
173 case BRW_REGISTER_TYPE_UB:
174 case BRW_REGISTER_TYPE_B:
175 return 1;
176 default:
177 return 0;
178 }
179 }
180
181 /**
182 * Construct a brw_reg.
183 * \param file one of the BRW_x_REGISTER_FILE values
184 * \param nr register number/index
185 * \param subnr register sub number
186 * \param type one of BRW_REGISTER_TYPE_x
187 * \param vstride one of BRW_VERTICAL_STRIDE_x
188 * \param width one of BRW_WIDTH_x
189 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
190 * \param swizzle one of BRW_SWIZZLE_x
191 * \param writemask WRITEMASK_X/Y/Z/W bitfield
192 */
193 static INLINE struct brw_reg brw_reg( GLuint file,
194 GLuint nr,
195 GLuint subnr,
196 GLuint type,
197 GLuint vstride,
198 GLuint width,
199 GLuint hstride,
200 GLuint swizzle,
201 GLuint writemask )
202 {
203 struct brw_reg reg;
204 if (file == BRW_GENERAL_REGISTER_FILE)
205 assert(nr < BRW_MAX_GRF);
206 else if (file == BRW_MESSAGE_REGISTER_FILE)
207 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
208 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
209 assert(nr <= BRW_ARF_IP);
210
211 reg.type = type;
212 reg.file = file;
213 reg.nr = nr;
214 reg.subnr = subnr * type_sz(type);
215 reg.negate = 0;
216 reg.abs = 0;
217 reg.vstride = vstride;
218 reg.width = width;
219 reg.hstride = hstride;
220 reg.address_mode = BRW_ADDRESS_DIRECT;
221 reg.pad0 = 0;
222
223 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
224 * set swizzle and writemask to W, as the lower bits of subnr will
225 * be lost when converted to align16. This is probably too much to
226 * keep track of as you'd want it adjusted by suboffset(), etc.
227 * Perhaps fix up when converting to align16?
228 */
229 reg.dw1.bits.swizzle = swizzle;
230 reg.dw1.bits.writemask = writemask;
231 reg.dw1.bits.indirect_offset = 0;
232 reg.dw1.bits.pad1 = 0;
233 return reg;
234 }
235
236 /** Construct float[16] register */
237 static INLINE struct brw_reg brw_vec16_reg( GLuint file,
238 GLuint nr,
239 GLuint subnr )
240 {
241 return brw_reg(file,
242 nr,
243 subnr,
244 BRW_REGISTER_TYPE_F,
245 BRW_VERTICAL_STRIDE_16,
246 BRW_WIDTH_16,
247 BRW_HORIZONTAL_STRIDE_1,
248 BRW_SWIZZLE_XYZW,
249 WRITEMASK_XYZW);
250 }
251
252 /** Construct float[8] register */
253 static INLINE struct brw_reg brw_vec8_reg( GLuint file,
254 GLuint nr,
255 GLuint subnr )
256 {
257 return brw_reg(file,
258 nr,
259 subnr,
260 BRW_REGISTER_TYPE_F,
261 BRW_VERTICAL_STRIDE_8,
262 BRW_WIDTH_8,
263 BRW_HORIZONTAL_STRIDE_1,
264 BRW_SWIZZLE_XYZW,
265 WRITEMASK_XYZW);
266 }
267
268 /** Construct float[4] register */
269 static INLINE struct brw_reg brw_vec4_reg( GLuint file,
270 GLuint nr,
271 GLuint subnr )
272 {
273 return brw_reg(file,
274 nr,
275 subnr,
276 BRW_REGISTER_TYPE_F,
277 BRW_VERTICAL_STRIDE_4,
278 BRW_WIDTH_4,
279 BRW_HORIZONTAL_STRIDE_1,
280 BRW_SWIZZLE_XYZW,
281 WRITEMASK_XYZW);
282 }
283
284 /** Construct float[2] register */
285 static INLINE struct brw_reg brw_vec2_reg( GLuint file,
286 GLuint nr,
287 GLuint subnr )
288 {
289 return brw_reg(file,
290 nr,
291 subnr,
292 BRW_REGISTER_TYPE_F,
293 BRW_VERTICAL_STRIDE_2,
294 BRW_WIDTH_2,
295 BRW_HORIZONTAL_STRIDE_1,
296 BRW_SWIZZLE_XYXY,
297 WRITEMASK_XY);
298 }
299
300 /** Construct float[1] register */
301 static INLINE struct brw_reg brw_vec1_reg( GLuint file,
302 GLuint nr,
303 GLuint subnr )
304 {
305 return brw_reg(file,
306 nr,
307 subnr,
308 BRW_REGISTER_TYPE_F,
309 BRW_VERTICAL_STRIDE_0,
310 BRW_WIDTH_1,
311 BRW_HORIZONTAL_STRIDE_0,
312 BRW_SWIZZLE_XXXX,
313 WRITEMASK_X);
314 }
315
316
317 static INLINE struct brw_reg retype( struct brw_reg reg,
318 GLuint type )
319 {
320 reg.type = type;
321 return reg;
322 }
323
324 static inline struct brw_reg
325 sechalf(struct brw_reg reg)
326 {
327 if (reg.vstride)
328 reg.nr++;
329 return reg;
330 }
331
332 static INLINE struct brw_reg suboffset( struct brw_reg reg,
333 GLuint delta )
334 {
335 reg.subnr += delta * type_sz(reg.type);
336 return reg;
337 }
338
339
340 static INLINE struct brw_reg offset( struct brw_reg reg,
341 GLuint delta )
342 {
343 reg.nr += delta;
344 return reg;
345 }
346
347
348 static INLINE struct brw_reg byte_offset( struct brw_reg reg,
349 GLuint bytes )
350 {
351 GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
352 reg.nr = newoffset / REG_SIZE;
353 reg.subnr = newoffset % REG_SIZE;
354 return reg;
355 }
356
357
358 /** Construct unsigned word[16] register */
359 static INLINE struct brw_reg brw_uw16_reg( GLuint file,
360 GLuint nr,
361 GLuint subnr )
362 {
363 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
364 }
365
366 /** Construct unsigned word[8] register */
367 static INLINE struct brw_reg brw_uw8_reg( GLuint file,
368 GLuint nr,
369 GLuint subnr )
370 {
371 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
372 }
373
374 /** Construct unsigned word[1] register */
375 static INLINE struct brw_reg brw_uw1_reg( GLuint file,
376 GLuint nr,
377 GLuint subnr )
378 {
379 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
380 }
381
382 static INLINE struct brw_reg brw_imm_reg( GLuint type )
383 {
384 return brw_reg( BRW_IMMEDIATE_VALUE,
385 0,
386 0,
387 type,
388 BRW_VERTICAL_STRIDE_0,
389 BRW_WIDTH_1,
390 BRW_HORIZONTAL_STRIDE_0,
391 0,
392 0);
393 }
394
395 /** Construct float immediate register */
396 static INLINE struct brw_reg brw_imm_f( GLfloat f )
397 {
398 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
399 imm.dw1.f = f;
400 return imm;
401 }
402
403 /** Construct integer immediate register */
404 static INLINE struct brw_reg brw_imm_d( GLint d )
405 {
406 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
407 imm.dw1.d = d;
408 return imm;
409 }
410
411 /** Construct uint immediate register */
412 static INLINE struct brw_reg brw_imm_ud( GLuint ud )
413 {
414 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
415 imm.dw1.ud = ud;
416 return imm;
417 }
418
419 /** Construct ushort immediate register */
420 static INLINE struct brw_reg brw_imm_uw( GLushort uw )
421 {
422 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
423 imm.dw1.ud = uw | (uw << 16);
424 return imm;
425 }
426
427 /** Construct short immediate register */
428 static INLINE struct brw_reg brw_imm_w( GLshort w )
429 {
430 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
431 imm.dw1.d = w | (w << 16);
432 return imm;
433 }
434
435 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
436 * numbers alias with _V and _VF below:
437 */
438
439 /** Construct vector of eight signed half-byte values */
440 static INLINE struct brw_reg brw_imm_v( GLuint v )
441 {
442 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
443 imm.vstride = BRW_VERTICAL_STRIDE_0;
444 imm.width = BRW_WIDTH_8;
445 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
446 imm.dw1.ud = v;
447 return imm;
448 }
449
450 /** Construct vector of four 8-bit float values */
451 static INLINE struct brw_reg brw_imm_vf( GLuint v )
452 {
453 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
454 imm.vstride = BRW_VERTICAL_STRIDE_0;
455 imm.width = BRW_WIDTH_4;
456 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
457 imm.dw1.ud = v;
458 return imm;
459 }
460
461 #define VF_ZERO 0x0
462 #define VF_ONE 0x30
463 #define VF_NEG (1<<7)
464
465 static INLINE struct brw_reg brw_imm_vf4( GLuint v0,
466 GLuint v1,
467 GLuint v2,
468 GLuint v3)
469 {
470 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
471 imm.vstride = BRW_VERTICAL_STRIDE_0;
472 imm.width = BRW_WIDTH_4;
473 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
474 imm.dw1.ud = ((v0 << 0) |
475 (v1 << 8) |
476 (v2 << 16) |
477 (v3 << 24));
478 return imm;
479 }
480
481
482 static INLINE struct brw_reg brw_address( struct brw_reg reg )
483 {
484 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
485 }
486
487 /** Construct float[1] general-purpose register */
488 static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
489 {
490 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
491 }
492
493 /** Construct float[2] general-purpose register */
494 static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
495 {
496 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
497 }
498
499 /** Construct float[4] general-purpose register */
500 static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
501 {
502 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
503 }
504
505 /** Construct float[8] general-purpose register */
506 static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
507 {
508 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
509 }
510
511
512 static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
513 {
514 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
515 }
516
517 static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
518 {
519 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
520 }
521
522
523 /** Construct null register (usually used for setting condition codes) */
524 static INLINE struct brw_reg brw_null_reg( void )
525 {
526 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
527 BRW_ARF_NULL,
528 0);
529 }
530
531 static INLINE struct brw_reg brw_address_reg( GLuint subnr )
532 {
533 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
534 BRW_ARF_ADDRESS,
535 subnr);
536 }
537
538 /* If/else instructions break in align16 mode if writemask & swizzle
539 * aren't xyzw. This goes against the convention for other scalar
540 * regs:
541 */
542 static INLINE struct brw_reg brw_ip_reg( void )
543 {
544 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
545 BRW_ARF_IP,
546 0,
547 BRW_REGISTER_TYPE_UD,
548 BRW_VERTICAL_STRIDE_4, /* ? */
549 BRW_WIDTH_1,
550 BRW_HORIZONTAL_STRIDE_0,
551 BRW_SWIZZLE_XYZW, /* NOTE! */
552 WRITEMASK_XYZW); /* NOTE! */
553 }
554
555 static INLINE struct brw_reg brw_acc_reg( void )
556 {
557 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
558 BRW_ARF_ACCUMULATOR,
559 0);
560 }
561
562 static INLINE struct brw_reg brw_notification_1_reg(void)
563 {
564
565 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
566 BRW_ARF_NOTIFICATION_COUNT,
567 1,
568 BRW_REGISTER_TYPE_UD,
569 BRW_VERTICAL_STRIDE_0,
570 BRW_WIDTH_1,
571 BRW_HORIZONTAL_STRIDE_0,
572 BRW_SWIZZLE_XXXX,
573 WRITEMASK_X);
574 }
575
576
577 static INLINE struct brw_reg brw_flag_reg( void )
578 {
579 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
580 BRW_ARF_FLAG,
581 0);
582 }
583
584
585 static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
586 {
587 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
588 BRW_ARF_MASK,
589 subnr);
590 }
591
592 static INLINE struct brw_reg brw_message_reg( GLuint nr )
593 {
594 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
595 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
596 nr,
597 0);
598 }
599
600
601
602
603 /* This is almost always called with a numeric constant argument, so
604 * make things easy to evaluate at compile time:
605 */
606 static INLINE GLuint cvt( GLuint val )
607 {
608 switch (val) {
609 case 0: return 0;
610 case 1: return 1;
611 case 2: return 2;
612 case 4: return 3;
613 case 8: return 4;
614 case 16: return 5;
615 case 32: return 6;
616 }
617 return 0;
618 }
619
620 static INLINE struct brw_reg stride( struct brw_reg reg,
621 GLuint vstride,
622 GLuint width,
623 GLuint hstride )
624 {
625 reg.vstride = cvt(vstride);
626 reg.width = cvt(width) - 1;
627 reg.hstride = cvt(hstride);
628 return reg;
629 }
630
631
632 static INLINE struct brw_reg vec16( struct brw_reg reg )
633 {
634 return stride(reg, 16,16,1);
635 }
636
637 static INLINE struct brw_reg vec8( struct brw_reg reg )
638 {
639 return stride(reg, 8,8,1);
640 }
641
642 static INLINE struct brw_reg vec4( struct brw_reg reg )
643 {
644 return stride(reg, 4,4,1);
645 }
646
647 static INLINE struct brw_reg vec2( struct brw_reg reg )
648 {
649 return stride(reg, 2,2,1);
650 }
651
652 static INLINE struct brw_reg vec1( struct brw_reg reg )
653 {
654 return stride(reg, 0,1,0);
655 }
656
657
658 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
659 {
660 return vec1(suboffset(reg, elt));
661 }
662
663 static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
664 {
665 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
666 }
667
668 static INLINE struct brw_reg get_element_d( struct brw_reg reg, GLuint elt )
669 {
670 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
671 }
672
673
674 static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
675 GLuint x,
676 GLuint y,
677 GLuint z,
678 GLuint w)
679 {
680 assert(reg.file != BRW_IMMEDIATE_VALUE);
681
682 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
683 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
684 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
685 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
686 return reg;
687 }
688
689
690 static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
691 GLuint x )
692 {
693 return brw_swizzle(reg, x, x, x, x);
694 }
695
696 static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
697 GLuint mask )
698 {
699 assert(reg.file != BRW_IMMEDIATE_VALUE);
700 reg.dw1.bits.writemask &= mask;
701 return reg;
702 }
703
704 static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
705 GLuint mask )
706 {
707 assert(reg.file != BRW_IMMEDIATE_VALUE);
708 reg.dw1.bits.writemask = mask;
709 return reg;
710 }
711
712 static INLINE struct brw_reg negate( struct brw_reg reg )
713 {
714 reg.negate ^= 1;
715 return reg;
716 }
717
718 static INLINE struct brw_reg brw_abs( struct brw_reg reg )
719 {
720 reg.abs = 1;
721 reg.negate = 0;
722 return reg;
723 }
724
725 /***********************************************************************
726 */
727 static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
728 GLint offset )
729 {
730 struct brw_reg reg = brw_vec4_grf(0, 0);
731 reg.subnr = subnr;
732 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
733 reg.dw1.bits.indirect_offset = offset;
734 return reg;
735 }
736
737 static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
738 GLint offset )
739 {
740 struct brw_reg reg = brw_vec1_grf(0, 0);
741 reg.subnr = subnr;
742 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
743 reg.dw1.bits.indirect_offset = offset;
744 return reg;
745 }
746
747 static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
748 {
749 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
750 }
751
752 static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
753 {
754 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
755 }
756
757 static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
758 {
759 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
760 }
761
762 static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
763 {
764 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
765 }
766
767 static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
768 {
769 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
770 }
771
772 static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
773 {
774 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
775 }
776
777 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
778 {
779 return brw_address_reg(ptr.addr_subnr);
780 }
781
782 static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
783 {
784 ptr.addr_offset += offset;
785 return ptr;
786 }
787
788 static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
789 {
790 struct brw_indirect ptr;
791 ptr.addr_subnr = addr_subnr;
792 ptr.addr_offset = offset;
793 ptr.pad = 0;
794 return ptr;
795 }
796
797 /** Do two brw_regs refer to the same register? */
798 static INLINE bool
799 brw_same_reg(struct brw_reg r1, struct brw_reg r2)
800 {
801 return r1.file == r2.file && r1.nr == r2.nr;
802 }
803
804 static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
805 {
806 return &p->store[p->nr_insn];
807 }
808
809 void brw_pop_insn_state( struct brw_compile *p );
810 void brw_push_insn_state( struct brw_compile *p );
811 void brw_set_mask_control( struct brw_compile *p, GLuint value );
812 void brw_set_saturate( struct brw_compile *p, GLuint value );
813 void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
814 void brw_set_compression_control(struct brw_compile *p, enum brw_compression c);
815 void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
816 void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
817 void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse);
818 void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
819 void brw_set_acc_write_control(struct brw_compile *p, GLuint value);
820
821 void brw_init_compile(struct brw_context *, struct brw_compile *p,
822 void *mem_ctx);
823 const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
824
825 struct brw_instruction *brw_next_insn(struct brw_compile *p, GLuint opcode);
826 void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn,
827 struct brw_reg dest);
828 void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn,
829 struct brw_reg reg);
830
831 void gen6_resolve_implied_move(struct brw_compile *p,
832 struct brw_reg *src,
833 GLuint msg_reg_nr);
834
835 /* Helpers for regular instructions:
836 */
837 #define ALU1(OP) \
838 struct brw_instruction *brw_##OP(struct brw_compile *p, \
839 struct brw_reg dest, \
840 struct brw_reg src0);
841
842 #define ALU2(OP) \
843 struct brw_instruction *brw_##OP(struct brw_compile *p, \
844 struct brw_reg dest, \
845 struct brw_reg src0, \
846 struct brw_reg src1);
847
848 #define ROUND(OP) \
849 void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0);
850
851
852 ALU1(MOV)
853 ALU2(SEL)
854 ALU1(NOT)
855 ALU2(AND)
856 ALU2(OR)
857 ALU2(XOR)
858 ALU2(SHR)
859 ALU2(SHL)
860 ALU2(RSR)
861 ALU2(RSL)
862 ALU2(ASR)
863 ALU2(JMPI)
864 ALU2(ADD)
865 ALU2(MUL)
866 ALU1(FRC)
867 ALU1(RNDD)
868 ALU2(MAC)
869 ALU2(MACH)
870 ALU1(LZD)
871 ALU2(DP4)
872 ALU2(DPH)
873 ALU2(DP3)
874 ALU2(DP2)
875 ALU2(LINE)
876 ALU2(PLN)
877
878 ROUND(RNDZ)
879 ROUND(RNDE)
880
881 #undef ALU1
882 #undef ALU2
883 #undef ROUND
884
885
886 /* Helpers for SEND instruction:
887 */
888 void brw_set_dp_read_message(struct brw_compile *p,
889 struct brw_instruction *insn,
890 GLuint binding_table_index,
891 GLuint msg_control,
892 GLuint msg_type,
893 GLuint target_cache,
894 GLuint msg_length,
895 GLuint response_length);
896
897 void brw_set_dp_write_message(struct brw_compile *p,
898 struct brw_instruction *insn,
899 GLuint binding_table_index,
900 GLuint msg_control,
901 GLuint msg_type,
902 GLuint msg_length,
903 bool header_present,
904 GLuint last_render_target,
905 GLuint response_length,
906 GLuint end_of_thread,
907 GLuint send_commit_msg);
908
909 void brw_urb_WRITE(struct brw_compile *p,
910 struct brw_reg dest,
911 GLuint msg_reg_nr,
912 struct brw_reg src0,
913 bool allocate,
914 bool used,
915 GLuint msg_length,
916 GLuint response_length,
917 bool eot,
918 bool writes_complete,
919 GLuint offset,
920 GLuint swizzle);
921
922 void brw_ff_sync(struct brw_compile *p,
923 struct brw_reg dest,
924 GLuint msg_reg_nr,
925 struct brw_reg src0,
926 bool allocate,
927 GLuint response_length,
928 bool eot);
929
930 void brw_svb_write(struct brw_compile *p,
931 struct brw_reg dest,
932 GLuint msg_reg_nr,
933 struct brw_reg src0,
934 GLuint binding_table_index,
935 bool send_commit_msg);
936
937 void brw_fb_WRITE(struct brw_compile *p,
938 int dispatch_width,
939 GLuint msg_reg_nr,
940 struct brw_reg src0,
941 GLuint binding_table_index,
942 GLuint msg_length,
943 GLuint response_length,
944 bool eot,
945 bool header_present);
946
947 void brw_SAMPLE(struct brw_compile *p,
948 struct brw_reg dest,
949 GLuint msg_reg_nr,
950 struct brw_reg src0,
951 GLuint binding_table_index,
952 GLuint sampler,
953 GLuint writemask,
954 GLuint msg_type,
955 GLuint response_length,
956 GLuint msg_length,
957 GLuint header_present,
958 GLuint simd_mode,
959 GLuint return_format);
960
961 void brw_math_16( struct brw_compile *p,
962 struct brw_reg dest,
963 GLuint function,
964 GLuint saturate,
965 GLuint msg_reg_nr,
966 struct brw_reg src,
967 GLuint precision );
968
969 void brw_math( struct brw_compile *p,
970 struct brw_reg dest,
971 GLuint function,
972 GLuint saturate,
973 GLuint msg_reg_nr,
974 struct brw_reg src,
975 GLuint data_type,
976 GLuint precision );
977
978 void brw_math2(struct brw_compile *p,
979 struct brw_reg dest,
980 GLuint function,
981 struct brw_reg src0,
982 struct brw_reg src1);
983
984 void brw_oword_block_read(struct brw_compile *p,
985 struct brw_reg dest,
986 struct brw_reg mrf,
987 uint32_t offset,
988 uint32_t bind_table_index);
989
990 void brw_oword_block_read_scratch(struct brw_compile *p,
991 struct brw_reg dest,
992 struct brw_reg mrf,
993 int num_regs,
994 GLuint offset);
995
996 void brw_oword_block_write_scratch(struct brw_compile *p,
997 struct brw_reg mrf,
998 int num_regs,
999 GLuint offset);
1000
1001 void brw_dword_scattered_read(struct brw_compile *p,
1002 struct brw_reg dest,
1003 struct brw_reg mrf,
1004 uint32_t bind_table_index);
1005
1006 void brw_dp_READ_4_vs( struct brw_compile *p,
1007 struct brw_reg dest,
1008 GLuint location,
1009 GLuint bind_table_index );
1010
1011 void brw_dp_READ_4_vs_relative(struct brw_compile *p,
1012 struct brw_reg dest,
1013 struct brw_reg addrReg,
1014 GLuint offset,
1015 GLuint bind_table_index);
1016
1017 /* If/else/endif. Works by manipulating the execution flags on each
1018 * channel.
1019 */
1020 struct brw_instruction *brw_IF(struct brw_compile *p,
1021 GLuint execute_size);
1022 struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
1023 struct brw_reg src0, struct brw_reg src1);
1024
1025 void brw_ELSE(struct brw_compile *p);
1026 void brw_ENDIF(struct brw_compile *p);
1027
1028 /* DO/WHILE loops:
1029 */
1030 struct brw_instruction *brw_DO(struct brw_compile *p,
1031 GLuint execute_size);
1032
1033 struct brw_instruction *brw_WHILE(struct brw_compile *p);
1034
1035 struct brw_instruction *brw_BREAK(struct brw_compile *p);
1036 struct brw_instruction *brw_CONT(struct brw_compile *p);
1037 struct brw_instruction *gen6_CONT(struct brw_compile *p);
1038 /* Forward jumps:
1039 */
1040 void brw_land_fwd_jump(struct brw_compile *p,
1041 struct brw_instruction *jmp_insn);
1042
1043
1044
1045 void brw_NOP(struct brw_compile *p);
1046
1047 void brw_WAIT(struct brw_compile *p);
1048
1049 /* Special case: there is never a destination, execution size will be
1050 * taken from src0:
1051 */
1052 void brw_CMP(struct brw_compile *p,
1053 struct brw_reg dest,
1054 GLuint conditional,
1055 struct brw_reg src0,
1056 struct brw_reg src1);
1057
1058 void brw_print_reg( struct brw_reg reg );
1059
1060
1061 /***********************************************************************
1062 * brw_eu_util.c:
1063 */
1064
1065 void brw_copy_indirect_to_indirect(struct brw_compile *p,
1066 struct brw_indirect dst_ptr,
1067 struct brw_indirect src_ptr,
1068 GLuint count);
1069
1070 void brw_copy_from_indirect(struct brw_compile *p,
1071 struct brw_reg dst,
1072 struct brw_indirect ptr,
1073 GLuint count);
1074
1075 void brw_copy4(struct brw_compile *p,
1076 struct brw_reg dst,
1077 struct brw_reg src,
1078 GLuint count);
1079
1080 void brw_copy8(struct brw_compile *p,
1081 struct brw_reg dst,
1082 struct brw_reg src,
1083 GLuint count);
1084
1085 void brw_math_invert( struct brw_compile *p,
1086 struct brw_reg dst,
1087 struct brw_reg src);
1088
1089 void brw_set_src1(struct brw_compile *p,
1090 struct brw_instruction *insn,
1091 struct brw_reg reg);
1092
1093 void brw_set_uip_jip(struct brw_compile *p);
1094
1095 uint32_t brw_swap_cmod(uint32_t cmod);
1096
1097 /* brw_optimize.c */
1098 void brw_optimize(struct brw_compile *p);
1099 void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
1100 void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
1101
1102 #endif