llvmpipe: fix occlusion queries with early depth test
for genuine early depth tests, the samplecount must be updated after depth
test but before samplemask is applied
for inferred-early or regular depth tests, the samplemask can be applied
before the depth test
Fixes: d9276ae965 ("llvmpipe: handle gl_SampleMask writing.")
fixes:
dEQP-VK.fragment_operations.early_fragment.sample_count_early_fragment_tests_depth_samples_4
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15319>
This commit is contained in:
committed by
Marge Bot
parent
f7175bf416
commit
42e78ba125
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user