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