[Mesa-dev] [PATCH 1/6] mesa: Add _mesa_format_fallback_rgba_to_rgbx()

Dylan Baker dylan at pnwbakers.com
Tue Jun 6 20:51:07 UTC 2017


Quoting Chad Versace (2017-06-06 13:36:55)
> The new function takes a mesa_format and, if the format is an alpha
> format with a non-alpha variant, returns the non-alpha format.
> Otherwise, it returns the original format.
> 
> Example:
>   input -> output
> 
>   // Fallback exists
>   MESA_FORMAT_R8G8B8X8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
>   MESA_FORMAT_RGBX_UNORM16 -> MESA_FORMAT_RGBA_UNORM16
> 
>   // No fallback
>   MESA_FORMAT_R8G8B8A8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
>   MESA_FORMAT_Z_FLOAT32 -> MESA_FORMAT_Z_FLOAT32
> 
> i965 will use this for EGLImages and DRIimages.
> ---
>  src/mesa/Android.gen.mk          |  12 +++
>  src/mesa/Makefile.am             |   7 ++
>  src/mesa/Makefile.sources        |   2 +
>  src/mesa/main/.gitignore         |   1 +
>  src/mesa/main/format_fallback.h  |  31 +++++++
>  src/mesa/main/format_fallback.py | 180 +++++++++++++++++++++++++++++++++++++++
>  6 files changed, 233 insertions(+)
>  create mode 100644 src/mesa/main/format_fallback.h
>  create mode 100644 src/mesa/main/format_fallback.py
> 
> diff --git a/src/mesa/Android.gen.mk b/src/mesa/Android.gen.mk
> index 42d4ba1969..8dcfb460e9 100644
> --- a/src/mesa/Android.gen.mk
> +++ b/src/mesa/Android.gen.mk
> @@ -34,6 +34,7 @@ sources := \
>         main/enums.c \
>         main/api_exec.c \
>         main/dispatch.h \
> +       main/format_fallback.c \
>         main/format_pack.c \
>         main/format_unpack.c \
>         main/format_info.h \
> @@ -135,6 +136,17 @@ $(intermediates)/main/get_hash.h: $(glapi)/gl_and_es_API.xml \
>                 $(LOCAL_PATH)/main/get_hash_params.py $(GET_HASH_GEN)
>         $(call es-gen)
>  
> +FORMAT_FALLBACK := $(LOCAL_PATH)/main/format_fallback.py
> +format_fallback_deps := \
> +       $(LOCAL_PATH)/main/formats.csv \
> +       $(LOCAL_PATH)/main/format_parser.py \
> +       $(FORMAT_FALLBACK)
> +
> +$(intermediates)/main/format_fallback.c: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(FORMAT_FALLBACK)
> +$(intermediates)/main/format_fallback.c: PRIVATE_XML :=
> +$(intermediates)/main/format_fallback.c: $(format_fallback_deps)
> +       $(call es-gen, $<)
> +
>  FORMAT_INFO := $(LOCAL_PATH)/main/format_info.py
>  format_info_deps := \
>         $(LOCAL_PATH)/main/formats.csv \
> diff --git a/src/mesa/Makefile.am b/src/mesa/Makefile.am
> index 53f311d2a9..2c39374aef 100644
> --- a/src/mesa/Makefile.am
> +++ b/src/mesa/Makefile.am
> @@ -37,6 +37,7 @@ include Makefile.sources
>  
>  EXTRA_DIST = \
>         drivers/SConscript \
> +       main/format_fallback.py \
>         main/format_info.py \
>         main/format_pack.py \
>         main/format_parser.py \
> @@ -54,6 +55,7 @@ EXTRA_DIST = \
>  
>  BUILT_SOURCES = \
>         main/get_hash.h \
> +       main/format_fallback.c \
>         main/format_info.h \
>         main/format_pack.c \
>         main/format_unpack.c \
> @@ -70,6 +72,11 @@ main/get_hash.h: ../mapi/glapi/gen/gl_and_es_API.xml main/get_hash_params.py \
>         $(PYTHON_GEN) $(srcdir)/main/get_hash_generator.py \
>                 -f $(srcdir)/../mapi/glapi/gen/gl_and_es_API.xml > $@
>  
> +main/format_fallback.c: main/format_fallback.py \
> +                        main/format_parser.py \
> +                       main/formats.csv
> +       $(PYTHON_GEN) $(srcdir)/main/format_fallback.py $(srcdir)/main/formats.csv > $@
> +
>  main/format_info.h: main/formats.csv \
>                      main/format_parser.py main/format_info.py
>         $(PYTHON_GEN) $(srcdir)/main/format_info.py $(srcdir)/main/formats.csv > $@
> diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
> index 8a65fbe663..642100b956 100644
> --- a/src/mesa/Makefile.sources
> +++ b/src/mesa/Makefile.sources
> @@ -94,6 +94,8 @@ MAIN_FILES = \
>         main/ffvertex_prog.h \
>         main/fog.c \
>         main/fog.h \
> +       main/format_fallback.h \
> +       main/format_fallback.c \
>         main/format_info.h \
>         main/format_pack.h \
>         main/format_pack.c \
> diff --git a/src/mesa/main/.gitignore b/src/mesa/main/.gitignore
> index 836d8f104a..8cc33cfee6 100644
> --- a/src/mesa/main/.gitignore
> +++ b/src/mesa/main/.gitignore
> @@ -4,6 +4,7 @@ enums.c
>  remap_helper.h
>  get_hash.h
>  get_hash.h.tmp
> +format_fallback.c
>  format_info.h
>  format_info.c
>  format_pack.c
> diff --git a/src/mesa/main/format_fallback.h b/src/mesa/main/format_fallback.h
> new file mode 100644
> index 0000000000..5ca8269b2f
> --- /dev/null
> +++ b/src/mesa/main/format_fallback.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright 2017 Google
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included
> + * in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifndef FORMAT_FALLBACK_H
> +#define FORMAT_FALLBACK_H
> +
> +#include "formats.h"
> +
> +mesa_format
> +_mesa_format_fallback_rgbx_to_rgba(mesa_format format);
> +
> +#endif /* FORMAT_FALLBACK_H */
> diff --git a/src/mesa/main/format_fallback.py b/src/mesa/main/format_fallback.py
> new file mode 100644
> index 0000000000..253cd0e3e7
> --- /dev/null
> +++ b/src/mesa/main/format_fallback.py
> @@ -0,0 +1,180 @@
> +# Copyright 2017 Google
> +#
> +# Permission is hereby granted, free of charge, to any person obtaining a
> +# copy of this software and associated documentation files (the
> +# "Software"), to deal in the Software without restriction, including
> +# without limitation the rights to use, copy, modify, merge, publish,
> +# distribute, sub license, and/or sell copies of the Software, and to
> +# permit persons to whom the Software is furnished to do so, subject to
> +# the following conditions:
> +#
> +# The above copyright notice and this permission notice (including the
> +# next paragraph) shall be included in all copies or substantial portions
> +# of the Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> +# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
> +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
> +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +
> +# stdlib
> +import argparse
> +from sys import stdout
> +from textwrap import dedent
> +
> +# local
> +import format_parser
> +
> +def format_is_rgbx(fmt):
> +    return fmt.has_channel('a')
> +
> +def parse_args():
> +    p = argparse.ArgumentParser()
> +    p.add_argument("csv")
> +    return p.parse_args()
> +
> +def write_preamble(out):
> +    out.write(dedent('''\
> +        /*
> +         * Copyright 2017 Google
> +         *
> +         * Permission is hereby granted, free of charge, to any person obtaining a
> +         * copy of this software and associated documentation files (the "Software"),
> +         * to deal in the Software without restriction, including without limitation
> +         * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> +         * and/or sell copies of the Software, and to permit persons to whom the
> +         * Software is furnished to do so, subject to the following conditions:
> +         *
> +         * The above copyright notice and this permission notice shall be included
> +         * in all copies or substantial portions of the Software.
> +         *
> +         * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> +         * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +         * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> +         * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> +         * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> +         * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> +         * OTHER DEALINGS IN THE SOFTWARE.
> +         */
> +
> +         /*
> +          * This file is GENERATED.  Do not edit it manually or commit it into version
> +          * control.
> +          */
> +
> +          #include "format_fallback.h"
> +
> +          '''))
> +
> +def format_get_alpha_channel_string(fmt):
> +    """Return alpha channel's substring in the format name. If the format has
> +    no alpha channel, then return None.
> +
> +    The name of alpha formats fall into the following cases:
> +
> +       - The alpha channel's size follows the "A". For example,
> +         MESA_FORMAT_R8G8B8A8_UNORM. In this case, the channel substring
> +         is "A8".
> +
> +       - The alpha channel's size implicitly appears as the datatype size. For
> +         example, MESA_FORMAT_RGBA_FLOAT32. In this case, the channel
> +         substring is just "A".
> +    """
> +
> +    alpha_channel = fmt.get_channel('a')
> +    if not alpha_channel:
> +        return None
> +
> +    assert alpha_channel.size > 0
> +
> +    alpha_channel_name = "A" + str(alpha_channel.size)
> +    if alpha_channel_name in fmt.name:
> +        return alpha_channel_name
> +
> +    return "A"
> +
> +def format_convert_alpha_to_x(fmt, all_formats):
> +    """If the format is an alpha format for which a non-alpha variant
> +    exists with the same bit layout, then return the non-alpha format.
> +    Otherwise return None.
> +    """
> +
> +    a_str = format_get_alpha_channel_string(fmt)
> +    if not a_str:
> +        # Format has no alpha channel
> +        return None
> +
> +    x_str = a_str.replace("A", "X")
> +
> +    # Succesively replace each occurence of a_str in the format name with
> +    # x_str until we find a valid format name.
> +    i = -1
> +    while True:
> +        i += 1
> +        i = fmt.name.find(a_str, i)
> +        if i == -1:
> +            break
> +
> +        x_fmt_name = fmt.name[:i] + fmt.name[i:].replace(a_str, x_str)
> +        # Assert that the string replacement actually occured.
> +        assert x_fmt_name != fmt.name
> +
> +        x_fmt = all_formats.get(x_fmt_name, None)
> +        if x_fmt is None:
> +            continue
> +
> +        return x_fmt
> +
> +    return None
> +
> +def write_func_mesa_format_fallback_rgbx_to_rgba(out, formats):
> +    out.write(dedent('''\
> +        /**
> +          * If the format has an alpha channel, and there exists a non-alpha
> +          * variant of the format with an identical bit layout, then return
> +          * the non-alpha format. Otherwise return the original format.
> +          *
> +          * Examples:
> +          *    Fallback exists:
> +          *       MESA_FORMAT_R8G8B8X8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
> +          *       MESA_FORMAT_RGBX_UNORM16 -> MESA_FORMAT_RGBA_UNORM16
> +          *
> +          *    No fallback:
> +          *       MESA_FORMAT_R8G8B8A8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
> +          *       MESA_FORMAT_Z_FLOAT32 -> MESA_FORMAT_Z_FLOAT32
> +          */
> +        mesa_format
> +        _mesa_format_fallback_rgbx_to_rgba(mesa_format format)
> +        {
> +           switch (format) {
> +        '''))
> +
> +    for alpha_format in formats.values():
> +        x_format = format_convert_alpha_to_x(alpha_format, formats)
> +        if x_format is None:
> +            continue
> +
> +        out.write("   case {}: return {};\n".format(
> +            x_format.name, alpha_format.name))
> +
> +    out.write(dedent('''\
> +           default: return format;
> +           }
> +        }
> +        '''))
> +
> +def main():
> +    pargs = parse_args()
> +
> +    formats = {}
> +    for fmt in format_parser.parse(pargs.csv):
> +        formats[fmt.name] = fmt

You could simplify this as:
formats = {f.name: f for f in format_parser.parse(pargs.csv)}

> +
> +    write_preamble(stdout)
> +    write_func_mesa_format_fallback_rgbx_to_rgba(stdout, formats)

We really shouldn't write to stdout like this, it can cause all kinds of
breakages if there's ever a UTF-8 character (say ©) and the terminal doesn't
have a unicode locale it'll fail, if you just open the file you want (say one
passed as an argument) then it doesn't matter what the console supports. We do
this all over the place so it's not a blocker for me, but I still think it's a
bad idea to write to stdout.

If you decide not to change this you at the very least need to call
stdout.flush() after write_func_mesa_format_fallback_Rgbx_to_rgba.

Dylan

> +
> +if __name__ == "__main__":
> +    main()
> -- 
> 2.13.0
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: signature
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170606/8452562f/attachment.sig>


More information about the mesa-dev mailing list