tgsi_ureg.h revision 681ed756c05ad0be03425417dce18fb1d525e0bd
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 ureg_src *src, 455 unsigned nr_src ); 456 457 458void 459ureg_label_insn(struct ureg_program *ureg, 460 unsigned opcode, 461 const struct ureg_src *src, 462 unsigned nr_src, 463 unsigned *label); 464 465 466/*********************************************************************** 467 * Internal instruction helpers, don't call these directly: 468 */ 469 470struct ureg_emit_insn_result { 471 unsigned insn_token; /*< Used to fixup insn size. */ 472 unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */ 473}; 474 475struct ureg_emit_insn_result 476ureg_emit_insn(struct ureg_program *ureg, 477 unsigned opcode, 478 boolean saturate, 479 boolean predicate, 480 boolean pred_negate, 481 unsigned pred_swizzle_x, 482 unsigned pred_swizzle_y, 483 unsigned pred_swizzle_z, 484 unsigned pred_swizzle_w, 485 unsigned num_dst, 486 unsigned num_src ); 487 488void 489ureg_emit_label(struct ureg_program *ureg, 490 unsigned insn_token, 491 unsigned *label_token ); 492 493void 494ureg_emit_texture(struct ureg_program *ureg, 495 unsigned insn_token, 496 unsigned target ); 497 498void 499ureg_emit_dst( struct ureg_program *ureg, 500 struct ureg_dst dst ); 501 502void 503ureg_emit_src( struct ureg_program *ureg, 504 struct ureg_src src ); 505 506void 507ureg_fixup_insn_size(struct ureg_program *ureg, 508 unsigned insn ); 509 510 511#define OP00( op ) \ 512static INLINE void ureg_##op( struct ureg_program *ureg ) \ 513{ \ 514 unsigned opcode = TGSI_OPCODE_##op; \ 515 unsigned insn = ureg_emit_insn(ureg, \ 516 opcode, \ 517 FALSE, \ 518 FALSE, \ 519 FALSE, \ 520 TGSI_SWIZZLE_X, \ 521 TGSI_SWIZZLE_Y, \ 522 TGSI_SWIZZLE_Z, \ 523 TGSI_SWIZZLE_W, \ 524 0, \ 525 0).insn_token; \ 526 ureg_fixup_insn_size( ureg, insn ); \ 527} 528 529#define OP01( op ) \ 530static INLINE void ureg_##op( struct ureg_program *ureg, \ 531 struct ureg_src src ) \ 532{ \ 533 unsigned opcode = TGSI_OPCODE_##op; \ 534 unsigned insn = ureg_emit_insn(ureg, \ 535 opcode, \ 536 FALSE, \ 537 FALSE, \ 538 FALSE, \ 539 TGSI_SWIZZLE_X, \ 540 TGSI_SWIZZLE_Y, \ 541 TGSI_SWIZZLE_Z, \ 542 TGSI_SWIZZLE_W, \ 543 0, \ 544 1).insn_token; \ 545 ureg_emit_src( ureg, src ); \ 546 ureg_fixup_insn_size( ureg, insn ); \ 547} 548 549#define OP00_LBL( op ) \ 550static INLINE void ureg_##op( struct ureg_program *ureg, \ 551 unsigned *label_token ) \ 552{ \ 553 unsigned opcode = TGSI_OPCODE_##op; \ 554 struct ureg_emit_insn_result insn; \ 555 insn = ureg_emit_insn(ureg, \ 556 opcode, \ 557 FALSE, \ 558 FALSE, \ 559 FALSE, \ 560 TGSI_SWIZZLE_X, \ 561 TGSI_SWIZZLE_Y, \ 562 TGSI_SWIZZLE_Z, \ 563 TGSI_SWIZZLE_W, \ 564 0, \ 565 0); \ 566 ureg_emit_label( ureg, insn.extended_token, label_token ); \ 567 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 568} 569 570#define OP01_LBL( op ) \ 571static INLINE void ureg_##op( struct ureg_program *ureg, \ 572 struct ureg_src src, \ 573 unsigned *label_token ) \ 574{ \ 575 unsigned opcode = TGSI_OPCODE_##op; \ 576 struct ureg_emit_insn_result insn; \ 577 insn = ureg_emit_insn(ureg, \ 578 opcode, \ 579 FALSE, \ 580 FALSE, \ 581 FALSE, \ 582 TGSI_SWIZZLE_X, \ 583 TGSI_SWIZZLE_Y, \ 584 TGSI_SWIZZLE_Z, \ 585 TGSI_SWIZZLE_W, \ 586 0, \ 587 1); \ 588 ureg_emit_label( ureg, insn.extended_token, label_token ); \ 589 ureg_emit_src( ureg, src ); \ 590 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 591} 592 593#define OP10( op ) \ 594static INLINE void ureg_##op( struct ureg_program *ureg, \ 595 struct ureg_dst dst ) \ 596{ \ 597 unsigned opcode = TGSI_OPCODE_##op; \ 598 unsigned insn = ureg_emit_insn(ureg, \ 599 opcode, \ 600 dst.Saturate, \ 601 dst.Predicate, \ 602 dst.PredNegate, \ 603 dst.PredSwizzleX, \ 604 dst.PredSwizzleY, \ 605 dst.PredSwizzleZ, \ 606 dst.PredSwizzleW, \ 607 1, \ 608 0).insn_token; \ 609 ureg_emit_dst( ureg, dst ); \ 610 ureg_fixup_insn_size( ureg, insn ); \ 611} 612 613 614#define OP11( op ) \ 615static INLINE void ureg_##op( struct ureg_program *ureg, \ 616 struct ureg_dst dst, \ 617 struct ureg_src src ) \ 618{ \ 619 unsigned opcode = TGSI_OPCODE_##op; \ 620 unsigned insn = ureg_emit_insn(ureg, \ 621 opcode, \ 622 dst.Saturate, \ 623 dst.Predicate, \ 624 dst.PredNegate, \ 625 dst.PredSwizzleX, \ 626 dst.PredSwizzleY, \ 627 dst.PredSwizzleZ, \ 628 dst.PredSwizzleW, \ 629 1, \ 630 1).insn_token; \ 631 ureg_emit_dst( ureg, dst ); \ 632 ureg_emit_src( ureg, src ); \ 633 ureg_fixup_insn_size( ureg, insn ); \ 634} 635 636#define OP12( op ) \ 637static INLINE void ureg_##op( struct ureg_program *ureg, \ 638 struct ureg_dst dst, \ 639 struct ureg_src src0, \ 640 struct ureg_src src1 ) \ 641{ \ 642 unsigned opcode = TGSI_OPCODE_##op; \ 643 unsigned insn = ureg_emit_insn(ureg, \ 644 opcode, \ 645 dst.Saturate, \ 646 dst.Predicate, \ 647 dst.PredNegate, \ 648 dst.PredSwizzleX, \ 649 dst.PredSwizzleY, \ 650 dst.PredSwizzleZ, \ 651 dst.PredSwizzleW, \ 652 1, \ 653 2).insn_token; \ 654 ureg_emit_dst( ureg, dst ); \ 655 ureg_emit_src( ureg, src0 ); \ 656 ureg_emit_src( ureg, src1 ); \ 657 ureg_fixup_insn_size( ureg, insn ); \ 658} 659 660#define OP12_TEX( op ) \ 661static INLINE void ureg_##op( struct ureg_program *ureg, \ 662 struct ureg_dst dst, \ 663 unsigned target, \ 664 struct ureg_src src0, \ 665 struct ureg_src src1 ) \ 666{ \ 667 unsigned opcode = TGSI_OPCODE_##op; \ 668 struct ureg_emit_insn_result insn; \ 669 insn = ureg_emit_insn(ureg, \ 670 opcode, \ 671 dst.Saturate, \ 672 dst.Predicate, \ 673 dst.PredNegate, \ 674 dst.PredSwizzleX, \ 675 dst.PredSwizzleY, \ 676 dst.PredSwizzleZ, \ 677 dst.PredSwizzleW, \ 678 1, \ 679 2); \ 680 ureg_emit_texture( ureg, insn.extended_token, target ); \ 681 ureg_emit_dst( ureg, dst ); \ 682 ureg_emit_src( ureg, src0 ); \ 683 ureg_emit_src( ureg, src1 ); \ 684 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 685} 686 687#define OP13( op ) \ 688static INLINE void ureg_##op( struct ureg_program *ureg, \ 689 struct ureg_dst dst, \ 690 struct ureg_src src0, \ 691 struct ureg_src src1, \ 692 struct ureg_src src2 ) \ 693{ \ 694 unsigned opcode = TGSI_OPCODE_##op; \ 695 unsigned insn = ureg_emit_insn(ureg, \ 696 opcode, \ 697 dst.Saturate, \ 698 dst.Predicate, \ 699 dst.PredNegate, \ 700 dst.PredSwizzleX, \ 701 dst.PredSwizzleY, \ 702 dst.PredSwizzleZ, \ 703 dst.PredSwizzleW, \ 704 1, \ 705 3).insn_token; \ 706 ureg_emit_dst( ureg, dst ); \ 707 ureg_emit_src( ureg, src0 ); \ 708 ureg_emit_src( ureg, src1 ); \ 709 ureg_emit_src( ureg, src2 ); \ 710 ureg_fixup_insn_size( ureg, insn ); \ 711} 712 713#define OP14_TEX( op ) \ 714static INLINE void ureg_##op( struct ureg_program *ureg, \ 715 struct ureg_dst dst, \ 716 unsigned target, \ 717 struct ureg_src src0, \ 718 struct ureg_src src1, \ 719 struct ureg_src src2, \ 720 struct ureg_src src3 ) \ 721{ \ 722 unsigned opcode = TGSI_OPCODE_##op; \ 723 struct ureg_emit_insn_result insn; \ 724 insn = ureg_emit_insn(ureg, \ 725 opcode, \ 726 dst.Saturate, \ 727 dst.Predicate, \ 728 dst.PredNegate, \ 729 dst.PredSwizzleX, \ 730 dst.PredSwizzleY, \ 731 dst.PredSwizzleZ, \ 732 dst.PredSwizzleW, \ 733 1, \ 734 4); \ 735 ureg_emit_texture( ureg, insn.extended_token, target ); \ 736 ureg_emit_dst( ureg, dst ); \ 737 ureg_emit_src( ureg, src0 ); \ 738 ureg_emit_src( ureg, src1 ); \ 739 ureg_emit_src( ureg, src2 ); \ 740 ureg_emit_src( ureg, src3 ); \ 741 ureg_fixup_insn_size( ureg, insn.insn_token ); \ 742} 743 744 745#define OP14( op ) \ 746static INLINE void ureg_##op( struct ureg_program *ureg, \ 747 struct ureg_dst dst, \ 748 struct ureg_src src0, \ 749 struct ureg_src src1, \ 750 struct ureg_src src2, \ 751 struct ureg_src src3 ) \ 752{ \ 753 unsigned opcode = TGSI_OPCODE_##op; \ 754 unsigned insn = ureg_emit_insn(ureg, \ 755 opcode, \ 756 dst.Saturate, \ 757 dst.Predicate, \ 758 dst.PredNegate, \ 759 dst.PredSwizzleX, \ 760 dst.PredSwizzleY, \ 761 dst.PredSwizzleZ, \ 762 dst.PredSwizzleW, \ 763 1, \ 764 4).insn_token; \ 765 ureg_emit_dst( ureg, dst ); \ 766 ureg_emit_src( ureg, src0 ); \ 767 ureg_emit_src( ureg, src1 ); \ 768 ureg_emit_src( ureg, src2 ); \ 769 ureg_emit_src( ureg, src3 ); \ 770 ureg_fixup_insn_size( ureg, insn ); \ 771} 772 773 774#define OP15( op ) \ 775static INLINE void ureg_##op( struct ureg_program *ureg, \ 776 struct ureg_dst dst, \ 777 struct ureg_src src0, \ 778 struct ureg_src src1, \ 779 struct ureg_src src2, \ 780 struct ureg_src src3, \ 781 struct ureg_src src4 ) \ 782{ \ 783 unsigned opcode = TGSI_OPCODE_##op; \ 784 unsigned insn = ureg_emit_insn(ureg, \ 785 opcode, \ 786 dst.Saturate, \ 787 dst.Predicate, \ 788 dst.PredNegate, \ 789 dst.PredSwizzleX, \ 790 dst.PredSwizzleY, \ 791 dst.PredSwizzleZ, \ 792 dst.PredSwizzleW, \ 793 1, \ 794 5).insn_token; \ 795 ureg_emit_dst( ureg, dst ); \ 796 ureg_emit_src( ureg, src0 ); \ 797 ureg_emit_src( ureg, src1 ); \ 798 ureg_emit_src( ureg, src2 ); \ 799 ureg_emit_src( ureg, src3 ); \ 800 ureg_emit_src( ureg, src4 ); \ 801 ureg_fixup_insn_size( ureg, insn ); \ 802} 803 804 805/* Use a template include to generate a correctly-typed ureg_OP() 806 * function for each TGSI opcode: 807 */ 808#include "tgsi_opcode_tmp.h" 809 810 811/*********************************************************************** 812 * Inline helpers for manipulating register structs: 813 */ 814static INLINE struct ureg_src 815ureg_negate( struct ureg_src reg ) 816{ 817 assert(reg.File != TGSI_FILE_NULL); 818 reg.Negate ^= 1; 819 return reg; 820} 821 822static INLINE struct ureg_src 823ureg_abs( struct ureg_src reg ) 824{ 825 assert(reg.File != TGSI_FILE_NULL); 826 reg.Absolute = 1; 827 reg.Negate = 0; 828 return reg; 829} 830 831static INLINE struct ureg_src 832ureg_swizzle( struct ureg_src reg, 833 int x, int y, int z, int w ) 834{ 835 unsigned swz = ( (reg.SwizzleX << 0) | 836 (reg.SwizzleY << 2) | 837 (reg.SwizzleZ << 4) | 838 (reg.SwizzleW << 6)); 839 840 assert(reg.File != TGSI_FILE_NULL); 841 assert(x < 4); 842 assert(y < 4); 843 assert(z < 4); 844 assert(w < 4); 845 846 reg.SwizzleX = (swz >> (x*2)) & 0x3; 847 reg.SwizzleY = (swz >> (y*2)) & 0x3; 848 reg.SwizzleZ = (swz >> (z*2)) & 0x3; 849 reg.SwizzleW = (swz >> (w*2)) & 0x3; 850 return reg; 851} 852 853static INLINE struct ureg_src 854ureg_scalar( struct ureg_src reg, int x ) 855{ 856 return ureg_swizzle(reg, x, x, x, x); 857} 858 859static INLINE struct ureg_dst 860ureg_writemask( struct ureg_dst reg, 861 unsigned writemask ) 862{ 863 assert(reg.File != TGSI_FILE_NULL); 864 reg.WriteMask &= writemask; 865 return reg; 866} 867 868static INLINE struct ureg_dst 869ureg_saturate( struct ureg_dst reg ) 870{ 871 assert(reg.File != TGSI_FILE_NULL); 872 reg.Saturate = 1; 873 return reg; 874} 875 876static INLINE struct ureg_dst 877ureg_predicate(struct ureg_dst reg, 878 boolean negate, 879 unsigned swizzle_x, 880 unsigned swizzle_y, 881 unsigned swizzle_z, 882 unsigned swizzle_w) 883{ 884 assert(reg.File != TGSI_FILE_NULL); 885 reg.Predicate = 1; 886 reg.PredNegate = negate; 887 reg.PredSwizzleX = swizzle_x; 888 reg.PredSwizzleY = swizzle_y; 889 reg.PredSwizzleZ = swizzle_z; 890 reg.PredSwizzleW = swizzle_w; 891 return reg; 892} 893 894static INLINE struct ureg_dst 895ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr ) 896{ 897 assert(reg.File != TGSI_FILE_NULL); 898 assert(addr.File == TGSI_FILE_ADDRESS); 899 reg.Indirect = 1; 900 reg.IndirectIndex = addr.Index; 901 reg.IndirectSwizzle = addr.SwizzleX; 902 return reg; 903} 904 905static INLINE struct ureg_src 906ureg_src_indirect( struct ureg_src reg, struct ureg_src addr ) 907{ 908 assert(reg.File != TGSI_FILE_NULL); 909 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY); 910 reg.Indirect = 1; 911 reg.IndirectFile = addr.File; 912 reg.IndirectIndex = addr.Index; 913 reg.IndirectSwizzle = addr.SwizzleX; 914 return reg; 915} 916 917static INLINE struct ureg_src 918ureg_src_dimension( struct ureg_src reg, int index ) 919{ 920 assert(reg.File != TGSI_FILE_NULL); 921 reg.Dimension = 1; 922 reg.DimIndirect = 0; 923 reg.DimensionIndex = index; 924 return reg; 925} 926 927 928static INLINE struct ureg_src 929ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr, 930 int index ) 931{ 932 assert(reg.File != TGSI_FILE_NULL); 933 reg.Dimension = 1; 934 reg.DimIndirect = 1; 935 reg.DimensionIndex = index; 936 reg.DimIndFile = addr.File; 937 reg.DimIndIndex = addr.Index; 938 reg.DimIndSwizzle = addr.SwizzleX; 939 return reg; 940} 941 942static INLINE struct ureg_dst 943ureg_dst( struct ureg_src src ) 944{ 945 struct ureg_dst dst; 946 947 assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS); 948 949 dst.File = src.File; 950 dst.WriteMask = TGSI_WRITEMASK_XYZW; 951 dst.Indirect = src.Indirect; 952 dst.IndirectIndex = src.IndirectIndex; 953 dst.IndirectSwizzle = src.IndirectSwizzle; 954 dst.Saturate = 0; 955 dst.Predicate = 0; 956 dst.PredNegate = 0; 957 dst.PredSwizzleX = TGSI_SWIZZLE_X; 958 dst.PredSwizzleY = TGSI_SWIZZLE_Y; 959 dst.PredSwizzleZ = TGSI_SWIZZLE_Z; 960 dst.PredSwizzleW = TGSI_SWIZZLE_W; 961 dst.Index = src.Index; 962 963 return dst; 964} 965 966static INLINE struct ureg_src 967ureg_src_register(unsigned file, 968 unsigned index) 969{ 970 struct ureg_src src; 971 972 src.File = file; 973 src.SwizzleX = TGSI_SWIZZLE_X; 974 src.SwizzleY = TGSI_SWIZZLE_Y; 975 src.SwizzleZ = TGSI_SWIZZLE_Z; 976 src.SwizzleW = TGSI_SWIZZLE_W; 977 src.Indirect = 0; 978 src.IndirectFile = TGSI_FILE_NULL; 979 src.IndirectIndex = 0; 980 src.IndirectSwizzle = 0; 981 src.Absolute = 0; 982 src.Index = index; 983 src.Negate = 0; 984 src.Dimension = 0; 985 src.DimensionIndex = 0; 986 src.DimIndirect = 0; 987 src.DimIndFile = TGSI_FILE_NULL; 988 src.DimIndIndex = 0; 989 src.DimIndSwizzle = 0; 990 991 return src; 992} 993 994static INLINE struct ureg_src 995ureg_src( struct ureg_dst dst ) 996{ 997 struct ureg_src src; 998 999 src.File = dst.File; 1000 src.SwizzleX = TGSI_SWIZZLE_X; 1001 src.SwizzleY = TGSI_SWIZZLE_Y; 1002 src.SwizzleZ = TGSI_SWIZZLE_Z; 1003 src.SwizzleW = TGSI_SWIZZLE_W; 1004 src.Indirect = dst.Indirect; 1005 src.IndirectFile = TGSI_FILE_ADDRESS; 1006 src.IndirectIndex = dst.IndirectIndex; 1007 src.IndirectSwizzle = dst.IndirectSwizzle; 1008 src.Absolute = 0; 1009 src.Index = dst.Index; 1010 src.Negate = 0; 1011 src.Dimension = 0; 1012 src.DimensionIndex = 0; 1013 src.DimIndirect = 0; 1014 src.DimIndFile = TGSI_FILE_NULL; 1015 src.DimIndIndex = 0; 1016 src.DimIndSwizzle = 0; 1017 1018 return src; 1019} 1020 1021 1022 1023static INLINE struct ureg_dst 1024ureg_dst_undef( void ) 1025{ 1026 struct ureg_dst dst; 1027 1028 dst.File = TGSI_FILE_NULL; 1029 dst.WriteMask = 0; 1030 dst.Indirect = 0; 1031 dst.IndirectIndex = 0; 1032 dst.IndirectSwizzle = 0; 1033 dst.Saturate = 0; 1034 dst.Predicate = 0; 1035 dst.PredNegate = 0; 1036 dst.PredSwizzleX = TGSI_SWIZZLE_X; 1037 dst.PredSwizzleY = TGSI_SWIZZLE_Y; 1038 dst.PredSwizzleZ = TGSI_SWIZZLE_Z; 1039 dst.PredSwizzleW = TGSI_SWIZZLE_W; 1040 dst.Index = 0; 1041 1042 return dst; 1043} 1044 1045static INLINE struct ureg_src 1046ureg_src_undef( void ) 1047{ 1048 struct ureg_src src; 1049 1050 src.File = TGSI_FILE_NULL; 1051 src.SwizzleX = 0; 1052 src.SwizzleY = 0; 1053 src.SwizzleZ = 0; 1054 src.SwizzleW = 0; 1055 src.Indirect = 0; 1056 src.IndirectFile = TGSI_FILE_NULL; 1057 src.IndirectIndex = 0; 1058 src.IndirectSwizzle = 0; 1059 src.Absolute = 0; 1060 src.Index = 0; 1061 src.Negate = 0; 1062 src.Dimension = 0; 1063 src.DimensionIndex = 0; 1064 src.DimIndirect = 0; 1065 src.DimIndFile = TGSI_FILE_NULL; 1066 src.DimIndIndex = 0; 1067 src.DimIndSwizzle = 0; 1068 1069 return src; 1070} 1071 1072static INLINE boolean 1073ureg_src_is_undef( struct ureg_src src ) 1074{ 1075 return src.File == TGSI_FILE_NULL; 1076} 1077 1078static INLINE boolean 1079ureg_dst_is_undef( struct ureg_dst dst ) 1080{ 1081 return dst.File == TGSI_FILE_NULL; 1082} 1083 1084 1085#ifdef __cplusplus 1086} 1087#endif 1088 1089#endif 1090