diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index 8eb0c765800..91bb347e307 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -836,7 +836,8 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm, LLVMValueRef face, LLVMValueRef *z_value, LLVMValueRef *s_value, - boolean do_branch) + boolean do_branch, + bool restrict_depth) { LLVMBuilderRef builder = gallivm->builder; struct lp_type z_type; @@ -856,10 +857,13 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm, * Depths are expected to be between 0 and 1, even if they are stored in * floats. Setting these bits here will ensure that the lp_build_conv() call * below won't try to unnecessarily clamp the incoming values. + * If depths are expected outside 0..1 don't set these bits. */ if (z_src_type.floating) { - z_src_type.sign = FALSE; - z_src_type.norm = TRUE; + if (restrict_depth) { + z_src_type.sign = FALSE; + z_src_type.norm = TRUE; + } } else { assert(!z_src_type.sign); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.h b/src/gallium/drivers/llvmpipe/lp_bld_depth.h index 8cf8580bf8d..1900cf68eec 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.h @@ -68,7 +68,8 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm, LLVMValueRef face, LLVMValueRef *z_value, LLVMValueRef *s_value, - boolean do_branch); + boolean do_branch, + bool restrict_depth); void lp_build_depth_stencil_load_swizzled(struct gallivm_state *gallivm, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c index b8ebbb6bd41..61d0bfa492f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c @@ -425,16 +425,6 @@ attribs_update_simple(struct lp_build_interp_soa_context *bld, coeff_bld->type, bld->a0aos[0], lp_build_const_int32(gallivm, 0)); a = LLVMBuildFAdd(builder, a, offset, ""); - - if (!bld->depth_clamp){ - /* OpenGL requires clamping z to 0..1 range after polgon offset - * is applied if depth-clamping isn't enabled. - * - * This also fixes the problem that depth values can exceed 1.0, - * due to imprecision in the calculations. - */ - a = lp_build_clamp(coeff_bld, a, coeff_bld->zero, coeff_bld->one); - } } bld->attribs[attrib][chan] = a; @@ -687,7 +677,6 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, unsigned coverage_samples, LLVMValueRef sample_pos_array, LLVMValueRef num_loop, - boolean depth_clamp, LLVMBuilderRef builder, struct lp_type type, LLVMValueRef a0_ptr, @@ -756,7 +745,6 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, } else { bld->pos_offset = 0.5; } - bld->depth_clamp = depth_clamp; bld->coverage_samples = coverage_samples; bld->num_loop = num_loop; bld->sample_pos_array = sample_pos_array; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h index c13a2055dbb..f9c9211cbb8 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h @@ -126,7 +126,6 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, unsigned coverage_samples, LLVMValueRef sample_pos_array, LLVMValueRef num_loop, - boolean depth_clamp, LLVMBuilderRef builder, struct lp_type type, LLVMValueRef a0_ptr, diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 617a9bac429..658642664ee 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -345,6 +345,8 @@ lp_llvm_viewport(LLVMValueRef context_ptr, static LLVMValueRef lp_build_depth_clamp(struct gallivm_state *gallivm, LLVMBuilderRef builder, + bool depth_clamp, + bool restrict_depth, struct lp_type type, LLVMValueRef context_ptr, LLVMValueRef thread_data_ptr, @@ -357,6 +359,12 @@ lp_build_depth_clamp(struct gallivm_state *gallivm, assert(type.floating); lp_build_context_init(&f32_bld, gallivm, type); + if (restrict_depth) + z = lp_build_clamp(&f32_bld, z, f32_bld.zero, f32_bld.one); + + if (!depth_clamp) + return z; + /* * Assumes clamping of the viewport index will occur in setup/gs. Value * is passed through the rasterization stage via lp_rast_shader_inputs. @@ -870,13 +878,10 @@ generate_fs_loop(struct gallivm_state *gallivm, } if (depth_mode & EARLY_DEPTH_TEST) { - /* - * Clamp according to ARB_depth_clamp semantics. - */ - if (key->depth_clamp) { - z = lp_build_depth_clamp(gallivm, builder, type, context_ptr, - thread_data_ptr, z); - } + z = lp_build_depth_clamp(gallivm, builder, key->depth_clamp, + key->restrict_depth_values, type, context_ptr, + thread_data_ptr, z); + lp_build_depth_stencil_load_swizzled(gallivm, type, zs_format_desc, key->resource_1d, depth_ptr, depth_stride, @@ -892,7 +897,8 @@ generate_fs_loop(struct gallivm_state *gallivm, z, z_fb, s_fb, facing, &z_value, &s_value, - !simple_shader && !key->multisample); + !simple_shader && !key->multisample, + key->restrict_depth_values); if (depth_mode & EARLY_DEPTH_WRITE) { lp_build_depth_stencil_write_swizzled(gallivm, type, @@ -1254,16 +1260,9 @@ generate_fs_loop(struct gallivm_state *gallivm, /* * Clamp according to ARB_depth_clamp semantics. */ - if (key->depth_clamp) { - z = lp_build_depth_clamp(gallivm, builder, type, context_ptr, - thread_data_ptr, z); - } else { - struct lp_build_context f32_bld; - lp_build_context_init(&f32_bld, gallivm, type); - z = lp_build_clamp(&f32_bld, z, - lp_build_const_vec(gallivm, type, 0.0), - lp_build_const_vec(gallivm, type, 1.0)); - } + z = lp_build_depth_clamp(gallivm, builder, key->depth_clamp, + key->restrict_depth_values, type, context_ptr, + thread_data_ptr, z); if (shader->info.base.writes_stencil) { LLVMValueRef idx = loop_state.counter; @@ -1295,7 +1294,8 @@ generate_fs_loop(struct gallivm_state *gallivm, z, z_fb, s_fb, facing, &z_value, &s_value, - !simple_shader); + !simple_shader, + key->restrict_depth_values); /* Late Z write */ if (depth_mode & LATE_DEPTH_WRITE) { lp_build_depth_stencil_write_swizzled(gallivm, type, @@ -3288,7 +3288,6 @@ generate_fragment(struct llvmpipe_context *lp, pixel_center_integer, key->coverage_samples, glob_sample_pos, num_loop, - key->depth_clamp, builder, fs_type, a0_ptr, dadx_ptr, dady_ptr, x, y); @@ -3467,6 +3466,9 @@ dump_fs_variant_key(struct lp_fragment_shader_variant_key *key) if (key->depth_clamp) debug_printf("depth_clamp = 1\n"); + if (key->restrict_depth_values) + debug_printf("restrict_depth_values = 1\n"); + if (key->multisample) { debug_printf("multisample = 1\n"); debug_printf("coverage samples = %d\n", key->coverage_samples); @@ -4277,6 +4279,14 @@ make_variant_key(struct llvmpipe_context *lp, } key->zsbuf_nr_samples = util_res_sample_count(lp->framebuffer.zsbuf->texture); + + /* + * Restrict depth values if the API is clamped (GL, VK with ext) + * for non float Z buffer + */ + key->restrict_depth_values = + !(lp->rasterizer->unclamped_fragment_depth_values && + util_format_get_depth_only(zsbuf_format) == PIPE_FORMAT_Z32_FLOAT); } /* diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h index fd1f2def6e9..1f6b5db54b4 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.h +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h @@ -104,6 +104,7 @@ struct lp_fragment_shader_variant_key unsigned depth_clamp:1; unsigned multisample:1; unsigned no_ms_sample_mask_out:1; + unsigned restrict_depth_values:1; enum pipe_format zsbuf_format; enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS];