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