From d89aea73e2ff9c28516ada9a31fed4ba5fb42c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Fri, 17 Feb 2023 20:14:00 +0100 Subject: [PATCH] util: Add util_format_get_array. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a poor man's version of MESA_ARRAY_FORMAT. Implemented based on a gigantic switch-case with some help from the C preprocessor. Thank you, preprocessor! Signed-off-by: Timur Kristóf Reviewed-by: Faith Ekstrand Part-of: --- src/util/format/u_format.c | 67 ++++++++++++++++++++++++++++++++++++++ src/util/format/u_format.h | 6 ++++ 2 files changed, 73 insertions(+) diff --git a/src/util/format/u_format.c b/src/util/format/u_format.c index a1edafe2d10..bfbefc6176d 100644 --- a/src/util/format/u_format.c +++ b/src/util/format/u_format.c @@ -1367,3 +1367,70 @@ util_format_rgbx_to_rgba(enum pipe_format format) } } } + +enum pipe_format +util_format_get_array(const enum util_format_type type, const unsigned bits, + const unsigned nr_components, const bool normalized, + const bool pure_integer) +{ +#define CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS, NR_VAR) \ + case BITS: \ + switch (NR_VAR) { \ + case 1: \ + return PIPE_FORMAT_R##BITS##_##TYPE; \ + case 2: \ + return PIPE_FORMAT_R##BITS##G##BITS##_##TYPE; \ + case 3: \ + return PIPE_FORMAT_R##BITS##G##BITS##B##BITS##_##TYPE; \ + case 4: \ + return PIPE_FORMAT_R##BITS##G##BITS##B##BITS##A##BITS##_##TYPE; \ + default: \ + return PIPE_FORMAT_NONE; \ + } + +#define SWITCH_BY_BITS_CASEX3(TYPE, BITS_VAR, BITS1, BITS2, BITS3, NR_VAR) \ + switch (BITS_VAR) { \ + CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS1, NR_VAR) \ + CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS2, NR_VAR) \ + CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS3, NR_VAR) \ + default: \ + return PIPE_FORMAT_NONE; \ + } + +#define SWITCH_BY_BITS_CASEX4(TYPE, BITS_VAR, BITS1, BITS2, BITS3, BITS4, NR_VAR) \ + switch (BITS_VAR) { \ + CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS1, NR_VAR) \ + CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS2, NR_VAR) \ + CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS3, NR_VAR) \ + CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS4, NR_VAR) \ + default: \ + return PIPE_FORMAT_NONE; \ + } + + switch (type) { + case UTIL_FORMAT_TYPE_UNSIGNED: + if (normalized) + SWITCH_BY_BITS_CASEX3(UNORM, bits, 8, 16, 32, nr_components) + else if (!pure_integer) + SWITCH_BY_BITS_CASEX3(USCALED, bits, 8, 16, 32, nr_components) + else + SWITCH_BY_BITS_CASEX4(UINT, bits, 8, 16, 32, 64, nr_components) + case UTIL_FORMAT_TYPE_SIGNED: + if (normalized) + SWITCH_BY_BITS_CASEX3(SNORM, bits, 8, 16, 32, nr_components) + else if (!pure_integer) + SWITCH_BY_BITS_CASEX3(SSCALED, bits, 8, 16, 32, nr_components) + else + SWITCH_BY_BITS_CASEX4(SINT, bits, 8, 16, 32, 64, nr_components) + case UTIL_FORMAT_TYPE_FLOAT: + SWITCH_BY_BITS_CASEX3(FLOAT, bits, 16, 32, 64, nr_components) + default: + return PIPE_FORMAT_NONE; + } + +#undef CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4 +#undef SWITCH_BY_BITS_CASEX3 +#undef SWITCH_BY_BITS_CASEX4 + + return PIPE_FORMAT_NONE; +} diff --git a/src/util/format/u_format.h b/src/util/format/u_format.h index 035a7e0bba8..439c3ceb0cc 100644 --- a/src/util/format/u_format.h +++ b/src/util/format/u_format.h @@ -1706,6 +1706,12 @@ util_format_snorm_to_unorm(enum pipe_format format); enum pipe_format util_format_rgbx_to_rgba(enum pipe_format format); +/* Returns the pipe format for the given array type, bitsize and component count. */ +enum pipe_format +util_format_get_array(const enum util_format_type type, const unsigned bits, + const unsigned nr_components, const bool normalized, + const bool pure_integer); + #ifdef __cplusplus } // extern "C" { #endif