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 <vector> 22 #include <unordered_set> 23 24 #include "vulkan/cereal/common/goldfish_vk_dispatch.h" 25 26 namespace gfxstream { 27 namespace vk { 28 29 // TODO: Support VK_AMD_buffer_marker. 30 class DeviceLostHelper { 31 public: DeviceLostHelper()32 DeviceLostHelper() : mEnabled(false) {}; 33 34 DeviceLostHelper(const DeviceLostHelper&) = delete; 35 DeviceLostHelper& operator=(const DeviceLostHelper&) = delete; 36 37 DeviceLostHelper(DeviceLostHelper&&) = delete; 38 DeviceLostHelper& operator=(const DeviceLostHelper&&) = delete; 39 40 void enableWithNvidiaDeviceDiagnosticCheckpoints(); 41 42 void addNeededDeviceExtensions(std::vector<const char*>* deviceExtensions); 43 44 void onBeginCommandBuffer(const VkCommandBuffer& commandBuffer, const VulkanDispatch* vk); 45 void onEndCommandBuffer(const VkCommandBuffer& commandBuffer, const VulkanDispatch* vk); 46 47 void onResetCommandBuffer(const VkCommandBuffer& commandBuffer); 48 void onFreeCommandBuffer(const VkCommandBuffer& commandBuffer); 49 50 struct DeviceWithQueues { 51 VkDevice device; 52 const VulkanDispatch* deviceDispatch; 53 std::vector<VkQueue> queues; 54 }; 55 void onDeviceLost(const std::vector<DeviceWithQueues>& devicesWithQueues); 56 57 private: 58 enum class MarkerType { kBegin, kEnd }; 59 60 struct CheckpointMarker { 61 VkCommandBuffer commandBuffer; 62 MarkerType type; 63 }; 64 65 struct CheckpointMarkerEq { operatorCheckpointMarkerEq66 bool operator()(const CheckpointMarker& lhs, const CheckpointMarker& rhs) const { 67 return lhs.commandBuffer == rhs.commandBuffer && lhs.type == rhs.type; 68 } 69 }; 70 71 struct CheckpointMarkerHash { operatorCheckpointMarkerHash72 size_t operator()(const CheckpointMarker& marker) const { 73 std::size_t h1 = (std::size_t)(marker.commandBuffer); 74 std::size_t h2 = (std::size_t)(marker.type); 75 return h1 ^ (h2 << 1); 76 } 77 }; 78 79 const void* createMarkerForCommandBuffer(const VkCommandBuffer& commandBuffer, MarkerType type); 80 void removeMarkersForCommandBuffer(const VkCommandBuffer& commandBuffer); 81 82 bool mEnabled = false; 83 84 std::mutex mMarkersMutex; 85 std::unordered_set<CheckpointMarker, CheckpointMarkerHash, CheckpointMarkerEq> mMarkers; 86 }; 87 88 } // namespace vk 89 } // namespace gfxstream 90