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, VulkanTypeIterator 19 20from .wrapperdefs import VulkanWrapperGenerator 21from .wrapperdefs import STRUCT_EXTENSION_PARAM, STRUCT_EXTENSION_PARAM_FOR_WRITE 22 23class HandleMapCodegen(VulkanTypeIterator): 24 def __init__(self, cgen, inputVar, handlemapVarName, prefix, isHandleFunc): 25 self.cgen = cgen 26 self.inputVar = inputVar 27 self.prefix = prefix 28 self.handlemapVarName = handlemapVarName 29 30 def makeAccess(varName, asPtr = True): 31 return lambda t: self.cgen.generalAccess(t, parentVarName = varName, asPtr = asPtr) 32 33 def makeLengthAccess(varName): 34 return lambda t: self.cgen.generalLengthAccess(t, parentVarName = varName) 35 36 def makeLengthAccessGuard(varName): 37 return lambda t: self.cgen.generalLengthAccessGuard(t, parentVarName=varName) 38 39 self.exprAccessor = makeAccess(self.inputVar) 40 self.exprAccessorValue = makeAccess(self.inputVar, asPtr = False) 41 self.lenAccessor = makeLengthAccess(self.inputVar) 42 self.lenAccessorGuard = makeLengthAccessGuard(self.inputVar) 43 44 self.checked = False 45 self.isHandleFunc = isHandleFunc 46 47 def needSkip(self, vulkanType): 48 return False 49 50 def makeCastExpr(self, vulkanType): 51 return "(%s)" % ( 52 self.cgen.makeCTypeDecl(vulkanType, useParamName=False)) 53 54 def asNonConstCast(self, access, vulkanType): 55 if vulkanType.staticArrExpr: 56 casted = "%s(%s)" % (self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()), access) 57 elif vulkanType.accessibleAsPointer(): 58 casted = "%s(%s)" % (self.makeCastExpr(vulkanType.getForNonConstAccess()), access) 59 else: 60 casted = "%s(%s)" % (self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()), access) 61 return casted 62 63 def onCheck(self, vulkanType): 64 pass 65 66 def endCheck(self, vulkanType): 67 pass 68 69 def onCompoundType(self, vulkanType): 70 71 if self.needSkip(vulkanType): 72 self.cgen.line("// TODO: Unsupported : %s" % 73 self.cgen.makeCTypeDecl(vulkanType)) 74 return 75 access = self.exprAccessor(vulkanType) 76 lenAccess = self.lenAccessor(vulkanType) 77 lenAccessGuard = self.lenAccessorGuard(vulkanType) 78 79 isPtr = vulkanType.pointerIndirectionLevels > 0 80 81 if lenAccessGuard is not None: 82 self.cgen.beginIf(lenAccessGuard) 83 84 if isPtr: 85 self.cgen.beginIf(access) 86 87 if lenAccess is not None: 88 89 loopVar = "i" 90 access = "%s + %s" % (access, loopVar) 91 forInit = "uint32_t %s = 0" % loopVar 92 forCond = "%s < (uint32_t)%s" % (loopVar, lenAccess) 93 forIncr = "++%s" % loopVar 94 95 self.cgen.beginFor(forInit, forCond, forIncr) 96 97 accessCasted = self.asNonConstCast(access, vulkanType) 98 self.cgen.funcCall(None, self.prefix + vulkanType.typeName, 99 [self.handlemapVarName, accessCasted]) 100 101 if lenAccess is not None: 102 self.cgen.endFor() 103 104 if isPtr: 105 self.cgen.endIf() 106 107 if lenAccessGuard is not None: 108 self.cgen.endIf() 109 110 def onString(self, vulkanType): 111 pass 112 113 def onStringArray(self, vulkanType): 114 pass 115 116 def onStaticArr(self, vulkanType): 117 if not self.isHandleFunc(vulkanType): 118 return 119 120 accessLhs = self.exprAccessor(vulkanType) 121 lenAccess = self.lenAccessor(vulkanType) 122 123 self.cgen.stmt("%s->mapHandles_%s(%s%s, %s)" % \ 124 (self.handlemapVarName, vulkanType.typeName, 125 self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()), 126 accessLhs, lenAccess)) 127 128 def onStructExtension(self, vulkanType): 129 access = self.exprAccessor(vulkanType) 130 131 castedAccessExpr = "(%s)(%s)" % ("void*", access) 132 self.cgen.beginIf(access) 133 self.cgen.funcCall(None, self.prefix + "extension_struct", 134 [self.handlemapVarName, castedAccessExpr]) 135 self.cgen.endIf() 136 137 def onPointer(self, vulkanType): 138 if self.needSkip(vulkanType): 139 return 140 141 if not self.isHandleFunc(vulkanType): 142 return 143 144 access = self.exprAccessor(vulkanType) 145 lenAccess = self.lenAccessor(vulkanType) 146 lenAccess = "1" if lenAccess is None else lenAccess 147 148 self.cgen.beginIf(access) 149 150 self.cgen.stmt( \ 151 "%s->mapHandles_%s(%s%s, %s)" % \ 152 (self.handlemapVarName, 153 vulkanType.typeName, 154 self.makeCastExpr(vulkanType.getForNonConstAccess()), 155 access, 156 lenAccess)) 157 158 self.cgen.endIf() 159 160 def onValue(self, vulkanType): 161 if not self.isHandleFunc(vulkanType): 162 return 163 access = self.exprAccessor(vulkanType) 164 self.cgen.stmt( 165 "%s->mapHandles_%s(%s%s)" % \ 166 (self.handlemapVarName, vulkanType.typeName, 167 self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()), 168 access)) 169 170class VulkanHandleMap(VulkanWrapperGenerator): 171 def __init__(self, module, typeInfo): 172 VulkanWrapperGenerator.__init__(self, module, typeInfo) 173 174 self.codegen = CodeGen() 175 176 self.handlemapPrefix = "handlemap_" 177 self.toMapVar = "toMap" 178 self.handlemapVarName = "handlemap" 179 self.handlemapParam = \ 180 makeVulkanTypeSimple(False, "VulkanHandleMapping", 1, 181 self.handlemapVarName) 182 self.voidType = makeVulkanTypeSimple(False, "void", 0) 183 184 self.handlemapCodegen = \ 185 HandleMapCodegen( 186 None, 187 self.toMapVar, 188 self.handlemapVarName, 189 self.handlemapPrefix, 190 lambda vtype : typeInfo.isHandleType(vtype.typeName)) 191 192 self.knownDefs = {} 193 194 self.extensionHandlemapPrototype = \ 195 VulkanAPI(self.handlemapPrefix + "extension_struct", 196 self.voidType, 197 [self.handlemapParam, STRUCT_EXTENSION_PARAM_FOR_WRITE]) 198 199 def onBegin(self,): 200 VulkanWrapperGenerator.onBegin(self) 201 self.module.appendImpl(self.codegen.makeFuncDecl( 202 self.extensionHandlemapPrototype)) 203 204 def onGenType(self, typeXml, name, alias): 205 VulkanWrapperGenerator.onGenType(self, typeXml, name, alias) 206 207 if name in self.knownDefs: 208 return 209 210 category = self.typeInfo.categoryOf(name) 211 212 if category in ["struct", "union"] and alias: 213 self.module.appendHeader( 214 self.codegen.makeFuncAlias(self.handlemapPrefix + name, 215 self.handlemapPrefix + alias)) 216 217 if category in ["struct", "union"] and not alias: 218 219 structInfo = self.typeInfo.structs[name] 220 221 typeFromName = \ 222 lambda varname: \ 223 makeVulkanTypeSimple(varname == "from", name, 1, varname) 224 225 handlemapParams = \ 226 [self.handlemapParam] + \ 227 list(map(typeFromName, [self.toMapVar])) 228 229 handlemapPrototype = \ 230 VulkanAPI(self.handlemapPrefix + name, 231 self.voidType, 232 handlemapParams) 233 234 def funcDefGenerator(cgen): 235 self.handlemapCodegen.cgen = cgen 236 for p in handlemapParams: 237 cgen.stmt("(void)%s" % p.paramName) 238 for member in structInfo.members: 239 iterateVulkanType(self.typeInfo, member, 240 self.handlemapCodegen) 241 242 self.module.appendHeader( 243 self.codegen.makeFuncDecl(handlemapPrototype)) 244 self.module.appendImpl( 245 self.codegen.makeFuncImpl(handlemapPrototype, funcDefGenerator)) 246 247 def onGenCmd(self, cmdinfo, name, alias): 248 VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias) 249 250 def onEnd(self,): 251 VulkanWrapperGenerator.onEnd(self) 252 253 def forEachExtensionHandlemap(ext, castedAccess, cgen): 254 cgen.funcCall(None, self.handlemapPrefix + ext.name, 255 [self.handlemapVarName, castedAccess]) 256 257 self.module.appendImpl( 258 self.codegen.makeFuncImpl( 259 self.extensionHandlemapPrototype, 260 lambda cgen: self.emitForEachStructExtension( 261 cgen, 262 self.voidType, 263 STRUCT_EXTENSION_PARAM_FOR_WRITE, 264 forEachExtensionHandlemap))) 265