1# Copyright 2023 Google LLC 2# SPDX-License-Identifier: MIT 3 4import os, re, sys 5from generator import * 6from pathlib import Path, PurePosixPath 7 8import cereal 9from cereal.wrapperdefs import VULKAN_STREAM_TYPE 10from cereal.wrapperdefs import VULKAN_STREAM_TYPE_GUEST 11 12# CerealGenerator - generates set of driver sources 13# while being agnostic to the stream implementation 14from reg import GroupInfo, TypeInfo, EnumInfo 15 16VK_CEREAL_FLAG_HOST = 1 17VK_CEREAL_FLAG_GUEST = 2 18VK_CEREAL_FLAG_ALL = VK_CEREAL_FLAG_GUEST | VK_CEREAL_FLAG_HOST 19 20SUPPORTED_FEATURES = [ 21 "VK_VERSION_1_0", 22 "VK_VERSION_1_1", 23 "VK_VERSION_1_2", 24 "VK_VERSION_1_3", 25 "VK_VERSION_1_4", 26 # Instance extensions 27 "VK_KHR_get_physical_device_properties2", 28 "VK_KHR_external_semaphore_capabilities", 29 "VK_KHR_external_memory_capabilities", 30 "VK_KHR_external_fence_capabilities", 31 "VK_EXT_debug_utils", 32 "VK_EXT_debug_report", 33 "VK_EXT_validation_features", 34 # Device extensions 35 "VK_EXT_external_memory_host", 36 "VK_KHR_storage_buffer_storage_class", 37 "VK_KHR_vulkan_memory_model", 38 "VK_KHR_buffer_device_address", 39 "VK_KHR_maintenance1", 40 "VK_KHR_maintenance2", 41 "VK_KHR_maintenance3", 42 "VK_KHR_bind_memory2", 43 "VK_KHR_dedicated_allocation", 44 "VK_KHR_get_memory_requirements2", 45 "VK_KHR_sampler_ycbcr_conversion", 46 "VK_KHR_shader_float16_int8", 47 "VK_AMD_gpu_shader_half_float", 48 "VK_NV_shader_subgroup_partitioned", 49 "VK_KHR_shader_subgroup_extended_types", 50 "VK_EXT_provoking_vertex", 51 "VK_EXT_line_rasterization", 52 "VK_KHR_line_rasterization", 53 "VK_EXT_transform_feedback", 54 "VK_EXT_primitive_topology_list_restart", 55 "VK_EXT_index_type_uint8", 56 "VK_EXT_load_store_op_none", 57 "VK_EXT_swapchain_colorspace", 58 "VK_EXT_custom_border_color", 59 "VK_EXT_shader_stencil_export", 60 "VK_KHR_image_format_list", 61 "VK_KHR_incremental_present", 62 "VK_KHR_pipeline_executable_properties", 63 "VK_EXT_queue_family_foreign", 64 "VK_EXT_scalar_block_layout", 65 "VK_KHR_external_semaphore", 66 "VK_KHR_external_semaphore_fd", 67 "VK_KHR_external_memory", 68 "VK_KHR_external_fence", 69 "VK_KHR_external_fence_fd", 70 "VK_EXT_device_memory_report", 71 "VK_KHR_create_renderpass2", 72 "VK_KHR_imageless_framebuffer", 73 "VK_KHR_descriptor_update_template", 74 "VK_EXT_depth_clip_enable", 75 "VK_EXT_robustness2", 76 # see aosp/2736079 + b/268351352 77 "VK_EXT_swapchain_maintenance1", 78 "VK_KHR_maintenance5", 79 "VK_EXT_host_image_copy", 80 "VK_EXT_image_compression_control", 81 "VK_EXT_image_compression_control_swapchain", 82 "VK_EXT_image_drm_format_modifier", 83 # VK1.3 extensions: see b/298704840 84 "VK_KHR_copy_commands2", 85 "VK_KHR_dynamic_rendering", 86 "VK_KHR_format_feature_flags2", 87 "VK_KHR_maintenance4", 88 "VK_KHR_shader_integer_dot_product", 89 "VK_KHR_shader_non_semantic_info", 90 "VK_KHR_shader_terminate_invocation", 91 "VK_KHR_synchronization2", 92 "VK_KHR_zero_initialize_workgroup_memory", 93 "VK_EXT_4444_formats", 94 "VK_EXT_extended_dynamic_state", 95 "VK_EXT_extended_dynamic_state2", 96 "VK_EXT_image_robustness", 97 "VK_EXT_inline_uniform_block", 98 "VK_EXT_pipeline_creation_cache_control", 99 "VK_EXT_pipeline_creation_feedback", 100 "VK_EXT_private_data", 101 "VK_EXT_shader_demote_to_helper_invocation", 102 "VK_EXT_subgroup_size_control", 103 "VK_EXT_texel_buffer_alignment", 104 "VK_EXT_texture_compression_astc_hdr", 105 "VK_EXT_tooling_info", 106 "VK_EXT_ycbcr_2plane_444_formats", 107 # Host dispatch 108 "VK_KHR_surface", 109 "VK_KHR_swapchain", 110 "VK_KHR_xcb_surface", 111 "VK_KHR_win32_surface", 112 "VK_EXT_metal_surface", 113 "VK_EXT_metal_objects", 114 "VK_EXT_external_memory_metal", 115 "VK_KHR_external_semaphore_win32", 116 "VK_KHR_external_memory_win32", 117 "VK_NV_device_diagnostic_checkpoints", 118 "VK_KHR_ray_tracing_pipeline", 119 "VK_KHR_pipeline_library", 120 # Android 121 "VK_ANDROID_native_buffer", 122 "VK_ANDROID_external_memory_android_hardware_buffer", 123 "VK_KHR_android_surface", 124 # Linux 125 "VK_KHR_external_memory_fd", 126 # Custom 127 "VK_GOOGLE_gfxstream", 128 # Used in tests without proper support checks 129 "VK_EXT_graphics_pipeline_library", 130 # Used by guest ANGLE 131 "VK_EXT_vertex_attribute_divisor", 132 # QNX 133 "VK_QNX_external_memory_screen_buffer", 134 # b/320855472 Chrome 135 "VK_EXT_fragment_density_map", 136 # b/349122558 Zink 137 "VK_EXT_color_write_enable", 138] 139 140HOST_MODULES = ["goldfish_vk_extension_structs", "goldfish_vk_marshaling", 141 "goldfish_vk_reserved_marshaling", "goldfish_vk_deepcopy", 142 "goldfish_vk_dispatch", "goldfish_vk_transform", "VkDecoder", 143 "VkDecoderSnapshot", "VkSubDecoder"] 144 145# By default, the all wrappers are run all on all features. In certain cases, 146# we wish run wrappers when the module requires it. For example, `VK_GOOGLE_gfxstream` 147# shouldn't generate a function table entry since it's an internal interface. 148SUPPORTED_MODULES = { 149 "VK_EXT_external_memory_host": HOST_MODULES, 150 "VK_EXT_debug_utils": HOST_MODULES, 151 "VK_EXT_debug_report": HOST_MODULES, 152 "VK_EXT_validation_features": HOST_MODULES, 153 "VK_KHR_surface": ["goldfish_vk_dispatch"], 154 "VK_KHR_xcb_surface": ["goldfish_vk_dispatch"], 155 "VK_KHR_win32_surface": ["goldfish_vk_dispatch"], 156 "VK_EXT_metal_surface": ["goldfish_vk_dispatch"], 157 "VK_EXT_metal_objects": ["goldfish_vk_dispatch"], 158 "VK_EXT_external_memory_metal": ["goldfish_vk_dispatch"], 159 "VK_KHR_external_semaphore_win32" : ["goldfish_vk_dispatch"], 160 "VK_KHR_external_memory_win32" : ["goldfish_vk_dispatch"], 161 # Host dispatch for Linux hosts + and entrypoint for guests 162 "VK_KHR_external_memory_fd": ["goldfish_vk_dispatch", "func_table"], 163 "VK_QNX_external_memory_screen_buffer": ["goldfish_vk_dispatch"], 164 "VK_ANDROID_external_memory_android_hardware_buffer": ["func_table"], 165 "VK_KHR_android_surface": ["func_table"], 166 "VK_EXT_swapchain_maintenance1" : HOST_MODULES, 167 "VK_KHR_swapchain" : HOST_MODULES, 168 "VK_NV_device_diagnostic_checkpoints": ["goldfish_vk_dispatch"], 169 "VK_KHR_ray_tracing_pipeline": HOST_MODULES, 170 "VK_KHR_pipeline_library": HOST_MODULES, 171} 172 173# These modules will be used when the feature is not supported. 174# This is necessary to cover all extensions where needed. 175UNSUPPORTED_FEATURE_MODULES = { 176 "goldfish_vk_extension_structs", 177} 178 179 180REQUIRED_TYPES = { 181 "int", 182 "uint16_t", 183 "int64_t", 184 "double", 185 "VkPresentScalingFlagsEXT", 186 "VkPresentGravityFlagsEXT", 187} 188 189copyrightHeader = """// Copyright (C) 2018 The Android Open Source Project 190// Copyright (C) 2018 Google Inc. 191// 192// Licensed under the Apache License, Version 2.0 (the "License"); 193// you may not use this file except in compliance with the License. 194// You may obtain a copy of the License at 195// 196// http://www.apache.org/licenses/LICENSE-2.0 197// 198// Unless required by applicable law or agreed to in writing, software 199// distributed under the License is distributed on an "AS IS" BASIS, 200// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201// See the License for the specific language governing permissions and 202// limitations under the License. 203""" 204 205# We put the long generated commands in a separate paragraph, so that the formatter won't mess up 206# with other texts. 207autogeneratedHeaderTemplate = """ 208// Autogenerated module %s 209// 210// %s 211// 212// Please do not modify directly; 213// re-run mesa3d/src/gfxstream/codegen/generate-gfxstream-vulkan.sh, 214// or directly from Python by defining: 215// VULKAN_REGISTRY_XML_DIR : Directory containing vk.xml 216// VULKAN_REGISTRY_SCRIPTS_DIR : Directory containing genvk.py 217// CEREAL_OUTPUT_DIR: Where to put the generated sources. 218// 219// python3 $VULKAN_REGISTRY_SCRIPTS_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o $CEREAL_OUTPUT_DIR 220// 221""" 222namespaceBegin =""" 223namespace gfxstream { 224namespace vk {\n 225""" 226 227namespaceEnd = """ 228} // namespace vk 229} // namespace gfxstream 230""" 231 232def banner_command(argv): 233 """Return sanitized command-line description. 234 |argv| must be a list of command-line parameters, e.g. sys.argv. 235 Return a string corresponding to the command, with platform-specific 236 paths removed.""" 237 238 def makePosixRelative(someArg): 239 # Do not use relative for /tmp/ to avoid effects of checkout location 240 if os.path.exists(someArg) and someArg != "/tmp/": 241 return str(PurePosixPath(Path(os.path.relpath(someArg)))) 242 return someArg 243 244 return ' '.join(map(makePosixRelative, argv)) 245 246def envGetOrDefault(key, default=None): 247 if key in os.environ: 248 return os.environ[key] 249 return default 250 251# ---- methods overriding base class ---- 252# beginFile(genOpts) 253# endFile() 254# beginFeature(interface, emit) 255# endFeature() 256# genType(typeinfo,name) 257# genStruct(typeinfo,name) 258# genGroup(groupinfo,name) 259# genEnum(enuminfo, name) 260# genCmd(cmdinfo) 261class CerealGenerator(OutputGenerator): 262 263 """Generate serialization code""" 264 def __init__(self, errFile = sys.stderr, 265 warnFile = sys.stderr, 266 diagFile = sys.stdout): 267 OutputGenerator.__init__(self, errFile, warnFile, diagFile) 268 269 self.typeInfo = cereal.VulkanTypeInfo(self) 270 271 self.modules = {} 272 self.protos = {} 273 self.moduleList = [] 274 self.protoList = [] 275 276 self.wrappers = [] 277 278 self.codegen = cereal.CodeGen() 279 self.featureSupported = False 280 self.supportedModules = None 281 282 self.baseLibDirPrefix = "aemu/base" 283 self.utilsHeaderDirPrefix = "utils" 284 285 # The cereal variant should be an environmental variable of one of 286 # the following: 287 # - "guest" 288 # - "host" 289 # - "both" 290 cerealVariant = envGetOrDefault("CEREAL_VARIANT", "both") 291 if cerealVariant == "guest": 292 self.cerealFlags = VK_CEREAL_FLAG_GUEST 293 elif cerealVariant == "host": 294 self.cerealFlags = VK_CEREAL_FLAG_HOST 295 else: 296 self.cerealFlags = VK_CEREAL_FLAG_ALL 297 298 # THe host always needs all possible guest struct definitions, while the guest only needs 299 # platform sepcific headers. 300 self.hostCommonExtraVulkanHeaders = '#include "vk_android_native_buffer_gfxstream.h"' 301 302 encoderInclude = f""" 303#include "goldfish_vk_private_defs.h" 304#include <memory> 305 306namespace gfxstream {{ 307namespace guest {{ 308class IOStream; 309}} // namespace guest 310}} // namespace gfxstream 311""" 312 encoderImplInclude = f""" 313#include "Resources.h" 314#include "ResourceTracker.h" 315#include "Validation.h" 316#include "%s.h" 317#include "gfxstream/guest/IOStream.h" 318 319#include "AlignedBuf.h" 320#include "BumpPool.h" 321 322#include "goldfish_vk_marshaling_guest.h" 323#include "goldfish_vk_reserved_marshaling_guest.h" 324#include "goldfish_vk_deepcopy_guest.h" 325#include "goldfish_vk_counting_guest.h" 326#include "goldfish_vk_private_defs.h" 327#include "goldfish_vk_transform_guest.h" 328 329#include <memory> 330#include <optional> 331#include <unordered_map> 332#include <string> 333#include <vector> 334 335""" % VULKAN_STREAM_TYPE_GUEST 336 337 functableImplInclude = """ 338#include "VkEncoder.h" 339#include "ResourceTracker.h" 340#include "gfxstream_vk_entrypoints.h" 341#include "gfxstream_vk_private.h" 342 343#include "goldfish_vk_private_defs.h" 344 345#include <cstring> 346 347// Stuff we are not going to use but if included, 348// will cause compile errors. These are Android Vulkan 349// required extensions, but the approach will be to 350// implement them completely on the guest side. 351#undef VK_KHR_android_surface 352#if defined(LINUX_GUEST_BUILD) || DETECT_OS_FUCHSIA || DETECT_OS_WINDOWS 353#undef VK_ANDROID_native_buffer 354#endif 355""" 356 marshalIncludeGuest = """ 357#include "goldfish_vk_marshaling_guest.h" 358#include "goldfish_vk_private_defs.h" 359#include "%s.h" 360 361// Stuff we are not going to use but if included, 362// will cause compile errors. These are Android Vulkan 363// required extensions, but the approach will be to 364// implement them completely on the guest side. 365#undef VK_KHR_android_surface 366#undef VK_ANDROID_external_memory_android_hardware_buffer 367""" % VULKAN_STREAM_TYPE_GUEST 368 369 reservedmarshalIncludeGuest = """ 370#include "goldfish_vk_marshaling_guest.h" 371#include "goldfish_vk_private_defs.h" 372#include "%s.h" 373 374// Stuff we are not going to use but if included, 375// will cause compile errors. These are Android Vulkan 376// required extensions, but the approach will be to 377// implement them completely on the guest side. 378#undef VK_KHR_android_surface 379#undef VK_ANDROID_external_memory_android_hardware_buffer 380""" % VULKAN_STREAM_TYPE_GUEST 381 382 reservedmarshalImplIncludeGuest = """ 383#include "Resources.h" 384""" 385 386 vulkanStreamIncludeHost = f""" 387{self.hostCommonExtraVulkanHeaders} 388#include "goldfish_vk_private_defs.h" 389 390#include "%s.h" 391#include "{self.baseLibDirPrefix}/files/StreamSerializing.h" 392""" % VULKAN_STREAM_TYPE 393 394 poolInclude = f""" 395{self.hostCommonExtraVulkanHeaders} 396#include "goldfish_vk_private_defs.h" 397#include "{self.baseLibDirPrefix}/BumpPool.h" 398using android::base::Allocator; 399using android::base::BumpPool; 400""" 401 transformIncludeGuest = """ 402#include "goldfish_vk_private_defs.h" 403""" 404 transformInclude = f""" 405{self.hostCommonExtraVulkanHeaders} 406#include "goldfish_vk_private_defs.h" 407#include "goldfish_vk_extension_structs.h" 408""" 409 transformImplIncludeGuest = """ 410#include "ResourceTracker.h" 411""" 412 transformImplInclude = """ 413#include "VkDecoderGlobalState.h" 414""" 415 deepcopyInclude = """ 416#include "vk_util.h" 417""" 418 poolIncludeGuest = f""" 419#include "goldfish_vk_private_defs.h" 420#include "BumpPool.h" 421using gfxstream::aemu::Allocator; 422using gfxstream::aemu::BumpPool; 423// Stuff we are not going to use but if included, 424// will cause compile errors. These are Android Vulkan 425// required extensions, but the approach will be to 426// implement them completely on the guest side. 427#undef VK_KHR_android_surface 428#undef VK_ANDROID_external_memory_android_hardware_buffer 429""" 430 dispatchHeaderDefs = f""" 431{self.hostCommonExtraVulkanHeaders} 432#include "goldfish_vk_private_defs.h" 433namespace gfxstream {{ 434namespace vk {{ 435 436struct VulkanDispatch; 437 438}} // namespace vk 439}} // namespace gfxstream 440using DlOpenFunc = void* (void); 441using DlSymFunc = void* (void*, const char*); 442""" 443 444 extensionStructsInclude = f""" 445{self.hostCommonExtraVulkanHeaders} 446#include "goldfish_vk_private_defs.h" 447#include "host-common/GfxstreamFatalError.h" 448#include "vulkan/vk_enum_string_helper.h" 449""" 450 451 extensionStructsIncludeGuest = """ 452#include "vk_platform_compat.h" 453#include "goldfish_vk_private_defs.h" 454// Stuff we are not going to use but if included, 455// will cause compile errors. These are Android Vulkan 456// required extensions, but the approach will be to 457// implement them completely on the guest side. 458#undef VK_KHR_android_surface 459#undef VK_ANDROID_external_memory_android_hardware_buffer 460""" 461 commonCerealImplIncludes = """ 462#include "goldfish_vk_extension_structs.h" 463#include "goldfish_vk_private_defs.h" 464#include <string.h> 465""" 466 commonCerealIncludesGuest = """ 467#include "vk_platform_compat.h" 468""" 469 commonCerealImplIncludesGuest = """ 470#include "goldfish_vk_extension_structs_guest.h" 471#include "goldfish_vk_private_defs.h" 472 473#include <cstring> 474""" 475 countingIncludes = """ 476#include "vk_platform_compat.h" 477#include "goldfish_vk_private_defs.h" 478""" 479 480 dispatchImplIncludes = """ 481#include <stdio.h> 482#include <stdlib.h> 483#include <string.h> 484""" 485 486 decoderSnapshotHeaderIncludes = f""" 487#include <memory> 488 489#include "VkSnapshotApiCall.h" 490#include "{self.utilsHeaderDirPrefix}/GfxApiLogger.h" 491#include "{self.baseLibDirPrefix}/HealthMonitor.h" 492#include "goldfish_vk_private_defs.h" 493""" 494 decoderSnapshotImplIncludes = f""" 495#include <mutex> 496 497#include "VulkanHandleMapping.h" 498#include "VkDecoderGlobalState.h" 499#include "VkReconstruction.h" 500#include "{self.baseLibDirPrefix}/ThreadAnnotations.h" 501""" 502 503 decoderHeaderIncludes = f""" 504#include "VkDecoderContext.h" 505#include "ProcessResources.h" 506 507#include <memory> 508 509namespace android {{ 510namespace base {{ 511class BumpPool; 512}} // namespace android 513}} // namespace base 514 515""" 516 517 decoderImplIncludes = f""" 518#include "common/goldfish_vk_marshaling.h" 519#include "common/goldfish_vk_reserved_marshaling.h" 520#include "goldfish_vk_private_defs.h" 521#include "common/goldfish_vk_transform.h" 522 523#include "{self.baseLibDirPrefix}/BumpPool.h" 524#include "{self.baseLibDirPrefix}/system/System.h" 525#include "{self.baseLibDirPrefix}/Metrics.h" 526#include "render-utils/IOStream.h" 527#include "FrameBuffer.h" 528#include "gfxstream/host/Tracing.h" 529#include "host-common/feature_control.h" 530#include "host-common/GfxstreamFatalError.h" 531#include "host-common/logging.h" 532 533#include "VkDecoderGlobalState.h" 534#include "VkDecoderSnapshot.h" 535 536#include "VulkanDispatch.h" 537#include "%s.h" 538 539#include <functional> 540#include <optional> 541#include <unordered_map> 542""" % VULKAN_STREAM_TYPE 543 544 def createVkExtensionStructureTypePreamble(extensionName: str) -> str: 545 return f""" 546#define {extensionName}_ENUM(type,id) \ 547 ((type)(1000000000 + (1000 * ({extensionName}_NUMBER - 1)) + (id))) 548""" 549 self.guest_encoder_tag = "guest_encoder" 550 self.host_tag = "host" 551 552 default_guest_abs_encoder_destination = \ 553 os.path.join( 554 os.getcwd(), 555 "..", "..", 556 "device", "generic", "goldfish-opengl", 557 "system", "vulkan_enc") 558 self.guest_abs_encoder_destination = \ 559 envGetOrDefault("GFXSTREAM_GUEST_ENCODER_DIR", 560 default_guest_abs_encoder_destination) 561 562 default_host_abs_decoder_destination = \ 563 os.path.join( 564 os.getcwd(), 565 "android", "android-emugl", "host", 566 "libs", "libOpenglRender", "vulkan") 567 self.host_abs_decoder_destination = \ 568 envGetOrDefault("GFXSTREAM_HOST_DECODER_DIR", 569 default_host_abs_decoder_destination) 570 self.host_script_destination = envGetOrDefault("GFXSTREAM_SCRIPTS_DIR") 571 572 if self.cerealFlags & VK_CEREAL_FLAG_GUEST: 573 self.addGuestEncoderModule( 574 "VkEncoder", 575 extraHeader = encoderInclude, 576 extraImpl = encoderImplInclude) 577 578 self.addGuestEncoderModule("goldfish_vk_extension_structs_guest", 579 extraHeader=extensionStructsIncludeGuest) 580 self.addGuestEncoderModule("goldfish_vk_marshaling_guest", 581 extraHeader=commonCerealIncludesGuest + marshalIncludeGuest, 582 extraImpl=commonCerealImplIncludesGuest) 583 self.addGuestEncoderModule("goldfish_vk_reserved_marshaling_guest", 584 extraHeader=commonCerealIncludesGuest + reservedmarshalIncludeGuest, 585 extraImpl=commonCerealImplIncludesGuest + reservedmarshalImplIncludeGuest) 586 self.addGuestEncoderModule("goldfish_vk_deepcopy_guest", 587 extraHeader=commonCerealIncludesGuest + poolIncludeGuest, 588 extraImpl=commonCerealImplIncludesGuest + deepcopyInclude) 589 self.addGuestEncoderModule("goldfish_vk_counting_guest", 590 extraHeader=countingIncludes, 591 extraImpl=commonCerealImplIncludesGuest) 592 self.addGuestEncoderModule("goldfish_vk_transform_guest", 593 extraHeader=commonCerealIncludesGuest + transformIncludeGuest, 594 extraImpl=commonCerealImplIncludesGuest + transformImplIncludeGuest) 595 self.addGuestEncoderModule( 596 "vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True, 597 moduleName="vulkan_gfxstream_structure_type_guest", useNamespace=False, 598 suppressVulkanHeaders=True, 599 extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM')) 600 601 self.addGuestEncoderModule("func_table", extraImpl=functableImplInclude, implOnly = True, 602 useNamespace = False) 603 604 self.addWrapper(cereal.VulkanEncoder, "VkEncoder") 605 self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs_guest", variant = "guest") 606 self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling_guest", variant = "guest") 607 self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling_guest", variant = "guest") 608 self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy_guest") 609 self.addWrapper(cereal.VulkanCounting, "goldfish_vk_counting_guest") 610 self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform_guest") 611 self.addWrapper(cereal.VulkanFuncTable, "func_table") 612 self.addWrapper(cereal.VulkanGfxstreamStructureType, 613 "vulkan_gfxstream_structure_type_guest") 614 615 if self.cerealFlags & VK_CEREAL_FLAG_HOST: 616 self.addCppModule("common", "goldfish_vk_extension_structs", 617 extraHeader=extensionStructsInclude) 618 self.addCppModule("common", "goldfish_vk_marshaling", 619 extraHeader=vulkanStreamIncludeHost, 620 extraImpl=commonCerealImplIncludes) 621 self.addCppModule("common", "goldfish_vk_reserved_marshaling", 622 extraHeader=vulkanStreamIncludeHost, 623 extraImpl=commonCerealImplIncludes) 624 self.addCppModule("common", "goldfish_vk_deepcopy", 625 extraHeader=poolInclude, 626 extraImpl=commonCerealImplIncludes + deepcopyInclude) 627 self.addCppModule("common", "goldfish_vk_dispatch", 628 extraHeader=dispatchHeaderDefs, 629 extraImpl=dispatchImplIncludes) 630 self.addCppModule("common", "goldfish_vk_transform", 631 extraHeader=transformInclude, 632 extraImpl=transformImplInclude) 633 self.addHostModule("VkDecoder", 634 extraHeader=decoderHeaderIncludes, 635 extraImpl=decoderImplIncludes, 636 useNamespace=False) 637 self.addHostModule("VkDecoderSnapshot", 638 extraHeader=decoderSnapshotHeaderIncludes, 639 extraImpl=decoderSnapshotImplIncludes, 640 useNamespace=False) 641 self.addHostModule("VkSubDecoder", 642 extraHeader="", 643 extraImpl="", 644 useNamespace=False, 645 implOnly=True) 646 647 self.addModule(cereal.PyScript(self.host_tag, "vulkan_printer", customAbsDir=Path( 648 self.host_script_destination) / "print_gfx_logs"), moduleName="ApiLogDecoder") 649 self.addHostModule( 650 "vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True, 651 moduleName="vulkan_gfxstream_structure_type_host", useNamespace=False, 652 suppressVulkanHeaders=True, 653 extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM')) 654 self.addHostModule( 655 "vk_android_native_buffer_structure_type", headerOnly=True, suppressFeatureGuards=True, 656 useNamespace=False, suppressVulkanHeaders=True, 657 extraHeader=createVkExtensionStructureTypePreamble('VK_ANDROID_NATIVE_BUFFER')) 658 659 self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs", variant = "host") 660 self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling") 661 self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling", variant = "host") 662 self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy") 663 self.addWrapper(cereal.VulkanDispatch, "goldfish_vk_dispatch") 664 self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform", resourceTrackerTypeName="VkDecoderGlobalState") 665 self.addWrapper(cereal.VulkanDecoder, "VkDecoder") 666 self.addWrapper(cereal.VulkanDecoderSnapshot, "VkDecoderSnapshot") 667 self.addWrapper(cereal.VulkanSubDecoder, "VkSubDecoder") 668 self.addWrapper(cereal.ApiLogDecoder, "ApiLogDecoder") 669 self.addWrapper(cereal.VulkanGfxstreamStructureType, "vulkan_gfxstream_structure_type_host") 670 self.addWrapper(cereal.VulkanAndroidNativeBufferStructureType, 671 "vk_android_native_buffer_structure_type") 672 673 def addGuestEncoderModule( 674 self, basename, extraHeader="", extraImpl="", useNamespace=True, headerOnly=False, 675 suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False, implOnly=False): 676 if not os.path.exists(self.guest_abs_encoder_destination): 677 print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination) 678 return 679 self.addCppModule(self.guest_encoder_tag, basename, extraHeader=extraHeader, 680 extraImpl=extraImpl, customAbsDir=self.guest_abs_encoder_destination, 681 useNamespace=useNamespace, implOnly=implOnly, headerOnly=headerOnly, 682 suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName, 683 suppressVulkanHeaders=suppressVulkanHeaders) 684 685 def addHostModule( 686 self, basename, extraHeader="", extraImpl="", useNamespace=True, implOnly=False, 687 suppress=False, headerOnly=False, suppressFeatureGuards=False, moduleName=None, 688 suppressVulkanHeaders=False): 689 if not os.path.exists(self.host_abs_decoder_destination): 690 print("Path [%s] not found (host encoder path), skipping" % 691 self.host_abs_decoder_destination) 692 return 693 if not suppressVulkanHeaders: 694 extraHeader = self.hostCommonExtraVulkanHeaders + '\n' + extraHeader 695 self.addCppModule( 696 self.host_tag, basename, extraHeader=extraHeader, extraImpl=extraImpl, 697 customAbsDir=self.host_abs_decoder_destination, useNamespace=useNamespace, 698 implOnly=implOnly, suppress=suppress, headerOnly=headerOnly, 699 suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName, 700 suppressVulkanHeaders=suppressVulkanHeaders) 701 702 def addModule(self, module, moduleName=None): 703 if moduleName is None: 704 moduleName = module.basename 705 self.moduleList.append(moduleName) 706 self.modules[moduleName] = module 707 708 def addCppModule( 709 self, directory, basename, extraHeader="", extraImpl="", customAbsDir=None, 710 useNamespace=True, implOnly=False, suppress=False, headerOnly=False, 711 suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False): 712 module = cereal.Module( 713 directory, basename, customAbsDir=customAbsDir, suppress=suppress, implOnly=implOnly, 714 headerOnly=headerOnly, suppressFeatureGuards=suppressFeatureGuards) 715 self.addModule(module, moduleName=moduleName) 716 module.headerPreamble = copyrightHeader 717 module.headerPreamble += \ 718 autogeneratedHeaderTemplate % \ 719 (basename, "(header) generated by %s" % banner_command(sys.argv)) 720 721 module.headerPreamble += "#pragma once\n" 722 if (not suppressVulkanHeaders): 723 module.headerPreamble += "#include <vulkan/vulkan.h>\n" 724 module.headerPreamble += '#include "vulkan_gfxstream.h"\n' 725 module.headerPreamble += '#include "vk_android_native_buffer_gfxstream.h"\n' 726 module.headerPreamble += extraHeader + '\n' 727 if useNamespace: 728 module.headerPreamble += namespaceBegin 729 730 module.implPreamble = copyrightHeader 731 module.implPreamble += \ 732 autogeneratedHeaderTemplate % \ 733 (basename, "(impl) generated by %s" % \ 734 banner_command(sys.argv)) 735 if not implOnly: 736 module.implPreamble += '\n#include "%s.h"' % \ 737 (basename) 738 739 module.implPreamble += extraImpl 740 741 if useNamespace: 742 module.implPreamble += namespaceBegin 743 module.implPostamble += namespaceEnd 744 module.headerPostamble += namespaceEnd 745 746 def addWrapper(self, moduleType, moduleName, **kwargs): 747 if moduleName not in self.modules: 748 print(f'Unknown module: {moduleName}. All known modules are: {", ".join(self.modules)}.') 749 return 750 self.wrappers.append( 751 (moduleType( 752 self.modules[moduleName], 753 self.typeInfo, **kwargs), 754 moduleName) 755 ) 756 757 def forEachModule(self, func): 758 for moduleName in self.moduleList: 759 func(self.modules[moduleName]) 760 761 def forEachWrapper(self, func, supportedModules): 762 for wrapper in self.wrappers: 763 if supportedModules is None: 764 func(wrapper[0]) 765 elif wrapper[1] in supportedModules: 766 func(wrapper[0]) 767 768## Overrides#################################################################### 769 770 def beginFile(self, genOpts): 771 OutputGenerator.beginFile(self, genOpts) 772 773 self.forEachModule(lambda m: m.begin(self.genOpts.directory)) 774 self.forEachWrapper(lambda w: w.onBegin(), None) 775 776 def endFile(self): 777 OutputGenerator.endFile(self) 778 779 self.typeInfo.onEnd() 780 781 self.forEachWrapper(lambda w: w.onEnd(), None) 782 self.forEachModule(lambda m: m.end()) 783 784 def beginFeature(self, interface, emit): 785 # Start processing in superclass 786 OutputGenerator.beginFeature(self, interface, emit) 787 788 for supportedFeature in SUPPORTED_FEATURES: 789 if self.featureName == supportedFeature: 790 self.featureSupported = True 791 792 if self.featureSupported == False and UNSUPPORTED_FEATURE_MODULES: 793 self.featureSupported = True 794 self.supportedModules = UNSUPPORTED_FEATURE_MODULES 795 elif self.featureSupported == False: 796 return 797 else: 798 self.supportedModules = SUPPORTED_MODULES.get(self.featureName) 799 800 self.typeInfo.onBeginFeature(self.featureName, self.featureType) 801 802 self.forEachModule( 803 lambda m: m.appendHeader("#ifdef %s\n" % self.featureName) 804 if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None) 805 self.forEachModule( 806 lambda m: m.appendImpl("#ifdef %s\n" % self.featureName) 807 if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None) 808 self.forEachWrapper(lambda w: w.onBeginFeature(self.featureName, self.featureType), self.supportedModules) 809 # functable needs to understand the feature type (device vs instance) of each cmd 810 for features in interface.findall('require'): 811 for c in features.findall('command'): 812 self.forEachWrapper(lambda w: w.onFeatureNewCmd(c.get('name')), self.supportedModules) 813 814 def endFeature(self): 815 # Finish processing in superclass 816 OutputGenerator.endFeature(self) 817 818 if self.featureSupported == False: 819 return 820 821 self.featureSupported = False 822 823 self.typeInfo.onEndFeature() 824 825 self.forEachModule(lambda m: m.appendHeader("#endif\n") if isinstance( 826 m, cereal.Module) and not m.suppressFeatureGuards else None) 827 self.forEachModule(lambda m: m.appendImpl("#endif\n") if isinstance( 828 m, cereal.Module) and not m.suppressFeatureGuards else None) 829 self.forEachWrapper(lambda w: w.onEndFeature(), self.supportedModules) 830 831 def genType(self, typeinfo: TypeInfo, name, alias): 832 OutputGenerator.genType(self, typeinfo, name, alias) 833 834 # Maybe this check can be removed if we refactor other things inside 835 # the cereal subdirectory. 836 if self.featureSupported == False and name in REQUIRED_TYPES: 837 self.typeInfo.onGenType(typeinfo, name, alias) 838 return 839 840 if self.featureSupported == False: 841 return 842 843 self.typeInfo.onGenType(typeinfo, name, alias) 844 self.forEachWrapper(lambda w: w.onGenType(typeinfo, name, alias), self.supportedModules) 845 846 def genStruct(self, typeinfo, typeName, alias): 847 OutputGenerator.genStruct(self, typeinfo, typeName, alias) 848 if self.featureSupported == False: 849 return 850 851 self.typeInfo.onGenStruct(typeinfo, typeName, alias) 852 self.forEachWrapper(lambda w: w.onGenStruct(typeinfo, typeName, alias), self.supportedModules) 853 854 def genGroup(self, groupinfo: GroupInfo, groupName, alias = None): 855 OutputGenerator.genGroup(self, groupinfo, groupName, alias) 856 if self.featureSupported == False: 857 return 858 859 self.typeInfo.onGenGroup(groupinfo, groupName, alias) 860 self.forEachWrapper(lambda w: w.onGenGroup(groupinfo, groupName, alias), self.supportedModules) 861 862 def genEnum(self, enuminfo: EnumInfo, name, alias): 863 OutputGenerator.genEnum(self, enuminfo, name, alias) 864 if self.featureSupported == False: 865 return 866 self.typeInfo.onGenEnum(enuminfo, name, alias) 867 self.forEachWrapper(lambda w: w.onGenEnum(enuminfo, name, alias), self.supportedModules) 868 869 def genCmd(self, cmdinfo, name, alias): 870 OutputGenerator.genCmd(self, cmdinfo, name, alias) 871 if self.featureSupported == False: 872 return 873 874 self.typeInfo.onGenCmd(cmdinfo, name, alias) 875 self.forEachWrapper(lambda w: w.onGenCmd(cmdinfo, name, alias), self.supportedModules) 876