summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2014-07-11 08:52:12 -0700
committerJason Ekstrand <[email protected]>2014-08-05 10:56:16 -0700
commit6b912dc12918c93fe729d3785e985132e9a81f51 (patch)
treea52312b104d6fa6f875412c6c2dd39ce764542b1 /src/mesa
parentd55f77b503ab7b59ecdd8f31c4f7dc498710e75b (diff)
mesa/format_utils: Add a function to convert a mesa_format to an array format
This commits adds the _mesa_format_to_array 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 v3: Fixed a potential segfault from an invalid endianness swizzle Signed-off-by: Jason Ekstrand <[email protected]> Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/format_utils.c107
-rw-r--r--src/mesa/main/format_utils.h4
2 files changed, 111 insertions, 0 deletions
diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c
index 86259696cc8..240e3bc0c19 100644
--- a/src/mesa/main/format_utils.c
+++ b/src/mesa/main/format_utils.c
@@ -25,6 +25,113 @@
#include "format_utils.h"
#include "glformats.h"
+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:
+ endian = map_identity;
+ 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:
+ endian = map_identity;
+ 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 11546aaf04b..9f778e37734 100644
--- a/src/mesa/main/format_utils.h
+++ b/src/mesa/main/format_utils.h
@@ -33,6 +33,10 @@
#include "imports.h"
+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,