Mesa (master): draw/gs: use mask to limit vertex emission.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 7 20:37:18 UTC 2020


Module: Mesa
Branch: master
Commit: d146d7bb97df94869684f06d075cb54374e5faac
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d146d7bb97df94869684f06d075cb54374e5faac

Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Jul  6 12:06:46 2020 +1000

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 at vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5555>

---

 src/gallium/auxiliary/draw/draw_llvm.c          | 5 ++++-
 src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c  | 1 +
 src/gallium/auxiliary/gallivm/lp_bld_tgsi.h     | 2 +-
 src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 1 +
 src/gallium/drivers/swr/swr_shader.cpp          | 1 +
 5 files changed, 8 insertions(+), 2 deletions(-)

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;



More information about the mesa-commit mailing list