1/* 2 * Copyright © 2013 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "brw_compiler.h" 25#include "compiler/nir/nir.h" 26 27static char const *get_qual_name(int mode) 28{ 29 switch (mode) { 30 case INTERP_MODE_NONE: return "none"; 31 case INTERP_MODE_FLAT: return "flat"; 32 case INTERP_MODE_SMOOTH: return "smooth"; 33 case INTERP_MODE_NOPERSPECTIVE: return "nopersp"; 34 default: return "???"; 35 } 36} 37 38static void 39gfx4_frag_prog_set_interp_modes(struct brw_wm_prog_data *prog_data, 40 const struct brw_vue_map *vue_map, 41 unsigned location, unsigned slot_count, 42 enum glsl_interp_mode interp) 43{ 44 for (unsigned k = 0; k < slot_count; k++) { 45 unsigned slot = vue_map->varying_to_slot[location + k]; 46 if (slot != -1 && prog_data->interp_mode[slot] == INTERP_MODE_NONE) { 47 prog_data->interp_mode[slot] = interp; 48 49 if (prog_data->interp_mode[slot] == INTERP_MODE_FLAT) { 50 prog_data->contains_flat_varying = true; 51 } else if (prog_data->interp_mode[slot] == INTERP_MODE_NOPERSPECTIVE) { 52 prog_data->contains_noperspective_varying = true; 53 } 54 } 55 } 56} 57 58/* Set up interpolation modes for every element in the VUE */ 59void 60brw_setup_vue_interpolation(const struct brw_vue_map *vue_map, nir_shader *nir, 61 struct brw_wm_prog_data *prog_data) 62{ 63 /* Initialise interp_mode. INTERP_MODE_NONE == 0 */ 64 memset(prog_data->interp_mode, 0, sizeof(prog_data->interp_mode)); 65 66 if (!vue_map) 67 return; 68 69 /* HPOS always wants noperspective. setting it up here allows 70 * us to not need special handling in the SF program. 71 */ 72 unsigned pos_slot = vue_map->varying_to_slot[VARYING_SLOT_POS]; 73 if (pos_slot != -1) {; 74 prog_data->interp_mode[pos_slot] = INTERP_MODE_NOPERSPECTIVE; 75 prog_data->contains_noperspective_varying = true; 76 } 77 78 nir_foreach_shader_in_variable(var, nir) { 79 unsigned location = var->data.location; 80 unsigned slot_count = glsl_count_attribute_slots(var->type, false); 81 82 gfx4_frag_prog_set_interp_modes(prog_data, vue_map, location, slot_count, 83 var->data.interpolation); 84 85 if (location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1) { 86 location = location + VARYING_SLOT_BFC0 - VARYING_SLOT_COL0; 87 gfx4_frag_prog_set_interp_modes(prog_data, vue_map, location, 88 slot_count, var->data.interpolation); 89 } 90 } 91 92 const bool debug = false; 93 if (debug) { 94 fprintf(stderr, "VUE map:\n"); 95 for (int i = 0; i < vue_map->num_slots; i++) { 96 int varying = vue_map->slot_to_varying[i]; 97 if (varying == -1) { 98 fprintf(stderr, "%d: --\n", i); 99 continue; 100 } 101 102 fprintf(stderr, "%d: %d %s ofs %d\n", 103 i, varying, 104 get_qual_name(prog_data->interp_mode[i]), 105 brw_vue_slot_to_offset(i)); 106 } 107 } 108} 109