• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15 
16 #include "VkSnapshotApiCall.h"
17 #include "VulkanHandleMapping.h"
18 #include "VulkanHandles.h"
19 #include "aemu/base/HealthMonitor.h"
20 #include "aemu/base/files/Stream.h"
21 #include "common/goldfish_vk_marshaling.h"
22 #include "utils/GfxApiLogger.h"
23 
24 namespace gfxstream {
25 namespace vk {
26 
27 // A class that captures all important data structures for
28 // reconstructing a Vulkan system state via trimmed API record and replay.
29 class VkReconstruction {
30    public:
31     VkReconstruction();
32 
33     void clear();
34 
35     void saveReplayBuffers(android::base::Stream* stream);
36     static void loadReplayBuffers(android::base::Stream* stream,
37                                   std::vector<uint64_t>* outHandleBuffer,
38                                   std::vector<uint8_t>* outDecoderBuffer);
39 
40     enum HandleState { BEGIN = 0, CREATED = 0, BOUND_MEMORY = 1, HANDLE_STATE_COUNT };
41 
42     typedef std::pair<uint64_t, HandleState> HandleWithState;
43     struct HandleWithStateHash {
operatorHandleWithStateHash44         inline size_t operator()(const HandleWithState& v) const {
45             std::hash<uint64_t> int_hasher;
46             return int_hasher(v.first) ^ int_hasher(v.second);
47         }
48     };
49 
50     struct HandleReconstruction {
51         std::vector<VkSnapshotApiCallHandle> apiRefs;
52         std::unordered_set<HandleWithState, HandleWithStateHash> childHandles;
53         std::vector<HandleWithState> parentHandles;
54     };
55 
56     struct HandleWithStateReconstruction {
57         std::vector<HandleReconstruction> states =
58             std::vector<HandleReconstruction>(HANDLE_STATE_COUNT);
59         bool delayed_destroy = false;
60         bool destroying = false;
61     };
62 
63     using HandleWithStateReconstructions =
64         android::base::UnpackedComponentManager<32, 16, 16, HandleWithStateReconstruction>;
65 
66     struct HandleModification {
67         std::vector<VkSnapshotApiCallHandle> apiRefs;
68         uint32_t order = 0;
69     };
70 
71     using HandleModifications =
72         android::base::UnpackedComponentManager<32, 16, 16, HandleModification>;
73 
74     VkSnapshotApiCallInfo* createApiCallInfo();
75     void destroyApiCallInfo(VkSnapshotApiCallHandle handle);
76     void destroyApiCallInfoIfUnused(VkSnapshotApiCallInfo* info);
77 
78     void removeHandleFromApiInfo(VkSnapshotApiCallHandle h, uint64_t toRemove);
79 
80     VkSnapshotApiCallInfo* getApiInfo(VkSnapshotApiCallHandle h);
81 
82     void setApiTrace(VkSnapshotApiCallInfo* apiInfo, const uint8_t* traceBegin, size_t traceBytes);
83 
84     void dump();
85 
86     void addHandles(const uint64_t* toAdd, uint32_t count);
87     void removeHandles(const uint64_t* toRemove, uint32_t count, bool recursive = true);
88 
89     void forEachHandleAddApi(const uint64_t* toProcess, uint32_t count,
90                              uint64_t VkSnapshotApiCallHandle, HandleState state = CREATED);
91     void forEachHandleDeleteApi(const uint64_t* toProcess, uint32_t count);
92 
93     void addHandleDependency(const uint64_t* handles, uint32_t count, uint64_t parentHandle,
94                              HandleState childState = CREATED, HandleState parentState = CREATED);
95 
96     void setCreatedHandlesForApi(VkSnapshotApiCallHandle handle , const uint64_t* created,
97                                  uint32_t count);
98 
99     void forEachHandleAddModifyApi(const uint64_t* toProcess, uint32_t count,
100                                    VkSnapshotApiCallHandle handle);
101 
102     void forEachHandleClearModifyApi(const uint64_t* toProcess, uint32_t count);
103 
104     void setModifiedHandlesForApi(VkSnapshotApiCallHandle handle, const uint64_t* modified,
105                                   uint32_t count);
106 
107     // Used by on_vkCreateDescriptorPool.
108     //
109     // Snapshot keeps track of all the boxed handles created by each function. By default
110     // the generated code assumes no extra internal boxed handles are generated by
111     // VkDecoderGlobalState. But this is not the case for on_vkCreateDescriptorPool.
112     // Thus we add an extra API to VkReconstruction, which gives it the list of all the
113     // extra boxed handles.
114     //
115     // Implementation-wise it is a bit tricky. The regular workflow looks like:
116     //
117     // on_vkCreateDescriptorPool(... pDescriptorPool)
118     // ...
119     // mReconstruction.setCreatedHandlesForApi(OP_vkCreateDescriptorPool, pDescriptorPool);
120     //
121     // It is not easy to directly tell mReconstruction that OP_vkCreateDescriptorPool created
122     // extra handles. Instead, we add an API to VkReconstruction to cache the extra handles.
123     // Next time setCreatedHandlesForApi is called, it will check the cached handles and
124     // add them to OP_vkCreateDescriptorPool.
125     void createExtraHandlesForNextApi(const uint64_t* created, uint32_t count);
126 
127    private:
128     std::vector<uint64_t> getOrderedUniqueModifyApis() const;
129 
130     VkSnapshotApiCallManager mApiCallManager;
131 
132     HandleWithStateReconstructions mHandleReconstructions;
133     HandleModifications mHandleModifications;
134 
135     std::vector<uint8_t> mLoadedTrace;
136 };
137 
138 }  // namespace vk
139 }  // namespace gfxstream
140