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