radeonsi: bump glsl version to 450 for nir backend
[mesa.git] / src / gallium / drivers / radeonsi / si_shader.c
index 816396bf86f67190ce9b664f3f495c829e4bc1fa..8e91a454550a0452179b7e9146aa23e8da716325 100644 (file)
@@ -241,13 +241,10 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
 /**
  * Get the value of a shader input parameter and extract a bitfield.
  */
-static LLVMValueRef unpack_param(struct si_shader_context *ctx,
-                                unsigned param, unsigned rshift,
-                                unsigned bitwidth)
+static LLVMValueRef unpack_llvm_param(struct si_shader_context *ctx,
+                                     LLVMValueRef value, unsigned rshift,
+                                     unsigned bitwidth)
 {
-       LLVMValueRef value = LLVMGetParam(ctx->main_fn,
-                                         param);
-
        if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMFloatTypeKind)
                value = ac_to_integer(&ctx->ac, value);
 
@@ -264,11 +261,20 @@ static LLVMValueRef unpack_param(struct si_shader_context *ctx,
        return value;
 }
 
+static LLVMValueRef unpack_param(struct si_shader_context *ctx,
+                                unsigned param, unsigned rshift,
+                                unsigned bitwidth)
+{
+       LLVMValueRef value = LLVMGetParam(ctx->main_fn, param);
+
+       return unpack_llvm_param(ctx, value, rshift, bitwidth);
+}
+
 static LLVMValueRef get_rel_patch_id(struct si_shader_context *ctx)
 {
        switch (ctx->type) {
        case PIPE_SHADER_TESS_CTRL:
-               return unpack_param(ctx, ctx->param_tcs_rel_ids, 0, 8);
+               return unpack_llvm_param(ctx, ctx->abi.tcs_rel_ids, 0, 8);
 
        case PIPE_SHADER_TESS_EVAL:
                return LLVMGetParam(ctx->main_fn,
@@ -763,11 +769,9 @@ static LLVMValueRef get_primitive_id(struct si_shader_context *ctx,
                return LLVMGetParam(ctx->main_fn,
                                    ctx->param_vs_prim_id);
        case PIPE_SHADER_TESS_CTRL:
-               return LLVMGetParam(ctx->main_fn,
-                                   ctx->param_tcs_patch_id);
+               return ctx->abi.tcs_patch_id;
        case PIPE_SHADER_TESS_EVAL:
-               return LLVMGetParam(ctx->main_fn,
-                                   ctx->param_tes_patch_id);
+               return ctx->abi.tes_patch_id;
        case PIPE_SHADER_GEOMETRY:
                return ctx->abi.gs_prim_id;
        default:
@@ -1208,16 +1212,17 @@ static LLVMValueRef fetch_input_tcs(
        return lds_load(bld_base, tgsi2llvmtype(bld_base, type), swizzle, dw_addr);
 }
 
-static LLVMValueRef si_nir_load_input_tcs(struct ac_shader_abi *abi,
-                                         LLVMValueRef vertex_index,
-                                         LLVMValueRef param_index,
-                                         unsigned const_index,
-                                         unsigned location,
-                                         unsigned driver_location,
-                                         unsigned component,
-                                         unsigned num_components,
-                                         bool is_patch,
-                                         bool is_compact)
+static LLVMValueRef si_nir_load_tcs_varyings(struct ac_shader_abi *abi,
+                                            LLVMValueRef vertex_index,
+                                            LLVMValueRef param_index,
+                                            unsigned const_index,
+                                            unsigned location,
+                                            unsigned driver_location,
+                                            unsigned component,
+                                            unsigned num_components,
+                                            bool is_patch,
+                                            bool is_compact,
+                                            bool load_input)
 {
        struct si_shader_context *ctx = si_shader_context_from_abi(abi);
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
@@ -1226,8 +1231,18 @@ static LLVMValueRef si_nir_load_input_tcs(struct ac_shader_abi *abi,
 
        driver_location = driver_location / 4;
 
-       stride = get_tcs_in_vertex_dw_stride(ctx);
-       dw_addr = get_tcs_in_current_patch_offset(ctx);
+       if (load_input) {
+               stride = get_tcs_in_vertex_dw_stride(ctx);
+               dw_addr = get_tcs_in_current_patch_offset(ctx);
+       } else {
+               if (is_patch) {
+                       stride = NULL;
+                       dw_addr = get_tcs_out_current_patch_data_offset(ctx);
+               } else {
+                       stride = get_tcs_out_vertex_dw_stride(ctx);
+                       dw_addr = get_tcs_out_current_patch_offset(ctx);
+               }
+       }
 
        if (param_index) {
                /* Add the constant index to the indirect index */
@@ -1298,7 +1313,8 @@ LLVMValueRef si_nir_load_input_tes(struct ac_shader_abi *abi,
                                   unsigned component,
                                   unsigned num_components,
                                   bool is_patch,
-                                  bool is_compact)
+                                  bool is_compact,
+                                  bool load_input)
 {
        struct si_shader_context *ctx = si_shader_context_from_abi(abi);
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
@@ -1434,6 +1450,123 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
        }
 }
 
+static void si_nir_store_output_tcs(struct ac_shader_abi *abi,
+                                   LLVMValueRef vertex_index,
+                                   LLVMValueRef param_index,
+                                   unsigned const_index,
+                                   unsigned location,
+                                   unsigned driver_location,
+                                   LLVMValueRef src,
+                                   unsigned component,
+                                   bool is_patch,
+                                   bool is_compact,
+                                   unsigned writemask)
+{
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+       struct tgsi_shader_info *info = &ctx->shader->selector->info;
+       LLVMValueRef dw_addr, stride;
+       LLVMValueRef buffer, base, addr;
+       LLVMValueRef values[4];
+       bool skip_lds_store;
+       bool is_tess_factor = false, is_tess_inner = false;
+
+       driver_location = driver_location / 4;
+
+       if (param_index) {
+               /* Add the constant index to the indirect index */
+               param_index = LLVMBuildAdd(ctx->ac.builder, param_index,
+                                          LLVMConstInt(ctx->i32, const_index, 0), "");
+       } else {
+               if (const_index != 0)
+                       param_index = LLVMConstInt(ctx->i32, const_index, 0);
+       }
+
+       if (!is_patch) {
+               stride = get_tcs_out_vertex_dw_stride(ctx);
+               dw_addr = get_tcs_out_current_patch_offset(ctx);
+               dw_addr = get_dw_address_from_generic_indices(ctx, stride, dw_addr,
+                                                             vertex_index, param_index,
+                                                             driver_location,
+                                                             info->output_semantic_name,
+                                                             info->output_semantic_index,
+                                                             is_patch);
+
+               skip_lds_store = !info->reads_pervertex_outputs;
+       } else {
+               dw_addr = get_tcs_out_current_patch_data_offset(ctx);
+               dw_addr = get_dw_address_from_generic_indices(ctx, NULL, dw_addr,
+                                                             vertex_index, param_index,
+                                                             driver_location,
+                                                             info->output_semantic_name,
+                                                             info->output_semantic_index,
+                                                             is_patch);
+
+               skip_lds_store = !info->reads_perpatch_outputs;
+
+               if (!param_index) {
+                       int name = info->output_semantic_name[driver_location];
+
+                       /* Always write tess factors into LDS for the TCS epilog. */
+                       if (name == TGSI_SEMANTIC_TESSINNER ||
+                           name == TGSI_SEMANTIC_TESSOUTER) {
+                               /* The epilog doesn't read LDS if invocation 0 defines tess factors. */
+                               skip_lds_store = !info->reads_tessfactor_outputs &&
+                                                ctx->shader->selector->tcs_info.tessfactors_are_def_in_all_invocs;
+                               is_tess_factor = true;
+                               is_tess_inner = name == TGSI_SEMANTIC_TESSINNER;
+                       }
+               }
+       }
+
+       buffer = desc_from_addr_base64k(ctx, ctx->param_tcs_offchip_addr_base64k);
+
+       base = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
+
+       addr = get_tcs_tes_buffer_address_from_generic_indices(ctx, vertex_index,
+                                                              param_index, driver_location,
+                                                              info->output_semantic_name,
+                                                              info->output_semantic_index,
+                                                              is_patch);
+
+       for (unsigned chan = 0; chan < 4; chan++) {
+               if (!(writemask & (1 << chan)))
+                       continue;
+               LLVMValueRef value = ac_llvm_extract_elem(&ctx->ac, src, chan - component);
+
+               /* Skip LDS stores if there is no LDS read of this output. */
+               if (!skip_lds_store)
+                       ac_lds_store(&ctx->ac, dw_addr, value);
+
+               value = ac_to_integer(&ctx->ac, value);
+               values[chan] = value;
+
+               if (writemask != 0xF && !is_tess_factor) {
+                       ac_build_buffer_store_dword(&ctx->ac, buffer, value, 1,
+                                                   addr, base,
+                                                   4 * chan, 1, 0, true, false);
+               }
+
+               /* Write tess factors into VGPRs for the epilog. */
+               if (is_tess_factor &&
+                   ctx->shader->selector->tcs_info.tessfactors_are_def_in_all_invocs) {
+                       if (!is_tess_inner) {
+                               LLVMBuildStore(ctx->ac.builder, value, /* outer */
+                                              ctx->invoc0_tess_factors[chan]);
+                       } else if (chan < 2) {
+                               LLVMBuildStore(ctx->ac.builder, value, /* inner */
+                                              ctx->invoc0_tess_factors[4 + chan]);
+                       }
+               }
+       }
+
+       if (writemask == 0xF && !is_tess_factor) {
+               LLVMValueRef value = lp_build_gather_values(&ctx->gallivm,
+                                                           values, 4);
+               ac_build_buffer_store_dword(&ctx->ac, buffer, value, 4, addr,
+                                           base, 0, 1, 0, true, false);
+       }
+}
+
 LLVMValueRef si_llvm_load_input_gs(struct ac_shader_abi *abi,
                                   unsigned input_index,
                                   unsigned vtx_offset_param,
@@ -1772,11 +1905,83 @@ static LLVMValueRef load_sample_position(struct si_shader_context *ctx, LLVMValu
        return lp_build_gather_values(&ctx->gallivm, pos, 4);
 }
 
+static LLVMValueRef si_load_tess_coord(struct ac_shader_abi *abi,
+                                      LLVMTypeRef type,
+                                      unsigned num_components)
+{
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+       struct lp_build_context *bld = &ctx->bld_base.base;
+
+       LLVMValueRef coord[4] = {
+               LLVMGetParam(ctx->main_fn, ctx->param_tes_u),
+               LLVMGetParam(ctx->main_fn, ctx->param_tes_v),
+               ctx->ac.f32_0,
+               ctx->ac.f32_0
+       };
+
+       /* For triangles, the vector should be (u, v, 1-u-v). */
+       if (ctx->shader->selector->info.properties[TGSI_PROPERTY_TES_PRIM_MODE] ==
+           PIPE_PRIM_TRIANGLES)
+               coord[2] = lp_build_sub(bld, ctx->ac.f32_1,
+                                       lp_build_add(bld, coord[0], coord[1]));
+
+       return lp_build_gather_values(&ctx->gallivm, coord, 4);
+}
+
+static LLVMValueRef load_tess_level(struct si_shader_context *ctx,
+                                   unsigned semantic_name)
+{
+       LLVMValueRef buffer, base, addr;
+
+       int param = si_shader_io_get_unique_index_patch(semantic_name, 0);
+
+       buffer = desc_from_addr_base64k(ctx, ctx->param_tcs_offchip_addr_base64k);
+
+       base = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
+       addr = get_tcs_tes_buffer_address(ctx, get_rel_patch_id(ctx), NULL,
+                                         LLVMConstInt(ctx->i32, param, 0));
+
+       return buffer_load(&ctx->bld_base, ctx->f32,
+                          ~0, buffer, base, addr, true);
+
+}
+
+static LLVMValueRef si_load_tess_level(struct ac_shader_abi *abi,
+                                      unsigned varying_id)
+{
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+       unsigned semantic_name;
+
+       switch (varying_id) {
+       case VARYING_SLOT_TESS_LEVEL_INNER:
+               semantic_name = TGSI_SEMANTIC_TESSINNER;
+               break;
+       case VARYING_SLOT_TESS_LEVEL_OUTER:
+               semantic_name = TGSI_SEMANTIC_TESSOUTER;
+               break;
+       default:
+               unreachable("unknown tess level");
+       }
+
+       return load_tess_level(ctx, semantic_name);
+
+}
+
+static LLVMValueRef si_load_patch_vertices_in(struct ac_shader_abi *abi)
+{
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+       if (ctx->type == PIPE_SHADER_TESS_CTRL)
+               return unpack_param(ctx, ctx->param_tcs_out_lds_layout, 26, 6);
+       else if (ctx->type == PIPE_SHADER_TESS_EVAL)
+               return get_num_tcs_out_vertices(ctx);
+       else
+               unreachable("invalid shader stage for TGSI_SEMANTIC_VERTICESIN");
+}
+
 void si_load_system_value(struct si_shader_context *ctx,
                          unsigned index,
                          const struct tgsi_full_declaration *decl)
 {
-       struct lp_build_context *bld = &ctx->bld_base.base;
        LLVMValueRef value = 0;
 
        assert(index < RADEON_LLVM_MAX_SYSTEM_VALUES);
@@ -1825,7 +2030,7 @@ void si_load_system_value(struct si_shader_context *ctx,
 
        case TGSI_SEMANTIC_INVOCATIONID:
                if (ctx->type == PIPE_SHADER_TESS_CTRL)
-                       value = unpack_param(ctx, ctx->param_tcs_rel_ids, 8, 5);
+                       value = unpack_llvm_param(ctx, ctx->abi.tcs_rel_ids, 8, 5);
                else if (ctx->type == PIPE_SHADER_GEOMETRY)
                        value = ctx->abi.gs_invocation_id;
                else
@@ -1877,50 +2082,17 @@ void si_load_system_value(struct si_shader_context *ctx,
                break;
 
        case TGSI_SEMANTIC_TESSCOORD:
-       {
-               LLVMValueRef coord[4] = {
-                       LLVMGetParam(ctx->main_fn, ctx->param_tes_u),
-                       LLVMGetParam(ctx->main_fn, ctx->param_tes_v),
-                       ctx->ac.f32_0,
-                       ctx->ac.f32_0
-               };
-
-               /* For triangles, the vector should be (u, v, 1-u-v). */
-               if (ctx->shader->selector->info.properties[TGSI_PROPERTY_TES_PRIM_MODE] ==
-                   PIPE_PRIM_TRIANGLES)
-                       coord[2] = lp_build_sub(bld, ctx->ac.f32_1,
-                                               lp_build_add(bld, coord[0], coord[1]));
-
-               value = lp_build_gather_values(&ctx->gallivm, coord, 4);
+               value = si_load_tess_coord(&ctx->abi, NULL, 4);
                break;
-       }
 
        case TGSI_SEMANTIC_VERTICESIN:
-               if (ctx->type == PIPE_SHADER_TESS_CTRL)
-                       value = unpack_param(ctx, ctx->param_tcs_out_lds_layout, 26, 6);
-               else if (ctx->type == PIPE_SHADER_TESS_EVAL)
-                       value = get_num_tcs_out_vertices(ctx);
-               else
-                       assert(!"invalid shader stage for TGSI_SEMANTIC_VERTICESIN");
+               value = si_load_patch_vertices_in(&ctx->abi);
                break;
 
        case TGSI_SEMANTIC_TESSINNER:
        case TGSI_SEMANTIC_TESSOUTER:
-       {
-               LLVMValueRef buffer, base, addr;
-               int param = si_shader_io_get_unique_index_patch(decl->Semantic.Name, 0);
-
-               buffer = desc_from_addr_base64k(ctx, ctx->param_tcs_offchip_addr_base64k);
-
-               base = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
-               addr = get_tcs_tes_buffer_address(ctx, get_rel_patch_id(ctx), NULL,
-                                         LLVMConstInt(ctx->i32, param, 0));
-
-               value = buffer_load(&ctx->bld_base, ctx->f32,
-                                   ~0, buffer, base, addr, true);
-
+               value = load_tess_level(ctx, decl->Semantic.Name);
                break;
-       }
 
        case TGSI_SEMANTIC_DEFAULT_TESSOUTER_SI:
        case TGSI_SEMANTIC_DEFAULT_TESSINNER_SI:
@@ -2874,7 +3046,7 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
        LLVMValueRef lds_vertex_stride, lds_vertex_offset, lds_base;
        uint64_t inputs;
 
-       invocation_id = unpack_param(ctx, ctx->param_tcs_rel_ids, 8, 5);
+       invocation_id = unpack_llvm_param(ctx, ctx->abi.tcs_rel_ids, 8, 5);
        buffer = desc_from_addr_base64k(ctx, ctx->param_tcs_offchip_addr_base64k);
        buffer_offset = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
 
@@ -3118,16 +3290,19 @@ si_insert_input_ptr_as_2xi32(struct si_shader_context *ctx, LLVMValueRef ret,
 }
 
 /* This only writes the tessellation factor levels. */
-static void si_llvm_emit_tcs_epilogue(struct lp_build_tgsi_context *bld_base)
+static void si_llvm_emit_tcs_epilogue(struct ac_shader_abi *abi,
+                                     unsigned max_outputs,
+                                     LLVMValueRef *addrs)
 {
-       struct si_shader_context *ctx = si_shader_context(bld_base);
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        LLVMBuilderRef builder = ctx->ac.builder;
        LLVMValueRef rel_patch_id, invocation_id, tf_lds_offset;
 
        si_copy_tcs_inputs(bld_base);
 
        rel_patch_id = get_rel_patch_id(ctx);
-       invocation_id = unpack_param(ctx, ctx->param_tcs_rel_ids, 8, 5);
+       invocation_id = unpack_llvm_param(ctx, ctx->abi.tcs_rel_ids, 8, 5);
        tf_lds_offset = get_tcs_out_current_patch_data_offset(ctx);
 
        if (ctx->screen->info.chip_class >= GFX9) {
@@ -3188,7 +3363,7 @@ static void si_llvm_emit_tcs_epilogue(struct lp_build_tgsi_context *bld_base)
        tf_lds_offset = ac_to_float(&ctx->ac, tf_lds_offset);
 
        /* Leave a hole corresponding to the two input VGPRs. This ensures that
-        * the invocation_id output does not alias the param_tcs_rel_ids input,
+        * the invocation_id output does not alias the tcs_rel_ids input,
         * which saves a V_MOV on gfx9.
         */
        vgpr += 2;
@@ -3246,10 +3421,12 @@ static void si_set_ls_return_value_for_tcs(struct si_shader_context *ctx)
                                           8 + GFX9_SGPR_TCS_SAMPLERS_AND_IMAGES);
 
        unsigned vgpr = 8 + GFX9_TCS_NUM_USER_SGPR;
-       ret = si_insert_input_ret_float(ctx, ret,
-                                       ctx->param_tcs_patch_id, vgpr++);
-       ret = si_insert_input_ret_float(ctx, ret,
-                                       ctx->param_tcs_rel_ids, vgpr++);
+       ret = LLVMBuildInsertValue(ctx->ac.builder, ret,
+                                  ac_to_float(&ctx->ac, ctx->abi.tcs_patch_id),
+                                  vgpr++, "");
+       ret = LLVMBuildInsertValue(ctx->ac.builder, ret,
+                                  ac_to_float(&ctx->ac, ctx->abi.tcs_rel_ids),
+                                  vgpr++, "");
        ctx->return_value = ret;
 }
 
@@ -4447,7 +4624,7 @@ static void declare_tes_input_vgprs(struct si_shader_context *ctx,
        ctx->param_tes_u = add_arg(fninfo, ARG_VGPR, ctx->f32);
        ctx->param_tes_v = add_arg(fninfo, ARG_VGPR, ctx->f32);
        ctx->param_tes_rel_patch_id = add_arg(fninfo, ARG_VGPR, ctx->i32);
-       ctx->param_tes_patch_id = add_arg(fninfo, ARG_VGPR, ctx->i32);
+       add_arg_assign(fninfo, ARG_VGPR, ctx->i32, &ctx->abi.tes_patch_id);
 }
 
 enum {
@@ -4544,8 +4721,8 @@ static void create_function(struct si_shader_context *ctx)
                ctx->param_tcs_factor_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
 
                /* VGPRs */
-               ctx->param_tcs_patch_id = add_arg(&fninfo, ARG_VGPR, ctx->i32);
-               ctx->param_tcs_rel_ids = add_arg(&fninfo, ARG_VGPR, ctx->i32);
+               add_arg_assign(&fninfo, ARG_VGPR, ctx->i32, &ctx->abi.tcs_patch_id);
+               add_arg_assign(&fninfo, ARG_VGPR, ctx->i32, &ctx->abi.tcs_rel_ids);
 
                /* param_tcs_offchip_offset and param_tcs_factor_offset are
                 * placed after the user SGPRs.
@@ -4583,8 +4760,8 @@ static void create_function(struct si_shader_context *ctx)
                                                ctx->type == PIPE_SHADER_TESS_CTRL);
 
                /* VGPRs (first TCS, then VS) */
-               ctx->param_tcs_patch_id = add_arg(&fninfo, ARG_VGPR, ctx->i32);
-               ctx->param_tcs_rel_ids = add_arg(&fninfo, ARG_VGPR, ctx->i32);
+               add_arg_assign(&fninfo, ARG_VGPR, ctx->i32, &ctx->abi.tcs_patch_id);
+               add_arg_assign(&fninfo, ARG_VGPR, ctx->i32, &ctx->abi.tcs_rel_ids);
 
                if (ctx->type == PIPE_SHADER_VERTEX) {
                        declare_vs_input_vgprs(ctx, &fninfo,
@@ -5822,14 +5999,20 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
                break;
        case PIPE_SHADER_TESS_CTRL:
                bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tcs;
-               ctx->abi.load_tess_inputs = si_nir_load_input_tcs;
+               ctx->abi.load_tess_varyings = si_nir_load_tcs_varyings;
                bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = fetch_output_tcs;
                bld_base->emit_store = store_output_tcs;
-               bld_base->emit_epilogue = si_llvm_emit_tcs_epilogue;
+               ctx->abi.store_tcs_outputs = si_nir_store_output_tcs;
+               ctx->abi.emit_outputs = si_llvm_emit_tcs_epilogue;
+               ctx->abi.load_patch_vertices_in = si_load_patch_vertices_in;
+               bld_base->emit_epilogue = si_tgsi_emit_epilogue;
                break;
        case PIPE_SHADER_TESS_EVAL:
                bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tes;
-               ctx->abi.load_tess_inputs = si_nir_load_input_tes;
+               ctx->abi.load_tess_varyings = si_nir_load_input_tes;
+               ctx->abi.load_tess_coord = si_load_tess_coord;
+               ctx->abi.load_tess_level = si_load_tess_level;
+               ctx->abi.load_patch_vertices_in = si_load_patch_vertices_in;
                if (shader->key.as_es)
                        ctx->abi.emit_outputs = si_llvm_emit_es_epilogue;
                else