OSDN Git Service

radeonsi: always enable NIR for Civilization 6 to fix corruption
[android-x86/external-mesa.git] / src / util / merge_driinfo.py
1 #
2 # Copyright 2017 Advanced Micro Devices, Inc.
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the "Software"),
6 # to deal in the Software without restriction, including without limitation
7 # on the rights to use, copy, modify, merge, publish, distribute, sub
8 # license, and/or sell copies of the Software, and to permit persons to whom
9 # the Software is furnished to do so, subject to the following conditions:
10 #
11 # The above copyright notice and this permission notice (including the next
12 # paragraph) shall be included in all copies or substantial portions of the
13 # Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 # THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 # USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 """
24 usage: merge_driinfo.py <list of input files>
25
26 Generates a source file which contains the DRI_CONF_xxx macros for generating
27 the driinfo XML that describes the available DriConf options for a driver and
28 its supported state trackers, based on the merged information from the input
29 files.
30 """
31
32 from __future__ import print_function
33
34 import mako.template
35 import re
36 import sys
37
38
39 # Some regexps used during input parsing
40 RE_section_begin = re.compile(r'DRI_CONF_SECTION_(.*)')
41 RE_option = re.compile(r'DRI_CONF_(.*)\((.*)\)')
42
43
44 class Option(object):
45    """
46    Represent a config option as:
47     * name: the xxx part of the DRI_CONF_xxx macro
48     * defaults: the defaults parameters that are passed into the macro
49    """
50    def __init__(self, name, defaults):
51       self.name = name
52       self.defaults = defaults
53
54
55 class Section(object):
56    """
57    Represent a config section description as:
58     * name: the xxx part of the DRI_CONF_SECTION_xxx macro
59     * options: list of options
60    """
61    def __init__(self, name):
62       self.name = name
63       self.options = []
64
65
66 def parse_inputs(input_filenames):
67    success = True
68    sections_lists = []
69
70    for input_filename in input_filenames:
71       with open(input_filename, 'r') as infile:
72          sections = []
73          sections_lists.append(sections)
74
75          section = None
76
77          linenum = 0
78          for line in infile:
79             linenum += 1
80             line = line.strip()
81             if not line:
82                continue
83
84             if line.startswith('//'):
85                continue
86
87             if line == 'DRI_CONF_SECTION_END':
88                if section is None:
89                   print('{}:{}: no open section'
90                         .format(input_filename, linenum))
91                   success = False
92                   continue
93                section = None
94                continue
95
96             m = RE_section_begin.match(line)
97             if m:
98                if section is not None:
99                   print('{}:{}: nested sections are not supported'
100                         .format(input_filename, linenum))
101                   success = False
102                   continue
103                if sections is None:
104                   print('{}:{}: missing DRIINFO line'
105                         .format(input_filename, linenum))
106                   success = False
107                   break # parsing the rest really makes no sense
108                section = Section(m.group(1))
109                sections.append(section)
110                continue
111
112             m = RE_option.match(line)
113             if m:
114                if section is None:
115                   print('{}:{}: no open section'
116                         .format(input_filename, linenum))
117                   success = False
118                   break
119                section.options.append(Option(m.group(1), m.group(2)))
120                continue
121
122             print('{}:{}: do not understand this line'
123                   .format(input_filename, linenum))
124             success = False
125
126          if section is not None:
127             print('{}:end-of-file: missing end of section'
128                   .format(input_filename))
129             success = False
130
131    if success:
132       return sections_lists
133    return None
134
135
136 def merge_sections(section_list):
137    """
138    section_list: list of Section objects to be merged, all of the same name
139    Return a merged Section object (everything is deeply copied)
140    """
141    merged_section = Section(section_list[0].name)
142
143    for section in section_list:
144       assert section.name == merged_section.name
145
146       for orig_option in section.options:
147          for merged_option in merged_section.options:
148             if orig_option.name == merged_option.name:
149                merged_option.defaults = orig_option.defaults
150                break
151          else:
152             merged_section.options.append(Option(orig_option.name, orig_option.defaults))
153
154    return merged_section
155
156
157 def merge_sections_lists(sections_lists):
158    """
159    sections_lists: list of lists of Section objects to be merged
160    Return a merged list of merged Section objects; everything is deeply copied.
161    Default values for options in later lists override earlier default values.
162    """
163    merged_sections = []
164
165    for idx,sections in enumerate(sections_lists):
166       for base_section in sections:
167          original_sections = [base_section]
168          for next_sections in sections_lists[idx+1:]:
169             for j,section in enumerate(next_sections):
170                if section.name == base_section.name:
171                   original_sections.append(section)
172                   del next_sections[j]
173                   break
174
175          merged_section = merge_sections(original_sections)
176
177          merged_sections.append(merged_section)
178
179    return merged_sections
180
181
182 def main(input_filenames):
183    sections_lists = parse_inputs(input_filenames)
184    if sections_lists is None:
185       return False
186
187    merged_sections_list = merge_sections_lists(sections_lists)
188
189    driinfo_h_template = mako.template.Template("""\
190 // DO NOT EDIT - this file is automatically generated by merge_driinfo.py
191
192 /*
193 Use as:
194
195 #include "xmlpool.h"
196
197 static const char driinfo_xml[] =
198 #include "this_file"
199 ;
200 */
201
202 DRI_CONF_BEGIN
203 % for section in sections:
204    DRI_CONF_SECTION_${section.name}
205 % for option in section.options:
206       DRI_CONF_${option.name}(${option.defaults})
207 % endfor
208    DRI_CONF_SECTION_END
209 % endfor
210 DRI_CONF_END""")
211
212    print(driinfo_h_template.render(sections=merged_sections_list))
213    return True
214
215
216 if __name__ == '__main__':
217    if len(sys.argv) <= 1:
218       print('Missing arguments')
219       sys.exit(1)
220
221    if not main(sys.argv[1:]):
222       sys.exit(1)