Mesa (master): gallivm/llvmpipe: added lp_rast_shader_inputs:: facing and pass through

Brian Paul brianp at kemper.freedesktop.org
Thu Mar 18 19:09:48 UTC 2010


Module: Mesa
Branch: master
Commit: 22e6dc387039e79f6d1435ae8b7422a6514d5d10
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=22e6dc387039e79f6d1435ae8b7422a6514d5d10

Author: Brian Paul <brianp at vmware.com>
Date:   Thu Mar 18 13:02:53 2010 -0600

gallivm/llvmpipe: added lp_rast_shader_inputs::facing and pass through

The triangle rasterizer sets this field to indicate front/back-facing.
It gets passed into the generated fragment code as another parameter.
Used now for stencil front/back selection but will also be used for
fragment shaders in general (see TGSI_SEMANTIC_FACE).

With this commit two-sided stenciling mostly works but there's
still a bug or two...

---

 src/gallium/auxiliary/gallivm/lp_bld_depth.c |   22 ++++++----
 src/gallium/auxiliary/gallivm/lp_bld_depth.h |    3 +-
 src/gallium/drivers/llvmpipe/lp_jit.h        |    1 +
 src/gallium/drivers/llvmpipe/lp_rast.c       |    2 +
 src/gallium/drivers/llvmpipe/lp_rast.h       |    2 +
 src/gallium/drivers/llvmpipe/lp_rast_priv.h  |    1 +
 src/gallium/drivers/llvmpipe/lp_setup_tri.c  |    2 +
 src/gallium/drivers/llvmpipe/lp_state_fs.c   |   61 ++++++++++++++-----------
 8 files changed, 57 insertions(+), 37 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.c b/src/gallium/auxiliary/gallivm/lp_bld_depth.c
index c253764..e1558dc 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_depth.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.c
@@ -143,7 +143,7 @@ lp_build_stencil_test(struct lp_build_context *bld,
       struct lp_build_if_state if_ctx;
       LLVMValueRef front_facing;
       LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
-      LLVMValueRef result = NULL;
+      LLVMValueRef result = bld->undef;
 
       flow_ctx = lp_build_flow_create(bld->builder);
       lp_build_flow_scope_begin(flow_ctx);
@@ -151,7 +151,7 @@ lp_build_stencil_test(struct lp_build_context *bld,
       lp_build_flow_scope_declare(flow_ctx, &result);
 
       /* front_facing = face > 0.0 */
-      front_facing = lp_build_cmp(bld, PIPE_FUNC_GREATER, face, zero);
+      front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
 
       lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
       {
@@ -287,7 +287,7 @@ lp_build_stencil_op(struct lp_build_context *bld,
       struct lp_build_if_state if_ctx;
       LLVMValueRef front_facing;
       LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
-      LLVMValueRef result = NULL;
+      LLVMValueRef result = bld->undef;
 
       flow_ctx = lp_build_flow_create(bld->builder);
       lp_build_flow_scope_begin(flow_ctx);
@@ -295,7 +295,7 @@ lp_build_stencil_op(struct lp_build_context *bld,
       lp_build_flow_scope_declare(flow_ctx, &result);
 
       /* front_facing = face > 0.0 */
-      front_facing = lp_build_cmp(bld, PIPE_FUNC_GREATER, face, zero);
+      front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
 
       lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
       {
@@ -367,11 +367,15 @@ lp_depth_type(const struct util_format_description *format_desc,
  * Generate code for performing depth and/or stencil tests.
  * We operate on a vector of values (typically a 2x2 quad).
  *
+ * \param depth  the depth test state
+ * \param stencil  the front/back stencil state
  * \param type  the data type of the fragment depth/stencil values
  * \param format_desc  description of the depth/stencil surface
- * \param mask  the alive/dead pixel mask for the quad
- * \param src  the incoming depth/stencil values (a 2x2 quad)
- * \param dst_ptr  the outgoing/updated depth/stencil values
+ * \param mask  the alive/dead pixel mask for the quad (vector)
+ * \param stencil_refs  the front/back stencil ref values (scalar)
+ * \param z_src  the incoming depth/stencil values (a 2x2 quad)
+ * \param zs_dst_ptr  pointer to depth/stencil values in framebuffer
+ * \param facing  contains float value indicating front/back facing polygon
  */
 void
 lp_build_depth_stencil_test(LLVMBuilderRef builder,
@@ -382,7 +386,8 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
                             struct lp_build_mask_context *mask,
                             LLVMValueRef stencil_refs[2],
                             LLVMValueRef z_src,
-                            LLVMValueRef zs_dst_ptr)
+                            LLVMValueRef zs_dst_ptr,
+                            LLVMValueRef face)
 {
    struct lp_build_context bld;
    unsigned z_swizzle, s_swizzle;
@@ -391,7 +396,6 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
    LLVMValueRef z_bitmask = NULL, s_bitmask = NULL;
    LLVMValueRef z_pass = NULL, s_pass_mask = NULL;
    LLVMValueRef orig_mask = mask->value;
-   LLVMValueRef face = NULL;
 
    assert(depth->enabled || stencil[0].enabled);
 
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.h b/src/gallium/auxiliary/gallivm/lp_bld_depth.h
index 5708ced..27dd46b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_depth.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.h
@@ -59,7 +59,8 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder,
                             struct lp_build_mask_context *mask,
                             LLVMValueRef stencil_refs[2],
                             LLVMValueRef zs_src,
-                            LLVMValueRef zs_dst_ptr);
+                            LLVMValueRef zs_dst_ptr,
+                            LLVMValueRef facing);
 
 
 #endif /* !LP_BLD_DEPTH_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 690b439..4930ff0 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -155,6 +155,7 @@ typedef void
 (*lp_jit_frag_func)(const struct lp_jit_context *context,
                     uint32_t x,
                     uint32_t y,
+                    float facing,
                     const void *a0,
                     const void *dadx,
                     const void *dady,
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 30b43cc..3a51800 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -314,6 +314,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
          /* run shader */
          state->jit_function[RAST_WHOLE]( &state->jit_context,
                                           tile_x + x, tile_y + y,
+                                          inputs->facing,
                                           inputs->a0,
                                           inputs->dadx,
                                           inputs->dady,
@@ -377,6 +378,7 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
    /* run shader */
    state->jit_function[RAST_EDGE_TEST]( &state->jit_context,
                                         x, y,
+                                        inputs->facing,
                                         inputs->a0,
                                         inputs->dadx,
                                         inputs->dady,
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 303f6e3..ae838f3 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -82,6 +82,8 @@ struct lp_rast_state {
  * These pointers point into the bin data buffer.
  */
 struct lp_rast_shader_inputs {
+   float facing;     /** Positive for front-facing, negative for back-facing */
+
    float (*a0)[4];
    float (*dadx)[4];
    float (*dady)[4];
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 39bf2c2..6ee9bca 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -195,6 +195,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
    /* run shader */
    state->jit_function[0]( &state->jit_context,
                            x, y,
+                           inputs->facing,
                            inputs->a0,
                            inputs->dadx,
                            inputs->dady,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index ac6264d..ce689d3 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -361,6 +361,8 @@ do_triangle_ccw(struct lp_setup_context *setup,
     */
    setup_tri_coefficients( setup, tri, oneoverarea, v1, v2, v3, frontfacing );
 
+   tri->inputs.facing = frontfacing ? 1.0F : -1.0F;
+
    /* half-edge constants, will be interated over the whole render target.
     */
    tri->c1 = tri->dy12 * x1 - tri->dx12 * y1;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 5f70d52..7bbf348 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -147,7 +147,8 @@ generate_depth_stencil(LLVMBuilderRef builder,
                        struct lp_build_mask_context *mask,
                        LLVMValueRef stencil_refs[2],
                        LLVMValueRef src,
-                       LLVMValueRef dst_ptr)
+                       LLVMValueRef dst_ptr,
+                       LLVMValueRef facing)
 {
    const struct util_format_description *format_desc;
    struct lp_type dst_type;
@@ -193,7 +194,8 @@ generate_depth_stencil(LLVMBuilderRef builder,
                                mask,
                                stencil_refs,
                                src,
-                               dst_ptr);
+                               dst_ptr,
+                               facing);
 }
 
 
@@ -393,6 +395,7 @@ generate_fs(struct llvmpipe_context *lp,
             LLVMValueRef *pmask,
             LLVMValueRef (*color)[4],
             LLVMValueRef depth_ptr,
+            LLVMValueRef facing,
             unsigned do_tri_test,
             LLVMValueRef c0,
             LLVMValueRef c1,
@@ -469,7 +472,7 @@ generate_fs(struct llvmpipe_context *lp,
    if (early_depth_stencil_test)
       generate_depth_stencil(builder, key,
                              type, &mask,
-                             stencil_refs, z, depth_ptr);
+                             stencil_refs, z, depth_ptr, facing);
 
    lp_build_tgsi_soa(builder, tokens, type, &mask,
                      consts_ptr, interp->pos, interp->inputs,
@@ -516,7 +519,7 @@ generate_fs(struct llvmpipe_context *lp,
    if (!early_depth_stencil_test)
       generate_depth_stencil(builder, key,
                              type, &mask,
-                             stencil_refs, z, depth_ptr);
+                             stencil_refs, z, depth_ptr, facing);
 
    lp_build_mask_end(&mask);
 
@@ -627,7 +630,7 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMTypeRef fs_int_vec_type;
    LLVMTypeRef blend_vec_type;
    LLVMTypeRef blend_int_vec_type;
-   LLVMTypeRef arg_types[14];
+   LLVMTypeRef arg_types[15];
    LLVMTypeRef func_type;
    LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type();
    LLVMValueRef context_ptr;
@@ -650,6 +653,7 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMValueRef blend_mask;
    LLVMValueRef blend_in_color[NUM_CHANNELS];
    LLVMValueRef function;
+   LLVMValueRef facing;
    unsigned num_fs;
    unsigned i;
    unsigned chan;
@@ -689,20 +693,21 @@ generate_fragment(struct llvmpipe_context *lp,
    arg_types[0] = screen->context_ptr_type;            /* context */
    arg_types[1] = LLVMInt32Type();                     /* x */
    arg_types[2] = LLVMInt32Type();                     /* y */
-   arg_types[3] = LLVMPointerType(fs_elem_type, 0);    /* a0 */
-   arg_types[4] = LLVMPointerType(fs_elem_type, 0);    /* dadx */
-   arg_types[5] = LLVMPointerType(fs_elem_type, 0);    /* dady */
-   arg_types[6] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0);  /* color */
-   arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
-   arg_types[8] = LLVMInt32Type();                     /* c0 */
-   arg_types[9] = LLVMInt32Type();                     /* c1 */
-   arg_types[10] = LLVMInt32Type();                    /* c2 */
+   arg_types[3] = LLVMFloatType();                     /* facing */
+   arg_types[4] = LLVMPointerType(fs_elem_type, 0);    /* a0 */
+   arg_types[5] = LLVMPointerType(fs_elem_type, 0);    /* dadx */
+   arg_types[6] = LLVMPointerType(fs_elem_type, 0);    /* dady */
+   arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0);  /* color */
+   arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
+   arg_types[9] = LLVMInt32Type();                     /* c0 */
+   arg_types[10] = LLVMInt32Type();                    /* c1 */
+   arg_types[11] = LLVMInt32Type();                    /* c2 */
    /* Note: the step arrays are built as int32[16] but we interpret
     * them here as int32_vec4[4].
     */
-   arg_types[11] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
-   arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
-   arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
+   arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
+   arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
+   arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
 
    func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
 
@@ -722,17 +727,18 @@ generate_fragment(struct llvmpipe_context *lp,
    context_ptr  = LLVMGetParam(function, 0);
    x            = LLVMGetParam(function, 1);
    y            = LLVMGetParam(function, 2);
-   a0_ptr       = LLVMGetParam(function, 3);
-   dadx_ptr     = LLVMGetParam(function, 4);
-   dady_ptr     = LLVMGetParam(function, 5);
-   color_ptr_ptr = LLVMGetParam(function, 6);
-   depth_ptr    = LLVMGetParam(function, 7);
-   c0           = LLVMGetParam(function, 8);
-   c1           = LLVMGetParam(function, 9);
-   c2           = LLVMGetParam(function, 10);
-   step0_ptr    = LLVMGetParam(function, 11);
-   step1_ptr    = LLVMGetParam(function, 12);
-   step2_ptr    = LLVMGetParam(function, 13);
+   facing       = LLVMGetParam(function, 3);
+   a0_ptr       = LLVMGetParam(function, 4);
+   dadx_ptr     = LLVMGetParam(function, 5);
+   dady_ptr     = LLVMGetParam(function, 6);
+   color_ptr_ptr = LLVMGetParam(function, 7);
+   depth_ptr    = LLVMGetParam(function, 8);
+   c0           = LLVMGetParam(function, 9);
+   c1           = LLVMGetParam(function, 10);
+   c2           = LLVMGetParam(function, 11);
+   step0_ptr    = LLVMGetParam(function, 12);
+   step1_ptr    = LLVMGetParam(function, 13);
+   step2_ptr    = LLVMGetParam(function, 14);
 
    lp_build_name(context_ptr, "context");
    lp_build_name(x, "x");
@@ -791,6 +797,7 @@ generate_fragment(struct llvmpipe_context *lp,
                   &fs_mask[i], /* output */
                   out_color,
                   depth_ptr_i,
+                  facing,
                   do_tri_test,
                   c0, c1, c2,
                   step0_ptr, step1_ptr, step2_ptr);




More information about the mesa-commit mailing list