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