radv: gather more info about push constants
[mesa.git] / src / amd / vulkan / radv_shader_info.c
index f7888ec6a6af5c4ba00854ecab9faa7879a7b940..bece7b20f024aa891b8cee2fb1507060ae1dde77 100644 (file)
@@ -101,7 +101,7 @@ gather_intrinsic_load_deref_info(const nir_shader *nir,
        case MESA_SHADER_VERTEX: {
                nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
 
-               if (var->data.mode == nir_var_shader_in) {
+               if (var && var->data.mode == nir_var_shader_in) {
                        unsigned idx = var->data.location;
                        uint8_t mask = nir_ssa_def_components_read(&instr->dest.ssa);
 
@@ -150,7 +150,7 @@ gather_intrinsic_store_deref_info(const nir_shader *nir,
 {
        nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
 
-       if (var->data.mode == nir_var_shader_out) {
+       if (var && var->data.mode == nir_var_shader_out) {
                unsigned idx = var->data.location;
 
                switch (nir->info.stage) {
@@ -190,6 +190,33 @@ gather_intrinsic_store_deref_info(const nir_shader *nir,
        }
 }
 
+static void
+gather_push_constant_info(const nir_shader *nir,
+                         const nir_intrinsic_instr *instr,
+                         struct radv_shader_info *info)
+{
+       nir_const_value *cval = nir_src_as_const_value(instr->src[0]);
+       int base = nir_intrinsic_base(instr);
+       int range = nir_intrinsic_range(instr);
+
+       if (!cval) {
+               info->has_indirect_push_constants = true;
+       } else {
+               uint32_t min = base + cval->u32[0];
+               uint32_t max = min + instr->num_components * 4;
+
+               info->max_push_constant_used =
+                       MAX2(max, info->max_push_constant_used);
+               info->min_push_constant_used =
+                       MIN2(min, info->min_push_constant_used);
+       }
+
+       if (instr->dest.ssa.bit_size != 32)
+               info->has_only_32bit_push_constants = false;
+
+       info->loads_push_constants = true;
+}
+
 static void
 gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
                      struct radv_shader_info *info)
@@ -243,7 +270,7 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
                info->uses_prim_id = true;
                break;
        case nir_intrinsic_load_push_constant:
-               info->loads_push_constants = true;
+               gather_push_constant_info(nir, instr, info);
                break;
        case nir_intrinsic_vulkan_resource_index:
                info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr));
@@ -270,15 +297,15 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
                }
                mark_sampler_desc(var, info);
 
-               if (nir_intrinsic_image_deref_store ||
-                   nir_intrinsic_image_deref_atomic_add ||
-                   nir_intrinsic_image_deref_atomic_min ||
-                   nir_intrinsic_image_deref_atomic_max ||
-                   nir_intrinsic_image_deref_atomic_and ||
-                   nir_intrinsic_image_deref_atomic_or ||
-                   nir_intrinsic_image_deref_atomic_xor ||
-                   nir_intrinsic_image_deref_atomic_exchange ||
-                   nir_intrinsic_image_deref_atomic_comp_swap) {
+               if (instr->intrinsic == nir_intrinsic_image_deref_store ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_add ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_min ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_max ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_and ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_or ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_xor ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_exchange ||
+                   instr->intrinsic == nir_intrinsic_image_deref_atomic_comp_swap) {
                        if (nir->info.stage == MESA_SHADER_FRAGMENT)
                                info->ps.writes_memory = true;
                }
@@ -504,6 +531,14 @@ gather_xfb_info(const nir_shader *nir, struct radv_shader_info *info)
        ralloc_free(xfb);
 }
 
+void
+radv_nir_shader_info_init(struct radv_shader_info *info)
+{
+       /* Assume that shaders only have 32-bit push constants by default. */
+       info->min_push_constant_used = UINT8_MAX;
+       info->has_only_32bit_push_constants = true;
+}
+
 void
 radv_nir_shader_info_pass(const struct nir_shader *nir,
                          const struct radv_nir_compiler_options *options,
@@ -512,8 +547,10 @@ radv_nir_shader_info_pass(const struct nir_shader *nir,
        struct nir_function *func =
                (struct nir_function *)exec_list_get_head_const(&nir->functions);
 
-       if (options->layout && options->layout->dynamic_offset_count)
+       if (options->layout && options->layout->dynamic_offset_count &&
+           (options->layout->dynamic_shader_stages & mesa_to_vk_shader_stage(nir->info.stage))) {
                info->loads_push_constants = true;
+       }
 
        nir_foreach_variable(variable, &nir->inputs)
                gather_info_input_decl(nir, variable, info);