mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 20:20:09 +01:00
d3d12: Update depth invert to deal with multi-viewport
Turn the context state and shader key into a bitmask. When lowering the depth invert into the shader, scan for writes to viewport index. If found, move position to the end of the function (or current vertex) and check if the current viewport needs the depth invert before applying. Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14881>
This commit is contained in:
parent
52b3e6be5f
commit
a26f647caa
6 changed files with 68 additions and 20 deletions
|
|
@ -165,7 +165,7 @@ 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);
|
||||
NIR_PASS_V(nir, d3d12_nir_invert_depth, key->invert_depth);
|
||||
NIR_PASS_V(nir, nir_lower_clip_halfz);
|
||||
NIR_PASS_V(nir, d3d12_lower_yflip);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ struct d3d12_shader_key {
|
|||
uint64_t next_varying_inputs;
|
||||
uint64_t prev_varying_outputs;
|
||||
unsigned last_vertex_processing_stage : 1;
|
||||
unsigned invert_depth : 1;
|
||||
unsigned invert_depth : 16;
|
||||
unsigned samples_int_textures : 1;
|
||||
unsigned input_clip_size : 4;
|
||||
unsigned tex_saturate_s : PIPE_MAX_SAMPLERS;
|
||||
|
|
|
|||
|
|
@ -1300,12 +1300,14 @@ d3d12_set_viewport_states(struct pipe_context *pctx,
|
|||
float near_depth = state[i].translate[2] - state[i].scale[2];
|
||||
float far_depth = state[i].translate[2] + state[i].scale[2];
|
||||
|
||||
ctx->reverse_depth_range = near_depth > far_depth;
|
||||
if (ctx->reverse_depth_range) {
|
||||
bool reverse_depth_range = near_depth > far_depth;
|
||||
if (reverse_depth_range) {
|
||||
float tmp = near_depth;
|
||||
near_depth = far_depth;
|
||||
far_depth = tmp;
|
||||
}
|
||||
ctx->reverse_depth_range |= (1 << (start_slot + i));
|
||||
} else
|
||||
ctx->reverse_depth_range &= ~(1 << (start_slot + i));
|
||||
ctx->viewports[start_slot + i].MinDepth = near_depth;
|
||||
ctx->viewports[start_slot + i].MaxDepth = far_depth;
|
||||
ctx->viewport_states[start_slot + i] = state[i];
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ struct d3d12_context {
|
|||
unsigned cmdlist_dirty;
|
||||
ID3D12PipelineState *current_gfx_pso;
|
||||
ID3D12PipelineState *current_compute_pso;
|
||||
bool reverse_depth_range;
|
||||
uint16_t reverse_depth_range;
|
||||
|
||||
ID3D12Fence *cmdqueue_fence;
|
||||
uint64_t fence_value;
|
||||
|
|
|
|||
|
|
@ -388,30 +388,70 @@ d3d12_lower_load_patch_vertices_in(struct nir_shader *nir)
|
|||
nir_metadata_block_index | nir_metadata_dominance, &var);
|
||||
}
|
||||
|
||||
static void
|
||||
invert_depth(nir_builder *b, struct nir_instr *instr)
|
||||
struct invert_depth_state
|
||||
{
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return;
|
||||
unsigned viewport_mask;
|
||||
nir_ssa_def *viewport_index;
|
||||
nir_instr *store_pos_instr;
|
||||
};
|
||||
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_store_deref)
|
||||
return;
|
||||
static void
|
||||
invert_depth_impl(nir_builder *b, struct invert_depth_state *state)
|
||||
{
|
||||
assert(state->store_pos_instr);
|
||||
|
||||
nir_variable *var = nir_intrinsic_get_var(intr, 0);
|
||||
if (var->data.mode != nir_var_shader_out ||
|
||||
var->data.location != VARYING_SLOT_POS)
|
||||
return;
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(state->store_pos_instr);
|
||||
if (state->viewport_index) {
|
||||
/* Cursor is assigned before calling. Make sure that storing pos comes
|
||||
* after computing the viewport.
|
||||
*/
|
||||
nir_instr_move(b->cursor, &intr->instr);
|
||||
}
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
nir_ssa_def *pos = nir_ssa_for_src(b, intr->src[1], 4);
|
||||
|
||||
if (state->viewport_index) {
|
||||
nir_push_if(b, nir_i2b1(b, nir_iand_imm(b,
|
||||
nir_ishl(b, nir_imm_int(b, 1), state->viewport_index),
|
||||
state->viewport_mask)));
|
||||
}
|
||||
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)),
|
||||
nir_channel(b, pos, 3));
|
||||
if (state->viewport_index) {
|
||||
nir_pop_if(b, NULL);
|
||||
def = nir_if_phi(b, def, pos);
|
||||
}
|
||||
nir_instr_rewrite_src(&intr->instr, intr->src + 1, nir_src_for_ssa(def));
|
||||
|
||||
state->viewport_index = NULL;
|
||||
state->store_pos_instr = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
invert_depth_instr(nir_builder *b, struct nir_instr *instr, struct invert_depth_state *state)
|
||||
{
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return;
|
||||
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic == nir_intrinsic_store_deref) {
|
||||
nir_variable *var = nir_intrinsic_get_var(intr, 0);
|
||||
if (var->data.mode != nir_var_shader_out)
|
||||
return;
|
||||
|
||||
if (var->data.location == VARYING_SLOT_VIEWPORT)
|
||||
state->viewport_index = intr->src[1].ssa;
|
||||
if (var->data.location == VARYING_SLOT_POS)
|
||||
state->store_pos_instr = instr;
|
||||
} else if (intr->intrinsic == nir_intrinsic_emit_vertex) {
|
||||
b->cursor = nir_before_instr(instr);
|
||||
invert_depth_impl(b, state);
|
||||
}
|
||||
}
|
||||
|
||||
/* In OpenGL the windows space depth value z_w is evaluated according to "s * z_d + b"
|
||||
|
|
@ -420,13 +460,14 @@ invert_depth(nir_builder *b, struct nir_instr *instr)
|
|||
* to compensate by inverting "z_d' = -z_d" with this lowering pass.
|
||||
*/
|
||||
void
|
||||
d3d12_nir_invert_depth(nir_shader *shader)
|
||||
d3d12_nir_invert_depth(nir_shader *shader, unsigned viewport_mask)
|
||||
{
|
||||
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 };
|
||||
nir_foreach_function(function, shader) {
|
||||
if (function->impl) {
|
||||
nir_builder b;
|
||||
|
|
@ -434,10 +475,15 @@ d3d12_nir_invert_depth(nir_shader *shader)
|
|||
|
||||
nir_foreach_block(block, function->impl) {
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
invert_depth(&b, instr);
|
||||
invert_depth_instr(&b, instr, &state);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.store_pos_instr) {
|
||||
b.cursor = nir_after_block(function->impl->end_block);
|
||||
invert_depth_impl(&b, &state);
|
||||
}
|
||||
|
||||
nir_metadata_preserve(function->impl, nir_metadata_block_index |
|
||||
nir_metadata_dominance);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
d3d12_nir_invert_depth(nir_shader *s, unsigned viewport_mask);
|
||||
|
||||
bool
|
||||
d3d12_lower_int_cubmap_to_array(nir_shader *s);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue