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

d3d12: Don't draw wireframe diagonals in quads and polygons

parent 4bbe0c99
......@@ -327,6 +327,14 @@ needs_point_sprite_lowering(struct d3d12_context *ctx, const struct pipe_draw_in
}
}
static bool
needs_edge_flag_fix(enum pipe_prim_type mode)
{
return (mode == PIPE_PRIM_QUADS ||
mode == PIPE_PRIM_QUAD_STRIP ||
mode == PIPE_PRIM_POLYGON);
}
static unsigned
fill_mode_lowered(struct d3d12_context *ctx, const struct pipe_draw_info *dinfo)
{
......@@ -344,7 +352,8 @@ fill_mode_lowered(struct d3d12_context *ctx, const struct pipe_draw_info *dinfo)
ctx->gfx_pipeline_state.rast->base.cull_face != PIPE_FACE_FRONT) ||
(ctx->gfx_pipeline_state.rast->base.fill_back == PIPE_POLYGON_MODE_LINE &&
ctx->gfx_pipeline_state.rast->base.cull_face == PIPE_FACE_FRONT)) &&
vs->initial->info.outputs_written & VARYING_BIT_EDGE)
(vs->initial->info.outputs_written & VARYING_BIT_EDGE ||
needs_edge_flag_fix(ctx->initial_api_prim)))
return PIPE_POLYGON_MODE_LINE;
if (ctx->gfx_pipeline_state.rast->base.fill_front == PIPE_POLYGON_MODE_POINT)
......@@ -491,6 +500,7 @@ validate_geometry_shader_variant(struct d3d12_selection_context *sel_ctx)
variant_needed = true;
} else if (sel_ctx->fill_mode_lowered != PIPE_POLYGON_MODE_FILL) {
key.fill_mode = sel_ctx->fill_mode_lowered;
key.edge_flag_fix = needs_edge_flag_fix(ctx->initial_api_prim);
fill_flat_varyings(&key, fs);
if (key.flat_varyings != 0)
key.flatshade_first = ctx->gfx_pipeline_state.rast->base.flatshade_first;
......
......@@ -139,6 +139,7 @@ struct d3d12_gs_variant_key
unsigned provoking_vertex:3;
unsigned alternate_tri:1;
unsigned fill_mode:2;
unsigned edge_flag_fix:1;
unsigned flatshade_first:1;
uint64_t flat_varyings;
struct d3d12_varying_info varyings;
......
......@@ -192,6 +192,7 @@ struct d3d12_context {
unsigned num_vbs;
float flip_y;
bool need_zero_one_depth_range;
enum pipe_prim_type initial_api_prim;
struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS];
D3D12_VIEWPORT viewports[PIPE_MAX_VIEWPORTS];
unsigned num_viewports;
......
......@@ -434,14 +434,18 @@ d3d12_draw_vbo(struct pipe_context *pctx,
!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count))
return;
ctx->initial_api_prim = dinfo->mode;
util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->gfx_pipeline_state.rast->base);
util_primconvert_draw_vbo(ctx->primconvert, dinfo);
return;
}
struct d3d12_rasterizer_state *rast = ctx->gfx_pipeline_state.rast;
if (rast->twoface_back)
if (rast->twoface_back) {
enum pipe_prim_type saved_mode = ctx->initial_api_prim;
twoface_emulation(ctx, rast, dinfo);
ctx->initial_api_prim = saved_mode;
}
if (ctx->pstipple.enabled)
ctx->shader_dirty[PIPE_SHADER_FRAGMENT] |= D3D12_SHADER_DIRTY_SAMPLER_VIEWS |
......@@ -468,6 +472,9 @@ d3d12_draw_vbo(struct pipe_context *pctx,
}
}
/* Reset to an invalid value after it's been used */
ctx->initial_api_prim = PIPE_PRIM_MAX;
/* Copy the stream output info from the current vertex/geometry shader */
if (ctx->state_dirty & D3D12_DIRTY_SHADER) {
struct d3d12_shader_selector *sel = d3d12_last_vertex_stage(ctx);
......
......@@ -203,6 +203,18 @@ d3d12_begin_emit_primitives_gs(struct emit_primitives_context *emit_ctx,
emit_ctx->loop_index_deref = nir_build_deref_var(b, loop_index_var);
nir_store_deref(b, emit_ctx->loop_index_deref, nir_imm_int(b, 0), 1);
nir_ssa_def *diagonal_vertex = NULL;
if (key->edge_flag_fix) {
nir_ssa_def *prim_id = nir_load_primitive_id(b);
nir_ssa_def *odd = nir_build_alu(b, nir_op_imod,
prim_id,
nir_imm_int(b, 2),
NULL, NULL);
diagonal_vertex = nir_bcsel(b, nir_i2b(b, odd),
nir_imm_int(b, 2),
nir_imm_int(b, 1));
}
/**
* while {
* if (loop_index >= 3)
......@@ -223,6 +235,14 @@ d3d12_begin_emit_primitives_gs(struct emit_primitives_context *emit_ctx,
emit_ctx->edgeflag_cmp = nir_feq(b, nir_channel(b, edge_flag, 0), nir_imm_float(b, 1.0));
}
if (key->edge_flag_fix) {
nir_ssa_def *is_edge = nir_ine(b, emit_ctx->loop_index, diagonal_vertex);
if (emit_ctx->edgeflag_cmp)
emit_ctx->edgeflag_cmp = nir_iand(b, emit_ctx->edgeflag_cmp, is_edge);
else
emit_ctx->edgeflag_cmp = is_edge;
}
return true;
}
......
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