1# Copyright (c) 2018 The Android Open Source Project 2# Copyright (c) 2018 Google Inc. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16from .common.codegen import CodeGen 17from .common.vulkantypes import \ 18 VulkanAPI, makeVulkanTypeSimple, iterateVulkanType 19 20from .wrapperdefs import VulkanWrapperGenerator 21from .wrapperdefs import STRUCT_EXTENSION_PARAM 22from .wrapperdefs import STRUCT_EXTENSION_PARAM_FOR_WRITE 23from .wrapperdefs import EXTENSION_SIZE_API_NAME 24from .wrapperdefs import EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME 25from .wrapperdefs import STRUCT_TYPE_API_NAME 26 27class VulkanExtensionStructs(VulkanWrapperGenerator): 28 29 def __init__(self, module, typeInfo, variant="host"): 30 VulkanWrapperGenerator.__init__(self, module, typeInfo) 31 32 self.codegen = CodeGen() 33 34 self.variant = variant 35 36 self.structTypeRetType = \ 37 makeVulkanTypeSimple(False, "uint32_t", 0) 38 39 self.rootTypeVarName = "rootType" 40 self.rootTypeParam = \ 41 makeVulkanTypeSimple(False, "VkStructureType", 42 0, self.rootTypeVarName) 43 self.structTypePrototype = \ 44 VulkanAPI(STRUCT_TYPE_API_NAME, 45 self.structTypeRetType, 46 [STRUCT_EXTENSION_PARAM]) 47 48 self.extensionStructSizeRetType = \ 49 makeVulkanTypeSimple(False, "size_t", 0) 50 self.extensionStructSizePrototype = \ 51 VulkanAPI(EXTENSION_SIZE_API_NAME, 52 self.extensionStructSizeRetType, 53 [self.rootTypeParam, STRUCT_EXTENSION_PARAM]) 54 55 self.streamFeaturesType = makeVulkanTypeSimple(False, "uint32_t", 0, "streamFeatures") 56 57 self.extensionStructSizeWithStreamFeaturesPrototype = \ 58 VulkanAPI(EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME, 59 self.extensionStructSizeRetType, 60 [self.streamFeaturesType, self.rootTypeParam, STRUCT_EXTENSION_PARAM]) 61 def onBegin(self,): 62 VulkanWrapperGenerator.onBegin(self) 63 self.module.appendHeader(self.codegen.makeFuncDecl( 64 self.structTypePrototype)) 65 self.module.appendHeader(self.codegen.makeFuncDecl( 66 self.extensionStructSizePrototype)) 67 self.module.appendHeader(self.codegen.makeFuncDecl( 68 self.extensionStructSizeWithStreamFeaturesPrototype)) 69 70 def onGenType(self, typeXml, name, alias): 71 VulkanWrapperGenerator.onGenType(self, typeXml, name, alias) 72 73 def onGenCmd(self, cmdinfo, name, alias): 74 VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias) 75 76 def onEnd(self,): 77 VulkanWrapperGenerator.onEnd(self) 78 79 def castAsStruct(varName, typeName, const=True): 80 return "reinterpret_cast<%s%s*>(%s)" % \ 81 ("const " if const else "", typeName, varName) 82 83 def structTypeImpl(cgen): 84 cgen.stmt( 85 "const uint32_t asStructType = *(%s)" % 86 (castAsStruct(STRUCT_EXTENSION_PARAM.paramName, "uint32_t"))) 87 cgen.stmt("return asStructType") 88 89 self.module.appendImpl( 90 self.codegen.makeFuncImpl( 91 self.structTypePrototype, structTypeImpl)) 92 93 def forEachExtensionReturnSize(ext, _, cgen): 94 cgen.stmt("return sizeof(%s)" % ext.name) 95 96 def forEachExtensionReturnSizeProtectedByFeature(ext, _, cgen): 97 streamFeature = ext.getProtectStreamFeature() 98 if streamFeature is None: 99 cgen.stmt("return sizeof(%s)" % ext.name) 100 return 101 cgen.beginIf("%s & %s" % ("streamFeatures", streamFeature)) 102 cgen.stmt("return sizeof(%s)" % ext.name) 103 cgen.endIf() 104 cgen.beginElse() 105 cgen.stmt("return 0") 106 cgen.endIf() 107 108 def defaultAbortEmit(cgen): 109 # The 'structType' name and return behavior are defined in 110 # emitForEachStructExtension and not accessible here. Consequently, 111 # this is a copy-paste from there and must be updated accordingly. 112 # NOTE: No need for %% if no substitution is made. 113 cgen.stmt("fprintf(stderr, \"Unhandled Vulkan structure type %d, aborting.\\n\", structType)") 114 cgen.stmt("GFXSTREAM_ABORT(::emugl::FatalError(::emugl::ABORT_REASON_OTHER))") 115 cgen.stmt("return (%s)0" % self.extensionStructSizeRetType.typeName) 116 117 self.module.appendImpl( 118 self.codegen.makeFuncImpl( 119 self.extensionStructSizePrototype, 120 lambda cgen: self.emitForEachStructExtension( 121 cgen, 122 self.extensionStructSizeRetType, 123 STRUCT_EXTENSION_PARAM, 124 forEachExtensionReturnSize, autoBreak=False, 125 defaultEmit=(defaultAbortEmit if self.variant == "host" else None), 126 rootTypeVar=self.rootTypeParam))) 127 128 self.module.appendImpl( 129 self.codegen.makeFuncImpl( 130 self.extensionStructSizeWithStreamFeaturesPrototype, 131 lambda cgen: self.emitForEachStructExtension( 132 cgen, 133 self.extensionStructSizeRetType, 134 STRUCT_EXTENSION_PARAM, 135 forEachExtensionReturnSizeProtectedByFeature, autoBreak=False, 136 defaultEmit=(defaultAbortEmit if self.variant == "host" else None), 137 rootTypeVar=self.rootTypeParam))) 138