mesa/src/gfxstream/codegen/scripts/cerealgenerator.py
Serdar Kocdemir 5cb7bbce17 Add VK_EXT_debug_report extension support
This extension is enabled from the platform side via the Android
loader and the applications using the functions or structures of
it would crash even if they check the support of the extension.
Guest callback addresses within the structures of this extension
cannot be used and are already being removed when creating the
instances.

Reviewed-by: Aaron Ruby <aruby@blackberry.com>
Acked-by: Yonggang Luo <luoyonggang@gmail.com>
Acked-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27246>
2024-09-19 20:06:01 +00:00

872 lines
34 KiB
Python

#!/usr/bin/python3 -i
#
# Copyright (c) 2013-2018 The Khronos Group Inc.
# Copyright (c) 2013-2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os, re, sys
from generator import *
from pathlib import Path, PurePosixPath
import cereal
from cereal.wrapperdefs import VULKAN_STREAM_TYPE
from cereal.wrapperdefs import VULKAN_STREAM_TYPE_GUEST
# CerealGenerator - generates set of driver sources
# while being agnostic to the stream implementation
from reg import GroupInfo, TypeInfo, EnumInfo
VK_CEREAL_FLAG_HOST = 1
VK_CEREAL_FLAG_GUEST = 2
VK_CEREAL_FLAG_ALL = VK_CEREAL_FLAG_GUEST | VK_CEREAL_FLAG_HOST
SUPPORTED_FEATURES = [
"VK_VERSION_1_0",
"VK_VERSION_1_1",
"VK_VERSION_1_2",
"VK_VERSION_1_3",
# Instance extensions
"VK_KHR_get_physical_device_properties2",
"VK_KHR_external_semaphore_capabilities",
"VK_KHR_external_memory_capabilities",
"VK_KHR_external_fence_capabilities",
"VK_EXT_debug_utils",
"VK_EXT_debug_report",
"VK_EXT_validation_features",
# Device extensions
"VK_KHR_storage_buffer_storage_class",
"VK_KHR_vulkan_memory_model",
"VK_KHR_buffer_device_address",
"VK_KHR_maintenance1",
"VK_KHR_maintenance2",
"VK_KHR_maintenance3",
"VK_KHR_bind_memory2",
"VK_KHR_dedicated_allocation",
"VK_KHR_get_memory_requirements2",
"VK_KHR_sampler_ycbcr_conversion",
"VK_KHR_shader_float16_int8",
"VK_AMD_gpu_shader_half_float",
"VK_NV_shader_subgroup_partitioned",
"VK_KHR_shader_subgroup_extended_types",
"VK_EXT_provoking_vertex",
"VK_EXT_line_rasterization",
"VK_EXT_transform_feedback",
"VK_EXT_primitive_topology_list_restart",
"VK_EXT_index_type_uint8",
"VK_EXT_load_store_op_none",
"VK_EXT_swapchain_colorspace",
"VK_EXT_custom_border_color",
"VK_EXT_shader_stencil_export",
"VK_KHR_image_format_list",
"VK_KHR_incremental_present",
"VK_KHR_pipeline_executable_properties",
"VK_EXT_queue_family_foreign",
"VK_EXT_scalar_block_layout",
"VK_KHR_external_semaphore",
"VK_KHR_external_semaphore_fd",
"VK_KHR_external_memory",
"VK_KHR_external_fence",
"VK_KHR_external_fence_fd",
"VK_EXT_device_memory_report",
"VK_KHR_create_renderpass2",
"VK_KHR_imageless_framebuffer",
"VK_KHR_descriptor_update_template",
"VK_EXT_depth_clip_enable",
"VK_EXT_robustness2",
# see aosp/2736079 + b/268351352
"VK_EXT_swapchain_maintenance1",
"VK_KHR_maintenance5",
"VK_EXT_host_image_copy",
"VK_EXT_image_compression_control",
"VK_EXT_image_compression_control_swapchain",
# VK1.3 extensions: see b/298704840
"VK_KHR_copy_commands2",
"VK_KHR_dynamic_rendering",
"VK_KHR_format_feature_flags2",
"VK_KHR_maintenance4",
"VK_KHR_shader_integer_dot_product",
"VK_KHR_shader_non_semantic_info",
"VK_KHR_shader_terminate_invocation",
"VK_KHR_synchronization2",
"VK_KHR_zero_initialize_workgroup_memory",
"VK_EXT_4444_formats",
"VK_EXT_extended_dynamic_state",
"VK_EXT_extended_dynamic_state2",
"VK_EXT_image_robustness",
"VK_EXT_inline_uniform_block",
"VK_EXT_pipeline_creation_cache_control",
"VK_EXT_pipeline_creation_feedback",
"VK_EXT_private_data",
"VK_EXT_shader_demote_to_helper_invocation",
"VK_EXT_subgroup_size_control",
"VK_EXT_texel_buffer_alignment",
"VK_EXT_texture_compression_astc_hdr",
"VK_EXT_tooling_info",
"VK_EXT_ycbcr_2plane_444_formats",
# Host dispatch
"VK_KHR_surface",
"VK_KHR_swapchain",
"VK_KHR_xcb_surface",
"VK_KHR_win32_surface",
"VK_EXT_metal_surface",
"VK_MVK_moltenvk",
"VK_EXT_metal_objects",
"VK_KHR_external_semaphore_win32",
"VK_KHR_external_memory_win32",
# Android
"VK_ANDROID_native_buffer",
"VK_ANDROID_external_memory_android_hardware_buffer",
"VK_KHR_android_surface",
# Linux
"VK_KHR_external_memory_fd",
# Custom
"VK_GOOGLE_gfxstream",
# Used in tests without proper support checks
"VK_EXT_graphics_pipeline_library",
# Used by guest ANGLE
"VK_EXT_vertex_attribute_divisor",
# QNX
"VK_QNX_external_memory_screen_buffer",
# b/320855472 Chrome
"VK_EXT_fragment_density_map",
]
HOST_MODULES = ["goldfish_vk_extension_structs", "goldfish_vk_marshaling",
"goldfish_vk_reserved_marshaling", "goldfish_vk_deepcopy",
"goldfish_vk_dispatch", "goldfish_vk_transform", "VkDecoder",
"VkDecoderSnapshot", "VkSubDecoder"]
# By default, the all wrappers are run all on all features. In certain cases,
# we wish run wrappers when the module requires it. For example, `VK_GOOGLE_gfxstream`
# shouldn't generate a function table entry since it's an internal interface.
SUPPORTED_MODULES = {
"VK_EXT_debug_utils": HOST_MODULES,
"VK_EXT_debug_report": HOST_MODULES,
"VK_EXT_validation_features": HOST_MODULES,
"VK_KHR_surface": ["goldfish_vk_dispatch"],
"VK_KHR_xcb_surface": ["goldfish_vk_dispatch"],
"VK_KHR_win32_surface": ["goldfish_vk_dispatch"],
"VK_EXT_metal_surface": ["goldfish_vk_dispatch"],
# VK_MVK_moltenvk doesn't generate a generate dispatch entry for some reason, but should. The
# lack of this extension doesn't cause any build failures though.
"VK_MVK_moltenvk": ["goldfish_vk_dispatch"],
"VK_EXT_metal_objects": ["goldfish_vk_dispatch"],
"VK_KHR_external_semaphore_win32" : ["goldfish_vk_dispatch"],
"VK_KHR_external_memory_win32" : ["goldfish_vk_dispatch"],
# Host dispatch for Linux hosts + and entrypoint for guests
"VK_KHR_external_memory_fd": ["goldfish_vk_dispatch", "func_table"],
"VK_QNX_external_memory_screen_buffer": ["goldfish_vk_dispatch"],
"VK_ANDROID_external_memory_android_hardware_buffer": ["func_table"],
"VK_KHR_android_surface": ["func_table"],
"VK_EXT_swapchain_maintenance1" : HOST_MODULES,
"VK_KHR_swapchain" : HOST_MODULES,
}
REQUIRED_TYPES = {
"int",
"uint16_t",
"int64_t",
"double",
"VkPresentScalingFlagsEXT",
"VkPresentGravityFlagsEXT",
}
copyrightHeader = """// Copyright (C) 2018 The Android Open Source Project
// Copyright (C) 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
"""
# We put the long generated commands in a separate paragraph, so that the formatter won't mess up
# with other texts.
autogeneratedHeaderTemplate = """
// Autogenerated module %s
//
// %s
//
// Please do not modify directly;
// re-run gfxstream-protocols/scripts/generate-vulkan-sources.sh,
// or directly from Python by defining:
// VULKAN_REGISTRY_XML_DIR : Directory containing vk.xml
// VULKAN_REGISTRY_SCRIPTS_DIR : Directory containing genvk.py
// CEREAL_OUTPUT_DIR: Where to put the generated sources.
//
// python3 $VULKAN_REGISTRY_SCRIPTS_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o $CEREAL_OUTPUT_DIR
//
"""
namespaceBegin ="""
namespace gfxstream {
namespace vk {\n
"""
namespaceEnd = """
} // namespace vk
} // namespace gfxstream
"""
def banner_command(argv):
"""Return sanitized command-line description.
|argv| must be a list of command-line parameters, e.g. sys.argv.
Return a string corresponding to the command, with platform-specific
paths removed."""
def makePosixRelative(someArg):
if os.path.exists(someArg):
return str(PurePosixPath(Path(os.path.relpath(someArg))))
return someArg
return ' '.join(map(makePosixRelative, argv))
def envGetOrDefault(key, default=None):
if key in os.environ:
return os.environ[key]
print("envGetOrDefault: notfound: %s" % key)
return default
# ---- methods overriding base class ----
# beginFile(genOpts)
# endFile()
# beginFeature(interface, emit)
# endFeature()
# genType(typeinfo,name)
# genStruct(typeinfo,name)
# genGroup(groupinfo,name)
# genEnum(enuminfo, name)
# genCmd(cmdinfo)
class CerealGenerator(OutputGenerator):
"""Generate serialization code"""
def __init__(self, errFile = sys.stderr,
warnFile = sys.stderr,
diagFile = sys.stdout):
OutputGenerator.__init__(self, errFile, warnFile, diagFile)
self.typeInfo = cereal.VulkanTypeInfo(self)
self.modules = {}
self.protos = {}
self.moduleList = []
self.protoList = []
self.wrappers = []
self.codegen = cereal.CodeGen()
self.featureSupported = False
self.supportedModules = None
self.guestBaseLibDirPrefix = "aemu/base"
self.baseLibDirPrefix = "aemu/base"
self.utilsHeaderDirPrefix = "utils"
# The cereal variant should be an environmental variable of one of
# the following:
# - "guest"
# - "host"
# - "both"
cerealVariant = envGetOrDefault("CEREAL_VARIANT", "both")
if cerealVariant == "guest":
self.cerealFlags = VK_CEREAL_FLAG_GUEST
elif cerealVariant == "host":
self.cerealFlags = VK_CEREAL_FLAG_HOST
else:
self.cerealFlags = VK_CEREAL_FLAG_ALL
# THe host always needs all possible guest struct definitions, while the guest only needs
# platform sepcific headers.
self.hostCommonExtraVulkanHeaders = '#include "vk_android_native_buffer_gfxstream.h"'
encoderInclude = f"""
#include "{self.guestBaseLibDirPrefix}/AndroidHealthMonitor.h"
#include "goldfish_vk_private_defs.h"
#include <memory>
namespace gfxstream {{
namespace guest {{
class IOStream;
}} // namespace guest
}} // namespace gfxstream
"""
encoderImplInclude = f"""
#include "EncoderDebug.h"
#include "Resources.h"
#include "ResourceTracker.h"
#include "Validation.h"
#include "%s.h"
#include "gfxstream/guest/IOStream.h"
#include "{self.guestBaseLibDirPrefix}/AlignedBuf.h"
#include "{self.guestBaseLibDirPrefix}/BumpPool.h"
#include "{self.guestBaseLibDirPrefix}/synchronization/AndroidLock.h"
#include <cutils/properties.h>
#include "goldfish_vk_marshaling_guest.h"
#include "goldfish_vk_reserved_marshaling_guest.h"
#include "goldfish_vk_deepcopy_guest.h"
#include "goldfish_vk_counting_guest.h"
#include "goldfish_vk_private_defs.h"
#include "goldfish_vk_transform_guest.h"
#include <memory>
#include <optional>
#include <unordered_map>
#include <string>
#include <vector>
""" % VULKAN_STREAM_TYPE_GUEST
functableImplInclude = """
#include "VkEncoder.h"
#include "../OpenglSystemCommon/HostConnection.h"
#include "ResourceTracker.h"
#include "gfxstream_vk_entrypoints.h"
#include "gfxstream_vk_private.h"
#include "goldfish_vk_private_defs.h"
#include <log/log.h>
#include <cstring>
// Stuff we are not going to use but if included,
// will cause compile errors. These are Android Vulkan
// required extensions, but the approach will be to
// implement them completely on the guest side.
#undef VK_KHR_android_surface
#if defined(LINUX_GUEST_BUILD) || defined(__Fuchsia__)
#undef VK_ANDROID_native_buffer
#endif
"""
marshalIncludeGuest = """
#include "goldfish_vk_marshaling_guest.h"
#include "goldfish_vk_private_defs.h"
#include "%s.h"
// Stuff we are not going to use but if included,
// will cause compile errors. These are Android Vulkan
// required extensions, but the approach will be to
// implement them completely on the guest side.
#undef VK_KHR_android_surface
#undef VK_ANDROID_external_memory_android_hardware_buffer
""" % VULKAN_STREAM_TYPE_GUEST
reservedmarshalIncludeGuest = """
#include "goldfish_vk_marshaling_guest.h"
#include "goldfish_vk_private_defs.h"
#include "%s.h"
// Stuff we are not going to use but if included,
// will cause compile errors. These are Android Vulkan
// required extensions, but the approach will be to
// implement them completely on the guest side.
#undef VK_KHR_android_surface
#undef VK_ANDROID_external_memory_android_hardware_buffer
""" % VULKAN_STREAM_TYPE_GUEST
reservedmarshalImplIncludeGuest = """
#include "Resources.h"
"""
vulkanStreamIncludeHost = f"""
{self.hostCommonExtraVulkanHeaders}
#include "goldfish_vk_private_defs.h"
#include "%s.h"
#include "{self.baseLibDirPrefix}/files/StreamSerializing.h"
""" % VULKAN_STREAM_TYPE
poolInclude = f"""
{self.hostCommonExtraVulkanHeaders}
#include "goldfish_vk_private_defs.h"
#include "{self.baseLibDirPrefix}/BumpPool.h"
using android::base::Allocator;
using android::base::BumpPool;
"""
transformIncludeGuest = """
#include "goldfish_vk_private_defs.h"
"""
transformInclude = f"""
{self.hostCommonExtraVulkanHeaders}
#include "goldfish_vk_private_defs.h"
#include "goldfish_vk_extension_structs.h"
"""
transformImplIncludeGuest = """
#include "ResourceTracker.h"
"""
transformImplInclude = """
#include "VkDecoderGlobalState.h"
"""
deepcopyInclude = """
#include "vk_util.h"
"""
poolIncludeGuest = f"""
#include "goldfish_vk_private_defs.h"
#include "{self.guestBaseLibDirPrefix}/BumpPool.h"
using gfxstream::guest::Allocator;
using gfxstream::guest::BumpPool;
// Stuff we are not going to use but if included,
// will cause compile errors. These are Android Vulkan
// required extensions, but the approach will be to
// implement them completely on the guest side.
#undef VK_KHR_android_surface
#undef VK_ANDROID_external_memory_android_hardware_buffer
"""
dispatchHeaderDefs = f"""
{self.hostCommonExtraVulkanHeaders}
#include "goldfish_vk_private_defs.h"
namespace gfxstream {{
namespace vk {{
struct VulkanDispatch;
}} // namespace vk
}} // namespace gfxstream
using DlOpenFunc = void* (void);
using DlSymFunc = void* (void*, const char*);
"""
extensionStructsInclude = f"""
{self.hostCommonExtraVulkanHeaders}
#include "goldfish_vk_private_defs.h"
#include "host-common/GfxstreamFatalError.h"
"""
extensionStructsIncludeGuest = """
#include "vk_platform_compat.h"
#include "goldfish_vk_private_defs.h"
// Stuff we are not going to use but if included,
// will cause compile errors. These are Android Vulkan
// required extensions, but the approach will be to
// implement them completely on the guest side.
#undef VK_KHR_android_surface
#undef VK_ANDROID_external_memory_android_hardware_buffer
"""
commonCerealImplIncludes = """
#include "goldfish_vk_extension_structs.h"
#include "goldfish_vk_private_defs.h"
#include <string.h>
"""
commonCerealIncludesGuest = """
#include "vk_platform_compat.h"
"""
commonCerealImplIncludesGuest = """
#include "goldfish_vk_extension_structs_guest.h"
#include "goldfish_vk_private_defs.h"
#include <cstring>
"""
countingIncludes = """
#include "vk_platform_compat.h"
#include "goldfish_vk_private_defs.h"
"""
dispatchImplIncludes = """
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
"""
decoderSnapshotHeaderIncludes = f"""
#include <memory>
#include "{self.utilsHeaderDirPrefix}/GfxApiLogger.h"
#include "{self.baseLibDirPrefix}/HealthMonitor.h"
#include "goldfish_vk_private_defs.h"
"""
decoderSnapshotImplIncludes = f"""
#include "VulkanHandleMapping.h"
#include "VkDecoderGlobalState.h"
#include "VkReconstruction.h"
#include "{self.baseLibDirPrefix}/synchronization/Lock.h"
"""
decoderHeaderIncludes = f"""
#include "VkDecoderContext.h"
#include "ProcessResources.h"
#include <memory>
namespace android {{
namespace base {{
class BumpPool;
}} // namespace android
}} // namespace base
"""
decoderImplIncludes = f"""
#include "common/goldfish_vk_marshaling.h"
#include "common/goldfish_vk_reserved_marshaling.h"
#include "goldfish_vk_private_defs.h"
#include "common/goldfish_vk_transform.h"
#include "{self.baseLibDirPrefix}/BumpPool.h"
#include "{self.baseLibDirPrefix}/system/System.h"
#include "{self.baseLibDirPrefix}/Tracing.h"
#include "{self.baseLibDirPrefix}/Metrics.h"
#include "render-utils/IOStream.h"
#include "FrameBuffer.h"
#include "host-common/feature_control.h"
#include "host-common/GfxstreamFatalError.h"
#include "host-common/logging.h"
#include "VkDecoderGlobalState.h"
#include "VkDecoderSnapshot.h"
#include "VulkanDispatch.h"
#include "%s.h"
#include <functional>
#include <optional>
#include <unordered_map>
""" % VULKAN_STREAM_TYPE
def createVkExtensionStructureTypePreamble(extensionName: str) -> str:
return f"""
#define {extensionName}_ENUM(type,id) \
((type)(1000000000 + (1000 * ({extensionName}_NUMBER - 1)) + (id)))
"""
self.guest_encoder_tag = "guest_encoder"
self.host_tag = "host"
default_guest_abs_encoder_destination = \
os.path.join(
os.getcwd(),
"..", "..",
"device", "generic", "goldfish-opengl",
"system", "vulkan_enc")
self.guest_abs_encoder_destination = \
envGetOrDefault("GFXSTREAM_GUEST_ENCODER_DIR",
default_guest_abs_encoder_destination)
default_host_abs_decoder_destination = \
os.path.join(
os.getcwd(),
"android", "android-emugl", "host",
"libs", "libOpenglRender", "vulkan")
self.host_abs_decoder_destination = \
envGetOrDefault("GFXSTREAM_HOST_DECODER_DIR",
default_host_abs_decoder_destination)
self.host_script_destination = envGetOrDefault("GFXSTREAM_SCRIPTS_DIR")
assert(self.host_script_destination is not None)
if self.cerealFlags & VK_CEREAL_FLAG_GUEST:
self.addGuestEncoderModule(
"VkEncoder",
extraHeader = encoderInclude,
extraImpl = encoderImplInclude)
self.addGuestEncoderModule("goldfish_vk_extension_structs_guest",
extraHeader=extensionStructsIncludeGuest)
self.addGuestEncoderModule("goldfish_vk_marshaling_guest",
extraHeader=commonCerealIncludesGuest + marshalIncludeGuest,
extraImpl=commonCerealImplIncludesGuest)
self.addGuestEncoderModule("goldfish_vk_reserved_marshaling_guest",
extraHeader=commonCerealIncludesGuest + reservedmarshalIncludeGuest,
extraImpl=commonCerealImplIncludesGuest + reservedmarshalImplIncludeGuest)
self.addGuestEncoderModule("goldfish_vk_deepcopy_guest",
extraHeader=commonCerealIncludesGuest + poolIncludeGuest,
extraImpl=commonCerealImplIncludesGuest + deepcopyInclude)
self.addGuestEncoderModule("goldfish_vk_counting_guest",
extraHeader=countingIncludes,
extraImpl=commonCerealImplIncludesGuest)
self.addGuestEncoderModule("goldfish_vk_transform_guest",
extraHeader=commonCerealIncludesGuest + transformIncludeGuest,
extraImpl=commonCerealImplIncludesGuest + transformImplIncludeGuest)
self.addGuestEncoderModule(
"vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True,
moduleName="vulkan_gfxstream_structure_type_guest", useNamespace=False,
suppressVulkanHeaders=True,
extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM'))
self.addGuestEncoderModule("func_table", extraImpl=functableImplInclude, implOnly = True,
useNamespace = False)
self.addWrapper(cereal.VulkanEncoder, "VkEncoder")
self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs_guest", variant = "guest")
self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling_guest", variant = "guest")
self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling_guest", variant = "guest")
self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy_guest")
self.addWrapper(cereal.VulkanCounting, "goldfish_vk_counting_guest")
self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform_guest")
self.addWrapper(cereal.VulkanFuncTable, "func_table")
self.addWrapper(cereal.VulkanGfxstreamStructureType,
"vulkan_gfxstream_structure_type_guest")
if self.cerealFlags & VK_CEREAL_FLAG_HOST:
self.addCppModule("common", "goldfish_vk_extension_structs",
extraHeader=extensionStructsInclude)
self.addCppModule("common", "goldfish_vk_marshaling",
extraHeader=vulkanStreamIncludeHost,
extraImpl=commonCerealImplIncludes)
self.addCppModule("common", "goldfish_vk_reserved_marshaling",
extraHeader=vulkanStreamIncludeHost,
extraImpl=commonCerealImplIncludes)
self.addCppModule("common", "goldfish_vk_deepcopy",
extraHeader=poolInclude,
extraImpl=commonCerealImplIncludes + deepcopyInclude)
self.addCppModule("common", "goldfish_vk_dispatch",
extraHeader=dispatchHeaderDefs,
extraImpl=dispatchImplIncludes)
self.addCppModule("common", "goldfish_vk_transform",
extraHeader=transformInclude,
extraImpl=transformImplInclude)
self.addHostModule("VkDecoder",
extraHeader=decoderHeaderIncludes,
extraImpl=decoderImplIncludes,
useNamespace=False)
self.addHostModule("VkDecoderSnapshot",
extraHeader=decoderSnapshotHeaderIncludes,
extraImpl=decoderSnapshotImplIncludes,
useNamespace=False)
self.addHostModule("VkSubDecoder",
extraHeader="",
extraImpl="",
useNamespace=False,
implOnly=True)
self.addModule(cereal.PyScript(self.host_tag, "vulkan_printer", customAbsDir=Path(
self.host_script_destination) / "print_gfx_logs"), moduleName="ApiLogDecoder")
self.addHostModule(
"vulkan_gfxstream_structure_type", headerOnly=True, suppressFeatureGuards=True,
moduleName="vulkan_gfxstream_structure_type_host", useNamespace=False,
suppressVulkanHeaders=True,
extraHeader=createVkExtensionStructureTypePreamble('VK_GOOGLE_GFXSTREAM'))
self.addHostModule(
"vk_android_native_buffer_structure_type", headerOnly=True, suppressFeatureGuards=True,
useNamespace=False, suppressVulkanHeaders=True,
extraHeader=createVkExtensionStructureTypePreamble('VK_ANDROID_NATIVE_BUFFER'))
self.addWrapper(cereal.VulkanExtensionStructs, "goldfish_vk_extension_structs", variant = "host")
self.addWrapper(cereal.VulkanMarshaling, "goldfish_vk_marshaling")
self.addWrapper(cereal.VulkanReservedMarshaling, "goldfish_vk_reserved_marshaling", variant = "host")
self.addWrapper(cereal.VulkanDeepcopy, "goldfish_vk_deepcopy")
self.addWrapper(cereal.VulkanDispatch, "goldfish_vk_dispatch")
self.addWrapper(cereal.VulkanTransform, "goldfish_vk_transform", resourceTrackerTypeName="VkDecoderGlobalState")
self.addWrapper(cereal.VulkanDecoder, "VkDecoder")
self.addWrapper(cereal.VulkanDecoderSnapshot, "VkDecoderSnapshot")
self.addWrapper(cereal.VulkanSubDecoder, "VkSubDecoder")
self.addWrapper(cereal.ApiLogDecoder, "ApiLogDecoder")
self.addWrapper(cereal.VulkanGfxstreamStructureType, "vulkan_gfxstream_structure_type_host")
self.addWrapper(cereal.VulkanAndroidNativeBufferStructureType,
"vk_android_native_buffer_structure_type")
def addGuestEncoderModule(
self, basename, extraHeader="", extraImpl="", useNamespace=True, headerOnly=False,
suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False, implOnly=False):
if not os.path.exists(self.guest_abs_encoder_destination):
print("Path [%s] not found (guest encoder path), skipping" % self.guest_abs_encoder_destination)
return
self.addCppModule(self.guest_encoder_tag, basename, extraHeader=extraHeader,
extraImpl=extraImpl, customAbsDir=self.guest_abs_encoder_destination,
useNamespace=useNamespace, implOnly=implOnly, headerOnly=headerOnly,
suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName,
suppressVulkanHeaders=suppressVulkanHeaders)
def addHostModule(
self, basename, extraHeader="", extraImpl="", useNamespace=True, implOnly=False,
suppress=False, headerOnly=False, suppressFeatureGuards=False, moduleName=None,
suppressVulkanHeaders=False):
if not os.path.exists(self.host_abs_decoder_destination):
print("Path [%s] not found (host encoder path), skipping" %
self.host_abs_decoder_destination)
return
if not suppressVulkanHeaders:
extraHeader = self.hostCommonExtraVulkanHeaders + '\n' + extraHeader
self.addCppModule(
self.host_tag, basename, extraHeader=extraHeader, extraImpl=extraImpl,
customAbsDir=self.host_abs_decoder_destination, useNamespace=useNamespace,
implOnly=implOnly, suppress=suppress, headerOnly=headerOnly,
suppressFeatureGuards=suppressFeatureGuards, moduleName=moduleName,
suppressVulkanHeaders=suppressVulkanHeaders)
def addModule(self, module, moduleName=None):
if moduleName is None:
moduleName = module.basename
self.moduleList.append(moduleName)
self.modules[moduleName] = module
def addCppModule(
self, directory, basename, extraHeader="", extraImpl="", customAbsDir=None,
useNamespace=True, implOnly=False, suppress=False, headerOnly=False,
suppressFeatureGuards=False, moduleName=None, suppressVulkanHeaders=False):
module = cereal.Module(
directory, basename, customAbsDir=customAbsDir, suppress=suppress, implOnly=implOnly,
headerOnly=headerOnly, suppressFeatureGuards=suppressFeatureGuards)
self.addModule(module, moduleName=moduleName)
module.headerPreamble = copyrightHeader
module.headerPreamble += \
autogeneratedHeaderTemplate % \
(basename, "(header) generated by %s" % banner_command(sys.argv))
module.headerPreamble += "#pragma once\n"
if (not suppressVulkanHeaders):
module.headerPreamble += "#include <vulkan/vulkan.h>\n"
module.headerPreamble += '#include "vulkan_gfxstream.h"\n'
module.headerPreamble += '#include "vk_android_native_buffer_gfxstream.h"\n'
module.headerPreamble += extraHeader + '\n'
if useNamespace:
module.headerPreamble += namespaceBegin
module.implPreamble = copyrightHeader
module.implPreamble += \
autogeneratedHeaderTemplate % \
(basename, "(impl) generated by %s" % \
banner_command(sys.argv))
if not implOnly:
module.implPreamble += '\n#include "%s.h"' % \
(basename)
module.implPreamble += extraImpl
if useNamespace:
module.implPreamble += namespaceBegin
module.implPostamble += namespaceEnd
module.headerPostamble += namespaceEnd
def addWrapper(self, moduleType, moduleName, **kwargs):
if moduleName not in self.modules:
print(f'Unknown module: {moduleName}. All known modules are: {", ".join(self.modules)}.')
return
self.wrappers.append(
(moduleType(
self.modules[moduleName],
self.typeInfo, **kwargs),
moduleName)
)
def forEachModule(self, func):
for moduleName in self.moduleList:
func(self.modules[moduleName])
def forEachWrapper(self, func, supportedModules):
for wrapper in self.wrappers:
if supportedModules is None:
func(wrapper[0])
elif wrapper[1] in supportedModules:
func(wrapper[0])
## Overrides####################################################################
def beginFile(self, genOpts):
OutputGenerator.beginFile(self, genOpts)
self.forEachModule(lambda m: m.begin(self.genOpts.directory))
self.forEachWrapper(lambda w: w.onBegin(), None)
def endFile(self):
OutputGenerator.endFile(self)
self.typeInfo.onEnd()
self.forEachWrapper(lambda w: w.onEnd(), None)
self.forEachModule(lambda m: m.end())
def beginFeature(self, interface, emit):
# Start processing in superclass
OutputGenerator.beginFeature(self, interface, emit)
for supportedFeature in SUPPORTED_FEATURES:
if self.featureName == supportedFeature:
self.featureSupported = True
if self.featureSupported == False:
return
self.supportedModules = SUPPORTED_MODULES.get(self.featureName)
self.typeInfo.onBeginFeature(self.featureName, self.featureType)
self.forEachModule(
lambda m: m.appendHeader("#ifdef %s\n" % self.featureName)
if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None)
self.forEachModule(
lambda m: m.appendImpl("#ifdef %s\n" % self.featureName)
if isinstance(m, cereal.Module) and not m.suppressFeatureGuards else None)
self.forEachWrapper(lambda w: w.onBeginFeature(self.featureName, self.featureType), self.supportedModules)
# functable needs to understand the feature type (device vs instance) of each cmd
for features in interface.findall('require'):
for c in features.findall('command'):
self.forEachWrapper(lambda w: w.onFeatureNewCmd(c.get('name')), self.supportedModules)
def endFeature(self):
# Finish processing in superclass
OutputGenerator.endFeature(self)
if self.featureSupported == False:
return
self.featureSupported = False
self.typeInfo.onEndFeature()
self.forEachModule(lambda m: m.appendHeader("#endif\n") if isinstance(
m, cereal.Module) and not m.suppressFeatureGuards else None)
self.forEachModule(lambda m: m.appendImpl("#endif\n") if isinstance(
m, cereal.Module) and not m.suppressFeatureGuards else None)
self.forEachWrapper(lambda w: w.onEndFeature(), self.supportedModules)
def genType(self, typeinfo: TypeInfo, name, alias):
OutputGenerator.genType(self, typeinfo, name, alias)
# Maybe this check can be removed if we refactor other things inside
# the cereal subdirectory.
if self.featureSupported == False and name in REQUIRED_TYPES:
self.typeInfo.onGenType(typeinfo, name, alias)
return
if self.featureSupported == False:
return
self.typeInfo.onGenType(typeinfo, name, alias)
self.forEachWrapper(lambda w: w.onGenType(typeinfo, name, alias), self.supportedModules)
def genStruct(self, typeinfo, typeName, alias):
OutputGenerator.genStruct(self, typeinfo, typeName, alias)
if self.featureSupported == False:
return
self.typeInfo.onGenStruct(typeinfo, typeName, alias)
self.forEachWrapper(lambda w: w.onGenStruct(typeinfo, typeName, alias), self.supportedModules)
def genGroup(self, groupinfo: GroupInfo, groupName, alias = None):
OutputGenerator.genGroup(self, groupinfo, groupName, alias)
if self.featureSupported == False:
return
self.typeInfo.onGenGroup(groupinfo, groupName, alias)
self.forEachWrapper(lambda w: w.onGenGroup(groupinfo, groupName, alias), self.supportedModules)
def genEnum(self, enuminfo: EnumInfo, name, alias):
OutputGenerator.genEnum(self, enuminfo, name, alias)
if self.featureSupported == False:
return
self.typeInfo.onGenEnum(enuminfo, name, alias)
self.forEachWrapper(lambda w: w.onGenEnum(enuminfo, name, alias), self.supportedModules)
def genCmd(self, cmdinfo, name, alias):
OutputGenerator.genCmd(self, cmdinfo, name, alias)
if self.featureSupported == False:
return
self.typeInfo.onGenCmd(cmdinfo, name, alias)
self.forEachWrapper(lambda w: w.onGenCmd(cmdinfo, name, alias), self.supportedModules)