[Mesa-dev] [PATCH] draw: fix base instance handling in llvm path

Jose Fonseca jfonseca at vmware.com
Tue Aug 26 06:33:47 PDT 2014


Great find Roland.

Patch looks good.

Jose

On 25/08/14 21:05, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> The base instance needs to be passed to the jited function, otherwise the
> instanced data fetch will only work with the same start instance when the
> jit function was created (and baking that into the key instead is not a viable
> option).
> This fixes piglit arb_base_instance-drawarrays (modulo some unrelated
> core/compat context trouble I get for the test).
> And fix the pipe cap bit in llvmpipe for it now that it actually works (it
> already worked for softpipe).
> ---
>   src/gallium/auxiliary/draw/draw_llvm.c                   | 16 ++++++++++------
>   src/gallium/auxiliary/draw/draw_llvm.h                   |  6 ++++--
>   .../auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c   |  6 ++++--
>   src/gallium/drivers/llvmpipe/lp_screen.c                 |  2 +-
>   src/gallium/drivers/softpipe/sp_screen.c                 |  2 +-
>   5 files changed, 20 insertions(+), 12 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
> index 2c6ca0d..467f074 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm.c
> @@ -645,7 +645,8 @@ generate_fetch(struct gallivm_state *gallivm,
>                  struct pipe_vertex_element *velem,
>                  LLVMValueRef vbuf,
>                  LLVMValueRef index,
> -               LLVMValueRef instance_id)
> +               LLVMValueRef instance_id,
> +               LLVMValueRef start_instance)
>   {
>      const struct util_format_description *format_desc =
>         util_format_description(velem->src_format);
> @@ -675,11 +676,11 @@ generate_fetch(struct gallivm_state *gallivm,
>          * index = start_instance + (instance_id  / divisor)
>          */
>         LLVMValueRef current_instance;
> -      index = lp_build_const_int32(gallivm, draw->start_instance);
>         current_instance = LLVMBuildUDiv(builder, instance_id,
>                                          lp_build_const_int32(gallivm, velem->instance_divisor),
>                                          "instance_divisor");
> -      index = lp_build_uadd_overflow(gallivm, index, current_instance, &ofbit);
> +      index = lp_build_uadd_overflow(gallivm, start_instance,
> +                                     current_instance, &ofbit);
>      }
>
>      stride = lp_build_umul_overflow(gallivm, vb_stride, index, &ofbit);
> @@ -1473,7 +1474,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
>      struct gallivm_state *gallivm = variant->gallivm;
>      LLVMContextRef context = gallivm->context;
>      LLVMTypeRef int32_type = LLVMInt32TypeInContext(context);
> -   LLVMTypeRef arg_types[10];
> +   LLVMTypeRef arg_types[11];
>      unsigned num_arg_types =
>         elts ? Elements(arg_types) : Elements(arg_types) - 1;
>      LLVMTypeRef func_type;
> @@ -1484,7 +1485,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
>      struct lp_type vs_type;
>      LLVMValueRef end, start;
>      LLVMValueRef count, fetch_elts, fetch_elt_max, fetch_count;
> -   LLVMValueRef vertex_id_offset;
> +   LLVMValueRef vertex_id_offset, start_instance;
>      LLVMValueRef stride, step, io_itr;
>      LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr;
>      LLVMValueRef zero = lp_build_const_int32(gallivm, 0);
> @@ -1533,6 +1534,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
>      arg_types[i++] = get_vb_ptr_type(variant);       /* pipe_vertex_buffer's */
>      arg_types[i++] = int32_type;                     /* instance_id */
>      arg_types[i++] = int32_type;                     /* vertex_id_offset */
> +   arg_types[i++] = int32_type;                     /* start_instance */
>
>      func_type = LLVMFunctionType(int32_type, arg_types, num_arg_types, 0);
>
> @@ -1556,6 +1558,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
>      vb_ptr                    = LLVMGetParam(variant_func, 6 + (elts ? 1 : 0));
>      system_values.instance_id = LLVMGetParam(variant_func, 7 + (elts ? 1 : 0));
>      vertex_id_offset          = LLVMGetParam(variant_func, 8 + (elts ? 1 : 0));
> +   start_instance            = LLVMGetParam(variant_func, 9 + (elts ? 1 : 0));
>
>      lp_build_name(context_ptr, "context");
>      lp_build_name(io_ptr, "io");
> @@ -1564,6 +1567,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
>      lp_build_name(vb_ptr, "vb");
>      lp_build_name(system_values.instance_id, "instance_id");
>      lp_build_name(vertex_id_offset, "vertex_id_offset");
> +   lp_build_name(start_instance, "start_instance");
>
>      if (elts) {
>         fetch_elts    = LLVMGetParam(variant_func, 3);
> @@ -1712,7 +1716,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
>               LLVMValueRef vb = LLVMBuildGEP(builder, vb_ptr, &vb_index, 1, "");
>               generate_fetch(gallivm, draw, vbuffers_ptr,
>                              &aos_attribs[j][i], velem, vb, true_index,
> -                           system_values.instance_id);
> +                           system_values.instance_id, start_instance);
>            }
>         }
>         convert_to_soa(gallivm, aos_attribs, inputs,
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
> index 2e465b2..ed97cf7 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.h
> +++ b/src/gallium/auxiliary/draw/draw_llvm.h
> @@ -274,7 +274,8 @@ typedef int
>                         unsigned stride,
>                         struct pipe_vertex_buffer *vertex_buffers,
>                         unsigned instance_id,
> -                      unsigned vertex_id_offset);
> +                      unsigned vertex_id_offset,
> +                      unsigned start_instance);
>
>
>   typedef int
> @@ -287,7 +288,8 @@ typedef int
>                              unsigned stride,
>                              struct pipe_vertex_buffer *vertex_buffers,
>                              unsigned instance_id,
> -                           unsigned vertex_id_offset);
> +                           unsigned vertex_id_offset,
> +                           unsigned start_instance);
>
>
>   typedef int
> diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> index 481553a..5549cb3 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> @@ -387,7 +387,8 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
>                                          fpme->vertex_size,
>                                          draw->pt.vertex_buffer,
>                                          draw->instance_id,
> -                                       draw->start_index);
> +                                       draw->start_index,
> +                                       draw->start_instance);
>      else
>         clipped = fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context,
>                                               llvm_vert_info.verts,
> @@ -398,7 +399,8 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
>                                               fpme->vertex_size,
>                                               draw->pt.vertex_buffer,
>                                               draw->instance_id,
> -                                            draw->pt.user.eltBias);
> +                                            draw->pt.user.eltBias,
> +                                            draw->start_instance);
>
>      /* Finished with fetch and vs:
>       */
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
> index 2a6e673..74707a6 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -168,6 +168,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
>         return 0;
>      case PIPE_CAP_TGSI_INSTANCEID:
>      case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
> +   case PIPE_CAP_START_INSTANCE:
>         return 1;
>      case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
>         return 0;
> @@ -223,7 +224,6 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
>
>      case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
>         return 16;
> -   case PIPE_CAP_START_INSTANCE:
>      case PIPE_CAP_TEXTURE_MULTISAMPLE:
>      case PIPE_CAP_CUBE_MAP_ARRAY:
>         return 0;
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
> index d54112c..be9a6c8 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -129,6 +129,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
>         return 1;
>      case PIPE_CAP_TGSI_INSTANCEID:
>      case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
> +   case PIPE_CAP_START_INSTANCE:
>         return 1;
>      case PIPE_CAP_SEAMLESS_CUBE_MAP:
>      case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
> @@ -167,7 +168,6 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
>      case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
>      case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
>      case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
> -   case PIPE_CAP_START_INSTANCE:
>      case PIPE_CAP_TEXTURE_MULTISAMPLE:
>         return 0;
>      case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
>



More information about the mesa-dev mailing list