diff options
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 147 |
1 files changed, 67 insertions, 80 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 3610ec90a89..8c4f4e75653 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2790,6 +2790,70 @@ static void si_build_param_exports(struct si_shader_context *ctx, shader->info.nr_param_exports = param_count; } +/** + * 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. + */ +static void si_vertex_color_clamping(struct si_shader_context *ctx, + struct si_shader_output_values *outputs, + unsigned noutput) +{ + LLVMValueRef addr[SI_MAX_VS_OUTPUTS][4]; + bool has_colors = false; + + /* Store original colors to alloca variables. */ + for (unsigned i = 0; i < noutput; i++) { + if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR && + outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR) + continue; + + for (unsigned j = 0; j < 4; j++) { + addr[i][j] = ac_build_alloca_undef(&ctx->ac, ctx->f32, ""); + LLVMBuildStore(ctx->ac.builder, outputs[i].values[j], addr[i][j]); + } + has_colors = true; + } + + if (!has_colors) + return; + + /* The state is in the first bit of the user SGPR. */ + LLVMValueRef cond = LLVMGetParam(ctx->main_fn, ctx->param_vs_state_bits); + cond = LLVMBuildTrunc(ctx->ac.builder, cond, ctx->i1, ""); + + struct lp_build_if_state if_ctx; + lp_build_if(&if_ctx, &ctx->gallivm, cond); + + /* Store clamped colors to alloca variables within the conditional block. */ + for (unsigned i = 0; i < noutput; i++) { + if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR && + outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR) + continue; + + for (unsigned j = 0; j < 4; j++) { + LLVMBuildStore(ctx->ac.builder, + ac_build_clamp(&ctx->ac, outputs[i].values[j]), + addr[i][j]); + } + } + lp_build_endif(&if_ctx); + + /* Load clamped colors */ + for (unsigned i = 0; i < noutput; i++) { + if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR && + outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR) + continue; + + for (unsigned j = 0; j < 4; j++) { + outputs[i].values[j] = + LLVMBuildLoad(ctx->ac.builder, addr[i][j], ""); + } + } +} + /* Generate export instructions for hardware VS shader stage */ static void si_llvm_export_vs(struct si_shader_context *ctx, struct si_shader_output_values *outputs, @@ -2801,6 +2865,8 @@ static void si_llvm_export_vs(struct si_shader_context *ctx, unsigned pos_idx; int i; + si_vertex_color_clamping(ctx, outputs, noutput); + /* Build position exports. */ for (i = 0; i < noutput; i++) { switch (outputs[i].semantic_name) { @@ -3510,42 +3576,6 @@ static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi, 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. - */ - struct lp_build_if_state if_ctx; - LLVMValueRef cond = NULL; - LLVMValueRef addr, val; - - for (i = 0; i < info->num_outputs; i++) { - if (info->output_semantic_name[i] != TGSI_SEMANTIC_COLOR && - info->output_semantic_name[i] != TGSI_SEMANTIC_BCOLOR) - continue; - - /* We've found a color. */ - 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(ctx->ac.builder, cond, - ctx->i1, ""); - lp_build_if(&if_ctx, &ctx->gallivm, cond); - } - - for (j = 0; j < 4; j++) { - addr = addrs[4 * i + j]; - val = LLVMBuildLoad(ctx->ac.builder, addr, ""); - val = ac_build_clamp(&ctx->ac, val); - LLVMBuildStore(ctx->ac.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]; @@ -5640,51 +5670,8 @@ si_generate_gs_copy_shader(struct si_screen *sscreen, stream); } - if (stream == 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. - */ - struct lp_build_if_state if_ctx; - LLVMValueRef v[2], cond = NULL; - LLVMBasicBlockRef blocks[2]; - - for (unsigned i = 0; i < gsinfo->num_outputs; i++) { - if (gsinfo->output_semantic_name[i] != TGSI_SEMANTIC_COLOR && - gsinfo->output_semantic_name[i] != TGSI_SEMANTIC_BCOLOR) - continue; - - /* We've found a color. */ - 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(ctx.ac.builder, cond, - ctx.i1, ""); - lp_build_if(&if_ctx, &ctx.gallivm, cond); - /* Remember blocks for Phi. */ - blocks[0] = if_ctx.true_block; - blocks[1] = if_ctx.entry_block; - } - - for (unsigned j = 0; j < 4; j++) { - /* Insert clamp into the true block. */ - v[0] = ac_build_clamp(&ctx.ac, outputs[i].values[j]); - v[1] = outputs[i].values[j]; - - /* Insert Phi into the endif block. */ - LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.merge_block); - outputs[i].values[j] = ac_build_phi(&ctx.ac, ctx.f32, 2, v, blocks); - LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.true_block); - } - } - if (cond) - lp_build_endif(&if_ctx); - + if (stream == 0) si_llvm_export_vs(&ctx, outputs, gsinfo->num_outputs); - } LLVMBuildBr(builder, end_bb); } |