"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/compiler/nir/nir_lower_input_attachments.c" (16 Sep 2020, 6566 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 "nir_lower_input_attachments.c" 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 /*
    2  * Copyright © 2016 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 "nir.h"
   25 #include "nir_builder.h"
   26 
   27 static nir_ssa_def *
   28 load_frag_coord(nir_builder *b)
   29 {
   30    nir_foreach_variable(var, &b->shader->inputs) {
   31       if (var->data.location == VARYING_SLOT_POS)
   32          return nir_load_var(b, var);
   33    }
   34 
   35    nir_variable *pos = nir_variable_create(b->shader, nir_var_shader_in,
   36                                            glsl_vec4_type(), NULL);
   37    pos->data.location = VARYING_SLOT_POS;
   38    /**
   39     * From Vulkan spec:
   40     *   "The OriginLowerLeft execution mode must not be used; fragment entry
   41     *    points must declare OriginUpperLeft."
   42     *
   43     * So at this point origin_upper_left should be true
   44     */
   45    assert(b->shader->info.fs.origin_upper_left == true);
   46 
   47    return nir_load_var(b, pos);
   48 }
   49 
   50 static bool
   51 try_lower_input_load(nir_function_impl *impl, nir_intrinsic_instr *load,
   52                      bool use_fragcoord_sysval)
   53 {
   54    nir_deref_instr *deref = nir_src_as_deref(load->src[0]);
   55    assert(glsl_type_is_image(deref->type));
   56 
   57    enum glsl_sampler_dim image_dim = glsl_get_sampler_dim(deref->type);
   58    if (image_dim != GLSL_SAMPLER_DIM_SUBPASS &&
   59        image_dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
   60       return false;
   61 
   62    const bool multisampled = (image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
   63 
   64    nir_builder b;
   65    nir_builder_init(&b, impl);
   66    b.cursor = nir_instr_remove(&load->instr);
   67 
   68    nir_ssa_def *frag_coord = use_fragcoord_sysval ? nir_load_frag_coord(&b)
   69                                                   : load_frag_coord(&b);
   70    frag_coord = nir_f2i32(&b, frag_coord);
   71    nir_ssa_def *offset = nir_ssa_for_src(&b, load->src[1], 2);
   72    nir_ssa_def *pos = nir_iadd(&b, frag_coord, offset);
   73 
   74    nir_ssa_def *layer = nir_load_layer_id(&b);
   75    nir_ssa_def *coord =
   76       nir_vec3(&b, nir_channel(&b, pos, 0), nir_channel(&b, pos, 1), layer);
   77 
   78    nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3 + multisampled);
   79 
   80    tex->op = nir_texop_txf;
   81    tex->sampler_dim = image_dim;
   82 
   83    switch (glsl_get_sampler_result_type(deref->type)) {
   84    case GLSL_TYPE_FLOAT:
   85       tex->dest_type = nir_type_float;
   86       break;
   87    case GLSL_TYPE_INT:
   88       tex->dest_type = nir_type_int;
   89       break;
   90    case GLSL_TYPE_UINT:
   91       tex->dest_type = nir_type_uint;
   92       break;
   93    default:
   94       unreachable("Invalid image type");
   95    }
   96    tex->is_array = true;
   97    tex->is_shadow = false;
   98 
   99    tex->texture_index = 0;
  100    tex->sampler_index = 0;
  101 
  102    tex->src[0].src_type = nir_tex_src_texture_deref;
  103    tex->src[0].src = nir_src_for_ssa(&deref->dest.ssa);
  104 
  105    tex->src[1].src_type = nir_tex_src_coord;
  106    tex->src[1].src = nir_src_for_ssa(coord);
  107    tex->coord_components = 3;
  108 
  109    tex->src[2].src_type = nir_tex_src_lod;
  110    tex->src[2].src = nir_src_for_ssa(nir_imm_int(&b, 0));
  111 
  112    if (image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS) {
  113       tex->op = nir_texop_txf_ms;
  114       tex->src[3].src_type = nir_tex_src_ms_index;
  115       tex->src[3].src = load->src[2];
  116    }
  117 
  118    tex->texture_non_uniform = nir_intrinsic_access(load) & ACCESS_NON_UNIFORM;
  119 
  120    nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
  121    nir_builder_instr_insert(&b, &tex->instr);
  122 
  123    nir_ssa_def_rewrite_uses(&load->dest.ssa,
  124                             nir_src_for_ssa(&tex->dest.ssa));
  125 
  126    return true;
  127 }
  128 
  129 static bool
  130 try_lower_input_texop(nir_function_impl *impl, nir_tex_instr *tex,
  131                              bool use_fragcoord_sysval)
  132 {
  133    nir_deref_instr *deref = nir_src_as_deref(tex->src[0].src);
  134 
  135    if (glsl_get_sampler_dim(deref->type) != GLSL_SAMPLER_DIM_SUBPASS_MS)
  136       return false;
  137 
  138    nir_builder b;
  139    nir_builder_init(&b, impl);
  140    b.cursor = nir_before_instr(&tex->instr);
  141 
  142    nir_ssa_def *frag_coord = use_fragcoord_sysval ? nir_load_frag_coord(&b)
  143                                                   : load_frag_coord(&b);
  144    frag_coord = nir_f2i32(&b, frag_coord);
  145 
  146    nir_ssa_def *layer = nir_load_layer_id(&b);
  147    nir_ssa_def *coord = nir_vec3(&b, nir_channel(&b, frag_coord, 0),
  148                                      nir_channel(&b, frag_coord, 1), layer);
  149 
  150    tex->coord_components = 3;
  151 
  152    nir_instr_rewrite_src(&tex->instr, &tex->src[1].src, nir_src_for_ssa(coord));
  153 
  154    return true;
  155 }
  156 
  157 bool
  158 nir_lower_input_attachments(nir_shader *shader, bool use_fragcoord_sysval)
  159 {
  160    assert(shader->info.stage == MESA_SHADER_FRAGMENT);
  161    bool progress = false;
  162 
  163    nir_foreach_function(function, shader) {
  164       if (!function->impl)
  165          continue;
  166 
  167       nir_foreach_block(block, function->impl) {
  168          nir_foreach_instr_safe(instr, block) {
  169             switch (instr->type) {
  170             case nir_instr_type_tex: {
  171                nir_tex_instr *tex = nir_instr_as_tex(instr);
  172 
  173                if (tex->op == nir_texop_fragment_mask_fetch ||
  174                    tex->op == nir_texop_fragment_fetch) {
  175                   progress |= try_lower_input_texop(function->impl, tex,
  176                                                     use_fragcoord_sysval);
  177                }
  178                break;
  179             }
  180             case nir_instr_type_intrinsic: {
  181                nir_intrinsic_instr *load = nir_instr_as_intrinsic(instr);
  182 
  183                if (load->intrinsic == nir_intrinsic_image_deref_load) {
  184                   progress |= try_lower_input_load(function->impl, load,
  185                                                    use_fragcoord_sysval);
  186                }
  187                break;
  188             }
  189             default:
  190                break;
  191             }
  192          }
  193       }
  194    }
  195 
  196    return progress;
  197 }