Home | History | Annotate | Download | only in tgsi
      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 pipe_screen;
     40 struct ureg_program;
     41 struct pipe_stream_output_info;
     42 
     43 /* Almost a tgsi_src_register, but we need to pull in the Absolute
     44  * flag from the _ext token.  Indirect flag always implies ADDR[0].
     45  */
     46 struct ureg_src
     47 {
     48    unsigned File             : 4;  /* TGSI_FILE_ */
     49    unsigned SwizzleX         : 2;  /* TGSI_SWIZZLE_ */
     50    unsigned SwizzleY         : 2;  /* TGSI_SWIZZLE_ */
     51    unsigned SwizzleZ         : 2;  /* TGSI_SWIZZLE_ */
     52    unsigned SwizzleW         : 2;  /* TGSI_SWIZZLE_ */
     53    unsigned Indirect         : 1;  /* BOOL */
     54    unsigned DimIndirect      : 1;  /* BOOL */
     55    unsigned Dimension        : 1;  /* BOOL */
     56    unsigned Absolute         : 1;  /* BOOL */
     57    unsigned Negate           : 1;  /* BOOL */
     58    unsigned IndirectFile     : 4;  /* TGSI_FILE_ */
     59    unsigned IndirectSwizzle  : 2;  /* TGSI_SWIZZLE_ */
     60    unsigned DimIndFile       : 4;  /* TGSI_FILE_ */
     61    unsigned DimIndSwizzle    : 2;  /* TGSI_SWIZZLE_ */
     62    int      Index            : 16; /* SINT */
     63    int      IndirectIndex    : 16; /* SINT */
     64    int      DimensionIndex   : 16; /* SINT */
     65    int      DimIndIndex      : 16; /* SINT */
     66    unsigned ArrayID          : 10; /* UINT */
     67 };
     68 
     69 /* Very similar to a tgsi_dst_register, removing unsupported fields
     70  * and adding a Saturate flag.  It's easier to push saturate into the
     71  * destination register than to try and create a _SAT variant of each
     72  * instruction function.
     73  */
     74 struct ureg_dst
     75 {
     76    unsigned File            : 4;  /* TGSI_FILE_ */
     77    unsigned WriteMask       : 4;  /* TGSI_WRITEMASK_ */
     78    unsigned Indirect        : 1;  /* BOOL */
     79    unsigned DimIndirect     : 1;  /* BOOL */
     80    unsigned Dimension       : 1;  /* BOOL */
     81    unsigned Saturate        : 1;  /* BOOL */
     82    unsigned Predicate       : 1;
     83    unsigned PredNegate      : 1;  /* BOOL */
     84    unsigned PredSwizzleX    : 2;  /* TGSI_SWIZZLE_ */
     85    unsigned PredSwizzleY    : 2;  /* TGSI_SWIZZLE_ */
     86    unsigned PredSwizzleZ    : 2;  /* TGSI_SWIZZLE_ */
     87    unsigned PredSwizzleW    : 2;  /* TGSI_SWIZZLE_ */
     88    int      Index           : 16; /* SINT */
     89    int      IndirectIndex   : 16; /* SINT */
     90    unsigned IndirectFile    : 4;  /* TGSI_FILE_ */
     91    int      IndirectSwizzle : 2;  /* TGSI_SWIZZLE_ */
     92    unsigned DimIndFile      : 4;  /* TGSI_FILE_ */
     93    unsigned DimIndSwizzle   : 2;  /* TGSI_SWIZZLE_ */
     94    int      DimensionIndex  : 16; /* SINT */
     95    int      DimIndIndex     : 16; /* SINT */
     96    unsigned ArrayID         : 10; /* UINT */
     97 };
     98 
     99 struct pipe_context;
    100 
    101 struct ureg_program *
    102 ureg_create(unsigned processor);
    103 
    104 struct ureg_program *
    105 ureg_create_with_screen(unsigned processor, struct pipe_screen *screen);
    106 
    107 const struct tgsi_token *
    108 ureg_finalize( struct ureg_program * );
    109 
    110 /* Create and return a shader:
    111  */
    112 void *
    113 ureg_create_shader( struct ureg_program *,
    114                     struct pipe_context *pipe,
    115 		    const struct pipe_stream_output_info *so );
    116 
    117 void
    118 ureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor);
    119 
    120 /* Alternately, return the built token stream and hand ownership of
    121  * that memory to the caller:
    122  */
    123 const struct tgsi_token *
    124 ureg_get_tokens( struct ureg_program *ureg,
    125                  unsigned *nr_tokens );
    126 
    127 /*
    128  * Returns the number of currently declared outputs.
    129  */
    130 unsigned
    131 ureg_get_nr_outputs( const struct ureg_program *ureg );
    132 
    133 
    134 /* Free the tokens created by ureg_get_tokens() */
    135 void ureg_free_tokens( const struct tgsi_token *tokens );
    136 
    137 
    138 void
    139 ureg_destroy( struct ureg_program * );
    140 
    141 
    142 /***********************************************************************
    143  * Convenience routine:
    144  */
    145 static inline void *
    146 ureg_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 
    155 static inline void *
    156 ureg_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 
    167 void
    168 ureg_property(struct ureg_program *ureg, unsigned name, unsigned value);
    169 
    170 
    171 /***********************************************************************
    172  * Build shader declarations:
    173  */
    174 
    175 struct ureg_src
    176 ureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program *,
    177                        unsigned semantic_name,
    178                        unsigned semantic_index,
    179                        unsigned interp_mode,
    180                        unsigned cylindrical_wrap,
    181                        unsigned interp_location,
    182                        unsigned index,
    183                        unsigned usage_mask,
    184                        unsigned array_id,
    185                        unsigned array_size);
    186 
    187 struct ureg_src
    188 ureg_DECL_fs_input_cyl_centroid(struct ureg_program *,
    189                        unsigned semantic_name,
    190                        unsigned semantic_index,
    191                        unsigned interp_mode,
    192                        unsigned cylindrical_wrap,
    193                        unsigned interp_location,
    194                        unsigned array_id,
    195                        unsigned array_size);
    196 
    197 static inline struct ureg_src
    198 ureg_DECL_fs_input_cyl(struct ureg_program *ureg,
    199                        unsigned semantic_name,
    200                        unsigned semantic_index,
    201                        unsigned interp_mode,
    202                        unsigned cylindrical_wrap)
    203 {
    204    return ureg_DECL_fs_input_cyl_centroid(ureg,
    205                                  semantic_name,
    206                                  semantic_index,
    207                                  interp_mode,
    208                                  cylindrical_wrap,
    209                                  0, 0, 1);
    210 }
    211 
    212 static inline struct ureg_src
    213 ureg_DECL_fs_input(struct ureg_program *ureg,
    214                    unsigned semantic_name,
    215                    unsigned semantic_index,
    216                    unsigned interp_mode)
    217 {
    218    return ureg_DECL_fs_input_cyl_centroid(ureg,
    219                                  semantic_name,
    220                                  semantic_index,
    221                                  interp_mode,
    222                                  0, 0, 0, 1);
    223 }
    224 
    225 struct ureg_src
    226 ureg_DECL_vs_input( struct ureg_program *,
    227                     unsigned index );
    228 
    229 struct ureg_src
    230 ureg_DECL_input_layout(struct ureg_program *,
    231                 unsigned semantic_name,
    232                 unsigned semantic_index,
    233                 unsigned index,
    234                 unsigned usage_mask,
    235                 unsigned array_id,
    236                 unsigned array_size);
    237 
    238 struct ureg_src
    239 ureg_DECL_input(struct ureg_program *,
    240                 unsigned semantic_name,
    241                 unsigned semantic_index,
    242                 unsigned array_id,
    243                 unsigned array_size);
    244 
    245 struct ureg_src
    246 ureg_DECL_system_value(struct ureg_program *,
    247                        unsigned semantic_name,
    248                        unsigned semantic_index);
    249 
    250 struct ureg_dst
    251 ureg_DECL_output_layout(struct ureg_program *,
    252                         unsigned semantic_name,
    253                         unsigned semantic_index,
    254                         unsigned streams,
    255                         unsigned index,
    256                         unsigned usage_mask,
    257                         unsigned array_id,
    258                         unsigned array_size);
    259 
    260 struct ureg_dst
    261 ureg_DECL_output_masked(struct ureg_program *,
    262                         unsigned semantic_name,
    263                         unsigned semantic_index,
    264                         unsigned usage_mask,
    265                         unsigned array_id,
    266                         unsigned array_size);
    267 
    268 struct ureg_dst
    269 ureg_DECL_output(struct ureg_program *,
    270                  unsigned semantic_name,
    271                  unsigned semantic_index);
    272 
    273 struct ureg_dst
    274 ureg_DECL_output_array(struct ureg_program *ureg,
    275                        unsigned semantic_name,
    276                        unsigned semantic_index,
    277                        unsigned array_id,
    278                        unsigned array_size);
    279 
    280 struct ureg_src
    281 ureg_DECL_immediate( struct ureg_program *,
    282                      const float *v,
    283                      unsigned nr );
    284 
    285 struct ureg_src
    286 ureg_DECL_immediate_f64( struct ureg_program *,
    287                          const double *v,
    288                          unsigned nr );
    289 
    290 struct ureg_src
    291 ureg_DECL_immediate_uint( struct ureg_program *,
    292                           const unsigned *v,
    293                           unsigned nr );
    294 
    295 struct ureg_src
    296 ureg_DECL_immediate_block_uint( struct ureg_program *,
    297                                 const unsigned *v,
    298                                 unsigned nr );
    299 
    300 struct ureg_src
    301 ureg_DECL_immediate_int( struct ureg_program *,
    302                          const int *v,
    303                          unsigned nr );
    304 
    305 struct ureg_src
    306 ureg_DECL_immediate_uint64( struct ureg_program *,
    307                             const uint64_t *v,
    308                             unsigned nr );
    309 
    310 struct ureg_src
    311 ureg_DECL_immediate_int64( struct ureg_program *,
    312                            const int64_t *v,
    313                            unsigned nr );
    314 
    315 void
    316 ureg_DECL_constant2D(struct ureg_program *ureg,
    317                      unsigned first,
    318                      unsigned last,
    319                      unsigned index2D);
    320 
    321 struct ureg_src
    322 ureg_DECL_constant( struct ureg_program *,
    323                     unsigned index );
    324 
    325 struct ureg_dst
    326 ureg_DECL_temporary( struct ureg_program * );
    327 
    328 /**
    329  * Emit a temporary with the LOCAL declaration flag set.  For use when
    330  * the register value is not required to be preserved across
    331  * subroutine boundaries.
    332  */
    333 struct ureg_dst
    334 ureg_DECL_local_temporary( struct ureg_program * );
    335 
    336 /**
    337  * Declare "size" continuous temporary registers.
    338  */
    339 struct ureg_dst
    340 ureg_DECL_array_temporary( struct ureg_program *,
    341                            unsigned size,
    342                            boolean local );
    343 
    344 void
    345 ureg_release_temporary( struct ureg_program *ureg,
    346                         struct ureg_dst tmp );
    347 
    348 struct ureg_dst
    349 ureg_DECL_address( struct ureg_program * );
    350 
    351 struct ureg_dst
    352 ureg_DECL_predicate(struct ureg_program *);
    353 
    354 /* Supply an index to the sampler declaration as this is the hook to
    355  * the external pipe_sampler state.  Users of this function probably
    356  * don't want just any sampler, but a specific one which they've set
    357  * up state for in the context.
    358  */
    359 struct ureg_src
    360 ureg_DECL_sampler( struct ureg_program *,
    361                    unsigned index );
    362 
    363 struct ureg_src
    364 ureg_DECL_sampler_view(struct ureg_program *,
    365                        unsigned index,
    366                        unsigned target,
    367                        unsigned return_type_x,
    368                        unsigned return_type_y,
    369                        unsigned return_type_z,
    370                        unsigned return_type_w );
    371 
    372 struct ureg_src
    373 ureg_DECL_image(struct ureg_program *ureg,
    374                 unsigned index,
    375                 unsigned target,
    376                 unsigned format,
    377                 boolean wr,
    378                 boolean raw);
    379 
    380 struct ureg_src
    381 ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, bool atomic);
    382 
    383 struct ureg_src
    384 ureg_DECL_memory(struct ureg_program *ureg, unsigned memory_type);
    385 
    386 static inline struct ureg_src
    387 ureg_imm4f( struct ureg_program *ureg,
    388                        float a, float b,
    389                        float c, float d)
    390 {
    391    float v[4];
    392    v[0] = a;
    393    v[1] = b;
    394    v[2] = c;
    395    v[3] = d;
    396    return ureg_DECL_immediate( ureg, v, 4 );
    397 }
    398 
    399 static inline struct ureg_src
    400 ureg_imm3f( struct ureg_program *ureg,
    401                        float a, float b,
    402                        float c)
    403 {
    404    float v[3];
    405    v[0] = a;
    406    v[1] = b;
    407    v[2] = c;
    408    return ureg_DECL_immediate( ureg, v, 3 );
    409 }
    410 
    411 static inline struct ureg_src
    412 ureg_imm2f( struct ureg_program *ureg,
    413                        float a, float b)
    414 {
    415    float v[2];
    416    v[0] = a;
    417    v[1] = b;
    418    return ureg_DECL_immediate( ureg, v, 2 );
    419 }
    420 
    421 static inline struct ureg_src
    422 ureg_imm1f( struct ureg_program *ureg,
    423                        float a)
    424 {
    425    float v[1];
    426    v[0] = a;
    427    return ureg_DECL_immediate( ureg, v, 1 );
    428 }
    429 
    430 static inline struct ureg_src
    431 ureg_imm4u( struct ureg_program *ureg,
    432             unsigned a, unsigned b,
    433             unsigned c, unsigned d)
    434 {
    435    unsigned v[4];
    436    v[0] = a;
    437    v[1] = b;
    438    v[2] = c;
    439    v[3] = d;
    440    return ureg_DECL_immediate_uint( ureg, v, 4 );
    441 }
    442 
    443 static inline struct ureg_src
    444 ureg_imm3u( struct ureg_program *ureg,
    445             unsigned a, unsigned b,
    446             unsigned c)
    447 {
    448    unsigned v[3];
    449    v[0] = a;
    450    v[1] = b;
    451    v[2] = c;
    452    return ureg_DECL_immediate_uint( ureg, v, 3 );
    453 }
    454 
    455 static inline struct ureg_src
    456 ureg_imm2u( struct ureg_program *ureg,
    457             unsigned a, unsigned b)
    458 {
    459    unsigned v[2];
    460    v[0] = a;
    461    v[1] = b;
    462    return ureg_DECL_immediate_uint( ureg, v, 2 );
    463 }
    464 
    465 static inline struct ureg_src
    466 ureg_imm1u( struct ureg_program *ureg,
    467             unsigned a)
    468 {
    469    return ureg_DECL_immediate_uint( ureg, &a, 1 );
    470 }
    471 
    472 static inline struct ureg_src
    473 ureg_imm4i( struct ureg_program *ureg,
    474             int a, int b,
    475             int c, int d)
    476 {
    477    int v[4];
    478    v[0] = a;
    479    v[1] = b;
    480    v[2] = c;
    481    v[3] = d;
    482    return ureg_DECL_immediate_int( ureg, v, 4 );
    483 }
    484 
    485 static inline struct ureg_src
    486 ureg_imm3i( struct ureg_program *ureg,
    487             int a, int b,
    488             int c)
    489 {
    490    int v[3];
    491    v[0] = a;
    492    v[1] = b;
    493    v[2] = c;
    494    return ureg_DECL_immediate_int( ureg, v, 3 );
    495 }
    496 
    497 static inline struct ureg_src
    498 ureg_imm2i( struct ureg_program *ureg,
    499             int a, int b)
    500 {
    501    int v[2];
    502    v[0] = a;
    503    v[1] = b;
    504    return ureg_DECL_immediate_int( ureg, v, 2 );
    505 }
    506 
    507 static inline struct ureg_src
    508 ureg_imm1i( struct ureg_program *ureg,
    509             int a)
    510 {
    511    return ureg_DECL_immediate_int( ureg, &a, 1 );
    512 }
    513 
    514 /* Where the destination register has a valid file, but an empty
    515  * writemask.
    516  */
    517 static inline boolean
    518 ureg_dst_is_empty( struct ureg_dst dst )
    519 {
    520    return dst.File != TGSI_FILE_NULL &&
    521           dst.WriteMask == 0;
    522 }
    523 
    524 /***********************************************************************
    525  * Functions for patching up labels
    526  */
    527 
    528 
    529 /* Will return a number which can be used in a label to point to the
    530  * next instruction to be emitted.
    531  */
    532 unsigned
    533 ureg_get_instruction_number( struct ureg_program *ureg );
    534 
    535 
    536 /* Patch a given label (expressed as a token number) to point to a
    537  * given instruction (expressed as an instruction number).
    538  *
    539  * Labels are obtained from instruction emitters, eg ureg_CAL().
    540  * Instruction numbers are obtained from ureg_get_instruction_number(),
    541  * above.
    542  */
    543 void
    544 ureg_fixup_label(struct ureg_program *ureg,
    545                  unsigned label_token,
    546                  unsigned instruction_number );
    547 
    548 
    549 /* Generic instruction emitter.  Use if you need to pass the opcode as
    550  * a parameter, rather than using the emit_OP() variants below.
    551  */
    552 void
    553 ureg_insn(struct ureg_program *ureg,
    554           unsigned opcode,
    555           const struct ureg_dst *dst,
    556           unsigned nr_dst,
    557           const struct ureg_src *src,
    558           unsigned nr_src );
    559 
    560 
    561 void
    562 ureg_tex_insn(struct ureg_program *ureg,
    563               unsigned opcode,
    564               const struct ureg_dst *dst,
    565               unsigned nr_dst,
    566               unsigned target,
    567               const struct tgsi_texture_offset *texoffsets,
    568               unsigned nr_offset,
    569               const struct ureg_src *src,
    570               unsigned nr_src );
    571 
    572 
    573 void
    574 ureg_label_insn(struct ureg_program *ureg,
    575                 unsigned opcode,
    576                 const struct ureg_src *src,
    577                 unsigned nr_src,
    578                 unsigned *label);
    579 
    580 void
    581 ureg_memory_insn(struct ureg_program *ureg,
    582                  unsigned opcode,
    583                  const struct ureg_dst *dst,
    584                  unsigned nr_dst,
    585                  const struct ureg_src *src,
    586                  unsigned nr_src,
    587                  unsigned qualifier,
    588                  unsigned texture,
    589                  unsigned format);
    590 
    591 /***********************************************************************
    592  * Internal instruction helpers, don't call these directly:
    593  */
    594 
    595 struct ureg_emit_insn_result {
    596    unsigned insn_token;       /*< Used to fixup insn size. */
    597    unsigned extended_token;   /*< Used to set the Extended bit, usually the same as insn_token. */
    598 };
    599 
    600 struct ureg_emit_insn_result
    601 ureg_emit_insn(struct ureg_program *ureg,
    602                unsigned opcode,
    603                boolean saturate,
    604                boolean predicate,
    605                boolean pred_negate,
    606                unsigned pred_swizzle_x,
    607                unsigned pred_swizzle_y,
    608                unsigned pred_swizzle_z,
    609                unsigned pred_swizzle_w,
    610                unsigned num_dst,
    611                unsigned num_src );
    612 
    613 void
    614 ureg_emit_label(struct ureg_program *ureg,
    615                 unsigned insn_token,
    616                 unsigned *label_token );
    617 
    618 void
    619 ureg_emit_texture(struct ureg_program *ureg,
    620                   unsigned insn_token,
    621                   unsigned target, unsigned num_offsets);
    622 
    623 void
    624 ureg_emit_texture_offset(struct ureg_program *ureg,
    625                          const struct tgsi_texture_offset *offset);
    626 
    627 void
    628 ureg_emit_memory(struct ureg_program *ureg,
    629                  unsigned insn_token,
    630                  unsigned qualifier,
    631                  unsigned texture,
    632                  unsigned format);
    633 
    634 void
    635 ureg_emit_dst( struct ureg_program *ureg,
    636                struct ureg_dst dst );
    637 
    638 void
    639 ureg_emit_src( struct ureg_program *ureg,
    640                struct ureg_src src );
    641 
    642 void
    643 ureg_fixup_insn_size(struct ureg_program *ureg,
    644                      unsigned insn );
    645 
    646 
    647 #define OP00( op )                                              \
    648 static inline void ureg_##op( struct ureg_program *ureg )       \
    649 {                                                               \
    650    unsigned opcode = TGSI_OPCODE_##op;                          \
    651    struct ureg_emit_insn_result insn;                           \
    652    insn = ureg_emit_insn(ureg,                                  \
    653                          opcode,                                \
    654                          FALSE,                                 \
    655                          FALSE,                                 \
    656                          FALSE,                                 \
    657                          TGSI_SWIZZLE_X,                        \
    658                          TGSI_SWIZZLE_Y,                        \
    659                          TGSI_SWIZZLE_Z,                        \
    660                          TGSI_SWIZZLE_W,                        \
    661                          0,                                     \
    662                          0);                                    \
    663    ureg_fixup_insn_size( ureg, insn.insn_token );               \
    664 }
    665 
    666 #define OP01( op )                                              \
    667 static inline void ureg_##op( struct ureg_program *ureg,        \
    668                               struct ureg_src src )             \
    669 {                                                               \
    670    unsigned opcode = TGSI_OPCODE_##op;                          \
    671    struct ureg_emit_insn_result insn;                           \
    672    insn = ureg_emit_insn(ureg,                                  \
    673                          opcode,                                \
    674                          FALSE,                                 \
    675                          FALSE,                                 \
    676                          FALSE,                                 \
    677                          TGSI_SWIZZLE_X,                        \
    678                          TGSI_SWIZZLE_Y,                        \
    679                          TGSI_SWIZZLE_Z,                        \
    680                          TGSI_SWIZZLE_W,                        \
    681                          0,                                     \
    682                          1);                                    \
    683    ureg_emit_src( ureg, src );                                  \
    684    ureg_fixup_insn_size( ureg, insn.insn_token );               \
    685 }
    686 
    687 #define OP00_LBL( op )                                          \
    688 static inline void ureg_##op( struct ureg_program *ureg,        \
    689                               unsigned *label_token )           \
    690 {                                                               \
    691    unsigned opcode = TGSI_OPCODE_##op;                          \
    692    struct ureg_emit_insn_result insn;                           \
    693    insn = ureg_emit_insn(ureg,                                  \
    694                          opcode,                                \
    695                          FALSE,                                 \
    696                          FALSE,                                 \
    697                          FALSE,                                 \
    698                          TGSI_SWIZZLE_X,                        \
    699                          TGSI_SWIZZLE_Y,                        \
    700                          TGSI_SWIZZLE_Z,                        \
    701                          TGSI_SWIZZLE_W,                        \
    702                          0,                                     \
    703                          0);                                    \
    704    ureg_emit_label( ureg, insn.extended_token, label_token );   \
    705    ureg_fixup_insn_size( ureg, insn.insn_token );               \
    706 }
    707 
    708 #define OP01_LBL( op )                                          \
    709 static inline void ureg_##op( struct ureg_program *ureg,        \
    710                               struct ureg_src src,              \
    711                               unsigned *label_token )          \
    712 {                                                               \
    713    unsigned opcode = TGSI_OPCODE_##op;                          \
    714    struct ureg_emit_insn_result insn;                           \
    715    insn = ureg_emit_insn(ureg,                                  \
    716                          opcode,                                \
    717                          FALSE,                                 \
    718                          FALSE,                                 \
    719                          FALSE,                                 \
    720                          TGSI_SWIZZLE_X,                        \
    721                          TGSI_SWIZZLE_Y,                        \
    722                          TGSI_SWIZZLE_Z,                        \
    723                          TGSI_SWIZZLE_W,                        \
    724                          0,                                     \
    725                          1);                                    \
    726    ureg_emit_label( ureg, insn.extended_token, label_token );   \
    727    ureg_emit_src( ureg, src );                                  \
    728    ureg_fixup_insn_size( ureg, insn.insn_token );               \
    729 }
    730 
    731 #define OP10( op )                                                      \
    732 static inline void ureg_##op( struct ureg_program *ureg,                \
    733                               struct ureg_dst dst )                     \
    734 {                                                                       \
    735    unsigned 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                          dst.Predicate,                                 \
    743                          dst.PredNegate,                                \
    744                          dst.PredSwizzleX,                              \
    745                          dst.PredSwizzleY,                              \
    746                          dst.PredSwizzleZ,                              \
    747                          dst.PredSwizzleW,                              \
    748                          1,                                             \
    749                          0);                                            \
    750    ureg_emit_dst( ureg, dst );                                          \
    751    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    752 }
    753 
    754 
    755 #define OP11( op )                                                      \
    756 static inline void ureg_##op( struct ureg_program *ureg,                \
    757                               struct ureg_dst dst,                      \
    758                               struct ureg_src src )                     \
    759 {                                                                       \
    760    unsigned opcode = TGSI_OPCODE_##op;                                  \
    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                          dst.Predicate,                                 \
    768                          dst.PredNegate,                                \
    769                          dst.PredSwizzleX,                              \
    770                          dst.PredSwizzleY,                              \
    771                          dst.PredSwizzleZ,                              \
    772                          dst.PredSwizzleW,                              \
    773                          1,                                             \
    774                          1);                                            \
    775    ureg_emit_dst( ureg, dst );                                          \
    776    ureg_emit_src( ureg, src );                                          \
    777    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    778 }
    779 
    780 #define OP12( 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 {                                                                       \
    786    unsigned opcode = TGSI_OPCODE_##op;                                  \
    787    struct ureg_emit_insn_result insn;                                   \
    788    if (ureg_dst_is_empty(dst))                                          \
    789       return;                                                           \
    790    insn = ureg_emit_insn(ureg,                                          \
    791                          opcode,                                        \
    792                          dst.Saturate,                                  \
    793                          dst.Predicate,                                 \
    794                          dst.PredNegate,                                \
    795                          dst.PredSwizzleX,                              \
    796                          dst.PredSwizzleY,                              \
    797                          dst.PredSwizzleZ,                              \
    798                          dst.PredSwizzleW,                              \
    799                          1,                                             \
    800                          2);                                            \
    801    ureg_emit_dst( ureg, dst );                                          \
    802    ureg_emit_src( ureg, src0 );                                         \
    803    ureg_emit_src( ureg, src1 );                                         \
    804    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    805 }
    806 
    807 #define OP12_TEX( op )                                                  \
    808 static inline void ureg_##op( struct ureg_program *ureg,                \
    809                               struct ureg_dst dst,                      \
    810                               unsigned target,                          \
    811                               struct ureg_src src0,                     \
    812                               struct ureg_src src1 )                    \
    813 {                                                                       \
    814    unsigned opcode = TGSI_OPCODE_##op;                                  \
    815    struct ureg_emit_insn_result insn;                                   \
    816    if (ureg_dst_is_empty(dst))                                          \
    817       return;                                                           \
    818    insn = ureg_emit_insn(ureg,                                          \
    819                          opcode,                                        \
    820                          dst.Saturate,                                  \
    821                          dst.Predicate,                                 \
    822                          dst.PredNegate,                                \
    823                          dst.PredSwizzleX,                              \
    824                          dst.PredSwizzleY,                              \
    825                          dst.PredSwizzleZ,                              \
    826                          dst.PredSwizzleW,                              \
    827                          1,                                             \
    828                          2);                                            \
    829    ureg_emit_texture( ureg, insn.extended_token, target, 0 );		\
    830    ureg_emit_dst( ureg, dst );                                          \
    831    ureg_emit_src( ureg, src0 );                                         \
    832    ureg_emit_src( ureg, src1 );                                         \
    833    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    834 }
    835 
    836 #define OP12_SAMPLE( op )                                               \
    837 static inline void ureg_##op( struct ureg_program *ureg,                \
    838                               struct ureg_dst dst,                      \
    839                               struct ureg_src src0,                     \
    840                               struct ureg_src src1 )                    \
    841 {                                                                       \
    842    unsigned opcode = TGSI_OPCODE_##op;                                  \
    843    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
    844    struct ureg_emit_insn_result insn;                                   \
    845    if (ureg_dst_is_empty(dst))                                          \
    846       return;                                                           \
    847    insn = ureg_emit_insn(ureg,                                          \
    848                          opcode,                                        \
    849                          dst.Saturate,                                  \
    850                          dst.Predicate,                                 \
    851                          dst.PredNegate,                                \
    852                          dst.PredSwizzleX,                              \
    853                          dst.PredSwizzleY,                              \
    854                          dst.PredSwizzleZ,                              \
    855                          dst.PredSwizzleW,                              \
    856                          1,                                             \
    857                          2);                                            \
    858    ureg_emit_texture( ureg, insn.extended_token, target, 0 );           \
    859    ureg_emit_dst( ureg, dst );                                          \
    860    ureg_emit_src( ureg, src0 );                                         \
    861    ureg_emit_src( ureg, src1 );                                         \
    862    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    863 }
    864 
    865 #define OP13( op )                                                      \
    866 static inline void ureg_##op( struct ureg_program *ureg,                \
    867                               struct ureg_dst dst,                      \
    868                               struct ureg_src src0,                     \
    869                               struct ureg_src src1,                     \
    870                               struct ureg_src src2 )                    \
    871 {                                                                       \
    872    unsigned opcode = TGSI_OPCODE_##op;                                  \
    873    struct ureg_emit_insn_result insn;                                   \
    874    if (ureg_dst_is_empty(dst))                                          \
    875       return;                                                           \
    876    insn = ureg_emit_insn(ureg,                                          \
    877                          opcode,                                        \
    878                          dst.Saturate,                                  \
    879                          dst.Predicate,                                 \
    880                          dst.PredNegate,                                \
    881                          dst.PredSwizzleX,                              \
    882                          dst.PredSwizzleY,                              \
    883                          dst.PredSwizzleZ,                              \
    884                          dst.PredSwizzleW,                              \
    885                          1,                                             \
    886                          3);                                            \
    887    ureg_emit_dst( ureg, dst );                                          \
    888    ureg_emit_src( ureg, src0 );                                         \
    889    ureg_emit_src( ureg, src1 );                                         \
    890    ureg_emit_src( ureg, src2 );                                         \
    891    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    892 }
    893 
    894 #define OP13_SAMPLE( op )                                               \
    895 static inline void ureg_##op( struct ureg_program *ureg,                \
    896                               struct ureg_dst dst,                      \
    897                               struct ureg_src src0,                     \
    898                               struct ureg_src src1,                     \
    899                               struct ureg_src src2 )                    \
    900 {                                                                       \
    901    unsigned opcode = TGSI_OPCODE_##op;                                  \
    902    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
    903    struct ureg_emit_insn_result insn;                                   \
    904    if (ureg_dst_is_empty(dst))                                          \
    905       return;                                                           \
    906    insn = ureg_emit_insn(ureg,                                          \
    907                          opcode,                                        \
    908                          dst.Saturate,                                  \
    909                          dst.Predicate,                                 \
    910                          dst.PredNegate,                                \
    911                          dst.PredSwizzleX,                              \
    912                          dst.PredSwizzleY,                              \
    913                          dst.PredSwizzleZ,                              \
    914                          dst.PredSwizzleW,                              \
    915                          1,                                             \
    916                          3);                                            \
    917    ureg_emit_texture( ureg, insn.extended_token, target, 0 );           \
    918    ureg_emit_dst( ureg, dst );                                          \
    919    ureg_emit_src( ureg, src0 );                                         \
    920    ureg_emit_src( ureg, src1 );                                         \
    921    ureg_emit_src( ureg, src2 );                                         \
    922    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    923 }
    924 
    925 #define OP14_TEX( op )                                                  \
    926 static inline void ureg_##op( struct ureg_program *ureg,                \
    927                               struct ureg_dst dst,                      \
    928                               unsigned target,                          \
    929                               struct ureg_src src0,                     \
    930                               struct ureg_src src1,                     \
    931                               struct ureg_src src2,                     \
    932                               struct ureg_src src3 )                    \
    933 {                                                                       \
    934    unsigned opcode = TGSI_OPCODE_##op;                                  \
    935    struct ureg_emit_insn_result insn;                                   \
    936    if (ureg_dst_is_empty(dst))                                          \
    937       return;                                                           \
    938    insn = ureg_emit_insn(ureg,                                          \
    939                          opcode,                                        \
    940                          dst.Saturate,                                  \
    941                          dst.Predicate,                                 \
    942                          dst.PredNegate,                                \
    943                          dst.PredSwizzleX,                              \
    944                          dst.PredSwizzleY,                              \
    945                          dst.PredSwizzleZ,                              \
    946                          dst.PredSwizzleW,                              \
    947                          1,                                             \
    948                          4);                                            \
    949    ureg_emit_texture( ureg, insn.extended_token, target, 0 );		\
    950    ureg_emit_dst( ureg, dst );                                          \
    951    ureg_emit_src( ureg, src0 );                                         \
    952    ureg_emit_src( ureg, src1 );                                         \
    953    ureg_emit_src( ureg, src2 );                                         \
    954    ureg_emit_src( ureg, src3 );                                         \
    955    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    956 }
    957 
    958 #define OP14_SAMPLE( op )                                               \
    959 static inline void ureg_##op( struct ureg_program *ureg,                \
    960                               struct ureg_dst dst,                      \
    961                               struct ureg_src src0,                     \
    962                               struct ureg_src src1,                     \
    963                               struct ureg_src src2,                     \
    964                               struct ureg_src src3 )                    \
    965 {                                                                       \
    966    unsigned opcode = TGSI_OPCODE_##op;                                  \
    967    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
    968    struct ureg_emit_insn_result insn;                                   \
    969    if (ureg_dst_is_empty(dst))                                          \
    970       return;                                                           \
    971    insn = ureg_emit_insn(ureg,                                          \
    972                          opcode,                                        \
    973                          dst.Saturate,                                  \
    974                          dst.Predicate,                                 \
    975                          dst.PredNegate,                                \
    976                          dst.PredSwizzleX,                              \
    977                          dst.PredSwizzleY,                              \
    978                          dst.PredSwizzleZ,                              \
    979                          dst.PredSwizzleW,                              \
    980                          1,                                             \
    981                          4);                                            \
    982    ureg_emit_texture( ureg, insn.extended_token, target, 0 );           \
    983    ureg_emit_dst( ureg, dst );                                          \
    984    ureg_emit_src( ureg, src0 );                                         \
    985    ureg_emit_src( ureg, src1 );                                         \
    986    ureg_emit_src( ureg, src2 );                                         \
    987    ureg_emit_src( ureg, src3 );                                         \
    988    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
    989 }
    990 
    991 
    992 #define OP14( op )                                                      \
    993 static inline void ureg_##op( struct ureg_program *ureg,                \
    994                               struct ureg_dst dst,                      \
    995                               struct ureg_src src0,                     \
    996                               struct ureg_src src1,                     \
    997                               struct ureg_src src2,                     \
    998                               struct ureg_src src3 )                    \
    999 {                                                                       \
   1000    unsigned opcode = TGSI_OPCODE_##op;                                  \
   1001    struct ureg_emit_insn_result insn;                                   \
   1002    if (ureg_dst_is_empty(dst))                                          \
   1003       return;                                                           \
   1004    insn = ureg_emit_insn(ureg,                                          \
   1005                          opcode,                                        \
   1006                          dst.Saturate,                                  \
   1007                          dst.Predicate,                                 \
   1008                          dst.PredNegate,                                \
   1009                          dst.PredSwizzleX,                              \
   1010                          dst.PredSwizzleY,                              \
   1011                          dst.PredSwizzleZ,                              \
   1012                          dst.PredSwizzleW,                              \
   1013                          1,                                             \
   1014                          4);                                            \
   1015    ureg_emit_dst( ureg, dst );                                          \
   1016    ureg_emit_src( ureg, src0 );                                         \
   1017    ureg_emit_src( ureg, src1 );                                         \
   1018    ureg_emit_src( ureg, src2 );                                         \
   1019    ureg_emit_src( ureg, src3 );                                         \
   1020    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
   1021 }
   1022 
   1023 
   1024 #define OP15( op )                                                      \
   1025 static inline void ureg_##op( struct ureg_program *ureg,                \
   1026                               struct ureg_dst dst,                      \
   1027                               struct ureg_src src0,                     \
   1028                               struct ureg_src src1,                     \
   1029                               struct ureg_src src2,                     \
   1030                               struct ureg_src src3,                     \
   1031                               struct ureg_src src4 )                    \
   1032 {                                                                       \
   1033    unsigned opcode = TGSI_OPCODE_##op;                                  \
   1034    struct ureg_emit_insn_result insn;                                   \
   1035    if (ureg_dst_is_empty(dst))                                          \
   1036       return;                                                           \
   1037    insn = ureg_emit_insn(ureg,                                          \
   1038                          opcode,                                        \
   1039                          dst.Saturate,                                  \
   1040                          dst.Predicate,                                 \
   1041                          dst.PredNegate,                                \
   1042                          dst.PredSwizzleX,                              \
   1043                          dst.PredSwizzleY,                              \
   1044                          dst.PredSwizzleZ,                              \
   1045                          dst.PredSwizzleW,                              \
   1046                          1,                                             \
   1047                          5);                                            \
   1048    ureg_emit_dst( ureg, dst );                                          \
   1049    ureg_emit_src( ureg, src0 );                                         \
   1050    ureg_emit_src( ureg, src1 );                                         \
   1051    ureg_emit_src( ureg, src2 );                                         \
   1052    ureg_emit_src( ureg, src3 );                                         \
   1053    ureg_emit_src( ureg, src4 );                                         \
   1054    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
   1055 }
   1056 
   1057 #define OP15_SAMPLE( op )                                               \
   1058 static inline void ureg_##op( struct ureg_program *ureg,                \
   1059                               struct ureg_dst dst,                      \
   1060                               struct ureg_src src0,                     \
   1061                               struct ureg_src src1,                     \
   1062                               struct ureg_src src2,                     \
   1063                               struct ureg_src src3,                     \
   1064                               struct ureg_src src4 )                    \
   1065 {                                                                       \
   1066    unsigned opcode = TGSI_OPCODE_##op;                                  \
   1067    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
   1068    struct ureg_emit_insn_result insn;                                   \
   1069    if (ureg_dst_is_empty(dst))                                          \
   1070       return;                                                           \
   1071    insn = ureg_emit_insn(ureg,                                          \
   1072                          opcode,                                        \
   1073                          dst.Saturate,                                  \
   1074                          dst.Predicate,                                 \
   1075                          dst.PredNegate,                                \
   1076                          dst.PredSwizzleX,                              \
   1077                          dst.PredSwizzleY,                              \
   1078                          dst.PredSwizzleZ,                              \
   1079                          dst.PredSwizzleW,                              \
   1080                          1,                                             \
   1081                          5);                                            \
   1082    ureg_emit_texture( ureg, insn.extended_token, target, 0 );           \
   1083    ureg_emit_dst( ureg, dst );                                          \
   1084    ureg_emit_src( ureg, src0 );                                         \
   1085    ureg_emit_src( ureg, src1 );                                         \
   1086    ureg_emit_src( ureg, src2 );                                         \
   1087    ureg_emit_src( ureg, src3 );                                         \
   1088    ureg_emit_src( ureg, src4 );                                         \
   1089    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
   1090 }
   1091 
   1092 /* Use a template include to generate a correctly-typed ureg_OP()
   1093  * function for each TGSI opcode:
   1094  */
   1095 #include "tgsi_opcode_tmp.h"
   1096 
   1097 
   1098 /***********************************************************************
   1099  * Inline helpers for manipulating register structs:
   1100  */
   1101 static inline struct ureg_src
   1102 ureg_negate( struct ureg_src reg )
   1103 {
   1104    assert(reg.File != TGSI_FILE_NULL);
   1105    reg.Negate ^= 1;
   1106    return reg;
   1107 }
   1108 
   1109 static inline struct ureg_src
   1110 ureg_abs( struct ureg_src reg )
   1111 {
   1112    assert(reg.File != TGSI_FILE_NULL);
   1113    reg.Absolute = 1;
   1114    reg.Negate = 0;
   1115    return reg;
   1116 }
   1117 
   1118 static inline struct ureg_src
   1119 ureg_swizzle( struct ureg_src reg,
   1120               int x, int y, int z, int w )
   1121 {
   1122    unsigned swz = ( (reg.SwizzleX << 0) |
   1123                     (reg.SwizzleY << 2) |
   1124                     (reg.SwizzleZ << 4) |
   1125                     (reg.SwizzleW << 6));
   1126 
   1127    assert(reg.File != TGSI_FILE_NULL);
   1128    assert(x < 4);
   1129    assert(y < 4);
   1130    assert(z < 4);
   1131    assert(w < 4);
   1132 
   1133    reg.SwizzleX = (swz >> (x*2)) & 0x3;
   1134    reg.SwizzleY = (swz >> (y*2)) & 0x3;
   1135    reg.SwizzleZ = (swz >> (z*2)) & 0x3;
   1136    reg.SwizzleW = (swz >> (w*2)) & 0x3;
   1137    return reg;
   1138 }
   1139 
   1140 static inline struct ureg_src
   1141 ureg_scalar( struct ureg_src reg, int x )
   1142 {
   1143    return ureg_swizzle(reg, x, x, x, x);
   1144 }
   1145 
   1146 static inline struct ureg_dst
   1147 ureg_writemask( struct ureg_dst reg,
   1148                 unsigned writemask )
   1149 {
   1150    assert(reg.File != TGSI_FILE_NULL);
   1151    reg.WriteMask &= writemask;
   1152    return reg;
   1153 }
   1154 
   1155 static inline struct ureg_dst
   1156 ureg_saturate( struct ureg_dst reg )
   1157 {
   1158    assert(reg.File != TGSI_FILE_NULL);
   1159    reg.Saturate = 1;
   1160    return reg;
   1161 }
   1162 
   1163 static inline struct ureg_dst
   1164 ureg_predicate(struct ureg_dst reg,
   1165                boolean negate,
   1166                unsigned swizzle_x,
   1167                unsigned swizzle_y,
   1168                unsigned swizzle_z,
   1169                unsigned swizzle_w)
   1170 {
   1171    assert(reg.File != TGSI_FILE_NULL);
   1172    reg.Predicate = 1;
   1173    reg.PredNegate = negate;
   1174    reg.PredSwizzleX = swizzle_x;
   1175    reg.PredSwizzleY = swizzle_y;
   1176    reg.PredSwizzleZ = swizzle_z;
   1177    reg.PredSwizzleW = swizzle_w;
   1178    return reg;
   1179 }
   1180 
   1181 static inline struct ureg_dst
   1182 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
   1183 {
   1184    assert(reg.File != TGSI_FILE_NULL);
   1185    assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
   1186    reg.Indirect = 1;
   1187    reg.IndirectFile = addr.File;
   1188    reg.IndirectIndex = addr.Index;
   1189    reg.IndirectSwizzle = addr.SwizzleX;
   1190    return reg;
   1191 }
   1192 
   1193 static inline struct ureg_src
   1194 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
   1195 {
   1196    assert(reg.File != TGSI_FILE_NULL);
   1197    assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
   1198    reg.Indirect = 1;
   1199    reg.IndirectFile = addr.File;
   1200    reg.IndirectIndex = addr.Index;
   1201    reg.IndirectSwizzle = addr.SwizzleX;
   1202    return reg;
   1203 }
   1204 
   1205 static inline struct ureg_dst
   1206 ureg_dst_dimension( struct ureg_dst reg, int index )
   1207 {
   1208    assert(reg.File != TGSI_FILE_NULL);
   1209    reg.Dimension = 1;
   1210    reg.DimIndirect = 0;
   1211    reg.DimensionIndex = index;
   1212    return reg;
   1213 }
   1214 
   1215 static inline struct ureg_src
   1216 ureg_src_dimension( struct ureg_src reg, int index )
   1217 {
   1218    assert(reg.File != TGSI_FILE_NULL);
   1219    reg.Dimension = 1;
   1220    reg.DimIndirect = 0;
   1221    reg.DimensionIndex = index;
   1222    return reg;
   1223 }
   1224 
   1225 static inline struct ureg_dst
   1226 ureg_dst_dimension_indirect( struct ureg_dst reg, struct ureg_src addr,
   1227                              int index )
   1228 {
   1229    assert(reg.File != TGSI_FILE_NULL);
   1230    reg.Dimension = 1;
   1231    reg.DimIndirect = 1;
   1232    reg.DimensionIndex = index;
   1233    reg.DimIndFile = addr.File;
   1234    reg.DimIndIndex = addr.Index;
   1235    reg.DimIndSwizzle = addr.SwizzleX;
   1236    return reg;
   1237 }
   1238 
   1239 static inline struct ureg_src
   1240 ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
   1241                              int index )
   1242 {
   1243    assert(reg.File != TGSI_FILE_NULL);
   1244    reg.Dimension = 1;
   1245    reg.DimIndirect = 1;
   1246    reg.DimensionIndex = index;
   1247    reg.DimIndFile = addr.File;
   1248    reg.DimIndIndex = addr.Index;
   1249    reg.DimIndSwizzle = addr.SwizzleX;
   1250    return reg;
   1251 }
   1252 
   1253 static inline struct ureg_src
   1254 ureg_src_array_offset(struct ureg_src reg, int offset)
   1255 {
   1256    reg.Index += offset;
   1257    return reg;
   1258 }
   1259 
   1260 static inline struct ureg_dst
   1261 ureg_dst_array_offset( struct ureg_dst reg, int offset )
   1262 {
   1263    reg.Index += offset;
   1264    return reg;
   1265 }
   1266 
   1267 static inline struct ureg_dst
   1268 ureg_dst_array_register(unsigned file,
   1269                         unsigned index,
   1270                         unsigned array_id)
   1271 {
   1272    struct ureg_dst dst;
   1273 
   1274    dst.File      = file;
   1275    dst.WriteMask = TGSI_WRITEMASK_XYZW;
   1276    dst.Indirect  = 0;
   1277    dst.IndirectFile = TGSI_FILE_NULL;
   1278    dst.IndirectIndex = 0;
   1279    dst.IndirectSwizzle = 0;
   1280    dst.Saturate  = 0;
   1281    dst.Predicate = 0;
   1282    dst.PredNegate = 0;
   1283    dst.PredSwizzleX = TGSI_SWIZZLE_X;
   1284    dst.PredSwizzleY = TGSI_SWIZZLE_Y;
   1285    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
   1286    dst.PredSwizzleW = TGSI_SWIZZLE_W;
   1287    dst.Index     = index;
   1288    dst.Dimension = 0;
   1289    dst.DimensionIndex = 0;
   1290    dst.DimIndirect = 0;
   1291    dst.DimIndFile = TGSI_FILE_NULL;
   1292    dst.DimIndIndex = 0;
   1293    dst.DimIndSwizzle = 0;
   1294    dst.ArrayID = array_id;
   1295 
   1296    return dst;
   1297 }
   1298 
   1299 static inline struct ureg_dst
   1300 ureg_dst_register(unsigned file,
   1301                   unsigned index)
   1302 {
   1303    return ureg_dst_array_register(file, index, 0);
   1304 }
   1305 
   1306 static inline struct ureg_dst
   1307 ureg_dst( struct ureg_src src )
   1308 {
   1309    struct ureg_dst dst;
   1310 
   1311    assert(!src.Indirect ||
   1312           (src.IndirectFile == TGSI_FILE_ADDRESS ||
   1313            src.IndirectFile == TGSI_FILE_TEMPORARY));
   1314 
   1315    dst.File      = src.File;
   1316    dst.WriteMask = TGSI_WRITEMASK_XYZW;
   1317    dst.IndirectFile = src.IndirectFile;
   1318    dst.Indirect  = src.Indirect;
   1319    dst.IndirectIndex = src.IndirectIndex;
   1320    dst.IndirectSwizzle = src.IndirectSwizzle;
   1321    dst.Saturate  = 0;
   1322    dst.Predicate = 0;
   1323    dst.PredNegate = 0;
   1324    dst.PredSwizzleX = TGSI_SWIZZLE_X;
   1325    dst.PredSwizzleY = TGSI_SWIZZLE_Y;
   1326    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
   1327    dst.PredSwizzleW = TGSI_SWIZZLE_W;
   1328    dst.Index     = src.Index;
   1329    dst.Dimension = src.Dimension;
   1330    dst.DimensionIndex = src.DimensionIndex;
   1331    dst.DimIndirect = src.DimIndirect;
   1332    dst.DimIndFile = src.DimIndFile;
   1333    dst.DimIndIndex = src.DimIndIndex;
   1334    dst.DimIndSwizzle = src.DimIndSwizzle;
   1335    dst.ArrayID = src.ArrayID;
   1336 
   1337    return dst;
   1338 }
   1339 
   1340 static inline struct ureg_src
   1341 ureg_src_array_register(unsigned file,
   1342                         unsigned index,
   1343                         unsigned array_id)
   1344 {
   1345    struct ureg_src src;
   1346 
   1347    src.File = file;
   1348    src.SwizzleX = TGSI_SWIZZLE_X;
   1349    src.SwizzleY = TGSI_SWIZZLE_Y;
   1350    src.SwizzleZ = TGSI_SWIZZLE_Z;
   1351    src.SwizzleW = TGSI_SWIZZLE_W;
   1352    src.Indirect = 0;
   1353    src.IndirectFile = TGSI_FILE_NULL;
   1354    src.IndirectIndex = 0;
   1355    src.IndirectSwizzle = 0;
   1356    src.Absolute = 0;
   1357    src.Index = index;
   1358    src.Negate = 0;
   1359    src.Dimension = 0;
   1360    src.DimensionIndex = 0;
   1361    src.DimIndirect = 0;
   1362    src.DimIndFile = TGSI_FILE_NULL;
   1363    src.DimIndIndex = 0;
   1364    src.DimIndSwizzle = 0;
   1365    src.ArrayID = array_id;
   1366 
   1367    return src;
   1368 }
   1369 
   1370 static inline struct ureg_src
   1371 ureg_src_register(unsigned file,
   1372                   unsigned index)
   1373 {
   1374    return ureg_src_array_register(file, index, 0);
   1375 }
   1376 
   1377 static inline struct ureg_src
   1378 ureg_src( struct ureg_dst dst )
   1379 {
   1380    struct ureg_src src;
   1381 
   1382    src.File      = dst.File;
   1383    src.SwizzleX  = TGSI_SWIZZLE_X;
   1384    src.SwizzleY  = TGSI_SWIZZLE_Y;
   1385    src.SwizzleZ  = TGSI_SWIZZLE_Z;
   1386    src.SwizzleW  = TGSI_SWIZZLE_W;
   1387    src.Indirect  = dst.Indirect;
   1388    src.IndirectFile = dst.IndirectFile;
   1389    src.IndirectIndex = dst.IndirectIndex;
   1390    src.IndirectSwizzle = dst.IndirectSwizzle;
   1391    src.Absolute  = 0;
   1392    src.Index     = dst.Index;
   1393    src.Negate    = 0;
   1394    src.Dimension = dst.Dimension;
   1395    src.DimensionIndex = dst.DimensionIndex;
   1396    src.DimIndirect = dst.DimIndirect;
   1397    src.DimIndFile = dst.DimIndFile;
   1398    src.DimIndIndex = dst.DimIndIndex;
   1399    src.DimIndSwizzle = dst.DimIndSwizzle;
   1400    src.ArrayID = dst.ArrayID;
   1401 
   1402    return src;
   1403 }
   1404 
   1405 
   1406 
   1407 static inline struct ureg_dst
   1408 ureg_dst_undef( void )
   1409 {
   1410    struct ureg_dst dst;
   1411 
   1412    dst.File      = TGSI_FILE_NULL;
   1413    dst.WriteMask = 0;
   1414    dst.Indirect  = 0;
   1415    dst.IndirectFile = TGSI_FILE_NULL;
   1416    dst.IndirectIndex = 0;
   1417    dst.IndirectSwizzle = 0;
   1418    dst.Saturate  = 0;
   1419    dst.Predicate = 0;
   1420    dst.PredNegate = 0;
   1421    dst.PredSwizzleX = TGSI_SWIZZLE_X;
   1422    dst.PredSwizzleY = TGSI_SWIZZLE_Y;
   1423    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
   1424    dst.PredSwizzleW = TGSI_SWIZZLE_W;
   1425    dst.Index     = 0;
   1426    dst.Dimension = 0;
   1427    dst.DimensionIndex = 0;
   1428    dst.DimIndirect = 0;
   1429    dst.DimIndFile = TGSI_FILE_NULL;
   1430    dst.DimIndIndex = 0;
   1431    dst.DimIndSwizzle = 0;
   1432    dst.ArrayID = 0;
   1433 
   1434    return dst;
   1435 }
   1436 
   1437 static inline struct ureg_src
   1438 ureg_src_undef( void )
   1439 {
   1440    struct ureg_src src;
   1441 
   1442    src.File      = TGSI_FILE_NULL;
   1443    src.SwizzleX  = 0;
   1444    src.SwizzleY  = 0;
   1445    src.SwizzleZ  = 0;
   1446    src.SwizzleW  = 0;
   1447    src.Indirect  = 0;
   1448    src.IndirectFile = TGSI_FILE_NULL;
   1449    src.IndirectIndex = 0;
   1450    src.IndirectSwizzle = 0;
   1451    src.Absolute  = 0;
   1452    src.Index     = 0;
   1453    src.Negate    = 0;
   1454    src.Dimension = 0;
   1455    src.DimensionIndex = 0;
   1456    src.DimIndirect = 0;
   1457    src.DimIndFile = TGSI_FILE_NULL;
   1458    src.DimIndIndex = 0;
   1459    src.DimIndSwizzle = 0;
   1460    src.ArrayID = 0;
   1461 
   1462    return src;
   1463 }
   1464 
   1465 static inline boolean
   1466 ureg_src_is_undef( struct ureg_src src )
   1467 {
   1468    return src.File == TGSI_FILE_NULL;
   1469 }
   1470 
   1471 static inline boolean
   1472 ureg_dst_is_undef( struct ureg_dst dst )
   1473 {
   1474    return dst.File == TGSI_FILE_NULL;
   1475 }
   1476 
   1477 
   1478 #ifdef __cplusplus
   1479 }
   1480 #endif
   1481 
   1482 #endif
   1483