blob: b06fb312cc2718fbd6ab2863011fd86ce86e1330 [file] [log] [blame]
Jon Ashburn9eed2892015-06-01 10:02:09 -06001/*
Jon Ashburn9eed2892015-06-01 10:02:09 -06002 *
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Jon Ashburn9eed2892015-06-01 10:02:09 -06004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060022 *
23 * Author: Tobin Ehlis <tobin@lunarg.com>
Jon Ashburn9eed2892015-06-01 10:02:09 -060024 */
25#include <assert.h>
26#include <unordered_map>
27#include "vk_dispatch_table_helper.h"
David Pinedo9316d3b2015-11-06 12:54:48 -070028#include "vulkan/vk_layer.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060029#include "vk_layer_table.h"
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060030static device_table_map tableMap;
31static instance_table_map tableInstanceMap;
Jon Ashburn9eed2892015-06-01 10:02:09 -060032
Jon Ashburn94f36d92015-06-15 09:30:12 -060033#define DISPATCH_MAP_DEBUG 0
Jon Ashburn9eed2892015-06-01 10:02:09 -060034
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060035// Map lookup must be thread safe
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060036VkLayerDispatchTable *device_dispatch_table(void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060037{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060038 dispatch_key key = get_dispatch_key(object);
39 device_table_map::const_iterator it = tableMap.find((void *) key);
40 assert(it != tableMap.end() && "Not able to find device dispatch entry");
41 return it->second;
42}
43
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060044VkLayerInstanceDispatchTable *instance_dispatch_table(void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060045{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060046 dispatch_key key = get_dispatch_key(object);
47 instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060048#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060049 if (it != tableInstanceMap.end()) {
50 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
51 } else {
52 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
53 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060054#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060055 assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
56 return it->second;
57}
58
59void destroy_dispatch_table(device_table_map &map, dispatch_key key)
60{
61 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060062#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060063 if (it != map.end()) {
64 fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
65 } else {
66 fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
67 assert(it != map.end());
68 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060069#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060070 map.erase(key);
71}
72
73void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
74{
75 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060076#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060077 if (it != map.end()) {
78 fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
79 } else {
80 fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
81 assert(it != map.end());
82 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060083#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060084 map.erase(key);
85}
86
87void destroy_device_dispatch_table(dispatch_key key)
88{
89 destroy_dispatch_table(tableMap, key);
90}
91
92void destroy_instance_dispatch_table(dispatch_key key)
93{
94 destroy_dispatch_table(tableInstanceMap, key);
95}
96
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060097VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060098{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060099 dispatch_key key = get_dispatch_key(object);
100 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600101#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600102 if (it != map.end()) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700103 fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600104 } else {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700105 fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600106 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600107#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600108 assert(it != map.end() && "Not able to find device dispatch entry");
109 return it->second;
110}
111
Tobin Ehlisa30e7e52015-07-06 14:02:36 -0600112VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600113{
114// VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
115 dispatch_key key = get_dispatch_key(object);
116 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600117#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600118 if (it != map.end()) {
119 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
120 } else {
121 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
122 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600123#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600124 assert(it != map.end() && "Not able to find instance dispatch entry");
125 return it->second;
126}
127
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700128VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func)
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700129{
130 VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *) pCreateInfo->pNext;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700131 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
132 && chain_info->function == func)) {
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700133 chain_info = (VkLayerInstanceCreateInfo *) chain_info->pNext;
134 }
135 assert(chain_info != NULL);
136 return chain_info;
137}
138
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700139VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func)
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700140{
141 VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *) pCreateInfo->pNext;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700142 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
143 && chain_info->function == func)) {
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700144 chain_info = (VkLayerDeviceCreateInfo *) chain_info->pNext;
145 }
146 assert(chain_info != NULL);
147 return chain_info;
148}
149
Jon Ashburn9eed2892015-06-01 10:02:09 -0600150/* Various dispatchable objects will use the same underlying dispatch table if they
151 * are created from that "parent" object. Thus use pointer to dispatch table
152 * as the key to these table maps.
153 * Instance -> PhysicalDevice
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800154 * Device -> CommandBuffer or Queue
Jon Ashburn9eed2892015-06-01 10:02:09 -0600155 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
156 * and a new key inserted into map */
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700157VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600158{
159 VkLayerInstanceDispatchTable *pTable;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700160 dispatch_key key = get_dispatch_key(instance);
161 instance_table_map::const_iterator it = map.find((void *) key);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600162
Jeremy Hayesd427d722015-06-19 10:57:11 -0600163 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600164 {
165 pTable = new VkLayerInstanceDispatchTable;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700166 map[(void *) key] = pTable;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600167#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700168 fprintf(stderr, "New, Instance: map: %p, key: %p, table: %p\n", &map, key, pTable);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600169#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600170 } else
171 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600172#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700173 fprintf(stderr, "Instance: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600174#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600175 return it->second;
176 }
177
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700178 layer_init_instance_dispatch_table(instance, pTable, gpa);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600179
180 return pTable;
181}
182
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700183VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600184{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700185 return initInstanceTable(instance, gpa, tableInstanceMap);
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600186}
187
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700188VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map)
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600189{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700190 VkLayerDispatchTable *pTable;
191 dispatch_key key = get_dispatch_key(device);
192 device_table_map::const_iterator it = map.find((void *) key);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600193
Jeremy Hayesd427d722015-06-19 10:57:11 -0600194 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600195 {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700196 pTable = new VkLayerDispatchTable;
197 map[(void *) key] = pTable;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600198#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700199 fprintf(stderr, "New, Device: map: %p, key: %p, table: %p\n", &map, key, pTable);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600200#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600201 } else
202 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600203#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700204 fprintf(stderr, "Device: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600205#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600206 return it->second;
207 }
208
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700209 layer_init_device_dispatch_table(device, pTable, gpa);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600210
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700211 return pTable;
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600212}
213
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700214VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa)
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600215{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700216 return initDeviceTable(device, gpa, tableMap);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600217}