radv: add support for VK_EXT_depth_range_unrestricted
[mesa.git] / src / amd / vulkan / radv_nir_to_llvm.c
index 1b50b2cc1f14c6e4e835d3a4a453f14d70aaeee4..c8d383e021d0fbf51624cd94d81fbf14e37703b9 100644 (file)
@@ -62,7 +62,6 @@ struct radv_shader_context {
        LLVMValueRef vs_prim_id;
        LLVMValueRef es2gs_offset;
 
-       LLVMValueRef tcs_offchip_layout;
        LLVMValueRef oc_lds;
        LLVMValueRef merged_wave_info;
        LLVMValueRef tess_factor_offset;
@@ -70,8 +69,6 @@ struct radv_shader_context {
        LLVMValueRef tes_u;
        LLVMValueRef tes_v;
 
-       LLVMValueRef gsvs_ring_stride;
-       LLVMValueRef gsvs_num_entries;
        LLVMValueRef gs2vs_offset;
        LLVMValueRef gs_wave_id;
        LLVMValueRef gs_vtx_offset[6];
@@ -99,14 +96,14 @@ struct radv_shader_context {
        unsigned gs_max_out_vertices;
 
        unsigned tes_primitive_mode;
-       uint64_t tess_outputs_written;
-       uint64_t tess_patch_outputs_written;
 
        uint32_t tcs_patch_outputs_read;
        uint64_t tcs_outputs_read;
        uint32_t tcs_vertices_per_patch;
        uint32_t tcs_num_inputs;
        uint32_t tcs_num_patches;
+       uint32_t max_gsvs_emit_size;
+       uint32_t gsvs_vertex_size;
 };
 
 enum radeon_llvm_calling_convention {
@@ -177,6 +174,38 @@ get_tcs_num_patches(struct radv_shader_context *ctx)
        return num_patches;
 }
 
+static unsigned
+calculate_tess_lds_size(struct radv_shader_context *ctx)
+{
+       unsigned num_tcs_input_cp = ctx->options->key.tcs.input_vertices;
+       unsigned num_tcs_output_cp;
+       unsigned num_tcs_outputs, num_tcs_patch_outputs;
+       unsigned input_vertex_size, output_vertex_size;
+       unsigned input_patch_size, output_patch_size;
+       unsigned pervertex_output_patch_size;
+       unsigned output_patch0_offset;
+       unsigned num_patches;
+       unsigned lds_size;
+
+       num_tcs_output_cp = ctx->tcs_vertices_per_patch;
+       num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
+       num_tcs_patch_outputs = util_last_bit64(ctx->shader_info->info.tcs.patch_outputs_written);
+
+       input_vertex_size = ctx->tcs_num_inputs * 16;
+       output_vertex_size = num_tcs_outputs * 16;
+
+       input_patch_size = num_tcs_input_cp * input_vertex_size;
+
+       pervertex_output_patch_size = num_tcs_output_cp * output_vertex_size;
+       output_patch_size = pervertex_output_patch_size + num_tcs_patch_outputs * 16;
+
+       num_patches = ctx->tcs_num_patches;
+       output_patch0_offset = input_patch_size * num_patches;
+
+       lds_size = output_patch0_offset + output_patch_size * num_patches;
+       return lds_size;
+}
+
 /* Tessellation shaders pass outputs to the next shader using LDS.
  *
  * LS outputs = TCS inputs
@@ -533,17 +562,13 @@ static void allocate_user_sgprs(struct radv_shader_context *ctx,
                }
                break;
        case MESA_SHADER_TESS_EVAL:
-               user_sgpr_info->sgpr_count += 1;
                break;
        case MESA_SHADER_GEOMETRY:
                if (has_previous_stage) {
                        if (previous_stage == MESA_SHADER_VERTEX) {
                                user_sgpr_info->sgpr_count += count_vs_user_sgprs(ctx);
-                       } else {
-                               user_sgpr_info->sgpr_count++;
                        }
                }
-               user_sgpr_info->sgpr_count += 2;
                break;
        default:
                break;
@@ -861,7 +886,6 @@ static void create_function(struct radv_shader_context *ctx,
                                           previous_stage, &user_sgpr_info,
                                           &args, &desc_sets);
 
-               add_arg(&args, ARG_SGPR, ctx->ac.i32, &ctx->tcs_offchip_layout);
                if (needs_view_index)
                        add_arg(&args, ARG_SGPR, ctx->ac.i32,
                                &ctx->abi.view_index);
@@ -896,20 +920,13 @@ static void create_function(struct radv_shader_context *ctx,
                                                   &user_sgpr_info, &args,
                                                   &desc_sets);
 
-                       if (previous_stage == MESA_SHADER_TESS_EVAL) {
-                               add_arg(&args, ARG_SGPR, ctx->ac.i32,
-                                       &ctx->tcs_offchip_layout);
-                       } else {
+                       if (previous_stage != MESA_SHADER_TESS_EVAL) {
                                declare_vs_specific_input_sgprs(ctx, stage,
                                                                has_previous_stage,
                                                                previous_stage,
                                                                &args);
                        }
 
-                       add_arg(&args, ARG_SGPR, ctx->ac.i32,
-                               &ctx->gsvs_ring_stride);
-                       add_arg(&args, ARG_SGPR, ctx->ac.i32,
-                               &ctx->gsvs_num_entries);
                        if (needs_view_index)
                                add_arg(&args, ARG_SGPR, ctx->ac.i32,
                                        &ctx->abi.view_index);
@@ -937,10 +954,6 @@ static void create_function(struct radv_shader_context *ctx,
                                                   &user_sgpr_info, &args,
                                                   &desc_sets);
 
-                       add_arg(&args, ARG_SGPR, ctx->ac.i32,
-                               &ctx->gsvs_ring_stride);
-                       add_arg(&args, ARG_SGPR, ctx->ac.i32,
-                               &ctx->gsvs_num_entries);
                        if (needs_view_index)
                                add_arg(&args, ARG_SGPR, ctx->ac.i32,
                                        &ctx->abi.view_index);
@@ -1055,7 +1068,6 @@ static void create_function(struct radv_shader_context *ctx,
                        set_loc_shader(ctx, AC_UD_VIEW_INDEX, &user_sgpr_idx, 1);
                break;
        case MESA_SHADER_TESS_EVAL:
-               set_loc_shader(ctx, AC_UD_TES_OFFCHIP_LAYOUT, &user_sgpr_idx, 1);
                if (ctx->abi.view_index)
                        set_loc_shader(ctx, AC_UD_VIEW_INDEX, &user_sgpr_idx, 1);
                break;
@@ -1066,12 +1078,7 @@ static void create_function(struct radv_shader_context *ctx,
                                                           has_previous_stage,
                                                           previous_stage,
                                                           &user_sgpr_idx);
-                       else
-                               set_loc_shader(ctx, AC_UD_TES_OFFCHIP_LAYOUT,
-                                              &user_sgpr_idx, 1);
                }
-               set_loc_shader(ctx, AC_UD_GS_VS_RING_STRIDE_ENTRIES,
-                              &user_sgpr_idx, 2);
                if (ctx->abi.view_index)
                        set_loc_shader(ctx, AC_UD_VIEW_INDEX, &user_sgpr_idx, 1);
                break;
@@ -1149,35 +1156,27 @@ radv_load_resource(struct ac_shader_abi *abi, LLVMValueRef index,
  */
 static LLVMValueRef get_non_vertex_index_offset(struct radv_shader_context *ctx)
 {
-       if (ctx->stage == MESA_SHADER_TESS_CTRL) {
-               uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
-               uint32_t output_vertex_size = num_tcs_outputs * 16;
-               uint32_t pervertex_output_patch_size = ctx->tcs_vertices_per_patch * output_vertex_size;
-               uint32_t num_patches = ctx->tcs_num_patches;
+       uint32_t num_patches = ctx->tcs_num_patches;
+       uint32_t num_tcs_outputs;
+       if (ctx->stage == MESA_SHADER_TESS_CTRL)
+               num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
+       else
+               num_tcs_outputs = ctx->options->key.tes.tcs_num_outputs;
 
-               return LLVMConstInt(ctx->ac.i32, pervertex_output_patch_size * num_patches, false);
-       } else
-               return ac_unpack_param(&ctx->ac, ctx->tcs_offchip_layout, 16, 16);
+       uint32_t output_vertex_size = num_tcs_outputs * 16;
+       uint32_t pervertex_output_patch_size = ctx->tcs_vertices_per_patch * output_vertex_size;
+
+       return LLVMConstInt(ctx->ac.i32, pervertex_output_patch_size * num_patches, false);
 }
 
 static LLVMValueRef calc_param_stride(struct radv_shader_context *ctx,
                                      LLVMValueRef vertex_index)
 {
        LLVMValueRef param_stride;
-       if (ctx->stage == MESA_SHADER_TESS_CTRL) {
-               if (vertex_index)
-                       param_stride = LLVMConstInt(ctx->ac.i32, ctx->tcs_vertices_per_patch * ctx->tcs_num_patches, false);
-               else
-                       param_stride = LLVMConstInt(ctx->ac.i32, ctx->tcs_num_patches, false);
-       } else {
-               LLVMValueRef num_patches = ac_unpack_param(&ctx->ac, ctx->tcs_offchip_layout, 0, 9);
-               LLVMValueRef vertices_per_patch = LLVMConstInt(ctx->ac.i32, ctx->tcs_vertices_per_patch, false);
-               if (vertex_index)
-                       param_stride = LLVMBuildMul(ctx->ac.builder, vertices_per_patch,
-                                           num_patches, "");
-               else
-                       param_stride = num_patches;
-       }
+       if (vertex_index)
+               param_stride = LLVMConstInt(ctx->ac.i32, ctx->tcs_vertices_per_patch * ctx->tcs_num_patches, false);
+       else
+               param_stride = LLVMConstInt(ctx->ac.i32, ctx->tcs_num_patches, false);
        return param_stride;
 }
 
@@ -1236,18 +1235,6 @@ static LLVMValueRef get_tcs_tes_buffer_address_params(struct radv_shader_context
        return get_tcs_tes_buffer_address(ctx, vertex_index, param_index);
 }
 
-static void
-mark_tess_output(struct radv_shader_context *ctx,
-                bool is_patch, uint32_t param, int num_slots)
-
-{
-       uint64_t slot_mask = (1ull << num_slots) - 1;
-       if (is_patch) {
-               ctx->tess_patch_outputs_written |= (slot_mask << param);
-       } else
-               ctx->tess_outputs_written |= (slot_mask << param);
-}
-
 static LLVMValueRef
 get_dw_address(struct radv_shader_context *ctx,
               LLVMValueRef dw_addr,
@@ -1343,7 +1330,6 @@ store_tcs_output(struct ac_shader_abi *abi,
        const unsigned component = var->data.location_frac;
        const bool is_patch = var->data.patch;
        const bool is_compact = var->data.compact;
-       const unsigned count = glsl_count_attribute_slots(var->type, false);
        LLVMValueRef dw_addr;
        LLVMValueRef stride = NULL;
        LLVMValueRef buf_addr = NULL;
@@ -1372,11 +1358,6 @@ store_tcs_output(struct ac_shader_abi *abi,
                dw_addr = get_tcs_out_current_patch_data_offset(ctx);
        }
 
-       if (param_index)
-               mark_tess_output(ctx, is_patch, param, count);
-       else
-               mark_tess_output(ctx, is_patch, param, 1);
-
        dw_addr = get_dw_address(ctx, dw_addr, param, const_index, is_compact, vertex_index, stride,
                                 param_index);
        buf_addr = get_tcs_tes_buffer_address_params(ctx, param, const_index, is_compact,
@@ -2202,7 +2183,7 @@ radv_load_output(struct radv_shader_context *ctx, unsigned index, unsigned chan)
 
 static void
 handle_vs_outputs_post(struct radv_shader_context *ctx,
-                      bool export_prim_id,
+                      bool export_prim_id, bool export_layer_id,
                       struct radv_vs_output_info *outinfo)
 {
        uint32_t param_count = 0;
@@ -2376,12 +2357,24 @@ handle_vs_outputs_post(struct radv_shader_context *ctx,
                for (unsigned j = 1; j < 4; j++)
                        values[j] = ctx->ac.f32_0;
 
-               radv_export_param(ctx, param_count, values, 0xf);
+               radv_export_param(ctx, param_count, values, 0x1);
 
                outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count++;
                outinfo->export_prim_id = true;
        }
 
+       if (export_layer_id && layer_value) {
+               LLVMValueRef values[4];
+
+               values[0] = layer_value;
+               for (unsigned j = 1; j < 4; j++)
+                       values[j] = ctx->ac.f32_0;
+
+               radv_export_param(ctx, param_count, values, 0x1);
+
+               outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = param_count++;
+       }
+
        outinfo->pos_exports = num_pos_exports;
        outinfo->param_exports = param_count;
 }
@@ -2482,9 +2475,6 @@ handle_ls_outputs_post(struct radv_shader_context *ctx)
                if (i == VARYING_SLOT_CLIP_DIST0)
                        length = ctx->num_output_clips + ctx->num_output_culls;
                int param = shader_io_get_unique_index(i);
-               mark_tess_output(ctx, false, param, 1);
-               if (length > 4)
-                       mark_tess_output(ctx, false, param + 1, 1);
                LLVMValueRef dw_addr = LLVMBuildAdd(ctx->ac.builder, base_dw_addr,
                                                    LLVMConstInt(ctx->ac.i32, param * 4, false),
                                                    "");
@@ -2628,13 +2618,11 @@ write_tess_factors(struct radv_shader_context *ctx)
 
        if (inner_comps) {
                tess_inner_index = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_INNER);
-               mark_tess_output(ctx, true, tess_inner_index, 1);
                lds_inner = LLVMBuildAdd(ctx->ac.builder, lds_base,
                                         LLVMConstInt(ctx->ac.i32, tess_inner_index * 4, false), "");
        }
 
        tess_outer_index = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_OUTER);
-       mark_tess_output(ctx, true, tess_outer_index, 1);
        lds_outer = LLVMBuildAdd(ctx->ac.builder, lds_base,
                                 LLVMConstInt(ctx->ac.i32, tess_outer_index * 4, false), "");
 
@@ -2849,6 +2837,7 @@ handle_shader_outputs_post(struct ac_shader_abi *abi, unsigned max_outputs,
                        handle_es_outputs_post(ctx, &ctx->shader_info->vs.es_info);
                else
                        handle_vs_outputs_post(ctx, ctx->options->key.vs.export_prim_id,
+                                              ctx->options->key.vs.export_layer_id,
                                               &ctx->shader_info->vs.outinfo);
                break;
        case MESA_SHADER_FRAGMENT:
@@ -2865,6 +2854,7 @@ handle_shader_outputs_post(struct ac_shader_abi *abi, unsigned max_outputs,
                        handle_es_outputs_post(ctx, &ctx->shader_info->tes.es_info);
                else
                        handle_vs_outputs_post(ctx, ctx->options->key.tes.export_prim_id,
+                                              ctx->options->key.tes.export_layer_id,
                                               &ctx->shader_info->tes.outinfo);
                break;
        default:
@@ -2946,14 +2936,20 @@ ac_setup_rings(struct radv_shader_context *ctx)
        }
        if (ctx->stage == MESA_SHADER_GEOMETRY) {
                LLVMValueRef tmp;
+               uint32_t num_entries = 64;
+               LLVMValueRef gsvs_ring_stride = LLVMConstInt(ctx->ac.i32, ctx->max_gsvs_emit_size, false);
+               LLVMValueRef gsvs_ring_desc = LLVMConstInt(ctx->ac.i32, ctx->max_gsvs_emit_size << 16, false);
                ctx->esgs_ring = ac_build_load_to_sgpr(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->ac.i32, RING_ESGS_GS, false));
                ctx->gsvs_ring = ac_build_load_to_sgpr(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->ac.i32, RING_GSVS_GS, false));
 
                ctx->gsvs_ring = LLVMBuildBitCast(ctx->ac.builder, ctx->gsvs_ring, ctx->ac.v4i32, "");
 
-               ctx->gsvs_ring = LLVMBuildInsertElement(ctx->ac.builder, ctx->gsvs_ring, ctx->gsvs_num_entries, LLVMConstInt(ctx->ac.i32, 2, false), "");
+               tmp = LLVMConstInt(ctx->ac.i32, num_entries, false);
+               if (ctx->options->chip_class >= VI)
+                       tmp = LLVMBuildMul(ctx->ac.builder, gsvs_ring_stride, tmp, "");
+               ctx->gsvs_ring = LLVMBuildInsertElement(ctx->ac.builder, ctx->gsvs_ring, tmp, LLVMConstInt(ctx->ac.i32, 2, false), "");
                tmp = LLVMBuildExtractElement(ctx->ac.builder, ctx->gsvs_ring, ctx->ac.i32_1, "");
-               tmp = LLVMBuildOr(ctx->ac.builder, tmp, ctx->gsvs_ring_stride, "");
+               tmp = LLVMBuildOr(ctx->ac.builder, tmp, gsvs_ring_desc, "");
                ctx->gsvs_ring = LLVMBuildInsertElement(ctx->ac.builder, ctx->gsvs_ring, tmp, ctx->ac.i32_1, "");
        }
 
@@ -3082,7 +3078,6 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
        for(int i = 0; i < shader_count; ++i) {
                ctx.stage = shaders[i]->info.stage;
                ctx.output_mask = 0;
-               ctx.tess_outputs_written = 0;
                ctx.num_output_clips = shaders[i]->info.clip_distance_array_size;
                ctx.num_output_culls = shaders[i]->info.cull_distance_array_size;
 
@@ -3109,6 +3104,7 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
                        ctx.abi.load_tess_coord = load_tess_coord;
                        ctx.abi.load_patch_vertices_in = load_patch_vertices_in;
                        ctx.tcs_vertices_per_patch = shaders[i]->info.tess.tcs_vertices_out;
+                       ctx.tcs_num_patches = ctx.options->key.tes.num_patches;
                } else if (shaders[i]->info.stage == MESA_SHADER_VERTEX) {
                        if (shader_info->info.vs.needs_instance_id) {
                                if (ctx.options->key.vs.as_ls) {
@@ -3131,6 +3127,17 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
                if (i)
                        ac_emit_barrier(&ctx.ac, ctx.stage);
 
+               nir_foreach_variable(variable, &shaders[i]->outputs)
+                       scan_shader_output_decl(&ctx, variable, shaders[i], shaders[i]->info.stage);
+
+               if (shaders[i]->info.stage == MESA_SHADER_GEOMETRY) {
+                       unsigned addclip = shaders[i]->info.clip_distance_array_size +
+                                       shaders[i]->info.cull_distance_array_size > 4;
+                       ctx.gsvs_vertex_size = (util_bitcount64(ctx.output_mask) + addclip) * 16;
+                       ctx.max_gsvs_emit_size = ctx.gsvs_vertex_size *
+                               shaders[i]->info.gs.vertices_out;
+               }
+
                ac_setup_rings(&ctx);
 
                LLVMBasicBlockRef merge_block;
@@ -3157,9 +3164,6 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
                else if(shader_count >= 2 && shaders[i]->info.stage == MESA_SHADER_GEOMETRY)
                        prepare_gs_input_vgprs(&ctx);
 
-               nir_foreach_variable(variable, &shaders[i]->outputs)
-                       scan_shader_output_decl(&ctx, variable, shaders[i], shaders[i]->info.stage);
-
                ac_nir_translate(&ctx.ac, &ctx.abi, shaders[i]);
 
                if (shader_count >= 2) {
@@ -3168,19 +3172,11 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
                }
 
                if (shaders[i]->info.stage == MESA_SHADER_GEOMETRY) {
-                       unsigned addclip = shaders[i]->info.clip_distance_array_size +
-                                       shaders[i]->info.cull_distance_array_size > 4;
-                       shader_info->gs.gsvs_vertex_size = (util_bitcount64(ctx.output_mask) + addclip) * 16;
-                       shader_info->gs.max_gsvs_emit_size = shader_info->gs.gsvs_vertex_size *
-                               shaders[i]->info.gs.vertices_out;
+                       shader_info->gs.gsvs_vertex_size = ctx.gsvs_vertex_size;
+                       shader_info->gs.max_gsvs_emit_size = ctx.max_gsvs_emit_size;
                } else if (shaders[i]->info.stage == MESA_SHADER_TESS_CTRL) {
-                       shader_info->tcs.outputs_written = ctx.tess_outputs_written;
-                       shader_info->tcs.patch_outputs_written = ctx.tess_patch_outputs_written;
-                       assert(ctx.tess_outputs_written == ctx.shader_info->info.tcs.outputs_written);
-                       assert(ctx.tess_patch_outputs_written == ctx.shader_info->info.tcs.patch_outputs_written);
-               } else if (shaders[i]->info.stage == MESA_SHADER_VERTEX && ctx.options->key.vs.as_ls) {
-                       shader_info->vs.outputs_written = ctx.tess_outputs_written;
-                       assert(ctx.tess_outputs_written == ctx.shader_info->info.vs.ls_outputs_written);
+                       shader_info->tcs.num_patches = ctx.tcs_num_patches;
+                       shader_info->tcs.lds_size = calculate_tess_lds_size(&ctx);
                }
        }
 
@@ -3457,7 +3453,7 @@ ac_gs_copy_shader_emit(struct radv_shader_context *ctx)
                }
                idx += slot_inc;
        }
-       handle_vs_outputs_post(ctx, false, &ctx->shader_info->vs.outinfo);
+       handle_vs_outputs_post(ctx, false, false, &ctx->shader_info->vs.outinfo);
 }
 
 void