Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2009-2010 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, INC 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.  
  29. #include "pipe/p_context.h"
  30. #include "pipe/p_state.h"
  31. #include "tgsi/tgsi_ureg.h"
  32. #include "tgsi/tgsi_build.h"
  33. #include "tgsi/tgsi_info.h"
  34. #include "tgsi/tgsi_dump.h"
  35. #include "tgsi/tgsi_sanity.h"
  36. #include "util/u_debug.h"
  37. #include "util/u_memory.h"
  38. #include "util/u_math.h"
  39. #include "util/u_bitmask.h"
  40.  
  41. union tgsi_any_token {
  42.    struct tgsi_header header;
  43.    struct tgsi_processor processor;
  44.    struct tgsi_token token;
  45.    struct tgsi_property prop;
  46.    struct tgsi_property_data prop_data;
  47.    struct tgsi_declaration decl;
  48.    struct tgsi_declaration_range decl_range;
  49.    struct tgsi_declaration_dimension decl_dim;
  50.    struct tgsi_declaration_interp decl_interp;
  51.    struct tgsi_declaration_semantic decl_semantic;
  52.    struct tgsi_declaration_sampler_view decl_sampler_view;
  53.    struct tgsi_declaration_array array;
  54.    struct tgsi_immediate imm;
  55.    union  tgsi_immediate_data imm_data;
  56.    struct tgsi_instruction insn;
  57.    struct tgsi_instruction_predicate insn_predicate;
  58.    struct tgsi_instruction_label insn_label;
  59.    struct tgsi_instruction_texture insn_texture;
  60.    struct tgsi_texture_offset insn_texture_offset;
  61.    struct tgsi_src_register src;
  62.    struct tgsi_ind_register ind;
  63.    struct tgsi_dimension dim;
  64.    struct tgsi_dst_register dst;
  65.    unsigned value;
  66. };
  67.  
  68.  
  69. struct ureg_tokens {
  70.    union tgsi_any_token *tokens;
  71.    unsigned size;
  72.    unsigned order;
  73.    unsigned count;
  74. };
  75.  
  76. #define UREG_MAX_INPUT PIPE_MAX_SHADER_INPUTS
  77. #define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS
  78. #define UREG_MAX_OUTPUT PIPE_MAX_SHADER_OUTPUTS
  79. #define UREG_MAX_CONSTANT_RANGE 32
  80. #define UREG_MAX_IMMEDIATE 4096
  81. #define UREG_MAX_ADDR 3
  82. #define UREG_MAX_PRED 1
  83. #define UREG_MAX_ARRAY_TEMPS 256
  84.  
  85. struct const_decl {
  86.    struct {
  87.       unsigned first;
  88.       unsigned last;
  89.    } constant_range[UREG_MAX_CONSTANT_RANGE];
  90.    unsigned nr_constant_ranges;
  91. };
  92.  
  93. #define DOMAIN_DECL 0
  94. #define DOMAIN_INSN 1
  95.  
  96. struct ureg_program
  97. {
  98.    unsigned processor;
  99.    struct pipe_context *pipe;
  100.  
  101.    struct {
  102.       unsigned semantic_name;
  103.       unsigned semantic_index;
  104.       unsigned interp;
  105.       unsigned char cylindrical_wrap;
  106.       unsigned interp_location;
  107.    } fs_input[UREG_MAX_INPUT];
  108.    unsigned nr_fs_inputs;
  109.  
  110.    unsigned vs_inputs[UREG_MAX_INPUT/32];
  111.  
  112.    struct {
  113.       unsigned index;
  114.       unsigned semantic_name;
  115.       unsigned semantic_index;
  116.    } gs_input[UREG_MAX_INPUT];
  117.    unsigned nr_gs_inputs;
  118.  
  119.    struct {
  120.       unsigned index;
  121.       unsigned semantic_name;
  122.       unsigned semantic_index;
  123.    } system_value[UREG_MAX_SYSTEM_VALUE];
  124.    unsigned nr_system_values;
  125.  
  126.    struct {
  127.       unsigned semantic_name;
  128.       unsigned semantic_index;
  129.       unsigned usage_mask; /* = TGSI_WRITEMASK_* */
  130.    } output[UREG_MAX_OUTPUT];
  131.    unsigned nr_outputs;
  132.  
  133.    struct {
  134.       union {
  135.          float f[4];
  136.          unsigned u[4];
  137.          int i[4];
  138.       } value;
  139.       unsigned nr;
  140.       unsigned type;
  141.    } immediate[UREG_MAX_IMMEDIATE];
  142.    unsigned nr_immediates;
  143.  
  144.    struct ureg_src sampler[PIPE_MAX_SAMPLERS];
  145.    unsigned nr_samplers;
  146.  
  147.    struct {
  148.       unsigned index;
  149.       unsigned target;
  150.       unsigned return_type_x;
  151.       unsigned return_type_y;
  152.       unsigned return_type_z;
  153.       unsigned return_type_w;
  154.    } sampler_view[PIPE_MAX_SHADER_SAMPLER_VIEWS];
  155.    unsigned nr_sampler_views;
  156.  
  157.    struct util_bitmask *free_temps;
  158.    struct util_bitmask *local_temps;
  159.    struct util_bitmask *decl_temps;
  160.    unsigned nr_temps;
  161.  
  162.    unsigned array_temps[UREG_MAX_ARRAY_TEMPS];
  163.    unsigned nr_array_temps;
  164.  
  165.    struct const_decl const_decls;
  166.    struct const_decl const_decls2D[PIPE_MAX_CONSTANT_BUFFERS];
  167.  
  168.    unsigned properties[TGSI_PROPERTY_COUNT];
  169.  
  170.    unsigned nr_addrs;
  171.    unsigned nr_preds;
  172.    unsigned nr_instructions;
  173.  
  174.    struct ureg_tokens domain[2];
  175. };
  176.  
  177. static union tgsi_any_token error_tokens[32];
  178.  
  179. static void tokens_error( struct ureg_tokens *tokens )
  180. {
  181.    if (tokens->tokens && tokens->tokens != error_tokens)
  182.       FREE(tokens->tokens);
  183.  
  184.    tokens->tokens = error_tokens;
  185.    tokens->size = Elements(error_tokens);
  186.    tokens->count = 0;
  187. }
  188.  
  189.  
  190. static void tokens_expand( struct ureg_tokens *tokens,
  191.                            unsigned count )
  192. {
  193.    unsigned old_size = tokens->size * sizeof(unsigned);
  194.  
  195.    if (tokens->tokens == error_tokens) {
  196.       return;
  197.    }
  198.  
  199.    while (tokens->count + count > tokens->size) {
  200.       tokens->size = (1 << ++tokens->order);
  201.    }
  202.  
  203.    tokens->tokens = REALLOC(tokens->tokens,
  204.                             old_size,
  205.                             tokens->size * sizeof(unsigned));
  206.    if (tokens->tokens == NULL) {
  207.       tokens_error(tokens);
  208.    }
  209. }
  210.  
  211. static void set_bad( struct ureg_program *ureg )
  212. {
  213.    tokens_error(&ureg->domain[0]);
  214. }
  215.  
  216.  
  217.  
  218. static union tgsi_any_token *get_tokens( struct ureg_program *ureg,
  219.                                          unsigned domain,
  220.                                          unsigned count )
  221. {
  222.    struct ureg_tokens *tokens = &ureg->domain[domain];
  223.    union tgsi_any_token *result;
  224.  
  225.    if (tokens->count + count > tokens->size)
  226.       tokens_expand(tokens, count);
  227.  
  228.    result = &tokens->tokens[tokens->count];
  229.    tokens->count += count;
  230.    return result;
  231. }
  232.  
  233.  
  234. static union tgsi_any_token *retrieve_token( struct ureg_program *ureg,
  235.                                             unsigned domain,
  236.                                             unsigned nr )
  237. {
  238.    if (ureg->domain[domain].tokens == error_tokens)
  239.       return &error_tokens[0];
  240.  
  241.    return &ureg->domain[domain].tokens[nr];
  242. }
  243.  
  244. void
  245. ureg_property(struct ureg_program *ureg, unsigned name, unsigned value)
  246. {
  247.    assert(name < Elements(ureg->properties));
  248.    ureg->properties[name] = value;
  249. }
  250.  
  251. struct ureg_src
  252. ureg_DECL_fs_input_cyl_centroid(struct ureg_program *ureg,
  253.                        unsigned semantic_name,
  254.                        unsigned semantic_index,
  255.                        unsigned interp_mode,
  256.                        unsigned cylindrical_wrap,
  257.                        unsigned interp_location)
  258. {
  259.    unsigned i;
  260.  
  261.    for (i = 0; i < ureg->nr_fs_inputs; i++) {
  262.       if (ureg->fs_input[i].semantic_name == semantic_name &&
  263.           ureg->fs_input[i].semantic_index == semantic_index) {
  264.          goto out;
  265.       }
  266.    }
  267.  
  268.    if (ureg->nr_fs_inputs < UREG_MAX_INPUT) {
  269.       ureg->fs_input[i].semantic_name = semantic_name;
  270.       ureg->fs_input[i].semantic_index = semantic_index;
  271.       ureg->fs_input[i].interp = interp_mode;
  272.       ureg->fs_input[i].cylindrical_wrap = cylindrical_wrap;
  273.       ureg->fs_input[i].interp_location = interp_location;
  274.       ureg->nr_fs_inputs++;
  275.    } else {
  276.       set_bad(ureg);
  277.    }
  278.  
  279. out:
  280.    return ureg_src_register(TGSI_FILE_INPUT, i);
  281. }
  282.  
  283.  
  284. struct ureg_src
  285. ureg_DECL_vs_input( struct ureg_program *ureg,
  286.                     unsigned index )
  287. {
  288.    assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
  289.    
  290.    ureg->vs_inputs[index/32] |= 1 << (index % 32);
  291.    return ureg_src_register( TGSI_FILE_INPUT, index );
  292. }
  293.  
  294.  
  295. struct ureg_src
  296. ureg_DECL_gs_input(struct ureg_program *ureg,
  297.                    unsigned index,
  298.                    unsigned semantic_name,
  299.                    unsigned semantic_index)
  300. {
  301.    if (ureg->nr_gs_inputs < UREG_MAX_INPUT) {
  302.       ureg->gs_input[ureg->nr_gs_inputs].index = index;
  303.       ureg->gs_input[ureg->nr_gs_inputs].semantic_name = semantic_name;
  304.       ureg->gs_input[ureg->nr_gs_inputs].semantic_index = semantic_index;
  305.       ureg->nr_gs_inputs++;
  306.    } else {
  307.       set_bad(ureg);
  308.    }
  309.  
  310.    /* XXX: Add suport for true 2D input registers. */
  311.    return ureg_src_register(TGSI_FILE_INPUT, index);
  312. }
  313.  
  314.  
  315. struct ureg_src
  316. ureg_DECL_system_value(struct ureg_program *ureg,
  317.                        unsigned index,
  318.                        unsigned semantic_name,
  319.                        unsigned semantic_index)
  320. {
  321.    if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) {
  322.       ureg->system_value[ureg->nr_system_values].index = index;
  323.       ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name;
  324.       ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index;
  325.       ureg->nr_system_values++;
  326.    } else {
  327.       set_bad(ureg);
  328.    }
  329.  
  330.    return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, index);
  331. }
  332.  
  333.  
  334. struct ureg_dst
  335. ureg_DECL_output_masked( struct ureg_program *ureg,
  336.                          unsigned name,
  337.                          unsigned index,
  338.                          unsigned usage_mask )
  339. {
  340.    unsigned i;
  341.  
  342.    assert(usage_mask != 0);
  343.  
  344.    for (i = 0; i < ureg->nr_outputs; i++) {
  345.       if (ureg->output[i].semantic_name == name &&
  346.           ureg->output[i].semantic_index == index) {
  347.          ureg->output[i].usage_mask |= usage_mask;
  348.          goto out;
  349.       }
  350.    }
  351.  
  352.    if (ureg->nr_outputs < UREG_MAX_OUTPUT) {
  353.       ureg->output[i].semantic_name = name;
  354.       ureg->output[i].semantic_index = index;
  355.       ureg->output[i].usage_mask = usage_mask;
  356.       ureg->nr_outputs++;
  357.    }
  358.    else {
  359.       set_bad( ureg );
  360.    }
  361.  
  362. out:
  363.    return ureg_dst_register( TGSI_FILE_OUTPUT, i );
  364. }
  365.  
  366.  
  367. struct ureg_dst
  368. ureg_DECL_output( struct ureg_program *ureg,
  369.                   unsigned name,
  370.                   unsigned index )
  371. {
  372.    return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW);
  373. }
  374.  
  375.  
  376. /* Returns a new constant register.  Keep track of which have been
  377.  * referred to so that we can emit decls later.
  378.  *
  379.  * Constant operands declared with this function must be addressed
  380.  * with a two-dimensional index.
  381.  *
  382.  * There is nothing in this code to bind this constant to any tracked
  383.  * value or manage any constant_buffer contents -- that's the
  384.  * resposibility of the calling code.
  385.  */
  386. void
  387. ureg_DECL_constant2D(struct ureg_program *ureg,
  388.                      unsigned first,
  389.                      unsigned last,
  390.                      unsigned index2D)
  391. {
  392.    struct const_decl *decl = &ureg->const_decls2D[index2D];
  393.  
  394.    assert(index2D < PIPE_MAX_CONSTANT_BUFFERS);
  395.  
  396.    if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
  397.       uint i = decl->nr_constant_ranges++;
  398.  
  399.       decl->constant_range[i].first = first;
  400.       decl->constant_range[i].last = last;
  401.    }
  402. }
  403.  
  404.  
  405. /* A one-dimensional, depricated version of ureg_DECL_constant2D().
  406.  *
  407.  * Constant operands declared with this function must be addressed
  408.  * with a one-dimensional index.
  409.  */
  410. struct ureg_src
  411. ureg_DECL_constant(struct ureg_program *ureg,
  412.                    unsigned index)
  413. {
  414.    struct const_decl *decl = &ureg->const_decls;
  415.    unsigned minconst = index, maxconst = index;
  416.    unsigned i;
  417.  
  418.    /* Inside existing range?
  419.     */
  420.    for (i = 0; i < decl->nr_constant_ranges; i++) {
  421.       if (decl->constant_range[i].first <= index &&
  422.           decl->constant_range[i].last >= index) {
  423.          goto out;
  424.       }
  425.    }
  426.  
  427.    /* Extend existing range?
  428.     */
  429.    for (i = 0; i < decl->nr_constant_ranges; i++) {
  430.       if (decl->constant_range[i].last == index - 1) {
  431.          decl->constant_range[i].last = index;
  432.          goto out;
  433.       }
  434.  
  435.       if (decl->constant_range[i].first == index + 1) {
  436.          decl->constant_range[i].first = index;
  437.          goto out;
  438.       }
  439.  
  440.       minconst = MIN2(minconst, decl->constant_range[i].first);
  441.       maxconst = MAX2(maxconst, decl->constant_range[i].last);
  442.    }
  443.  
  444.    /* Create new range?
  445.     */
  446.    if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
  447.       i = decl->nr_constant_ranges++;
  448.       decl->constant_range[i].first = index;
  449.       decl->constant_range[i].last = index;
  450.       goto out;
  451.    }
  452.  
  453.    /* Collapse all ranges down to one:
  454.     */
  455.    i = 0;
  456.    decl->constant_range[0].first = minconst;
  457.    decl->constant_range[0].last = maxconst;
  458.    decl->nr_constant_ranges = 1;
  459.  
  460. out:
  461.    assert(i < decl->nr_constant_ranges);
  462.    assert(decl->constant_range[i].first <= index);
  463.    assert(decl->constant_range[i].last >= index);
  464.    return ureg_src_register(TGSI_FILE_CONSTANT, index);
  465. }
  466.  
  467. static struct ureg_dst alloc_temporary( struct ureg_program *ureg,
  468.                                         boolean local )
  469. {
  470.    unsigned i;
  471.  
  472.    /* Look for a released temporary.
  473.     */
  474.    for (i = util_bitmask_get_first_index(ureg->free_temps);
  475.         i != UTIL_BITMASK_INVALID_INDEX;
  476.         i = util_bitmask_get_next_index(ureg->free_temps, i + 1)) {
  477.       if (util_bitmask_get(ureg->local_temps, i) == local)
  478.          break;
  479.    }
  480.  
  481.    /* Or allocate a new one.
  482.     */
  483.    if (i == UTIL_BITMASK_INVALID_INDEX) {
  484.       i = ureg->nr_temps++;
  485.  
  486.       if (local)
  487.          util_bitmask_set(ureg->local_temps, i);
  488.  
  489.       /* Start a new declaration when the local flag changes */
  490.       if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local)
  491.          util_bitmask_set(ureg->decl_temps, i);
  492.    }
  493.  
  494.    util_bitmask_clear(ureg->free_temps, i);
  495.  
  496.    return ureg_dst_register( TGSI_FILE_TEMPORARY, i );
  497. }
  498.  
  499. struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg )
  500. {
  501.    return alloc_temporary(ureg, FALSE);
  502. }
  503.  
  504. struct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg )
  505. {
  506.    return alloc_temporary(ureg, TRUE);
  507. }
  508.  
  509. struct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg,
  510.                                            unsigned size,
  511.                                            boolean local )
  512. {
  513.    unsigned i = ureg->nr_temps;
  514.    struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i );
  515.  
  516.    if (local)
  517.       util_bitmask_set(ureg->local_temps, i);
  518.  
  519.    /* Always start a new declaration at the start */
  520.    util_bitmask_set(ureg->decl_temps, i);
  521.  
  522.    ureg->nr_temps += size;
  523.  
  524.    /* and also at the end of the array */
  525.    util_bitmask_set(ureg->decl_temps, ureg->nr_temps);
  526.  
  527.    if (ureg->nr_array_temps < UREG_MAX_ARRAY_TEMPS) {
  528.       ureg->array_temps[ureg->nr_array_temps++] = i;
  529.       dst.ArrayID = ureg->nr_array_temps;
  530.    }
  531.  
  532.    return dst;
  533. }
  534.  
  535. void ureg_release_temporary( struct ureg_program *ureg,
  536.                              struct ureg_dst tmp )
  537. {
  538.    if(tmp.File == TGSI_FILE_TEMPORARY)
  539.       util_bitmask_set(ureg->free_temps, tmp.Index);
  540. }
  541.  
  542.  
  543. /* Allocate a new address register.
  544.  */
  545. struct ureg_dst ureg_DECL_address( struct ureg_program *ureg )
  546. {
  547.    if (ureg->nr_addrs < UREG_MAX_ADDR)
  548.       return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ );
  549.  
  550.    assert( 0 );
  551.    return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
  552. }
  553.  
  554. /* Allocate a new predicate register.
  555.  */
  556. struct ureg_dst
  557. ureg_DECL_predicate(struct ureg_program *ureg)
  558. {
  559.    if (ureg->nr_preds < UREG_MAX_PRED) {
  560.       return ureg_dst_register(TGSI_FILE_PREDICATE, ureg->nr_preds++);
  561.    }
  562.  
  563.    assert(0);
  564.    return ureg_dst_register(TGSI_FILE_PREDICATE, 0);
  565. }
  566.  
  567. /* Allocate a new sampler.
  568.  */
  569. struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
  570.                                    unsigned nr )
  571. {
  572.    unsigned i;
  573.  
  574.    for (i = 0; i < ureg->nr_samplers; i++)
  575.       if (ureg->sampler[i].Index == nr)
  576.          return ureg->sampler[i];
  577.    
  578.    if (i < PIPE_MAX_SAMPLERS) {
  579.       ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );
  580.       ureg->nr_samplers++;
  581.       return ureg->sampler[i];
  582.    }
  583.  
  584.    assert( 0 );
  585.    return ureg->sampler[0];
  586. }
  587.  
  588. /*
  589.  * Allocate a new shader sampler view.
  590.  */
  591. struct ureg_src
  592. ureg_DECL_sampler_view(struct ureg_program *ureg,
  593.                        unsigned index,
  594.                        unsigned target,
  595.                        unsigned return_type_x,
  596.                        unsigned return_type_y,
  597.                        unsigned return_type_z,
  598.                        unsigned return_type_w)
  599. {
  600.    struct ureg_src reg = ureg_src_register(TGSI_FILE_SAMPLER_VIEW, index);
  601.    uint i;
  602.  
  603.    for (i = 0; i < ureg->nr_sampler_views; i++) {
  604.       if (ureg->sampler_view[i].index == index) {
  605.          return reg;
  606.       }
  607.    }
  608.  
  609.    if (i < PIPE_MAX_SHADER_SAMPLER_VIEWS) {
  610.       ureg->sampler_view[i].index = index;
  611.       ureg->sampler_view[i].target = target;
  612.       ureg->sampler_view[i].return_type_x = return_type_x;
  613.       ureg->sampler_view[i].return_type_y = return_type_y;
  614.       ureg->sampler_view[i].return_type_z = return_type_z;
  615.       ureg->sampler_view[i].return_type_w = return_type_w;
  616.       ureg->nr_sampler_views++;
  617.       return reg;
  618.    }
  619.  
  620.    assert(0);
  621.    return reg;
  622. }
  623.  
  624. static int
  625. match_or_expand_immediate64( const unsigned *v,
  626.                              int type,
  627.                              unsigned nr,
  628.                              unsigned *v2,
  629.                              unsigned *pnr2,
  630.                              unsigned *swizzle )
  631. {
  632.    unsigned nr2 = *pnr2;
  633.    unsigned i, j;
  634.    *swizzle = 0;
  635.  
  636.    for (i = 0; i < nr; i += 2) {
  637.       boolean found = FALSE;
  638.  
  639.       for (j = 0; j < nr2 && !found; j += 2) {
  640.          if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) {
  641.             *swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2));
  642.             found = TRUE;
  643.          }
  644.       }
  645.       if (!found) {
  646.          if ((nr2) >= 4) {
  647.             return FALSE;
  648.          }
  649.  
  650.          v2[nr2] = v[i];
  651.          v2[nr2 + 1] = v[i + 1];
  652.  
  653.          *swizzle |= (nr2 << (i * 2)) | ((nr2 + 1) << ((i + 1) * 2));
  654.          nr2 += 2;
  655.       }
  656.    }
  657.  
  658.    /* Actually expand immediate only when fully succeeded.
  659.     */
  660.    *pnr2 = nr2;
  661.    return TRUE;
  662. }
  663.  
  664. static int
  665. match_or_expand_immediate( const unsigned *v,
  666.                            int type,
  667.                            unsigned nr,
  668.                            unsigned *v2,
  669.                            unsigned *pnr2,
  670.                            unsigned *swizzle )
  671. {
  672.    unsigned nr2 = *pnr2;
  673.    unsigned i, j;
  674.  
  675.    if (type == TGSI_IMM_FLOAT64)
  676.       return match_or_expand_immediate64(v, type, nr, v2, pnr2, swizzle);
  677.  
  678.    *swizzle = 0;
  679.  
  680.    for (i = 0; i < nr; i++) {
  681.       boolean found = FALSE;
  682.  
  683.       for (j = 0; j < nr2 && !found; j++) {
  684.          if (v[i] == v2[j]) {
  685.             *swizzle |= j << (i * 2);
  686.             found = TRUE;
  687.          }
  688.       }
  689.  
  690.       if (!found) {
  691.          if (nr2 >= 4) {
  692.             return FALSE;
  693.          }
  694.  
  695.          v2[nr2] = v[i];
  696.          *swizzle |= nr2 << (i * 2);
  697.          nr2++;
  698.       }
  699.    }
  700.  
  701.    /* Actually expand immediate only when fully succeeded.
  702.     */
  703.    *pnr2 = nr2;
  704.    return TRUE;
  705. }
  706.  
  707.  
  708. static struct ureg_src
  709. decl_immediate( struct ureg_program *ureg,
  710.                 const unsigned *v,
  711.                 unsigned nr,
  712.                 unsigned type )
  713. {
  714.    unsigned i, j;
  715.    unsigned swizzle = 0;
  716.  
  717.    /* Could do a first pass where we examine all existing immediates
  718.     * without expanding.
  719.     */
  720.  
  721.    for (i = 0; i < ureg->nr_immediates; i++) {
  722.       if (ureg->immediate[i].type != type) {
  723.          continue;
  724.       }
  725.       if (match_or_expand_immediate(v,
  726.                                     type,
  727.                                     nr,
  728.                                     ureg->immediate[i].value.u,
  729.                                     &ureg->immediate[i].nr,
  730.                                     &swizzle)) {
  731.          goto out;
  732.       }
  733.    }
  734.  
  735.    if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {
  736.       i = ureg->nr_immediates++;
  737.       ureg->immediate[i].type = type;
  738.       if (match_or_expand_immediate(v,
  739.                                     type,
  740.                                     nr,
  741.                                     ureg->immediate[i].value.u,
  742.                                     &ureg->immediate[i].nr,
  743.                                     &swizzle)) {
  744.          goto out;
  745.       }
  746.    }
  747.  
  748.    set_bad(ureg);
  749.  
  750. out:
  751.    /* Make sure that all referenced elements are from this immediate.
  752.     * Has the effect of making size-one immediates into scalars.
  753.     */
  754.    if (type == TGSI_IMM_FLOAT64) {
  755.       for (j = nr; j < 4; j+=2) {
  756.          swizzle |= (swizzle & 0xf) << (j * 2);
  757.       }
  758.    } else {
  759.       for (j = nr; j < 4; j++) {
  760.          swizzle |= (swizzle & 0x3) << (j * 2);
  761.       }
  762.    }
  763.    return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),
  764.                        (swizzle >> 0) & 0x3,
  765.                        (swizzle >> 2) & 0x3,
  766.                        (swizzle >> 4) & 0x3,
  767.                        (swizzle >> 6) & 0x3);
  768. }
  769.  
  770.  
  771. struct ureg_src
  772. ureg_DECL_immediate( struct ureg_program *ureg,
  773.                      const float *v,
  774.                      unsigned nr )
  775. {
  776.    union {
  777.       float f[4];
  778.       unsigned u[4];
  779.    } fu;
  780.    unsigned int i;
  781.  
  782.    for (i = 0; i < nr; i++) {
  783.       fu.f[i] = v[i];
  784.    }
  785.  
  786.    return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);
  787. }
  788.  
  789. struct ureg_src
  790. ureg_DECL_immediate_f64( struct ureg_program *ureg,
  791.                          const double *v,
  792.                          unsigned nr )
  793. {
  794.    union {
  795.       unsigned u[4];
  796.       double d[2];
  797.    } fu;
  798.    unsigned int i;
  799.  
  800.    assert((nr / 2) < 3);
  801.    for (i = 0; i < nr / 2; i++) {
  802.       fu.d[i] = v[i];
  803.    }
  804.  
  805.    return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT64);
  806. }
  807.  
  808. struct ureg_src
  809. ureg_DECL_immediate_uint( struct ureg_program *ureg,
  810.                           const unsigned *v,
  811.                           unsigned nr )
  812. {
  813.    return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32);
  814. }
  815.  
  816.  
  817. struct ureg_src
  818. ureg_DECL_immediate_block_uint( struct ureg_program *ureg,
  819.                                 const unsigned *v,
  820.                                 unsigned nr )
  821. {
  822.    uint index;
  823.    uint i;
  824.  
  825.    if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) {
  826.       set_bad(ureg);
  827.       return ureg_src_register(TGSI_FILE_IMMEDIATE, 0);
  828.    }
  829.  
  830.    index = ureg->nr_immediates;
  831.    ureg->nr_immediates += (nr + 3) / 4;
  832.  
  833.    for (i = index; i < ureg->nr_immediates; i++) {
  834.       ureg->immediate[i].type = TGSI_IMM_UINT32;
  835.       ureg->immediate[i].nr = nr > 4 ? 4 : nr;
  836.       memcpy(ureg->immediate[i].value.u,
  837.              &v[(i - index) * 4],
  838.              ureg->immediate[i].nr * sizeof(uint));
  839.       nr -= 4;
  840.    }
  841.  
  842.    return ureg_src_register(TGSI_FILE_IMMEDIATE, index);
  843. }
  844.  
  845.  
  846. struct ureg_src
  847. ureg_DECL_immediate_int( struct ureg_program *ureg,
  848.                          const int *v,
  849.                          unsigned nr )
  850. {
  851.    return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32);
  852. }
  853.  
  854.  
  855. void
  856. ureg_emit_src( struct ureg_program *ureg,
  857.                struct ureg_src src )
  858. {
  859.    unsigned size = 1 + (src.Indirect ? 1 : 0) +
  860.                    (src.Dimension ? (src.DimIndirect ? 2 : 1) : 0);
  861.  
  862.    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
  863.    unsigned n = 0;
  864.  
  865.    assert(src.File != TGSI_FILE_NULL);
  866.    assert(src.File < TGSI_FILE_COUNT);
  867.    
  868.    out[n].value = 0;
  869.    out[n].src.File = src.File;
  870.    out[n].src.SwizzleX = src.SwizzleX;
  871.    out[n].src.SwizzleY = src.SwizzleY;
  872.    out[n].src.SwizzleZ = src.SwizzleZ;
  873.    out[n].src.SwizzleW = src.SwizzleW;
  874.    out[n].src.Index = src.Index;
  875.    out[n].src.Negate = src.Negate;
  876.    out[0].src.Absolute = src.Absolute;
  877.    n++;
  878.  
  879.    if (src.Indirect) {
  880.       out[0].src.Indirect = 1;
  881.       out[n].value = 0;
  882.       out[n].ind.File = src.IndirectFile;
  883.       out[n].ind.Swizzle = src.IndirectSwizzle;
  884.       out[n].ind.Index = src.IndirectIndex;
  885.       out[n].ind.ArrayID = src.ArrayID;
  886.       n++;
  887.    }
  888.  
  889.    if (src.Dimension) {
  890.       out[0].src.Dimension = 1;
  891.       out[n].dim.Dimension = 0;
  892.       out[n].dim.Padding = 0;
  893.       if (src.DimIndirect) {
  894.          out[n].dim.Indirect = 1;
  895.          out[n].dim.Index = src.DimensionIndex;
  896.          n++;
  897.          out[n].value = 0;
  898.          out[n].ind.File = src.DimIndFile;
  899.          out[n].ind.Swizzle = src.DimIndSwizzle;
  900.          out[n].ind.Index = src.DimIndIndex;
  901.          out[n].ind.ArrayID = src.ArrayID;
  902.       } else {
  903.          out[n].dim.Indirect = 0;
  904.          out[n].dim.Index = src.DimensionIndex;
  905.       }
  906.       n++;
  907.    }
  908.  
  909.    assert(n == size);
  910. }
  911.  
  912.  
  913. void
  914. ureg_emit_dst( struct ureg_program *ureg,
  915.                struct ureg_dst dst )
  916. {
  917.    unsigned size = 1 + (dst.Indirect ? 1 : 0) +
  918.                    (dst.Dimension ? (dst.DimIndirect ? 2 : 1) : 0);
  919.  
  920.    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
  921.    unsigned n = 0;
  922.  
  923.    assert(dst.File != TGSI_FILE_NULL);
  924.    assert(dst.File != TGSI_FILE_CONSTANT);
  925.    assert(dst.File != TGSI_FILE_INPUT);
  926.    assert(dst.File != TGSI_FILE_SAMPLER);
  927.    assert(dst.File != TGSI_FILE_SAMPLER_VIEW);
  928.    assert(dst.File != TGSI_FILE_IMMEDIATE);
  929.    assert(dst.File < TGSI_FILE_COUNT);
  930.  
  931.    out[n].value = 0;
  932.    out[n].dst.File = dst.File;
  933.    out[n].dst.WriteMask = dst.WriteMask;
  934.    out[n].dst.Indirect = dst.Indirect;
  935.    out[n].dst.Index = dst.Index;
  936.    n++;
  937.    
  938.    if (dst.Indirect) {
  939.       out[n].value = 0;
  940.       out[n].ind.File = dst.IndirectFile;
  941.       out[n].ind.Swizzle = dst.IndirectSwizzle;
  942.       out[n].ind.Index = dst.IndirectIndex;
  943.       out[n].ind.ArrayID = dst.ArrayID;
  944.       n++;
  945.    }
  946.  
  947.    if (dst.Dimension) {
  948.       out[0].dst.Dimension = 1;
  949.       out[n].dim.Dimension = 0;
  950.       out[n].dim.Padding = 0;
  951.       if (dst.DimIndirect) {
  952.          out[n].dim.Indirect = 1;
  953.          out[n].dim.Index = dst.DimensionIndex;
  954.          n++;
  955.          out[n].value = 0;
  956.          out[n].ind.File = dst.DimIndFile;
  957.          out[n].ind.Swizzle = dst.DimIndSwizzle;
  958.          out[n].ind.Index = dst.DimIndIndex;
  959.          out[n].ind.ArrayID = dst.ArrayID;
  960.       } else {
  961.          out[n].dim.Indirect = 0;
  962.          out[n].dim.Index = dst.DimensionIndex;
  963.       }
  964.       n++;
  965.    }
  966.  
  967.    assert(n == size);
  968. }
  969.  
  970.  
  971. static void validate( unsigned opcode,
  972.                       unsigned nr_dst,
  973.                       unsigned nr_src )
  974. {
  975. #ifdef DEBUG
  976.    const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
  977.    assert(info);
  978.    if(info) {
  979.       assert(nr_dst == info->num_dst);
  980.       assert(nr_src == info->num_src);
  981.    }
  982. #endif
  983. }
  984.  
  985. struct ureg_emit_insn_result
  986. ureg_emit_insn(struct ureg_program *ureg,
  987.                unsigned opcode,
  988.                boolean saturate,
  989.                boolean predicate,
  990.                boolean pred_negate,
  991.                unsigned pred_swizzle_x,
  992.                unsigned pred_swizzle_y,
  993.                unsigned pred_swizzle_z,
  994.                unsigned pred_swizzle_w,
  995.                unsigned num_dst,
  996.                unsigned num_src )
  997. {
  998.    union tgsi_any_token *out;
  999.    uint count = predicate ? 2 : 1;
  1000.    struct ureg_emit_insn_result result;
  1001.  
  1002.    validate( opcode, num_dst, num_src );
  1003.    
  1004.    out = get_tokens( ureg, DOMAIN_INSN, count );
  1005.    out[0].insn = tgsi_default_instruction();
  1006.    out[0].insn.Opcode = opcode;
  1007.    out[0].insn.Saturate = saturate;
  1008.    out[0].insn.NumDstRegs = num_dst;
  1009.    out[0].insn.NumSrcRegs = num_src;
  1010.  
  1011.    result.insn_token = ureg->domain[DOMAIN_INSN].count - count;
  1012.    result.extended_token = result.insn_token;
  1013.  
  1014.    if (predicate) {
  1015.       out[0].insn.Predicate = 1;
  1016.       out[1].insn_predicate = tgsi_default_instruction_predicate();
  1017.       out[1].insn_predicate.Negate = pred_negate;
  1018.       out[1].insn_predicate.SwizzleX = pred_swizzle_x;
  1019.       out[1].insn_predicate.SwizzleY = pred_swizzle_y;
  1020.       out[1].insn_predicate.SwizzleZ = pred_swizzle_z;
  1021.       out[1].insn_predicate.SwizzleW = pred_swizzle_w;
  1022.    }
  1023.  
  1024.    ureg->nr_instructions++;
  1025.  
  1026.    return result;
  1027. }
  1028.  
  1029.  
  1030. void
  1031. ureg_emit_label(struct ureg_program *ureg,
  1032.                 unsigned extended_token,
  1033.                 unsigned *label_token )
  1034. {
  1035.    union tgsi_any_token *out, *insn;
  1036.  
  1037.    if(!label_token)
  1038.       return;
  1039.  
  1040.    out = get_tokens( ureg, DOMAIN_INSN, 1 );
  1041.    out[0].value = 0;
  1042.  
  1043.    insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
  1044.    insn->insn.Label = 1;
  1045.  
  1046.    *label_token = ureg->domain[DOMAIN_INSN].count - 1;
  1047. }
  1048.  
  1049. /* Will return a number which can be used in a label to point to the
  1050.  * next instruction to be emitted.
  1051.  */
  1052. unsigned
  1053. ureg_get_instruction_number( struct ureg_program *ureg )
  1054. {
  1055.    return ureg->nr_instructions;
  1056. }
  1057.  
  1058. /* Patch a given label (expressed as a token number) to point to a
  1059.  * given instruction (expressed as an instruction number).
  1060.  */
  1061. void
  1062. ureg_fixup_label(struct ureg_program *ureg,
  1063.                  unsigned label_token,
  1064.                  unsigned instruction_number )
  1065. {
  1066.    union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token );
  1067.  
  1068.    out->insn_label.Label = instruction_number;
  1069. }
  1070.  
  1071.  
  1072. void
  1073. ureg_emit_texture(struct ureg_program *ureg,
  1074.                   unsigned extended_token,
  1075.                   unsigned target, unsigned num_offsets)
  1076. {
  1077.    union tgsi_any_token *out, *insn;
  1078.  
  1079.    out = get_tokens( ureg, DOMAIN_INSN, 1 );
  1080.    insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
  1081.  
  1082.    insn->insn.Texture = 1;
  1083.  
  1084.    out[0].value = 0;
  1085.    out[0].insn_texture.Texture = target;
  1086.    out[0].insn_texture.NumOffsets = num_offsets;
  1087. }
  1088.  
  1089. void
  1090. ureg_emit_texture_offset(struct ureg_program *ureg,
  1091.                          const struct tgsi_texture_offset *offset)
  1092. {
  1093.    union tgsi_any_token *out;
  1094.  
  1095.    out = get_tokens( ureg, DOMAIN_INSN, 1);
  1096.  
  1097.    out[0].value = 0;
  1098.    out[0].insn_texture_offset = *offset;
  1099.    
  1100. }
  1101.  
  1102.  
  1103. void
  1104. ureg_fixup_insn_size(struct ureg_program *ureg,
  1105.                      unsigned insn )
  1106. {
  1107.    union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );
  1108.  
  1109.    assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
  1110.    out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
  1111. }
  1112.  
  1113.  
  1114. void
  1115. ureg_insn(struct ureg_program *ureg,
  1116.           unsigned opcode,
  1117.           const struct ureg_dst *dst,
  1118.           unsigned nr_dst,
  1119.           const struct ureg_src *src,
  1120.           unsigned nr_src )
  1121. {
  1122.    struct ureg_emit_insn_result insn;
  1123.    unsigned i;
  1124.    boolean saturate;
  1125.    boolean predicate;
  1126.    boolean negate = FALSE;
  1127.    unsigned swizzle[4] = { 0 };
  1128.  
  1129.    if (nr_dst && ureg_dst_is_empty(dst[0])) {
  1130.       return;
  1131.    }
  1132.  
  1133.    saturate = nr_dst ? dst[0].Saturate : FALSE;
  1134.    predicate = nr_dst ? dst[0].Predicate : FALSE;
  1135.    if (predicate) {
  1136.       negate = dst[0].PredNegate;
  1137.       swizzle[0] = dst[0].PredSwizzleX;
  1138.       swizzle[1] = dst[0].PredSwizzleY;
  1139.       swizzle[2] = dst[0].PredSwizzleZ;
  1140.       swizzle[3] = dst[0].PredSwizzleW;
  1141.    }
  1142.  
  1143.    insn = ureg_emit_insn(ureg,
  1144.                          opcode,
  1145.                          saturate,
  1146.                          predicate,
  1147.                          negate,
  1148.                          swizzle[0],
  1149.                          swizzle[1],
  1150.                          swizzle[2],
  1151.                          swizzle[3],
  1152.                          nr_dst,
  1153.                          nr_src);
  1154.  
  1155.    for (i = 0; i < nr_dst; i++)
  1156.       ureg_emit_dst( ureg, dst[i] );
  1157.  
  1158.    for (i = 0; i < nr_src; i++)
  1159.       ureg_emit_src( ureg, src[i] );
  1160.  
  1161.    ureg_fixup_insn_size( ureg, insn.insn_token );
  1162. }
  1163.  
  1164. void
  1165. ureg_tex_insn(struct ureg_program *ureg,
  1166.               unsigned opcode,
  1167.               const struct ureg_dst *dst,
  1168.               unsigned nr_dst,
  1169.               unsigned target,
  1170.               const struct tgsi_texture_offset *texoffsets,
  1171.               unsigned nr_offset,
  1172.               const struct ureg_src *src,
  1173.               unsigned nr_src )
  1174. {
  1175.    struct ureg_emit_insn_result insn;
  1176.    unsigned i;
  1177.    boolean saturate;
  1178.    boolean predicate;
  1179.    boolean negate = FALSE;
  1180.    unsigned swizzle[4] = { 0 };
  1181.  
  1182.    if (nr_dst && ureg_dst_is_empty(dst[0])) {
  1183.       return;
  1184.    }
  1185.  
  1186.    saturate = nr_dst ? dst[0].Saturate : FALSE;
  1187.    predicate = nr_dst ? dst[0].Predicate : FALSE;
  1188.    if (predicate) {
  1189.       negate = dst[0].PredNegate;
  1190.       swizzle[0] = dst[0].PredSwizzleX;
  1191.       swizzle[1] = dst[0].PredSwizzleY;
  1192.       swizzle[2] = dst[0].PredSwizzleZ;
  1193.       swizzle[3] = dst[0].PredSwizzleW;
  1194.    }
  1195.  
  1196.    insn = ureg_emit_insn(ureg,
  1197.                          opcode,
  1198.                          saturate,
  1199.                          predicate,
  1200.                          negate,
  1201.                          swizzle[0],
  1202.                          swizzle[1],
  1203.                          swizzle[2],
  1204.                          swizzle[3],
  1205.                          nr_dst,
  1206.                          nr_src);
  1207.  
  1208.    ureg_emit_texture( ureg, insn.extended_token, target, nr_offset );
  1209.  
  1210.    for (i = 0; i < nr_offset; i++)
  1211.       ureg_emit_texture_offset( ureg, &texoffsets[i]);
  1212.  
  1213.    for (i = 0; i < nr_dst; i++)
  1214.       ureg_emit_dst( ureg, dst[i] );
  1215.  
  1216.    for (i = 0; i < nr_src; i++)
  1217.       ureg_emit_src( ureg, src[i] );
  1218.  
  1219.    ureg_fixup_insn_size( ureg, insn.insn_token );
  1220. }
  1221.  
  1222.  
  1223. void
  1224. ureg_label_insn(struct ureg_program *ureg,
  1225.                 unsigned opcode,
  1226.                 const struct ureg_src *src,
  1227.                 unsigned nr_src,
  1228.                 unsigned *label_token )
  1229. {
  1230.    struct ureg_emit_insn_result insn;
  1231.    unsigned i;
  1232.  
  1233.    insn = ureg_emit_insn(ureg,
  1234.                          opcode,
  1235.                          FALSE,
  1236.                          FALSE,
  1237.                          FALSE,
  1238.                          TGSI_SWIZZLE_X,
  1239.                          TGSI_SWIZZLE_Y,
  1240.                          TGSI_SWIZZLE_Z,
  1241.                          TGSI_SWIZZLE_W,
  1242.                          0,
  1243.                          nr_src);
  1244.  
  1245.    ureg_emit_label( ureg, insn.extended_token, label_token );
  1246.  
  1247.    for (i = 0; i < nr_src; i++)
  1248.       ureg_emit_src( ureg, src[i] );
  1249.  
  1250.    ureg_fixup_insn_size( ureg, insn.insn_token );
  1251. }
  1252.  
  1253.  
  1254. static void
  1255. emit_decl_semantic(struct ureg_program *ureg,
  1256.                    unsigned file,
  1257.                    unsigned index,
  1258.                    unsigned semantic_name,
  1259.                    unsigned semantic_index,
  1260.                    unsigned usage_mask)
  1261. {
  1262.    union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
  1263.  
  1264.    out[0].value = 0;
  1265.    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
  1266.    out[0].decl.NrTokens = 3;
  1267.    out[0].decl.File = file;
  1268.    out[0].decl.UsageMask = usage_mask;
  1269.    out[0].decl.Semantic = 1;
  1270.  
  1271.    out[1].value = 0;
  1272.    out[1].decl_range.First = index;
  1273.    out[1].decl_range.Last = index;
  1274.  
  1275.    out[2].value = 0;
  1276.    out[2].decl_semantic.Name = semantic_name;
  1277.    out[2].decl_semantic.Index = semantic_index;
  1278. }
  1279.  
  1280.  
  1281. static void
  1282. emit_decl_fs(struct ureg_program *ureg,
  1283.              unsigned file,
  1284.              unsigned index,
  1285.              unsigned semantic_name,
  1286.              unsigned semantic_index,
  1287.              unsigned interpolate,
  1288.              unsigned cylindrical_wrap,
  1289.              unsigned interpolate_location)
  1290. {
  1291.    union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 4);
  1292.  
  1293.    out[0].value = 0;
  1294.    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
  1295.    out[0].decl.NrTokens = 4;
  1296.    out[0].decl.File = file;
  1297.    out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */
  1298.    out[0].decl.Interpolate = 1;
  1299.    out[0].decl.Semantic = 1;
  1300.  
  1301.    out[1].value = 0;
  1302.    out[1].decl_range.First = index;
  1303.    out[1].decl_range.Last = index;
  1304.  
  1305.    out[2].value = 0;
  1306.    out[2].decl_interp.Interpolate = interpolate;
  1307.    out[2].decl_interp.CylindricalWrap = cylindrical_wrap;
  1308.    out[2].decl_interp.Location = interpolate_location;
  1309.  
  1310.    out[3].value = 0;
  1311.    out[3].decl_semantic.Name = semantic_name;
  1312.    out[3].decl_semantic.Index = semantic_index;
  1313. }
  1314.  
  1315. static void
  1316. emit_decl_temps( struct ureg_program *ureg,
  1317.                  unsigned first, unsigned last,
  1318.                  boolean local,
  1319.                  unsigned arrayid )
  1320. {
  1321.    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL,
  1322.                                            arrayid ? 3 : 2 );
  1323.  
  1324.    out[0].value = 0;
  1325.    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
  1326.    out[0].decl.NrTokens = 2;
  1327.    out[0].decl.File = TGSI_FILE_TEMPORARY;
  1328.    out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
  1329.    out[0].decl.Local = local;
  1330.  
  1331.    out[1].value = 0;
  1332.    out[1].decl_range.First = first;
  1333.    out[1].decl_range.Last = last;
  1334.  
  1335.    if (arrayid) {
  1336.       out[0].decl.Array = 1;
  1337.       out[2].value = 0;
  1338.       out[2].array.ArrayID = arrayid;
  1339.    }
  1340. }
  1341.  
  1342. static void emit_decl_range( struct ureg_program *ureg,
  1343.                              unsigned file,
  1344.                              unsigned first,
  1345.                              unsigned count )
  1346. {
  1347.    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
  1348.  
  1349.    out[0].value = 0;
  1350.    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
  1351.    out[0].decl.NrTokens = 2;
  1352.    out[0].decl.File = file;
  1353.    out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
  1354.    out[0].decl.Semantic = 0;
  1355.  
  1356.    out[1].value = 0;
  1357.    out[1].decl_range.First = first;
  1358.    out[1].decl_range.Last = first + count - 1;
  1359. }
  1360.  
  1361. static void
  1362. emit_decl_range2D(struct ureg_program *ureg,
  1363.                   unsigned file,
  1364.                   unsigned first,
  1365.                   unsigned last,
  1366.                   unsigned index2D)
  1367. {
  1368.    union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
  1369.  
  1370.    out[0].value = 0;
  1371.    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
  1372.    out[0].decl.NrTokens = 3;
  1373.    out[0].decl.File = file;
  1374.    out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
  1375.    out[0].decl.Dimension = 1;
  1376.  
  1377.    out[1].value = 0;
  1378.    out[1].decl_range.First = first;
  1379.    out[1].decl_range.Last = last;
  1380.  
  1381.    out[2].value = 0;
  1382.    out[2].decl_dim.Index2D = index2D;
  1383. }
  1384.  
  1385. static void
  1386. emit_decl_sampler_view(struct ureg_program *ureg,
  1387.                        unsigned index,
  1388.                        unsigned target,
  1389.                        unsigned return_type_x,
  1390.                        unsigned return_type_y,
  1391.                        unsigned return_type_z,
  1392.                        unsigned return_type_w )
  1393. {
  1394.    union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
  1395.  
  1396.    out[0].value = 0;
  1397.    out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
  1398.    out[0].decl.NrTokens = 3;
  1399.    out[0].decl.File = TGSI_FILE_SAMPLER_VIEW;
  1400.    out[0].decl.UsageMask = 0xf;
  1401.  
  1402.    out[1].value = 0;
  1403.    out[1].decl_range.First = index;
  1404.    out[1].decl_range.Last = index;
  1405.  
  1406.    out[2].value = 0;
  1407.    out[2].decl_sampler_view.Resource    = target;
  1408.    out[2].decl_sampler_view.ReturnTypeX = return_type_x;
  1409.    out[2].decl_sampler_view.ReturnTypeY = return_type_y;
  1410.    out[2].decl_sampler_view.ReturnTypeZ = return_type_z;
  1411.    out[2].decl_sampler_view.ReturnTypeW = return_type_w;
  1412. }
  1413.  
  1414. static void
  1415. emit_immediate( struct ureg_program *ureg,
  1416.                 const unsigned *v,
  1417.                 unsigned type )
  1418. {
  1419.    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
  1420.  
  1421.    out[0].value = 0;
  1422.    out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
  1423.    out[0].imm.NrTokens = 5;
  1424.    out[0].imm.DataType = type;
  1425.    out[0].imm.Padding = 0;
  1426.  
  1427.    out[1].imm_data.Uint = v[0];
  1428.    out[2].imm_data.Uint = v[1];
  1429.    out[3].imm_data.Uint = v[2];
  1430.    out[4].imm_data.Uint = v[3];
  1431. }
  1432.  
  1433. static void
  1434. emit_property(struct ureg_program *ureg,
  1435.               unsigned name,
  1436.               unsigned data)
  1437. {
  1438.    union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
  1439.  
  1440.    out[0].value = 0;
  1441.    out[0].prop.Type = TGSI_TOKEN_TYPE_PROPERTY;
  1442.    out[0].prop.NrTokens = 2;
  1443.    out[0].prop.PropertyName = name;
  1444.  
  1445.    out[1].prop_data.Data = data;
  1446. }
  1447.  
  1448.  
  1449. static void emit_decls( struct ureg_program *ureg )
  1450. {
  1451.    unsigned i;
  1452.  
  1453.    for (i = 0; i < Elements(ureg->properties); i++)
  1454.       if (ureg->properties[i] != ~0)
  1455.          emit_property(ureg, i, ureg->properties[i]);
  1456.  
  1457.    if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
  1458.       for (i = 0; i < UREG_MAX_INPUT; i++) {
  1459.          if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
  1460.             emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
  1461.          }
  1462.       }
  1463.    } else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) {
  1464.       for (i = 0; i < ureg->nr_fs_inputs; i++) {
  1465.          emit_decl_fs(ureg,
  1466.                       TGSI_FILE_INPUT,
  1467.                       i,
  1468.                       ureg->fs_input[i].semantic_name,
  1469.                       ureg->fs_input[i].semantic_index,
  1470.                       ureg->fs_input[i].interp,
  1471.                       ureg->fs_input[i].cylindrical_wrap,
  1472.                       ureg->fs_input[i].interp_location);
  1473.       }
  1474.    } else {
  1475.       for (i = 0; i < ureg->nr_gs_inputs; i++) {
  1476.          emit_decl_semantic(ureg,
  1477.                             TGSI_FILE_INPUT,
  1478.                             ureg->gs_input[i].index,
  1479.                             ureg->gs_input[i].semantic_name,
  1480.                             ureg->gs_input[i].semantic_index,
  1481.                             TGSI_WRITEMASK_XYZW);
  1482.       }
  1483.    }
  1484.  
  1485.    for (i = 0; i < ureg->nr_system_values; i++) {
  1486.       emit_decl_semantic(ureg,
  1487.                          TGSI_FILE_SYSTEM_VALUE,
  1488.                          ureg->system_value[i].index,
  1489.                          ureg->system_value[i].semantic_name,
  1490.                          ureg->system_value[i].semantic_index,
  1491.                          TGSI_WRITEMASK_XYZW);
  1492.    }
  1493.  
  1494.    for (i = 0; i < ureg->nr_outputs; i++) {
  1495.       emit_decl_semantic(ureg,
  1496.                          TGSI_FILE_OUTPUT,
  1497.                          i,
  1498.                          ureg->output[i].semantic_name,
  1499.                          ureg->output[i].semantic_index,
  1500.                          ureg->output[i].usage_mask);
  1501.    }
  1502.  
  1503.    for (i = 0; i < ureg->nr_samplers; i++) {
  1504.       emit_decl_range( ureg,
  1505.                        TGSI_FILE_SAMPLER,
  1506.                        ureg->sampler[i].Index, 1 );
  1507.    }
  1508.  
  1509.    for (i = 0; i < ureg->nr_sampler_views; i++) {
  1510.       emit_decl_sampler_view(ureg,
  1511.                              ureg->sampler_view[i].index,
  1512.                              ureg->sampler_view[i].target,
  1513.                              ureg->sampler_view[i].return_type_x,
  1514.                              ureg->sampler_view[i].return_type_y,
  1515.                              ureg->sampler_view[i].return_type_z,
  1516.                              ureg->sampler_view[i].return_type_w);
  1517.    }
  1518.  
  1519.    if (ureg->const_decls.nr_constant_ranges) {
  1520.       for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) {
  1521.          emit_decl_range(ureg,
  1522.                          TGSI_FILE_CONSTANT,
  1523.                          ureg->const_decls.constant_range[i].first,
  1524.                          ureg->const_decls.constant_range[i].last - ureg->const_decls.constant_range[i].first + 1);
  1525.       }
  1526.    }
  1527.  
  1528.    for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
  1529.       struct const_decl *decl = &ureg->const_decls2D[i];
  1530.  
  1531.       if (decl->nr_constant_ranges) {
  1532.          uint j;
  1533.  
  1534.          for (j = 0; j < decl->nr_constant_ranges; j++) {
  1535.             emit_decl_range2D(ureg,
  1536.                               TGSI_FILE_CONSTANT,
  1537.                               decl->constant_range[j].first,
  1538.                               decl->constant_range[j].last,
  1539.                               i);
  1540.          }
  1541.       }
  1542.    }
  1543.  
  1544.    if (ureg->nr_temps) {
  1545.       unsigned array = 0;
  1546.       for (i = 0; i < ureg->nr_temps;) {
  1547.          boolean local = util_bitmask_get(ureg->local_temps, i);
  1548.          unsigned first = i;
  1549.          i = util_bitmask_get_next_index(ureg->decl_temps, i + 1);
  1550.          if (i == UTIL_BITMASK_INVALID_INDEX)
  1551.             i = ureg->nr_temps;
  1552.  
  1553.          if (array < ureg->nr_array_temps && ureg->array_temps[array] == first)
  1554.             emit_decl_temps( ureg, first, i - 1, local, ++array );
  1555.          else
  1556.             emit_decl_temps( ureg, first, i - 1, local, 0 );
  1557.       }
  1558.    }
  1559.  
  1560.    if (ureg->nr_addrs) {
  1561.       emit_decl_range( ureg,
  1562.                        TGSI_FILE_ADDRESS,
  1563.                        0, ureg->nr_addrs );
  1564.    }
  1565.  
  1566.    if (ureg->nr_preds) {
  1567.       emit_decl_range(ureg,
  1568.                       TGSI_FILE_PREDICATE,
  1569.                       0,
  1570.                       ureg->nr_preds);
  1571.    }
  1572.  
  1573.    for (i = 0; i < ureg->nr_immediates; i++) {
  1574.       emit_immediate( ureg,
  1575.                       ureg->immediate[i].value.u,
  1576.                       ureg->immediate[i].type );
  1577.    }
  1578. }
  1579.  
  1580. /* Append the instruction tokens onto the declarations to build a
  1581.  * contiguous stream suitable to send to the driver.
  1582.  */
  1583. static void copy_instructions( struct ureg_program *ureg )
  1584. {
  1585.    unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count;
  1586.    union tgsi_any_token *out = get_tokens( ureg,
  1587.                                            DOMAIN_DECL,
  1588.                                            nr_tokens );
  1589.  
  1590.    memcpy(out,
  1591.           ureg->domain[DOMAIN_INSN].tokens,
  1592.           nr_tokens * sizeof out[0] );
  1593. }
  1594.  
  1595.  
  1596. static void
  1597. fixup_header_size(struct ureg_program *ureg)
  1598. {
  1599.    union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 );
  1600.  
  1601.    out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2;
  1602. }
  1603.  
  1604.  
  1605. static void
  1606. emit_header( struct ureg_program *ureg )
  1607. {
  1608.    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
  1609.  
  1610.    out[0].header.HeaderSize = 2;
  1611.    out[0].header.BodySize = 0;
  1612.  
  1613.    out[1].processor.Processor = ureg->processor;
  1614.    out[1].processor.Padding = 0;
  1615. }
  1616.  
  1617.  
  1618. const struct tgsi_token *ureg_finalize( struct ureg_program *ureg )
  1619. {
  1620.    const struct tgsi_token *tokens;
  1621.  
  1622.    emit_header( ureg );
  1623.    emit_decls( ureg );
  1624.    copy_instructions( ureg );
  1625.    fixup_header_size( ureg );
  1626.    
  1627.    if (ureg->domain[0].tokens == error_tokens ||
  1628.        ureg->domain[1].tokens == error_tokens) {
  1629.       debug_printf("%s: error in generated shader\n", __FUNCTION__);
  1630.       assert(0);
  1631.       return NULL;
  1632.    }
  1633.  
  1634.    tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
  1635.  
  1636.    if (0) {
  1637.       debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__,
  1638.                    ureg->domain[DOMAIN_DECL].count);
  1639.       tgsi_dump( tokens, 0 );
  1640.    }
  1641.  
  1642. #if DEBUG
  1643.    if (tokens && !tgsi_sanity_check(tokens)) {
  1644.       debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n");
  1645.       tgsi_dump(tokens, 0);
  1646.       assert(0);
  1647.    }
  1648. #endif
  1649.  
  1650.    
  1651.    return tokens;
  1652. }
  1653.  
  1654.  
  1655. void *ureg_create_shader( struct ureg_program *ureg,
  1656.                           struct pipe_context *pipe,
  1657.                           const struct pipe_stream_output_info *so )
  1658. {
  1659.    struct pipe_shader_state state;
  1660.  
  1661.    state.tokens = ureg_finalize(ureg);
  1662.    if(!state.tokens)
  1663.       return NULL;
  1664.  
  1665.    if (so)
  1666.       state.stream_output = *so;
  1667.    else
  1668.       memset(&state.stream_output, 0, sizeof(state.stream_output));
  1669.  
  1670.    if (ureg->processor == TGSI_PROCESSOR_VERTEX)
  1671.       return pipe->create_vs_state( pipe, &state );
  1672.    else
  1673.       return pipe->create_fs_state( pipe, &state );
  1674. }
  1675.  
  1676.  
  1677. const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg,
  1678.                                           unsigned *nr_tokens )
  1679. {
  1680.    const struct tgsi_token *tokens;
  1681.  
  1682.    ureg_finalize(ureg);
  1683.  
  1684.    tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
  1685.  
  1686.    if (nr_tokens)
  1687.       *nr_tokens = ureg->domain[DOMAIN_DECL].size;
  1688.  
  1689.    ureg->domain[DOMAIN_DECL].tokens = 0;
  1690.    ureg->domain[DOMAIN_DECL].size = 0;
  1691.    ureg->domain[DOMAIN_DECL].order = 0;
  1692.    ureg->domain[DOMAIN_DECL].count = 0;
  1693.  
  1694.    return tokens;
  1695. }
  1696.  
  1697.  
  1698. void ureg_free_tokens( const struct tgsi_token *tokens )
  1699. {
  1700.    FREE((struct tgsi_token *)tokens);
  1701. }
  1702.  
  1703.  
  1704. struct ureg_program *ureg_create( unsigned processor )
  1705. {
  1706.    int i;
  1707.    struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
  1708.    if (ureg == NULL)
  1709.       goto no_ureg;
  1710.  
  1711.    ureg->processor = processor;
  1712.  
  1713.    for (i = 0; i < Elements(ureg->properties); i++)
  1714.       ureg->properties[i] = ~0;
  1715.  
  1716.    ureg->free_temps = util_bitmask_create();
  1717.    if (ureg->free_temps == NULL)
  1718.       goto no_free_temps;
  1719.  
  1720.    ureg->local_temps = util_bitmask_create();
  1721.    if (ureg->local_temps == NULL)
  1722.       goto no_local_temps;
  1723.  
  1724.    ureg->decl_temps = util_bitmask_create();
  1725.    if (ureg->decl_temps == NULL)
  1726.       goto no_decl_temps;
  1727.  
  1728.    return ureg;
  1729.  
  1730. no_decl_temps:
  1731.    util_bitmask_destroy(ureg->local_temps);
  1732. no_local_temps:
  1733.    util_bitmask_destroy(ureg->free_temps);
  1734. no_free_temps:
  1735.    FREE(ureg);
  1736. no_ureg:
  1737.    return NULL;
  1738. }
  1739.  
  1740.  
  1741. unsigned
  1742. ureg_get_nr_outputs( const struct ureg_program *ureg )
  1743. {
  1744.    if (!ureg)
  1745.       return 0;
  1746.    return ureg->nr_outputs;
  1747. }
  1748.  
  1749.  
  1750. void ureg_destroy( struct ureg_program *ureg )
  1751. {
  1752.    unsigned i;
  1753.  
  1754.    for (i = 0; i < Elements(ureg->domain); i++) {
  1755.       if (ureg->domain[i].tokens &&
  1756.           ureg->domain[i].tokens != error_tokens)
  1757.          FREE(ureg->domain[i].tokens);
  1758.    }
  1759.  
  1760.    util_bitmask_destroy(ureg->free_temps);
  1761.    util_bitmask_destroy(ureg->local_temps);
  1762.    util_bitmask_destroy(ureg->decl_temps);
  1763.  
  1764.    FREE(ureg);
  1765. }
  1766.