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