1288e4f7d378f9185c714ead36a17dff64be24e49Mark Lobodzinski/* Copyright (c) 2015-2016 The Khronos Group Inc.
2288e4f7d378f9185c714ead36a17dff64be24e49Mark Lobodzinski * Copyright (c) 2015-2016 Valve Corporation
3288e4f7d378f9185c714ead36a17dff64be24e49Mark Lobodzinski * Copyright (c) 2015-2016 LunarG, Inc.
4288e4f7d378f9185c714ead36a17dff64be24e49Mark Lobodzinski * Copyright (C) 2015-2016 Google Inc.
50b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis *
643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Licensed under the Apache License, Version 2.0 (the "License");
743b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * you may not use this file except in compliance with the License.
843b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * You may obtain a copy of the License at
90b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis *
1043b53e83705f02245da6ae61e31273866a35b833Jon Ashburn *     http://www.apache.org/licenses/LICENSE-2.0
110b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis *
1243b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Unless required by applicable law or agreed to in writing, software
1343b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * distributed under the License is distributed on an "AS IS" BASIS,
1443b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1543b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * See the License for the specific language governing permissions and
1643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * limitations under the License.
170b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis *
180b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis * Author: Tobin Ehlis <tobine@google.com>
1936f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinski * Author: Mark Lobodzinski <mark@lunarg.com>
200b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis */
210b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis
226f25bb7c1c77be0bcfbca387329550a4d069f706Jamie Madill#include "vulkan/vulkan.h"
236f25bb7c1c77be0bcfbca387329550a4d069f706Jamie Madill
240b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis#include "vk_layer_data.h"
259aac555fc92f69fd059781139e17647eb7277992Tobin Ehlis#include "vk_safe_struct.h"
26f1ea418f193d10a8455cdf47e0eeeeb1f4d8b5bfJon Ashburn#include "vk_layer_utils.h"
2736f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinski#include "mutex"
2836f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinski
2936f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinski#pragma once
300b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis
311c0b73114010d6eb49ff34243fa9474493ef6eaeChia-I Wunamespace unique_objects {
321c0b73114010d6eb49ff34243fa9474493ef6eaeChia-I Wu
33dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski// The display-server-specific WSI extensions are handled explicitly
34dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinskistatic const char *kUniqueObjectsSupportedInstanceExtensions =
35dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#ifdef VK_USE_PLATFORM_XLIB_KHR
36dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_XLIB_SURFACE_EXTENSION_NAME
37dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#endif
38dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#ifdef VK_USE_PLATFORM_XCB_KHR
39dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_XCB_SURFACE_EXTENSION_NAME
40dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#endif
41dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#ifdef VK_USE_PLATFORM_WAYLAND_KHR
42dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
43dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#endif
44dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#ifdef VK_USE_PLATFORM_MIR_KHR
45dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_MIR_SURFACE_EXTENSION_NAME
46dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#endif
47dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#ifdef VK_USE_PLATFORM_ANDROID_KHR
48dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
49dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#endif
50dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#ifdef VK_USE_PLATFORM_WIN32_KHR
51dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_WIN32_SURFACE_EXTENSION_NAME
52dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski#endif
53dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_EXT_DEBUG_MARKER_EXTENSION_NAME
54dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_EXT_DEBUG_REPORT_EXTENSION_NAME
55dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_DISPLAY_EXTENSION_NAME
56df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_KHR_SURFACE_EXTENSION_NAME
57df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME
58df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME;
59dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski
60dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinskistatic const char *kUniqueObjectsSupportedDeviceExtensions =
61dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME
62dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME
63dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME
64dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_AMD_GCN_SHADER_EXTENSION_NAME
65dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_IMG_FILTER_CUBIC_EXTENSION_NAME
66dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_IMG_FORMAT_PVRTC_EXTENSION_NAME
67dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME
68dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_SWAPCHAIN_EXTENSION_NAME
69dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME
70dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski    VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME
71df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_NV_GLSL_SHADER_EXTENSION_NAME
72df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME
73edc793f0d8e086912c46c7ef669a53ffedb4fdecMark Lobodzinski    VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME
74df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME
75edc793f0d8e086912c46c7ef669a53ffedb4fdecMark Lobodzinski    VK_AMD_SHADER_BALLOT_EXTENSION_NAME
76df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME
77df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski#ifdef VK_USE_PLATFORM_WIN32_KHR
78df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME
79df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME
80df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski#endif
81df0735146ddd6ce7d29fc74232f59b4f862c400dMark Lobodzinski    VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME;
82dae6e857077ff54f468613f56fdd6dbffcaec8b5Mark Lobodzinski
83e8c386537125cba5ebc02b394bae69fd47c2b5d1Mark Lobodzinski// All increments must be guarded by global_lock
84e8c386537125cba5ebc02b394bae69fd47c2b5d1Mark Lobodzinskistatic uint64_t global_unique_id = 1;
85e8c386537125cba5ebc02b394bae69fd47c2b5d1Mark Lobodzinski
860b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlisstruct layer_data {
87edac63503f87b4429c524ce796f6642c0dce4adcChia-I Wu    VkInstance instance;
88edac63503f87b4429c524ce796f6642c0dce4adcChia-I Wu
89625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski    debug_report_data *report_data;
90625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski    std::vector<VkDebugReportCallbackEXT> logging_callback;
9136f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinski    VkLayerDispatchTable *device_dispatch_table;
9236f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinski    VkLayerInstanceDispatchTable *instance_dispatch_table;
93625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski
94625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski    // The following are for keeping track of the temporary callbacks that can
95625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski    // be used in vkCreateInstance and vkDestroyInstance:
96625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski    uint32_t num_tmp_callbacks;
97625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski    VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
98625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski    VkDebugReportCallbackEXT *tmp_callbacks;
99625cac1aeb4cfffb9b6a3c06bdf857d077bed173Mark Lobodzinski
1000b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis    bool wsi_enabled;
1012fb0dba25a2ef615bc82cb43af333acacd99b82fTobin Ehlis    std::unordered_map<uint64_t, uint64_t> unique_id_mapping; // Map uniqueID to actual object handle
1022fb0dba25a2ef615bc82cb43af333acacd99b82fTobin Ehlis    VkPhysicalDevice gpu;
1030b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis
104e8c386537125cba5ebc02b394bae69fd47c2b5d1Mark Lobodzinski    layer_data() : wsi_enabled(false), gpu(VK_NULL_HANDLE){};
1050b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis};
1060b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis
10761d505ea40b189b7ae63f311e2f13210eef219d2Mark Lobodzinskistruct instance_extension_enables {
1080b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis    bool wsi_enabled;
109115790b84c1afea132a994b5e47ffec7601d6759Tobin Ehlis    bool xlib_enabled;
110115790b84c1afea132a994b5e47ffec7601d6759Tobin Ehlis    bool xcb_enabled;
111115790b84c1afea132a994b5e47ffec7601d6759Tobin Ehlis    bool wayland_enabled;
112115790b84c1afea132a994b5e47ffec7601d6759Tobin Ehlis    bool mir_enabled;
113115790b84c1afea132a994b5e47ffec7601d6759Tobin Ehlis    bool android_enabled;
114115790b84c1afea132a994b5e47ffec7601d6759Tobin Ehlis    bool win32_enabled;
11570ebf4a7c86c77a8ce9b09683e06e872c975977cJon Ashburn    bool display_enabled;
1160b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis};
1170b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis
11836f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinskistatic std::unordered_map<void *, struct instance_extension_enables> instance_ext_map;
119491a3cd11793892b996a8b5771479cc539198f99Jon Ashburnstatic std::unordered_map<void *, layer_data *> layer_data_map;
12036f9d19dce58d509c189c22b4e630ba9a450ce5aMark Lobodzinski
1212fb0dba25a2ef615bc82cb43af333acacd99b82fTobin Ehlisstatic std::mutex global_lock; // Protect map accesses and unique_id increments
1220b99d0383bb88c3b128c7d7922151d6a833da51dTobin Ehlis
12315b4845aaf667fa51be8fa910970901da84cc5a9Dustin Gravesstruct GenericHeader {
12415b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves    VkStructureType sType;
12515b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves    void *pNext;
12615b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves};
12715b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves
12815b4845aaf667fa51be8fa910970901da84cc5a9Dustin Gravestemplate <typename T> bool ContainsExtStruct(const T *target, VkStructureType ext_type) {
12915b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves    assert(target != nullptr);
13015b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves
13115b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves    const GenericHeader *ext_struct = reinterpret_cast<const GenericHeader *>(target->pNext);
13215b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves
13315b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves    while (ext_struct != nullptr) {
13415b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves        if (ext_struct->sType == ext_type) {
13515b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves            return true;
13615b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves        }
13715b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves
13815b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves        ext_struct = reinterpret_cast<const GenericHeader *>(ext_struct->pNext);
13915b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves    }
14015b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves
14115b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves    return false;
14215b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves}
14315b4845aaf667fa51be8fa910970901da84cc5a9Dustin Graves
1441c0b73114010d6eb49ff34243fa9474493ef6eaeChia-I Wu} // namespace unique_objects
145