Commit 8f327d7c authored by Louis-Francis Ratté-Boulianne's avatar Louis-Francis Ratté-Boulianne Committed by Erik Faye-Lund
Browse files

d3d12: Fix gl_FrontFacing value when lowering polygon mode

parent 950b4a2e
......@@ -514,7 +514,8 @@ validate_geometry_shader_variant(struct d3d12_selection_context *sel_ctx)
} else if (sel_ctx->fill_mode_lowered != PIPE_POLYGON_MODE_FILL) {
key.fill_mode = sel_ctx->fill_mode_lowered;
key.cull_mode = sel_ctx->cull_mode_lowered;
if (key.cull_mode != PIPE_FACE_NONE)
key.has_front_face = (fs->initial->info.inputs_read & VARYING_BIT_FACE) ? 1 : 0;
if (key.cull_mode != PIPE_FACE_NONE || key.has_front_face)
key.front_ccw = ctx->gfx_pipeline_state.rast->base.front_ccw ^ (ctx->flip_y < 0);
key.edge_flag_fix = needs_edge_flag_fix(ctx->initial_api_prim);
fill_flat_varyings(&key, fs);
......@@ -725,6 +726,13 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
sel_ctx->ctx->gfx_pipeline_state.ves->num_elements * sizeof(enum pipe_format));
}
}
if (stage == PIPE_SHADER_FRAGMENT &&
sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY] &&
sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->is_gs_variant &&
sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->gs_key.has_front_face) {
key->fs.remap_front_facing = 1;
}
}
static void
......@@ -781,6 +789,16 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele
nir_shader_gather_info(new_nir_variant, impl);
}
if (key.fs.remap_front_facing) {
nir_foreach_variable(input, &new_nir_variant->inputs) {
if (input->data.location == VARYING_SLOT_FACE)
input->data.location = VARYING_SLOT_VAR12;
}
nir_function_impl *impl = nir_shader_get_entrypoint(new_nir_variant);
nir_shader_gather_info(new_nir_variant, impl);
}
if (key.fs.missing_dual_src_outputs) {
NIR_PASS_V(new_nir_variant, d3d12_add_missing_dual_src_target,
key.fs.missing_dual_src_outputs);
......
......@@ -92,6 +92,7 @@ struct d3d12_shader_key {
unsigned provoking_vertex : 2;
unsigned manual_depth_range : 1;
unsigned polygon_stipple : 1;
unsigned remap_front_facing : 1;
} fs;
int n_texture_states;
......@@ -140,6 +141,7 @@ struct d3d12_gs_variant_key
unsigned alternate_tri:1;
unsigned fill_mode:2;
unsigned cull_mode:2;
unsigned has_front_face:1;
unsigned front_ccw:1;
unsigned edge_flag_fix:1;
unsigned flatshade_first:1;
......
......@@ -149,11 +149,13 @@ struct emit_primitives_context
unsigned num_vars;
nir_variable *in[MAX_VARYING];
nir_variable *out[MAX_VARYING];
nir_variable *front_facing_var;
nir_loop *loop;
nir_deref_instr *loop_index_deref;
nir_ssa_def *loop_index;
nir_ssa_def *edgeflag_cmp;
nir_ssa_def *front_facing;
};
static bool
......@@ -219,6 +221,16 @@ d3d12_begin_emit_primitives_gs(struct emit_primitives_context *emit_ctx,
emit_ctx->num_vars++;
}
if (key->has_front_face) {
emit_ctx->front_facing_var = nir_variable_create(nir,
nir_var_shader_out,
glsl_uint_type(),
"gl_FrontFacing");
emit_ctx->front_facing_var->data.location = VARYING_SLOT_VAR12;
emit_ctx->front_facing_var->data.driver_location = emit_ctx->num_vars;
emit_ctx->front_facing_var->data.interpolation = INTERP_MODE_FLAT;
}
/* Temporary variable "loop_index" to loop over input vertices */
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
nir_variable *loop_index_var =
......@@ -238,11 +250,19 @@ d3d12_begin_emit_primitives_gs(struct emit_primitives_context *emit_ctx,
nir_imm_int(b, 1));
}
if (key->cull_mode != PIPE_FACE_NONE) {
if (key->cull_mode != PIPE_FACE_NONE || key->has_front_face) {
if (key->cull_mode == PIPE_FACE_BACK)
emit_ctx->edgeflag_cmp = nir_cull_face(b, pos_var, key->front_ccw);
else if (key->cull_mode == PIPE_FACE_FRONT)
emit_ctx->edgeflag_cmp = nir_cull_face(b, pos_var, !key->front_ccw);
if (key->has_front_face) {
if (key->cull_mode == PIPE_FACE_BACK)
emit_ctx->front_facing = emit_ctx->edgeflag_cmp;
else
emit_ctx->front_facing = nir_cull_face(b, pos_var, key->front_ccw);
emit_ctx->front_facing = nir_i2i32(b, emit_ctx->front_facing);
}
}
/**
......@@ -343,6 +363,8 @@ d3d12_emit_points(struct d3d12_context *ctx, struct d3d12_gs_variant_key *key)
nir_copy_deref(b, nir_build_deref_var(b, emit_ctx.out[i]), in_value);
}
}
if (key->has_front_face)
nir_store_var(b, emit_ctx.front_facing_var, emit_ctx.front_facing, 0x1);
nir_emit_vertex(b, 0);
return d3d12_finish_emit_primitives_gs(&emit_ctx, false);
......@@ -365,6 +387,8 @@ d3d12_emit_lines(struct d3d12_context *ctx, struct d3d12_gs_variant_key *key)
nir_deref_instr *in_value = nir_build_deref_array(b, nir_build_deref_var(b, emit_ctx.in[i]), index);
nir_copy_deref(b, nir_build_deref_var(b, emit_ctx.out[i]), in_value);
}
if (key->has_front_face)
nir_store_var(b, emit_ctx.front_facing_var, emit_ctx.front_facing, 0x1);
nir_emit_vertex(b, 0);
/* Second vertex. If not an edge, use same position as first vertex */
......@@ -377,6 +401,8 @@ d3d12_emit_lines(struct d3d12_context *ctx, struct d3d12_gs_variant_key *key)
nir_copy_deref(b, nir_build_deref_var(b, emit_ctx.out[i]),
nir_build_deref_array(b, nir_build_deref_var(b, emit_ctx.in[i]), index));
}
if (key->has_front_face)
nir_store_var(b, emit_ctx.front_facing_var, emit_ctx.front_facing, 0x1);
nir_emit_vertex(b, 0);
nir_end_primitve(b, 0);
......
......@@ -495,6 +495,8 @@ get_input_signature(struct dxil_module *mod, nir_shader *s)
static const char *out_sysvalue_name(nir_variable *var)
{
switch (var->data.location) {
case VARYING_SLOT_FACE:
return "FACE";
case VARYING_SLOT_POS:
return "POS";
case VARYING_SLOT_CLIP_DIST0:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment