diff options
author | Jason Ekstrand <[email protected]> | 2018-01-26 11:34:04 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2018-05-09 11:16:33 -0700 |
commit | 047e68389f0aa56213503e99d31d5357284acdde (patch) | |
tree | 3fe47b25e3db9ffb5176d4b7d791fc8bba15be40 /src/compiler | |
parent | a6b66a7b26ae1cc01355d3ccfaa604a5c8e1dae5 (diff) |
nir/format_convert: Add code for bitcasting vectors
This is a fairly direct port from blorp. The only real change is that
the nir_format_convert version doesn't assume that everything is a vec4.
Reviewed-by: Topi Pohjolainen <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/nir/nir_format_convert.h | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_format_convert.h b/src/compiler/nir/nir_format_convert.h index 1b34f6086d3..33d90f260cd 100644 --- a/src/compiler/nir/nir_format_convert.h +++ b/src/compiler/nir/nir_format_convert.h @@ -108,6 +108,59 @@ nir_format_pack_uint(nir_builder *b, nir_ssa_def *color, } static inline nir_ssa_def * +nir_format_bitcast_uint_vec_unmasked(nir_builder *b, nir_ssa_def *src, + unsigned src_bits, unsigned dst_bits) +{ + assert(src_bits == 8 || src_bits == 16 || src_bits == 32); + assert(dst_bits == 8 || dst_bits == 16 || dst_bits == 32); + + if (src_bits == dst_bits) + return src; + + const unsigned dst_components = + DIV_ROUND_UP(src->num_components * src_bits, dst_bits); + assert(dst_components <= 4); + + nir_ssa_def *dst_chan[4] = { }; + if (dst_bits > src_bits) { + unsigned shift = 0; + unsigned dst_idx = 0; + for (unsigned i = 0; i < src->num_components; i++) { + nir_ssa_def *shifted = nir_ishl(b, nir_channel(b, src, i), + nir_imm_int(b, shift)); + if (shift == 0) { + dst_chan[dst_idx] = shifted; + } else { + dst_chan[dst_idx] = nir_ior(b, dst_chan[dst_idx], shifted); + } + + shift += src_bits; + if (shift >= dst_bits) { + dst_idx++; + shift = 0; + } + } + } else { + nir_ssa_def *mask = nir_imm_int(b, ~0u >> (32 - dst_bits)); + + unsigned src_idx = 0; + unsigned shift = 0; + for (unsigned i = 0; i < dst_components; i++) { + dst_chan[i] = nir_iand(b, nir_ushr(b, nir_channel(b, src, src_idx), + nir_imm_int(b, shift)), + mask); + shift += dst_bits; + if (shift >= src_bits) { + src_idx++; + shift = 0; + } + } + } + + return nir_vec(b, dst_chan, dst_components); +} + +static inline nir_ssa_def * nir_format_linear_to_srgb(nir_builder *b, nir_ssa_def *c) { nir_ssa_def *linear = nir_fmul(b, c, nir_imm_float(b, 12.92f)); |