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