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