i965/fs: Don't consider the stencil output to be a color output.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_reg.h
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics 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 <keithw@vmware.com>
30 */
31
32 /** @file brw_reg.h
33 *
34 * This file defines struct brw_reg, which is our representation for EU
35 * registers. They're not a hardware specific format, just an abstraction
36 * that intends to capture the full flexibility of the hardware registers.
37 *
38 * The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
39 * the abstract brw_reg type into the actual hardware instruction encoding.
40 */
41
42 #ifndef BRW_REG_H
43 #define BRW_REG_H
44
45 #include <stdbool.h>
46 #include "main/compiler.h"
47 #include "main/macros.h"
48 #include "program/prog_instruction.h"
49 #include "brw_defines.h"
50
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 struct brw_device_info;
56
57 /** Number of general purpose registers (VS, WM, etc) */
58 #define BRW_MAX_GRF 128
59
60 /**
61 * First GRF used for the MRF hack.
62 *
63 * On gen7, MRFs are no longer used, and contiguous GRFs are used instead. We
64 * haven't converted our compiler to be aware of this, so it asks for MRFs and
65 * brw_eu_emit.c quietly converts them to be accesses of the top GRFs. The
66 * register allocators have to be careful of this to avoid corrupting the "MRF"s
67 * with actual GRF allocations.
68 */
69 #define GEN7_MRF_HACK_START 112
70
71 /** Number of message register file registers */
72 #define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
73
74 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
75 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
76
77 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
78 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
79 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
80 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
81 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
82 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
83 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
84 #define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
85 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
86 #define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
87 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
88 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
89 #define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
90
91 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
92 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
93
94 static inline bool
95 brw_is_single_value_swizzle(unsigned swiz)
96 {
97 return (swiz == BRW_SWIZZLE_XXXX ||
98 swiz == BRW_SWIZZLE_YYYY ||
99 swiz == BRW_SWIZZLE_ZZZZ ||
100 swiz == BRW_SWIZZLE_WWWW);
101 }
102
103 /**
104 * Compute the swizzle obtained from the application of \p swz0 on the result
105 * of \p swz1. The argument ordering is expected to match function
106 * composition.
107 */
108 static inline unsigned
109 brw_compose_swizzle(unsigned swz0, unsigned swz1)
110 {
111 return BRW_SWIZZLE4(
112 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
113 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
114 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
115 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
116 }
117
118 /**
119 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
120 * (AKA image).
121 */
122 static inline unsigned
123 brw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
124 {
125 unsigned result = 0;
126
127 for (unsigned i = 0; i < 4; i++) {
128 if (mask & (1 << BRW_GET_SWZ(swz, i)))
129 result |= 1 << i;
130 }
131
132 return result;
133 }
134
135 /**
136 * Return the result of applying the inverse of swizzle \p swz to shuffle the
137 * bits of \p mask (AKA preimage). Useful to find out which components are
138 * read from a swizzled source given the instruction writemask.
139 */
140 static inline unsigned
141 brw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
142 {
143 unsigned result = 0;
144
145 for (unsigned i = 0; i < 4; i++) {
146 if (mask & (1 << i))
147 result |= 1 << BRW_GET_SWZ(swz, i);
148 }
149
150 return result;
151 }
152
153 /**
154 * Construct an identity swizzle for the set of enabled channels given by \p
155 * mask. The result will only reference channels enabled in the provided \p
156 * mask, assuming that \p mask is non-zero. The constructed swizzle will
157 * satisfy the property that for any instruction OP and any mask:
158 *
159 * brw_OP(p, brw_writemask(dst, mask),
160 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
161 *
162 * will be equivalent to the same instruction without swizzle:
163 *
164 * brw_OP(p, brw_writemask(dst, mask), src);
165 */
166 static inline unsigned
167 brw_swizzle_for_mask(unsigned mask)
168 {
169 unsigned last = (mask ? ffs(mask) - 1 : 0);
170 unsigned swz[4];
171
172 for (unsigned i = 0; i < 4; i++)
173 last = swz[i] = (mask & (1 << i) ? i : last);
174
175 return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
176 }
177
178 /**
179 * Construct an identity swizzle for the first \p n components of a vector.
180 * When only a subset of channels of a vec4 are used we don't want to
181 * reference the other channels, as that will tell optimization passes that
182 * those other channels are used.
183 */
184 static inline unsigned
185 brw_swizzle_for_size(unsigned n)
186 {
187 return brw_swizzle_for_mask((1 << n) - 1);
188 }
189
190 /**
191 * Converse of brw_swizzle_for_mask(). Returns the mask of components
192 * accessed by the specified swizzle \p swz.
193 */
194 static inline unsigned
195 brw_mask_for_swizzle(unsigned swz)
196 {
197 return brw_apply_inv_swizzle_to_mask(swz, ~0);
198 }
199
200 enum PACKED brw_reg_type {
201 BRW_REGISTER_TYPE_UD = 0,
202 BRW_REGISTER_TYPE_D,
203 BRW_REGISTER_TYPE_UW,
204 BRW_REGISTER_TYPE_W,
205 BRW_REGISTER_TYPE_F,
206
207 /** Non-immediates only: @{ */
208 BRW_REGISTER_TYPE_UB,
209 BRW_REGISTER_TYPE_B,
210 /** @} */
211
212 /** Immediates only: @{ */
213 BRW_REGISTER_TYPE_UV, /* Gen6+ */
214 BRW_REGISTER_TYPE_V,
215 BRW_REGISTER_TYPE_VF,
216 /** @} */
217
218 BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */
219
220 /* Gen8+ */
221 BRW_REGISTER_TYPE_HF,
222 BRW_REGISTER_TYPE_UQ,
223 BRW_REGISTER_TYPE_Q,
224 };
225
226 unsigned brw_reg_type_to_hw_type(const struct brw_device_info *devinfo,
227 enum brw_reg_type type, enum brw_reg_file file);
228 const char *brw_reg_type_letters(unsigned brw_reg_type);
229 uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
230
231 #define REG_SIZE (8*4)
232
233 /* These aren't hardware structs, just something useful for us to pass around:
234 *
235 * Align1 operation has a lot of control over input ranges. Used in
236 * WM programs to implement shaders decomposed into "channel serial"
237 * or "structure of array" form:
238 */
239 struct brw_reg {
240 union {
241 struct {
242 enum brw_reg_type type:4;
243 enum brw_reg_file file:3; /* :2 hardware format */
244 unsigned negate:1; /* source only */
245 unsigned abs:1; /* source only */
246 unsigned address_mode:1; /* relative addressing, hopefully! */
247 unsigned pad0:1;
248 unsigned subnr:5; /* :1 in align16 */
249 unsigned nr:16;
250 };
251 uint32_t bits;
252 };
253
254 union {
255 struct {
256 unsigned swizzle:8; /* src only, align16 only */
257 unsigned writemask:4; /* dest only, align16 only */
258 int indirect_offset:10; /* relative addressing offset */
259 unsigned vstride:4; /* source only */
260 unsigned width:3; /* src only, align1 only */
261 unsigned hstride:2; /* align1 only */
262 unsigned pad1:1;
263 };
264
265 double df;
266 uint64_t u64;
267 float f;
268 int d;
269 unsigned ud;
270 };
271 };
272
273 static inline bool
274 brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
275 {
276 const bool df = a->type == BRW_REGISTER_TYPE_DF && a->file == IMM;
277 return a->bits == b->bits && (df ? a->u64 == b->u64 : a->ud == b->ud);
278 }
279
280 struct brw_indirect {
281 unsigned addr_subnr:4;
282 int addr_offset:10;
283 unsigned pad:18;
284 };
285
286
287 static inline unsigned
288 type_sz(unsigned type)
289 {
290 switch(type) {
291 case BRW_REGISTER_TYPE_UQ:
292 case BRW_REGISTER_TYPE_Q:
293 case BRW_REGISTER_TYPE_DF:
294 return 8;
295 case BRW_REGISTER_TYPE_UD:
296 case BRW_REGISTER_TYPE_D:
297 case BRW_REGISTER_TYPE_F:
298 case BRW_REGISTER_TYPE_VF:
299 return 4;
300 case BRW_REGISTER_TYPE_UW:
301 case BRW_REGISTER_TYPE_W:
302 case BRW_REGISTER_TYPE_UV:
303 case BRW_REGISTER_TYPE_V:
304 case BRW_REGISTER_TYPE_HF:
305 return 2;
306 case BRW_REGISTER_TYPE_UB:
307 case BRW_REGISTER_TYPE_B:
308 return 1;
309 default:
310 unreachable("not reached");
311 }
312 }
313
314 /**
315 * Return an integer type of the requested size and signedness.
316 */
317 static inline enum brw_reg_type
318 brw_int_type(unsigned sz, bool is_signed)
319 {
320 switch (sz) {
321 case 1:
322 return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
323 case 2:
324 return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
325 case 4:
326 return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
327 case 8:
328 return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
329 default:
330 unreachable("Not reached.");
331 }
332 }
333
334 /**
335 * Construct a brw_reg.
336 * \param file one of the BRW_x_REGISTER_FILE values
337 * \param nr register number/index
338 * \param subnr register sub number
339 * \param negate register negate modifier
340 * \param abs register abs modifier
341 * \param type one of BRW_REGISTER_TYPE_x
342 * \param vstride one of BRW_VERTICAL_STRIDE_x
343 * \param width one of BRW_WIDTH_x
344 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
345 * \param swizzle one of BRW_SWIZZLE_x
346 * \param writemask WRITEMASK_X/Y/Z/W bitfield
347 */
348 static inline struct brw_reg
349 brw_reg(enum brw_reg_file file,
350 unsigned nr,
351 unsigned subnr,
352 unsigned negate,
353 unsigned abs,
354 enum brw_reg_type type,
355 unsigned vstride,
356 unsigned width,
357 unsigned hstride,
358 unsigned swizzle,
359 unsigned writemask)
360 {
361 struct brw_reg reg;
362 if (file == BRW_GENERAL_REGISTER_FILE)
363 assert(nr < BRW_MAX_GRF);
364 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
365 assert(nr <= BRW_ARF_TIMESTAMP);
366 /* Asserting on the MRF register number requires to know the hardware gen
367 * (gen6 has 24 MRF registers), which we don't know here, so we assert
368 * for that in the generators and in brw_eu_emit.c
369 */
370
371 reg.type = type;
372 reg.file = file;
373 reg.negate = negate;
374 reg.abs = abs;
375 reg.address_mode = BRW_ADDRESS_DIRECT;
376 reg.pad0 = 0;
377 reg.subnr = subnr * type_sz(type);
378 reg.nr = nr;
379
380 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
381 * set swizzle and writemask to W, as the lower bits of subnr will
382 * be lost when converted to align16. This is probably too much to
383 * keep track of as you'd want it adjusted by suboffset(), etc.
384 * Perhaps fix up when converting to align16?
385 */
386 reg.swizzle = swizzle;
387 reg.writemask = writemask;
388 reg.indirect_offset = 0;
389 reg.vstride = vstride;
390 reg.width = width;
391 reg.hstride = hstride;
392 reg.pad1 = 0;
393 return reg;
394 }
395
396 /** Construct float[16] register */
397 static inline struct brw_reg
398 brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
399 {
400 return brw_reg(file,
401 nr,
402 subnr,
403 0,
404 0,
405 BRW_REGISTER_TYPE_F,
406 BRW_VERTICAL_STRIDE_16,
407 BRW_WIDTH_16,
408 BRW_HORIZONTAL_STRIDE_1,
409 BRW_SWIZZLE_XYZW,
410 WRITEMASK_XYZW);
411 }
412
413 /** Construct float[8] register */
414 static inline struct brw_reg
415 brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
416 {
417 return brw_reg(file,
418 nr,
419 subnr,
420 0,
421 0,
422 BRW_REGISTER_TYPE_F,
423 BRW_VERTICAL_STRIDE_8,
424 BRW_WIDTH_8,
425 BRW_HORIZONTAL_STRIDE_1,
426 BRW_SWIZZLE_XYZW,
427 WRITEMASK_XYZW);
428 }
429
430 /** Construct float[4] register */
431 static inline struct brw_reg
432 brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
433 {
434 return brw_reg(file,
435 nr,
436 subnr,
437 0,
438 0,
439 BRW_REGISTER_TYPE_F,
440 BRW_VERTICAL_STRIDE_4,
441 BRW_WIDTH_4,
442 BRW_HORIZONTAL_STRIDE_1,
443 BRW_SWIZZLE_XYZW,
444 WRITEMASK_XYZW);
445 }
446
447 /** Construct float[2] register */
448 static inline struct brw_reg
449 brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
450 {
451 return brw_reg(file,
452 nr,
453 subnr,
454 0,
455 0,
456 BRW_REGISTER_TYPE_F,
457 BRW_VERTICAL_STRIDE_2,
458 BRW_WIDTH_2,
459 BRW_HORIZONTAL_STRIDE_1,
460 BRW_SWIZZLE_XYXY,
461 WRITEMASK_XY);
462 }
463
464 /** Construct float[1] register */
465 static inline struct brw_reg
466 brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
467 {
468 return brw_reg(file,
469 nr,
470 subnr,
471 0,
472 0,
473 BRW_REGISTER_TYPE_F,
474 BRW_VERTICAL_STRIDE_0,
475 BRW_WIDTH_1,
476 BRW_HORIZONTAL_STRIDE_0,
477 BRW_SWIZZLE_XXXX,
478 WRITEMASK_X);
479 }
480
481 static inline struct brw_reg
482 brw_vecn_reg(unsigned width, enum brw_reg_file file,
483 unsigned nr, unsigned subnr)
484 {
485 switch (width) {
486 case 1:
487 return brw_vec1_reg(file, nr, subnr);
488 case 2:
489 return brw_vec2_reg(file, nr, subnr);
490 case 4:
491 return brw_vec4_reg(file, nr, subnr);
492 case 8:
493 return brw_vec8_reg(file, nr, subnr);
494 case 16:
495 return brw_vec16_reg(file, nr, subnr);
496 default:
497 unreachable("Invalid register width");
498 }
499 }
500
501 static inline struct brw_reg
502 retype(struct brw_reg reg, enum brw_reg_type type)
503 {
504 reg.type = type;
505 return reg;
506 }
507
508 static inline struct brw_reg
509 firsthalf(struct brw_reg reg)
510 {
511 return reg;
512 }
513
514 static inline struct brw_reg
515 sechalf(struct brw_reg reg)
516 {
517 if (reg.vstride)
518 reg.nr++;
519 return reg;
520 }
521
522 static inline struct brw_reg
523 suboffset(struct brw_reg reg, unsigned delta)
524 {
525 reg.subnr += delta * type_sz(reg.type);
526 return reg;
527 }
528
529
530 static inline struct brw_reg
531 offset(struct brw_reg reg, unsigned delta)
532 {
533 reg.nr += delta;
534 return reg;
535 }
536
537
538 static inline struct brw_reg
539 byte_offset(struct brw_reg reg, unsigned bytes)
540 {
541 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
542 reg.nr = newoffset / REG_SIZE;
543 reg.subnr = newoffset % REG_SIZE;
544 return reg;
545 }
546
547
548 /** Construct unsigned word[16] register */
549 static inline struct brw_reg
550 brw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
551 {
552 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
553 }
554
555 /** Construct unsigned word[8] register */
556 static inline struct brw_reg
557 brw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
558 {
559 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
560 }
561
562 /** Construct unsigned word[1] register */
563 static inline struct brw_reg
564 brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
565 {
566 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
567 }
568
569 static inline struct brw_reg
570 brw_imm_reg(enum brw_reg_type type)
571 {
572 return brw_reg(BRW_IMMEDIATE_VALUE,
573 0,
574 0,
575 0,
576 0,
577 type,
578 BRW_VERTICAL_STRIDE_0,
579 BRW_WIDTH_1,
580 BRW_HORIZONTAL_STRIDE_0,
581 0,
582 0);
583 }
584
585 /** Construct float immediate register */
586 static inline struct brw_reg
587 brw_imm_df(double df)
588 {
589 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
590 imm.df = df;
591 return imm;
592 }
593
594 static inline struct brw_reg
595 brw_imm_f(float f)
596 {
597 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
598 imm.f = f;
599 return imm;
600 }
601
602 /** Construct integer immediate register */
603 static inline struct brw_reg
604 brw_imm_d(int d)
605 {
606 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
607 imm.d = d;
608 return imm;
609 }
610
611 /** Construct uint immediate register */
612 static inline struct brw_reg
613 brw_imm_ud(unsigned ud)
614 {
615 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
616 imm.ud = ud;
617 return imm;
618 }
619
620 /** Construct ushort immediate register */
621 static inline struct brw_reg
622 brw_imm_uw(uint16_t uw)
623 {
624 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
625 imm.ud = uw | (uw << 16);
626 return imm;
627 }
628
629 /** Construct short immediate register */
630 static inline struct brw_reg
631 brw_imm_w(int16_t w)
632 {
633 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
634 imm.d = w | (w << 16);
635 return imm;
636 }
637
638 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
639 * numbers alias with _V and _VF below:
640 */
641
642 /** Construct vector of eight signed half-byte values */
643 static inline struct brw_reg
644 brw_imm_v(unsigned v)
645 {
646 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
647 imm.ud = v;
648 return imm;
649 }
650
651 /** Construct vector of eight unsigned half-byte values */
652 static inline struct brw_reg
653 brw_imm_uv(unsigned uv)
654 {
655 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
656 imm.ud = uv;
657 return imm;
658 }
659
660 /** Construct vector of four 8-bit float values */
661 static inline struct brw_reg
662 brw_imm_vf(unsigned v)
663 {
664 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
665 imm.ud = v;
666 return imm;
667 }
668
669 static inline struct brw_reg
670 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
671 {
672 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
673 imm.vstride = BRW_VERTICAL_STRIDE_0;
674 imm.width = BRW_WIDTH_4;
675 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
676 imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
677 return imm;
678 }
679
680
681 static inline struct brw_reg
682 brw_address(struct brw_reg reg)
683 {
684 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
685 }
686
687 /** Construct float[1] general-purpose register */
688 static inline struct brw_reg
689 brw_vec1_grf(unsigned nr, unsigned subnr)
690 {
691 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
692 }
693
694 /** Construct float[2] general-purpose register */
695 static inline struct brw_reg
696 brw_vec2_grf(unsigned nr, unsigned subnr)
697 {
698 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
699 }
700
701 /** Construct float[4] general-purpose register */
702 static inline struct brw_reg
703 brw_vec4_grf(unsigned nr, unsigned subnr)
704 {
705 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
706 }
707
708 /** Construct float[8] general-purpose register */
709 static inline struct brw_reg
710 brw_vec8_grf(unsigned nr, unsigned subnr)
711 {
712 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
713 }
714
715 /** Construct float[16] general-purpose register */
716 static inline struct brw_reg
717 brw_vec16_grf(unsigned nr, unsigned subnr)
718 {
719 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
720 }
721
722
723 static inline struct brw_reg
724 brw_uw8_grf(unsigned nr, unsigned subnr)
725 {
726 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
727 }
728
729 static inline struct brw_reg
730 brw_uw16_grf(unsigned nr, unsigned subnr)
731 {
732 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
733 }
734
735
736 /** Construct null register (usually used for setting condition codes) */
737 static inline struct brw_reg
738 brw_null_reg(void)
739 {
740 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
741 }
742
743 static inline struct brw_reg
744 brw_null_vec(unsigned width)
745 {
746 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
747 }
748
749 static inline struct brw_reg
750 brw_address_reg(unsigned subnr)
751 {
752 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
753 }
754
755 /* If/else instructions break in align16 mode if writemask & swizzle
756 * aren't xyzw. This goes against the convention for other scalar
757 * regs:
758 */
759 static inline struct brw_reg
760 brw_ip_reg(void)
761 {
762 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
763 BRW_ARF_IP,
764 0,
765 0,
766 0,
767 BRW_REGISTER_TYPE_UD,
768 BRW_VERTICAL_STRIDE_4, /* ? */
769 BRW_WIDTH_1,
770 BRW_HORIZONTAL_STRIDE_0,
771 BRW_SWIZZLE_XYZW, /* NOTE! */
772 WRITEMASK_XYZW); /* NOTE! */
773 }
774
775 static inline struct brw_reg
776 brw_notification_reg(void)
777 {
778 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
779 BRW_ARF_NOTIFICATION_COUNT,
780 0,
781 0,
782 0,
783 BRW_REGISTER_TYPE_UD,
784 BRW_VERTICAL_STRIDE_0,
785 BRW_WIDTH_1,
786 BRW_HORIZONTAL_STRIDE_0,
787 BRW_SWIZZLE_XXXX,
788 WRITEMASK_X);
789 }
790
791 static inline struct brw_reg
792 brw_sr0_reg(void)
793 {
794 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
795 BRW_ARF_STATE,
796 0,
797 0,
798 0,
799 BRW_REGISTER_TYPE_UD,
800 BRW_VERTICAL_STRIDE_8,
801 BRW_WIDTH_8,
802 BRW_HORIZONTAL_STRIDE_1,
803 BRW_SWIZZLE_XYZW,
804 WRITEMASK_XYZW);
805 }
806
807 static inline struct brw_reg
808 brw_acc_reg(unsigned width)
809 {
810 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
811 BRW_ARF_ACCUMULATOR, 0);
812 }
813
814 static inline struct brw_reg
815 brw_flag_reg(int reg, int subreg)
816 {
817 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
818 BRW_ARF_FLAG + reg, subreg);
819 }
820
821 /**
822 * Return the mask register present in Gen4-5, or the related register present
823 * in Gen7.5 and later hardware referred to as "channel enable" register in
824 * the documentation.
825 */
826 static inline struct brw_reg
827 brw_mask_reg(unsigned subnr)
828 {
829 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
830 }
831
832 static inline struct brw_reg
833 brw_message_reg(unsigned nr)
834 {
835 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
836 }
837
838 static inline struct brw_reg
839 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
840 {
841 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
842 BRW_REGISTER_TYPE_UD);
843 }
844
845 /* This is almost always called with a numeric constant argument, so
846 * make things easy to evaluate at compile time:
847 */
848 static inline unsigned cvt(unsigned val)
849 {
850 switch (val) {
851 case 0: return 0;
852 case 1: return 1;
853 case 2: return 2;
854 case 4: return 3;
855 case 8: return 4;
856 case 16: return 5;
857 case 32: return 6;
858 }
859 return 0;
860 }
861
862 static inline struct brw_reg
863 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
864 {
865 reg.vstride = cvt(vstride);
866 reg.width = cvt(width) - 1;
867 reg.hstride = cvt(hstride);
868 return reg;
869 }
870
871 /**
872 * Multiply the vertical and horizontal stride of a register by the given
873 * factor \a s.
874 */
875 static inline struct brw_reg
876 spread(struct brw_reg reg, unsigned s)
877 {
878 if (s) {
879 assert(_mesa_is_pow_two(s));
880
881 if (reg.hstride)
882 reg.hstride += cvt(s) - 1;
883
884 if (reg.vstride)
885 reg.vstride += cvt(s) - 1;
886
887 return reg;
888 } else {
889 return stride(reg, 0, 1, 0);
890 }
891 }
892
893 static inline struct brw_reg
894 vec16(struct brw_reg reg)
895 {
896 return stride(reg, 16,16,1);
897 }
898
899 static inline struct brw_reg
900 vec8(struct brw_reg reg)
901 {
902 return stride(reg, 8,8,1);
903 }
904
905 static inline struct brw_reg
906 vec4(struct brw_reg reg)
907 {
908 return stride(reg, 4,4,1);
909 }
910
911 static inline struct brw_reg
912 vec2(struct brw_reg reg)
913 {
914 return stride(reg, 2,2,1);
915 }
916
917 static inline struct brw_reg
918 vec1(struct brw_reg reg)
919 {
920 return stride(reg, 0,1,0);
921 }
922
923
924 static inline struct brw_reg
925 get_element(struct brw_reg reg, unsigned elt)
926 {
927 return vec1(suboffset(reg, elt));
928 }
929
930 static inline struct brw_reg
931 get_element_ud(struct brw_reg reg, unsigned elt)
932 {
933 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
934 }
935
936 static inline struct brw_reg
937 get_element_d(struct brw_reg reg, unsigned elt)
938 {
939 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
940 }
941
942 static inline struct brw_reg
943 brw_swizzle(struct brw_reg reg, unsigned swz)
944 {
945 if (reg.file == BRW_IMMEDIATE_VALUE)
946 reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
947 else
948 reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
949
950 return reg;
951 }
952
953 static inline struct brw_reg
954 brw_writemask(struct brw_reg reg, unsigned mask)
955 {
956 assert(reg.file != BRW_IMMEDIATE_VALUE);
957 reg.writemask &= mask;
958 return reg;
959 }
960
961 static inline struct brw_reg
962 brw_set_writemask(struct brw_reg reg, unsigned mask)
963 {
964 assert(reg.file != BRW_IMMEDIATE_VALUE);
965 reg.writemask = mask;
966 return reg;
967 }
968
969 static inline unsigned
970 brw_writemask_for_size(unsigned n)
971 {
972 return (1 << n) - 1;
973 }
974
975 static inline unsigned
976 brw_writemask_for_component_packing(unsigned n, unsigned first_component)
977 {
978 assert(first_component + n <= 4);
979 return (((1 << n) - 1) << first_component);
980 }
981
982 static inline struct brw_reg
983 negate(struct brw_reg reg)
984 {
985 reg.negate ^= 1;
986 return reg;
987 }
988
989 static inline struct brw_reg
990 brw_abs(struct brw_reg reg)
991 {
992 reg.abs = 1;
993 reg.negate = 0;
994 return reg;
995 }
996
997 /************************************************************************/
998
999 static inline struct brw_reg
1000 brw_vec4_indirect(unsigned subnr, int offset)
1001 {
1002 struct brw_reg reg = brw_vec4_grf(0, 0);
1003 reg.subnr = subnr;
1004 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1005 reg.indirect_offset = offset;
1006 return reg;
1007 }
1008
1009 static inline struct brw_reg
1010 brw_vec1_indirect(unsigned subnr, int offset)
1011 {
1012 struct brw_reg reg = brw_vec1_grf(0, 0);
1013 reg.subnr = subnr;
1014 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1015 reg.indirect_offset = offset;
1016 return reg;
1017 }
1018
1019 static inline struct brw_reg
1020 brw_VxH_indirect(unsigned subnr, int offset)
1021 {
1022 struct brw_reg reg = brw_vec1_grf(0, 0);
1023 reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
1024 reg.subnr = subnr;
1025 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1026 reg.indirect_offset = offset;
1027 return reg;
1028 }
1029
1030 static inline struct brw_reg
1031 deref_4f(struct brw_indirect ptr, int offset)
1032 {
1033 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1034 }
1035
1036 static inline struct brw_reg
1037 deref_1f(struct brw_indirect ptr, int offset)
1038 {
1039 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1040 }
1041
1042 static inline struct brw_reg
1043 deref_4b(struct brw_indirect ptr, int offset)
1044 {
1045 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
1046 }
1047
1048 static inline struct brw_reg
1049 deref_1uw(struct brw_indirect ptr, int offset)
1050 {
1051 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
1052 }
1053
1054 static inline struct brw_reg
1055 deref_1d(struct brw_indirect ptr, int offset)
1056 {
1057 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
1058 }
1059
1060 static inline struct brw_reg
1061 deref_1ud(struct brw_indirect ptr, int offset)
1062 {
1063 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
1064 }
1065
1066 static inline struct brw_reg
1067 get_addr_reg(struct brw_indirect ptr)
1068 {
1069 return brw_address_reg(ptr.addr_subnr);
1070 }
1071
1072 static inline struct brw_indirect
1073 brw_indirect_offset(struct brw_indirect ptr, int offset)
1074 {
1075 ptr.addr_offset += offset;
1076 return ptr;
1077 }
1078
1079 static inline struct brw_indirect
1080 brw_indirect(unsigned addr_subnr, int offset)
1081 {
1082 struct brw_indirect ptr;
1083 ptr.addr_subnr = addr_subnr;
1084 ptr.addr_offset = offset;
1085 ptr.pad = 0;
1086 return ptr;
1087 }
1088
1089 static inline bool
1090 region_matches(struct brw_reg reg, enum brw_vertical_stride v,
1091 enum brw_width w, enum brw_horizontal_stride h)
1092 {
1093 return reg.vstride == v &&
1094 reg.width == w &&
1095 reg.hstride == h;
1096 }
1097
1098 #define has_scalar_region(reg) \
1099 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1100 BRW_HORIZONTAL_STRIDE_0)
1101
1102 /* brw_packed_float.c */
1103 int brw_float_to_vf(float f);
1104 float brw_vf_to_float(unsigned char vf);
1105
1106 #ifdef __cplusplus
1107 }
1108 #endif
1109
1110 #endif