llvmpipe/fs: handle unrestricted depth values.

It moves the explicit clamping of incoming Z from vertex stages
after interp, to the depth clamp function.

It adds support to the depth clamp function to restrict incoming
Z values to 0..1 range.

It fixes the depth test conversions to allow unrestricted depth
values.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17612>
This commit is contained in:
Dave Airlie 2022-07-19 14:41:01 +10:00
parent 189755a9ac
commit 876db77bae
6 changed files with 40 additions and 37 deletions

View file

@ -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);

View file

@ -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,

View file

@ -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;

View file

@ -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,

View file

@ -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);
}
/*

View file

@ -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];