[Mesa-dev] [PATCH 2/2] draw: hack around weird primitive id input in gs

Brian Paul brianp at vmware.com
Thu Aug 7 13:59:14 PDT 2014


On 08/07/2014 02:50 PM, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> The distinction between system values and ordinary inputs is not very
> obvious in gallium - further fueled by the fact that they use the same
> semantic names.
> Still, if there's any value which imho really is a system value, it's the
> primitive id input into the gs (while earlier (tessleation) stages could read
> it, it is _always_ generated by the system). For some odd reason though (which
> I'd classify as a bug but seems too complicated to fix) the glsl compiler in
> mesa treats this as an ordinary varying, and everything else after that
> (including the state tracker and other drivers) just go along with that.
> But input fetching in gs for llvm based draw was definitely limited to the
> ordinary (2-dimensional) inputs so only worked with other state trackers,
> the code was also additionally relying on tgsi_scan_shader filling
> uses_primid correctly which did not happen neither (would set it only for
> all stages if it was a system value, but only set it for the fragment shader
> if it was an input value).
> This fixes piglit glsl-1.50-geometry-primitive-id-restart and primitive-id-in
> in llvmpipe.
> ---
>   src/gallium/auxiliary/draw/draw_gs.c            |  8 ++++++--
>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 12 ++++++++++++
>   src/gallium/auxiliary/tgsi/tgsi_scan.c          |  6 +++---
>   3 files changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
> index 2b6d2a0..bbf515a 100644
> --- a/src/gallium/auxiliary/draw/draw_gs.c
> +++ b/src/gallium/auxiliary/draw/draw_gs.c
> @@ -228,8 +228,7 @@ llvm_fetch_gs_input(struct draw_geometry_shader *shader,
>      const float (*input_ptr)[4];
>      float (*input_data)[6][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS][TGSI_NUM_CHANNELS] = &shader->gs_input->data;
>
> -   shader->llvm_prim_ids[shader->fetched_prim_count] =
> -      shader->in_prim_idx;
> +   shader->llvm_prim_ids[shader->fetched_prim_count] = shader->in_prim_idx;
>
>      input_ptr = shader->input;
>
> @@ -244,6 +243,11 @@ llvm_fetch_gs_input(struct draw_geometry_shader *shader,
>         for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
>            if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_PRIMID) {
>               /* skip. we handle system values through gallivm */
> +            /* NOTE: If we hit this case here it's an ordinary input not a sv,
> +             * even though it probably should be a sv.
> +             * Not sure how to set it up as regular input however if that even,
> +             * would make sense so hack around this later in gallivm.
> +             */
>            } else {
>               vs_slot = draw_gs_get_input_index(
>                  shader->info.input_semantic_name[slot],
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 02a4a52..f54e856 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -1408,12 +1408,24 @@ emit_fetch_gs_input(
>   {
>      struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
>      struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> +   const struct tgsi_shader_info *info = bld->bld_base.info;
>      LLVMBuilderRef builder = gallivm->builder;
>      LLVMValueRef attrib_index = NULL;
>      LLVMValueRef vertex_index = NULL;
>      LLVMValueRef swizzle_index = lp_build_const_int32(gallivm, swizzle);
>      LLVMValueRef res;
>
> +   if (info->input_semantic_name[reg->Register.Index] == TGSI_SEMANTIC_PRIMID) {
> +      /* This is really a system value not a regular input */
> +      assert(!reg->Register.Indirect);
> +      assert(!reg->Dimension.Indirect);
> +      res = bld->system_values.prim_id;
> +      if (stype != TGSI_TYPE_UNSIGNED && stype != TGSI_TYPE_SIGNED) {
> +         res = LLVMBuildBitCast(builder, res, bld_base->base.vec_type, "");
> +      }
> +      return res;
> +   }
> +
>      if (reg->Register.Indirect) {
>         attrib_index = get_indirect_index(bld,
>                                           reg->Register.File,
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> index 563d2c5..c71bb36 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> @@ -191,11 +191,11 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
>                     info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Interp.CylindricalWrap;
>                     info->num_inputs++;
>
> -                  if (procType == TGSI_PROCESSOR_FRAGMENT) {
> +                  if (semName == TGSI_SEMANTIC_PRIMID)
> +                     info->uses_primid = TRUE;
> +                  else if (procType == TGSI_PROCESSOR_FRAGMENT) {
>                        if (semName == TGSI_SEMANTIC_POSITION)
>                           info->reads_position = TRUE;
> -                     else if (semName == TGSI_SEMANTIC_PRIMID)
> -                        info->uses_primid = TRUE;
>                        else if (semName == TGSI_SEMANTIC_FACE)
>                           info->uses_frontface = TRUE;
>                     }
>

Reviewed-by: Brian Paul <brianp at vmware.com>




More information about the mesa-dev mailing list