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