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_defines.h"
55 struct brw_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_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)
91 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
92 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
95 brw_is_single_value_swizzle(unsigned swiz
)
97 return (swiz
== BRW_SWIZZLE_XXXX
||
98 swiz
== BRW_SWIZZLE_YYYY
||
99 swiz
== BRW_SWIZZLE_ZZZZ
||
100 swiz
== BRW_SWIZZLE_WWWW
);
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
108 static inline unsigned
109 brw_compose_swizzle(unsigned swz0
, unsigned swz1
)
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)));
119 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
122 static inline unsigned
123 brw_apply_swizzle_to_mask(unsigned swz
, unsigned mask
)
127 for (unsigned i
= 0; i
< 4; i
++) {
128 if (mask
& (1 << BRW_GET_SWZ(swz
, i
)))
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.
140 static inline unsigned
141 brw_apply_inv_swizzle_to_mask(unsigned swz
, unsigned mask
)
145 for (unsigned i
= 0; i
< 4; i
++) {
147 result
|= 1 << BRW_GET_SWZ(swz
, i
);
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:
159 * brw_OP(p, brw_writemask(dst, mask),
160 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
162 * will be equivalent to the same instruction without swizzle:
164 * brw_OP(p, brw_writemask(dst, mask), src);
166 static inline unsigned
167 brw_swizzle_for_mask(unsigned mask
)
169 unsigned last
= (mask
? ffs(mask
) - 1 : 0);
172 for (unsigned i
= 0; i
< 4; i
++)
173 last
= swz
[i
] = (mask
& (1 << i
) ? i
: last
);
175 return BRW_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
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.
184 static inline unsigned
185 brw_swizzle_for_size(unsigned n
)
187 return brw_swizzle_for_mask((1 << n
) - 1);
191 * Converse of brw_swizzle_for_mask(). Returns the mask of components
192 * accessed by the specified swizzle \p swz.
194 static inline unsigned
195 brw_mask_for_swizzle(unsigned swz
)
197 return brw_apply_inv_swizzle_to_mask(swz
, ~0);
200 enum PACKED brw_reg_type
{
201 BRW_REGISTER_TYPE_UD
= 0,
203 BRW_REGISTER_TYPE_UW
,
207 /** Non-immediates only: @{ */
208 BRW_REGISTER_TYPE_UB
,
212 /** Immediates only: @{ */
213 BRW_REGISTER_TYPE_UV
, /* Gen6+ */
215 BRW_REGISTER_TYPE_VF
,
218 BRW_REGISTER_TYPE_DF
, /* Gen7+ (no immediates until Gen8+) */
221 BRW_REGISTER_TYPE_HF
,
222 BRW_REGISTER_TYPE_UQ
,
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
);
231 #define REG_SIZE (8*4)
233 /* These aren't hardware structs, just something useful for us to pass around:
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:
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! */
248 unsigned subnr
:5; /* :1 in align16 */
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 */
274 brw_regs_equal(const struct brw_reg
*a
, const struct brw_reg
*b
)
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
);
280 struct brw_indirect
{
281 unsigned addr_subnr
:4;
287 static inline unsigned
288 type_sz(unsigned type
)
291 case BRW_REGISTER_TYPE_UQ
:
292 case BRW_REGISTER_TYPE_Q
:
293 case BRW_REGISTER_TYPE_DF
:
295 case BRW_REGISTER_TYPE_UD
:
296 case BRW_REGISTER_TYPE_D
:
297 case BRW_REGISTER_TYPE_F
:
298 case BRW_REGISTER_TYPE_VF
:
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
:
306 case BRW_REGISTER_TYPE_UB
:
307 case BRW_REGISTER_TYPE_B
:
310 unreachable("not reached");
315 * Return an integer type of the requested size and signedness.
317 static inline enum brw_reg_type
318 brw_int_type(unsigned sz
, bool is_signed
)
322 return (is_signed
? BRW_REGISTER_TYPE_B
: BRW_REGISTER_TYPE_UB
);
324 return (is_signed
? BRW_REGISTER_TYPE_W
: BRW_REGISTER_TYPE_UW
);
326 return (is_signed
? BRW_REGISTER_TYPE_D
: BRW_REGISTER_TYPE_UD
);
328 return (is_signed
? BRW_REGISTER_TYPE_Q
: BRW_REGISTER_TYPE_UQ
);
330 unreachable("Not reached.");
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
348 static inline struct brw_reg
349 brw_reg(enum brw_reg_file file
,
354 enum brw_reg_type type
,
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
375 reg
.address_mode
= BRW_ADDRESS_DIRECT
;
377 reg
.subnr
= subnr
* type_sz(type
);
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?
386 reg
.swizzle
= swizzle
;
387 reg
.writemask
= writemask
;
388 reg
.indirect_offset
= 0;
389 reg
.vstride
= vstride
;
391 reg
.hstride
= hstride
;
396 /** Construct float[16] register */
397 static inline struct brw_reg
398 brw_vec16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
406 BRW_VERTICAL_STRIDE_16
,
408 BRW_HORIZONTAL_STRIDE_1
,
413 /** Construct float[8] register */
414 static inline struct brw_reg
415 brw_vec8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
423 BRW_VERTICAL_STRIDE_8
,
425 BRW_HORIZONTAL_STRIDE_1
,
430 /** Construct float[4] register */
431 static inline struct brw_reg
432 brw_vec4_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
440 BRW_VERTICAL_STRIDE_4
,
442 BRW_HORIZONTAL_STRIDE_1
,
447 /** Construct float[2] register */
448 static inline struct brw_reg
449 brw_vec2_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
457 BRW_VERTICAL_STRIDE_2
,
459 BRW_HORIZONTAL_STRIDE_1
,
464 /** Construct float[1] register */
465 static inline struct brw_reg
466 brw_vec1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
474 BRW_VERTICAL_STRIDE_0
,
476 BRW_HORIZONTAL_STRIDE_0
,
481 static inline struct brw_reg
482 brw_vecn_reg(unsigned width
, enum brw_reg_file file
,
483 unsigned nr
, unsigned subnr
)
487 return brw_vec1_reg(file
, nr
, subnr
);
489 return brw_vec2_reg(file
, nr
, subnr
);
491 return brw_vec4_reg(file
, nr
, subnr
);
493 return brw_vec8_reg(file
, nr
, subnr
);
495 return brw_vec16_reg(file
, nr
, subnr
);
497 unreachable("Invalid register width");
501 static inline struct brw_reg
502 retype(struct brw_reg reg
, enum brw_reg_type type
)
508 static inline struct brw_reg
509 firsthalf(struct brw_reg reg
)
514 static inline struct brw_reg
515 sechalf(struct brw_reg reg
)
522 static inline struct brw_reg
523 suboffset(struct brw_reg reg
, unsigned delta
)
525 reg
.subnr
+= delta
* type_sz(reg
.type
);
530 static inline struct brw_reg
531 offset(struct brw_reg reg
, unsigned delta
)
538 static inline struct brw_reg
539 byte_offset(struct brw_reg reg
, unsigned bytes
)
541 unsigned newoffset
= reg
.nr
* REG_SIZE
+ reg
.subnr
+ bytes
;
542 reg
.nr
= newoffset
/ REG_SIZE
;
543 reg
.subnr
= newoffset
% REG_SIZE
;
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
)
552 return suboffset(retype(brw_vec16_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
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
)
559 return suboffset(retype(brw_vec8_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
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
)
566 return suboffset(retype(brw_vec1_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
569 static inline struct brw_reg
570 brw_imm_reg(enum brw_reg_type type
)
572 return brw_reg(BRW_IMMEDIATE_VALUE
,
578 BRW_VERTICAL_STRIDE_0
,
580 BRW_HORIZONTAL_STRIDE_0
,
585 /** Construct float immediate register */
586 static inline struct brw_reg
587 brw_imm_df(double df
)
589 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_DF
);
594 static inline struct brw_reg
597 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_F
);
602 /** Construct integer immediate register */
603 static inline struct brw_reg
606 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_D
);
611 /** Construct uint immediate register */
612 static inline struct brw_reg
613 brw_imm_ud(unsigned ud
)
615 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UD
);
620 /** Construct ushort immediate register */
621 static inline struct brw_reg
622 brw_imm_uw(uint16_t uw
)
624 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UW
);
625 imm
.ud
= uw
| (uw
<< 16);
629 /** Construct short immediate register */
630 static inline struct brw_reg
633 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_W
);
634 imm
.d
= w
| (w
<< 16);
638 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
639 * numbers alias with _V and _VF below:
642 /** Construct vector of eight signed half-byte values */
643 static inline struct brw_reg
644 brw_imm_v(unsigned v
)
646 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_V
);
651 /** Construct vector of eight unsigned half-byte values */
652 static inline struct brw_reg
653 brw_imm_uv(unsigned uv
)
655 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UV
);
660 /** Construct vector of four 8-bit float values */
661 static inline struct brw_reg
662 brw_imm_vf(unsigned v
)
664 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
669 static inline struct brw_reg
670 brw_imm_vf4(unsigned v0
, unsigned v1
, unsigned v2
, unsigned v3
)
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));
681 static inline struct brw_reg
682 brw_address(struct brw_reg reg
)
684 return brw_imm_uw(reg
.nr
* REG_SIZE
+ reg
.subnr
);
687 /** Construct float[1] general-purpose register */
688 static inline struct brw_reg
689 brw_vec1_grf(unsigned nr
, unsigned subnr
)
691 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
694 /** Construct float[2] general-purpose register */
695 static inline struct brw_reg
696 brw_vec2_grf(unsigned nr
, unsigned subnr
)
698 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
701 /** Construct float[4] general-purpose register */
702 static inline struct brw_reg
703 brw_vec4_grf(unsigned nr
, unsigned subnr
)
705 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
708 /** Construct float[8] general-purpose register */
709 static inline struct brw_reg
710 brw_vec8_grf(unsigned nr
, unsigned subnr
)
712 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
715 /** Construct float[16] general-purpose register */
716 static inline struct brw_reg
717 brw_vec16_grf(unsigned nr
, unsigned subnr
)
719 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
723 static inline struct brw_reg
724 brw_uw8_grf(unsigned nr
, unsigned subnr
)
726 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
729 static inline struct brw_reg
730 brw_uw16_grf(unsigned nr
, unsigned subnr
)
732 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
736 /** Construct null register (usually used for setting condition codes) */
737 static inline struct brw_reg
740 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
743 static inline struct brw_reg
744 brw_null_vec(unsigned width
)
746 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
749 static inline struct brw_reg
750 brw_address_reg(unsigned subnr
)
752 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_ADDRESS
, subnr
);
755 /* If/else instructions break in align16 mode if writemask & swizzle
756 * aren't xyzw. This goes against the convention for other scalar
759 static inline struct brw_reg
762 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
767 BRW_REGISTER_TYPE_UD
,
768 BRW_VERTICAL_STRIDE_4
, /* ? */
770 BRW_HORIZONTAL_STRIDE_0
,
771 BRW_SWIZZLE_XYZW
, /* NOTE! */
772 WRITEMASK_XYZW
); /* NOTE! */
775 static inline struct brw_reg
776 brw_notification_reg(void)
778 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
779 BRW_ARF_NOTIFICATION_COUNT
,
783 BRW_REGISTER_TYPE_UD
,
784 BRW_VERTICAL_STRIDE_0
,
786 BRW_HORIZONTAL_STRIDE_0
,
791 static inline struct brw_reg
794 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
799 BRW_REGISTER_TYPE_UD
,
800 BRW_VERTICAL_STRIDE_8
,
802 BRW_HORIZONTAL_STRIDE_1
,
807 static inline struct brw_reg
808 brw_acc_reg(unsigned width
)
810 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
,
811 BRW_ARF_ACCUMULATOR
, 0);
814 static inline struct brw_reg
815 brw_flag_reg(int reg
, int subreg
)
817 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
818 BRW_ARF_FLAG
+ reg
, subreg
);
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
826 static inline struct brw_reg
827 brw_mask_reg(unsigned subnr
)
829 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_MASK
, subnr
);
832 static inline struct brw_reg
833 brw_message_reg(unsigned nr
)
835 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, nr
, 0);
838 static inline struct brw_reg
839 brw_uvec_mrf(unsigned width
, unsigned nr
, unsigned subnr
)
841 return retype(brw_vecn_reg(width
, BRW_MESSAGE_REGISTER_FILE
, nr
, subnr
),
842 BRW_REGISTER_TYPE_UD
);
845 /* This is almost always called with a numeric constant argument, so
846 * make things easy to evaluate at compile time:
848 static inline unsigned cvt(unsigned val
)
862 static inline struct brw_reg
863 stride(struct brw_reg reg
, unsigned vstride
, unsigned width
, unsigned hstride
)
865 reg
.vstride
= cvt(vstride
);
866 reg
.width
= cvt(width
) - 1;
867 reg
.hstride
= cvt(hstride
);
872 * Multiply the vertical and horizontal stride of a register by the given
875 static inline struct brw_reg
876 spread(struct brw_reg reg
, unsigned s
)
879 assert(_mesa_is_pow_two(s
));
882 reg
.hstride
+= cvt(s
) - 1;
885 reg
.vstride
+= cvt(s
) - 1;
889 return stride(reg
, 0, 1, 0);
893 static inline struct brw_reg
894 vec16(struct brw_reg reg
)
896 return stride(reg
, 16,16,1);
899 static inline struct brw_reg
900 vec8(struct brw_reg reg
)
902 return stride(reg
, 8,8,1);
905 static inline struct brw_reg
906 vec4(struct brw_reg reg
)
908 return stride(reg
, 4,4,1);
911 static inline struct brw_reg
912 vec2(struct brw_reg reg
)
914 return stride(reg
, 2,2,1);
917 static inline struct brw_reg
918 vec1(struct brw_reg reg
)
920 return stride(reg
, 0,1,0);
924 static inline struct brw_reg
925 get_element(struct brw_reg reg
, unsigned elt
)
927 return vec1(suboffset(reg
, elt
));
930 static inline struct brw_reg
931 get_element_ud(struct brw_reg reg
, unsigned elt
)
933 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_UD
), elt
));
936 static inline struct brw_reg
937 get_element_d(struct brw_reg reg
, unsigned elt
)
939 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_D
), elt
));
942 static inline struct brw_reg
943 brw_swizzle(struct brw_reg reg
, unsigned swz
)
945 if (reg
.file
== BRW_IMMEDIATE_VALUE
)
946 reg
.ud
= brw_swizzle_immediate(reg
.type
, reg
.ud
, swz
);
948 reg
.swizzle
= brw_compose_swizzle(swz
, reg
.swizzle
);
953 static inline struct brw_reg
954 brw_writemask(struct brw_reg reg
, unsigned mask
)
956 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
957 reg
.writemask
&= mask
;
961 static inline struct brw_reg
962 brw_set_writemask(struct brw_reg reg
, unsigned mask
)
964 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
965 reg
.writemask
= mask
;
969 static inline unsigned
970 brw_writemask_for_size(unsigned n
)
975 static inline struct brw_reg
976 negate(struct brw_reg reg
)
982 static inline struct brw_reg
983 brw_abs(struct brw_reg reg
)
990 /************************************************************************/
992 static inline struct brw_reg
993 brw_vec4_indirect(unsigned subnr
, int offset
)
995 struct brw_reg reg
= brw_vec4_grf(0, 0);
997 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
998 reg
.indirect_offset
= offset
;
1002 static inline struct brw_reg
1003 brw_vec1_indirect(unsigned subnr
, int offset
)
1005 struct brw_reg reg
= brw_vec1_grf(0, 0);
1007 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1008 reg
.indirect_offset
= offset
;
1012 static inline struct brw_reg
1013 brw_VxH_indirect(unsigned subnr
, int offset
)
1015 struct brw_reg reg
= brw_vec1_grf(0, 0);
1016 reg
.vstride
= BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
;
1018 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1019 reg
.indirect_offset
= offset
;
1023 static inline struct brw_reg
1024 deref_4f(struct brw_indirect ptr
, int offset
)
1026 return brw_vec4_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1029 static inline struct brw_reg
1030 deref_1f(struct brw_indirect ptr
, int offset
)
1032 return brw_vec1_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1035 static inline struct brw_reg
1036 deref_4b(struct brw_indirect ptr
, int offset
)
1038 return retype(deref_4f(ptr
, offset
), BRW_REGISTER_TYPE_B
);
1041 static inline struct brw_reg
1042 deref_1uw(struct brw_indirect ptr
, int offset
)
1044 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UW
);
1047 static inline struct brw_reg
1048 deref_1d(struct brw_indirect ptr
, int offset
)
1050 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_D
);
1053 static inline struct brw_reg
1054 deref_1ud(struct brw_indirect ptr
, int offset
)
1056 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UD
);
1059 static inline struct brw_reg
1060 get_addr_reg(struct brw_indirect ptr
)
1062 return brw_address_reg(ptr
.addr_subnr
);
1065 static inline struct brw_indirect
1066 brw_indirect_offset(struct brw_indirect ptr
, int offset
)
1068 ptr
.addr_offset
+= offset
;
1072 static inline struct brw_indirect
1073 brw_indirect(unsigned addr_subnr
, int offset
)
1075 struct brw_indirect ptr
;
1076 ptr
.addr_subnr
= addr_subnr
;
1077 ptr
.addr_offset
= offset
;
1083 region_matches(struct brw_reg reg
, enum brw_vertical_stride v
,
1084 enum brw_width w
, enum brw_horizontal_stride h
)
1086 return reg
.vstride
== v
&&
1091 #define has_scalar_region(reg) \
1092 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1093 BRW_HORIZONTAL_STRIDE_0)
1095 /* brw_packed_float.c */
1096 int brw_float_to_vf(float f
);
1097 float brw_vf_to_float(unsigned char vf
);