blob: cbe80bed3fd268639474b055f8468deebe1a9d5f [file] [log] [blame]
Jon Ashburn9eed2892015-06-01 10:02:09 -06001/*
2 * Vulkan
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#include <assert.h>
25#include <unordered_map>
26#include "vk_dispatch_table_helper.h"
Tobin Ehlis0c6f9ee2015-07-03 09:42:57 -060027#include "vk_layer.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060028#include "vk_layer_table.h"
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060029static device_table_map tableMap;
30static instance_table_map tableInstanceMap;
Jon Ashburn9eed2892015-06-01 10:02:09 -060031
Jon Ashburn94f36d92015-06-15 09:30:12 -060032#define DISPATCH_MAP_DEBUG 0
Jon Ashburn9eed2892015-06-01 10:02:09 -060033
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060034// Map lookup must be thread safe
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060035VkLayerDispatchTable *device_dispatch_table(void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060036{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060037 dispatch_key key = get_dispatch_key(object);
38 device_table_map::const_iterator it = tableMap.find((void *) key);
39 assert(it != tableMap.end() && "Not able to find device dispatch entry");
40 return it->second;
41}
42
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060043VkLayerInstanceDispatchTable *instance_dispatch_table(void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060044{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060045 dispatch_key key = get_dispatch_key(object);
46 instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060047#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060048 if (it != tableInstanceMap.end()) {
49 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
50 } else {
51 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
52 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060053#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060054 assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
55 return it->second;
56}
57
58void destroy_dispatch_table(device_table_map &map, dispatch_key key)
59{
60 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060061#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060062 if (it != map.end()) {
63 fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
64 } else {
65 fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
66 assert(it != map.end());
67 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060068#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060069 map.erase(key);
70}
71
72void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
73{
74 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060075#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060076 if (it != map.end()) {
77 fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
78 } else {
79 fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
80 assert(it != map.end());
81 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060082#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060083 map.erase(key);
84}
85
86void destroy_device_dispatch_table(dispatch_key key)
87{
88 destroy_dispatch_table(tableMap, key);
89}
90
91void destroy_instance_dispatch_table(dispatch_key key)
92{
93 destroy_dispatch_table(tableInstanceMap, key);
94}
95
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060096VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060097{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060098 dispatch_key key = get_dispatch_key(object);
99 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600100#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600101 if (it != map.end()) {
102 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
103 } else {
104 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
105 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600106#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600107 assert(it != map.end() && "Not able to find device dispatch entry");
108 return it->second;
109}
110
Tobin Ehlisa30e7e52015-07-06 14:02:36 -0600111VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600112{
113// VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
114 dispatch_key key = get_dispatch_key(object);
115 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600116#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600117 if (it != map.end()) {
118 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
119 } else {
120 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
121 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600122#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600123 assert(it != map.end() && "Not able to find instance dispatch entry");
124 return it->second;
125}
126
Jon Ashburn9eed2892015-06-01 10:02:09 -0600127/* Various dispatchable objects will use the same underlying dispatch table if they
128 * are created from that "parent" object. Thus use pointer to dispatch table
129 * as the key to these table maps.
130 * Instance -> PhysicalDevice
131 * Device -> CmdBuffer or Queue
132 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
133 * and a new key inserted into map */
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600134VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600135{
136 VkLayerInstanceDispatchTable *pTable;
137 assert(instancew);
138 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;
139
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600140 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
Jeremy Hayesd427d722015-06-19 10:57:11 -0600141 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600142 {
143 pTable = new VkLayerInstanceDispatchTable;
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600144 map[(void *) *ppDisp] = pTable;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600145#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600146 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 -0600147#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600148 } else
149 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600150#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600151 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 -0600152#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600153 return it->second;
154 }
155
156 layer_init_instance_dispatch_table(pTable, instancew);
157
158 return pTable;
159}
160
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600161VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600162{
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600163 return initInstanceTable(tableInstanceMap, instancew);
164}
165
166VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
167{
168 VkLayerDispatchTable *layer_device_table = NULL;
Jon Ashburn9eed2892015-06-01 10:02:09 -0600169 assert(devw);
170 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600171 VkLayerDispatchTable *base_device_table = *ppDisp;
Jon Ashburn9eed2892015-06-01 10:02:09 -0600172
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600173 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
Jeremy Hayesd427d722015-06-19 10:57:11 -0600174 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600175 {
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600176 layer_device_table = new VkLayerDispatchTable;
177 map[(void *) base_device_table] = layer_device_table;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600178#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600179 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 -0600180#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600181 } else
182 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600183#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600184 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 -0600185#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600186 return it->second;
187 }
188
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600189 layer_initialize_dispatch_table(layer_device_table, devw);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600190
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600191 return layer_device_table;
192}
193
194VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
195{
196 return initDeviceTable(tableMap, devw);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600197}