This is RADV specific code.
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
common/ac_llvm_util.h \
common/ac_lower_subgroups.c \
common/ac_shader_abi.h \
- common/ac_shader_info.c \
- common/ac_shader_info.h \
common/ac_shader_util.c \
common/ac_shader_util.h
#include "llvm-c/TargetMachine.h"
#include "amd_family.h"
#include "../vulkan/radv_descriptor_set.h"
-#include "ac_shader_info.h"
#include "compiler/shader_enums.h"
struct ac_shader_binary;
struct ac_shader_config;
+++ /dev/null
-/*
- * Copyright © 2017 Red Hat
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-#include "nir/nir.h"
-#include "ac_shader_info.h"
-#include "ac_nir_to_llvm.h"
-
-static void mark_sampler_desc(const nir_variable *var,
- struct ac_shader_info *info)
-{
- info->desc_set_used_mask |= (1 << var->data.descriptor_set);
-}
-
-static void
-gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
- struct ac_shader_info *info)
-{
- switch (instr->intrinsic) {
- case nir_intrinsic_interp_var_at_sample:
- info->ps.needs_sample_positions = true;
- break;
- case nir_intrinsic_load_draw_id:
- info->vs.needs_draw_id = true;
- break;
- case nir_intrinsic_load_instance_id:
- info->vs.needs_instance_id = true;
- break;
- case nir_intrinsic_load_num_work_groups:
- info->cs.uses_grid_size = true;
- break;
- case nir_intrinsic_load_local_invocation_id:
- case nir_intrinsic_load_work_group_id: {
- unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa);
- while (mask) {
- unsigned i = u_bit_scan(&mask);
-
- if (instr->intrinsic == nir_intrinsic_load_work_group_id)
- info->cs.uses_block_id[i] = true;
- else
- info->cs.uses_thread_id[i] = true;
- }
- break;
- }
- case nir_intrinsic_load_local_invocation_index:
- case nir_intrinsic_load_subgroup_id:
- case nir_intrinsic_load_num_subgroups:
- info->cs.uses_local_invocation_idx = true;
- break;
- case nir_intrinsic_load_sample_id:
- info->ps.force_persample = true;
- break;
- case nir_intrinsic_load_sample_pos:
- info->ps.force_persample = true;
- break;
- case nir_intrinsic_load_view_index:
- info->needs_multiview_view_index = true;
- break;
- case nir_intrinsic_load_invocation_id:
- info->uses_invocation_id = true;
- break;
- case nir_intrinsic_load_primitive_id:
- info->uses_prim_id = true;
- break;
- case nir_intrinsic_load_push_constant:
- info->loads_push_constants = true;
- break;
- case nir_intrinsic_vulkan_resource_index:
- info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr));
- break;
- case nir_intrinsic_image_load:
- case nir_intrinsic_image_store:
- case nir_intrinsic_image_atomic_add:
- case nir_intrinsic_image_atomic_min:
- case nir_intrinsic_image_atomic_max:
- case nir_intrinsic_image_atomic_and:
- case nir_intrinsic_image_atomic_or:
- case nir_intrinsic_image_atomic_xor:
- case nir_intrinsic_image_atomic_exchange:
- case nir_intrinsic_image_atomic_comp_swap:
- case nir_intrinsic_image_size: {
- const struct glsl_type *type = instr->variables[0]->var->type;
- if(instr->variables[0]->deref.child)
- type = instr->variables[0]->deref.child->type;
-
- enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
- if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
- dim == GLSL_SAMPLER_DIM_SUBPASS_MS)
- info->ps.uses_input_attachments = true;
- mark_sampler_desc(instr->variables[0]->var, info);
-
- if (nir_intrinsic_image_store ||
- nir_intrinsic_image_atomic_add ||
- nir_intrinsic_image_atomic_min ||
- nir_intrinsic_image_atomic_max ||
- nir_intrinsic_image_atomic_and ||
- nir_intrinsic_image_atomic_or ||
- nir_intrinsic_image_atomic_xor ||
- nir_intrinsic_image_atomic_exchange ||
- nir_intrinsic_image_atomic_comp_swap) {
- if (nir->info.stage == MESA_SHADER_FRAGMENT)
- info->ps.writes_memory = true;
- }
- break;
- }
- case nir_intrinsic_store_ssbo:
- case nir_intrinsic_ssbo_atomic_add:
- case nir_intrinsic_ssbo_atomic_imin:
- case nir_intrinsic_ssbo_atomic_umin:
- case nir_intrinsic_ssbo_atomic_imax:
- case nir_intrinsic_ssbo_atomic_umax:
- case nir_intrinsic_ssbo_atomic_and:
- case nir_intrinsic_ssbo_atomic_or:
- case nir_intrinsic_ssbo_atomic_xor:
- case nir_intrinsic_ssbo_atomic_exchange:
- case nir_intrinsic_ssbo_atomic_comp_swap:
- if (nir->info.stage == MESA_SHADER_FRAGMENT)
- info->ps.writes_memory = true;
- break;
- case nir_intrinsic_load_var:
- if (nir->info.stage == MESA_SHADER_VERTEX) {
- nir_deref_var *dvar = instr->variables[0];
- nir_variable *var = dvar->var;
-
- if (var->data.mode == nir_var_shader_in) {
- unsigned idx = var->data.location;
- uint8_t mask =
- nir_ssa_def_components_read(&instr->dest.ssa) << var->data.location_frac;
- info->vs.input_usage_mask[idx] |= mask;
- }
- }
- break;
- case nir_intrinsic_store_var: {
- nir_deref_var *dvar = instr->variables[0];
- nir_variable *var = dvar->var;
-
- if (var->data.mode == nir_var_shader_out) {
- unsigned idx = var->data.location;
- unsigned comp = var->data.location_frac;
-
- if (nir->info.stage == MESA_SHADER_VERTEX) {
- info->vs.output_usage_mask[idx] |=
- instr->const_index[0] << comp;
- } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) {
- info->tes.output_usage_mask[idx] |=
- instr->const_index[0] << comp;
- }
- }
- break;
- }
- default:
- break;
- }
-}
-
-static void
-gather_tex_info(const nir_shader *nir, const nir_tex_instr *instr,
- struct ac_shader_info *info)
-{
- if (instr->sampler)
- mark_sampler_desc(instr->sampler->var, info);
- if (instr->texture)
- mark_sampler_desc(instr->texture->var, info);
-}
-
-static void
-gather_info_block(const nir_shader *nir, const nir_block *block,
- struct ac_shader_info *info)
-{
- nir_foreach_instr(instr, block) {
- switch (instr->type) {
- case nir_instr_type_intrinsic:
- gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info);
- break;
- case nir_instr_type_tex:
- gather_tex_info(nir, nir_instr_as_tex(instr), info);
- break;
- default:
- break;
- }
- }
-}
-
-static void
-gather_info_input_decl_vs(const nir_shader *nir, const nir_variable *var,
- struct ac_shader_info *info)
-{
- int idx = var->data.location;
-
- if (idx >= VERT_ATTRIB_GENERIC0 && idx <= VERT_ATTRIB_GENERIC15)
- info->vs.has_vertex_buffers = true;
-}
-
-static void
-gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var,
- struct ac_shader_info *info)
-{
- const struct glsl_type *type = glsl_without_array(var->type);
- int idx = var->data.location;
-
- switch (idx) {
- case VARYING_SLOT_PNTC:
- info->ps.has_pcoord = true;
- break;
- case VARYING_SLOT_PRIMITIVE_ID:
- info->ps.prim_id_input = true;
- break;
- case VARYING_SLOT_LAYER:
- info->ps.layer_input = true;
- break;
- default:
- break;
- }
-
- if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT) {
- if (var->data.sample)
- info->ps.force_persample = true;
- }
-}
-
-static void
-gather_info_input_decl(const nir_shader *nir, const nir_variable *var,
- struct ac_shader_info *info)
-{
- switch (nir->info.stage) {
- case MESA_SHADER_VERTEX:
- gather_info_input_decl_vs(nir, var, info);
- break;
- case MESA_SHADER_FRAGMENT:
- gather_info_input_decl_ps(nir, var, info);
- break;
- default:
- break;
- }
-}
-
-static void
-gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var,
- struct ac_shader_info *info)
-{
- int idx = var->data.location;
-
- switch (idx) {
- case FRAG_RESULT_DEPTH:
- info->ps.writes_z = true;
- break;
- case FRAG_RESULT_STENCIL:
- info->ps.writes_stencil = true;
- break;
- case FRAG_RESULT_SAMPLE_MASK:
- info->ps.writes_sample_mask = true;
- break;
- default:
- break;
- }
-}
-
-static void
-gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
- struct ac_shader_info *info)
-{
- switch (nir->info.stage) {
- case MESA_SHADER_FRAGMENT:
- gather_info_output_decl_ps(nir, var, info);
- break;
- default:
- break;
- }
-}
-
-void
-ac_nir_shader_info_pass(const struct nir_shader *nir,
- const struct ac_nir_compiler_options *options,
- struct ac_shader_info *info)
-{
- struct nir_function *func =
- (struct nir_function *)exec_list_get_head_const(&nir->functions);
-
- if (options->layout->dynamic_offset_count)
- info->loads_push_constants = true;
-
- nir_foreach_variable(variable, &nir->inputs)
- gather_info_input_decl(nir, variable, info);
-
- nir_foreach_block(block, func->impl) {
- gather_info_block(nir, block, info);
- }
-
- nir_foreach_variable(variable, &nir->outputs)
- gather_info_output_decl(nir, variable, info);
-}
+++ /dev/null
-/*
- * Copyright © 2017 Red Hat
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef AC_SHADER_INFO_H
-#define AC_SHADER_INFO_H
-
-#include "compiler/shader_enums.h"
-
-struct nir_shader;
-struct ac_nir_compiler_options;
-
-struct ac_shader_info {
- bool loads_push_constants;
- uint32_t desc_set_used_mask;
- bool needs_multiview_view_index;
- bool uses_invocation_id;
- bool uses_prim_id;
- struct {
- uint8_t input_usage_mask[VERT_ATTRIB_MAX];
- uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1];
- bool has_vertex_buffers; /* needs vertex buffers and base/start */
- bool needs_draw_id;
- bool needs_instance_id;
- } vs;
- struct {
- uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1];
- } tes;
- struct {
- bool force_persample;
- bool needs_sample_positions;
- bool uses_input_attachments;
- bool writes_memory;
- bool writes_z;
- bool writes_stencil;
- bool writes_sample_mask;
- bool has_pcoord;
- bool prim_id_input;
- bool layer_input;
- } ps;
- struct {
- bool uses_grid_size;
- bool uses_block_id[3];
- bool uses_thread_id[3];
- bool uses_local_invocation_idx;
- } cs;
-};
-
-/* A NIR pass to gather all the info needed to optimise the allocation patterns
- * for the RADV user sgprs
- */
-void
-ac_nir_shader_info_pass(const struct nir_shader *nir,
- const struct ac_nir_compiler_options *options,
- struct ac_shader_info *info);
-
-#endif
'ac_llvm_util.h',
'ac_lower_subgroups.c',
'ac_shader_abi.h',
- 'ac_shader_info.c',
- 'ac_shader_info.h',
'ac_shader_util.c',
'ac_shader_util.h',
'ac_nir_to_llvm.c',
radv_private.h \
radv_radeon_winsys.h \
radv_shader.c \
+ radv_shader_info.c \
radv_shader.h \
radv_query.c \
radv_util.c \
'radv_radeon_winsys.h',
'radv_shader.c',
'radv_shader.h',
+ 'radv_shader_info.c',
'radv_query.c',
'radv_util.c',
'radv_util.h',
memset(shader_info, 0, sizeof(*shader_info));
for(int i = 0; i < shader_count; ++i)
- ac_nir_shader_info_pass(shaders[i], options, &shader_info->info);
+ radv_nir_shader_info_pass(shaders[i], options, &shader_info->info);
for (i = 0; i < RADV_UD_MAX_SETS; i++)
shader_info->user_sgprs_locs.descriptor_sets[i].sgpr_idx = -1;
const struct ac_nir_compiler_options *options,
bool dump_shader);
+/* radv_shader_info.h */
+struct radv_shader_info;
+
+void radv_nir_shader_info_pass(const struct nir_shader *nir,
+ const struct ac_nir_compiler_options *options,
+ struct radv_shader_info *info);
+
struct radeon_winsys_sem;
#define RADV_DEFINE_HANDLE_CASTS(__radv_type, __VkType) \
case MESA_SHADER_FRAGMENT:
break;
case MESA_SHADER_COMPUTE: {
- struct ac_shader_info *info = &variant->info.info;
+ struct radv_shader_info *info = &variant->info.info;
variant->rsrc2 |=
S_00B84C_TGID_X_EN(info->cs.uses_block_id[0]) |
S_00B84C_TGID_Y_EN(info->cs.uses_block_id[1]) |
if (device->physical_device->rad_info.chip_class >= GFX9 &&
stage == MESA_SHADER_GEOMETRY) {
- struct ac_shader_info *info = &variant->info.info;
+ struct radv_shader_info *info = &variant->info.info;
unsigned es_type = variant->info.gs.es_type;
unsigned gs_vgpr_comp_cnt, es_vgpr_comp_cnt;
char data[0];
};
+struct radv_shader_info {
+ bool loads_push_constants;
+ uint32_t desc_set_used_mask;
+ bool needs_multiview_view_index;
+ bool uses_invocation_id;
+ bool uses_prim_id;
+ struct {
+ uint8_t input_usage_mask[VERT_ATTRIB_MAX];
+ uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1];
+ bool has_vertex_buffers; /* needs vertex buffers and base/start */
+ bool needs_draw_id;
+ bool needs_instance_id;
+ } vs;
+ struct {
+ uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1];
+ } tes;
+ struct {
+ bool force_persample;
+ bool needs_sample_positions;
+ bool uses_input_attachments;
+ bool writes_memory;
+ bool writes_z;
+ bool writes_stencil;
+ bool writes_sample_mask;
+ bool has_pcoord;
+ bool prim_id_input;
+ bool layer_input;
+ } ps;
+ struct {
+ bool uses_grid_size;
+ bool uses_block_id[3];
+ bool uses_thread_id[3];
+ bool uses_local_invocation_idx;
+ } cs;
+};
+
struct radv_userdata_info {
int8_t sgpr_idx;
uint8_t num_sgprs;
struct radv_shader_variant_info {
struct radv_userdata_locations user_sgprs_locs;
- struct ac_shader_info info;
+ struct radv_shader_info info;
unsigned num_user_sgprs;
unsigned num_input_sgprs;
unsigned num_input_vgprs;
--- /dev/null
+/*
+ * Copyright © 2017 Red Hat
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include "radv_private.h"
+#include "radv_shader.h"
+#include "nir/nir.h"
+
+static void mark_sampler_desc(const nir_variable *var,
+ struct radv_shader_info *info)
+{
+ info->desc_set_used_mask |= (1 << var->data.descriptor_set);
+}
+
+static void
+gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
+ struct radv_shader_info *info)
+{
+ switch (instr->intrinsic) {
+ case nir_intrinsic_interp_var_at_sample:
+ info->ps.needs_sample_positions = true;
+ break;
+ case nir_intrinsic_load_draw_id:
+ info->vs.needs_draw_id = true;
+ break;
+ case nir_intrinsic_load_instance_id:
+ info->vs.needs_instance_id = true;
+ break;
+ case nir_intrinsic_load_num_work_groups:
+ info->cs.uses_grid_size = true;
+ break;
+ case nir_intrinsic_load_local_invocation_id:
+ case nir_intrinsic_load_work_group_id: {
+ unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa);
+ while (mask) {
+ unsigned i = u_bit_scan(&mask);
+
+ if (instr->intrinsic == nir_intrinsic_load_work_group_id)
+ info->cs.uses_block_id[i] = true;
+ else
+ info->cs.uses_thread_id[i] = true;
+ }
+ break;
+ }
+ case nir_intrinsic_load_local_invocation_index:
+ case nir_intrinsic_load_subgroup_id:
+ case nir_intrinsic_load_num_subgroups:
+ info->cs.uses_local_invocation_idx = true;
+ break;
+ case nir_intrinsic_load_sample_id:
+ info->ps.force_persample = true;
+ break;
+ case nir_intrinsic_load_sample_pos:
+ info->ps.force_persample = true;
+ break;
+ case nir_intrinsic_load_view_index:
+ info->needs_multiview_view_index = true;
+ break;
+ case nir_intrinsic_load_invocation_id:
+ info->uses_invocation_id = true;
+ break;
+ case nir_intrinsic_load_primitive_id:
+ info->uses_prim_id = true;
+ break;
+ case nir_intrinsic_load_push_constant:
+ info->loads_push_constants = true;
+ break;
+ case nir_intrinsic_vulkan_resource_index:
+ info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr));
+ break;
+ case nir_intrinsic_image_load:
+ case nir_intrinsic_image_store:
+ case nir_intrinsic_image_atomic_add:
+ case nir_intrinsic_image_atomic_min:
+ case nir_intrinsic_image_atomic_max:
+ case nir_intrinsic_image_atomic_and:
+ case nir_intrinsic_image_atomic_or:
+ case nir_intrinsic_image_atomic_xor:
+ case nir_intrinsic_image_atomic_exchange:
+ case nir_intrinsic_image_atomic_comp_swap:
+ case nir_intrinsic_image_size: {
+ const struct glsl_type *type = instr->variables[0]->var->type;
+ if(instr->variables[0]->deref.child)
+ type = instr->variables[0]->deref.child->type;
+
+ enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
+ if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
+ dim == GLSL_SAMPLER_DIM_SUBPASS_MS)
+ info->ps.uses_input_attachments = true;
+ mark_sampler_desc(instr->variables[0]->var, info);
+
+ if (nir_intrinsic_image_store ||
+ nir_intrinsic_image_atomic_add ||
+ nir_intrinsic_image_atomic_min ||
+ nir_intrinsic_image_atomic_max ||
+ nir_intrinsic_image_atomic_and ||
+ nir_intrinsic_image_atomic_or ||
+ nir_intrinsic_image_atomic_xor ||
+ nir_intrinsic_image_atomic_exchange ||
+ nir_intrinsic_image_atomic_comp_swap) {
+ if (nir->info.stage == MESA_SHADER_FRAGMENT)
+ info->ps.writes_memory = true;
+ }
+ break;
+ }
+ case nir_intrinsic_store_ssbo:
+ case nir_intrinsic_ssbo_atomic_add:
+ case nir_intrinsic_ssbo_atomic_imin:
+ case nir_intrinsic_ssbo_atomic_umin:
+ case nir_intrinsic_ssbo_atomic_imax:
+ case nir_intrinsic_ssbo_atomic_umax:
+ case nir_intrinsic_ssbo_atomic_and:
+ case nir_intrinsic_ssbo_atomic_or:
+ case nir_intrinsic_ssbo_atomic_xor:
+ case nir_intrinsic_ssbo_atomic_exchange:
+ case nir_intrinsic_ssbo_atomic_comp_swap:
+ if (nir->info.stage == MESA_SHADER_FRAGMENT)
+ info->ps.writes_memory = true;
+ break;
+ case nir_intrinsic_load_var:
+ if (nir->info.stage == MESA_SHADER_VERTEX) {
+ nir_deref_var *dvar = instr->variables[0];
+ nir_variable *var = dvar->var;
+
+ if (var->data.mode == nir_var_shader_in) {
+ unsigned idx = var->data.location;
+ uint8_t mask =
+ nir_ssa_def_components_read(&instr->dest.ssa) << var->data.location_frac;
+ info->vs.input_usage_mask[idx] |= mask;
+ }
+ }
+ break;
+ case nir_intrinsic_store_var: {
+ nir_deref_var *dvar = instr->variables[0];
+ nir_variable *var = dvar->var;
+
+ if (var->data.mode == nir_var_shader_out) {
+ unsigned idx = var->data.location;
+ unsigned comp = var->data.location_frac;
+
+ if (nir->info.stage == MESA_SHADER_VERTEX) {
+ info->vs.output_usage_mask[idx] |=
+ instr->const_index[0] << comp;
+ } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) {
+ info->tes.output_usage_mask[idx] |=
+ instr->const_index[0] << comp;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void
+gather_tex_info(const nir_shader *nir, const nir_tex_instr *instr,
+ struct radv_shader_info *info)
+{
+ if (instr->sampler)
+ mark_sampler_desc(instr->sampler->var, info);
+ if (instr->texture)
+ mark_sampler_desc(instr->texture->var, info);
+}
+
+static void
+gather_info_block(const nir_shader *nir, const nir_block *block,
+ struct radv_shader_info *info)
+{
+ nir_foreach_instr(instr, block) {
+ switch (instr->type) {
+ case nir_instr_type_intrinsic:
+ gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info);
+ break;
+ case nir_instr_type_tex:
+ gather_tex_info(nir, nir_instr_as_tex(instr), info);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void
+gather_info_input_decl_vs(const nir_shader *nir, const nir_variable *var,
+ struct radv_shader_info *info)
+{
+ int idx = var->data.location;
+
+ if (idx >= VERT_ATTRIB_GENERIC0 && idx <= VERT_ATTRIB_GENERIC15)
+ info->vs.has_vertex_buffers = true;
+}
+
+static void
+gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var,
+ struct radv_shader_info *info)
+{
+ const struct glsl_type *type = glsl_without_array(var->type);
+ int idx = var->data.location;
+
+ switch (idx) {
+ case VARYING_SLOT_PNTC:
+ info->ps.has_pcoord = true;
+ break;
+ case VARYING_SLOT_PRIMITIVE_ID:
+ info->ps.prim_id_input = true;
+ break;
+ case VARYING_SLOT_LAYER:
+ info->ps.layer_input = true;
+ break;
+ default:
+ break;
+ }
+
+ if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT) {
+ if (var->data.sample)
+ info->ps.force_persample = true;
+ }
+}
+
+static void
+gather_info_input_decl(const nir_shader *nir, const nir_variable *var,
+ struct radv_shader_info *info)
+{
+ switch (nir->info.stage) {
+ case MESA_SHADER_VERTEX:
+ gather_info_input_decl_vs(nir, var, info);
+ break;
+ case MESA_SHADER_FRAGMENT:
+ gather_info_input_decl_ps(nir, var, info);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var,
+ struct radv_shader_info *info)
+{
+ int idx = var->data.location;
+
+ switch (idx) {
+ case FRAG_RESULT_DEPTH:
+ info->ps.writes_z = true;
+ break;
+ case FRAG_RESULT_STENCIL:
+ info->ps.writes_stencil = true;
+ break;
+ case FRAG_RESULT_SAMPLE_MASK:
+ info->ps.writes_sample_mask = true;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
+ struct radv_shader_info *info)
+{
+ switch (nir->info.stage) {
+ case MESA_SHADER_FRAGMENT:
+ gather_info_output_decl_ps(nir, var, info);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+radv_nir_shader_info_pass(const struct nir_shader *nir,
+ const struct ac_nir_compiler_options *options,
+ struct radv_shader_info *info)
+{
+ struct nir_function *func =
+ (struct nir_function *)exec_list_get_head_const(&nir->functions);
+
+ if (options->layout->dynamic_offset_count)
+ info->loads_push_constants = true;
+
+ nir_foreach_variable(variable, &nir->inputs)
+ gather_info_input_decl(nir, variable, info);
+
+ nir_foreach_block(block, func->impl) {
+ gather_info_block(nir, block, info);
+ }
+
+ nir_foreach_variable(variable, &nir->outputs)
+ gather_info_output_decl(nir, variable, info);
+}