• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 Collabora Ltd.
2# SPDX-License-Identifier: MIT
3
4"""Generates nil_format_table.c"""
5
6import argparse
7import csv
8import os
9
10from mako import template
11
12TEMPLATE_H = template.Template(text="""\
13/* Copyright 2024 Collabora Ltd.
14 * SPDX-License-Identifier: MIT
15 */
16
17#ifndef ${guard}
18#define ${guard}
19
20#include "util/format/u_format.h"
21
22enum nil_format_support_flags {
23   NIL_FORMAT_SUPPORTS_TEXTURE_BIT        = BITFIELD_BIT(0),
24   NIL_FORMAT_SUPPORTS_BUFFER_BIT         = BITFIELD_BIT(1),
25   NIL_FORMAT_SUPPORTS_STORAGE_BIT        = BITFIELD_BIT(2),
26   NIL_FORMAT_SUPPORTS_RENDER_BIT         = BITFIELD_BIT(3),
27   NIL_FORMAT_SUPPORTS_ALPHA_BLEND_BIT    = BITFIELD_BIT(4),
28   NIL_FORMAT_SUPPORTS_DEPTH_STENCIL_BIT  = BITFIELD_BIT(5),
29   NIL_FORMAT_SUPPORTS_SCANOUT_BIT        = BITFIELD_BIT(6),
30};
31
32struct nil_tic_format {
33   unsigned comp_sizes:8;
34   unsigned type_r:3;
35   unsigned type_g:3;
36   unsigned type_b:3;
37   unsigned type_a:3;
38   unsigned src_x:3;
39   unsigned src_y:3;
40   unsigned src_z:3;
41   unsigned src_w:3;
42};
43
44struct nil_format_info {
45   unsigned czt:8;
46   unsigned support:24;
47   struct nil_tic_format tic;
48};
49
50extern const struct nil_format_info nil_format_table[PIPE_FORMAT_COUNT];
51
52#endif /* ${guard} */
53""");
54
55TEMPLATE_C = template.Template(text="""\
56/* Copyright 2024 Collabora Ltd.
57 * SPDX-License-Identifier: MIT
58 */
59
60/* This file is autogenerated by nil_format_table_gen.py. DO NOT EDIT! */
61
62#include "nil_format_table.h"
63
64#include "cl9097.h"
65#include "cl9097tex.h"
66#include "clb097.h"
67#include "clb097tex.h"
68#include "clb197.h"
69#include "clb197tex.h"
70
71const struct nil_format_info nil_format_table[PIPE_FORMAT_COUNT] = {
72% for f in formats:
73    [PIPE_FORMAT_${f.pipe}] = {
74        .czt = ${f.czt()},
75        .support = ${f.support()},
76        .tic = {
77            .comp_sizes = ${f.tcs()},
78            .type_r = ${f.type(0)},
79            .type_g = ${f.type(1)},
80            .type_b = ${f.type(2)},
81            .type_a = ${f.type(3)},
82            .src_x = ${f.src(0)},
83            .src_y = ${f.src(1)},
84            .src_z = ${f.src(2)},
85            .src_w = ${f.src(3)},
86        },
87    },
88% endfor
89};
90""");
91
92CT_FORMAT_PREFIX = {
93    None        : 'NV9097_SET_COLOR_TARGET_FORMAT_V_',
94    'maxwella'  : 'NVB097_SET_COLOR_TARGET_FORMAT_V_',
95    'tk1'       : 'NVB097_SET_COLOR_TARGET_FORMAT_V_',
96}
97
98ZT_FORMAT_PREFIX = {
99    None        : 'NV9097_SET_ZT_FORMAT_V_',
100    'maxwella'  : 'NVB097_SET_ZT_FORMAT_V_',
101    'maxwellb'  : 'NVB197_SET_ZT_FORMAT_V_',
102    'tk1'       : 'NVB097_SET_ZT_FORMAT_V_',
103}
104
105TCS_PREFIX = {
106    None        : 'NV9097_TEXHEADV2_0_COMPONENT_SIZES_',
107    'maxwella'  : 'NVB097_TEXHEAD_BL_COMPONENTS_SIZES_',
108    'maxwellb'  : 'NVB197_TEXHEAD_BL_COMPONENTS_SIZES_',
109    'tk1'       : 'NVB097_TEXHEAD_BL_COMPONENTS_SIZES_',
110}
111
112DATA_TYPES = {
113    'S' : 'NV9097_TEXHEADV2_0_R_DATA_TYPE_NUM_SNORM',
114    'N' : 'NV9097_TEXHEADV2_0_R_DATA_TYPE_NUM_UNORM',
115    'I' : 'NV9097_TEXHEADV2_0_R_DATA_TYPE_NUM_SINT',
116    'U' : 'NV9097_TEXHEADV2_0_R_DATA_TYPE_NUM_UINT',
117    'F' : 'NV9097_TEXHEADV2_0_R_DATA_TYPE_NUM_FLOAT',
118}
119
120SOURCES = {
121    '0' : 'NV9097_TEXHEADV2_0_Z_SOURCE_IN_ZERO',
122    'R' : 'NV9097_TEXHEADV2_0_Z_SOURCE_IN_R',
123    'G' : 'NV9097_TEXHEADV2_0_Z_SOURCE_IN_G',
124    'B' : 'NV9097_TEXHEADV2_0_Z_SOURCE_IN_B',
125    'A' : 'NV9097_TEXHEADV2_0_Z_SOURCE_IN_A',
126    '1' : 'NV9097_TEXHEADV2_0_Z_SOURCE_IN_ONE',
127}
128
129SUPPORT_FLAGS = {
130    'T' : 'NIL_FORMAT_SUPPORTS_TEXTURE_BIT',
131    'B' : 'NIL_FORMAT_SUPPORTS_BUFFER_BIT',
132    'S' : 'NIL_FORMAT_SUPPORTS_STORAGE_BIT',
133    'C' : 'NIL_FORMAT_SUPPORTS_RENDER_BIT',
134    'A' : 'NIL_FORMAT_SUPPORTS_ALPHA_BLEND_BIT',
135    'Z' : 'NIL_FORMAT_SUPPORTS_DEPTH_STENCIL_BIT',
136    'D' : 'NIL_FORMAT_SUPPORTS_SCANOUT_BIT',
137}
138
139class Format(object):
140    def __init__(self, line):
141        self.pipe = line[0].strip()
142        self._czt = line[1].strip()
143        self._tcs = line[2].strip()
144        self._types = list(line[3].strip())
145        self._srcs = list(line[4].strip())
146        self._support = list(line[5].strip())
147        if len(line) > 6:
148            self.hw = line[6].strip().lower()
149        else:
150            self.hw = None
151
152    def czt(self):
153        if self._czt == 'NONE':
154            return CT_FORMAT_PREFIX[self.hw] + 'DISABLED'
155        elif 'Z' in self._support:
156            return ZT_FORMAT_PREFIX[self.hw] + self._czt
157        else:
158            return CT_FORMAT_PREFIX[self.hw] + self._czt
159
160    def support(self):
161        return ' | '.join(SUPPORT_FLAGS[f] for f in self._support)
162
163    def tcs(self):
164        return TCS_PREFIX[self.hw] + self._tcs
165
166    def type(self, comp):
167        if comp < len(self._types):
168            return DATA_TYPES[self._types[comp]]
169        else:
170            return DATA_TYPES[self._types[0]]
171
172    def src(self, comp):
173        if self._srcs[comp] == '1':
174            # Find any component which isn't a 0/1 and look at that
175            # component's data type to determine whether or not 1 is an
176            # integer.
177            for s in self._srcs:
178                c = 'RGBA'.find(s)
179                if c >= 0:
180                    if self._types[c] in 'SNF':
181                        return SOURCES['1'] + '_FLOAT'
182                    else:
183                        return SOURCES['1'] + '_INT'
184            assert False, self.pipe + ': Failed to find non-constant component'
185        else:
186            c = 'RGBA'.find(self._srcs[comp])
187            assert c < len(self._types), self.pipe + ': Swizzle is out of bounds'
188            return SOURCES[self._srcs[comp]]
189
190def reader(csvfile):
191    """Wrapper around csv.reader that skips comments and blanks."""
192    # csv.reader actually reads the file one line at a time (it was designed to
193    # open excel generated sheets), so hold the file until all of the lines are
194    # read.
195    with open(csvfile, 'r') as f:
196        for line in csv.reader(f):
197            if line and not line[0].startswith('#'):
198                yield line
199
200def main():
201    """Main function."""
202    parser = argparse.ArgumentParser()
203    parser.add_argument('--csv', action='store', help='The CSV file to parse.')
204    parser.add_argument('--out-c', required=True, help='Output C file.')
205    parser.add_argument('--out-h', required=True, help='Output H file.')
206    args = parser.parse_args()
207
208    formats = [Format(l) for l in reader(args.csv)]
209
210    try:
211        with open(args.out_h, 'w', encoding='utf-8') as f:
212            guard = os.path.basename(args.out_h).replace('.', '_').upper()
213            f.write(TEMPLATE_H.render(guard=guard))
214        with open(args.out_c, 'w', encoding='utf-8') as f:
215            f.write(TEMPLATE_C.render(formats=formats))
216
217    except Exception:
218        # In the event there's an error, this imports some helpers from mako
219        # to print a useful stack trace and prints it, then exits with
220        # status 1, if python is run with debug; otherwise it just raises
221        # the exception
222        import sys
223        from mako import exceptions
224        print(exceptions.text_error_template().render(), file=sys.stderr)
225        sys.exit(1)
226
227if __name__ == '__main__':
228    main()
229