diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-11-02 04:34:57 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-11-02 04:34:57 +0000 |
commit | 32aeb3c41fedbbd7b11aacfec48e8f699d16bff0 (patch) | |
tree | fc5893a490729ebf6b87b83eebf5d4ebfdfccf27 /lib/mesa/src/gallium/auxiliary/nir/nir_draw_helpers.c | |
parent | 286ec9d289bada8abb84753c461cfa3432866e98 (diff) |
Import Mesa 23.1.9
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/nir/nir_draw_helpers.c')
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/nir/nir_draw_helpers.c | 223 |
1 files changed, 158 insertions, 65 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/nir/nir_draw_helpers.c b/lib/mesa/src/gallium/auxiliary/nir/nir_draw_helpers.c index daa1fcb26..ad0d6d15e 100644 --- a/lib/mesa/src/gallium/auxiliary/nir/nir_draw_helpers.c +++ b/lib/mesa/src/gallium/auxiliary/nir/nir_draw_helpers.c @@ -44,6 +44,7 @@ typedef struct { bool fs_pos_is_sysval; nir_variable *stip_tex; nir_ssa_def *fragcoord; + nir_alu_type bool_type; } lower_pstipple; static nir_ssa_def * @@ -89,7 +90,21 @@ nir_lower_pstipple_block(nir_block *block, nir_builder_instr_insert(b, &tex->instr); - nir_ssa_def *condition = nir_f2b32(b, nir_channel(b, &tex->dest.ssa, 3)); + nir_ssa_def *condition; + + switch (state->bool_type) { + case nir_type_bool1: + condition = nir_fneu(b, nir_channel(b, &tex->dest.ssa, 3), + nir_imm_floatN_t(b, 0.0, tex->dest.ssa.bit_size)); + break; + case nir_type_bool32: + condition = nir_fneu32(b, nir_channel(b, &tex->dest.ssa, 3), + nir_imm_floatN_t(b, 0.0, tex->dest.ssa.bit_size)); + break; + default: + unreachable("Invalid Boolean type."); + } + nir_discard_if(b, condition); b->shader->info.fs.uses_discard = true; } @@ -110,12 +125,18 @@ void nir_lower_pstipple_fs(struct nir_shader *shader, unsigned *samplerUnitOut, unsigned fixedUnit, - bool fs_pos_is_sysval) + bool fs_pos_is_sysval, + nir_alu_type bool_type) { lower_pstipple state = { .shader = shader, .fs_pos_is_sysval = fs_pos_is_sysval, + .bool_type = bool_type, }; + + assert(bool_type == nir_type_bool1 || + bool_type == nir_type_bool32); + if (shader->info.stage != MESA_SHADER_FRAGMENT) return; @@ -147,71 +168,94 @@ nir_lower_pstipple_fs(struct nir_shader *shader, } typedef struct { - nir_builder b; - nir_shader *shader; nir_variable *line_width_input; + nir_variable *stipple_counter; + nir_variable *stipple_pattern; } lower_aaline; -static void -nir_lower_aaline_block(nir_block *block, - lower_aaline *state) +static bool +lower_aaline_instr(nir_builder *b, nir_instr *instr, void *data) { - nir_builder *b = &state->b; - nir_foreach_instr(instr, block) { - if (instr->type != nir_instr_type_intrinsic) - continue; - - nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); - if (intrin->intrinsic != nir_intrinsic_store_deref) - continue; - - nir_variable *var = nir_intrinsic_get_var(intrin, 0); - if (var->data.mode != nir_var_shader_out) - continue; - if (var->data.location < FRAG_RESULT_DATA0 && var->data.location != FRAG_RESULT_COLOR) - continue; - - nir_ssa_def *out_input = intrin->src[1].ssa; - b->cursor = nir_before_instr(instr); - nir_ssa_def *lw = nir_load_var(b, state->line_width_input); - nir_ssa_def *tmp = nir_fsat(b, nir_fadd(b, nir_channel(b, lw, 1), - nir_fneg(b, nir_fabs(b, nir_channel(b, lw, 0))))); - nir_ssa_def *tmp1 = nir_fsat(b, nir_fadd(b, nir_channel(b, lw, 3), - nir_fneg(b, nir_fabs(b, nir_channel(b, lw, 2))))); - - tmp = nir_fmul(b, tmp, tmp1); - tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); - - nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0), - nir_channel(b, out_input, 1), - nir_channel(b, out_input, 2), - tmp); - nir_instr_rewrite_src(instr, &intrin->src[1], nir_src_for_ssa(out)); + lower_aaline *state = data; + + if (instr->type != nir_instr_type_intrinsic) + return false; + + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + if (intrin->intrinsic != nir_intrinsic_store_deref) + return false; + + nir_variable *var = nir_intrinsic_get_var(intrin, 0); + if (var->data.mode != nir_var_shader_out) + return false; + if (var->data.location < FRAG_RESULT_DATA0 && var->data.location != FRAG_RESULT_COLOR) + return false; + + nir_ssa_def *out_input = intrin->src[1].ssa; + b->cursor = nir_before_instr(instr); + nir_ssa_def *lw = nir_load_var(b, state->line_width_input); + nir_ssa_def *len = nir_channel(b, lw, 3); + len = nir_fadd_imm(b, nir_fmul_imm(b, len, 2.0), -1.0); + 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), max)); + tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); -static void -nir_lower_aaline_impl(nir_function_impl *impl, - lower_aaline *state) -{ - nir_builder *b = &state->b; - - nir_builder_init(b, impl); - - nir_foreach_block(block, impl) { - nir_lower_aaline_block(block, state); - } + nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0), + nir_channel(b, out_input, 1), + nir_channel(b, out_input, 2), + tmp); + nir_instr_rewrite_src(instr, &intrin->src[1], nir_src_for_ssa(out)); + return true; } 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 = { - .shader = shader, + .stipple_counter = stipple_counter, + .stipple_pattern = stipple_pattern, }; - if (shader->info.stage != MESA_SHADER_FRAGMENT) - return; + assert(shader->info.stage == MESA_SHADER_FRAGMENT); int highest_location = -1, highest_drv_location = -1; nir_foreach_shader_in_variable(var, shader) { @@ -234,11 +278,8 @@ nir_lower_aaline_fs(struct nir_shader *shader, int *varying) *varying = tgsi_get_generic_gl_varying_index(line_width->data.location, true); state.line_width_input = line_width; - nir_foreach_function(function, shader) { - if (function->impl) { - nir_lower_aaline_impl(function->impl, &state); - } - } + nir_shader_instructions_pass(shader, lower_aaline_instr, + nir_metadata_dominance, &state); } typedef struct { @@ -280,8 +321,8 @@ nir_lower_aapoint_block(nir_block *block, } static void -nir_lower_aapoint_impl(nir_function_impl *impl, - lower_aapoint *state) +nir_lower_aapoint_impl(nir_function_impl *impl, lower_aapoint *state, + nir_alu_type bool_type) { nir_builder *b = &state->b; @@ -297,7 +338,21 @@ nir_lower_aapoint_impl(nir_function_impl *impl, nir_ssa_def *k = nir_channel(b, aainput, 2); nir_ssa_def *chan_val_one = nir_channel(b, aainput, 3); - nir_ssa_def *comp = nir_flt32(b, chan_val_one, dist); + nir_ssa_def *comp; + + switch (bool_type) { + case nir_type_bool1: + comp = nir_flt(b, chan_val_one, dist); + break; + case nir_type_bool32: + comp = nir_flt32(b, chan_val_one, dist); + break; + case nir_type_float32: + comp = nir_slt(b, chan_val_one, dist); + break; + default: + unreachable("Invalid Boolean type."); + } nir_discard_if(b, comp); b->shader->info.fs.uses_discard = true; @@ -319,7 +374,41 @@ nir_lower_aapoint_impl(nir_function_impl *impl, * else * sel = 1.0; */ - nir_ssa_def *sel = nir_b32csel(b, nir_fge32(b, k, dist), coverage, chan_val_one); + nir_ssa_def *sel; + + switch (bool_type) { + case nir_type_bool1: + sel = nir_b32csel(b, nir_fge(b, k, dist), coverage, chan_val_one); + break; + case nir_type_bool32: + sel = nir_b32csel(b, nir_fge32(b, k, dist), coverage, chan_val_one); + break; + case nir_type_float32: { + /* On this path, don't assume that any "fancy" instructions are + * supported, but also try to emit something decent. + * + * sel = (k >= distance) ? coverage : 1.0; + * sel = (k >= distance) * coverage : (1 - (k >= distance)) * 1.0 + * sel = (k >= distance) * coverage : (1 - (k >= distance)) + * + * Since (k >= distance) * coverage is zero when (1 - (k >= distance)) + * is not zero, + * + * sel = (k >= distance) * coverage + (1 - (k >= distance)) + * + * If we assume that coverage == fsat(coverage), this could be further + * optimized to fsat(coverage + (1 - (k >= distance))), but I don't feel + * like verifying that right now. + */ + nir_ssa_def *cmp_result = nir_sge(b, k, dist); + sel = nir_fadd(b, + nir_fmul(b, coverage, cmp_result), + nir_fadd(b, chan_val_one, nir_fneg(b, cmp_result))); + break; + } + default: + unreachable("Invalid Boolean type."); + } nir_foreach_block(block, impl) { nir_lower_aapoint_block(block, state, sel); @@ -327,8 +416,12 @@ nir_lower_aapoint_impl(nir_function_impl *impl, } void -nir_lower_aapoint_fs(struct nir_shader *shader, int *varying) +nir_lower_aapoint_fs(struct nir_shader *shader, int *varying, const nir_alu_type bool_type) { + assert(bool_type == nir_type_bool1 || + bool_type == nir_type_bool32 || + bool_type == nir_type_float32); + lower_aapoint state = { .shader = shader, }; @@ -358,7 +451,7 @@ nir_lower_aapoint_fs(struct nir_shader *shader, int *varying) nir_foreach_function(function, shader) { if (function->impl) { - nir_lower_aapoint_impl(function->impl, &state); + nir_lower_aapoint_impl(function->impl, &state, bool_type); } } } |