blob: 3cee6ddb727c6c8573de368ccc95fa42d975c4bf [file] [log] [blame]
Mark Lobodzinski6eda00a2016-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.
Jon Ashburn9eed2892015-06-01 10:02:09 -06004 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07005 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and/or associated documentation files (the "Materials"), to
7 * deal in the Materials without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Materials, and to permit persons to whom the Materials
10 * are furnished to do so, subject to the following conditions:
Jon Ashburn9eed2892015-06-01 10:02:09 -060011 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070012 * The above copyright notice(s) and this permission notice shall be included
13 * in all copies or substantial portions of the Materials.
Jon Ashburn9eed2892015-06-01 10:02:09 -060014 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070015 * The Materials are Confidential Information as defined by the Khronos
16 * Membership Agreement until designated non-confidential by Khronos, at which
17 * point this condition clause shall be removed.
Jon Ashburn9eed2892015-06-01 10:02:09 -060018 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070019 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jon Ashburn9eed2892015-06-01 10:02:09 -060020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 *
23 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
24 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
26 * USE OR OTHER DEALINGS IN THE MATERIALS
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060027 *
28 * Author: Tobin Ehlis <tobin@lunarg.com>
Jon Ashburn9eed2892015-06-01 10:02:09 -060029 */
30#include <assert.h>
31#include <unordered_map>
32#include "vk_dispatch_table_helper.h"
David Pinedo9316d3b2015-11-06 12:54:48 -070033#include "vulkan/vk_layer.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060034#include "vk_layer_table.h"
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060035static device_table_map tableMap;
36static instance_table_map tableInstanceMap;
Jon Ashburn9eed2892015-06-01 10:02:09 -060037
Jon Ashburn94f36d92015-06-15 09:30:12 -060038#define DISPATCH_MAP_DEBUG 0
Jon Ashburn9eed2892015-06-01 10:02:09 -060039
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060040// Map lookup must be thread safe
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060041VkLayerDispatchTable *device_dispatch_table(void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060042{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060043 dispatch_key key = get_dispatch_key(object);
44 device_table_map::const_iterator it = tableMap.find((void *) key);
45 assert(it != tableMap.end() && "Not able to find device dispatch entry");
46 return it->second;
47}
48
Tobin Ehlisa30e7e52015-07-06 14:02:36 -060049VkLayerInstanceDispatchTable *instance_dispatch_table(void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060050{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060051 dispatch_key key = get_dispatch_key(object);
52 instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060053#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060054 if (it != tableInstanceMap.end()) {
55 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
56 } else {
57 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
58 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060059#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060060 assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
61 return it->second;
62}
63
64void destroy_dispatch_table(device_table_map &map, dispatch_key key)
65{
66 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060067#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060068 if (it != map.end()) {
69 fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
70 } else {
71 fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
72 assert(it != map.end());
73 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060074#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060075 map.erase(key);
76}
77
78void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
79{
80 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060081#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060082 if (it != map.end()) {
83 fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
84 } else {
85 fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
86 assert(it != map.end());
87 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -060088#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -060089 map.erase(key);
90}
91
92void destroy_device_dispatch_table(dispatch_key key)
93{
94 destroy_dispatch_table(tableMap, key);
95}
96
97void destroy_instance_dispatch_table(dispatch_key key)
98{
99 destroy_dispatch_table(tableInstanceMap, key);
100}
101
Tobin Ehlisa30e7e52015-07-06 14:02:36 -0600102VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600103{
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600104 dispatch_key key = get_dispatch_key(object);
105 device_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600106#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600107 if (it != map.end()) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700108 fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600109 } else {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700110 fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600111 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600112#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600113 assert(it != map.end() && "Not able to find device dispatch entry");
114 return it->second;
115}
116
Tobin Ehlisa30e7e52015-07-06 14:02:36 -0600117VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object)
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600118{
119// VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
120 dispatch_key key = get_dispatch_key(object);
121 instance_table_map::const_iterator it = map.find((void *) key);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600122#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600123 if (it != map.end()) {
124 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
125 } else {
126 fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
127 }
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600128#endif
Courtney Goeltzenleuchterc08e72d2015-06-13 21:18:30 -0600129 assert(it != map.end() && "Not able to find instance dispatch entry");
130 return it->second;
131}
132
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700133VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func)
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700134{
135 VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *) pCreateInfo->pNext;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700136 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
137 && chain_info->function == func)) {
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700138 chain_info = (VkLayerInstanceCreateInfo *) chain_info->pNext;
139 }
140 assert(chain_info != NULL);
141 return chain_info;
142}
143
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700144VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func)
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700145{
146 VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *) pCreateInfo->pNext;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700147 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
148 && chain_info->function == func)) {
Courtney Goeltzenleuchter93a89cc2016-01-08 11:52:37 -0700149 chain_info = (VkLayerDeviceCreateInfo *) chain_info->pNext;
150 }
151 assert(chain_info != NULL);
152 return chain_info;
153}
154
Jon Ashburn9eed2892015-06-01 10:02:09 -0600155/* Various dispatchable objects will use the same underlying dispatch table if they
156 * are created from that "parent" object. Thus use pointer to dispatch table
157 * as the key to these table maps.
158 * Instance -> PhysicalDevice
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800159 * Device -> CommandBuffer or Queue
Jon Ashburn9eed2892015-06-01 10:02:09 -0600160 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
161 * and a new key inserted into map */
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700162VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600163{
164 VkLayerInstanceDispatchTable *pTable;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700165 dispatch_key key = get_dispatch_key(instance);
166 instance_table_map::const_iterator it = map.find((void *) key);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600167
Jeremy Hayesd427d722015-06-19 10:57:11 -0600168 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600169 {
170 pTable = new VkLayerInstanceDispatchTable;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700171 map[(void *) key] = pTable;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600172#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700173 fprintf(stderr, "New, Instance: map: %p, key: %p, table: %p\n", &map, key, pTable);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600174#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600175 } else
176 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600177#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700178 fprintf(stderr, "Instance: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600179#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600180 return it->second;
181 }
182
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700183 layer_init_instance_dispatch_table(instance, pTable, gpa);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600184
185 return pTable;
186}
187
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700188VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa)
Jon Ashburn9eed2892015-06-01 10:02:09 -0600189{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700190 return initInstanceTable(instance, gpa, tableInstanceMap);
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600191}
192
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700193VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map)
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600194{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700195 VkLayerDispatchTable *pTable;
196 dispatch_key key = get_dispatch_key(device);
197 device_table_map::const_iterator it = map.find((void *) key);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600198
Jeremy Hayesd427d722015-06-19 10:57:11 -0600199 if (it == map.end())
Jon Ashburn9eed2892015-06-01 10:02:09 -0600200 {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700201 pTable = new VkLayerDispatchTable;
202 map[(void *) key] = pTable;
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600203#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700204 fprintf(stderr, "New, Device: map: %p, key: %p, table: %p\n", &map, key, pTable);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600205#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600206 } else
207 {
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600208#if DISPATCH_MAP_DEBUG
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700209 fprintf(stderr, "Device: map: %p, key: %p, table: %p\n", &map, key, it->second);
Courtney Goeltzenleuchtere3d3f5d2015-06-13 21:48:26 -0600210#endif
Jon Ashburn9eed2892015-06-01 10:02:09 -0600211 return it->second;
212 }
213
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700214 layer_init_device_dispatch_table(device, pTable, gpa);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600215
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700216 return pTable;
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600217}
218
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700219VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa)
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600220{
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700221 return initDeviceTable(device, gpa, tableMap);
Jon Ashburn9eed2892015-06-01 10:02:09 -0600222}