Module: Mesa Branch: main Commit: ce8ea9e602a04a665bd082f02568b1b57a461da5 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=ce8ea9e602a04a665bd082f02568b1b57a461da5
Author: Boris Brezillon <[email protected]> Date: Mon Sep 6 14:27:01 2021 +0200 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 <[email protected]> Acked-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12793> --- src/panfrost/util/pan_lower_framebuffer.c | 51 +++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/panfrost/util/pan_lower_framebuffer.c b/src/panfrost/util/pan_lower_framebuffer.c index da906c281bb..0d6107932fb 100644 --- a/src/panfrost/util/pan_lower_framebuffer.c +++ b/src/panfrost/util/pan_lower_framebuffer.c @@ -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 */ 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), - nir_imm_ivec4(b, 0, 10, 20, 30)); + v = nir_u2u32(b, v); + + /* Clamp the values */ + if (is_signed) { + 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)); + } - nir_ssa_def *p = nir_ior(b, - nir_ior(b, nir_channel(b, shift, 0), nir_channel(b, shift, 1)), - nir_ior(b, nir_channel(b, shift, 2), nir_channel(b, shift, 3))); + 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, p); + return pan_replicate_4(b, v); } 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), - nir_imm_ivec4(b, 0, 10, 20, 30)); + /* Left shift all components so the sign bit is on the MSB, and + * 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, - nir_imm_ivec4(b, 0x3ff, 0x3ff, 0x3ff, 0x3)); + if (is_signed) + 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 */ @@ -427,7 +440,10 @@ pan_unpack(nir_builder *b, switch (desc->format) { case PIPE_FORMAT_R10G10B10A2_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: return pan_unpack_r11g11b10(b, packed); default: @@ -491,7 +507,10 @@ pan_pack(nir_builder *b, return pan_pack_unorm_1010102(b, unpacked); case PIPE_FORMAT_R10G10B10A2_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: return pan_pack_r11g11b10(b, unpacked); default:
