From e28fbbd86120955360f814520500ac292c1f32df Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Tue, 22 Oct 2019 19:30:51 -0700 Subject: [PATCH] freedreno/ir3: Implement TCS synchronization intrinsics We add two new IR3 specific nir intrinsics that map to the new condend and endpatch instructions. Signed-off-by: Kristian H. Kristensen Acked-by: Eric Anholt Reviewed-by: Rob Clark --- src/compiler/nir/nir_intrinsics.py | 8 +++++++ src/freedreno/ir3/ir3_compiler_nir.c | 33 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 55050a9e058..4658187ea16 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -798,6 +798,14 @@ system_value("tess_factor_base_ir3", 2) system_value("tess_param_base_ir3", 2) system_value("tcs_header_ir3", 1) +# IR3-specific intrinsics for tessellation control shaders. cond_end_ir3 end +# the shader when src0 is false and is used to narrow down the TCS shader to +# just thread 0 before writing out tessellation levels. +intrinsic("cond_end_ir3", src_comp=[1]) +# end_patch_ir3 is used just before thread 0 exist the TCS and presumably +# signals the TE that the patch is complete and can be tessellated. +intrinsic("end_patch_ir3") + # IR3-specific load/store intrinsics. These access a buffer used to pass data # between geometry stages - perhaps it's explicit access to the vertex cache. diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index b2068a35466..2341c359324 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -1406,6 +1406,15 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) dst[2] = create_immed(b, 0); break; + case nir_intrinsic_end_patch_ir3: + assert(ctx->so->type == MESA_SHADER_TESS_CTRL); + struct ir3_instruction *end = ir3_ENDPATCH(b); + array_insert(b, b->keeps, end); + + end->barrier_class = IR3_BARRIER_EVERYTHING; + end->barrier_conflict = IR3_BARRIER_EVERYTHING; + break; + case nir_intrinsic_store_global_ir3: { struct ir3_instruction *value, *addr, *offset; @@ -1762,6 +1771,30 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) break; } + + case nir_intrinsic_cond_end_ir3: { + struct ir3_instruction *cond, *kill; + + src = ir3_get_src(ctx, &intr->src[0]); + cond = ir3_b2n(b, src[0]); + + /* NOTE: only cmps.*.* can write p0.x: */ + cond = ir3_CMPS_S(b, cond, 0, create_immed(b, 0), 0); + cond->cat2.condition = IR3_COND_NE; + + /* condition always goes in predicate register: */ + cond->regs[0]->num = regid(REG_P0, 0); + + kill = ir3_CONDEND(b, cond, 0); + + kill->barrier_class = IR3_BARRIER_EVERYTHING; + kill->barrier_conflict = IR3_BARRIER_EVERYTHING; + + array_insert(ctx->ir, ctx->ir->predicates, kill); + array_insert(b, b->keeps, kill); + break; + } + case nir_intrinsic_load_shared_ir3: emit_intrinsic_load_shared_ir3(ctx, intr, dst); break; -- 2.30.2