blob: 6360e37e018d037273d3f4d95306256b32aee2a1 [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 .common.codegen import CodeGen
from .common.vulkantypes import \
VulkanAPI, makeVulkanTypeSimple, iterateVulkanType, VulkanTypeIterator
from .wrapperdefs import VulkanWrapperGenerator
from .wrapperdefs import STRUCT_EXTENSION_PARAM, STRUCT_EXTENSION_PARAM_FOR_WRITE
class HandleMapCodegen(VulkanTypeIterator):
def __init__(self, cgen, inputVar, handlemapVarName, prefix, isHandleFunc):
self.cgen = cgen
self.inputVar = inputVar
self.prefix = prefix
self.handlemapVarName = handlemapVarName
def makeAccess(varName, asPtr = True):
return lambda t: self.cgen.generalAccess(t, parentVarName = varName, asPtr = asPtr)
def makeLengthAccess(varName):
return lambda t: self.cgen.generalLengthAccess(t, parentVarName = varName)
def makeLengthAccessGuard(varName):
return lambda t: self.cgen.generalLengthAccessGuard(t, parentVarName=varName)
self.exprAccessor = makeAccess(self.inputVar)
self.exprAccessorValue = makeAccess(self.inputVar, asPtr = False)
self.lenAccessor = makeLengthAccess(self.inputVar)
self.lenAccessorGuard = makeLengthAccessGuard(self.inputVar)
self.checked = False
self.isHandleFunc = isHandleFunc
def needSkip(self, vulkanType):
return False
def makeCastExpr(self, vulkanType):
return "(%s)" % (
self.cgen.makeCTypeDecl(vulkanType, useParamName=False))
def asNonConstCast(self, access, vulkanType):
if vulkanType.staticArrExpr:
casted = "%s(%s)" % (self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()), access)
elif vulkanType.accessibleAsPointer():
casted = "%s(%s)" % (self.makeCastExpr(vulkanType.getForNonConstAccess()), access)
else:
casted = "%s(%s)" % (self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()), access)
return casted
def onCheck(self, vulkanType):
pass
def endCheck(self, vulkanType):
pass
def onCompoundType(self, vulkanType):
if self.needSkip(vulkanType):
self.cgen.line("// TODO: Unsupported : %s" %
self.cgen.makeCTypeDecl(vulkanType))
return
access = self.exprAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
lenAccessGuard = self.lenAccessorGuard(vulkanType)
isPtr = vulkanType.pointerIndirectionLevels > 0
if lenAccessGuard is not None:
self.cgen.beginIf(lenAccessGuard)
if isPtr:
self.cgen.beginIf(access)
if lenAccess is not None:
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)
accessCasted = self.asNonConstCast(access, vulkanType)
self.cgen.funcCall(None, self.prefix + vulkanType.typeName,
[self.handlemapVarName, accessCasted])
if lenAccess is not None:
self.cgen.endFor()
if isPtr:
self.cgen.endIf()
if lenAccessGuard is not None:
self.cgen.endIf()
def onString(self, vulkanType):
pass
def onStringArray(self, vulkanType):
pass
def onStaticArr(self, vulkanType):
if not self.isHandleFunc(vulkanType):
return
accessLhs = self.exprAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
self.cgen.stmt("%s->mapHandles_%s(%s%s, %s)" % \
(self.handlemapVarName, vulkanType.typeName,
self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()),
accessLhs, lenAccess))
def onStructExtension(self, vulkanType):
access = self.exprAccessor(vulkanType)
castedAccessExpr = "(%s)(%s)" % ("void*", access)
self.cgen.beginIf(access)
self.cgen.funcCall(None, self.prefix + "extension_struct",
[self.handlemapVarName, castedAccessExpr])
self.cgen.endIf()
def onPointer(self, vulkanType):
if self.needSkip(vulkanType):
return
if not self.isHandleFunc(vulkanType):
return
access = self.exprAccessor(vulkanType)
lenAccess = self.lenAccessor(vulkanType)
lenAccess = "1" if lenAccess is None else lenAccess
self.cgen.beginIf(access)
self.cgen.stmt( \
"%s->mapHandles_%s(%s%s, %s)" % \
(self.handlemapVarName,
vulkanType.typeName,
self.makeCastExpr(vulkanType.getForNonConstAccess()),
access,
lenAccess))
self.cgen.endIf()
def onValue(self, vulkanType):
if not self.isHandleFunc(vulkanType):
return
access = self.exprAccessor(vulkanType)
self.cgen.stmt(
"%s->mapHandles_%s(%s%s)" % \
(self.handlemapVarName, vulkanType.typeName,
self.makeCastExpr(vulkanType.getForAddressAccess().getForNonConstAccess()),
access))
class VulkanHandleMap(VulkanWrapperGenerator):
def __init__(self, module, typeInfo):
VulkanWrapperGenerator.__init__(self, module, typeInfo)
self.codegen = CodeGen()
self.handlemapPrefix = "handlemap_"
self.toMapVar = "toMap"
self.handlemapVarName = "handlemap"
self.handlemapParam = \
makeVulkanTypeSimple(False, "VulkanHandleMapping", 1,
self.handlemapVarName)
self.voidType = makeVulkanTypeSimple(False, "void", 0)
self.handlemapCodegen = \
HandleMapCodegen(
None,
self.toMapVar,
self.handlemapVarName,
self.handlemapPrefix,
lambda vtype : typeInfo.isHandleType(vtype.typeName))
self.knownDefs = {}
self.extensionHandlemapPrototype = \
VulkanAPI(self.handlemapPrefix + "extension_struct",
self.voidType,
[self.handlemapParam, STRUCT_EXTENSION_PARAM_FOR_WRITE])
def onBegin(self,):
VulkanWrapperGenerator.onBegin(self)
self.module.appendImpl(self.codegen.makeFuncDecl(
self.extensionHandlemapPrototype))
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.codegen.makeFuncAlias(self.handlemapPrefix + name,
self.handlemapPrefix + alias))
if category in ["struct", "union"] and not alias:
structInfo = self.typeInfo.structs[name]
typeFromName = \
lambda varname: \
makeVulkanTypeSimple(varname == "from", name, 1, varname)
handlemapParams = \
[self.handlemapParam] + \
list(map(typeFromName, [self.toMapVar]))
handlemapPrototype = \
VulkanAPI(self.handlemapPrefix + name,
self.voidType,
handlemapParams)
def funcDefGenerator(cgen):
self.handlemapCodegen.cgen = cgen
for p in handlemapParams:
cgen.stmt("(void)%s" % p.paramName)
for member in structInfo.members:
iterateVulkanType(self.typeInfo, member,
self.handlemapCodegen)
self.module.appendHeader(
self.codegen.makeFuncDecl(handlemapPrototype))
self.module.appendImpl(
self.codegen.makeFuncImpl(handlemapPrototype, funcDefGenerator))
def onGenCmd(self, cmdinfo, name, alias):
VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias)
def onEnd(self,):
VulkanWrapperGenerator.onEnd(self)
def forEachExtensionHandlemap(ext, castedAccess, cgen):
cgen.funcCall(None, self.handlemapPrefix + ext.name,
[self.handlemapVarName, castedAccess])
self.module.appendImpl(
self.codegen.makeFuncImpl(
self.extensionHandlemapPrototype,
lambda cgen: self.emitForEachStructExtension(
cgen,
self.voidType,
STRUCT_EXTENSION_PARAM_FOR_WRITE,
forEachExtensionHandlemap)))