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