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