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 'p010', 90 'p012', 91 'p016', 92 'p030', 93 'y210', 94 'y212', 95 'y216', 96 'y410', 97 'y412', 98 'y416', 99 'xyuv', 100 'ayuv', 101 'r8g8_r8b8_unorm', 102 'r8b8_r8g8_unorm', 103 'g8r8_b8r8_unorm', 104 'b8r8_g8r8_unorm', 105 'g8r8_g8b8_unorm', 106 'g8b8_g8r8_unorm', 107 'b8g8_r8g8_unorm', 108 'y8_400_unorm', 109 'y8_u8_v8_422_unorm', 110 'y8_u8v8_422_unorm', 111 'y8_u8_v8_444_unorm', 112 'y8_u8_v8_440_unorm', 113 'y16_u16_v16_420_unorm', 114 'y16_u16_v16_422_unorm', 115 'y16_u16v16_422_unorm', 116 'y16_u16_v16_444_unorm', 117 'r8_g8b8_420_unorm', 118 'r8_b8g8_420_unorm', 119 'g8_b8r8_420_unorm', 120 'r8_g8_b8_420_unorm', 121 'r8_b8_g8_420_unorm', 122 'g8_b8_r8_420_unorm', 123 'r8_g8_b8_unorm', 124 'y8_unorm', 125 ] 126 if format.short_name() in noaccess_formats: 127 return False 128 if format.layout in ('astc', 'atc'): 129 return False 130 if format.layout == 'etc' and format.short_name() != 'etc1_rgb8': 131 return False 132 return True 133 134def write_format_table_header(file): 135 print('/* This file is autogenerated by u_format_table.py from u_format.yaml. Do not edit directly. */', file=file) 136 print(file=file) 137 # This will print the copyright message on the top of this file 138 print(CopyRight.strip(), file=file) 139 print(file=file) 140 141def write_format_aliases(formats): 142 print("#if UTIL_ARCH_LITTLE_ENDIAN", file=sys.stdout3) 143 for f in formats: 144 if f.le_alias: 145 print("#define %s %s" % (f.le_alias, f.name), file=sys.stdout3) 146 print("#elif UTIL_ARCH_BIG_ENDIAN", file=sys.stdout3) 147 for f in formats: 148 if f.be_alias: 149 print("#define %s %s" % (f.be_alias, f.name), file=sys.stdout3) 150 print("#endif", file=sys.stdout3) 151 152 153def write_format_table(formats): 154 write_format_table_header(sys.stdout) 155 print('#include "util/format/u_format.h"') 156 print('#include "u_format_bptc.h"') 157 print('#include "u_format_fxt1.h"') 158 print('#include "u_format_s3tc.h"') 159 print('#include "u_format_rgtc.h"') 160 print('#include "u_format_latc.h"') 161 print('#include "u_format_etc.h"') 162 print() 163 164 write_format_table_header(sys.stdout2) 165 166 print('#ifdef __cplusplus', file=sys.stdout2) 167 print('extern "C" {', file=sys.stdout2) 168 print('#endif', file=sys.stdout2) 169 print('#include "util/format/u_format.h"', file=sys.stdout2) 170 print(file=sys.stdout2) 171 172 u_format_pack.generate(formats) 173 174 print('#ifdef __cplusplus', file=sys.stdout2) 175 print('} /* extern "C" */', file=sys.stdout2) 176 print('#endif', file=sys.stdout2) 177 178 179 write_format_table_header(sys.stdout3) 180 181 print('#ifdef __cplusplus', file=sys.stdout3) 182 print('extern "C" {', file=sys.stdout3) 183 print('#endif', file=sys.stdout3) 184 print(file=sys.stdout3) 185 186 write_format_aliases(formats) 187 188 print('#ifdef __cplusplus', file=sys.stdout3) 189 print('} /* extern "C" */', file=sys.stdout3) 190 print('#endif', file=sys.stdout3) 191 192 def do_channel_array(channels, swizzles): 193 print(" {") 194 for i in range(4): 195 channel = channels[i] 196 if i < 3: 197 sep = "," 198 else: 199 sep = "" 200 if channel.size: 201 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)) 202 else: 203 print(" {0, 0, 0, 0, 0}%s" % (sep,)) 204 print(" },") 205 206 def do_swizzle_array(channels, swizzles): 207 print(" {") 208 for i in range(4): 209 swizzle = swizzles[i] 210 if i < 3: 211 sep = "," 212 else: 213 sep = "" 214 try: 215 comment = colorspace_channels_map[format.colorspace][i] 216 except (KeyError, IndexError): 217 comment = 'ignored' 218 print(" %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment)) 219 print(" },") 220 221 def generate_table_getter(type): 222 suffix = "" 223 if type == "unpack_": 224 suffix = "_generic" 225 print("ATTRIBUTE_RETURNS_NONNULL const struct util_format_%sdescription *" % type) 226 print("util_format_%sdescription%s(enum pipe_format format)" % (type, suffix)) 227 print("{") 228 print(" assert(format < PIPE_FORMAT_COUNT);") 229 print(" return &util_format_%sdescriptions[format];" % (type)) 230 print("}") 231 print() 232 233 def generate_function_getter(func): 234 print("util_format_%s_func_ptr" % func) 235 print("util_format_%s_func(enum pipe_format format)" % (func)) 236 print("{") 237 print(" assert(format < PIPE_FORMAT_COUNT);") 238 print(" return util_format_%s_table[format];" % (func)) 239 print("}") 240 print() 241 242 print('static const struct util_format_description') 243 print('util_format_descriptions[PIPE_FORMAT_COUNT] = {') 244 for format in formats: 245 sn = format.short_name() 246 247 print(" [%s] = {" % (format.name,)) 248 print(" .format = %s," % (format.name,)) 249 print(" .name = \"%s\"," % (format.name,)) 250 print(" .short_name = \"%s\"," % (sn,)) 251 print(" .block = {%u, %u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_depth, format.block_size())) 252 print(" .layout = %s," % (layout_map(format.layout),)) 253 print(" .nr_channels = %u,\t/* nr_channels */" % (format.nr_channels(),)) 254 print(" .is_array = %s,\t/* is_array */" % (bool_map(format.is_array()),)) 255 print(" .is_bitmask = %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),)) 256 print(" .is_mixed = %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),)) 257 print(" .is_unorm = %s,\t/* is_unorm */" % (bool_map(format.is_unorm()),)) 258 print(" .is_snorm = %s,\t/* is_snorm */" % (bool_map(format.is_snorm()),)) 259 u_format_pack.print_channels(format, do_channel_array) 260 u_format_pack.print_channels(format, do_swizzle_array) 261 print(" .colorspace = %s," % (colorspace_map(format.colorspace),)) 262 if format.srgb_equivalent: 263 print(" .srgb_equivalent = %s,\t/* srgb_equivalent */" % format.srgb_equivalent.name) 264 elif format.linear_equivalent: 265 print(" .linear_equivalent = %s,\t/* linear_equivalent */" % format.linear_equivalent.name) 266 else: 267 print(" .srgb_equivalent = PIPE_FORMAT_NONE,\t/* srgb_equivalent */") 268 print(" },") 269 print() 270 print("};") 271 print() 272 generate_table_getter("") 273 274 print('static const struct util_format_pack_description') 275 print('util_format_pack_descriptions[PIPE_FORMAT_COUNT] = {') 276 for format in formats: 277 sn = format.short_name() 278 279 if not has_access(format): 280 print(" [%s] = { 0 }," % (format.name,)) 281 continue 282 283 print(" [%s] = {" % (format.name,)) 284 if format.colorspace != ZS and not format.is_pure_color(): 285 print(" .pack_rgba_8unorm = &util_format_%s_pack_rgba_8unorm," % sn) 286 print(" .pack_rgba_float = &util_format_%s_pack_rgba_float," % sn) 287 288 if format.has_depth(): 289 print(" .pack_z_32unorm = &util_format_%s_pack_z_32unorm," % sn) 290 print(" .pack_z_float = &util_format_%s_pack_z_float," % sn) 291 292 if format.has_stencil(): 293 print(" .pack_s_8uint = &util_format_%s_pack_s_8uint," % sn) 294 295 if format.is_pure_unsigned() or format.is_pure_signed(): 296 print(" .pack_rgba_uint = &util_format_%s_pack_unsigned," % sn) 297 print(" .pack_rgba_sint = &util_format_%s_pack_signed," % sn) 298 print(" },") 299 print() 300 print("};") 301 print() 302 generate_table_getter("pack_") 303 print('static const struct util_format_unpack_description') 304 print('util_format_unpack_descriptions[PIPE_FORMAT_COUNT] = {') 305 for format in formats: 306 sn = format.short_name() 307 308 if not has_access(format): 309 print(" [%s] = { 0 }," % (format.name,)) 310 continue 311 312 print(" [%s] = {" % (format.name,)) 313 314 if format.colorspace != ZS and not format.is_pure_color(): 315 if format.layout == 's3tc' or format.layout == 'rgtc': 316 print(" .fetch_rgba_8unorm = &util_format_%s_fetch_rgba_8unorm," % sn) 317 if format.block_width > 1: 318 print( 319 " .unpack_rgba_8unorm_rect = &util_format_%s_unpack_rgba_8unorm," % sn) 320 print( 321 " .unpack_rgba_rect = &util_format_%s_unpack_rgba_float," % sn) 322 else: 323 print( 324 " .unpack_rgba_8unorm = &util_format_%s_unpack_rgba_8unorm," % sn) 325 print(" .unpack_rgba = &util_format_%s_unpack_rgba_float," % sn) 326 327 if format.has_depth(): 328 print(" .unpack_z_32unorm = &util_format_%s_unpack_z_32unorm," % sn) 329 print(" .unpack_z_float = &util_format_%s_unpack_z_float," % sn) 330 331 if format.has_stencil(): 332 print(" .unpack_s_8uint = &util_format_%s_unpack_s_8uint," % sn) 333 334 if format.is_pure_unsigned(): 335 print(" .unpack_rgba = &util_format_%s_unpack_unsigned," % sn) 336 elif format.is_pure_signed(): 337 print(" .unpack_rgba = &util_format_%s_unpack_signed," % sn) 338 print(" },") 339 print("};") 340 print() 341 342 generate_table_getter("unpack_") 343 344 print('static const util_format_fetch_rgba_func_ptr util_format_fetch_rgba_table[PIPE_FORMAT_COUNT] = {') 345 for format in formats: 346 sn = format.short_name() 347 348 if format.colorspace != ZS and has_access(format): 349 print(" [%s] = &util_format_%s_fetch_rgba," % (format.name, sn)) 350 else: 351 print(" [%s] = NULL," % format.name) 352 353 print("};") 354 print() 355 356 generate_function_getter("fetch_rgba") 357 358def main(): 359 formats = {} 360 361 sys.stdout2 = open(os.devnull, "w") 362 sys.stdout3 = open(os.devnull, "w") 363 364 for arg in sys.argv[1:]: 365 if arg == '--header': 366 sys.stdout2 = sys.stdout 367 sys.stdout = open(os.devnull, "w") 368 sys.stdout3 = sys.stdout 369 continue 370 elif arg == '--enums': 371 sys.stdout3 = sys.stdout 372 sys.stdout = open(os.devnull, "w") 373 sys.stdout2 = sys.stdout 374 continue 375 376 to_add = parse(arg) 377 duplicates = [x.name for x in to_add if x.name in formats] 378 if len(duplicates): 379 raise RuntimeError(f"Duplicate format entries {', '.join(duplicates)}") 380 formats.update({ x.name: x for x in to_add }) 381 382 write_format_table(formats.values()) 383 384if __name__ == '__main__': 385 main() 386