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 */ 69struct 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 122struct MT_FB_ATTACHMENT_INFO { 123 IMAGE_VIEW_STATE *view_state; 124 VkImage image; 125 VkDeviceMemory mem; 126}; 127 128struct GENERIC_HEADER { 129 VkStructureType sType; 130 const void *pNext; 131}; 132 133struct IMAGE_LAYOUT_NODE { 134 VkImageLayout layout; 135 VkFormat format; 136}; 137 138class PHYS_DEV_PROPERTIES_NODE { 139 public: 140 VkPhysicalDeviceProperties properties; 141 std::vector<VkQueueFamilyProperties> queue_family_properties; 142}; 143 144enum FENCE_STATE { FENCE_UNSIGNALED, FENCE_INFLIGHT, FENCE_RETIRED }; 145 146class 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 154 FENCE_NODE() : state(FENCE_UNSIGNALED) {} 155}; 156 157class SEMAPHORE_NODE : public BASE_NODE { 158 public: 159 std::pair<VkQueue, uint64_t> signaler; 160 bool signaled; 161}; 162 163class EVENT_STATE : public BASE_NODE { 164 public: 165 int write_in_use; 166 bool needsSignaled; 167 VkPipelineStageFlags stageMask; 168}; 169 170class 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 181class QUERY_POOL_NODE : public BASE_NODE { 182 public: 183 VkQueryPoolCreateInfo createInfo; 184}; 185 186class 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; 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 198struct 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 206enum 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 212struct 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 224struct SURFACE_STATE { 225 VkSurfaceKHR surface = VK_NULL_HANDLE; 226 SWAPCHAIN_NODE *swapchain = nullptr; 227 SWAPCHAIN_NODE *old_swapchain = nullptr; 228 229 SURFACE_STATE() {} 230 SURFACE_STATE(VkSurfaceKHR surface) 231 : surface(surface) {} 232}; 233