565f4ef1c59e9a12a8857b22ce980bf1c80beb01
[mesa.git] / src / gallium / drivers / 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 "util/u_debug.h"
37 #include "pipe/p_error.h"
38
39 #include "brw_structs.h"
40 #include "brw_defines.h"
41
42 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
43 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
44
45 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
46 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
47 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
48 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
49
50 #define BRW_WRITEMASK_NONE 0x00
51 #define BRW_WRITEMASK_X 0x01
52 #define BRW_WRITEMASK_Y 0x02
53 #define BRW_WRITEMASK_XY 0x03
54 #define BRW_WRITEMASK_Z 0x04
55 #define BRW_WRITEMASK_XZ 0x05
56 #define BRW_WRITEMASK_YZ 0x06
57 #define BRW_WRITEMASK_XYZ 0x07
58 #define BRW_WRITEMASK_W 0x08
59 #define BRW_WRITEMASK_XW 0x09
60 #define BRW_WRITEMASK_YW 0x0A
61 #define BRW_WRITEMASK_XYW 0x0B
62 #define BRW_WRITEMASK_ZW 0x0C
63 #define BRW_WRITEMASK_XZW 0x0D
64 #define BRW_WRITEMASK_YZW 0x0E
65 #define BRW_WRITEMASK_XYZW 0x0F
66
67
68 #define REG_SIZE (8*4)
69
70
71 /* These aren't hardware structs, just something useful for us to pass around:
72 *
73 * Align1 operation has a lot of control over input ranges. Used in
74 * WM programs to implement shaders decomposed into "channel serial"
75 * or "structure of array" form:
76 */
77 struct brw_reg
78 {
79 GLuint type:4;
80 GLuint file:2;
81 GLuint nr:8;
82 GLuint subnr:5; /* :1 in align16 */
83 GLuint negate:1; /* source only */
84 GLuint abs:1; /* source only */
85 GLuint vstride:4; /* source only */
86 GLuint width:3; /* src only, align1 only */
87 GLuint hstride:2; /* align1 only */
88 GLuint address_mode:1; /* relative addressing, hopefully! */
89 GLuint pad0:1;
90
91 union {
92 struct {
93 GLuint swizzle:8; /* src only, align16 only */
94 GLuint writemask:4; /* dest only, align16 only */
95 GLint indirect_offset:10; /* relative addressing offset */
96 GLuint pad1:10; /* two dwords total */
97 } bits;
98
99 GLfloat f;
100 GLint d;
101 GLuint ud;
102 } dw1;
103 };
104
105
106 struct brw_indirect {
107 GLuint addr_subnr:4;
108 GLint addr_offset:10;
109 GLuint pad:18;
110 };
111
112
113 struct brw_eu_label;
114 struct brw_eu_call;
115
116
117
118 #define BRW_EU_MAX_INSN_STACK 5
119 #define BRW_EU_MAX_INSN 10000
120
121 struct brw_compile {
122 struct brw_instruction store[BRW_EU_MAX_INSN];
123 GLuint nr_insn;
124
125 /* Allow clients to push/pop instruction state:
126 */
127 struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
128 struct brw_instruction *current;
129
130 GLuint flag_value;
131 GLboolean single_program_flow;
132 struct brw_context *brw;
133
134 struct brw_eu_label *first_label; /**< linked list of labels */
135 struct brw_eu_call *first_call; /**< linked list of CALs */
136
137 boolean error;
138 };
139
140
141 void
142 brw_save_label(struct brw_compile *c, unsigned label, GLuint position);
143
144 void
145 brw_save_call(struct brw_compile *c, unsigned label, GLuint call_pos);
146
147 void
148 brw_resolve_cals(struct brw_compile *c);
149
150
151
152 static INLINE int type_sz( GLuint type )
153 {
154 switch( type ) {
155 case BRW_REGISTER_TYPE_UD:
156 case BRW_REGISTER_TYPE_D:
157 case BRW_REGISTER_TYPE_F:
158 return 4;
159 case BRW_REGISTER_TYPE_HF:
160 case BRW_REGISTER_TYPE_UW:
161 case BRW_REGISTER_TYPE_W:
162 return 2;
163 case BRW_REGISTER_TYPE_UB:
164 case BRW_REGISTER_TYPE_B:
165 return 1;
166 default:
167 return 0;
168 }
169 }
170
171 /**
172 * Construct a brw_reg.
173 * \param file one of the BRW_x_REGISTER_FILE values
174 * \param nr register number/index
175 * \param subnr register sub number
176 * \param type one of BRW_REGISTER_TYPE_x
177 * \param vstride one of BRW_VERTICAL_STRIDE_x
178 * \param width one of BRW_WIDTH_x
179 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
180 * \param swizzle one of BRW_SWIZZLE_x
181 * \param writemask BRW_WRITEMASK_X/Y/Z/W bitfield
182 */
183 static INLINE struct brw_reg brw_reg( GLuint file,
184 GLuint nr,
185 GLuint subnr,
186 GLuint type,
187 GLuint vstride,
188 GLuint width,
189 GLuint hstride,
190 GLuint swizzle,
191 GLuint writemask )
192 {
193 struct brw_reg reg;
194 if (type == BRW_GENERAL_REGISTER_FILE)
195 assert(nr < BRW_MAX_GRF);
196 else if (type == BRW_MESSAGE_REGISTER_FILE)
197 assert(nr < BRW_MAX_MRF);
198 else if (type == BRW_ARCHITECTURE_REGISTER_FILE)
199 assert(nr <= BRW_ARF_IP);
200
201 reg.type = type;
202 reg.file = file;
203 reg.nr = nr;
204 reg.subnr = subnr * type_sz(type);
205 reg.negate = 0;
206 reg.abs = 0;
207 reg.vstride = vstride;
208 reg.width = width;
209 reg.hstride = hstride;
210 reg.address_mode = BRW_ADDRESS_DIRECT;
211 reg.pad0 = 0;
212
213 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
214 * set swizzle and writemask to W, as the lower bits of subnr will
215 * be lost when converted to align16. This is probably too much to
216 * keep track of as you'd want it adjusted by suboffset(), etc.
217 * Perhaps fix up when converting to align16?
218 */
219 reg.dw1.bits.swizzle = swizzle;
220 reg.dw1.bits.writemask = writemask;
221 reg.dw1.bits.indirect_offset = 0;
222 reg.dw1.bits.pad1 = 0;
223 return reg;
224 }
225
226 /** Construct float[16] register */
227 static INLINE struct brw_reg brw_vec16_reg( GLuint file,
228 GLuint nr,
229 GLuint subnr )
230 {
231 return brw_reg(file,
232 nr,
233 subnr,
234 BRW_REGISTER_TYPE_F,
235 BRW_VERTICAL_STRIDE_16,
236 BRW_WIDTH_16,
237 BRW_HORIZONTAL_STRIDE_1,
238 BRW_SWIZZLE_XYZW,
239 BRW_WRITEMASK_XYZW);
240 }
241
242 /** Construct float[8] register */
243 static INLINE struct brw_reg brw_vec8_reg( GLuint file,
244 GLuint nr,
245 GLuint subnr )
246 {
247 return brw_reg(file,
248 nr,
249 subnr,
250 BRW_REGISTER_TYPE_F,
251 BRW_VERTICAL_STRIDE_8,
252 BRW_WIDTH_8,
253 BRW_HORIZONTAL_STRIDE_1,
254 BRW_SWIZZLE_XYZW,
255 BRW_WRITEMASK_XYZW);
256 }
257
258 /** Construct float[4] register */
259 static INLINE struct brw_reg brw_vec4_reg( GLuint file,
260 GLuint nr,
261 GLuint subnr )
262 {
263 return brw_reg(file,
264 nr,
265 subnr,
266 BRW_REGISTER_TYPE_F,
267 BRW_VERTICAL_STRIDE_4,
268 BRW_WIDTH_4,
269 BRW_HORIZONTAL_STRIDE_1,
270 BRW_SWIZZLE_XYZW,
271 BRW_WRITEMASK_XYZW);
272 }
273
274 /** Construct float[2] register */
275 static INLINE struct brw_reg brw_vec2_reg( GLuint file,
276 GLuint nr,
277 GLuint subnr )
278 {
279 return brw_reg(file,
280 nr,
281 subnr,
282 BRW_REGISTER_TYPE_F,
283 BRW_VERTICAL_STRIDE_2,
284 BRW_WIDTH_2,
285 BRW_HORIZONTAL_STRIDE_1,
286 BRW_SWIZZLE_XYXY,
287 BRW_WRITEMASK_XY);
288 }
289
290 /** Construct float[1] register */
291 static INLINE struct brw_reg brw_vec1_reg( GLuint file,
292 GLuint nr,
293 GLuint subnr )
294 {
295 return brw_reg(file,
296 nr,
297 subnr,
298 BRW_REGISTER_TYPE_F,
299 BRW_VERTICAL_STRIDE_0,
300 BRW_WIDTH_1,
301 BRW_HORIZONTAL_STRIDE_0,
302 BRW_SWIZZLE_XXXX,
303 BRW_WRITEMASK_X);
304 }
305
306
307 static INLINE struct brw_reg retype( struct brw_reg reg,
308 GLuint type )
309 {
310 reg.type = type;
311 return reg;
312 }
313
314 static INLINE struct brw_reg suboffset( struct brw_reg reg,
315 GLuint delta )
316 {
317 reg.subnr += delta * type_sz(reg.type);
318 return reg;
319 }
320
321
322 static INLINE struct brw_reg offset( struct brw_reg reg,
323 GLuint delta )
324 {
325 reg.nr += delta;
326 return reg;
327 }
328
329
330 static INLINE struct brw_reg byte_offset( struct brw_reg reg,
331 GLuint bytes )
332 {
333 GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
334 reg.nr = newoffset / REG_SIZE;
335 reg.subnr = newoffset % REG_SIZE;
336 return reg;
337 }
338
339
340 /** Construct unsigned word[16] register */
341 static INLINE struct brw_reg brw_uw16_reg( GLuint file,
342 GLuint nr,
343 GLuint subnr )
344 {
345 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
346 }
347
348 /** Construct unsigned word[8] register */
349 static INLINE struct brw_reg brw_uw8_reg( GLuint file,
350 GLuint nr,
351 GLuint subnr )
352 {
353 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
354 }
355
356 /** Construct unsigned word[1] register */
357 static INLINE struct brw_reg brw_uw1_reg( GLuint file,
358 GLuint nr,
359 GLuint subnr )
360 {
361 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
362 }
363
364 static INLINE struct brw_reg brw_imm_reg( GLuint type )
365 {
366 return brw_reg( BRW_IMMEDIATE_VALUE,
367 0,
368 0,
369 type,
370 BRW_VERTICAL_STRIDE_0,
371 BRW_WIDTH_1,
372 BRW_HORIZONTAL_STRIDE_0,
373 0,
374 0);
375 }
376
377 /** Construct float immediate register */
378 static INLINE struct brw_reg brw_imm_f( GLfloat f )
379 {
380 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
381 imm.dw1.f = f;
382 return imm;
383 }
384
385 /** Construct integer immediate register */
386 static INLINE struct brw_reg brw_imm_d( GLint d )
387 {
388 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
389 imm.dw1.d = d;
390 return imm;
391 }
392
393 /** Construct uint immediate register */
394 static INLINE struct brw_reg brw_imm_ud( GLuint ud )
395 {
396 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
397 imm.dw1.ud = ud;
398 return imm;
399 }
400
401 /** Construct ushort immediate register */
402 static INLINE struct brw_reg brw_imm_uw( GLushort uw )
403 {
404 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
405 imm.dw1.ud = uw | (uw << 16);
406 return imm;
407 }
408
409 /** Construct short immediate register */
410 static INLINE struct brw_reg brw_imm_w( GLshort w )
411 {
412 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
413 imm.dw1.d = w | (w << 16);
414 return imm;
415 }
416
417 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
418 * numbers alias with _V and _VF below:
419 */
420
421 /** Construct vector of eight signed half-byte values */
422 static INLINE struct brw_reg brw_imm_v( GLuint v )
423 {
424 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
425 imm.vstride = BRW_VERTICAL_STRIDE_0;
426 imm.width = BRW_WIDTH_8;
427 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
428 imm.dw1.ud = v;
429 return imm;
430 }
431
432 /** Construct vector of four 8-bit float values */
433 static INLINE struct brw_reg brw_imm_vf( GLuint v )
434 {
435 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
436 imm.vstride = BRW_VERTICAL_STRIDE_0;
437 imm.width = BRW_WIDTH_4;
438 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
439 imm.dw1.ud = v;
440 return imm;
441 }
442
443 #define VF_ZERO 0x0
444 #define VF_ONE 0x30
445 #define VF_NEG (1<<7)
446
447 static INLINE struct brw_reg brw_imm_vf4( GLuint v0,
448 GLuint v1,
449 GLuint v2,
450 GLuint v3)
451 {
452 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
453 imm.vstride = BRW_VERTICAL_STRIDE_0;
454 imm.width = BRW_WIDTH_4;
455 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
456 imm.dw1.ud = ((v0 << 0) |
457 (v1 << 8) |
458 (v2 << 16) |
459 (v3 << 24));
460 return imm;
461 }
462
463
464 static INLINE struct brw_reg brw_address( struct brw_reg reg )
465 {
466 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
467 }
468
469 /** Construct float[1] general-purpose register */
470 static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
471 {
472 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
473 }
474
475 /** Construct float[2] general-purpose register */
476 static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
477 {
478 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
479 }
480
481 /** Construct float[4] general-purpose register */
482 static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
483 {
484 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
485 }
486
487 /** Construct float[8] general-purpose register */
488 static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
489 {
490 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
491 }
492
493
494 static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
495 {
496 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
497 }
498
499 static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
500 {
501 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
502 }
503
504
505 /** Construct null register (usually used for setting condition codes) */
506 static INLINE struct brw_reg brw_null_reg( void )
507 {
508 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
509 BRW_ARF_NULL,
510 0);
511 }
512
513 static INLINE struct brw_reg brw_address_reg( GLuint subnr )
514 {
515 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
516 BRW_ARF_ADDRESS,
517 subnr);
518 }
519
520 /* If/else instructions break in align16 mode if writemask & swizzle
521 * aren't xyzw. This goes against the convention for other scalar
522 * regs:
523 */
524 static INLINE struct brw_reg brw_ip_reg( void )
525 {
526 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
527 BRW_ARF_IP,
528 0,
529 BRW_REGISTER_TYPE_UD,
530 BRW_VERTICAL_STRIDE_4, /* ? */
531 BRW_WIDTH_1,
532 BRW_HORIZONTAL_STRIDE_0,
533 BRW_SWIZZLE_XYZW, /* NOTE! */
534 BRW_WRITEMASK_XYZW); /* NOTE! */
535 }
536
537 static INLINE struct brw_reg brw_acc_reg( void )
538 {
539 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
540 BRW_ARF_ACCUMULATOR,
541 0);
542 }
543
544
545 static INLINE struct brw_reg brw_flag_reg( void )
546 {
547 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
548 BRW_ARF_FLAG,
549 0);
550 }
551
552
553 static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
554 {
555 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
556 BRW_ARF_MASK,
557 subnr);
558 }
559
560 static INLINE struct brw_reg brw_message_reg( GLuint nr )
561 {
562 assert(nr < BRW_MAX_MRF);
563 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
564 nr,
565 0);
566 }
567
568
569
570
571 /* This is almost always called with a numeric constant argument, so
572 * make things easy to evaluate at compile time:
573 */
574 static INLINE GLuint cvt( GLuint val )
575 {
576 switch (val) {
577 case 0: return 0;
578 case 1: return 1;
579 case 2: return 2;
580 case 4: return 3;
581 case 8: return 4;
582 case 16: return 5;
583 case 32: return 6;
584 }
585 return 0;
586 }
587
588 static INLINE struct brw_reg stride( struct brw_reg reg,
589 GLuint vstride,
590 GLuint width,
591 GLuint hstride )
592 {
593 reg.vstride = cvt(vstride);
594 reg.width = cvt(width) - 1;
595 reg.hstride = cvt(hstride);
596 return reg;
597 }
598
599
600 static INLINE struct brw_reg vec16( struct brw_reg reg )
601 {
602 return stride(reg, 16,16,1);
603 }
604
605 static INLINE struct brw_reg vec8( struct brw_reg reg )
606 {
607 return stride(reg, 8,8,1);
608 }
609
610 static INLINE struct brw_reg vec4( struct brw_reg reg )
611 {
612 return stride(reg, 4,4,1);
613 }
614
615 static INLINE struct brw_reg vec2( struct brw_reg reg )
616 {
617 return stride(reg, 2,2,1);
618 }
619
620 static INLINE struct brw_reg vec1( struct brw_reg reg )
621 {
622 return stride(reg, 0,1,0);
623 }
624
625
626 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
627 {
628 return vec1(suboffset(reg, elt));
629 }
630
631 static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
632 {
633 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
634 }
635
636
637 static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
638 GLuint x,
639 GLuint y,
640 GLuint z,
641 GLuint w)
642 {
643 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
644 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
645 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
646 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
647 return reg;
648 }
649
650
651 static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
652 GLuint x )
653 {
654 return brw_swizzle(reg, x, x, x, x);
655 }
656
657 static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
658 GLuint mask )
659 {
660 reg.dw1.bits.writemask &= mask;
661 return reg;
662 }
663
664 static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
665 GLuint mask )
666 {
667 reg.dw1.bits.writemask = mask;
668 return reg;
669 }
670
671 static INLINE struct brw_reg negate( struct brw_reg reg )
672 {
673 reg.negate ^= 1;
674 return reg;
675 }
676
677 static INLINE struct brw_reg brw_abs( struct brw_reg reg )
678 {
679 reg.abs = 1;
680 return reg;
681 }
682
683 /***********************************************************************
684 */
685 static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
686 GLint offset )
687 {
688 struct brw_reg reg = brw_vec4_grf(0, 0);
689 reg.subnr = subnr;
690 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
691 reg.dw1.bits.indirect_offset = offset;
692 return reg;
693 }
694
695 static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
696 GLint offset )
697 {
698 struct brw_reg reg = brw_vec1_grf(0, 0);
699 reg.subnr = subnr;
700 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
701 reg.dw1.bits.indirect_offset = offset;
702 return reg;
703 }
704
705 static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
706 {
707 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
708 }
709
710 static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
711 {
712 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
713 }
714
715 static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
716 {
717 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
718 }
719
720 static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
721 {
722 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
723 }
724
725 static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
726 {
727 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
728 }
729
730 static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
731 {
732 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
733 }
734
735 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
736 {
737 return brw_address_reg(ptr.addr_subnr);
738 }
739
740 static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
741 {
742 ptr.addr_offset += offset;
743 return ptr;
744 }
745
746 static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
747 {
748 struct brw_indirect ptr;
749 ptr.addr_subnr = addr_subnr;
750 ptr.addr_offset = offset;
751 ptr.pad = 0;
752 return ptr;
753 }
754
755 /** Do two brw_regs refer to the same register? */
756 static INLINE GLboolean
757 brw_same_reg(struct brw_reg r1, struct brw_reg r2)
758 {
759 return r1.file == r2.file && r1.nr == r2.nr;
760 }
761
762 static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
763 {
764 return &p->store[p->nr_insn];
765 }
766
767 void brw_pop_insn_state( struct brw_compile *p );
768 void brw_push_insn_state( struct brw_compile *p );
769 void brw_set_mask_control( struct brw_compile *p, GLuint value );
770 void brw_set_saturate( struct brw_compile *p, GLuint value );
771 void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
772 void brw_set_compression_control( struct brw_compile *p, GLboolean control );
773 void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
774 void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
775 void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
776
777 void brw_init_compile( struct brw_context *, struct brw_compile *p );
778
779 enum pipe_error brw_get_program( struct brw_compile *p,
780 const GLuint **program,
781 GLuint *sz );
782
783
784 /* Helpers for regular instructions:
785 */
786 #define ALU1(OP) \
787 struct brw_instruction *brw_##OP(struct brw_compile *p, \
788 struct brw_reg dest, \
789 struct brw_reg src0);
790
791 #define ALU2(OP) \
792 struct brw_instruction *brw_##OP(struct brw_compile *p, \
793 struct brw_reg dest, \
794 struct brw_reg src0, \
795 struct brw_reg src1);
796
797 ALU1(MOV)
798 ALU2(SEL)
799 ALU1(NOT)
800 ALU2(AND)
801 ALU2(OR)
802 ALU2(XOR)
803 ALU2(SHR)
804 ALU2(SHL)
805 ALU2(RSR)
806 ALU2(RSL)
807 ALU2(ASR)
808 ALU2(JMPI)
809 ALU2(ADD)
810 ALU2(MUL)
811 ALU1(FRC)
812 ALU1(RNDD)
813 ALU1(RNDZ)
814 ALU2(MAC)
815 ALU2(MACH)
816 ALU1(LZD)
817 ALU2(DP4)
818 ALU2(DPH)
819 ALU2(DP3)
820 ALU2(DP2)
821 ALU2(LINE)
822
823 #undef ALU1
824 #undef ALU2
825
826
827
828 /* Helpers for SEND instruction:
829 */
830 void brw_urb_WRITE(struct brw_compile *p,
831 struct brw_reg dest,
832 GLuint msg_reg_nr,
833 struct brw_reg src0,
834 GLboolean allocate,
835 GLboolean used,
836 GLuint msg_length,
837 GLuint response_length,
838 GLboolean eot,
839 GLboolean writes_complete,
840 GLuint offset,
841 GLuint swizzle);
842
843 void brw_ff_sync(struct brw_compile *p,
844 struct brw_reg dest,
845 GLuint msg_reg_nr,
846 struct brw_reg src0,
847 GLboolean allocate,
848 GLboolean used,
849 GLuint msg_length,
850 GLuint response_length,
851 GLboolean eot,
852 GLboolean writes_complete,
853 GLuint offset,
854 GLuint swizzle);
855
856 void brw_fb_WRITE(struct brw_compile *p,
857 struct brw_reg dest,
858 GLuint msg_reg_nr,
859 struct brw_reg src0,
860 GLuint binding_table_index,
861 GLuint msg_length,
862 GLuint response_length,
863 GLboolean eot);
864
865 void brw_SAMPLE(struct brw_compile *p,
866 struct brw_reg dest,
867 GLuint msg_reg_nr,
868 struct brw_reg src0,
869 GLuint binding_table_index,
870 GLuint sampler,
871 GLuint writemask,
872 GLuint msg_type,
873 GLuint response_length,
874 GLuint msg_length,
875 GLboolean eot,
876 GLuint header_present,
877 GLuint simd_mode);
878
879 void brw_math_16( struct brw_compile *p,
880 struct brw_reg dest,
881 GLuint function,
882 GLuint saturate,
883 GLuint msg_reg_nr,
884 struct brw_reg src,
885 GLuint precision );
886
887 void brw_math( struct brw_compile *p,
888 struct brw_reg dest,
889 GLuint function,
890 GLuint saturate,
891 GLuint msg_reg_nr,
892 struct brw_reg src,
893 GLuint data_type,
894 GLuint precision );
895
896 void brw_dp_READ_16( struct brw_compile *p,
897 struct brw_reg dest,
898 GLuint scratch_offset );
899
900 void brw_dp_READ_4( struct brw_compile *p,
901 struct brw_reg dest,
902 GLboolean relAddr,
903 GLuint location,
904 GLuint bind_table_index );
905
906 void brw_dp_READ_4_vs( struct brw_compile *p,
907 struct brw_reg dest,
908 GLuint oword,
909 GLboolean relAddr,
910 struct brw_reg addrReg,
911 GLuint location,
912 GLuint bind_table_index );
913
914 void brw_dp_WRITE_16( struct brw_compile *p,
915 struct brw_reg src,
916 GLuint scratch_offset );
917
918 /* If/else/endif. Works by manipulating the execution flags on each
919 * channel.
920 */
921 struct brw_instruction *brw_IF(struct brw_compile *p,
922 GLuint execute_size);
923
924 struct brw_instruction *brw_ELSE(struct brw_compile *p,
925 struct brw_instruction *if_insn);
926
927 void brw_ENDIF(struct brw_compile *p,
928 struct brw_instruction *if_or_else_insn);
929
930
931 /* DO/WHILE loops:
932 */
933 struct brw_instruction *brw_DO(struct brw_compile *p,
934 GLuint execute_size);
935
936 struct brw_instruction *brw_WHILE(struct brw_compile *p,
937 struct brw_instruction *patch_insn);
938
939 struct brw_instruction *brw_BREAK(struct brw_compile *p);
940 struct brw_instruction *brw_CONT(struct brw_compile *p);
941 /* Forward jumps:
942 */
943 void brw_land_fwd_jump(struct brw_compile *p,
944 struct brw_instruction *jmp_insn);
945
946
947
948 void brw_NOP(struct brw_compile *p);
949
950 /* Special case: there is never a destination, execution size will be
951 * taken from src0:
952 */
953 void brw_CMP(struct brw_compile *p,
954 struct brw_reg dest,
955 GLuint conditional,
956 struct brw_reg src0,
957 struct brw_reg src1);
958
959 void brw_print_reg( struct brw_reg reg );
960
961
962 /***********************************************************************
963 * brw_eu_util.c:
964 */
965
966 void brw_copy_indirect_to_indirect(struct brw_compile *p,
967 struct brw_indirect dst_ptr,
968 struct brw_indirect src_ptr,
969 GLuint count);
970
971 void brw_copy_from_indirect(struct brw_compile *p,
972 struct brw_reg dst,
973 struct brw_indirect ptr,
974 GLuint count);
975
976 void brw_copy4(struct brw_compile *p,
977 struct brw_reg dst,
978 struct brw_reg src,
979 GLuint count);
980
981 void brw_copy8(struct brw_compile *p,
982 struct brw_reg dst,
983 struct brw_reg src,
984 GLuint count);
985
986 void brw_math_invert( struct brw_compile *p,
987 struct brw_reg dst,
988 struct brw_reg src);
989
990 void brw_set_src1( struct brw_instruction *insn,
991 struct brw_reg reg );
992 #endif