From d1c9e598838aeac3c8cb90afee00b2cc683be273 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 16 Mar 2010 18:26:51 -0600 Subject: [PATCH] gallivm/llvmpipe: more asst changes for stencil testing --- src/gallium/auxiliary/gallivm/lp_bld_depth.c | 60 +++++++++++--------- src/gallium/auxiliary/gallivm/lp_bld_depth.h | 17 +++--- src/gallium/drivers/llvmpipe/lp_state_fs.c | 55 +++++++++--------- 3 files changed, 69 insertions(+), 63 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.c b/src/gallium/auxiliary/gallivm/lp_bld_depth.c index 3a5da4edce7..0cbe42c9e5a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_depth.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.c @@ -212,34 +212,36 @@ lp_depth_type(const struct util_format_description *format_desc, * \param dst_ptr the outgoing/updated depth/stencil values */ void -lp_build_depth_test(LLVMBuilderRef builder, - const struct pipe_depth_state *state, - struct lp_type type, - const struct util_format_description *format_desc, - struct lp_build_mask_context *mask, - LLVMValueRef stencil_refs, - LLVMValueRef src, - LLVMValueRef dst_ptr) +lp_build_depth_stencil_test(LLVMBuilderRef builder, + const struct pipe_depth_state *depth, + const struct pipe_stencil_state stencil[2], + struct lp_type type, + const struct util_format_description *format_desc, + struct lp_build_mask_context *mask, + LLVMValueRef stencil_refs, + LLVMValueRef z_src, + LLVMValueRef zs_dst_ptr) { struct lp_build_context bld; - unsigned z_swizzle; - LLVMValueRef dst; + unsigned z_swizzle, s_swizzle; + LLVMValueRef zs_dst; LLVMValueRef z_bitmask = NULL; - LLVMValueRef test; + LLVMValueRef z_pass; (void) lp_build_stencil_test; (void) lp_build_stencil_op; - if(!state->enabled) - return; + assert(depth->enabled || stencil[0].enabled); assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); assert(format_desc->block.width == 1); assert(format_desc->block.height == 1); z_swizzle = format_desc->swizzle[0]; - if(z_swizzle == UTIL_FORMAT_SWIZZLE_NONE) - return; + s_swizzle = format_desc->swizzle[1]; + + assert(z_swizzle != UTIL_FORMAT_SWIZZLE_NONE || + s_swizzle != UTIL_FORMAT_SWIZZLE_NONE); /* Sanity checking */ assert(z_swizzle < 4); @@ -260,9 +262,9 @@ lp_build_depth_test(LLVMBuilderRef builder, /* Setup build context */ lp_build_context_init(&bld, builder, type); - dst = LLVMBuildLoad(builder, dst_ptr, ""); + zs_dst = LLVMBuildLoad(builder, zs_dst_ptr, ""); - lp_build_name(dst, "zsbuf"); + lp_build_name(zs_dst, "zsbuf"); /* Align the source depth bits with the destination's, and mask out any * stencil or padding bits from both */ @@ -271,6 +273,7 @@ lp_build_depth_test(LLVMBuilderRef builder, /* nothing to do */ } else { + /* shift/mask bits to right-justify the Z bits */ unsigned padding_left; unsigned padding_right; unsigned chan; @@ -287,32 +290,33 @@ lp_build_depth_test(LLVMBuilderRef builder, (padding_right + format_desc->channel[z_swizzle].size); if(padding_left || padding_right) { - const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1; - const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1; + const unsigned long long mask_left = (1ULL << (format_desc->block.bits - padding_left)) - 1; + const unsigned long long mask_right = (1ULL << (padding_right)) - 1; z_bitmask = lp_build_const_int_vec(type, mask_left ^ mask_right); } if(padding_left) - src = LLVMBuildLShr(builder, src, lp_build_const_int_vec(type, padding_left), ""); + z_src = LLVMBuildLShr(builder, z_src, + lp_build_const_int_vec(type, padding_left), ""); if(padding_right) - src = LLVMBuildAnd(builder, src, z_bitmask, ""); + z_src = LLVMBuildAnd(builder, z_src, z_bitmask, ""); if(padding_left || padding_right) - dst = LLVMBuildAnd(builder, dst, z_bitmask, ""); + zs_dst = LLVMBuildAnd(builder, zs_dst, z_bitmask, ""); } - lp_build_name(dst, "zsbuf.z"); + lp_build_name(zs_dst, "zsbuf.z"); /* compare src Z to dst Z, returning 'pass' mask */ - test = lp_build_cmp(&bld, state->func, src, dst); - lp_build_mask_update(mask, test); + z_pass = lp_build_cmp(&bld, depth->func, z_src, zs_dst); + lp_build_mask_update(mask, z_pass); - if(state->writemask) { + if (depth->writemask) { if(z_bitmask) z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, ""); else z_bitmask = mask->value; - dst = lp_build_select(&bld, z_bitmask, src, dst); - LLVMBuildStore(builder, dst, dst_ptr); + zs_dst = lp_build_select(&bld, z_bitmask, z_src, zs_dst); + LLVMBuildStore(builder, zs_dst, zs_dst_ptr); } } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.h b/src/gallium/auxiliary/gallivm/lp_bld_depth.h index a7f67d21005..eedc1e419b5 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_depth.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.h @@ -51,14 +51,15 @@ lp_depth_type(const struct util_format_description *format_desc, void -lp_build_depth_test(LLVMBuilderRef builder, - const struct pipe_depth_state *state, - struct lp_type type, - const struct util_format_description *format_desc, - struct lp_build_mask_context *mask, - LLVMValueRef stencil_refs, - LLVMValueRef src, - LLVMValueRef dst_ptr); +lp_build_depth_stencil_test(LLVMBuilderRef builder, + const struct pipe_depth_state *depth, + const struct pipe_stencil_state stencil[2], + struct lp_type type, + const struct util_format_description *format_desc, + struct lp_build_mask_context *mask, + LLVMValueRef stencil_refs, + LLVMValueRef zs_src, + LLVMValueRef zs_dst_ptr); #endif /* !LP_BLD_DEPTH_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 5b00792eec4..15317ce10f3 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -141,13 +141,13 @@ generate_pos0(LLVMBuilderRef builder, * Generate the depth test. */ static void -generate_depth(LLVMBuilderRef builder, - const struct lp_fragment_shader_variant_key *key, - struct lp_type src_type, - struct lp_build_mask_context *mask, - LLVMValueRef stencil_refs, - LLVMValueRef src, - LLVMValueRef dst_ptr) +generate_depth_stencil(LLVMBuilderRef builder, + const struct lp_fragment_shader_variant_key *key, + struct lp_type src_type, + struct lp_build_mask_context *mask, + LLVMValueRef stencil_refs, + LLVMValueRef src, + LLVMValueRef dst_ptr) { const struct util_format_description *format_desc; struct lp_type dst_type; @@ -179,20 +179,21 @@ generate_depth(LLVMBuilderRef builder, assert(dst_type.width == src_type.width); assert(dst_type.length == src_type.length); + /* Convert fragment Z from float to integer */ lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1); dst_ptr = LLVMBuildBitCast(builder, dst_ptr, LLVMPointerType(lp_build_vec_type(dst_type), 0), ""); - - lp_build_depth_test(builder, - &key->depth, - dst_type, - format_desc, - mask, - stencil_refs, - src, - dst_ptr); + lp_build_depth_stencil_test(builder, + &key->depth, + key->stencil, + dst_type, + format_desc, + mask, + stencil_refs, + src, + dst_ptr); } @@ -410,7 +411,7 @@ generate_fs(struct llvmpipe_context *lp, LLVMValueRef stencil_refs; struct lp_build_flow_context *flow; struct lp_build_mask_context mask; - boolean early_depth_test; + boolean early_depth_stencil_test; unsigned attrib; unsigned chan; unsigned cbuf; @@ -458,16 +459,16 @@ generate_fs(struct llvmpipe_context *lp, lp_build_mask_update(&mask, smask); } - early_depth_test = - key->depth.enabled && + early_depth_stencil_test = + (key->depth.enabled || key->stencil[0].enabled) && !key->alpha.enabled && !shader->info.uses_kill && !shader->info.writes_z; - if(early_depth_test) - generate_depth(builder, key, - type, &mask, - stencil_refs, z, depth_ptr); + if (early_depth_stencil_test) + generate_depth_stencil(builder, key, + type, &mask, + stencil_refs, z, depth_ptr); lp_build_tgsi_soa(builder, tokens, type, &mask, consts_ptr, interp->pos, interp->inputs, @@ -511,10 +512,10 @@ generate_fs(struct llvmpipe_context *lp, } } - if(!early_depth_test) - generate_depth(builder, key, - type, &mask, - stencil_refs, z, depth_ptr); + if (!early_depth_stencil_test) + generate_depth_stencil(builder, key, + type, &mask, + stencil_refs, z, depth_ptr); lp_build_mask_end(&mask);