blob: d8df778075f3a09d0a28ed73ba9831bd778d726c [file] [log] [blame]
# 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
from .common.codegen import CodeGen
from .common.vulkantypes import \
VulkanAPI, makeVulkanTypeSimple, iterateVulkanType, VulkanTypeIterator, Atom, FuncExpr, FuncExprVal, FuncLambda
from .wrapperdefs import VulkanWrapperGenerator
from .wrapperdefs import ROOT_TYPE_VAR_NAME, ROOT_TYPE_PARAM
from .wrapperdefs import STRUCT_EXTENSION_PARAM, STRUCT_EXTENSION_PARAM_FOR_WRITE, EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME
class VulkanCountingCodegen(VulkanTypeIterator):
def __init__(self, cgen, featureBitsVar, toCountVar, countVar, rootTypeVar, prefix, forApiOutput=False, mapHandles=True, handleMapOverwrites=False, doFiltering=True):
self.cgen = cgen
self.featureBitsVar = featureBitsVar
self.toCountVar = toCountVar
self.rootTypeVar = rootTypeVar
self.countVar = countVar
self.prefix = prefix
self.forApiOutput = forApiOutput
self.exprAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.toCountVar, asPtr = True)
self.exprValueAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.toCountVar, asPtr = False)
self.exprPrimitiveValueAccessor = lambda t: self.cgen.generalAccess(t, parentVarName = self.toCountVar, asPtr = False)
self.lenAccessor = lambda t: self.cgen.generalLengthAccess(t, parentVarName = self.toCountVar)
self.lenAccessorGuard = lambda t: self.cgen.generalLengthAccessGuard(t, parentVarName = self.toCountVar)
self.filterVarAccessor = lambda t: self.cgen.filterVarAccess(t, parentVarName = self.toCountVar)
self.checked = False
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()
return res
def makeCastExpr(self, vulkanType):
return "(%s)" % (
self.cgen.makeCTypeDecl(vulkanType, useParamName=False))
def genCount(self, sizeExpr):
self.cgen.stmt("*%s += %s" % (self.countVar, sizeExpr))
def genPrimitiveStreamCall(self, vulkanType):
self.genCount(str(self.cgen.countPrimitive(
self.typeInfo,
vulkanType)))
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.handleMapOverwrites:
# self.cgen.stmt(
# "static_assert(8 == sizeof(%s), \"handle map overwrite requres %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.genCount("8 * %s" % lenAccess)
else:
# self.cgen.stmt(
# "%s->handleMapping()->mapHandles_%s_u64(%s, %s, %s)" %
# (self.streamVarName, vulkanType.typeName,
# access,
# handle64VarAccess, lenAccess))
self.genCount(handle64Bytes)
if lenAccess != "1":
self.cgen.endIf()
def doAllocSpace(self, vulkanType):
pass
def getOptionalStringFeatureExpr(self, vulkanType):
if vulkanType.optionalStr is not None:
if vulkanType.optionalStr.startswith("streamFeature:"):
splitted = vulkanType.optionalStr.split(":")
featureExpr = "%s & %s" % (self.featureBitsVar, 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")
checkAccess = self.exprAccessor(vulkanType)
addrExpr = "&" + checkAccess
sizeExpr = self.cgen.sizeofExpr(vulkanType)
if featureExpr is not None:
self.cgen.beginIf(featureExpr)
self.genPrimitiveStreamCall(
vulkanType)
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 & VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT" % self.featureBitsVar)
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 "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 & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT" % self.featureBitsVar
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.featureBitsVar,
self.rootTypeVar, accessWithCast, self.countVar]
for (bindName, localName) in vulkanType.binds.items():
callParams.append(self.getEnvAccessExpr(localName))
self.cgen.funcCall(None, self.prefix + vulkanType.typeName,
callParams)
if lenAccess is not None:
self.cgen.endFor()
if lenAccessGuard is not None:
self.cgen.endIf()
self.endFilterGuard(vulkanType)
def onString(self, vulkanType):
access = self.exprAccessor(vulkanType)
self.genCount("sizeof(uint32_t) + (%s ? strlen(%s) : 0)" % (access, access))
def onStringArray(self, vulkanType):
access = self.exprAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
lenAccessGuard = self.lenAccessorGuard(vulkanType)
self.genCount("sizeof(uint32_t)")
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
self.cgen.beginFor("uint32_t i = 0", "i < %s" % lenAccess, "++i")
self.cgen.stmt("size_t l = %s[i] ? strlen(%s[i]) : 0" % (access, access))
self.genCount("sizeof(uint32_t) + (%s[i] ? strlen(%s[i]) : 0)" % (access, access))
self.cgen.endFor()
if lenAccessGuard is not None:
self.cgen.endIf()
def onStaticArr(self, vulkanType):
access = self.exprValueAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
lenAccessGuard = self.lenAccessorGuard(vulkanType)
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
finalLenExpr = "%s * %s" % (lenAccess, self.cgen.sizeofExpr(vulkanType))
if lenAccessGuard is not None:
self.cgen.endIf()
self.genCount(finalLenExpr)
def onStructExtension(self, vulkanType):
sTypeParam = copy(vulkanType)
sTypeParam.paramName = "sType"
access = self.exprAccessor(vulkanType)
sizeVar = "%s_size" % vulkanType.paramName
castedAccessExpr = access
sTypeAccess = self.exprAccessor(sTypeParam)
self.cgen.beginIf("%s == VK_STRUCTURE_TYPE_MAX_ENUM" %
self.rootTypeVar)
self.cgen.stmt("%s = %s" % (self.rootTypeVar, sTypeAccess))
self.cgen.endIf()
self.cgen.funcCall(None, self.prefix + "extension_struct",
[self.featureBitsVar, self.rootTypeVar, castedAccessExpr, self.countVar])
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())
self.cgen.endFor()
if lenAccessGuard is not None:
self.cgen.endIf()
else:
self.genPrimitiveStreamCall(vulkanType.getForValueAccess())
else:
if lenAccess is not None:
needLenAccessGuard = True
finalLenExpr = "%s * %s" % (
lenAccess, self.cgen.sizeofExpr(vulkanType.getForValueAccess()))
else:
needLenAccessGuard = False
finalLenExpr = "%s" % (
self.cgen.sizeofExpr(vulkanType.getForValueAccess()))
if needLenAccessGuard and lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
self.genCount(finalLenExpr)
if needLenAccessGuard and lenAccessGuard is not None:
self.cgen.endIf()
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)
else:
access = self.exprAccessor(vulkanType)
self.genCount(self.cgen.sizeofExpr(vulkanType))
self.endFilterGuard(vulkanType)
def streamLetParameter(self, structInfo, letParamInfo):
filterFeature = "%s & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT" % (self.featureBitsVar)
self.cgen.stmt("%s %s = 1" % (letParamInfo.typeName, letParamInfo.paramName))
self.cgen.beginIf(filterFeature)
bodyExpr = self.currentStructInfo.environment[letParamInfo.paramName]["body"]
self.cgen.stmt("%s = %s" % (letParamInfo.paramName, self.genFilterFunc(bodyExpr, self.currentStructInfo.environment)))
self.genPrimitiveStreamCall(letParamInfo)
self.cgen.endIf()
class VulkanCounting(VulkanWrapperGenerator):
def __init__(self, module, typeInfo):
VulkanWrapperGenerator.__init__(self, module, typeInfo)
self.codegen = CodeGen()
self.featureBitsVar = "featureBits"
self.featureBitsVarType = makeVulkanTypeSimple(False, "uint32_t", 0, self.featureBitsVar)
self.countingPrefix = "count_"
self.countVars = ["toCount", "count"]
self.countVarType = makeVulkanTypeSimple(False, "size_t", 1, self.countVars[1])
self.voidType = makeVulkanTypeSimple(False, "void", 0)
self.rootTypeVar = ROOT_TYPE_VAR_NAME
self.countingCodegen = \
VulkanCountingCodegen(
self.codegen,
self.featureBitsVar,
self.countVars[0],
self.countVars[1],
self.rootTypeVar,
self.countingPrefix)
self.knownDefs = {}
self.extensionCountingPrototype = \
VulkanAPI(self.countingPrefix + "extension_struct",
self.voidType,
[self.featureBitsVarType,
ROOT_TYPE_PARAM,
STRUCT_EXTENSION_PARAM,
self.countVarType])
def onBegin(self,):
VulkanWrapperGenerator.onBegin(self)
self.module.appendImpl(self.codegen.makeFuncDecl(
self.extensionCountingPrototype))
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:
# TODO(liyl): might not work if freeParams != []
self.module.appendHeader(
self.codegen.makeFuncAlias(self.countingPrefix + name,
self.countingPrefix + alias))
if category in ["struct", "union"] and not alias:
structInfo = self.typeInfo.structs[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))
typeFromName = \
lambda varname: \
makeVulkanTypeSimple(True, name, 1, varname)
countingParams = \
[makeVulkanTypeSimple(False, "uint32_t", 0, self.featureBitsVar),
ROOT_TYPE_PARAM,
typeFromName(self.countVars[0]),
makeVulkanTypeSimple(False, "size_t", 1, self.countVars[1])]
countingPrototype = \
VulkanAPI(self.countingPrefix + name,
self.voidType,
countingParams + freeParams)
countingPrototypeNoFilter = \
VulkanAPI(self.countingPrefix + name,
self.voidType,
countingParams)
def structCountingDef(cgen):
self.countingCodegen.cgen = cgen
self.countingCodegen.currentStructInfo = structInfo
cgen.stmt("(void)%s" % self.featureBitsVar);
cgen.stmt("(void)%s" % self.rootTypeVar);
cgen.stmt("(void)%s" % self.countVars[0]);
cgen.stmt("(void)%s" % self.countVars[1]);
if category == "struct":
# marshal 'let' parameters first
for letp in letParams:
self.countingCodegen.streamLetParameter(self.typeInfo, letp)
for member in structInfo.members:
iterateVulkanType(self.typeInfo, member, self.countingCodegen)
if category == "union":
iterateVulkanType(self.typeInfo, structInfo.members[0], self.countingCodegen)
def structCountingDefNoFilter(cgen):
self.countingCodegen.cgen = cgen
self.countingCodegen.currentStructInfo = structInfo
self.countingCodegen.doFiltering = False
cgen.stmt("(void)%s" % self.featureBitsVar);
cgen.stmt("(void)%s" % self.rootTypeVar);
cgen.stmt("(void)%s" % self.countVars[0]);
cgen.stmt("(void)%s" % self.countVars[1]);
if category == "struct":
# marshal 'let' parameters first
for letp in letParams:
self.countingCodegen.streamLetParameter(self.typeInfo, letp)
for member in structInfo.members:
iterateVulkanType(self.typeInfo, member, self.countingCodegen)
if category == "union":
iterateVulkanType(self.typeInfo, structInfo.members[0], self.countingCodegen)
self.countingCodegen.doFiltering = True
self.module.appendHeader(
self.codegen.makeFuncDecl(countingPrototype))
self.module.appendImpl(
self.codegen.makeFuncImpl(countingPrototype, structCountingDef))
if freeParams != []:
self.module.appendHeader(
self.cgenHeader.makeFuncDecl(countingPrototypeNoFilter))
self.module.appendImpl(
self.cgenImpl.makeFuncImpl(
countingPrototypeNoFilter, structCountingDefNoFilter))
def onGenCmd(self, cmdinfo, name, alias):
VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias)
def doExtensionStructCountCodegen(self, cgen, extParam, forEach, funcproto):
accessVar = "structAccess"
sizeVar = "currExtSize"
cgen.stmt("VkInstanceCreateInfo* %s = (VkInstanceCreateInfo*)(%s)" % (accessVar, extParam.paramName))
cgen.stmt("size_t %s = %s(%s, %s, %s)" % (sizeVar, EXTENSION_SIZE_WITH_STREAM_FEATURES_API_NAME,
self.featureBitsVar, 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, [
self.featureBitsVar, ROOT_TYPE_VAR_NAME, "(void*)%s->pNext" % accessVar, self.countVars[1]])
cgen.stmt("return")
cgen.endIf()
cgen.beginElse()
cgen.line("// known or null extension struct")
cgen.stmt("*%s += sizeof(uint32_t)" % self.countVars[1])
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()
cgen.stmt("*%s += sizeof(VkStructureType)" % self.countVars[1])
def fatalDefault(cgen):
cgen.line("// fatal; the switch is only taken if the extension struct is known");
cgen.stmt("abort()")
pass
self.emitForEachStructExtension(
cgen,
makeVulkanTypeSimple(False, "void", 0, "void"),
extParam,
forEach,
defaultEmit=fatalDefault,
rootTypeVar=ROOT_TYPE_PARAM)
def onEnd(self,):
VulkanWrapperGenerator.onEnd(self)
def forEachExtensionCounting(ext, castedAccess, cgen):
cgen.funcCall(None, self.countingPrefix + ext.name,
[self.featureBitsVar, self.rootTypeVar, castedAccess, self.countVars[1]])
self.module.appendImpl(
self.codegen.makeFuncImpl(
self.extensionCountingPrototype,
lambda cgen: self.doExtensionStructCountCodegen(
cgen,
STRUCT_EXTENSION_PARAM,
forEachExtensionCounting,
self.extensionCountingPrototype)))