mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 08:40:11 +01:00
zink: fix line-smooth interpolation
Extending the lines by half a pixel in each direction without doing anything about the varyings makes the varyings interpolate over a distance than intended. While this can be negligeble for long lines, it can lead to big error for short lines. Let's instead add extra geometry for each of the line-caps, so we can make sure the varyings stay constant for the whole cap, and interpolate over the intended distance instead. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19847>
This commit is contained in:
parent
80285db9ef
commit
c6cc1dc37c
1 changed files with 15 additions and 7 deletions
|
|
@ -637,23 +637,31 @@ lower_line_smooth_gs_emit_vertex(nir_builder *b,
|
|||
tangent = nir_pad_vector_imm_int(b, tangent, 0, 4);
|
||||
dir = nir_fmul_imm(b, nir_fmul(b, dir, vp_scale_rcp), 0.5);
|
||||
|
||||
nir_ssa_def *line_offets[4] = {
|
||||
nir_ssa_def *line_offets[8] = {
|
||||
nir_fadd(b, tangent, nir_fneg(b, dir)),
|
||||
nir_fadd(b, nir_fneg(b, tangent), nir_fneg(b, dir)),
|
||||
tangent,
|
||||
nir_fneg(b, tangent),
|
||||
tangent,
|
||||
nir_fneg(b, tangent),
|
||||
nir_fadd(b, tangent, dir),
|
||||
nir_fadd(b, nir_fneg(b, tangent), dir),
|
||||
};
|
||||
nir_ssa_def *line_coord =
|
||||
nir_vec4(b, half_width, half_width, half_length, half_length);
|
||||
nir_ssa_def *line_coords[4] = {
|
||||
nir_ssa_def *line_coords[8] = {
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, -1, 1)),
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, -1, 1)),
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, 0, 1)),
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, 0, 1)),
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, 0, 1)),
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, 0, 1)),
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, 1, 1)),
|
||||
nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, 1, 1)),
|
||||
};
|
||||
|
||||
/* emit first two vertices */
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
/* emit first end-cap, and start line */
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_out) {
|
||||
gl_varying_slot location = var->data.location;
|
||||
if (state->prev_varyings[location])
|
||||
|
|
@ -666,8 +674,8 @@ lower_line_smooth_gs_emit_vertex(nir_builder *b,
|
|||
nir_emit_vertex(b);
|
||||
}
|
||||
|
||||
/* emit last two vertices */
|
||||
for (int i = 2; i < 4; ++i) {
|
||||
/* finish line and emit last end-cap */
|
||||
for (int i = 4; i < 8; ++i) {
|
||||
nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_out) {
|
||||
gl_varying_slot location = var->data.location;
|
||||
if (state->varyings[location])
|
||||
|
|
@ -794,7 +802,7 @@ lower_line_smooth_gs(nir_shader *shader)
|
|||
b.cursor = nir_before_cf_list(&entry->body);
|
||||
nir_store_var(&b, state.pos_counter, nir_imm_int(&b, 0), 1);
|
||||
|
||||
shader->info.gs.vertices_out = 2 * shader->info.gs.vertices_out;
|
||||
shader->info.gs.vertices_out = 8 * shader->info.gs.vertices_out;
|
||||
shader->info.gs.output_primitive = SHADER_PRIM_TRIANGLE_STRIP;
|
||||
|
||||
return nir_shader_instructions_pass(shader, lower_line_smooth_gs_instr,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue