radeonsi/nir: emit FS outputs
[mesa.git] / src / gallium / drivers / radeonsi / si_shader.c
index 900b3c3a7f1f45e37e3c5580badcbc127470a6bf..5fb820693defefe0f6131b6dc03cd3512ca2055a 100644 (file)
@@ -409,10 +409,9 @@ static LLVMValueRef extract_double_to_float(struct si_shader_context *ctx,
        return LLVMBuildFPTrunc(builder, value, ctx->f32, "");
 }
 
-static void declare_input_vs(
+void si_llvm_load_input_vs(
        struct si_shader_context *ctx,
        unsigned input_index,
-       const struct tgsi_full_declaration *decl,
        LLVMValueRef out[4])
 {
        struct gallivm_state *gallivm = &ctx->gallivm;
@@ -615,6 +614,14 @@ static void declare_input_vs(
        }
 }
 
+static void declare_input_vs(
+       struct si_shader_context *ctx,
+       unsigned input_index,
+       const struct tgsi_full_declaration *decl,
+       LLVMValueRef out[4])
+{
+       si_llvm_load_input_vs(ctx, input_index, out);
+}
 
 static LLVMValueRef get_primitive_id(struct si_shader_context *ctx,
                                     unsigned swizzle)
@@ -1385,25 +1392,28 @@ static void interp_fs_input(struct si_shader_context *ctx,
        }
 }
 
-static void declare_input_fs(
+void si_llvm_load_input_fs(
        struct si_shader_context *ctx,
        unsigned input_index,
-       const struct tgsi_full_declaration *decl,
        LLVMValueRef out[4])
 {
        struct lp_build_context *base = &ctx->bld_base.base;
        struct si_shader *shader = ctx->shader;
+       struct tgsi_shader_info *info = &shader->selector->info;
        LLVMValueRef main_fn = ctx->main_fn;
        LLVMValueRef interp_param = NULL;
        int interp_param_idx;
+       enum tgsi_semantic semantic_name = info->input_semantic_name[input_index];
+       unsigned semantic_index = info->input_semantic_index[input_index];
+       enum tgsi_interpolate_mode interp_mode = info->input_interpolate[input_index];
+       enum tgsi_interpolate_loc interp_loc = info->input_interpolate_loc[input_index];
 
        /* Get colors from input VGPRs (set by the prolog). */
-       if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR) {
-               unsigned i = decl->Semantic.Index;
+       if (semantic_name == TGSI_SEMANTIC_COLOR) {
                unsigned colors_read = shader->selector->info.colors_read;
-               unsigned mask = colors_read >> (i * 4);
+               unsigned mask = colors_read >> (semantic_index * 4);
                unsigned offset = SI_PARAM_POS_FIXED_PT + 1 +
-                                 (i ? util_bitcount(colors_read & 0xf) : 0);
+                                 (semantic_index ? util_bitcount(colors_read & 0xf) : 0);
 
                out[0] = mask & 0x1 ? LLVMGetParam(main_fn, offset++) : base->undef;
                out[1] = mask & 0x2 ? LLVMGetParam(main_fn, offset++) : base->undef;
@@ -1412,22 +1422,30 @@ static void declare_input_fs(
                return;
        }
 
-       interp_param_idx = lookup_interp_param_index(decl->Interp.Interpolate,
-                                                    decl->Interp.Location);
+       interp_param_idx = lookup_interp_param_index(interp_mode, interp_loc);
        if (interp_param_idx == -1)
                return;
        else if (interp_param_idx) {
                interp_param = LLVMGetParam(ctx->main_fn, interp_param_idx);
        }
 
-       interp_fs_input(ctx, input_index, decl->Semantic.Name,
-                       decl->Semantic.Index, 0, /* this param is unused */
+       interp_fs_input(ctx, input_index, semantic_name,
+                       semantic_index, 0, /* this param is unused */
                        shader->selector->info.colors_read, interp_param,
                        LLVMGetParam(main_fn, SI_PARAM_PRIM_MASK),
                        LLVMGetParam(main_fn, SI_PARAM_FRONT_FACE),
                        &out[0]);
 }
 
+static void declare_input_fs(
+       struct si_shader_context *ctx,
+       unsigned input_index,
+       const struct tgsi_full_declaration *decl,
+       LLVMValueRef out[4])
+{
+       si_llvm_load_input_fs(ctx, input_index, out);
+}
+
 static LLVMValueRef get_sample_id(struct si_shader_context *ctx)
 {
        return unpack_param(ctx, SI_PARAM_ANCILLARY, 8, 4);
@@ -1776,6 +1794,18 @@ static LLVMValueRef load_const_buffer_desc(struct si_shader_context *ctx, int i)
                        LLVMConstInt(ctx->i32, si_get_constbuf_slot(i), 0));
 }
 
+static LLVMValueRef load_ubo(struct ac_shader_abi *abi, LLVMValueRef index)
+{
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+       LLVMValueRef ptr = LLVMGetParam(ctx->main_fn, ctx->param_const_and_shader_buffers);
+
+       index = si_llvm_bound_index(ctx, index, ctx->num_const_buffers);
+       index = LLVMBuildAdd(ctx->gallivm.builder, index,
+                            LLVMConstInt(ctx->i32, SI_NUM_SHADER_BUFFERS, 0), "");
+
+       return ac_build_indexed_load_const(&ctx->ac, ptr, index);
+}
+
 static LLVMValueRef fetch_constant(
        struct lp_build_tgsi_context *bld_base,
        const struct tgsi_full_src_register *reg,
@@ -3327,9 +3357,11 @@ static void si_export_null(struct lp_build_tgsi_context *bld_base)
  *
  * The alpha-ref SGPR is returned via its original location.
  */
-static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
+static void si_llvm_return_fs_outputs(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 si_shader *shader = ctx->shader;
        struct tgsi_shader_info *info = &shader->selector->info;
        LLVMBuilderRef builder = ctx->gallivm.builder;
@@ -3351,22 +3383,22 @@ static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
                case TGSI_SEMANTIC_COLOR:
                        assert(semantic_index < 8);
                        for (j = 0; j < 4; j++) {
-                               LLVMValueRef ptr = ctx->outputs[i][j];
+                               LLVMValueRef ptr = addrs[4 * i + j];
                                LLVMValueRef result = LLVMBuildLoad(builder, ptr, "");
                                color[semantic_index][j] = result;
                        }
                        break;
                case TGSI_SEMANTIC_POSITION:
                        depth = LLVMBuildLoad(builder,
-                                             ctx->outputs[i][2], "");
+                                             addrs[4 * i + 2], "");
                        break;
                case TGSI_SEMANTIC_STENCIL:
                        stencil = LLVMBuildLoad(builder,
-                                               ctx->outputs[i][1], "");
+                                               addrs[4 * i + 1], "");
                        break;
                case TGSI_SEMANTIC_SAMPLEMASK:
                        samplemask = LLVMBuildLoad(builder,
-                                                  ctx->outputs[i][0], "");
+                                                  addrs[4 * i + 0], "");
                        break;
                default:
                        fprintf(stderr, "Warning: SI unhandled fs output type:%d\n",
@@ -3379,9 +3411,10 @@ static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
 
        /* Set SGPRs. */
        ret = LLVMBuildInsertValue(builder, ret,
-                                  bitcast(bld_base, TGSI_TYPE_SIGNED,
-                                          LLVMGetParam(ctx->main_fn,
-                                                       SI_PARAM_ALPHA_REF)),
+                                  LLVMBuildBitCast(ctx->ac.builder,
+                                               LLVMGetParam(ctx->main_fn,
+                                                       SI_PARAM_ALPHA_REF),
+                                               ctx->i32, ""),
                                   SI_SGPR_ALPHA_REF, "");
 
        /* Set VGPRs */
@@ -5599,7 +5632,8 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
                break;
        case PIPE_SHADER_FRAGMENT:
                ctx->load_input = declare_input_fs;
-               bld_base->emit_epilogue = si_llvm_return_fs_outputs;
+               ctx->abi.emit_outputs = si_llvm_return_fs_outputs;
+               bld_base->emit_epilogue = si_tgsi_emit_epilogue;
                break;
        case PIPE_SHADER_COMPUTE:
                ctx->declare_memory_region = declare_compute_memory;
@@ -5609,6 +5643,8 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
                return false;
        }
 
+       ctx->abi.load_ubo = load_ubo;
+
        create_function(ctx);
        preload_ring_buffers(ctx);