blob: fda2b5636a31de7ccf817a4e2c738b8c5d64a28b [file] [log] [blame]
Jon Ashburn5a10d212015-06-01 10:02:09 -06001/*
Jon Ashburn5a10d212015-06-01 10:02:09 -06002 *
3 * Copyright (C) 2014 LunarG, Inc.
4 *
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.
22 */
23#include <assert.h>
24#include <unordered_map>
25#include "vk_dispatch_table_helper.h"
Tobin Ehlis2d1d9702015-07-03 09:42:57 -060026#include "vk_layer.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060027#include "vk_layer_table.h"
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060028static device_table_map tableMap;
29static instance_table_map tableInstanceMap;
Jon Ashburn5a10d212015-06-01 10:02:09 -060030
Jon Ashburn4ec582f2015-06-15 09:30:12 -060031#define DISPATCH_MAP_DEBUG 0
Jon Ashburn5a10d212015-06-01 10:02:09 -060032
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060033// Map lookup must be thread safe
Tobin Ehlis0b9c1952015-07-06 14:02:36 -060034VkLayerDispatchTable *device_dispatch_table(void* object)
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060035{
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060036 dispatch_key key = get_dispatch_key(object);
37 device_table_map::const_iterator it = tableMap.find((void *) key);
38 assert(it != tableMap.end() && "Not able to find device dispatch entry");
39 return it->second;
40}
41
Tobin Ehlis0b9c1952015-07-06 14:02:36 -060042VkLayerInstanceDispatchTable *instance_dispatch_table(void* object)
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060043{
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060044 dispatch_key key = get_dispatch_key(object);
45 instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060046#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060047 if (it != tableInstanceMap.end()) {
48 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
49 } else {
50 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
51 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060052#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060053 assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
54 return it->second;
55}
56
57void destroy_dispatch_table(device_table_map &map, dispatch_key key)
58{
59 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060060#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060061 if (it != map.end()) {
62 fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
63 } else {
64 fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
65 assert(it != map.end());
66 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060067#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060068 map.erase(key);
69}
70
71void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
72{
73 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060074#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060075 if (it != map.end()) {
76 fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
77 } else {
78 fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
79 assert(it != map.end());
80 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060081#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060082 map.erase(key);
83}
84
85void destroy_device_dispatch_table(dispatch_key key)
86{
87 destroy_dispatch_table(tableMap, key);
88}
89
90void destroy_instance_dispatch_table(dispatch_key key)
91{
92 destroy_dispatch_table(tableInstanceMap, key);
93}
94
Tobin Ehlis0b9c1952015-07-06 14:02:36 -060095VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object)
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060096{
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060097 dispatch_key key = get_dispatch_key(object);
98 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060099#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600100 if (it != map.end()) {
101 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
102 } else {
103 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
104 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600105#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600106 assert(it != map.end() && "Not able to find device dispatch entry");
107 return it->second;
108}
109
Tobin Ehlis0b9c1952015-07-06 14:02:36 -0600110VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object)
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600111{
112// VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
113 dispatch_key key = get_dispatch_key(object);
114 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600115#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600116 if (it != map.end()) {
117 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
118 } else {
119 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
120 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600121#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600122 assert(it != map.end() && "Not able to find instance dispatch entry");
123 return it->second;
124}
125
Jon Ashburn5a10d212015-06-01 10:02:09 -0600126/* Various dispatchable objects will use the same underlying dispatch table if they
127 * are created from that "parent" object. Thus use pointer to dispatch table
128 * as the key to these table maps.
129 * Instance -> PhysicalDevice
Chia-I Wu1f851912015-10-27 18:04:07 +0800130 * Device -> CommandBuffer or Queue
Jon Ashburn5a10d212015-06-01 10:02:09 -0600131 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
132 * and a new key inserted into map */
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600133VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
Jon Ashburn5a10d212015-06-01 10:02:09 -0600134{
135 VkLayerInstanceDispatchTable *pTable;
136 assert(instancew);
137 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;
138
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600139 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
Jeremy Hayes70af09d2015-06-19 10:57:11 -0600140 if (it == map.end())
Jon Ashburn5a10d212015-06-01 10:02:09 -0600141 {
142 pTable = new VkLayerInstanceDispatchTable;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600143 map[(void *) *ppDisp] = pTable;
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600144#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600145 fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600146#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600147 } else
148 {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600149#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600150 fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600151#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600152 return it->second;
153 }
154
155 layer_init_instance_dispatch_table(pTable, instancew);
156
157 return pTable;
158}
159
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600160VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
Jon Ashburn5a10d212015-06-01 10:02:09 -0600161{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600162 return initInstanceTable(tableInstanceMap, instancew);
163}
164
165VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
166{
167 VkLayerDispatchTable *layer_device_table = NULL;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600168 assert(devw);
169 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600170 VkLayerDispatchTable *base_device_table = *ppDisp;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600171
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600172 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
Jeremy Hayes70af09d2015-06-19 10:57:11 -0600173 if (it == map.end())
Jon Ashburn5a10d212015-06-01 10:02:09 -0600174 {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600175 layer_device_table = new VkLayerDispatchTable;
176 map[(void *) base_device_table] = layer_device_table;
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600177#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600178 fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600179#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600180 } else
181 {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600182#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600183 fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600184#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600185 return it->second;
186 }
187
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600188 layer_initialize_dispatch_table(layer_device_table, devw);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600189
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600190 return layer_device_table;
191}
192
193VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
194{
195 return initDeviceTable(tableMap, devw);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600196}