[Mesa-dev] [PATCH v2 09/13] mesa/format_utils: Add a function to convert a mesa_format to an array format
Brian Paul
brianp at vmware.com
Mon Aug 4 07:55:42 PDT 2014
On 08/02/2014 02:11 PM, Jason Ekstrand wrote:
> This commits adds the _mesa_format_to_arary function that determines if the
"array"
> 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.ekstrand at 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");
I think MSVC (and maybe optimized gcc) will complain than 'endian' is
not initialized for all cases. It would probably be best to initialize
endian to point to map_identity[] in the declaration. If the
"impossible" happens and the default case is hit in release build, we
should try to not crash.
> + }
> + 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,
>
More information about the mesa-dev
mailing list