blob: b2edb5c42d6c92b0072c6f8494cc94043f8ac6f7 [file] [log] [blame]
Jon Ashburn5a10d212015-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"
27#include "vkLayer.h"
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060028#include "layers_table.h"
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060029static device_table_map tableMap;
30static instance_table_map tableInstanceMap;
Jon Ashburn5a10d212015-06-01 10:02:09 -060031
Jon Ashburn4ec582f2015-06-15 09:30:12 -060032#define DISPATCH_MAP_DEBUG 0
Jon Ashburn5a10d212015-06-01 10:02:09 -060033
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060034// Map lookup must be thread safe
35VkLayerDispatchTable *device_dispatch_table(VkObject object)
36{
37// VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;
38 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
44VkLayerInstanceDispatchTable *instance_dispatch_table(VkObject object)
45{
46// VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
47 dispatch_key key = get_dispatch_key(object);
48 instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060049#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060050 if (it != tableInstanceMap.end()) {
51 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
52 } else {
53 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
54 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060055#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060056 assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
57 return it->second;
58}
59
60void destroy_dispatch_table(device_table_map &map, dispatch_key key)
61{
62 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060063#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060064 if (it != map.end()) {
65 fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
66 } else {
67 fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
68 assert(it != map.end());
69 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060070#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060071 map.erase(key);
72}
73
74void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
75{
76 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060077#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060078 if (it != map.end()) {
79 fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
80 } else {
81 fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
82 assert(it != map.end());
83 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060084#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060085 map.erase(key);
86}
87
88void destroy_device_dispatch_table(dispatch_key key)
89{
90 destroy_dispatch_table(tableMap, key);
91}
92
93void destroy_instance_dispatch_table(dispatch_key key)
94{
95 destroy_dispatch_table(tableInstanceMap, key);
96}
97
98VkLayerDispatchTable *get_dispatch_table(device_table_map &map, VkObject object)
99{
100// VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;
101 dispatch_key key = get_dispatch_key(object);
102 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600103#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600104 if (it != map.end()) {
105 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
106 } else {
107 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
108 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600109#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600110 assert(it != map.end() && "Not able to find device dispatch entry");
111 return it->second;
112}
113
114VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, VkObject object)
115{
116// VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
117 dispatch_key key = get_dispatch_key(object);
118 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600119#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600120 if (it != map.end()) {
121 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
122 } else {
123 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
124 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600125#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600126 assert(it != map.end() && "Not able to find instance dispatch entry");
127 return it->second;
128}
129
Jon Ashburn5a10d212015-06-01 10:02:09 -0600130/* Various dispatchable objects will use the same underlying dispatch table if they
131 * are created from that "parent" object. Thus use pointer to dispatch table
132 * as the key to these table maps.
133 * Instance -> PhysicalDevice
134 * Device -> CmdBuffer or Queue
135 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
136 * and a new key inserted into map */
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600137VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
Jon Ashburn5a10d212015-06-01 10:02:09 -0600138{
139 VkLayerInstanceDispatchTable *pTable;
140 assert(instancew);
141 VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;
142
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600143 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
Jeremy Hayes70af09d2015-06-19 10:57:11 -0600144 if (it == map.end())
Jon Ashburn5a10d212015-06-01 10:02:09 -0600145 {
146 pTable = new VkLayerInstanceDispatchTable;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600147 map[(void *) *ppDisp] = pTable;
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600148#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600149 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 -0600150#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600151 assert(map.size() <= 1 && "Instance dispatch table map has more than one entry");
Jon Ashburn5a10d212015-06-01 10:02:09 -0600152 } else
153 {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600154#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600155 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 -0600156#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600157 return it->second;
158 }
159
160 layer_init_instance_dispatch_table(pTable, instancew);
161
162 return pTable;
163}
164
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600165VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
Jon Ashburn5a10d212015-06-01 10:02:09 -0600166{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600167 return initInstanceTable(tableInstanceMap, instancew);
168}
169
170VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
171{
172 VkLayerDispatchTable *layer_device_table = NULL;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600173 assert(devw);
174 VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600175 VkLayerDispatchTable *base_device_table = *ppDisp;
Jon Ashburn5a10d212015-06-01 10:02:09 -0600176
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600177 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
Jeremy Hayes70af09d2015-06-19 10:57:11 -0600178 if (it == map.end())
Jon Ashburn5a10d212015-06-01 10:02:09 -0600179 {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600180 layer_device_table = new VkLayerDispatchTable;
181 map[(void *) base_device_table] = layer_device_table;
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600182#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600183 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 -0600184#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600185 } else
186 {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600187#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600188 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 -0600189#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600190 return it->second;
191 }
192
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600193 layer_initialize_dispatch_table(layer_device_table, devw);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600194
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600195 return layer_device_table;
196}
197
198VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
199{
200 return initDeviceTable(tableMap, devw);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600201}