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