Home | History | Annotate | Download | only in layers
      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 (at) google.com>
     19  * Author: Tobin Ehlis <tobine (at) google.com>
     20  * Author: Chris Forbes <chrisf (at) ijw.co.nz>
     21  * Author: Mark Lobodzinski <mark (at) 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
    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;
    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 
    229     SURFACE_STATE() {}
    230     SURFACE_STATE(VkSurfaceKHR surface)
    231         : surface(surface) {}
    232 };
    233