llvmpipe: defer attribute interpolation until after mask and ztest
authorKeith Whitwell <keithw@vmware.com>
Wed, 6 Oct 2010 21:25:48 +0000 (22:25 +0100)
committerKeith Whitwell <keithw@vmware.com>
Sat, 9 Oct 2010 10:42:48 +0000 (11:42 +0100)
Don't calculate 1/w for quads which aren't visible...

src/gallium/drivers/llvmpipe/lp_bld_interp.c
src/gallium/drivers/llvmpipe/lp_bld_interp.h
src/gallium/drivers/llvmpipe/lp_state_fs.c

index ee92ce3cdc1242d40f1180ae207dfccf473ed0a6..c9da8900d0c1042510f7d6adab83a4507e68eec6 100644 (file)
@@ -272,7 +272,10 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
  * This is called when we move from one quad to the next.
  */
 static void
-attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
+attribs_update(struct lp_build_interp_soa_context *bld,
+               int quad_index,
+               int start,
+               int end)
 {
    struct lp_build_context *coeff_bld = &bld->coeff_bld;
    LLVMValueRef shuffle = lp_build_const_int_vec(coeff_bld->type, quad_index);
@@ -282,7 +285,7 @@ attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
 
    assert(quad_index < 4);
 
-   for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
+   for(attrib = start; attrib < end; ++attrib) {
       const unsigned mask = bld->mask[attrib];
       const unsigned interp = bld->interp[attrib];
       for(chan = 0; chan < NUM_CHANNELS; ++chan) {
@@ -442,8 +445,6 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
    pos_init(bld, x0, y0);
 
    coeffs_init(bld, a0_ptr, dadx_ptr, dady_ptr);
-
-   attribs_update(bld, 0);
 }
 
 
@@ -451,10 +452,20 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
  * Advance the position and inputs to the given quad within the block.
  */
 void
-lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld,
-                           int quad_index)
+lp_build_interp_soa_update_inputs(struct lp_build_interp_soa_context *bld,
+                                  int quad_index)
+{
+   assert(quad_index < 4);
+
+   attribs_update(bld, quad_index, 1, bld->num_attribs);
+}
+
+void
+lp_build_interp_soa_update_pos(struct lp_build_interp_soa_context *bld,
+                                  int quad_index)
 {
    assert(quad_index < 4);
 
-   attribs_update(bld, quad_index);
+   attribs_update(bld, quad_index, 0, 1);
 }
+
index 3054030f7394f38b3878544e8c0242bd39ee84d2..6588f7f2755f09c862c52b8362697748a3abd51b 100644 (file)
@@ -89,7 +89,11 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
                          LLVMValueRef y);
 
 void
-lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld,
+lp_build_interp_soa_update_inputs(struct lp_build_interp_soa_context *bld,
+                           int quad_index);
+
+void
+lp_build_interp_soa_update_pos(struct lp_build_interp_soa_context *bld,
                            int quad_index);
 
 
index 3ce8be5a0a99b50676abd70bacf8e508aa1eba35..0530c6132308bedb22011432e3bf15bcd8d99b1a 100644 (file)
@@ -262,7 +262,7 @@ generate_fs(struct llvmpipe_context *lp,
             struct lp_type type,
             LLVMValueRef context_ptr,
             unsigned i,
-            const struct lp_build_interp_soa_context *interp,
+            struct lp_build_interp_soa_context *interp,
             struct lp_build_sampler_soa *sampler,
             LLVMValueRef *pmask,
             LLVMValueRef (*color)[4],
@@ -276,7 +276,7 @@ generate_fs(struct llvmpipe_context *lp,
    LLVMTypeRef vec_type;
    LLVMValueRef consts_ptr;
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
-   LLVMValueRef z = interp->pos[2];
+   LLVMValueRef z;
    LLVMValueRef stencil_refs[2];
    struct lp_build_flow_context *flow;
    struct lp_build_mask_context mask;
@@ -307,7 +307,6 @@ generate_fs(struct llvmpipe_context *lp,
         lp_build_flow_scope_declare(flow, &color[cbuf][chan]);
       }
    }
-   lp_build_flow_scope_declare(flow, &z);
 
    /* do triangle edge testing */
    if (partial_mask) {
@@ -321,6 +320,13 @@ generate_fs(struct llvmpipe_context *lp,
    /* 'mask' will control execution based on quad's pixel alive/killed state */
    lp_build_mask_begin(&mask, flow, type, *pmask);
 
+   lp_build_interp_soa_update_pos(interp, i);
+
+   /* Try to avoid the 1/w for quads where mask is zero.  TODO: avoid
+    * this for depth-fail quads also.
+    */
+   z = interp->pos[2];
+
    early_depth_stencil_test =
       (key->depth.enabled || key->stencil[0].enabled) &&
       !key->alpha.enabled &&
@@ -332,6 +338,8 @@ generate_fs(struct llvmpipe_context *lp,
                              type, &mask,
                              stencil_refs, z, depth_ptr, facing, counter);
 
+   lp_build_interp_soa_update_inputs(interp, i);
+
    lp_build_tgsi_soa(builder, tokens, type, &mask,
                      consts_ptr, interp->pos, interp->inputs,
                      outputs, sampler, &shader->info);
@@ -621,9 +629,6 @@ generate_fragment(struct llvmpipe_context *lp,
       LLVMValueRef out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS];
       LLVMValueRef depth_ptr_i;
 
-      if(i != 0)
-         lp_build_interp_soa_update(&interp, i);
-
       depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, "");
 
       generate_fs(lp, shader, key,