blob: 153f565c395f2966b7ef418f9d77dce811d2e177 [file] [log] [blame]
Mark Lobodzinski288e4f72016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
Michael Lentine584ccab2016-02-03 16:51:46 -06004 * Copyright (c) 2015-2016 Google, Inc.
Jon Ashburn5a10d212015-06-01 10:02:09 -06005 *
Mark Lobodzinski288e4f72016-02-02 15:55:36 -07006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials
11 * are furnished to do so, subject to the following conditions:
Jon Ashburn5a10d212015-06-01 10:02:09 -060012 *
Mark Lobodzinski288e4f72016-02-02 15:55:36 -070013 * The above copyright notice(s) and this permission notice shall be included
14 * in all copies or substantial portions of the Materials.
Jon Ashburn5a10d212015-06-01 10:02:09 -060015 *
Mark Lobodzinski288e4f72016-02-02 15:55:36 -070016 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jon Ashburn5a10d212015-06-01 10:02:09 -060017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Mark Lobodzinski288e4f72016-02-02 15:55:36 -070018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 *
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23 * USE OR OTHER DEALINGS IN THE MATERIALS
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060024 *
25 * Author: Tobin Ehlis <tobin@lunarg.com>
Jon Ashburn5a10d212015-06-01 10:02:09 -060026 */
27#include <assert.h>
28#include <unordered_map>
29#include "vk_dispatch_table_helper.h"
David Pinedo329ca9e2015-11-06 12:54:48 -070030#include "vulkan/vk_layer.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060031#include "vk_layer_table.h"
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060032static device_table_map tableMap;
33static instance_table_map tableInstanceMap;
Jon Ashburn5a10d212015-06-01 10:02:09 -060034
Jon Ashburn4ec582f2015-06-15 09:30:12 -060035#define DISPATCH_MAP_DEBUG 0
Jon Ashburn5a10d212015-06-01 10:02:09 -060036
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060037// Map lookup must be thread safe
Jon Ashburn491a3cd2016-03-08 17:48:44 -070038VkLayerDispatchTable *device_dispatch_table(void *object) {
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060039 dispatch_key key = get_dispatch_key(object);
Jon Ashburn491a3cd2016-03-08 17:48:44 -070040 device_table_map::const_iterator it = tableMap.find((void *)key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060041 assert(it != tableMap.end() && "Not able to find device dispatch entry");
42 return it->second;
43}
44
Jon Ashburn491a3cd2016-03-08 17:48:44 -070045VkLayerInstanceDispatchTable *instance_dispatch_table(void *object) {
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060046 dispatch_key key = get_dispatch_key(object);
Jon Ashburn491a3cd2016-03-08 17:48:44 -070047 instance_table_map::const_iterator it = tableInstanceMap.find((void *)key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060048#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060049 if (it != tableInstanceMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -070050 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key,
51 it->second);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060052 } else {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070053 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060054 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060055#endif
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070056 assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060057 return it->second;
58}
59
Jon Ashburn491a3cd2016-03-08 17:48:44 -070060void destroy_dispatch_table(device_table_map &map, dispatch_key key) {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060061#if DISPATCH_MAP_DEBUG
Michael Lentine584ccab2016-02-03 16:51:46 -060062 device_table_map::const_iterator it = map.find((void *)key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060063 if (it != map.end()) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070064 fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060065 } else {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070066 fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060067 assert(it != map.end());
68 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060069#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060070 map.erase(key);
71}
72
Jon Ashburn491a3cd2016-03-08 17:48:44 -070073void destroy_dispatch_table(instance_table_map &map, dispatch_key key) {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060074#if DISPATCH_MAP_DEBUG
Michael Lentine584ccab2016-02-03 16:51:46 -060075 instance_table_map::const_iterator it = map.find((void *)key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060076 if (it != map.end()) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070077 fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060078 } else {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070079 fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060080 assert(it != map.end());
81 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060082#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060083 map.erase(key);
84}
85
Jon Ashburn491a3cd2016-03-08 17:48:44 -070086void destroy_device_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableMap, key); }
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060087
Jon Ashburn491a3cd2016-03-08 17:48:44 -070088void destroy_instance_dispatch_table(dispatch_key key) { destroy_dispatch_table(tableInstanceMap, key); }
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060089
Jon Ashburn491a3cd2016-03-08 17:48:44 -070090VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void *object) {
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060091 dispatch_key key = get_dispatch_key(object);
Jon Ashburn491a3cd2016-03-08 17:48:44 -070092 device_table_map::const_iterator it = map.find((void *)key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -060093#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060094 if (it != map.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -070095 fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key,
96 it->second);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060097 } else {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070098 fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -060099 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600100#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600101 assert(it != map.end() && "Not able to find device dispatch entry");
102 return it->second;
103}
104
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700105VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void *object) {
106 // VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600107 dispatch_key key = get_dispatch_key(object);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700108 instance_table_map::const_iterator it = map.find((void *)key);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600109#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600110 if (it != map.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700111 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key,
112 it->second);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600113 } else {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700114 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600115 }
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600116#endif
Courtney Goeltzenleuchterfde3a532015-06-13 21:18:30 -0600117 assert(it != map.end() && "Not able to find instance dispatch entry");
118 return it->second;
119}
120
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700121VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func) {
122 VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
123 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) {
124 chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext;
Courtney Goeltzenleuchtercfbccd82016-01-08 11:52:37 -0700125 }
126 assert(chain_info != NULL);
127 return chain_info;
128}
129
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700130VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func) {
131 VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
132 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) {
133 chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext;
Courtney Goeltzenleuchtercfbccd82016-01-08 11:52:37 -0700134 }
135 assert(chain_info != NULL);
136 return chain_info;
137}
138
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700139/* Various dispatchable objects will use the same underlying dispatch table if they
Jon Ashburn5a10d212015-06-01 10:02:09 -0600140 * are created from that "parent" object. Thus use pointer to dispatch table
141 * as the key to these table maps.
142 * Instance -> PhysicalDevice
Chia-I Wu1f851912015-10-27 18:04:07 +0800143 * Device -> CommandBuffer or Queue
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700144 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
Jon Ashburn5a10d212015-06-01 10:02:09 -0600145 * and a new key inserted into map */
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700146VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map) {
Jon Ashburn5a10d212015-06-01 10:02:09 -0600147 VkLayerInstanceDispatchTable *pTable;
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700148 dispatch_key key = get_dispatch_key(instance);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700149 instance_table_map::const_iterator it = map.find((void *)key);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600150
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700151 if (it == map.end()) {
152 pTable = new VkLayerInstanceDispatchTable;
153 map[(void *)key] = pTable;
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600154#if DISPATCH_MAP_DEBUG
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700155 fprintf(stderr, "New, Instance: map: %p, key: %p, table: %p\n", &map, key, pTable);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600156#endif
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700157 } else {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600158#if DISPATCH_MAP_DEBUG
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700159 fprintf(stderr, "Instance: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600160#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600161 return it->second;
162 }
163
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700164 layer_init_instance_dispatch_table(instance, pTable, gpa);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600165
166 return pTable;
167}
168
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700169VkLayerInstanceDispatchTable *initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa) {
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700170 return initInstanceTable(instance, gpa, tableInstanceMap);
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600171}
172
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700173VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map) {
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700174 VkLayerDispatchTable *pTable;
175 dispatch_key key = get_dispatch_key(device);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700176 device_table_map::const_iterator it = map.find((void *)key);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600177
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700178 if (it == map.end()) {
179 pTable = new VkLayerDispatchTable;
180 map[(void *)key] = pTable;
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600181#if DISPATCH_MAP_DEBUG
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700182 fprintf(stderr, "New, Device: map: %p, key: %p, table: %p\n", &map, key, pTable);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600183#endif
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700184 } else {
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600185#if DISPATCH_MAP_DEBUG
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700186 fprintf(stderr, "Device: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchter2906bb52015-06-13 21:48:26 -0600187#endif
Jon Ashburn5a10d212015-06-01 10:02:09 -0600188 return it->second;
189 }
190
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700191 layer_init_device_dispatch_table(device, pTable, gpa);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600192
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700193 return pTable;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600194}
195
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700196VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa) {
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700197 return initDeviceTable(device, gpa, tableMap);
Jon Ashburn5a10d212015-06-01 10:02:09 -0600198}