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", "aemu/base") 143 self.baseLibDirPrefix = \ 144 envGetOrDefault("VK_CEREAL_BASELIB_PREFIX", "aemu/base") 145 self.baseLibLinkName = \ 146 envGetOrDefault("VK_CEREAL_BASELIB_LINKNAME", "android-emu-base") 147 self.vulkanHeaderTargetName = envGetOrDefault("VK_CEREAL_VK_HEADER_TARGET", "") 148 self.utilsHeader = envGetOrDefault("VK_CEREAL_UTILS_LINKNAME", "") 149 self.utilsHeaderDirPrefix = envGetOrDefault("VK_CEREAL_UTILS_PREFIX", "utils") 150 151 # THe host always needs all possible guest struct definitions, while the guest only needs 152 # platform sepcific headers. 153 self.hostCommonExtraVulkanHeaders = '#include "vk_android_native_buffer.h"' 154 self.host_cmake_generator = lambda cppFiles: f"""{autogeneratedMkTemplate % banner_command(sys.argv)} 155add_library(OpenglRender_vulkan_cereal {cppFiles}) 156target_compile_definitions(OpenglRender_vulkan_cereal PRIVATE -DVK_GOOGLE_gfxstream) 157if (WIN32) 158 target_compile_definitions(OpenglRender_vulkan_cereal PRIVATE -DVK_USE_PLATFORM_WIN32_KHR) 159endif() 160target_link_libraries( 161 OpenglRender_vulkan_cereal 162 PUBLIC 163 {self.baseLibLinkName} 164 {self.vulkanHeaderTargetName} 165 PRIVATE 166 {self.utilsHeader}) 167 168target_include_directories(OpenglRender_vulkan_cereal 169 PUBLIC 170 . 171 PRIVATE 172 .. 173 ../.. 174 ../../../include) 175""" 176 177 encoderInclude = f""" 178#include "{self.guestBaseLibDirPrefix}/AndroidHealthMonitor.h" 179#include "goldfish_vk_private_defs.h" 180#include <memory> 181class IOStream; 182""" 183 encoderImplInclude = f""" 184#include "EncoderDebug.h" 185#include "IOStream.h" 186#include "Resources.h" 187#include "ResourceTracker.h" 188#include "Validation.h" 189#include "%s.h" 190 191#include "{self.guestBaseLibDirPrefix}/AlignedBuf.h" 192#include "{self.guestBaseLibDirPrefix}/BumpPool.h" 193#include "{self.guestBaseLibDirPrefix}/synchronization/AndroidLock.h" 194 195#include <cutils/properties.h> 196 197#include "goldfish_vk_marshaling_guest.h" 198#include "goldfish_vk_reserved_marshaling_guest.h" 199#include "goldfish_vk_deepcopy_guest.h" 200#include "goldfish_vk_counting_guest.h" 201#include "goldfish_vk_handlemap_guest.h" 202#include "goldfish_vk_private_defs.h" 203#include "goldfish_vk_transform_guest.h" 204 205#include <memory> 206#include <optional> 207#include <unordered_map> 208#include <string> 209#include <vector> 210 211""" % VULKAN_STREAM_TYPE_GUEST 212 213 functableImplInclude = """ 214#include "VkEncoder.h" 215#include "../OpenglSystemCommon/HostConnection.h" 216#include "ResourceTracker.h" 217 218#include "goldfish_vk_private_defs.h" 219 220#include <log/log.h> 221#include <cstring> 222 223// Stuff we are not going to use but if included, 224// will cause compile errors. These are Android Vulkan 225// required extensions, but the approach will be to 226// implement them completely on the guest side. 227#undef VK_KHR_android_surface 228""" 229 marshalIncludeGuest = """ 230#include "goldfish_vk_marshaling_guest.h" 231#include "goldfish_vk_private_defs.h" 232#include "%s.h" 233 234// Stuff we are not going to use but if included, 235// will cause compile errors. These are Android Vulkan 236// required extensions, but the approach will be to 237// implement them completely on the guest side. 238#undef VK_KHR_android_surface 239#undef VK_ANDROID_external_memory_android_hardware_buffer 240""" % VULKAN_STREAM_TYPE_GUEST 241 242 reservedmarshalIncludeGuest = """ 243#include "goldfish_vk_marshaling_guest.h" 244#include "goldfish_vk_private_defs.h" 245#include "%s.h" 246 247// Stuff we are not going to use but if included, 248// will cause compile errors. These are Android Vulkan 249// required extensions, but the approach will be to 250// implement them completely on the guest side. 251#undef VK_KHR_android_surface 252#undef VK_ANDROID_external_memory_android_hardware_buffer 253""" % VULKAN_STREAM_TYPE_GUEST 254 255 reservedmarshalImplIncludeGuest = """ 256#include "Resources.h" 257""" 258 259 vulkanStreamIncludeHost = f""" 260{self.hostCommonExtraVulkanHeaders} 261#include "goldfish_vk_private_defs.h" 262 263#include "%s.h" 264#include "{self.baseLibDirPrefix}/files/StreamSerializing.h" 265""" % VULKAN_STREAM_TYPE 266 267 testingInclude = f""" 268{self.hostCommonExtraVulkanHeaders} 269#include "goldfish_vk_private_defs.h" 270#include <string.h> 271#include <functional> 272using OnFailCompareFunc = std::function<void(const char*)>; 273""" 274 poolInclude = f""" 275{self.hostCommonExtraVulkanHeaders} 276#include "goldfish_vk_private_defs.h" 277#include "{self.baseLibDirPrefix}/BumpPool.h" 278using android::base::Allocator; 279using android::base::BumpPool; 280""" 281 handleMapInclude = f""" 282{self.hostCommonExtraVulkanHeaders} 283#include "goldfish_vk_private_defs.h" 284#include "VulkanHandleMapping.h" 285""" 286 transformIncludeGuest = """ 287#include "goldfish_vk_private_defs.h" 288""" 289 transformInclude = f""" 290{self.hostCommonExtraVulkanHeaders} 291#include "goldfish_vk_private_defs.h" 292#include "goldfish_vk_extension_structs.h" 293""" 294 transformImplIncludeGuest = """ 295#include "ResourceTracker.h" 296""" 297 transformImplInclude = """ 298#include "VkDecoderGlobalState.h" 299""" 300 deepcopyInclude = """ 301#include "vk_util.h" 302""" 303 poolIncludeGuest = f""" 304#include "goldfish_vk_private_defs.h" 305#include "{self.guestBaseLibDirPrefix}/BumpPool.h" 306using android::base::Allocator; 307using android::base::BumpPool; 308// Stuff we are not going to use but if included, 309// will cause compile errors. These are Android Vulkan 310// required extensions, but the approach will be to 311// implement them completely on the guest side. 312#undef VK_KHR_android_surface 313#undef VK_ANDROID_external_memory_android_hardware_buffer 314""" 315 handleMapIncludeGuest = """ 316#include "goldfish_vk_private_defs.h" 317#include "VulkanHandleMapping.h" 318// Stuff we are not going to use but if included, 319// will cause compile errors. These are Android Vulkan 320// required extensions, but the approach will be to 321// implement them completely on the guest side. 322#undef VK_KHR_android_surface 323#undef VK_ANDROID_external_memory_android_hardware_buffer 324""" 325 dispatchHeaderDefs = f""" 326{self.hostCommonExtraVulkanHeaders} 327#include "goldfish_vk_private_defs.h" 328namespace gfxstream {{ 329namespace vk {{ 330 331struct VulkanDispatch; 332 333}} // namespace vk 334}} // namespace gfxstream 335using DlOpenFunc = void* (void); 336using DlSymFunc = void* (void*, const char*); 337""" 338 339 extensionStructsInclude = f""" 340{self.hostCommonExtraVulkanHeaders} 341#include "goldfish_vk_private_defs.h" 342""" 343 344 extensionStructsIncludeGuest = """ 345#include "vk_platform_compat.h" 346#include "goldfish_vk_private_defs.h" 347// Stuff we are not going to use but if included, 348// will cause compile errors. These are Android Vulkan 349// required extensions, but the approach will be to 350// implement them completely on the guest side. 351#undef VK_KHR_android_surface 352#undef VK_ANDROID_external_memory_android_hardware_buffer 353""" 354 commonCerealImplIncludes = """ 355#include "goldfish_vk_extension_structs.h" 356#include "goldfish_vk_private_defs.h" 357#include <string.h> 358""" 359 commonCerealIncludesGuest = """ 360#include "vk_platform_compat.h" 361""" 362 commonCerealImplIncludesGuest = """ 363#include "goldfish_vk_extension_structs_guest.h" 364#include "goldfish_vk_private_defs.h" 365 366#include <cstring> 367""" 368 countingIncludes = """ 369#include "vk_platform_compat.h" 370#include "goldfish_vk_private_defs.h" 371""" 372 373 dispatchImplIncludes = """ 374#include <stdio.h> 375#include <stdlib.h> 376#include <string.h> 377""" 378 379 decoderSnapshotHeaderIncludes = f""" 380#include <memory> 381#include "{self.utilsHeaderDirPrefix}/GfxApiLogger.h" 382#include "{self.baseLibDirPrefix}/HealthMonitor.h" 383#include "common/goldfish_vk_private_defs.h" 384""" 385 decoderSnapshotImplIncludes = f""" 386#include "VulkanHandleMapping.h" 387#include "VkDecoderGlobalState.h" 388#include "VkReconstruction.h" 389 390#include "{self.baseLibDirPrefix}/synchronization/Lock.h" 391""" 392 393 decoderHeaderIncludes = f""" 394#include "VkDecoderContext.h" 395 396#include <memory> 397 398namespace android {{ 399namespace base {{ 400class BumpPool; 401}} // namespace android 402}} // namespace base 403 404""" 405 406 decoderImplIncludes = f""" 407#include "common/goldfish_vk_marshaling.h" 408#include "common/goldfish_vk_reserved_marshaling.h" 409#include "common/goldfish_vk_private_defs.h" 410#include "common/goldfish_vk_transform.h" 411 412#include "{self.baseLibDirPrefix}/BumpPool.h" 413#include "{self.baseLibDirPrefix}/system/System.h" 414#include "{self.baseLibDirPrefix}/Tracing.h" 415#include "{self.baseLibDirPrefix}/Metrics.h" 416#include "stream-servers/FrameBuffer.h" 417#include "stream-servers/IOStream.h" 418#include "host-common/feature_control.h" 419#include "host-common/GfxstreamFatalError.h" 420#include "host-common/logging.h" 421 422#include "VkDecoderGlobalState.h" 423#include "VkDecoderSnapshot.h" 424 425#include "VulkanDispatch.h" 426#include "%s.h" 427 428#include <functional> 429#include <optional> 430#include <unordered_map> 431""" % VULKAN_STREAM_TYPE 432 433 def createVkExtensionStructureTypePreamble(extensionName: str) -> str: 434 return f""" 435#define {extensionName}_ENUM(type,id) \ 436 ((type)(1000000000 + (1000 * ({extensionName}_NUMBER - 1)) + (id))) 437""" 438 self.guest_encoder_tag = "guest_encoder" 439 self.guest_hal_tag = "guest_hal" 440 self.host_tag = "host" 441 442 default_guest_abs_encoder_destination = \ 443 os.path.join( 444 os.getcwd(), 445 "..", "..", 446 "device", "generic", "goldfish-opengl", 447 "system", "vulkan_enc") 448 self.guest_abs_encoder_destination = \ 449 envGetOrDefault("VK_CEREAL_GUEST_ENCODER_DIR", 450 default_guest_abs_encoder_destination) 451 452 default_guest_abs_hal_destination = \ 453 os.path.join( 454 os.getcwd(), 455 "..", "..", 456 "device", "generic", "goldfish-opengl", 457 "system", "vulkan") 458 self.guest_abs_hal_destination = \ 459 envGetOrDefault("VK_CEREAL_GUEST_HAL_DIR", 460 default_guest_abs_hal_destination) 461 462 default_host_abs_decoder_destination = \ 463 os.path.join( 464 os.getcwd(), 465 "android", "android-emugl", "host", 466 "libs", "libOpenglRender", "vulkan") 467 self.host_abs_decoder_destination = \ 468 envGetOrDefault("VK_CEREAL_HOST_DECODER_DIR", 469 default_host_abs_decoder_destination) 470 self.host_script_destination = envGetOrDefault("VK_CEREAL_HOST_SCRIPTS_DIR") 471 assert(self.host_script_destination is not None) 472 473 self.addGuestEncoderModule( 474 "VkEncoder", 475 extraHeader = encoderInclude, 476 extraImpl = encoderImplInclude) 477 478 self.addGuestEncoderModule("goldfish_vk_extension_structs_guest", 479 extraHeader=extensionStructsIncludeGuest) 480 self.addGuestEncoderModule("goldfish_vk_marshaling_guest", 481 extraHeader=commonCerealIncludesGuest + marshalIncludeGuest, 482 extraImpl=commonCerealImplIncludesGuest) 483 self.addGuestEncoderModule("goldfish_vk_reserved_marshaling_guest", 484 extraHeader=commonCerealIncludesGuest + reservedmarshalIncludeGuest, 485 extraImpl=commonCerealImplIncludesGuest + reservedmarshalImplIncludeGuest) 486 self.addGuestEncoderModule("goldfish_vk_deepcopy_guest", 487 extraHeader=commonCerealIncludesGuest + poolIncludeGuest, 488 extraImpl=commonCerealImplIncludesGuest + deepcopyInclude) 489 self.addGuestEncoderModule("goldfish_vk_counting_guest", 490 extraHeader=countingIncludes, 491 extraImpl=commonCerealImplIncludesGuest) 492 self.addGuestEncoderModule("goldfish_vk_handlemap_guest", 493 extraHeader=commonCerealIncludesGuest + handleMapIncludeGuest, 494 extraImpl=commonCerealImplIncludesGuest) 495 self.addGuestEncoderModule("goldfish_vk_transform_guest", 496 extraHeader=commonCerealIncludesGuest + transformIncludeGuest, 497 extraImpl=commonCerealImplIncludesGuest + transformImplIncludeGuest) 498 self.addGuestEncoderModule( 499 "vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True, 500 moduleName="vulkan_gfxstream_structure_type_guest", useNamespace=False, 501 suppressVulkanHeaders=True, 502 extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM')) 503 504 self.addGuestEncoderModule("func_table", extraImpl=functableImplInclude) 505 506 self.addCppModule("common", "goldfish_vk_extension_structs", 507 extraHeader=extensionStructsInclude) 508 self.addCppModule("common", "goldfish_vk_marshaling", 509 extraHeader=vulkanStreamIncludeHost, 510 extraImpl=commonCerealImplIncludes) 511 self.addCppModule("common", "goldfish_vk_reserved_marshaling", 512 extraHeader=vulkanStreamIncludeHost, 513 extraImpl=commonCerealImplIncludes) 514 self.addCppModule("common", "goldfish_vk_testing", 515 extraHeader=testingInclude, 516 extraImpl=commonCerealImplIncludes) 517 self.addCppModule("common", "goldfish_vk_deepcopy", 518 extraHeader=poolInclude, 519 extraImpl=commonCerealImplIncludes + deepcopyInclude) 520 self.addCppModule("common", "goldfish_vk_handlemap", 521 extraHeader=handleMapInclude, 522 extraImpl=commonCerealImplIncludes) 523 self.addCppModule("common", "goldfish_vk_dispatch", 524 extraHeader=dispatchHeaderDefs, 525 extraImpl=dispatchImplIncludes) 526 self.addCppModule("common", "goldfish_vk_transform", 527 extraHeader=transformInclude, 528 extraImpl=transformImplInclude) 529 self.addHostModule("VkDecoder", 530 extraHeader=decoderHeaderIncludes, 531 extraImpl=decoderImplIncludes, 532 useNamespace=False) 533 self.addHostModule("VkDecoderSnapshot", 534 extraHeader=decoderSnapshotHeaderIncludes, 535 extraImpl=decoderSnapshotImplIncludes, 536 useNamespace=False) 537 self.addHostModule("VkSubDecoder", 538 extraHeader="", 539 extraImpl="", 540 useNamespace=False, 541 implOnly=True) 542 543 self.addModule(cereal.PyScript(self.host_tag, "vulkan_printer", customAbsDir=Path( 544 self.host_script_destination) / "print_gfx_logs"), moduleName="ApiLogDecoder") 545 self.addHostModule( 546 "vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True, 547 moduleName="vulkan_gfxstream_structure_type_host", useNamespace=False, 548 suppressVulkanHeaders=True, 549 extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM')) 550 self.addHostModule( 551 "vk_android_native_buffer_structure_type", headerOnly=True, suppressFeatureGuards=True, 552 useNamespace=False, suppressVulkanHeaders=True, 553 extraHeader=createVkExtensionStructureTypePreamble('VK_ANDROID_NATIVE_BUFFER')) 554 555 self.addWrapper(cereal.VulkanEncoder, "VkEncoder") 556 self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs_guest") 557 self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling_guest", variant = "guest") 558 self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling_guest", variant = "guest") 559 self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy_guest") 560 self.addWrapper(cereal.VulkanCounting, "goldfish_vk_counting_guest") 561 self.addWrapper(cereal.VulkanHandleMap, "goldfish_vk_handlemap_guest") 562 self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform_guest") 563 self.addWrapper(cereal.VulkanFuncTable, "func_table") 564 self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs") 565 self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling") 566 self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling", variant = "host") 567 self.addWrapper(cereal.VulkanTesting, "goldfish_vk_testing") 568 self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy") 569 self.addWrapper(cereal.VulkanHandleMap, "goldfish_vk_handlemap") 570 self.addWrapper(cereal.VulkanDispatch, "goldfish_vk_dispatch") 571 self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform", resourceTrackerTypeName="VkDecoderGlobalState") 572 self.addWrapper(cereal.VulkanDecoder, "VkDecoder") 573 self.addWrapper(cereal.VulkanDecoderSnapshot, "VkDecoderSnapshot") 574 self.addWrapper(cereal.VulkanSubDecoder, "VkSubDecoder") 575 self.addWrapper(cereal.ApiLogDecoder, "ApiLogDecoder") 576 self.addWrapper(cereal.VulkanGfxstreamStructureType, 577 "vulkan_gfxstream_structure_type_guest") 578 self.addWrapper(cereal.VulkanGfxstreamStructureType, "vulkan_gfxstream_structure_type_host") 579 self.addWrapper(cereal.VulkanAndroidNativeBufferStructureType, 580 "vk_android_native_buffer_structure_type") 581 582 self.guestAndroidMkCppFiles = "" 583 self.hostCMakeCppFiles = "" 584 self.hostDecoderCMakeCppFiles = "" 585 586 def addSrcEntry(m): 587 mkSrcEntry = m.getMakefileSrcEntry() 588 cmakeSrcEntry = m.getCMakeSrcEntry() 589 if m.directory == self.guest_encoder_tag: 590 self.guestAndroidMkCppFiles += mkSrcEntry 591 elif m.directory == self.host_tag: 592 self.hostDecoderCMakeCppFiles += cmakeSrcEntry 593 elif m.directory != self.guest_hal_tag: 594 self.hostCMakeCppFiles += cmakeSrcEntry 595 596 self.forEachModule(addSrcEntry) 597 598 def addGuestEncoderModule( 599 self, basename, extraHeader="", extraImpl="", useNamespace=True, headerOnly=False, 600 suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False): 601 if not os.path.exists(self.guest_abs_encoder_destination): 602 print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination) 603 return 604 self.addCppModule(self.guest_encoder_tag, basename, extraHeader=extraHeader, 605 extraImpl=extraImpl, customAbsDir=self.guest_abs_encoder_destination, 606 useNamespace=useNamespace, headerOnly=headerOnly, 607 suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName, 608 suppressVulkanHeaders=suppressVulkanHeaders) 609 610 def addGuestHalModule(self, basename, extraHeader = "", extraImpl = "", useNamespace = True): 611 if not os.path.exists(self.guest_abs_hal_destination): 612 print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination) 613 return 614 self.addCppModule(self.guest_hal_tag, 615 basename, 616 extraHeader = extraHeader, 617 extraImpl = extraImpl, 618 customAbsDir = self.guest_abs_hal_destination, 619 useNamespace = useNamespace) 620 621 def addHostModule( 622 self, basename, extraHeader="", extraImpl="", useNamespace=True, implOnly=False, 623 suppress=False, headerOnly=False, suppressFeatureGuards=False, moduleName=None, 624 suppressVulkanHeaders=False): 625 if not os.path.exists(self.host_abs_decoder_destination): 626 print("Path [%s] not found (host encoder path), skipping" % 627 self.host_abs_decoder_destination) 628 return 629 if not suppressVulkanHeaders: 630 extraHeader = self.hostCommonExtraVulkanHeaders + '\n' + extraHeader 631 self.addCppModule( 632 self.host_tag, basename, extraHeader=extraHeader, extraImpl=extraImpl, 633 customAbsDir=self.host_abs_decoder_destination, useNamespace=useNamespace, 634 implOnly=implOnly, suppress=suppress, headerOnly=headerOnly, 635 suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName, 636 suppressVulkanHeaders=suppressVulkanHeaders) 637 638 def addModule(self, module, moduleName=None): 639 if moduleName is None: 640 moduleName = module.basename 641 self.moduleList.append(moduleName) 642 self.modules[moduleName] = module 643 644 def addCppModule( 645 self, directory, basename, extraHeader="", extraImpl="", customAbsDir=None, 646 useNamespace=True, implOnly=False, suppress=False, headerOnly=False, 647 suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False): 648 module = cereal.Module( 649 directory, basename, customAbsDir=customAbsDir, suppress=suppress, implOnly=implOnly, 650 headerOnly=headerOnly, suppressFeatureGuards=suppressFeatureGuards) 651 self.addModule(module, moduleName=moduleName) 652 module.headerPreamble = copyrightHeader 653 module.headerPreamble += \ 654 autogeneratedHeaderTemplate % \ 655 (basename, "(header) generated by %s" % banner_command(sys.argv)) 656 657 658 namespaceBegin = """ 659namespace gfxstream { 660namespace vk { 661""" if useNamespace else "" 662 663 namespaceEnd = """ 664} // namespace vk" 665} // namespace gfxstream 666""" if useNamespace else "" 667 668 module.headerPreamble += "#pragma once\n" 669 if (not suppressVulkanHeaders): 670 module.headerPreamble += "#include <vulkan/vulkan.h>\n" 671 module.headerPreamble += '#include "vulkan_gfxstream.h"\n' 672 module.headerPreamble += extraHeader + '\n' 673 if namespaceBegin: 674 module.headerPreamble += namespaceBegin + '\n' 675 676 module.implPreamble = copyrightHeader 677 module.implPreamble += \ 678 autogeneratedHeaderTemplate % \ 679 (basename, "(impl) generated by %s" % \ 680 banner_command(sys.argv)) 681 if not implOnly: 682 module.implPreamble += """ 683#include "%s.h" 684 685%s 686 687%s 688 689""" % (basename, extraImpl, namespaceBegin) 690 691 module.headerPostamble = """ 692%s 693""" % namespaceEnd 694 module.implPostamble = """ 695%s 696""" % namespaceEnd 697 698 def addWrapper(self, moduleType, moduleName, **kwargs): 699 if moduleName not in self.modules: 700 print(f'Unknown module: {moduleName}. All known modules are: {", ".join(self.modules)}.') 701 return 702 self.wrappers.append( 703 moduleType( 704 self.modules[moduleName], 705 self.typeInfo, **kwargs)) 706 707 def forEachModule(self, func): 708 for moduleName in self.moduleList: 709 func(self.modules[moduleName]) 710 711 def forEachWrapper(self, func): 712 for wrapper in self.wrappers: 713 func(wrapper) 714 715## Overrides#################################################################### 716 717 def beginFile(self, genOpts): 718 OutputGenerator.beginFile(self, genOpts, suppressEnabled) 719 720 if suppressEnabled: 721 def enableSuppression(m): 722 m.suppress = True 723 self.forEachModule(enableSuppression) 724 self.modules[suppressExceptModule].suppress = False 725 726 if not suppressEnabled: 727 write(self.host_cmake_generator(self.hostCMakeCppFiles), 728 file = self.outFile) 729 730 guestEncoderAndroidMkPath = \ 731 os.path.join( \ 732 self.guest_abs_encoder_destination, 733 "Android.mk") 734 735 self.forEachModule(lambda m: m.begin(self.genOpts.directory)) 736 self.forEachWrapper(lambda w: w.onBegin()) 737 738 def endFile(self): 739 OutputGenerator.endFile(self) 740 741 self.typeInfo.onEnd() 742 743 self.forEachWrapper(lambda w: w.onEnd()) 744 self.forEachModule(lambda m: m.end()) 745 746 def beginFeature(self, interface, emit): 747 # Start processing in superclass 748 OutputGenerator.beginFeature(self, interface, emit) 749 750 self.typeInfo.onBeginFeature(self.featureName, self.featureType) 751 752 self.forEachModule( 753 lambda m: m.appendHeader("#ifdef %s\n" % self.featureName) 754 if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None) 755 self.forEachModule( 756 lambda m: m.appendImpl("#ifdef %s\n" % self.featureName) 757 if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None) 758 self.forEachWrapper(lambda w: w.onBeginFeature(self.featureName, self.featureType)) 759 # functable needs to understand the feature type (device vs instance) of each cmd 760 for features in interface.findall('require'): 761 for c in features.findall('command'): 762 self.forEachWrapper(lambda w: w.onFeatureNewCmd(c.get('name'))) 763 764 def endFeature(self): 765 # Finish processing in superclass 766 OutputGenerator.endFeature(self) 767 768 self.typeInfo.onEndFeature() 769 770 self.forEachModule(lambda m: m.appendHeader("#endif\n") if isinstance( 771 m, cereal.Module) and not m.suppressFeatureGuards else None) 772 self.forEachModule(lambda m: m.appendImpl("#endif\n") if isinstance( 773 m, cereal.Module) and not m.suppressFeatureGuards else None) 774 self.forEachWrapper(lambda w: w.onEndFeature()) 775 776 def genType(self, typeinfo: TypeInfo, name, alias): 777 OutputGenerator.genType(self, typeinfo, name, alias) 778 self.typeInfo.onGenType(typeinfo, name, alias) 779 self.forEachWrapper(lambda w: w.onGenType(typeinfo, name, alias)) 780 781 def genStruct(self, typeinfo, typeName, alias): 782 OutputGenerator.genStruct(self, typeinfo, typeName, alias) 783 self.typeInfo.onGenStruct(typeinfo, typeName, alias) 784 self.forEachWrapper(lambda w: w.onGenStruct(typeinfo, typeName, alias)) 785 786 def genGroup(self, groupinfo: GroupInfo, groupName, alias = None): 787 OutputGenerator.genGroup(self, groupinfo, groupName, alias) 788 self.typeInfo.onGenGroup(groupinfo, groupName, alias) 789 self.forEachWrapper(lambda w: w.onGenGroup(groupinfo, groupName, alias)) 790 791 def genEnum(self, enuminfo: EnumInfo, name, alias): 792 OutputGenerator.genEnum(self, enuminfo, name, alias) 793 self.typeInfo.onGenEnum(enuminfo, name, alias) 794 self.forEachWrapper(lambda w: w.onGenEnum(enuminfo, name, alias)) 795 796 def genCmd(self, cmdinfo, name, alias): 797 OutputGenerator.genCmd(self, cmdinfo, name, alias) 798 self.typeInfo.onGenCmd(cmdinfo, name, alias) 799 self.forEachWrapper(lambda w: w.onGenCmd(cmdinfo, name, alias)) 800