xref: /aosp_15_r20/external/mesa3d/src/compiler/nir/nir_lower_single_sampled.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2021 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 bool
lower_single_sampled_instr(nir_builder * b,nir_intrinsic_instr * intrin,UNUSED void * cb_data)28 lower_single_sampled_instr(nir_builder *b,
29                            nir_intrinsic_instr *intrin,
30                            UNUSED void *cb_data)
31 {
32    nir_def *lowered;
33    switch (intrin->intrinsic) {
34    case nir_intrinsic_load_sample_id:
35       b->cursor = nir_before_instr(&intrin->instr);
36       lowered = nir_imm_int(b, 0);
37       break;
38 
39    case nir_intrinsic_load_sample_pos:
40       b->cursor = nir_before_instr(&intrin->instr);
41       lowered = nir_imm_vec2(b, 0.5, 0.5);
42       break;
43 
44    case nir_intrinsic_load_sample_mask_in:
45       /* Don't lower to helper invocations if helper invocations are going
46        * to be lowered right back to sample mask.
47        */
48       if (b->shader->options->lower_helper_invocation)
49          return false;
50 
51       b->cursor = nir_before_instr(&intrin->instr);
52       lowered = nir_b2i32(b, nir_inot(b, nir_load_helper_invocation(b, 1)));
53       break;
54 
55    case nir_intrinsic_interp_deref_at_centroid:
56    case nir_intrinsic_interp_deref_at_sample:
57       b->cursor = nir_before_instr(&intrin->instr);
58       lowered = nir_load_deref(b, nir_src_as_deref(intrin->src[0]));
59       break;
60 
61    case nir_intrinsic_load_barycentric_centroid:
62    case nir_intrinsic_load_barycentric_sample:
63    case nir_intrinsic_load_barycentric_at_sample:
64       b->cursor = nir_before_instr(&intrin->instr);
65       lowered = nir_load_barycentric(b, nir_intrinsic_load_barycentric_pixel,
66                                      nir_intrinsic_interp_mode(intrin));
67 
68       if (nir_intrinsic_interp_mode(intrin) == INTERP_MODE_NOPERSPECTIVE) {
69          BITSET_SET(b->shader->info.system_values_read,
70                     SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL);
71       } else {
72          BITSET_SET(b->shader->info.system_values_read,
73                     SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL);
74       }
75       break;
76 
77    default:
78       return false;
79    }
80 
81    nir_def_replace(&intrin->def, lowered);
82    return true;
83 }
84 
85 /* Assume the fragment shader is single-sampled and lower accordingly
86  *
87  * This drops sample/centroid qualifiers from all input variables, forces
88  * barycentrics to pixel, and constant-folds various built-ins.
89  */
90 bool
nir_lower_single_sampled(nir_shader * shader)91 nir_lower_single_sampled(nir_shader *shader)
92 {
93    assert(shader->info.stage == MESA_SHADER_FRAGMENT);
94 
95    bool progress = false;
96    nir_foreach_shader_in_variable(var, shader) {
97       if (var->data.sample) {
98          var->data.sample = false;
99          progress = true;
100       }
101       if (var->data.centroid) {
102          var->data.centroid = false;
103          progress = true;
104       }
105    }
106 
107    /* We're going to get rid of any uses of these */
108    BITSET_CLEAR(shader->info.system_values_read,
109                 SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE);
110    BITSET_CLEAR(shader->info.system_values_read,
111                 SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID);
112    BITSET_CLEAR(shader->info.system_values_read,
113                 SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE);
114    BITSET_CLEAR(shader->info.system_values_read,
115                 SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID);
116 
117    return nir_shader_intrinsics_pass(shader, lower_single_sampled_instr,
118                                        nir_metadata_control_flow,
119                                        NULL) ||
120           progress;
121 }
122