Mesa (lp-offset-twoside): llvmpipe: Moved draw pipeline twoside function to llvm setup code

Keith Whitwell keithw at kemper.freedesktop.org
Mon Nov 1 14:15:17 UTC 2010


Module: Mesa
Branch: lp-offset-twoside
Commit: 7f0dc5ea1bb330c6589125baf4017c51a14dce8e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7f0dc5ea1bb330c6589125baf4017c51a14dce8e

Author: Hui Qi Tay <tayhuiqithq at gmail.com>
Date:   Fri Oct 29 00:47:13 2010 +0100

llvmpipe: Moved draw pipeline twoside function to llvm setup code

---

 src/gallium/drivers/llvmpipe/lp_context.h       |    6 ++
 src/gallium/drivers/llvmpipe/lp_state_derived.c |   14 ++++-
 src/gallium/drivers/llvmpipe/lp_state_setup.c   |   85 ++++++++++++++++++++++-
 src/gallium/drivers/llvmpipe/lp_state_setup.h   |    3 +-
 4 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index db09c95..2230d50 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -104,6 +104,12 @@ struct llvmpipe_context {
    /** Vertex format */
    struct vertex_info vertex_info;
    
+   /** Which vertex shader output slot contains color */
+   int color_slot;
+
+   /** Which vertex shader output slot contains bcolor */
+   int bcolor_slot;
+
    /** Which vertex shader output slot contains point size */
    int psize_slot;
 
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index 0f5f736..1c9f03a 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -75,13 +75,25 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
       vs_index = draw_find_shader_output(llvmpipe->draw,
                                          lpfs->info.base.input_semantic_name[i],
                                          lpfs->info.base.input_semantic_index[i]);
-
+      if (lpfs->info.base.input_semantic_name[i]==TGSI_SEMANTIC_COLOR){
+         llvmpipe->color_slot = vinfo->num_attribs;
+      }
       /*
        * Emit the requested fs attribute for all but position.
        */
       draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
    }
 
+   /* Figure out if we need bcolor as well.
+    */
+   vs_index = draw_find_shader_output(llvmpipe->draw,
+                                      TGSI_SEMANTIC_BCOLOR, 0);
+
+   if (vs_index > 0) {
+      llvmpipe->bcolor_slot = vinfo->num_attribs;
+      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
+   }
+
    /* Figure out if we need pointsize as well.
     */
    vs_index = draw_find_shader_output(llvmpipe->draw,
diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c
index 2c8b8b9..8383494 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c
@@ -33,6 +33,7 @@
 #include "gallivm/lp_bld_debug.h"
 #include "gallivm/lp_bld_init.h"
 #include "gallivm/lp_bld_intr.h"
+#include "gallivm/lp_bld_flow.h"
 #include <llvm-c/Analysis.h>	/* for LLVMVerifyFunction */
 
 #include "lp_perf.h"
@@ -74,6 +75,14 @@ struct lp_setup_args
    LLVMValueRef dy01_ooa;
    LLVMValueRef dx20_ooa;
    LLVMValueRef dx01_ooa;
+
+   /* For twoside calcs 
+    */
+   LLVMValueRef det;
+   LLVMValueRef sign;
+   LLVMValueRef bcolor_slot;
+   LLVMValueRef color_slot;
+   
 };
 
 static LLVMTypeRef type4f(void)
@@ -472,13 +481,78 @@ init_args(LLVMBuilderRef b,
    args->y0_center = vec4f_from_scalar(b, y0_center, "y0_center_4f");
 }
 
+static void
+set_args_attr(struct llvmpipe_context *lp,
+           struct lp_setup_args *args)
+{
+   args->color_slot = LLVMConstInt(LLVMInt32Type(), lp->color_slot, 0);
+   args->bcolor_slot = LLVMConstInt(LLVMInt32Type(), lp->bcolor_slot, 0);
+   args->sign =  LLVMConstReal(LLVMFloatType(), (lp->rasterizer->front_ccw ? -1.0f : 1.0f));
+}
+
+static void
+lp_twoside(LLVMBuilderRef b, 
+           struct lp_setup_args *args,
+           const struct lp_setup_variant_key *key)
+{
+   struct lp_build_if_state if_state;
+ 
+   LLVMValueRef a0_old, a1_old, a2_old;
+   LLVMValueRef a0_new, a1_new, a2_new;
+
+   LLVMValueRef idx1 = args->color_slot;
+   LLVMValueRef idx2 = args->bcolor_slot;
+
+   LLVMValueRef facing = args->facing;
+   LLVMValueRef front_facing = LLVMBuildICmp(b, LLVMIntEQ, facing, LLVMConstInt(LLVMInt32Type(), 0, 0), ""); /** need i1 for loop condition */
+   
+#if 0 
+/*Probably can delete this, just tried to follow draw_pipe_twoside way of 
+  calculating det*/
+   /* edge vectors: e = v0 - v2, f = v1 - v2 */
+   LLVMValueRef e = LLVMBuildFSub(b, args->v0, args->v2, "e");
+   LLVMValueRef f = LLVMBuildFSub(b, args->v1, args->v2, "f");
+   LLVMValueRef dx02 = vert_attrib(b, e, 0, 0, "dx02");
+   LLVMValueRef dy02 = vert_attrib(b, e, 0, 1, "dy02");
+   LLVMValueRef dx12 = vert_attrib(b, f, 0, 0, "dx12");
+   LLVMValueRef dy12 = vert_attrib(b, f, 0, 1, "dy12");
+ 
+   /* det = cross(e,f).z */
+   LLVMValueRef dx02_dy12  = LLVMBuildFMul(b, dx02, dy12, "dx02_dy12");
+   LLVMValueRef dy02_dx12  = LLVMBuildFMul(b, dy02, dx12, "dy02_dx12");
+   LLVMValueRef det  = LLVMBuildFSub(b, dx02_dy12, dy02_dx12, "det");
+   args->det = det;
+   LLVMValueRef result = LLVMBuildFMul(b, det, args->sign, "dy02_dx12");
+#endif
+ 
+   lp_build_if(&if_state, b, front_facing);
+   {
+      /* swap the front and back attrib values */
+      a0_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx1, 1, ""), "v0a");
+      a1_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx1, 1, ""), "v1a");
+      a2_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx1, 1, ""), "v2a");
+
+      a0_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx2, 1, ""), "v0a");
+      a1_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx2, 1, ""), "v1a");
+      a2_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx2, 1, ""), "v2a");
+
+      LLVMBuildStore(b, a0_new, LLVMBuildGEP(b, args->v0, &idx1, 1, ""));
+      LLVMBuildStore(b, a1_new, LLVMBuildGEP(b, args->v1, &idx1, 1, ""));
+      LLVMBuildStore(b, a2_new, LLVMBuildGEP(b, args->v2, &idx1, 1, ""));
+   }
+   lp_build_endif(&if_state);
+   
+}
+
+
 /**
  * Generate the runtime callable function for the coefficient calculation.
  *
  */
 static struct lp_setup_variant *
 generate_setup_variant(struct llvmpipe_screen *screen,
-		       struct lp_setup_variant_key *key)
+		       struct lp_setup_variant_key *key,
+                       struct llvmpipe_context *lp)
 {
    struct lp_setup_variant *variant = NULL;
    struct lp_setup_args args;
@@ -555,6 +629,10 @@ generate_setup_variant(struct llvmpipe_screen *screen,
 
    set_noalias(builder, variant->function, arg_types, Elements(arg_types));
    init_args(builder, &args, variant);
+   if (variant->key.twoside){
+      set_args_attr(lp, &args);
+      lp_twoside(builder, &args, &variant->key);
+   }
    emit_tri_coef(builder, &variant->key, &args);
 
    lp_emit_emms(builder);
@@ -605,6 +683,7 @@ lp_make_setup_variant_key(struct llvmpipe_context *lp,
    key->num_inputs = fs->info.base.num_inputs;
    key->flatshade_first = lp->rasterizer->flatshade_first;
    key->pixel_center_half = lp->rasterizer->gl_rasterization_rules;
+   key->twoside = lp->rasterizer->light_twoside;
    key->size = Offset(struct lp_setup_variant_key,
 		      inputs[key->num_inputs]);
    key->pad = 0;
@@ -612,7 +691,7 @@ lp_make_setup_variant_key(struct llvmpipe_context *lp,
    memcpy(key->inputs, fs->inputs, key->num_inputs * sizeof key->inputs[0]);
    for (i = 0; i < key->num_inputs; i++) {
       if (key->inputs[i].interp == LP_INTERP_COLOR) {
-	 if (lp->rasterizer->flatshade)
+         if (lp->rasterizer->flatshade)
 	    key->inputs[i].interp = LP_INTERP_CONSTANT;
 	 else
 	    key->inputs[i].interp = LP_INTERP_LINEAR;
@@ -702,7 +781,7 @@ llvmpipe_update_setup(struct llvmpipe_context *lp)
 	 cull_setup_variants(lp);
       }
 
-      variant = generate_setup_variant(screen, key);
+      variant = generate_setup_variant(screen, key, lp);
       insert_at_head(&lp->setup_variants_list, &variant->list_item_global);
       lp->nr_setup_variants++;
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.h b/src/gallium/drivers/llvmpipe/lp_state_setup.h
index b0c81ba..4079fb7 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h
@@ -18,7 +18,8 @@ struct lp_setup_variant_key {
    unsigned num_inputs:8;
    unsigned flatshade_first:1;
    unsigned pixel_center_half:1;
-   unsigned pad:7;
+   unsigned twoside:1;
+   unsigned pad:6;
    unsigned size:16;
    struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
 };




More information about the mesa-commit mailing list