diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 3771d1b5262..c38dba820f8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -301,6 +301,7 @@ generate_quad_mask(struct gallivm_state *gallivm, #define LATE_DEPTH_TEST 0x2 #define EARLY_DEPTH_WRITE 0x4 #define LATE_DEPTH_WRITE 0x8 +#define EARLY_DEPTH_TEST_INFERRED 0x10 //only with EARLY_DEPTH_TEST static int find_output_by_semantic( const struct tgsi_shader_info *info, @@ -637,10 +638,10 @@ generate_fs_loop(struct gallivm_state *gallivm, key->stencil[1].writemask))) depth_mode = LATE_DEPTH_TEST | LATE_DEPTH_WRITE; else - depth_mode = EARLY_DEPTH_TEST | LATE_DEPTH_WRITE; + depth_mode = EARLY_DEPTH_TEST | LATE_DEPTH_WRITE | EARLY_DEPTH_TEST_INFERRED; } else - depth_mode = EARLY_DEPTH_TEST | EARLY_DEPTH_WRITE; + depth_mode = EARLY_DEPTH_TEST | EARLY_DEPTH_WRITE | EARLY_DEPTH_TEST_INFERRED; } else { depth_mode = LATE_DEPTH_TEST | LATE_DEPTH_WRITE; @@ -1146,8 +1147,10 @@ generate_fs_loop(struct gallivm_state *gallivm, if (key->min_samples == 1) s_mask = LLVMBuildAnd(builder, s_mask, lp_build_mask_value(&mask), ""); - /* if the shader writes sample mask use that */ - if (shader->info.base.writes_samplemask) { + /* if the shader writes sample mask use that, + * but only if this isn't genuine early-depth to avoid breaking occlusion query */ + if (shader->info.base.writes_samplemask && + (!(depth_mode & EARLY_DEPTH_TEST) || (depth_mode & (EARLY_DEPTH_TEST_INFERRED)))) { LLVMValueRef out_smask_idx = LLVMBuildShl(builder, lp_build_const_int32(gallivm, 1), sample_loop_state.counter, ""); out_smask_idx = lp_build_broadcast(gallivm, int_vec_type, out_smask_idx); LLVMValueRef output_smask = LLVMBuildLoad(builder, out_sample_mask_storage, ""); @@ -1263,6 +1266,23 @@ generate_fs_loop(struct gallivm_state *gallivm, key->multisample ? s_mask : lp_build_mask_value(&mask), counter); } + /* if this is genuine early-depth in the shader, write samplemask now + * after occlusion count has been updated + */ + if (key->multisample && shader->info.base.writes_samplemask && + (depth_mode & (EARLY_DEPTH_TEST_INFERRED | EARLY_DEPTH_TEST)) == EARLY_DEPTH_TEST) { + /* if the shader writes sample mask use that */ + LLVMValueRef out_smask_idx = LLVMBuildShl(builder, lp_build_const_int32(gallivm, 1), sample_loop_state.counter, ""); + out_smask_idx = lp_build_broadcast(gallivm, int_vec_type, out_smask_idx); + LLVMValueRef output_smask = LLVMBuildLoad(builder, out_sample_mask_storage, ""); + LLVMValueRef smask_bit = LLVMBuildAnd(builder, output_smask, out_smask_idx, ""); + LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntNE, smask_bit, lp_build_const_int_vec(gallivm, int_type, 0), ""); + smask_bit = LLVMBuildSExt(builder, cmp, int_vec_type, ""); + + s_mask = LLVMBuildAnd(builder, s_mask, smask_bit, ""); + } + + if (key->multisample) { /* store the sample mask for this loop */ LLVMBuildStore(builder, s_mask, s_mask_ptr);