Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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