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