mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-01 16:10:09 +01:00
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:
parent
189755a9ac
commit
876db77bae
6 changed files with 40 additions and 37 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue