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