From d77c77936b3956e8925504ad980acbff74422e7c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 18 Sep 2019 14:01:29 -0700 Subject: [PATCH] mesa: Add support for array formats of depth and stencil. In desktop GL, you can specify things like GL_DEPTH_COMPONENT/GL_BYTE as a ReadPixels format, and we need to be able to represent that to see if we have proper MESA_FORMATs for them. That's exactly what the mesa_array_format enum is for. v2: Drop _mesa from static fn. Reviewed-by: Kenneth Graunke --- src/mesa/main/format_info.py | 5 +++++ src/mesa/main/format_utils.c | 12 ++++++++---- src/mesa/main/formats.c | 9 +++++++++ src/mesa/main/formats.h | 19 +++++++++++++++++-- src/mesa/main/glformats.c | 24 ++++++++++++++++++++++-- src/mesa/main/tests/mesa_formats.cpp | 22 ++++++++++++++++++++++ 6 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py index 432578f4e19..d3ec486f155 100644 --- a/src/mesa/main/format_info.py +++ b/src/mesa/main/format_info.py @@ -176,6 +176,10 @@ static const struct mesa_format_info format_info[MESA_FORMAT_COUNT] = def format_channel_bits(fmat, tuple_list): return ['.%s = %s' % (field, str(get_channel_bits(fmat, name))) for (field, name) in tuple_list] +bf_map = { + "GL_DEPTH_COMPONENT" : "MESA_ARRAY_FORMAT_BASE_FORMAT_DEPTH", + "GL_STENCIL_INDEX" : "MESA_ARRAY_FORMAT_BASE_FORMAT_STENCIL", +} for fmat in formats: print(' {') @@ -200,6 +204,7 @@ for fmat in formats: chan = fmat.array_element() norm = chan.norm or chan.type == parser.FLOAT print(' .ArrayFormat = MESA_ARRAY_FORMAT({0}),'.format(', '.join([ + bf_map.get(get_gl_base_format(fmat), "MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS"), str(chan.size // 8), str(int(chan.sign)), str(int(chan.type == parser.FLOAT)), diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c index 6959bf062a1..58a65adc4de 100644 --- a/src/mesa/main/format_utils.c +++ b/src/mesa/main/format_utils.c @@ -29,16 +29,20 @@ #include "format_unpack.h" const mesa_array_format RGBA32_FLOAT = - MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3); + MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS, + 4, 1, 1, 1, 4, 0, 1, 2, 3); const mesa_array_format RGBA8_UBYTE = - MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3); + MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS, + 1, 0, 0, 1, 4, 0, 1, 2, 3); const mesa_array_format RGBA32_UINT = - MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3); + MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS, + 4, 0, 0, 0, 4, 0, 1, 2, 3); const mesa_array_format RGBA32_INT = - MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3); + MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS, + 4, 1, 0, 0, 4, 0, 1, 2, 3); static void invert_swizzle(uint8_t dst[4], const uint8_t src[4]) diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 1abc83c66ab..b40b275f497 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -232,6 +232,15 @@ get_base_format_for_array_format(mesa_array_format format) uint8_t swizzle[4]; int num_channels; + switch (_mesa_array_format_get_base_format(format)) { + case MESA_ARRAY_FORMAT_BASE_FORMAT_DEPTH: + return GL_DEPTH_COMPONENT; + case MESA_ARRAY_FORMAT_BASE_FORMAT_STENCIL: + return GL_STENCIL_INDEX; + case MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS: + break; + } + _mesa_array_format_get_swizzle(format, swizzle); num_channels = _mesa_array_format_get_num_channels(format); diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index abfd73313ef..92d0c341df4 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -109,6 +109,12 @@ enum mesa_array_format_datatype { MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe, }; +enum mesa_array_format_base_format { + MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS = 0x0, + MESA_ARRAY_FORMAT_BASE_FORMAT_DEPTH = 0x1, + MESA_ARRAY_FORMAT_BASE_FORMAT_STENCIL = 0x2, +}; + /** * An enum useful to encode/decode information stored in a mesa_array_format */ @@ -124,11 +130,12 @@ enum { MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK = 0x03800, MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK = 0x1c000, MESA_ARRAY_FORMAT_SWIZZLE_W_MASK = 0xe0000, + MESA_ARRAY_FORMAT_BASE_FORMAT_MASK = 0x300000, MESA_ARRAY_FORMAT_BIT = 0x80000000 }; -#define MESA_ARRAY_FORMAT(SIZE, SIGNED, IS_FLOAT, NORM, NUM_CHANS, \ - SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) ( \ +#define MESA_ARRAY_FORMAT(BASE_FORMAT, SIZE, SIGNED, IS_FLOAT, NORM, NUM_CHANS, \ + SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) ( \ (((SIZE >> 1) ) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) | \ (((SIGNED) << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) | \ (((IS_FLOAT) << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) | \ @@ -138,6 +145,7 @@ enum { (((SWIZZLE_Y) << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) | \ (((SWIZZLE_Z) << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) | \ (((SWIZZLE_W) << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) | \ + (((BASE_FORMAT) << 20) & MESA_ARRAY_FORMAT_BASE_FORMAT_MASK) | \ MESA_ARRAY_FORMAT_BIT) /** @@ -161,6 +169,13 @@ _mesa_array_format_is_normalized(mesa_array_format f) return (f & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) !=0; } +static inline enum mesa_array_format_base_format +_mesa_array_format_get_base_format(mesa_array_format f) +{ + return (enum mesa_array_format_base_format) + ((f & MESA_ARRAY_FORMAT_BASE_FORMAT_MASK) >> 20); +} + static inline enum mesa_array_format_datatype _mesa_array_format_get_datatype(mesa_array_format f) { diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c index f2af50cd855..41becd47d8b 100644 --- a/src/mesa/main/glformats.c +++ b/src/mesa/main/glformats.c @@ -3501,6 +3501,12 @@ get_swizzle_from_gl_format(GLenum format, uint8_t *swizzle) case GL_INTENSITY: set_swizzle(swizzle, 0, 0, 0, 0); return true; + case GL_DEPTH_COMPONENT: + set_swizzle(swizzle, 0, 6, 6, 6); + return true; + case GL_STENCIL_INDEX: + set_swizzle(swizzle, 6, 0, 6, 6); + return true; default: return false; } @@ -3577,10 +3583,24 @@ _mesa_format_from_format_and_type(GLenum format, GLenum type) * create the array format */ if (is_array_format) { - normalized = !_mesa_is_enum_format_integer(format); + enum mesa_array_format_base_format bf; + switch (format) { + case GL_DEPTH_COMPONENT: + bf = MESA_ARRAY_FORMAT_BASE_FORMAT_DEPTH; + break; + case GL_STENCIL_INDEX: + bf = MESA_ARRAY_FORMAT_BASE_FORMAT_STENCIL; + break; + default: + bf = MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS; + break; + } + + normalized = !(_mesa_is_enum_format_integer(format) || + format == GL_STENCIL_INDEX); num_channels = _mesa_components_in_format(format); - return MESA_ARRAY_FORMAT(type_size, is_signed, is_float, + return MESA_ARRAY_FORMAT(bf, type_size, is_signed, is_float, normalized, num_channels, swizzle[0], swizzle[1], swizzle[2], swizzle[3]); } diff --git a/src/mesa/main/tests/mesa_formats.cpp b/src/mesa/main/tests/mesa_formats.cpp index 5356cd919a8..e4f95163c28 100644 --- a/src/mesa/main/tests/mesa_formats.cpp +++ b/src/mesa/main/tests/mesa_formats.cpp @@ -137,3 +137,25 @@ TEST(MesaFormatsTest, FormatSanity) } } + +static mesa_format fffat_wrap(GLenum format, GLenum type) +{ + uint32_t f = _mesa_format_from_format_and_type(format, type); + if (_mesa_format_is_mesa_array_format(f)) + f = _mesa_format_from_array_format((mesa_array_format)f); + return (mesa_format)f; +} + +TEST(MesaFormatsTest, FormatFromFormatAndType) +{ + EXPECT_EQ(fffat_wrap(GL_RGBA, GL_SHORT), + MESA_FORMAT_RGBA_SNORM16); + EXPECT_EQ(fffat_wrap(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT), + MESA_FORMAT_Z_UNORM16); + EXPECT_EQ(fffat_wrap(GL_STENCIL_INDEX, GL_UNSIGNED_BYTE), + MESA_FORMAT_S_UINT8); + + /* Should return an array format, but not a proper MESA_FORMAT. */ + EXPECT_TRUE(_mesa_format_is_mesa_array_format(_mesa_format_from_format_and_type(GL_DEPTH_COMPONENT, + GL_BYTE))); +} -- 2.30.2