diff options
author | Rob Clark <[email protected]> | 2015-11-05 10:23:48 -0500 |
---|---|---|
committer | Rob Clark <[email protected]> | 2015-11-19 20:03:32 -0500 |
commit | acca6c65d3c793885b343aad17cbdbad7fbe1830 (patch) | |
tree | 4b35da101381c06989822b71e062f2ffe2fe5a44 /src | |
parent | c73f40c4731235153e29222eee8e12241166094a (diff) |
nir: add nir_ssa_for_alu_src()
Using something like:
numer = nir_ssa_for_src(bld, alu->src[0].src,
nir_ssa_alu_instr_src_components(alu, 0));
for alu src's with swizzle, like:
vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
vec2 ssa_2 = udiv ssa_10.xx, ssa_11
ends up turning into something like:
vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
vec2 ssa_13 = imov ssa_10
...
because nir_ssa_for_src() ignore's the original nir_alu_src's swizzle.
Instead for alu instructions, nir_src_for_alu_src() should be used to
ensure the original alu src's swizzle doesn't get lost in translation:
vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
vec2 ssa_13 = imov ssa_10.xx
...
v2: check for abs/neg, and re-use existing nir_alu_src
Signed-off-by: Rob Clark <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/nir/nir_builder.h | 21 | ||||
-rw-r--r-- | src/glsl/nir/nir_lower_idiv.c | 6 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/glsl/nir/nir_builder.h b/src/glsl/nir/nir_builder.h index 624329d0a8a..d09f929405b 100644 --- a/src/glsl/nir/nir_builder.h +++ b/src/glsl/nir/nir_builder.h @@ -259,6 +259,8 @@ nir_channel(nir_builder *b, nir_ssa_def *def, unsigned c) /** * Turns a nir_src into a nir_ssa_def * so it can be passed to * nir_build_alu()-based builder calls. + * + * See nir_ssa_for_alu_src() for alu instructions. */ static inline nir_ssa_def * nir_ssa_for_src(nir_builder *build, nir_src src, int num_components) @@ -274,6 +276,25 @@ nir_ssa_for_src(nir_builder *build, nir_src src, int num_components) return nir_imov_alu(build, alu, num_components); } +/** + * Similar to nir_ssa_for_src(), but for alu src's, respecting the + * nir_alu_src's swizzle. + */ +static inline nir_ssa_def * +nir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn) +{ + static uint8_t trivial_swizzle[4] = { 0, 1, 2, 3 }; + nir_alu_src *src = &instr->src[srcn]; + unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn); + + if (src->src.is_ssa && (src->src.ssa->num_components == num_components) && + !src->abs && !src->negate && + (memcmp(src->swizzle, trivial_swizzle, num_components) == 0)) + return src->src.ssa; + + return nir_imov_alu(build, *src, num_components); +} + static inline nir_ssa_def * nir_load_var(nir_builder *build, nir_variable *var) { diff --git a/src/glsl/nir/nir_lower_idiv.c b/src/glsl/nir/nir_lower_idiv.c index 3580ced0ac0..f64b3eac8a0 100644 --- a/src/glsl/nir/nir_lower_idiv.c +++ b/src/glsl/nir/nir_lower_idiv.c @@ -52,10 +52,8 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu) bld->cursor = nir_before_instr(&alu->instr); - numer = nir_ssa_for_src(bld, alu->src[0].src, - nir_ssa_alu_instr_src_components(alu, 0)); - denom = nir_ssa_for_src(bld, alu->src[1].src, - nir_ssa_alu_instr_src_components(alu, 1)); + numer = nir_ssa_for_alu_src(bld, alu, 0); + denom = nir_ssa_for_alu_src(bld, alu, 1); if (is_signed) { af = nir_i2f(bld, numer); |