mesa/i965/i915/r200: eliminate gl_vertex_program
[mesa.git] / src / mesa / drivers / dri / i965 / brw_reg.h
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics to
4 develop this 3D driver.
5
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:
13
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.
17
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.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keithw@vmware.com>
30 */
31
32 /** @file brw_reg.h
33 *
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.
37 *
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.
40 */
41
42 #ifndef BRW_REG_H
43 #define BRW_REG_H
44
45 #include <stdbool.h>
46 #include "main/compiler.h"
47 #include "main/macros.h"
48 #include "program/prog_instruction.h"
49 #include "brw_defines.h"
50
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 struct gen_device_info;
56
57 /** Number of general purpose registers (VS, WM, etc) */
58 #define BRW_MAX_GRF 128
59
60 /**
61 * First GRF used for the MRF hack.
62 *
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.
68 */
69 #define GEN7_MRF_HACK_START 112
70
71 /** Number of message register file registers */
72 #define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
73
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)
76
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)
90
91 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
92 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
93
94 static inline bool
95 brw_is_single_value_swizzle(unsigned swiz)
96 {
97 return (swiz == BRW_SWIZZLE_XXXX ||
98 swiz == BRW_SWIZZLE_YYYY ||
99 swiz == BRW_SWIZZLE_ZZZZ ||
100 swiz == BRW_SWIZZLE_WWWW);
101 }
102
103 /**
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
106 * composition.
107 */
108 static inline unsigned
109 brw_compose_swizzle(unsigned swz0, unsigned swz1)
110 {
111 return BRW_SWIZZLE4(
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)));
116 }
117
118 /**
119 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
120 * (AKA image).
121 */
122 static inline unsigned
123 brw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
124 {
125 unsigned result = 0;
126
127 for (unsigned i = 0; i < 4; i++) {
128 if (mask & (1 << BRW_GET_SWZ(swz, i)))
129 result |= 1 << i;
130 }
131
132 return result;
133 }
134
135 /**
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.
139 */
140 static inline unsigned
141 brw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
142 {
143 unsigned result = 0;
144
145 for (unsigned i = 0; i < 4; i++) {
146 if (mask & (1 << i))
147 result |= 1 << BRW_GET_SWZ(swz, i);
148 }
149
150 return result;
151 }
152
153 /**
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:
158 *
159 * brw_OP(p, brw_writemask(dst, mask),
160 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
161 *
162 * will be equivalent to the same instruction without swizzle:
163 *
164 * brw_OP(p, brw_writemask(dst, mask), src);
165 */
166 static inline unsigned
167 brw_swizzle_for_mask(unsigned mask)
168 {
169 unsigned last = (mask ? ffs(mask) - 1 : 0);
170 unsigned swz[4];
171
172 for (unsigned i = 0; i < 4; i++)
173 last = swz[i] = (mask & (1 << i) ? i : last);
174
175 return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
176 }
177
178 /**
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.
183 */
184 static inline unsigned
185 brw_swizzle_for_size(unsigned n)
186 {
187 return brw_swizzle_for_mask((1 << n) - 1);
188 }
189
190 /**
191 * Converse of brw_swizzle_for_mask(). Returns the mask of components
192 * accessed by the specified swizzle \p swz.
193 */
194 static inline unsigned
195 brw_mask_for_swizzle(unsigned swz)
196 {
197 return brw_apply_inv_swizzle_to_mask(swz, ~0);
198 }
199
200 enum PACKED brw_reg_type {
201 BRW_REGISTER_TYPE_UD = 0,
202 BRW_REGISTER_TYPE_D,
203 BRW_REGISTER_TYPE_UW,
204 BRW_REGISTER_TYPE_W,
205 BRW_REGISTER_TYPE_F,
206
207 /** Non-immediates only: @{ */
208 BRW_REGISTER_TYPE_UB,
209 BRW_REGISTER_TYPE_B,
210 /** @} */
211
212 /** Immediates only: @{ */
213 BRW_REGISTER_TYPE_UV, /* Gen6+ */
214 BRW_REGISTER_TYPE_V,
215 BRW_REGISTER_TYPE_VF,
216 /** @} */
217
218 BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */
219
220 /* Gen8+ */
221 BRW_REGISTER_TYPE_HF,
222 BRW_REGISTER_TYPE_UQ,
223 BRW_REGISTER_TYPE_Q,
224 };
225
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);
230
231 #define REG_SIZE (8*4)
232
233 /* These aren't hardware structs, just something useful for us to pass around:
234 *
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:
238 */
239 struct brw_reg {
240 union {
241 struct {
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! */
247 unsigned pad0:1;
248 unsigned subnr:5; /* :1 in align16 */
249 unsigned nr:16;
250 };
251 uint32_t bits;
252 };
253
254 union {
255 struct {
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 */
262 unsigned pad1:1;
263 };
264
265 double df;
266 uint64_t u64;
267 float f;
268 int d;
269 unsigned ud;
270 };
271 };
272
273 static inline bool
274 brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
275 {
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);
278 }
279
280 struct brw_indirect {
281 unsigned addr_subnr:4;
282 int addr_offset:10;
283 unsigned pad:18;
284 };
285
286
287 static inline unsigned
288 type_sz(unsigned type)
289 {
290 switch(type) {
291 case BRW_REGISTER_TYPE_UQ:
292 case BRW_REGISTER_TYPE_Q:
293 case BRW_REGISTER_TYPE_DF:
294 return 8;
295 case BRW_REGISTER_TYPE_UD:
296 case BRW_REGISTER_TYPE_D:
297 case BRW_REGISTER_TYPE_F:
298 case BRW_REGISTER_TYPE_VF:
299 return 4;
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:
305 return 2;
306 case BRW_REGISTER_TYPE_UB:
307 case BRW_REGISTER_TYPE_B:
308 return 1;
309 default:
310 unreachable("not reached");
311 }
312 }
313
314 /**
315 * Return an integer type of the requested size and signedness.
316 */
317 static inline enum brw_reg_type
318 brw_int_type(unsigned sz, bool is_signed)
319 {
320 switch (sz) {
321 case 1:
322 return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
323 case 2:
324 return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
325 case 4:
326 return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
327 case 8:
328 return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
329 default:
330 unreachable("Not reached.");
331 }
332 }
333
334 /**
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
347 */
348 static inline struct brw_reg
349 brw_reg(enum brw_reg_file file,
350 unsigned nr,
351 unsigned subnr,
352 unsigned negate,
353 unsigned abs,
354 enum brw_reg_type type,
355 unsigned vstride,
356 unsigned width,
357 unsigned hstride,
358 unsigned swizzle,
359 unsigned writemask)
360 {
361 struct brw_reg reg;
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
369 */
370
371 reg.type = type;
372 reg.file = file;
373 reg.negate = negate;
374 reg.abs = abs;
375 reg.address_mode = BRW_ADDRESS_DIRECT;
376 reg.pad0 = 0;
377 reg.subnr = subnr * type_sz(type);
378 reg.nr = nr;
379
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?
385 */
386 reg.swizzle = swizzle;
387 reg.writemask = writemask;
388 reg.indirect_offset = 0;
389 reg.vstride = vstride;
390 reg.width = width;
391 reg.hstride = hstride;
392 reg.pad1 = 0;
393 return reg;
394 }
395
396 /** Construct float[16] register */
397 static inline struct brw_reg
398 brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
399 {
400 return brw_reg(file,
401 nr,
402 subnr,
403 0,
404 0,
405 BRW_REGISTER_TYPE_F,
406 BRW_VERTICAL_STRIDE_16,
407 BRW_WIDTH_16,
408 BRW_HORIZONTAL_STRIDE_1,
409 BRW_SWIZZLE_XYZW,
410 WRITEMASK_XYZW);
411 }
412
413 /** Construct float[8] register */
414 static inline struct brw_reg
415 brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
416 {
417 return brw_reg(file,
418 nr,
419 subnr,
420 0,
421 0,
422 BRW_REGISTER_TYPE_F,
423 BRW_VERTICAL_STRIDE_8,
424 BRW_WIDTH_8,
425 BRW_HORIZONTAL_STRIDE_1,
426 BRW_SWIZZLE_XYZW,
427 WRITEMASK_XYZW);
428 }
429
430 /** Construct float[4] register */
431 static inline struct brw_reg
432 brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
433 {
434 return brw_reg(file,
435 nr,
436 subnr,
437 0,
438 0,
439 BRW_REGISTER_TYPE_F,
440 BRW_VERTICAL_STRIDE_4,
441 BRW_WIDTH_4,
442 BRW_HORIZONTAL_STRIDE_1,
443 BRW_SWIZZLE_XYZW,
444 WRITEMASK_XYZW);
445 }
446
447 /** Construct float[2] register */
448 static inline struct brw_reg
449 brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
450 {
451 return brw_reg(file,
452 nr,
453 subnr,
454 0,
455 0,
456 BRW_REGISTER_TYPE_F,
457 BRW_VERTICAL_STRIDE_2,
458 BRW_WIDTH_2,
459 BRW_HORIZONTAL_STRIDE_1,
460 BRW_SWIZZLE_XYXY,
461 WRITEMASK_XY);
462 }
463
464 /** Construct float[1] register */
465 static inline struct brw_reg
466 brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
467 {
468 return brw_reg(file,
469 nr,
470 subnr,
471 0,
472 0,
473 BRW_REGISTER_TYPE_F,
474 BRW_VERTICAL_STRIDE_0,
475 BRW_WIDTH_1,
476 BRW_HORIZONTAL_STRIDE_0,
477 BRW_SWIZZLE_XXXX,
478 WRITEMASK_X);
479 }
480
481 static inline struct brw_reg
482 brw_vecn_reg(unsigned width, enum brw_reg_file file,
483 unsigned nr, unsigned subnr)
484 {
485 switch (width) {
486 case 1:
487 return brw_vec1_reg(file, nr, subnr);
488 case 2:
489 return brw_vec2_reg(file, nr, subnr);
490 case 4:
491 return brw_vec4_reg(file, nr, subnr);
492 case 8:
493 return brw_vec8_reg(file, nr, subnr);
494 case 16:
495 return brw_vec16_reg(file, nr, subnr);
496 default:
497 unreachable("Invalid register width");
498 }
499 }
500
501 static inline struct brw_reg
502 retype(struct brw_reg reg, enum brw_reg_type type)
503 {
504 reg.type = type;
505 return reg;
506 }
507
508 static inline struct brw_reg
509 firsthalf(struct brw_reg reg)
510 {
511 return reg;
512 }
513
514 static inline struct brw_reg
515 sechalf(struct brw_reg reg)
516 {
517 if (reg.vstride)
518 reg.nr++;
519 return reg;
520 }
521
522 static inline struct brw_reg
523 offset(struct brw_reg reg, unsigned delta)
524 {
525 reg.nr += delta;
526 return reg;
527 }
528
529
530 static inline struct brw_reg
531 byte_offset(struct brw_reg reg, unsigned bytes)
532 {
533 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
534 reg.nr = newoffset / REG_SIZE;
535 reg.subnr = newoffset % REG_SIZE;
536 return reg;
537 }
538
539 static inline struct brw_reg
540 suboffset(struct brw_reg reg, unsigned delta)
541 {
542 return byte_offset(reg, delta * type_sz(reg.type));
543 }
544
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)
548 {
549 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
550 }
551
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)
555 {
556 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
557 }
558
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)
562 {
563 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
564 }
565
566 static inline struct brw_reg
567 brw_ud1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
568 {
569 return retype(brw_vec1_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
570 }
571
572 static inline struct brw_reg
573 brw_imm_reg(enum brw_reg_type type)
574 {
575 return brw_reg(BRW_IMMEDIATE_VALUE,
576 0,
577 0,
578 0,
579 0,
580 type,
581 BRW_VERTICAL_STRIDE_0,
582 BRW_WIDTH_1,
583 BRW_HORIZONTAL_STRIDE_0,
584 0,
585 0);
586 }
587
588 /** Construct float immediate register */
589 static inline struct brw_reg
590 brw_imm_df(double df)
591 {
592 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
593 imm.df = df;
594 return imm;
595 }
596
597 static inline struct brw_reg
598 brw_imm_f(float f)
599 {
600 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
601 imm.f = f;
602 return imm;
603 }
604
605 /** Construct integer immediate register */
606 static inline struct brw_reg
607 brw_imm_d(int d)
608 {
609 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
610 imm.d = d;
611 return imm;
612 }
613
614 /** Construct uint immediate register */
615 static inline struct brw_reg
616 brw_imm_ud(unsigned ud)
617 {
618 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
619 imm.ud = ud;
620 return imm;
621 }
622
623 /** Construct ushort immediate register */
624 static inline struct brw_reg
625 brw_imm_uw(uint16_t uw)
626 {
627 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
628 imm.ud = uw | (uw << 16);
629 return imm;
630 }
631
632 /** Construct short immediate register */
633 static inline struct brw_reg
634 brw_imm_w(int16_t w)
635 {
636 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
637 imm.d = w | (w << 16);
638 return imm;
639 }
640
641 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
642 * numbers alias with _V and _VF below:
643 */
644
645 /** Construct vector of eight signed half-byte values */
646 static inline struct brw_reg
647 brw_imm_v(unsigned v)
648 {
649 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
650 imm.ud = v;
651 return imm;
652 }
653
654 /** Construct vector of eight unsigned half-byte values */
655 static inline struct brw_reg
656 brw_imm_uv(unsigned uv)
657 {
658 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
659 imm.ud = uv;
660 return imm;
661 }
662
663 /** Construct vector of four 8-bit float values */
664 static inline struct brw_reg
665 brw_imm_vf(unsigned v)
666 {
667 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
668 imm.ud = v;
669 return imm;
670 }
671
672 static inline struct brw_reg
673 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
674 {
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));
680 return imm;
681 }
682
683
684 static inline struct brw_reg
685 brw_address(struct brw_reg reg)
686 {
687 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
688 }
689
690 /** Construct float[1] general-purpose register */
691 static inline struct brw_reg
692 brw_vec1_grf(unsigned nr, unsigned subnr)
693 {
694 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
695 }
696
697 /** Construct float[2] general-purpose register */
698 static inline struct brw_reg
699 brw_vec2_grf(unsigned nr, unsigned subnr)
700 {
701 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
702 }
703
704 /** Construct float[4] general-purpose register */
705 static inline struct brw_reg
706 brw_vec4_grf(unsigned nr, unsigned subnr)
707 {
708 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
709 }
710
711 /** Construct float[8] general-purpose register */
712 static inline struct brw_reg
713 brw_vec8_grf(unsigned nr, unsigned subnr)
714 {
715 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
716 }
717
718 /** Construct float[16] general-purpose register */
719 static inline struct brw_reg
720 brw_vec16_grf(unsigned nr, unsigned subnr)
721 {
722 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
723 }
724
725
726 static inline struct brw_reg
727 brw_uw8_grf(unsigned nr, unsigned subnr)
728 {
729 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
730 }
731
732 static inline struct brw_reg
733 brw_uw16_grf(unsigned nr, unsigned subnr)
734 {
735 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
736 }
737
738
739 /** Construct null register (usually used for setting condition codes) */
740 static inline struct brw_reg
741 brw_null_reg(void)
742 {
743 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
744 }
745
746 static inline struct brw_reg
747 brw_null_vec(unsigned width)
748 {
749 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
750 }
751
752 static inline struct brw_reg
753 brw_address_reg(unsigned subnr)
754 {
755 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
756 }
757
758 /* If/else instructions break in align16 mode if writemask & swizzle
759 * aren't xyzw. This goes against the convention for other scalar
760 * regs:
761 */
762 static inline struct brw_reg
763 brw_ip_reg(void)
764 {
765 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
766 BRW_ARF_IP,
767 0,
768 0,
769 0,
770 BRW_REGISTER_TYPE_UD,
771 BRW_VERTICAL_STRIDE_4, /* ? */
772 BRW_WIDTH_1,
773 BRW_HORIZONTAL_STRIDE_0,
774 BRW_SWIZZLE_XYZW, /* NOTE! */
775 WRITEMASK_XYZW); /* NOTE! */
776 }
777
778 static inline struct brw_reg
779 brw_notification_reg(void)
780 {
781 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
782 BRW_ARF_NOTIFICATION_COUNT,
783 0,
784 0,
785 0,
786 BRW_REGISTER_TYPE_UD,
787 BRW_VERTICAL_STRIDE_0,
788 BRW_WIDTH_1,
789 BRW_HORIZONTAL_STRIDE_0,
790 BRW_SWIZZLE_XXXX,
791 WRITEMASK_X);
792 }
793
794 static inline struct brw_reg
795 brw_sr0_reg(unsigned subnr)
796 {
797 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_STATE, subnr);
798 }
799
800 static inline struct brw_reg
801 brw_acc_reg(unsigned width)
802 {
803 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
804 BRW_ARF_ACCUMULATOR, 0);
805 }
806
807 static inline struct brw_reg
808 brw_flag_reg(int reg, int subreg)
809 {
810 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
811 BRW_ARF_FLAG + reg, subreg);
812 }
813
814 /**
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
817 * the documentation.
818 */
819 static inline struct brw_reg
820 brw_mask_reg(unsigned subnr)
821 {
822 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
823 }
824
825 static inline struct brw_reg
826 brw_vmask_reg()
827 {
828 return brw_sr0_reg(3);
829 }
830
831 static inline struct brw_reg
832 brw_dmask_reg()
833 {
834 return brw_sr0_reg(2);
835 }
836
837 static inline struct brw_reg
838 brw_message_reg(unsigned nr)
839 {
840 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
841 }
842
843 static inline struct brw_reg
844 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
845 {
846 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
847 BRW_REGISTER_TYPE_UD);
848 }
849
850 /* This is almost always called with a numeric constant argument, so
851 * make things easy to evaluate at compile time:
852 */
853 static inline unsigned cvt(unsigned val)
854 {
855 switch (val) {
856 case 0: return 0;
857 case 1: return 1;
858 case 2: return 2;
859 case 4: return 3;
860 case 8: return 4;
861 case 16: return 5;
862 case 32: return 6;
863 }
864 return 0;
865 }
866
867 static inline struct brw_reg
868 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
869 {
870 reg.vstride = cvt(vstride);
871 reg.width = cvt(width) - 1;
872 reg.hstride = cvt(hstride);
873 return reg;
874 }
875
876 /**
877 * Multiply the vertical and horizontal stride of a register by the given
878 * factor \a s.
879 */
880 static inline struct brw_reg
881 spread(struct brw_reg reg, unsigned s)
882 {
883 if (s) {
884 assert(_mesa_is_pow_two(s));
885
886 if (reg.hstride)
887 reg.hstride += cvt(s) - 1;
888
889 if (reg.vstride)
890 reg.vstride += cvt(s) - 1;
891
892 return reg;
893 } else {
894 return stride(reg, 0, 1, 0);
895 }
896 }
897
898 static inline struct brw_reg
899 vec16(struct brw_reg reg)
900 {
901 return stride(reg, 16,16,1);
902 }
903
904 static inline struct brw_reg
905 vec8(struct brw_reg reg)
906 {
907 return stride(reg, 8,8,1);
908 }
909
910 static inline struct brw_reg
911 vec4(struct brw_reg reg)
912 {
913 return stride(reg, 4,4,1);
914 }
915
916 static inline struct brw_reg
917 vec2(struct brw_reg reg)
918 {
919 return stride(reg, 2,2,1);
920 }
921
922 static inline struct brw_reg
923 vec1(struct brw_reg reg)
924 {
925 return stride(reg, 0,1,0);
926 }
927
928
929 static inline struct brw_reg
930 get_element(struct brw_reg reg, unsigned elt)
931 {
932 return vec1(suboffset(reg, elt));
933 }
934
935 static inline struct brw_reg
936 get_element_ud(struct brw_reg reg, unsigned elt)
937 {
938 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
939 }
940
941 static inline struct brw_reg
942 get_element_d(struct brw_reg reg, unsigned elt)
943 {
944 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
945 }
946
947 static inline struct brw_reg
948 brw_swizzle(struct brw_reg reg, unsigned swz)
949 {
950 if (reg.file == BRW_IMMEDIATE_VALUE)
951 reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
952 else
953 reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
954
955 return reg;
956 }
957
958 static inline struct brw_reg
959 brw_writemask(struct brw_reg reg, unsigned mask)
960 {
961 assert(reg.file != BRW_IMMEDIATE_VALUE);
962 reg.writemask &= mask;
963 return reg;
964 }
965
966 static inline struct brw_reg
967 brw_set_writemask(struct brw_reg reg, unsigned mask)
968 {
969 assert(reg.file != BRW_IMMEDIATE_VALUE);
970 reg.writemask = mask;
971 return reg;
972 }
973
974 static inline unsigned
975 brw_writemask_for_size(unsigned n)
976 {
977 return (1 << n) - 1;
978 }
979
980 static inline unsigned
981 brw_writemask_for_component_packing(unsigned n, unsigned first_component)
982 {
983 assert(first_component + n <= 4);
984 return (((1 << n) - 1) << first_component);
985 }
986
987 static inline struct brw_reg
988 negate(struct brw_reg reg)
989 {
990 reg.negate ^= 1;
991 return reg;
992 }
993
994 static inline struct brw_reg
995 brw_abs(struct brw_reg reg)
996 {
997 reg.abs = 1;
998 reg.negate = 0;
999 return reg;
1000 }
1001
1002 /************************************************************************/
1003
1004 static inline struct brw_reg
1005 brw_vec4_indirect(unsigned subnr, int offset)
1006 {
1007 struct brw_reg reg = brw_vec4_grf(0, 0);
1008 reg.subnr = subnr;
1009 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1010 reg.indirect_offset = offset;
1011 return reg;
1012 }
1013
1014 static inline struct brw_reg
1015 brw_vec1_indirect(unsigned subnr, int offset)
1016 {
1017 struct brw_reg reg = brw_vec1_grf(0, 0);
1018 reg.subnr = subnr;
1019 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1020 reg.indirect_offset = offset;
1021 return reg;
1022 }
1023
1024 static inline struct brw_reg
1025 brw_VxH_indirect(unsigned subnr, int offset)
1026 {
1027 struct brw_reg reg = brw_vec1_grf(0, 0);
1028 reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
1029 reg.subnr = subnr;
1030 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1031 reg.indirect_offset = offset;
1032 return reg;
1033 }
1034
1035 static inline struct brw_reg
1036 deref_4f(struct brw_indirect ptr, int offset)
1037 {
1038 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1039 }
1040
1041 static inline struct brw_reg
1042 deref_1f(struct brw_indirect ptr, int offset)
1043 {
1044 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1045 }
1046
1047 static inline struct brw_reg
1048 deref_4b(struct brw_indirect ptr, int offset)
1049 {
1050 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
1051 }
1052
1053 static inline struct brw_reg
1054 deref_1uw(struct brw_indirect ptr, int offset)
1055 {
1056 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
1057 }
1058
1059 static inline struct brw_reg
1060 deref_1d(struct brw_indirect ptr, int offset)
1061 {
1062 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
1063 }
1064
1065 static inline struct brw_reg
1066 deref_1ud(struct brw_indirect ptr, int offset)
1067 {
1068 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
1069 }
1070
1071 static inline struct brw_reg
1072 get_addr_reg(struct brw_indirect ptr)
1073 {
1074 return brw_address_reg(ptr.addr_subnr);
1075 }
1076
1077 static inline struct brw_indirect
1078 brw_indirect_offset(struct brw_indirect ptr, int offset)
1079 {
1080 ptr.addr_offset += offset;
1081 return ptr;
1082 }
1083
1084 static inline struct brw_indirect
1085 brw_indirect(unsigned addr_subnr, int offset)
1086 {
1087 struct brw_indirect ptr;
1088 ptr.addr_subnr = addr_subnr;
1089 ptr.addr_offset = offset;
1090 ptr.pad = 0;
1091 return ptr;
1092 }
1093
1094 static inline bool
1095 region_matches(struct brw_reg reg, enum brw_vertical_stride v,
1096 enum brw_width w, enum brw_horizontal_stride h)
1097 {
1098 return reg.vstride == v &&
1099 reg.width == w &&
1100 reg.hstride == h;
1101 }
1102
1103 #define has_scalar_region(reg) \
1104 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1105 BRW_HORIZONTAL_STRIDE_0)
1106
1107 /* brw_packed_float.c */
1108 int brw_float_to_vf(float f);
1109 float brw_vf_to_float(unsigned char vf);
1110
1111 #ifdef __cplusplus
1112 }
1113 #endif
1114
1115 #endif