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