1bf215546Sopenharmony_ci# Copyright © 2020 Hoe Hao Cheng 2bf215546Sopenharmony_ci# 3bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 4bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 5bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation 6bf215546Sopenharmony_ci# the rights to use, copy, modify, merge, publish, distribute, sublicense, 7bf215546Sopenharmony_ci# and/or sell copies of the Software, and to permit persons to whom the 8bf215546Sopenharmony_ci# Software is furnished to do so, subject to the following conditions: 9bf215546Sopenharmony_ci# 10bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next 11bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 12bf215546Sopenharmony_ci# Software. 13bf215546Sopenharmony_ci# 14bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19bf215546Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20bf215546Sopenharmony_ci# IN THE SOFTWARE. 21bf215546Sopenharmony_ci# 22bf215546Sopenharmony_ci# Authors: 23bf215546Sopenharmony_ci# Hoe Hao Cheng <haochengho12907@gmail.com> 24bf215546Sopenharmony_ci# 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_cifrom mako.template import Template 27bf215546Sopenharmony_cifrom mako.lookup import TemplateLookup 28bf215546Sopenharmony_cifrom os import path 29bf215546Sopenharmony_cifrom zink_extensions import Extension,ExtensionRegistry,Version 30bf215546Sopenharmony_ciimport sys 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci# constructor: 33bf215546Sopenharmony_ci# Extension(name, alias="", required=False, properties=False, features=False, conditions=None, guard=False) 34bf215546Sopenharmony_ci# The attributes: 35bf215546Sopenharmony_ci# - required: the generated code debug_prints "ZINK: {name} required!" and 36bf215546Sopenharmony_ci# returns NULL if the extension is unavailable. 37bf215546Sopenharmony_ci# 38bf215546Sopenharmony_ci# - properties: enable the detection of extension properties in a physical 39bf215546Sopenharmony_ci# device in the generated code using vkGetPhysicalDeviceProperties2(), 40bf215546Sopenharmony_ci# and store the returned properties struct inside 41bf215546Sopenharmony_ci# `zink_device_info.{alias}_props`. 42bf215546Sopenharmony_ci# Example: the properties for `VK_EXT_transform_feedback`, is stored in 43bf215546Sopenharmony_ci# `VkPhysicalDeviceTransformFeedbackPropertiesEXT tf_props`. 44bf215546Sopenharmony_ci# 45bf215546Sopenharmony_ci# - features: enable the getting extension features in a 46bf215546Sopenharmony_ci# device. Similar to `properties`, this stores the features 47bf215546Sopenharmony_ci# struct inside `zink_device_info.{alias}_feats`. 48bf215546Sopenharmony_ci# 49bf215546Sopenharmony_ci# - conditions: criteria for enabling an extension. This is an array of strings, 50bf215546Sopenharmony_ci# where each string is a condition, and all conditions have to be true 51bf215546Sopenharmony_ci# for `zink_device_info.have_{name}` to be true. 52bf215546Sopenharmony_ci# 53bf215546Sopenharmony_ci# The code generator will replace "$feats" and "$props" with the 54bf215546Sopenharmony_ci# respective variables, e.g. "$feats.nullDescriptor" becomes 55bf215546Sopenharmony_ci# "info->rb2_feats.nullDescriptor" in the final code for VK_EXT_robustness2. 56bf215546Sopenharmony_ci# 57bf215546Sopenharmony_ci# When empty or None, the extension is enabled when the extensions 58bf215546Sopenharmony_ci# given by vkEnumerateDeviceExtensionProperties() include the extension. 59bf215546Sopenharmony_ci# 60bf215546Sopenharmony_ci# - guard: adds a #if defined(`extension_name`)/#endif guard around the code generated for this Extension. 61bf215546Sopenharmony_ciEXTENSIONS = [ 62bf215546Sopenharmony_ci Extension("VK_KHR_maintenance1", 63bf215546Sopenharmony_ci required=True), 64bf215546Sopenharmony_ci Extension("VK_KHR_maintenance2"), 65bf215546Sopenharmony_ci Extension("VK_KHR_maintenance3"), 66bf215546Sopenharmony_ci Extension("VK_KHR_external_memory"), 67bf215546Sopenharmony_ci Extension("VK_KHR_external_memory_fd"), 68bf215546Sopenharmony_ci Extension("VK_KHR_vulkan_memory_model"), 69bf215546Sopenharmony_ci Extension("VK_KHR_external_semaphore_fd"), 70bf215546Sopenharmony_ci Extension("VK_KHR_create_renderpass2", required=True), 71bf215546Sopenharmony_ci Extension("VK_KHR_synchronization2", 72bf215546Sopenharmony_ci alias="sync2", 73bf215546Sopenharmony_ci features=True), 74bf215546Sopenharmony_ci Extension("VK_KHR_external_memory_win32"), 75bf215546Sopenharmony_ci Extension("VK_KHR_external_semaphore_win32"), 76bf215546Sopenharmony_ci Extension("VK_EXT_external_memory_dma_buf"), 77bf215546Sopenharmony_ci Extension("VK_EXT_queue_family_foreign"), 78bf215546Sopenharmony_ci Extension("VK_KHR_swapchain_mutable_format"), 79bf215546Sopenharmony_ci Extension("VK_EXT_provoking_vertex", 80bf215546Sopenharmony_ci alias="pv", 81bf215546Sopenharmony_ci features=True, 82bf215546Sopenharmony_ci properties=True, 83bf215546Sopenharmony_ci conditions=["$feats.provokingVertexLast"]), 84bf215546Sopenharmony_ci Extension("VK_EXT_shader_viewport_index_layer"), 85bf215546Sopenharmony_ci Extension("VK_KHR_get_memory_requirements2"), 86bf215546Sopenharmony_ci Extension("VK_EXT_post_depth_coverage"), 87bf215546Sopenharmony_ci Extension("VK_EXT_depth_clip_control", alias="clip_control", features=True), 88bf215546Sopenharmony_ci Extension("VK_EXT_shader_subgroup_ballot"), 89bf215546Sopenharmony_ci Extension("VK_EXT_shader_subgroup_vote"), 90bf215546Sopenharmony_ci Extension("VK_EXT_shader_atomic_float", alias="atomic_float", features=True), 91bf215546Sopenharmony_ci Extension("VK_KHR_8bit_storage", 92bf215546Sopenharmony_ci alias="storage_8bit", 93bf215546Sopenharmony_ci features=True, 94bf215546Sopenharmony_ci conditions=["$feats.storageBuffer8BitAccess"]), 95bf215546Sopenharmony_ci Extension("VK_KHR_16bit_storage", 96bf215546Sopenharmony_ci alias="storage_16bit", 97bf215546Sopenharmony_ci features=True, 98bf215546Sopenharmony_ci conditions=["$feats.storageBuffer16BitAccess"]), 99bf215546Sopenharmony_ci Extension("VK_EXT_image_2d_view_of_3d", 100bf215546Sopenharmony_ci alias="view2d", 101bf215546Sopenharmony_ci features=True), 102bf215546Sopenharmony_ci Extension("VK_KHR_driver_properties", 103bf215546Sopenharmony_ci alias="driver", 104bf215546Sopenharmony_ci properties=True), 105bf215546Sopenharmony_ci Extension("VK_EXT_memory_budget"), 106bf215546Sopenharmony_ci Extension("VK_KHR_draw_indirect_count"), 107bf215546Sopenharmony_ci Extension("VK_EXT_fragment_shader_interlock", 108bf215546Sopenharmony_ci alias="interlock", 109bf215546Sopenharmony_ci features=True, 110bf215546Sopenharmony_ci conditions=["$feats.fragmentShaderSampleInterlock", "$feats.fragmentShaderPixelInterlock"]), 111bf215546Sopenharmony_ci Extension("VK_EXT_sample_locations", 112bf215546Sopenharmony_ci alias="sample_locations", 113bf215546Sopenharmony_ci properties=True), 114bf215546Sopenharmony_ci Extension("VK_EXT_conservative_rasterization", 115bf215546Sopenharmony_ci alias="cons_raster", 116bf215546Sopenharmony_ci properties=True, 117bf215546Sopenharmony_ci conditions=["$props.fullyCoveredFragmentShaderInputVariable"]), 118bf215546Sopenharmony_ci Extension("VK_KHR_shader_draw_parameters"), 119bf215546Sopenharmony_ci Extension("VK_KHR_sampler_mirror_clamp_to_edge"), 120bf215546Sopenharmony_ci Extension("VK_EXT_conditional_rendering", 121bf215546Sopenharmony_ci alias="cond_render", 122bf215546Sopenharmony_ci features=True, 123bf215546Sopenharmony_ci conditions=["$feats.conditionalRendering"]), 124bf215546Sopenharmony_ci Extension("VK_EXT_transform_feedback", 125bf215546Sopenharmony_ci alias="tf", 126bf215546Sopenharmony_ci properties=True, 127bf215546Sopenharmony_ci features=True, 128bf215546Sopenharmony_ci conditions=["$feats.transformFeedback"]), 129bf215546Sopenharmony_ci Extension("VK_EXT_index_type_uint8", 130bf215546Sopenharmony_ci alias="index_uint8", 131bf215546Sopenharmony_ci features=True, 132bf215546Sopenharmony_ci conditions=["$feats.indexTypeUint8"]), 133bf215546Sopenharmony_ci Extension("VK_KHR_image_format_list"), 134bf215546Sopenharmony_ci Extension("VK_KHR_sampler_ycbcr_conversion"), 135bf215546Sopenharmony_ci Extension("VK_KHR_imageless_framebuffer", 136bf215546Sopenharmony_ci alias="imgless", 137bf215546Sopenharmony_ci features=True, 138bf215546Sopenharmony_ci required=True), 139bf215546Sopenharmony_ci Extension("VK_EXT_robustness2", 140bf215546Sopenharmony_ci alias="rb2", 141bf215546Sopenharmony_ci properties=True, 142bf215546Sopenharmony_ci features=True, 143bf215546Sopenharmony_ci conditions=["$feats.nullDescriptor"]), 144bf215546Sopenharmony_ci Extension("VK_EXT_image_drm_format_modifier"), 145bf215546Sopenharmony_ci Extension("VK_EXT_vertex_attribute_divisor", 146bf215546Sopenharmony_ci alias="vdiv", 147bf215546Sopenharmony_ci properties=True, 148bf215546Sopenharmony_ci features=True, 149bf215546Sopenharmony_ci conditions=["$feats.vertexAttributeInstanceRateDivisor"]), 150bf215546Sopenharmony_ci Extension("VK_EXT_calibrated_timestamps"), 151bf215546Sopenharmony_ci Extension("VK_NV_linear_color_attachment", 152bf215546Sopenharmony_ci alias="linear_color", 153bf215546Sopenharmony_ci features=True), 154bf215546Sopenharmony_ci Extension("VK_KHR_dynamic_rendering", 155bf215546Sopenharmony_ci alias="dynamic_render", 156bf215546Sopenharmony_ci features=True), 157bf215546Sopenharmony_ci Extension("VK_KHR_shader_clock", 158bf215546Sopenharmony_ci alias="shader_clock", 159bf215546Sopenharmony_ci features=True, 160bf215546Sopenharmony_ci conditions=["$feats.shaderSubgroupClock"]), 161bf215546Sopenharmony_ci Extension("VK_EXT_sampler_filter_minmax", 162bf215546Sopenharmony_ci alias="reduction", 163bf215546Sopenharmony_ci properties=True, 164bf215546Sopenharmony_ci conditions=["$props.filterMinmaxSingleComponentFormats"]), 165bf215546Sopenharmony_ci Extension("VK_EXT_custom_border_color", 166bf215546Sopenharmony_ci alias="border_color", 167bf215546Sopenharmony_ci properties=True, 168bf215546Sopenharmony_ci features=True, 169bf215546Sopenharmony_ci conditions=["$feats.customBorderColors"]), 170bf215546Sopenharmony_ci Extension("VK_EXT_non_seamless_cube_map", 171bf215546Sopenharmony_ci alias="nonseamless", 172bf215546Sopenharmony_ci features=True), 173bf215546Sopenharmony_ci Extension("VK_EXT_border_color_swizzle", 174bf215546Sopenharmony_ci alias="border_swizzle", 175bf215546Sopenharmony_ci features=True), 176bf215546Sopenharmony_ci Extension("VK_EXT_blend_operation_advanced", 177bf215546Sopenharmony_ci alias="blend", 178bf215546Sopenharmony_ci properties=True, 179bf215546Sopenharmony_ci # TODO: we can probably support non-premul here with some work? 180bf215546Sopenharmony_ci conditions=["$props.advancedBlendNonPremultipliedSrcColor", "$props.advancedBlendNonPremultipliedDstColor"]), 181bf215546Sopenharmony_ci Extension("VK_EXT_extended_dynamic_state", 182bf215546Sopenharmony_ci alias="dynamic_state", 183bf215546Sopenharmony_ci features=True, 184bf215546Sopenharmony_ci conditions=["$feats.extendedDynamicState"]), 185bf215546Sopenharmony_ci Extension("VK_EXT_extended_dynamic_state2", 186bf215546Sopenharmony_ci alias="dynamic_state2", 187bf215546Sopenharmony_ci features=True, 188bf215546Sopenharmony_ci conditions=["$feats.extendedDynamicState2"]), 189bf215546Sopenharmony_ci Extension("VK_EXT_pipeline_creation_cache_control", 190bf215546Sopenharmony_ci alias="pipeline_cache_control", 191bf215546Sopenharmony_ci features=True, 192bf215546Sopenharmony_ci conditions=["$feats.pipelineCreationCacheControl"]), 193bf215546Sopenharmony_ci Extension("VK_EXT_shader_stencil_export", 194bf215546Sopenharmony_ci alias="stencil_export"), 195bf215546Sopenharmony_ci Extension("VK_KHR_portability_subset", 196bf215546Sopenharmony_ci alias="portability_subset", 197bf215546Sopenharmony_ci features=True, 198bf215546Sopenharmony_ci guard=True), 199bf215546Sopenharmony_ci Extension("VK_KHR_timeline_semaphore", alias="timeline", features=True), 200bf215546Sopenharmony_ci Extension("VK_EXT_color_write_enable", alias="cwrite", features=True), 201bf215546Sopenharmony_ci Extension("VK_EXT_4444_formats", 202bf215546Sopenharmony_ci alias="format_4444", 203bf215546Sopenharmony_ci features=True), 204bf215546Sopenharmony_ci Extension("VK_EXT_scalar_block_layout", 205bf215546Sopenharmony_ci alias="scalar_block_layout", 206bf215546Sopenharmony_ci features=True, 207bf215546Sopenharmony_ci conditions=["$feats.scalarBlockLayout"]), 208bf215546Sopenharmony_ci Extension("VK_KHR_swapchain"), 209bf215546Sopenharmony_ci Extension("VK_KHR_shader_float16_int8", 210bf215546Sopenharmony_ci alias="shader_float16_int8", 211bf215546Sopenharmony_ci features=True), 212bf215546Sopenharmony_ci Extension("VK_EXT_multi_draw", 213bf215546Sopenharmony_ci alias="multidraw", 214bf215546Sopenharmony_ci features=True, 215bf215546Sopenharmony_ci properties=True, 216bf215546Sopenharmony_ci conditions=["$feats.multiDraw"]), 217bf215546Sopenharmony_ci Extension("VK_EXT_primitives_generated_query", 218bf215546Sopenharmony_ci alias="primgen", 219bf215546Sopenharmony_ci features=True), 220bf215546Sopenharmony_ci Extension("VK_KHR_push_descriptor", 221bf215546Sopenharmony_ci alias="push", 222bf215546Sopenharmony_ci properties=True), 223bf215546Sopenharmony_ci Extension("VK_KHR_descriptor_update_template", 224bf215546Sopenharmony_ci alias="template"), 225bf215546Sopenharmony_ci Extension("VK_EXT_line_rasterization", 226bf215546Sopenharmony_ci alias="line_rast", 227bf215546Sopenharmony_ci properties=True, 228bf215546Sopenharmony_ci features=True), 229bf215546Sopenharmony_ci Extension("VK_EXT_vertex_input_dynamic_state", 230bf215546Sopenharmony_ci alias="vertex_input", 231bf215546Sopenharmony_ci features=True, 232bf215546Sopenharmony_ci conditions=["$feats.vertexInputDynamicState"]), 233bf215546Sopenharmony_ci Extension("VK_EXT_primitive_topology_list_restart", 234bf215546Sopenharmony_ci alias="list_restart", 235bf215546Sopenharmony_ci features=True, 236bf215546Sopenharmony_ci conditions=["$feats.primitiveTopologyListRestart"]), 237bf215546Sopenharmony_ci Extension("VK_KHR_dedicated_allocation", 238bf215546Sopenharmony_ci alias="dedicated"), 239bf215546Sopenharmony_ci Extension("VK_EXT_descriptor_indexing", 240bf215546Sopenharmony_ci alias="desc_indexing", 241bf215546Sopenharmony_ci features=True, 242bf215546Sopenharmony_ci properties=True, 243bf215546Sopenharmony_ci conditions=["$feats.descriptorBindingPartiallyBound"]), 244bf215546Sopenharmony_ci Extension("VK_EXT_depth_clip_enable", 245bf215546Sopenharmony_ci alias="depth_clip_enable", 246bf215546Sopenharmony_ci features=True), 247bf215546Sopenharmony_ci] 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci# constructor: Versions(device_version(major, minor, patch), struct_version(major, minor)) 250bf215546Sopenharmony_ci# The attributes: 251bf215546Sopenharmony_ci# - device_version: Vulkan version, as tuple, to use with 252bf215546Sopenharmony_ci# VK_MAKE_VERSION(version_major, version_minor, version_patch) 253bf215546Sopenharmony_ci# 254bf215546Sopenharmony_ci# - struct_version: Vulkan version, as tuple, to use with structures and macros 255bf215546Sopenharmony_ciVERSIONS = [ 256bf215546Sopenharmony_ci Version((1,1,0), (1,1)), 257bf215546Sopenharmony_ci Version((1,2,0), (1,2)), 258bf215546Sopenharmony_ci] 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci# There exists some inconsistencies regarding the enum constants, fix them. 261bf215546Sopenharmony_ci# This is basically generated_code.replace(key, value). 262bf215546Sopenharmony_ciREPLACEMENTS = { 263bf215546Sopenharmony_ci "PROPERTIES_PROPERTIES": "PROPERTIES", 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci# This template provides helper functions for the other templates. 268bf215546Sopenharmony_ci# Right now, the following functions are defined: 269bf215546Sopenharmony_ci# - guard(ext) : surrounds the body with an if-def guard according to 270bf215546Sopenharmony_ci# `ext.extension_name()` if `ext.guard` is True. 271bf215546Sopenharmony_ciinclude_template = """ 272bf215546Sopenharmony_ci<%def name="guard_(ext, body)"> 273bf215546Sopenharmony_ci%if ext.guard: 274bf215546Sopenharmony_ci#ifdef ${ext.extension_name()} 275bf215546Sopenharmony_ci%endif 276bf215546Sopenharmony_ci ${capture(body)|trim} 277bf215546Sopenharmony_ci%if ext.guard: 278bf215546Sopenharmony_ci#endif 279bf215546Sopenharmony_ci%endif 280bf215546Sopenharmony_ci</%def> 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci## This ugliness is here to prevent mako from adding tons of excessive whitespace 283bf215546Sopenharmony_ci<%def name="guard(ext)">${capture(guard_, ext, body=caller.body).strip('\\r\\n')}</%def> 284bf215546Sopenharmony_ci""" 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ciheader_code = """ 287bf215546Sopenharmony_ci<%namespace name="helpers" file="helpers"/> 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci#ifndef ZINK_DEVICE_INFO_H 290bf215546Sopenharmony_ci#define ZINK_DEVICE_INFO_H 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci#include "util/u_memory.h" 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci#include <vulkan/vulkan.h> 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_cistruct zink_screen; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_cistruct zink_device_info { 299bf215546Sopenharmony_ci uint32_t device_version; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci%for ext in extensions: 302bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 303bf215546Sopenharmony_ci bool have_${ext.name_with_vendor()}; 304bf215546Sopenharmony_ci</%helpers:guard> 305bf215546Sopenharmony_ci%endfor 306bf215546Sopenharmony_ci%for version in versions: 307bf215546Sopenharmony_ci bool have_vulkan${version.struct()}; 308bf215546Sopenharmony_ci%endfor 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci VkPhysicalDeviceFeatures2 feats; 311bf215546Sopenharmony_ci VkPhysicalDeviceSubgroupProperties subgroup; 312bf215546Sopenharmony_ci%for version in versions: 313bf215546Sopenharmony_ci VkPhysicalDeviceVulkan${version.struct()}Features feats${version.struct()}; 314bf215546Sopenharmony_ci%endfor 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci VkPhysicalDeviceProperties props; 317bf215546Sopenharmony_ci%for version in versions: 318bf215546Sopenharmony_ci VkPhysicalDeviceVulkan${version.struct()}Properties props${version.struct()}; 319bf215546Sopenharmony_ci%endfor 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci VkPhysicalDeviceMemoryProperties mem_props; 322bf215546Sopenharmony_ci VkPhysicalDeviceIDProperties deviceid_props; 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci%for ext in extensions: 325bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 326bf215546Sopenharmony_ci%if ext.has_features: 327bf215546Sopenharmony_ci ${ext.physical_device_struct("Features")} ${ext.field("feats")}; 328bf215546Sopenharmony_ci%endif 329bf215546Sopenharmony_ci%if ext.has_properties: 330bf215546Sopenharmony_ci ${ext.physical_device_struct("Properties")} ${ext.field("props")}; 331bf215546Sopenharmony_ci%endif 332bf215546Sopenharmony_ci</%helpers:guard> 333bf215546Sopenharmony_ci%endfor 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci const char *extensions[${len(extensions)}]; 336bf215546Sopenharmony_ci uint32_t num_extensions; 337bf215546Sopenharmony_ci}; 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_cibool 340bf215546Sopenharmony_cizink_get_physical_device_info(struct zink_screen *screen); 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_civoid 343bf215546Sopenharmony_cizink_verify_device_extensions(struct zink_screen *screen); 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci/* stub functions that get inserted into the dispatch table if they are not 346bf215546Sopenharmony_ci * properly loaded. 347bf215546Sopenharmony_ci */ 348bf215546Sopenharmony_ci%for ext in extensions: 349bf215546Sopenharmony_ci%if registry.in_registry(ext.name): 350bf215546Sopenharmony_ci%for cmd in registry.get_registry_entry(ext.name).device_commands: 351bf215546Sopenharmony_civoid zink_stub_${cmd.lstrip("vk")}(void); 352bf215546Sopenharmony_ci%endfor 353bf215546Sopenharmony_ci%endif 354bf215546Sopenharmony_ci%endfor 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci#endif 357bf215546Sopenharmony_ci""" 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ciimpl_code = """ 361bf215546Sopenharmony_ci<%namespace name="helpers" file="helpers"/> 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci#include "vk_enum_to_str.h" 364bf215546Sopenharmony_ci#include "zink_device_info.h" 365bf215546Sopenharmony_ci#include "zink_screen.h" 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_cibool 368bf215546Sopenharmony_cizink_get_physical_device_info(struct zink_screen *screen) 369bf215546Sopenharmony_ci{ 370bf215546Sopenharmony_ci struct zink_device_info *info = &screen->info; 371bf215546Sopenharmony_ci%for ext in extensions: 372bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 373bf215546Sopenharmony_ci bool support_${ext.name_with_vendor()} = false; 374bf215546Sopenharmony_ci</%helpers:guard> 375bf215546Sopenharmony_ci%endfor 376bf215546Sopenharmony_ci uint32_t num_extensions = 0; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci // get device memory properties 379bf215546Sopenharmony_ci screen->vk.GetPhysicalDeviceMemoryProperties(screen->pdev, &info->mem_props); 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci // enumerate device supported extensions 382bf215546Sopenharmony_ci VkResult result = screen->vk.EnumerateDeviceExtensionProperties(screen->pdev, NULL, &num_extensions, NULL); 383bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 384bf215546Sopenharmony_ci mesa_loge("ZINK: vkEnumerateDeviceExtensionProperties failed (%s)", vk_Result_to_str(result)); 385bf215546Sopenharmony_ci } else { 386bf215546Sopenharmony_ci if (num_extensions > 0) { 387bf215546Sopenharmony_ci VkExtensionProperties *extensions = MALLOC(sizeof(VkExtensionProperties) * num_extensions); 388bf215546Sopenharmony_ci if (!extensions) goto fail; 389bf215546Sopenharmony_ci result = screen->vk.EnumerateDeviceExtensionProperties(screen->pdev, NULL, &num_extensions, extensions); 390bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 391bf215546Sopenharmony_ci mesa_loge("ZINK: vkEnumerateDeviceExtensionProperties failed (%s)", vk_Result_to_str(result)); 392bf215546Sopenharmony_ci } 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci for (uint32_t i = 0; i < num_extensions; ++i) { 395bf215546Sopenharmony_ci %for ext in extensions: 396bf215546Sopenharmony_ci <%helpers:guard ext="${ext}"> 397bf215546Sopenharmony_ci if (!strcmp(extensions[i].extensionName, "${ext.name}")) { 398bf215546Sopenharmony_ci %if not (ext.has_features or ext.has_properties): 399bf215546Sopenharmony_ci info->have_${ext.name_with_vendor()} = true; 400bf215546Sopenharmony_ci %else: 401bf215546Sopenharmony_ci support_${ext.name_with_vendor()} = true; 402bf215546Sopenharmony_ci %endif 403bf215546Sopenharmony_ci } 404bf215546Sopenharmony_ci </%helpers:guard> 405bf215546Sopenharmony_ci %endfor 406bf215546Sopenharmony_ci } 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci FREE(extensions); 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci } 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci // get device features 413bf215546Sopenharmony_ci if (screen->vk.GetPhysicalDeviceFeatures2) { 414bf215546Sopenharmony_ci // check for device extension features 415bf215546Sopenharmony_ci info->feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci%for version in versions: 418bf215546Sopenharmony_ci%if version.device_version < (1,2,0): 419bf215546Sopenharmony_ci if (VK_MAKE_VERSION(1,2,0) <= screen->vk_version) { 420bf215546Sopenharmony_ci /* VkPhysicalDeviceVulkan11Features was added in 1.2, not 1.1 as one would think */ 421bf215546Sopenharmony_ci%else: 422bf215546Sopenharmony_ci if (${version.version()} <= screen->vk_version) { 423bf215546Sopenharmony_ci%endif 424bf215546Sopenharmony_ci info->feats${version.struct()}.sType = ${version.stype("FEATURES")}; 425bf215546Sopenharmony_ci info->feats${version.struct()}.pNext = info->feats.pNext; 426bf215546Sopenharmony_ci info->feats.pNext = &info->feats${version.struct()}; 427bf215546Sopenharmony_ci info->have_vulkan${version.struct()} = true; 428bf215546Sopenharmony_ci } 429bf215546Sopenharmony_ci%endfor 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci%for ext in extensions: 432bf215546Sopenharmony_ci%if ext.has_features: 433bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 434bf215546Sopenharmony_ci%if ext.features_promoted: 435bf215546Sopenharmony_ci if (support_${ext.name_with_vendor()} && !info->have_vulkan${ext.core_since.struct()}) { 436bf215546Sopenharmony_ci%else: 437bf215546Sopenharmony_ci if (support_${ext.name_with_vendor()}) { 438bf215546Sopenharmony_ci%endif 439bf215546Sopenharmony_ci info->${ext.field("feats")}.sType = ${ext.stype("FEATURES")}; 440bf215546Sopenharmony_ci info->${ext.field("feats")}.pNext = info->feats.pNext; 441bf215546Sopenharmony_ci info->feats.pNext = &info->${ext.field("feats")}; 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci</%helpers:guard> 444bf215546Sopenharmony_ci%endif 445bf215546Sopenharmony_ci%endfor 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci screen->vk.GetPhysicalDeviceFeatures2(screen->pdev, &info->feats); 448bf215546Sopenharmony_ci } else { 449bf215546Sopenharmony_ci screen->vk.GetPhysicalDeviceFeatures(screen->pdev, &info->feats.features); 450bf215546Sopenharmony_ci } 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci // check for device properties 453bf215546Sopenharmony_ci if (screen->vk.GetPhysicalDeviceProperties2) { 454bf215546Sopenharmony_ci VkPhysicalDeviceProperties2 props = {0}; 455bf215546Sopenharmony_ci props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci%for version in versions: 458bf215546Sopenharmony_ci%if version.device_version < (1,2,0): 459bf215546Sopenharmony_ci if (VK_MAKE_VERSION(1,2,0) <= screen->vk_version) { 460bf215546Sopenharmony_ci /* VkPhysicalDeviceVulkan11Properties was added in 1.2, not 1.1 as one would think */ 461bf215546Sopenharmony_ci%else: 462bf215546Sopenharmony_ci if (${version.version()} <= screen->vk_version) { 463bf215546Sopenharmony_ci%endif 464bf215546Sopenharmony_ci info->props${version.struct()}.sType = ${version.stype("PROPERTIES")}; 465bf215546Sopenharmony_ci info->props${version.struct()}.pNext = props.pNext; 466bf215546Sopenharmony_ci props.pNext = &info->props${version.struct()}; 467bf215546Sopenharmony_ci } 468bf215546Sopenharmony_ci%endfor 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci%for ext in extensions: 471bf215546Sopenharmony_ci%if ext.has_properties: 472bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 473bf215546Sopenharmony_ci%if ext.properties_promoted: 474bf215546Sopenharmony_ci if (support_${ext.name_with_vendor()} && !info->have_vulkan${ext.core_since.struct()}) { 475bf215546Sopenharmony_ci%else: 476bf215546Sopenharmony_ci if (support_${ext.name_with_vendor()}) { 477bf215546Sopenharmony_ci%endif 478bf215546Sopenharmony_ci info->${ext.field("props")}.sType = ${ext.stype("PROPERTIES")}; 479bf215546Sopenharmony_ci info->${ext.field("props")}.pNext = props.pNext; 480bf215546Sopenharmony_ci props.pNext = &info->${ext.field("props")}; 481bf215546Sopenharmony_ci } 482bf215546Sopenharmony_ci</%helpers:guard> 483bf215546Sopenharmony_ci%endif 484bf215546Sopenharmony_ci%endfor 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci if (screen->vk_version < VK_MAKE_VERSION(1,2,0) && screen->instance_info.have_KHR_external_memory_capabilities) { 487bf215546Sopenharmony_ci info->deviceid_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; 488bf215546Sopenharmony_ci info->deviceid_props.pNext = props.pNext; 489bf215546Sopenharmony_ci props.pNext = &info->deviceid_props; 490bf215546Sopenharmony_ci } 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci if (screen->vk_version >= VK_MAKE_VERSION(1,1,0)) { 493bf215546Sopenharmony_ci info->subgroup.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; 494bf215546Sopenharmony_ci info->subgroup.pNext = props.pNext; 495bf215546Sopenharmony_ci props.pNext = &info->subgroup; 496bf215546Sopenharmony_ci } 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci // note: setting up local VkPhysicalDeviceProperties2. 499bf215546Sopenharmony_ci screen->vk.GetPhysicalDeviceProperties2(screen->pdev, &props); 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci /* We re-apply the fields from VkPhysicalDeviceVulkanXYFeatures struct 503bf215546Sopenharmony_ci * onto their respective fields in the VkPhysicalDeviceExtensionNameFeatures 504bf215546Sopenharmony_ci * struct if the former is provided by the VK implementation. 505bf215546Sopenharmony_ci * 506bf215546Sopenharmony_ci * As for why this is done: the spec mentions that once an extension is 507bf215546Sopenharmony_ci * promoted to core and its feature fields are added in VulkanXYFeatures, 508bf215546Sopenharmony_ci * including both ExtensionNameFeatures and VulkanXYFeatures at the same 509bf215546Sopenharmony_ci * time is prohibited when using vkGetPhysicalDeviceFeatures2. 510bf215546Sopenharmony_ci */ 511bf215546Sopenharmony_ci%for ext in extensions: 512bf215546Sopenharmony_ci%if ext.features_promoted: 513bf215546Sopenharmony_ci if (info->have_vulkan${ext.core_since.struct()}) { 514bf215546Sopenharmony_ci %for field in registry.get_registry_entry(ext.name).features_fields: 515bf215546Sopenharmony_ci info->${ext.field("feats")}.${field} = info->feats${ext.core_since.struct()}.${field}; 516bf215546Sopenharmony_ci %endfor 517bf215546Sopenharmony_ci } 518bf215546Sopenharmony_ci%endif 519bf215546Sopenharmony_ci%endfor 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci /* See above, but for VulkanXYProperties. 522bf215546Sopenharmony_ci * Unlike VulkanXYFeatures with all the booleans, VulkanXYProperties can 523bf215546Sopenharmony_ci * contain different types of data, including arrays. The C language hates us 524bf215546Sopenharmony_ci * when we assign an array to another array, therefore we use an memcpy here. 525bf215546Sopenharmony_ci */ 526bf215546Sopenharmony_ci%for ext in extensions: 527bf215546Sopenharmony_ci%if ext.properties_promoted: 528bf215546Sopenharmony_ci if (info->have_vulkan${ext.core_since.struct()}) { 529bf215546Sopenharmony_ci %for field in registry.get_registry_entry(ext.name).properties_fields: 530bf215546Sopenharmony_ci memcpy(&info->${ext.field("props")}.${field}, 531bf215546Sopenharmony_ci &info->props${ext.core_since.struct()}.${field}, 532bf215546Sopenharmony_ci sizeof(info->${ext.field("props")}.${field})); 533bf215546Sopenharmony_ci %endfor 534bf215546Sopenharmony_ci } 535bf215546Sopenharmony_ci%endif 536bf215546Sopenharmony_ci%endfor 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci // enable the extensions if they match the conditions given by ext.enable_conds 539bf215546Sopenharmony_ci if (screen->vk.GetPhysicalDeviceProperties2) { 540bf215546Sopenharmony_ci %for ext in extensions: 541bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 542bf215546Sopenharmony_ci<% 543bf215546Sopenharmony_ci conditions = "" 544bf215546Sopenharmony_ci if ext.enable_conds: 545bf215546Sopenharmony_ci for cond in ext.enable_conds: 546bf215546Sopenharmony_ci cond = cond.replace("$feats", "info->" + ext.field("feats")) 547bf215546Sopenharmony_ci cond = cond.replace("$props", "info->" + ext.field("props")) 548bf215546Sopenharmony_ci conditions += "&& (" + cond + ")\\n" 549bf215546Sopenharmony_ci conditions = conditions.strip() 550bf215546Sopenharmony_ci%>\ 551bf215546Sopenharmony_ci info->have_${ext.name_with_vendor()} |= support_${ext.name_with_vendor()} 552bf215546Sopenharmony_ci ${conditions}; 553bf215546Sopenharmony_ci</%helpers:guard> 554bf215546Sopenharmony_ci %endfor 555bf215546Sopenharmony_ci } 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci // generate extension list 558bf215546Sopenharmony_ci num_extensions = 0; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci%for ext in extensions: 561bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 562bf215546Sopenharmony_ci if (info->have_${ext.name_with_vendor()}) { 563bf215546Sopenharmony_ci info->extensions[num_extensions++] = "${ext.name}"; 564bf215546Sopenharmony_ci%if ext.is_required: 565bf215546Sopenharmony_ci } else { 566bf215546Sopenharmony_ci debug_printf("ZINK: ${ext.name} required!\\n"); 567bf215546Sopenharmony_ci goto fail; 568bf215546Sopenharmony_ci%endif 569bf215546Sopenharmony_ci } 570bf215546Sopenharmony_ci</%helpers:guard> 571bf215546Sopenharmony_ci%endfor 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci info->num_extensions = num_extensions; 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_ci return true; 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_cifail: 578bf215546Sopenharmony_ci return false; 579bf215546Sopenharmony_ci} 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_civoid 582bf215546Sopenharmony_cizink_verify_device_extensions(struct zink_screen *screen) 583bf215546Sopenharmony_ci{ 584bf215546Sopenharmony_ci%for ext in extensions: 585bf215546Sopenharmony_ci%if registry.in_registry(ext.name): 586bf215546Sopenharmony_ci<%helpers:guard ext="${ext}"> 587bf215546Sopenharmony_ci if (screen->info.have_${ext.name_with_vendor()}) { 588bf215546Sopenharmony_ci%for cmd in registry.get_registry_entry(ext.name).device_commands: 589bf215546Sopenharmony_ci%if cmd.find("win32"): 590bf215546Sopenharmony_ci#ifdef _WIN32 591bf215546Sopenharmony_ci%endif 592bf215546Sopenharmony_ci if (!screen->vk.${cmd.lstrip("vk")}) { 593bf215546Sopenharmony_ci#ifndef NDEBUG 594bf215546Sopenharmony_ci screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_${cmd.lstrip("vk")}; 595bf215546Sopenharmony_ci#else 596bf215546Sopenharmony_ci screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_function_not_loaded; 597bf215546Sopenharmony_ci#endif 598bf215546Sopenharmony_ci } 599bf215546Sopenharmony_ci%if cmd.find("win32"): 600bf215546Sopenharmony_ci#endif 601bf215546Sopenharmony_ci%endif 602bf215546Sopenharmony_ci%endfor 603bf215546Sopenharmony_ci } 604bf215546Sopenharmony_ci</%helpers:guard> 605bf215546Sopenharmony_ci%endif 606bf215546Sopenharmony_ci%endfor 607bf215546Sopenharmony_ci} 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci#ifndef NDEBUG 610bf215546Sopenharmony_ci/* generated stub functions */ 611bf215546Sopenharmony_ci## remember the stub functions that are already generated 612bf215546Sopenharmony_ci<% generated_funcs = set() %> 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci%for ext in extensions: 615bf215546Sopenharmony_ci%if registry.in_registry(ext.name): 616bf215546Sopenharmony_ci%for cmd in registry.get_registry_entry(ext.name).device_commands: 617bf215546Sopenharmony_ci## 618bf215546Sopenharmony_ci## some functions are added by multiple extensions, which creates duplication 619bf215546Sopenharmony_ci## and thus redefinition of stubs (eg. vkCmdPushDescriptorSetWithTemplateKHR) 620bf215546Sopenharmony_ci## 621bf215546Sopenharmony_ci%if cmd in generated_funcs: 622bf215546Sopenharmony_ci <% continue %> 623bf215546Sopenharmony_ci%else: 624bf215546Sopenharmony_ci <% generated_funcs.add(cmd) %> 625bf215546Sopenharmony_ci%endif 626bf215546Sopenharmony_civoid 627bf215546Sopenharmony_cizink_stub_${cmd.lstrip("vk")}() 628bf215546Sopenharmony_ci{ 629bf215546Sopenharmony_ci mesa_loge("ZINK: ${cmd} is not loaded properly!"); 630bf215546Sopenharmony_ci abort(); 631bf215546Sopenharmony_ci} 632bf215546Sopenharmony_ci%endfor 633bf215546Sopenharmony_ci%endif 634bf215546Sopenharmony_ci%endfor 635bf215546Sopenharmony_ci#endif 636bf215546Sopenharmony_ci""" 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_cidef replace_code(code: str, replacement: dict): 640bf215546Sopenharmony_ci for (k, v) in replacement.items(): 641bf215546Sopenharmony_ci code = code.replace(k, v) 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci return code 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ciif __name__ == "__main__": 647bf215546Sopenharmony_ci try: 648bf215546Sopenharmony_ci header_path = sys.argv[1] 649bf215546Sopenharmony_ci impl_path = sys.argv[2] 650bf215546Sopenharmony_ci vkxml_path = sys.argv[3] 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci header_path = path.abspath(header_path) 653bf215546Sopenharmony_ci impl_path = path.abspath(impl_path) 654bf215546Sopenharmony_ci vkxml_path = path.abspath(vkxml_path) 655bf215546Sopenharmony_ci except: 656bf215546Sopenharmony_ci print("usage: %s <path to .h> <path to .c> <path to vk.xml>" % sys.argv[0]) 657bf215546Sopenharmony_ci exit(1) 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci registry = ExtensionRegistry(vkxml_path) 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci extensions = EXTENSIONS 662bf215546Sopenharmony_ci versions = VERSIONS 663bf215546Sopenharmony_ci replacement = REPLACEMENTS 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci # Perform extension validation and set core_since for the extension if available 666bf215546Sopenharmony_ci error_count = 0 667bf215546Sopenharmony_ci for ext in extensions: 668bf215546Sopenharmony_ci if not registry.in_registry(ext.name): 669bf215546Sopenharmony_ci # disable validation for nonstandard extensions 670bf215546Sopenharmony_ci if ext.is_nonstandard: 671bf215546Sopenharmony_ci continue 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci error_count += 1 674bf215546Sopenharmony_ci print("The extension {} is not registered in vk.xml - a typo?".format(ext.name)) 675bf215546Sopenharmony_ci continue 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci entry = registry.get_registry_entry(ext.name) 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci if entry.ext_type != "device": 680bf215546Sopenharmony_ci error_count += 1 681bf215546Sopenharmony_ci print("The extension {} is {} extension - expected a device extension.".format(ext.name, entry.ext_type)) 682bf215546Sopenharmony_ci continue 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci if ext.has_features: 685bf215546Sopenharmony_ci if not (entry.features_struct and ext.physical_device_struct("Features") == entry.features_struct): 686bf215546Sopenharmony_ci error_count += 1 687bf215546Sopenharmony_ci print("The extension {} does not provide a features struct.".format(ext.name)) 688bf215546Sopenharmony_ci ext.features_promoted = entry.features_promoted 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci if ext.has_properties: 691bf215546Sopenharmony_ci if not (entry.properties_struct and ext.physical_device_struct("Properties") == entry.properties_struct): 692bf215546Sopenharmony_ci error_count += 1 693bf215546Sopenharmony_ci print("The extension {} does not provide a properties struct.".format(ext.name)) 694bf215546Sopenharmony_ci ext.properties_promoted = entry.properties_promoted 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci if entry.promoted_in and entry.promoted_in <= versions[-1].struct_version: 697bf215546Sopenharmony_ci ext.core_since = Version((*entry.promoted_in, 0)) 698bf215546Sopenharmony_ci else: 699bf215546Sopenharmony_ci # even if the ext is promoted in a newer VK version, consider it 700bf215546Sopenharmony_ci # unpromoted until there's an entry for that VK version in VERSIONS 701bf215546Sopenharmony_ci ext.features_promoted = False 702bf215546Sopenharmony_ci ext.properties_promoted = False 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci if error_count > 0: 705bf215546Sopenharmony_ci print("zink_device_info.py: Found {} error(s) in total. Quitting.".format(error_count)) 706bf215546Sopenharmony_ci exit(1) 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_ci lookup = TemplateLookup() 709bf215546Sopenharmony_ci lookup.put_string("helpers", include_template) 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci with open(header_path, "w") as header_file: 712bf215546Sopenharmony_ci header = Template(header_code, lookup=lookup).render(extensions=extensions, versions=versions, registry=registry).strip() 713bf215546Sopenharmony_ci header = replace_code(header, replacement) 714bf215546Sopenharmony_ci print(header, file=header_file) 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci with open(impl_path, "w") as impl_file: 717bf215546Sopenharmony_ci impl = Template(impl_code, lookup=lookup).render(extensions=extensions, versions=versions, registry=registry).strip() 718bf215546Sopenharmony_ci impl = replace_code(impl, replacement) 719bf215546Sopenharmony_ci print(impl, file=impl_file) 720