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