brw_eu.h revision 33dfdc735e052d9c9b33883350e926d40220b6ac
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@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 42extern "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 56static 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 */ 73struct 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 102struct 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 111struct 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 155static 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 */ 186static 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 */ 230static 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 */ 246static 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 */ 262static 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 */ 278static 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 */ 294static 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 310static INLINE struct brw_reg retype( struct brw_reg reg, 311 GLuint type ) 312{ 313 reg.type = type; 314 return reg; 315} 316 317static inline struct brw_reg 318sechalf(struct brw_reg reg) 319{ 320 if (reg.vstride) 321 reg.nr++; 322 return reg; 323} 324 325static 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 333static INLINE struct brw_reg offset( struct brw_reg reg, 334 GLuint delta ) 335{ 336 reg.nr += delta; 337 return reg; 338} 339 340 341static 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 */ 352static 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 */ 360static 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 */ 368static 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 375static 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 */ 389static 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 */ 397static 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 */ 405static 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 */ 413static 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 */ 421static 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 */ 433static 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 */ 444static 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 458static 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 475static 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 */ 481static 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 */ 487static 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 */ 493static 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 */ 499static 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 505static 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 510static 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) */ 517static 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 524static 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 */ 535static 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 548static 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 555static 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 570static 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 578static 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 585static 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 */ 599static 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 613static 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 625static INLINE struct brw_reg vec16( struct brw_reg reg ) 626{ 627 return stride(reg, 16,16,1); 628} 629 630static INLINE struct brw_reg vec8( struct brw_reg reg ) 631{ 632 return stride(reg, 8,8,1); 633} 634 635static INLINE struct brw_reg vec4( struct brw_reg reg ) 636{ 637 return stride(reg, 4,4,1); 638} 639 640static INLINE struct brw_reg vec2( struct brw_reg reg ) 641{ 642 return stride(reg, 2,2,1); 643} 644 645static INLINE struct brw_reg vec1( struct brw_reg reg ) 646{ 647 return stride(reg, 0,1,0); 648} 649 650 651static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt ) 652{ 653 return vec1(suboffset(reg, elt)); 654} 655 656static 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 661static 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 667static 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 683static 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 689static 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 697static 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 705static INLINE struct brw_reg negate( struct brw_reg reg ) 706{ 707 reg.negate ^= 1; 708 return reg; 709} 710 711static 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 */ 720static 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 730static 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 740static 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 745static 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 750static 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 755static 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 760static 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 765static 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 770static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr) 771{ 772 return brw_address_reg(ptr.addr_subnr); 773} 774 775static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset ) 776{ 777 ptr.addr_offset += offset; 778 return ptr; 779} 780 781static 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? */ 791static INLINE bool 792brw_same_reg(struct brw_reg r1, struct brw_reg r2) 793{ 794 return r1.file == r2.file && r1.nr == r2.nr; 795} 796 797static INLINE struct brw_instruction *current_insn( struct brw_compile *p) 798{ 799 return &p->store[p->nr_insn]; 800} 801 802void brw_pop_insn_state( struct brw_compile *p ); 803void brw_push_insn_state( struct brw_compile *p ); 804void brw_set_mask_control( struct brw_compile *p, GLuint value ); 805void brw_set_saturate( struct brw_compile *p, bool enable ); 806void brw_set_access_mode( struct brw_compile *p, GLuint access_mode ); 807void brw_set_compression_control(struct brw_compile *p, enum brw_compression c); 808void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value ); 809void brw_set_predicate_control( struct brw_compile *p, GLuint pc ); 810void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse); 811void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional ); 812void brw_set_acc_write_control(struct brw_compile *p, GLuint value); 813 814void brw_init_compile(struct brw_context *, struct brw_compile *p, 815 void *mem_ctx); 816const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz ); 817 818struct brw_instruction *brw_next_insn(struct brw_compile *p, GLuint opcode); 819void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn, 820 struct brw_reg dest); 821void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn, 822 struct brw_reg reg); 823 824void 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) \ 831struct brw_instruction *brw_##OP(struct brw_compile *p, \ 832 struct brw_reg dest, \ 833 struct brw_reg src0); 834 835#define ALU2(OP) \ 836struct 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) \ 842struct 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) \ 849void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0); 850 851ALU1(MOV) 852ALU2(SEL) 853ALU1(NOT) 854ALU2(AND) 855ALU2(OR) 856ALU2(XOR) 857ALU2(SHR) 858ALU2(SHL) 859ALU2(RSR) 860ALU2(RSL) 861ALU2(ASR) 862ALU2(JMPI) 863ALU2(ADD) 864ALU2(AVG) 865ALU2(MUL) 866ALU1(FRC) 867ALU1(RNDD) 868ALU2(MAC) 869ALU2(MACH) 870ALU1(LZD) 871ALU2(DP4) 872ALU2(DPH) 873ALU2(DP3) 874ALU2(DP2) 875ALU2(LINE) 876ALU2(PLN) 877ALU3(MAD) 878 879ROUND(RNDZ) 880ROUND(RNDE) 881 882#undef ALU1 883#undef ALU2 884#undef ALU3 885#undef ROUND 886 887 888/* Helpers for SEND instruction: 889 */ 890void 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 901void 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 910void 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 922void 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 935void 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 943void 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 950void 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 961void 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 975void brw_math_16( struct brw_compile *p, 976 struct brw_reg dest, 977 GLuint function, 978 GLuint saturate, 979 GLuint msg_reg_nr, 980 struct brw_reg src, 981 GLuint precision ); 982 983void brw_math( struct brw_compile *p, 984 struct brw_reg dest, 985 GLuint function, 986 GLuint saturate, 987 GLuint msg_reg_nr, 988 struct brw_reg src, 989 GLuint data_type, 990 GLuint precision ); 991 992void brw_math2(struct brw_compile *p, 993 struct brw_reg dest, 994 GLuint function, 995 struct brw_reg src0, 996 struct brw_reg src1); 997 998void brw_oword_block_read(struct brw_compile *p, 999 struct brw_reg dest, 1000 struct brw_reg mrf, 1001 uint32_t offset, 1002 uint32_t bind_table_index); 1003 1004void brw_oword_block_read_scratch(struct brw_compile *p, 1005 struct brw_reg dest, 1006 struct brw_reg mrf, 1007 int num_regs, 1008 GLuint offset); 1009 1010void brw_oword_block_write_scratch(struct brw_compile *p, 1011 struct brw_reg mrf, 1012 int num_regs, 1013 GLuint offset); 1014 1015void brw_dword_scattered_read(struct brw_compile *p, 1016 struct brw_reg dest, 1017 struct brw_reg mrf, 1018 uint32_t bind_table_index); 1019 1020void brw_dp_READ_4_vs( struct brw_compile *p, 1021 struct brw_reg dest, 1022 GLuint location, 1023 GLuint bind_table_index ); 1024 1025void brw_dp_READ_4_vs_relative(struct brw_compile *p, 1026 struct brw_reg dest, 1027 struct brw_reg addrReg, 1028 GLuint offset, 1029 GLuint bind_table_index); 1030 1031/* If/else/endif. Works by manipulating the execution flags on each 1032 * channel. 1033 */ 1034struct brw_instruction *brw_IF(struct brw_compile *p, 1035 GLuint execute_size); 1036struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional, 1037 struct brw_reg src0, struct brw_reg src1); 1038 1039void brw_ELSE(struct brw_compile *p); 1040void brw_ENDIF(struct brw_compile *p); 1041 1042/* DO/WHILE loops: 1043 */ 1044struct brw_instruction *brw_DO(struct brw_compile *p, 1045 GLuint execute_size); 1046 1047struct brw_instruction *brw_WHILE(struct brw_compile *p); 1048 1049struct brw_instruction *brw_BREAK(struct brw_compile *p); 1050struct brw_instruction *brw_CONT(struct brw_compile *p); 1051struct brw_instruction *gen6_CONT(struct brw_compile *p); 1052/* Forward jumps: 1053 */ 1054void brw_land_fwd_jump(struct brw_compile *p, int jmp_insn_idx); 1055 1056 1057 1058void brw_NOP(struct brw_compile *p); 1059 1060void brw_WAIT(struct brw_compile *p); 1061 1062/* Special case: there is never a destination, execution size will be 1063 * taken from src0: 1064 */ 1065void brw_CMP(struct brw_compile *p, 1066 struct brw_reg dest, 1067 GLuint conditional, 1068 struct brw_reg src0, 1069 struct brw_reg src1); 1070 1071void brw_print_reg( struct brw_reg reg ); 1072 1073 1074/*********************************************************************** 1075 * brw_eu_util.c: 1076 */ 1077 1078void brw_copy_indirect_to_indirect(struct brw_compile *p, 1079 struct brw_indirect dst_ptr, 1080 struct brw_indirect src_ptr, 1081 GLuint count); 1082 1083void brw_copy_from_indirect(struct brw_compile *p, 1084 struct brw_reg dst, 1085 struct brw_indirect ptr, 1086 GLuint count); 1087 1088void brw_copy4(struct brw_compile *p, 1089 struct brw_reg dst, 1090 struct brw_reg src, 1091 GLuint count); 1092 1093void brw_copy8(struct brw_compile *p, 1094 struct brw_reg dst, 1095 struct brw_reg src, 1096 GLuint count); 1097 1098void brw_math_invert( struct brw_compile *p, 1099 struct brw_reg dst, 1100 struct brw_reg src); 1101 1102void brw_set_src1(struct brw_compile *p, 1103 struct brw_instruction *insn, 1104 struct brw_reg reg); 1105 1106void brw_set_uip_jip(struct brw_compile *p); 1107 1108uint32_t brw_swap_cmod(uint32_t cmod); 1109 1110/* brw_optimize.c */ 1111void brw_optimize(struct brw_compile *p); 1112void brw_remove_duplicate_mrf_moves(struct brw_compile *p); 1113void brw_remove_grf_to_mrf_moves(struct brw_compile *p); 1114 1115#ifdef __cplusplus 1116} 1117#endif 1118 1119#endif 1120