pan/lower_fb: Add support for rgb10a2 _SINT variants

It's just a matter of taking the sign bit into account in the
pack/unpack routines.

Needed for panvk rgb10a2_sint blits.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12793>
This commit is contained in:
Boris Brezillon 2021-09-06 14:27:01 +02:00 committed by Marge Bot
parent 15f6cd7f72
commit ce8ea9e602
1 changed files with 35 additions and 16 deletions

View File

@ -325,30 +325,43 @@ pan_pack_unorm_1010102(nir_builder *b, nir_ssa_def *v)
/* On the other hand, the pure int RGB10_A2 is identical to the spec */ /* On the other hand, the pure int RGB10_A2 is identical to the spec */
static nir_ssa_def * static nir_ssa_def *
pan_pack_uint_1010102(nir_builder *b, nir_ssa_def *v) pan_pack_int_1010102(nir_builder *b, nir_ssa_def *v, bool is_signed)
{ {
nir_ssa_def *shift = nir_ishl(b, nir_u2u32(b, v), v = nir_u2u32(b, v);
nir_imm_ivec4(b, 0, 10, 20, 30));
nir_ssa_def *p = nir_ior(b, /* Clamp the values */
nir_ior(b, nir_channel(b, shift, 0), nir_channel(b, shift, 1)), if (is_signed) {
nir_ior(b, nir_channel(b, shift, 2), nir_channel(b, shift, 3))); v = nir_imin(b, v, nir_imm_ivec4(b, 511, 511, 511, 1));
v = nir_imax(b, v, nir_imm_ivec4(b, -512, -512, -512, -2));
} else {
v = nir_umin(b, v, nir_imm_ivec4(b, 1023, 1023, 1023, 3));
}
return pan_replicate_4(b, p); v = nir_ishl(b, v, nir_imm_ivec4(b, 0, 10, 20, 30));
v = nir_ior(b,
nir_ior(b, nir_channel(b, v, 0), nir_channel(b, v, 1)),
nir_ior(b, nir_channel(b, v, 2), nir_channel(b, v, 3)));
return pan_replicate_4(b, v);
} }
static nir_ssa_def * static nir_ssa_def *
pan_unpack_uint_1010102(nir_builder *b, nir_ssa_def *packed) pan_unpack_int_1010102(nir_builder *b, nir_ssa_def *packed, bool is_signed)
{ {
nir_ssa_def *chan = nir_channel(b, packed, 0); nir_ssa_def *v = pan_replicate_4(b, nir_channel(b, packed, 0));
nir_ssa_def *shift = nir_ushr(b, pan_replicate_4(b, chan), /* Left shift all components so the sign bit is on the MSB, and
nir_imm_ivec4(b, 0, 10, 20, 30)); * can be extended by ishr(). The ishl()+[u,i]shr() combination
* sets all unused bits to 0 without requiring a mask.
*/
v = nir_ishl(b, v, nir_imm_ivec4(b, 22, 12, 2, 0));
nir_ssa_def *mask = nir_iand(b, shift, if (is_signed)
nir_imm_ivec4(b, 0x3ff, 0x3ff, 0x3ff, 0x3)); v = nir_ishr(b, v, nir_imm_ivec4(b, 22, 22, 22, 30));
else
v = nir_ushr(b, v, nir_imm_ivec4(b, 22, 22, 22, 30));
return nir_i2i16(b, mask); return nir_i2i16(b, v);
} }
/* NIR means we can *finally* catch a break */ /* NIR means we can *finally* catch a break */
@ -427,7 +440,10 @@ pan_unpack(nir_builder *b,
switch (desc->format) { switch (desc->format) {
case PIPE_FORMAT_R10G10B10A2_UINT: case PIPE_FORMAT_R10G10B10A2_UINT:
case PIPE_FORMAT_B10G10R10A2_UINT: case PIPE_FORMAT_B10G10R10A2_UINT:
return pan_unpack_uint_1010102(b, packed); return pan_unpack_int_1010102(b, packed, false);
case PIPE_FORMAT_R10G10B10A2_SINT:
case PIPE_FORMAT_B10G10R10A2_SINT:
return pan_unpack_int_1010102(b, packed, true);
case PIPE_FORMAT_R11G11B10_FLOAT: case PIPE_FORMAT_R11G11B10_FLOAT:
return pan_unpack_r11g11b10(b, packed); return pan_unpack_r11g11b10(b, packed);
default: default:
@ -491,7 +507,10 @@ pan_pack(nir_builder *b,
return pan_pack_unorm_1010102(b, unpacked); return pan_pack_unorm_1010102(b, unpacked);
case PIPE_FORMAT_R10G10B10A2_UINT: case PIPE_FORMAT_R10G10B10A2_UINT:
case PIPE_FORMAT_B10G10R10A2_UINT: case PIPE_FORMAT_B10G10R10A2_UINT:
return pan_pack_uint_1010102(b, unpacked); return pan_pack_int_1010102(b, unpacked, false);
case PIPE_FORMAT_R10G10B10A2_SINT:
case PIPE_FORMAT_B10G10R10A2_SINT:
return pan_pack_int_1010102(b, unpacked, true);
case PIPE_FORMAT_R11G11B10_FLOAT: case PIPE_FORMAT_R11G11B10_FLOAT:
return pan_pack_r11g11b10(b, unpacked); return pan_pack_r11g11b10(b, unpacked);
default: default: