X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_lower_wpos_ytransform.c;h=62166e787461eb9ab79088ef7d9725eae145ac06;hb=6b1e26e181fbe7fd64b42a0b77f80535be4d7690;hp=41f8554424688472141161eb64744fa8a43597dc;hpb=287f099db170132518b75142de8580fd252fde45;p=mesa.git diff --git a/src/compiler/nir/nir_lower_wpos_ytransform.c b/src/compiler/nir/nir_lower_wpos_ytransform.c index 41f85544246..62166e78746 100644 --- a/src/compiler/nir/nir_lower_wpos_ytransform.c +++ b/src/compiler/nir/nir_lower_wpos_ytransform.c @@ -123,19 +123,15 @@ emit_wpos_adjustment(lower_wpos_ytransform_state *state, * inversion/identity, or the other way around if we're drawing to an FBO. */ if (invert) { - /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy - */ - wpos_temp_y = nir_ffma(b, - nir_channel(b, wpos_temp, 1), - nir_channel(b, wpostrans, 0), - nir_channel(b, wpostrans, 1)); + /* wpos_temp.y = wpos_input * wpostrans.xxxx + wpostrans.yyyy */ + wpos_temp_y = nir_fadd(b, nir_fmul(b, nir_channel(b, wpos_temp, 1), + nir_channel(b, wpostrans, 0)), + nir_channel(b, wpostrans, 1)); } else { - /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww - */ - wpos_temp_y = nir_ffma(b, - nir_channel(b, wpos_temp, 1), - nir_channel(b, wpostrans, 2), - nir_channel(b, wpostrans, 3)); + /* wpos_temp.y = wpos_input * wpostrans.zzzz + wpostrans.wwww */ + wpos_temp_y = nir_fadd(b, nir_fmul(b, nir_channel(b, wpos_temp, 1), + nir_channel(b, wpostrans, 2)), + nir_channel(b, wpostrans, 3)); } wpos_temp = nir_vec4(b, @@ -163,7 +159,7 @@ lower_fragcoord(lower_wpos_ytransform_state *state, nir_intrinsic_instr *intr) * * The bias of the y-coordinate depends on whether y-inversion takes place * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are - * drawing to an FBO (causes additional inversion), and whether the the pipe + * drawing to an FBO (causes additional inversion), and whether the pipe * driver origin and the requested origin differ (the latter condition is * stored in the 'invert' variable). * @@ -257,7 +253,46 @@ lower_fddy(lower_wpos_ytransform_state *state, nir_alu_instr *fddy) fddy->src[0].swizzle[i] = MIN2(i, pt->num_components - 1); } -static bool +/* Multiply interp_var_at_offset's offset by transform.x to flip it. */ +static void +lower_interp_var_at_offset(lower_wpos_ytransform_state *state, + nir_intrinsic_instr *interp) +{ + nir_builder *b = &state->b; + nir_ssa_def *offset; + nir_ssa_def *flip_y; + + b->cursor = nir_before_instr(&interp->instr); + + offset = nir_ssa_for_src(b, interp->src[0], 2); + flip_y = nir_fmul(b, nir_channel(b, offset, 1), + nir_channel(b, get_transform(state), 0)); + nir_instr_rewrite_src(&interp->instr, &interp->src[0], + nir_src_for_ssa(nir_vec2(b, nir_channel(b, offset, 0), + flip_y))); +} + +static void +lower_load_sample_pos(lower_wpos_ytransform_state *state, + nir_intrinsic_instr *intr) +{ + nir_builder *b = &state->b; + b->cursor = nir_after_instr(&intr->instr); + + nir_ssa_def *pos = &intr->dest.ssa; + nir_ssa_def *scale = nir_channel(b, get_transform(state), 0); + nir_ssa_def *neg_scale = nir_channel(b, get_transform(state), 2); + /* Either y or 1-y for scale equal to 1 or -1 respectively. */ + nir_ssa_def *flipped_y = + nir_fadd(b, nir_fmax(b, neg_scale, nir_imm_float(b, 0.0)), + nir_fmul(b, nir_channel(b, pos, 1), scale)); + nir_ssa_def *flipped_pos = nir_vec2(b, nir_channel(b, pos, 0), flipped_y); + + nir_ssa_def_rewrite_uses_after(&intr->dest.ssa, nir_src_for_ssa(flipped_pos), + flipped_pos->parent_instr); +} + +static void lower_wpos_ytransform_block(lower_wpos_ytransform_state *state, nir_block *block) { nir_foreach_instr_safe(instr, block) { @@ -267,20 +302,33 @@ lower_wpos_ytransform_block(lower_wpos_ytransform_state *state, nir_block *block nir_deref_var *dvar = intr->variables[0]; nir_variable *var = dvar->var; - if (strcmp(var->name, "gl_FragCoord") == 0) { - /* gl_FragCoord should not have array/struct deref's: */ + if ((var->data.mode == nir_var_shader_in && + var->data.location == VARYING_SLOT_POS) || + (var->data.mode == nir_var_system_value && + var->data.location == SYSTEM_VALUE_FRAG_COORD)) { + /* gl_FragCoord should not have array/struct derefs: */ assert(dvar->deref.child == NULL); lower_fragcoord(state, intr); + } else if (var->data.mode == nir_var_system_value && + var->data.location == SYSTEM_VALUE_SAMPLE_POS) { + assert(dvar->deref.child == NULL); + lower_load_sample_pos(state, intr); } + } else if (intr->intrinsic == nir_intrinsic_load_frag_coord) { + lower_fragcoord(state, intr); + } else if (intr->intrinsic == nir_intrinsic_load_sample_pos) { + lower_load_sample_pos(state, intr); + } else if (intr->intrinsic == nir_intrinsic_interp_var_at_offset) { + lower_interp_var_at_offset(state, intr); } } else if (instr->type == nir_instr_type_alu) { nir_alu_instr *alu = nir_instr_as_alu(instr); - if (alu->op == nir_op_fddy) + if (alu->op == nir_op_fddy || + alu->op == nir_op_fddy_fine || + alu->op == nir_op_fddy_coarse) lower_fddy(state, alu); } } - - return true; } static void @@ -304,7 +352,7 @@ nir_lower_wpos_ytransform(nir_shader *shader, .shader = shader, }; - assert(shader->stage == MESA_SHADER_FRAGMENT); + assert(shader->info.stage == MESA_SHADER_FRAGMENT); nir_foreach_function(function, shader) { if (function->impl)