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 <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5555>
This commit is contained in:
Dave Airlie
2020-07-06 12:06:46 +10:00
parent 72ed9e7046
commit d146d7bb97
5 changed files with 8 additions and 2 deletions

View File

@@ -1785,7 +1785,7 @@ draw_gs_llvm_emit_vertex(const struct lp_build_gs_iface *gs_base,
struct lp_build_context * bld, struct lp_build_context * bld,
LLVMValueRef (*outputs)[4], LLVMValueRef (*outputs)[4],
LLVMValueRef emitted_vertices_vec, 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); const struct draw_gs_llvm_iface *gs_iface = draw_gs_llvm_iface(gs_base);
struct draw_gs_llvm_variant *variant = gs_iface->variant; 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; unsigned i;
const struct tgsi_shader_info *gs_info = &variant->shader->base.info; 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) { for (i = 0; i < gs_type.length; ++i) {
LLVMValueRef ind = lp_build_const_int32(gallivm, i); LLVMValueRef ind = lp_build_const_int32(gallivm, i);
LLVMValueRef currently_emitted = LLVMValueRef currently_emitted =
LLVMBuildExtractElement(builder, emitted_vertices_vec, ind, ""); LLVMBuildExtractElement(builder, emitted_vertices_vec, ind, "");
indices[i] = LLVMBuildMul(builder, ind, next_prim_offset, ""); indices[i] = LLVMBuildMul(builder, ind, next_prim_offset, "");
indices[i] = LLVMBuildAdd(builder, indices[i], currently_emitted, ""); 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), ""); LLVMValueRef stream_idx = LLVMBuildExtractElement(builder, stream_id, lp_build_const_int32(gallivm, 0), "");

View File

@@ -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->gs_iface->emit_vertex(bld->gs_iface, &bld->bld_base.base,
bld->outputs, bld->outputs,
total_emitted_vertices_vec, total_emitted_vertices_vec,
mask,
lp_build_const_int_vec(bld->bld_base.base.gallivm, bld->bld_base.base.type, stream_id)); 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], increment_vec_ptr_by_mask(bld_base, bld->emitted_vertices_vec_ptr[stream_id],

View File

@@ -429,7 +429,7 @@ struct lp_build_gs_iface
struct lp_build_context * bld, struct lp_build_context * bld,
LLVMValueRef (*outputs)[4], LLVMValueRef (*outputs)[4],
LLVMValueRef emitted_vertices_vec, LLVMValueRef emitted_vertices_vec,
LLVMValueRef stream_id); LLVMValueRef mask_vec, LLVMValueRef stream_id);
void (*end_primitive)(const struct lp_build_gs_iface *gs_iface, void (*end_primitive)(const struct lp_build_gs_iface *gs_iface,
struct lp_build_context * bld, struct lp_build_context * bld,
LLVMValueRef total_emitted_vertices_vec, LLVMValueRef total_emitted_vertices_vec,

View File

@@ -3969,6 +3969,7 @@ emit_vertex(
bld->gs_iface->emit_vertex(bld->gs_iface, &bld->bld_base.base, bld->gs_iface->emit_vertex(bld->gs_iface, &bld->bld_base.base,
bld->outputs, bld->outputs,
total_emitted_vertices_vec, total_emitted_vertices_vec,
mask,
stream_id); stream_id);
increment_vec_ptr_by_mask(bld_base, bld->emitted_vertices_vec_ptr, increment_vec_ptr_by_mask(bld_base, bld->emitted_vertices_vec_ptr,
mask); mask);

View File

@@ -504,6 +504,7 @@ swr_gs_llvm_emit_vertex(const struct lp_build_gs_iface *gs_base,
struct lp_build_context * bld, struct lp_build_context * bld,
LLVMValueRef (*outputs)[4], LLVMValueRef (*outputs)[4],
LLVMValueRef emitted_vertices_vec, LLVMValueRef emitted_vertices_vec,
LLVMValueRef mask_vec,
LLVMValueRef stream_id) LLVMValueRef stream_id)
{ {
swr_gs_llvm_iface *iface = (swr_gs_llvm_iface*)gs_base; swr_gs_llvm_iface *iface = (swr_gs_llvm_iface*)gs_base;