Path: blob/21.2-virgl/src/gallium/drivers/svga/svga_link.c
4570 views
/*/1* Copyright 2013 VMware, Inc. All rights reserved.2*3* Permission is hereby granted, free of charge, to any person4* obtaining a copy of this software and associated documentation5* files (the "Software"), to deal in the Software without6* restriction, including without limitation the rights to use, copy,7* modify, merge, publish, distribute, sublicense, and/or sell copies8* of the Software, and to permit persons to whom the Software is9* furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/232425#include "svga_context.h"26#include "svga_link.h"27#include "svga_debug.h"2829#include "tgsi/tgsi_strings.h"303132#define INVALID_INDEX 255333435/**36* Examine input and output shaders info to link outputs from the37* output shader to inputs from the input shader.38* Basically, we'll remap input shader's input slots to new numbers39* based on semantic name/index of the outputs from the output shader.40*/41void42svga_link_shaders(const struct tgsi_shader_info *outshader_info,43const struct tgsi_shader_info *inshader_info,44struct shader_linkage *linkage)45{46unsigned i, free_slot;4748for (i = 0; i < ARRAY_SIZE(linkage->input_map); i++) {49linkage->input_map[i] = INVALID_INDEX;50}5152for (i = 0; i < ARRAY_SIZE(linkage->prevShader.output_map); i++) {53linkage->prevShader.output_map[i] = INVALID_INDEX;54}5556/* Assign input slots for input shader inputs.57* Basically, we want to use the same index for the output shader's outputs58* and the input shader's inputs that should be linked together.59* We'll modify the input shader's inputs to match the output shader.60*/61assert(inshader_info->num_inputs <=62ARRAY_SIZE(inshader_info->input_semantic_name));6364/* free register index that can be used for built-in varyings */65free_slot = outshader_info->num_outputs + 1;6667for (i = 0; i < inshader_info->num_inputs; i++) {68enum tgsi_semantic sem_name = inshader_info->input_semantic_name[i];69unsigned sem_index = inshader_info->input_semantic_index[i];70unsigned j;71unsigned out_index;7273/* search output shader outputs for same item */74for (j = 0; j < outshader_info->num_outputs; j++) {75assert(j < ARRAY_SIZE(outshader_info->output_semantic_name));76if (outshader_info->output_semantic_name[j] == sem_name &&77outshader_info->output_semantic_index[j] == sem_index) {78linkage->input_map[i] = j;79linkage->prevShader.output_map[j] = i;80break;81}82}8384/**85* The clip distance inputs come from the output shader's86* clip distance shadow copy, so mark the input index to match87* the index of the shadow copy.88*/89if (sem_name == TGSI_SEMANTIC_CLIPDIST) {90out_index = outshader_info->num_outputs + 1 + sem_index;91linkage->input_map[i] = out_index;92linkage->prevShader.output_map[out_index] = i;93/* make sure free_slot includes this extra output */94free_slot = MAX2(free_slot, linkage->input_map[i] + 1);95}96}9798/* Find the index for position */99linkage->position_index = 0;100for (i = 0; i < outshader_info->num_outputs; i++) {101if (outshader_info->output_semantic_name[i] == TGSI_SEMANTIC_POSITION) {102linkage->position_index = i;103break;104}105}106107linkage->num_inputs = inshader_info->num_inputs;108linkage->prevShader.num_outputs = outshader_info->num_outputs;109110/* Things like the front-face register are handled here */111for (i = 0; i < inshader_info->num_inputs; i++) {112if (linkage->input_map[i] == INVALID_INDEX) {113unsigned j = free_slot++;114linkage->input_map[i] = j;115linkage->prevShader.output_map[j] = i;116}117}118linkage->input_map_max = free_slot - 1;119120/* Debug */121if (SVGA_DEBUG & DEBUG_TGSI) {122uint64_t reg = 0;123uint64_t one = 1;124125debug_printf(126"### linkage info: num_inputs=%d input_map_max=%d prevShader.num_outputs=%d\n",127linkage->num_inputs, linkage->input_map_max,128linkage->prevShader.num_outputs);129130for (i = 0; i < linkage->num_inputs; i++) {131132assert(linkage->input_map[i] != INVALID_INDEX);133134debug_printf(" input[%d] slot %u %s %u %s\n",135i,136linkage->input_map[i],137tgsi_semantic_names[inshader_info->input_semantic_name[i]],138inshader_info->input_semantic_index[i],139tgsi_interpolate_names[inshader_info->input_interpolate[i]]);140141/* make sure no repeating register index */142assert((reg & (one << linkage->input_map[i])) == 0);143reg |= one << linkage->input_map[i];144}145}146}147148149