X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fradeonsi%2Fsi_shader_tgsi_alu.c;h=854f7ec8a6845d228336d36aca72cfe77aa6f85c;hb=f7de8686de823f523ee53f354063d313f9dcecbe;hp=ad7a42f7b84bb2641adba831db5952b10ffa33d0;hpb=1ff9e27cbdd1fe770f18e5316c6f32a867e39095;p=mesa.git diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c index ad7a42f7b84..854f7ec8a68 100644 --- a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c +++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c @@ -53,12 +53,32 @@ static void kill_if_fetch_args(struct lp_build_tgsi_context *bld_base, emit_data->args[0] = conds[0]; } +void si_llvm_emit_kill(struct ac_shader_abi *abi, LLVMValueRef visible) +{ + struct si_shader_context *ctx = si_shader_context_from_abi(abi); + LLVMBuilderRef builder = ctx->ac.builder; + + if (ctx->shader->selector->force_correct_derivs_after_kill) { + /* LLVM 6.0 can kill immediately while maintaining WQM. */ + if (HAVE_LLVM >= 0x0600) { + ac_build_kill_if_false(&ctx->ac, + ac_build_wqm_vote(&ctx->ac, visible)); + } + + LLVMValueRef mask = LLVMBuildLoad(builder, ctx->postponed_kill, ""); + mask = LLVMBuildAnd(builder, mask, visible, ""); + LLVMBuildStore(builder, mask, ctx->postponed_kill); + return; + } + + ac_build_kill_if_false(&ctx->ac, visible); +} + static void kil_emit(const struct lp_build_tgsi_action *action, struct lp_build_tgsi_context *bld_base, struct lp_build_emit_data *emit_data) { struct si_shader_context *ctx = si_shader_context(bld_base); - LLVMBuilderRef builder = ctx->ac.builder; LLVMValueRef visible; if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_KILL_IF) { @@ -68,14 +88,7 @@ static void kil_emit(const struct lp_build_tgsi_action *action, visible = LLVMConstInt(ctx->i1, false, 0); } - if (ctx->postponed_kill) { - LLVMValueRef mask = LLVMBuildLoad(builder, ctx->postponed_kill, ""); - mask = LLVMBuildAnd(builder, mask, visible, ""); - LLVMBuildStore(builder, mask, ctx->postponed_kill); - return; - } - - ac_build_kill_if_false(&ctx->ac, visible); + si_llvm_emit_kill(&ctx->abi, visible); } static void emit_icmp(const struct lp_build_tgsi_action *action, @@ -342,30 +355,17 @@ static void emit_ssg(const struct lp_build_tgsi_action *action, struct lp_build_emit_data *emit_data) { struct si_shader_context *ctx = si_shader_context(bld_base); - LLVMBuilderRef builder = ctx->ac.builder; - LLVMValueRef cmp, val; + LLVMValueRef val; if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_I64SSG) { - cmp = LLVMBuildICmp(builder, LLVMIntSGT, emit_data->args[0], bld_base->int64_bld.zero, ""); - val = LLVMBuildSelect(builder, cmp, bld_base->int64_bld.one, emit_data->args[0], ""); - cmp = LLVMBuildICmp(builder, LLVMIntSGE, val, bld_base->int64_bld.zero, ""); - val = LLVMBuildSelect(builder, cmp, val, LLVMConstInt(ctx->i64, -1, true), ""); + val = ac_build_isign(&ctx->ac, emit_data->args[0], 64); } else if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_ISSG) { - cmp = LLVMBuildICmp(builder, LLVMIntSGT, emit_data->args[0], ctx->i32_0, ""); - val = LLVMBuildSelect(builder, cmp, ctx->i32_1, emit_data->args[0], ""); - cmp = LLVMBuildICmp(builder, LLVMIntSGE, val, ctx->i32_0, ""); - val = LLVMBuildSelect(builder, cmp, val, LLVMConstInt(ctx->i32, -1, true), ""); + val = ac_build_isign(&ctx->ac, emit_data->args[0], 32); } else if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_DSSG) { - cmp = LLVMBuildFCmp(builder, LLVMRealOGT, emit_data->args[0], bld_base->dbl_bld.zero, ""); - val = LLVMBuildSelect(builder, cmp, bld_base->dbl_bld.one, emit_data->args[0], ""); - cmp = LLVMBuildFCmp(builder, LLVMRealOGE, val, bld_base->dbl_bld.zero, ""); - val = LLVMBuildSelect(builder, cmp, val, LLVMConstReal(bld_base->dbl_bld.elem_type, -1), ""); - } else { // float SSG - cmp = LLVMBuildFCmp(builder, LLVMRealOGT, emit_data->args[0], ctx->ac.f32_0, ""); - val = LLVMBuildSelect(builder, cmp, ctx->ac.f32_1, emit_data->args[0], ""); - cmp = LLVMBuildFCmp(builder, LLVMRealOGE, val, ctx->ac.f32_0, ""); - val = LLVMBuildSelect(builder, cmp, val, LLVMConstReal(ctx->f32, -1), ""); + val = ac_build_fsign(&ctx->ac, emit_data->args[0], 64); + } else { + val = ac_build_fsign(&ctx->ac, emit_data->args[0], 32); } emit_data->output[emit_data->chan] = val; @@ -394,22 +394,19 @@ static void emit_frac(const struct lp_build_tgsi_action *action, struct lp_build_emit_data *emit_data) { struct si_shader_context *ctx = si_shader_context(bld_base); - char *intr; + unsigned bitsize; if (emit_data->info->opcode == TGSI_OPCODE_FRC) - intr = "llvm.floor.f32"; + bitsize = 32; else if (emit_data->info->opcode == TGSI_OPCODE_DFRAC) - intr = "llvm.floor.f64"; + bitsize = 64; else { assert(0); return; } - LLVMValueRef floor = lp_build_intrinsic(ctx->ac.builder, intr, emit_data->dst_type, - &emit_data->args[0], 1, - LP_FUNC_ATTR_READNONE); - emit_data->output[emit_data->chan] = LLVMBuildFSub(ctx->ac.builder, - emit_data->args[0], floor, ""); + emit_data->output[emit_data->chan] = + ac_build_fract(&ctx->ac, emit_data->args[0], bitsize); } static void emit_f2i(const struct lp_build_tgsi_action *action, @@ -529,31 +526,8 @@ static void emit_lsb(const struct lp_build_tgsi_action *action, struct lp_build_emit_data *emit_data) { struct si_shader_context *ctx = si_shader_context(bld_base); - LLVMValueRef args[2] = { - emit_data->args[0], - - /* The value of 1 means that ffs(x=0) = undef, so LLVM won't - * add special code to check for x=0. The reason is that - * the LLVM behavior for x=0 is different from what we - * need here. However, LLVM also assumes that ffs(x) is - * in [0, 31], but GLSL expects that ffs(0) = -1, so - * a conditional assignment to handle 0 is still required. - */ - LLVMConstInt(ctx->i1, 1, 0) - }; - - LLVMValueRef lsb = - lp_build_intrinsic(ctx->ac.builder, "llvm.cttz.i32", - emit_data->dst_type, args, ARRAY_SIZE(args), - LP_FUNC_ATTR_READNONE); - /* TODO: We need an intrinsic to skip this conditional. */ - /* Check for zero: */ - emit_data->output[emit_data->chan] = - LLVMBuildSelect(ctx->ac.builder, - LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ, args[0], - ctx->i32_0, ""), - LLVMConstInt(ctx->i32, -1, 0), lsb, ""); + emit_data->output[emit_data->chan] = ac_find_lsb(&ctx->ac, emit_data->dst_type, emit_data->args[0]); } /* Find the last bit set. */ @@ -685,13 +659,7 @@ static void emit_fdiv(const struct lp_build_tgsi_action *action, struct si_shader_context *ctx = si_shader_context(bld_base); emit_data->output[emit_data->chan] = - LLVMBuildFDiv(ctx->ac.builder, - emit_data->args[0], emit_data->args[1], ""); - - /* Use v_rcp_f32 instead of precise division. */ - if (!LLVMIsConstant(emit_data->output[emit_data->chan])) - LLVMSetMetadata(emit_data->output[emit_data->chan], - ctx->fpmath_md_kind, ctx->fpmath_md_2p5_ulp); + ac_build_fdiv(&ctx->ac, emit_data->args[0], emit_data->args[1]); } /* 1/sqrt is translated to rsq for f32 if fp32 denormals are not enabled in