From: Nicolai Hähnle <nicolai.haeh...@amd.com> --- src/gallium/drivers/radeonsi/si_shader.c | 95 ++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 35 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 81c361e..ec5f950 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -6751,20 +6751,36 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx, if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) { fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n"); return false; } si_llvm_build_ret(ctx, ctx->return_value); return true; } +/** + * Compute the PS epilog key, which contains all the information needed to + * build the PS epilog function. + */ +static void si_get_ps_epilog_key(struct si_shader *shader, + union si_shader_part_key *key) +{ + struct tgsi_shader_info *info = &shader->selector->info; + memset(key, 0, sizeof(*key)); + key->ps_epilog.colors_written = info->colors_written; + key->ps_epilog.writes_z = info->writes_z; + key->ps_epilog.writes_stencil = info->writes_stencil; + key->ps_epilog.writes_samplemask = info->writes_samplemask; + key->ps_epilog.states = shader->key.ps.epilog; +} + int si_compile_tgsi_shader(struct si_screen *sscreen, LLVMTargetMachineRef tm, struct si_shader *shader, bool is_monolithic, struct pipe_debug_callback *debug) { struct si_shader_selector *sel = shader->selector; struct si_shader_context ctx; struct lp_build_tgsi_context *bld_base; LLVMModuleRef mod; @@ -7591,71 +7607,61 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen, if (si_compile_llvm(sscreen, &out->binary, &out->config, tm, gallivm->module, debug, ctx.type, "Fragment Shader Prolog")) status = false; si_llvm_dispose(&ctx); return status; } /** - * Compile the pixel shader epilog. This handles everything that must be + * Build the pixel shader epilog function. This handles everything that must be * emulated for pixel shader exports. (alpha-test, format conversions, etc) */ -static bool si_compile_ps_epilog(struct si_screen *sscreen, - LLVMTargetMachineRef tm, - struct pipe_debug_callback *debug, - struct si_shader_part *out) +static void si_build_ps_epilog_function(struct si_shader_context *ctx, + union si_shader_part_key *key) { - union si_shader_part_key *key = &out->key; - struct si_shader shader = {}; - struct si_shader_context ctx; - struct gallivm_state *gallivm = &ctx.gallivm; - struct lp_build_tgsi_context *bld_base = &ctx.soa.bld_base; + struct gallivm_state *gallivm = &ctx->gallivm; + struct lp_build_tgsi_context *bld_base = &ctx->soa.bld_base; LLVMTypeRef params[16+8*4+3]; LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL; int last_sgpr, num_params, i; - bool status = true; struct si_ps_exports exp = {}; - si_init_shader_ctx(&ctx, sscreen, &shader, tm); - ctx.type = PIPE_SHADER_FRAGMENT; - shader.key.ps.epilog = key->ps_epilog.states; - /* Declare input SGPRs. */ - params[SI_PARAM_RW_BUFFERS] = ctx.i64; - params[SI_PARAM_CONST_BUFFERS] = ctx.i64; - params[SI_PARAM_SAMPLERS] = ctx.i64; - params[SI_PARAM_IMAGES] = ctx.i64; - params[SI_PARAM_SHADER_BUFFERS] = ctx.i64; - params[SI_PARAM_ALPHA_REF] = ctx.f32; + params[SI_PARAM_RW_BUFFERS] = ctx->i64; + params[SI_PARAM_CONST_BUFFERS] = ctx->i64; + params[SI_PARAM_SAMPLERS] = ctx->i64; + params[SI_PARAM_IMAGES] = ctx->i64; + params[SI_PARAM_SHADER_BUFFERS] = ctx->i64; + params[SI_PARAM_ALPHA_REF] = ctx->f32; last_sgpr = SI_PARAM_ALPHA_REF; /* Declare input VGPRs. */ num_params = (last_sgpr + 1) + util_bitcount(key->ps_epilog.colors_written) * 4 + key->ps_epilog.writes_z + key->ps_epilog.writes_stencil + key->ps_epilog.writes_samplemask; num_params = MAX2(num_params, last_sgpr + 1 + PS_EPILOG_SAMPLEMASK_MIN_LOC + 1); assert(num_params <= ARRAY_SIZE(params)); for (i = last_sgpr + 1; i < num_params; i++) - params[i] = ctx.f32; + params[i] = ctx->f32; /* Create the function. */ - si_create_function(&ctx, "ps_epilog", NULL, 0, params, num_params, last_sgpr); + si_create_function(ctx, "ps_epilog", NULL, 0, params, num_params, last_sgpr); /* Disable elimination of unused inputs. */ - si_llvm_add_attribute(ctx.main_fn, + si_llvm_add_attribute(ctx->main_fn, "InitialPSInputAddr", 0xffffff); /* Process colors. */ unsigned vgpr = last_sgpr + 1; unsigned colors_written = key->ps_epilog.colors_written; int last_color_export = -1; /* Find the last color export. */ if (!key->ps_epilog.writes_z && !key->ps_epilog.writes_stencil && @@ -7674,45 +7680,69 @@ static bool si_compile_ps_epilog(struct si_screen *sscreen, (spi_format >> (i * 4)) & 0xf) last_color_export = i; } } while (colors_written) { LLVMValueRef color[4]; int mrt = u_bit_scan(&colors_written); for (i = 0; i < 4; i++) - color[i] = LLVMGetParam(ctx.main_fn, vgpr++); + color[i] = LLVMGetParam(ctx->main_fn, vgpr++); si_export_mrt_color(bld_base, color, mrt, num_params - 1, mrt == last_color_export, &exp); } /* Process depth, stencil, samplemask. */ if (key->ps_epilog.writes_z) - depth = LLVMGetParam(ctx.main_fn, vgpr++); + depth = LLVMGetParam(ctx->main_fn, vgpr++); if (key->ps_epilog.writes_stencil) - stencil = LLVMGetParam(ctx.main_fn, vgpr++); + stencil = LLVMGetParam(ctx->main_fn, vgpr++); if (key->ps_epilog.writes_samplemask) - samplemask = LLVMGetParam(ctx.main_fn, vgpr++); + samplemask = LLVMGetParam(ctx->main_fn, vgpr++); if (depth || stencil || samplemask) si_export_mrt_z(bld_base, depth, stencil, samplemask, &exp); else if (last_color_export == -1) si_export_null(bld_base); if (exp.num) - si_emit_ps_exports(&ctx, &exp); + si_emit_ps_exports(ctx, &exp); /* Compile. */ LLVMBuildRetVoid(gallivm->builder); +} + + +/** + * Compile the pixel shader epilog to a binary for concatenation. + */ +static bool si_compile_ps_epilog(struct si_screen *sscreen, + LLVMTargetMachineRef tm, + struct pipe_debug_callback *debug, + struct si_shader_part *out) +{ + union si_shader_part_key *key = &out->key; + struct si_shader shader = {}; + struct si_shader_context ctx; + struct gallivm_state *gallivm = &ctx.gallivm; + bool status = true; + + si_init_shader_ctx(&ctx, sscreen, &shader, tm); + ctx.type = PIPE_SHADER_FRAGMENT; + shader.key.ps.epilog = key->ps_epilog.states; + + si_build_ps_epilog_function(&ctx, key); + + /* Compile. */ si_llvm_finalize_module(&ctx, r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT)); if (si_compile_llvm(sscreen, &out->binary, &out->config, tm, gallivm->module, debug, ctx.type, "Fragment Shader Epilog")) status = false; si_llvm_dispose(&ctx); return status; @@ -7845,26 +7875,21 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen, prolog_key.ps_prolog.states.poly_stipple) { shader->prolog = si_get_shader_part(sscreen, &sscreen->ps_prologs, &prolog_key, tm, debug, si_compile_ps_prolog); if (!shader->prolog) return false; } /* Get the epilog. */ - memset(&epilog_key, 0, sizeof(epilog_key)); - epilog_key.ps_epilog.colors_written = info->colors_written; - epilog_key.ps_epilog.writes_z = info->writes_z; - epilog_key.ps_epilog.writes_stencil = info->writes_stencil; - epilog_key.ps_epilog.writes_samplemask = info->writes_samplemask; - epilog_key.ps_epilog.states = shader->key.ps.epilog; + si_get_ps_epilog_key(shader, &epilog_key); shader->epilog = si_get_shader_part(sscreen, &sscreen->ps_epilogs, &epilog_key, tm, debug, si_compile_ps_epilog); if (!shader->epilog) return false; /* Enable POS_FIXED_PT if polygon stippling is enabled. */ if (shader->key.ps.prolog.poly_stipple) { -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev