aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2017-10-04 04:51:39 +0200
committerMarek Olšák <[email protected]>2017-10-24 14:56:34 +0200
commit1ff9e27cbdd1fe770f18e5316c6f32a867e39095 (patch)
treea5b282c567496845ba6986e22e52ac046fa0cbcf /src
parentf0a2bbd1a4a0caf85d91469e61d01a126cfc2a36 (diff)
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/amd/common/ac_llvm_build.c19
-rw-r--r--src/amd/common/ac_llvm_build.h2
-rw-r--r--src/amd/common/ac_nir_to_llvm.c16
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c48
-rw-r--r--src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c42
5 files changed, 49 insertions, 78 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 4d8f42d572c..5bd04663216 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -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,
diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h
index aa2a2899ab4..8f7a9abb76c 100644
--- a/src/amd/common/ac_llvm_build.h
+++ b/src/amd/common/ac_llvm_build.h
@@ -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);
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 2e50e50b129..4f7e8449725 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -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;
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index c3fe13deeaa..8abacac8c8d 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -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) {
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
index fc705c376e5..ad7a42f7b84 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
@@ -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,