tgsi_ureg.h revision 2083a276eb270b748d1c2668eb9faa5aadc8e700
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 unsigned IndirectFile : 4; /* TGSI_FILE_ */ 57 unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */ 58 unsigned DimIndFile : 4; /* TGSI_FILE_ */ 59 unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */ 60 int Index : 16; /* SINT */ 61 int IndirectIndex : 16; /* SINT */ 62 int DimensionIndex : 16; /* SINT */ 63 int DimIndIndex : 16; /* SINT */ 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 variant 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 273struct ureg_src 274ureg_DECL_resource(struct ureg_program *, 275 unsigned index, 276 unsigned target, 277 unsigned return_type_x, 278 unsigned return_type_y, 279 unsigned return_type_z, 280 unsigned return_type_w ); 281 282 283static INLINE struct ureg_src 284ureg_imm4f( struct ureg_program *ureg, 285 float a, float b, 286 float c, float d) 287{ 288 float v[4]; 289 v[0] = a; 290 v[1] = b; 291 v[2] = c; 292 v[3] = d; 293 return ureg_DECL_immediate( ureg, v, 4 ); 294} 295 296static INLINE struct ureg_src 297ureg_imm3f( struct ureg_program *ureg, 298 float a, float b, 299 float c) 300{ 301 float v[3]; 302 v[0] = a; 303 v[1] = b; 304 v[2] = c; 305 return ureg_DECL_immediate( ureg, v, 3 ); 306} 307 308static INLINE struct ureg_src 309ureg_imm2f( struct ureg_program *ureg, 310 float a, float b) 311{ 312 float v[2]; 313 v[0] = a; 314 v[1] = b; 315 return ureg_DECL_immediate( ureg, v, 2 ); 316} 317 318static INLINE struct ureg_src 319ureg_imm1f( struct ureg_program *ureg, 320 float a) 321{ 322 float v[1]; 323 v[0] = a; 324 return ureg_DECL_immediate( ureg, v, 1 ); 325} 326 327static INLINE struct ureg_src 328ureg_imm4u( struct ureg_program *ureg, 329 unsigned a, unsigned b, 330 unsigned c, unsigned d) 331{ 332 unsigned v[4]; 333 v[0] = a; 334 v[1] = b; 335 v[2] = c; 336 v[3] = d; 337 return ureg_DECL_immediate_uint( ureg, v, 4 ); 338} 339 340static INLINE struct ureg_src 341ureg_imm3u( struct ureg_program *ureg, 342 unsigned a, unsigned b, 343 unsigned c) 344{ 345 unsigned v[3]; 346 v[0] = a; 347 v[1] = b; 348 v[2] = c; 349 return ureg_DECL_immediate_uint( ureg, v, 3 ); 350} 351 352static INLINE struct ureg_src 353ureg_imm2u( struct ureg_program *ureg, 354 unsigned a, unsigned b) 355{ 356 unsigned v[2]; 357 v[0] = a; 358 v[1] = b; 359 return ureg_DECL_immediate_uint( ureg, v, 2 ); 360} 361 362static INLINE struct ureg_src 363ureg_imm1u( struct ureg_program *ureg, 364 unsigned a) 365{ 366 return ureg_DECL_immediate_uint( ureg, &a, 1 ); 367} 368 369static INLINE struct ureg_src 370ureg_imm4i( struct ureg_program *ureg, 371 int a, int b, 372 int c, int d) 373{ 374 int v[4]; 375 v[0] = a; 376 v[1] = b; 377 v[2] = c; 378 v[3] = d; 379 return ureg_DECL_immediate_int( ureg, v, 4 ); 380} 381 382static INLINE struct ureg_src 383ureg_imm3i( struct ureg_program *ureg, 384 int a, int b, 385 int c) 386{ 387 int v[3]; 388 v[0] = a; 389 v[1] = b; 390 v[2] = c; 391 return ureg_DECL_immediate_int( ureg, v, 3 ); 392} 393 394static INLINE struct ureg_src 395ureg_imm2i( struct ureg_program *ureg, 396 int a, int b) 397{ 398 int v[2]; 399 v[0] = a; 400 v[1] = b; 401 return ureg_DECL_immediate_int( ureg, v, 2 ); 402} 403 404static INLINE struct ureg_src 405ureg_imm1i( struct ureg_program *ureg, 406 int a) 407{ 408 return ureg_DECL_immediate_int( ureg, &a, 1 ); 409} 410 411/*********************************************************************** 412 * Functions for patching up labels 413 */ 414 415 416/* Will return a number which can be used in a label to point to the 417 * next instruction to be emitted. 418 */ 419unsigned 420ureg_get_instruction_number( struct ureg_program *ureg ); 421 422 423/* Patch a given label (expressed as a token number) to point to a 424 * given instruction (expressed as an instruction number). 425 * 426 * Labels are obtained from instruction emitters, eg ureg_CAL(). 427 * Instruction numbers are obtained from ureg_get_instruction_number(), 428 * above. 429 */ 430void 431ureg_fixup_label(struct ureg_program *ureg, 432 unsigned label_token, 433 unsigned instruction_number ); 434 435 436/* Generic instruction emitter. Use if you need to pass the opcode as 437 * a parameter, rather than using the emit_OP() variants below. 438 */ 439void 440ureg_insn(struct ureg_program *ureg, 441 unsigned opcode, 442 const struct ureg_dst *dst, 443 unsigned nr_dst, 444 const struct ureg_src *src, 445 unsigned nr_src ); 446 447 448void 449ureg_tex_insn(struct ureg_program *ureg, 450 unsigned opcode, 451 const struct ureg_dst *dst, 452 unsigned nr_dst, 453 unsigned target, 454 const struct tgsi_texture_offset *texoffsets, 455 unsigned nr_offset, 456 const struct ureg_src *src, 457 unsigned nr_src ); 458 459 460void 461ureg_label_insn(struct ureg_program *ureg, 462 unsigned opcode, 463 const struct ureg_src *src, 464 unsigned nr_src, 465 unsigned *label); 466 467 468/*********************************************************************** 469 * Internal instruction helpers, don't call these directly: 470 */ 471 472struct ureg_emit_insn_result { 473 unsigned insn_token; /*< Used to fixup insn size. */ 474 unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */ 475}; 476 477struct ureg_emit_insn_result 478ureg_emit_insn(struct ureg_program *ureg, 479 unsigned opcode, 480 boolean saturate, 481 boolean predicate, 482 boolean pred_negate, 483 unsigned pred_swizzle_x, 484 unsigned pred_swizzle_y, 485 unsigned pred_swizzle_z, 486 unsigned pred_swizzle_w, 487 unsigned num_dst, 488 unsigned num_src ); 489 490void 491ureg_emit_label(struct ureg_program *ureg, 492 unsigned insn_token, 493 unsigned *label_token ); 494 495void 496ureg_emit_texture(struct ureg_program *ureg, 497 unsigned insn_token, 498 unsigned target, unsigned num_offsets); 499 500void 501ureg_emit_texture_offset(struct ureg_program *ureg, 502 const struct tgsi_texture_offset *offset); 503 504void 505ureg_emit_dst( struct ureg_program *ureg, 506 struct ureg_dst dst ); 507 508void 509ureg_emit_src( struct ureg_program *ureg, 510 struct ureg_src src ); 511 512void 513ureg_fixup_insn_size(struct ureg_program *ureg, 514 unsigned insn ); 515 516 517#define OP00( op ) \ 518static INLINE void ureg_##op( struct ureg_program *ureg ) \ 519{ \ 520 unsigned opcode = TGSI_OPCODE_##op; \ 521 unsigned insn = ureg_emit_insn(ureg, \ 522 opcode, \ 523 FALSE, \ 524 FALSE, \ 525 FALSE, \ 526 TGSI_SWIZZLE_X, \ 527 TGSI_SWIZZLE_Y, \ 528 TGSI_SWIZZLE_Z, \ 529 TGSI_SWIZZLE_W, \ 530 0, \ 531 0).insn_token; \ 532 ureg_fixup_insn_size( ureg, insn ); \ 533} 534 535#define OP01( op ) \ 536static INLINE void ureg_##op( struct ureg_program *ureg, \ 537 struct ureg_src src ) \ 538{ \ 539 unsigned opcode = TGSI_OPCODE_##op; \ 540 unsigned insn = ureg_emit_insn(ureg, \ 541 opcode, \ 542 FALSE, \ 543 FALSE, \ 544 FALSE, \ 545 TGSI_SWIZZLE_X, \ 546 TGSI_SWIZZLE_Y, \ 547 TGSI_SWIZZLE_Z, \ 548 TGSI_SWIZZLE_W, \ 549 0, \ 550 1).insn_token; \ 551 ureg_emit_src( ureg, src ); \ 552 ureg_fixup_insn_size( ureg, insn ); \ 553} 554 555#define OP00_LBL( op ) \ 556static INLINE void ureg_##op( struct ureg_program *ureg, \ 557 unsigned *label_token ) \ 558{ \ 559 unsigned opcode = TGSI_OPCODE_##op; \ 560 struct ureg_emit_insn_result insn; \ 561 insn = ureg_emit_insn(ureg, \ 562 opcode, \ 563 FALSE, \ 564 FALSE, \ 565 FALSE, \ 566 TGSI_SWIZZLE_X, \ 567 TGSI_SWIZZLE_Y, \ 568 TGSI_SWIZZLE_Z, \ 569 TGSI_SWIZZLE_W, \ 570 0, \ 571 0); \ 572 ureg_emit_label( ureg, insn.extended_token, label_token ); \ 573 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 574} 575 576#define OP01_LBL( op ) \ 577static INLINE void ureg_##op( struct ureg_program *ureg, \ 578 struct ureg_src src, \ 579 unsigned *label_token ) \ 580{ \ 581 unsigned opcode = TGSI_OPCODE_##op; \ 582 struct ureg_emit_insn_result insn; \ 583 insn = ureg_emit_insn(ureg, \ 584 opcode, \ 585 FALSE, \ 586 FALSE, \ 587 FALSE, \ 588 TGSI_SWIZZLE_X, \ 589 TGSI_SWIZZLE_Y, \ 590 TGSI_SWIZZLE_Z, \ 591 TGSI_SWIZZLE_W, \ 592 0, \ 593 1); \ 594 ureg_emit_label( ureg, insn.extended_token, label_token ); \ 595 ureg_emit_src( ureg, src ); \ 596 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 597} 598 599#define OP10( op ) \ 600static INLINE void ureg_##op( struct ureg_program *ureg, \ 601 struct ureg_dst dst ) \ 602{ \ 603 unsigned opcode = TGSI_OPCODE_##op; \ 604 unsigned insn = ureg_emit_insn(ureg, \ 605 opcode, \ 606 dst.Saturate, \ 607 dst.Predicate, \ 608 dst.PredNegate, \ 609 dst.PredSwizzleX, \ 610 dst.PredSwizzleY, \ 611 dst.PredSwizzleZ, \ 612 dst.PredSwizzleW, \ 613 1, \ 614 0).insn_token; \ 615 ureg_emit_dst( ureg, dst ); \ 616 ureg_fixup_insn_size( ureg, insn ); \ 617} 618 619 620#define OP11( op ) \ 621static INLINE void ureg_##op( struct ureg_program *ureg, \ 622 struct ureg_dst dst, \ 623 struct ureg_src src ) \ 624{ \ 625 unsigned opcode = TGSI_OPCODE_##op; \ 626 unsigned insn = ureg_emit_insn(ureg, \ 627 opcode, \ 628 dst.Saturate, \ 629 dst.Predicate, \ 630 dst.PredNegate, \ 631 dst.PredSwizzleX, \ 632 dst.PredSwizzleY, \ 633 dst.PredSwizzleZ, \ 634 dst.PredSwizzleW, \ 635 1, \ 636 1).insn_token; \ 637 ureg_emit_dst( ureg, dst ); \ 638 ureg_emit_src( ureg, src ); \ 639 ureg_fixup_insn_size( ureg, insn ); \ 640} 641 642#define OP12( op ) \ 643static INLINE void ureg_##op( struct ureg_program *ureg, \ 644 struct ureg_dst dst, \ 645 struct ureg_src src0, \ 646 struct ureg_src src1 ) \ 647{ \ 648 unsigned opcode = TGSI_OPCODE_##op; \ 649 unsigned insn = ureg_emit_insn(ureg, \ 650 opcode, \ 651 dst.Saturate, \ 652 dst.Predicate, \ 653 dst.PredNegate, \ 654 dst.PredSwizzleX, \ 655 dst.PredSwizzleY, \ 656 dst.PredSwizzleZ, \ 657 dst.PredSwizzleW, \ 658 1, \ 659 2).insn_token; \ 660 ureg_emit_dst( ureg, dst ); \ 661 ureg_emit_src( ureg, src0 ); \ 662 ureg_emit_src( ureg, src1 ); \ 663 ureg_fixup_insn_size( ureg, insn ); \ 664} 665 666#define OP12_TEX( op ) \ 667static INLINE void ureg_##op( struct ureg_program *ureg, \ 668 struct ureg_dst dst, \ 669 unsigned target, \ 670 struct ureg_src src0, \ 671 struct ureg_src src1 ) \ 672{ \ 673 unsigned opcode = TGSI_OPCODE_##op; \ 674 struct ureg_emit_insn_result insn; \ 675 insn = ureg_emit_insn(ureg, \ 676 opcode, \ 677 dst.Saturate, \ 678 dst.Predicate, \ 679 dst.PredNegate, \ 680 dst.PredSwizzleX, \ 681 dst.PredSwizzleY, \ 682 dst.PredSwizzleZ, \ 683 dst.PredSwizzleW, \ 684 1, \ 685 2); \ 686 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \ 687 ureg_emit_dst( ureg, dst ); \ 688 ureg_emit_src( ureg, src0 ); \ 689 ureg_emit_src( ureg, src1 ); \ 690 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 691} 692 693#define OP13( op ) \ 694static INLINE void ureg_##op( struct ureg_program *ureg, \ 695 struct ureg_dst dst, \ 696 struct ureg_src src0, \ 697 struct ureg_src src1, \ 698 struct ureg_src src2 ) \ 699{ \ 700 unsigned opcode = TGSI_OPCODE_##op; \ 701 unsigned insn = ureg_emit_insn(ureg, \ 702 opcode, \ 703 dst.Saturate, \ 704 dst.Predicate, \ 705 dst.PredNegate, \ 706 dst.PredSwizzleX, \ 707 dst.PredSwizzleY, \ 708 dst.PredSwizzleZ, \ 709 dst.PredSwizzleW, \ 710 1, \ 711 3).insn_token; \ 712 ureg_emit_dst( ureg, dst ); \ 713 ureg_emit_src( ureg, src0 ); \ 714 ureg_emit_src( ureg, src1 ); \ 715 ureg_emit_src( ureg, src2 ); \ 716 ureg_fixup_insn_size( ureg, insn ); \ 717} 718 719#define OP14_TEX( op ) \ 720static INLINE void ureg_##op( struct ureg_program *ureg, \ 721 struct ureg_dst dst, \ 722 unsigned target, \ 723 struct ureg_src src0, \ 724 struct ureg_src src1, \ 725 struct ureg_src src2, \ 726 struct ureg_src src3 ) \ 727{ \ 728 unsigned opcode = TGSI_OPCODE_##op; \ 729 struct ureg_emit_insn_result insn; \ 730 insn = ureg_emit_insn(ureg, \ 731 opcode, \ 732 dst.Saturate, \ 733 dst.Predicate, \ 734 dst.PredNegate, \ 735 dst.PredSwizzleX, \ 736 dst.PredSwizzleY, \ 737 dst.PredSwizzleZ, \ 738 dst.PredSwizzleW, \ 739 1, \ 740 4); \ 741 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \ 742 ureg_emit_dst( ureg, dst ); \ 743 ureg_emit_src( ureg, src0 ); \ 744 ureg_emit_src( ureg, src1 ); \ 745 ureg_emit_src( ureg, src2 ); \ 746 ureg_emit_src( ureg, src3 ); \ 747 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 748} 749 750 751#define OP14( op ) \ 752static INLINE void ureg_##op( struct ureg_program *ureg, \ 753 struct ureg_dst dst, \ 754 struct ureg_src src0, \ 755 struct ureg_src src1, \ 756 struct ureg_src src2, \ 757 struct ureg_src src3 ) \ 758{ \ 759 unsigned opcode = TGSI_OPCODE_##op; \ 760 unsigned insn = ureg_emit_insn(ureg, \ 761 opcode, \ 762 dst.Saturate, \ 763 dst.Predicate, \ 764 dst.PredNegate, \ 765 dst.PredSwizzleX, \ 766 dst.PredSwizzleY, \ 767 dst.PredSwizzleZ, \ 768 dst.PredSwizzleW, \ 769 1, \ 770 4).insn_token; \ 771 ureg_emit_dst( ureg, dst ); \ 772 ureg_emit_src( ureg, src0 ); \ 773 ureg_emit_src( ureg, src1 ); \ 774 ureg_emit_src( ureg, src2 ); \ 775 ureg_emit_src( ureg, src3 ); \ 776 ureg_fixup_insn_size( ureg, insn ); \ 777} 778 779 780#define OP15( op ) \ 781static INLINE void ureg_##op( struct ureg_program *ureg, \ 782 struct ureg_dst dst, \ 783 struct ureg_src src0, \ 784 struct ureg_src src1, \ 785 struct ureg_src src2, \ 786 struct ureg_src src3, \ 787 struct ureg_src src4 ) \ 788{ \ 789 unsigned opcode = TGSI_OPCODE_##op; \ 790 unsigned insn = ureg_emit_insn(ureg, \ 791 opcode, \ 792 dst.Saturate, \ 793 dst.Predicate, \ 794 dst.PredNegate, \ 795 dst.PredSwizzleX, \ 796 dst.PredSwizzleY, \ 797 dst.PredSwizzleZ, \ 798 dst.PredSwizzleW, \ 799 1, \ 800 5).insn_token; \ 801 ureg_emit_dst( ureg, dst ); \ 802 ureg_emit_src( ureg, src0 ); \ 803 ureg_emit_src( ureg, src1 ); \ 804 ureg_emit_src( ureg, src2 ); \ 805 ureg_emit_src( ureg, src3 ); \ 806 ureg_emit_src( ureg, src4 ); \ 807 ureg_fixup_insn_size( ureg, insn ); \ 808} 809 810 811/* Use a template include to generate a correctly-typed ureg_OP() 812 * function for each TGSI opcode: 813 */ 814#include "tgsi_opcode_tmp.h" 815 816 817/*********************************************************************** 818 * Inline helpers for manipulating register structs: 819 */ 820static INLINE struct ureg_src 821ureg_negate( struct ureg_src reg ) 822{ 823 assert(reg.File != TGSI_FILE_NULL); 824 reg.Negate ^= 1; 825 return reg; 826} 827 828static INLINE struct ureg_src 829ureg_abs( struct ureg_src reg ) 830{ 831 assert(reg.File != TGSI_FILE_NULL); 832 reg.Absolute = 1; 833 reg.Negate = 0; 834 return reg; 835} 836 837static INLINE struct ureg_src 838ureg_swizzle( struct ureg_src reg, 839 int x, int y, int z, int w ) 840{ 841 unsigned swz = ( (reg.SwizzleX << 0) | 842 (reg.SwizzleY << 2) | 843 (reg.SwizzleZ << 4) | 844 (reg.SwizzleW << 6)); 845 846 assert(reg.File != TGSI_FILE_NULL); 847 assert(x < 4); 848 assert(y < 4); 849 assert(z < 4); 850 assert(w < 4); 851 852 reg.SwizzleX = (swz >> (x*2)) & 0x3; 853 reg.SwizzleY = (swz >> (y*2)) & 0x3; 854 reg.SwizzleZ = (swz >> (z*2)) & 0x3; 855 reg.SwizzleW = (swz >> (w*2)) & 0x3; 856 return reg; 857} 858 859static INLINE struct ureg_src 860ureg_scalar( struct ureg_src reg, int x ) 861{ 862 return ureg_swizzle(reg, x, x, x, x); 863} 864 865static INLINE struct ureg_dst 866ureg_writemask( struct ureg_dst reg, 867 unsigned writemask ) 868{ 869 assert(reg.File != TGSI_FILE_NULL); 870 reg.WriteMask &= writemask; 871 return reg; 872} 873 874static INLINE struct ureg_dst 875ureg_saturate( struct ureg_dst reg ) 876{ 877 assert(reg.File != TGSI_FILE_NULL); 878 reg.Saturate = 1; 879 return reg; 880} 881 882static INLINE struct ureg_dst 883ureg_predicate(struct ureg_dst reg, 884 boolean negate, 885 unsigned swizzle_x, 886 unsigned swizzle_y, 887 unsigned swizzle_z, 888 unsigned swizzle_w) 889{ 890 assert(reg.File != TGSI_FILE_NULL); 891 reg.Predicate = 1; 892 reg.PredNegate = negate; 893 reg.PredSwizzleX = swizzle_x; 894 reg.PredSwizzleY = swizzle_y; 895 reg.PredSwizzleZ = swizzle_z; 896 reg.PredSwizzleW = swizzle_w; 897 return reg; 898} 899 900static INLINE struct ureg_dst 901ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr ) 902{ 903 assert(reg.File != TGSI_FILE_NULL); 904 assert(addr.File == TGSI_FILE_ADDRESS); 905 reg.Indirect = 1; 906 reg.IndirectIndex = addr.Index; 907 reg.IndirectSwizzle = addr.SwizzleX; 908 return reg; 909} 910 911static INLINE struct ureg_src 912ureg_src_indirect( struct ureg_src reg, struct ureg_src addr ) 913{ 914 assert(reg.File != TGSI_FILE_NULL); 915 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY); 916 reg.Indirect = 1; 917 reg.IndirectFile = addr.File; 918 reg.IndirectIndex = addr.Index; 919 reg.IndirectSwizzle = addr.SwizzleX; 920 return reg; 921} 922 923static INLINE struct ureg_src 924ureg_src_dimension( struct ureg_src reg, int index ) 925{ 926 assert(reg.File != TGSI_FILE_NULL); 927 reg.Dimension = 1; 928 reg.DimIndirect = 0; 929 reg.DimensionIndex = index; 930 return reg; 931} 932 933 934static INLINE struct ureg_src 935ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr, 936 int index ) 937{ 938 assert(reg.File != TGSI_FILE_NULL); 939 reg.Dimension = 1; 940 reg.DimIndirect = 1; 941 reg.DimensionIndex = index; 942 reg.DimIndFile = addr.File; 943 reg.DimIndIndex = addr.Index; 944 reg.DimIndSwizzle = addr.SwizzleX; 945 return reg; 946} 947 948static INLINE struct ureg_dst 949ureg_dst( struct ureg_src src ) 950{ 951 struct ureg_dst dst; 952 953 assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS); 954 955 dst.File = src.File; 956 dst.WriteMask = TGSI_WRITEMASK_XYZW; 957 dst.Indirect = src.Indirect; 958 dst.IndirectIndex = src.IndirectIndex; 959 dst.IndirectSwizzle = src.IndirectSwizzle; 960 dst.Saturate = 0; 961 dst.Predicate = 0; 962 dst.PredNegate = 0; 963 dst.PredSwizzleX = TGSI_SWIZZLE_X; 964 dst.PredSwizzleY = TGSI_SWIZZLE_Y; 965 dst.PredSwizzleZ = TGSI_SWIZZLE_Z; 966 dst.PredSwizzleW = TGSI_SWIZZLE_W; 967 dst.Index = src.Index; 968 969 return dst; 970} 971 972static INLINE struct ureg_src 973ureg_src_register(unsigned file, 974 unsigned index) 975{ 976 struct ureg_src src; 977 978 src.File = file; 979 src.SwizzleX = TGSI_SWIZZLE_X; 980 src.SwizzleY = TGSI_SWIZZLE_Y; 981 src.SwizzleZ = TGSI_SWIZZLE_Z; 982 src.SwizzleW = TGSI_SWIZZLE_W; 983 src.Indirect = 0; 984 src.IndirectFile = TGSI_FILE_NULL; 985 src.IndirectIndex = 0; 986 src.IndirectSwizzle = 0; 987 src.Absolute = 0; 988 src.Index = index; 989 src.Negate = 0; 990 src.Dimension = 0; 991 src.DimensionIndex = 0; 992 src.DimIndirect = 0; 993 src.DimIndFile = TGSI_FILE_NULL; 994 src.DimIndIndex = 0; 995 src.DimIndSwizzle = 0; 996 997 return src; 998} 999 1000static INLINE struct ureg_src 1001ureg_src( struct ureg_dst dst ) 1002{ 1003 struct ureg_src src; 1004 1005 src.File = dst.File; 1006 src.SwizzleX = TGSI_SWIZZLE_X; 1007 src.SwizzleY = TGSI_SWIZZLE_Y; 1008 src.SwizzleZ = TGSI_SWIZZLE_Z; 1009 src.SwizzleW = TGSI_SWIZZLE_W; 1010 src.Indirect = dst.Indirect; 1011 src.IndirectFile = TGSI_FILE_ADDRESS; 1012 src.IndirectIndex = dst.IndirectIndex; 1013 src.IndirectSwizzle = dst.IndirectSwizzle; 1014 src.Absolute = 0; 1015 src.Index = dst.Index; 1016 src.Negate = 0; 1017 src.Dimension = 0; 1018 src.DimensionIndex = 0; 1019 src.DimIndirect = 0; 1020 src.DimIndFile = TGSI_FILE_NULL; 1021 src.DimIndIndex = 0; 1022 src.DimIndSwizzle = 0; 1023 1024 return src; 1025} 1026 1027 1028 1029static INLINE struct ureg_dst 1030ureg_dst_undef( void ) 1031{ 1032 struct ureg_dst dst; 1033 1034 dst.File = TGSI_FILE_NULL; 1035 dst.WriteMask = 0; 1036 dst.Indirect = 0; 1037 dst.IndirectIndex = 0; 1038 dst.IndirectSwizzle = 0; 1039 dst.Saturate = 0; 1040 dst.Predicate = 0; 1041 dst.PredNegate = 0; 1042 dst.PredSwizzleX = TGSI_SWIZZLE_X; 1043 dst.PredSwizzleY = TGSI_SWIZZLE_Y; 1044 dst.PredSwizzleZ = TGSI_SWIZZLE_Z; 1045 dst.PredSwizzleW = TGSI_SWIZZLE_W; 1046 dst.Index = 0; 1047 1048 return dst; 1049} 1050 1051static INLINE struct ureg_src 1052ureg_src_undef( void ) 1053{ 1054 struct ureg_src src; 1055 1056 src.File = TGSI_FILE_NULL; 1057 src.SwizzleX = 0; 1058 src.SwizzleY = 0; 1059 src.SwizzleZ = 0; 1060 src.SwizzleW = 0; 1061 src.Indirect = 0; 1062 src.IndirectFile = TGSI_FILE_NULL; 1063 src.IndirectIndex = 0; 1064 src.IndirectSwizzle = 0; 1065 src.Absolute = 0; 1066 src.Index = 0; 1067 src.Negate = 0; 1068 src.Dimension = 0; 1069 src.DimensionIndex = 0; 1070 src.DimIndirect = 0; 1071 src.DimIndFile = TGSI_FILE_NULL; 1072 src.DimIndIndex = 0; 1073 src.DimIndSwizzle = 0; 1074 1075 return src; 1076} 1077 1078static INLINE boolean 1079ureg_src_is_undef( struct ureg_src src ) 1080{ 1081 return src.File == TGSI_FILE_NULL; 1082} 1083 1084static INLINE boolean 1085ureg_dst_is_undef( struct ureg_dst dst ) 1086{ 1087 return dst.File == TGSI_FILE_NULL; 1088} 1089 1090 1091#ifdef __cplusplus 1092} 1093#endif 1094 1095#endif 1096