This commits adds the _mesa_format_to_arary function that determines if the given format can be represented as an array format and computes the array format parameters. This is a direct helper function for using _mesa_swizzle_and_convert
v2: Better documentation and commit message Signed-off-by: Jason Ekstrand <jason.ekstr...@intel.com> --- src/mesa/main/format_utils.c | 105 +++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/format_utils.h | 4 ++ 2 files changed, 109 insertions(+) diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c index d60aeb3..95b4612 100644 --- a/src/mesa/main/format_utils.c +++ b/src/mesa/main/format_utils.c @@ -55,6 +55,111 @@ _mesa_srgb_ubyte_to_linear_float(uint8_t cl) return lut[cl]; } +static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 }; +static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 }; +static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 }; + +/** + * Describes a format as an array format, if possible + * + * A helper function for figuring out if a (possibly packed) format is + * actually an array format and, if so, what the array parameters are. + * + * \param[in] format the mesa format + * \param[out] type the GL type of the array (GL_BYTE, etc.) + * \param[out] num_components the number of components in the array + * \param[out] swizzle a swizzle describing how to get from the + * given format to RGBA + * \param[out] normalized for integer formats, this represents whether + * the format is a normalized integer or a + * regular integer + * \return true if this format is an array format, false otherwise + */ +bool +_mesa_format_to_array(mesa_format format, GLenum *type, int *num_components, + uint8_t swizzle[4], bool *normalized) +{ + int i; + GLuint format_components; + uint8_t packed_swizzle[4]; + const uint8_t *endian; + + if (_mesa_is_format_compressed(format)) + return false; + + *normalized = !_mesa_is_format_integer(format); + + _mesa_format_to_type_and_comps(format, type, &format_components); + + switch (_mesa_get_format_layout(format)) { + case MESA_FORMAT_LAYOUT_ARRAY: + *num_components = format_components; + _mesa_get_format_swizzle(format, swizzle); + return true; + case MESA_FORMAT_LAYOUT_PACKED: + switch (*type) { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + if (_mesa_get_format_max_bits(format) != 8) + return false; + *num_components = _mesa_get_format_bytes(format); + switch (*num_components) { + case 1: + endian = map_identity; + break; + case 2: + endian = _mesa_little_endian() ? map_identity : map_1032; + break; + case 4: + endian = _mesa_little_endian() ? map_identity : map_3210; + break; + default: + assert(!"Invalid number of components"); + } + break; + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_HALF_FLOAT: + if (_mesa_get_format_max_bits(format) != 16) + return false; + *num_components = _mesa_get_format_bytes(format) / 2; + switch (*num_components) { + case 1: + endian = map_identity; + break; + case 2: + endian = _mesa_little_endian() ? map_identity : map_1032; + break; + default: + assert(!"Invalid number of components"); + } + break; + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FLOAT: + /* This isn't packed. At least not really. */ + assert(format_components == 1); + if (_mesa_get_format_max_bits(format) != 32) + return false; + *num_components = format_components; + endian = map_identity; + break; + default: + return false; + } + + _mesa_get_format_swizzle(format, packed_swizzle); + + for (i = 0; i < 4; ++i) + swizzle[i] = endian[packed_swizzle[i]]; + + return true; + case MESA_FORMAT_LAYOUT_OTHER: + default: + return false; + } +} + /* A bunch of format conversion macros and helper functions used below */ /* Only guaranteed to work for BITS <= 32 */ diff --git a/src/mesa/main/format_utils.h b/src/mesa/main/format_utils.h index 1a6d7e0..632600e 100644 --- a/src/mesa/main/format_utils.h +++ b/src/mesa/main/format_utils.h @@ -65,6 +65,10 @@ _mesa_srgb_to_linear(float cs) float _mesa_srgb_ubyte_to_linear_float(uint8_t cl); +bool +_mesa_format_to_array(mesa_format, GLenum *type, int *num_components, + uint8_t swizzle[4], bool *normalized); + void _mesa_swizzle_and_convert(void *dst, GLenum dst_type, int num_dst_channels, const void *src, GLenum src_type, int num_src_channels, -- 2.0.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev