llvmpipe: add plumbing for ARB_depth_clamp
With this patch llvmpipe will adhere to the ARB_depth_clamp enabled state when clamping the fragment's zw value. To support this, the variant key now includes the depth_clamp state. key->depth_clamp is derived from pipe_rasterizer_state's (depth_clip == 0), thus depth clamp is only enabled when depth clip is disabled. Reviewed-by: Roland Scheidegger <sroland@vmware.com> Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
00faf82832
commit
e84a1ab3c4
|
@ -656,6 +656,7 @@ lp_setup_set_viewports(struct lp_setup_context *setup,
|
|||
unsigned num_viewports,
|
||||
const struct pipe_viewport_state *viewports)
|
||||
{
|
||||
struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
|
||||
unsigned i;
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
|
||||
|
@ -670,8 +671,14 @@ lp_setup_set_viewports(struct lp_setup_context *setup,
|
|||
float min_depth;
|
||||
float max_depth;
|
||||
|
||||
min_depth = viewports[i].translate[2];
|
||||
max_depth = viewports[i].translate[2] + viewports[i].scale[2];
|
||||
if (lp->rasterizer->clip_halfz == 0) {
|
||||
float half_depth = viewports[i].scale[2];
|
||||
min_depth = viewports[i].translate[2] - half_depth;
|
||||
max_depth = min_depth + half_depth * 2.0f;
|
||||
} else {
|
||||
min_depth = viewports[i].translate[2];
|
||||
max_depth = min_depth + viewports[i].scale[2];
|
||||
}
|
||||
|
||||
if (setup->viewports[i].min_depth != min_depth ||
|
||||
setup->viewports[i].max_depth != max_depth) {
|
||||
|
|
|
@ -445,47 +445,52 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
0);
|
||||
|
||||
if (pos0 != -1 && outputs[pos0][2]) {
|
||||
LLVMValueRef viewport, min_depth, max_depth;
|
||||
LLVMValueRef viewport_index;
|
||||
struct lp_build_context f32_bld;
|
||||
|
||||
assert(type.floating);
|
||||
lp_build_context_init(&f32_bld, gallivm, type);
|
||||
|
||||
/*
|
||||
* Assumes clamping of the viewport index will occur in setup/gs. Value
|
||||
* is passed through the rasterization stage via lp_rast_shader_inputs.
|
||||
*
|
||||
* See: draw_clamp_viewport_idx and lp_clamp_viewport_idx for clamping
|
||||
* semantics.
|
||||
*/
|
||||
viewport_index = lp_jit_thread_data_raster_state_viewport_index(gallivm,
|
||||
thread_data_ptr);
|
||||
|
||||
/*
|
||||
* Load the min and max depth from the lp_jit_context.viewports
|
||||
* array of lp_jit_viewport structures.
|
||||
*/
|
||||
viewport = lp_llvm_viewport(context_ptr, gallivm, viewport_index);
|
||||
|
||||
/* viewports[viewport_index].min_depth */
|
||||
min_depth = LLVMBuildExtractElement(builder, viewport,
|
||||
lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MIN_DEPTH),
|
||||
"");
|
||||
min_depth = lp_build_broadcast_scalar(&f32_bld, min_depth);
|
||||
|
||||
/* viewports[viewport_index].max_depth */
|
||||
max_depth = LLVMBuildExtractElement(builder, viewport,
|
||||
lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MAX_DEPTH),
|
||||
"");
|
||||
max_depth = lp_build_broadcast_scalar(&f32_bld, max_depth);
|
||||
|
||||
z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
|
||||
|
||||
/*
|
||||
* Clamp to the min and max depth values for the given viewport.
|
||||
* Clamp according to ARB_depth_clamp semantics.
|
||||
*/
|
||||
z = lp_build_clamp(&f32_bld, z, min_depth, max_depth);
|
||||
if (key->depth_clamp) {
|
||||
LLVMValueRef viewport, min_depth, max_depth;
|
||||
LLVMValueRef viewport_index;
|
||||
struct lp_build_context f32_bld;
|
||||
|
||||
assert(type.floating);
|
||||
lp_build_context_init(&f32_bld, gallivm, type);
|
||||
|
||||
/*
|
||||
* Assumes clamping of the viewport index will occur in setup/gs. Value
|
||||
* is passed through the rasterization stage via lp_rast_shader_inputs.
|
||||
*
|
||||
* See: draw_clamp_viewport_idx and lp_clamp_viewport_idx for clamping
|
||||
* semantics.
|
||||
*/
|
||||
viewport_index = lp_jit_thread_data_raster_state_viewport_index(gallivm,
|
||||
thread_data_ptr);
|
||||
|
||||
/*
|
||||
* Load the min and max depth from the lp_jit_context.viewports
|
||||
* array of lp_jit_viewport structures.
|
||||
*/
|
||||
viewport = lp_llvm_viewport(context_ptr, gallivm, viewport_index);
|
||||
|
||||
/* viewports[viewport_index].min_depth */
|
||||
min_depth = LLVMBuildExtractElement(builder, viewport,
|
||||
lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MIN_DEPTH),
|
||||
"");
|
||||
min_depth = lp_build_broadcast_scalar(&f32_bld, min_depth);
|
||||
|
||||
/* viewports[viewport_index].max_depth */
|
||||
max_depth = LLVMBuildExtractElement(builder, viewport,
|
||||
lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MAX_DEPTH),
|
||||
"");
|
||||
max_depth = lp_build_broadcast_scalar(&f32_bld, max_depth);
|
||||
|
||||
/*
|
||||
* Clamp to the min and max depth values for the given viewport.
|
||||
*/
|
||||
z = lp_build_clamp(&f32_bld, z, min_depth, max_depth);
|
||||
}
|
||||
}
|
||||
|
||||
lp_build_depth_stencil_load_swizzled(gallivm, type,
|
||||
|
@ -2860,6 +2865,18 @@ make_variant_key(struct llvmpipe_context *lp,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Propagate the depth clamp setting from the rasterizer state.
|
||||
* depth_clip == 0 implies depth clamping is enabled.
|
||||
*
|
||||
* When clip_halfz is enabled, then always clamp the depth values.
|
||||
*/
|
||||
if (lp->rasterizer->clip_halfz) {
|
||||
key->depth_clamp = 1;
|
||||
} else {
|
||||
key->depth_clamp = (lp->rasterizer->depth_clip == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* alpha test only applies if render buffer 0 is non-integer (or does not exist) */
|
||||
if (!lp->framebuffer.nr_cbufs ||
|
||||
!util_format_is_pure_integer(lp->framebuffer.cbufs[0]->format)) {
|
||||
|
|
|
@ -76,6 +76,7 @@ struct lp_fragment_shader_variant_key
|
|||
unsigned flatshade:1;
|
||||
unsigned occlusion_count:1;
|
||||
unsigned resource_1d:1;
|
||||
unsigned depth_clamp:1;
|
||||
|
||||
enum pipe_format zsbuf_format;
|
||||
enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS];
|
||||
|
|
|
@ -130,6 +130,8 @@ struct pipe_rasterizer_state
|
|||
/**
|
||||
* When true clip space in the z axis goes from [0..1] (D3D). When false
|
||||
* [-1, 1] (GL).
|
||||
*
|
||||
* NOTE: D3D will always use depth clamping.
|
||||
*/
|
||||
unsigned clip_halfz:1;
|
||||
|
||||
|
|
Loading…
Reference in New Issue