blob: 1c4fa13394d067b9da24d06a513e514f5fce6947 [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()) {
103 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
104 } else {
105 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
106 }
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
Jon Ashburn9eed2892015-06-01 10:02:09 -0600128/* Various dispatchable objects will use the same underlying dispatch table if they
129 * are created from that "parent" object. Thus use pointer to dispatch table
130 * as the key to these table maps.
131 * Instance -> PhysicalDevice
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800132 * Device -> CommandBuffer or Queue
Jon Ashburn9eed2892015-06-01 10:02:09 -0600133 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
134 * and a new key inserted into map */
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600135VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600136{
137 VkLayerInstanceDispatchTable *pTable;
138 assert(instancew);
139 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;
140
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600141 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
Jeremy Hayesd427d722015-06-19 10:57:11 -0600142 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600143 {
144 pTable = new VkLayerInstanceDispatchTable;
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600145 map[(void *) *ppDisp] = pTable;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600146#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600147 fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600148#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600149 } else
150 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600151#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600152 fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600153#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600154 return it->second;
155 }
156
157 layer_init_instance_dispatch_table(pTable, instancew);
158
159 return pTable;
160}
161
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600162VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600163{
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600164 return initInstanceTable(tableInstanceMap, instancew);
165}
166
167VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
168{
169 VkLayerDispatchTable *layer_device_table = NULL;
Jon Ashburn9eed2892015-06-01 10:02:09 -0600170 assert(devw);
171 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600172 VkLayerDispatchTable *base_device_table = *ppDisp;
Jon Ashburn9eed2892015-06-01 10:02:09 -0600173
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600174 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
Jeremy Hayesd427d722015-06-19 10:57:11 -0600175 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600176 {
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600177 layer_device_table = new VkLayerDispatchTable;
178 map[(void *) base_device_table] = layer_device_table;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600179#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600180 fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600181#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600182 } else
183 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600184#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600185 fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600186#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600187 return it->second;
188 }
189
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600190 layer_initialize_dispatch_table(layer_device_table, devw);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600191
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600192 return layer_device_table;
193}
194
195VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
196{
197 return initDeviceTable(tableMap, devw);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600198}