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"
50 #include "brw_reg_type.h"
56 struct gen_device_info
;
58 /** Number of general purpose registers (VS, WM, etc) */
59 #define BRW_MAX_GRF 128
62 * First GRF used for the MRF hack.
64 * On gen7, MRFs are no longer used, and contiguous GRFs are used instead. We
65 * haven't converted our compiler to be aware of this, so it asks for MRFs and
66 * brw_eu_emit.c quietly converts them to be accesses of the top GRFs. The
67 * register allocators have to be careful of this to avoid corrupting the "MRF"s
68 * with actual GRF allocations.
70 #define GEN7_MRF_HACK_START 112
72 /** Number of message register file registers */
73 #define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
75 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
76 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
78 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
79 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
80 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
81 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
82 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
83 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
84 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
85 #define BRW_SWIZZLE_YXYX BRW_SWIZZLE4(1,0,1,0)
86 #define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
87 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
88 #define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
89 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
90 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
91 #define BRW_SWIZZLE_WZWZ BRW_SWIZZLE4(3,2,3,2)
92 #define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
93 #define BRW_SWIZZLE_XXZZ BRW_SWIZZLE4(0,0,2,2)
94 #define BRW_SWIZZLE_YYWW BRW_SWIZZLE4(1,1,3,3)
95 #define BRW_SWIZZLE_YXWZ BRW_SWIZZLE4(1,0,3,2)
97 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
98 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
101 brw_is_single_value_swizzle(unsigned swiz
)
103 return (swiz
== BRW_SWIZZLE_XXXX
||
104 swiz
== BRW_SWIZZLE_YYYY
||
105 swiz
== BRW_SWIZZLE_ZZZZ
||
106 swiz
== BRW_SWIZZLE_WWWW
);
110 * Compute the swizzle obtained from the application of \p swz0 on the result
111 * of \p swz1. The argument ordering is expected to match function
114 static inline unsigned
115 brw_compose_swizzle(unsigned swz0
, unsigned swz1
)
118 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 0)),
119 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 1)),
120 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 2)),
121 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 3)));
125 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
128 static inline unsigned
129 brw_apply_swizzle_to_mask(unsigned swz
, unsigned mask
)
133 for (unsigned i
= 0; i
< 4; i
++) {
134 if (mask
& (1 << BRW_GET_SWZ(swz
, i
)))
142 * Return the result of applying the inverse of swizzle \p swz to shuffle the
143 * bits of \p mask (AKA preimage). Useful to find out which components are
144 * read from a swizzled source given the instruction writemask.
146 static inline unsigned
147 brw_apply_inv_swizzle_to_mask(unsigned swz
, unsigned mask
)
151 for (unsigned i
= 0; i
< 4; i
++) {
153 result
|= 1 << BRW_GET_SWZ(swz
, i
);
160 * Construct an identity swizzle for the set of enabled channels given by \p
161 * mask. The result will only reference channels enabled in the provided \p
162 * mask, assuming that \p mask is non-zero. The constructed swizzle will
163 * satisfy the property that for any instruction OP and any mask:
165 * brw_OP(p, brw_writemask(dst, mask),
166 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
168 * will be equivalent to the same instruction without swizzle:
170 * brw_OP(p, brw_writemask(dst, mask), src);
172 static inline unsigned
173 brw_swizzle_for_mask(unsigned mask
)
175 unsigned last
= (mask
? ffs(mask
) - 1 : 0);
178 for (unsigned i
= 0; i
< 4; i
++)
179 last
= swz
[i
] = (mask
& (1 << i
) ? i
: last
);
181 return BRW_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
185 * Construct an identity swizzle for the first \p n components of a vector.
186 * When only a subset of channels of a vec4 are used we don't want to
187 * reference the other channels, as that will tell optimization passes that
188 * those other channels are used.
190 static inline unsigned
191 brw_swizzle_for_size(unsigned n
)
193 return brw_swizzle_for_mask((1 << n
) - 1);
197 * Converse of brw_swizzle_for_mask(). Returns the mask of components
198 * accessed by the specified swizzle \p swz.
200 static inline unsigned
201 brw_mask_for_swizzle(unsigned swz
)
203 return brw_apply_inv_swizzle_to_mask(swz
, ~0);
206 uint32_t brw_swizzle_immediate(enum brw_reg_type type
, uint32_t x
, unsigned swz
);
208 #define REG_SIZE (8*4)
210 /* These aren't hardware structs, just something useful for us to pass around:
212 * Align1 operation has a lot of control over input ranges. Used in
213 * WM programs to implement shaders decomposed into "channel serial"
214 * or "structure of array" form:
219 enum brw_reg_type type
:4;
220 enum brw_reg_file file
:3; /* :2 hardware format */
221 unsigned negate
:1; /* source only */
222 unsigned abs
:1; /* source only */
223 unsigned address_mode
:1; /* relative addressing, hopefully! */
225 unsigned subnr
:5; /* :1 in align16 */
233 unsigned swizzle
:8; /* src only, align16 only */
234 unsigned writemask
:4; /* dest only, align16 only */
235 int indirect_offset
:10; /* relative addressing offset */
236 unsigned vstride
:4; /* source only */
237 unsigned width
:3; /* src only, align1 only */
238 unsigned hstride
:2; /* align1 only */
252 brw_regs_equal(const struct brw_reg
*a
, const struct brw_reg
*b
)
254 const bool df
= a
->type
== BRW_REGISTER_TYPE_DF
&& a
->file
== IMM
;
255 return a
->bits
== b
->bits
&& (df
? a
->u64
== b
->u64
: a
->ud
== b
->ud
);
258 struct brw_indirect
{
259 unsigned addr_subnr
:4;
265 static inline unsigned
266 type_sz(unsigned type
)
269 case BRW_REGISTER_TYPE_UQ
:
270 case BRW_REGISTER_TYPE_Q
:
271 case BRW_REGISTER_TYPE_DF
:
273 case BRW_REGISTER_TYPE_UD
:
274 case BRW_REGISTER_TYPE_D
:
275 case BRW_REGISTER_TYPE_F
:
276 case BRW_REGISTER_TYPE_VF
:
278 case BRW_REGISTER_TYPE_UW
:
279 case BRW_REGISTER_TYPE_W
:
280 case BRW_REGISTER_TYPE_UV
:
281 case BRW_REGISTER_TYPE_V
:
282 case BRW_REGISTER_TYPE_HF
:
284 case BRW_REGISTER_TYPE_UB
:
285 case BRW_REGISTER_TYPE_B
:
288 unreachable("not reached");
292 static inline enum brw_reg_type
293 get_exec_type(const enum brw_reg_type type
)
296 case BRW_REGISTER_TYPE_B
:
297 case BRW_REGISTER_TYPE_V
:
298 return BRW_REGISTER_TYPE_W
;
299 case BRW_REGISTER_TYPE_UB
:
300 case BRW_REGISTER_TYPE_UV
:
301 return BRW_REGISTER_TYPE_UW
;
302 case BRW_REGISTER_TYPE_VF
:
303 return BRW_REGISTER_TYPE_F
;
310 * Return an integer type of the requested size and signedness.
312 static inline enum brw_reg_type
313 brw_int_type(unsigned sz
, bool is_signed
)
317 return (is_signed
? BRW_REGISTER_TYPE_B
: BRW_REGISTER_TYPE_UB
);
319 return (is_signed
? BRW_REGISTER_TYPE_W
: BRW_REGISTER_TYPE_UW
);
321 return (is_signed
? BRW_REGISTER_TYPE_D
: BRW_REGISTER_TYPE_UD
);
323 return (is_signed
? BRW_REGISTER_TYPE_Q
: BRW_REGISTER_TYPE_UQ
);
325 unreachable("Not reached.");
330 * Construct a brw_reg.
331 * \param file one of the BRW_x_REGISTER_FILE values
332 * \param nr register number/index
333 * \param subnr register sub number
334 * \param negate register negate modifier
335 * \param abs register abs modifier
336 * \param type one of BRW_REGISTER_TYPE_x
337 * \param vstride one of BRW_VERTICAL_STRIDE_x
338 * \param width one of BRW_WIDTH_x
339 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
340 * \param swizzle one of BRW_SWIZZLE_x
341 * \param writemask WRITEMASK_X/Y/Z/W bitfield
343 static inline struct brw_reg
344 brw_reg(enum brw_reg_file file
,
349 enum brw_reg_type type
,
357 if (file
== BRW_GENERAL_REGISTER_FILE
)
358 assert(nr
< BRW_MAX_GRF
);
359 else if (file
== BRW_ARCHITECTURE_REGISTER_FILE
)
360 assert(nr
<= BRW_ARF_TIMESTAMP
);
361 /* Asserting on the MRF register number requires to know the hardware gen
362 * (gen6 has 24 MRF registers), which we don't know here, so we assert
363 * for that in the generators and in brw_eu_emit.c
370 reg
.address_mode
= BRW_ADDRESS_DIRECT
;
372 reg
.subnr
= subnr
* type_sz(type
);
375 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
376 * set swizzle and writemask to W, as the lower bits of subnr will
377 * be lost when converted to align16. This is probably too much to
378 * keep track of as you'd want it adjusted by suboffset(), etc.
379 * Perhaps fix up when converting to align16?
381 reg
.swizzle
= swizzle
;
382 reg
.writemask
= writemask
;
383 reg
.indirect_offset
= 0;
384 reg
.vstride
= vstride
;
386 reg
.hstride
= hstride
;
391 /** Construct float[16] register */
392 static inline struct brw_reg
393 brw_vec16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
401 BRW_VERTICAL_STRIDE_16
,
403 BRW_HORIZONTAL_STRIDE_1
,
408 /** Construct float[8] register */
409 static inline struct brw_reg
410 brw_vec8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
418 BRW_VERTICAL_STRIDE_8
,
420 BRW_HORIZONTAL_STRIDE_1
,
425 /** Construct float[4] register */
426 static inline struct brw_reg
427 brw_vec4_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
435 BRW_VERTICAL_STRIDE_4
,
437 BRW_HORIZONTAL_STRIDE_1
,
442 /** Construct float[2] register */
443 static inline struct brw_reg
444 brw_vec2_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
452 BRW_VERTICAL_STRIDE_2
,
454 BRW_HORIZONTAL_STRIDE_1
,
459 /** Construct float[1] register */
460 static inline struct brw_reg
461 brw_vec1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
469 BRW_VERTICAL_STRIDE_0
,
471 BRW_HORIZONTAL_STRIDE_0
,
476 static inline struct brw_reg
477 brw_vecn_reg(unsigned width
, enum brw_reg_file file
,
478 unsigned nr
, unsigned subnr
)
482 return brw_vec1_reg(file
, nr
, subnr
);
484 return brw_vec2_reg(file
, nr
, subnr
);
486 return brw_vec4_reg(file
, nr
, subnr
);
488 return brw_vec8_reg(file
, nr
, subnr
);
490 return brw_vec16_reg(file
, nr
, subnr
);
492 unreachable("Invalid register width");
496 static inline struct brw_reg
497 retype(struct brw_reg reg
, enum brw_reg_type type
)
503 static inline struct brw_reg
504 firsthalf(struct brw_reg reg
)
509 static inline struct brw_reg
510 sechalf(struct brw_reg reg
)
517 static inline struct brw_reg
518 offset(struct brw_reg reg
, unsigned delta
)
525 static inline struct brw_reg
526 byte_offset(struct brw_reg reg
, unsigned bytes
)
528 unsigned newoffset
= reg
.nr
* REG_SIZE
+ reg
.subnr
+ bytes
;
529 reg
.nr
= newoffset
/ REG_SIZE
;
530 reg
.subnr
= newoffset
% REG_SIZE
;
534 static inline struct brw_reg
535 suboffset(struct brw_reg reg
, unsigned delta
)
537 return byte_offset(reg
, delta
* type_sz(reg
.type
));
540 /** Construct unsigned word[16] register */
541 static inline struct brw_reg
542 brw_uw16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
544 return suboffset(retype(brw_vec16_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
547 /** Construct unsigned word[8] register */
548 static inline struct brw_reg
549 brw_uw8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
551 return suboffset(retype(brw_vec8_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
554 /** Construct unsigned word[1] register */
555 static inline struct brw_reg
556 brw_uw1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
558 return suboffset(retype(brw_vec1_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
561 static inline struct brw_reg
562 brw_ud1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
564 return retype(brw_vec1_reg(file
, nr
, subnr
), BRW_REGISTER_TYPE_UD
);
567 static inline struct brw_reg
568 brw_imm_reg(enum brw_reg_type type
)
570 return brw_reg(BRW_IMMEDIATE_VALUE
,
576 BRW_VERTICAL_STRIDE_0
,
578 BRW_HORIZONTAL_STRIDE_0
,
583 /** Construct float immediate register */
584 static inline struct brw_reg
585 brw_imm_df(double df
)
587 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_DF
);
592 static inline struct brw_reg
595 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_F
);
600 /** Construct integer immediate register */
601 static inline struct brw_reg
604 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_D
);
609 /** Construct uint immediate register */
610 static inline struct brw_reg
611 brw_imm_ud(unsigned ud
)
613 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UD
);
618 /** Construct ushort immediate register */
619 static inline struct brw_reg
620 brw_imm_uw(uint16_t uw
)
622 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UW
);
623 imm
.ud
= uw
| (uw
<< 16);
627 /** Construct short immediate register */
628 static inline struct brw_reg
631 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_W
);
632 imm
.d
= w
| (w
<< 16);
636 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
637 * numbers alias with _V and _VF below:
640 /** Construct vector of eight signed half-byte values */
641 static inline struct brw_reg
642 brw_imm_v(unsigned v
)
644 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_V
);
649 /** Construct vector of eight unsigned half-byte values */
650 static inline struct brw_reg
651 brw_imm_uv(unsigned uv
)
653 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UV
);
658 /** Construct vector of four 8-bit float values */
659 static inline struct brw_reg
660 brw_imm_vf(unsigned v
)
662 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
667 static inline struct brw_reg
668 brw_imm_vf4(unsigned v0
, unsigned v1
, unsigned v2
, unsigned v3
)
670 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
671 imm
.vstride
= BRW_VERTICAL_STRIDE_0
;
672 imm
.width
= BRW_WIDTH_4
;
673 imm
.hstride
= BRW_HORIZONTAL_STRIDE_1
;
674 imm
.ud
= ((v0
<< 0) | (v1
<< 8) | (v2
<< 16) | (v3
<< 24));
679 static inline struct brw_reg
680 brw_address(struct brw_reg reg
)
682 return brw_imm_uw(reg
.nr
* REG_SIZE
+ reg
.subnr
);
685 /** Construct float[1] general-purpose register */
686 static inline struct brw_reg
687 brw_vec1_grf(unsigned nr
, unsigned subnr
)
689 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
692 /** Construct float[2] general-purpose register */
693 static inline struct brw_reg
694 brw_vec2_grf(unsigned nr
, unsigned subnr
)
696 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
699 /** Construct float[4] general-purpose register */
700 static inline struct brw_reg
701 brw_vec4_grf(unsigned nr
, unsigned subnr
)
703 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
706 /** Construct float[8] general-purpose register */
707 static inline struct brw_reg
708 brw_vec8_grf(unsigned nr
, unsigned subnr
)
710 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
713 /** Construct float[16] general-purpose register */
714 static inline struct brw_reg
715 brw_vec16_grf(unsigned nr
, unsigned subnr
)
717 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
720 static inline struct brw_reg
721 brw_vecn_grf(unsigned width
, unsigned nr
, unsigned subnr
)
723 return brw_vecn_reg(width
, BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
727 static inline struct brw_reg
728 brw_uw8_grf(unsigned nr
, unsigned subnr
)
730 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
733 static inline struct brw_reg
734 brw_uw16_grf(unsigned nr
, unsigned subnr
)
736 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
740 /** Construct null register (usually used for setting condition codes) */
741 static inline struct brw_reg
744 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
747 static inline struct brw_reg
748 brw_null_vec(unsigned width
)
750 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
753 static inline struct brw_reg
754 brw_address_reg(unsigned subnr
)
756 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_ADDRESS
, subnr
);
759 /* If/else instructions break in align16 mode if writemask & swizzle
760 * aren't xyzw. This goes against the convention for other scalar
763 static inline struct brw_reg
766 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
771 BRW_REGISTER_TYPE_UD
,
772 BRW_VERTICAL_STRIDE_4
, /* ? */
774 BRW_HORIZONTAL_STRIDE_0
,
775 BRW_SWIZZLE_XYZW
, /* NOTE! */
776 WRITEMASK_XYZW
); /* NOTE! */
779 static inline struct brw_reg
780 brw_notification_reg(void)
782 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
783 BRW_ARF_NOTIFICATION_COUNT
,
787 BRW_REGISTER_TYPE_UD
,
788 BRW_VERTICAL_STRIDE_0
,
790 BRW_HORIZONTAL_STRIDE_0
,
795 static inline struct brw_reg
796 brw_sr0_reg(unsigned subnr
)
798 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_STATE
, subnr
);
801 static inline struct brw_reg
802 brw_acc_reg(unsigned width
)
804 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
,
805 BRW_ARF_ACCUMULATOR
, 0);
808 static inline struct brw_reg
809 brw_flag_reg(int reg
, int subreg
)
811 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
812 BRW_ARF_FLAG
+ reg
, subreg
);
816 * Return the mask register present in Gen4-5, or the related register present
817 * in Gen7.5 and later hardware referred to as "channel enable" register in
820 static inline struct brw_reg
821 brw_mask_reg(unsigned subnr
)
823 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_MASK
, subnr
);
826 static inline struct brw_reg
829 return brw_sr0_reg(3);
832 static inline struct brw_reg
835 return brw_sr0_reg(2);
838 static inline struct brw_reg
839 brw_message_reg(unsigned nr
)
841 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, nr
, 0);
844 static inline struct brw_reg
845 brw_uvec_mrf(unsigned width
, unsigned nr
, unsigned subnr
)
847 return retype(brw_vecn_reg(width
, BRW_MESSAGE_REGISTER_FILE
, nr
, subnr
),
848 BRW_REGISTER_TYPE_UD
);
851 /* This is almost always called with a numeric constant argument, so
852 * make things easy to evaluate at compile time:
854 static inline unsigned cvt(unsigned val
)
868 static inline struct brw_reg
869 stride(struct brw_reg reg
, unsigned vstride
, unsigned width
, unsigned hstride
)
871 reg
.vstride
= cvt(vstride
);
872 reg
.width
= cvt(width
) - 1;
873 reg
.hstride
= cvt(hstride
);
878 * Multiply the vertical and horizontal stride of a register by the given
881 static inline struct brw_reg
882 spread(struct brw_reg reg
, unsigned s
)
885 assert(_mesa_is_pow_two(s
));
888 reg
.hstride
+= cvt(s
) - 1;
891 reg
.vstride
+= cvt(s
) - 1;
895 return stride(reg
, 0, 1, 0);
899 static inline struct brw_reg
900 vec16(struct brw_reg reg
)
902 return stride(reg
, 16,16,1);
905 static inline struct brw_reg
906 vec8(struct brw_reg reg
)
908 return stride(reg
, 8,8,1);
911 static inline struct brw_reg
912 vec4(struct brw_reg reg
)
914 return stride(reg
, 4,4,1);
917 static inline struct brw_reg
918 vec2(struct brw_reg reg
)
920 return stride(reg
, 2,2,1);
923 static inline struct brw_reg
924 vec1(struct brw_reg reg
)
926 return stride(reg
, 0,1,0);
930 static inline struct brw_reg
931 get_element(struct brw_reg reg
, unsigned elt
)
933 return vec1(suboffset(reg
, elt
));
936 static inline struct brw_reg
937 get_element_ud(struct brw_reg reg
, unsigned elt
)
939 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_UD
), elt
));
942 static inline struct brw_reg
943 get_element_d(struct brw_reg reg
, unsigned elt
)
945 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_D
), elt
));
948 static inline struct brw_reg
949 brw_swizzle(struct brw_reg reg
, unsigned swz
)
951 if (reg
.file
== BRW_IMMEDIATE_VALUE
)
952 reg
.ud
= brw_swizzle_immediate(reg
.type
, reg
.ud
, swz
);
954 reg
.swizzle
= brw_compose_swizzle(swz
, reg
.swizzle
);
959 static inline struct brw_reg
960 brw_writemask(struct brw_reg reg
, unsigned mask
)
962 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
963 reg
.writemask
&= mask
;
967 static inline struct brw_reg
968 brw_set_writemask(struct brw_reg reg
, unsigned mask
)
970 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
971 reg
.writemask
= mask
;
975 static inline unsigned
976 brw_writemask_for_size(unsigned n
)
981 static inline unsigned
982 brw_writemask_for_component_packing(unsigned n
, unsigned first_component
)
984 assert(first_component
+ n
<= 4);
985 return (((1 << n
) - 1) << first_component
);
988 static inline struct brw_reg
989 negate(struct brw_reg reg
)
995 static inline struct brw_reg
996 brw_abs(struct brw_reg reg
)
1003 /************************************************************************/
1005 static inline struct brw_reg
1006 brw_vec4_indirect(unsigned subnr
, int offset
)
1008 struct brw_reg reg
= brw_vec4_grf(0, 0);
1010 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1011 reg
.indirect_offset
= offset
;
1015 static inline struct brw_reg
1016 brw_vec1_indirect(unsigned subnr
, int offset
)
1018 struct brw_reg reg
= brw_vec1_grf(0, 0);
1020 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1021 reg
.indirect_offset
= offset
;
1025 static inline struct brw_reg
1026 brw_VxH_indirect(unsigned subnr
, int offset
)
1028 struct brw_reg reg
= brw_vec1_grf(0, 0);
1029 reg
.vstride
= BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
;
1031 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1032 reg
.indirect_offset
= offset
;
1036 static inline struct brw_reg
1037 deref_4f(struct brw_indirect ptr
, int offset
)
1039 return brw_vec4_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1042 static inline struct brw_reg
1043 deref_1f(struct brw_indirect ptr
, int offset
)
1045 return brw_vec1_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1048 static inline struct brw_reg
1049 deref_4b(struct brw_indirect ptr
, int offset
)
1051 return retype(deref_4f(ptr
, offset
), BRW_REGISTER_TYPE_B
);
1054 static inline struct brw_reg
1055 deref_1uw(struct brw_indirect ptr
, int offset
)
1057 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UW
);
1060 static inline struct brw_reg
1061 deref_1d(struct brw_indirect ptr
, int offset
)
1063 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_D
);
1066 static inline struct brw_reg
1067 deref_1ud(struct brw_indirect ptr
, int offset
)
1069 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UD
);
1072 static inline struct brw_reg
1073 get_addr_reg(struct brw_indirect ptr
)
1075 return brw_address_reg(ptr
.addr_subnr
);
1078 static inline struct brw_indirect
1079 brw_indirect_offset(struct brw_indirect ptr
, int offset
)
1081 ptr
.addr_offset
+= offset
;
1085 static inline struct brw_indirect
1086 brw_indirect(unsigned addr_subnr
, int offset
)
1088 struct brw_indirect ptr
;
1089 ptr
.addr_subnr
= addr_subnr
;
1090 ptr
.addr_offset
= offset
;
1096 region_matches(struct brw_reg reg
, enum brw_vertical_stride v
,
1097 enum brw_width w
, enum brw_horizontal_stride h
)
1099 return reg
.vstride
== v
&&
1104 #define has_scalar_region(reg) \
1105 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1106 BRW_HORIZONTAL_STRIDE_0)
1108 /* brw_packed_float.c */
1109 int brw_float_to_vf(float f
);
1110 float brw_vf_to_float(unsigned char vf
);