From 22e6dc387039e79f6d1435ae8b7422a6514d5d10 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 18 Mar 2010 13:02:53 -0600 Subject: 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(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.c b/src/gallium/auxiliary/gallivm/lp_bld_depth.c index c253764e60..e1558dca0e 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 5708ced983..27dd46b625 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 690b439307..4930ff02e6 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 30b43cce19..3a51800c40 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 303f6e3f7e..ae838f3fbe 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 39bf2c2587..6ee9bcaae3 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 ac6264dc73..ce689d3d56 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 5f70d52b6c..7bbf348e0b 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); -- cgit v1.2.3