• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from .common.codegen import CodeGen, VulkanWrapperGenerator, VulkanAPIWrapper
2from .common.vulkantypes import \
3        VulkanAPI, makeVulkanTypeSimple, iterateVulkanType, DISPATCHABLE_HANDLE_TYPES, NON_DISPATCHABLE_HANDLE_TYPES
4
5from .transform import TransformCodegen, genTransformsForVulkanType
6
7from .wrapperdefs import API_PREFIX_MARSHAL
8from .wrapperdefs import API_PREFIX_UNMARSHAL
9from .wrapperdefs import VULKAN_STREAM_TYPE
10
11from copy import copy
12
13decoder_snapshot_decl_preamble = """
14
15namespace android {
16namespace base {
17class BumpPool;
18class Stream;
19} // namespace base {
20} // namespace android {
21
22class VkDecoderSnapshot {
23public:
24    VkDecoderSnapshot();
25    ~VkDecoderSnapshot();
26
27    void save(android::base::Stream* stream);
28    void load(android::base::Stream* stream, emugl::GfxApiLogger& gfx_logger,
29              emugl::HealthMonitor<>* healthMonitor);
30"""
31
32decoder_snapshot_decl_postamble = """
33private:
34    class Impl;
35    std::unique_ptr<Impl> mImpl;
36
37};
38"""
39
40decoder_snapshot_impl_preamble ="""
41
42using namespace gfxstream::vk;
43using emugl::GfxApiLogger;
44using emugl::HealthMonitor;
45
46class VkDecoderSnapshot::Impl {
47public:
48    Impl() { }
49
50    void save(android::base::Stream* stream) {
51        mReconstruction.save(stream);
52    }
53
54    void load(android::base::Stream* stream, GfxApiLogger& gfx_logger,
55              HealthMonitor<>* healthMonitor) {
56        mReconstruction.load(stream, gfx_logger, healthMonitor);
57    }
58
59"""
60
61decoder_snapshot_impl_postamble = """
62private:
63    android::base::Lock mLock;
64    VkReconstruction mReconstruction;
65};
66
67VkDecoderSnapshot::VkDecoderSnapshot() :
68    mImpl(new VkDecoderSnapshot::Impl()) { }
69
70void VkDecoderSnapshot::save(android::base::Stream* stream) {
71    mImpl->save(stream);
72}
73
74void VkDecoderSnapshot::load(android::base::Stream* stream, GfxApiLogger& gfx_logger,
75                             HealthMonitor<>* healthMonitor) {
76    mImpl->load(stream, gfx_logger, healthMonitor);
77}
78
79VkDecoderSnapshot::~VkDecoderSnapshot() = default;
80"""
81
82AUXILIARY_SNAPSHOT_API_BASE_PARAM_COUNT = 3
83
84AUXILIARY_SNAPSHOT_API_PARAM_NAMES = [
85    "input_result",
86]
87
88# Vulkan handle dependencies.
89# (a, b): a depends on b
90SNAPSHOT_HANDLE_DEPENDENCIES = [
91    # Dispatchable handle types
92    ("VkCommandBuffer", "VkCommandPool"),
93    ("VkCommandPool", "VkDevice"),
94    ("VkQueue", "VkDevice"),
95    ("VkDevice", "VkPhysicalDevice"),
96    ("VkPhysicalDevice", "VkInstance")] + \
97    list(map(lambda handleType : (handleType, "VkDevice"), NON_DISPATCHABLE_HANDLE_TYPES))
98
99handleDependenciesDict = dict(SNAPSHOT_HANDLE_DEPENDENCIES)
100
101def extract_deps_vkAllocateCommandBuffers(param, access, lenExpr, api, cgen):
102    cgen.stmt("mReconstruction.addHandleDependency((const uint64_t*)%s, %s, (uint64_t)(uintptr_t)%s)" % \
103              (access, lenExpr, "unboxed_to_boxed_non_dispatchable_VkCommandPool(pAllocateInfo->commandPool)"))
104
105specialCaseDependencyExtractors = {
106    "vkAllocateCommandBuffers" : extract_deps_vkAllocateCommandBuffers,
107}
108
109apiSequences = {
110    "vkAllocateMemory" : ["vkAllocateMemory", "vkMapMemoryIntoAddressSpaceGOOGLE"]
111}
112
113apiModifies = {
114    "vkMapMemoryIntoAddressSpaceGOOGLE" : ["memory"],
115}
116
117def is_modify_operation(api, param):
118    if api.name in apiModifies:
119        if param.paramName in apiModifies[api.name]:
120            return True
121    return False
122
123def emit_impl(typeInfo, api, cgen):
124
125    cgen.line("// TODO: Implement")
126
127    for p in api.parameters:
128        if not (p.isHandleType):
129            continue
130
131        lenExpr = cgen.generalLengthAccess(p)
132        lenAccessGuard = cgen.generalLengthAccessGuard(p)
133
134        if lenExpr is None:
135            lenExpr = "1"
136
137        if p.pointerIndirectionLevels > 0:
138            access = p.paramName
139        else:
140            access = "(&%s)" % p.paramName
141
142        if p.isCreatedBy(api):
143            cgen.stmt("android::base::AutoLock lock(mLock)")
144            cgen.line("// %s create" % p.paramName)
145            cgen.stmt("mReconstruction.addHandles((const uint64_t*)%s, %s)" % (access, lenExpr));
146
147            if p.typeName in handleDependenciesDict:
148                dependsOnType = handleDependenciesDict[p.typeName];
149                for p2 in api.parameters:
150                    if p2.typeName == dependsOnType:
151                        cgen.stmt("mReconstruction.addHandleDependency((const uint64_t*)%s, %s, (uint64_t)(uintptr_t)%s)" % (access, lenExpr, p2.paramName))
152                if api.name in specialCaseDependencyExtractors:
153                    specialCaseDependencyExtractors[api.name](p, access, lenExpr, api, cgen)
154
155            cgen.stmt("if (!%s) return" % access)
156            cgen.stmt("auto apiHandle = mReconstruction.createApiInfo()")
157            cgen.stmt("auto apiInfo = mReconstruction.getApiInfo(apiHandle)")
158            cgen.stmt("mReconstruction.setApiTrace(apiInfo, OP_%s, snapshotTraceBegin, snapshotTraceBytes)" % api.name)
159            if lenAccessGuard is not None:
160                cgen.beginIf(lenAccessGuard)
161            cgen.stmt("mReconstruction.forEachHandleAddApi((const uint64_t*)%s, %s, apiHandle)" % (access, lenExpr))
162            cgen.stmt("mReconstruction.setCreatedHandlesForApi(apiHandle, (const uint64_t*)%s, %s)" % (access, lenExpr))
163            if lenAccessGuard is not None:
164                cgen.endIf()
165
166        if p.isDestroyedBy(api):
167            cgen.stmt("android::base::AutoLock lock(mLock)")
168            cgen.line("// %s destroy" % p.paramName)
169            if lenAccessGuard is not None:
170                cgen.beginIf(lenAccessGuard)
171            cgen.stmt("mReconstruction.removeHandles((const uint64_t*)%s, %s)" % (access, lenExpr));
172            if lenAccessGuard is not None:
173                cgen.endIf()
174
175        if is_modify_operation(api, p):
176            cgen.stmt("android::base::AutoLock lock(mLock)")
177            cgen.line("// %s modify" % p.paramName)
178            cgen.stmt("auto apiHandle = mReconstruction.createApiInfo()")
179            cgen.stmt("auto apiInfo = mReconstruction.getApiInfo(apiHandle)")
180            cgen.stmt("mReconstruction.setApiTrace(apiInfo, OP_%s, snapshotTraceBegin, snapshotTraceBytes)" % api.name)
181            if lenAccessGuard is not None:
182                cgen.beginIf(lenAccessGuard)
183            cgen.beginFor("uint32_t i = 0", "i < %s" % lenExpr, "++i")
184            if p.isNonDispatchableHandleType():
185                cgen.stmt("%s boxed = unboxed_to_boxed_non_dispatchable_%s(%s[i])" % (p.typeName, p.typeName, access))
186            else:
187                cgen.stmt("%s boxed = unboxed_to_boxed_%s(%s[i])" % (p.typeName, p.typeName, access))
188            cgen.stmt("mReconstruction.forEachHandleAddModifyApi((const uint64_t*)(&boxed), 1, apiHandle)")
189            cgen.endFor()
190            if lenAccessGuard is not None:
191                cgen.endIf()
192
193def emit_passthrough_to_impl(typeInfo, api, cgen):
194    cgen.vkApiCall(api, customPrefix = "mImpl->")
195
196class VulkanDecoderSnapshot(VulkanWrapperGenerator):
197    def __init__(self, module, typeInfo):
198        VulkanWrapperGenerator.__init__(self, module, typeInfo)
199
200        self.typeInfo = typeInfo
201
202        self.cgenHeader = CodeGen()
203        self.cgenHeader.incrIndent()
204
205        self.cgenImpl = CodeGen()
206
207        self.currentFeature = None
208
209        self.feature_apis = []
210
211    def onBegin(self,):
212        self.module.appendHeader(decoder_snapshot_decl_preamble)
213        self.module.appendImpl(decoder_snapshot_impl_preamble)
214
215    def onBeginFeature(self, featureName, featureType):
216        VulkanWrapperGenerator.onBeginFeature(self, featureName, featureType)
217        self.currentFeature = featureName
218
219    def onGenCmd(self, cmdinfo, name, alias):
220        VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias)
221
222        api = self.typeInfo.apis[name]
223
224        additionalParams = [ \
225            makeVulkanTypeSimple(True, "uint8_t", 1, "snapshotTraceBegin"),
226            makeVulkanTypeSimple(False, "size_t", 0, "snapshotTraceBytes"),
227            makeVulkanTypeSimple(False, "android::base::BumpPool", 1, "pool"),]
228
229        if api.retType.typeName != "void":
230            additionalParams.append( \
231                makeVulkanTypeSimple(False, api.retType.typeName, 0, "input_result"))
232
233        apiForSnapshot = \
234            api.withCustomParameters( \
235                additionalParams + \
236                api.parameters).withCustomReturnType( \
237                    makeVulkanTypeSimple(False, "void", 0, "void"))
238
239        self.feature_apis.append((self.currentFeature, apiForSnapshot))
240
241        self.cgenHeader.stmt(self.cgenHeader.makeFuncProto(apiForSnapshot))
242        self.module.appendHeader(self.cgenHeader.swapCode())
243
244        self.cgenImpl.emitFuncImpl( \
245            apiForSnapshot, lambda cgen: emit_impl(self.typeInfo, apiForSnapshot, cgen))
246        self.module.appendImpl(self.cgenImpl.swapCode())
247
248    def onEnd(self,):
249        self.module.appendHeader(decoder_snapshot_decl_postamble)
250        self.module.appendImpl(decoder_snapshot_impl_postamble)
251        self.cgenHeader.decrIndent()
252
253        for feature, api in self.feature_apis:
254            if feature is not None:
255                self.cgenImpl.line("#ifdef %s" % feature)
256
257            apiImplShell = \
258                api.withModifiedName("VkDecoderSnapshot::" + api.name)
259
260            self.cgenImpl.emitFuncImpl( \
261                apiImplShell, lambda cgen: emit_passthrough_to_impl(self.typeInfo, api, cgen))
262
263            if feature is not None:
264                self.cgenImpl.line("#endif")
265
266        self.module.appendImpl(self.cgenImpl.swapCode())
267
268