[Mesa-dev] [PATCH] gallivm/gs: fix indirect addressing in geometry shaders
Roland Scheidegger
sroland at vmware.com
Wed Apr 17 12:43:42 PDT 2013
Am 17.04.2013 21:17, schrieb Zack Rusin:
> We were always treating the vertex index as a scalar but when the
> shader is using indirect addressing it will be a vector of indices
> for each channel. This was causing some nasty crashes insides
> LLVM.
>
> Signed-off-by: Zack Rusin <zackr at vmware.com>
> ---
> src/gallium/auxiliary/draw/draw_llvm.c | 34 +++++++++++++++++++----
> src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 1 +
> src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 1 +
> 3 files changed, 30 insertions(+), 6 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
> index 33fe40d..8e3ea88 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm.c
> @@ -1253,6 +1253,7 @@ clipmask_booli32(struct gallivm_state *gallivm,
> static LLVMValueRef
> draw_gs_llvm_fetch_input(const struct lp_build_tgsi_gs_iface *gs_iface,
> struct lp_build_tgsi_context * bld_base,
> + boolean is_indirect,
> LLVMValueRef vertex_index,
> LLVMValueRef attrib_index,
> LLVMValueRef swizzle_index)
> @@ -1262,13 +1263,34 @@ draw_gs_llvm_fetch_input(const struct lp_build_tgsi_gs_iface *gs_iface,
> LLVMBuilderRef builder = gallivm->builder;
> LLVMValueRef indices[3];
> LLVMValueRef res;
> + struct lp_type type = bld_base->base.type;
> +
> + if (is_indirect) {
> + int i;
> + res = bld_base->base.zero;
> + for (i = 0; i < type.length; ++i) {
> + LLVMValueRef idx = lp_build_const_int32(gallivm, i);
> + LLVMValueRef vert_chan_index = LLVMBuildExtractElement(builder,
> + vertex_index, idx, "");
> + LLVMValueRef channel_vec, value;
> + indices[0] = vert_chan_index;
> + indices[1] = attrib_index;
> + indices[2] = swizzle_index;
> +
> + channel_vec = LLVMBuildGEP(builder, gs->input, indices, 3, "");
> + channel_vec = LLVMBuildLoad(builder, channel_vec, "");
> + value = LLVMBuildExtractElement(builder, channel_vec, idx, "");
> +
> + res = LLVMBuildInsertElement(builder, res, value, idx, "");
> + }
> + } else {
> + indices[0] = vertex_index;
> + indices[1] = attrib_index;
> + indices[2] = swizzle_index;
>
> - indices[0] = vertex_index;
> - indices[1] = attrib_index;
> - indices[2] = swizzle_index;
> -
> - res = LLVMBuildGEP(builder, gs->input, indices, 3, "");
> - res = LLVMBuildLoad(builder, res, "");
> + res = LLVMBuildGEP(builder, gs->input, indices, 3, "");
> + res = LLVMBuildLoad(builder, res, "");
> + }
>
> return res;
> }
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> index 0fbb8aa..78a1f0e 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> @@ -368,6 +368,7 @@ struct lp_build_tgsi_gs_iface
> {
> LLVMValueRef (*fetch_input)(const struct lp_build_tgsi_gs_iface *gs_iface,
> struct lp_build_tgsi_context * bld_base,
> + boolean is_indirect,
> LLVMValueRef vertex_index,
> LLVMValueRef attrib_index,
> LLVMValueRef swizzle_index);
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 28eb57b..ea7dec7 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -829,6 +829,7 @@ emit_fetch_gs_input(
> }
>
> res = bld->gs_iface->fetch_input(bld->gs_iface, bld_base,
> + reg->Dimension.Indirect,
> vertex_index, attrib_index,
> swizzle_index);
>
>
Looks good.
Reviewed-by: Roland Scheidegger <sroland at vmware.com>
More information about the mesa-dev
mailing list