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/imports.h"
47
#include "main/compiler.h"
48
#include "program/prog_instruction.h"
49
#include "brw_defines.h"
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 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_YZXW BRW_SWIZZLE4(1,2,0,3)
85
#define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
86
#define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
89
brw_is_single_value_swizzle(int swiz)
91
return (swiz == BRW_SWIZZLE_XXXX ||
92
swiz == BRW_SWIZZLE_YYYY ||
93
swiz == BRW_SWIZZLE_ZZZZ ||
94
swiz == BRW_SWIZZLE_WWWW);
97
enum PACKED brw_reg_type {
98
BRW_REGISTER_TYPE_UD = 0,
100
BRW_REGISTER_TYPE_UW,
104
/** Non-immediates only: @{ */
105
BRW_REGISTER_TYPE_UB,
109
/** Immediates only: @{ */
110
BRW_REGISTER_TYPE_UV,
112
BRW_REGISTER_TYPE_VF,
115
BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */
118
BRW_REGISTER_TYPE_HF,
119
BRW_REGISTER_TYPE_UQ,
123
unsigned brw_reg_type_to_hw_type(const struct brw_context *brw,
124
enum brw_reg_type type, unsigned file);
125
const char *brw_reg_type_letters(unsigned brw_reg_type);
127
#define REG_SIZE (8*4)
129
/* These aren't hardware structs, just something useful for us to pass around:
131
* Align1 operation has a lot of control over input ranges. Used in
132
* WM programs to implement shaders decomposed into "channel serial"
133
* or "structure of array" form:
136
enum brw_reg_type type:4;
139
unsigned subnr:5; /* :1 in align16 */
140
unsigned negate:1; /* source only */
141
unsigned abs:1; /* source only */
142
unsigned vstride:4; /* source only */
143
unsigned width:3; /* src only, align1 only */
144
unsigned hstride:2; /* align1 only */
145
unsigned address_mode:1; /* relative addressing, hopefully! */
150
unsigned swizzle:8; /* src only, align16 only */
151
unsigned writemask:4; /* dest only, align16 only */
152
int indirect_offset:10; /* relative addressing offset */
153
unsigned pad1:10; /* two dwords total */
163
struct brw_indirect {
164
unsigned addr_subnr:4;
171
type_sz(unsigned type)
174
case BRW_REGISTER_TYPE_UD:
175
case BRW_REGISTER_TYPE_D:
176
case BRW_REGISTER_TYPE_F:
178
case BRW_REGISTER_TYPE_UW:
179
case BRW_REGISTER_TYPE_W:
181
case BRW_REGISTER_TYPE_UB:
182
case BRW_REGISTER_TYPE_B:
190
type_is_signed(unsigned type)
193
case BRW_REGISTER_TYPE_D:
194
case BRW_REGISTER_TYPE_W:
195
case BRW_REGISTER_TYPE_F:
196
case BRW_REGISTER_TYPE_B:
197
case BRW_REGISTER_TYPE_V:
198
case BRW_REGISTER_TYPE_VF:
199
case BRW_REGISTER_TYPE_DF:
200
case BRW_REGISTER_TYPE_HF:
201
case BRW_REGISTER_TYPE_Q:
204
case BRW_REGISTER_TYPE_UD:
205
case BRW_REGISTER_TYPE_UW:
206
case BRW_REGISTER_TYPE_UB:
207
case BRW_REGISTER_TYPE_UV:
208
case BRW_REGISTER_TYPE_UQ:
212
unreachable("not reached");
217
* Construct a brw_reg.
218
* \param file one of the BRW_x_REGISTER_FILE values
219
* \param nr register number/index
220
* \param subnr register sub number
221
* \param type one of BRW_REGISTER_TYPE_x
222
* \param vstride one of BRW_VERTICAL_STRIDE_x
223
* \param width one of BRW_WIDTH_x
224
* \param hstride one of BRW_HORIZONTAL_STRIDE_x
225
* \param swizzle one of BRW_SWIZZLE_x
226
* \param writemask WRITEMASK_X/Y/Z/W bitfield
228
static inline struct brw_reg
229
brw_reg(unsigned file,
232
enum brw_reg_type type,
240
if (file == BRW_GENERAL_REGISTER_FILE)
241
assert(nr < BRW_MAX_GRF);
242
else if (file == BRW_MESSAGE_REGISTER_FILE)
243
assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
244
else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
245
assert(nr <= BRW_ARF_TIMESTAMP);
250
reg.subnr = subnr * type_sz(type);
253
reg.vstride = vstride;
255
reg.hstride = hstride;
256
reg.address_mode = BRW_ADDRESS_DIRECT;
259
/* Could do better: If the reg is r5.3<0;1,0>, we probably want to
260
* set swizzle and writemask to W, as the lower bits of subnr will
261
* be lost when converted to align16. This is probably too much to
262
* keep track of as you'd want it adjusted by suboffset(), etc.
263
* Perhaps fix up when converting to align16?
265
reg.dw1.bits.swizzle = swizzle;
266
reg.dw1.bits.writemask = writemask;
267
reg.dw1.bits.indirect_offset = 0;
268
reg.dw1.bits.pad1 = 0;
272
/** Construct float[16] register */
273
static inline struct brw_reg
274
brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
280
BRW_VERTICAL_STRIDE_16,
282
BRW_HORIZONTAL_STRIDE_1,
287
/** Construct float[8] register */
288
static inline struct brw_reg
289
brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
295
BRW_VERTICAL_STRIDE_8,
297
BRW_HORIZONTAL_STRIDE_1,
302
/** Construct float[4] register */
303
static inline struct brw_reg
304
brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
310
BRW_VERTICAL_STRIDE_4,
312
BRW_HORIZONTAL_STRIDE_1,
317
/** Construct float[2] register */
318
static inline struct brw_reg
319
brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
325
BRW_VERTICAL_STRIDE_2,
327
BRW_HORIZONTAL_STRIDE_1,
332
/** Construct float[1] register */
333
static inline struct brw_reg
334
brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
340
BRW_VERTICAL_STRIDE_0,
342
BRW_HORIZONTAL_STRIDE_0,
347
static inline struct brw_reg
348
brw_vecn_reg(unsigned width, unsigned file, unsigned nr, unsigned subnr)
352
return brw_vec1_reg(file, nr, subnr);
354
return brw_vec2_reg(file, nr, subnr);
356
return brw_vec4_reg(file, nr, subnr);
358
return brw_vec8_reg(file, nr, subnr);
360
return brw_vec16_reg(file, nr, subnr);
362
unreachable("Invalid register width");
366
static inline struct brw_reg
367
retype(struct brw_reg reg, enum brw_reg_type type)
373
static inline struct brw_reg
374
sechalf(struct brw_reg reg)
381
static inline struct brw_reg
382
suboffset(struct brw_reg reg, unsigned delta)
384
reg.subnr += delta * type_sz(reg.type);
389
static inline struct brw_reg
390
offset(struct brw_reg reg, unsigned delta)
397
static inline struct brw_reg
398
byte_offset(struct brw_reg reg, unsigned bytes)
400
unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
401
reg.nr = newoffset / REG_SIZE;
402
reg.subnr = newoffset % REG_SIZE;
407
/** Construct unsigned word[16] register */
408
static inline struct brw_reg
409
brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
411
return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
414
/** Construct unsigned word[8] register */
415
static inline struct brw_reg
416
brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
418
return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
421
/** Construct unsigned word[1] register */
422
static inline struct brw_reg
423
brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
425
return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
428
static inline struct brw_reg
429
brw_imm_reg(enum brw_reg_type type)
431
return brw_reg(BRW_IMMEDIATE_VALUE,
435
BRW_VERTICAL_STRIDE_0,
437
BRW_HORIZONTAL_STRIDE_0,
442
/** Construct float immediate register */
443
static inline struct brw_reg
446
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
451
/** Construct integer immediate register */
452
static inline struct brw_reg
455
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
460
/** Construct uint immediate register */
461
static inline struct brw_reg
462
brw_imm_ud(unsigned ud)
464
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
469
/** Construct ushort immediate register */
470
static inline struct brw_reg
471
brw_imm_uw(uint16_t uw)
473
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
474
imm.dw1.ud = uw | (uw << 16);
478
/** Construct short immediate register */
479
static inline struct brw_reg
482
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
483
imm.dw1.d = w | (w << 16);
487
/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
488
* numbers alias with _V and _VF below:
491
/** Construct vector of eight signed half-byte values */
492
static inline struct brw_reg
493
brw_imm_v(unsigned v)
495
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
496
imm.vstride = BRW_VERTICAL_STRIDE_0;
497
imm.width = BRW_WIDTH_8;
498
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
503
/** Construct vector of four 8-bit float values */
504
static inline struct brw_reg
505
brw_imm_vf(unsigned v)
507
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
508
imm.vstride = BRW_VERTICAL_STRIDE_0;
509
imm.width = BRW_WIDTH_4;
510
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
516
* Convert an integer into a "restricted" 8-bit float, used in vector
517
* immediates. The 8-bit floating point format has a sign bit, an
518
* excess-3 3-bit exponent, and a 4-bit mantissa. All integer values
519
* from -31 to 31 can be represented exactly.
521
static inline uint8_t
527
return 1 << 7 | int_to_float8(-x);
529
const unsigned exponent = _mesa_logbase2(x);
530
const unsigned mantissa = (x - (1 << exponent)) << (4 - exponent);
531
assert(exponent <= 4);
532
return (exponent + 3) << 4 | mantissa;
537
* Construct a floating-point packed vector immediate from its integer
538
* values. \sa int_to_float8()
540
static inline struct brw_reg
541
brw_imm_vf4(int v0, int v1, int v2, int v3)
543
return brw_imm_vf((int_to_float8(v0) << 0) |
544
(int_to_float8(v1) << 8) |
545
(int_to_float8(v2) << 16) |
546
(int_to_float8(v3) << 24));
550
static inline struct brw_reg
551
brw_address(struct brw_reg reg)
553
return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
556
/** Construct float[1] general-purpose register */
557
static inline struct brw_reg
558
brw_vec1_grf(unsigned nr, unsigned subnr)
560
return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
563
/** Construct float[2] general-purpose register */
564
static inline struct brw_reg
565
brw_vec2_grf(unsigned nr, unsigned subnr)
567
return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
570
/** Construct float[4] general-purpose register */
571
static inline struct brw_reg
572
brw_vec4_grf(unsigned nr, unsigned subnr)
574
return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
577
/** Construct float[8] general-purpose register */
578
static inline struct brw_reg
579
brw_vec8_grf(unsigned nr, unsigned subnr)
581
return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
585
static inline struct brw_reg
586
brw_uw8_grf(unsigned nr, unsigned subnr)
588
return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
591
static inline struct brw_reg
592
brw_uw16_grf(unsigned nr, unsigned subnr)
594
return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
598
/** Construct null register (usually used for setting condition codes) */
599
static inline struct brw_reg
602
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
605
static inline struct brw_reg
606
brw_address_reg(unsigned subnr)
608
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
611
/* If/else instructions break in align16 mode if writemask & swizzle
612
* aren't xyzw. This goes against the convention for other scalar
615
static inline struct brw_reg
618
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
621
BRW_REGISTER_TYPE_UD,
622
BRW_VERTICAL_STRIDE_4, /* ? */
624
BRW_HORIZONTAL_STRIDE_0,
625
BRW_SWIZZLE_XYZW, /* NOTE! */
626
WRITEMASK_XYZW); /* NOTE! */
629
static inline struct brw_reg
632
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
635
static inline struct brw_reg
636
brw_flag_reg(int reg, int subreg)
638
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
639
BRW_ARF_FLAG + reg, subreg);
643
static inline struct brw_reg
644
brw_mask_reg(unsigned subnr)
646
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
649
static inline struct brw_reg
650
brw_message_reg(unsigned nr)
652
assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
653
return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
656
static inline struct brw_reg
657
brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
659
return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
660
BRW_REGISTER_TYPE_UD);
663
/* This is almost always called with a numeric constant argument, so
664
* make things easy to evaluate at compile time:
666
static inline unsigned cvt(unsigned val)
680
static inline struct brw_reg
681
stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
683
reg.vstride = cvt(vstride);
684
reg.width = cvt(width) - 1;
685
reg.hstride = cvt(hstride);
690
static inline struct brw_reg
691
vec16(struct brw_reg reg)
693
return stride(reg, 16,16,1);
696
static inline struct brw_reg
697
vec8(struct brw_reg reg)
699
return stride(reg, 8,8,1);
702
static inline struct brw_reg
703
vec4(struct brw_reg reg)
705
return stride(reg, 4,4,1);
708
static inline struct brw_reg
709
vec2(struct brw_reg reg)
711
return stride(reg, 2,2,1);
714
static inline struct brw_reg
715
vec1(struct brw_reg reg)
717
return stride(reg, 0,1,0);
721
static inline struct brw_reg
722
get_element(struct brw_reg reg, unsigned elt)
724
return vec1(suboffset(reg, elt));
727
static inline struct brw_reg
728
get_element_ud(struct brw_reg reg, unsigned elt)
730
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
733
static inline struct brw_reg
734
get_element_d(struct brw_reg reg, unsigned elt)
736
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
740
static inline struct brw_reg
741
brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
743
assert(reg.file != BRW_IMMEDIATE_VALUE);
745
reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
746
BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
747
BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
748
BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
753
static inline struct brw_reg
754
brw_swizzle1(struct brw_reg reg, unsigned x)
756
return brw_swizzle(reg, x, x, x, x);
759
static inline struct brw_reg
760
brw_writemask(struct brw_reg reg, unsigned mask)
762
assert(reg.file != BRW_IMMEDIATE_VALUE);
763
reg.dw1.bits.writemask &= mask;
767
static inline struct brw_reg
768
brw_set_writemask(struct brw_reg reg, unsigned mask)
770
assert(reg.file != BRW_IMMEDIATE_VALUE);
771
reg.dw1.bits.writemask = mask;
775
static inline struct brw_reg
776
negate(struct brw_reg reg)
782
static inline struct brw_reg
783
brw_abs(struct brw_reg reg)
790
/************************************************************************/
792
static inline struct brw_reg
793
brw_vec4_indirect(unsigned subnr, int offset)
795
struct brw_reg reg = brw_vec4_grf(0, 0);
797
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
798
reg.dw1.bits.indirect_offset = offset;
802
static inline struct brw_reg
803
brw_vec1_indirect(unsigned subnr, int offset)
805
struct brw_reg reg = brw_vec1_grf(0, 0);
807
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
808
reg.dw1.bits.indirect_offset = offset;
812
static inline struct brw_reg
813
deref_4f(struct brw_indirect ptr, int offset)
815
return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
818
static inline struct brw_reg
819
deref_1f(struct brw_indirect ptr, int offset)
821
return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
824
static inline struct brw_reg
825
deref_4b(struct brw_indirect ptr, int offset)
827
return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
830
static inline struct brw_reg
831
deref_1uw(struct brw_indirect ptr, int offset)
833
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
836
static inline struct brw_reg
837
deref_1d(struct brw_indirect ptr, int offset)
839
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
842
static inline struct brw_reg
843
deref_1ud(struct brw_indirect ptr, int offset)
845
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
848
static inline struct brw_reg
849
get_addr_reg(struct brw_indirect ptr)
851
return brw_address_reg(ptr.addr_subnr);
854
static inline struct brw_indirect
855
brw_indirect_offset(struct brw_indirect ptr, int offset)
857
ptr.addr_offset += offset;
861
static inline struct brw_indirect
862
brw_indirect(unsigned addr_subnr, int offset)
864
struct brw_indirect ptr;
865
ptr.addr_subnr = addr_subnr;
866
ptr.addr_offset = offset;