diff options
Diffstat (limited to 'codegen/vulkan/scripts/cereal/marshaling.py')
-rw-r--r-- | codegen/vulkan/scripts/cereal/marshaling.py | 1037 |
1 files changed, 0 insertions, 1037 deletions
diff --git a/codegen/vulkan/scripts/cereal/marshaling.py b/codegen/vulkan/scripts/cereal/marshaling.py deleted file mode 100644 index 3427fed7..00000000 --- a/codegen/vulkan/scripts/cereal/marshaling.py +++ /dev/null @@ -1,1037 +0,0 @@ -# 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. - -from copy import copy -import hashlib, sys - -from .common.codegen import CodeGen, VulkanAPIWrapper -from .common.vulkantypes import \ - VulkanAPI, makeVulkanTypeSimple, iterateVulkanType, VulkanTypeIterator, Atom, FuncExpr, FuncExprVal, FuncLambda - -from .wrapperdefs import VulkanWrapperGenerator -from .wrapperdefs import VULKAN_STREAM_VAR_NAME -from .wrapperdefs import ROOT_TYPE_VAR_NAME, ROOT_TYPE_PARAM -from .wrapperdefs import STREAM_RET_TYPE -from .wrapperdefs import MARSHAL_INPUT_VAR_NAME -from .wrapperdefs import UNMARSHAL_INPUT_VAR_NAME -from .wrapperdefs import PARAMETERS_MARSHALING -from .wrapperdefs import PARAMETERS_MARSHALING_GUEST -from .wrapperdefs import STYPE_OVERRIDE -from .wrapperdefs import STRUCT_EXTENSION_PARAM, STRUCT_EXTENSION_PARAM_FOR_WRITE, EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME -from .wrapperdefs import API_PREFIX_MARSHAL -from .wrapperdefs import API_PREFIX_UNMARSHAL - -from .marshalingdefs import KNOWN_FUNCTION_OPCODES, CUSTOM_MARSHAL_TYPES - -class VulkanMarshalingCodegen(VulkanTypeIterator): - - def __init__(self, - cgen, - streamVarName, - rootTypeVarName, - inputVarName, - marshalPrefix, - direction = "write", - forApiOutput = False, - dynAlloc = False, - mapHandles = True, - handleMapOverwrites = False, - doFiltering = True): - self.cgen = cgen - self.direction = direction - self.processSimple = "write" if self.direction == "write" else "read" - self.forApiOutput = forApiOutput - - self.checked = False - - self.streamVarName = streamVarName - self.rootTypeVarName = rootTypeVarName - self.inputVarName = inputVarName - self.marshalPrefix = marshalPrefix - - self.exprAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.inputVarName, asPtr = True) - self.exprValueAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.inputVarName, asPtr = False) - self.exprPrimitiveValueAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.inputVarName, asPtr = False) - self.lenAccessor = lambda t: self.cgen.generalLengthAccess(t, parentVarName = self.inputVarName) - self.lenAccessorGuard = lambda t: self.cgen.generalLengthAccessGuard( - t, parentVarName=self.inputVarName) - self.filterVarAccessor = lambda t: self.cgen.filterVarAccess(t, parentVarName = self.inputVarName) - - self.dynAlloc = dynAlloc - self.mapHandles = mapHandles - self.handleMapOverwrites = handleMapOverwrites - self.doFiltering = doFiltering - - def getTypeForStreaming(self, vulkanType): - res = copy(vulkanType) - - if not vulkanType.accessibleAsPointer(): - res = res.getForAddressAccess() - - if vulkanType.staticArrExpr: - res = res.getForAddressAccess() - - if self.direction == "write": - return res - else: - return res.getForNonConstAccess() - - def makeCastExpr(self, vulkanType): - return "(%s)" % ( - self.cgen.makeCTypeDecl(vulkanType, useParamName=False)) - - def genStreamCall(self, vulkanType, toStreamExpr, sizeExpr): - varname = self.streamVarName - func = self.processSimple - cast = self.makeCastExpr(self.getTypeForStreaming(vulkanType)) - - self.cgen.stmt( - "%s->%s(%s%s, %s)" % (varname, func, cast, toStreamExpr, sizeExpr)) - - def genPrimitiveStreamCall(self, vulkanType, access): - varname = self.streamVarName - - self.cgen.streamPrimitive( - self.typeInfo, - varname, - access, - vulkanType, - direction=self.direction) - - def genHandleMappingCall(self, vulkanType, access, lenAccess): - - if lenAccess is None: - lenAccess = "1" - handle64Bytes = "8" - else: - handle64Bytes = "%s * 8" % lenAccess - - handle64Var = self.cgen.var() - if lenAccess != "1": - self.cgen.beginIf(lenAccess) - self.cgen.stmt("uint64_t* %s" % handle64Var) - self.cgen.stmt( - "%s->alloc((void**)&%s, %s * 8)" % \ - (self.streamVarName, handle64Var, lenAccess)) - handle64VarAccess = handle64Var - handle64VarType = \ - makeVulkanTypeSimple(False, "uint64_t", 1, paramName=handle64Var) - else: - self.cgen.stmt("uint64_t %s" % handle64Var) - handle64VarAccess = "&%s" % handle64Var - handle64VarType = \ - makeVulkanTypeSimple(False, "uint64_t", 0, paramName=handle64Var) - - if self.direction == "write": - if self.handleMapOverwrites: - self.cgen.stmt( - "static_assert(8 == sizeof(%s), \"handle map overwrite requires %s to be 8 bytes long\")" % \ - (vulkanType.typeName, vulkanType.typeName)) - self.cgen.stmt( - "%s->handleMapping()->mapHandles_%s((%s*)%s, %s)" % - (self.streamVarName, vulkanType.typeName, vulkanType.typeName, - access, lenAccess)) - self.genStreamCall(vulkanType, access, "8 * %s" % lenAccess) - else: - self.cgen.stmt( - "%s->handleMapping()->mapHandles_%s_u64(%s, %s, %s)" % - (self.streamVarName, vulkanType.typeName, - access, - handle64VarAccess, lenAccess)) - self.genStreamCall(handle64VarType, handle64VarAccess, handle64Bytes) - else: - self.genStreamCall(handle64VarType, handle64VarAccess, handle64Bytes) - self.cgen.stmt( - "%s->handleMapping()->mapHandles_u64_%s(%s, %s%s, %s)" % - (self.streamVarName, vulkanType.typeName, - handle64VarAccess, - self.makeCastExpr(vulkanType.getForNonConstAccess()), access, - lenAccess)) - - if lenAccess != "1": - self.cgen.endIf() - - def doAllocSpace(self, vulkanType): - if self.dynAlloc and self.direction == "read": - access = self.exprAccessor(vulkanType) - lenAccess = self.lenAccessor(vulkanType) - sizeof = self.cgen.sizeofExpr( \ - vulkanType.getForValueAccess()) - if lenAccess: - bytesExpr = "%s * %s" % (lenAccess, sizeof) - else: - bytesExpr = sizeof - - self.cgen.stmt( \ - "%s->alloc((void**)&%s, %s)" % - (self.streamVarName, - access, bytesExpr)) - - def getOptionalStringFeatureExpr(self, vulkanType): - if vulkanType.optionalStr is not None: - if vulkanType.optionalStr.startswith("streamFeature:"): - splitted = vulkanType.optionalStr.split(":") - featureExpr = "%s->getFeatureBits() & %s" % (self.streamVarName, splitted[1]) - return featureExpr - return None - - def onCheck(self, vulkanType): - - if self.forApiOutput: - return - - featureExpr = self.getOptionalStringFeatureExpr(vulkanType); - - self.checked = True - - access = self.exprAccessor(vulkanType) - - needConsistencyCheck = False - - self.cgen.line("// WARNING PTR CHECK") - if (self.dynAlloc and self.direction == "read") or self.direction == "write": - checkAccess = self.exprAccessor(vulkanType) - addrExpr = "&" + checkAccess - sizeExpr = self.cgen.sizeofExpr(vulkanType) - else: - checkName = "check_%s" % vulkanType.paramName - self.cgen.stmt("%s %s" % ( - self.cgen.makeCTypeDecl(vulkanType, useParamName = False), checkName)) - checkAccess = checkName - addrExpr = "&" + checkAccess - sizeExpr = self.cgen.sizeofExpr(vulkanType) - needConsistencyCheck = True - - if featureExpr is not None: - self.cgen.beginIf(featureExpr) - - self.genPrimitiveStreamCall( - vulkanType, - checkAccess) - - if featureExpr is not None: - self.cgen.endIf() - - if featureExpr is not None: - self.cgen.beginIf("(!(%s) || %s)" % (featureExpr, access)) - else: - self.cgen.beginIf(access) - - if needConsistencyCheck and featureExpr is None: - self.cgen.beginIf("!(%s)" % checkName) - self.cgen.stmt( - "fprintf(stderr, \"fatal: %s inconsistent between guest and host\\n\")" % (access)) - self.cgen.endIf() - - - def onCheckWithNullOptionalStringFeature(self, vulkanType): - self.cgen.beginIf("%s->getFeatureBits() & VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT" % self.streamVarName) - self.onCheck(vulkanType) - - def endCheckWithNullOptionalStringFeature(self, vulkanType): - self.endCheck(vulkanType) - self.cgen.endIf() - self.cgen.beginElse() - - def finalCheckWithNullOptionalStringFeature(self, vulkanType): - self.cgen.endElse() - - def endCheck(self, vulkanType): - - if self.checked: - self.cgen.endIf() - self.checked = False - - def genFilterFunc(self, filterfunc, env): - - def loop(expr, lambdaEnv={}): - def do_func(expr): - fnamestr = expr.name.name - if "not" == fnamestr: - return "!(%s)" % (loop(expr.args[0], lambdaEnv)) - if "eq" == fnamestr: - return "(%s == %s)" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv)) - if "and" == fnamestr: - return "(%s && %s)" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv)) - if "or" == fnamestr: - return "(%s || %s)" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv)) - if "bitwise_and" == fnamestr: - return "(%s & %s)" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv)) - if "getfield" == fnamestr: - ptrlevels = get_ptrlevels(expr.args[0].val.name) - if ptrlevels == 0: - return "%s.%s" % (loop(expr.args[0], lambdaEnv), expr.args[1].val) - else: - return "(%s(%s)).%s" % ("*" * ptrlevels, loop(expr.args[0], lambdaEnv), expr.args[1].val) - - if "if" == fnamestr: - return "((%s) ? (%s) : (%s))" % (loop(expr.args[0], lambdaEnv), loop(expr.args[1], lambdaEnv), loop(expr.args[2], lambdaEnv)) - - return "%s(%s)" % (fnamestr, ", ".join(map(lambda e: loop(e, lambdaEnv), expr.args))) - - def do_expratom(atomname, lambdaEnv= {}): - if lambdaEnv.get(atomname, None) is not None: - return atomname - - enventry = env.get(atomname, None) - if None != enventry: - return self.getEnvAccessExpr(atomname) - return atomname - - def get_ptrlevels(atomname, lambdaEnv= {}): - if lambdaEnv.get(atomname, None) is not None: - return 0 - - enventry = env.get(atomname, None) - if None != enventry: - return self.getPointerIndirectionLevels(atomname) - - return 0 - - def do_exprval(expr, lambdaEnv= {}): - expratom = expr.val - - if Atom == type(expratom): - return do_expratom(expratom.name, lambdaEnv) - - return "%s" % expratom - - def do_lambda(expr, lambdaEnv= {}): - params = expr.vs - body = expr.body - newEnv = {} - - for (k, v) in lambdaEnv.items(): - newEnv[k] = v - - for p in params: - newEnv[p.name] = p.typ - - return "[](%s) { return %s; }" % (", ".join(list(map(lambda p: "%s %s" % (p.typ, p.name), params))), loop(body, lambdaEnv=newEnv)) - - if FuncExpr == type(expr): - return do_func(expr) - if FuncLambda == type(expr): - return do_lambda(expr) - elif FuncExprVal == type(expr): - return do_exprval(expr) - - return loop(filterfunc) - - def beginFilterGuard(self, vulkanType): - if vulkanType.filterVar == None: - return - - if self.doFiltering == False: - return - - filterVarAccess = self.getEnvAccessExpr(vulkanType.filterVar) - - filterValsExpr = None - filterFuncExpr = None - filterExpr = None - - filterFeature = "%s->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT" % self.streamVarName - - if None != vulkanType.filterVals: - filterValsExpr = " || ".join(map(lambda filterval: "(%s == %s)" % (filterval, filterVarAccess), vulkanType.filterVals)) - - if None != vulkanType.filterFunc: - filterFuncExpr = self.genFilterFunc(vulkanType.filterFunc, self.currentStructInfo.environment) - - if None != filterValsExpr and None != filterFuncExpr: - filterExpr = "%s || %s" % (filterValsExpr, filterFuncExpr) - elif None == filterValsExpr and None == filterFuncExpr: - # Assume is bool - self.cgen.beginIf(filterVarAccess) - elif None != filterValsExpr: - self.cgen.beginIf("(!(%s) || (%s))" % (filterFeature, filterValsExpr)) - elif None != filterFuncExpr: - self.cgen.beginIf("(!(%s) || (%s))" % (filterFeature, filterFuncExpr)) - - def endFilterGuard(self, vulkanType, cleanupExpr=None): - if vulkanType.filterVar == None: - return - - if self.doFiltering == False: - return - - if cleanupExpr == None: - self.cgen.endIf() - else: - self.cgen.endIf() - self.cgen.beginElse() - self.cgen.stmt(cleanupExpr) - self.cgen.endElse() - - def getEnvAccessExpr(self, varName): - parentEnvEntry = self.currentStructInfo.environment.get(varName, None) - - if parentEnvEntry != None: - isParentMember = parentEnvEntry["structmember"] - - if isParentMember: - envAccess = self.exprValueAccessor(list(filter(lambda member: member.paramName == varName, self.currentStructInfo.members))[0]) - else: - envAccess = varName - return envAccess - - return None - - def getPointerIndirectionLevels(self, varName): - parentEnvEntry = self.currentStructInfo.environment.get(varName, None) - - if parentEnvEntry != None: - isParentMember = parentEnvEntry["structmember"] - - if isParentMember: - return list(filter(lambda member: member.paramName == varName, self.currentStructInfo.members))[0].pointerIndirectionLevels - else: - return 0 - return 0 - - return 0 - - - def onCompoundType(self, vulkanType): - - access = self.exprAccessor(vulkanType) - lenAccess = self.lenAccessor(vulkanType) - lenAccessGuard = self.lenAccessorGuard(vulkanType) - - self.beginFilterGuard(vulkanType) - - if vulkanType.pointerIndirectionLevels > 0: - self.doAllocSpace(vulkanType) - - if lenAccess is not None: - if lenAccessGuard is not None: - self.cgen.beginIf(lenAccessGuard) - loopVar = "i" - access = "%s + %s" % (access, loopVar) - forInit = "uint32_t %s = 0" % loopVar - forCond = "%s < (uint32_t)%s" % (loopVar, lenAccess) - forIncr = "++%s" % loopVar - self.cgen.beginFor(forInit, forCond, forIncr) - - accessWithCast = "%s(%s)" % (self.makeCastExpr( - self.getTypeForStreaming(vulkanType)), access) - - callParams = [self.streamVarName, self.rootTypeVarName, accessWithCast] - - for (bindName, localName) in vulkanType.binds.items(): - callParams.append(self.getEnvAccessExpr(localName)) - - self.cgen.funcCall(None, self.marshalPrefix + vulkanType.typeName, - callParams) - - if lenAccess is not None: - self.cgen.endFor() - if lenAccessGuard is not None: - self.cgen.endIf() - - if self.direction == "read": - self.endFilterGuard(vulkanType, "%s = 0" % self.exprAccessor(vulkanType)) - else: - self.endFilterGuard(vulkanType) - - def onString(self, vulkanType): - - access = self.exprAccessor(vulkanType) - - if self.direction == "write": - self.cgen.stmt("%s->putString(%s)" % (self.streamVarName, access)) - else: - castExpr = \ - self.makeCastExpr( \ - self.getTypeForStreaming( \ - vulkanType.getForAddressAccess())) - - self.cgen.stmt( \ - "%s->loadStringInPlace(%s&%s)" % (self.streamVarName, castExpr, access)) - - def onStringArray(self, vulkanType): - - access = self.exprAccessor(vulkanType) - lenAccess = self.lenAccessor(vulkanType) - - if self.direction == "write": - self.cgen.stmt("saveStringArray(%s, %s, %s)" % (self.streamVarName, - access, lenAccess)) - else: - castExpr = \ - self.makeCastExpr( \ - self.getTypeForStreaming( \ - vulkanType.getForAddressAccess())) - - self.cgen.stmt("%s->loadStringArrayInPlace(%s&%s)" % (self.streamVarName, castExpr, access)) - - def onStaticArr(self, vulkanType): - access = self.exprValueAccessor(vulkanType) - lenAccess = self.lenAccessor(vulkanType) - finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType)) - self.genStreamCall(vulkanType, access, finalLenExpr) - - # Old version VkEncoder may have some sType values conflict with VkDecoder - # of new versions. For host decoder, it should not carry the incorrect old - # sType values to the |forUnmarshaling| struct. Instead it should overwrite - # the sType value. - def overwriteSType(self, vulkanType): - if self.direction == "read": - sTypeParam = copy(vulkanType) - sTypeParam.paramName = "sType" - sTypeAccess = self.exprAccessor(sTypeParam) - - typeName = vulkanType.parent.typeName - if typeName in STYPE_OVERRIDE: - self.cgen.stmt("%s = %s" % - (sTypeAccess, STYPE_OVERRIDE[typeName])) - - def onStructExtension(self, vulkanType): - self.overwriteSType(vulkanType) - - sTypeParam = copy(vulkanType) - sTypeParam.paramName = "sType" - - access = self.exprAccessor(vulkanType) - sizeVar = "%s_size" % vulkanType.paramName - - if self.direction == "read": - castedAccessExpr = "(%s)(%s)" % ("void*", access) - else: - castedAccessExpr = access - - sTypeAccess = self.exprAccessor(sTypeParam) - self.cgen.beginIf("%s == VK_STRUCTURE_TYPE_MAX_ENUM" % - self.rootTypeVarName) - self.cgen.stmt("%s = %s" % (self.rootTypeVarName, sTypeAccess)) - self.cgen.endIf() - - if self.direction == "read" and self.dynAlloc: - self.cgen.stmt("size_t %s" % sizeVar) - self.cgen.stmt("%s = %s->getBe32()" % \ - (sizeVar, self.streamVarName)) - self.cgen.stmt("%s = nullptr" % access) - self.cgen.beginIf(sizeVar) - self.cgen.stmt( \ - "%s->alloc((void**)&%s, sizeof(VkStructureType))" % - (self.streamVarName, access)) - - self.genStreamCall(vulkanType, access, "sizeof(VkStructureType)") - self.cgen.stmt("VkStructureType extType = *(VkStructureType*)(%s)" % access) - self.cgen.stmt( \ - "%s->alloc((void**)&%s, %s(%s->getFeatureBits(), %s, %s))" % - (self.streamVarName, access, EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME, self.streamVarName, self.rootTypeVarName, access)) - self.cgen.stmt("*(VkStructureType*)%s = extType" % access) - - self.cgen.funcCall(None, self.marshalPrefix + "extension_struct", - [self.streamVarName, self.rootTypeVarName, castedAccessExpr]) - self.cgen.endIf() - else: - - self.cgen.funcCall(None, self.marshalPrefix + "extension_struct", - [self.streamVarName, self.rootTypeVarName, castedAccessExpr]) - - - def onPointer(self, vulkanType): - access = self.exprAccessor(vulkanType) - - lenAccess = self.lenAccessor(vulkanType) - lenAccessGuard = self.lenAccessorGuard(vulkanType) - - self.beginFilterGuard(vulkanType) - self.doAllocSpace(vulkanType) - - if vulkanType.filterVar != None: - print("onPointer Needs filter: %s filterVar %s" % (access, vulkanType.filterVar)) - - if vulkanType.isHandleType() and self.mapHandles: - self.genHandleMappingCall(vulkanType, access, lenAccess) - else: - if self.typeInfo.isNonAbiPortableType(vulkanType.typeName): - if lenAccess is not None: - if lenAccessGuard is not None: - self.cgen.beginIf(lenAccessGuard) - self.cgen.beginFor("uint32_t i = 0", "i < (uint32_t)%s" % lenAccess, "++i") - self.genPrimitiveStreamCall(vulkanType.getForValueAccess(), "%s[i]" % access) - self.cgen.endFor() - if lenAccessGuard is not None: - self.cgen.endIf() - else: - self.genPrimitiveStreamCall(vulkanType.getForValueAccess(), "(*%s)" % access) - else: - if lenAccess is not None: - finalLenExpr = "%s * %s" % ( - lenAccess, self.cgen.sizeofExpr(vulkanType.getForValueAccess())) - else: - finalLenExpr = "%s" % ( - self.cgen.sizeofExpr(vulkanType.getForValueAccess())) - self.genStreamCall(vulkanType, access, finalLenExpr) - - if self.direction == "read": - self.endFilterGuard(vulkanType, "%s = 0" % access) - else: - self.endFilterGuard(vulkanType) - - def onValue(self, vulkanType): - self.beginFilterGuard(vulkanType) - - if vulkanType.isHandleType() and self.mapHandles: - access = self.exprAccessor(vulkanType) - if vulkanType.filterVar != None: - print("onValue Needs filter: %s filterVar %s" % (access, vulkanType.filterVar)) - self.genHandleMappingCall( - vulkanType.getForAddressAccess(), access, "1") - elif self.typeInfo.isNonAbiPortableType(vulkanType.typeName): - access = self.exprPrimitiveValueAccessor(vulkanType) - self.genPrimitiveStreamCall(vulkanType, access) - else: - access = self.exprAccessor(vulkanType) - self.genStreamCall(vulkanType, access, self.cgen.sizeofExpr(vulkanType)) - - self.endFilterGuard(vulkanType) - - def streamLetParameter(self, structInfo, letParamInfo): - filterFeature = "%s->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT" % self.streamVarName - self.cgen.stmt("%s %s = 1" % (letParamInfo.typeName, letParamInfo.paramName)) - - self.cgen.beginIf(filterFeature) - - if self.direction == "write": - bodyExpr = self.currentStructInfo.environment[letParamInfo.paramName]["body"] - self.cgen.stmt("%s = %s" % (letParamInfo.paramName, self.genFilterFunc(bodyExpr, self.currentStructInfo.environment))) - - self.genPrimitiveStreamCall(letParamInfo, letParamInfo.paramName) - - self.cgen.endIf() - - -class VulkanMarshaling(VulkanWrapperGenerator): - - def __init__(self, module, typeInfo, variant="host"): - VulkanWrapperGenerator.__init__(self, module, typeInfo) - - self.cgenHeader = CodeGen() - self.cgenImpl = CodeGen() - - self.variant = variant - - self.currentFeature = None - self.apiOpcodes = {} - self.dynAlloc = self.variant != "guest" - - if self.variant == "guest": - self.marshalingParams = PARAMETERS_MARSHALING_GUEST - else: - self.marshalingParams = PARAMETERS_MARSHALING - - self.writeCodegen = \ - VulkanMarshalingCodegen( - None, - VULKAN_STREAM_VAR_NAME, - ROOT_TYPE_VAR_NAME, - MARSHAL_INPUT_VAR_NAME, - API_PREFIX_MARSHAL, - direction = "write") - - self.readCodegen = \ - VulkanMarshalingCodegen( - None, - VULKAN_STREAM_VAR_NAME, - ROOT_TYPE_VAR_NAME, - UNMARSHAL_INPUT_VAR_NAME, - API_PREFIX_UNMARSHAL, - direction = "read", - dynAlloc=self.dynAlloc) - - self.knownDefs = {} - - # Begin Vulkan API opcodes from something high - # that is not going to interfere with renderControl - # opcodes - self.beginOpcodeOld = 20000 - self.endOpcodeOld = 30000 - - self.beginOpcode = 200000000 - self.endOpcode = 300000000 - self.knownOpcodes = set() - - self.extensionMarshalPrototype = \ - VulkanAPI(API_PREFIX_MARSHAL + "extension_struct", - STREAM_RET_TYPE, - self.marshalingParams + - [STRUCT_EXTENSION_PARAM]) - - self.extensionUnmarshalPrototype = \ - VulkanAPI(API_PREFIX_UNMARSHAL + "extension_struct", - STREAM_RET_TYPE, - self.marshalingParams + - [STRUCT_EXTENSION_PARAM_FOR_WRITE]) - - def onBegin(self,): - VulkanWrapperGenerator.onBegin(self) - self.module.appendImpl(self.cgenImpl.makeFuncDecl(self.extensionMarshalPrototype)) - self.module.appendImpl(self.cgenImpl.makeFuncDecl(self.extensionUnmarshalPrototype)) - - def onBeginFeature(self, featureName, featureType): - VulkanWrapperGenerator.onBeginFeature(self, featureName, featureType) - self.currentFeature = featureName - - def onGenType(self, typeXml, name, alias): - VulkanWrapperGenerator.onGenType(self, typeXml, name, alias) - - if name in self.knownDefs: - return - - category = self.typeInfo.categoryOf(name) - - if category in ["struct", "union"] and alias: - self.module.appendHeader( - self.cgenHeader.makeFuncAlias(API_PREFIX_MARSHAL + name, - API_PREFIX_MARSHAL + alias)) - self.module.appendHeader( - self.cgenHeader.makeFuncAlias(API_PREFIX_UNMARSHAL + name, - API_PREFIX_UNMARSHAL + alias)) - - if category in ["struct", "union"] and not alias: - - structInfo = self.typeInfo.structs[name] - - marshalParams = self.marshalingParams + \ - [makeVulkanTypeSimple(True, name, 1, MARSHAL_INPUT_VAR_NAME)] - - freeParams = [] - letParams = [] - - for (envname, bindingInfo) in list(sorted(structInfo.environment.items(), key = lambda kv: kv[0])): - if None == bindingInfo["binding"]: - freeParams.append(makeVulkanTypeSimple(True, bindingInfo["type"], 0, envname)) - else: - if not bindingInfo["structmember"]: - letParams.append(makeVulkanTypeSimple(True, bindingInfo["type"], 0, envname)) - - marshalPrototype = \ - VulkanAPI(API_PREFIX_MARSHAL + name, - STREAM_RET_TYPE, - marshalParams + freeParams) - - marshalPrototypeNoFilter = \ - VulkanAPI(API_PREFIX_MARSHAL + name, - STREAM_RET_TYPE, - marshalParams) - - def structMarshalingCustom(cgen): - self.writeCodegen.cgen = cgen - self.writeCodegen.currentStructInfo = structInfo - self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME) - - marshalingCode = \ - CUSTOM_MARSHAL_TYPES[name]["common"] + \ - CUSTOM_MARSHAL_TYPES[name]["marshaling"].format( - streamVarName=self.writeCodegen.streamVarName, - rootTypeVarName=self.writeCodegen.rootTypeVarName, - inputVarName=self.writeCodegen.inputVarName, - newInputVarName=self.writeCodegen.inputVarName + "_new") - for line in marshalingCode.split('\n'): - cgen.line(line) - - def structMarshalingDef(cgen): - self.writeCodegen.cgen = cgen - self.writeCodegen.currentStructInfo = structInfo - self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME) - - if category == "struct": - # marshal 'let' parameters first - for letp in letParams: - self.writeCodegen.streamLetParameter(self.typeInfo, letp) - - for member in structInfo.members: - iterateVulkanType(self.typeInfo, member, self.writeCodegen) - if category == "union": - iterateVulkanType(self.typeInfo, structInfo.members[0], self.writeCodegen) - - def structMarshalingDefNoFilter(cgen): - self.writeCodegen.cgen = cgen - self.writeCodegen.currentStructInfo = structInfo - self.writeCodegen.doFiltering = False - self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME) - - if category == "struct": - # marshal 'let' parameters first - for letp in letParams: - self.writeCodegen.streamLetParameter(self.typeInfo, letp) - - for member in structInfo.members: - iterateVulkanType(self.typeInfo, member, self.writeCodegen) - if category == "union": - iterateVulkanType(self.typeInfo, structInfo.members[0], self.writeCodegen) - self.writeCodegen.doFiltering = True - - self.module.appendHeader( - self.cgenHeader.makeFuncDecl(marshalPrototype)) - - if name in CUSTOM_MARSHAL_TYPES: - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - marshalPrototype, structMarshalingCustom)) - else: - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - marshalPrototype, structMarshalingDef)) - - if freeParams != []: - self.module.appendHeader( - self.cgenHeader.makeFuncDecl(marshalPrototypeNoFilter)) - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - marshalPrototypeNoFilter, structMarshalingDefNoFilter)) - - unmarshalPrototype = \ - VulkanAPI(API_PREFIX_UNMARSHAL + name, - STREAM_RET_TYPE, - self.marshalingParams + [makeVulkanTypeSimple(False, name, 1, UNMARSHAL_INPUT_VAR_NAME)] + freeParams) - - unmarshalPrototypeNoFilter = \ - VulkanAPI(API_PREFIX_UNMARSHAL + name, - STREAM_RET_TYPE, - self.marshalingParams + [makeVulkanTypeSimple(False, name, 1, UNMARSHAL_INPUT_VAR_NAME)]) - - def structUnmarshalingCustom(cgen): - self.readCodegen.cgen = cgen - self.readCodegen.currentStructInfo = structInfo - self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME) - - unmarshalingCode = \ - CUSTOM_MARSHAL_TYPES[name]["common"] + \ - CUSTOM_MARSHAL_TYPES[name]["unmarshaling"].format( - streamVarName=self.readCodegen.streamVarName, - rootTypeVarName=self.readCodegen.rootTypeVarName, - inputVarName=self.readCodegen.inputVarName, - newInputVarName=self.readCodegen.inputVarName + "_new") - for line in unmarshalingCode.split('\n'): - cgen.line(line) - - def structUnmarshalingDef(cgen): - self.readCodegen.cgen = cgen - self.readCodegen.currentStructInfo = structInfo - self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME) - - if category == "struct": - # unmarshal 'let' parameters first - for letp in letParams: - self.readCodegen.streamLetParameter(self.typeInfo, letp) - - for member in structInfo.members: - iterateVulkanType(self.typeInfo, member, self.readCodegen) - if category == "union": - iterateVulkanType(self.typeInfo, structInfo.members[0], self.readCodegen) - - def structUnmarshalingDefNoFilter(cgen): - self.readCodegen.cgen = cgen - self.readCodegen.currentStructInfo = structInfo - self.readCodegen.doFiltering = False - self.writeCodegen.cgen.stmt("(void)%s" % ROOT_TYPE_VAR_NAME) - - if category == "struct": - # unmarshal 'let' parameters first - for letp in letParams: - iterateVulkanType(self.typeInfo, letp, self.readCodegen) - for member in structInfo.members: - iterateVulkanType(self.typeInfo, member, self.readCodegen) - if category == "union": - iterateVulkanType(self.typeInfo, structInfo.members[0], self.readCodegen) - self.readCodegen.doFiltering = True - - self.module.appendHeader( - self.cgenHeader.makeFuncDecl(unmarshalPrototype)) - - if name in CUSTOM_MARSHAL_TYPES: - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - unmarshalPrototype, structUnmarshalingCustom)) - else: - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - unmarshalPrototype, structUnmarshalingDef)) - - if freeParams != []: - self.module.appendHeader( - self.cgenHeader.makeFuncDecl(unmarshalPrototypeNoFilter)) - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - unmarshalPrototypeNoFilter, structUnmarshalingDefNoFilter)) - - def onGenCmd(self, cmdinfo, name, alias): - VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias) - if name in KNOWN_FUNCTION_OPCODES: - opcode = KNOWN_FUNCTION_OPCODES[name] - else: - hashCode = hashlib.sha256(name.encode()).hexdigest()[:8] - hashInt = int(hashCode, 16) - opcode = self.beginOpcode + hashInt % (self.endOpcode - self.beginOpcode) - hasHashCollision = False - while opcode in self.knownOpcodes: - hasHashCollision = True - opcode += 1 - if hasHashCollision: - print("Hash collision occurred on function '{}'. " - "Please add the following line to marshalingdefs.py:".format(name), file=sys.stderr) - print("----------------------", file=sys.stderr) - print(" \"{}\": {},".format(name, opcode), file=sys.stderr) - print("----------------------", file=sys.stderr) - - self.module.appendHeader( - "#define OP_%s %d\n" % (name, opcode)) - self.apiOpcodes[name] = (opcode, self.currentFeature) - self.knownOpcodes.add(opcode) - - def doExtensionStructMarshalingCodegen(self, cgen, retType, extParam, forEach, funcproto, direction): - accessVar = "structAccess" - sizeVar = "currExtSize" - cgen.stmt("VkInstanceCreateInfo* %s = (VkInstanceCreateInfo*)(%s)" % (accessVar, extParam.paramName)) - cgen.stmt("size_t %s = %s(%s->getFeatureBits(), %s, %s)" % (sizeVar, - EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME, VULKAN_STREAM_VAR_NAME, ROOT_TYPE_VAR_NAME, extParam.paramName)) - - cgen.beginIf("!%s && %s" % (sizeVar, extParam.paramName)) - - cgen.line("// unknown struct extension; skip and call on its pNext field"); - cgen.funcCall(None, funcproto.name, [ - "vkStream", ROOT_TYPE_VAR_NAME, "(void*)%s->pNext" % accessVar]) - cgen.stmt("return") - - cgen.endIf() - cgen.beginElse() - - cgen.line("// known or null extension struct") - - if direction == "write": - cgen.stmt("vkStream->putBe32(%s)" % sizeVar) - elif not self.dynAlloc: - cgen.stmt("vkStream->getBe32()"); - - cgen.beginIf("!%s" % (sizeVar)) - cgen.line("// exit if this was a null extension struct (size == 0 in this branch)") - cgen.stmt("return") - cgen.endIf() - - cgen.endIf() - - # Now we can do stream stuff - if direction == "write": - cgen.stmt("vkStream->write(%s, sizeof(VkStructureType))" % extParam.paramName) - elif not self.dynAlloc: - cgen.stmt("uint64_t pNext_placeholder") - placeholderAccess = "(&pNext_placeholder)" - cgen.stmt("vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType))") - cgen.stmt("(void)pNext_placeholder") - - def fatalDefault(cgen): - cgen.line("// fatal; the switch is only taken if the extension struct is known"); - cgen.stmt("abort()") - pass - - self.emitForEachStructExtension( - cgen, - retType, - extParam, - forEach, - defaultEmit=fatalDefault, - rootTypeVar=ROOT_TYPE_PARAM) - - def onEnd(self,): - VulkanWrapperGenerator.onEnd(self) - - def forEachExtensionMarshal(ext, castedAccess, cgen): - cgen.funcCall(None, API_PREFIX_MARSHAL + ext.name, - [VULKAN_STREAM_VAR_NAME, ROOT_TYPE_VAR_NAME, castedAccess]) - - def forEachExtensionUnmarshal(ext, castedAccess, cgen): - cgen.funcCall(None, API_PREFIX_UNMARSHAL + ext.name, - [VULKAN_STREAM_VAR_NAME, ROOT_TYPE_VAR_NAME, castedAccess]) - - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - self.extensionMarshalPrototype, - lambda cgen: self.doExtensionStructMarshalingCodegen( - cgen, - STREAM_RET_TYPE, - STRUCT_EXTENSION_PARAM, - forEachExtensionMarshal, - self.extensionMarshalPrototype, - "write"))) - - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - self.extensionUnmarshalPrototype, - lambda cgen: self.doExtensionStructMarshalingCodegen( - cgen, - STREAM_RET_TYPE, - STRUCT_EXTENSION_PARAM_FOR_WRITE, - forEachExtensionUnmarshal, - self.extensionUnmarshalPrototype, - "read"))) - - opcode2stringPrototype = \ - VulkanAPI("api_opcode_to_string", - makeVulkanTypeSimple(True, "char", 1, "none"), - [ makeVulkanTypeSimple(True, "uint32_t", 0, "opcode") ]) - - self.module.appendHeader( - self.cgenHeader.makeFuncDecl(opcode2stringPrototype)) - - def emitOpcode2StringImpl(apiOpcodes, cgen): - cgen.line("switch(opcode)") - cgen.beginBlock() - - currFeature = None - - for (name, (opcodeNum, feature)) in sorted(apiOpcodes.items(), key = lambda x : x[1][0]): - if not currFeature: - cgen.leftline("#ifdef %s" % feature) - currFeature = feature - - if currFeature and feature != currFeature: - cgen.leftline("#endif") - cgen.leftline("#ifdef %s" % feature) - currFeature = feature - - cgen.line("case OP_%s:" % name) - cgen.beginBlock() - cgen.stmt("return \"OP_%s\"" % name) - cgen.endBlock() - - if currFeature: - cgen.leftline("#endif") - - cgen.line("default:") - cgen.beginBlock() - cgen.stmt("return \"OP_UNKNOWN_API_CALL\"") - cgen.endBlock() - - cgen.endBlock() - - self.module.appendImpl( - self.cgenImpl.makeFuncImpl( - opcode2stringPrototype, - lambda cgen: emitOpcode2StringImpl(self.apiOpcodes, cgen))) - - self.module.appendHeader( - "#define OP_vkFirst_old %d\n" % (self.beginOpcodeOld)) - self.module.appendHeader( - "#define OP_vkLast_old %d\n" % (self.endOpcodeOld)) - self.module.appendHeader( - "#define OP_vkFirst %d\n" % (self.beginOpcode)) - self.module.appendHeader( - "#define OP_vkLast %d\n" % (self.endOpcode)) |