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