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:
@@ -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), "");
|
||||
|
@@ -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],
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user