On Mon, Aug 4, 2014 at 7:55 AM, Brian Paul <bri...@vmware.com> wrote:
> 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.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"); >> > > 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. > > > Thanks Brian, fixed. I also fixed it for the GL_SHORT case below too. --Jason > > > + } >> + 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, >> >> >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev