radeonsi: fork tgsi_shader_info and tgsi_tessctrl_info
[mesa.git] / src / gallium / drivers / radeonsi / si_shader_nir.c
index aa82a7bd371d6d9d69d9f2b44d13ef8cd3ce0a40..331103fe3a3bcbd19c7f9c73fb74e154bfbdf83e 100644 (file)
@@ -128,7 +128,7 @@ static void gather_usage(const nir_deref_instr *deref,
 static void gather_intrinsic_load_deref_input_info(const nir_shader *nir,
                                                   const nir_intrinsic_instr *instr,
                                                   const nir_deref_instr *deref,
-                                                  struct tgsi_shader_info *info)
+                                                  struct si_shader_info *info)
 {
        switch (nir->info.stage) {
        case MESA_SHADER_VERTEX:
@@ -141,7 +141,7 @@ static void gather_intrinsic_load_deref_input_info(const nir_shader *nir,
 static void gather_intrinsic_load_deref_output_info(const nir_shader *nir,
                                                    const nir_intrinsic_instr *instr,
                                                    nir_variable *var,
-                                                   struct tgsi_shader_info *info)
+                                                   struct si_shader_info *info)
 {
        assert(var && var->data.mode == nir_var_shader_out);
 
@@ -167,7 +167,7 @@ static void gather_intrinsic_load_deref_output_info(const nir_shader *nir,
 static void gather_intrinsic_store_deref_output_info(const nir_shader *nir,
                                                     const nir_intrinsic_instr *instr,
                                                     const nir_deref_instr *deref,
-                                                    struct tgsi_shader_info *info)
+                                                    struct si_shader_info *info)
 {
        switch (nir->info.stage) {
        case MESA_SHADER_VERTEX: /* needed by LS, ES */
@@ -181,7 +181,7 @@ static void gather_intrinsic_store_deref_output_info(const nir_shader *nir,
 }
 
 static void scan_instruction(const struct nir_shader *nir,
-                            struct tgsi_shader_info *info,
+                            struct si_shader_info *info,
                             nir_instr *instr)
 {
        if (instr->type == nir_instr_type_alu) {
@@ -236,6 +236,11 @@ static void scan_instruction(const struct nir_shader *nir,
                case nir_intrinsic_load_num_work_groups:
                        info->uses_grid_size = true;
                        break;
+               case nir_intrinsic_load_local_invocation_index:
+               case nir_intrinsic_load_subgroup_id:
+               case nir_intrinsic_load_num_subgroups:
+                       info->uses_subgroup_info = true;
+                       break;
                case nir_intrinsic_load_local_group_size:
                        /* The block size is translated to IMM with a fixed block size. */
                        if (info->properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] == 0)
@@ -426,7 +431,7 @@ static void scan_instruction(const struct nir_shader *nir,
 }
 
 void si_nir_scan_tess_ctrl(const struct nir_shader *nir,
-                          struct tgsi_tessctrl_info *out)
+                          struct si_tessctrl_info *out)
 {
        memset(out, 0, sizeof(*out));
 
@@ -440,7 +445,7 @@ void si_nir_scan_tess_ctrl(const struct nir_shader *nir,
 static void scan_output_slot(const nir_variable *var,
                             unsigned var_idx,
                             unsigned component, unsigned num_components,
-                            struct tgsi_shader_info *info)
+                            struct si_shader_info *info)
 {
        assert(component + num_components <= 4);
        assert(component < 4);
@@ -466,8 +471,8 @@ static void scan_output_slot(const nir_variable *var,
        ubyte usagemask = ((1 << num_components) - 1) << component;
 
        unsigned gs_out_streams;
-       if (var->data.stream & (1u << 31)) {
-               gs_out_streams = var->data.stream & ~(1u << 31);
+       if (var->data.stream & NIR_STREAM_PACKED) {
+               gs_out_streams = var->data.stream & ~NIR_STREAM_PACKED;
        } else {
                assert(var->data.stream < 4);
                gs_out_streams = 0;
@@ -540,9 +545,9 @@ static void scan_output_slot(const nir_variable *var,
 static void scan_output_helper(const nir_variable *var,
                               unsigned location,
                               const struct glsl_type *type,
-                              struct tgsi_shader_info *info)
+                              struct si_shader_info *info)
 {
-       if (glsl_type_is_struct(type)) {
+       if (glsl_type_is_struct(type) || glsl_type_is_interface(type)) {
                for (unsigned i = 0; i < glsl_get_length(type); i++) {
                        const struct glsl_type *ft = glsl_get_struct_field(type, i);
                        scan_output_helper(var, location, ft, info);
@@ -586,7 +591,7 @@ static void scan_output_helper(const nir_variable *var,
 }
 
 void si_nir_scan_shader(const struct nir_shader *nir,
-                       struct tgsi_shader_info *info)
+                       struct si_shader_info *info)
 {
        nir_function *func;
        unsigned i;
@@ -801,14 +806,10 @@ void si_nir_scan_shader(const struct nir_shader *nir,
        }
 }
 
-void
+static void
 si_nir_opts(struct nir_shader *nir)
 {
        bool progress;
-        unsigned lower_flrp =
-                (nir->options->lower_flrp16 ? 16 : 0) |
-                (nir->options->lower_flrp32 ? 32 : 0) |
-                (nir->options->lower_flrp64 ? 64 : 0);
 
        do {
                progress = false;
@@ -839,7 +840,12 @@ si_nir_opts(struct nir_shader *nir)
                NIR_PASS(progress, nir, nir_opt_algebraic);
                NIR_PASS(progress, nir, nir_opt_constant_folding);
 
-               if (lower_flrp != 0) {
+               if (!nir->info.flrp_lowered) {
+                       unsigned lower_flrp =
+                               (nir->options->lower_flrp16 ? 16 : 0) |
+                               (nir->options->lower_flrp32 ? 32 : 0) |
+                               (nir->options->lower_flrp64 ? 64 : 0);
+                       assert(lower_flrp);
                        bool lower_flrp_progress = false;
 
                        NIR_PASS(lower_flrp_progress, nir, nir_lower_flrp,
@@ -855,7 +861,7 @@ si_nir_opts(struct nir_shader *nir)
                        /* Nothing should rematerialize any flrps, so we only
                         * need to do this lowering once.
                         */
-                       lower_flrp = 0;
+                       nir->info.flrp_lowered = true;
                }
 
                NIR_PASS(progress, nir, nir_opt_undef);
@@ -913,7 +919,7 @@ si_nir_lower_color(nir_shader *nir)
         }
 }
 
-void si_nir_lower_ps_inputs(struct nir_shader *nir)
+static void si_nir_lower_ps_inputs(struct nir_shader *nir)
 {
        if (nir->info.stage != MESA_SHADER_FRAGMENT)
                return;
@@ -938,11 +944,7 @@ void si_nir_lower_ps_inputs(struct nir_shader *nir)
                   nir_var_shader_in);
 }
 
-/**
- * Perform "lowering" operations on the NIR that are run once when the shader
- * selector is created.
- */
-void si_lower_nir(struct si_screen *sscreen, struct nir_shader *nir)
+void si_nir_adjust_driver_locations(struct nir_shader *nir)
 {
        /* Adjust the driver location of inputs and outputs. The state tracker
         * interprets them as slots, while the ac/nir backend interprets them
@@ -953,17 +955,16 @@ void si_lower_nir(struct si_screen *sscreen, struct nir_shader *nir)
                        variable->data.driver_location *= 4;
        }
 
-       nir_foreach_variable(variable, &nir->outputs) {
+       nir_foreach_variable(variable, &nir->outputs)
                variable->data.driver_location *= 4;
+}
 
-               if (nir->info.stage == MESA_SHADER_FRAGMENT) {
-                       if (variable->data.location == FRAG_RESULT_DEPTH)
-                               variable->data.driver_location += 2;
-                       else if (variable->data.location == FRAG_RESULT_STENCIL)
-                               variable->data.driver_location += 1;
-               }
-       }
-
+/**
+ * Perform "lowering" operations on the NIR that are run once when the shader
+ * selector is created.
+ */
+static void si_lower_nir(struct si_screen *sscreen, struct nir_shader *nir)
+{
        /* Perform lowerings (and optimizations) of code.
         *
         * Performance considerations aside, we must:
@@ -990,20 +991,38 @@ void si_lower_nir(struct si_screen *sscreen, struct nir_shader *nir)
        /* Lower load constants to scalar and then clean up the mess */
        NIR_PASS_V(nir, nir_lower_load_const_to_scalar);
        NIR_PASS_V(nir, nir_lower_var_copies);
+       NIR_PASS_V(nir, nir_lower_pack);
+       NIR_PASS_V(nir, nir_opt_access);
        si_nir_opts(nir);
 
        /* Lower large variables that are always constant with load_constant
         * intrinsics, which get turned into PC-relative loads from a data
         * section next to the shader.
+        *
+        * st/mesa calls finalize_nir twice, but we can't call this pass twice.
         */
-       NIR_PASS_V(nir, nir_opt_large_constants,
-                  glsl_get_natural_size_align_bytes, 16);
-
-       ac_lower_indirect_derefs(nir, sscreen->info.chip_class);
+       bool changed = false;
+       if (!nir->constant_data) {
+               NIR_PASS(changed, nir, nir_opt_large_constants,
+                        glsl_get_natural_size_align_bytes, 16);
+       }
 
-       si_nir_opts(nir);
+       changed |= ac_lower_indirect_derefs(nir, sscreen->info.chip_class);
+       if (changed)
+               si_nir_opts(nir);
 
        NIR_PASS_V(nir, nir_lower_bool_to_int32);
+       NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_function_temp);
+}
+
+void si_finalize_nir(struct pipe_screen *screen, void *nirptr, bool optimize)
+{
+       struct si_screen *sscreen = (struct si_screen *)screen;
+       struct nir_shader *nir = (struct nir_shader *)nirptr;
+
+       nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
+       si_nir_lower_ps_inputs(nir);
+       si_lower_nir(sscreen, nir);
 }
 
 static void declare_nir_input_vs(struct si_shader_context *ctx,
@@ -1026,19 +1045,19 @@ si_nir_lookup_interp_param(struct ac_shader_abi *abi,
        case INTERP_MODE_SMOOTH:
        case INTERP_MODE_NONE:
                if (location == INTERP_CENTER)
-                       return ctx->abi.persp_center;
+                       return ac_get_arg(&ctx->ac, ctx->args.persp_center);
                else if (location == INTERP_CENTROID)
                        return ctx->abi.persp_centroid;
                else if (location == INTERP_SAMPLE)
-                       return ctx->abi.persp_sample;
+                       return ac_get_arg(&ctx->ac, ctx->args.persp_sample);
                break;
        case INTERP_MODE_NOPERSPECTIVE:
                if (location == INTERP_CENTER)
-                       return ctx->abi.linear_center;
+                       return ac_get_arg(&ctx->ac, ctx->args.linear_center);
                else if (location == INTERP_CENTROID)
-                       return ctx->abi.linear_centroid;
+                       return ac_get_arg(&ctx->ac, ctx->args.linear_centroid);
                else if (location == INTERP_SAMPLE)
-                       return ctx->abi.linear_sample;
+                       return ac_get_arg(&ctx->ac, ctx->args.linear_sample);
                break;
        default:
                assert(!"Unhandled interpolation mode.");
@@ -1061,8 +1080,7 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi,
        assert(desc_type <= AC_DESC_BUFFER);
 
        if (bindless) {
-               LLVMValueRef list =
-                       LLVMGetParam(ctx->main_fn, ctx->param_bindless_samplers_and_images);
+               LLVMValueRef list = ac_get_arg(&ctx->ac, ctx->bindless_samplers_and_images);
 
                /* dynamic_index is the bindless handle */
                if (image) {
@@ -1093,7 +1111,7 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi,
        unsigned num_slots = image ? ctx->num_images : ctx->num_samplers;
        assert(const_index < num_slots || dynamic_index);
 
-       LLVMValueRef list = LLVMGetParam(ctx->main_fn, ctx->param_samplers_and_images);
+       LLVMValueRef list = ac_get_arg(&ctx->ac, ctx->samplers_and_images);
        LLVMValueRef index = LLVMConstInt(ctx->ac.i32, const_index, false);
 
        if (dynamic_index) {
@@ -1140,7 +1158,7 @@ static void bitcast_inputs(struct si_shader_context *ctx,
 
 bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir)
 {
-       struct tgsi_shader_info *info = &ctx->shader->selector->info;
+       struct si_shader_info *info = &ctx->shader->selector->info;
 
        if (nir->info.stage == MESA_SHADER_VERTEX) {
                uint64_t processed_inputs = 0;
@@ -1209,7 +1227,7 @@ bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir)
                        ctx->shader->key.mono.u.ps.interpolate_at_sample_force_center;
        } else if (nir->info.stage == MESA_SHADER_COMPUTE) {
                if (nir->info.cs.user_data_components_amd) {
-                       ctx->abi.user_data = LLVMGetParam(ctx->main_fn, ctx->param_cs_user_data);
+                       ctx->abi.user_data = ac_get_arg(&ctx->ac, ctx->cs_user_data);
                        ctx->abi.user_data = ac_build_expand_to_vec4(&ctx->ac, ctx->abi.user_data,
                                                                     nir->info.cs.user_data_components_amd);
                }
@@ -1227,7 +1245,7 @@ bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir)
                assert(gl_shader_stage_is_compute(nir->info.stage));
                si_declare_compute_memory(ctx);
        }
-       ac_nir_translate(&ctx->ac, &ctx->abi, nir);
+       ac_nir_translate(&ctx->ac, &ctx->abi, &ctx->args, nir);
 
        return true;
 }