Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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