Home | History | Annotate | Download | only in svga
      1 /*/
      2  * Copyright 2013 VMware, Inc.  All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  */
     24 
     25 
     26 #include "svga_context.h"
     27 #include "svga_link.h"
     28 #include "svga_debug.h"
     29 
     30 #include "tgsi/tgsi_strings.h"
     31 
     32 
     33 #define INVALID_INDEX 255
     34 
     35 
     36 /**
     37  * Examine input and output shaders info to link outputs from the
     38  * output shader to inputs from the input shader.
     39  * Basically, we'll remap input shader's input slots to new numbers
     40  * based on semantic name/index of the outputs from the output shader.
     41  */
     42 void
     43 svga_link_shaders(const struct tgsi_shader_info *outshader_info,
     44                   const struct tgsi_shader_info *inshader_info,
     45                   struct shader_linkage *linkage)
     46 {
     47    unsigned i, free_slot;
     48 
     49    for (i = 0; i < ARRAY_SIZE(linkage->input_map); i++) {
     50       linkage->input_map[i] = INVALID_INDEX;
     51    }
     52 
     53    /* Assign input slots for input shader inputs.
     54     * Basically, we want to use the same index for the output shader's outputs
     55     * and the input shader's inputs that should be linked together.
     56     * We'll modify the input shader's inputs to match the output shader.
     57     */
     58    assert(inshader_info->num_inputs <=
     59           ARRAY_SIZE(inshader_info->input_semantic_name));
     60 
     61    /* free register index that can be used for built-in varyings */
     62    free_slot = outshader_info->num_outputs + 1;
     63 
     64    for (i = 0; i < inshader_info->num_inputs; i++) {
     65       unsigned sem_name = inshader_info->input_semantic_name[i];
     66       unsigned sem_index = inshader_info->input_semantic_index[i];
     67       unsigned j;
     68       /**
     69        * Get the clip distance inputs from the output shader's
     70        * clip distance shadow copy.
     71        */
     72       if (sem_name == TGSI_SEMANTIC_CLIPDIST) {
     73          linkage->input_map[i] = outshader_info->num_outputs + 1 + sem_index;
     74          /* make sure free_slot includes this extra output */
     75          free_slot = MAX2(free_slot, linkage->input_map[i] + 1);
     76       }
     77       else {
     78          /* search output shader outputs for same item */
     79          for (j = 0; j < outshader_info->num_outputs; j++) {
     80             assert(j < ARRAY_SIZE(outshader_info->output_semantic_name));
     81             if (outshader_info->output_semantic_name[j] == sem_name &&
     82                 outshader_info->output_semantic_index[j] == sem_index) {
     83                linkage->input_map[i] = j;
     84                break;
     85             }
     86          }
     87       }
     88    }
     89 
     90    linkage->num_inputs = inshader_info->num_inputs;
     91 
     92    /* Things like the front-face register are handled here */
     93    for (i = 0; i < inshader_info->num_inputs; i++) {
     94       if (linkage->input_map[i] == INVALID_INDEX) {
     95          unsigned j = free_slot++;
     96          linkage->input_map[i] = j;
     97       }
     98    }
     99 
    100    /* Debug */
    101    if (SVGA_DEBUG & DEBUG_TGSI) {
    102       unsigned reg = 0;
    103       debug_printf("### linkage info:\n");
    104 
    105       for (i = 0; i < linkage->num_inputs; i++) {
    106 
    107          assert(linkage->input_map[i] != INVALID_INDEX);
    108 
    109          debug_printf("   input[%d] slot %u  %s %u %s\n",
    110                       i,
    111                       linkage->input_map[i],
    112                       tgsi_semantic_names[inshader_info->input_semantic_name[i]],
    113                       inshader_info->input_semantic_index[i],
    114                       tgsi_interpolate_names[inshader_info->input_interpolate[i]]);
    115 
    116          /* make sure no repeating register index */
    117          if (reg & 1 << linkage->input_map[i]) {
    118             assert(0);
    119          }
    120          reg |= 1 << linkage->input_map[i];
    121       }
    122    }
    123 }
    124