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