From: Nicolai Hähnle <[email protected]>

---
 src/amd/common/ac_shader_abi.h                    |  4 +++
 src/gallium/drivers/radeonsi/si_shader.c          | 37 ++++++++++++++++-------
 src/gallium/drivers/radeonsi/si_shader_internal.h |  7 +++++
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/src/amd/common/ac_shader_abi.h b/src/amd/common/ac_shader_abi.h
index 16b63d1..0d91dd2 100644
--- a/src/amd/common/ac_shader_abi.h
+++ b/src/amd/common/ac_shader_abi.h
@@ -33,13 +33,17 @@ struct ac_shader_abi {
        int param_draw_id;
        int param_vertex_id;
        int param_instance_id;
 
        /* For VS and PS: pre-loaded shader inputs.
         *
         * Currently only used for NIR shaders; indexed by variables'
         * driver_location.
         */
        LLVMValueRef *inputs;
+
+       void (*emit_outputs)(struct ac_shader_abi *abi,
+                            unsigned max_outputs,
+                            LLVMValueRef *addrs);
 };
 
 #endif /* AC_SHADER_ABI_H */
diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index 0c975ae..c3ea666 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -2946,29 +2946,32 @@ static LLVMValueRef si_get_gs_wave_id(struct 
si_shader_context *ctx)
 }
 
 static void si_llvm_emit_gs_epilogue(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
 
        ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_NOP | AC_SENDMSG_GS_DONE,
                         si_get_gs_wave_id(ctx));
 }
 
-static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
+static void si_llvm_emit_vs_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 gallivm_state *gallivm = &ctx->gallivm;
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
        struct si_shader_output_values *outputs = NULL;
        int i,j;
 
        assert(!ctx->shader->is_gs_copy_shader);
+       assert(info->num_outputs <= max_outputs);
 
        outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0]));
 
        /* Vertex color clamping.
         *
         * This uses a state constant loaded in a user data SGPR and
         * an IF statement is added that clamps all colors if the constant
         * is true.
         */
        if (ctx->type == PIPE_SHADER_VERTEX) {
@@ -2985,66 +2988,74 @@ static void si_llvm_emit_vs_epilogue(struct 
lp_build_tgsi_context *bld_base)
                        if (!cond) {
                                /* The state is in the first bit of the user 
SGPR. */
                                cond = LLVMGetParam(ctx->main_fn,
                                                    ctx->param_vs_state_bits);
                                cond = LLVMBuildTrunc(gallivm->builder, cond,
                                                      ctx->i1, "");
                                lp_build_if(&if_ctx, gallivm, cond);
                        }
 
                        for (j = 0; j < 4; j++) {
-                               addr = ctx->outputs[i][j];
+                               addr = addrs[4 * i + j];
                                val = LLVMBuildLoad(gallivm->builder, addr, "");
                                val = ac_build_clamp(&ctx->ac, val);
                                LLVMBuildStore(gallivm->builder, val, addr);
                        }
                }
 
                if (cond)
                        lp_build_endif(&if_ctx);
        }
 
        for (i = 0; i < info->num_outputs; i++) {
                outputs[i].semantic_name = info->output_semantic_name[i];
                outputs[i].semantic_index = info->output_semantic_index[i];
 
                for (j = 0; j < 4; j++) {
                        outputs[i].values[j] =
                                LLVMBuildLoad(gallivm->builder,
-                                             ctx->outputs[i][j],
+                                             addrs[4 * i + j],
                                              "");
                        outputs[i].vertex_stream[j] =
                                (info->output_streams[i] >> (2 * j)) & 3;
                }
        }
 
        if (ctx->shader->selector->so.num_outputs)
                si_llvm_emit_streamout(ctx, outputs, i, 0);
 
        /* Export PrimitiveID. */
        if (ctx->shader->key.mono.u.vs_export_prim_id) {
                outputs[i].semantic_name = TGSI_SEMANTIC_PRIMID;
                outputs[i].semantic_index = 0;
-               outputs[i].values[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-                                              get_primitive_id(ctx, 0));
+               outputs[i].values[0] = LLVMBuildBitCast(gallivm->builder,
+                               get_primitive_id(ctx, 0), ctx->f32, "");
                for (j = 1; j < 4; j++)
                        outputs[i].values[j] = LLVMConstReal(ctx->f32, 0);
 
                memset(outputs[i].vertex_stream, 0,
                       sizeof(outputs[i].vertex_stream));
                i++;
        }
 
-       si_llvm_export_vs(bld_base, outputs, i);
+       si_llvm_export_vs(&ctx->bld_base, outputs, i);
        FREE(outputs);
 }
 
+static void si_tgsi_emit_epilogue(struct lp_build_tgsi_context *bld_base)
+{
+       struct si_shader_context *ctx = si_shader_context(bld_base);
+
+       ctx->abi.emit_outputs(&ctx->abi, RADEON_LLVM_MAX_OUTPUTS,
+                             &ctx->outputs[0][0]);
+}
+
 struct si_ps_exports {
        unsigned num;
        struct ac_export_args args[10];
 };
 
 unsigned si_get_spi_shader_z_format(bool writes_z, bool writes_stencil,
                                    bool writes_samplemask)
 {
        if (writes_z) {
                /* Z needs 32 bits. */
@@ -5492,35 +5503,39 @@ static bool si_compile_tgsi_main(struct 
si_shader_context *ctx,
        struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
 
        // TODO clean all this up!
        switch (ctx->type) {
        case PIPE_SHADER_VERTEX:
                ctx->load_input = declare_input_vs;
                if (shader->key.as_ls)
                        bld_base->emit_epilogue = si_llvm_emit_ls_epilogue;
                else if (shader->key.as_es)
                        bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
-               else
-                       bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
+               else {
+                       ctx->abi.emit_outputs = si_llvm_emit_vs_epilogue;
+                       bld_base->emit_epilogue = si_tgsi_emit_epilogue;
+               }
                break;
        case PIPE_SHADER_TESS_CTRL:
                bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tcs;
                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;
                break;
        case PIPE_SHADER_TESS_EVAL:
                bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tes;
                if (shader->key.as_es)
                        bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
-               else
-                       bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
+               else {
+                       ctx->abi.emit_outputs = si_llvm_emit_vs_epilogue;
+                       bld_base->emit_epilogue = si_tgsi_emit_epilogue;
+               }
                break;
        case PIPE_SHADER_GEOMETRY:
                bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_gs;
                bld_base->emit_epilogue = si_llvm_emit_gs_epilogue;
                break;
        case PIPE_SHADER_FRAGMENT:
                ctx->load_input = declare_input_fs;
                bld_base->emit_epilogue = si_llvm_return_fs_outputs;
                break;
        case PIPE_SHADER_COMPUTE:
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h 
b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 2054a73..c8dcd5c 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -235,20 +235,27 @@ struct si_shader_context {
 
        LLVMValueRef shared_memory;
 };
 
 static inline struct si_shader_context *
 si_shader_context(struct lp_build_tgsi_context *bld_base)
 {
        return (struct si_shader_context*)bld_base;
 }
 
+static inline struct si_shader_context *
+si_shader_context_from_abi(struct ac_shader_abi *abi)
+{
+       struct si_shader_context *ctx = NULL;
+       return container_of(abi, ctx, abi);
+}
+
 void si_llvm_add_attribute(LLVMValueRef F, const char *name, int value);
 
 LLVMTargetRef si_llvm_get_amdgpu_target(const char *triple);
 
 unsigned si_llvm_compile(LLVMModuleRef M, struct ac_shader_binary *binary,
                         LLVMTargetMachineRef tm,
                         struct pipe_debug_callback *debug);
 
 LLVMTypeRef tgsi2llvmtype(struct lp_build_tgsi_context *bld_base,
                          enum tgsi_opcode_type type);
-- 
2.9.3

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to