diff options
author | Brian Paul <brianp@vmware.com> | 2010-01-14 19:15:00 -0700 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2010-01-14 19:15:00 -0700 |
commit | 4461442849bfdb817334b38567136f7f9dabdf59 (patch) | |
tree | 2539c1448256f7c617e6b902deba793ca63a4959 /src/gallium/drivers/llvmpipe/lp_state_fs.c | |
parent | ca12e30d97b83fb33e1f8f83da05b5ed2809b0af (diff) |
llvmpipe: implement scissor testing
The scissor test is implemented as another per-quad operation in
the JIT code. The four scissor box params are passed via the
lp_jit_context. In the JIT code we compare the quad's x/y coords
against the clip bounds and create a new in/out mask that's AND'd
with the main quad mask.
Note: we should also do scissor testing in the triangle setup code
to improve efficiency. That's not done yet.
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_state_fs.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 26a2d6cc23..d12d3f6091 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -304,6 +304,51 @@ generate_tri_edge_mask(LLVMBuilderRef builder, } +static LLVMValueRef +generate_scissor_test(LLVMBuilderRef builder, + LLVMValueRef context_ptr, + const struct lp_build_interp_soa_context *interp, + struct lp_type type) +{ + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMValueRef xpos = interp->pos[0], ypos = interp->pos[1]; + LLVMValueRef xmin, ymin, xmax, ymax; + LLVMValueRef m0, m1, m2, m3, m; + + /* xpos, ypos contain the window coords for the four pixels in the quad */ + assert(xpos); + assert(ypos); + + /* get the current scissor bounds, convert to vectors */ + xmin = lp_jit_context_scissor_xmin_value(builder, context_ptr); + xmin = lp_build_broadcast(builder, vec_type, xmin); + + ymin = lp_jit_context_scissor_ymin_value(builder, context_ptr); + ymin = lp_build_broadcast(builder, vec_type, ymin); + + xmax = lp_jit_context_scissor_xmax_value(builder, context_ptr); + xmax = lp_build_broadcast(builder, vec_type, xmax); + + ymax = lp_jit_context_scissor_ymax_value(builder, context_ptr); + ymax = lp_build_broadcast(builder, vec_type, ymax); + + /* compare the fragment's position coordinates against the scissor bounds */ + m0 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, xpos, xmin); + m1 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, ypos, ymin); + m2 = lp_build_compare(builder, type, PIPE_FUNC_LESS, xpos, xmax); + m3 = lp_build_compare(builder, type, PIPE_FUNC_LESS, ypos, ymax); + + /* AND all the masks together */ + m = LLVMBuildAnd(builder, m0, m1, ""); + m = LLVMBuildAnd(builder, m, m2, ""); + m = LLVMBuildAnd(builder, m, m3, ""); + + lp_build_name(m, "scissormask"); + + return m; +} + + /** * Generate the fragment shader, depth/stencil test, and alpha tests. * \param i which quad in the tile, in range [0,3] @@ -372,6 +417,11 @@ 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); + if (key->scissor) { + LLVMValueRef smask = + generate_scissor_test(builder, context_ptr, interp, type); + lp_build_mask_update(&mask, smask); + } early_depth_test = key->depth.enabled && @@ -968,6 +1018,7 @@ make_variant_key(struct llvmpipe_context *lp, /* alpha.ref_value is passed in jit_context */ key->flatshade = lp->rasterizer->flatshade; + key->scissor = lp->rasterizer->scissor; if (lp->framebuffer.nr_cbufs) { memcpy(&key->blend, lp->blend, sizeof key->blend); @@ -1033,6 +1084,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) key.blend.colormask == 0xf && !key.alpha.enabled && !key.depth.enabled && + !key.scissor && !shader->info.uses_kill ? TRUE : FALSE; |