From 4fd42a7c2798d03476c84b79cb855984a15c222c Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 3 Jun 2015 01:34:06 +0200 Subject: [PATCH] llvmpipe: Implement stencil export Pretty trivial, fixes the issue that we're expected to be able to blit stencil surfaces (as the blit just relies on util blitter code which needs stencil export to do it). 2 piglits skip->pass, 11 fail->pass v2: prettify, keep different stencil ref value handling out of depth/stencil test itself. Reviewed-by: Jose Fonseca Reviewed-by: Dave Airlie --- src/gallium/drivers/llvmpipe/lp_bld_depth.c | 4 ---- src/gallium/drivers/llvmpipe/lp_screen.c | 2 +- src/gallium/drivers/llvmpipe/lp_state_fs.c | 25 ++++++++++++++++----- src/gallium/drivers/llvmpipe/lp_surface.c | 5 ----- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index b6c32ffb979..b25e0413750 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -975,10 +975,6 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm, s_bld.int_vec_type, ""); } - /* convert scalar stencil refs into vectors */ - stencil_refs[0] = lp_build_broadcast_scalar(&s_bld, stencil_refs[0]); - stencil_refs[1] = lp_build_broadcast_scalar(&s_bld, stencil_refs[1]); - s_pass_mask = lp_build_stencil_test(&s_bld, stencil, stencil_refs, stencil_vals, front_facing); diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 09ac9af50ec..47f1897c732 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -165,7 +165,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_DEPTH_CLIP_DISABLE: return 1; case PIPE_CAP_SHADER_STENCIL_EXPORT: - return 0; + return 1; case PIPE_CAP_TGSI_INSTANCEID: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_START_INSTANCE: diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 35fe7b20181..b5ce8683f1a 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -260,7 +260,8 @@ generate_fs_loop(struct gallivm_state *gallivm, { const struct util_format_description *zs_format_desc = NULL; const struct tgsi_token *tokens = shader->base.tokens; - LLVMTypeRef vec_type; + struct lp_type int_type = lp_int_type(type); + LLVMTypeRef vec_type, int_vec_type; LLVMValueRef mask_ptr, mask_val; LLVMValueRef consts_ptr, num_consts_ptr; LLVMValueRef z; @@ -295,7 +296,7 @@ generate_fs_loop(struct gallivm_state *gallivm, zs_format_desc = util_format_description(key->zsbuf_format); assert(zs_format_desc); - if (!shader->info.base.writes_z) { + if (!shader->info.base.writes_z && !shader->info.base.writes_stencil) { if (key->alpha.enabled || key->blend.alpha_to_coverage || shader->info.base.uses_kill) { @@ -329,11 +330,14 @@ generate_fs_loop(struct gallivm_state *gallivm, depth_mode = 0; } + vec_type = lp_build_vec_type(gallivm, type); + int_vec_type = lp_build_vec_type(gallivm, int_type); stencil_refs[0] = lp_jit_context_stencil_ref_front_value(gallivm, context_ptr); stencil_refs[1] = lp_jit_context_stencil_ref_back_value(gallivm, context_ptr); - - vec_type = lp_build_vec_type(gallivm, type); + /* convert scalar stencil refs into vectors */ + stencil_refs[0] = lp_build_broadcast(gallivm, int_vec_type, stencil_refs[0]); + stencil_refs[1] = lp_build_broadcast(gallivm, int_vec_type, stencil_refs[1]); consts_ptr = lp_jit_context_constants(gallivm, context_ptr); num_consts_ptr = lp_jit_context_num_constants(gallivm, context_ptr); @@ -462,7 +466,9 @@ generate_fs_loop(struct gallivm_state *gallivm, int pos0 = find_output_by_semantic(&shader->info.base, TGSI_SEMANTIC_POSITION, 0); - + int s_out = find_output_by_semantic(&shader->info.base, + TGSI_SEMANTIC_STENCIL, + 0); if (pos0 != -1 && outputs[pos0][2]) { z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z"); @@ -512,6 +518,15 @@ generate_fs_loop(struct gallivm_state *gallivm, } } + if (s_out != -1 && outputs[s_out][1]) { + /* there's only one value, and spec says to discard additional bits */ + LLVMValueRef s_max_mask = lp_build_const_int_vec(gallivm, int_type, 255); + stencil_refs[0] = LLVMBuildLoad(builder, outputs[s_out][1], "output.s"); + stencil_refs[0] = LLVMBuildBitCast(builder, stencil_refs[0], int_vec_type, ""); + stencil_refs[0] = LLVMBuildAnd(builder, stencil_refs[0], s_max_mask, ""); + stencil_refs[1] = stencil_refs[0]; + } + lp_build_depth_stencil_load_swizzled(gallivm, type, zs_format_desc, key->resource_1d, depth_ptr, depth_stride, diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 08f968f7f0a..b985877e43e 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -139,11 +139,6 @@ static void lp_blit(struct pipe_context *pipe, return; /* done */ } - if (info.mask & PIPE_MASK_S) { - debug_printf("llvmpipe: cannot blit stencil, skipping\n"); - info.mask &= ~PIPE_MASK_S; - } - if (!util_blitter_is_blit_supported(lp->blitter, &info)) { debug_printf("llvmpipe: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), -- 2.30.2