diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 464f9c3dd96..d2bc475b243 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -361,7 +361,7 @@ generate_aaline_fs_nir(struct aaline_stage *aaline) if (!aaline_fs.ir.nir) return FALSE; - nir_lower_aaline_fs(aaline_fs.ir.nir, &aaline->fs->generic_attrib); + nir_lower_aaline_fs(aaline_fs.ir.nir, &aaline->fs->generic_attrib, NULL, NULL); aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe, &aaline_fs); if (aaline->fs->aaline_fs == NULL) return FALSE; diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c index a3f4de32d9c..0ebc1ef0b69 100644 --- a/src/gallium/auxiliary/nir/nir_draw_helpers.c +++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c @@ -148,6 +148,8 @@ nir_lower_pstipple_fs(struct nir_shader *shader, typedef struct { nir_variable *line_width_input; + nir_variable *stipple_counter; + nir_variable *stipple_pattern; } lower_aaline; static bool @@ -176,8 +178,43 @@ lower_aaline_instr(nir_builder *b, nir_instr *instr, void *data) nir_ssa_def *tmp = nir_fsat(b, nir_fadd(b, nir_channels(b, lw, 0xa), nir_fneg(b, nir_fabs(b, nir_channels(b, lw, 0x5))))); + nir_ssa_def *max = len; + if (state->stipple_counter) { + assert(state->stipple_pattern); + + nir_ssa_def *counter = nir_load_var(b, state->stipple_counter); + nir_ssa_def *pattern = nir_load_var(b, state->stipple_pattern); + nir_ssa_def *factor = nir_i2f32(b, nir_ishr_imm(b, pattern, 16)); + pattern = nir_iand_imm(b, pattern, 0xffff); + + nir_ssa_def *stipple_pos = nir_vec2(b, nir_fadd_imm(b, counter, -0.5), + nir_fadd_imm(b, counter, 0.5)); + + stipple_pos = nir_frem(b, nir_fdiv(b, stipple_pos, factor), + nir_imm_float(b, 16.0)); + + nir_ssa_def *p = nir_f2i32(b, stipple_pos); + nir_ssa_def *one = nir_imm_float(b, 1.0); + + // float t = 1.0 - min((1.0 - fract(stipple_pos.x)) * factor, 1.0); + nir_ssa_def *t = nir_ffract(b, nir_channel(b, stipple_pos, 0)); + t = nir_fsub(b, one, + nir_fmin(b, nir_fmul(b, factor, + nir_fsub(b, one, t)), one)); + + // vec2 a = vec2((uvec2(pattern) >> p) & uvec2(1u)); + nir_ssa_def *a = nir_i2f32(b, + nir_iand(b, nir_ishr(b, nir_vec2(b, pattern, pattern), p), + nir_imm_ivec2(b, 1, 1))); + + // float cov = mix(a.x, a.y, t); + nir_ssa_def *cov = nir_flrp(b, nir_channel(b, a, 0), nir_channel(b, a, 1), t); + + max = nir_fmin(b, len, cov); + } + tmp = nir_fmul(b, nir_channel(b, tmp, 0), - nir_fmin(b, nir_channel(b, tmp, 1), len)); + nir_fmin(b, nir_channel(b, tmp, 1), max)); tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0), @@ -189,9 +226,14 @@ lower_aaline_instr(nir_builder *b, nir_instr *instr, void *data) } void -nir_lower_aaline_fs(struct nir_shader *shader, int *varying) +nir_lower_aaline_fs(struct nir_shader *shader, int *varying, + nir_variable *stipple_counter, + nir_variable *stipple_pattern) { - lower_aaline state; + lower_aaline state = { + .stipple_counter = stipple_counter, + .stipple_pattern = stipple_pattern, + }; assert(shader->info.stage == MESA_SHADER_FRAGMENT); int highest_location = -1, highest_drv_location = -1; diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.h b/src/gallium/auxiliary/nir/nir_draw_helpers.h index 4262c45ef42..114fc8d89b4 100644 --- a/src/gallium/auxiliary/nir/nir_draw_helpers.h +++ b/src/gallium/auxiliary/nir/nir_draw_helpers.h @@ -38,7 +38,9 @@ nir_lower_pstipple_fs(struct nir_shader *shader, bool fs_pos_is_sysval); void -nir_lower_aaline_fs(struct nir_shader *shader, int *varying); +nir_lower_aaline_fs(struct nir_shader *shader, int *varying, + nir_variable *stipple_counter, + nir_variable *stipple_pattern); void nir_lower_aapoint_fs(struct nir_shader *shader, int *varying); diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index a8691d445e5..236bb8b6ccf 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -813,7 +813,7 @@ static bool lower_line_smooth_fs(nir_shader *shader) { int dummy; - nir_lower_aaline_fs(shader, &dummy); + nir_lower_aaline_fs(shader, &dummy, NULL, NULL); return true; }