This should be useful in making more generic fast paths in the pixel
paths.
---
src/mesa/main/formats.c | 306 +++
src/mesa/main/formats.h |3 +
2 files changed, 309 insertions(+), 0 deletions(-)
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 6307f8e..b9a2434 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -2444,3 +2444,309 @@ _mesa_format_to_type_and_comps(gl_format format,
*comps = 1;
}
}
+
+/**
+ * Returns a MESA_FORMAT describing pixels with the given format/type if
+ * available, or MESA_FORMAT_NONE.
+ *
+ * If a format is returned, it should be suitable to memcpy
+ * _mesa_get_format_bytes() at a time to move the pixel data.
+ */
+GLboolean
+_mesa_format_matches_format_and_type(gl_format gl_format,
+GLenum format, GLenum type)
+{
+ /* Note: When reading a GL format/type combination, the format lists channel
+* assignments from most significant channel in the type to least
+* significant. A type with _REV indicates that the assignments are
swapped,
+* so they are listed from least significant to most significant.
+*
+* For sanity, please keep this switch statement ordered the same as the
enum
+* in formats.h.
+*/
+
+ switch (gl_format) {
+
+ case MESA_FORMAT_NONE:
+ case MESA_FORMAT_COUNT:
+ return GL_FALSE;
+
+ case MESA_FORMAT_RGBA:
+ return format == GL_RGBA type == GL_UNSIGNED_INT_8_8_8_8;
+ case MESA_FORMAT_RGBA_REV:
+ return format == GL_RGBA type == GL_UNSIGNED_INT_8_8_8_8_REV;
+
+ case MESA_FORMAT_ARGB:
+ return format == GL_BGRA type == GL_UNSIGNED_INT_8_8_8_8_REV;
+ case MESA_FORMAT_ARGB_REV:
+ return format == GL_BGRA type == GL_UNSIGNED_INT_8_8_8_8;
+
+ case MESA_FORMAT_XRGB:
+ case MESA_FORMAT_XRGB_REV:
+ return GL_FALSE;
+
+ case MESA_FORMAT_RGB888:
+ return format == GL_RGB type == GL_UNSIGNED_BYTE;
+ case MESA_FORMAT_BGR888:
+ return GL_FALSE;
+
+ case MESA_FORMAT_RGB565:
+ return format == GL_RGB type == GL_UNSIGNED_SHORT_5_6_5;
+ case MESA_FORMAT_RGB565_REV:
+ /* Some of the 16-bit MESA_FORMATs that would seem to correspond to
+ * GL_UNSIGNED_SHORT_* are byte-swapped instead of channel-reversed,
+ * according to formats.h, so they can't be matched.
+ */
+ return GL_FALSE;
+
+ case MESA_FORMAT_ARGB:
+ return format == GL_BGRA type == GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ case MESA_FORMAT_ARGB_REV:
+ return GL_FALSE;
+
+ case MESA_FORMAT_RGBA5551:
+ return format == GL_RGBA type == GL_UNSIGNED_SHORT_5_5_5_1;
+
+ case MESA_FORMAT_ARGB1555:
+ return format == GL_BGRA type == GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ case MESA_FORMAT_ARGB1555_REV:
+ return GL_FALSE;
+
+ case MESA_FORMAT_AL44:
+ return GL_FALSE;
+ case MESA_FORMAT_AL88:
+ return GL_FALSE;
+ case MESA_FORMAT_AL88_REV:
+ return format == GL_LUMINANCE_ALPHA type == GL_UNSIGNED_BYTE;
+
+ case MESA_FORMAT_AL1616:
+ return GL_FALSE;
+ case MESA_FORMAT_AL1616_REV:
+ return format == GL_LUMINANCE_ALPHA type == GL_UNSIGNED_SHORT;
+
+ case MESA_FORMAT_RGB332:
+ return format == GL_RGB type == GL_UNSIGNED_BYTE_3_3_2;
+
+ case MESA_FORMAT_A8:
+ return format == GL_ALPHA type == GL_UNSIGNED_BYTE;
+ case MESA_FORMAT_A16:
+ return format == GL_ALPHA type == GL_UNSIGNED_SHORT;
+ case MESA_FORMAT_L8:
+ return format == GL_LUMINANCE type == GL_UNSIGNED_BYTE;
+ case MESA_FORMAT_L16:
+ return format == GL_LUMINANCE type == GL_UNSIGNED_SHORT;
+ case MESA_FORMAT_I8:
+ return format == GL_INTENSITY type == GL_UNSIGNED_BYTE;
+ case MESA_FORMAT_I16:
+ return format == GL_INTENSITY type == GL_UNSIGNED_SHORT;
+
+ case MESA_FORMAT_YCBCR:
+ case MESA_FORMAT_YCBCR_REV:
+ return GL_FALSE;
+
+ case MESA_FORMAT_R8:
+ return format == GL_RED type == GL_UNSIGNED_BYTE;
+ case MESA_FORMAT_RG88:
+ return format == GL_RG type == GL_UNSIGNED_BYTE;
+ case MESA_FORMAT_RG88_REV:
+ return GL_FALSE;
+
+ case MESA_FORMAT_R16:
+ return format == GL_RED type == GL_UNSIGNED_SHORT;
+ case MESA_FORMAT_RG1616:
+ return format == GL_RG type == GL_UNSIGNED_SHORT;
+ case MESA_FORMAT_RG1616_REV:
+ return GL_FALSE;
+
+ case MESA_FORMAT_ARGB2101010:
+ return format == GL_BGRA type == GL_UNSIGNED_INT_2_10_10_10_REV;
+
+ case MESA_FORMAT_Z24_S8:
+ return format == GL_DEPTH_STENCIL type == GL_UNSIGNED_INT_24_8;
+ case MESA_FORMAT_Z24_X8:
+ case MESA_FORMAT_S8_Z24:
+ return GL_FALSE;
+
+ case MESA_FORMAT_Z16:
+ return format == GL_DEPTH_COMPONENT type == GL_UNSIGNED_SHORT;
+
+ case MESA_FORMAT_X8_Z24:
+ return GL_FALSE;
+
+ case MESA_FORMAT_Z32:
+ return format == GL_DEPTH_COMPONENT type == GL_UNSIGNED_INT;
+
+ case MESA_FORMAT_S8:
+ return GL_FALSE;
+