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