mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-23 18:24:13 +08:00
d3d12: Support clip halfz
Reviewed-by: Giancarlo Devich <gdevich@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17567>
This commit is contained in:
parent
948c03bf58
commit
fccd6e275c
@ -213,7 +213,7 @@ GL 4.4, GLSL 4.40 -- all DONE: i965/gen8+, nvc0, r600, radeonsi, llvmpipe, zink
|
||||
GL 4.5, GLSL 4.50 -- all DONE: nvc0, r600, radeonsi, llvmpipe, zink
|
||||
|
||||
GL_ARB_ES3_1_compatibility DONE (i965/hsw+, softpipe, virgl)
|
||||
GL_ARB_clip_control DONE (freedreno, i965, nv50, softpipe, virgl, lima)
|
||||
GL_ARB_clip_control DONE (freedreno, i965, nv50, softpipe, virgl, lima, d3d12)
|
||||
GL_ARB_conditional_render_inverted DONE (freedreno, i965, nv50, softpipe, virgl, panfrost, d3d12)
|
||||
GL_ARB_cull_distance DONE (freedreno/a6xx, i965, nv50, softpipe, virgl)
|
||||
GL_ARB_derivative_control DONE (i965, nv50, softpipe, virgl)
|
||||
|
@ -319,9 +319,6 @@ spec/arb_clear_texture/arb_clear_texture-sized-formats: skip
|
||||
spec/arb_clear_texture/arb_clear_texture-srgb: skip
|
||||
spec/arb_clear_texture/arb_clear_texture-stencil: skip
|
||||
spec/arb_clear_texture/arb_clear_texture-texview: skip
|
||||
spec/arb_clip_control/arb_clip_control-clip-control: skip
|
||||
spec/arb_clip_control/arb_clip_control-depth-precision: skip
|
||||
spec/arb_clip_control/arb_clip_control-viewport: skip
|
||||
spec/arb_compute_shader/compute-and-render-bug-109630: fail
|
||||
spec/arb_copy_image/arb_copy_image-api_errors: skip
|
||||
spec/arb_copy_image/arb_copy_image-format-swizzle: skip
|
||||
@ -3515,10 +3512,10 @@ wgl/wgl-sanity: skip
|
||||
summary:
|
||||
name: results
|
||||
---- --------
|
||||
pass: 17870
|
||||
pass: 17873
|
||||
fail: 2035
|
||||
crash: 12
|
||||
skip: 1448
|
||||
skip: 1445
|
||||
timeout: 0
|
||||
warn: 10
|
||||
incomplete: 0
|
||||
|
@ -123,8 +123,9 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
|
||||
|
||||
if (key->last_vertex_processing_stage) {
|
||||
if (key->invert_depth)
|
||||
NIR_PASS_V(nir, d3d12_nir_invert_depth, key->invert_depth);
|
||||
NIR_PASS_V(nir, nir_lower_clip_halfz);
|
||||
NIR_PASS_V(nir, d3d12_nir_invert_depth, key->invert_depth, key->halfz);
|
||||
if (!key->halfz)
|
||||
NIR_PASS_V(nir, nir_lower_clip_halfz);
|
||||
NIR_PASS_V(nir, d3d12_lower_yflip);
|
||||
}
|
||||
NIR_PASS_V(nir, nir_lower_packed_ubo_loads);
|
||||
@ -790,7 +791,8 @@ d3d12_compare_shader_keys(const d3d12_shader_key *expect, const d3d12_shader_key
|
||||
expect->n_images * sizeof(struct d3d12_image_format_conversion_info)))
|
||||
return false;
|
||||
|
||||
if (expect->invert_depth != have->invert_depth)
|
||||
if (expect->invert_depth != have->invert_depth ||
|
||||
expect->halfz != have->halfz)
|
||||
return false;
|
||||
|
||||
if (expect->stage == PIPE_SHADER_VERTEX) {
|
||||
@ -930,6 +932,8 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
|
||||
(!next || next->stage == PIPE_SHADER_FRAGMENT))) {
|
||||
key->last_vertex_processing_stage = 1;
|
||||
key->invert_depth = sel_ctx->ctx->reverse_depth_range;
|
||||
key->halfz = sel_ctx->ctx->gfx_pipeline_state.rast ?
|
||||
sel_ctx->ctx->gfx_pipeline_state.rast->base.clip_halfz : false;
|
||||
if (sel_ctx->ctx->pstipple.enabled &&
|
||||
sel_ctx->ctx->gfx_pipeline_state.rast->base.poly_stipple_enable)
|
||||
key->next_varying_inputs |= VARYING_BIT_POS;
|
||||
|
@ -92,6 +92,7 @@ struct d3d12_shader_key {
|
||||
uint64_t prev_varying_outputs;
|
||||
unsigned last_vertex_processing_stage : 1;
|
||||
unsigned invert_depth : 16;
|
||||
unsigned halfz : 1;
|
||||
unsigned samples_int_textures : 1;
|
||||
unsigned input_clip_size : 4;
|
||||
unsigned tex_saturate_s : PIPE_MAX_SAMPLERS;
|
||||
|
@ -1313,9 +1313,25 @@ d3d12_set_viewport_states(struct pipe_context *pctx,
|
||||
ctx->viewports[start_slot + i].TopLeftX = state[i].translate[0] - state[i].scale[0];
|
||||
ctx->viewports[start_slot + i].Width = state[i].scale[0] * 2;
|
||||
|
||||
float near_depth = state[i].translate[2] - state[i].scale[2];
|
||||
float near_depth = state[i].translate[2];
|
||||
float far_depth = state[i].translate[2] + state[i].scale[2];
|
||||
|
||||
/* When the rasterizer is configured for "full" depth clipping ([-1, 1])
|
||||
* the viewport that we get is set to cover the positive half of clip space.
|
||||
* E.g. a [0, 1] viewport from the GL API will come to the driver as [0.5, 1].
|
||||
* Since we halve clipping space from [-1, 1] to [0, 1], we need to double the
|
||||
* viewport, treating translate as the center instead of the near plane. When
|
||||
* the rasterizer is configured for "half" depth clipping ([0, 1]), the viewport
|
||||
* covers the entire clip range, so no fixup is needed.
|
||||
*
|
||||
* Note: If halfz mode changes, both the rasterizer and viewport are dirtied,
|
||||
* and on the next draw we will get the rasterizer state first, and viewport
|
||||
* second, because ST_NEW_RASTERIZER comes before ST_NEW_VIEWPORT.
|
||||
*/
|
||||
if (ctx->gfx_pipeline_state.rast && !ctx->gfx_pipeline_state.rast->base.clip_halfz) {
|
||||
near_depth -= state[i].scale[2];
|
||||
}
|
||||
|
||||
bool reverse_depth_range = near_depth > far_depth;
|
||||
if (reverse_depth_range) {
|
||||
float tmp = near_depth;
|
||||
|
@ -391,6 +391,7 @@ d3d12_lower_load_patch_vertices_in(struct nir_shader *nir)
|
||||
struct invert_depth_state
|
||||
{
|
||||
unsigned viewport_mask;
|
||||
bool clip_halfz;
|
||||
nir_ssa_def *viewport_index;
|
||||
nir_instr *store_pos_instr;
|
||||
};
|
||||
@ -415,10 +416,14 @@ invert_depth_impl(nir_builder *b, struct invert_depth_state *state)
|
||||
if (state->viewport_index) {
|
||||
nir_push_if(b, nir_test_mask(b, nir_ishl(b, nir_imm_int(b, 1), state->viewport_index), state->viewport_mask));
|
||||
}
|
||||
nir_ssa_def *old_depth = nir_channel(b, pos, 2);
|
||||
nir_ssa_def *new_depth = nir_fneg(b, old_depth);
|
||||
if (state->clip_halfz)
|
||||
new_depth = nir_fadd_imm(b, new_depth, 1.0);
|
||||
nir_ssa_def *def = nir_vec4(b,
|
||||
nir_channel(b, pos, 0),
|
||||
nir_channel(b, pos, 1),
|
||||
nir_fneg(b, nir_channel(b, pos, 2)),
|
||||
new_depth,
|
||||
nir_channel(b, pos, 3));
|
||||
if (state->viewport_index) {
|
||||
nir_pop_if(b, NULL);
|
||||
@ -453,19 +458,20 @@ invert_depth_instr(nir_builder *b, struct nir_instr *instr, struct invert_depth_
|
||||
}
|
||||
|
||||
/* In OpenGL the windows space depth value z_w is evaluated according to "s * z_d + b"
|
||||
* with "s + (far - near) / 2" (depth clip:minus_one_to_one) [OpenGL 3.3, 2.13.1].
|
||||
* with "s = (far - near) / 2" (depth clip:minus_one_to_one) [OpenGL 3.3, 2.13.1].
|
||||
* When we switch the far and near value to satisfy DirectX requirements we have
|
||||
* to compensate by inverting "z_d' = -z_d" with this lowering pass.
|
||||
* When depth clip is set zero_to_one, we compensate with "z_d' = 1.0f - z_d" instead.
|
||||
*/
|
||||
void
|
||||
d3d12_nir_invert_depth(nir_shader *shader, unsigned viewport_mask)
|
||||
d3d12_nir_invert_depth(nir_shader *shader, unsigned viewport_mask, bool clip_halfz)
|
||||
{
|
||||
if (shader->info.stage != MESA_SHADER_VERTEX &&
|
||||
shader->info.stage != MESA_SHADER_TESS_EVAL &&
|
||||
shader->info.stage != MESA_SHADER_GEOMETRY)
|
||||
return;
|
||||
|
||||
struct invert_depth_state state = { viewport_mask };
|
||||
struct invert_depth_state state = { viewport_mask, clip_halfz };
|
||||
nir_foreach_function(function, shader) {
|
||||
if (function->impl) {
|
||||
nir_builder b;
|
||||
|
@ -88,7 +88,7 @@ bool
|
||||
d3d12_fix_io_uint_type(struct nir_shader *s, uint64_t in_mask, uint64_t out_mask);
|
||||
|
||||
void
|
||||
d3d12_nir_invert_depth(nir_shader *s, unsigned viewport_mask);
|
||||
d3d12_nir_invert_depth(nir_shader *s, unsigned viewport_mask, bool clip_halfz);
|
||||
|
||||
bool
|
||||
nir_lower_packed_ubo_loads(struct nir_shader *nir);
|
||||
|
@ -329,6 +329,7 @@ d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_MEMOBJ:
|
||||
case PIPE_CAP_FENCE_SIGNAL:
|
||||
case PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT:
|
||||
case PIPE_CAP_CLIP_HALFZ:
|
||||
return 1;
|
||||
|
||||
case PIPE_CAP_MAX_VERTEX_STREAMS:
|
||||
|
Loading…
Reference in New Issue
Block a user