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)
92 brw_is_single_value_swizzle(unsigned swiz
)
94 return (swiz
== BRW_SWIZZLE_XXXX
||
95 swiz
== BRW_SWIZZLE_YYYY
||
96 swiz
== BRW_SWIZZLE_ZZZZ
||
97 swiz
== BRW_SWIZZLE_WWWW
);
101 * Compute the swizzle obtained from the application of \p swz0 on the result
102 * of \p swz1. The argument ordering is expected to match function
105 static inline unsigned
106 brw_compose_swizzle(unsigned swz0
, unsigned swz1
)
109 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 0)),
110 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 1)),
111 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 2)),
112 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 3)));
116 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
119 static inline unsigned
120 brw_apply_swizzle_to_mask(unsigned swz
, unsigned mask
)
124 for (unsigned i
= 0; i
< 4; i
++) {
125 if (mask
& (1 << BRW_GET_SWZ(swz
, i
)))
133 * Return the result of applying the inverse of swizzle \p swz to shuffle the
134 * bits of \p mask (AKA preimage). Useful to find out which components are
135 * read from a swizzled source given the instruction writemask.
137 static inline unsigned
138 brw_apply_inv_swizzle_to_mask(unsigned swz
, unsigned mask
)
142 for (unsigned i
= 0; i
< 4; i
++) {
144 result
|= 1 << BRW_GET_SWZ(swz
, i
);
151 * Construct an identity swizzle for the set of enabled channels given by \p
152 * mask. The result will only reference channels enabled in the provided \p
153 * mask, assuming that \p mask is non-zero. The constructed swizzle will
154 * satisfy the property that for any instruction OP and any mask:
156 * brw_OP(p, brw_writemask(dst, mask),
157 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
159 * will be equivalent to the same instruction without swizzle:
161 * brw_OP(p, brw_writemask(dst, mask), src);
163 static inline unsigned
164 brw_swizzle_for_mask(unsigned mask
)
166 unsigned last
= (mask
? ffs(mask
) - 1 : 0);
169 for (unsigned i
= 0; i
< 4; i
++)
170 last
= swz
[i
] = (mask
& (1 << i
) ? i
: last
);
172 return BRW_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
176 * Construct an identity swizzle for the first \p n components of a vector.
177 * When only a subset of channels of a vec4 are used we don't want to
178 * reference the other channels, as that will tell optimization passes that
179 * those other channels are used.
181 static inline unsigned
182 brw_swizzle_for_size(unsigned n
)
184 return brw_swizzle_for_mask((1 << n
) - 1);
188 * Converse of brw_swizzle_for_mask(). Returns the mask of components
189 * accessed by the specified swizzle \p swz.
191 static inline unsigned
192 brw_mask_for_swizzle(unsigned swz
)
194 return brw_apply_inv_swizzle_to_mask(swz
, ~0);
197 enum PACKED brw_reg_type
{
198 BRW_REGISTER_TYPE_UD
= 0,
200 BRW_REGISTER_TYPE_UW
,
204 /** Non-immediates only: @{ */
205 BRW_REGISTER_TYPE_UB
,
209 /** Immediates only: @{ */
210 BRW_REGISTER_TYPE_UV
, /* Gen6+ */
212 BRW_REGISTER_TYPE_VF
,
215 BRW_REGISTER_TYPE_DF
, /* Gen7+ (no immediates until Gen8+) */
218 BRW_REGISTER_TYPE_HF
,
219 BRW_REGISTER_TYPE_UQ
,
223 unsigned brw_reg_type_to_hw_type(const struct brw_device_info
*devinfo
,
224 enum brw_reg_type type
, enum brw_reg_file file
);
225 const char *brw_reg_type_letters(unsigned brw_reg_type
);
227 #define REG_SIZE (8*4)
229 /* These aren't hardware structs, just something useful for us to pass around:
231 * Align1 operation has a lot of control over input ranges. Used in
232 * WM programs to implement shaders decomposed into "channel serial"
233 * or "structure of array" form:
236 enum brw_reg_type type
:4;
237 enum brw_reg_file file
:3; /* :2 hardware format */
238 unsigned negate
:1; /* source only */
239 unsigned abs
:1; /* source only */
240 unsigned address_mode
:1; /* relative addressing, hopefully! */
242 unsigned subnr
:5; /* :1 in align16 */
247 unsigned swizzle
:8; /* src only, align16 only */
248 unsigned writemask
:4; /* dest only, align16 only */
249 int indirect_offset
:10; /* relative addressing offset */
250 unsigned vstride
:4; /* source only */
251 unsigned width
:3; /* src only, align1 only */
252 unsigned hstride
:2; /* align1 only */
263 struct brw_indirect
{
264 unsigned addr_subnr
:4;
270 static inline unsigned
271 type_sz(unsigned type
)
274 case BRW_REGISTER_TYPE_UQ
:
275 case BRW_REGISTER_TYPE_Q
:
277 case BRW_REGISTER_TYPE_UD
:
278 case BRW_REGISTER_TYPE_D
:
279 case BRW_REGISTER_TYPE_F
:
281 case BRW_REGISTER_TYPE_UW
:
282 case BRW_REGISTER_TYPE_W
:
284 case BRW_REGISTER_TYPE_UB
:
285 case BRW_REGISTER_TYPE_B
:
293 * Construct a brw_reg.
294 * \param file one of the BRW_x_REGISTER_FILE values
295 * \param nr register number/index
296 * \param subnr register sub number
297 * \param negate register negate modifier
298 * \param abs register abs modifier
299 * \param type one of BRW_REGISTER_TYPE_x
300 * \param vstride one of BRW_VERTICAL_STRIDE_x
301 * \param width one of BRW_WIDTH_x
302 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
303 * \param swizzle one of BRW_SWIZZLE_x
304 * \param writemask WRITEMASK_X/Y/Z/W bitfield
306 static inline struct brw_reg
307 brw_reg(enum brw_reg_file file
,
312 enum brw_reg_type type
,
320 if (file
== BRW_GENERAL_REGISTER_FILE
)
321 assert(nr
< BRW_MAX_GRF
);
322 else if (file
== BRW_ARCHITECTURE_REGISTER_FILE
)
323 assert(nr
<= BRW_ARF_TIMESTAMP
);
324 /* Asserting on the MRF register number requires to know the hardware gen
325 * (gen6 has 24 MRF registers), which we don't know here, so we assert
326 * for that in the generators and in brw_eu_emit.c
333 reg
.address_mode
= BRW_ADDRESS_DIRECT
;
335 reg
.subnr
= subnr
* type_sz(type
);
338 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
339 * set swizzle and writemask to W, as the lower bits of subnr will
340 * be lost when converted to align16. This is probably too much to
341 * keep track of as you'd want it adjusted by suboffset(), etc.
342 * Perhaps fix up when converting to align16?
344 reg
.swizzle
= swizzle
;
345 reg
.writemask
= writemask
;
346 reg
.indirect_offset
= 0;
347 reg
.vstride
= vstride
;
349 reg
.hstride
= hstride
;
354 /** Construct float[16] register */
355 static inline struct brw_reg
356 brw_vec16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
364 BRW_VERTICAL_STRIDE_16
,
366 BRW_HORIZONTAL_STRIDE_1
,
371 /** Construct float[8] register */
372 static inline struct brw_reg
373 brw_vec8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
381 BRW_VERTICAL_STRIDE_8
,
383 BRW_HORIZONTAL_STRIDE_1
,
388 /** Construct float[4] register */
389 static inline struct brw_reg
390 brw_vec4_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
398 BRW_VERTICAL_STRIDE_4
,
400 BRW_HORIZONTAL_STRIDE_1
,
405 /** Construct float[2] register */
406 static inline struct brw_reg
407 brw_vec2_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
415 BRW_VERTICAL_STRIDE_2
,
417 BRW_HORIZONTAL_STRIDE_1
,
422 /** Construct float[1] register */
423 static inline struct brw_reg
424 brw_vec1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
432 BRW_VERTICAL_STRIDE_0
,
434 BRW_HORIZONTAL_STRIDE_0
,
439 static inline struct brw_reg
440 brw_vecn_reg(unsigned width
, enum brw_reg_file file
,
441 unsigned nr
, unsigned subnr
)
445 return brw_vec1_reg(file
, nr
, subnr
);
447 return brw_vec2_reg(file
, nr
, subnr
);
449 return brw_vec4_reg(file
, nr
, subnr
);
451 return brw_vec8_reg(file
, nr
, subnr
);
453 return brw_vec16_reg(file
, nr
, subnr
);
455 unreachable("Invalid register width");
459 static inline struct brw_reg
460 retype(struct brw_reg reg
, enum brw_reg_type type
)
466 static inline struct brw_reg
467 firsthalf(struct brw_reg reg
)
472 static inline struct brw_reg
473 sechalf(struct brw_reg reg
)
480 static inline struct brw_reg
481 suboffset(struct brw_reg reg
, unsigned delta
)
483 reg
.subnr
+= delta
* type_sz(reg
.type
);
488 static inline struct brw_reg
489 offset(struct brw_reg reg
, unsigned delta
)
496 static inline struct brw_reg
497 byte_offset(struct brw_reg reg
, unsigned bytes
)
499 unsigned newoffset
= reg
.nr
* REG_SIZE
+ reg
.subnr
+ bytes
;
500 reg
.nr
= newoffset
/ REG_SIZE
;
501 reg
.subnr
= newoffset
% REG_SIZE
;
506 /** Construct unsigned word[16] register */
507 static inline struct brw_reg
508 brw_uw16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
510 return suboffset(retype(brw_vec16_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
513 /** Construct unsigned word[8] register */
514 static inline struct brw_reg
515 brw_uw8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
517 return suboffset(retype(brw_vec8_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
520 /** Construct unsigned word[1] register */
521 static inline struct brw_reg
522 brw_uw1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
524 return suboffset(retype(brw_vec1_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
527 static inline struct brw_reg
528 brw_imm_reg(enum brw_reg_type type
)
530 return brw_reg(BRW_IMMEDIATE_VALUE
,
536 BRW_VERTICAL_STRIDE_0
,
538 BRW_HORIZONTAL_STRIDE_0
,
543 /** Construct float immediate register */
544 static inline struct brw_reg
547 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_F
);
552 /** Construct integer immediate register */
553 static inline struct brw_reg
556 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_D
);
561 /** Construct uint immediate register */
562 static inline struct brw_reg
563 brw_imm_ud(unsigned ud
)
565 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UD
);
570 /** Construct ushort immediate register */
571 static inline struct brw_reg
572 brw_imm_uw(uint16_t uw
)
574 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UW
);
575 imm
.ud
= uw
| (uw
<< 16);
579 /** Construct short immediate register */
580 static inline struct brw_reg
583 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_W
);
584 imm
.d
= w
| (w
<< 16);
588 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
589 * numbers alias with _V and _VF below:
592 /** Construct vector of eight signed half-byte values */
593 static inline struct brw_reg
594 brw_imm_v(unsigned v
)
596 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_V
);
601 /** Construct vector of eight unsigned half-byte values */
602 static inline struct brw_reg
603 brw_imm_uv(unsigned uv
)
605 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UV
);
610 /** Construct vector of four 8-bit float values */
611 static inline struct brw_reg
612 brw_imm_vf(unsigned v
)
614 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
619 static inline struct brw_reg
620 brw_imm_vf4(unsigned v0
, unsigned v1
, unsigned v2
, unsigned v3
)
622 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
623 imm
.vstride
= BRW_VERTICAL_STRIDE_0
;
624 imm
.width
= BRW_WIDTH_4
;
625 imm
.hstride
= BRW_HORIZONTAL_STRIDE_1
;
626 imm
.ud
= ((v0
<< 0) | (v1
<< 8) | (v2
<< 16) | (v3
<< 24));
631 static inline struct brw_reg
632 brw_address(struct brw_reg reg
)
634 return brw_imm_uw(reg
.nr
* REG_SIZE
+ reg
.subnr
);
637 /** Construct float[1] general-purpose register */
638 static inline struct brw_reg
639 brw_vec1_grf(unsigned nr
, unsigned subnr
)
641 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
644 /** Construct float[2] general-purpose register */
645 static inline struct brw_reg
646 brw_vec2_grf(unsigned nr
, unsigned subnr
)
648 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
651 /** Construct float[4] general-purpose register */
652 static inline struct brw_reg
653 brw_vec4_grf(unsigned nr
, unsigned subnr
)
655 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
658 /** Construct float[8] general-purpose register */
659 static inline struct brw_reg
660 brw_vec8_grf(unsigned nr
, unsigned subnr
)
662 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
665 /** Construct float[16] general-purpose register */
666 static inline struct brw_reg
667 brw_vec16_grf(unsigned nr
, unsigned subnr
)
669 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
673 static inline struct brw_reg
674 brw_uw8_grf(unsigned nr
, unsigned subnr
)
676 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
679 static inline struct brw_reg
680 brw_uw16_grf(unsigned nr
, unsigned subnr
)
682 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
686 /** Construct null register (usually used for setting condition codes) */
687 static inline struct brw_reg
690 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
693 static inline struct brw_reg
694 brw_null_vec(unsigned width
)
696 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
699 static inline struct brw_reg
700 brw_address_reg(unsigned subnr
)
702 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_ADDRESS
, subnr
);
705 /* If/else instructions break in align16 mode if writemask & swizzle
706 * aren't xyzw. This goes against the convention for other scalar
709 static inline struct brw_reg
712 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
717 BRW_REGISTER_TYPE_UD
,
718 BRW_VERTICAL_STRIDE_4
, /* ? */
720 BRW_HORIZONTAL_STRIDE_0
,
721 BRW_SWIZZLE_XYZW
, /* NOTE! */
722 WRITEMASK_XYZW
); /* NOTE! */
725 static inline struct brw_reg
726 brw_notification_reg(void)
728 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
729 BRW_ARF_NOTIFICATION_COUNT
,
733 BRW_REGISTER_TYPE_UD
,
734 BRW_VERTICAL_STRIDE_0
,
736 BRW_HORIZONTAL_STRIDE_0
,
741 static inline struct brw_reg
742 brw_acc_reg(unsigned width
)
744 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
,
745 BRW_ARF_ACCUMULATOR
, 0);
748 static inline struct brw_reg
749 brw_flag_reg(int reg
, int subreg
)
751 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
752 BRW_ARF_FLAG
+ reg
, subreg
);
756 * Return the mask register present in Gen4-5, or the related register present
757 * in Gen7.5 and later hardware referred to as "channel enable" register in
760 static inline struct brw_reg
761 brw_mask_reg(unsigned subnr
)
763 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_MASK
, subnr
);
766 static inline struct brw_reg
767 brw_message_reg(unsigned nr
)
769 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, nr
, 0);
772 static inline struct brw_reg
773 brw_uvec_mrf(unsigned width
, unsigned nr
, unsigned subnr
)
775 return retype(brw_vecn_reg(width
, BRW_MESSAGE_REGISTER_FILE
, nr
, subnr
),
776 BRW_REGISTER_TYPE_UD
);
779 /* This is almost always called with a numeric constant argument, so
780 * make things easy to evaluate at compile time:
782 static inline unsigned cvt(unsigned val
)
796 static inline struct brw_reg
797 stride(struct brw_reg reg
, unsigned vstride
, unsigned width
, unsigned hstride
)
799 reg
.vstride
= cvt(vstride
);
800 reg
.width
= cvt(width
) - 1;
801 reg
.hstride
= cvt(hstride
);
806 * Multiply the vertical and horizontal stride of a register by the given
809 static inline struct brw_reg
810 spread(struct brw_reg reg
, unsigned s
)
813 assert(_mesa_is_pow_two(s
));
816 reg
.hstride
+= cvt(s
) - 1;
819 reg
.vstride
+= cvt(s
) - 1;
823 return stride(reg
, 0, 1, 0);
827 static inline struct brw_reg
828 vec16(struct brw_reg reg
)
830 return stride(reg
, 16,16,1);
833 static inline struct brw_reg
834 vec8(struct brw_reg reg
)
836 return stride(reg
, 8,8,1);
839 static inline struct brw_reg
840 vec4(struct brw_reg reg
)
842 return stride(reg
, 4,4,1);
845 static inline struct brw_reg
846 vec2(struct brw_reg reg
)
848 return stride(reg
, 2,2,1);
851 static inline struct brw_reg
852 vec1(struct brw_reg reg
)
854 return stride(reg
, 0,1,0);
858 static inline struct brw_reg
859 get_element(struct brw_reg reg
, unsigned elt
)
861 return vec1(suboffset(reg
, elt
));
864 static inline struct brw_reg
865 get_element_ud(struct brw_reg reg
, unsigned elt
)
867 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_UD
), elt
));
870 static inline struct brw_reg
871 get_element_d(struct brw_reg reg
, unsigned elt
)
873 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_D
), elt
));
876 static inline struct brw_reg
877 brw_swizzle(struct brw_reg reg
, unsigned swz
)
879 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
881 reg
.swizzle
= brw_compose_swizzle(swz
, reg
.swizzle
);
885 static inline struct brw_reg
886 brw_writemask(struct brw_reg reg
, unsigned mask
)
888 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
889 reg
.writemask
&= mask
;
893 static inline struct brw_reg
894 brw_set_writemask(struct brw_reg reg
, unsigned mask
)
896 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
897 reg
.writemask
= mask
;
901 static inline unsigned
902 brw_writemask_for_size(unsigned n
)
907 static inline struct brw_reg
908 negate(struct brw_reg reg
)
914 static inline struct brw_reg
915 brw_abs(struct brw_reg reg
)
922 /************************************************************************/
924 static inline struct brw_reg
925 brw_vec4_indirect(unsigned subnr
, int offset
)
927 struct brw_reg reg
= brw_vec4_grf(0, 0);
929 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
930 reg
.indirect_offset
= offset
;
934 static inline struct brw_reg
935 brw_vec1_indirect(unsigned subnr
, int offset
)
937 struct brw_reg reg
= brw_vec1_grf(0, 0);
939 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
940 reg
.indirect_offset
= offset
;
944 static inline struct brw_reg
945 brw_VxH_indirect(unsigned subnr
, int offset
)
947 struct brw_reg reg
= brw_vec1_grf(0, 0);
948 reg
.vstride
= BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
;
950 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
951 reg
.indirect_offset
= offset
;
955 static inline struct brw_reg
956 deref_4f(struct brw_indirect ptr
, int offset
)
958 return brw_vec4_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
961 static inline struct brw_reg
962 deref_1f(struct brw_indirect ptr
, int offset
)
964 return brw_vec1_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
967 static inline struct brw_reg
968 deref_4b(struct brw_indirect ptr
, int offset
)
970 return retype(deref_4f(ptr
, offset
), BRW_REGISTER_TYPE_B
);
973 static inline struct brw_reg
974 deref_1uw(struct brw_indirect ptr
, int offset
)
976 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UW
);
979 static inline struct brw_reg
980 deref_1d(struct brw_indirect ptr
, int offset
)
982 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_D
);
985 static inline struct brw_reg
986 deref_1ud(struct brw_indirect ptr
, int offset
)
988 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UD
);
991 static inline struct brw_reg
992 get_addr_reg(struct brw_indirect ptr
)
994 return brw_address_reg(ptr
.addr_subnr
);
997 static inline struct brw_indirect
998 brw_indirect_offset(struct brw_indirect ptr
, int offset
)
1000 ptr
.addr_offset
+= offset
;
1004 static inline struct brw_indirect
1005 brw_indirect(unsigned addr_subnr
, int offset
)
1007 struct brw_indirect ptr
;
1008 ptr
.addr_subnr
= addr_subnr
;
1009 ptr
.addr_offset
= offset
;
1015 region_matches(struct brw_reg reg
, enum brw_vertical_stride v
,
1016 enum brw_width w
, enum brw_horizontal_stride h
)
1018 return reg
.vstride
== v
&&
1023 #define has_scalar_region(reg) \
1024 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1025 BRW_HORIZONTAL_STRIDE_0)
1027 /* brw_packed_float.c */
1028 int brw_float_to_vf(float f
);
1029 float brw_vf_to_float(unsigned char vf
);