1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2017 Red Hat 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg#include "radv_private.h" 24b8e80941Smrg#include "radv_shader.h" 25b8e80941Smrg#include "nir/nir.h" 26b8e80941Smrg#include "nir/nir_deref.h" 27b8e80941Smrg#include "nir/nir_xfb_info.h" 28b8e80941Smrg 29b8e80941Smrgstatic void mark_sampler_desc(const nir_variable *var, 30b8e80941Smrg struct radv_shader_info *info) 31b8e80941Smrg{ 32b8e80941Smrg info->desc_set_used_mask |= (1 << var->data.descriptor_set); 33b8e80941Smrg} 34b8e80941Smrg 35b8e80941Smrgstatic void mark_ls_output(struct radv_shader_info *info, 36b8e80941Smrg uint32_t param, int num_slots) 37b8e80941Smrg{ 38b8e80941Smrg uint64_t mask = (1ull << num_slots) - 1ull; 39b8e80941Smrg info->vs.ls_outputs_written |= (mask << param); 40b8e80941Smrg} 41b8e80941Smrg 42b8e80941Smrgstatic void mark_tess_output(struct radv_shader_info *info, 43b8e80941Smrg bool is_patch, uint32_t param, int num_slots) 44b8e80941Smrg{ 45b8e80941Smrg uint64_t mask = (1ull << num_slots) - 1ull; 46b8e80941Smrg if (is_patch) 47b8e80941Smrg info->tcs.patch_outputs_written |= (mask << param); 48b8e80941Smrg else 49b8e80941Smrg info->tcs.outputs_written |= (mask << param); 50b8e80941Smrg} 51b8e80941Smrg 52b8e80941Smrgstatic void 53b8e80941Smrgget_deref_offset(nir_deref_instr *instr, 54b8e80941Smrg unsigned *const_out) 55b8e80941Smrg{ 56b8e80941Smrg nir_variable *var = nir_deref_instr_get_variable(instr); 57b8e80941Smrg nir_deref_path path; 58b8e80941Smrg unsigned idx_lvl = 1; 59b8e80941Smrg 60b8e80941Smrg if (var->data.compact) { 61b8e80941Smrg assert(instr->deref_type == nir_deref_type_array); 62b8e80941Smrg *const_out = nir_src_as_uint(instr->arr.index); 63b8e80941Smrg return; 64b8e80941Smrg } 65b8e80941Smrg 66b8e80941Smrg nir_deref_path_init(&path, instr, NULL); 67b8e80941Smrg 68b8e80941Smrg uint32_t const_offset = 0; 69b8e80941Smrg 70b8e80941Smrg for (; path.path[idx_lvl]; ++idx_lvl) { 71b8e80941Smrg const struct glsl_type *parent_type = path.path[idx_lvl - 1]->type; 72b8e80941Smrg if (path.path[idx_lvl]->deref_type == nir_deref_type_struct) { 73b8e80941Smrg unsigned index = path.path[idx_lvl]->strct.index; 74b8e80941Smrg 75b8e80941Smrg for (unsigned i = 0; i < index; i++) { 76b8e80941Smrg const struct glsl_type *ft = glsl_get_struct_field(parent_type, i); 77b8e80941Smrg const_offset += glsl_count_attribute_slots(ft, false); 78b8e80941Smrg } 79b8e80941Smrg } else if(path.path[idx_lvl]->deref_type == nir_deref_type_array) { 80b8e80941Smrg unsigned size = glsl_count_attribute_slots(path.path[idx_lvl]->type, false); 81b8e80941Smrg if (nir_src_is_const(path.path[idx_lvl]->arr.index)) 82b8e80941Smrg const_offset += nir_src_as_uint(path.path[idx_lvl]->arr.index) * size; 83b8e80941Smrg } else 84b8e80941Smrg unreachable("Uhandled deref type in get_deref_instr_offset"); 85b8e80941Smrg } 86b8e80941Smrg 87b8e80941Smrg *const_out = const_offset; 88b8e80941Smrg 89b8e80941Smrg nir_deref_path_finish(&path); 90b8e80941Smrg} 91b8e80941Smrg 92b8e80941Smrgstatic void 93b8e80941Smrggather_intrinsic_load_deref_info(const nir_shader *nir, 94b8e80941Smrg const nir_intrinsic_instr *instr, 95b8e80941Smrg struct radv_shader_info *info) 96b8e80941Smrg{ 97b8e80941Smrg switch (nir->info.stage) { 98b8e80941Smrg case MESA_SHADER_VERTEX: { 99b8e80941Smrg nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr)); 100b8e80941Smrg 101b8e80941Smrg if (var && var->data.mode == nir_var_shader_in) { 102b8e80941Smrg unsigned idx = var->data.location; 103b8e80941Smrg uint8_t mask = nir_ssa_def_components_read(&instr->dest.ssa); 104b8e80941Smrg 105b8e80941Smrg info->vs.input_usage_mask[idx] |= 106b8e80941Smrg mask << var->data.location_frac; 107b8e80941Smrg } 108b8e80941Smrg break; 109b8e80941Smrg } 110b8e80941Smrg default: 111b8e80941Smrg break; 112b8e80941Smrg } 113b8e80941Smrg} 114b8e80941Smrg 115b8e80941Smrgstatic uint32_t 116b8e80941Smrgwiden_writemask(uint32_t wrmask) 117b8e80941Smrg{ 118b8e80941Smrg uint32_t new_wrmask = 0; 119b8e80941Smrg for(unsigned i = 0; i < 4; i++) 120b8e80941Smrg new_wrmask |= (wrmask & (1 << i) ? 0x3 : 0x0) << (i * 2); 121b8e80941Smrg return new_wrmask; 122b8e80941Smrg} 123b8e80941Smrg 124b8e80941Smrgstatic void 125b8e80941Smrgset_output_usage_mask(const nir_shader *nir, const nir_intrinsic_instr *instr, 126b8e80941Smrg uint8_t *output_usage_mask) 127b8e80941Smrg{ 128b8e80941Smrg nir_deref_instr *deref_instr = 129b8e80941Smrg nir_instr_as_deref(instr->src[0].ssa->parent_instr); 130b8e80941Smrg nir_variable *var = nir_deref_instr_get_variable(deref_instr); 131b8e80941Smrg unsigned attrib_count = glsl_count_attribute_slots(deref_instr->type, false); 132b8e80941Smrg unsigned idx = var->data.location; 133b8e80941Smrg unsigned comp = var->data.location_frac; 134b8e80941Smrg unsigned const_offset = 0; 135b8e80941Smrg 136b8e80941Smrg get_deref_offset(deref_instr, &const_offset); 137b8e80941Smrg 138b8e80941Smrg if (var->data.compact) { 139b8e80941Smrg assert(!glsl_type_is_64bit(deref_instr->type)); 140b8e80941Smrg const_offset += comp; 141b8e80941Smrg output_usage_mask[idx + const_offset / 4] |= 1 << (const_offset % 4); 142b8e80941Smrg return; 143b8e80941Smrg } 144b8e80941Smrg 145b8e80941Smrg uint32_t wrmask = nir_intrinsic_write_mask(instr); 146b8e80941Smrg if (glsl_type_is_64bit(deref_instr->type)) 147b8e80941Smrg wrmask = widen_writemask(wrmask); 148b8e80941Smrg 149b8e80941Smrg for (unsigned i = 0; i < attrib_count; i++) 150b8e80941Smrg output_usage_mask[idx + i + const_offset] |= 151b8e80941Smrg ((wrmask >> (i * 4)) & 0xf) << comp; 152b8e80941Smrg} 153b8e80941Smrg 154b8e80941Smrgstatic void 155b8e80941Smrggather_intrinsic_store_deref_info(const nir_shader *nir, 156b8e80941Smrg const nir_intrinsic_instr *instr, 157b8e80941Smrg struct radv_shader_info *info) 158b8e80941Smrg{ 159b8e80941Smrg nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr)); 160b8e80941Smrg 161b8e80941Smrg if (var && var->data.mode == nir_var_shader_out) { 162b8e80941Smrg unsigned idx = var->data.location; 163b8e80941Smrg 164b8e80941Smrg switch (nir->info.stage) { 165b8e80941Smrg case MESA_SHADER_VERTEX: 166b8e80941Smrg set_output_usage_mask(nir, instr, 167b8e80941Smrg info->vs.output_usage_mask); 168b8e80941Smrg break; 169b8e80941Smrg case MESA_SHADER_GEOMETRY: 170b8e80941Smrg set_output_usage_mask(nir, instr, 171b8e80941Smrg info->gs.output_usage_mask); 172b8e80941Smrg break; 173b8e80941Smrg case MESA_SHADER_TESS_EVAL: 174b8e80941Smrg set_output_usage_mask(nir, instr, 175b8e80941Smrg info->tes.output_usage_mask); 176b8e80941Smrg break; 177b8e80941Smrg case MESA_SHADER_TESS_CTRL: { 178b8e80941Smrg unsigned param = shader_io_get_unique_index(idx); 179b8e80941Smrg const struct glsl_type *type = var->type; 180b8e80941Smrg 181b8e80941Smrg if (!var->data.patch) 182b8e80941Smrg type = glsl_get_array_element(var->type); 183b8e80941Smrg 184b8e80941Smrg unsigned slots = 185b8e80941Smrg var->data.compact ? DIV_ROUND_UP(var->data.location_frac + glsl_get_length(type), 4) 186b8e80941Smrg : glsl_count_attribute_slots(type, false); 187b8e80941Smrg 188b8e80941Smrg mark_tess_output(info, var->data.patch, param, slots); 189b8e80941Smrg break; 190b8e80941Smrg } 191b8e80941Smrg default: 192b8e80941Smrg break; 193b8e80941Smrg } 194b8e80941Smrg } 195b8e80941Smrg} 196b8e80941Smrg 197b8e80941Smrgstatic void 198b8e80941Smrggather_push_constant_info(const nir_shader *nir, 199b8e80941Smrg const nir_intrinsic_instr *instr, 200b8e80941Smrg struct radv_shader_info *info) 201b8e80941Smrg{ 202b8e80941Smrg int base = nir_intrinsic_base(instr); 203b8e80941Smrg 204b8e80941Smrg if (!nir_src_is_const(instr->src[0])) { 205b8e80941Smrg info->has_indirect_push_constants = true; 206b8e80941Smrg } else { 207b8e80941Smrg uint32_t min = base + nir_src_as_uint(instr->src[0]); 208b8e80941Smrg uint32_t max = min + instr->num_components * 4; 209b8e80941Smrg 210b8e80941Smrg info->max_push_constant_used = 211b8e80941Smrg MAX2(max, info->max_push_constant_used); 212b8e80941Smrg info->min_push_constant_used = 213b8e80941Smrg MIN2(min, info->min_push_constant_used); 214b8e80941Smrg } 215b8e80941Smrg 216b8e80941Smrg if (instr->dest.ssa.bit_size != 32) 217b8e80941Smrg info->has_only_32bit_push_constants = false; 218b8e80941Smrg 219b8e80941Smrg info->loads_push_constants = true; 220b8e80941Smrg} 221b8e80941Smrg 222b8e80941Smrgstatic void 223b8e80941Smrggather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, 224b8e80941Smrg struct radv_shader_info *info) 225b8e80941Smrg{ 226b8e80941Smrg switch (instr->intrinsic) { 227b8e80941Smrg case nir_intrinsic_interp_deref_at_sample: 228b8e80941Smrg info->ps.needs_sample_positions = true; 229b8e80941Smrg break; 230b8e80941Smrg case nir_intrinsic_load_draw_id: 231b8e80941Smrg info->vs.needs_draw_id = true; 232b8e80941Smrg break; 233b8e80941Smrg case nir_intrinsic_load_instance_id: 234b8e80941Smrg info->vs.needs_instance_id = true; 235b8e80941Smrg break; 236b8e80941Smrg case nir_intrinsic_load_num_work_groups: 237b8e80941Smrg info->cs.uses_grid_size = true; 238b8e80941Smrg break; 239b8e80941Smrg case nir_intrinsic_load_local_invocation_id: 240b8e80941Smrg case nir_intrinsic_load_work_group_id: { 241b8e80941Smrg unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa); 242b8e80941Smrg while (mask) { 243b8e80941Smrg unsigned i = u_bit_scan(&mask); 244b8e80941Smrg 245b8e80941Smrg if (instr->intrinsic == nir_intrinsic_load_work_group_id) 246b8e80941Smrg info->cs.uses_block_id[i] = true; 247b8e80941Smrg else 248b8e80941Smrg info->cs.uses_thread_id[i] = true; 249b8e80941Smrg } 250b8e80941Smrg break; 251b8e80941Smrg } 252b8e80941Smrg case nir_intrinsic_load_local_invocation_index: 253b8e80941Smrg case nir_intrinsic_load_subgroup_id: 254b8e80941Smrg case nir_intrinsic_load_num_subgroups: 255b8e80941Smrg info->cs.uses_local_invocation_idx = true; 256b8e80941Smrg break; 257b8e80941Smrg case nir_intrinsic_load_sample_id: 258b8e80941Smrg info->ps.force_persample = true; 259b8e80941Smrg break; 260b8e80941Smrg case nir_intrinsic_load_sample_pos: 261b8e80941Smrg info->ps.force_persample = true; 262b8e80941Smrg break; 263b8e80941Smrg case nir_intrinsic_load_view_index: 264b8e80941Smrg info->needs_multiview_view_index = true; 265b8e80941Smrg if (nir->info.stage == MESA_SHADER_FRAGMENT) 266b8e80941Smrg info->ps.layer_input = true; 267b8e80941Smrg break; 268b8e80941Smrg case nir_intrinsic_load_invocation_id: 269b8e80941Smrg info->uses_invocation_id = true; 270b8e80941Smrg break; 271b8e80941Smrg case nir_intrinsic_load_primitive_id: 272b8e80941Smrg info->uses_prim_id = true; 273b8e80941Smrg break; 274b8e80941Smrg case nir_intrinsic_load_push_constant: 275b8e80941Smrg gather_push_constant_info(nir, instr, info); 276b8e80941Smrg break; 277b8e80941Smrg case nir_intrinsic_vulkan_resource_index: 278b8e80941Smrg info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr)); 279b8e80941Smrg break; 280b8e80941Smrg case nir_intrinsic_image_deref_load: 281b8e80941Smrg case nir_intrinsic_image_deref_store: 282b8e80941Smrg case nir_intrinsic_image_deref_atomic_add: 283b8e80941Smrg case nir_intrinsic_image_deref_atomic_min: 284b8e80941Smrg case nir_intrinsic_image_deref_atomic_max: 285b8e80941Smrg case nir_intrinsic_image_deref_atomic_and: 286b8e80941Smrg case nir_intrinsic_image_deref_atomic_or: 287b8e80941Smrg case nir_intrinsic_image_deref_atomic_xor: 288b8e80941Smrg case nir_intrinsic_image_deref_atomic_exchange: 289b8e80941Smrg case nir_intrinsic_image_deref_atomic_comp_swap: 290b8e80941Smrg case nir_intrinsic_image_deref_size: { 291b8e80941Smrg nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr)); 292b8e80941Smrg const struct glsl_type *type = glsl_without_array(var->type); 293b8e80941Smrg 294b8e80941Smrg enum glsl_sampler_dim dim = glsl_get_sampler_dim(type); 295b8e80941Smrg if (dim == GLSL_SAMPLER_DIM_SUBPASS || 296b8e80941Smrg dim == GLSL_SAMPLER_DIM_SUBPASS_MS) { 297b8e80941Smrg info->ps.layer_input = true; 298b8e80941Smrg info->ps.uses_input_attachments = true; 299b8e80941Smrg } 300b8e80941Smrg mark_sampler_desc(var, info); 301b8e80941Smrg 302b8e80941Smrg if (instr->intrinsic == nir_intrinsic_image_deref_store || 303b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_add || 304b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_min || 305b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_max || 306b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_and || 307b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_or || 308b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_xor || 309b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_exchange || 310b8e80941Smrg instr->intrinsic == nir_intrinsic_image_deref_atomic_comp_swap) { 311b8e80941Smrg if (nir->info.stage == MESA_SHADER_FRAGMENT) 312b8e80941Smrg info->ps.writes_memory = true; 313b8e80941Smrg } 314b8e80941Smrg break; 315b8e80941Smrg } 316b8e80941Smrg case nir_intrinsic_store_ssbo: 317b8e80941Smrg case nir_intrinsic_ssbo_atomic_add: 318b8e80941Smrg case nir_intrinsic_ssbo_atomic_imin: 319b8e80941Smrg case nir_intrinsic_ssbo_atomic_umin: 320b8e80941Smrg case nir_intrinsic_ssbo_atomic_imax: 321b8e80941Smrg case nir_intrinsic_ssbo_atomic_umax: 322b8e80941Smrg case nir_intrinsic_ssbo_atomic_and: 323b8e80941Smrg case nir_intrinsic_ssbo_atomic_or: 324b8e80941Smrg case nir_intrinsic_ssbo_atomic_xor: 325b8e80941Smrg case nir_intrinsic_ssbo_atomic_exchange: 326b8e80941Smrg case nir_intrinsic_ssbo_atomic_comp_swap: 327b8e80941Smrg if (nir->info.stage == MESA_SHADER_FRAGMENT) 328b8e80941Smrg info->ps.writes_memory = true; 329b8e80941Smrg break; 330b8e80941Smrg case nir_intrinsic_load_deref: 331b8e80941Smrg gather_intrinsic_load_deref_info(nir, instr, info); 332b8e80941Smrg break; 333b8e80941Smrg case nir_intrinsic_store_deref: 334b8e80941Smrg gather_intrinsic_store_deref_info(nir, instr, info); 335b8e80941Smrg break; 336b8e80941Smrg default: 337b8e80941Smrg break; 338b8e80941Smrg } 339b8e80941Smrg} 340b8e80941Smrg 341b8e80941Smrgstatic void 342b8e80941Smrggather_tex_info(const nir_shader *nir, const nir_tex_instr *instr, 343b8e80941Smrg struct radv_shader_info *info) 344b8e80941Smrg{ 345b8e80941Smrg for (unsigned i = 0; i < instr->num_srcs; i++) { 346b8e80941Smrg switch (instr->src[i].src_type) { 347b8e80941Smrg case nir_tex_src_texture_deref: 348b8e80941Smrg mark_sampler_desc(nir_deref_instr_get_variable(nir_src_as_deref(instr->src[i].src)), info); 349b8e80941Smrg break; 350b8e80941Smrg case nir_tex_src_sampler_deref: 351b8e80941Smrg mark_sampler_desc(nir_deref_instr_get_variable(nir_src_as_deref(instr->src[i].src)), info); 352b8e80941Smrg break; 353b8e80941Smrg default: 354b8e80941Smrg break; 355b8e80941Smrg } 356b8e80941Smrg } 357b8e80941Smrg} 358b8e80941Smrg 359b8e80941Smrgstatic void 360b8e80941Smrggather_info_block(const nir_shader *nir, const nir_block *block, 361b8e80941Smrg struct radv_shader_info *info) 362b8e80941Smrg{ 363b8e80941Smrg nir_foreach_instr(instr, block) { 364b8e80941Smrg switch (instr->type) { 365b8e80941Smrg case nir_instr_type_intrinsic: 366b8e80941Smrg gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info); 367b8e80941Smrg break; 368b8e80941Smrg case nir_instr_type_tex: 369b8e80941Smrg gather_tex_info(nir, nir_instr_as_tex(instr), info); 370b8e80941Smrg break; 371b8e80941Smrg default: 372b8e80941Smrg break; 373b8e80941Smrg } 374b8e80941Smrg } 375b8e80941Smrg} 376b8e80941Smrg 377b8e80941Smrgstatic void 378b8e80941Smrggather_info_input_decl_vs(const nir_shader *nir, const nir_variable *var, 379b8e80941Smrg struct radv_shader_info *info) 380b8e80941Smrg{ 381b8e80941Smrg int idx = var->data.location; 382b8e80941Smrg 383b8e80941Smrg if (idx >= VERT_ATTRIB_GENERIC0 && idx <= VERT_ATTRIB_GENERIC15) 384b8e80941Smrg info->vs.has_vertex_buffers = true; 385b8e80941Smrg} 386b8e80941Smrg 387b8e80941Smrgstatic void 388b8e80941Smrggather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var, 389b8e80941Smrg struct radv_shader_info *info) 390b8e80941Smrg{ 391b8e80941Smrg unsigned attrib_count = glsl_count_attribute_slots(var->type, false); 392b8e80941Smrg const struct glsl_type *type = glsl_without_array(var->type); 393b8e80941Smrg int idx = var->data.location; 394b8e80941Smrg 395b8e80941Smrg switch (idx) { 396b8e80941Smrg case VARYING_SLOT_PNTC: 397b8e80941Smrg info->ps.has_pcoord = true; 398b8e80941Smrg break; 399b8e80941Smrg case VARYING_SLOT_PRIMITIVE_ID: 400b8e80941Smrg info->ps.prim_id_input = true; 401b8e80941Smrg break; 402b8e80941Smrg case VARYING_SLOT_LAYER: 403b8e80941Smrg info->ps.layer_input = true; 404b8e80941Smrg break; 405b8e80941Smrg case VARYING_SLOT_CLIP_DIST0: 406b8e80941Smrg case VARYING_SLOT_CLIP_DIST1: 407b8e80941Smrg info->ps.num_input_clips_culls += attrib_count; 408b8e80941Smrg break; 409b8e80941Smrg default: 410b8e80941Smrg break; 411b8e80941Smrg } 412b8e80941Smrg 413b8e80941Smrg if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT) { 414b8e80941Smrg if (var->data.sample) 415b8e80941Smrg info->ps.force_persample = true; 416b8e80941Smrg } 417b8e80941Smrg} 418b8e80941Smrg 419b8e80941Smrgstatic void 420b8e80941Smrggather_info_input_decl(const nir_shader *nir, const nir_variable *var, 421b8e80941Smrg struct radv_shader_info *info) 422b8e80941Smrg{ 423b8e80941Smrg switch (nir->info.stage) { 424b8e80941Smrg case MESA_SHADER_VERTEX: 425b8e80941Smrg gather_info_input_decl_vs(nir, var, info); 426b8e80941Smrg break; 427b8e80941Smrg case MESA_SHADER_FRAGMENT: 428b8e80941Smrg gather_info_input_decl_ps(nir, var, info); 429b8e80941Smrg break; 430b8e80941Smrg default: 431b8e80941Smrg break; 432b8e80941Smrg } 433b8e80941Smrg} 434b8e80941Smrg 435b8e80941Smrgstatic void 436b8e80941Smrggather_info_output_decl_ls(const nir_shader *nir, const nir_variable *var, 437b8e80941Smrg struct radv_shader_info *info) 438b8e80941Smrg{ 439b8e80941Smrg int idx = var->data.location; 440b8e80941Smrg unsigned param = shader_io_get_unique_index(idx); 441b8e80941Smrg int num_slots = glsl_count_attribute_slots(var->type, false); 442b8e80941Smrg if (var->data.compact) 443b8e80941Smrg num_slots = DIV_ROUND_UP(var->data.location_frac + glsl_get_length(var->type), 4); 444b8e80941Smrg mark_ls_output(info, param, num_slots); 445b8e80941Smrg} 446b8e80941Smrg 447b8e80941Smrgstatic void 448b8e80941Smrggather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var, 449b8e80941Smrg struct radv_shader_info *info) 450b8e80941Smrg{ 451b8e80941Smrg int idx = var->data.location; 452b8e80941Smrg 453b8e80941Smrg switch (idx) { 454b8e80941Smrg case FRAG_RESULT_DEPTH: 455b8e80941Smrg info->ps.writes_z = true; 456b8e80941Smrg break; 457b8e80941Smrg case FRAG_RESULT_STENCIL: 458b8e80941Smrg info->ps.writes_stencil = true; 459b8e80941Smrg break; 460b8e80941Smrg case FRAG_RESULT_SAMPLE_MASK: 461b8e80941Smrg info->ps.writes_sample_mask = true; 462b8e80941Smrg break; 463b8e80941Smrg default: 464b8e80941Smrg break; 465b8e80941Smrg } 466b8e80941Smrg} 467b8e80941Smrg 468b8e80941Smrgstatic void 469b8e80941Smrggather_info_output_decl_gs(const nir_shader *nir, const nir_variable *var, 470b8e80941Smrg struct radv_shader_info *info) 471b8e80941Smrg{ 472b8e80941Smrg unsigned num_components = glsl_get_component_slots(var->type); 473b8e80941Smrg unsigned stream = var->data.stream; 474b8e80941Smrg unsigned idx = var->data.location; 475b8e80941Smrg 476b8e80941Smrg assert(stream < 4); 477b8e80941Smrg 478b8e80941Smrg info->gs.max_stream = MAX2(info->gs.max_stream, stream); 479b8e80941Smrg info->gs.num_stream_output_components[stream] += num_components; 480b8e80941Smrg info->gs.output_streams[idx] = stream; 481b8e80941Smrg} 482b8e80941Smrg 483b8e80941Smrgstatic void 484b8e80941Smrggather_info_output_decl(const nir_shader *nir, const nir_variable *var, 485b8e80941Smrg struct radv_shader_info *info, 486b8e80941Smrg const struct radv_nir_compiler_options *options) 487b8e80941Smrg{ 488b8e80941Smrg switch (nir->info.stage) { 489b8e80941Smrg case MESA_SHADER_FRAGMENT: 490b8e80941Smrg gather_info_output_decl_ps(nir, var, info); 491b8e80941Smrg break; 492b8e80941Smrg case MESA_SHADER_VERTEX: 493b8e80941Smrg if (options->key.vs.as_ls) 494b8e80941Smrg gather_info_output_decl_ls(nir, var, info); 495b8e80941Smrg break; 496b8e80941Smrg case MESA_SHADER_GEOMETRY: 497b8e80941Smrg gather_info_output_decl_gs(nir, var, info); 498b8e80941Smrg break; 499b8e80941Smrg default: 500b8e80941Smrg break; 501b8e80941Smrg } 502b8e80941Smrg} 503b8e80941Smrg 504b8e80941Smrgstatic void 505b8e80941Smrggather_xfb_info(const nir_shader *nir, struct radv_shader_info *info) 506b8e80941Smrg{ 507b8e80941Smrg nir_xfb_info *xfb = nir_gather_xfb_info(nir, NULL); 508b8e80941Smrg struct radv_streamout_info *so = &info->so; 509b8e80941Smrg 510b8e80941Smrg if (!xfb) 511b8e80941Smrg return; 512b8e80941Smrg 513b8e80941Smrg assert(xfb->output_count < MAX_SO_OUTPUTS); 514b8e80941Smrg so->num_outputs = xfb->output_count; 515b8e80941Smrg 516b8e80941Smrg for (unsigned i = 0; i < xfb->output_count; i++) { 517b8e80941Smrg struct radv_stream_output *output = &so->outputs[i]; 518b8e80941Smrg 519b8e80941Smrg output->buffer = xfb->outputs[i].buffer; 520b8e80941Smrg output->stream = xfb->buffer_to_stream[xfb->outputs[i].buffer]; 521b8e80941Smrg output->offset = xfb->outputs[i].offset; 522b8e80941Smrg output->location = xfb->outputs[i].location; 523b8e80941Smrg output->component_mask = xfb->outputs[i].component_mask; 524b8e80941Smrg 525b8e80941Smrg so->enabled_stream_buffers_mask |= 526b8e80941Smrg (1 << output->buffer) << (output->stream * 4); 527b8e80941Smrg 528b8e80941Smrg } 529b8e80941Smrg 530b8e80941Smrg for (unsigned i = 0; i < NIR_MAX_XFB_BUFFERS; i++) { 531b8e80941Smrg so->strides[i] = xfb->buffers[i].stride / 4; 532b8e80941Smrg } 533b8e80941Smrg 534b8e80941Smrg ralloc_free(xfb); 535b8e80941Smrg} 536b8e80941Smrg 537b8e80941Smrgvoid 538b8e80941Smrgradv_nir_shader_info_init(struct radv_shader_info *info) 539b8e80941Smrg{ 540b8e80941Smrg /* Assume that shaders only have 32-bit push constants by default. */ 541b8e80941Smrg info->min_push_constant_used = UINT8_MAX; 542b8e80941Smrg info->has_only_32bit_push_constants = true; 543b8e80941Smrg} 544b8e80941Smrg 545b8e80941Smrgvoid 546b8e80941Smrgradv_nir_shader_info_pass(const struct nir_shader *nir, 547b8e80941Smrg const struct radv_nir_compiler_options *options, 548b8e80941Smrg struct radv_shader_info *info) 549b8e80941Smrg{ 550b8e80941Smrg struct nir_function *func = 551b8e80941Smrg (struct nir_function *)exec_list_get_head_const(&nir->functions); 552b8e80941Smrg 553b8e80941Smrg if (options->layout && options->layout->dynamic_offset_count && 554b8e80941Smrg (options->layout->dynamic_shader_stages & mesa_to_vk_shader_stage(nir->info.stage))) { 555b8e80941Smrg info->loads_push_constants = true; 556b8e80941Smrg info->loads_dynamic_offsets = true; 557b8e80941Smrg } 558b8e80941Smrg 559b8e80941Smrg nir_foreach_variable(variable, &nir->inputs) 560b8e80941Smrg gather_info_input_decl(nir, variable, info); 561b8e80941Smrg 562b8e80941Smrg nir_foreach_block(block, func->impl) { 563b8e80941Smrg gather_info_block(nir, block, info); 564b8e80941Smrg } 565b8e80941Smrg 566b8e80941Smrg nir_foreach_variable(variable, &nir->outputs) 567b8e80941Smrg gather_info_output_decl(nir, variable, info, options); 568b8e80941Smrg 569b8e80941Smrg if (nir->info.stage == MESA_SHADER_VERTEX || 570b8e80941Smrg nir->info.stage == MESA_SHADER_TESS_EVAL || 571b8e80941Smrg nir->info.stage == MESA_SHADER_GEOMETRY) 572b8e80941Smrg gather_xfb_info(nir, info); 573b8e80941Smrg} 574