• 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: Tobin Ehlis <tobin@lunarg.com>
19  */
20 #include <assert.h>
21 #include <unordered_map>
22 #include "vk_dispatch_table_helper.h"
23 #include "vulkan/vk_layer.h"
24 #include "vk_layer_table.h"
25 static device_table_map tableMap;
26 static instance_table_map tableInstanceMap;
27 
28 // Map lookup must be thread safe
device_dispatch_table(void * object)29 VkLayerDispatchTable *device_dispatch_table(void *object) {
30     dispatch_key key = get_dispatch_key(object);
31     device_table_map::const_iterator it = tableMap.find((void *)key);
32     assert(it != tableMap.end() && "Not able to find device dispatch entry");
33     return it->second;
34 }
35 
instance_dispatch_table(void * object)36 VkLayerInstanceDispatchTable *instance_dispatch_table(void *object) {
37     dispatch_key key = get_dispatch_key(object);
38     instance_table_map::const_iterator it = tableInstanceMap.find((void *)key);
39     assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
40     return it->second;
41 }
42 
destroy_dispatch_table(device_table_map & map,dispatch_key key)43 void destroy_dispatch_table(device_table_map &map, dispatch_key key) {
44     device_table_map::const_iterator it = map.find((void *)key);
45     if (it != map.end()) {
46         delete it->second;
47         map.erase(it);
48     }
49 }
50 
destroy_dispatch_table(instance_table_map & map,dispatch_key key)51 void destroy_dispatch_table(instance_table_map &map, dispatch_key key) {
52     instance_table_map::const_iterator it = map.find((void *)key);
53     if (it != map.end()) {
54         delete it->second;
55         map.erase(it);
56     }
57 }
58 
destroy_device_dispatch_table(dispatch_key key)59 void destroy_device_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableMap, key); }
60 
destroy_instance_dispatch_table(dispatch_key key)61 void destroy_instance_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableInstanceMap, key); }
62 
get_dispatch_table(device_table_map & map,void * object)63 VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void *object) {
64     dispatch_key key = get_dispatch_key(object);
65     device_table_map::const_iterator it = map.find((void *)key);
66     assert(it != map.end() && "Not able to find device dispatch entry");
67     return it->second;
68 }
69 
get_dispatch_table(instance_table_map & map,void * object)70 VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void *object) {
71     dispatch_key key = get_dispatch_key(object);
72     instance_table_map::const_iterator it = map.find((void *)key);
73     assert(it != map.end() && "Not able to find instance dispatch entry");
74     return it->second;
75 }
76 
get_chain_info(const VkInstanceCreateInfo * pCreateInfo,VkLayerFunction func)77 VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func) {
78     VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
79     while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) {
80         chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext;
81     }
82     assert(chain_info != NULL);
83     return chain_info;
84 }
85 
get_chain_info(const VkDeviceCreateInfo * pCreateInfo,VkLayerFunction func)86 VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func) {
87     VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
88     while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) {
89         chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext;
90     }
91     assert(chain_info != NULL);
92     return chain_info;
93 }
94 
95 /* Various dispatchable objects will use the same underlying dispatch table if they
96  * are created from that "parent" object. Thus use pointer to dispatch table
97  * as the key to these table maps.
98  *    Instance -> PhysicalDevice
99  *    Device -> CommandBuffer or Queue
100  * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
101  * and a new key inserted into map */
initInstanceTable(VkInstance instance,const PFN_vkGetInstanceProcAddr gpa,instance_table_map & map)102 VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map) {
103     VkLayerInstanceDispatchTable *pTable;
104     dispatch_key key = get_dispatch_key(instance);
105     instance_table_map::const_iterator it = map.find((void *)key);
106 
107     if (it == map.end()) {
108         pTable = new VkLayerInstanceDispatchTable;
109         map[(void *)key] = pTable;
110     } else {
111         return it->second;
112     }
113 
114     layer_init_instance_dispatch_table(instance, pTable, gpa);
115 
116     // Setup func pointers that are required but not externally exposed.  These won't be added to the instance dispatch table by
117     // default.
118     pTable->GetPhysicalDeviceProcAddr = (PFN_GetPhysicalDeviceProcAddr)gpa(instance, "vk_layerGetPhysicalDeviceProcAddr");
119 
120     return pTable;
121 }
122 
initInstanceTable(VkInstance instance,const PFN_vkGetInstanceProcAddr gpa)123 VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa) {
124     return initInstanceTable(instance, gpa, tableInstanceMap);
125 }
126 
initDeviceTable(VkDevice device,const PFN_vkGetDeviceProcAddr gpa,device_table_map & map)127 VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map) {
128     VkLayerDispatchTable *pTable;
129     dispatch_key key = get_dispatch_key(device);
130     device_table_map::const_iterator it = map.find((void *)key);
131 
132     if (it == map.end()) {
133         pTable = new VkLayerDispatchTable;
134         map[(void *)key] = pTable;
135     } else {
136         return it->second;
137     }
138 
139     layer_init_device_dispatch_table(device, pTable, gpa);
140 
141     return pTable;
142 }
143 
initDeviceTable(VkDevice device,const PFN_vkGetDeviceProcAddr gpa)144 VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa) {
145     return initDeviceTable(device, gpa, tableMap);
146 }
147