draw llvm: hook up the generated function into the draw elts path
[mesa.git] / src / gallium / auxiliary / draw / draw_pt_fetch_shade_pipeline_llvm.c
index f93df37d92b9cc66fbbd6b1bc73eea5e115e2c47..f71271bd915645e876914a21f5d9bef6d97e5d51 100644 (file)
@@ -35,8 +35,6 @@
 #include "draw/draw_gs.h"
 #include "draw/draw_llvm.h"
 
-#include "translate/translate.h"
-
 
 struct llvm_middle_end {
    struct draw_pt_middle_end base;
@@ -53,6 +51,9 @@ struct llvm_middle_end {
    unsigned opt;
 
    struct draw_llvm *llvm;
+   struct draw_llvm_variant *variants;
+   struct draw_llvm_variant *current_variant;
+   int nr_variants;
 };
 
 
@@ -66,6 +67,8 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
    struct draw_context *draw = fpme->draw;
    struct draw_vertex_shader *vs = draw->vs.vertex_shader;
    struct draw_geometry_shader *gs = draw->gs.geometry_shader;
+   struct draw_llvm_variant_key key;
+   struct draw_llvm_variant *variant = NULL;
    unsigned i;
    unsigned instance_id_index = ~0;
 
@@ -129,7 +132,23 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
    /* return even number */
    *max_vertices = *max_vertices & ~1;
 
-   draw_llvm_prepare(fpme->llvm);
+   draw_llvm_make_variant_key(fpme->llvm, &key);
+
+   variant = fpme->variants;
+   while(variant) {
+      if(memcmp(&variant->key, &key, sizeof key) == 0)
+         break;
+
+      variant = variant->next;
+   }
+
+   if (!variant) {
+      variant = draw_llvm_prepare(fpme->llvm, nr);
+      variant->next = fpme->variants;
+      fpme->variants = variant;
+      ++fpme->nr_variants;
+   }
+   fpme->current_variant = variant;
 
    /*XXX we only support one constant buffer */
    fpme->llvm->jit_context.vs_constants =
@@ -245,12 +264,17 @@ static void llvm_middle_end_linear_run( struct draw_pt_middle_end *middle,
       return;
    }
 
-   fpme->llvm->jit_func( &fpme->llvm->jit_context,
-                         pipeline_verts,
-                         (const char **)draw->pt.user.vbuffer,
-                         start,
-                         count,
-                         fpme->vertex_size );
+#if 0
+   debug_printf("#### Pipeline = %p (data = %p)\n",
+                pipeline_verts, pipeline_verts->data);
+#endif
+   fpme->current_variant->jit_func( &fpme->llvm->jit_context,
+                                    pipeline_verts,
+                                    (const char **)draw->pt.user.vbuffer,
+                                    start,
+                                    count,
+                                    fpme->vertex_size,
+                                    draw->pt.vertex_buffer );
 
    if (draw_pt_post_vs_run( fpme->post_vs,
                            pipeline_verts,
@@ -290,8 +314,6 @@ llvm_middle_end_linear_run_elts( struct draw_pt_middle_end *middle,
 {
    struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
-   struct draw_vertex_shader *shader = draw->vs.vertex_shader;
-   struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
    unsigned opt = fpme->opt;
    unsigned alloc_count = align( count, 4 );
 
@@ -301,37 +323,13 @@ llvm_middle_end_linear_run_elts( struct draw_pt_middle_end *middle,
    if (!pipeline_verts)
       return FALSE;
 
-   /* Fetch into our vertex buffer
-    */
-   draw_pt_fetch_run_linear( fpme->fetch,
-                             start,
-                             count,
-                             (char *)pipeline_verts );
-
-   /* Run the shader, note that this overwrites the data[] parts of
-    * the pipeline verts.  If there is no shader, ie if
-    * bypass_vs_clip_and_viewport, then the inputs == outputs, and are
-    * already in the correct place.
-    */
-   if (opt & PT_SHADE)
-   {
-      shader->run_linear(shader,
-                        (const float (*)[4])pipeline_verts->data,
-                        (      float (*)[4])pipeline_verts->data,
-                        draw->pt.user.vs_constants,
-                        count,
-                        fpme->vertex_size,
-                        fpme->vertex_size);
-
-      if (geometry_shader)
-         draw_geometry_shader_run(geometry_shader,
-                                  (const float (*)[4])pipeline_verts->data,
-                                  (      float (*)[4])pipeline_verts->data,
-                                  draw->pt.user.gs_constants,
-                                  count,
-                                  fpme->vertex_size,
-                                  fpme->vertex_size);
-   }
+   fpme->current_variant->jit_func( &fpme->llvm->jit_context,
+                                    pipeline_verts,
+                                    (const char **)draw->pt.user.vbuffer,
+                                    start,
+                                    count,
+                                    fpme->vertex_size,
+                                    draw->pt.vertex_buffer );
 
    if (draw_pt_post_vs_run( fpme->post_vs,
                            pipeline_verts,
@@ -428,6 +426,10 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm( struct draw_cont
    if (!fpme->llvm)
       goto fail;
 
+   fpme->variants = NULL;
+   fpme->current_variant = NULL;
+   fpme->nr_variants = 0;
+
    return &fpme->base;
 
  fail: