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