X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_lower_wpos_ytransform.c;h=2771f2afedef2bd0865930bc4aad16942657add9;hb=ce6f66242ad33be84c0a34519f18bdc15c195950;hp=7b20f8a3b1a8995f60e88360ba1b715bffb67128;hpb=a3589bb01f73e7b9c23ffb15ee78f21fe4c846a0;p=mesa.git diff --git a/src/compiler/nir/nir_lower_wpos_ytransform.c b/src/compiler/nir/nir_lower_wpos_ytransform.c index 7b20f8a3b1a..2771f2afede 100644 --- a/src/compiler/nir/nir_lower_wpos_ytransform.c +++ b/src/compiler/nir/nir_lower_wpos_ytransform.c @@ -61,7 +61,7 @@ get_transform(lower_wpos_ytransform_state *state) var->state_slots[0].swizzle = SWIZZLE_XYZW; memcpy(var->state_slots[0].tokens, state->options->state_tokens, sizeof(var->state_slots[0].tokens)); - + var->data.how_declared = nir_var_hidden; state->transform = var; } return nir_load_var(&state->b, state->transform); @@ -77,18 +77,18 @@ nir_cmp(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1, nir_ssa_def *src2) /* see emit_wpos_adjustment() in st_mesa_to_tgsi.c */ static void emit_wpos_adjustment(lower_wpos_ytransform_state *state, - nir_intrinsic_instr *intr, nir_variable *fragcoord, - bool invert, float adjX, float adjY[2]) + nir_intrinsic_instr *intr, bool invert, + float adjX, float adjY[2]) { nir_builder *b = &state->b; nir_ssa_def *wpostrans, *wpos_temp, *wpos_temp_y, *wpos_input; assert(intr->dest.is_ssa); + wpos_input = &intr->dest.ssa; - b->cursor = nir_before_instr(&intr->instr); + b->cursor = nir_after_instr(&intr->instr); wpostrans = get_transform(state); - wpos_input = nir_load_var(b, fragcoord); /* First, apply the coordinate shift: */ if (adjX || adjY[0] || adjY[1]) { @@ -139,12 +139,13 @@ emit_wpos_adjustment(lower_wpos_ytransform_state *state, nir_channel(b, wpos_temp, 2), nir_channel(b, wpos_temp, 3)); - nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(wpos_temp)); + nir_ssa_def_rewrite_uses_after(&intr->dest.ssa, + nir_src_for_ssa(wpos_temp), + wpos_temp->parent_instr); } static void -lower_fragcoord(lower_wpos_ytransform_state *state, - nir_intrinsic_instr *intr, nir_variable *fragcoord) +lower_fragcoord(lower_wpos_ytransform_state *state, nir_intrinsic_instr *intr) { const nir_lower_wpos_ytransform_options *options = state->options; float adjX = 0.0f; @@ -181,7 +182,7 @@ lower_fragcoord(lower_wpos_ytransform_state *state, * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0 */ - if (fragcoord->data.origin_upper_left) { + if (state->shader->info.fs.origin_upper_left) { /* Fragment shader wants origin in upper-left */ if (options->fs_coord_origin_upper_left) { /* the driver supports upper-left origin */ @@ -203,7 +204,7 @@ lower_fragcoord(lower_wpos_ytransform_state *state, } } - if (fragcoord->data.pixel_center_integer) { + if (state->shader->info.fs.pixel_center_integer) { /* Fragment shader wants pixel center integer */ if (options->fs_coord_pixel_center_integer) { /* the driver supports pixel center integer */ @@ -228,7 +229,32 @@ lower_fragcoord(lower_wpos_ytransform_state *state, } } - emit_wpos_adjustment(state, intr, fragcoord, invert, adjX, adjY); + emit_wpos_adjustment(state, intr, invert, adjX, adjY); +} + +static void +lower_load_pointcoord(lower_wpos_ytransform_state *state, + nir_intrinsic_instr *intr) +{ + nir_builder *b = &state->b; + b->cursor = nir_after_instr(&intr->instr); + + nir_ssa_def *pntc = &intr->dest.ssa; + nir_ssa_def *transform = get_transform(state); + nir_ssa_def *y = nir_channel(b, pntc, 1); + /* The offset is 1 if we're flipping, 0 otherwise. */ + nir_ssa_def *offset = nir_fmax(b, nir_channel(b, transform, 2), + nir_imm_float(b, 0.0)); + /* Flip the sign of y if we're flipping. */ + nir_ssa_def *scaled = nir_fmul(b, y, nir_channel(b, transform, 0)); + + /* Reassemble the vector. */ + nir_ssa_def *flipped_pntc = nir_vec2(b, + nir_channel(b, pntc, 0), + nir_fadd(b, offset, scaled)); + + nir_ssa_def_rewrite_uses_after(&intr->dest.ssa, nir_src_for_ssa(flipped_pntc), + flipped_pntc->parent_instr); } /* turns 'fddy(p)' into 'fddy(fmul(p, transform.x))' */ @@ -241,8 +267,11 @@ lower_fddy(lower_wpos_ytransform_state *state, nir_alu_instr *fddy) b->cursor = nir_before_instr(&fddy->instr); p = nir_ssa_for_alu_src(b, fddy, 0); - trans = get_transform(state); - pt = nir_fmul(b, p, nir_channel(b, trans, 0)); + trans = nir_channel(b, get_transform(state), 0); + if (p->bit_size == 16) + trans = nir_f2f16(b, trans); + + pt = nir_fmul(b, p, trans); nir_instr_rewrite_src(&fddy->instr, &fddy->src[0].src, @@ -306,13 +335,17 @@ lower_wpos_ytransform_block(lower_wpos_ytransform_state *state, nir_block *block (var->data.mode == nir_var_system_value && var->data.location == SYSTEM_VALUE_FRAG_COORD)) { /* gl_FragCoord should not have array/struct derefs: */ - lower_fragcoord(state, intr, var); + lower_fragcoord(state, intr); } else if (var->data.mode == nir_var_system_value && var->data.location == SYSTEM_VALUE_SAMPLE_POS) { lower_load_sample_pos(state, intr); + } else if (var->data.mode == nir_var_shader_in && + var->data.location == VARYING_SLOT_PNTC && + state->shader->options->lower_wpos_pntc) { + lower_load_pointcoord(state, intr); } } else if (intr->intrinsic == nir_intrinsic_load_frag_coord) { - lower_fragcoord(state, intr, NULL); + 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_deref_at_offset) { @@ -349,8 +382,6 @@ nir_lower_wpos_ytransform(nir_shader *shader, .shader = shader, }; - nir_assert_unlowered_derefs(shader, nir_lower_load_store_derefs); - assert(shader->info.stage == MESA_SHADER_FRAGMENT); nir_foreach_function(function, shader) {