Argh, nevermind, I was reading it wrong... On Thu, Jan 22, 2015 at 8:18 PM, Connor Abbott <cwabbo...@gmail.com> wrote: > What happens if you have something like foo = vec3(foo.z, bar.x, > foo.x)? I don't think emitting vector mov's for only the contiguous > components is enough. > > On Thu, Jan 22, 2015 at 4:51 PM, Eric Anholt <e...@anholt.net> wrote: >> It now emits vector MOVs instead of a series of individual MOVs, which >> should be useful to any vector backends. This pushes the problem of >> src/dest aliasing of channels on a scalar chip to the backend, but if >> there are any vector operations in your shader then you needed to be >> handling this already. >> >> Fixes fs-swap-problem with my scalarizing patches. >> --- >> src/glsl/nir/nir_lower_vec_to_movs.c | 74 >> +++++++++++++++++++++++++++++++----- >> 1 file changed, 64 insertions(+), 10 deletions(-) >> >> diff --git a/src/glsl/nir/nir_lower_vec_to_movs.c >> b/src/glsl/nir/nir_lower_vec_to_movs.c >> index 022889e..489901e 100644 >> --- a/src/glsl/nir/nir_lower_vec_to_movs.c >> +++ b/src/glsl/nir/nir_lower_vec_to_movs.c >> @@ -33,6 +33,49 @@ >> */ >> >> static bool >> +src_matches_dest_reg(nir_dest *dest, nir_src *src) >> +{ >> + if (dest->is_ssa || src->is_ssa) >> + return false; >> + >> + return (dest->reg.reg == src->reg.reg && >> + dest->reg.base_offset == src->reg.base_offset && >> + !dest->reg.indirect && >> + !src->reg.indirect); >> +} >> + >> +static unsigned >> +insert_movs(nir_alu_instr *vec, unsigned start_channel, >> + unsigned start_src_idx, void *mem_ctx)
We need a comment explaining what this function does and what it returns. Also, it only creates a single move so it should be called insert_mov(). >> +{ >> + unsigned src_idx = start_src_idx; >> + assert(src_idx < nir_op_infos[vec->op].num_inputs); >> + >> + nir_alu_instr *mov = nir_alu_instr_create(mem_ctx, nir_op_imov); >> + nir_alu_src_copy(&mov->src[0], &vec->src[src_idx], mem_ctx); >> + nir_alu_dest_copy(&mov->dest, &vec->dest, mem_ctx); >> + >> + mov->dest.write_mask = (1u << start_channel); >> + mov->src[0].swizzle[start_channel] = vec->src[src_idx].swizzle[0]; >> + src_idx++; >> + >> + for (unsigned i = start_channel + 1; i < 4; i++) { >> + if (!(vec->dest.write_mask & (1 << i))) >> + continue; >> + >> + if (nir_srcs_equal(vec->src[src_idx].src, >> vec->src[start_src_idx].src)) { >> + mov->dest.write_mask |= (1 << i); >> + mov->src[0].swizzle[i] = vec->src[src_idx].swizzle[0]; >> + } >> + src_idx++; >> + } >> + >> + nir_instr_insert_before(&vec->instr, &mov->instr); >> + >> + return mov->dest.write_mask; >> +} >> + >> +static bool >> lower_vec_to_movs_block(nir_block *block, void *mem_ctx) >> { >> nir_foreach_instr_safe(block, instr) { >> @@ -50,22 +93,33 @@ lower_vec_to_movs_block(nir_block *block, void *mem_ctx) >> continue; /* The loop */ >> } >> >> + /* Since we insert multiple MOVs, we have to be non-SSA. */ >> + assert(!vec->dest.dest.is_ssa); >> + >> + unsigned finished_write_mask = 0; >> + >> + /* First, emit a MOV for all the src channels that are in the >> + * destination reg, in case other values we're populating in the dest >> + * might overwrite them. >> + */ >> for (unsigned i = 0, src_idx = 0; i < 4; i++) { >> if (!(vec->dest.write_mask & (1 << i))) >> continue; >> >> - assert(src_idx < nir_op_infos[vec->op].num_inputs); >> - >> - nir_alu_instr *mov = nir_alu_instr_create(mem_ctx, nir_op_imov); >> - nir_alu_src_copy(&mov->src[0], &vec->src[src_idx], mem_ctx); >> - >> - /* We only care about the one swizzle */ >> - mov->src[0].swizzle[i] = vec->src[src_idx].swizzle[0]; >> + if (src_matches_dest_reg(&vec->dest.dest, &vec->src[src_idx].src)) >> { >> + finished_write_mask |= insert_movs(vec, i, src_idx, mem_ctx); >> + break; >> + } >> + src_idx++; >> + } >> >> - nir_alu_dest_copy(&mov->dest, &vec->dest, mem_ctx); >> - mov->dest.write_mask = (1u << i); >> + /* Now, emit MOVs for all the other src channels. */ >> + for (unsigned i = 0, src_idx = 0; i < 4; i++) { >> + if (!(vec->dest.write_mask & (1 << i))) >> + continue; >> >> - nir_instr_insert_before(&vec->instr, &mov->instr); >> + if (!(finished_write_mask & (1 << i))) >> + finished_write_mask |= insert_movs(vec, i, src_idx, mem_ctx); >> >> src_idx++; >> } >> -- >> 2.1.3 >> >> _______________________________________________ >> mesa-dev mailing list >> mesa-dev@lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev