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/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 .bw = ${format.bw}, 72 .bh = ${format.bh}, 73 .bd = ${format.bd}, 74 .channels = { 75 % for mask in ['r', 'g', 'b', 'a', 'l', 'i', 'p']: 76 <% channel = getattr(format, mask, None) %>\\ 77 % if channel.type is not None: 78 .${mask} = { ISL_${channel.type}, ${channel.size} }, 79 % else: 80 .${mask} = {}, 81 % endif 82 % endfor 83 }, 84 .colorspace = ISL_COLORSPACE_${format.colorspace}, 85 .txc = ISL_TXC_${format.txc}, 86 }, 87 88 % endfor 89 }; 90 """), 91 future_imports=['division'], 92 output_encoding='utf-8') 93 94 95 class Channel(object): 96 """Class representing a Channel. 97 98 Converts the csv encoded data into the format that the template (and thus 99 the consuming C code) expects. 100 101 """ 102 # If the csv file grew very large this class could be put behind a factory 103 # to increase efficiency. Right now though it's fast enough that It didn't 104 # seem worthwhile to add all of the boilerplate 105 _types = { 106 'x': 'void', 107 'r': 'raw', 108 'un': 'unorm', 109 'sn': 'snorm', 110 'uf': 'ufloat', 111 'sf': 'sfloat', 112 'ux': 'ufixed', 113 'sx': 'sfixed', 114 'ui': 'uint', 115 'si': 'sint', 116 'us': 'uscaled', 117 'ss': 'sscaled', 118 } 119 _splitter = re.compile(r'\s*(?P<type>[a-z]+)(?P<size>[0-9]+)') 120 121 def __init__(self, line): 122 # If the line is just whitespace then just set everything to None to 123 # save on the regex cost and let the template skip on None. 124 if line.isspace(): 125 self.size = None 126 self.type = None 127 else: 128 grouped = self._splitter.match(line) 129 self.type = self._types[grouped.group('type')].upper() 130 self.size = grouped.group('size') 131 132 133 class Format(object): 134 """Class taht contains all values needed by the template.""" 135 def __init__(self, line): 136 # pylint: disable=invalid-name 137 self.name = line[0].strip() 138 139 # Future division makes this work in python 2. 140 self.bpb = int(line[1]) 141 self.bw = line[2].strip() 142 self.bh = line[3].strip() 143 self.bd = line[4].strip() 144 self.r = Channel(line[5]) 145 self.g = Channel(line[6]) 146 self.b = Channel(line[7]) 147 self.a = Channel(line[8]) 148 self.l = Channel(line[9]) 149 self.i = Channel(line[10]) 150 self.p = Channel(line[11]) 151 152 # alpha doesn't have a colorspace of it's own. 153 self.colorspace = line[12].strip().upper() 154 if self.colorspace in ['', 'ALPHA']: 155 self.colorspace = 'NONE' 156 157 # This sets it to the line value, or if it's an empty string 'NONE' 158 self.txc = line[13].strip().upper() or 'NONE' 159 160 161 def reader(csvfile): 162 """Wrapper around csv.reader that skips comments and blanks.""" 163 # csv.reader actually reads the file one line at a time (it was designed to 164 # open excel generated sheets), so hold the file until all of the lines are 165 # read. 166 with open(csvfile, 'r') as f: 167 for line in csv.reader(f): 168 if line and not line[0].startswith('#'): 169 yield line 170 171 172 def main(): 173 """Main function.""" 174 parser = argparse.ArgumentParser() 175 parser.add_argument('--csv', action='store', help='The CSV file to parse.') 176 parser.add_argument( 177 '--out', 178 action='store', 179 help='The location to put the generated C file.') 180 args = parser.parse_args() 181 182 # This generator opens and writes the file itself, and it does so in bytes 183 # mode. This solves both python 2 vs 3 problems and solves the locale 184 # problem: Unicode can be rendered even if the shell calling this script 185 # doesn't. 186 with open(args.out, 'wb') as f: 187 try: 188 # This basically does lazy evaluation and initialization, which 189 # saves on memory and startup overhead. 190 f.write(TEMPLATE.render( 191 formats=(Format(l) for l in reader(args.csv)))) 192 except Exception: 193 # In the even there's an error this imports some helpers from mako 194 # to print a useful stack trace and prints it, then exits with 195 # status 1, if python is run with debug; otherwise it just raises 196 # the exception 197 if __debug__: 198 import sys 199 from mako import exceptions 200 print(exceptions.text_error_template().render(), 201 file=sys.stderr) 202 sys.exit(1) 203 raise 204 205 206 if __name__ == '__main__': 207 main() 208