1#!/usr/bin/env python3 2COPYRIGHT = """\ 3/* 4 * Copyright 2024 Intel Corporation 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26""" 27 28import os 29import sys 30from textwrap import indent 31 32from mako.template import Template 33from mako import exceptions 34 35from intel_device_info import TYPES_BY_NAME, Enum 36 37template = COPYRIGHT + """ 38 39/* DO NOT EDIT - This file generated automatically by intel_device_info_gen_h.py script */ 40 41#ifndef INTEL_DEVICE_INFO_GEN_H 42#define INTEL_DEVICE_INFO_GEN_H 43 44#include <stdbool.h> 45#include <stdint.h> 46 47#include "util/macros.h" 48#include "compiler/shader_enums.h" 49#include "intel/dev/intel_wa.h" 50 51#ifdef __cplusplus 52extern "C" { 53#endif 54<%! import intel_device_info %> 55% for decl in intel_device_info.TYPES: 56% if isinstance(decl, intel_device_info.Define): 57${format_define(decl)} 58% elif isinstance(decl, intel_device_info.Enum) and not decl.external: 59 60enum ${decl.name} { 61% for value in decl.values: 62${format_enum_value(value)} 63% endfor 64}; 65% elif isinstance(decl, intel_device_info.Struct): 66 67struct ${decl.name} 68{ 69% for member in decl.members: 70${format_struct_member(member)} 71% endfor 72% if decl.name == "intel_device_info": 73 BITSET_DECLARE(workarounds, INTEL_WA_NUM); 74% endif 75}; 76% endif 77% endfor 78 79#ifdef __cplusplus 80} 81#endif 82 83#endif /* INTEL_DEVICE_INFO_GEN_H */ 84""" 85 86def format_enum_value(v): 87 """ 88 Routine to format the individual lines within an enum declaration. 89 This is inconvenient to implement with mako. Templates are an 90 inconvenient tool for conditionally formatting: 91 - inline comments 92 - "grouped" values as required by intel_platform 93 - specific values 94 """ 95 comment = "" 96 if v.comment: 97 comment = f" /* {v.comment} */" 98 value = "" 99 if v.value is not None: 100 value = f" = {v.value}" 101 decl = f"{v.name}{value},{comment}" 102 if v.group_begin: 103 decl = f"{decl}\nINTEL_PLATFORM_{v.group_begin}_START = {v.name}," 104 if v.group_end: 105 decl = f"{decl}\nINTEL_PLATFORM_{v.group_end}_END = {v.name}," 106 return indent(decl, " ") 107 108def format_define(v): 109 """ 110 Routine to format the printing of a macro declaration. Conditional 111 inline comments are difficult to format in mako. 112 """ 113 comment = "" 114 if v.comment: 115 comment = f" /* {v.comment} */" 116 return f"#define {v.name} ({v.value}){comment}" 117 118def format_struct_member(m): 119 """ 120 Routine to format the printing of a struct member. Mako templates are not 121 helpful in formatting the following aspects of intel_device_info structs: 122 - multiline vs single line comments 123 - optional array lengths 124 - enum / struct member type declarations 125 """ 126 comment = "" 127 if m.comment: 128 if "\n" in m.comment: 129 comment_lines = [ f" * {line}".rstrip() for line in m.comment.split('\n')] 130 comment_lines.insert(0, "\n/**") 131 comment_lines.append(" */\n") 132 comment = '\n'.join(comment_lines) 133 else: 134 comment = f"\n/* {m.comment} */\n" 135 array = "" 136 if m.array: 137 array = f"[{m.array}]" 138 member_type = m.member_type 139 if member_type in TYPES_BY_NAME: 140 if isinstance(TYPES_BY_NAME[member_type], Enum): 141 member_type = f"enum {member_type}" 142 else: 143 member_type = f"struct {member_type}" 144 return indent(f"{comment}{member_type} {m.name}{array};", " ") 145 146def main(): 147 """print intel_device_info_gen.h at the specified path""" 148 if len(sys.argv) > 1: 149 outf = open(sys.argv[1], 'w', encoding='utf-8') 150 else: 151 outf = sys.stdout 152 153 try: 154 outf.write(Template(template).render(format_enum_value=format_enum_value, 155 format_struct_member=format_struct_member, 156 format_define=format_define)) 157 except: 158 # provide some debug information to the user 159 print(exceptions.text_error_template().render(format_enum_value=format_enum_value, 160 format_struct_member=format_struct_member, 161 format_define=format_define)) 162 sys.exit(1) 163 outf.close() 164 165if __name__ == "__main__": 166 main() 167