tgsi_ureg.h revision c9c8a5ed02408495b3132cabd7947cc352a117a2
1/************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * 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, sub license, 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 portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#ifndef TGSI_UREG_H 29#define TGSI_UREG_H 30 31#include "pipe/p_compiler.h" 32#include "pipe/p_shader_tokens.h" 33#include "util/u_debug.h" 34 35#ifdef __cplusplus 36extern "C" { 37#endif 38 39struct ureg_program; 40 41/* Almost a tgsi_src_register, but we need to pull in the Absolute 42 * flag from the _ext token. Indirect flag always implies ADDR[0]. 43 */ 44struct ureg_src 45{ 46 unsigned File : 4; /* TGSI_FILE_ */ 47 unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */ 48 unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */ 49 unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */ 50 unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */ 51 unsigned Indirect : 1; /* BOOL */ 52 unsigned DimIndirect : 1; /* BOOL */ 53 unsigned Dimension : 1; /* BOOL */ 54 unsigned Absolute : 1; /* BOOL */ 55 unsigned Negate : 1; /* BOOL */ 56 int Index : 16; /* SINT */ 57 unsigned IndirectFile : 4; /* TGSI_FILE_ */ 58 int IndirectIndex : 16; /* SINT */ 59 unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */ 60 int DimensionIndex : 16; /* SINT */ 61 unsigned DimIndFile : 4; /* TGSI_FILE_ */ 62 int DimIndIndex : 16; /* SINT */ 63 unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */ 64}; 65 66/* Very similar to a tgsi_dst_register, removing unsupported fields 67 * and adding a Saturate flag. It's easier to push saturate into the 68 * destination register than to try and create a _SAT varient of each 69 * instruction function. 70 */ 71struct ureg_dst 72{ 73 unsigned File : 4; /* TGSI_FILE_ */ 74 unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ 75 unsigned Indirect : 1; /* BOOL */ 76 unsigned Saturate : 1; /* BOOL */ 77 unsigned Predicate : 1; 78 unsigned PredNegate : 1; /* BOOL */ 79 unsigned PredSwizzleX: 2; /* TGSI_SWIZZLE_ */ 80 unsigned PredSwizzleY: 2; /* TGSI_SWIZZLE_ */ 81 unsigned PredSwizzleZ: 2; /* TGSI_SWIZZLE_ */ 82 unsigned PredSwizzleW: 2; /* TGSI_SWIZZLE_ */ 83 int Index : 16; /* SINT */ 84 int IndirectIndex : 16; /* SINT */ 85 int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */ 86}; 87 88struct pipe_context; 89 90struct ureg_program * 91ureg_create( unsigned processor ); 92 93const struct tgsi_token * 94ureg_finalize( struct ureg_program * ); 95 96/* Create and return a shader: 97 */ 98void * 99ureg_create_shader( struct ureg_program *, 100 struct pipe_context *pipe ); 101 102 103/* Alternately, return the built token stream and hand ownership of 104 * that memory to the caller: 105 */ 106const struct tgsi_token * 107ureg_get_tokens( struct ureg_program *ureg, 108 unsigned *nr_tokens ); 109 110 111/* Free the tokens created by ureg_get_tokens() */ 112void ureg_free_tokens( const struct tgsi_token *tokens ); 113 114 115void 116ureg_destroy( struct ureg_program * ); 117 118 119/*********************************************************************** 120 * Convenience routine: 121 */ 122static INLINE void * 123ureg_create_shader_and_destroy( struct ureg_program *p, 124 struct pipe_context *pipe ) 125{ 126 void *result = ureg_create_shader( p, pipe ); 127 ureg_destroy( p ); 128 return result; 129} 130 131 132/*********************************************************************** 133 * Build shader properties: 134 */ 135 136void 137ureg_property_gs_input_prim(struct ureg_program *ureg, 138 unsigned input_prim); 139 140void 141ureg_property_gs_output_prim(struct ureg_program *ureg, 142 unsigned output_prim); 143 144void 145ureg_property_gs_max_vertices(struct ureg_program *ureg, 146 unsigned max_vertices); 147 148void 149ureg_property_fs_coord_origin(struct ureg_program *ureg, 150 unsigned fs_coord_origin); 151 152void 153ureg_property_fs_coord_pixel_center(struct ureg_program *ureg, 154 unsigned fs_coord_pixel_center); 155 156void 157ureg_property_fs_color0_writes_all_cbufs(struct ureg_program *ureg, 158 unsigned fs_color0_writes_all_cbufs); 159 160/*********************************************************************** 161 * Build shader declarations: 162 */ 163 164struct ureg_src 165ureg_DECL_fs_input_cyl_centroid(struct ureg_program *, 166 unsigned semantic_name, 167 unsigned semantic_index, 168 unsigned interp_mode, 169 unsigned cylindrical_wrap, 170 unsigned centroid); 171 172static INLINE struct ureg_src 173ureg_DECL_fs_input_cyl(struct ureg_program *ureg, 174 unsigned semantic_name, 175 unsigned semantic_index, 176 unsigned interp_mode, 177 unsigned cylindrical_wrap) 178{ 179 return ureg_DECL_fs_input_cyl_centroid(ureg, 180 semantic_name, 181 semantic_index, 182 interp_mode, 183 cylindrical_wrap, 184 0); 185} 186 187static INLINE struct ureg_src 188ureg_DECL_fs_input(struct ureg_program *ureg, 189 unsigned semantic_name, 190 unsigned semantic_index, 191 unsigned interp_mode) 192{ 193 return ureg_DECL_fs_input_cyl_centroid(ureg, 194 semantic_name, 195 semantic_index, 196 interp_mode, 197 0, 0); 198} 199 200struct ureg_src 201ureg_DECL_vs_input( struct ureg_program *, 202 unsigned index ); 203 204struct ureg_src 205ureg_DECL_gs_input(struct ureg_program *, 206 unsigned index, 207 unsigned semantic_name, 208 unsigned semantic_index); 209 210struct ureg_src 211ureg_DECL_system_value(struct ureg_program *, 212 unsigned index, 213 unsigned semantic_name, 214 unsigned semantic_index); 215 216struct ureg_dst 217ureg_DECL_output( struct ureg_program *, 218 unsigned semantic_name, 219 unsigned semantic_index ); 220 221struct ureg_src 222ureg_DECL_immediate( struct ureg_program *, 223 const float *v, 224 unsigned nr ); 225 226struct ureg_src 227ureg_DECL_immediate_uint( struct ureg_program *, 228 const unsigned *v, 229 unsigned nr ); 230 231struct ureg_src 232ureg_DECL_immediate_block_uint( struct ureg_program *, 233 const unsigned *v, 234 unsigned nr ); 235 236struct ureg_src 237ureg_DECL_immediate_int( struct ureg_program *, 238 const int *v, 239 unsigned nr ); 240 241void 242ureg_DECL_constant2D(struct ureg_program *ureg, 243 unsigned first, 244 unsigned last, 245 unsigned index2D); 246 247struct ureg_src 248ureg_DECL_constant( struct ureg_program *, 249 unsigned index ); 250 251struct ureg_dst 252ureg_DECL_temporary( struct ureg_program * ); 253 254void 255ureg_release_temporary( struct ureg_program *ureg, 256 struct ureg_dst tmp ); 257 258struct ureg_dst 259ureg_DECL_address( struct ureg_program * ); 260 261struct ureg_dst 262ureg_DECL_predicate(struct ureg_program *); 263 264/* Supply an index to the sampler declaration as this is the hook to 265 * the external pipe_sampler state. Users of this function probably 266 * don't want just any sampler, but a specific one which they've set 267 * up state for in the context. 268 */ 269struct ureg_src 270ureg_DECL_sampler( struct ureg_program *, 271 unsigned index ); 272 273 274static INLINE struct ureg_src 275ureg_imm4f( struct ureg_program *ureg, 276 float a, float b, 277 float c, float d) 278{ 279 float v[4]; 280 v[0] = a; 281 v[1] = b; 282 v[2] = c; 283 v[3] = d; 284 return ureg_DECL_immediate( ureg, v, 4 ); 285} 286 287static INLINE struct ureg_src 288ureg_imm3f( struct ureg_program *ureg, 289 float a, float b, 290 float c) 291{ 292 float v[3]; 293 v[0] = a; 294 v[1] = b; 295 v[2] = c; 296 return ureg_DECL_immediate( ureg, v, 3 ); 297} 298 299static INLINE struct ureg_src 300ureg_imm2f( struct ureg_program *ureg, 301 float a, float b) 302{ 303 float v[2]; 304 v[0] = a; 305 v[1] = b; 306 return ureg_DECL_immediate( ureg, v, 2 ); 307} 308 309static INLINE struct ureg_src 310ureg_imm1f( struct ureg_program *ureg, 311 float a) 312{ 313 float v[1]; 314 v[0] = a; 315 return ureg_DECL_immediate( ureg, v, 1 ); 316} 317 318static INLINE struct ureg_src 319ureg_imm4u( struct ureg_program *ureg, 320 unsigned a, unsigned b, 321 unsigned c, unsigned d) 322{ 323 unsigned v[4]; 324 v[0] = a; 325 v[1] = b; 326 v[2] = c; 327 v[3] = d; 328 return ureg_DECL_immediate_uint( ureg, v, 4 ); 329} 330 331static INLINE struct ureg_src 332ureg_imm3u( struct ureg_program *ureg, 333 unsigned a, unsigned b, 334 unsigned c) 335{ 336 unsigned v[3]; 337 v[0] = a; 338 v[1] = b; 339 v[2] = c; 340 return ureg_DECL_immediate_uint( ureg, v, 3 ); 341} 342 343static INLINE struct ureg_src 344ureg_imm2u( struct ureg_program *ureg, 345 unsigned a, unsigned b) 346{ 347 unsigned v[2]; 348 v[0] = a; 349 v[1] = b; 350 return ureg_DECL_immediate_uint( ureg, v, 2 ); 351} 352 353static INLINE struct ureg_src 354ureg_imm1u( struct ureg_program *ureg, 355 unsigned a) 356{ 357 return ureg_DECL_immediate_uint( ureg, &a, 1 ); 358} 359 360static INLINE struct ureg_src 361ureg_imm4i( struct ureg_program *ureg, 362 int a, int b, 363 int c, int d) 364{ 365 int v[4]; 366 v[0] = a; 367 v[1] = b; 368 v[2] = c; 369 v[3] = d; 370 return ureg_DECL_immediate_int( ureg, v, 4 ); 371} 372 373static INLINE struct ureg_src 374ureg_imm3i( struct ureg_program *ureg, 375 int a, int b, 376 int c) 377{ 378 int v[3]; 379 v[0] = a; 380 v[1] = b; 381 v[2] = c; 382 return ureg_DECL_immediate_int( ureg, v, 3 ); 383} 384 385static INLINE struct ureg_src 386ureg_imm2i( struct ureg_program *ureg, 387 int a, int b) 388{ 389 int v[2]; 390 v[0] = a; 391 v[1] = b; 392 return ureg_DECL_immediate_int( ureg, v, 2 ); 393} 394 395static INLINE struct ureg_src 396ureg_imm1i( struct ureg_program *ureg, 397 int a) 398{ 399 return ureg_DECL_immediate_int( ureg, &a, 1 ); 400} 401 402/*********************************************************************** 403 * Functions for patching up labels 404 */ 405 406 407/* Will return a number which can be used in a label to point to the 408 * next instruction to be emitted. 409 */ 410unsigned 411ureg_get_instruction_number( struct ureg_program *ureg ); 412 413 414/* Patch a given label (expressed as a token number) to point to a 415 * given instruction (expressed as an instruction number). 416 * 417 * Labels are obtained from instruction emitters, eg ureg_CAL(). 418 * Instruction numbers are obtained from ureg_get_instruction_number(), 419 * above. 420 */ 421void 422ureg_fixup_label(struct ureg_program *ureg, 423 unsigned label_token, 424 unsigned instruction_number ); 425 426 427/* Generic instruction emitter. Use if you need to pass the opcode as 428 * a parameter, rather than using the emit_OP() varients below. 429 */ 430void 431ureg_insn(struct ureg_program *ureg, 432 unsigned opcode, 433 const struct ureg_dst *dst, 434 unsigned nr_dst, 435 const struct ureg_src *src, 436 unsigned nr_src ); 437 438 439void 440ureg_tex_insn(struct ureg_program *ureg, 441 unsigned opcode, 442 const struct ureg_dst *dst, 443 unsigned nr_dst, 444 unsigned target, 445 const struct ureg_src *src, 446 unsigned nr_src ); 447 448 449void 450ureg_label_insn(struct ureg_program *ureg, 451 unsigned opcode, 452 const struct ureg_src *src, 453 unsigned nr_src, 454 unsigned *label); 455 456 457/*********************************************************************** 458 * Internal instruction helpers, don't call these directly: 459 */ 460 461struct ureg_emit_insn_result { 462 unsigned insn_token; /*< Used to fixup insn size. */ 463 unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */ 464}; 465 466struct ureg_emit_insn_result 467ureg_emit_insn(struct ureg_program *ureg, 468 unsigned opcode, 469 boolean saturate, 470 boolean predicate, 471 boolean pred_negate, 472 unsigned pred_swizzle_x, 473 unsigned pred_swizzle_y, 474 unsigned pred_swizzle_z, 475 unsigned pred_swizzle_w, 476 unsigned num_dst, 477 unsigned num_src ); 478 479void 480ureg_emit_label(struct ureg_program *ureg, 481 unsigned insn_token, 482 unsigned *label_token ); 483 484void 485ureg_emit_texture(struct ureg_program *ureg, 486 unsigned insn_token, 487 unsigned target ); 488 489void 490ureg_emit_dst( struct ureg_program *ureg, 491 struct ureg_dst dst ); 492 493void 494ureg_emit_src( struct ureg_program *ureg, 495 struct ureg_src src ); 496 497void 498ureg_fixup_insn_size(struct ureg_program *ureg, 499 unsigned insn ); 500 501 502#define OP00( op ) \ 503static INLINE void ureg_##op( struct ureg_program *ureg ) \ 504{ \ 505 unsigned opcode = TGSI_OPCODE_##op; \ 506 unsigned insn = ureg_emit_insn(ureg, \ 507 opcode, \ 508 FALSE, \ 509 FALSE, \ 510 FALSE, \ 511 TGSI_SWIZZLE_X, \ 512 TGSI_SWIZZLE_Y, \ 513 TGSI_SWIZZLE_Z, \ 514 TGSI_SWIZZLE_W, \ 515 0, \ 516 0).insn_token; \ 517 ureg_fixup_insn_size( ureg, insn ); \ 518} 519 520#define OP01( op ) \ 521static INLINE void ureg_##op( struct ureg_program *ureg, \ 522 struct ureg_src src ) \ 523{ \ 524 unsigned opcode = TGSI_OPCODE_##op; \ 525 unsigned insn = ureg_emit_insn(ureg, \ 526 opcode, \ 527 FALSE, \ 528 FALSE, \ 529 FALSE, \ 530 TGSI_SWIZZLE_X, \ 531 TGSI_SWIZZLE_Y, \ 532 TGSI_SWIZZLE_Z, \ 533 TGSI_SWIZZLE_W, \ 534 0, \ 535 1).insn_token; \ 536 ureg_emit_src( ureg, src ); \ 537 ureg_fixup_insn_size( ureg, insn ); \ 538} 539 540#define OP00_LBL( op ) \ 541static INLINE void ureg_##op( struct ureg_program *ureg, \ 542 unsigned *label_token ) \ 543{ \ 544 unsigned opcode = TGSI_OPCODE_##op; \ 545 struct ureg_emit_insn_result insn; \ 546 insn = ureg_emit_insn(ureg, \ 547 opcode, \ 548 FALSE, \ 549 FALSE, \ 550 FALSE, \ 551 TGSI_SWIZZLE_X, \ 552 TGSI_SWIZZLE_Y, \ 553 TGSI_SWIZZLE_Z, \ 554 TGSI_SWIZZLE_W, \ 555 0, \ 556 0); \ 557 ureg_emit_label( ureg, insn.extended_token, label_token ); \ 558 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 559} 560 561#define OP01_LBL( op ) \ 562static INLINE void ureg_##op( struct ureg_program *ureg, \ 563 struct ureg_src src, \ 564 unsigned *label_token ) \ 565{ \ 566 unsigned opcode = TGSI_OPCODE_##op; \ 567 struct ureg_emit_insn_result insn; \ 568 insn = ureg_emit_insn(ureg, \ 569 opcode, \ 570 FALSE, \ 571 FALSE, \ 572 FALSE, \ 573 TGSI_SWIZZLE_X, \ 574 TGSI_SWIZZLE_Y, \ 575 TGSI_SWIZZLE_Z, \ 576 TGSI_SWIZZLE_W, \ 577 0, \ 578 1); \ 579 ureg_emit_label( ureg, insn.extended_token, label_token ); \ 580 ureg_emit_src( ureg, src ); \ 581 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 582} 583 584#define OP10( op ) \ 585static INLINE void ureg_##op( struct ureg_program *ureg, \ 586 struct ureg_dst dst ) \ 587{ \ 588 unsigned opcode = TGSI_OPCODE_##op; \ 589 unsigned insn = ureg_emit_insn(ureg, \ 590 opcode, \ 591 dst.Saturate, \ 592 dst.Predicate, \ 593 dst.PredNegate, \ 594 dst.PredSwizzleX, \ 595 dst.PredSwizzleY, \ 596 dst.PredSwizzleZ, \ 597 dst.PredSwizzleW, \ 598 1, \ 599 0).insn_token; \ 600 ureg_emit_dst( ureg, dst ); \ 601 ureg_fixup_insn_size( ureg, insn ); \ 602} 603 604 605#define OP11( op ) \ 606static INLINE void ureg_##op( struct ureg_program *ureg, \ 607 struct ureg_dst dst, \ 608 struct ureg_src src ) \ 609{ \ 610 unsigned opcode = TGSI_OPCODE_##op; \ 611 unsigned insn = ureg_emit_insn(ureg, \ 612 opcode, \ 613 dst.Saturate, \ 614 dst.Predicate, \ 615 dst.PredNegate, \ 616 dst.PredSwizzleX, \ 617 dst.PredSwizzleY, \ 618 dst.PredSwizzleZ, \ 619 dst.PredSwizzleW, \ 620 1, \ 621 1).insn_token; \ 622 ureg_emit_dst( ureg, dst ); \ 623 ureg_emit_src( ureg, src ); \ 624 ureg_fixup_insn_size( ureg, insn ); \ 625} 626 627#define OP12( op ) \ 628static INLINE void ureg_##op( struct ureg_program *ureg, \ 629 struct ureg_dst dst, \ 630 struct ureg_src src0, \ 631 struct ureg_src src1 ) \ 632{ \ 633 unsigned opcode = TGSI_OPCODE_##op; \ 634 unsigned insn = ureg_emit_insn(ureg, \ 635 opcode, \ 636 dst.Saturate, \ 637 dst.Predicate, \ 638 dst.PredNegate, \ 639 dst.PredSwizzleX, \ 640 dst.PredSwizzleY, \ 641 dst.PredSwizzleZ, \ 642 dst.PredSwizzleW, \ 643 1, \ 644 2).insn_token; \ 645 ureg_emit_dst( ureg, dst ); \ 646 ureg_emit_src( ureg, src0 ); \ 647 ureg_emit_src( ureg, src1 ); \ 648 ureg_fixup_insn_size( ureg, insn ); \ 649} 650 651#define OP12_TEX( op ) \ 652static INLINE void ureg_##op( struct ureg_program *ureg, \ 653 struct ureg_dst dst, \ 654 unsigned target, \ 655 struct ureg_src src0, \ 656 struct ureg_src src1 ) \ 657{ \ 658 unsigned opcode = TGSI_OPCODE_##op; \ 659 struct ureg_emit_insn_result insn; \ 660 insn = ureg_emit_insn(ureg, \ 661 opcode, \ 662 dst.Saturate, \ 663 dst.Predicate, \ 664 dst.PredNegate, \ 665 dst.PredSwizzleX, \ 666 dst.PredSwizzleY, \ 667 dst.PredSwizzleZ, \ 668 dst.PredSwizzleW, \ 669 1, \ 670 2); \ 671 ureg_emit_texture( ureg, insn.extended_token, target ); \ 672 ureg_emit_dst( ureg, dst ); \ 673 ureg_emit_src( ureg, src0 ); \ 674 ureg_emit_src( ureg, src1 ); \ 675 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 676} 677 678#define OP13( op ) \ 679static INLINE void ureg_##op( struct ureg_program *ureg, \ 680 struct ureg_dst dst, \ 681 struct ureg_src src0, \ 682 struct ureg_src src1, \ 683 struct ureg_src src2 ) \ 684{ \ 685 unsigned opcode = TGSI_OPCODE_##op; \ 686 unsigned insn = ureg_emit_insn(ureg, \ 687 opcode, \ 688 dst.Saturate, \ 689 dst.Predicate, \ 690 dst.PredNegate, \ 691 dst.PredSwizzleX, \ 692 dst.PredSwizzleY, \ 693 dst.PredSwizzleZ, \ 694 dst.PredSwizzleW, \ 695 1, \ 696 3).insn_token; \ 697 ureg_emit_dst( ureg, dst ); \ 698 ureg_emit_src( ureg, src0 ); \ 699 ureg_emit_src( ureg, src1 ); \ 700 ureg_emit_src( ureg, src2 ); \ 701 ureg_fixup_insn_size( ureg, insn ); \ 702} 703 704#define OP14_TEX( op ) \ 705static INLINE void ureg_##op( struct ureg_program *ureg, \ 706 struct ureg_dst dst, \ 707 unsigned target, \ 708 struct ureg_src src0, \ 709 struct ureg_src src1, \ 710 struct ureg_src src2, \ 711 struct ureg_src src3 ) \ 712{ \ 713 unsigned opcode = TGSI_OPCODE_##op; \ 714 struct ureg_emit_insn_result insn; \ 715 insn = ureg_emit_insn(ureg, \ 716 opcode, \ 717 dst.Saturate, \ 718 dst.Predicate, \ 719 dst.PredNegate, \ 720 dst.PredSwizzleX, \ 721 dst.PredSwizzleY, \ 722 dst.PredSwizzleZ, \ 723 dst.PredSwizzleW, \ 724 1, \ 725 4); \ 726 ureg_emit_texture( ureg, insn.extended_token, target ); \ 727 ureg_emit_dst( ureg, dst ); \ 728 ureg_emit_src( ureg, src0 ); \ 729 ureg_emit_src( ureg, src1 ); \ 730 ureg_emit_src( ureg, src2 ); \ 731 ureg_emit_src( ureg, src3 ); \ 732 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 733} 734 735 736/* Use a template include to generate a correctly-typed ureg_OP() 737 * function for each TGSI opcode: 738 */ 739#include "tgsi_opcode_tmp.h" 740 741 742/*********************************************************************** 743 * Inline helpers for manipulating register structs: 744 */ 745static INLINE struct ureg_src 746ureg_negate( struct ureg_src reg ) 747{ 748 assert(reg.File != TGSI_FILE_NULL); 749 reg.Negate ^= 1; 750 return reg; 751} 752 753static INLINE struct ureg_src 754ureg_abs( struct ureg_src reg ) 755{ 756 assert(reg.File != TGSI_FILE_NULL); 757 reg.Absolute = 1; 758 reg.Negate = 0; 759 return reg; 760} 761 762static INLINE struct ureg_src 763ureg_swizzle( struct ureg_src reg, 764 int x, int y, int z, int w ) 765{ 766 unsigned swz = ( (reg.SwizzleX << 0) | 767 (reg.SwizzleY << 2) | 768 (reg.SwizzleZ << 4) | 769 (reg.SwizzleW << 6)); 770 771 assert(reg.File != TGSI_FILE_NULL); 772 assert(x < 4); 773 assert(y < 4); 774 assert(z < 4); 775 assert(w < 4); 776 777 reg.SwizzleX = (swz >> (x*2)) & 0x3; 778 reg.SwizzleY = (swz >> (y*2)) & 0x3; 779 reg.SwizzleZ = (swz >> (z*2)) & 0x3; 780 reg.SwizzleW = (swz >> (w*2)) & 0x3; 781 return reg; 782} 783 784static INLINE struct ureg_src 785ureg_scalar( struct ureg_src reg, int x ) 786{ 787 return ureg_swizzle(reg, x, x, x, x); 788} 789 790static INLINE struct ureg_dst 791ureg_writemask( struct ureg_dst reg, 792 unsigned writemask ) 793{ 794 assert(reg.File != TGSI_FILE_NULL); 795 reg.WriteMask &= writemask; 796 return reg; 797} 798 799static INLINE struct ureg_dst 800ureg_saturate( struct ureg_dst reg ) 801{ 802 assert(reg.File != TGSI_FILE_NULL); 803 reg.Saturate = 1; 804 return reg; 805} 806 807static INLINE struct ureg_dst 808ureg_predicate(struct ureg_dst reg, 809 boolean negate, 810 unsigned swizzle_x, 811 unsigned swizzle_y, 812 unsigned swizzle_z, 813 unsigned swizzle_w) 814{ 815 assert(reg.File != TGSI_FILE_NULL); 816 reg.Predicate = 1; 817 reg.PredNegate = negate; 818 reg.PredSwizzleX = swizzle_x; 819 reg.PredSwizzleY = swizzle_y; 820 reg.PredSwizzleZ = swizzle_z; 821 reg.PredSwizzleW = swizzle_w; 822 return reg; 823} 824 825static INLINE struct ureg_dst 826ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr ) 827{ 828 assert(reg.File != TGSI_FILE_NULL); 829 assert(addr.File == TGSI_FILE_ADDRESS); 830 reg.Indirect = 1; 831 reg.IndirectIndex = addr.Index; 832 reg.IndirectSwizzle = addr.SwizzleX; 833 return reg; 834} 835 836static INLINE struct ureg_src 837ureg_src_indirect( struct ureg_src reg, struct ureg_src addr ) 838{ 839 assert(reg.File != TGSI_FILE_NULL); 840 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY); 841 reg.Indirect = 1; 842 reg.IndirectFile = addr.File; 843 reg.IndirectIndex = addr.Index; 844 reg.IndirectSwizzle = addr.SwizzleX; 845 return reg; 846} 847 848static INLINE struct ureg_src 849ureg_src_dimension( struct ureg_src reg, int index ) 850{ 851 assert(reg.File != TGSI_FILE_NULL); 852 reg.Dimension = 1; 853 reg.DimIndirect = 0; 854 reg.DimensionIndex = index; 855 return reg; 856} 857 858 859static INLINE struct ureg_src 860ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr, 861 int index ) 862{ 863 assert(reg.File != TGSI_FILE_NULL); 864 reg.Dimension = 1; 865 reg.DimIndirect = 1; 866 reg.DimensionIndex = index; 867 reg.DimIndFile = addr.File; 868 reg.DimIndIndex = addr.Index; 869 reg.DimIndSwizzle = addr.SwizzleX; 870 return reg; 871} 872 873static INLINE struct ureg_dst 874ureg_dst( struct ureg_src src ) 875{ 876 struct ureg_dst dst; 877 878 assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS); 879 880 dst.File = src.File; 881 dst.WriteMask = TGSI_WRITEMASK_XYZW; 882 dst.Indirect = src.Indirect; 883 dst.IndirectIndex = src.IndirectIndex; 884 dst.IndirectSwizzle = src.IndirectSwizzle; 885 dst.Saturate = 0; 886 dst.Predicate = 0; 887 dst.PredNegate = 0; 888 dst.PredSwizzleX = TGSI_SWIZZLE_X; 889 dst.PredSwizzleY = TGSI_SWIZZLE_Y; 890 dst.PredSwizzleZ = TGSI_SWIZZLE_Z; 891 dst.PredSwizzleW = TGSI_SWIZZLE_W; 892 dst.Index = src.Index; 893 894 return dst; 895} 896 897static INLINE struct ureg_src 898ureg_src_register(unsigned file, 899 unsigned index) 900{ 901 struct ureg_src src; 902 903 src.File = file; 904 src.SwizzleX = TGSI_SWIZZLE_X; 905 src.SwizzleY = TGSI_SWIZZLE_Y; 906 src.SwizzleZ = TGSI_SWIZZLE_Z; 907 src.SwizzleW = TGSI_SWIZZLE_W; 908 src.Indirect = 0; 909 src.IndirectFile = TGSI_FILE_NULL; 910 src.IndirectIndex = 0; 911 src.IndirectSwizzle = 0; 912 src.Absolute = 0; 913 src.Index = index; 914 src.Negate = 0; 915 src.Dimension = 0; 916 src.DimensionIndex = 0; 917 src.DimIndirect = 0; 918 src.DimIndFile = TGSI_FILE_NULL; 919 src.DimIndIndex = 0; 920 src.DimIndSwizzle = 0; 921 922 return src; 923} 924 925static INLINE struct ureg_src 926ureg_src( struct ureg_dst dst ) 927{ 928 struct ureg_src src; 929 930 src.File = dst.File; 931 src.SwizzleX = TGSI_SWIZZLE_X; 932 src.SwizzleY = TGSI_SWIZZLE_Y; 933 src.SwizzleZ = TGSI_SWIZZLE_Z; 934 src.SwizzleW = TGSI_SWIZZLE_W; 935 src.Indirect = dst.Indirect; 936 src.IndirectFile = TGSI_FILE_ADDRESS; 937 src.IndirectIndex = dst.IndirectIndex; 938 src.IndirectSwizzle = dst.IndirectSwizzle; 939 src.Absolute = 0; 940 src.Index = dst.Index; 941 src.Negate = 0; 942 src.Dimension = 0; 943 src.DimensionIndex = 0; 944 src.DimIndirect = 0; 945 src.DimIndFile = TGSI_FILE_NULL; 946 src.DimIndIndex = 0; 947 src.DimIndSwizzle = 0; 948 949 return src; 950} 951 952 953 954static INLINE struct ureg_dst 955ureg_dst_undef( void ) 956{ 957 struct ureg_dst dst; 958 959 dst.File = TGSI_FILE_NULL; 960 dst.WriteMask = 0; 961 dst.Indirect = 0; 962 dst.IndirectIndex = 0; 963 dst.IndirectSwizzle = 0; 964 dst.Saturate = 0; 965 dst.Predicate = 0; 966 dst.PredNegate = 0; 967 dst.PredSwizzleX = TGSI_SWIZZLE_X; 968 dst.PredSwizzleY = TGSI_SWIZZLE_Y; 969 dst.PredSwizzleZ = TGSI_SWIZZLE_Z; 970 dst.PredSwizzleW = TGSI_SWIZZLE_W; 971 dst.Index = 0; 972 973 return dst; 974} 975 976static INLINE struct ureg_src 977ureg_src_undef( void ) 978{ 979 struct ureg_src src; 980 981 src.File = TGSI_FILE_NULL; 982 src.SwizzleX = 0; 983 src.SwizzleY = 0; 984 src.SwizzleZ = 0; 985 src.SwizzleW = 0; 986 src.Indirect = 0; 987 src.IndirectFile = TGSI_FILE_NULL; 988 src.IndirectIndex = 0; 989 src.IndirectSwizzle = 0; 990 src.Absolute = 0; 991 src.Index = 0; 992 src.Negate = 0; 993 src.Dimension = 0; 994 src.DimensionIndex = 0; 995 src.DimIndirect = 0; 996 src.DimIndFile = TGSI_FILE_NULL; 997 src.DimIndIndex = 0; 998 src.DimIndSwizzle = 0; 999 1000 return src; 1001} 1002 1003static INLINE boolean 1004ureg_src_is_undef( struct ureg_src src ) 1005{ 1006 return src.File == TGSI_FILE_NULL; 1007} 1008 1009static INLINE boolean 1010ureg_dst_is_undef( struct ureg_dst dst ) 1011{ 1012 return dst.File == TGSI_FILE_NULL; 1013} 1014 1015 1016#ifdef __cplusplus 1017} 1018#endif 1019 1020#endif 1021