summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/gen_load_functions_table.py
blob: eb3e4c5bf08212d427d6ab5031d7574ec4664930 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#!/usr/bin/python
# 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
#

import json, sys
from datetime import date

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 {copyright_year} 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}, Format::ID {angle_format})
{{
    // clang-format off
    switch ({internal_format})
    {{
{switch_data}
        default:
        {{
            static LoadFunctionMap emptyLoadFunctionsMap;
            return emptyLoadFunctionsMap;
        }}
    }}
    // clang-format on

}}  // 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.iteritems()):
        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.iteritems()):

        s = '        '

        table_data += s + 'case ' + internal_format + ':\n'

        do_switch = len(angle_to_type_map) > 1 or angle_to_type_map.keys()[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.iteritems()):

            if angle_format == angle_format_unknown:
                continue

            func_name = load_functions_name(internal_format, angle_format)

            # Main case statements
            table_data += s + 'case Format::ID::' + 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 angle_to_type_map[angle_format_unknown].iteritems():
                    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'

        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:
            table_data += s + '    break;\n'

        if do_switch:
            s = s[4:]
            table_data += s + '}\n'
            s = s[4:]
            table_data += s + '}\n'

    return table_data, load_functions_data

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,
                         copyright_year = date.today().year)

with open('load_functions_table_autogen.cpp', 'wt') as out_file:
    out_file.write(output)
    out_file.close()