brw_reg.h revision 24be658d13b13fdb8a1977208038b4ba43bce4ac
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 52extern "C" { 53#endif 54 55struct brw_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_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) 87#define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0) 88 89static inline bool 90brw_is_single_value_swizzle(unsigned swiz) 91{ 92 return (swiz == BRW_SWIZZLE_XXXX || 93 swiz == BRW_SWIZZLE_YYYY || 94 swiz == BRW_SWIZZLE_ZZZZ || 95 swiz == BRW_SWIZZLE_WWWW); 96} 97 98/** 99 * Compute the swizzle obtained from the application of \p swz0 on the result 100 * of \p swz1. The argument ordering is expected to match function 101 * composition. 102 */ 103static inline unsigned 104brw_compose_swizzle(unsigned swz0, unsigned swz1) 105{ 106 return BRW_SWIZZLE4( 107 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)), 108 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)), 109 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)), 110 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3))); 111} 112 113/** 114 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask 115 * (AKA image). 116 */ 117static inline unsigned 118brw_apply_swizzle_to_mask(unsigned swz, unsigned mask) 119{ 120 unsigned result = 0; 121 122 for (unsigned i = 0; i < 4; i++) { 123 if (mask & (1 << BRW_GET_SWZ(swz, i))) 124 result |= 1 << i; 125 } 126 127 return result; 128} 129 130/** 131 * Return the result of applying the inverse of swizzle \p swz to shuffle the 132 * bits of \p mask (AKA preimage). Useful to find out which components are 133 * read from a swizzled source given the instruction writemask. 134 */ 135static inline unsigned 136brw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask) 137{ 138 unsigned result = 0; 139 140 for (unsigned i = 0; i < 4; i++) { 141 if (mask & (1 << i)) 142 result |= 1 << BRW_GET_SWZ(swz, i); 143 } 144 145 return result; 146} 147 148/** 149 * Construct an identity swizzle for the set of enabled channels given by \p 150 * mask. The result will only reference channels enabled in the provided \p 151 * mask, assuming that \p mask is non-zero. The constructed swizzle will 152 * satisfy the property that for any instruction OP and any mask: 153 * 154 * brw_OP(p, brw_writemask(dst, mask), 155 * brw_swizzle(src, brw_swizzle_for_mask(mask))); 156 * 157 * will be equivalent to the same instruction without swizzle: 158 * 159 * brw_OP(p, brw_writemask(dst, mask), src); 160 */ 161static inline unsigned 162brw_swizzle_for_mask(unsigned mask) 163{ 164 unsigned last = (mask ? ffs(mask) - 1 : 0); 165 unsigned swz[4]; 166 167 for (unsigned i = 0; i < 4; i++) 168 last = swz[i] = (mask & (1 << i) ? i : last); 169 170 return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 171} 172 173/** 174 * Construct an identity swizzle for the first \p n components of a vector. 175 * When only a subset of channels of a vec4 are used we don't want to 176 * reference the other channels, as that will tell optimization passes that 177 * those other channels are used. 178 */ 179static inline unsigned 180brw_swizzle_for_size(unsigned n) 181{ 182 return brw_swizzle_for_mask((1 << n) - 1); 183} 184 185/** 186 * Converse of brw_swizzle_for_mask(). Returns the mask of components 187 * accessed by the specified swizzle \p swz. 188 */ 189static inline unsigned 190brw_mask_for_swizzle(unsigned swz) 191{ 192 return brw_apply_inv_swizzle_to_mask(swz, ~0); 193} 194 195enum PACKED brw_reg_type { 196 BRW_REGISTER_TYPE_UD = 0, 197 BRW_REGISTER_TYPE_D, 198 BRW_REGISTER_TYPE_UW, 199 BRW_REGISTER_TYPE_W, 200 BRW_REGISTER_TYPE_F, 201 202 /** Non-immediates only: @{ */ 203 BRW_REGISTER_TYPE_UB, 204 BRW_REGISTER_TYPE_B, 205 /** @} */ 206 207 /** Immediates only: @{ */ 208 BRW_REGISTER_TYPE_UV, /* Gen6+ */ 209 BRW_REGISTER_TYPE_V, 210 BRW_REGISTER_TYPE_VF, 211 /** @} */ 212 213 BRW_REGISTER_TYPE_DF, /* Gen7+ (no immediates until Gen8+) */ 214 215 /* Gen8+ */ 216 BRW_REGISTER_TYPE_HF, 217 BRW_REGISTER_TYPE_UQ, 218 BRW_REGISTER_TYPE_Q, 219}; 220 221unsigned brw_reg_type_to_hw_type(const struct brw_device_info *devinfo, 222 enum brw_reg_type type, enum brw_reg_file file); 223const char *brw_reg_type_letters(unsigned brw_reg_type); 224 225#define REG_SIZE (8*4) 226 227/* These aren't hardware structs, just something useful for us to pass around: 228 * 229 * Align1 operation has a lot of control over input ranges. Used in 230 * WM programs to implement shaders decomposed into "channel serial" 231 * or "structure of array" form: 232 */ 233struct brw_reg { 234 enum brw_reg_type type:4; 235 enum brw_reg_file file:3; /* :2 hardware format */ 236 unsigned negate:1; /* source only */ 237 unsigned abs:1; /* source only */ 238 unsigned address_mode:1; /* relative addressing, hopefully! */ 239 unsigned pad0:1; 240 unsigned subnr:5; /* :1 in align16 */ 241 unsigned nr:16; 242 243 union { 244 struct { 245 unsigned swizzle:8; /* src only, align16 only */ 246 unsigned writemask:4; /* dest only, align16 only */ 247 int indirect_offset:10; /* relative addressing offset */ 248 unsigned vstride:4; /* source only */ 249 unsigned width:3; /* src only, align1 only */ 250 unsigned hstride:2; /* align1 only */ 251 unsigned pad1:1; 252 }; 253 254 float f; 255 int d; 256 unsigned ud; 257 }; 258}; 259 260 261struct brw_indirect { 262 unsigned addr_subnr:4; 263 int addr_offset:10; 264 unsigned pad:18; 265}; 266 267 268static inline unsigned 269type_sz(unsigned type) 270{ 271 switch(type) { 272 case BRW_REGISTER_TYPE_UQ: 273 case BRW_REGISTER_TYPE_Q: 274 return 8; 275 case BRW_REGISTER_TYPE_UD: 276 case BRW_REGISTER_TYPE_D: 277 case BRW_REGISTER_TYPE_F: 278 return 4; 279 case BRW_REGISTER_TYPE_UW: 280 case BRW_REGISTER_TYPE_W: 281 return 2; 282 case BRW_REGISTER_TYPE_UB: 283 case BRW_REGISTER_TYPE_B: 284 return 1; 285 default: 286 return 0; 287 } 288} 289 290static inline bool 291type_is_signed(unsigned type) 292{ 293 switch(type) { 294 case BRW_REGISTER_TYPE_D: 295 case BRW_REGISTER_TYPE_W: 296 case BRW_REGISTER_TYPE_F: 297 case BRW_REGISTER_TYPE_B: 298 case BRW_REGISTER_TYPE_V: 299 case BRW_REGISTER_TYPE_VF: 300 case BRW_REGISTER_TYPE_DF: 301 case BRW_REGISTER_TYPE_HF: 302 case BRW_REGISTER_TYPE_Q: 303 return true; 304 305 case BRW_REGISTER_TYPE_UD: 306 case BRW_REGISTER_TYPE_UW: 307 case BRW_REGISTER_TYPE_UB: 308 case BRW_REGISTER_TYPE_UV: 309 case BRW_REGISTER_TYPE_UQ: 310 return false; 311 312 default: 313 unreachable("not reached"); 314 } 315} 316 317/** 318 * Construct a brw_reg. 319 * \param file one of the BRW_x_REGISTER_FILE values 320 * \param nr register number/index 321 * \param subnr register sub number 322 * \param negate register negate modifier 323 * \param abs register abs modifier 324 * \param type one of BRW_REGISTER_TYPE_x 325 * \param vstride one of BRW_VERTICAL_STRIDE_x 326 * \param width one of BRW_WIDTH_x 327 * \param hstride one of BRW_HORIZONTAL_STRIDE_x 328 * \param swizzle one of BRW_SWIZZLE_x 329 * \param writemask WRITEMASK_X/Y/Z/W bitfield 330 */ 331static inline struct brw_reg 332brw_reg(enum brw_reg_file file, 333 unsigned nr, 334 unsigned subnr, 335 unsigned negate, 336 unsigned abs, 337 enum brw_reg_type type, 338 unsigned vstride, 339 unsigned width, 340 unsigned hstride, 341 unsigned swizzle, 342 unsigned writemask) 343{ 344 struct brw_reg reg; 345 if (file == BRW_GENERAL_REGISTER_FILE) 346 assert(nr < BRW_MAX_GRF); 347 else if (file == BRW_ARCHITECTURE_REGISTER_FILE) 348 assert(nr <= BRW_ARF_TIMESTAMP); 349 /* Asserting on the MRF register number requires to know the hardware gen 350 * (gen6 has 24 MRF registers), which we don't know here, so we assert 351 * for that in the generators and in brw_eu_emit.c 352 */ 353 354 reg.type = type; 355 reg.file = file; 356 reg.negate = negate; 357 reg.abs = abs; 358 reg.address_mode = BRW_ADDRESS_DIRECT; 359 reg.pad0 = 0; 360 reg.subnr = subnr * type_sz(type); 361 reg.nr = nr; 362 363 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to 364 * set swizzle and writemask to W, as the lower bits of subnr will 365 * be lost when converted to align16. This is probably too much to 366 * keep track of as you'd want it adjusted by suboffset(), etc. 367 * Perhaps fix up when converting to align16? 368 */ 369 reg.swizzle = swizzle; 370 reg.writemask = writemask; 371 reg.indirect_offset = 0; 372 reg.vstride = vstride; 373 reg.width = width; 374 reg.hstride = hstride; 375 reg.pad1 = 0; 376 return reg; 377} 378 379/** Construct float[16] register */ 380static inline struct brw_reg 381brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr) 382{ 383 return brw_reg(file, 384 nr, 385 subnr, 386 0, 387 0, 388 BRW_REGISTER_TYPE_F, 389 BRW_VERTICAL_STRIDE_16, 390 BRW_WIDTH_16, 391 BRW_HORIZONTAL_STRIDE_1, 392 BRW_SWIZZLE_XYZW, 393 WRITEMASK_XYZW); 394} 395 396/** Construct float[8] register */ 397static inline struct brw_reg 398brw_vec8_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_8, 407 BRW_WIDTH_8, 408 BRW_HORIZONTAL_STRIDE_1, 409 BRW_SWIZZLE_XYZW, 410 WRITEMASK_XYZW); 411} 412 413/** Construct float[4] register */ 414static inline struct brw_reg 415brw_vec4_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_4, 424 BRW_WIDTH_4, 425 BRW_HORIZONTAL_STRIDE_1, 426 BRW_SWIZZLE_XYZW, 427 WRITEMASK_XYZW); 428} 429 430/** Construct float[2] register */ 431static inline struct brw_reg 432brw_vec2_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_2, 441 BRW_WIDTH_2, 442 BRW_HORIZONTAL_STRIDE_1, 443 BRW_SWIZZLE_XYXY, 444 WRITEMASK_XY); 445} 446 447/** Construct float[1] register */ 448static inline struct brw_reg 449brw_vec1_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_0, 458 BRW_WIDTH_1, 459 BRW_HORIZONTAL_STRIDE_0, 460 BRW_SWIZZLE_XXXX, 461 WRITEMASK_X); 462} 463 464static inline struct brw_reg 465brw_vecn_reg(unsigned width, enum brw_reg_file file, 466 unsigned nr, unsigned subnr) 467{ 468 switch (width) { 469 case 1: 470 return brw_vec1_reg(file, nr, subnr); 471 case 2: 472 return brw_vec2_reg(file, nr, subnr); 473 case 4: 474 return brw_vec4_reg(file, nr, subnr); 475 case 8: 476 return brw_vec8_reg(file, nr, subnr); 477 case 16: 478 return brw_vec16_reg(file, nr, subnr); 479 default: 480 unreachable("Invalid register width"); 481 } 482} 483 484static inline struct brw_reg 485retype(struct brw_reg reg, enum brw_reg_type type) 486{ 487 reg.type = type; 488 return reg; 489} 490 491static inline struct brw_reg 492firsthalf(struct brw_reg reg) 493{ 494 return reg; 495} 496 497static inline struct brw_reg 498sechalf(struct brw_reg reg) 499{ 500 if (reg.vstride) 501 reg.nr++; 502 return reg; 503} 504 505static inline struct brw_reg 506suboffset(struct brw_reg reg, unsigned delta) 507{ 508 reg.subnr += delta * type_sz(reg.type); 509 return reg; 510} 511 512 513static inline struct brw_reg 514offset(struct brw_reg reg, unsigned delta) 515{ 516 reg.nr += delta; 517 return reg; 518} 519 520 521static inline struct brw_reg 522byte_offset(struct brw_reg reg, unsigned bytes) 523{ 524 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes; 525 reg.nr = newoffset / REG_SIZE; 526 reg.subnr = newoffset % REG_SIZE; 527 return reg; 528} 529 530 531/** Construct unsigned word[16] register */ 532static inline struct brw_reg 533brw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr) 534{ 535 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); 536} 537 538/** Construct unsigned word[8] register */ 539static inline struct brw_reg 540brw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr) 541{ 542 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); 543} 544 545/** Construct unsigned word[1] register */ 546static inline struct brw_reg 547brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr) 548{ 549 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); 550} 551 552static inline struct brw_reg 553brw_imm_reg(enum brw_reg_type type) 554{ 555 return brw_reg(BRW_IMMEDIATE_VALUE, 556 0, 557 0, 558 0, 559 0, 560 type, 561 BRW_VERTICAL_STRIDE_0, 562 BRW_WIDTH_1, 563 BRW_HORIZONTAL_STRIDE_0, 564 0, 565 0); 566} 567 568/** Construct float immediate register */ 569static inline struct brw_reg 570brw_imm_f(float f) 571{ 572 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F); 573 imm.f = f; 574 return imm; 575} 576 577/** Construct integer immediate register */ 578static inline struct brw_reg 579brw_imm_d(int d) 580{ 581 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D); 582 imm.d = d; 583 return imm; 584} 585 586/** Construct uint immediate register */ 587static inline struct brw_reg 588brw_imm_ud(unsigned ud) 589{ 590 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD); 591 imm.ud = ud; 592 return imm; 593} 594 595/** Construct ushort immediate register */ 596static inline struct brw_reg 597brw_imm_uw(uint16_t uw) 598{ 599 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW); 600 imm.ud = uw | (uw << 16); 601 return imm; 602} 603 604/** Construct short immediate register */ 605static inline struct brw_reg 606brw_imm_w(int16_t w) 607{ 608 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W); 609 imm.d = w | (w << 16); 610 return imm; 611} 612 613/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type 614 * numbers alias with _V and _VF below: 615 */ 616 617/** Construct vector of eight signed half-byte values */ 618static inline struct brw_reg 619brw_imm_v(unsigned v) 620{ 621 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V); 622 imm.ud = v; 623 return imm; 624} 625 626/** Construct vector of eight unsigned half-byte values */ 627static inline struct brw_reg 628brw_imm_uv(unsigned uv) 629{ 630 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV); 631 imm.ud = uv; 632 return imm; 633} 634 635/** Construct vector of four 8-bit float values */ 636static inline struct brw_reg 637brw_imm_vf(unsigned v) 638{ 639 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); 640 imm.ud = v; 641 return imm; 642} 643 644static inline struct brw_reg 645brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) 646{ 647 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); 648 imm.vstride = BRW_VERTICAL_STRIDE_0; 649 imm.width = BRW_WIDTH_4; 650 imm.hstride = BRW_HORIZONTAL_STRIDE_1; 651 imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24)); 652 return imm; 653} 654 655 656static inline struct brw_reg 657brw_address(struct brw_reg reg) 658{ 659 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr); 660} 661 662/** Construct float[1] general-purpose register */ 663static inline struct brw_reg 664brw_vec1_grf(unsigned nr, unsigned subnr) 665{ 666 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 667} 668 669/** Construct float[2] general-purpose register */ 670static inline struct brw_reg 671brw_vec2_grf(unsigned nr, unsigned subnr) 672{ 673 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 674} 675 676/** Construct float[4] general-purpose register */ 677static inline struct brw_reg 678brw_vec4_grf(unsigned nr, unsigned subnr) 679{ 680 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 681} 682 683/** Construct float[8] general-purpose register */ 684static inline struct brw_reg 685brw_vec8_grf(unsigned nr, unsigned subnr) 686{ 687 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 688} 689 690/** Construct float[16] general-purpose register */ 691static inline struct brw_reg 692brw_vec16_grf(unsigned nr, unsigned subnr) 693{ 694 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 695} 696 697 698static inline struct brw_reg 699brw_uw8_grf(unsigned nr, unsigned subnr) 700{ 701 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 702} 703 704static inline struct brw_reg 705brw_uw16_grf(unsigned nr, unsigned subnr) 706{ 707 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 708} 709 710 711/** Construct null register (usually used for setting condition codes) */ 712static inline struct brw_reg 713brw_null_reg(void) 714{ 715 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0); 716} 717 718static inline struct brw_reg 719brw_null_vec(unsigned width) 720{ 721 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0); 722} 723 724static inline struct brw_reg 725brw_address_reg(unsigned subnr) 726{ 727 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr); 728} 729 730/* If/else instructions break in align16 mode if writemask & swizzle 731 * aren't xyzw. This goes against the convention for other scalar 732 * regs: 733 */ 734static inline struct brw_reg 735brw_ip_reg(void) 736{ 737 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, 738 BRW_ARF_IP, 739 0, 740 0, 741 0, 742 BRW_REGISTER_TYPE_UD, 743 BRW_VERTICAL_STRIDE_4, /* ? */ 744 BRW_WIDTH_1, 745 BRW_HORIZONTAL_STRIDE_0, 746 BRW_SWIZZLE_XYZW, /* NOTE! */ 747 WRITEMASK_XYZW); /* NOTE! */ 748} 749 750static inline struct brw_reg 751brw_notification_reg(void) 752{ 753 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, 754 BRW_ARF_NOTIFICATION_COUNT, 755 0, 756 0, 757 0, 758 BRW_REGISTER_TYPE_UD, 759 BRW_VERTICAL_STRIDE_0, 760 BRW_WIDTH_1, 761 BRW_HORIZONTAL_STRIDE_0, 762 BRW_SWIZZLE_XXXX, 763 WRITEMASK_X); 764} 765 766static inline struct brw_reg 767brw_acc_reg(unsigned width) 768{ 769 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, 770 BRW_ARF_ACCUMULATOR, 0); 771} 772 773static inline struct brw_reg 774brw_flag_reg(int reg, int subreg) 775{ 776 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, 777 BRW_ARF_FLAG + reg, subreg); 778} 779 780/** 781 * Return the mask register present in Gen4-5, or the related register present 782 * in Gen7.5 and later hardware referred to as "channel enable" register in 783 * the documentation. 784 */ 785static inline struct brw_reg 786brw_mask_reg(unsigned subnr) 787{ 788 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr); 789} 790 791static inline struct brw_reg 792brw_message_reg(unsigned nr) 793{ 794 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0); 795} 796 797static inline struct brw_reg 798brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr) 799{ 800 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr), 801 BRW_REGISTER_TYPE_UD); 802} 803 804/* This is almost always called with a numeric constant argument, so 805 * make things easy to evaluate at compile time: 806 */ 807static inline unsigned cvt(unsigned val) 808{ 809 switch (val) { 810 case 0: return 0; 811 case 1: return 1; 812 case 2: return 2; 813 case 4: return 3; 814 case 8: return 4; 815 case 16: return 5; 816 case 32: return 6; 817 } 818 return 0; 819} 820 821static inline struct brw_reg 822stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride) 823{ 824 reg.vstride = cvt(vstride); 825 reg.width = cvt(width) - 1; 826 reg.hstride = cvt(hstride); 827 return reg; 828} 829 830/** 831 * Multiply the vertical and horizontal stride of a register by the given 832 * factor \a s. 833 */ 834static inline struct brw_reg 835spread(struct brw_reg reg, unsigned s) 836{ 837 if (s) { 838 assert(_mesa_is_pow_two(s)); 839 840 if (reg.hstride) 841 reg.hstride += cvt(s) - 1; 842 843 if (reg.vstride) 844 reg.vstride += cvt(s) - 1; 845 846 return reg; 847 } else { 848 return stride(reg, 0, 1, 0); 849 } 850} 851 852static inline struct brw_reg 853vec16(struct brw_reg reg) 854{ 855 return stride(reg, 16,16,1); 856} 857 858static inline struct brw_reg 859vec8(struct brw_reg reg) 860{ 861 return stride(reg, 8,8,1); 862} 863 864static inline struct brw_reg 865vec4(struct brw_reg reg) 866{ 867 return stride(reg, 4,4,1); 868} 869 870static inline struct brw_reg 871vec2(struct brw_reg reg) 872{ 873 return stride(reg, 2,2,1); 874} 875 876static inline struct brw_reg 877vec1(struct brw_reg reg) 878{ 879 return stride(reg, 0,1,0); 880} 881 882 883static inline struct brw_reg 884get_element(struct brw_reg reg, unsigned elt) 885{ 886 return vec1(suboffset(reg, elt)); 887} 888 889static inline struct brw_reg 890get_element_ud(struct brw_reg reg, unsigned elt) 891{ 892 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt)); 893} 894 895static inline struct brw_reg 896get_element_d(struct brw_reg reg, unsigned elt) 897{ 898 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt)); 899} 900 901 902static inline struct brw_reg 903brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w) 904{ 905 assert(reg.file != BRW_IMMEDIATE_VALUE); 906 907 reg.swizzle = brw_compose_swizzle(BRW_SWIZZLE4(x, y, z, w), 908 reg.swizzle); 909 return reg; 910} 911 912 913static inline struct brw_reg 914brw_swizzle1(struct brw_reg reg, unsigned x) 915{ 916 return brw_swizzle(reg, x, x, x, x); 917} 918 919static inline struct brw_reg 920brw_writemask(struct brw_reg reg, unsigned mask) 921{ 922 assert(reg.file != BRW_IMMEDIATE_VALUE); 923 reg.writemask &= mask; 924 return reg; 925} 926 927static inline struct brw_reg 928brw_set_writemask(struct brw_reg reg, unsigned mask) 929{ 930 assert(reg.file != BRW_IMMEDIATE_VALUE); 931 reg.writemask = mask; 932 return reg; 933} 934 935static inline unsigned 936brw_writemask_for_size(unsigned n) 937{ 938 return (1 << n) - 1; 939} 940 941static inline struct brw_reg 942negate(struct brw_reg reg) 943{ 944 reg.negate ^= 1; 945 return reg; 946} 947 948static inline struct brw_reg 949brw_abs(struct brw_reg reg) 950{ 951 reg.abs = 1; 952 reg.negate = 0; 953 return reg; 954} 955 956/************************************************************************/ 957 958static inline struct brw_reg 959brw_vec4_indirect(unsigned subnr, int offset) 960{ 961 struct brw_reg reg = brw_vec4_grf(0, 0); 962 reg.subnr = subnr; 963 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; 964 reg.indirect_offset = offset; 965 return reg; 966} 967 968static inline struct brw_reg 969brw_vec1_indirect(unsigned subnr, int offset) 970{ 971 struct brw_reg reg = brw_vec1_grf(0, 0); 972 reg.subnr = subnr; 973 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; 974 reg.indirect_offset = offset; 975 return reg; 976} 977 978static inline struct brw_reg 979brw_VxH_indirect(unsigned subnr, int offset) 980{ 981 struct brw_reg reg = brw_vec1_grf(0, 0); 982 reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL; 983 reg.subnr = subnr; 984 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; 985 reg.indirect_offset = offset; 986 return reg; 987} 988 989static inline struct brw_reg 990deref_4f(struct brw_indirect ptr, int offset) 991{ 992 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset); 993} 994 995static inline struct brw_reg 996deref_1f(struct brw_indirect ptr, int offset) 997{ 998 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset); 999} 1000 1001static inline struct brw_reg 1002deref_4b(struct brw_indirect ptr, int offset) 1003{ 1004 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B); 1005} 1006 1007static inline struct brw_reg 1008deref_1uw(struct brw_indirect ptr, int offset) 1009{ 1010 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW); 1011} 1012 1013static inline struct brw_reg 1014deref_1d(struct brw_indirect ptr, int offset) 1015{ 1016 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D); 1017} 1018 1019static inline struct brw_reg 1020deref_1ud(struct brw_indirect ptr, int offset) 1021{ 1022 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD); 1023} 1024 1025static inline struct brw_reg 1026get_addr_reg(struct brw_indirect ptr) 1027{ 1028 return brw_address_reg(ptr.addr_subnr); 1029} 1030 1031static inline struct brw_indirect 1032brw_indirect_offset(struct brw_indirect ptr, int offset) 1033{ 1034 ptr.addr_offset += offset; 1035 return ptr; 1036} 1037 1038static inline struct brw_indirect 1039brw_indirect(unsigned addr_subnr, int offset) 1040{ 1041 struct brw_indirect ptr; 1042 ptr.addr_subnr = addr_subnr; 1043 ptr.addr_offset = offset; 1044 ptr.pad = 0; 1045 return ptr; 1046} 1047 1048static inline bool 1049region_matches(struct brw_reg reg, enum brw_vertical_stride v, 1050 enum brw_width w, enum brw_horizontal_stride h) 1051{ 1052 return reg.vstride == v && 1053 reg.width == w && 1054 reg.hstride == h; 1055} 1056 1057#define has_scalar_region(reg) \ 1058 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \ 1059 BRW_HORIZONTAL_STRIDE_0) 1060 1061/* brw_packed_float.c */ 1062int brw_float_to_vf(float f); 1063float brw_vf_to_float(unsigned char vf); 1064 1065#ifdef __cplusplus 1066} 1067#endif 1068 1069#endif 1070