Subversion Repositories Kolibri OS

Rev

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