diff --git a/src/util/format/u_format.yaml b/src/util/format/u_format.yaml index de6bcd6aed0..ff0afde0fd8 100644 --- a/src/util/format/u_format.yaml +++ b/src/util/format/u_format.yaml @@ -2192,6 +2192,15 @@ channels: [UN8] swizzles: [X, 0, 0, 1] +# 10-bit channels stored in 16-bit containers (upper 10 bits used, +# lower 6 bits are padding). +- name: X6R10X6G10X6B10X6A10_UNORM + layout: other + colorspace: RGB + block: {width: 1, height: 1, depth: 1} + channels: [UN16, UN16, UN16, UN16] + swizzles: [X, Y, Z, W] + # Formats for plane 0/plane 1 of P010 - name: X6R10_UNORM layout: plain diff --git a/src/util/format/u_format_other.c b/src/util/format/u_format_other.c index ce4b9d0976a..e4abaff2f56 100644 --- a/src/util/format/u_format_other.c +++ b/src/util/format/u_format_other.c @@ -352,3 +352,98 @@ util_format_r8g8bx_snorm_fetch_rgba(void *restrict in_dst, const uint8_t *restri dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ dst[3] = 1.0f; /* a */ } + +/* + * PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM + * + * 4 x 16-bit words, each with a 10-bit unorm value in the upper bits [15:6] + * and 6 padding bits in the lower bits [5:0]. + */ + +void +util_format_x6r10x6g10x6b10x6a10_unorm_unpack_rgba_float(void *restrict dst_row, + const uint8_t *restrict src_row, + unsigned width) +{ + float *dst = dst_row; + const uint16_t *src = (const uint16_t *)src_row; + for (unsigned x = 0; x < width; x += 1) { + dst[0] = (src[0] >> 6) * (1.0f / 0x3ff); /* r */ + dst[1] = (src[1] >> 6) * (1.0f / 0x3ff); /* g */ + dst[2] = (src[2] >> 6) * (1.0f / 0x3ff); /* b */ + dst[3] = (src[3] >> 6) * (1.0f / 0x3ff); /* a */ + src += 4; + dst += 4; + } +} + +void +util_format_x6r10x6g10x6b10x6a10_unorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, + const float *restrict src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + for (unsigned y = 0; y < height; y += 1) { + const float *src = src_row; + uint16_t *dst = (uint16_t *)dst_row; + for (unsigned x = 0; x < width; x += 1) { + dst[0] = (uint16_t)(CLAMP(src[0], 0.0f, 1.0f) * 0x3ff + 0.5f) << 6; /* r */ + dst[1] = (uint16_t)(CLAMP(src[1], 0.0f, 1.0f) * 0x3ff + 0.5f) << 6; /* g */ + dst[2] = (uint16_t)(CLAMP(src[2], 0.0f, 1.0f) * 0x3ff + 0.5f) << 6; /* b */ + dst[3] = (uint16_t)(CLAMP(src[3], 0.0f, 1.0f) * 0x3ff + 0.5f) << 6; /* a */ + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} + +void +util_format_x6r10x6g10x6b10x6a10_unorm_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, + UNUSED unsigned i, UNUSED unsigned j) +{ + float *dst = in_dst; + const uint16_t *s = (const uint16_t *)src; + dst[0] = (s[0] >> 6) * (1.0f / 0x3ff); /* r */ + dst[1] = (s[1] >> 6) * (1.0f / 0x3ff); /* g */ + dst[2] = (s[2] >> 6) * (1.0f / 0x3ff); /* b */ + dst[3] = (s[3] >> 6) * (1.0f / 0x3ff); /* a */ +} + +void +util_format_x6r10x6g10x6b10x6a10_unorm_unpack_rgba_8unorm(uint8_t *restrict dst_row, + const uint8_t *restrict src_row, + unsigned width) +{ + uint8_t *dst = dst_row; + const uint16_t *src = (const uint16_t *)src_row; + for (unsigned x = 0; x < width; x += 1) { + dst[0] = (uint8_t)((src[0] >> 6) * 0xff / 0x3ff); /* r */ + dst[1] = (uint8_t)((src[1] >> 6) * 0xff / 0x3ff); /* g */ + dst[2] = (uint8_t)((src[2] >> 6) * 0xff / 0x3ff); /* b */ + dst[3] = (uint8_t)((src[3] >> 6) * 0xff / 0x3ff); /* a */ + src += 4; + dst += 4; + } +} + +void +util_format_x6r10x6g10x6b10x6a10_unorm_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + for (unsigned y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint16_t *dst = (uint16_t *)dst_row; + for (unsigned x = 0; x < width; x += 1) { + dst[0] = (uint16_t)(src[0] * 0x3ff / 0xff) << 6; + dst[1] = (uint16_t)(src[1] * 0x3ff / 0xff) << 6; + dst[2] = (uint16_t)(src[2] * 0x3ff / 0xff) << 6; + dst[3] = (uint16_t)(src[3] * 0x3ff / 0xff) << 6; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} diff --git a/src/util/format/u_format_other.h b/src/util/format/u_format_other.h index 2a325fb65ef..b956c96bdae 100644 --- a/src/util/format/u_format_other.h +++ b/src/util/format/u_format_other.h @@ -108,4 +108,29 @@ util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned ds const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_x6r10x6g10x6b10x6a10_unorm_unpack_rgba_float(void *restrict dst_row, + const uint8_t *restrict src_row, + unsigned width); + +void +util_format_x6r10x6g10x6b10x6a10_unorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, + const float *restrict src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_x6r10x6g10x6b10x6a10_unorm_fetch_rgba(void *restrict dst, const uint8_t *restrict src, + unsigned i, unsigned j); + +void +util_format_x6r10x6g10x6b10x6a10_unorm_unpack_rgba_8unorm(uint8_t *restrict dst_row, + const uint8_t *restrict src_row, + unsigned width); + +void +util_format_x6r10x6g10x6b10x6a10_unorm_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height); + #endif /* U_FORMAT_OTHER_H_ */ diff --git a/src/util/format/u_format_tests.c b/src/util/format/u_format_tests.c index 652567d8680..ba677442f20 100644 --- a/src/util/format/u_format_tests.c +++ b/src/util/format/u_format_tests.c @@ -1077,6 +1077,16 @@ util_format_test_cases[] = {PIPE_FORMAT_B2G3R3_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x03), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, {PIPE_FORMAT_B2G3R3_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x1c), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, {PIPE_FORMAT_B2G3R3_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xe0), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, + + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0xffc0, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0x0000, 0xffc0, 0x0000, 0x0000), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0x0000, 0x0000, 0xffc0, 0x0000), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xffc0), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0x0040, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(1.0/1023.0, 0.0, 0.0, 0.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0x8000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(512.0/1023.0, 0.0, 0.0, 0.0)}, + {PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM, PACKED_4x16(0xffc0, 0xffc0, 0xffc0, 0xffc0), PACKED_4x16(0x0040, 0x8000, 0x5540, 0xffc0), UNPACKED_1x1(1.0/1023.0, 512.0/1023.0, 341.0/1023.0, 1.0)}, }; diff --git a/src/vulkan/util/vk_format.c b/src/vulkan/util/vk_format.c index 9093447d1fc..e453d23bc71 100644 --- a/src/vulkan/util/vk_format.c +++ b/src/vulkan/util/vk_format.c @@ -268,6 +268,8 @@ vk_format_to_pipe_format(VkFormat vkformat) return PIPE_FORMAT_X4R12_UNORM; case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: return PIPE_FORMAT_X6R10X6G10_UNORM; + case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: + return PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM; case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: return PIPE_FORMAT_X4R12X4G12_UNORM; case VK_FORMAT_G8B8G8R8_422_UNORM: @@ -464,6 +466,7 @@ static const VkFormat formats[PIPE_FORMAT_COUNT] = { [PIPE_FORMAT_X6R10_UNORM] = VK_FORMAT_R10X6_UNORM_PACK16, [PIPE_FORMAT_X4R12_UNORM] = VK_FORMAT_R12X4_UNORM_PACK16, [PIPE_FORMAT_X6R10X6G10_UNORM] = VK_FORMAT_R10X6G10X6_UNORM_2PACK16, + [PIPE_FORMAT_X6R10X6G10X6B10X6A10_UNORM] = VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, [PIPE_FORMAT_X4R12X4G12_UNORM] = VK_FORMAT_R12X4G12X4_UNORM_2PACK16, [PIPE_FORMAT_G8B8_G8R8_UNORM] = VK_FORMAT_G8B8G8R8_422_UNORM, [PIPE_FORMAT_B8G8_R8G8_UNORM] = VK_FORMAT_B8G8R8G8_422_UNORM,