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