• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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