1 /* 2 Copyright (C) Intel Corp. 2006. All Rights Reserved. 3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) 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 <keith (at) tungstengraphics.com> 30 */ 31 32 33 #ifndef BRW_EU_H 34 #define BRW_EU_H 35 36 #include <stdbool.h> 37 #include "brw_structs.h" 38 #include "brw_defines.h" 39 #include "program/prog_instruction.h" 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6)) 46 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3) 47 48 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3) 49 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3) 50 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0) 51 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1) 52 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2) 53 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3) 54 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1) 55 56 static inline bool brw_is_single_value_swizzle(int swiz) 57 { 58 return (swiz == BRW_SWIZZLE_XXXX || 59 swiz == BRW_SWIZZLE_YYYY || 60 swiz == BRW_SWIZZLE_ZZZZ || 61 swiz == BRW_SWIZZLE_WWWW); 62 } 63 64 #define REG_SIZE (8*4) 65 66 67 /* These aren't hardware structs, just something useful for us to pass around: 68 * 69 * Align1 operation has a lot of control over input ranges. Used in 70 * WM programs to implement shaders decomposed into "channel serial" 71 * or "structure of array" form: 72 */ 73 struct brw_reg 74 { 75 GLuint type:4; 76 GLuint file:2; 77 GLuint nr:8; 78 GLuint subnr:5; /* :1 in align16 */ 79 GLuint negate:1; /* source only */ 80 GLuint abs:1; /* source only */ 81 GLuint vstride:4; /* source only */ 82 GLuint width:3; /* src only, align1 only */ 83 GLuint hstride:2; /* align1 only */ 84 GLuint address_mode:1; /* relative addressing, hopefully! */ 85 GLuint pad0:1; 86 87 union { 88 struct { 89 GLuint swizzle:8; /* src only, align16 only */ 90 GLuint writemask:4; /* dest only, align16 only */ 91 GLint indirect_offset:10; /* relative addressing offset */ 92 GLuint pad1:10; /* two dwords total */ 93 } bits; 94 95 GLfloat f; 96 GLint d; 97 GLuint ud; 98 } dw1; 99 }; 100 101 102 struct brw_indirect { 103 GLuint addr_subnr:4; 104 GLint addr_offset:10; 105 GLuint pad:18; 106 }; 107 108 109 #define BRW_EU_MAX_INSN_STACK 5 110 111 struct brw_compile { 112 struct brw_instruction *store; 113 int store_size; 114 GLuint nr_insn; 115 116 void *mem_ctx; 117 118 /* Allow clients to push/pop instruction state: 119 */ 120 struct brw_instruction stack[BRW_EU_MAX_INSN_STACK]; 121 bool compressed_stack[BRW_EU_MAX_INSN_STACK]; 122 struct brw_instruction *current; 123 124 GLuint flag_value; 125 bool single_program_flow; 126 bool compressed; 127 struct brw_context *brw; 128 129 /* Control flow stacks: 130 * - if_stack contains IF and ELSE instructions which must be patched 131 * (and popped) once the matching ENDIF instruction is encountered. 132 * 133 * Just store the instruction pointer(an index). 134 */ 135 int *if_stack; 136 int if_stack_depth; 137 int if_stack_array_size; 138 139 /** 140 * loop_stack contains the instruction pointers of the starts of loops which 141 * must be patched (and popped) once the matching WHILE instruction is 142 * encountered. 143 */ 144 int *loop_stack; 145 /** 146 * pre-gen6, the BREAK and CONT instructions had to tell how many IF/ENDIF 147 * blocks they were popping out of, to fix up the mask stack. This tracks 148 * the IF/ENDIF nesting in each current nested loop level. 149 */ 150 int *if_depth_in_loop; 151 int loop_stack_depth; 152 int loop_stack_array_size; 153 }; 154 155 static INLINE int type_sz( GLuint type ) 156 { 157 switch( type ) { 158 case BRW_REGISTER_TYPE_UD: 159 case BRW_REGISTER_TYPE_D: 160 case BRW_REGISTER_TYPE_F: 161 return 4; 162 case BRW_REGISTER_TYPE_HF: 163 case BRW_REGISTER_TYPE_UW: 164 case BRW_REGISTER_TYPE_W: 165 return 2; 166 case BRW_REGISTER_TYPE_UB: 167 case BRW_REGISTER_TYPE_B: 168 return 1; 169 default: 170 return 0; 171 } 172 } 173 174 /** 175 * Construct a brw_reg. 176 * \param file one of the BRW_x_REGISTER_FILE values 177 * \param nr register number/index 178 * \param subnr register sub number 179 * \param type one of BRW_REGISTER_TYPE_x 180 * \param vstride one of BRW_VERTICAL_STRIDE_x 181 * \param width one of BRW_WIDTH_x 182 * \param hstride one of BRW_HORIZONTAL_STRIDE_x 183 * \param swizzle one of BRW_SWIZZLE_x 184 * \param writemask WRITEMASK_X/Y/Z/W bitfield 185 */ 186 static INLINE struct brw_reg brw_reg( GLuint file, 187 GLuint nr, 188 GLuint subnr, 189 GLuint type, 190 GLuint vstride, 191 GLuint width, 192 GLuint hstride, 193 GLuint swizzle, 194 GLuint writemask ) 195 { 196 struct brw_reg reg; 197 if (file == BRW_GENERAL_REGISTER_FILE) 198 assert(nr < BRW_MAX_GRF); 199 else if (file == BRW_MESSAGE_REGISTER_FILE) 200 assert((nr & ~(1 << 7)) < BRW_MAX_MRF); 201 else if (file == BRW_ARCHITECTURE_REGISTER_FILE) 202 assert(nr <= BRW_ARF_IP); 203 204 reg.type = type; 205 reg.file = file; 206 reg.nr = nr; 207 reg.subnr = subnr * type_sz(type); 208 reg.negate = 0; 209 reg.abs = 0; 210 reg.vstride = vstride; 211 reg.width = width; 212 reg.hstride = hstride; 213 reg.address_mode = BRW_ADDRESS_DIRECT; 214 reg.pad0 = 0; 215 216 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to 217 * set swizzle and writemask to W, as the lower bits of subnr will 218 * be lost when converted to align16. This is probably too much to 219 * keep track of as you'd want it adjusted by suboffset(), etc. 220 * Perhaps fix up when converting to align16? 221 */ 222 reg.dw1.bits.swizzle = swizzle; 223 reg.dw1.bits.writemask = writemask; 224 reg.dw1.bits.indirect_offset = 0; 225 reg.dw1.bits.pad1 = 0; 226 return reg; 227 } 228 229 /** Construct float[16] register */ 230 static INLINE struct brw_reg brw_vec16_reg( GLuint file, 231 GLuint nr, 232 GLuint subnr ) 233 { 234 return brw_reg(file, 235 nr, 236 subnr, 237 BRW_REGISTER_TYPE_F, 238 BRW_VERTICAL_STRIDE_16, 239 BRW_WIDTH_16, 240 BRW_HORIZONTAL_STRIDE_1, 241 BRW_SWIZZLE_XYZW, 242 WRITEMASK_XYZW); 243 } 244 245 /** Construct float[8] register */ 246 static INLINE struct brw_reg brw_vec8_reg( GLuint file, 247 GLuint nr, 248 GLuint subnr ) 249 { 250 return brw_reg(file, 251 nr, 252 subnr, 253 BRW_REGISTER_TYPE_F, 254 BRW_VERTICAL_STRIDE_8, 255 BRW_WIDTH_8, 256 BRW_HORIZONTAL_STRIDE_1, 257 BRW_SWIZZLE_XYZW, 258 WRITEMASK_XYZW); 259 } 260 261 /** Construct float[4] register */ 262 static INLINE struct brw_reg brw_vec4_reg( GLuint file, 263 GLuint nr, 264 GLuint subnr ) 265 { 266 return brw_reg(file, 267 nr, 268 subnr, 269 BRW_REGISTER_TYPE_F, 270 BRW_VERTICAL_STRIDE_4, 271 BRW_WIDTH_4, 272 BRW_HORIZONTAL_STRIDE_1, 273 BRW_SWIZZLE_XYZW, 274 WRITEMASK_XYZW); 275 } 276 277 /** Construct float[2] register */ 278 static INLINE struct brw_reg brw_vec2_reg( GLuint file, 279 GLuint nr, 280 GLuint subnr ) 281 { 282 return brw_reg(file, 283 nr, 284 subnr, 285 BRW_REGISTER_TYPE_F, 286 BRW_VERTICAL_STRIDE_2, 287 BRW_WIDTH_2, 288 BRW_HORIZONTAL_STRIDE_1, 289 BRW_SWIZZLE_XYXY, 290 WRITEMASK_XY); 291 } 292 293 /** Construct float[1] register */ 294 static INLINE struct brw_reg brw_vec1_reg( GLuint file, 295 GLuint nr, 296 GLuint subnr ) 297 { 298 return brw_reg(file, 299 nr, 300 subnr, 301 BRW_REGISTER_TYPE_F, 302 BRW_VERTICAL_STRIDE_0, 303 BRW_WIDTH_1, 304 BRW_HORIZONTAL_STRIDE_0, 305 BRW_SWIZZLE_XXXX, 306 WRITEMASK_X); 307 } 308 309 310 static INLINE struct brw_reg retype( struct brw_reg reg, 311 GLuint type ) 312 { 313 reg.type = type; 314 return reg; 315 } 316 317 static inline struct brw_reg 318 sechalf(struct brw_reg reg) 319 { 320 if (reg.vstride) 321 reg.nr++; 322 return reg; 323 } 324 325 static INLINE struct brw_reg suboffset( struct brw_reg reg, 326 GLuint delta ) 327 { 328 reg.subnr += delta * type_sz(reg.type); 329 return reg; 330 } 331 332 333 static INLINE struct brw_reg offset( struct brw_reg reg, 334 GLuint delta ) 335 { 336 reg.nr += delta; 337 return reg; 338 } 339 340 341 static INLINE struct brw_reg byte_offset( struct brw_reg reg, 342 GLuint bytes ) 343 { 344 GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes; 345 reg.nr = newoffset / REG_SIZE; 346 reg.subnr = newoffset % REG_SIZE; 347 return reg; 348 } 349 350 351 /** Construct unsigned word[16] register */ 352 static INLINE struct brw_reg brw_uw16_reg( GLuint file, 353 GLuint nr, 354 GLuint subnr ) 355 { 356 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); 357 } 358 359 /** Construct unsigned word[8] register */ 360 static INLINE struct brw_reg brw_uw8_reg( GLuint file, 361 GLuint nr, 362 GLuint subnr ) 363 { 364 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); 365 } 366 367 /** Construct unsigned word[1] register */ 368 static INLINE struct brw_reg brw_uw1_reg( GLuint file, 369 GLuint nr, 370 GLuint subnr ) 371 { 372 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); 373 } 374 375 static INLINE struct brw_reg brw_imm_reg( GLuint type ) 376 { 377 return brw_reg( BRW_IMMEDIATE_VALUE, 378 0, 379 0, 380 type, 381 BRW_VERTICAL_STRIDE_0, 382 BRW_WIDTH_1, 383 BRW_HORIZONTAL_STRIDE_0, 384 0, 385 0); 386 } 387 388 /** Construct float immediate register */ 389 static INLINE struct brw_reg brw_imm_f( GLfloat f ) 390 { 391 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F); 392 imm.dw1.f = f; 393 return imm; 394 } 395 396 /** Construct integer immediate register */ 397 static INLINE struct brw_reg brw_imm_d( GLint d ) 398 { 399 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D); 400 imm.dw1.d = d; 401 return imm; 402 } 403 404 /** Construct uint immediate register */ 405 static INLINE struct brw_reg brw_imm_ud( GLuint ud ) 406 { 407 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD); 408 imm.dw1.ud = ud; 409 return imm; 410 } 411 412 /** Construct ushort immediate register */ 413 static INLINE struct brw_reg brw_imm_uw( GLushort uw ) 414 { 415 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW); 416 imm.dw1.ud = uw | (uw << 16); 417 return imm; 418 } 419 420 /** Construct short immediate register */ 421 static INLINE struct brw_reg brw_imm_w( GLshort w ) 422 { 423 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W); 424 imm.dw1.d = w | (w << 16); 425 return imm; 426 } 427 428 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type 429 * numbers alias with _V and _VF below: 430 */ 431 432 /** Construct vector of eight signed half-byte values */ 433 static INLINE struct brw_reg brw_imm_v( GLuint v ) 434 { 435 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V); 436 imm.vstride = BRW_VERTICAL_STRIDE_0; 437 imm.width = BRW_WIDTH_8; 438 imm.hstride = BRW_HORIZONTAL_STRIDE_1; 439 imm.dw1.ud = v; 440 return imm; 441 } 442 443 /** Construct vector of four 8-bit float values */ 444 static INLINE struct brw_reg brw_imm_vf( GLuint v ) 445 { 446 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); 447 imm.vstride = BRW_VERTICAL_STRIDE_0; 448 imm.width = BRW_WIDTH_4; 449 imm.hstride = BRW_HORIZONTAL_STRIDE_1; 450 imm.dw1.ud = v; 451 return imm; 452 } 453 454 #define VF_ZERO 0x0 455 #define VF_ONE 0x30 456 #define VF_NEG (1<<7) 457 458 static INLINE struct brw_reg brw_imm_vf4( GLuint v0, 459 GLuint v1, 460 GLuint v2, 461 GLuint v3) 462 { 463 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); 464 imm.vstride = BRW_VERTICAL_STRIDE_0; 465 imm.width = BRW_WIDTH_4; 466 imm.hstride = BRW_HORIZONTAL_STRIDE_1; 467 imm.dw1.ud = ((v0 << 0) | 468 (v1 << 8) | 469 (v2 << 16) | 470 (v3 << 24)); 471 return imm; 472 } 473 474 475 static INLINE struct brw_reg brw_address( struct brw_reg reg ) 476 { 477 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr); 478 } 479 480 /** Construct float[1] general-purpose register */ 481 static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr ) 482 { 483 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 484 } 485 486 /** Construct float[2] general-purpose register */ 487 static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr ) 488 { 489 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 490 } 491 492 /** Construct float[4] general-purpose register */ 493 static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr ) 494 { 495 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 496 } 497 498 /** Construct float[8] general-purpose register */ 499 static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr ) 500 { 501 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 502 } 503 504 505 static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr ) 506 { 507 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 508 } 509 510 static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr ) 511 { 512 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); 513 } 514 515 516 /** Construct null register (usually used for setting condition codes) */ 517 static INLINE struct brw_reg brw_null_reg( void ) 518 { 519 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 520 BRW_ARF_NULL, 521 0); 522 } 523 524 static INLINE struct brw_reg brw_address_reg( GLuint subnr ) 525 { 526 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, 527 BRW_ARF_ADDRESS, 528 subnr); 529 } 530 531 /* If/else instructions break in align16 mode if writemask & swizzle 532 * aren't xyzw. This goes against the convention for other scalar 533 * regs: 534 */ 535 static INLINE struct brw_reg brw_ip_reg( void ) 536 { 537 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, 538 BRW_ARF_IP, 539 0, 540 BRW_REGISTER_TYPE_UD, 541 BRW_VERTICAL_STRIDE_4, /* ? */ 542 BRW_WIDTH_1, 543 BRW_HORIZONTAL_STRIDE_0, 544 BRW_SWIZZLE_XYZW, /* NOTE! */ 545 WRITEMASK_XYZW); /* NOTE! */ 546 } 547 548 static INLINE struct brw_reg brw_acc_reg( void ) 549 { 550 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 551 BRW_ARF_ACCUMULATOR, 552 0); 553 } 554 555 static INLINE struct brw_reg brw_notification_1_reg(void) 556 { 557 558 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, 559 BRW_ARF_NOTIFICATION_COUNT, 560 1, 561 BRW_REGISTER_TYPE_UD, 562 BRW_VERTICAL_STRIDE_0, 563 BRW_WIDTH_1, 564 BRW_HORIZONTAL_STRIDE_0, 565 BRW_SWIZZLE_XXXX, 566 WRITEMASK_X); 567 } 568 569 570 static INLINE struct brw_reg brw_flag_reg( void ) 571 { 572 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, 573 BRW_ARF_FLAG, 574 0); 575 } 576 577 578 static INLINE struct brw_reg brw_mask_reg( GLuint subnr ) 579 { 580 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, 581 BRW_ARF_MASK, 582 subnr); 583 } 584 585 static INLINE struct brw_reg brw_message_reg( GLuint nr ) 586 { 587 assert((nr & ~(1 << 7)) < BRW_MAX_MRF); 588 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 589 nr, 590 0); 591 } 592 593 594 595 596 /* This is almost always called with a numeric constant argument, so 597 * make things easy to evaluate at compile time: 598 */ 599 static INLINE GLuint cvt( GLuint val ) 600 { 601 switch (val) { 602 case 0: return 0; 603 case 1: return 1; 604 case 2: return 2; 605 case 4: return 3; 606 case 8: return 4; 607 case 16: return 5; 608 case 32: return 6; 609 } 610 return 0; 611 } 612 613 static INLINE struct brw_reg stride( struct brw_reg reg, 614 GLuint vstride, 615 GLuint width, 616 GLuint hstride ) 617 { 618 reg.vstride = cvt(vstride); 619 reg.width = cvt(width) - 1; 620 reg.hstride = cvt(hstride); 621 return reg; 622 } 623 624 625 static INLINE struct brw_reg vec16( struct brw_reg reg ) 626 { 627 return stride(reg, 16,16,1); 628 } 629 630 static INLINE struct brw_reg vec8( struct brw_reg reg ) 631 { 632 return stride(reg, 8,8,1); 633 } 634 635 static INLINE struct brw_reg vec4( struct brw_reg reg ) 636 { 637 return stride(reg, 4,4,1); 638 } 639 640 static INLINE struct brw_reg vec2( struct brw_reg reg ) 641 { 642 return stride(reg, 2,2,1); 643 } 644 645 static INLINE struct brw_reg vec1( struct brw_reg reg ) 646 { 647 return stride(reg, 0,1,0); 648 } 649 650 651 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt ) 652 { 653 return vec1(suboffset(reg, elt)); 654 } 655 656 static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt ) 657 { 658 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt)); 659 } 660 661 static INLINE struct brw_reg get_element_d( struct brw_reg reg, GLuint elt ) 662 { 663 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt)); 664 } 665 666 667 static INLINE struct brw_reg brw_swizzle( struct brw_reg reg, 668 GLuint x, 669 GLuint y, 670 GLuint z, 671 GLuint w) 672 { 673 assert(reg.file != BRW_IMMEDIATE_VALUE); 674 675 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x), 676 BRW_GET_SWZ(reg.dw1.bits.swizzle, y), 677 BRW_GET_SWZ(reg.dw1.bits.swizzle, z), 678 BRW_GET_SWZ(reg.dw1.bits.swizzle, w)); 679 return reg; 680 } 681 682 683 static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg, 684 GLuint x ) 685 { 686 return brw_swizzle(reg, x, x, x, x); 687 } 688 689 static INLINE struct brw_reg brw_writemask( struct brw_reg reg, 690 GLuint mask ) 691 { 692 assert(reg.file != BRW_IMMEDIATE_VALUE); 693 reg.dw1.bits.writemask &= mask; 694 return reg; 695 } 696 697 static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg, 698 GLuint mask ) 699 { 700 assert(reg.file != BRW_IMMEDIATE_VALUE); 701 reg.dw1.bits.writemask = mask; 702 return reg; 703 } 704 705 static INLINE struct brw_reg negate( struct brw_reg reg ) 706 { 707 reg.negate ^= 1; 708 return reg; 709 } 710 711 static INLINE struct brw_reg brw_abs( struct brw_reg reg ) 712 { 713 reg.abs = 1; 714 reg.negate = 0; 715 return reg; 716 } 717 718 /*********************************************************************** 719 */ 720 static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr, 721 GLint offset ) 722 { 723 struct brw_reg reg = brw_vec4_grf(0, 0); 724 reg.subnr = subnr; 725 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; 726 reg.dw1.bits.indirect_offset = offset; 727 return reg; 728 } 729 730 static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr, 731 GLint offset ) 732 { 733 struct brw_reg reg = brw_vec1_grf(0, 0); 734 reg.subnr = subnr; 735 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; 736 reg.dw1.bits.indirect_offset = offset; 737 return reg; 738 } 739 740 static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset) 741 { 742 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset); 743 } 744 745 static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset) 746 { 747 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset); 748 } 749 750 static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset) 751 { 752 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B); 753 } 754 755 static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset) 756 { 757 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW); 758 } 759 760 static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset) 761 { 762 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D); 763 } 764 765 static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset) 766 { 767 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD); 768 } 769 770 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr) 771 { 772 return brw_address_reg(ptr.addr_subnr); 773 } 774 775 static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset ) 776 { 777 ptr.addr_offset += offset; 778 return ptr; 779 } 780 781 static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset ) 782 { 783 struct brw_indirect ptr; 784 ptr.addr_subnr = addr_subnr; 785 ptr.addr_offset = offset; 786 ptr.pad = 0; 787 return ptr; 788 } 789 790 /** Do two brw_regs refer to the same register? */ 791 static INLINE bool 792 brw_same_reg(struct brw_reg r1, struct brw_reg r2) 793 { 794 return r1.file == r2.file && r1.nr == r2.nr; 795 } 796 797 static INLINE struct brw_instruction *current_insn( struct brw_compile *p) 798 { 799 return &p->store[p->nr_insn]; 800 } 801 802 void brw_pop_insn_state( struct brw_compile *p ); 803 void brw_push_insn_state( struct brw_compile *p ); 804 void brw_set_mask_control( struct brw_compile *p, GLuint value ); 805 void brw_set_saturate( struct brw_compile *p, bool enable ); 806 void brw_set_access_mode( struct brw_compile *p, GLuint access_mode ); 807 void brw_set_compression_control(struct brw_compile *p, enum brw_compression c); 808 void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value ); 809 void brw_set_predicate_control( struct brw_compile *p, GLuint pc ); 810 void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse); 811 void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional ); 812 void brw_set_acc_write_control(struct brw_compile *p, GLuint value); 813 814 void brw_init_compile(struct brw_context *, struct brw_compile *p, 815 void *mem_ctx); 816 const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz ); 817 818 struct brw_instruction *brw_next_insn(struct brw_compile *p, GLuint opcode); 819 void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn, 820 struct brw_reg dest); 821 void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn, 822 struct brw_reg reg); 823 824 void gen6_resolve_implied_move(struct brw_compile *p, 825 struct brw_reg *src, 826 GLuint msg_reg_nr); 827 828 /* Helpers for regular instructions: 829 */ 830 #define ALU1(OP) \ 831 struct brw_instruction *brw_##OP(struct brw_compile *p, \ 832 struct brw_reg dest, \ 833 struct brw_reg src0); 834 835 #define ALU2(OP) \ 836 struct brw_instruction *brw_##OP(struct brw_compile *p, \ 837 struct brw_reg dest, \ 838 struct brw_reg src0, \ 839 struct brw_reg src1); 840 841 #define ALU3(OP) \ 842 struct brw_instruction *brw_##OP(struct brw_compile *p, \ 843 struct brw_reg dest, \ 844 struct brw_reg src0, \ 845 struct brw_reg src1, \ 846 struct brw_reg src2); 847 848 #define ROUND(OP) \ 849 void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0); 850 851 ALU1(MOV) 852 ALU2(SEL) 853 ALU1(NOT) 854 ALU2(AND) 855 ALU2(OR) 856 ALU2(XOR) 857 ALU2(SHR) 858 ALU2(SHL) 859 ALU2(RSR) 860 ALU2(RSL) 861 ALU2(ASR) 862 ALU2(JMPI) 863 ALU2(ADD) 864 ALU2(AVG) 865 ALU2(MUL) 866 ALU1(FRC) 867 ALU1(RNDD) 868 ALU2(MAC) 869 ALU2(MACH) 870 ALU1(LZD) 871 ALU2(DP4) 872 ALU2(DPH) 873 ALU2(DP3) 874 ALU2(DP2) 875 ALU2(LINE) 876 ALU2(PLN) 877 ALU3(MAD) 878 879 ROUND(RNDZ) 880 ROUND(RNDE) 881 882 #undef ALU1 883 #undef ALU2 884 #undef ALU3 885 #undef ROUND 886 887 888 /* Helpers for SEND instruction: 889 */ 890 void brw_set_sampler_message(struct brw_compile *p, 891 struct brw_instruction *insn, 892 GLuint binding_table_index, 893 GLuint sampler, 894 GLuint msg_type, 895 GLuint response_length, 896 GLuint msg_length, 897 GLuint header_present, 898 GLuint simd_mode, 899 GLuint return_format); 900 901 void brw_set_dp_read_message(struct brw_compile *p, 902 struct brw_instruction *insn, 903 GLuint binding_table_index, 904 GLuint msg_control, 905 GLuint msg_type, 906 GLuint target_cache, 907 GLuint msg_length, 908 GLuint response_length); 909 910 void brw_set_dp_write_message(struct brw_compile *p, 911 struct brw_instruction *insn, 912 GLuint binding_table_index, 913 GLuint msg_control, 914 GLuint msg_type, 915 GLuint msg_length, 916 bool header_present, 917 GLuint last_render_target, 918 GLuint response_length, 919 GLuint end_of_thread, 920 GLuint send_commit_msg); 921 922 void brw_urb_WRITE(struct brw_compile *p, 923 struct brw_reg dest, 924 GLuint msg_reg_nr, 925 struct brw_reg src0, 926 bool allocate, 927 bool used, 928 GLuint msg_length, 929 GLuint response_length, 930 bool eot, 931 bool writes_complete, 932 GLuint offset, 933 GLuint swizzle); 934 935 void brw_ff_sync(struct brw_compile *p, 936 struct brw_reg dest, 937 GLuint msg_reg_nr, 938 struct brw_reg src0, 939 bool allocate, 940 GLuint response_length, 941 bool eot); 942 943 void brw_svb_write(struct brw_compile *p, 944 struct brw_reg dest, 945 GLuint msg_reg_nr, 946 struct brw_reg src0, 947 GLuint binding_table_index, 948 bool send_commit_msg); 949 950 void brw_fb_WRITE(struct brw_compile *p, 951 int dispatch_width, 952 GLuint msg_reg_nr, 953 struct brw_reg src0, 954 GLuint msg_control, 955 GLuint binding_table_index, 956 GLuint msg_length, 957 GLuint response_length, 958 bool eot, 959 bool header_present); 960 961 void brw_SAMPLE(struct brw_compile *p, 962 struct brw_reg dest, 963 GLuint msg_reg_nr, 964 struct brw_reg src0, 965 GLuint binding_table_index, 966 GLuint sampler, 967 GLuint writemask, 968 GLuint msg_type, 969 GLuint response_length, 970 GLuint msg_length, 971 GLuint header_present, 972 GLuint simd_mode, 973 GLuint return_format); 974 975 void brw_math_16( struct brw_compile *p, 976 struct brw_reg dest, 977 GLuint function, 978 GLuint msg_reg_nr, 979 struct brw_reg src, 980 GLuint precision ); 981 982 void brw_math( struct brw_compile *p, 983 struct brw_reg dest, 984 GLuint function, 985 GLuint msg_reg_nr, 986 struct brw_reg src, 987 GLuint data_type, 988 GLuint precision ); 989 990 void brw_math2(struct brw_compile *p, 991 struct brw_reg dest, 992 GLuint function, 993 struct brw_reg src0, 994 struct brw_reg src1); 995 996 void brw_oword_block_read(struct brw_compile *p, 997 struct brw_reg dest, 998 struct brw_reg mrf, 999 uint32_t offset, 1000 uint32_t bind_table_index); 1001 1002 void brw_oword_block_read_scratch(struct brw_compile *p, 1003 struct brw_reg dest, 1004 struct brw_reg mrf, 1005 int num_regs, 1006 GLuint offset); 1007 1008 void brw_oword_block_write_scratch(struct brw_compile *p, 1009 struct brw_reg mrf, 1010 int num_regs, 1011 GLuint offset); 1012 1013 void brw_dword_scattered_read(struct brw_compile *p, 1014 struct brw_reg dest, 1015 struct brw_reg mrf, 1016 uint32_t bind_table_index); 1017 1018 void brw_dp_READ_4_vs( struct brw_compile *p, 1019 struct brw_reg dest, 1020 GLuint location, 1021 GLuint bind_table_index ); 1022 1023 void brw_dp_READ_4_vs_relative(struct brw_compile *p, 1024 struct brw_reg dest, 1025 struct brw_reg addrReg, 1026 GLuint offset, 1027 GLuint bind_table_index); 1028 1029 /* If/else/endif. Works by manipulating the execution flags on each 1030 * channel. 1031 */ 1032 struct brw_instruction *brw_IF(struct brw_compile *p, 1033 GLuint execute_size); 1034 struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional, 1035 struct brw_reg src0, struct brw_reg src1); 1036 1037 void brw_ELSE(struct brw_compile *p); 1038 void brw_ENDIF(struct brw_compile *p); 1039 1040 /* DO/WHILE loops: 1041 */ 1042 struct brw_instruction *brw_DO(struct brw_compile *p, 1043 GLuint execute_size); 1044 1045 struct brw_instruction *brw_WHILE(struct brw_compile *p); 1046 1047 struct brw_instruction *brw_BREAK(struct brw_compile *p); 1048 struct brw_instruction *brw_CONT(struct brw_compile *p); 1049 struct brw_instruction *gen6_CONT(struct brw_compile *p); 1050 /* Forward jumps: 1051 */ 1052 void brw_land_fwd_jump(struct brw_compile *p, int jmp_insn_idx); 1053 1054 1055 1056 void brw_NOP(struct brw_compile *p); 1057 1058 void brw_WAIT(struct brw_compile *p); 1059 1060 /* Special case: there is never a destination, execution size will be 1061 * taken from src0: 1062 */ 1063 void brw_CMP(struct brw_compile *p, 1064 struct brw_reg dest, 1065 GLuint conditional, 1066 struct brw_reg src0, 1067 struct brw_reg src1); 1068 1069 void brw_print_reg( struct brw_reg reg ); 1070 1071 1072 /*********************************************************************** 1073 * brw_eu_util.c: 1074 */ 1075 1076 void brw_copy_indirect_to_indirect(struct brw_compile *p, 1077 struct brw_indirect dst_ptr, 1078 struct brw_indirect src_ptr, 1079 GLuint count); 1080 1081 void brw_copy_from_indirect(struct brw_compile *p, 1082 struct brw_reg dst, 1083 struct brw_indirect ptr, 1084 GLuint count); 1085 1086 void brw_copy4(struct brw_compile *p, 1087 struct brw_reg dst, 1088 struct brw_reg src, 1089 GLuint count); 1090 1091 void brw_copy8(struct brw_compile *p, 1092 struct brw_reg dst, 1093 struct brw_reg src, 1094 GLuint count); 1095 1096 void brw_math_invert( struct brw_compile *p, 1097 struct brw_reg dst, 1098 struct brw_reg src); 1099 1100 void brw_set_src1(struct brw_compile *p, 1101 struct brw_instruction *insn, 1102 struct brw_reg reg); 1103 1104 void brw_set_uip_jip(struct brw_compile *p); 1105 1106 uint32_t brw_swap_cmod(uint32_t cmod); 1107 1108 /* brw_optimize.c */ 1109 void brw_optimize(struct brw_compile *p); 1110 void brw_remove_duplicate_mrf_moves(struct brw_compile *p); 1111 void brw_remove_grf_to_mrf_moves(struct brw_compile *p); 1112 1113 #ifdef __cplusplus 1114 } 1115 #endif 1116 1117 #endif 1118