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