isl: Bring back isl_format_layout::bpb
[mesa.git] / src / intel / isl / gen_format_layout.py
1 # encoding=utf-8
2 # Copyright © 2016 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 """Generates isl_format_layout.c."""
23
24 from __future__ import absolute_import, division, print_function
25 import argparse
26 import csv
27 import re
28 import textwrap
29
30 from mako import template
31
32 # Load the template, ensure that __future__.division is imported, and set the
33 # bytes encoding to be utf-8. This last bit is important to getting simple
34 # consistent behavior for python 3 when we get there.
35 TEMPLATE = template.Template(
36 text=textwrap.dedent("""\
37 /* This file is autogenerated by gen_format_layout.py. DO NOT EDIT! */
38
39 /*
40 * Copyright 2015 Intel Corporation
41 *
42 * Permission is hereby granted, free of charge, to any person obtaining a
43 * copy of this software and associated documentation files (the "Software"),
44 * to deal in the Software without restriction, including without limitation
45 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
46 * and/or sell copies of the Software, and to permit persons to whom the
47 * Software is furnished to do so, subject to the following conditions:
48 *
49 * The above copyright notice and this permission notice (including the next
50 * paragraph) shall be included in all copies or substantial portions of the
51 * Software.
52 *
53 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
56 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
58 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
59 * IN THE SOFTWARE.
60 */
61
62 #include "isl.h"
63
64 const struct isl_format_layout
65 isl_format_layouts[] = {
66 % for format in formats:
67 [ISL_FORMAT_${format.name}] = {
68 .format = ISL_FORMAT_${format.name},
69 .name = "ISL_FORMAT_${format.name}",
70 .bpb = ${format.bpb},
71 .bs = ${format.bpb // 8},
72 .bw = ${format.bw},
73 .bh = ${format.bh},
74 .bd = ${format.bd},
75 .channels = {
76 % for mask in ['r', 'g', 'b', 'a', 'l', 'i', 'p']:
77 <% channel = getattr(format, mask, None) %>\\
78 % if channel.type is not None:
79 .${mask} = { ISL_${channel.type}, ${channel.size} },
80 % else:
81 .${mask} = {},
82 % endif
83 % endfor
84 },
85 .colorspace = ISL_COLORSPACE_${format.colorspace},
86 .txc = ISL_TXC_${format.txc},
87 },
88
89 % endfor
90 };
91 """),
92 future_imports=['division'],
93 output_encoding='utf-8')
94
95
96 class Channel(object):
97 """Class representing a Channel.
98
99 Converts the csv encoded data into the format that the template (and thus
100 the consuming C code) expects.
101
102 """
103 # If the csv file grew very large this class could be put behind a factory
104 # to increase efficiency. Right now though it's fast enough that It didn't
105 # seem worthwhile to add all of the boilerplate
106 _types = {
107 'x': 'void',
108 'r': 'raw',
109 'un': 'unorm',
110 'sn': 'snorm',
111 'uf': 'ufloat',
112 'sf': 'sfloat',
113 'ux': 'ufixed',
114 'sx': 'sfixed',
115 'ui': 'uint',
116 'si': 'sint',
117 'us': 'uscaled',
118 'ss': 'sscaled',
119 }
120 _splitter = re.compile(r'\s*(?P<type>[a-z]+)(?P<size>[0-9]+)')
121
122 def __init__(self, line):
123 # If the line is just whitespace then just set everything to None to
124 # save on the regex cost and let the template skip on None.
125 if line.isspace():
126 self.size = None
127 self.type = None
128 else:
129 grouped = self._splitter.match(line)
130 self.type = self._types[grouped.group('type')].upper()
131 self.size = grouped.group('size')
132
133
134 class Format(object):
135 """Class taht contains all values needed by the template."""
136 def __init__(self, line):
137 # pylint: disable=invalid-name
138 self.name = line[0].strip()
139
140 # Future division makes this work in python 2.
141 self.bpb = int(line[1])
142 self.bw = line[2].strip()
143 self.bh = line[3].strip()
144 self.bd = line[4].strip()
145 self.r = Channel(line[5])
146 self.g = Channel(line[6])
147 self.b = Channel(line[7])
148 self.a = Channel(line[8])
149 self.l = Channel(line[9])
150 self.i = Channel(line[10])
151 self.p = Channel(line[11])
152
153 # alpha doesn't have a colorspace of it's own.
154 self.colorspace = line[12].strip().upper()
155 if self.colorspace in ['', 'ALPHA']:
156 self.colorspace = 'NONE'
157
158 # This sets it to the line value, or if it's an empty string 'NONE'
159 self.txc = line[13].strip().upper() or 'NONE'
160
161
162 def reader(csvfile):
163 """Wrapper around csv.reader that skips comments and blanks."""
164 # csv.reader actually reads the file one line at a time (it was designed to
165 # open excel generated sheets), so hold the file until all of the lines are
166 # read.
167 with open(csvfile, 'r') as f:
168 for line in csv.reader(f):
169 if line and not line[0].startswith('#'):
170 yield line
171
172
173 def main():
174 """Main function."""
175 parser = argparse.ArgumentParser()
176 parser.add_argument('--csv', action='store', help='The CSV file to parse.')
177 parser.add_argument(
178 '--out',
179 action='store',
180 help='The location to put the generated C file.')
181 args = parser.parse_args()
182
183 # This generator opens and writes the file itself, and it does so in bytes
184 # mode. This solves both python 2 vs 3 problems and solves the locale
185 # problem: Unicode can be rendered even if the shell calling this script
186 # doesn't.
187 with open(args.out, 'wb') as f:
188 try:
189 # This basically does lazy evaluation and initialization, which
190 # saves on memory and startup overhead.
191 f.write(TEMPLATE.render(
192 formats=(Format(l) for l in reader(args.csv))))
193 except Exception:
194 # In the even there's an error this imports some helpers from mako
195 # to print a useful stack trace and prints it, then exits with
196 # status 1, if python is run with debug; otherwise it just raises
197 # the exception
198 if __debug__:
199 import sys
200 from mako import exceptions
201 print(exceptions.text_error_template().render(),
202 file=sys.stderr)
203 sys.exit(1)
204 raise
205
206
207 if __name__ == '__main__':
208 main()