• 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 #define DISPATCH_MAP_DEBUG 0
29 
30 // Map lookup must be thread safe
device_dispatch_table(void * object)31 VkLayerDispatchTable *device_dispatch_table(void *object) {
32     dispatch_key key = get_dispatch_key(object);
33     device_table_map::const_iterator it = tableMap.find((void *)key);
34     assert(it != tableMap.end() && "Not able to find device dispatch entry");
35     return it->second;
36 }
37 
instance_dispatch_table(void * object)38 VkLayerInstanceDispatchTable *instance_dispatch_table(void *object) {
39     dispatch_key key = get_dispatch_key(object);
40     instance_table_map::const_iterator it = tableInstanceMap.find((void *)key);
41 #if DISPATCH_MAP_DEBUG
42     if (it != tableInstanceMap.end()) {
43         fprintf(stderr, "instance_dispatch_table: map:  0x%p, object:  0x%p, key:  0x%p, table:  0x%p\n", &tableInstanceMap, object, key,
44                 it->second);
45     } else {
46         fprintf(stderr, "instance_dispatch_table: map:  0x%p, object:  0x%p, key:  0x%p, table: UNKNOWN\n", &tableInstanceMap, object, key);
47     }
48 #endif
49     assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
50     return it->second;
51 }
52 
destroy_dispatch_table(device_table_map & map,dispatch_key key)53 void destroy_dispatch_table(device_table_map &map, dispatch_key key) {
54 #if DISPATCH_MAP_DEBUG
55     device_table_map::const_iterator it = map.find((void *)key);
56     if (it != map.end()) {
57         fprintf(stderr, "destroy device dispatch_table: map:  0x%p, key:  0x%p, table:  0x%p\n", &map, key, it->second);
58     } else {
59         fprintf(stderr, "destroy device dispatch table: map:  0x%p, key:  0x%p, table: UNKNOWN\n", &map, key);
60         assert(it != map.end());
61     }
62 #endif
63     map.erase(key);
64 }
65 
destroy_dispatch_table(instance_table_map & map,dispatch_key key)66 void destroy_dispatch_table(instance_table_map &map, dispatch_key key) {
67 #if DISPATCH_MAP_DEBUG
68     instance_table_map::const_iterator it = map.find((void *)key);
69     if (it != map.end()) {
70         fprintf(stderr, "destroy instance dispatch_table: map:  0x%p, key:  0x%p, table:  0x%p\n", &map, key, it->second);
71     } else {
72         fprintf(stderr, "destroy instance dispatch table: map:  0x%p, key:  0x%p, table: UNKNOWN\n", &map, key);
73         assert(it != map.end());
74     }
75 #endif
76     map.erase(key);
77 }
78 
destroy_device_dispatch_table(dispatch_key key)79 void destroy_device_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableMap, key); }
80 
destroy_instance_dispatch_table(dispatch_key key)81 void destroy_instance_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableInstanceMap, key); }
82 
get_dispatch_table(device_table_map & map,void * object)83 VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void *object) {
84     dispatch_key key = get_dispatch_key(object);
85     device_table_map::const_iterator it = map.find((void *)key);
86 #if DISPATCH_MAP_DEBUG
87     if (it != map.end()) {
88         fprintf(stderr, "device_dispatch_table: map:  0x%p, object:  0x%p, key:  0x%p, table:  0x%p\n", &tableInstanceMap, object, key,
89                 it->second);
90     } else {
91         fprintf(stderr, "device_dispatch_table: map:  0x%p, object:  0x%p, key:  0x%p, table: UNKNOWN\n", &tableInstanceMap, object, key);
92     }
93 #endif
94     assert(it != map.end() && "Not able to find device dispatch entry");
95     return it->second;
96 }
97 
get_dispatch_table(instance_table_map & map,void * object)98 VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void *object) {
99     dispatch_key key = get_dispatch_key(object);
100     instance_table_map::const_iterator it = map.find((void *)key);
101 #if DISPATCH_MAP_DEBUG
102     if (it != map.end()) {
103         fprintf(stderr, "instance_dispatch_table: map:  0x%p, object:  0x%p, key:  0x%p, table:  0x%p\n", &tableInstanceMap, object, key,
104                 it->second);
105     } else {
106         fprintf(stderr, "instance_dispatch_table: map:  0x%p, object:  0x%p, key:  0x%p, table: UNKNOWN\n", &tableInstanceMap, object, key);
107     }
108 #endif
109     assert(it != map.end() && "Not able to find instance dispatch entry");
110     return it->second;
111 }
112 
get_chain_info(const VkInstanceCreateInfo * pCreateInfo,VkLayerFunction func)113 VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func) {
114     VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
115     while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) {
116         chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext;
117     }
118     assert(chain_info != NULL);
119     return chain_info;
120 }
121 
get_chain_info(const VkDeviceCreateInfo * pCreateInfo,VkLayerFunction func)122 VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func) {
123     VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
124     while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) {
125         chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext;
126     }
127     assert(chain_info != NULL);
128     return chain_info;
129 }
130 
131 /* Various dispatchable objects will use the same underlying dispatch table if they
132  * are created from that "parent" object. Thus use pointer to dispatch table
133  * as the key to these table maps.
134  *    Instance -> PhysicalDevice
135  *    Device -> CommandBuffer or Queue
136  * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
137  * and a new key inserted into map */
initInstanceTable(VkInstance instance,const PFN_vkGetInstanceProcAddr gpa,instance_table_map & map)138 VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map) {
139     VkLayerInstanceDispatchTable *pTable;
140     dispatch_key key = get_dispatch_key(instance);
141     instance_table_map::const_iterator it = map.find((void *)key);
142 
143     if (it == map.end()) {
144         pTable = new VkLayerInstanceDispatchTable;
145         map[(void *)key] = pTable;
146 #if DISPATCH_MAP_DEBUG
147         fprintf(stderr, "New, Instance: map:  0x%p, key:  0x%p, table:  0x%p\n", &map, key, pTable);
148 #endif
149     } else {
150 #if DISPATCH_MAP_DEBUG
151         fprintf(stderr, "Instance: map:  0x%p, key:  0x%p, table:  0x%p\n", &map, key, it->second);
152 #endif
153         return it->second;
154     }
155 
156     layer_init_instance_dispatch_table(instance, pTable, gpa);
157 
158     return pTable;
159 }
160 
initInstanceTable(VkInstance instance,const PFN_vkGetInstanceProcAddr gpa)161 VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa) {
162     return initInstanceTable(instance, gpa, tableInstanceMap);
163 }
164 
initDeviceTable(VkDevice device,const PFN_vkGetDeviceProcAddr gpa,device_table_map & map)165 VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map) {
166     VkLayerDispatchTable *pTable;
167     dispatch_key key = get_dispatch_key(device);
168     device_table_map::const_iterator it = map.find((void *)key);
169 
170     if (it == map.end()) {
171         pTable = new VkLayerDispatchTable;
172         map[(void *)key] = pTable;
173 #if DISPATCH_MAP_DEBUG
174         fprintf(stderr, "New, Device: map:  0x%p, key:  0x%p, table:  0x%p\n", &map, key, pTable);
175 #endif
176     } else {
177 #if DISPATCH_MAP_DEBUG
178         fprintf(stderr, "Device: map:  0x%p, key:  0x%p, table:  0x%p\n", &map, key, it->second);
179 #endif
180         return it->second;
181     }
182 
183     layer_init_device_dispatch_table(device, pTable, gpa);
184 
185     return pTable;
186 }
187 
initDeviceTable(VkDevice device,const PFN_vkGetDeviceProcAddr gpa)188 VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa) {
189     return initDeviceTable(device, gpa, tableMap);
190 }
191