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 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_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 gen_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 offset(struct brw_reg reg
, unsigned delta
)
530 static inline struct brw_reg
531 byte_offset(struct brw_reg reg
, unsigned bytes
)
533 unsigned newoffset
= reg
.nr
* REG_SIZE
+ reg
.subnr
+ bytes
;
534 reg
.nr
= newoffset
/ REG_SIZE
;
535 reg
.subnr
= newoffset
% REG_SIZE
;
539 static inline struct brw_reg
540 suboffset(struct brw_reg reg
, unsigned delta
)
542 return byte_offset(reg
, delta
* type_sz(reg
.type
));
545 /** Construct unsigned word[16] register */
546 static inline struct brw_reg
547 brw_uw16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
549 return suboffset(retype(brw_vec16_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
552 /** Construct unsigned word[8] register */
553 static inline struct brw_reg
554 brw_uw8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
556 return suboffset(retype(brw_vec8_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
559 /** Construct unsigned word[1] register */
560 static inline struct brw_reg
561 brw_uw1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
563 return suboffset(retype(brw_vec1_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
566 static inline struct brw_reg
567 brw_ud1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
569 return retype(brw_vec1_reg(file
, nr
, subnr
), BRW_REGISTER_TYPE_UD
);
572 static inline struct brw_reg
573 brw_imm_reg(enum brw_reg_type type
)
575 return brw_reg(BRW_IMMEDIATE_VALUE
,
581 BRW_VERTICAL_STRIDE_0
,
583 BRW_HORIZONTAL_STRIDE_0
,
588 /** Construct float immediate register */
589 static inline struct brw_reg
590 brw_imm_df(double df
)
592 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_DF
);
597 static inline struct brw_reg
600 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_F
);
605 /** Construct integer immediate register */
606 static inline struct brw_reg
609 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_D
);
614 /** Construct uint immediate register */
615 static inline struct brw_reg
616 brw_imm_ud(unsigned ud
)
618 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UD
);
623 /** Construct ushort immediate register */
624 static inline struct brw_reg
625 brw_imm_uw(uint16_t uw
)
627 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UW
);
628 imm
.ud
= uw
| (uw
<< 16);
632 /** Construct short immediate register */
633 static inline struct brw_reg
636 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_W
);
637 imm
.d
= w
| (w
<< 16);
641 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
642 * numbers alias with _V and _VF below:
645 /** Construct vector of eight signed half-byte values */
646 static inline struct brw_reg
647 brw_imm_v(unsigned v
)
649 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_V
);
654 /** Construct vector of eight unsigned half-byte values */
655 static inline struct brw_reg
656 brw_imm_uv(unsigned uv
)
658 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UV
);
663 /** Construct vector of four 8-bit float values */
664 static inline struct brw_reg
665 brw_imm_vf(unsigned v
)
667 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
672 static inline struct brw_reg
673 brw_imm_vf4(unsigned v0
, unsigned v1
, unsigned v2
, unsigned v3
)
675 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
676 imm
.vstride
= BRW_VERTICAL_STRIDE_0
;
677 imm
.width
= BRW_WIDTH_4
;
678 imm
.hstride
= BRW_HORIZONTAL_STRIDE_1
;
679 imm
.ud
= ((v0
<< 0) | (v1
<< 8) | (v2
<< 16) | (v3
<< 24));
684 static inline struct brw_reg
685 brw_address(struct brw_reg reg
)
687 return brw_imm_uw(reg
.nr
* REG_SIZE
+ reg
.subnr
);
690 /** Construct float[1] general-purpose register */
691 static inline struct brw_reg
692 brw_vec1_grf(unsigned nr
, unsigned subnr
)
694 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
697 /** Construct float[2] general-purpose register */
698 static inline struct brw_reg
699 brw_vec2_grf(unsigned nr
, unsigned subnr
)
701 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
704 /** Construct float[4] general-purpose register */
705 static inline struct brw_reg
706 brw_vec4_grf(unsigned nr
, unsigned subnr
)
708 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
711 /** Construct float[8] general-purpose register */
712 static inline struct brw_reg
713 brw_vec8_grf(unsigned nr
, unsigned subnr
)
715 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
718 /** Construct float[16] general-purpose register */
719 static inline struct brw_reg
720 brw_vec16_grf(unsigned nr
, unsigned subnr
)
722 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
726 static inline struct brw_reg
727 brw_uw8_grf(unsigned nr
, unsigned subnr
)
729 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
732 static inline struct brw_reg
733 brw_uw16_grf(unsigned nr
, unsigned subnr
)
735 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
739 /** Construct null register (usually used for setting condition codes) */
740 static inline struct brw_reg
743 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
746 static inline struct brw_reg
747 brw_null_vec(unsigned width
)
749 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
752 static inline struct brw_reg
753 brw_address_reg(unsigned subnr
)
755 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_ADDRESS
, subnr
);
758 /* If/else instructions break in align16 mode if writemask & swizzle
759 * aren't xyzw. This goes against the convention for other scalar
762 static inline struct brw_reg
765 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
770 BRW_REGISTER_TYPE_UD
,
771 BRW_VERTICAL_STRIDE_4
, /* ? */
773 BRW_HORIZONTAL_STRIDE_0
,
774 BRW_SWIZZLE_XYZW
, /* NOTE! */
775 WRITEMASK_XYZW
); /* NOTE! */
778 static inline struct brw_reg
779 brw_notification_reg(void)
781 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
782 BRW_ARF_NOTIFICATION_COUNT
,
786 BRW_REGISTER_TYPE_UD
,
787 BRW_VERTICAL_STRIDE_0
,
789 BRW_HORIZONTAL_STRIDE_0
,
794 static inline struct brw_reg
795 brw_sr0_reg(unsigned subnr
)
797 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_STATE
, subnr
);
800 static inline struct brw_reg
801 brw_acc_reg(unsigned width
)
803 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
,
804 BRW_ARF_ACCUMULATOR
, 0);
807 static inline struct brw_reg
808 brw_flag_reg(int reg
, int subreg
)
810 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
811 BRW_ARF_FLAG
+ reg
, subreg
);
815 * Return the mask register present in Gen4-5, or the related register present
816 * in Gen7.5 and later hardware referred to as "channel enable" register in
819 static inline struct brw_reg
820 brw_mask_reg(unsigned subnr
)
822 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_MASK
, subnr
);
825 static inline struct brw_reg
828 return brw_sr0_reg(3);
831 static inline struct brw_reg
834 return brw_sr0_reg(2);
837 static inline struct brw_reg
838 brw_message_reg(unsigned nr
)
840 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, nr
, 0);
843 static inline struct brw_reg
844 brw_uvec_mrf(unsigned width
, unsigned nr
, unsigned subnr
)
846 return retype(brw_vecn_reg(width
, BRW_MESSAGE_REGISTER_FILE
, nr
, subnr
),
847 BRW_REGISTER_TYPE_UD
);
850 /* This is almost always called with a numeric constant argument, so
851 * make things easy to evaluate at compile time:
853 static inline unsigned cvt(unsigned val
)
867 static inline struct brw_reg
868 stride(struct brw_reg reg
, unsigned vstride
, unsigned width
, unsigned hstride
)
870 reg
.vstride
= cvt(vstride
);
871 reg
.width
= cvt(width
) - 1;
872 reg
.hstride
= cvt(hstride
);
877 * Multiply the vertical and horizontal stride of a register by the given
880 static inline struct brw_reg
881 spread(struct brw_reg reg
, unsigned s
)
884 assert(_mesa_is_pow_two(s
));
887 reg
.hstride
+= cvt(s
) - 1;
890 reg
.vstride
+= cvt(s
) - 1;
894 return stride(reg
, 0, 1, 0);
898 static inline struct brw_reg
899 vec16(struct brw_reg reg
)
901 return stride(reg
, 16,16,1);
904 static inline struct brw_reg
905 vec8(struct brw_reg reg
)
907 return stride(reg
, 8,8,1);
910 static inline struct brw_reg
911 vec4(struct brw_reg reg
)
913 return stride(reg
, 4,4,1);
916 static inline struct brw_reg
917 vec2(struct brw_reg reg
)
919 return stride(reg
, 2,2,1);
922 static inline struct brw_reg
923 vec1(struct brw_reg reg
)
925 return stride(reg
, 0,1,0);
929 static inline struct brw_reg
930 get_element(struct brw_reg reg
, unsigned elt
)
932 return vec1(suboffset(reg
, elt
));
935 static inline struct brw_reg
936 get_element_ud(struct brw_reg reg
, unsigned elt
)
938 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_UD
), elt
));
941 static inline struct brw_reg
942 get_element_d(struct brw_reg reg
, unsigned elt
)
944 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_D
), elt
));
947 static inline struct brw_reg
948 brw_swizzle(struct brw_reg reg
, unsigned swz
)
950 if (reg
.file
== BRW_IMMEDIATE_VALUE
)
951 reg
.ud
= brw_swizzle_immediate(reg
.type
, reg
.ud
, swz
);
953 reg
.swizzle
= brw_compose_swizzle(swz
, reg
.swizzle
);
958 static inline struct brw_reg
959 brw_writemask(struct brw_reg reg
, unsigned mask
)
961 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
962 reg
.writemask
&= mask
;
966 static inline struct brw_reg
967 brw_set_writemask(struct brw_reg reg
, unsigned mask
)
969 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
970 reg
.writemask
= mask
;
974 static inline unsigned
975 brw_writemask_for_size(unsigned n
)
980 static inline unsigned
981 brw_writemask_for_component_packing(unsigned n
, unsigned first_component
)
983 assert(first_component
+ n
<= 4);
984 return (((1 << n
) - 1) << first_component
);
987 static inline struct brw_reg
988 negate(struct brw_reg reg
)
994 static inline struct brw_reg
995 brw_abs(struct brw_reg reg
)
1002 /************************************************************************/
1004 static inline struct brw_reg
1005 brw_vec4_indirect(unsigned subnr
, int offset
)
1007 struct brw_reg reg
= brw_vec4_grf(0, 0);
1009 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1010 reg
.indirect_offset
= offset
;
1014 static inline struct brw_reg
1015 brw_vec1_indirect(unsigned subnr
, int offset
)
1017 struct brw_reg reg
= brw_vec1_grf(0, 0);
1019 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1020 reg
.indirect_offset
= offset
;
1024 static inline struct brw_reg
1025 brw_VxH_indirect(unsigned subnr
, int offset
)
1027 struct brw_reg reg
= brw_vec1_grf(0, 0);
1028 reg
.vstride
= BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
;
1030 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1031 reg
.indirect_offset
= offset
;
1035 static inline struct brw_reg
1036 deref_4f(struct brw_indirect ptr
, int offset
)
1038 return brw_vec4_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1041 static inline struct brw_reg
1042 deref_1f(struct brw_indirect ptr
, int offset
)
1044 return brw_vec1_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1047 static inline struct brw_reg
1048 deref_4b(struct brw_indirect ptr
, int offset
)
1050 return retype(deref_4f(ptr
, offset
), BRW_REGISTER_TYPE_B
);
1053 static inline struct brw_reg
1054 deref_1uw(struct brw_indirect ptr
, int offset
)
1056 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UW
);
1059 static inline struct brw_reg
1060 deref_1d(struct brw_indirect ptr
, int offset
)
1062 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_D
);
1065 static inline struct brw_reg
1066 deref_1ud(struct brw_indirect ptr
, int offset
)
1068 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UD
);
1071 static inline struct brw_reg
1072 get_addr_reg(struct brw_indirect ptr
)
1074 return brw_address_reg(ptr
.addr_subnr
);
1077 static inline struct brw_indirect
1078 brw_indirect_offset(struct brw_indirect ptr
, int offset
)
1080 ptr
.addr_offset
+= offset
;
1084 static inline struct brw_indirect
1085 brw_indirect(unsigned addr_subnr
, int offset
)
1087 struct brw_indirect ptr
;
1088 ptr
.addr_subnr
= addr_subnr
;
1089 ptr
.addr_offset
= offset
;
1095 region_matches(struct brw_reg reg
, enum brw_vertical_stride v
,
1096 enum brw_width w
, enum brw_horizontal_stride h
)
1098 return reg
.vstride
== v
&&
1103 #define has_scalar_region(reg) \
1104 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1105 BRW_HORIZONTAL_STRIDE_0)
1107 /* brw_packed_float.c */
1108 int brw_float_to_vf(float f
);
1109 float brw_vf_to_float(unsigned char vf
);