1 /* 2 * Copyright 2017 Red Hat 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 #include "nir/nir.h" 24 #include "ac_shader_info.h" 25 #include "ac_nir_to_llvm.h" 26 27 static void mark_sampler_desc(const nir_variable *var, 28 struct ac_shader_info *info) 29 { 30 info->desc_set_used_mask = (1 << var->data.descriptor_set); 31 } 32 33 static void 34 gather_intrinsic_info(const nir_intrinsic_instr *instr, 35 struct ac_shader_info *info) 36 { 37 switch (instr->intrinsic) { 38 case nir_intrinsic_interp_var_at_sample: 39 info->ps.needs_sample_positions = true; 40 break; 41 case nir_intrinsic_load_draw_id: 42 info->vs.needs_draw_id = true; 43 break; 44 case nir_intrinsic_load_instance_id: 45 info->vs.needs_instance_id = true; 46 break; 47 case nir_intrinsic_load_num_work_groups: 48 info->cs.uses_grid_size = true; 49 break; 50 case nir_intrinsic_load_local_invocation_id: 51 case nir_intrinsic_load_work_group_id: { 52 unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa); 53 while (mask) { 54 unsigned i = u_bit_scan(&mask); 55 56 if (instr->intrinsic == nir_intrinsic_load_work_group_id) 57 info->cs.uses_block_id[i] = true; 58 else 59 info->cs.uses_thread_id[i] = true; 60 } 61 break; 62 } 63 case nir_intrinsic_load_local_invocation_index: 64 info->cs.uses_local_invocation_idx = true; 65 break; 66 case nir_intrinsic_load_sample_id: 67 info->ps.force_persample = true; 68 break; 69 case nir_intrinsic_load_sample_pos: 70 info->ps.force_persample = true; 71 break; 72 case nir_intrinsic_load_view_index: 73 info->needs_multiview_view_index = true; 74 break; 75 case nir_intrinsic_load_invocation_id: 76 info->uses_invocation_id = true; 77 break; 78 case nir_intrinsic_load_primitive_id: 79 info->uses_prim_id = true; 80 break; 81 case nir_intrinsic_load_push_constant: 82 info->loads_push_constants = true; 83 break; 84 case nir_intrinsic_vulkan_resource_index: 85 info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr)); 86 break; 87 case nir_intrinsic_image_load: 88 case nir_intrinsic_image_store: 89 case nir_intrinsic_image_atomic_add: 90 case nir_intrinsic_image_atomic_min: 91 case nir_intrinsic_image_atomic_max: 92 case nir_intrinsic_image_atomic_and: 93 case nir_intrinsic_image_atomic_or: 94 case nir_intrinsic_image_atomic_xor: 95 case nir_intrinsic_image_atomic_exchange: 96 case nir_intrinsic_image_atomic_comp_swap: 97 case nir_intrinsic_image_size: { 98 const struct glsl_type *type = instr->variables[0]->var->type; 99 if(instr->variables[0]->deref.child) 100 type = instr->variables[0]->deref.child->type; 101 102 enum glsl_sampler_dim dim = glsl_get_sampler_dim(type); 103 if (dim == GLSL_SAMPLER_DIM_SUBPASS || 104 dim == GLSL_SAMPLER_DIM_SUBPASS_MS) 105 info->ps.uses_input_attachments = true; 106 mark_sampler_desc(instr->variables[0]->var, info); 107 break; 108 } 109 default: 110 break; 111 } 112 } 113 114 static void 115 gather_tex_info(const nir_tex_instr *instr, struct ac_shader_info *info) 116 { 117 if (instr->sampler) 118 mark_sampler_desc(instr->sampler->var, info); 119 if (instr->texture) 120 mark_sampler_desc(instr->texture->var, info); 121 } 122 123 static void 124 gather_info_block(const nir_block *block, struct ac_shader_info *info) 125 { 126 nir_foreach_instr(instr, block) { 127 switch (instr->type) { 128 case nir_instr_type_intrinsic: 129 gather_intrinsic_info(nir_instr_as_intrinsic(instr), info); 130 break; 131 case nir_instr_type_tex: 132 gather_tex_info(nir_instr_as_tex(instr), info); 133 break; 134 default: 135 break; 136 } 137 } 138 } 139 140 static void 141 gather_info_input_decl(const nir_shader *nir, const nir_variable *var, 142 struct ac_shader_info *info) 143 { 144 switch (nir->info.stage) { 145 case MESA_SHADER_VERTEX: 146 info->vs.has_vertex_buffers = true; 147 break; 148 default: 149 break; 150 } 151 } 152 153 void 154 ac_nir_shader_info_pass(const struct nir_shader *nir, 155 const struct ac_nir_compiler_options *options, 156 struct ac_shader_info *info) 157 { 158 struct nir_function *func = 159 (struct nir_function *)exec_list_get_head_const(&nir->functions); 160 161 if (options->layout->dynamic_offset_count) 162 info->loads_push_constants = true; 163 164 nir_foreach_variable(variable, &nir->inputs) 165 gather_info_input_decl(nir, variable, info); 166 167 nir_foreach_block(block, func->impl) { 168 gather_info_block(block, info); 169 } 170 } 171