ac: replace ac_build_kill with ac_build_kill_if_false
This will be a new LLVM intrinsic and will also work nicely with llvm.amdgcn.wqm.vote. Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
@@ -1405,20 +1405,13 @@ LLVMValueRef ac_build_cvt_pkrtz_f16(struct ac_llvm_context *ctx,
|
||||
AC_FUNC_ATTR_LEGACY);
|
||||
}
|
||||
|
||||
/**
|
||||
* KILL, AKA discard in GLSL.
|
||||
*
|
||||
* \param value kill if value < 0.0 or value == NULL.
|
||||
*/
|
||||
void ac_build_kill(struct ac_llvm_context *ctx, LLVMValueRef value)
|
||||
void ac_build_kill_if_false(struct ac_llvm_context *ctx, LLVMValueRef i1)
|
||||
{
|
||||
if (value) {
|
||||
ac_build_intrinsic(ctx, "llvm.AMDGPU.kill", ctx->voidt,
|
||||
&value, 1, AC_FUNC_ATTR_LEGACY);
|
||||
} else {
|
||||
ac_build_intrinsic(ctx, "llvm.AMDGPU.kilp", ctx->voidt,
|
||||
NULL, 0, AC_FUNC_ATTR_LEGACY);
|
||||
}
|
||||
LLVMValueRef value = LLVMBuildSelect(ctx->builder, i1,
|
||||
LLVMConstReal(ctx->f32, 1),
|
||||
LLVMConstReal(ctx->f32, -1), "");
|
||||
ac_build_intrinsic(ctx, "llvm.AMDGPU.kill", ctx->voidt,
|
||||
&value, 1, AC_FUNC_ATTR_LEGACY);
|
||||
}
|
||||
|
||||
LLVMValueRef ac_build_bfe(struct ac_llvm_context *ctx, LLVMValueRef input,
|
||||
|
@@ -265,7 +265,7 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
|
||||
struct ac_image_args *a);
|
||||
LLVMValueRef ac_build_cvt_pkrtz_f16(struct ac_llvm_context *ctx,
|
||||
LLVMValueRef args[2]);
|
||||
void ac_build_kill(struct ac_llvm_context *ctx, LLVMValueRef value);
|
||||
void ac_build_kill_if_false(struct ac_llvm_context *ctx, LLVMValueRef i1);
|
||||
LLVMValueRef ac_build_bfe(struct ac_llvm_context *ctx, LLVMValueRef input,
|
||||
LLVMValueRef offset, LLVMValueRef width,
|
||||
bool is_signed);
|
||||
|
@@ -3779,14 +3779,10 @@ static void emit_discard_if(struct ac_nir_context *ctx,
|
||||
{
|
||||
LLVMValueRef cond;
|
||||
|
||||
cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntNE,
|
||||
cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ,
|
||||
get_src(ctx, instr->src[0]),
|
||||
ctx->ac.i32_0, "");
|
||||
|
||||
cond = LLVMBuildSelect(ctx->ac.builder, cond,
|
||||
LLVMConstReal(ctx->ac.f32, -1.0f),
|
||||
ctx->ac.f32_0, "");
|
||||
ac_build_kill(&ctx->ac, cond);
|
||||
ac_build_kill_if_false(&ctx->ac, cond);
|
||||
}
|
||||
|
||||
static LLVMValueRef
|
||||
@@ -4021,7 +4017,7 @@ visit_emit_vertex(struct nir_to_llvm_context *ctx,
|
||||
const nir_intrinsic_instr *instr)
|
||||
{
|
||||
LLVMValueRef gs_next_vertex;
|
||||
LLVMValueRef can_emit, kill;
|
||||
LLVMValueRef can_emit;
|
||||
int idx;
|
||||
|
||||
assert(instr->const_index[0] == 0);
|
||||
@@ -4037,11 +4033,7 @@ visit_emit_vertex(struct nir_to_llvm_context *ctx,
|
||||
*/
|
||||
can_emit = LLVMBuildICmp(ctx->builder, LLVMIntULT, gs_next_vertex,
|
||||
LLVMConstInt(ctx->i32, ctx->gs_max_out_vertices, false), "");
|
||||
|
||||
kill = LLVMBuildSelect(ctx->builder, can_emit,
|
||||
LLVMConstReal(ctx->f32, 1.0f),
|
||||
LLVMConstReal(ctx->f32, -1.0f), "");
|
||||
ac_build_kill(&ctx->ac, kill);
|
||||
ac_build_kill_if_false(&ctx->ac, can_emit);
|
||||
|
||||
/* loop num outputs */
|
||||
idx = 0;
|
||||
|
@@ -2272,22 +2272,24 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
|
||||
struct si_shader_context *ctx = si_shader_context(bld_base);
|
||||
|
||||
if (ctx->shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_NEVER) {
|
||||
static LLVMRealPredicate cond_map[PIPE_FUNC_ALWAYS + 1] = {
|
||||
[PIPE_FUNC_LESS] = LLVMRealOLT,
|
||||
[PIPE_FUNC_EQUAL] = LLVMRealOEQ,
|
||||
[PIPE_FUNC_LEQUAL] = LLVMRealOLE,
|
||||
[PIPE_FUNC_GREATER] = LLVMRealOGT,
|
||||
[PIPE_FUNC_NOTEQUAL] = LLVMRealONE,
|
||||
[PIPE_FUNC_GEQUAL] = LLVMRealOGE,
|
||||
};
|
||||
LLVMRealPredicate cond = cond_map[ctx->shader->key.part.ps.epilog.alpha_func];
|
||||
assert(cond);
|
||||
|
||||
LLVMValueRef alpha_ref = LLVMGetParam(ctx->main_fn,
|
||||
SI_PARAM_ALPHA_REF);
|
||||
|
||||
LLVMValueRef alpha_pass =
|
||||
lp_build_cmp(&bld_base->base,
|
||||
ctx->shader->key.part.ps.epilog.alpha_func,
|
||||
alpha, alpha_ref);
|
||||
LLVMValueRef arg =
|
||||
lp_build_select(&bld_base->base,
|
||||
alpha_pass,
|
||||
LLVMConstReal(ctx->f32, 1.0f),
|
||||
LLVMConstReal(ctx->f32, -1.0f));
|
||||
|
||||
ac_build_kill(&ctx->ac, arg);
|
||||
LLVMBuildFCmp(ctx->ac.builder, cond, alpha, alpha_ref, "");
|
||||
ac_build_kill_if_false(&ctx->ac, alpha_pass);
|
||||
} else {
|
||||
ac_build_kill(&ctx->ac, NULL);
|
||||
ac_build_kill_if_false(&ctx->ac, LLVMConstInt(ctx->i1, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3573,7 +3575,7 @@ static void si_llvm_return_fs_outputs(struct ac_shader_abi *abi,
|
||||
LLVMValueRef ret;
|
||||
|
||||
if (ctx->postponed_kill)
|
||||
ac_build_kill(&ctx->ac, LLVMBuildLoad(builder, ctx->postponed_kill, ""));
|
||||
ac_build_kill_if_false(&ctx->ac, LLVMBuildLoad(builder, ctx->postponed_kill, ""));
|
||||
|
||||
/* Read the output values. */
|
||||
for (i = 0; i < info->num_outputs; i++) {
|
||||
@@ -4056,7 +4058,7 @@ static void si_llvm_emit_vertex(
|
||||
LLVMValueRef soffset = LLVMGetParam(ctx->main_fn,
|
||||
ctx->param_gs2vs_offset);
|
||||
LLVMValueRef gs_next_vertex;
|
||||
LLVMValueRef can_emit, kill;
|
||||
LLVMValueRef can_emit;
|
||||
unsigned chan, offset;
|
||||
int i;
|
||||
unsigned stream;
|
||||
@@ -4082,11 +4084,7 @@ static void si_llvm_emit_vertex(
|
||||
|
||||
bool use_kill = !info->writes_memory;
|
||||
if (use_kill) {
|
||||
kill = lp_build_select(&bld_base->base, can_emit,
|
||||
LLVMConstReal(ctx->f32, 1.0f),
|
||||
LLVMConstReal(ctx->f32, -1.0f));
|
||||
|
||||
ac_build_kill(&ctx->ac, kill);
|
||||
ac_build_kill_if_false(&ctx->ac, can_emit);
|
||||
} else {
|
||||
lp_build_if(&if_state, &ctx->gallivm, can_emit);
|
||||
}
|
||||
@@ -4881,11 +4879,7 @@ static void si_llvm_emit_polygon_stipple(struct si_shader_context *ctx,
|
||||
row = ac_to_integer(&ctx->ac, row);
|
||||
bit = LLVMBuildLShr(builder, row, address[0], "");
|
||||
bit = LLVMBuildTrunc(builder, bit, ctx->i1, "");
|
||||
|
||||
/* The intrinsic kills the thread if arg < 0. */
|
||||
bit = LLVMBuildSelect(builder, bit, LLVMConstReal(ctx->f32, 0),
|
||||
LLVMConstReal(ctx->f32, -1), "");
|
||||
ac_build_kill(&ctx->ac, bit);
|
||||
ac_build_kill_if_false(&ctx->ac, bit);
|
||||
}
|
||||
|
||||
void si_shader_binary_read_config(struct ac_shader_binary *binary,
|
||||
@@ -5854,8 +5848,10 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
|
||||
|
||||
if (ctx->type == PIPE_SHADER_FRAGMENT && sel->info.uses_kill &&
|
||||
ctx->screen->b.debug_flags & DBG(FS_CORRECT_DERIVS_AFTER_KILL)) {
|
||||
/* This is initialized to 0.0 = not kill. */
|
||||
ctx->postponed_kill = lp_build_alloca(&ctx->gallivm, ctx->f32, "");
|
||||
ctx->postponed_kill = lp_build_alloca_undef(&ctx->gallivm, ctx->i1, "");
|
||||
/* true = don't kill. */
|
||||
LLVMBuildStore(ctx->ac.builder, LLVMConstInt(ctx->i1, 1, 0),
|
||||
ctx->postponed_kill);
|
||||
}
|
||||
|
||||
if (sel->tokens) {
|
||||
|
@@ -39,20 +39,18 @@ static void kill_if_fetch_args(struct lp_build_tgsi_context *bld_base,
|
||||
|
||||
for (i = 0; i < TGSI_NUM_CHANNELS; i++) {
|
||||
LLVMValueRef value = lp_build_emit_fetch(bld_base, inst, 0, i);
|
||||
conds[i] = LLVMBuildFCmp(builder, LLVMRealOLT, value,
|
||||
conds[i] = LLVMBuildFCmp(builder, LLVMRealOGE, value,
|
||||
ctx->ac.f32_0, "");
|
||||
}
|
||||
|
||||
/* Or the conditions together */
|
||||
/* And the conditions together */
|
||||
for (i = TGSI_NUM_CHANNELS - 1; i > 0; i--) {
|
||||
conds[i - 1] = LLVMBuildOr(builder, conds[i], conds[i - 1], "");
|
||||
conds[i - 1] = LLVMBuildAnd(builder, conds[i], conds[i - 1], "");
|
||||
}
|
||||
|
||||
emit_data->dst_type = ctx->voidt;
|
||||
emit_data->arg_count = 1;
|
||||
emit_data->args[0] = LLVMBuildSelect(builder, conds[0],
|
||||
LLVMConstReal(ctx->f32, -1.0f),
|
||||
ctx->ac.f32_0, "");
|
||||
emit_data->args[0] = conds[0];
|
||||
}
|
||||
|
||||
static void kil_emit(const struct lp_build_tgsi_action *action,
|
||||
@@ -61,31 +59,23 @@ static void kil_emit(const struct lp_build_tgsi_action *action,
|
||||
{
|
||||
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) {
|
||||
visible = emit_data->args[0];
|
||||
} else {
|
||||
assert(emit_data->inst->Instruction.Opcode == TGSI_OPCODE_KILL);
|
||||
visible = LLVMConstInt(ctx->i1, false, 0);
|
||||
}
|
||||
|
||||
if (ctx->postponed_kill) {
|
||||
if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_KILL_IF) {
|
||||
LLVMValueRef val;
|
||||
|
||||
/* Take the minimum kill value. This is the same as OR
|
||||
* between 2 kill values. If the value is negative,
|
||||
* the pixel will be killed.
|
||||
*/
|
||||
val = LLVMBuildLoad(builder, ctx->postponed_kill, "");
|
||||
val = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_MIN,
|
||||
val, emit_data->args[0]);
|
||||
LLVMBuildStore(builder, val, ctx->postponed_kill);
|
||||
} else {
|
||||
LLVMBuildStore(builder,
|
||||
LLVMConstReal(ctx->f32, -1),
|
||||
ctx->postponed_kill);
|
||||
}
|
||||
LLVMValueRef mask = LLVMBuildLoad(builder, ctx->postponed_kill, "");
|
||||
mask = LLVMBuildAnd(builder, mask, visible, "");
|
||||
LLVMBuildStore(builder, mask, ctx->postponed_kill);
|
||||
return;
|
||||
}
|
||||
|
||||
if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_KILL_IF)
|
||||
ac_build_kill(&ctx->ac, emit_data->args[0]);
|
||||
else
|
||||
ac_build_kill(&ctx->ac, NULL);
|
||||
ac_build_kill_if_false(&ctx->ac, visible);
|
||||
}
|
||||
|
||||
static void emit_icmp(const struct lp_build_tgsi_action *action,
|
||||
|
Reference in New Issue
Block a user