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 #ifndef NOEXCEPT 25 // Check for noexcept support 26 #if defined(__clang__) 27 #if __has_feature(cxx_noexcept) 28 #define HAS_NOEXCEPT 29 #endif 30 #else 31 #if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 32 #define HAS_NOEXCEPT 33 #else 34 #if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS 35 #define HAS_NOEXCEPT 36 #endif 37 #endif 38 #endif 39 40 #ifdef HAS_NOEXCEPT 41 #define NOEXCEPT noexcept 42 #else 43 #define NOEXCEPT 44 #endif 45 #endif 46 47 #pragma once 48 #include "core_validation_error_enums.h" 49 #include "vk_validation_error_messages.h" 50 #include "core_validation_types.h" 51 #include "descriptor_sets.h" 52 #include "vk_layer_logging.h" 53 #include "vulkan/vk_layer.h" 54 #include <atomic> 55 #include <functional> 56 #include <memory> 57 #include <unordered_map> 58 #include <unordered_set> 59 #include <vector> 60 #include <list> 61 #include <deque> 62 63 /* 64 * CHECK_DISABLED struct is a container for bools that can block validation checks from being performed. 65 * The end goal is to have all checks guarded by a bool. The bools are all "false" by default meaning that all checks 66 * are enabled. At CreateInstance time, the user can use the VK_EXT_validation_flags extension to pass in enum values 67 * of VkValidationCheckEXT that will selectively disable checks. 68 */ 69 struct CHECK_DISABLED { 70 bool command_buffer_state; 71 bool create_descriptor_set_layout; 72 bool destroy_buffer_view; // Skip validation at DestroyBufferView time 73 bool destroy_image_view; // Skip validation at DestroyImageView time 74 bool destroy_pipeline; // Skip validation at DestroyPipeline time 75 bool destroy_descriptor_pool; // Skip validation at DestroyDescriptorPool time 76 bool destroy_framebuffer; // Skip validation at DestroyFramebuffer time 77 bool destroy_renderpass; // Skip validation at DestroyRenderpass time 78 bool destroy_image; // Skip validation at DestroyImage time 79 bool destroy_sampler; // Skip validation at DestroySampler time 80 bool destroy_command_pool; // Skip validation at DestroyCommandPool time 81 bool destroy_event; // Skip validation at DestroyEvent time 82 bool free_memory; // Skip validation at FreeMemory time 83 bool object_in_use; // Skip all object in_use checking 84 bool idle_descriptor_set; // Skip check to verify that descriptor set is no in-use 85 bool push_constant_range; // Skip push constant range checks 86 bool free_descriptor_sets; // Skip validation prior to vkFreeDescriptorSets() 87 bool allocate_descriptor_sets; // Skip validation prior to vkAllocateDescriptorSets() 88 bool update_descriptor_sets; // Skip validation prior to vkUpdateDescriptorSets() 89 }; 90 91 /* 92 * MTMTODO : Update this comment 93 * Data Structure overview 94 * There are 4 global STL(' maps 95 * cbMap -- map of command Buffer (CB) objects to MT_CB_INFO structures 96 * Each MT_CB_INFO struct has an stl list container with 97 * memory objects that are referenced by this CB 98 * memObjMap -- map of Memory Objects to MT_MEM_OBJ_INFO structures 99 * Each MT_MEM_OBJ_INFO has two stl list containers with: 100 * -- all CBs referencing this mem obj 101 * -- all VK Objects that are bound to this memory 102 * objectMap -- map of objects to MT_OBJ_INFO structures 103 * 104 * Algorithm overview 105 * These are the primary events that should happen related to different objects 106 * 1. Command buffers 107 * CREATION - Add object,structure to map 108 * CMD BIND - If mem associated, add mem reference to list container 109 * DESTROY - Remove from map, decrement (and report) mem references 110 * 2. Mem Objects 111 * CREATION - Add object,structure to map 112 * OBJ BIND - Add obj structure to list container for that mem node 113 * CMB BIND - If mem-related add CB structure to list container for that mem node 114 * DESTROY - Flag as errors any remaining refs and remove from map 115 * 3. Generic Objects 116 * MEM BIND - DESTROY any previous binding, Add obj node w/ ref to map, add obj ref to list container for that mem node 117 * DESTROY - If mem bound, remove reference list container for that memInfo, remove object ref from map 118 */ 119 // TODO : Is there a way to track when Cmd Buffer finishes & remove mem references at that point? 120 // TODO : Could potentially store a list of freed mem allocs to flag when they're incorrectly used 121 122 struct MT_FB_ATTACHMENT_INFO { 123 IMAGE_VIEW_STATE *view_state; 124 VkImage image; 125 VkDeviceMemory mem; 126 }; 127 128 struct GENERIC_HEADER { 129 VkStructureType sType; 130 const void *pNext; 131 }; 132 133 struct IMAGE_LAYOUT_NODE { 134 VkImageLayout layout; 135 VkFormat format; 136 }; 137 138 class PHYS_DEV_PROPERTIES_NODE { 139 public: 140 VkPhysicalDeviceProperties properties; 141 std::vector<VkQueueFamilyProperties> queue_family_properties; 142 }; 143 144 enum FENCE_STATE { FENCE_UNSIGNALED, FENCE_INFLIGHT, FENCE_RETIRED }; 145 146 class FENCE_NODE { 147 public: 148 VkFence fence; 149 VkFenceCreateInfo createInfo; 150 std::pair<VkQueue, uint64_t> signaler; 151 FENCE_STATE state; 152 153 // Default constructor FENCE_NODE()154 FENCE_NODE() : state(FENCE_UNSIGNALED) {} 155 }; 156 157 class SEMAPHORE_NODE : public BASE_NODE { 158 public: 159 std::pair<VkQueue, uint64_t> signaler; 160 bool signaled; 161 }; 162 163 class EVENT_STATE : public BASE_NODE { 164 public: 165 int write_in_use; 166 bool needsSignaled; 167 VkPipelineStageFlags stageMask; 168 }; 169 170 class QUEUE_NODE { 171 public: 172 VkQueue queue; 173 uint32_t queueFamilyIndex; 174 std::unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap; 175 std::unordered_map<QueryObject, bool> queryToStateMap; // 0 is unavailable, 1 is available 176 177 uint64_t seq; 178 std::deque<CB_SUBMISSION> submissions; 179 }; 180 181 class QUERY_POOL_NODE : public BASE_NODE { 182 public: 183 VkQueryPoolCreateInfo createInfo; 184 }; 185 186 class FRAMEBUFFER_STATE : public BASE_NODE { 187 public: 188 VkFramebuffer framebuffer; 189 safe_VkFramebufferCreateInfo createInfo; 190 safe_VkRenderPassCreateInfo renderPassCreateInfo; 191 std::unordered_set<VkCommandBuffer> referencingCmdBuffers; 192 std::vector<MT_FB_ATTACHMENT_INFO> attachments; FRAMEBUFFER_STATE(VkFramebuffer fb,const VkFramebufferCreateInfo * pCreateInfo,const VkRenderPassCreateInfo * pRPCI)193 FRAMEBUFFER_STATE(VkFramebuffer fb, const VkFramebufferCreateInfo *pCreateInfo, const VkRenderPassCreateInfo *pRPCI) 194 : framebuffer(fb), createInfo(pCreateInfo), renderPassCreateInfo(pRPCI){}; 195 }; 196 197 // Track command pools and their command buffers 198 struct COMMAND_POOL_NODE : public BASE_NODE { 199 VkCommandPoolCreateFlags createFlags; 200 uint32_t queueFamilyIndex; 201 // TODO: why is this std::list? 202 std::list<VkCommandBuffer> commandBuffers; // container of cmd buffers allocated from this pool 203 }; 204 205 // Stuff from Device Limits Layer 206 enum CALL_STATE { 207 UNCALLED, // Function has not been called 208 QUERY_COUNT, // Function called once to query a count 209 QUERY_DETAILS, // Function called w/ a count to query details 210 }; 211 212 struct PHYSICAL_DEVICE_STATE { 213 // Track the call state and array sizes for various query functions 214 CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState = UNCALLED; 215 uint32_t queueFamilyPropertiesCount = 0; 216 CALL_STATE vkGetPhysicalDeviceLayerPropertiesState = UNCALLED; 217 CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState = UNCALLED; 218 CALL_STATE vkGetPhysicalDeviceFeaturesState = UNCALLED; 219 VkPhysicalDeviceFeatures features = {}; 220 VkPhysicalDevice phys_device = VK_NULL_HANDLE; 221 std::vector<VkQueueFamilyProperties> queue_family_properties; 222 }; 223 224 struct SURFACE_STATE { 225 VkSurfaceKHR surface = VK_NULL_HANDLE; 226 SWAPCHAIN_NODE *swapchain = nullptr; 227 SWAPCHAIN_NODE *old_swapchain = nullptr; 228 SURFACE_STATESURFACE_STATE229 SURFACE_STATE() {} SURFACE_STATESURFACE_STATE230 SURFACE_STATE(VkSurfaceKHR surface) 231 : surface(surface) {} 232 }; 233