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