Home | History | Annotate | Download | only in tgsi
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
      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 TUNGSTEN GRAPHICS 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 #include "util/u_debug.h"
     29 #include "pipe/p_format.h"
     30 #include "pipe/p_shader_tokens.h"
     31 #include "tgsi_build.h"
     32 #include "tgsi_parse.h"
     33 
     34 
     35 /*
     36  * header
     37  */
     38 
     39 struct tgsi_header
     40 tgsi_build_header( void )
     41 {
     42    struct tgsi_header header;
     43 
     44    header.HeaderSize = 1;
     45    header.BodySize = 0;
     46 
     47    return header;
     48 }
     49 
     50 static void
     51 header_headersize_grow( struct tgsi_header *header )
     52 {
     53    assert( header->HeaderSize < 0xFF );
     54    assert( header->BodySize == 0 );
     55 
     56    header->HeaderSize++;
     57 }
     58 
     59 static void
     60 header_bodysize_grow( struct tgsi_header *header )
     61 {
     62    assert( header->BodySize < 0xFFFFFF );
     63 
     64    header->BodySize++;
     65 }
     66 
     67 struct tgsi_processor
     68 tgsi_build_processor(
     69    unsigned type,
     70    struct tgsi_header *header )
     71 {
     72    struct tgsi_processor processor;
     73 
     74    processor.Processor = type;
     75    processor.Padding = 0;
     76 
     77    header_headersize_grow( header );
     78 
     79    return processor;
     80 }
     81 
     82 /*
     83  * declaration
     84  */
     85 
     86 static void
     87 declaration_grow(
     88    struct tgsi_declaration *declaration,
     89    struct tgsi_header *header )
     90 {
     91    assert( declaration->NrTokens < 0xFF );
     92 
     93    declaration->NrTokens++;
     94 
     95    header_bodysize_grow( header );
     96 }
     97 
     98 static struct tgsi_declaration
     99 tgsi_default_declaration( void )
    100 {
    101    struct tgsi_declaration declaration;
    102 
    103    declaration.Type = TGSI_TOKEN_TYPE_DECLARATION;
    104    declaration.NrTokens = 1;
    105    declaration.File = TGSI_FILE_NULL;
    106    declaration.UsageMask = TGSI_WRITEMASK_XYZW;
    107    declaration.Interpolate = 0;
    108    declaration.Dimension = 0;
    109    declaration.Semantic = 0;
    110    declaration.Invariant = 0;
    111    declaration.Local = 0;
    112    declaration.Padding = 0;
    113 
    114    return declaration;
    115 }
    116 
    117 static struct tgsi_declaration
    118 tgsi_build_declaration(
    119    unsigned file,
    120    unsigned usage_mask,
    121    unsigned interpolate,
    122    unsigned dimension,
    123    unsigned semantic,
    124    unsigned invariant,
    125    unsigned local,
    126    struct tgsi_header *header )
    127 {
    128    struct tgsi_declaration declaration;
    129 
    130    assert( file < TGSI_FILE_COUNT );
    131    assert( interpolate < TGSI_INTERPOLATE_COUNT );
    132 
    133    declaration = tgsi_default_declaration();
    134    declaration.File = file;
    135    declaration.UsageMask = usage_mask;
    136    declaration.Interpolate = interpolate;
    137    declaration.Dimension = dimension;
    138    declaration.Semantic = semantic;
    139    declaration.Invariant = invariant;
    140    declaration.Local = local;
    141 
    142    header_bodysize_grow( header );
    143 
    144    return declaration;
    145 }
    146 
    147 static struct tgsi_declaration_range
    148 tgsi_default_declaration_range( void )
    149 {
    150    struct tgsi_declaration_range dr;
    151 
    152    dr.First = 0;
    153    dr.Last = 0;
    154 
    155    return dr;
    156 }
    157 
    158 static struct tgsi_declaration_range
    159 tgsi_build_declaration_range(
    160    unsigned first,
    161    unsigned last,
    162    struct tgsi_declaration *declaration,
    163    struct tgsi_header *header )
    164 {
    165    struct tgsi_declaration_range declaration_range;
    166 
    167    assert( last >= first );
    168    assert( last <= 0xFFFF );
    169 
    170    declaration_range.First = first;
    171    declaration_range.Last = last;
    172 
    173    declaration_grow( declaration, header );
    174 
    175    return declaration_range;
    176 }
    177 
    178 static struct tgsi_declaration_dimension
    179 tgsi_build_declaration_dimension(unsigned index_2d,
    180                                  struct tgsi_declaration *declaration,
    181                                  struct tgsi_header *header)
    182 {
    183    struct tgsi_declaration_dimension dd;
    184 
    185    assert(index_2d <= 0xFFFF);
    186 
    187    dd.Index2D = index_2d;
    188    dd.Padding = 0;
    189 
    190    declaration_grow(declaration, header);
    191 
    192    return dd;
    193 }
    194 
    195 static struct tgsi_declaration_interp
    196 tgsi_default_declaration_interp( void )
    197 {
    198    struct tgsi_declaration_interp di;
    199 
    200    di.Interpolate = TGSI_INTERPOLATE_CONSTANT;
    201    di.Centroid = 0;
    202    di.CylindricalWrap = 0;
    203    di.Padding = 0;
    204 
    205    return di;
    206 }
    207 
    208 static struct tgsi_declaration_interp
    209 tgsi_build_declaration_interp(unsigned interpolate,
    210                               unsigned centroid,
    211                               unsigned cylindrical_wrap,
    212                               struct tgsi_declaration *declaration,
    213                               struct tgsi_header *header)
    214 {
    215    struct tgsi_declaration_interp di;
    216 
    217    di.Interpolate = interpolate;
    218    di.Centroid = centroid;
    219    di.CylindricalWrap = cylindrical_wrap;
    220    di.Padding = 0;
    221 
    222    declaration_grow(declaration, header);
    223 
    224    return di;
    225 }
    226 
    227 static struct tgsi_declaration_semantic
    228 tgsi_default_declaration_semantic( void )
    229 {
    230    struct tgsi_declaration_semantic ds;
    231 
    232    ds.Name = TGSI_SEMANTIC_POSITION;
    233    ds.Index = 0;
    234    ds.Padding = 0;
    235 
    236    return ds;
    237 }
    238 
    239 static struct tgsi_declaration_semantic
    240 tgsi_build_declaration_semantic(
    241    unsigned semantic_name,
    242    unsigned semantic_index,
    243    struct tgsi_declaration *declaration,
    244    struct tgsi_header *header )
    245 {
    246    struct tgsi_declaration_semantic ds;
    247 
    248    assert( semantic_name <= TGSI_SEMANTIC_COUNT );
    249    assert( semantic_index <= 0xFFFF );
    250 
    251    ds.Name = semantic_name;
    252    ds.Index = semantic_index;
    253    ds.Padding = 0;
    254 
    255    declaration_grow( declaration, header );
    256 
    257    return ds;
    258 }
    259 
    260 static struct tgsi_declaration_resource
    261 tgsi_default_declaration_resource(void)
    262 {
    263    struct tgsi_declaration_resource dr;
    264 
    265    dr.Resource = TGSI_TEXTURE_BUFFER;
    266    dr.Raw = 0;
    267    dr.Writable = 0;
    268    dr.Padding = 0;
    269 
    270    return dr;
    271 }
    272 
    273 static struct tgsi_declaration_resource
    274 tgsi_build_declaration_resource(unsigned texture,
    275                                 unsigned raw,
    276                                 unsigned writable,
    277                                 struct tgsi_declaration *declaration,
    278                                 struct tgsi_header *header)
    279 {
    280    struct tgsi_declaration_resource dr;
    281 
    282    dr = tgsi_default_declaration_resource();
    283    dr.Resource = texture;
    284    dr.Raw = raw;
    285    dr.Writable = writable;
    286 
    287    declaration_grow(declaration, header);
    288 
    289    return dr;
    290 }
    291 
    292 static struct tgsi_declaration_sampler_view
    293 tgsi_default_declaration_sampler_view(void)
    294 {
    295    struct tgsi_declaration_sampler_view dsv;
    296 
    297    dsv.Resource = TGSI_TEXTURE_BUFFER;
    298    dsv.ReturnTypeX = PIPE_TYPE_UNORM;
    299    dsv.ReturnTypeY = PIPE_TYPE_UNORM;
    300    dsv.ReturnTypeZ = PIPE_TYPE_UNORM;
    301    dsv.ReturnTypeW = PIPE_TYPE_UNORM;
    302 
    303    return dsv;
    304 }
    305 
    306 static struct tgsi_declaration_sampler_view
    307 tgsi_build_declaration_sampler_view(unsigned texture,
    308                                     unsigned return_type_x,
    309                                     unsigned return_type_y,
    310                                     unsigned return_type_z,
    311                                     unsigned return_type_w,
    312                                     struct tgsi_declaration *declaration,
    313                                     struct tgsi_header *header)
    314 {
    315    struct tgsi_declaration_sampler_view dsv;
    316 
    317    dsv = tgsi_default_declaration_sampler_view();
    318    dsv.Resource = texture;
    319    dsv.ReturnTypeX = return_type_x;
    320    dsv.ReturnTypeY = return_type_y;
    321    dsv.ReturnTypeZ = return_type_z;
    322    dsv.ReturnTypeW = return_type_w;
    323 
    324    declaration_grow(declaration, header);
    325 
    326    return dsv;
    327 }
    328 
    329 
    330 struct tgsi_full_declaration
    331 tgsi_default_full_declaration( void )
    332 {
    333    struct tgsi_full_declaration  full_declaration;
    334 
    335    full_declaration.Declaration  = tgsi_default_declaration();
    336    full_declaration.Range = tgsi_default_declaration_range();
    337    full_declaration.Semantic = tgsi_default_declaration_semantic();
    338    full_declaration.Interp = tgsi_default_declaration_interp();
    339    full_declaration.ImmediateData.u = NULL;
    340    full_declaration.Resource = tgsi_default_declaration_resource();
    341    full_declaration.SamplerView = tgsi_default_declaration_sampler_view();
    342 
    343    return full_declaration;
    344 }
    345 
    346 unsigned
    347 tgsi_build_full_declaration(
    348    const struct tgsi_full_declaration *full_decl,
    349    struct tgsi_token *tokens,
    350    struct tgsi_header *header,
    351    unsigned maxsize )
    352 {
    353    unsigned size = 0;
    354    struct tgsi_declaration *declaration;
    355    struct tgsi_declaration_range *dr;
    356 
    357    if( maxsize <= size )
    358       return 0;
    359    declaration = (struct tgsi_declaration *) &tokens[size];
    360    size++;
    361 
    362    *declaration = tgsi_build_declaration(
    363       full_decl->Declaration.File,
    364       full_decl->Declaration.UsageMask,
    365       full_decl->Declaration.Interpolate,
    366       full_decl->Declaration.Dimension,
    367       full_decl->Declaration.Semantic,
    368       full_decl->Declaration.Invariant,
    369       full_decl->Declaration.Local,
    370       header );
    371 
    372    if (maxsize <= size)
    373       return 0;
    374    dr = (struct tgsi_declaration_range *) &tokens[size];
    375    size++;
    376 
    377    *dr = tgsi_build_declaration_range(
    378       full_decl->Range.First,
    379       full_decl->Range.Last,
    380       declaration,
    381       header );
    382 
    383    if (full_decl->Declaration.Dimension) {
    384       struct tgsi_declaration_dimension *dd;
    385 
    386       if (maxsize <= size) {
    387          return 0;
    388       }
    389       dd = (struct tgsi_declaration_dimension *)&tokens[size];
    390       size++;
    391 
    392       *dd = tgsi_build_declaration_dimension(full_decl->Dim.Index2D,
    393                                              declaration,
    394                                              header);
    395    }
    396 
    397    if (full_decl->Declaration.Interpolate) {
    398       struct tgsi_declaration_interp *di;
    399 
    400       if (maxsize <= size) {
    401          return 0;
    402       }
    403       di = (struct tgsi_declaration_interp *)&tokens[size];
    404       size++;
    405 
    406       *di = tgsi_build_declaration_interp(full_decl->Interp.Interpolate,
    407                                           full_decl->Interp.Centroid,
    408                                           full_decl->Interp.CylindricalWrap,
    409                                           declaration,
    410                                           header);
    411    }
    412 
    413    if( full_decl->Declaration.Semantic ) {
    414       struct tgsi_declaration_semantic *ds;
    415 
    416       if( maxsize <= size )
    417          return  0;
    418       ds = (struct tgsi_declaration_semantic *) &tokens[size];
    419       size++;
    420 
    421       *ds = tgsi_build_declaration_semantic(
    422          full_decl->Semantic.Name,
    423          full_decl->Semantic.Index,
    424          declaration,
    425          header );
    426    }
    427 
    428    if (full_decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) {
    429       unsigned i, j;
    430       union tgsi_immediate_data *data;
    431 
    432       for (i = 0; i <= dr->Last; ++i) {
    433          for (j = 0; j < 4; ++j) {
    434             unsigned idx = i*4 + j;
    435             if (maxsize <= size)
    436                return 0;
    437             data = (union tgsi_immediate_data *) &tokens[size];
    438             ++size;
    439 
    440             *data = full_decl->ImmediateData.u[idx];
    441             declaration_grow( declaration, header );
    442          }
    443       }
    444    }
    445 
    446    if (full_decl->Declaration.File == TGSI_FILE_RESOURCE) {
    447       struct tgsi_declaration_resource *dr;
    448 
    449       if (maxsize <= size) {
    450          return  0;
    451       }
    452       dr = (struct tgsi_declaration_resource *)&tokens[size];
    453       size++;
    454 
    455       *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource,
    456                                             full_decl->Resource.Raw,
    457                                             full_decl->Resource.Writable,
    458                                             declaration,
    459                                             header);
    460    }
    461 
    462    if (full_decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
    463       struct tgsi_declaration_sampler_view *dsv;
    464 
    465       if (maxsize <= size) {
    466          return  0;
    467       }
    468       dsv = (struct tgsi_declaration_sampler_view *)&tokens[size];
    469       size++;
    470 
    471       *dsv = tgsi_build_declaration_sampler_view(
    472          full_decl->SamplerView.Resource,
    473          full_decl->SamplerView.ReturnTypeX,
    474          full_decl->SamplerView.ReturnTypeY,
    475          full_decl->SamplerView.ReturnTypeZ,
    476          full_decl->SamplerView.ReturnTypeW,
    477          declaration,
    478          header);
    479    }
    480 
    481    return size;
    482 }
    483 
    484 /*
    485  * immediate
    486  */
    487 
    488 static struct tgsi_immediate
    489 tgsi_default_immediate( void )
    490 {
    491    struct tgsi_immediate immediate;
    492 
    493    immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
    494    immediate.NrTokens = 1;
    495    immediate.DataType = TGSI_IMM_FLOAT32;
    496    immediate.Padding = 0;
    497 
    498    return immediate;
    499 }
    500 
    501 static struct tgsi_immediate
    502 tgsi_build_immediate(
    503    struct tgsi_header *header,
    504    unsigned type )
    505 {
    506    struct tgsi_immediate immediate;
    507 
    508    immediate = tgsi_default_immediate();
    509    immediate.DataType = type;
    510 
    511    header_bodysize_grow( header );
    512 
    513    return immediate;
    514 }
    515 
    516 struct tgsi_full_immediate
    517 tgsi_default_full_immediate( void )
    518 {
    519    struct tgsi_full_immediate fullimm;
    520 
    521    fullimm.Immediate = tgsi_default_immediate();
    522    fullimm.u[0].Float = 0.0f;
    523    fullimm.u[1].Float = 0.0f;
    524    fullimm.u[2].Float = 0.0f;
    525    fullimm.u[3].Float = 0.0f;
    526 
    527    return fullimm;
    528 }
    529 
    530 static void
    531 immediate_grow(
    532    struct tgsi_immediate *immediate,
    533    struct tgsi_header *header )
    534 {
    535    assert( immediate->NrTokens < 0xFF );
    536 
    537    immediate->NrTokens++;
    538 
    539    header_bodysize_grow( header );
    540 }
    541 
    542 unsigned
    543 tgsi_build_full_immediate(
    544    const struct tgsi_full_immediate *full_imm,
    545    struct tgsi_token *tokens,
    546    struct tgsi_header *header,
    547    unsigned maxsize )
    548 {
    549    unsigned size = 0, i;
    550    struct tgsi_immediate *immediate;
    551 
    552    if( maxsize <= size )
    553       return 0;
    554    immediate = (struct tgsi_immediate *) &tokens[size];
    555    size++;
    556 
    557    *immediate = tgsi_build_immediate( header, full_imm->Immediate.DataType );
    558 
    559    assert( full_imm->Immediate.NrTokens <= 4 + 1 );
    560 
    561    for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) {
    562       union tgsi_immediate_data *data;
    563 
    564       if( maxsize <= size )
    565          return  0;
    566 
    567       data = (union tgsi_immediate_data *) &tokens[size];
    568       *data = full_imm->u[i];
    569 
    570       immediate_grow( immediate, header );
    571       size++;
    572    }
    573 
    574    return size;
    575 }
    576 
    577 /*
    578  * instruction
    579  */
    580 
    581 struct tgsi_instruction
    582 tgsi_default_instruction( void )
    583 {
    584    struct tgsi_instruction instruction;
    585 
    586    instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
    587    instruction.NrTokens = 0;
    588    instruction.Opcode = TGSI_OPCODE_MOV;
    589    instruction.Saturate = TGSI_SAT_NONE;
    590    instruction.Predicate = 0;
    591    instruction.NumDstRegs = 1;
    592    instruction.NumSrcRegs = 1;
    593    instruction.Label = 0;
    594    instruction.Texture = 0;
    595    instruction.Padding  = 0;
    596 
    597    return instruction;
    598 }
    599 
    600 static struct tgsi_instruction
    601 tgsi_build_instruction(unsigned opcode,
    602                        unsigned saturate,
    603                        unsigned predicate,
    604                        unsigned num_dst_regs,
    605                        unsigned num_src_regs,
    606                        struct tgsi_header *header)
    607 {
    608    struct tgsi_instruction instruction;
    609 
    610    assert (opcode <= TGSI_OPCODE_LAST);
    611    assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE);
    612    assert (num_dst_regs <= 3);
    613    assert (num_src_regs <= 15);
    614 
    615    instruction = tgsi_default_instruction();
    616    instruction.Opcode = opcode;
    617    instruction.Saturate = saturate;
    618    instruction.Predicate = predicate;
    619    instruction.NumDstRegs = num_dst_regs;
    620    instruction.NumSrcRegs = num_src_regs;
    621 
    622    header_bodysize_grow( header );
    623 
    624    return instruction;
    625 }
    626 
    627 static void
    628 instruction_grow(
    629    struct tgsi_instruction *instruction,
    630    struct tgsi_header *header )
    631 {
    632    assert (instruction->NrTokens <   0xFF);
    633 
    634    instruction->NrTokens++;
    635 
    636    header_bodysize_grow( header );
    637 }
    638 
    639 struct tgsi_instruction_predicate
    640 tgsi_default_instruction_predicate(void)
    641 {
    642    struct tgsi_instruction_predicate instruction_predicate;
    643 
    644    instruction_predicate.SwizzleX = TGSI_SWIZZLE_X;
    645    instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y;
    646    instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z;
    647    instruction_predicate.SwizzleW = TGSI_SWIZZLE_W;
    648    instruction_predicate.Negate = 0;
    649    instruction_predicate.Index = 0;
    650    instruction_predicate.Padding = 0;
    651 
    652    return instruction_predicate;
    653 }
    654 
    655 static struct tgsi_instruction_predicate
    656 tgsi_build_instruction_predicate(int index,
    657                                  unsigned negate,
    658                                  unsigned swizzleX,
    659                                  unsigned swizzleY,
    660                                  unsigned swizzleZ,
    661                                  unsigned swizzleW,
    662                                  struct tgsi_instruction *instruction,
    663                                  struct tgsi_header *header)
    664 {
    665    struct tgsi_instruction_predicate instruction_predicate;
    666 
    667    instruction_predicate = tgsi_default_instruction_predicate();
    668    instruction_predicate.SwizzleX = swizzleX;
    669    instruction_predicate.SwizzleY = swizzleY;
    670    instruction_predicate.SwizzleZ = swizzleZ;
    671    instruction_predicate.SwizzleW = swizzleW;
    672    instruction_predicate.Negate = negate;
    673    instruction_predicate.Index = index;
    674 
    675    instruction_grow(instruction, header);
    676 
    677    return instruction_predicate;
    678 }
    679 
    680 static struct tgsi_instruction_label
    681 tgsi_default_instruction_label( void )
    682 {
    683    struct tgsi_instruction_label instruction_label;
    684 
    685    instruction_label.Label = 0;
    686    instruction_label.Padding = 0;
    687 
    688    return instruction_label;
    689 }
    690 
    691 static struct tgsi_instruction_label
    692 tgsi_build_instruction_label(
    693    unsigned label,
    694    struct tgsi_token  *prev_token,
    695    struct tgsi_instruction *instruction,
    696    struct tgsi_header *header )
    697 {
    698    struct tgsi_instruction_label instruction_label;
    699 
    700    instruction_label.Label = label;
    701    instruction_label.Padding = 0;
    702    instruction->Label = 1;
    703 
    704    instruction_grow( instruction, header );
    705 
    706    return instruction_label;
    707 }
    708 
    709 static struct tgsi_instruction_texture
    710 tgsi_default_instruction_texture( void )
    711 {
    712    struct tgsi_instruction_texture instruction_texture;
    713 
    714    instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
    715    instruction_texture.NumOffsets = 0;
    716    instruction_texture.Padding = 0;
    717 
    718    return instruction_texture;
    719 }
    720 
    721 static struct tgsi_instruction_texture
    722 tgsi_build_instruction_texture(
    723    unsigned texture,
    724    unsigned num_offsets,
    725    struct tgsi_token *prev_token,
    726    struct tgsi_instruction *instruction,
    727    struct tgsi_header *header )
    728 {
    729    struct tgsi_instruction_texture instruction_texture;
    730 
    731    instruction_texture.Texture = texture;
    732    instruction_texture.NumOffsets = num_offsets;
    733    instruction_texture.Padding = 0;
    734    instruction->Texture = 1;
    735 
    736    instruction_grow( instruction, header );
    737 
    738    return instruction_texture;
    739 }
    740 
    741 
    742 static struct tgsi_texture_offset
    743 tgsi_default_texture_offset( void )
    744 {
    745    struct tgsi_texture_offset texture_offset;
    746 
    747    texture_offset.Index = 0;
    748    texture_offset.File = 0;
    749    texture_offset.SwizzleX = 0;
    750    texture_offset.SwizzleY = 0;
    751    texture_offset.SwizzleZ = 0;
    752    texture_offset.Padding = 0;
    753 
    754    return texture_offset;
    755 }
    756 
    757 static struct tgsi_texture_offset
    758 tgsi_build_texture_offset(
    759    int index, int file, int swizzle_x, int swizzle_y, int swizzle_z,
    760    struct tgsi_token *prev_token,
    761    struct tgsi_instruction *instruction,
    762    struct tgsi_header *header )
    763 {
    764    struct tgsi_texture_offset texture_offset;
    765 
    766    texture_offset.Index = index;
    767    texture_offset.File = file;
    768    texture_offset.SwizzleX = swizzle_x;
    769    texture_offset.SwizzleY = swizzle_y;
    770    texture_offset.SwizzleZ = swizzle_z;
    771    texture_offset.Padding = 0;
    772 
    773    instruction_grow( instruction, header );
    774 
    775    return texture_offset;
    776 }
    777 
    778 static struct tgsi_src_register
    779 tgsi_default_src_register( void )
    780 {
    781    struct tgsi_src_register src_register;
    782 
    783    src_register.File = TGSI_FILE_NULL;
    784    src_register.SwizzleX = TGSI_SWIZZLE_X;
    785    src_register.SwizzleY = TGSI_SWIZZLE_Y;
    786    src_register.SwizzleZ = TGSI_SWIZZLE_Z;
    787    src_register.SwizzleW = TGSI_SWIZZLE_W;
    788    src_register.Negate = 0;
    789    src_register.Absolute = 0;
    790    src_register.Indirect = 0;
    791    src_register.Dimension = 0;
    792    src_register.Index = 0;
    793 
    794    return src_register;
    795 }
    796 
    797 static struct tgsi_src_register
    798 tgsi_build_src_register(
    799    unsigned file,
    800    unsigned swizzle_x,
    801    unsigned swizzle_y,
    802    unsigned swizzle_z,
    803    unsigned swizzle_w,
    804    unsigned negate,
    805    unsigned absolute,
    806    unsigned indirect,
    807    unsigned dimension,
    808    int index,
    809    struct tgsi_instruction *instruction,
    810    struct tgsi_header *header )
    811 {
    812    struct tgsi_src_register   src_register;
    813 
    814    assert( file < TGSI_FILE_COUNT );
    815    assert( swizzle_x <= TGSI_SWIZZLE_W );
    816    assert( swizzle_y <= TGSI_SWIZZLE_W );
    817    assert( swizzle_z <= TGSI_SWIZZLE_W );
    818    assert( swizzle_w <= TGSI_SWIZZLE_W );
    819    assert( negate <= 1 );
    820    assert( index >= -0x8000 && index <= 0x7FFF );
    821 
    822    src_register.File = file;
    823    src_register.SwizzleX = swizzle_x;
    824    src_register.SwizzleY = swizzle_y;
    825    src_register.SwizzleZ = swizzle_z;
    826    src_register.SwizzleW = swizzle_w;
    827    src_register.Negate = negate;
    828    src_register.Absolute = absolute;
    829    src_register.Indirect = indirect;
    830    src_register.Dimension = dimension;
    831    src_register.Index = index;
    832 
    833    instruction_grow( instruction, header );
    834 
    835    return src_register;
    836 }
    837 
    838 static struct tgsi_dimension
    839 tgsi_default_dimension( void )
    840 {
    841    struct tgsi_dimension dimension;
    842 
    843    dimension.Indirect = 0;
    844    dimension.Dimension = 0;
    845    dimension.Padding = 0;
    846    dimension.Index = 0;
    847 
    848    return dimension;
    849 }
    850 
    851 static struct tgsi_full_src_register
    852 tgsi_default_full_src_register( void )
    853 {
    854    struct tgsi_full_src_register full_src_register;
    855 
    856    full_src_register.Register = tgsi_default_src_register();
    857    full_src_register.Indirect = tgsi_default_src_register();
    858    full_src_register.Dimension = tgsi_default_dimension();
    859    full_src_register.DimIndirect = tgsi_default_src_register();
    860 
    861    return full_src_register;
    862 }
    863 
    864 static struct tgsi_dimension
    865 tgsi_build_dimension(
    866    unsigned indirect,
    867    unsigned index,
    868    struct tgsi_instruction *instruction,
    869    struct tgsi_header *header )
    870 {
    871    struct tgsi_dimension dimension;
    872 
    873    dimension.Indirect = indirect;
    874    dimension.Dimension = 0;
    875    dimension.Padding = 0;
    876    dimension.Index = index;
    877 
    878    instruction_grow( instruction, header );
    879 
    880    return dimension;
    881 }
    882 
    883 static struct tgsi_dst_register
    884 tgsi_default_dst_register( void )
    885 {
    886    struct tgsi_dst_register dst_register;
    887 
    888    dst_register.File = TGSI_FILE_NULL;
    889    dst_register.WriteMask = TGSI_WRITEMASK_XYZW;
    890    dst_register.Indirect = 0;
    891    dst_register.Dimension = 0;
    892    dst_register.Index = 0;
    893    dst_register.Padding = 0;
    894 
    895    return dst_register;
    896 }
    897 
    898 static struct tgsi_dst_register
    899 tgsi_build_dst_register(
    900    unsigned file,
    901    unsigned mask,
    902    unsigned indirect,
    903    unsigned dimension,
    904    int index,
    905    struct tgsi_instruction *instruction,
    906    struct tgsi_header *header )
    907 {
    908    struct tgsi_dst_register dst_register;
    909 
    910    assert( file < TGSI_FILE_COUNT );
    911    assert( mask <= TGSI_WRITEMASK_XYZW );
    912    assert( index >= -32768 && index <= 32767 );
    913 
    914    dst_register.File = file;
    915    dst_register.WriteMask = mask;
    916    dst_register.Indirect = indirect;
    917    dst_register.Dimension = dimension;
    918    dst_register.Index = index;
    919    dst_register.Padding = 0;
    920 
    921    instruction_grow( instruction, header );
    922 
    923    return dst_register;
    924 }
    925 
    926 static struct tgsi_full_dst_register
    927 tgsi_default_full_dst_register( void )
    928 {
    929    struct tgsi_full_dst_register full_dst_register;
    930 
    931    full_dst_register.Register = tgsi_default_dst_register();
    932    full_dst_register.Indirect = tgsi_default_src_register();
    933    full_dst_register.Dimension = tgsi_default_dimension();
    934    full_dst_register.DimIndirect = tgsi_default_src_register();
    935 
    936    return full_dst_register;
    937 }
    938 
    939 struct tgsi_full_instruction
    940 tgsi_default_full_instruction( void )
    941 {
    942    struct tgsi_full_instruction full_instruction;
    943    unsigned i;
    944 
    945    full_instruction.Instruction = tgsi_default_instruction();
    946    full_instruction.Predicate = tgsi_default_instruction_predicate();
    947    full_instruction.Label = tgsi_default_instruction_label();
    948    full_instruction.Texture = tgsi_default_instruction_texture();
    949    for( i = 0;  i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) {
    950       full_instruction.TexOffsets[i] = tgsi_default_texture_offset();
    951    }
    952    for( i = 0;  i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
    953       full_instruction.Dst[i] = tgsi_default_full_dst_register();
    954    }
    955    for( i = 0;  i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
    956       full_instruction.Src[i] = tgsi_default_full_src_register();
    957    }
    958 
    959    return full_instruction;
    960 }
    961 
    962 unsigned
    963 tgsi_build_full_instruction(
    964    const struct tgsi_full_instruction *full_inst,
    965    struct  tgsi_token *tokens,
    966    struct  tgsi_header *header,
    967    unsigned  maxsize )
    968 {
    969    unsigned size = 0;
    970    unsigned i;
    971    struct tgsi_instruction *instruction;
    972    struct tgsi_token *prev_token;
    973 
    974    if( maxsize <= size )
    975       return 0;
    976    instruction = (struct tgsi_instruction *) &tokens[size];
    977    size++;
    978 
    979    *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
    980                                          full_inst->Instruction.Saturate,
    981                                          full_inst->Instruction.Predicate,
    982                                          full_inst->Instruction.NumDstRegs,
    983                                          full_inst->Instruction.NumSrcRegs,
    984                                          header);
    985    prev_token = (struct tgsi_token  *) instruction;
    986 
    987    if (full_inst->Instruction.Predicate) {
    988       struct tgsi_instruction_predicate *instruction_predicate;
    989 
    990       if (maxsize <= size) {
    991          return 0;
    992       }
    993       instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size];
    994       size++;
    995 
    996       *instruction_predicate =
    997          tgsi_build_instruction_predicate(full_inst->Predicate.Index,
    998                                           full_inst->Predicate.Negate,
    999                                           full_inst->Predicate.SwizzleX,
   1000                                           full_inst->Predicate.SwizzleY,
   1001                                           full_inst->Predicate.SwizzleZ,
   1002                                           full_inst->Predicate.SwizzleW,
   1003                                           instruction,
   1004                                           header);
   1005    }
   1006 
   1007    if (full_inst->Instruction.Label) {
   1008       struct tgsi_instruction_label *instruction_label;
   1009 
   1010       if( maxsize <= size )
   1011          return 0;
   1012       instruction_label =
   1013          (struct  tgsi_instruction_label *) &tokens[size];
   1014       size++;
   1015 
   1016       *instruction_label = tgsi_build_instruction_label(
   1017          full_inst->Label.Label,
   1018          prev_token,
   1019          instruction,
   1020          header );
   1021       prev_token = (struct tgsi_token  *) instruction_label;
   1022    }
   1023 
   1024    if (full_inst->Instruction.Texture) {
   1025       struct tgsi_instruction_texture *instruction_texture;
   1026 
   1027       if( maxsize <= size )
   1028          return 0;
   1029       instruction_texture =
   1030          (struct  tgsi_instruction_texture *) &tokens[size];
   1031       size++;
   1032 
   1033       *instruction_texture = tgsi_build_instruction_texture(
   1034          full_inst->Texture.Texture,
   1035 	 full_inst->Texture.NumOffsets,
   1036          prev_token,
   1037          instruction,
   1038          header   );
   1039       prev_token = (struct tgsi_token  *) instruction_texture;
   1040 
   1041       for (i = 0; i < full_inst->Texture.NumOffsets; i++) {
   1042          struct tgsi_texture_offset *texture_offset;
   1043 
   1044          if ( maxsize <= size )
   1045             return 0;
   1046 	 texture_offset = (struct tgsi_texture_offset *)&tokens[size];
   1047          size++;
   1048          *texture_offset = tgsi_build_texture_offset(
   1049             full_inst->TexOffsets[i].Index,
   1050             full_inst->TexOffsets[i].File,
   1051             full_inst->TexOffsets[i].SwizzleX,
   1052             full_inst->TexOffsets[i].SwizzleY,
   1053             full_inst->TexOffsets[i].SwizzleZ,
   1054             prev_token,
   1055             instruction,
   1056             header);
   1057          prev_token = (struct tgsi_token *) texture_offset;
   1058       }
   1059    }
   1060    for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
   1061       const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
   1062       struct tgsi_dst_register *dst_register;
   1063 
   1064       if( maxsize <= size )
   1065          return 0;
   1066       dst_register = (struct tgsi_dst_register *) &tokens[size];
   1067       size++;
   1068 
   1069       *dst_register = tgsi_build_dst_register(
   1070          reg->Register.File,
   1071          reg->Register.WriteMask,
   1072          reg->Register.Indirect,
   1073          reg->Register.Dimension,
   1074          reg->Register.Index,
   1075          instruction,
   1076          header );
   1077 
   1078       if( reg->Register.Indirect ) {
   1079          struct tgsi_src_register *ind;
   1080 
   1081          if( maxsize <= size )
   1082             return 0;
   1083          ind = (struct tgsi_src_register *) &tokens[size];
   1084          size++;
   1085 
   1086          *ind = tgsi_build_src_register(
   1087             reg->Indirect.File,
   1088             reg->Indirect.SwizzleX,
   1089             reg->Indirect.SwizzleY,
   1090             reg->Indirect.SwizzleZ,
   1091             reg->Indirect.SwizzleW,
   1092             reg->Indirect.Negate,
   1093             reg->Indirect.Absolute,
   1094             reg->Indirect.Indirect,
   1095             reg->Indirect.Dimension,
   1096             reg->Indirect.Index,
   1097             instruction,
   1098             header );
   1099       }
   1100 
   1101       if( reg->Register.Dimension ) {
   1102          struct  tgsi_dimension *dim;
   1103 
   1104          assert( !reg->Dimension.Dimension );
   1105 
   1106          if( maxsize <= size )
   1107             return 0;
   1108          dim = (struct tgsi_dimension *) &tokens[size];
   1109          size++;
   1110 
   1111          *dim = tgsi_build_dimension(
   1112             reg->Dimension.Indirect,
   1113             reg->Dimension.Index,
   1114             instruction,
   1115             header );
   1116 
   1117          if( reg->Dimension.Indirect ) {
   1118             struct tgsi_src_register *ind;
   1119 
   1120             if( maxsize <= size )
   1121                return 0;
   1122             ind = (struct tgsi_src_register *) &tokens[size];
   1123             size++;
   1124 
   1125             *ind = tgsi_build_src_register(
   1126                reg->DimIndirect.File,
   1127                reg->DimIndirect.SwizzleX,
   1128                reg->DimIndirect.SwizzleY,
   1129                reg->DimIndirect.SwizzleZ,
   1130                reg->DimIndirect.SwizzleW,
   1131                reg->DimIndirect.Negate,
   1132                reg->DimIndirect.Absolute,
   1133                reg->DimIndirect.Indirect,
   1134                reg->DimIndirect.Dimension,
   1135                reg->DimIndirect.Index,
   1136                instruction,
   1137                header );
   1138          }
   1139       }
   1140    }
   1141 
   1142    for( i = 0;  i < full_inst->Instruction.NumSrcRegs; i++ ) {
   1143       const struct tgsi_full_src_register *reg = &full_inst->Src[i];
   1144       struct tgsi_src_register *src_register;
   1145 
   1146       if( maxsize <= size )
   1147          return 0;
   1148       src_register = (struct tgsi_src_register *)  &tokens[size];
   1149       size++;
   1150 
   1151       *src_register = tgsi_build_src_register(
   1152          reg->Register.File,
   1153          reg->Register.SwizzleX,
   1154          reg->Register.SwizzleY,
   1155          reg->Register.SwizzleZ,
   1156          reg->Register.SwizzleW,
   1157          reg->Register.Negate,
   1158          reg->Register.Absolute,
   1159          reg->Register.Indirect,
   1160          reg->Register.Dimension,
   1161          reg->Register.Index,
   1162          instruction,
   1163          header );
   1164 
   1165       if( reg->Register.Indirect ) {
   1166          struct  tgsi_src_register *ind;
   1167 
   1168          if( maxsize <= size )
   1169             return 0;
   1170          ind = (struct tgsi_src_register *) &tokens[size];
   1171          size++;
   1172 
   1173          *ind = tgsi_build_src_register(
   1174             reg->Indirect.File,
   1175             reg->Indirect.SwizzleX,
   1176             reg->Indirect.SwizzleY,
   1177             reg->Indirect.SwizzleZ,
   1178             reg->Indirect.SwizzleW,
   1179             reg->Indirect.Negate,
   1180             reg->Indirect.Absolute,
   1181             reg->Indirect.Indirect,
   1182             reg->Indirect.Dimension,
   1183             reg->Indirect.Index,
   1184             instruction,
   1185             header );
   1186       }
   1187 
   1188       if( reg->Register.Dimension ) {
   1189          struct  tgsi_dimension *dim;
   1190 
   1191          assert( !reg->Dimension.Dimension );
   1192 
   1193          if( maxsize <= size )
   1194             return 0;
   1195          dim = (struct tgsi_dimension *) &tokens[size];
   1196          size++;
   1197 
   1198          *dim = tgsi_build_dimension(
   1199             reg->Dimension.Indirect,
   1200             reg->Dimension.Index,
   1201             instruction,
   1202             header );
   1203 
   1204          if( reg->Dimension.Indirect ) {
   1205             struct tgsi_src_register *ind;
   1206 
   1207             if( maxsize <= size )
   1208                return 0;
   1209             ind = (struct tgsi_src_register *) &tokens[size];
   1210             size++;
   1211 
   1212             *ind = tgsi_build_src_register(
   1213                reg->DimIndirect.File,
   1214                reg->DimIndirect.SwizzleX,
   1215                reg->DimIndirect.SwizzleY,
   1216                reg->DimIndirect.SwizzleZ,
   1217                reg->DimIndirect.SwizzleW,
   1218                reg->DimIndirect.Negate,
   1219                reg->DimIndirect.Absolute,
   1220                reg->DimIndirect.Indirect,
   1221                reg->DimIndirect.Dimension,
   1222                reg->DimIndirect.Index,
   1223                instruction,
   1224                header );
   1225          }
   1226       }
   1227    }
   1228 
   1229    return size;
   1230 }
   1231 
   1232 static struct tgsi_property
   1233 tgsi_default_property( void )
   1234 {
   1235    struct tgsi_property property;
   1236 
   1237    property.Type = TGSI_TOKEN_TYPE_PROPERTY;
   1238    property.NrTokens = 1;
   1239    property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
   1240    property.Padding = 0;
   1241 
   1242    return property;
   1243 }
   1244 
   1245 static struct tgsi_property
   1246 tgsi_build_property(unsigned property_name,
   1247                     struct tgsi_header *header)
   1248 {
   1249    struct tgsi_property property;
   1250 
   1251    property = tgsi_default_property();
   1252    property.PropertyName = property_name;
   1253 
   1254    header_bodysize_grow( header );
   1255 
   1256    return property;
   1257 }
   1258 
   1259 
   1260 struct tgsi_full_property
   1261 tgsi_default_full_property( void )
   1262 {
   1263    struct tgsi_full_property  full_property;
   1264 
   1265    full_property.Property  = tgsi_default_property();
   1266    memset(full_property.u, 0,
   1267           sizeof(struct tgsi_property_data) * 8);
   1268 
   1269    return full_property;
   1270 }
   1271 
   1272 static void
   1273 property_grow(
   1274    struct tgsi_property *property,
   1275    struct tgsi_header *header )
   1276 {
   1277    assert( property->NrTokens < 0xFF );
   1278 
   1279    property->NrTokens++;
   1280 
   1281    header_bodysize_grow( header );
   1282 }
   1283 
   1284 static struct tgsi_property_data
   1285 tgsi_build_property_data(
   1286    unsigned value,
   1287    struct tgsi_property *property,
   1288    struct tgsi_header *header )
   1289 {
   1290    struct tgsi_property_data property_data;
   1291 
   1292    property_data.Data = value;
   1293 
   1294    property_grow( property, header );
   1295 
   1296    return property_data;
   1297 }
   1298 
   1299 unsigned
   1300 tgsi_build_full_property(
   1301    const struct tgsi_full_property *full_prop,
   1302    struct tgsi_token *tokens,
   1303    struct tgsi_header *header,
   1304    unsigned maxsize )
   1305 {
   1306    unsigned size = 0, i;
   1307    struct tgsi_property *property;
   1308 
   1309    if( maxsize <= size )
   1310       return 0;
   1311    property = (struct tgsi_property *) &tokens[size];
   1312    size++;
   1313 
   1314    *property = tgsi_build_property(
   1315       full_prop->Property.PropertyName,
   1316       header );
   1317 
   1318    assert( full_prop->Property.NrTokens <= 8 + 1 );
   1319 
   1320    for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
   1321       struct tgsi_property_data *data;
   1322 
   1323       if( maxsize <= size )
   1324          return  0;
   1325       data = (struct tgsi_property_data *) &tokens[size];
   1326       size++;
   1327 
   1328       *data = tgsi_build_property_data(
   1329          full_prop->u[i].Data,
   1330          property,
   1331          header );
   1332    }
   1333 
   1334    return size;
   1335 }
   1336