From 5f140bceda4c11b68c16ce175533f496434ff9a3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 12 Oct 2011 16:18:14 -0700 Subject: mesa: Add a function for comparing gl_format to format/type. This should be useful in making more generic fast paths in the pixel paths. v2: Add note about PACK_SWAP_BYTES, and fix up for endianness by synchronizing with memcpy_texture paths in texstore.c. Reviewed-by: Brian Paul --- src/mesa/main/formats.c | 318 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/formats.h | 3 + 2 files changed, 321 insertions(+) diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 6307f8e4df7..c6febb0e565 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -2444,3 +2444,321 @@ _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) +{ + const GLboolean littleEndian = _mesa_little_endian(); + + /* 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. + * + * This matching assumes that GL_PACK/UNPACK_SWAP_BYTES is unset. + */ + + switch (gl_format) { + + case MESA_FORMAT_NONE: + case MESA_FORMAT_COUNT: + return GL_FALSE; + + case MESA_FORMAT_RGBA8888: + return ((format == GL_RGBA && (type == GL_UNSIGNED_INT_8_8_8_8 || + (type == GL_UNSIGNED_BYTE && !littleEndian))) || + (format == GL_ABGR_EXT && (type == GL_UNSIGNED_INT_8_8_8_8_REV || + (type == GL_UNSIGNED_BYTE && littleEndian)))); + + case MESA_FORMAT_RGBA8888_REV: + return ((format == GL_RGBA && type == GL_UNSIGNED_INT_8_8_8_8_REV)); + + case MESA_FORMAT_ARGB8888: + return ((format == GL_BGRA && (type == GL_UNSIGNED_INT_8_8_8_8_REV || + (type == GL_UNSIGNED_BYTE && littleEndian)))); + + case MESA_FORMAT_ARGB8888_REV: + return ((format == GL_BGRA && (type == GL_UNSIGNED_INT_8_8_8_8 || + (type == GL_UNSIGNED_BYTE && !littleEndian)))); + + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_XRGB8888_REV: + return GL_FALSE; + + case MESA_FORMAT_RGB888: + return format == GL_RGB && type == GL_UNSIGNED_BYTE && littleEndian; + + 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_ARGB4444: + return format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV; + case MESA_FORMAT_ARGB4444_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 format == GL_LUMINANCE_ALPHA && type == GL_UNSIGNED_BYTE && littleEndian; + case MESA_FORMAT_AL88_REV: + return GL_FALSE; + + case MESA_FORMAT_AL1616: + return format == GL_LUMINANCE_ALPHA && type == GL_UNSIGNED_SHORT && littleEndian; + case MESA_FORMAT_AL1616_REV: + return GL_FALSE; + + 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 && littleEndian; + case MESA_FORMAT_L8: + return format == GL_LUMINANCE && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_L16: + return format == GL_LUMINANCE && type == GL_UNSIGNED_SHORT && littleEndian; + case MESA_FORMAT_I8: + return format == GL_INTENSITY && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_I16: + return format == GL_INTENSITY && type == GL_UNSIGNED_SHORT && littleEndian; + + 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_LUMINANCE_ALPHA && type == GL_UNSIGNED_BYTE && littleEndian; + case MESA_FORMAT_RG88_REV: + return GL_FALSE; + + case MESA_FORMAT_R16: + return format == GL_RED && type == GL_UNSIGNED_SHORT && littleEndian; + case MESA_FORMAT_RG1616: + return format == GL_RG && type == GL_UNSIGNED_SHORT && littleEndian; + 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; + + case MESA_FORMAT_SRGB8: + case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: + case MESA_FORMAT_SL8: + case MESA_FORMAT_SLA8: + case MESA_FORMAT_SRGB_DXT1: + case MESA_FORMAT_SRGBA_DXT1: + case MESA_FORMAT_SRGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT5: + return GL_FALSE; + + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + return GL_FALSE; + + case MESA_FORMAT_RGBA_FLOAT32: + return format == GL_RGBA && type == GL_FLOAT; + case MESA_FORMAT_RGBA_FLOAT16: + return format == GL_RGBA && type == GL_HALF_FLOAT; + + case MESA_FORMAT_RGB_FLOAT32: + return format == GL_RGB && type == GL_FLOAT; + case MESA_FORMAT_RGB_FLOAT16: + return format == GL_RGB && type == GL_HALF_FLOAT; + + case MESA_FORMAT_ALPHA_FLOAT32: + return format == GL_ALPHA && type == GL_FLOAT; + case MESA_FORMAT_ALPHA_FLOAT16: + return format == GL_ALPHA && type == GL_HALF_FLOAT; + + case MESA_FORMAT_LUMINANCE_FLOAT32: + return format == GL_LUMINANCE && type == GL_FLOAT; + case MESA_FORMAT_LUMINANCE_FLOAT16: + return format == GL_LUMINANCE && type == GL_HALF_FLOAT; + + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + return format == GL_LUMINANCE_ALPHA && type == GL_FLOAT; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + return format == GL_LUMINANCE_ALPHA && type == GL_HALF_FLOAT; + + case MESA_FORMAT_INTENSITY_FLOAT32: + return format == GL_INTENSITY && type == GL_FLOAT; + case MESA_FORMAT_INTENSITY_FLOAT16: + return format == GL_INTENSITY && type == GL_HALF_FLOAT; + + case MESA_FORMAT_R_FLOAT32: + return format == GL_RED && type == GL_FLOAT; + case MESA_FORMAT_R_FLOAT16: + return format == GL_RED && type == GL_HALF_FLOAT; + + case MESA_FORMAT_RG_FLOAT32: + return format == GL_RG && type == GL_FLOAT; + case MESA_FORMAT_RG_FLOAT16: + return format == GL_RG && type == GL_HALF_FLOAT; + + /* FINISHME: What do we want to do for GL_EXT_texture_integer? */ + case MESA_FORMAT_ALPHA_UINT8: + case MESA_FORMAT_ALPHA_UINT16: + case MESA_FORMAT_ALPHA_UINT32: + case MESA_FORMAT_ALPHA_INT8: + case MESA_FORMAT_ALPHA_INT16: + case MESA_FORMAT_ALPHA_INT32: + return GL_FALSE; + + case MESA_FORMAT_INTENSITY_UINT8: + case MESA_FORMAT_INTENSITY_UINT16: + case MESA_FORMAT_INTENSITY_UINT32: + case MESA_FORMAT_INTENSITY_INT8: + case MESA_FORMAT_INTENSITY_INT16: + case MESA_FORMAT_INTENSITY_INT32: + return GL_FALSE; + + case MESA_FORMAT_LUMINANCE_UINT8: + case MESA_FORMAT_LUMINANCE_UINT16: + case MESA_FORMAT_LUMINANCE_UINT32: + case MESA_FORMAT_LUMINANCE_INT8: + case MESA_FORMAT_LUMINANCE_INT16: + case MESA_FORMAT_LUMINANCE_INT32: + return GL_FALSE; + + case MESA_FORMAT_LUMINANCE_ALPHA_UINT8: + case MESA_FORMAT_LUMINANCE_ALPHA_UINT16: + case MESA_FORMAT_LUMINANCE_ALPHA_UINT32: + case MESA_FORMAT_LUMINANCE_ALPHA_INT8: + case MESA_FORMAT_LUMINANCE_ALPHA_INT16: + case MESA_FORMAT_LUMINANCE_ALPHA_INT32: + return GL_FALSE; + + case MESA_FORMAT_R_INT8: + case MESA_FORMAT_RG_INT8: + case MESA_FORMAT_RGB_INT8: + case MESA_FORMAT_RGBA_INT8: + case MESA_FORMAT_R_INT16: + case MESA_FORMAT_RG_INT16: + case MESA_FORMAT_RGB_INT16: + case MESA_FORMAT_RGBA_INT16: + case MESA_FORMAT_R_INT32: + case MESA_FORMAT_RG_INT32: + case MESA_FORMAT_RGB_INT32: + case MESA_FORMAT_RGBA_INT32: + return GL_FALSE; + + case MESA_FORMAT_R_UINT8: + case MESA_FORMAT_RG_UINT8: + case MESA_FORMAT_RGB_UINT8: + case MESA_FORMAT_RGBA_UINT8: + case MESA_FORMAT_R_UINT16: + case MESA_FORMAT_RG_UINT16: + case MESA_FORMAT_RGB_UINT16: + case MESA_FORMAT_RGBA_UINT16: + case MESA_FORMAT_R_UINT32: + case MESA_FORMAT_RG_UINT32: + case MESA_FORMAT_RGB_UINT32: + case MESA_FORMAT_RGBA_UINT32: + return GL_FALSE; + + case MESA_FORMAT_DUDV8: + case MESA_FORMAT_SIGNED_R8: + case MESA_FORMAT_SIGNED_RG88_REV: + case MESA_FORMAT_SIGNED_RGBX8888: + case MESA_FORMAT_SIGNED_RGBA8888: + case MESA_FORMAT_SIGNED_RGBA8888_REV: + case MESA_FORMAT_SIGNED_R16: + case MESA_FORMAT_SIGNED_GR1616: + case MESA_FORMAT_SIGNED_RGB_16: + case MESA_FORMAT_SIGNED_RGBA_16: + case MESA_FORMAT_RGBA_16: + /* FINISHME: SNORM */ + return GL_FALSE; + + case MESA_FORMAT_RED_RGTC1: + case MESA_FORMAT_SIGNED_RED_RGTC1: + case MESA_FORMAT_RG_RGTC2: + case MESA_FORMAT_SIGNED_RG_RGTC2: + return GL_FALSE; + + case MESA_FORMAT_L_LATC1: + case MESA_FORMAT_SIGNED_L_LATC1: + case MESA_FORMAT_LA_LATC2: + case MESA_FORMAT_SIGNED_LA_LATC2: + return GL_FALSE; + + case MESA_FORMAT_SIGNED_A8: + case MESA_FORMAT_SIGNED_L8: + case MESA_FORMAT_SIGNED_AL88: + case MESA_FORMAT_SIGNED_I8: + case MESA_FORMAT_SIGNED_A16: + case MESA_FORMAT_SIGNED_L16: + case MESA_FORMAT_SIGNED_AL1616: + case MESA_FORMAT_SIGNED_I16: + /* FINISHME: SNORM */ + return GL_FALSE; + + case MESA_FORMAT_RGB9_E5_FLOAT: + return format == GL_RGB && type == GL_UNSIGNED_INT_5_9_9_9_REV; + case MESA_FORMAT_R11_G11_B10_FLOAT: + return format == GL_RGB && type == GL_UNSIGNED_INT_10F_11F_11F_REV; + + case MESA_FORMAT_Z32_FLOAT: + return format == GL_DEPTH_COMPONENT && type == GL_FLOAT; + + case MESA_FORMAT_Z32_FLOAT_X24S8: + return GL_FALSE; + } + + return GL_FALSE; +} diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index 12758f03e1a..f24d52548de 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -318,5 +318,8 @@ _mesa_get_uncompressed_format(gl_format format); extern GLuint _mesa_format_num_components(gl_format format); +GLboolean +_mesa_format_matches_format_and_type(gl_format gl_format, + GLenum format, GLenum type); #endif /* FORMATS_H */ -- cgit v1.2.3