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.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Author: Tobin Ehlis <tobin@lunarg.com>
21 #include <unordered_map>
22 #include <vulkan/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
;
28 // Map lookup must be thread safe
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");
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");
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()) {
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()) {
59 void destroy_device_dispatch_table(dispatch_key key
) { destroy_dispatch_table(tableMap
, key
); }
61 void destroy_instance_dispatch_table(dispatch_key key
) { destroy_dispatch_table(tableInstanceMap
, key
); }
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");
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");
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
;
82 assert(chain_info
!= NULL
);
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
;
91 assert(chain_info
!= NULL
);
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 */
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
);
107 if (it
== map
.end()) {
108 pTable
= new VkLayerInstanceDispatchTable
;
109 map
[(void *)key
] = pTable
;
114 layer_init_instance_dispatch_table(instance
, pTable
, gpa
);
116 // Setup func pointers that are required but not externally exposed. These won't be added to the instance dispatch table by
118 pTable
->GetPhysicalDeviceProcAddr
= (PFN_GetPhysicalDeviceProcAddr
)gpa(instance
, "vk_layerGetPhysicalDeviceProcAddr");
123 VkLayerInstanceDispatchTable
*initInstanceTable(VkInstance instance
, const PFN_vkGetInstanceProcAddr gpa
) {
124 return initInstanceTable(instance
, gpa
, tableInstanceMap
);
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
);
132 if (it
== map
.end()) {
133 pTable
= new VkLayerDispatchTable
;
134 map
[(void *)key
] = pTable
;
139 layer_init_device_dispatch_table(device
, pTable
, gpa
);
144 VkLayerDispatchTable
*initDeviceTable(VkDevice device
, const PFN_vkGetDeviceProcAddr gpa
) {
145 return initDeviceTable(device
, gpa
, tableMap
);