nir/lower_blend: Avoid useless iand with logic ops

The upper bits start correctly, there's no need to clear them as long as we keep
them zero'ed by using ixor with a valid bit mask instead of inot.

Makes the code generated for logic op slightly less ridiculous. I'm joking. It's
still ridiculous but I'm not in the mood to fix up the Midgard compiler and it's
just a little ALU for a feature almost nothing uses.

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20016>
This commit is contained in:
Alyssa Rosenzweig 2022-11-25 21:40:38 -05:00 committed by Marge Bot
parent ee127f03e4
commit dbd0615e7a

View file

@ -225,37 +225,37 @@ static nir_ssa_def *
nir_logicop_func( nir_logicop_func(
nir_builder *b, nir_builder *b,
unsigned func, unsigned func,
nir_ssa_def *src, nir_ssa_def *dst) nir_ssa_def *src, nir_ssa_def *dst, nir_ssa_def *bitmask)
{ {
switch (func) { switch (func) {
case PIPE_LOGICOP_CLEAR: case PIPE_LOGICOP_CLEAR:
return nir_imm_ivec4(b, 0, 0, 0, 0); return nir_imm_ivec4(b, 0, 0, 0, 0);
case PIPE_LOGICOP_NOR: case PIPE_LOGICOP_NOR:
return nir_inot(b, nir_ior(b, src, dst)); return nir_ixor(b, nir_ior(b, src, dst), bitmask);
case PIPE_LOGICOP_AND_INVERTED: case PIPE_LOGICOP_AND_INVERTED:
return nir_iand(b, nir_inot(b, src), dst); return nir_iand(b, nir_ixor(b, src, bitmask), dst);
case PIPE_LOGICOP_COPY_INVERTED: case PIPE_LOGICOP_COPY_INVERTED:
return nir_inot(b, src); return nir_ixor(b, src, bitmask);
case PIPE_LOGICOP_AND_REVERSE: case PIPE_LOGICOP_AND_REVERSE:
return nir_iand(b, src, nir_inot(b, dst)); return nir_iand(b, src, nir_ixor(b, dst, bitmask));
case PIPE_LOGICOP_INVERT: case PIPE_LOGICOP_INVERT:
return nir_inot(b, dst); return nir_ixor(b, dst, bitmask);
case PIPE_LOGICOP_XOR: case PIPE_LOGICOP_XOR:
return nir_ixor(b, src, dst); return nir_ixor(b, src, dst);
case PIPE_LOGICOP_NAND: case PIPE_LOGICOP_NAND:
return nir_inot(b, nir_iand(b, src, dst)); return nir_ixor(b, nir_iand(b, src, dst), bitmask);
case PIPE_LOGICOP_AND: case PIPE_LOGICOP_AND:
return nir_iand(b, src, dst); return nir_iand(b, src, dst);
case PIPE_LOGICOP_EQUIV: case PIPE_LOGICOP_EQUIV:
return nir_inot(b, nir_ixor(b, src, dst)); return nir_ixor(b, nir_ixor(b, src, dst), bitmask);
case PIPE_LOGICOP_NOOP: case PIPE_LOGICOP_NOOP:
return dst; return dst;
case PIPE_LOGICOP_OR_INVERTED: case PIPE_LOGICOP_OR_INVERTED:
return nir_ior(b, nir_inot(b, src), dst); return nir_ior(b, nir_ixor(b, src, bitmask), dst);
case PIPE_LOGICOP_COPY: case PIPE_LOGICOP_COPY:
return src; return src;
case PIPE_LOGICOP_OR_REVERSE: case PIPE_LOGICOP_OR_REVERSE:
return nir_ior(b, src, nir_inot(b, dst)); return nir_ior(b, src, nir_ixor(b, dst, bitmask));
case PIPE_LOGICOP_OR: case PIPE_LOGICOP_OR:
return nir_ior(b, src, dst); return nir_ior(b, src, dst);
case PIPE_LOGICOP_SET: case PIPE_LOGICOP_SET:
@ -300,15 +300,12 @@ nir_blend_logicop(
assert(util_format_is_pure_integer(format)); assert(util_format_is_pure_integer(format));
} }
nir_ssa_def *out = nir_logicop_func(b, options->logicop_func, src, dst); nir_const_value mask[4];
for (int i = 0; i < 4; ++i)
mask[i] = nir_const_value_for_int(BITFIELD_MASK(bits[i]), 32);
if (bits[0] < 32) { nir_ssa_def *out = nir_logicop_func(b, options->logicop_func, src, dst,
nir_const_value mask[4]; nir_build_imm(b, 4, 32, mask));
for (int i = 0; i < 4; ++i)
mask[i] = nir_const_value_for_int((1u << bits[i]) - 1, 32);
out = nir_iand(b, out, nir_build_imm(b, 4, 32, mask));
}
if (util_format_is_unorm(format)) { if (util_format_is_unorm(format)) {
out = nir_format_unorm_to_float(b, out, bits); out = nir_format_unorm_to_float(b, out, bits);