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 30copyrightHeader = """// Copyright (C) 2018 The Android Open Source Project 31// Copyright (C) 2018 Google Inc. 32// 33// Licensed under the Apache License, Version 2.0 (the "License"); 34// you may not use this file except in compliance with the License. 35// You may obtain a copy of the License at 36// 37// http://www.apache.org/licenses/LICENSE-2.0 38// 39// Unless required by applicable law or agreed to in writing, software 40// distributed under the License is distributed on an "AS IS" BASIS, 41// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 42// See the License for the specific language governing permissions and 43// limitations under the License. 44""" 45 46# We put the long generated commands in a separate paragraph, so that the formatter won't mess up 47# with other texts. 48autogeneratedHeaderTemplate = """ 49// Autogenerated module %s 50// 51// %s 52// 53// Please do not modify directly; 54// re-run gfxstream-protocols/scripts/generate-vulkan-sources.sh, 55// or directly from Python by defining: 56// VULKAN_REGISTRY_XML_DIR : Directory containing vk.xml 57// VULKAN_REGISTRY_SCRIPTS_DIR : Directory containing genvk.py 58// CEREAL_OUTPUT_DIR: Where to put the generated sources. 59// 60// python3 $VULKAN_REGISTRY_SCRIPTS_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o $CEREAL_OUTPUT_DIR 61// 62""" 63 64autogeneratedMkTemplate = """ 65# Autogenerated makefile 66# %s 67# Please do not modify directly; 68# re-run gfxstream-protocols/scripts/generate-vulkan-sources.sh, 69# or directly from Python by defining: 70# VULKAN_REGISTRY_XML_DIR : Directory containing vk.xml 71# VULKAN_REGISTRY_SCRIPTS_DIR : Directory containing genvk.py 72# CEREAL_OUTPUT_DIR: Where to put the generated sources. 73# python3 $VULKAN_REGISTRY_SCRIPTS_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o $CEREAL_OUTPUT_DIR 74""" 75 76def banner_command(argv): 77 """Return sanitized command-line description. 78 |argv| must be a list of command-line parameters, e.g. sys.argv. 79 Return a string corresponding to the command, with platform-specific 80 paths removed.""" 81 82 def makePosixRelative(someArg): 83 if os.path.exists(someArg): 84 return str(PurePosixPath(Path(os.path.relpath(someArg)))) 85 return someArg 86 87 return ' '.join(map(makePosixRelative, argv)) 88 89suppressEnabled = False 90suppressExceptModule = None 91 92def envGetOrDefault(key, default=None): 93 if key in os.environ: 94 return os.environ[key] 95 print("envGetOrDefault: notfound: %s" % key) 96 return default 97 98def init_suppress_option(): 99 global suppressEnabled 100 global suppressExceptModule 101 102 if "ANDROID_EMU_VK_CEREAL_SUPPRESS" in os.environ: 103 option = os.environ["ANDROID_EMU_VK_CEREAL_SUPPRESS"] 104 105 if option != "": 106 suppressExceptModule = option 107 suppressEnabled = True 108 print("suppressEnabled: %s" % suppressExceptModule) 109 110# ---- methods overriding base class ---- 111# beginFile(genOpts) 112# endFile() 113# beginFeature(interface, emit) 114# endFeature() 115# genType(typeinfo,name) 116# genStruct(typeinfo,name) 117# genGroup(groupinfo,name) 118# genEnum(enuminfo, name) 119# genCmd(cmdinfo) 120class CerealGenerator(OutputGenerator): 121 122 """Generate serialization code""" 123 def __init__(self, errFile = sys.stderr, 124 warnFile = sys.stderr, 125 diagFile = sys.stdout): 126 OutputGenerator.__init__(self, errFile, warnFile, diagFile) 127 128 init_suppress_option() 129 130 self.typeInfo = cereal.VulkanTypeInfo(self) 131 132 self.modules = {} 133 self.protos = {} 134 self.moduleList = [] 135 self.protoList = [] 136 137 self.wrappers = [] 138 139 self.codegen = cereal.CodeGen() 140 141 self.guestBaseLibDirPrefix = \ 142 envGetOrDefault("VK_CEREAL_GUEST_BASELIB_PREFIX", "android/base") 143 self.baseLibDirPrefix = \ 144 envGetOrDefault("VK_CEREAL_BASELIB_PREFIX", "android/base") 145 self.baseLibLinkName = \ 146 envGetOrDefault("VK_CEREAL_BASELIB_LINKNAME", "android-emu-base") 147 self.vulkanHeaderTargetName = envGetOrDefault("VK_CEREAL_VK_HEADER_TARGET", "") 148 149 # THe host always needs all possible guest struct definitions, while the guest only needs 150 # platform sepcific headers. 151 self.hostCommonExtraVulkanHeaders = '#include "vk_android_native_buffer.h"' 152 self.host_cmake_generator = lambda cppFiles: f"""{autogeneratedMkTemplate % banner_command(sys.argv)} 153add_library(OpenglRender_vulkan_cereal {cppFiles}) 154target_compile_definitions(OpenglRender_vulkan_cereal PRIVATE -DVK_GOOGLE_gfxstream) 155if (WIN32) 156 target_compile_definitions(OpenglRender_vulkan_cereal PRIVATE -DVK_USE_PLATFORM_WIN32_KHR) 157endif() 158target_link_libraries(OpenglRender_vulkan_cereal PUBLIC {self.baseLibLinkName} {self.vulkanHeaderTargetName}) 159 160target_include_directories(OpenglRender_vulkan_cereal 161 PUBLIC 162 . 163 PRIVATE 164 .. 165 ../.. 166 ../../../include) 167""" 168 169 encoderInclude = """ 170#include "android/base/AndroidHealthMonitor.h" 171#include "goldfish_vk_private_defs.h" 172#include <memory> 173class IOStream; 174""" 175 encoderImplInclude = f""" 176#include "EncoderDebug.h" 177#include "IOStream.h" 178#include "Resources.h" 179#include "ResourceTracker.h" 180#include "Validation.h" 181#include "%s.h" 182 183#include "{self.guestBaseLibDirPrefix}/AlignedBuf.h" 184#include "{self.guestBaseLibDirPrefix}/BumpPool.h" 185#include "{self.guestBaseLibDirPrefix}/synchronization/AndroidLock.h" 186 187#include <cutils/properties.h> 188 189#include "goldfish_vk_marshaling_guest.h" 190#include "goldfish_vk_reserved_marshaling_guest.h" 191#include "goldfish_vk_deepcopy_guest.h" 192#include "goldfish_vk_counting_guest.h" 193#include "goldfish_vk_handlemap_guest.h" 194#include "goldfish_vk_private_defs.h" 195#include "goldfish_vk_transform_guest.h" 196 197#include <memory> 198#include <optional> 199#include <unordered_map> 200#include <string> 201#include <vector> 202 203""" % VULKAN_STREAM_TYPE_GUEST 204 205 functableImplInclude = """ 206#include "VkEncoder.h" 207#include "../OpenglSystemCommon/HostConnection.h" 208#include "ResourceTracker.h" 209 210#include "goldfish_vk_private_defs.h" 211 212#include <log/log.h> 213#include <cstring> 214 215// Stuff we are not going to use but if included, 216// will cause compile errors. These are Android Vulkan 217// required extensions, but the approach will be to 218// implement them completely on the guest side. 219#undef VK_KHR_android_surface 220""" 221 marshalIncludeGuest = """ 222#include "goldfish_vk_marshaling_guest.h" 223#include "goldfish_vk_private_defs.h" 224#include "%s.h" 225 226// Stuff we are not going to use but if included, 227// will cause compile errors. These are Android Vulkan 228// required extensions, but the approach will be to 229// implement them completely on the guest side. 230#undef VK_KHR_android_surface 231#undef VK_ANDROID_external_memory_android_hardware_buffer 232""" % VULKAN_STREAM_TYPE_GUEST 233 234 reservedmarshalIncludeGuest = """ 235#include "goldfish_vk_marshaling_guest.h" 236#include "goldfish_vk_private_defs.h" 237#include "%s.h" 238 239// Stuff we are not going to use but if included, 240// will cause compile errors. These are Android Vulkan 241// required extensions, but the approach will be to 242// implement them completely on the guest side. 243#undef VK_KHR_android_surface 244#undef VK_ANDROID_external_memory_android_hardware_buffer 245""" % VULKAN_STREAM_TYPE_GUEST 246 247 reservedmarshalImplIncludeGuest = """ 248#include "Resources.h" 249""" 250 251 vulkanStreamIncludeHost = f""" 252{self.hostCommonExtraVulkanHeaders} 253#include "goldfish_vk_private_defs.h" 254 255#include "%s.h" 256#include "{self.baseLibDirPrefix}/files/StreamSerializing.h" 257""" % VULKAN_STREAM_TYPE 258 259 testingInclude = f""" 260{self.hostCommonExtraVulkanHeaders} 261#include "goldfish_vk_private_defs.h" 262#include <string.h> 263#include <functional> 264using OnFailCompareFunc = std::function<void(const char*)>; 265""" 266 poolInclude = f""" 267{self.hostCommonExtraVulkanHeaders} 268#include "goldfish_vk_private_defs.h" 269#include "{self.baseLibDirPrefix}/BumpPool.h" 270using android::base::Allocator; 271using android::base::BumpPool; 272""" 273 handleMapInclude = f""" 274{self.hostCommonExtraVulkanHeaders} 275#include "goldfish_vk_private_defs.h" 276#include "VulkanHandleMapping.h" 277""" 278 transformIncludeGuest = """ 279#include "goldfish_vk_private_defs.h" 280""" 281 transformInclude = f""" 282{self.hostCommonExtraVulkanHeaders} 283#include "goldfish_vk_private_defs.h" 284#include "goldfish_vk_extension_structs.h" 285""" 286 transformImplIncludeGuest = """ 287#include "ResourceTracker.h" 288""" 289 transformImplInclude = """ 290#include "VkDecoderGlobalState.h" 291""" 292 deepcopyInclude = """ 293#include "vk_util.h" 294""" 295 poolIncludeGuest = f""" 296#include "goldfish_vk_private_defs.h" 297#include "{self.guestBaseLibDirPrefix}/BumpPool.h" 298using android::base::Allocator; 299using android::base::BumpPool; 300// Stuff we are not going to use but if included, 301// will cause compile errors. These are Android Vulkan 302// required extensions, but the approach will be to 303// implement them completely on the guest side. 304#undef VK_KHR_android_surface 305#undef VK_ANDROID_external_memory_android_hardware_buffer 306""" 307 handleMapIncludeGuest = """ 308#include "goldfish_vk_private_defs.h" 309#include "VulkanHandleMapping.h" 310// Stuff we are not going to use but if included, 311// will cause compile errors. These are Android Vulkan 312// required extensions, but the approach will be to 313// implement them completely on the guest side. 314#undef VK_KHR_android_surface 315#undef VK_ANDROID_external_memory_android_hardware_buffer 316""" 317 dispatchHeaderDefs = f""" 318{self.hostCommonExtraVulkanHeaders} 319#include "goldfish_vk_private_defs.h" 320namespace goldfish_vk {{ 321 322struct VulkanDispatch; 323 324}} // namespace goldfish_vk 325using DlOpenFunc = void* (void); 326using DlSymFunc = void* (void*, const char*); 327""" 328 329 extensionStructsInclude = f""" 330{self.hostCommonExtraVulkanHeaders} 331#include "goldfish_vk_private_defs.h" 332""" 333 334 extensionStructsIncludeGuest = """ 335#include "vk_platform_compat.h" 336#include "goldfish_vk_private_defs.h" 337// Stuff we are not going to use but if included, 338// will cause compile errors. These are Android Vulkan 339// required extensions, but the approach will be to 340// implement them completely on the guest side. 341#undef VK_KHR_android_surface 342#undef VK_ANDROID_external_memory_android_hardware_buffer 343""" 344 commonCerealImplIncludes = """ 345#include "goldfish_vk_extension_structs.h" 346#include "goldfish_vk_private_defs.h" 347#include <string.h> 348""" 349 commonCerealIncludesGuest = """ 350#include "vk_platform_compat.h" 351""" 352 commonCerealImplIncludesGuest = """ 353#include "goldfish_vk_extension_structs_guest.h" 354#include "goldfish_vk_private_defs.h" 355 356#include <cstring> 357""" 358 countingIncludes = """ 359#include "vk_platform_compat.h" 360#include "goldfish_vk_private_defs.h" 361""" 362 363 dispatchImplIncludes = """ 364#include <stdio.h> 365#include <stdlib.h> 366#include <string.h> 367""" 368 369 decoderSnapshotHeaderIncludes = f""" 370#include <memory> 371#include "{self.baseLibDirPrefix}/GfxApiLogger.h" 372#include "{self.baseLibDirPrefix}/HealthMonitor.h" 373#include "common/goldfish_vk_private_defs.h" 374""" 375 decoderSnapshotImplIncludes = f""" 376#include "VulkanHandleMapping.h" 377#include "VkDecoderGlobalState.h" 378#include "VkReconstruction.h" 379 380#include "{self.baseLibDirPrefix}/synchronization/Lock.h" 381""" 382 383 decoderHeaderIncludes = f""" 384#include "VkDecoderContext.h" 385 386#include <memory> 387 388namespace android {{ 389namespace base {{ 390class BumpPool; 391}} // namespace android 392}} // namespace base 393 394""" 395 396 decoderImplIncludes = f""" 397#include "common/goldfish_vk_marshaling.h" 398#include "common/goldfish_vk_reserved_marshaling.h" 399#include "common/goldfish_vk_private_defs.h" 400#include "common/goldfish_vk_transform.h" 401 402#include "{self.baseLibDirPrefix}/BumpPool.h" 403#include "{self.baseLibDirPrefix}/system/System.h" 404#include "{self.baseLibDirPrefix}/Tracing.h" 405#include "{self.baseLibDirPrefix}/Metrics.h" 406#include "stream-servers/IOStream.h" 407#include "host-common/feature_control.h" 408#include "host-common/GfxstreamFatalError.h" 409#include "host-common/logging.h" 410 411#include "VkDecoderGlobalState.h" 412#include "VkDecoderSnapshot.h" 413 414#include "VulkanDispatch.h" 415#include "%s.h" 416 417#include <functional> 418#include <optional> 419#include <unordered_map> 420""" % VULKAN_STREAM_TYPE 421 422 def createVkExtensionStructureTypePreamble(extensionName: str) -> str: 423 return f""" 424#define {extensionName}_ENUM(type,id) \ 425 ((type)(1000000000 + (1000 * ({extensionName}_NUMBER - 1)) + (id))) 426""" 427 self.guest_encoder_tag = "guest_encoder" 428 self.guest_hal_tag = "guest_hal" 429 self.host_tag = "host" 430 431 default_guest_abs_encoder_destination = \ 432 os.path.join( 433 os.getcwd(), 434 "..", "..", 435 "device", "generic", "goldfish-opengl", 436 "system", "vulkan_enc") 437 self.guest_abs_encoder_destination = \ 438 envGetOrDefault("VK_CEREAL_GUEST_ENCODER_DIR", 439 default_guest_abs_encoder_destination) 440 441 default_guest_abs_hal_destination = \ 442 os.path.join( 443 os.getcwd(), 444 "..", "..", 445 "device", "generic", "goldfish-opengl", 446 "system", "vulkan") 447 self.guest_abs_hal_destination = \ 448 envGetOrDefault("VK_CEREAL_GUEST_HAL_DIR", 449 default_guest_abs_hal_destination) 450 451 default_host_abs_decoder_destination = \ 452 os.path.join( 453 os.getcwd(), 454 "android", "android-emugl", "host", 455 "libs", "libOpenglRender", "vulkan") 456 self.host_abs_decoder_destination = \ 457 envGetOrDefault("VK_CEREAL_HOST_DECODER_DIR", 458 default_host_abs_decoder_destination) 459 self.host_script_destination = envGetOrDefault("VK_CEREAL_HOST_SCRIPTS_DIR") 460 assert(self.host_script_destination is not None) 461 462 self.addGuestEncoderModule( 463 "VkEncoder", 464 extraHeader = encoderInclude, 465 extraImpl = encoderImplInclude) 466 467 self.addGuestEncoderModule("goldfish_vk_extension_structs_guest", 468 extraHeader=extensionStructsIncludeGuest) 469 self.addGuestEncoderModule("goldfish_vk_marshaling_guest", 470 extraHeader=commonCerealIncludesGuest + marshalIncludeGuest, 471 extraImpl=commonCerealImplIncludesGuest) 472 self.addGuestEncoderModule("goldfish_vk_reserved_marshaling_guest", 473 extraHeader=commonCerealIncludesGuest + reservedmarshalIncludeGuest, 474 extraImpl=commonCerealImplIncludesGuest + reservedmarshalImplIncludeGuest) 475 self.addGuestEncoderModule("goldfish_vk_deepcopy_guest", 476 extraHeader=commonCerealIncludesGuest + poolIncludeGuest, 477 extraImpl=commonCerealImplIncludesGuest + deepcopyInclude) 478 self.addGuestEncoderModule("goldfish_vk_counting_guest", 479 extraHeader=countingIncludes, 480 extraImpl=commonCerealImplIncludesGuest) 481 self.addGuestEncoderModule("goldfish_vk_handlemap_guest", 482 extraHeader=commonCerealIncludesGuest + handleMapIncludeGuest, 483 extraImpl=commonCerealImplIncludesGuest) 484 self.addGuestEncoderModule("goldfish_vk_transform_guest", 485 extraHeader=commonCerealIncludesGuest + transformIncludeGuest, 486 extraImpl=commonCerealImplIncludesGuest + transformImplIncludeGuest) 487 self.addGuestEncoderModule( 488 "vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True, 489 moduleName="vulkan_gfxstream_structure_type_guest", useNamespace=False, 490 suppressVulkanHeaders=True, 491 extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM')) 492 493 self.addGuestEncoderModule("func_table", extraImpl=functableImplInclude) 494 495 self.addCppModule("common", "goldfish_vk_extension_structs", 496 extraHeader=extensionStructsInclude) 497 self.addCppModule("common", "goldfish_vk_marshaling", 498 extraHeader=vulkanStreamIncludeHost, 499 extraImpl=commonCerealImplIncludes) 500 self.addCppModule("common", "goldfish_vk_reserved_marshaling", 501 extraHeader=vulkanStreamIncludeHost, 502 extraImpl=commonCerealImplIncludes) 503 self.addCppModule("common", "goldfish_vk_testing", 504 extraHeader=testingInclude, 505 extraImpl=commonCerealImplIncludes) 506 self.addCppModule("common", "goldfish_vk_deepcopy", 507 extraHeader=poolInclude, 508 extraImpl=commonCerealImplIncludes + deepcopyInclude) 509 self.addCppModule("common", "goldfish_vk_handlemap", 510 extraHeader=handleMapInclude, 511 extraImpl=commonCerealImplIncludes) 512 self.addCppModule("common", "goldfish_vk_dispatch", 513 extraHeader=dispatchHeaderDefs, 514 extraImpl=dispatchImplIncludes) 515 self.addCppModule("common", "goldfish_vk_transform", 516 extraHeader=transformInclude, 517 extraImpl=transformImplInclude) 518 self.addHostModule("VkDecoder", 519 extraHeader=decoderHeaderIncludes, 520 extraImpl=decoderImplIncludes, 521 useNamespace=False) 522 self.addHostModule("VkDecoderSnapshot", 523 extraHeader=decoderSnapshotHeaderIncludes, 524 extraImpl=decoderSnapshotImplIncludes, 525 useNamespace=False) 526 self.addHostModule("VkSubDecoder", 527 extraHeader="", 528 extraImpl="", 529 useNamespace=False, 530 implOnly=True) 531 532 self.addModule(cereal.PyScript(self.host_tag, "vulkan_printer", customAbsDir=Path( 533 self.host_script_destination) / "print_gfx_logs"), moduleName="ApiLogDecoder") 534 self.addHostModule( 535 "vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True, 536 moduleName="vulkan_gfxstream_structure_type_host", useNamespace=False, 537 suppressVulkanHeaders=True, 538 extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM')) 539 self.addHostModule( 540 "vk_android_native_buffer_structure_type", headerOnly=True, suppressFeatureGuards=True, 541 useNamespace=False, suppressVulkanHeaders=True, 542 extraHeader=createVkExtensionStructureTypePreamble('VK_ANDROID_NATIVE_BUFFER')) 543 544 self.addWrapper(cereal.VulkanEncoder, "VkEncoder") 545 self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs_guest") 546 self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling_guest", variant = "guest") 547 self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling_guest", variant = "guest") 548 self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy_guest") 549 self.addWrapper(cereal.VulkanCounting, "goldfish_vk_counting_guest") 550 self.addWrapper(cereal.VulkanHandleMap, "goldfish_vk_handlemap_guest") 551 self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform_guest") 552 self.addWrapper(cereal.VulkanFuncTable, "func_table") 553 self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs") 554 self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling") 555 self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling", variant = "host") 556 self.addWrapper(cereal.VulkanTesting, "goldfish_vk_testing") 557 self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy") 558 self.addWrapper(cereal.VulkanHandleMap, "goldfish_vk_handlemap") 559 self.addWrapper(cereal.VulkanDispatch, "goldfish_vk_dispatch") 560 self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform", resourceTrackerTypeName="VkDecoderGlobalState") 561 self.addWrapper(cereal.VulkanDecoder, "VkDecoder") 562 self.addWrapper(cereal.VulkanDecoderSnapshot, "VkDecoderSnapshot") 563 self.addWrapper(cereal.VulkanSubDecoder, "VkSubDecoder") 564 self.addWrapper(cereal.ApiLogDecoder, "ApiLogDecoder") 565 self.addWrapper(cereal.VulkanGfxstreamStructureType, 566 "vulkan_gfxstream_structure_type_guest") 567 self.addWrapper(cereal.VulkanGfxstreamStructureType, "vulkan_gfxstream_structure_type_host") 568 self.addWrapper(cereal.VulkanAndroidNativeBufferStructureType, 569 "vk_android_native_buffer_structure_type") 570 571 self.guestAndroidMkCppFiles = "" 572 self.hostCMakeCppFiles = "" 573 self.hostDecoderCMakeCppFiles = "" 574 575 def addSrcEntry(m): 576 mkSrcEntry = m.getMakefileSrcEntry() 577 cmakeSrcEntry = m.getCMakeSrcEntry() 578 if m.directory == self.guest_encoder_tag: 579 self.guestAndroidMkCppFiles += mkSrcEntry 580 elif m.directory == self.host_tag: 581 self.hostDecoderCMakeCppFiles += cmakeSrcEntry 582 elif m.directory != self.guest_hal_tag: 583 self.hostCMakeCppFiles += cmakeSrcEntry 584 585 self.forEachModule(addSrcEntry) 586 587 def addGuestEncoderModule( 588 self, basename, extraHeader="", extraImpl="", useNamespace=True, headerOnly=False, 589 suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False): 590 if not os.path.exists(self.guest_abs_encoder_destination): 591 print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination) 592 return 593 self.addCppModule(self.guest_encoder_tag, basename, extraHeader=extraHeader, 594 extraImpl=extraImpl, customAbsDir=self.guest_abs_encoder_destination, 595 useNamespace=useNamespace, headerOnly=headerOnly, 596 suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName, 597 suppressVulkanHeaders=suppressVulkanHeaders) 598 599 def addGuestHalModule(self, basename, extraHeader = "", extraImpl = "", useNamespace = True): 600 if not os.path.exists(self.guest_abs_hal_destination): 601 print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination) 602 return 603 self.addCppModule(self.guest_hal_tag, 604 basename, 605 extraHeader = extraHeader, 606 extraImpl = extraImpl, 607 customAbsDir = self.guest_abs_hal_destination, 608 useNamespace = useNamespace) 609 610 def addHostModule( 611 self, basename, extraHeader="", extraImpl="", useNamespace=True, implOnly=False, 612 suppress=False, headerOnly=False, suppressFeatureGuards=False, moduleName=None, 613 suppressVulkanHeaders=False): 614 if not os.path.exists(self.host_abs_decoder_destination): 615 print("Path [%s] not found (host encoder path), skipping" % 616 self.host_abs_decoder_destination) 617 return 618 if not suppressVulkanHeaders: 619 extraHeader = self.hostCommonExtraVulkanHeaders + '\n' + extraHeader 620 self.addCppModule( 621 self.host_tag, basename, extraHeader=extraHeader, extraImpl=extraImpl, 622 customAbsDir=self.host_abs_decoder_destination, useNamespace=useNamespace, 623 implOnly=implOnly, suppress=suppress, headerOnly=headerOnly, 624 suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName, 625 suppressVulkanHeaders=suppressVulkanHeaders) 626 627 def addModule(self, module, moduleName=None): 628 if moduleName is None: 629 moduleName = module.basename 630 self.moduleList.append(moduleName) 631 self.modules[moduleName] = module 632 633 def addCppModule( 634 self, directory, basename, extraHeader="", extraImpl="", customAbsDir=None, 635 useNamespace=True, implOnly=False, suppress=False, headerOnly=False, 636 suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False): 637 module = cereal.Module( 638 directory, basename, customAbsDir=customAbsDir, suppress=suppress, implOnly=implOnly, 639 headerOnly=headerOnly, suppressFeatureGuards=suppressFeatureGuards) 640 self.addModule(module, moduleName=moduleName) 641 module.headerPreamble = copyrightHeader 642 module.headerPreamble += \ 643 autogeneratedHeaderTemplate % \ 644 (basename, "(header) generated by %s" % banner_command(sys.argv)) 645 646 namespaceBegin = "namespace goldfish_vk {" if useNamespace else "" 647 namespaceEnd = "} // namespace goldfish_vk" if useNamespace else "" 648 649 module.headerPreamble += "#pragma once\n" 650 if (not suppressVulkanHeaders): 651 module.headerPreamble += "#include <vulkan/vulkan.h>\n" 652 module.headerPreamble += '#include "vulkan_gfxstream.h"\n' 653 module.headerPreamble += extraHeader + '\n' 654 if namespaceBegin: 655 module.headerPreamble += namespaceBegin + '\n' 656 657 module.implPreamble = copyrightHeader 658 module.implPreamble += \ 659 autogeneratedHeaderTemplate % \ 660 (basename, "(impl) generated by %s" % \ 661 banner_command(sys.argv)) 662 if not implOnly: 663 module.implPreamble += """ 664#include "%s.h" 665 666%s 667 668%s 669 670""" % (basename, extraImpl, namespaceBegin) 671 672 module.headerPostamble = """ 673%s 674""" % namespaceEnd 675 module.implPostamble = """ 676%s 677""" % namespaceEnd 678 679 def addWrapper(self, moduleType, moduleName, **kwargs): 680 if moduleName not in self.modules: 681 print(f'Unknown module: {moduleName}. All known modules are: {", ".join(self.modules)}.') 682 return 683 self.wrappers.append( 684 moduleType( 685 self.modules[moduleName], 686 self.typeInfo, **kwargs)) 687 688 def forEachModule(self, func): 689 for moduleName in self.moduleList: 690 func(self.modules[moduleName]) 691 692 def forEachWrapper(self, func): 693 for wrapper in self.wrappers: 694 func(wrapper) 695 696## Overrides#################################################################### 697 698 def beginFile(self, genOpts): 699 OutputGenerator.beginFile(self, genOpts, suppressEnabled) 700 701 if suppressEnabled: 702 def enableSuppression(m): 703 m.suppress = True 704 self.forEachModule(enableSuppression) 705 self.modules[suppressExceptModule].suppress = False 706 707 if not suppressEnabled: 708 write(self.host_cmake_generator(self.hostCMakeCppFiles), 709 file = self.outFile) 710 711 guestEncoderAndroidMkPath = \ 712 os.path.join( \ 713 self.guest_abs_encoder_destination, 714 "Android.mk") 715 716 self.forEachModule(lambda m: m.begin(self.genOpts.directory)) 717 self.forEachWrapper(lambda w: w.onBegin()) 718 719 def endFile(self): 720 OutputGenerator.endFile(self) 721 722 self.typeInfo.onEnd() 723 724 self.forEachWrapper(lambda w: w.onEnd()) 725 self.forEachModule(lambda m: m.end()) 726 727 def beginFeature(self, interface, emit): 728 # Start processing in superclass 729 OutputGenerator.beginFeature(self, interface, emit) 730 731 self.typeInfo.onBeginFeature(self.featureName, self.featureType) 732 733 self.forEachModule( 734 lambda m: m.appendHeader("#ifdef %s\n" % self.featureName) 735 if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None) 736 self.forEachModule( 737 lambda m: m.appendImpl("#ifdef %s\n" % self.featureName) 738 if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None) 739 self.forEachWrapper(lambda w: w.onBeginFeature(self.featureName, self.featureType)) 740 # functable needs to understand the feature type (device vs instance) of each cmd 741 for features in interface.findall('require'): 742 for c in features.findall('command'): 743 self.forEachWrapper(lambda w: w.onFeatureNewCmd(c.get('name'))) 744 745 def endFeature(self): 746 # Finish processing in superclass 747 OutputGenerator.endFeature(self) 748 749 self.typeInfo.onEndFeature() 750 751 self.forEachModule(lambda m: m.appendHeader("#endif\n") if isinstance( 752 m, cereal.Module) and not m.suppressFeatureGuards else None) 753 self.forEachModule(lambda m: m.appendImpl("#endif\n") if isinstance( 754 m, cereal.Module) and not m.suppressFeatureGuards else None) 755 self.forEachWrapper(lambda w: w.onEndFeature()) 756 757 def genType(self, typeinfo: TypeInfo, name, alias): 758 OutputGenerator.genType(self, typeinfo, name, alias) 759 self.typeInfo.onGenType(typeinfo, name, alias) 760 self.forEachWrapper(lambda w: w.onGenType(typeinfo, name, alias)) 761 762 def genStruct(self, typeinfo, typeName, alias): 763 OutputGenerator.genStruct(self, typeinfo, typeName, alias) 764 self.typeInfo.onGenStruct(typeinfo, typeName, alias) 765 self.forEachWrapper(lambda w: w.onGenStruct(typeinfo, typeName, alias)) 766 767 def genGroup(self, groupinfo: GroupInfo, groupName, alias = None): 768 OutputGenerator.genGroup(self, groupinfo, groupName, alias) 769 self.typeInfo.onGenGroup(groupinfo, groupName, alias) 770 self.forEachWrapper(lambda w: w.onGenGroup(groupinfo, groupName, alias)) 771 772 def genEnum(self, enuminfo: EnumInfo, name, alias): 773 OutputGenerator.genEnum(self, enuminfo, name, alias) 774 self.typeInfo.onGenEnum(enuminfo, name, alias) 775 self.forEachWrapper(lambda w: w.onGenEnum(enuminfo, name, alias)) 776 777 def genCmd(self, cmdinfo, name, alias): 778 OutputGenerator.genCmd(self, cmdinfo, name, alias) 779 self.typeInfo.onGenCmd(cmdinfo, name, alias) 780 self.forEachWrapper(lambda w: w.onGenCmd(cmdinfo, name, alias)) 781