From: antonino Date: Mon, 6 Feb 2023 15:16:04 +0000 (+0100) Subject: zink: fix stipple pattern in oblique lines X-Git-Tag: upstream/23.3.3~11847 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=29be4e9e9baf59e1aa5ec3b4771edfdecfe67306;p=platform%2Fupstream%2Fmesa.git zink: fix stipple pattern in oblique lines Stipple lines now appear correctly when they are oblique. Previously the number of steps of the stipple counter between two vertices was calculated as the euclidian distance between them in screen space, however the length occupied by pixel along a line is only `1` for lines that are either vertical or horizontal and will be anywhere between `1` and `sqrt(2)` for other cases. Reviewed-by: Erik Faye-Lund Part-of: --- diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index ae6aed5..d516091 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -390,6 +390,7 @@ struct lower_line_stipple_state { nir_variable *prev_pos; nir_variable *pos_counter; nir_variable *stipple_counter; + bool line_rectangular; }; static nir_ssa_def * @@ -428,7 +429,13 @@ lower_line_stipple_gs_instr(nir_builder *b, nir_instr *instr, void *data) curr = viewport_map(b, curr, vp_scale); // calculate length of line - nir_ssa_def *len = nir_fast_distance(b, prev, curr); + nir_ssa_def *len; + if (state->line_rectangular) + len = nir_fast_distance(b, prev, curr); + else { + nir_ssa_def *diff = nir_fabs(b, nir_fsub(b, prev, curr)); + len = nir_fmax(b, nir_channel(b, diff, 0), nir_channel(b, diff, 1)); + } // update stipple_counter nir_store_var(b, state->stipple_counter, nir_fadd(b, nir_load_var(b, state->stipple_counter), @@ -448,7 +455,7 @@ lower_line_stipple_gs_instr(nir_builder *b, nir_instr *instr, void *data) } static bool -lower_line_stipple_gs(nir_shader *shader) +lower_line_stipple_gs(nir_shader *shader, bool line_rectangular) { nir_builder b; struct lower_line_stipple_state state; @@ -480,6 +487,7 @@ lower_line_stipple_gs(nir_shader *shader) glsl_float_type(), "__stipple_counter"); + state.line_rectangular = line_rectangular; // initialize pos_counter and stipple_counter nir_function_impl *entry = nir_shader_get_entrypoint(shader); nir_builder_init(&b, entry); @@ -3073,7 +3081,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, case MESA_SHADER_GEOMETRY: if (zink_gs_key(key)->lower_line_stipple) { - NIR_PASS_V(nir, lower_line_stipple_gs); + NIR_PASS_V(nir, lower_line_stipple_gs, zink_gs_key(key)->line_rectangular); NIR_PASS_V(nir, nir_lower_var_copies); need_optimize = true; } diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 41ddfb5..a9c6236 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -1713,6 +1713,13 @@ zink_update_fs_key_samples(struct zink_context *ctx) } } +void zink_update_gs_key_rectangular_line(struct zink_context *ctx) +{ + bool line_rectangular = zink_get_gs_key(ctx)->line_rectangular; + if (line_rectangular != ctx->rast_state->base.line_rectangular) + zink_set_gs_key(ctx)->line_rectangular = ctx->rast_state->base.line_rectangular; +} + static void zink_bind_fs_state(struct pipe_context *pctx, void *cso) diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index 2cc917d..d608a2c 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -312,6 +312,9 @@ zink_get_tcs_key(const struct zink_context *ctx) void zink_update_fs_key_samples(struct zink_context *ctx); +void +zink_update_gs_key_rectangular_line(struct zink_context *ctx); + static inline struct zink_vs_key * zink_set_vs_key(struct zink_context *ctx) { diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h index 3bbf2be..b5929ef 100644 --- a/src/gallium/drivers/zink/zink_shader_keys.h +++ b/src/gallium/drivers/zink/zink_shader_keys.h @@ -63,6 +63,7 @@ struct zink_gs_key { bool lower_line_stipple : 1; bool lower_line_smooth : 1; bool lower_gl_point : 1; + bool line_rectangular : 1; // not hashed unsigned size; }; diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c index 4661475..3938109 100644 --- a/src/gallium/drivers/zink/zink_state.c +++ b/src/gallium/drivers/zink/zink_state.c @@ -709,6 +709,9 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso) if (ctx->rast_state->base.half_pixel_center != half_pixel_center) ctx->vp_state_changed = true; + + if (!screen->optimal_keys) + zink_update_gs_key_rectangular_line(ctx); } }