1 /* Copyright (c) 2015-2016 The Khronos Group Inc. 2 * Copyright (c) 2015-2016 Valve Corporation 3 * Copyright (c) 2015-2016 LunarG, Inc. 4 * Copyright (C) 2015-2016 Google Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * Author: Courtney Goeltzenleuchter <courtneygo@google.com> 19 * Author: Tobin Ehlis <tobine@google.com> 20 * Author: Chris Forbes <chrisf@ijw.co.nz> 21 * Author: Mark Lobodzinski <mark@lunarg.com> 22 */ 23 24 #pragma once 25 #include "core_validation_error_enums.h" 26 #include "vk_validation_error_messages.h" 27 #include "core_validation_types.h" 28 #include "descriptor_sets.h" 29 #include "vk_layer_logging.h" 30 #include "vulkan/vk_layer.h" 31 #include <atomic> 32 #include <functional> 33 #include <memory> 34 #include <unordered_map> 35 #include <unordered_set> 36 #include <vector> 37 #include <list> 38 #include <deque> 39 40 /* 41 * MTMTODO : Update this comment 42 * Data Structure overview 43 * There are 4 global STL(' maps 44 * cbMap -- map of command Buffer (CB) objects to MT_CB_INFO structures 45 * Each MT_CB_INFO struct has an stl list container with 46 * memory objects that are referenced by this CB 47 * memObjMap -- map of Memory Objects to MT_MEM_OBJ_INFO structures 48 * Each MT_MEM_OBJ_INFO has two stl list containers with: 49 * -- all CBs referencing this mem obj 50 * -- all VK Objects that are bound to this memory 51 * objectMap -- map of objects to MT_OBJ_INFO structures 52 * 53 * Algorithm overview 54 * These are the primary events that should happen related to different objects 55 * 1. Command buffers 56 * CREATION - Add object,structure to map 57 * CMD BIND - If mem associated, add mem reference to list container 58 * DESTROY - Remove from map, decrement (and report) mem references 59 * 2. Mem Objects 60 * CREATION - Add object,structure to map 61 * OBJ BIND - Add obj structure to list container for that mem node 62 * CMB BIND - If mem-related add CB structure to list container for that mem node 63 * DESTROY - Flag as errors any remaining refs and remove from map 64 * 3. Generic Objects 65 * MEM BIND - DESTROY any previous binding, Add obj node w/ ref to map, add obj ref to list container for that mem node 66 * DESTROY - If mem bound, remove reference list container for that memInfo, remove object ref from map 67 */ 68 // TODO : Is there a way to track when Cmd Buffer finishes & remove mem references at that point? 69 // TODO : Could potentially store a list of freed mem allocs to flag when they're incorrectly used 70 71 struct GENERIC_HEADER { 72 VkStructureType sType; 73 const void *pNext; 74 }; 75 76 enum SyncScope { 77 kSyncScopeInternal, 78 kSyncScopeExternalTemporary, 79 kSyncScopeExternalPermanent, 80 }; 81 82 enum FENCE_STATE { FENCE_UNSIGNALED, FENCE_INFLIGHT, FENCE_RETIRED }; 83 84 class FENCE_NODE { 85 public: 86 VkFence fence; 87 VkFenceCreateInfo createInfo; 88 std::pair<VkQueue, uint64_t> signaler; 89 FENCE_STATE state; 90 SyncScope scope; 91 92 // Default constructor FENCE_NODE()93 FENCE_NODE() : state(FENCE_UNSIGNALED), scope(kSyncScopeInternal) {} 94 }; 95 96 class SEMAPHORE_NODE : public BASE_NODE { 97 public: 98 std::pair<VkQueue, uint64_t> signaler; 99 bool signaled; 100 SyncScope scope; 101 }; 102 103 class EVENT_STATE : public BASE_NODE { 104 public: 105 int write_in_use; 106 bool needsSignaled; 107 VkPipelineStageFlags stageMask; 108 }; 109 110 class QUEUE_STATE { 111 public: 112 VkQueue queue; 113 uint32_t queueFamilyIndex; 114 std::unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap; 115 std::unordered_map<QueryObject, bool> queryToStateMap; // 0 is unavailable, 1 is available 116 117 uint64_t seq; 118 std::deque<CB_SUBMISSION> submissions; 119 }; 120 121 class QUERY_POOL_NODE : public BASE_NODE { 122 public: 123 VkQueryPoolCreateInfo createInfo; 124 }; 125 126 struct PHYSICAL_DEVICE_STATE { 127 // Track the call state and array sizes for various query functions 128 CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState = UNCALLED; 129 CALL_STATE vkGetPhysicalDeviceLayerPropertiesState = UNCALLED; 130 CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState = UNCALLED; 131 CALL_STATE vkGetPhysicalDeviceFeaturesState = UNCALLED; 132 CALL_STATE vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = UNCALLED; 133 CALL_STATE vkGetPhysicalDeviceSurfacePresentModesKHRState = UNCALLED; 134 CALL_STATE vkGetPhysicalDeviceSurfaceFormatsKHRState = UNCALLED; 135 CALL_STATE vkGetPhysicalDeviceDisplayPlanePropertiesKHRState = UNCALLED; 136 VkPhysicalDeviceFeatures features = {}; 137 VkPhysicalDevice phys_device = VK_NULL_HANDLE; 138 uint32_t queue_family_count = 0; 139 std::vector<VkQueueFamilyProperties> queue_family_properties; 140 VkSurfaceCapabilitiesKHR surfaceCapabilities = {}; 141 std::vector<VkPresentModeKHR> present_modes; 142 std::vector<VkSurfaceFormatKHR> surface_formats; 143 uint32_t display_plane_property_count = 0; 144 }; 145 146 struct GpuQueue { 147 VkPhysicalDevice gpu; 148 uint32_t queue_family_index; 149 }; 150 151 inline bool operator==(GpuQueue const &lhs, GpuQueue const &rhs) { 152 return (lhs.gpu == rhs.gpu && lhs.queue_family_index == rhs.queue_family_index); 153 } 154 155 namespace std { 156 template <> 157 struct hash<GpuQueue> { 158 size_t operator()(GpuQueue gq) const throw() { 159 return hash<uint64_t>()((uint64_t)(gq.gpu)) ^ hash<uint32_t>()(gq.queue_family_index); 160 } 161 }; 162 } // namespace std 163 164 struct SURFACE_STATE { 165 VkSurfaceKHR surface = VK_NULL_HANDLE; 166 SWAPCHAIN_NODE *swapchain = nullptr; 167 SWAPCHAIN_NODE *old_swapchain = nullptr; 168 std::unordered_map<GpuQueue, bool> gpu_queue_support; 169 170 SURFACE_STATE() {} 171 SURFACE_STATE(VkSurfaceKHR surface) : surface(surface) {} 172 }; 173