• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 expresso or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <vulkan/vulkan.h>
18 
19 #include <memory>
20 #include <mutex>
21 #include <unordered_map>
22 #include <unordered_set>
23 #include <vector>
24 
25 #include "aemu/base/ThreadAnnotations.h"
26 #include "vulkan/cereal/common/goldfish_vk_dispatch.h"
27 
28 namespace gfxstream {
29 namespace vk {
30 
31 // TODO: Support VK_AMD_buffer_marker.
32 class DeviceLostHelper {
33    public:
DeviceLostHelper()34     DeviceLostHelper() : mEnabled(false) {};
35 
36     DeviceLostHelper(const DeviceLostHelper&) = delete;
37     DeviceLostHelper& operator=(const DeviceLostHelper&) = delete;
38 
39     DeviceLostHelper(DeviceLostHelper&&) = delete;
40     DeviceLostHelper& operator=(const DeviceLostHelper&&) = delete;
41 
42     void enableWithNvidiaDeviceDiagnosticCheckpoints();
43 
44     void addNeededDeviceExtensions(std::vector<const char*>* deviceExtensions);
45 
46     struct QueueWithMutex {
47         VkQueue queue = VK_NULL_HANDLE;
48         std::shared_ptr<std::mutex> queueMutex;
49     };
50     struct DeviceWithQueues {
51         VkDevice device = VK_NULL_HANDLE;
52         const VulkanDispatch* deviceDispatch = nullptr;
53         std::vector<QueueWithMutex> queues;
54     };
55     void onDeviceCreated(const DeviceWithQueues& deviceInfo);
56     void onDeviceDestroyed(VkDevice device);
57 
58     void onBeginCommandBuffer(const VkCommandBuffer& commandBuffer, const VulkanDispatch* vk);
59     void onEndCommandBuffer(const VkCommandBuffer& commandBuffer, const VulkanDispatch* vk);
60 
61     void onResetCommandBuffer(const VkCommandBuffer& commandBuffer);
62     void onFreeCommandBuffer(const VkCommandBuffer& commandBuffer);
63 
64     void onDeviceLost();
65 
66    private:
67     enum class MarkerType { kBegin, kEnd };
68 
69     struct CheckpointMarker {
70         VkCommandBuffer commandBuffer;
71         MarkerType type;
72     };
73 
74     struct CheckpointMarkerEq {
operatorCheckpointMarkerEq75         bool operator()(const CheckpointMarker& lhs, const CheckpointMarker& rhs) const {
76             return lhs.commandBuffer == rhs.commandBuffer && lhs.type == rhs.type;
77         }
78     };
79 
80     struct CheckpointMarkerHash {
operatorCheckpointMarkerHash81         size_t operator()(const CheckpointMarker& marker) const {
82             std::size_t h1 = (std::size_t)(marker.commandBuffer);
83             std::size_t h2 = (std::size_t)(marker.type);
84             return h1 ^ (h2 << 1);
85         }
86     };
87 
88     const void* createMarkerForCommandBuffer(const VkCommandBuffer& commandBuffer, MarkerType type);
89     void removeMarkersForCommandBuffer(const VkCommandBuffer& commandBuffer);
90 
91     bool mEnabled = false;
92 
93     std::mutex mMarkersMutex;
94     std::unordered_set<CheckpointMarker, CheckpointMarkerHash, CheckpointMarkerEq> mMarkers
95         GUARDED_BY(mMarkersMutex);
96 
97     std::mutex mDevicesMutex;
98     std::unordered_map<VkDevice, DeviceWithQueues> mDevices GUARDED_BY(mDevicesMutex);
99 };
100 
101 }  // namespace vk
102 }  // namespace gfxstream
103