mesa/src/intel/isl/gen_format_layout.py

208 lines
7.8 KiB
Python

# 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<type>[a-z]+)(?P<size>[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()