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