"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/r600/sfn/sfn_shaderio.cpp" (16 Sep 2020, 9357 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sfn_shaderio.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    1 /* -*- mesa-c++  -*-
    2  *
    3  * Copyright (c) 2018 Collabora LTD
    4  *
    5  * Author: Gert Wollny <gert.wollny@collabora.com>
    6  *
    7  * Permission is hereby granted, free of charge, to any person obtaining a
    8  * copy of this software and associated documentation files (the "Software"),
    9  * to deal in the Software without restriction, including without limitation
   10  * on the rights to use, copy, modify, merge, publish, distribute, sub
   11  * license, and/or sell copies of the Software, and to permit persons to whom
   12  * the Software is furnished to do so, subject to the following conditions:
   13  *
   14  * The above copyright notice and this permission notice (including the next
   15  * paragraph) shall be included in all copies or substantial portions of the
   16  * Software.
   17  *
   18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
   21  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
   22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
   23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
   24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
   25  */
   26 
   27 #include "sfn_shaderio.h"
   28 #include "sfn_debug.h"
   29 #include "tgsi/tgsi_from_mesa.h"
   30 
   31 #include <queue>
   32 
   33 namespace r600 {
   34 
   35 using std::vector;
   36 using std::priority_queue;
   37 
   38 ShaderIO::ShaderIO():
   39    m_two_sided(false),
   40    m_lds_pos(0)
   41 {
   42 
   43 }
   44 
   45 ShaderInput::ShaderInput(tgsi_semantic name):
   46    m_name(name),
   47    m_gpr(0),
   48    m_uses_interpolate_at_centroid(false)
   49 {
   50 }
   51 
   52 ShaderInput::~ShaderInput()
   53 {
   54 }
   55 
   56 void ShaderInput::set_lds_pos(UNUSED int lds_pos)
   57 {
   58 }
   59 
   60 int ShaderInput::ij_index() const
   61 {
   62    return -1;
   63 }
   64 
   65 bool ShaderInput::interpolate() const
   66 {
   67    return false;
   68 }
   69 
   70 int ShaderInput::lds_pos() const
   71 {
   72    return 0;
   73 }
   74 
   75 bool ShaderInput::is_varying() const
   76 {
   77    return false;
   78 }
   79 
   80 void ShaderInput::set_uses_interpolate_at_centroid()
   81 {
   82    m_uses_interpolate_at_centroid = true;
   83 }
   84 
   85 void ShaderInput::set_ioinfo(r600_shader_io& io, int translated_ij_index) const
   86 {
   87    io.name = m_name;
   88    io.gpr = m_gpr;
   89    io.ij_index = translated_ij_index;
   90    io.lds_pos = lds_pos();
   91    io.uses_interpolate_at_centroid = m_uses_interpolate_at_centroid;
   92 
   93    set_specific_ioinfo(io);
   94 }
   95 
   96 void ShaderInput::set_specific_ioinfo(UNUSED r600_shader_io& io) const
   97 {
   98 }
   99 
  100 ShaderInputSystemValue::ShaderInputSystemValue(tgsi_semantic name, int gpr):
  101    ShaderInput(name),
  102    m_gpr(gpr)
  103 {
  104 }
  105 
  106 void ShaderInputSystemValue::set_specific_ioinfo(r600_shader_io& io) const
  107 {
  108    io.gpr = m_gpr;
  109    io.ij_index = 0;
  110 }
  111 
  112 ShaderInputVarying::ShaderInputVarying(tgsi_semantic _name, int sid, nir_variable *input):
  113    ShaderInput(_name),
  114    m_driver_location(input->data.driver_location),
  115    m_location_frac(input->data.location_frac),
  116    m_sid(sid),
  117    m_ij_index(-10),
  118    m_mask((1 << input->type->components()) - 1)
  119 {
  120    sfn_log << SfnLog::io << __func__
  121            << "name:" << _name
  122            << " sid: " << sid
  123            << " op: " << input->data.interpolation;
  124 
  125    evaluate_spi_sid();
  126 
  127    enum glsl_base_type base_type =
  128       glsl_get_base_type(glsl_without_array(input->type));
  129 
  130    switch (input->data.interpolation) {
  131    case INTERP_MODE_NONE:
  132       if (glsl_base_type_is_integer(base_type)) {
  133          m_interpolate = TGSI_INTERPOLATE_CONSTANT;
  134          break;
  135       }
  136 
  137       if (name() == TGSI_SEMANTIC_COLOR) {
  138          m_interpolate = TGSI_INTERPOLATE_COLOR;
  139          m_ij_index = 0;
  140          break;
  141       }
  142       /* fall-through */
  143 
  144    case INTERP_MODE_SMOOTH:
  145       assert(!glsl_base_type_is_integer(base_type));
  146 
  147       m_interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
  148       m_ij_index = 0;
  149       break;
  150 
  151    case INTERP_MODE_NOPERSPECTIVE:
  152       assert(!glsl_base_type_is_integer(base_type));
  153 
  154       m_interpolate = TGSI_INTERPOLATE_LINEAR;
  155       m_ij_index = 3;
  156       break;
  157 
  158    case INTERP_MODE_FLAT:
  159       m_interpolate = TGSI_INTERPOLATE_CONSTANT;
  160       break;
  161    }
  162 
  163    if (input->data.sample) {
  164       m_interpolate_loc = TGSI_INTERPOLATE_LOC_SAMPLE;
  165    } else if (input->data.centroid) {
  166       m_interpolate_loc = TGSI_INTERPOLATE_LOC_CENTROID;
  167       m_ij_index += 2;
  168    } else {
  169       m_interpolate_loc = TGSI_INTERPOLATE_LOC_CENTER;
  170       m_ij_index += 1;
  171    }
  172    sfn_log << SfnLog::io
  173            << " -> IP:" << m_interpolate
  174            << " IJ:" << m_ij_index
  175            << "\n";
  176 }
  177 
  178 bool ShaderInputVarying::is_varying() const
  179 {
  180    return true;
  181 }
  182 
  183 void ShaderInputVarying::update_mask(int additional_comps)
  184 {
  185    m_mask |= additional_comps;
  186 }
  187 
  188 void ShaderInputVarying::evaluate_spi_sid()
  189 {
  190    switch (name()) {
  191    case TGSI_SEMANTIC_POSITION:
  192    case TGSI_SEMANTIC_PSIZE:
  193    case TGSI_SEMANTIC_EDGEFLAG:
  194    case TGSI_SEMANTIC_FACE:
  195    case TGSI_SEMANTIC_SAMPLEMASK:
  196       assert(0 && "System value used as varying");
  197       break;
  198    case TGSI_SEMANTIC_GENERIC:
  199       m_spi_sid = m_sid + 1;
  200       break;
  201    default:
  202       /* For non-generic params - pack name and sid into 8 bits */
  203       m_spi_sid = (0x80 | (name() << 3) | m_sid) + 1;
  204    }
  205 }
  206 
  207 ShaderInputVarying::ShaderInputVarying(tgsi_semantic name,
  208                                        const ShaderInputVarying& orig, size_t location):
  209    ShaderInput(name),
  210    m_driver_location(location),
  211    m_location_frac(orig.location_frac()),
  212 
  213    m_sid(orig.m_sid),
  214    m_spi_sid(orig.m_spi_sid),
  215    m_interpolate(orig.m_interpolate),
  216    m_interpolate_loc(orig.m_interpolate_loc),
  217    m_ij_index(orig.m_ij_index),
  218    m_lds_pos(0)
  219 {
  220    evaluate_spi_sid();
  221 }
  222 
  223 bool ShaderInputVarying::interpolate() const
  224 {
  225    return m_interpolate > 0;
  226 }
  227 
  228 int ShaderInputVarying::ij_index() const
  229 {
  230    return m_ij_index;
  231 }
  232 
  233 void ShaderInputVarying::set_lds_pos(int lds_pos)
  234 {
  235    m_lds_pos = lds_pos;
  236 }
  237 
  238 int ShaderInputVarying::lds_pos() const
  239 {
  240    return m_lds_pos;
  241 }
  242 
  243 void ShaderInputVarying::set_specific_ioinfo(r600_shader_io& io) const
  244 {
  245    io.interpolate = m_interpolate;
  246    io.interpolate_location = m_interpolate_loc;
  247    io.sid = m_sid;
  248    io.spi_sid = m_spi_sid;
  249    set_color_ioinfo(io);
  250 }
  251 
  252 void ShaderInputVarying::set_color_ioinfo(UNUSED r600_shader_io& io) const
  253 {
  254    sfn_log << SfnLog::io << __func__ << " Don't set color_ioinfo\n";
  255 }
  256 
  257 ShaderInputColor::ShaderInputColor(tgsi_semantic name, int sid, nir_variable *input):
  258    ShaderInputVarying(name, sid, input),
  259    m_back_color_input_idx(0)
  260 {
  261    sfn_log << SfnLog::io << __func__ << "name << " << name << " sid << " << sid << "\n";
  262 }
  263 
  264 void ShaderInputColor::set_back_color(unsigned back_color_input_idx)
  265 {
  266    sfn_log << SfnLog::io << "Set back color index " << back_color_input_idx << "\n";
  267    m_back_color_input_idx = back_color_input_idx;
  268 }
  269 
  270 void ShaderInputColor::set_color_ioinfo(r600_shader_io& io) const
  271 {
  272    sfn_log << SfnLog::io << __func__ << " set color_ioinfo " << m_back_color_input_idx << "\n";
  273    io.back_color_input = m_back_color_input_idx;
  274 }
  275 
  276 size_t ShaderIO::add_input(ShaderInput *input)
  277 {
  278    m_inputs.push_back(PShaderInput(input));
  279    return m_inputs.size() - 1;
  280 }
  281 
  282 PShaderInput ShaderIO::find_varying(tgsi_semantic name, int sid, int frac)
  283 {
  284    for (auto& a : m_inputs) {
  285       if (a->name() == name) {
  286          assert(a->is_varying());
  287          auto& v = static_cast<ShaderInputVarying&>(*a);
  288          if (v.sid() == sid && (v.location_frac() == frac))
  289             return a;
  290       }
  291    }
  292    return nullptr;
  293 }
  294 
  295 struct VaryingShaderIOLess {
  296    bool operator () (PShaderInput lhs, PShaderInput rhs) const
  297    {
  298       const ShaderInputVarying& l = static_cast<ShaderInputVarying&>(*lhs);
  299       const ShaderInputVarying& r = static_cast<ShaderInputVarying&>(*rhs);
  300       return l.location() > r.location();
  301    }
  302 };
  303 
  304 void ShaderIO::sort_varying_inputs()
  305 {
  306    priority_queue<PShaderInput, vector<PShaderInput>, VaryingShaderIOLess> q;
  307 
  308    vector<int> idx;
  309 
  310    for (auto i = 0u; i < m_inputs.size(); ++i) {
  311       if (m_inputs[i]->is_varying()) {
  312          q.push(m_inputs[i]);
  313          idx.push_back(i);
  314       }
  315    }
  316 
  317    auto next_index = idx.begin();
  318    while (!q.empty()) {
  319       auto si = q.top();
  320       q.pop();
  321       m_inputs[*next_index++] = si;
  322    }
  323 }
  324 
  325 void ShaderIO::update_lds_pos()
  326 {
  327    m_lds_pos = -1;
  328    m_ldspos.resize(m_inputs.size());
  329    for (auto& i : m_inputs) {
  330       if (!i->is_varying())
  331          continue;
  332 
  333       auto& v = static_cast<ShaderInputVarying&>(*i);
  334       /* There are shaders that miss an input ...*/
  335       if (m_ldspos.size() <= static_cast<unsigned>(v.location()))
  336           m_ldspos.resize(v.location() + 1);
  337    }
  338 
  339    std::fill(m_ldspos.begin(), m_ldspos.end(), -1);
  340    for (auto& i : m_inputs) {
  341       if (!i->is_varying())
  342          continue;
  343 
  344       auto& v = static_cast<ShaderInputVarying&>(*i);
  345       if (m_ldspos[v.location()] < 0) {
  346          ++m_lds_pos;
  347          m_ldspos[v.location()] = m_lds_pos;
  348       }
  349       v.set_lds_pos(m_lds_pos);
  350    }
  351    ++m_lds_pos;
  352 }
  353 
  354 std::vector<PShaderInput> &ShaderIO::inputs()
  355 {
  356    return m_inputs;
  357 }
  358 
  359 ShaderInput& ShaderIO::input(size_t k)
  360 {
  361    assert(k < m_inputs.size());
  362    return *m_inputs[k];
  363 }
  364 
  365 ShaderInput& ShaderIO::input(size_t driver_loc, int frac)
  366 {
  367    for (auto& i: m_inputs) {
  368       if (!i->is_varying())
  369          continue;
  370 
  371       auto& v = static_cast<ShaderInputVarying&>(*i);
  372       if (v.location() == driver_loc && v.location_frac() == frac)
  373          return v;
  374    }
  375    return input(driver_loc);
  376 }
  377 
  378 void ShaderIO::set_two_sided()
  379 {
  380    m_two_sided = true;
  381 }
  382 
  383 }
  384