1# Copyright 2018 Google LLC 2# SPDX-License-Identifier: MIT 3 4from .common.codegen import CodeGen 5from .common.vulkantypes import \ 6 VulkanAPI, makeVulkanTypeSimple, iterateVulkanType 7 8from .wrapperdefs import VulkanWrapperGenerator 9from .wrapperdefs import STRUCT_EXTENSION_PARAM 10from .wrapperdefs import STRUCT_EXTENSION_PARAM_FOR_WRITE 11from .wrapperdefs import EXTENSION_SIZE_API_NAME 12from .wrapperdefs import EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME 13from .wrapperdefs import STRUCT_TYPE_API_NAME 14 15class VulkanExtensionStructs(VulkanWrapperGenerator): 16 17 def __init__(self, module, typeInfo, variant="host"): 18 VulkanWrapperGenerator.__init__(self, module, typeInfo) 19 20 self.codegen = CodeGen() 21 22 self.variant = variant 23 24 self.structTypeRetType = \ 25 makeVulkanTypeSimple(False, "uint32_t", 0) 26 27 self.rootTypeVarName = "rootType" 28 self.rootTypeParam = \ 29 makeVulkanTypeSimple(False, "VkStructureType", 30 0, self.rootTypeVarName) 31 self.structTypePrototype = \ 32 VulkanAPI(STRUCT_TYPE_API_NAME, 33 self.structTypeRetType, 34 [STRUCT_EXTENSION_PARAM]) 35 36 self.extensionStructSizeRetType = \ 37 makeVulkanTypeSimple(False, "size_t", 0) 38 self.extensionStructSizePrototype = \ 39 VulkanAPI(EXTENSION_SIZE_API_NAME, 40 self.extensionStructSizeRetType, 41 [self.rootTypeParam, STRUCT_EXTENSION_PARAM]) 42 43 self.streamFeaturesType = makeVulkanTypeSimple(False, "uint32_t", 0, "streamFeatures") 44 45 self.extensionStructSizeWithStreamFeaturesPrototype = \ 46 VulkanAPI(EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME, 47 self.extensionStructSizeRetType, 48 [self.streamFeaturesType, self.rootTypeParam, STRUCT_EXTENSION_PARAM]) 49 def onBegin(self,): 50 VulkanWrapperGenerator.onBegin(self) 51 self.module.appendHeader(self.codegen.makeFuncDecl( 52 self.structTypePrototype)) 53 self.module.appendHeader(self.codegen.makeFuncDecl( 54 self.extensionStructSizePrototype)) 55 self.module.appendHeader(self.codegen.makeFuncDecl( 56 self.extensionStructSizeWithStreamFeaturesPrototype)) 57 58 def onGenType(self, typeXml, name, alias): 59 VulkanWrapperGenerator.onGenType(self, typeXml, name, alias) 60 61 def onGenCmd(self, cmdinfo, name, alias): 62 VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias) 63 64 def onEnd(self,): 65 VulkanWrapperGenerator.onEnd(self) 66 67 def castAsStruct(varName, typeName, const=True): 68 return "reinterpret_cast<%s%s*>(%s)" % \ 69 ("const " if const else "", typeName, varName) 70 71 def structTypeImpl(cgen): 72 cgen.stmt( 73 "const uint32_t asStructType = *(%s)" % 74 (castAsStruct(STRUCT_EXTENSION_PARAM.paramName, "uint32_t"))) 75 cgen.stmt("return asStructType") 76 77 self.module.appendImpl( 78 self.codegen.makeFuncImpl( 79 self.structTypePrototype, structTypeImpl)) 80 81 def forEachExtensionReturnSize(ext, _, cgen): 82 cgen.stmt("return sizeof(%s)" % ext.name) 83 84 def forEachExtensionReturnSizeProtectedByFeature(ext, _, cgen): 85 streamFeature = ext.getProtectStreamFeature() 86 if streamFeature is None: 87 cgen.stmt("return sizeof(%s)" % ext.name) 88 return 89 cgen.beginIf("%s & %s" % ("streamFeatures", streamFeature)) 90 cgen.stmt("return sizeof(%s)" % ext.name) 91 cgen.endIf() 92 cgen.beginElse() 93 cgen.stmt("return 0") 94 cgen.endIf() 95 96 def defaultAbortEmit(cgen): 97 # The 'structType' name and return behavior are defined in 98 # emitForEachStructExtension and not accessible here. Consequently, 99 # this is a copy-paste from there and must be updated accordingly. 100 # NOTE: No need for %% if no substitution is made. 101 cgen.stmt("fprintf(stderr, \"Unhandled Vulkan structure type %s [%d], aborting.\\n\", string_VkStructureType(VkStructureType(structType)), structType)") 102 cgen.stmt("GFXSTREAM_ABORT(::emugl::FatalError(::emugl::ABORT_REASON_OTHER))") 103 cgen.stmt("return static_cast<%s>(0)" % self.extensionStructSizeRetType.typeName) 104 105 self.module.appendImpl( 106 self.codegen.makeFuncImpl( 107 self.extensionStructSizePrototype, 108 lambda cgen: self.emitForEachStructExtension( 109 cgen, 110 self.extensionStructSizeRetType, 111 STRUCT_EXTENSION_PARAM, 112 forEachExtensionReturnSize, autoBreak=False, 113 defaultEmit=(defaultAbortEmit if self.variant == "host" else None), 114 rootTypeVar=self.rootTypeParam))) 115 116 self.module.appendImpl( 117 self.codegen.makeFuncImpl( 118 self.extensionStructSizeWithStreamFeaturesPrototype, 119 lambda cgen: self.emitForEachStructExtension( 120 cgen, 121 self.extensionStructSizeRetType, 122 STRUCT_EXTENSION_PARAM, 123 forEachExtensionReturnSizeProtectedByFeature, autoBreak=False, 124 defaultEmit=(defaultAbortEmit if self.variant == "host" else None), 125 rootTypeVar=self.rootTypeParam))) 126