Edit

kc3-lang/angle/src/libANGLE/renderer/gen_load_functions_table.py

Branch :

  • Show log

    Commit

  • Author : Cody Northrop
    Date : 2021-04-16 09:17:29
    Hash : 14f8918c
    Message : Migrate more scripts to python3 Test: python3 scripts/run_code_generation.py Bug: angleproject:5707 Change-Id: I5abae69c1c6bf03cc418f10beaabc80288fa1c94 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2828979 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Cody Northrop <cnorthrop@google.com>

  • src/libANGLE/renderer/gen_load_functions_table.py
  • #!/usr/bin/python3
    # Copyright 2015 The ANGLE Project Authors. All rights reserved.
    # Use of this source code is governed by a BSD-style license that can be
    # found in the LICENSE file.
    #
    # gen_load_functions_table.py:
    #  Code generation for the load function tables used for texture formats. These mappings are
    #  not renderer specific. The mappings are done from the GL internal format, to the ANGLE
    #  format ID, and then for the specific data type.
    #  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
    #
    
    import json, sys
    
    sys.path.append('../..')
    import angle_format
    
    template = """// GENERATED FILE - DO NOT EDIT.
    // Generated by gen_load_functions_table.py using data from load_functions_data.json
    //
    // Copyright 2020 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // load_functions_table:
    //   Contains the GetLoadFunctionsMap for texture_format_util.h
    //
    
    #include "libANGLE/renderer/load_functions_table.h"
    
    #include "image_util/copyimage.h"
    #include "image_util/generatemip.h"
    #include "image_util/loadimage.h"
    
    using namespace rx;
    
    namespace angle
    {{
    
    namespace
    {{
    
    // ES3 image loading functions vary based on:
    //    - the GL internal format (supplied to glTex*Image*D)
    //    - the GL data type given (supplied to glTex*Image*D)
    //    - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D
    //    device's capabilities)
    // This map type determines which loading function to use, based on these three parameters.
    // Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec.
    void UnimplementedLoadFunction(size_t width,
                                   size_t height,
                                   size_t depth,
                                   const uint8_t *input,
                                   size_t inputRowPitch,
                                   size_t inputDepthPitch,
                                   uint8_t *output,
                                   size_t outputRowPitch,
                                   size_t outputDepthPitch)
    {{
        UNIMPLEMENTED();
    }}
    
    void UnreachableLoadFunction(size_t width,
                                 size_t height,
                                 size_t depth,
                                 const uint8_t *input,
                                 size_t inputRowPitch,
                                 size_t inputDepthPitch,
                                 uint8_t *output,
                                 size_t outputRowPitch,
                                 size_t outputDepthPitch)
    {{
        UNREACHABLE();
    }}
    
    {load_functions_data}}}  // namespace
    
    LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, FormatID {angle_format})
    {{
        // clang-format off
        switch ({internal_format})
        {{
    {switch_data}
            default:
                break;
        }}
        // clang-format on
        ASSERT(internalFormat == GL_NONE || angleFormat == angle::FormatID::NONE);
        static LoadFunctionMap emptyLoadFunctionsMap;
        return emptyLoadFunctionsMap;
    
    }}  // GetLoadFunctionsMap
    
    }}  // namespace angle
    """
    
    internal_format_param = 'internalFormat'
    angle_format_param = 'angleFormat'
    angle_format_unknown = 'NONE'
    
    
    def load_functions_name(internal_format, angle_format):
        return internal_format[3:] + "_to_" + angle_format
    
    
    def unknown_func_name(internal_format):
        return load_functions_name(internal_format, "default")
    
    
    def get_load_func(func_name, type_functions):
        snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n"
        snippet += "{\n"
        snippet += "    switch (type)\n"
        snippet += "    {\n"
        for gl_type, load_function in sorted(type_functions.items()):
            snippet += "        case " + gl_type + ":\n"
            requiresConversion = str('LoadToNative<' not in load_function).lower()
            snippet += "            return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n"
        snippet += "        default:\n"
        snippet += "            UNREACHABLE();\n"
        snippet += "            return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n"
        snippet += "    }\n"
        snippet += "}\n"
        snippet += "\n"
    
        return snippet
    
    
    def get_unknown_load_func(angle_to_type_map, internal_format):
        assert angle_format_unknown in angle_to_type_map
        return get_load_func(
            unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown])
    
    
    def parse_json(json_data):
        table_data = ''
        load_functions_data = ''
        for internal_format, angle_to_type_map in sorted(json_data.items()):
    
            s = '        '
    
            table_data += s + 'case ' + internal_format + ':\n'
    
            do_switch = len(angle_to_type_map) > 1 or list(
                angle_to_type_map)[0] != angle_format_unknown
    
            if do_switch:
                table_data += s + '{\n'
                s += '    '
                table_data += s + 'switch (' + angle_format_param + ')\n'
                table_data += s + '{\n'
                s += '    '
    
            for angle_format, type_functions in sorted(angle_to_type_map.items()):
    
                if angle_format == angle_format_unknown:
                    continue
    
                func_name = load_functions_name(internal_format, angle_format)
    
                # Main case statements
                table_data += s + 'case FormatID::' + angle_format + ':\n'
                table_data += s + '    return ' + func_name + ';\n'
    
                if angle_format_unknown in angle_to_type_map:
                    for gl_type, load_function in sorted(
                            angle_to_type_map[angle_format_unknown].items()):
                        if gl_type not in type_functions:
                            type_functions[gl_type] = load_function
    
                load_functions_data += get_load_func(func_name, type_functions)
    
            if do_switch:
                table_data += s + 'default:\n'
    
            has_break_in_switch = False
            if angle_format_unknown in angle_to_type_map:
                table_data += s + '    return ' + unknown_func_name(internal_format) + ';\n'
                load_functions_data += get_unknown_load_func(angle_to_type_map, internal_format)
            else:
                has_break_in_switch = True
                table_data += s + '    break;\n'
    
            if do_switch:
                s = s[4:]
                table_data += s + '}\n'
                if has_break_in_switch:
                    # If the inner switch contains a break statement, add a break
                    # statement after the switch as well.
                    table_data += s + 'break;\n'
                s = s[4:]
                table_data += s + '}\n'
    
        return table_data, load_functions_data
    
    
    def main():
    
        # auto_script parameters.
        if len(sys.argv) > 1:
            inputs = ['angle_format.py', 'load_functions_data.json']
            outputs = ['load_functions_table_autogen.cpp']
    
            if sys.argv[1] == 'inputs':
                print(','.join(inputs))
            elif sys.argv[1] == 'outputs':
                print(','.join(outputs))
            else:
                print('Invalid script parameters')
                return 1
            return 0
    
        json_data = angle_format.load_json('load_functions_data.json')
    
        switch_data, load_functions_data = parse_json(json_data)
        output = template.format(
            internal_format=internal_format_param,
            angle_format=angle_format_param,
            switch_data=switch_data,
            load_functions_data=load_functions_data)
    
        with open('load_functions_table_autogen.cpp', 'wt') as out_file:
            out_file.write(output)
            out_file.close()
        return 0
    
    
    if __name__ == '__main__':
        sys.exit(main())