mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 07:20:10 +01:00
lp: Implement gallium depth_bounds_test capability
Support for this capability in llvmpipe expose support for GL_EXT_depth_bounds_test, as well as supporting the `depthBounds` device feature in lavapipe. Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36487>
This commit is contained in:
parent
36b0fdb7b7
commit
b75b0ce7b2
11 changed files with 113 additions and 5 deletions
|
|
@ -827,6 +827,8 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
LLVMValueRef z_fb,
|
||||
LLVMValueRef s_fb,
|
||||
LLVMValueRef face,
|
||||
LLVMValueRef min_depth_bounds,
|
||||
LLVMValueRef max_depth_bounds,
|
||||
LLVMValueRef *z_value,
|
||||
LLVMValueRef *s_value,
|
||||
bool do_branch,
|
||||
|
|
@ -841,7 +843,7 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
LLVMValueRef z_dst = NULL;
|
||||
LLVMValueRef stencil_vals = NULL;
|
||||
LLVMValueRef z_bitmask = NULL, stencil_shift = NULL;
|
||||
LLVMValueRef z_pass = NULL, s_pass_mask = NULL;
|
||||
LLVMValueRef z_pass = NULL, s_pass_mask = NULL, b_pass_mask = NULL;
|
||||
LLVMValueRef current_mask = mask ? lp_build_mask_value(mask) : *cov_mask;
|
||||
LLVMValueRef front_facing = NULL;
|
||||
bool have_z, have_s;
|
||||
|
|
@ -883,7 +885,7 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
assert(z_swizzle != PIPE_SWIZZLE_NONE ||
|
||||
s_swizzle != PIPE_SWIZZLE_NONE);
|
||||
|
||||
assert(depth->enabled || stencil[0].enabled);
|
||||
assert(depth->enabled || depth->depth_bounds_test || stencil[0].enabled);
|
||||
|
||||
assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
|
||||
assert(format_desc->block.width == 1);
|
||||
|
|
@ -1026,6 +1028,40 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
}
|
||||
}
|
||||
|
||||
if (depth->depth_bounds_test) {
|
||||
if (!z_type.floating) {
|
||||
struct lp_type f_type = lp_type_float_vec(32, 32 * z_type.length);
|
||||
struct lp_build_context f_bld;
|
||||
|
||||
lp_build_context_init(&f_bld, gallivm, f_type);
|
||||
|
||||
min_depth_bounds = lp_build_max(&f_bld,
|
||||
lp_build_const_vec(gallivm, f_type, 0.0f),
|
||||
min_depth_bounds);
|
||||
max_depth_bounds = lp_build_min(&f_bld,
|
||||
lp_build_const_vec(gallivm, f_type, 1.0f),
|
||||
max_depth_bounds);
|
||||
|
||||
min_depth_bounds =
|
||||
lp_build_clamped_float_to_unsigned_norm(gallivm, f_type, z_width,
|
||||
min_depth_bounds);
|
||||
max_depth_bounds =
|
||||
lp_build_clamped_float_to_unsigned_norm(gallivm, f_type, z_width,
|
||||
max_depth_bounds);
|
||||
}
|
||||
|
||||
LLVMValueRef above_min = lp_build_cmp(&z_bld, PIPE_FUNC_GEQUAL,
|
||||
z_dst, min_depth_bounds);
|
||||
LLVMValueRef below_max = lp_build_cmp(&z_bld, PIPE_FUNC_LEQUAL,
|
||||
z_dst, max_depth_bounds);
|
||||
|
||||
b_pass_mask =
|
||||
LLVMBuildAnd(builder, above_min, below_max, "");
|
||||
|
||||
/* Mask off any writes that failed the depth bounds test */
|
||||
current_mask = b_pass_mask;
|
||||
}
|
||||
|
||||
if (depth->enabled) {
|
||||
/*
|
||||
* Convert fragment Z to the desired type, aligning the LSB to the right.
|
||||
|
|
@ -1112,7 +1148,7 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
stencil_refs, stencil_vals,
|
||||
z_pass_mask, front_facing);
|
||||
}
|
||||
} else {
|
||||
} else if (stencil[0].enabled) {
|
||||
/* No depth test: apply Z-pass operator to stencil buffer values which
|
||||
* passed the stencil test.
|
||||
*/
|
||||
|
|
@ -1146,6 +1182,9 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
}
|
||||
|
||||
if (mask) {
|
||||
if (b_pass_mask)
|
||||
lp_build_mask_update(mask, b_pass_mask);
|
||||
|
||||
if (s_pass_mask)
|
||||
lp_build_mask_update(mask, s_pass_mask);
|
||||
|
||||
|
|
@ -1153,6 +1192,9 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
lp_build_mask_update(mask, z_pass);
|
||||
} else {
|
||||
LLVMValueRef tmp_mask = *cov_mask;
|
||||
if (b_pass_mask)
|
||||
tmp_mask = LLVMBuildAnd(builder, tmp_mask, b_pass_mask, "");
|
||||
|
||||
if (s_pass_mask)
|
||||
tmp_mask = LLVMBuildAnd(builder, tmp_mask, s_pass_mask, "");
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
|
|||
LLVMValueRef z_fb,
|
||||
LLVMValueRef s_fb,
|
||||
LLVMValueRef face,
|
||||
LLVMValueRef min_depth_bounds,
|
||||
LLVMValueRef max_depth_bounds,
|
||||
LLVMValueRef *z_value,
|
||||
LLVMValueRef *s_value,
|
||||
bool do_branch,
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
|
|||
LLVMTypeRef elem_types[LP_JIT_CTX_COUNT];
|
||||
LLVMTypeRef context_type;
|
||||
|
||||
elem_types[LP_JIT_CTX_MIN_DEPTH_BOUNDS] =
|
||||
elem_types[LP_JIT_CTX_MAX_DEPTH_BOUNDS] =
|
||||
elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatTypeInContext(lc);
|
||||
elem_types[LP_JIT_CTX_SAMPLE_MASK] =
|
||||
elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] =
|
||||
|
|
@ -107,6 +109,12 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
|
|||
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, viewports,
|
||||
gallivm->target, context_type,
|
||||
LP_JIT_CTX_VIEWPORTS);
|
||||
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, min_depth_bounds,
|
||||
gallivm->target, context_type,
|
||||
LP_JIT_CTX_MIN_DEPTH_BOUNDS);
|
||||
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, max_depth_bounds,
|
||||
gallivm->target, context_type,
|
||||
LP_JIT_CTX_MAX_DEPTH_BOUNDS);
|
||||
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, sample_mask,
|
||||
gallivm->target, context_type,
|
||||
LP_JIT_CTX_SAMPLE_MASK);
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ struct lp_jit_context
|
|||
|
||||
struct lp_jit_viewport *viewports;
|
||||
|
||||
float min_depth_bounds, max_depth_bounds;
|
||||
|
||||
uint32_t sample_mask;
|
||||
};
|
||||
|
||||
|
|
@ -100,6 +102,8 @@ enum {
|
|||
LP_JIT_CTX_U8_BLEND_COLOR,
|
||||
LP_JIT_CTX_F_BLEND_COLOR,
|
||||
LP_JIT_CTX_VIEWPORTS,
|
||||
LP_JIT_CTX_MIN_DEPTH_BOUNDS,
|
||||
LP_JIT_CTX_MAX_DEPTH_BOUNDS,
|
||||
LP_JIT_CTX_SAMPLE_MASK,
|
||||
LP_JIT_CTX_COUNT
|
||||
};
|
||||
|
|
@ -122,6 +126,12 @@ enum {
|
|||
#define lp_jit_context_viewports(_gallivm, _type, _ptr) \
|
||||
lp_build_struct_get2(_gallivm, _type, _ptr, LP_JIT_CTX_VIEWPORTS, "viewports")
|
||||
|
||||
#define lp_jit_context_min_depth_bounds(_gallivm, _type, _ptr) \
|
||||
lp_build_struct_get2(_gallivm, _type, _ptr, LP_JIT_CTX_MIN_DEPTH_BOUNDS, "min_depth_bounds")
|
||||
|
||||
#define lp_jit_context_max_depth_bounds(_gallivm, _type, _ptr) \
|
||||
lp_build_struct_get2(_gallivm, _type, _ptr, LP_JIT_CTX_MAX_DEPTH_BOUNDS, "max_depth_bounds")
|
||||
|
||||
#define lp_jit_context_sample_mask(_gallivm, _type, _ptr) \
|
||||
lp_build_struct_get_ptr2(_gallivm, _type, _ptr, LP_JIT_CTX_SAMPLE_MASK, "sample_mask")
|
||||
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ llvmpipe_init_screen_caps(struct pipe_screen *screen)
|
|||
caps->texture_multisample = true;
|
||||
caps->sample_shading = true;
|
||||
caps->gl_spirv = true;
|
||||
caps->depth_bounds_test = true;
|
||||
caps->post_depth_coverage = true;
|
||||
caps->shader_clock = true;
|
||||
caps->packed_uniforms = true;
|
||||
|
|
|
|||
|
|
@ -756,6 +756,21 @@ lp_setup_set_alpha_ref_value(struct lp_setup_context *setup,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
lp_setup_set_depth_bounds_test_value(struct lp_setup_context *setup,
|
||||
float min_depth_bounds,
|
||||
float max_depth_bounds)
|
||||
{
|
||||
LP_DBG(DEBUG_SETUP, "%s %f %f\n",
|
||||
__func__, min_depth_bounds, max_depth_bounds);
|
||||
|
||||
if (setup->fs.current.jit_context.min_depth_bounds != min_depth_bounds ||
|
||||
setup->fs.current.jit_context.max_depth_bounds != max_depth_bounds) {
|
||||
setup->fs.current.jit_context.min_depth_bounds = min_depth_bounds;
|
||||
setup->fs.current.jit_context.max_depth_bounds = max_depth_bounds;
|
||||
setup->dirty |= LP_SETUP_NEW_FS;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lp_setup_set_stencil_ref_values(struct lp_setup_context *setup,
|
||||
|
|
|
|||
|
|
@ -96,6 +96,11 @@ void
|
|||
lp_setup_set_alpha_ref_value(struct lp_setup_context *setup,
|
||||
float alpha_ref_value);
|
||||
|
||||
void
|
||||
lp_setup_set_depth_bounds_test_value(struct lp_setup_context *setup,
|
||||
float min_depth_bounds,
|
||||
float max_depth_bounds);
|
||||
|
||||
void
|
||||
lp_setup_set_stencil_ref_values(struct lp_setup_context *setup,
|
||||
const uint8_t refs[2]);
|
||||
|
|
|
|||
|
|
@ -118,6 +118,10 @@ llvmpipe_create_depth_stencil_state(struct pipe_context *pipe,
|
|||
state->depth_writemask = 0;
|
||||
state->stencil[0].enabled = 0;
|
||||
state->stencil[1].enabled = 0;
|
||||
|
||||
state->depth_bounds_test = 0;
|
||||
state->depth_bounds_min = 0.0;
|
||||
state->depth_bounds_max = 1.0;
|
||||
}
|
||||
|
||||
if (LP_PERF & PERF_NO_ALPHATEST) {
|
||||
|
|
|
|||
|
|
@ -345,6 +345,9 @@ llvmpipe_update_derived(struct llvmpipe_context *llvmpipe)
|
|||
llvmpipe->depth_stencil->alpha_ref_value);
|
||||
lp_setup_set_stencil_ref_values(llvmpipe->setup,
|
||||
llvmpipe->stencil_ref.ref_value);
|
||||
lp_setup_set_depth_bounds_test_value(llvmpipe->setup,
|
||||
llvmpipe->depth_stencil->depth_bounds_min,
|
||||
llvmpipe->depth_stencil->depth_bounds_max);
|
||||
}
|
||||
|
||||
if (llvmpipe->dirty & LP_NEW_FS_CONSTANTS)
|
||||
|
|
|
|||
|
|
@ -710,6 +710,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
LLVMValueRef z_fb, s_fb;
|
||||
LLVMValueRef zs_samples = lp_build_const_int32(gallivm, key->zsbuf_nr_samples);
|
||||
LLVMValueRef z_out = NULL, s_out = NULL;
|
||||
LLVMValueRef min_depth_bounds = NULL, max_depth_bounds = NULL;
|
||||
struct lp_build_for_loop_state loop_state, sample_loop_state = {0};
|
||||
struct lp_build_mask_context mask;
|
||||
struct nir_shader *nir = shader->base.ir.nir;
|
||||
|
|
@ -733,6 +734,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
unsigned depth_mode;
|
||||
const struct util_format_description *zs_format_desc = NULL;
|
||||
if (key->depth.enabled ||
|
||||
key->depth.depth_bounds_test ||
|
||||
key->stencil[0].enabled) {
|
||||
zs_format_desc = util_format_description(key->zsbuf_format);
|
||||
|
||||
|
|
@ -930,6 +932,14 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
depth_ptr, &sample_offset, 1, "");
|
||||
}
|
||||
|
||||
if (key->depth.depth_bounds_test) {
|
||||
min_depth_bounds = lp_jit_context_min_depth_bounds(gallivm, context_type, context_ptr);
|
||||
min_depth_bounds = lp_build_broadcast(gallivm, vec_type, min_depth_bounds);
|
||||
|
||||
max_depth_bounds = lp_jit_context_max_depth_bounds(gallivm, context_type, context_ptr);
|
||||
max_depth_bounds = lp_build_broadcast(gallivm, vec_type, max_depth_bounds);
|
||||
}
|
||||
|
||||
if (depth_mode & EARLY_DEPTH_TEST) {
|
||||
z = lp_build_depth_clamp(gallivm, builder, key->depth_clamp,
|
||||
key->restrict_depth_values, type,
|
||||
|
|
@ -950,6 +960,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
stencil_refs,
|
||||
z, z_fb, s_fb,
|
||||
facing,
|
||||
min_depth_bounds, max_depth_bounds,
|
||||
&z_value, &s_value,
|
||||
!key->multisample,
|
||||
key->restrict_depth_values);
|
||||
|
|
@ -1376,6 +1387,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
stencil_refs,
|
||||
z, z_fb, s_fb,
|
||||
facing,
|
||||
min_depth_bounds, max_depth_bounds,
|
||||
&z_value, &s_value,
|
||||
false,
|
||||
key->restrict_depth_values);
|
||||
|
|
@ -3566,7 +3578,8 @@ generate_fragment(struct llvmpipe_context *lp,
|
|||
|
||||
bool do_branch = ((key->depth.enabled
|
||||
|| key->stencil[0].enabled
|
||||
|| key->alpha.enabled)
|
||||
|| key->alpha.enabled
|
||||
|| key->depth.depth_bounds_test)
|
||||
&& !nir->info.fs.uses_discard);
|
||||
|
||||
color_ptr = LLVMBuildLoad2(builder, int8p_type,
|
||||
|
|
@ -3876,6 +3889,7 @@ generate_variant(struct llvmpipe_context *lp,
|
|||
!key->multisample &&
|
||||
!key->blend.alpha_to_coverage &&
|
||||
!key->depth.enabled &&
|
||||
!key->depth.depth_bounds_test &&
|
||||
!nir->info.fs.uses_discard &&
|
||||
!(nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) &&
|
||||
!nir->info.fs.uses_fbfetch_output;
|
||||
|
|
@ -3946,6 +3960,7 @@ generate_variant(struct llvmpipe_context *lp,
|
|||
const bool linear_pipeline =
|
||||
!key->stencil[0].enabled &&
|
||||
!key->depth.enabled &&
|
||||
!key->depth.depth_bounds_test &&
|
||||
!nir->info.fs.uses_discard &&
|
||||
!key->blend.logicop_enable &&
|
||||
(key->cbuf_format[0] == PIPE_FORMAT_B8G8R8A8_UNORM ||
|
||||
|
|
@ -4479,12 +4494,14 @@ make_variant_key(struct llvmpipe_context *lp,
|
|||
const struct util_format_description *zsbuf_desc =
|
||||
util_format_description(zsbuf_format);
|
||||
|
||||
if (lp->depth_stencil->depth_enabled &&
|
||||
if ((lp->depth_stencil->depth_enabled ||
|
||||
lp->depth_stencil->depth_bounds_test) &&
|
||||
util_format_has_depth(zsbuf_desc)) {
|
||||
key->zsbuf_format = zsbuf_format;
|
||||
key->depth.enabled = lp->depth_stencil->depth_enabled;
|
||||
key->depth.writemask = lp->depth_stencil->depth_writemask;
|
||||
key->depth.func = lp->depth_stencil->depth_func;
|
||||
key->depth.depth_bounds_test = lp->depth_stencil->depth_bounds_test;
|
||||
}
|
||||
if (lp->depth_stencil->stencil[0].enabled &&
|
||||
util_format_has_stencil(zsbuf_desc)) {
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ struct lp_depth_state
|
|||
unsigned enabled:1; /**< depth test enabled? */
|
||||
unsigned writemask:1; /**< allow depth buffer writes? */
|
||||
unsigned func:3; /**< depth test func (PIPE_FUNC_x) */
|
||||
unsigned depth_bounds_test:1;
|
||||
};
|
||||
|
||||
struct lp_fragment_shader_variant_key
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue