draw: fix base instance handling in llvm path
authorRoland Scheidegger <sroland@vmware.com>
Mon, 25 Aug 2014 20:05:16 +0000 (22:05 +0200)
committerRoland Scheidegger <sroland@vmware.com>
Thu, 28 Aug 2014 01:03:23 +0000 (03:03 +0200)
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).

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/softpipe/sp_screen.c

index 2c6ca0d0a52231392e7c8aa778956700995f726e..467f07420e2532335db4d41bcb912b76efacc692 100644 (file)
@@ -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,
index 2e465b2239c67e739172ddea1c90e7eddd5544f2..ed97cf7211545193b666e289885ea2d5b38cb0d6 100644 (file)
@@ -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
index 481553a78a4cefa0268d08dc2ec2be8155b4420b..5549cb3b90a3fcd3cac169c0854a5f42d920a9ce 100644 (file)
@@ -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:
     */
index 2a6e673b9e4cb634fef40df0b33b1771cdf7a58f..74707a6ce2b2fbad93a3efd057ab7c583f8e942f 100644 (file)
@@ -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;
index d54112c4940b513624e1a94fa8b452f8d51f81be..be9a6c8c77b98c8f310af767c8110b1e91c5336c 100644 (file)
@@ -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: