2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics to
4 develop this 3D driver.
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:
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.
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.
26 **********************************************************************/
29 * Keith Whitwell <keithw@vmware.com>
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.
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.
46 #include "main/compiler.h"
47 #include "main/macros.h"
48 #include "program/prog_instruction.h"
49 #include "brw_eu_defines.h"
55 struct gen_device_info
;
57 /** Number of general purpose registers (VS, WM, etc) */
58 #define BRW_MAX_GRF 128
61 * First GRF used for the MRF hack.
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.
69 #define GEN7_MRF_HACK_START 112
71 /** Number of message register file registers */
72 #define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
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)
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_YXYX BRW_SWIZZLE4(1,0,1,0)
85 #define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
86 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
87 #define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
88 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
89 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
90 #define BRW_SWIZZLE_WZWZ BRW_SWIZZLE4(3,2,3,2)
91 #define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
92 #define BRW_SWIZZLE_XXZZ BRW_SWIZZLE4(0,0,2,2)
93 #define BRW_SWIZZLE_YYWW BRW_SWIZZLE4(1,1,3,3)
94 #define BRW_SWIZZLE_YXWZ BRW_SWIZZLE4(1,0,3,2)
96 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
97 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
100 brw_is_single_value_swizzle(unsigned swiz
)
102 return (swiz
== BRW_SWIZZLE_XXXX
||
103 swiz
== BRW_SWIZZLE_YYYY
||
104 swiz
== BRW_SWIZZLE_ZZZZ
||
105 swiz
== BRW_SWIZZLE_WWWW
);
109 * Compute the swizzle obtained from the application of \p swz0 on the result
110 * of \p swz1. The argument ordering is expected to match function
113 static inline unsigned
114 brw_compose_swizzle(unsigned swz0
, unsigned swz1
)
117 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 0)),
118 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 1)),
119 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 2)),
120 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 3)));
124 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
127 static inline unsigned
128 brw_apply_swizzle_to_mask(unsigned swz
, unsigned mask
)
132 for (unsigned i
= 0; i
< 4; i
++) {
133 if (mask
& (1 << BRW_GET_SWZ(swz
, i
)))
141 * Return the result of applying the inverse of swizzle \p swz to shuffle the
142 * bits of \p mask (AKA preimage). Useful to find out which components are
143 * read from a swizzled source given the instruction writemask.
145 static inline unsigned
146 brw_apply_inv_swizzle_to_mask(unsigned swz
, unsigned mask
)
150 for (unsigned i
= 0; i
< 4; i
++) {
152 result
|= 1 << BRW_GET_SWZ(swz
, i
);
159 * Construct an identity swizzle for the set of enabled channels given by \p
160 * mask. The result will only reference channels enabled in the provided \p
161 * mask, assuming that \p mask is non-zero. The constructed swizzle will
162 * satisfy the property that for any instruction OP and any mask:
164 * brw_OP(p, brw_writemask(dst, mask),
165 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
167 * will be equivalent to the same instruction without swizzle:
169 * brw_OP(p, brw_writemask(dst, mask), src);
171 static inline unsigned
172 brw_swizzle_for_mask(unsigned mask
)
174 unsigned last
= (mask
? ffs(mask
) - 1 : 0);
177 for (unsigned i
= 0; i
< 4; i
++)
178 last
= swz
[i
] = (mask
& (1 << i
) ? i
: last
);
180 return BRW_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
184 * Construct an identity swizzle for the first \p n components of a vector.
185 * When only a subset of channels of a vec4 are used we don't want to
186 * reference the other channels, as that will tell optimization passes that
187 * those other channels are used.
189 static inline unsigned
190 brw_swizzle_for_size(unsigned n
)
192 return brw_swizzle_for_mask((1 << n
) - 1);
196 * Converse of brw_swizzle_for_mask(). Returns the mask of components
197 * accessed by the specified swizzle \p swz.
199 static inline unsigned
200 brw_mask_for_swizzle(unsigned swz
)
202 return brw_apply_inv_swizzle_to_mask(swz
, ~0);
205 enum PACKED brw_reg_type
{
206 BRW_REGISTER_TYPE_UD
= 0,
208 BRW_REGISTER_TYPE_UW
,
212 /** Non-immediates only: @{ */
213 BRW_REGISTER_TYPE_UB
,
217 /** Immediates only: @{ */
218 BRW_REGISTER_TYPE_UV
, /* Gen6+ */
220 BRW_REGISTER_TYPE_VF
,
223 BRW_REGISTER_TYPE_DF
, /* Gen7+ (no immediates until Gen8+) */
226 BRW_REGISTER_TYPE_HF
,
227 BRW_REGISTER_TYPE_UQ
,
231 unsigned brw_reg_type_to_hw_type(const struct gen_device_info
*devinfo
,
232 enum brw_reg_type type
, enum brw_reg_file file
);
234 #define brw_element_size(devinfo, inst, operand) \
235 brw_hw_reg_type_to_size(devinfo, \
236 brw_inst_ ## operand ## _reg_type(devinfo, inst), \
237 brw_inst_ ## operand ## _reg_file(devinfo, inst))
238 unsigned brw_hw_reg_type_to_size(const struct gen_device_info
*devinfo
,
239 unsigned type
, enum brw_reg_file file
);
241 const char *brw_reg_type_letters(unsigned brw_reg_type
);
242 uint32_t brw_swizzle_immediate(enum brw_reg_type type
, uint32_t x
, unsigned swz
);
244 #define REG_SIZE (8*4)
246 /* These aren't hardware structs, just something useful for us to pass around:
248 * Align1 operation has a lot of control over input ranges. Used in
249 * WM programs to implement shaders decomposed into "channel serial"
250 * or "structure of array" form:
255 enum brw_reg_type type
:4;
256 enum brw_reg_file file
:3; /* :2 hardware format */
257 unsigned negate
:1; /* source only */
258 unsigned abs
:1; /* source only */
259 unsigned address_mode
:1; /* relative addressing, hopefully! */
261 unsigned subnr
:5; /* :1 in align16 */
269 unsigned swizzle
:8; /* src only, align16 only */
270 unsigned writemask
:4; /* dest only, align16 only */
271 int indirect_offset
:10; /* relative addressing offset */
272 unsigned vstride
:4; /* source only */
273 unsigned width
:3; /* src only, align1 only */
274 unsigned hstride
:2; /* align1 only */
288 brw_regs_equal(const struct brw_reg
*a
, const struct brw_reg
*b
)
290 const bool df
= a
->type
== BRW_REGISTER_TYPE_DF
&& a
->file
== IMM
;
291 return a
->bits
== b
->bits
&& (df
? a
->u64
== b
->u64
: a
->ud
== b
->ud
);
294 struct brw_indirect
{
295 unsigned addr_subnr
:4;
301 static inline unsigned
302 type_sz(unsigned type
)
305 case BRW_REGISTER_TYPE_UQ
:
306 case BRW_REGISTER_TYPE_Q
:
307 case BRW_REGISTER_TYPE_DF
:
309 case BRW_REGISTER_TYPE_UD
:
310 case BRW_REGISTER_TYPE_D
:
311 case BRW_REGISTER_TYPE_F
:
312 case BRW_REGISTER_TYPE_VF
:
314 case BRW_REGISTER_TYPE_UW
:
315 case BRW_REGISTER_TYPE_W
:
316 case BRW_REGISTER_TYPE_UV
:
317 case BRW_REGISTER_TYPE_V
:
318 case BRW_REGISTER_TYPE_HF
:
320 case BRW_REGISTER_TYPE_UB
:
321 case BRW_REGISTER_TYPE_B
:
324 unreachable("not reached");
329 brw_reg_type_is_floating_point(enum brw_reg_type type
)
332 case BRW_REGISTER_TYPE_F
:
333 case BRW_REGISTER_TYPE_HF
:
334 case BRW_REGISTER_TYPE_DF
:
341 static inline enum brw_reg_type
342 get_exec_type(const enum brw_reg_type type
)
345 case BRW_REGISTER_TYPE_B
:
346 case BRW_REGISTER_TYPE_V
:
347 return BRW_REGISTER_TYPE_W
;
348 case BRW_REGISTER_TYPE_UB
:
349 case BRW_REGISTER_TYPE_UV
:
350 return BRW_REGISTER_TYPE_UW
;
351 case BRW_REGISTER_TYPE_VF
:
352 return BRW_REGISTER_TYPE_F
;
359 * Return an integer type of the requested size and signedness.
361 static inline enum brw_reg_type
362 brw_int_type(unsigned sz
, bool is_signed
)
366 return (is_signed
? BRW_REGISTER_TYPE_B
: BRW_REGISTER_TYPE_UB
);
368 return (is_signed
? BRW_REGISTER_TYPE_W
: BRW_REGISTER_TYPE_UW
);
370 return (is_signed
? BRW_REGISTER_TYPE_D
: BRW_REGISTER_TYPE_UD
);
372 return (is_signed
? BRW_REGISTER_TYPE_Q
: BRW_REGISTER_TYPE_UQ
);
374 unreachable("Not reached.");
379 * Construct a brw_reg.
380 * \param file one of the BRW_x_REGISTER_FILE values
381 * \param nr register number/index
382 * \param subnr register sub number
383 * \param negate register negate modifier
384 * \param abs register abs modifier
385 * \param type one of BRW_REGISTER_TYPE_x
386 * \param vstride one of BRW_VERTICAL_STRIDE_x
387 * \param width one of BRW_WIDTH_x
388 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
389 * \param swizzle one of BRW_SWIZZLE_x
390 * \param writemask WRITEMASK_X/Y/Z/W bitfield
392 static inline struct brw_reg
393 brw_reg(enum brw_reg_file file
,
398 enum brw_reg_type type
,
406 if (file
== BRW_GENERAL_REGISTER_FILE
)
407 assert(nr
< BRW_MAX_GRF
);
408 else if (file
== BRW_ARCHITECTURE_REGISTER_FILE
)
409 assert(nr
<= BRW_ARF_TIMESTAMP
);
410 /* Asserting on the MRF register number requires to know the hardware gen
411 * (gen6 has 24 MRF registers), which we don't know here, so we assert
412 * for that in the generators and in brw_eu_emit.c
419 reg
.address_mode
= BRW_ADDRESS_DIRECT
;
421 reg
.subnr
= subnr
* type_sz(type
);
424 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
425 * set swizzle and writemask to W, as the lower bits of subnr will
426 * be lost when converted to align16. This is probably too much to
427 * keep track of as you'd want it adjusted by suboffset(), etc.
428 * Perhaps fix up when converting to align16?
430 reg
.swizzle
= swizzle
;
431 reg
.writemask
= writemask
;
432 reg
.indirect_offset
= 0;
433 reg
.vstride
= vstride
;
435 reg
.hstride
= hstride
;
440 /** Construct float[16] register */
441 static inline struct brw_reg
442 brw_vec16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
450 BRW_VERTICAL_STRIDE_16
,
452 BRW_HORIZONTAL_STRIDE_1
,
457 /** Construct float[8] register */
458 static inline struct brw_reg
459 brw_vec8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
467 BRW_VERTICAL_STRIDE_8
,
469 BRW_HORIZONTAL_STRIDE_1
,
474 /** Construct float[4] register */
475 static inline struct brw_reg
476 brw_vec4_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
484 BRW_VERTICAL_STRIDE_4
,
486 BRW_HORIZONTAL_STRIDE_1
,
491 /** Construct float[2] register */
492 static inline struct brw_reg
493 brw_vec2_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
501 BRW_VERTICAL_STRIDE_2
,
503 BRW_HORIZONTAL_STRIDE_1
,
508 /** Construct float[1] register */
509 static inline struct brw_reg
510 brw_vec1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
518 BRW_VERTICAL_STRIDE_0
,
520 BRW_HORIZONTAL_STRIDE_0
,
525 static inline struct brw_reg
526 brw_vecn_reg(unsigned width
, enum brw_reg_file file
,
527 unsigned nr
, unsigned subnr
)
531 return brw_vec1_reg(file
, nr
, subnr
);
533 return brw_vec2_reg(file
, nr
, subnr
);
535 return brw_vec4_reg(file
, nr
, subnr
);
537 return brw_vec8_reg(file
, nr
, subnr
);
539 return brw_vec16_reg(file
, nr
, subnr
);
541 unreachable("Invalid register width");
545 static inline struct brw_reg
546 retype(struct brw_reg reg
, enum brw_reg_type type
)
552 static inline struct brw_reg
553 firsthalf(struct brw_reg reg
)
558 static inline struct brw_reg
559 sechalf(struct brw_reg reg
)
566 static inline struct brw_reg
567 offset(struct brw_reg reg
, unsigned delta
)
574 static inline struct brw_reg
575 byte_offset(struct brw_reg reg
, unsigned bytes
)
577 unsigned newoffset
= reg
.nr
* REG_SIZE
+ reg
.subnr
+ bytes
;
578 reg
.nr
= newoffset
/ REG_SIZE
;
579 reg
.subnr
= newoffset
% REG_SIZE
;
583 static inline struct brw_reg
584 suboffset(struct brw_reg reg
, unsigned delta
)
586 return byte_offset(reg
, delta
* type_sz(reg
.type
));
589 /** Construct unsigned word[16] register */
590 static inline struct brw_reg
591 brw_uw16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
593 return suboffset(retype(brw_vec16_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
596 /** Construct unsigned word[8] register */
597 static inline struct brw_reg
598 brw_uw8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
600 return suboffset(retype(brw_vec8_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
603 /** Construct unsigned word[1] register */
604 static inline struct brw_reg
605 brw_uw1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
607 return suboffset(retype(brw_vec1_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
610 static inline struct brw_reg
611 brw_ud1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
613 return retype(brw_vec1_reg(file
, nr
, subnr
), BRW_REGISTER_TYPE_UD
);
616 static inline struct brw_reg
617 brw_imm_reg(enum brw_reg_type type
)
619 return brw_reg(BRW_IMMEDIATE_VALUE
,
625 BRW_VERTICAL_STRIDE_0
,
627 BRW_HORIZONTAL_STRIDE_0
,
632 /** Construct float immediate register */
633 static inline struct brw_reg
634 brw_imm_df(double df
)
636 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_DF
);
641 static inline struct brw_reg
644 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_F
);
649 /** Construct integer immediate register */
650 static inline struct brw_reg
653 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_D
);
658 /** Construct uint immediate register */
659 static inline struct brw_reg
660 brw_imm_ud(unsigned ud
)
662 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UD
);
667 /** Construct ushort immediate register */
668 static inline struct brw_reg
669 brw_imm_uw(uint16_t uw
)
671 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UW
);
672 imm
.ud
= uw
| (uw
<< 16);
676 /** Construct short immediate register */
677 static inline struct brw_reg
680 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_W
);
681 imm
.d
= w
| (w
<< 16);
685 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
686 * numbers alias with _V and _VF below:
689 /** Construct vector of eight signed half-byte values */
690 static inline struct brw_reg
691 brw_imm_v(unsigned v
)
693 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_V
);
698 /** Construct vector of eight unsigned half-byte values */
699 static inline struct brw_reg
700 brw_imm_uv(unsigned uv
)
702 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UV
);
707 /** Construct vector of four 8-bit float values */
708 static inline struct brw_reg
709 brw_imm_vf(unsigned v
)
711 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
716 static inline struct brw_reg
717 brw_imm_vf4(unsigned v0
, unsigned v1
, unsigned v2
, unsigned v3
)
719 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
720 imm
.vstride
= BRW_VERTICAL_STRIDE_0
;
721 imm
.width
= BRW_WIDTH_4
;
722 imm
.hstride
= BRW_HORIZONTAL_STRIDE_1
;
723 imm
.ud
= ((v0
<< 0) | (v1
<< 8) | (v2
<< 16) | (v3
<< 24));
728 static inline struct brw_reg
729 brw_address(struct brw_reg reg
)
731 return brw_imm_uw(reg
.nr
* REG_SIZE
+ reg
.subnr
);
734 /** Construct float[1] general-purpose register */
735 static inline struct brw_reg
736 brw_vec1_grf(unsigned nr
, unsigned subnr
)
738 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
741 /** Construct float[2] general-purpose register */
742 static inline struct brw_reg
743 brw_vec2_grf(unsigned nr
, unsigned subnr
)
745 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
748 /** Construct float[4] general-purpose register */
749 static inline struct brw_reg
750 brw_vec4_grf(unsigned nr
, unsigned subnr
)
752 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
755 /** Construct float[8] general-purpose register */
756 static inline struct brw_reg
757 brw_vec8_grf(unsigned nr
, unsigned subnr
)
759 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
762 /** Construct float[16] general-purpose register */
763 static inline struct brw_reg
764 brw_vec16_grf(unsigned nr
, unsigned subnr
)
766 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
769 static inline struct brw_reg
770 brw_vecn_grf(unsigned width
, unsigned nr
, unsigned subnr
)
772 return brw_vecn_reg(width
, BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
776 static inline struct brw_reg
777 brw_uw8_grf(unsigned nr
, unsigned subnr
)
779 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
782 static inline struct brw_reg
783 brw_uw16_grf(unsigned nr
, unsigned subnr
)
785 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
789 /** Construct null register (usually used for setting condition codes) */
790 static inline struct brw_reg
793 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
796 static inline struct brw_reg
797 brw_null_vec(unsigned width
)
799 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
802 static inline struct brw_reg
803 brw_address_reg(unsigned subnr
)
805 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_ADDRESS
, subnr
);
808 /* If/else instructions break in align16 mode if writemask & swizzle
809 * aren't xyzw. This goes against the convention for other scalar
812 static inline struct brw_reg
815 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
820 BRW_REGISTER_TYPE_UD
,
821 BRW_VERTICAL_STRIDE_4
, /* ? */
823 BRW_HORIZONTAL_STRIDE_0
,
824 BRW_SWIZZLE_XYZW
, /* NOTE! */
825 WRITEMASK_XYZW
); /* NOTE! */
828 static inline struct brw_reg
829 brw_notification_reg(void)
831 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
832 BRW_ARF_NOTIFICATION_COUNT
,
836 BRW_REGISTER_TYPE_UD
,
837 BRW_VERTICAL_STRIDE_0
,
839 BRW_HORIZONTAL_STRIDE_0
,
844 static inline struct brw_reg
845 brw_sr0_reg(unsigned subnr
)
847 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_STATE
, subnr
);
850 static inline struct brw_reg
851 brw_acc_reg(unsigned width
)
853 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
,
854 BRW_ARF_ACCUMULATOR
, 0);
857 static inline struct brw_reg
858 brw_flag_reg(int reg
, int subreg
)
860 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
861 BRW_ARF_FLAG
+ reg
, subreg
);
865 * Return the mask register present in Gen4-5, or the related register present
866 * in Gen7.5 and later hardware referred to as "channel enable" register in
869 static inline struct brw_reg
870 brw_mask_reg(unsigned subnr
)
872 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_MASK
, subnr
);
875 static inline struct brw_reg
878 return brw_sr0_reg(3);
881 static inline struct brw_reg
884 return brw_sr0_reg(2);
887 static inline struct brw_reg
888 brw_message_reg(unsigned nr
)
890 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, nr
, 0);
893 static inline struct brw_reg
894 brw_uvec_mrf(unsigned width
, unsigned nr
, unsigned subnr
)
896 return retype(brw_vecn_reg(width
, BRW_MESSAGE_REGISTER_FILE
, nr
, subnr
),
897 BRW_REGISTER_TYPE_UD
);
900 /* This is almost always called with a numeric constant argument, so
901 * make things easy to evaluate at compile time:
903 static inline unsigned cvt(unsigned val
)
917 static inline struct brw_reg
918 stride(struct brw_reg reg
, unsigned vstride
, unsigned width
, unsigned hstride
)
920 reg
.vstride
= cvt(vstride
);
921 reg
.width
= cvt(width
) - 1;
922 reg
.hstride
= cvt(hstride
);
927 * Multiply the vertical and horizontal stride of a register by the given
930 static inline struct brw_reg
931 spread(struct brw_reg reg
, unsigned s
)
934 assert(_mesa_is_pow_two(s
));
937 reg
.hstride
+= cvt(s
) - 1;
940 reg
.vstride
+= cvt(s
) - 1;
944 return stride(reg
, 0, 1, 0);
948 static inline struct brw_reg
949 vec16(struct brw_reg reg
)
951 return stride(reg
, 16,16,1);
954 static inline struct brw_reg
955 vec8(struct brw_reg reg
)
957 return stride(reg
, 8,8,1);
960 static inline struct brw_reg
961 vec4(struct brw_reg reg
)
963 return stride(reg
, 4,4,1);
966 static inline struct brw_reg
967 vec2(struct brw_reg reg
)
969 return stride(reg
, 2,2,1);
972 static inline struct brw_reg
973 vec1(struct brw_reg reg
)
975 return stride(reg
, 0,1,0);
979 static inline struct brw_reg
980 get_element(struct brw_reg reg
, unsigned elt
)
982 return vec1(suboffset(reg
, elt
));
985 static inline struct brw_reg
986 get_element_ud(struct brw_reg reg
, unsigned elt
)
988 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_UD
), elt
));
991 static inline struct brw_reg
992 get_element_d(struct brw_reg reg
, unsigned elt
)
994 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_D
), elt
));
997 static inline struct brw_reg
998 brw_swizzle(struct brw_reg reg
, unsigned swz
)
1000 if (reg
.file
== BRW_IMMEDIATE_VALUE
)
1001 reg
.ud
= brw_swizzle_immediate(reg
.type
, reg
.ud
, swz
);
1003 reg
.swizzle
= brw_compose_swizzle(swz
, reg
.swizzle
);
1008 static inline struct brw_reg
1009 brw_writemask(struct brw_reg reg
, unsigned mask
)
1011 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
1012 reg
.writemask
&= mask
;
1016 static inline struct brw_reg
1017 brw_set_writemask(struct brw_reg reg
, unsigned mask
)
1019 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
1020 reg
.writemask
= mask
;
1024 static inline unsigned
1025 brw_writemask_for_size(unsigned n
)
1027 return (1 << n
) - 1;
1030 static inline unsigned
1031 brw_writemask_for_component_packing(unsigned n
, unsigned first_component
)
1033 assert(first_component
+ n
<= 4);
1034 return (((1 << n
) - 1) << first_component
);
1037 static inline struct brw_reg
1038 negate(struct brw_reg reg
)
1044 static inline struct brw_reg
1045 brw_abs(struct brw_reg reg
)
1052 /************************************************************************/
1054 static inline struct brw_reg
1055 brw_vec4_indirect(unsigned subnr
, int offset
)
1057 struct brw_reg reg
= brw_vec4_grf(0, 0);
1059 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1060 reg
.indirect_offset
= offset
;
1064 static inline struct brw_reg
1065 brw_vec1_indirect(unsigned subnr
, int offset
)
1067 struct brw_reg reg
= brw_vec1_grf(0, 0);
1069 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1070 reg
.indirect_offset
= offset
;
1074 static inline struct brw_reg
1075 brw_VxH_indirect(unsigned subnr
, int offset
)
1077 struct brw_reg reg
= brw_vec1_grf(0, 0);
1078 reg
.vstride
= BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
;
1080 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1081 reg
.indirect_offset
= offset
;
1085 static inline struct brw_reg
1086 deref_4f(struct brw_indirect ptr
, int offset
)
1088 return brw_vec4_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1091 static inline struct brw_reg
1092 deref_1f(struct brw_indirect ptr
, int offset
)
1094 return brw_vec1_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1097 static inline struct brw_reg
1098 deref_4b(struct brw_indirect ptr
, int offset
)
1100 return retype(deref_4f(ptr
, offset
), BRW_REGISTER_TYPE_B
);
1103 static inline struct brw_reg
1104 deref_1uw(struct brw_indirect ptr
, int offset
)
1106 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UW
);
1109 static inline struct brw_reg
1110 deref_1d(struct brw_indirect ptr
, int offset
)
1112 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_D
);
1115 static inline struct brw_reg
1116 deref_1ud(struct brw_indirect ptr
, int offset
)
1118 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UD
);
1121 static inline struct brw_reg
1122 get_addr_reg(struct brw_indirect ptr
)
1124 return brw_address_reg(ptr
.addr_subnr
);
1127 static inline struct brw_indirect
1128 brw_indirect_offset(struct brw_indirect ptr
, int offset
)
1130 ptr
.addr_offset
+= offset
;
1134 static inline struct brw_indirect
1135 brw_indirect(unsigned addr_subnr
, int offset
)
1137 struct brw_indirect ptr
;
1138 ptr
.addr_subnr
= addr_subnr
;
1139 ptr
.addr_offset
= offset
;
1145 region_matches(struct brw_reg reg
, enum brw_vertical_stride v
,
1146 enum brw_width w
, enum brw_horizontal_stride h
)
1148 return reg
.vstride
== v
&&
1153 #define has_scalar_region(reg) \
1154 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1155 BRW_HORIZONTAL_STRIDE_0)
1157 /* brw_packed_float.c */
1158 int brw_float_to_vf(float f
);
1159 float brw_vf_to_float(unsigned char vf
);