# encoding=utf-8 # Copyright © 2016 Intel Corporation # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """Generates isl_format_layout.c.""" from __future__ import absolute_import, division, print_function import argparse import csv import re import textwrap from mako import template # Load the template, ensure that __future__.division is imported, and set the # bytes encoding to be utf-8. This last bit is important to getting simple # consistent behavior for python 3 when we get there. TEMPLATE = template.Template( text=textwrap.dedent("""\ /* This file is autogenerated by gen_format_layout.py. DO NOT EDIT! */ /* * Copyright 2015 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "isl/isl.h" const struct isl_format_layout isl_format_layouts[] = { % for format in formats: [ISL_FORMAT_${format.name}] = { .format = ISL_FORMAT_${format.name}, .name = "ISL_FORMAT_${format.name}", .bpb = ${format.bpb}, .bw = ${format.bw}, .bh = ${format.bh}, .bd = ${format.bd}, .channels = { % for mask in ['r', 'g', 'b', 'a', 'l', 'i', 'p']: <% channel = getattr(format, mask, None) %>\\ % if channel.type is not None: .${mask} = { ISL_${channel.type}, ${channel.size} }, % else: .${mask} = {}, % endif % endfor }, .colorspace = ISL_COLORSPACE_${format.colorspace}, .txc = ISL_TXC_${format.txc}, }, % endfor }; """), future_imports=['division'], output_encoding='utf-8') class Channel(object): """Class representing a Channel. Converts the csv encoded data into the format that the template (and thus the consuming C code) expects. """ # If the csv file grew very large this class could be put behind a factory # to increase efficiency. Right now though it's fast enough that It didn't # seem worthwhile to add all of the boilerplate _types = { 'x': 'void', 'r': 'raw', 'un': 'unorm', 'sn': 'snorm', 'uf': 'ufloat', 'sf': 'sfloat', 'ux': 'ufixed', 'sx': 'sfixed', 'ui': 'uint', 'si': 'sint', 'us': 'uscaled', 'ss': 'sscaled', } _splitter = re.compile(r'\s*(?P[a-z]+)(?P[0-9]+)') def __init__(self, line): # If the line is just whitespace then just set everything to None to # save on the regex cost and let the template skip on None. if line.isspace(): self.size = None self.type = None else: grouped = self._splitter.match(line) self.type = self._types[grouped.group('type')].upper() self.size = grouped.group('size') class Format(object): """Class taht contains all values needed by the template.""" def __init__(self, line): # pylint: disable=invalid-name self.name = line[0].strip() # Future division makes this work in python 2. self.bpb = int(line[1]) self.bw = line[2].strip() self.bh = line[3].strip() self.bd = line[4].strip() self.r = Channel(line[5]) self.g = Channel(line[6]) self.b = Channel(line[7]) self.a = Channel(line[8]) self.l = Channel(line[9]) self.i = Channel(line[10]) self.p = Channel(line[11]) # alpha doesn't have a colorspace of it's own. self.colorspace = line[12].strip().upper() if self.colorspace in ['', 'ALPHA']: self.colorspace = 'NONE' # This sets it to the line value, or if it's an empty string 'NONE' self.txc = line[13].strip().upper() or 'NONE' def reader(csvfile): """Wrapper around csv.reader that skips comments and blanks.""" # csv.reader actually reads the file one line at a time (it was designed to # open excel generated sheets), so hold the file until all of the lines are # read. with open(csvfile, 'r') as f: for line in csv.reader(f): if line and not line[0].startswith('#'): yield line def main(): """Main function.""" parser = argparse.ArgumentParser() parser.add_argument('--csv', action='store', help='The CSV file to parse.') parser.add_argument( '--out', action='store', help='The location to put the generated C file.') args = parser.parse_args() # This generator opens and writes the file itself, and it does so in bytes # mode. This solves both python 2 vs 3 problems and solves the locale # problem: Unicode can be rendered even if the shell calling this script # doesn't. with open(args.out, 'wb') as f: try: # This basically does lazy evaluation and initialization, which # saves on memory and startup overhead. f.write(TEMPLATE.render( formats=(Format(l) for l in reader(args.csv)))) except Exception: # In the even there's an error this imports some helpers from mako # to print a useful stack trace and prints it, then exits with # status 1, if python is run with debug; otherwise it just raises # the exception if __debug__: import sys from mako import exceptions print(exceptions.text_error_template().render(), file=sys.stderr) sys.exit(1) raise if __name__ == '__main__': main()