Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/intel/genxml/gen_bits_header.py
7086 views
1
#encoding=utf-8
2
# Copyright © 2017 Intel Corporation
3
4
# Permission is hereby granted, free of charge, to any person obtaining a copy
5
# of this software and associated documentation files (the "Software"), to deal
6
# in the Software without restriction, including without limitation the rights
7
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
# copies of the Software, and to permit persons to whom the Software is
9
# furnished to do so, subject to the following conditions:
10
11
# The above copyright notice and this permission notice shall be included in
12
# all copies or substantial portions of the Software.
13
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
# SOFTWARE.
21
22
from __future__ import (
23
absolute_import, division, print_function, unicode_literals
24
)
25
26
import argparse
27
import os
28
import xml.parsers.expat
29
30
from mako.template import Template
31
from util import *
32
33
TEMPLATE = Template("""\
34
<%!
35
from operator import itemgetter
36
%>\
37
/*
38
* Copyright © 2017 Intel Corporation
39
*
40
* Permission is hereby granted, free of charge, to any person obtaining a
41
* copy of this software and associated documentation files (the "Software"),
42
* to deal in the Software without restriction, including without limitation
43
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
44
* and/or sell copies of the Software, and to permit persons to whom the
45
* Software is furnished to do so, subject to the following conditions:
46
*
47
* The above copyright notice and this permission notice (including the next
48
* paragraph) shall be included in all copies or substantial portions of the
49
* Software.
50
*
51
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
54
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
56
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
57
* IN THE SOFTWARE.
58
*/
59
60
/* THIS FILE HAS BEEN GENERATED, DO NOT HAND EDIT.
61
*
62
* Sizes of bitfields in genxml instructions, structures, and registers.
63
*/
64
65
#ifndef ${guard}
66
#define ${guard}
67
68
#include <stdint.h>
69
70
#include "dev/intel_device_info.h"
71
#include "util/macros.h"
72
73
<%def name="emit_per_gen_prop_func(item, prop)">
74
%if item.has_prop(prop):
75
% for gen, value in sorted(item.iter_prop(prop), reverse=True):
76
#define ${gen.prefix(item.token_name)}_${prop} ${value}
77
% endfor
78
79
static inline uint32_t ATTRIBUTE_PURE
80
${item.token_name}_${prop}(const struct intel_device_info *devinfo)
81
{
82
switch (devinfo->verx10) {
83
case 125: return ${item.get_prop(prop, 12.5)};
84
case 120: return ${item.get_prop(prop, 12)};
85
case 110: return ${item.get_prop(prop, 11)};
86
case 90: return ${item.get_prop(prop, 9)};
87
case 80: return ${item.get_prop(prop, 8)};
88
case 75: return ${item.get_prop(prop, 7.5)};
89
case 70: return ${item.get_prop(prop, 7)};
90
case 60: return ${item.get_prop(prop, 6)};
91
case 50: return ${item.get_prop(prop, 5)};
92
case 45: return ${item.get_prop(prop, 4.5)};
93
case 40: return ${item.get_prop(prop, 4)};
94
default:
95
unreachable("Invalid hardware generation");
96
}
97
}
98
%endif
99
</%def>
100
101
#ifdef __cplusplus
102
extern "C" {
103
#endif
104
% for _, container in sorted(containers.items(), key=itemgetter(0)):
105
106
/* ${container.name} */
107
108
${emit_per_gen_prop_func(container, 'length')}
109
110
% for _, field in sorted(container.fields.items(), key=itemgetter(0)):
111
112
/* ${container.name}::${field.name} */
113
114
${emit_per_gen_prop_func(field, 'bits')}
115
116
${emit_per_gen_prop_func(field, 'start')}
117
118
% endfor
119
% endfor
120
121
#ifdef __cplusplus
122
}
123
#endif
124
125
#endif /* ${guard} */""", output_encoding='utf-8')
126
127
class Gen(object):
128
129
def __init__(self, z):
130
# Convert potential "major.minor" string
131
self.tenx = int(float(z) * 10)
132
133
def __lt__(self, other):
134
return self.tenx < other.tenx
135
136
def __hash__(self):
137
return hash(self.tenx)
138
139
def __eq__(self, other):
140
return self.tenx == other.tenx
141
142
def prefix(self, token):
143
gen = self.tenx
144
145
if gen % 10 == 0:
146
gen //= 10
147
148
if token[0] == '_':
149
token = token[1:]
150
151
return 'GFX{}_{}'.format(gen, token)
152
153
class Container(object):
154
155
def __init__(self, name):
156
self.name = name
157
self.token_name = safe_name(name)
158
self.length_by_gen = {}
159
self.fields = {}
160
161
def add_gen(self, gen, xml_attrs):
162
assert isinstance(gen, Gen)
163
if 'length' in xml_attrs:
164
self.length_by_gen[gen] = xml_attrs['length']
165
166
def get_field(self, field_name, create=False):
167
key = to_alphanum(field_name)
168
if key not in self.fields:
169
if create:
170
self.fields[key] = Field(self, field_name)
171
else:
172
return None
173
return self.fields[key]
174
175
def has_prop(self, prop):
176
if prop == 'length':
177
return bool(self.length_by_gen)
178
else:
179
raise ValueError('Invalid property: "{0}"'.format(prop))
180
181
def iter_prop(self, prop):
182
if prop == 'length':
183
return self.length_by_gen.items()
184
else:
185
raise ValueError('Invalid property: "{0}"'.format(prop))
186
187
def get_prop(self, prop, gen):
188
if not isinstance(gen, Gen):
189
gen = Gen(gen)
190
191
if prop == 'length':
192
return self.length_by_gen.get(gen, 0)
193
else:
194
raise ValueError('Invalid property: "{0}"'.format(prop))
195
196
class Field(object):
197
198
def __init__(self, container, name):
199
self.name = name
200
self.token_name = safe_name('_'.join([container.name, self.name]))
201
self.bits_by_gen = {}
202
self.start_by_gen = {}
203
204
def add_gen(self, gen, xml_attrs):
205
assert isinstance(gen, Gen)
206
start = int(xml_attrs['start'])
207
end = int(xml_attrs['end'])
208
self.start_by_gen[gen] = start
209
self.bits_by_gen[gen] = 1 + end - start
210
211
def has_prop(self, prop):
212
return True
213
214
def iter_prop(self, prop):
215
if prop == 'bits':
216
return self.bits_by_gen.items()
217
elif prop == 'start':
218
return self.start_by_gen.items()
219
else:
220
raise ValueError('Invalid property: "{0}"'.format(prop))
221
222
def get_prop(self, prop, gen):
223
if not isinstance(gen, Gen):
224
gen = Gen(gen)
225
226
if prop == 'bits':
227
return self.bits_by_gen.get(gen, 0)
228
elif prop == 'start':
229
return self.start_by_gen.get(gen, 0)
230
else:
231
raise ValueError('Invalid property: "{0}"'.format(prop))
232
233
class XmlParser(object):
234
235
def __init__(self, containers):
236
self.parser = xml.parsers.expat.ParserCreate()
237
self.parser.StartElementHandler = self.start_element
238
self.parser.EndElementHandler = self.end_element
239
240
self.gen = None
241
self.containers = containers
242
self.container_stack = []
243
self.container_stack.append(None)
244
245
def parse(self, filename):
246
with open(filename, 'rb') as f:
247
self.parser.ParseFile(f)
248
249
def start_element(self, name, attrs):
250
if name == 'genxml':
251
self.gen = Gen(attrs['gen'])
252
elif name in ('instruction', 'struct', 'register'):
253
if name == 'instruction' and 'engine' in attrs:
254
engines = set(attrs['engine'].split('|'))
255
if not engines & self.engines:
256
self.container_stack.append(None)
257
return
258
self.start_container(attrs)
259
elif name == 'group':
260
self.container_stack.append(None)
261
elif name == 'field':
262
self.start_field(attrs)
263
else:
264
pass
265
266
def end_element(self, name):
267
if name == 'genxml':
268
self.gen = None
269
elif name in ('instruction', 'struct', 'register', 'group'):
270
self.container_stack.pop()
271
else:
272
pass
273
274
def start_container(self, attrs):
275
assert self.container_stack[-1] is None
276
name = attrs['name']
277
if name not in self.containers:
278
self.containers[name] = Container(name)
279
self.container_stack.append(self.containers[name])
280
self.container_stack[-1].add_gen(self.gen, attrs)
281
282
def start_field(self, attrs):
283
if self.container_stack[-1] is None:
284
return
285
286
field_name = attrs.get('name', None)
287
if not field_name:
288
return
289
290
self.container_stack[-1].get_field(field_name, True).add_gen(self.gen, attrs)
291
292
def parse_args():
293
p = argparse.ArgumentParser()
294
p.add_argument('-o', '--output', type=str,
295
help="If OUTPUT is unset or '-', then it defaults to '/dev/stdout'")
296
p.add_argument('--cpp-guard', type=str,
297
help='If unset, then CPP_GUARD is derived from OUTPUT.')
298
p.add_argument('--engines', nargs='?', type=str, default='render',
299
help="Comma-separated list of engines whose instructions should be parsed (default: %(default)s)")
300
p.add_argument('xml_sources', metavar='XML_SOURCE', nargs='+')
301
302
pargs = p.parse_args()
303
304
if pargs.output in (None, '-'):
305
pargs.output = '/dev/stdout'
306
307
if pargs.cpp_guard is None:
308
pargs.cpp_guard = os.path.basename(pargs.output).upper().replace('.', '_')
309
310
return pargs
311
312
def main():
313
pargs = parse_args()
314
315
engines = pargs.engines.split(',')
316
valid_engines = [ 'render', 'blitter', 'video' ]
317
if set(engines) - set(valid_engines):
318
print("Invalid engine specified, valid engines are:\n")
319
for e in valid_engines:
320
print("\t%s" % e)
321
sys.exit(1)
322
323
# Maps name => Container
324
containers = {}
325
326
for source in pargs.xml_sources:
327
p = XmlParser(containers)
328
p.engines = set(engines)
329
p.parse(source)
330
331
with open(pargs.output, 'wb') as f:
332
f.write(TEMPLATE.render(containers=containers, guard=pargs.cpp_guard))
333
334
if __name__ == '__main__':
335
main()
336
337