1CopyRight = ''' 2/************************************************************************** 3 * 4 * Copyright 2010 VMware, Inc. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28''' 29 30 31import sys, os 32 33from u_format_parse import * 34import u_format_pack 35 36 37def layout_map(layout): 38 return 'UTIL_FORMAT_LAYOUT_' + str(layout).upper() 39 40 41def colorspace_map(colorspace): 42 return 'UTIL_FORMAT_COLORSPACE_' + str(colorspace).upper() 43 44colorspace_channels_map = { 45 'RGB': ['r', 'g', 'b', 'a'], 46 'SRGB': ['sr', 'sg', 'sb', 'a'], 47 'ZS': ['z', 's'], 48 'YUV': ['y', 'u', 'v'], 49} 50 51 52type_map = { 53 VOID: "UTIL_FORMAT_TYPE_VOID", 54 UNSIGNED: "UTIL_FORMAT_TYPE_UNSIGNED", 55 SIGNED: "UTIL_FORMAT_TYPE_SIGNED", 56 FIXED: "UTIL_FORMAT_TYPE_FIXED", 57 FLOAT: "UTIL_FORMAT_TYPE_FLOAT", 58} 59 60 61def bool_map(value): 62 if value: 63 return "true" 64 else: 65 return "false" 66 67 68swizzle_map = { 69 SWIZZLE_X: "PIPE_SWIZZLE_X", 70 SWIZZLE_Y: "PIPE_SWIZZLE_Y", 71 SWIZZLE_Z: "PIPE_SWIZZLE_Z", 72 SWIZZLE_W: "PIPE_SWIZZLE_W", 73 SWIZZLE_0: "PIPE_SWIZZLE_0", 74 SWIZZLE_1: "PIPE_SWIZZLE_1", 75 SWIZZLE_NONE: "PIPE_SWIZZLE_NONE", 76} 77 78def has_access(format): 79 # We don't generate code for YUV formats, and many of the new ones lack 80 # pack/unpack functions for softpipe/llvmpipe. 81 noaccess_formats = [ 82 'r1_unorm', 83 'yv12', 84 'yv16', 85 'iyuv', 86 'nv12', 87 'nv16', 88 'nv21', 89 'nv15', 90 'nv20', 91 'p010', 92 'p012', 93 'p016', 94 'p030', 95 'y210', 96 'y212', 97 'y216', 98 'y410', 99 'y412', 100 'y416', 101 'xyuv', 102 'ayuv', 103 'r8g8_r8b8_unorm', 104 'r8b8_r8g8_unorm', 105 'g8r8_b8r8_unorm', 106 'b8r8_g8r8_unorm', 107 'g8r8_g8b8_unorm', 108 'g8b8_g8r8_unorm', 109 'b8g8_r8g8_unorm', 110 'x6g10_x6b10x6r10_420_unorm', 111 'x4g12_x4b12x4r12_420_unorm', 112 'y8_400_unorm', 113 'y8_u8_v8_422_unorm', 114 'y8_u8_v8_444_unorm', 115 'y8_u8_v8_440_unorm', 116 'y16_u16_v16_420_unorm', 117 'y16_u16_v16_422_unorm', 118 'y16_u16v16_422_unorm', 119 'y16_u16_v16_444_unorm', 120 'r8_g8b8_420_unorm', 121 'r8_b8g8_420_unorm', 122 'g8_b8r8_420_unorm', 123 'r8_g8b8_422_unorm', 124 'r10_g10b10_420_unorm', 125 'r10_g10b10_422_unorm', 126 'r8_g8_b8_420_unorm', 127 'r8_b8_g8_420_unorm', 128 'g8_b8_r8_420_unorm', 129 'r8_g8_b8_unorm', 130 'y8_unorm', 131 ] 132 if format.short_name() in noaccess_formats: 133 return False 134 if format.layout in ('astc', 'atc'): 135 return False 136 if format.layout == 'etc' and format.short_name() != 'etc1_rgb8': 137 return False 138 return True 139 140def write_format_table_header(file): 141 print('/* This file is autogenerated by u_format_table.py from u_format.yaml. Do not edit directly. */', file=file) 142 print(file=file) 143 # This will print the copyright message on the top of this file 144 print(CopyRight.strip(), file=file) 145 print(file=file) 146 147def write_format_aliases(formats): 148 print("#if UTIL_ARCH_LITTLE_ENDIAN", file=sys.stdout3) 149 for f in formats: 150 if f.le_alias: 151 print("#define %s %s" % (f.le_alias, f.name), file=sys.stdout3) 152 print("#elif UTIL_ARCH_BIG_ENDIAN", file=sys.stdout3) 153 for f in formats: 154 if f.be_alias: 155 print("#define %s %s" % (f.be_alias, f.name), file=sys.stdout3) 156 print("#endif", file=sys.stdout3) 157 158 159def write_format_table(formats): 160 write_format_table_header(sys.stdout) 161 print('#include "util/format/u_format.h"') 162 print('#include "u_format_bptc.h"') 163 print('#include "u_format_fxt1.h"') 164 print('#include "u_format_s3tc.h"') 165 print('#include "u_format_rgtc.h"') 166 print('#include "u_format_latc.h"') 167 print('#include "u_format_etc.h"') 168 print() 169 170 write_format_table_header(sys.stdout2) 171 172 print('#ifdef __cplusplus', file=sys.stdout2) 173 print('extern "C" {', file=sys.stdout2) 174 print('#endif', file=sys.stdout2) 175 print('#include "util/format/u_format.h"', file=sys.stdout2) 176 print(file=sys.stdout2) 177 178 u_format_pack.generate(formats) 179 180 print('#ifdef __cplusplus', file=sys.stdout2) 181 print('} /* extern "C" */', file=sys.stdout2) 182 print('#endif', file=sys.stdout2) 183 184 185 write_format_table_header(sys.stdout3) 186 187 print('#ifdef __cplusplus', file=sys.stdout3) 188 print('extern "C" {', file=sys.stdout3) 189 print('#endif', file=sys.stdout3) 190 print(file=sys.stdout3) 191 192 write_format_aliases(formats) 193 194 print('#ifdef __cplusplus', file=sys.stdout3) 195 print('} /* extern "C" */', file=sys.stdout3) 196 print('#endif', file=sys.stdout3) 197 198 def do_channel_array(channels, swizzles): 199 print(" {") 200 for i in range(4): 201 channel = channels[i] 202 if i < 3: 203 sep = "," 204 else: 205 sep = "" 206 if channel.size: 207 print(" {%s, %s, %s, %u, %u}%s\t/* %s = %s */" % (type_map[channel.type], bool_map(channel.norm), bool_map(channel.pure), channel.size, channel.shift, sep, "xyzw"[i], channel.name)) 208 else: 209 print(" {0, 0, 0, 0, 0}%s" % (sep,)) 210 print(" },") 211 212 def do_swizzle_array(channels, swizzles): 213 print(" {") 214 for i in range(4): 215 swizzle = swizzles[i] 216 if i < 3: 217 sep = "," 218 else: 219 sep = "" 220 try: 221 comment = colorspace_channels_map[format.colorspace][i] 222 except (KeyError, IndexError): 223 comment = 'ignored' 224 print(" %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment)) 225 print(" },") 226 227 def generate_table_getter(type): 228 suffix = "" 229 if type == "unpack_": 230 suffix = "_generic" 231 print("ATTRIBUTE_RETURNS_NONNULL const struct util_format_%sdescription *" % type) 232 print("util_format_%sdescription%s(enum pipe_format format)" % (type, suffix)) 233 print("{") 234 print(" assert(format < PIPE_FORMAT_COUNT);") 235 print(" return &util_format_%sdescriptions[format];" % (type)) 236 print("}") 237 print() 238 239 def generate_function_getter(func): 240 print("util_format_%s_func_ptr" % func) 241 print("util_format_%s_func(enum pipe_format format)" % (func)) 242 print("{") 243 print(" assert(format < PIPE_FORMAT_COUNT);") 244 print(" return util_format_%s_table[format];" % (func)) 245 print("}") 246 print() 247 248 print('static const struct util_format_description') 249 print('util_format_descriptions[PIPE_FORMAT_COUNT] = {') 250 for format in formats: 251 sn = format.short_name() 252 253 print(" [%s] = {" % (format.name,)) 254 print(" .format = %s," % (format.name,)) 255 print(" .name = \"%s\"," % (format.name,)) 256 print(" .short_name = \"%s\"," % (sn,)) 257 print(" .block = {%u, %u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_depth, format.block_size())) 258 print(" .layout = %s," % (layout_map(format.layout),)) 259 print(" .nr_channels = %u,\t/* nr_channels */" % (format.nr_channels(),)) 260 print(" .is_array = %s,\t/* is_array */" % (bool_map(format.is_array()),)) 261 print(" .is_bitmask = %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),)) 262 print(" .is_mixed = %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),)) 263 print(" .is_unorm = %s,\t/* is_unorm */" % (bool_map(format.is_unorm()),)) 264 print(" .is_snorm = %s,\t/* is_snorm */" % (bool_map(format.is_snorm()),)) 265 u_format_pack.print_channels(format, do_channel_array) 266 u_format_pack.print_channels(format, do_swizzle_array) 267 print(" .colorspace = %s," % (colorspace_map(format.colorspace),)) 268 if format.srgb_equivalent: 269 print(" .srgb_equivalent = %s,\t/* srgb_equivalent */" % format.srgb_equivalent.name) 270 elif format.linear_equivalent: 271 print(" .linear_equivalent = %s,\t/* linear_equivalent */" % format.linear_equivalent.name) 272 else: 273 print(" .srgb_equivalent = PIPE_FORMAT_NONE,\t/* srgb_equivalent */") 274 print(" },") 275 print() 276 print("};") 277 print() 278 generate_table_getter("") 279 280 print('static const struct util_format_pack_description') 281 print('util_format_pack_descriptions[PIPE_FORMAT_COUNT] = {') 282 for format in formats: 283 sn = format.short_name() 284 285 if not has_access(format): 286 print(" [%s] = { 0 }," % (format.name,)) 287 continue 288 289 print(" [%s] = {" % (format.name,)) 290 if format.colorspace != ZS and not format.is_pure_color(): 291 print(" .pack_rgba_8unorm = &util_format_%s_pack_rgba_8unorm," % sn) 292 print(" .pack_rgba_float = &util_format_%s_pack_rgba_float," % sn) 293 294 if format.has_depth(): 295 print(" .pack_z_32unorm = &util_format_%s_pack_z_32unorm," % sn) 296 print(" .pack_z_float = &util_format_%s_pack_z_float," % sn) 297 298 if format.has_stencil(): 299 print(" .pack_s_8uint = &util_format_%s_pack_s_8uint," % sn) 300 301 if format.is_pure_unsigned() or format.is_pure_signed(): 302 print(" .pack_rgba_uint = &util_format_%s_pack_unsigned," % sn) 303 print(" .pack_rgba_sint = &util_format_%s_pack_signed," % sn) 304 print(" },") 305 print() 306 print("};") 307 print() 308 generate_table_getter("pack_") 309 print('static const struct util_format_unpack_description') 310 print('util_format_unpack_descriptions[PIPE_FORMAT_COUNT] = {') 311 for format in formats: 312 sn = format.short_name() 313 314 if not has_access(format): 315 print(" [%s] = { 0 }," % (format.name,)) 316 continue 317 318 print(" [%s] = {" % (format.name,)) 319 320 if format.colorspace != ZS and not format.is_pure_color(): 321 if format.layout == 's3tc' or format.layout == 'rgtc': 322 print(" .fetch_rgba_8unorm = &util_format_%s_fetch_rgba_8unorm," % sn) 323 if format.block_width > 1: 324 print( 325 " .unpack_rgba_8unorm_rect = &util_format_%s_unpack_rgba_8unorm," % sn) 326 print( 327 " .unpack_rgba_rect = &util_format_%s_unpack_rgba_float," % sn) 328 else: 329 print( 330 " .unpack_rgba_8unorm = &util_format_%s_unpack_rgba_8unorm," % sn) 331 print(" .unpack_rgba = &util_format_%s_unpack_rgba_float," % sn) 332 333 if format.has_depth(): 334 print(" .unpack_z_32unorm = &util_format_%s_unpack_z_32unorm," % sn) 335 print(" .unpack_z_float = &util_format_%s_unpack_z_float," % sn) 336 337 if format.has_stencil(): 338 print(" .unpack_s_8uint = &util_format_%s_unpack_s_8uint," % sn) 339 340 if format.is_pure_unsigned(): 341 print(" .unpack_rgba = &util_format_%s_unpack_unsigned," % sn) 342 elif format.is_pure_signed(): 343 print(" .unpack_rgba = &util_format_%s_unpack_signed," % sn) 344 print(" },") 345 print("};") 346 print() 347 348 generate_table_getter("unpack_") 349 350 print('static const util_format_fetch_rgba_func_ptr util_format_fetch_rgba_table[PIPE_FORMAT_COUNT] = {') 351 for format in formats: 352 sn = format.short_name() 353 354 if format.colorspace != ZS and has_access(format): 355 print(" [%s] = &util_format_%s_fetch_rgba," % (format.name, sn)) 356 else: 357 print(" [%s] = NULL," % format.name) 358 359 print("};") 360 print() 361 362 generate_function_getter("fetch_rgba") 363 364def main(): 365 formats = {} 366 367 sys.stdout2 = open(os.devnull, "w") 368 sys.stdout3 = open(os.devnull, "w") 369 370 for arg in sys.argv[1:]: 371 if arg == '--header': 372 sys.stdout2 = sys.stdout 373 sys.stdout = open(os.devnull, "w") 374 sys.stdout3 = sys.stdout 375 continue 376 elif arg == '--enums': 377 sys.stdout3 = sys.stdout 378 sys.stdout = open(os.devnull, "w") 379 sys.stdout2 = sys.stdout 380 continue 381 382 to_add = parse(arg) 383 duplicates = [x.name for x in to_add if x.name in formats] 384 if len(duplicates): 385 raise RuntimeError(f"Duplicate format entries {', '.join(duplicates)}") 386 formats.update({ x.name: x for x in to_add }) 387 388 write_format_table(formats.values()) 389 390if __name__ == '__main__': 391 main() 392