/* Copyright (c) 2015-2016 The Khronos Group Inc. * Copyright (c) 2015-2016 Valve Corporation * Copyright (c) 2015-2016 LunarG, Inc. * Copyright (C) 2015-2016 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: Courtney Goeltzenleuchter * Author: Tobin Ehlis * Author: Chris Forbes * Author: Mark Lobodzinski */ #pragma once #include "core_validation_error_enums.h" #include "vk_validation_error_messages.h" #include "core_validation_types.h" #include "descriptor_sets.h" #include "vk_layer_logging.h" #include "vulkan/vk_layer.h" #include #include #include #include #include #include #include #include /* * MTMTODO : Update this comment * Data Structure overview * There are 4 global STL(' maps * cbMap -- map of command Buffer (CB) objects to MT_CB_INFO structures * Each MT_CB_INFO struct has an stl list container with * memory objects that are referenced by this CB * memObjMap -- map of Memory Objects to MT_MEM_OBJ_INFO structures * Each MT_MEM_OBJ_INFO has two stl list containers with: * -- all CBs referencing this mem obj * -- all VK Objects that are bound to this memory * objectMap -- map of objects to MT_OBJ_INFO structures * * Algorithm overview * These are the primary events that should happen related to different objects * 1. Command buffers * CREATION - Add object,structure to map * CMD BIND - If mem associated, add mem reference to list container * DESTROY - Remove from map, decrement (and report) mem references * 2. Mem Objects * CREATION - Add object,structure to map * OBJ BIND - Add obj structure to list container for that mem node * CMB BIND - If mem-related add CB structure to list container for that mem node * DESTROY - Flag as errors any remaining refs and remove from map * 3. Generic Objects * MEM BIND - DESTROY any previous binding, Add obj node w/ ref to map, add obj ref to list container for that mem node * DESTROY - If mem bound, remove reference list container for that memInfo, remove object ref from map */ // TODO : Is there a way to track when Cmd Buffer finishes & remove mem references at that point? // TODO : Could potentially store a list of freed mem allocs to flag when they're incorrectly used enum SyncScope { kSyncScopeInternal, kSyncScopeExternalTemporary, kSyncScopeExternalPermanent, }; enum FENCE_STATE { FENCE_UNSIGNALED, FENCE_INFLIGHT, FENCE_RETIRED }; class FENCE_NODE { public: VkFence fence; VkFenceCreateInfo createInfo; std::pair signaler; FENCE_STATE state; SyncScope scope; // Default constructor FENCE_NODE() : state(FENCE_UNSIGNALED), scope(kSyncScopeInternal) {} }; class SEMAPHORE_NODE : public BASE_NODE { public: std::pair signaler; bool signaled; SyncScope scope; }; class EVENT_STATE : public BASE_NODE { public: int write_in_use; bool needsSignaled; VkPipelineStageFlags stageMask; }; class QUEUE_STATE { public: VkQueue queue; uint32_t queueFamilyIndex; std::unordered_map eventToStageMap; std::unordered_map queryToStateMap; // 0 is unavailable, 1 is available uint64_t seq; std::deque submissions; }; class QUERY_POOL_NODE : public BASE_NODE { public: VkQueryPoolCreateInfo createInfo; }; struct PHYSICAL_DEVICE_STATE { // Track the call state and array sizes for various query functions CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState = UNCALLED; CALL_STATE vkGetPhysicalDeviceLayerPropertiesState = UNCALLED; CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState = UNCALLED; CALL_STATE vkGetPhysicalDeviceFeaturesState = UNCALLED; CALL_STATE vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = UNCALLED; CALL_STATE vkGetPhysicalDeviceSurfacePresentModesKHRState = UNCALLED; CALL_STATE vkGetPhysicalDeviceSurfaceFormatsKHRState = UNCALLED; CALL_STATE vkGetPhysicalDeviceDisplayPlanePropertiesKHRState = UNCALLED; safe_VkPhysicalDeviceFeatures2 features2 = {}; VkPhysicalDevice phys_device = VK_NULL_HANDLE; uint32_t queue_family_count = 0; std::vector queue_family_properties; VkSurfaceCapabilitiesKHR surfaceCapabilities = {}; std::vector present_modes; std::vector surface_formats; uint32_t display_plane_property_count = 0; }; struct GpuQueue { VkPhysicalDevice gpu; uint32_t queue_family_index; }; inline bool operator==(GpuQueue const &lhs, GpuQueue const &rhs) { return (lhs.gpu == rhs.gpu && lhs.queue_family_index == rhs.queue_family_index); } namespace std { template <> struct hash { size_t operator()(GpuQueue gq) const throw() { return hash()((uint64_t)(gq.gpu)) ^ hash()(gq.queue_family_index); } }; } // namespace std struct SURFACE_STATE { VkSurfaceKHR surface = VK_NULL_HANDLE; SWAPCHAIN_NODE *swapchain = nullptr; SWAPCHAIN_NODE *old_swapchain = nullptr; std::unordered_map gpu_queue_support; SURFACE_STATE() {} SURFACE_STATE(VkSurfaceKHR surface) : surface(surface) {} };