From: Dave Airlie Date: Mon, 6 Jul 2020 02:06:46 +0000 (+1000) Subject: draw/gs: use mask to limit vertex emission. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d146d7bb97df94869684f06d075cb54374e5faac;p=mesa.git draw/gs: use mask to limit vertex emission. When executing for a single primitive, the mask has only one active lane, however the vertex emit emits for all the lanes, pass in the active mask and write the excess lanes to the overflow slot. Fixes: glsl-1.50-gs-max-output -scan 1 20 Reviewed-by: Roland Scheidegger Part-of: --- diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 862c570efbf..845ed6242b1 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -1785,7 +1785,7 @@ draw_gs_llvm_emit_vertex(const struct lp_build_gs_iface *gs_base, struct lp_build_context * bld, LLVMValueRef (*outputs)[4], LLVMValueRef emitted_vertices_vec, - LLVMValueRef stream_id) + LLVMValueRef mask_vec, LLVMValueRef stream_id) { const struct draw_gs_llvm_iface *gs_iface = draw_gs_llvm_iface(gs_base); struct draw_gs_llvm_variant *variant = gs_iface->variant; @@ -1801,12 +1801,15 @@ draw_gs_llvm_emit_vertex(const struct lp_build_gs_iface *gs_base, unsigned i; const struct tgsi_shader_info *gs_info = &variant->shader->base.info; + LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE, mask_vec, lp_build_const_int_vec(gallivm, bld->type, 0), ""); for (i = 0; i < gs_type.length; ++i) { LLVMValueRef ind = lp_build_const_int32(gallivm, i); LLVMValueRef currently_emitted = LLVMBuildExtractElement(builder, emitted_vertices_vec, ind, ""); indices[i] = LLVMBuildMul(builder, ind, next_prim_offset, ""); indices[i] = LLVMBuildAdd(builder, indices[i], currently_emitted, ""); + indices[i] = LLVMBuildSelect(builder, LLVMBuildExtractElement(builder, cond, ind, ""), indices[i], + lp_build_const_int32(gallivm, variant->shader->base.primitive_boundary - 1), ""); } LLVMValueRef stream_idx = LLVMBuildExtractElement(builder, stream_id, lp_build_const_int32(gallivm, 0), ""); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index a363571a2cd..6af022a8bca 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -1604,6 +1604,7 @@ static void emit_vertex(struct lp_build_nir_context *bld_base, uint32_t stream_i bld->gs_iface->emit_vertex(bld->gs_iface, &bld->bld_base.base, bld->outputs, total_emitted_vertices_vec, + mask, lp_build_const_int_vec(bld->bld_base.base.gallivm, bld->bld_base.base.type, stream_id)); increment_vec_ptr_by_mask(bld_base, bld->emitted_vertices_vec_ptr[stream_id], diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 42a01ec6a77..b059c1a8a4e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -429,7 +429,7 @@ struct lp_build_gs_iface struct lp_build_context * bld, LLVMValueRef (*outputs)[4], LLVMValueRef emitted_vertices_vec, - LLVMValueRef stream_id); + LLVMValueRef mask_vec, LLVMValueRef stream_id); void (*end_primitive)(const struct lp_build_gs_iface *gs_iface, struct lp_build_context * bld, LLVMValueRef total_emitted_vertices_vec, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 9e00726b35d..f3f339923db 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -3969,6 +3969,7 @@ emit_vertex( bld->gs_iface->emit_vertex(bld->gs_iface, &bld->bld_base.base, bld->outputs, total_emitted_vertices_vec, + mask, stream_id); increment_vec_ptr_by_mask(bld_base, bld->emitted_vertices_vec_ptr, mask); diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index ea3701346aa..cc3bf717653 100644 --- a/src/gallium/drivers/swr/swr_shader.cpp +++ b/src/gallium/drivers/swr/swr_shader.cpp @@ -504,6 +504,7 @@ swr_gs_llvm_emit_vertex(const struct lp_build_gs_iface *gs_base, struct lp_build_context * bld, LLVMValueRef (*outputs)[4], LLVMValueRef emitted_vertices_vec, + LLVMValueRef mask_vec, LLVMValueRef stream_id) { swr_gs_llvm_iface *iface = (swr_gs_llvm_iface*)gs_base;