blob: ed35fe012bf32ad85abcd677ec881aa502f22c1d [file] [log] [blame]
Jon Ashburn79113cc2014-12-01 14:22:40 -07001/*
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002 * Vulkan
Jon Ashburn79113cc2014-12-01 14:22:40 -07003 *
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 */
Jon Ashburn1fec4242014-11-26 11:10:26 -070024#include <string.h>
25#include <stdlib.h>
26#include <assert.h>
27#include <unordered_map>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070028#include "loader_platform.h"
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060029#include "vk_dispatch_table_helper.h"
30#include "vkLayer.h"
Ian Elliott655cad72015-02-12 17:08:34 -070031// The following is #included again to catch certain OS-specific functions
32// being used:
33#include "loader_platform.h"
Jon Ashburn1fec4242014-11-26 11:10:26 -070034
Jon Ashburnbacb0f52015-04-06 10:58:22 -060035static std::unordered_map<void *, VkLayerDispatchTable *> tableMap;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -060036static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap;
37
38static VkLayerInstanceDispatchTable * initLayerInstanceTable(const VkBaseLayerObject *instancew)
39{
40 VkLayerInstanceDispatchTable *pTable;
41
42 assert(instancew);
43 std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap.find((void *) instancew->baseObject);
44 if (it == tableInstanceMap.end())
45 {
46 pTable = new VkLayerInstanceDispatchTable;
47 tableInstanceMap[(void *) instancew->baseObject] = pTable;
48 } else
49 {
50 return it->second;
51 }
52
53 layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instancew->pGPA, (VkInstance) instancew->nextObject);
54
55 return pTable;
56}
Jon Ashburn1fec4242014-11-26 11:10:26 -070057
Jon Ashburnbacb0f52015-04-06 10:58:22 -060058static VkLayerDispatchTable * initLayerTable(const VkBaseLayerObject *gpuw)
Jon Ashburn1fec4242014-11-26 11:10:26 -070059{
Jon Ashburnbacb0f52015-04-06 10:58:22 -060060 VkLayerDispatchTable *pTable;
Jon Ashburn1fec4242014-11-26 11:10:26 -070061
62 assert(gpuw);
Jon Ashburn4d9f4652015-04-08 21:33:34 -060063 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap.find((void *) gpuw->baseObject);
Jon Ashburn1fec4242014-11-26 11:10:26 -070064 if (it == tableMap.end())
65 {
Jon Ashburnbacb0f52015-04-06 10:58:22 -060066 pTable = new VkLayerDispatchTable;
Jon Ashburn4d9f4652015-04-08 21:33:34 -060067 tableMap[(void *) gpuw->baseObject] = pTable;
Jon Ashburn1fec4242014-11-26 11:10:26 -070068 } else
69 {
70 return it->second;
71 }
Chia-I Wuaa4121f2015-01-04 23:11:43 +080072
Jon Ashburnf6b33db2015-05-05 14:22:52 -060073 layer_initialize_dispatch_table(pTable, (PFN_vkGetProcAddr) gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
Chia-I Wuaa4121f2015-01-04 23:11:43 +080074
Jon Ashburn1fec4242014-11-26 11:10:26 -070075 return pTable;
76}
77
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -060078VK_LAYER_EXPORT VkResult VKAPI vkLayerExtension1(VkDevice device)
Jon Ashburn1fec4242014-11-26 11:10:26 -070079{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060080 printf("In vkLayerExtension1() call w/ device: %p\n", (void*)device);
81 printf("vkLayerExtension1 returning SUCCESS\n");
82 return VK_SUCCESS;
Jon Ashburn1fec4242014-11-26 11:10:26 -070083}
84
Jon Ashburn9fd4cc42015-04-10 14:33:07 -060085struct extProps {
86 uint32_t version;
87 const char * const name;
88};
89#define BASIC_LAYER_EXT_ARRAY_SIZE 2
90static const struct extProps basicExts[BASIC_LAYER_EXT_ARRAY_SIZE] = {
91 // TODO what is the version?
92 0x10, "Basic",
93 0x10, "vkLayerExtension1"
94};
95
96VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
97 VkExtensionInfoType infoType,
98 uint32_t extensionIndex,
99 size_t* pDataSize,
100 void* pData)
101{
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600102 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
103 VkExtensionProperties *ext_props;
104 uint32_t *count;
105
106 if (pDataSize == NULL)
107 return VK_ERROR_INVALID_POINTER;
108
109 switch (infoType) {
110 case VK_EXTENSION_INFO_TYPE_COUNT:
111 *pDataSize = sizeof(uint32_t);
112 if (pData == NULL)
113 return VK_SUCCESS;
114 count = (uint32_t *) pData;
115 *count = BASIC_LAYER_EXT_ARRAY_SIZE;
116 break;
117 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
118 *pDataSize = sizeof(VkExtensionProperties);
119 if (pData == NULL)
120 return VK_SUCCESS;
121 if (extensionIndex >= BASIC_LAYER_EXT_ARRAY_SIZE)
122 return VK_ERROR_INVALID_VALUE;
123 ext_props = (VkExtensionProperties *) pData;
124 ext_props->version = basicExts[extensionIndex].version;
125 strncpy(ext_props->extName, basicExts[extensionIndex].name,
126 VK_MAX_EXTENSION_NAME);
127 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
128 break;
129 default:
130 return VK_ERROR_INVALID_VALUE;
131 };
132
133 return VK_SUCCESS;
134}
135
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600136VK_LAYER_EXPORT VkResult VKAPI vkEnumeratePhysicalDevices(
137 VkInstance instance,
138 uint32_t* pPhysicalDeviceCount,
139 VkPhysicalDevice* pPhysicalDevices)
140{
141 /* Need to intercept this entrypoint to add the physDev objects to instance map */
142 VkLayerInstanceDispatchTable* pInstTable = tableInstanceMap[instance];
143 printf("At start of wrapped vkEnumeratePhysicalDevices() call w/ inst: %p\n", (void*)instance);
144 VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
145 if (pPhysicalDevices)
146 {
147 // create a mapping for the objects into the dispatch table
148 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
149 {
150 tableInstanceMap.emplace(*(pPhysicalDevices + i), pInstTable);
151 }
152 }
153 printf("Completed wrapped vkEnumeratePhysicalDevices() call w/ count %u\n", *pPhysicalDeviceCount);
154 return result;
155}
156
Tony Barbourd1c35722015-04-16 15:59:00 -0600157VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
Jon Ashburn1fec4242014-11-26 11:10:26 -0700158{
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600159 VkLayerInstanceDispatchTable* pInstTable = tableInstanceMap[gpu];
Jon Ashburn1fec4242014-11-26 11:10:26 -0700160
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600161 printf("At start of wrapped vkCreateDevice() call w/ gpu: %p\n", (void*)gpu);
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600162 VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600163 printf("Completed wrapped vkCreateDevice() call w/ pDevice, Device %p: %p\n", (void*)pDevice, (void *) *pDevice);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700164 return result;
165}
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600166
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600167VK_LAYER_EXPORT VkResult VKAPI vkGetFormatInfo(VkDevice device, VkFormat format, VkFormatInfoType infoType, size_t* pDataSize, void* pData)
Jon Ashburn1fec4242014-11-26 11:10:26 -0700168{
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600169 VkLayerDispatchTable* pTable = tableMap[device];
Jon Ashburn1fec4242014-11-26 11:10:26 -0700170
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600171 printf("At start of wrapped vkGetFormatInfo() call w/ device: %p\n", (void*)device);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600172 VkResult result = pTable->GetFormatInfo(device, format, infoType, pDataSize, pData);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600173 printf("Completed wrapped vkGetFormatInfo() call w/ device: %p\n", (void*)device);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700174 return result;
175}
176
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600177VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize, size_t* pLayerCount, char* const* pOutLayers, void* pReserved)
Jon Ashburn1fec4242014-11-26 11:10:26 -0700178{
179 if (gpu != NULL)
180 {
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600181 VkLayerInstanceDispatchTable* pTable = initLayerInstanceTable((const VkBaseLayerObject *) gpu);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700182
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600183 printf("At start of wrapped vkEnumerateLayers() call w/ gpu: %p\n", gpu);
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600184 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700185 return result;
186 } else
187 {
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600188 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pReserved == NULL)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600189 return VK_ERROR_INVALID_POINTER;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700190
191 // Example of a layer that is only compatible with Intel's GPUs
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600192 VkBaseLayerObject* gpuw = (VkBaseLayerObject*) pReserved;
Tony Barbourd1c35722015-04-16 15:59:00 -0600193 PFN_vkGetPhysicalDeviceInfo fpGetGpuInfo;
194 VkPhysicalDeviceProperties gpuProps;
195 size_t dataSize = sizeof(VkPhysicalDeviceProperties);
196 fpGetGpuInfo = (PFN_vkGetPhysicalDeviceInfo) gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, "vkGetPhysicalDeviceInfo");
197 fpGetGpuInfo((VkPhysicalDevice) gpuw->nextObject, VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES, &dataSize, &gpuProps);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700198 if (gpuProps.vendorId == 0x8086)
199 {
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600200 *pLayerCount = 1;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700201 strncpy((char *) pOutLayers[0], "Basic", maxStringSize);
202 } else
203 {
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600204 *pLayerCount = 0;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700205 }
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600206 return VK_SUCCESS;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700207 }
208}
209
Tony Barbourd1c35722015-04-16 15:59:00 -0600210VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700211{
Jon Ashburn1fec4242014-11-26 11:10:26 -0700212 if (gpu == NULL)
213 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800214
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600215 initLayerTable((const VkBaseLayerObject *) gpu);
Chia-I Wub665d942015-01-05 09:41:27 +0800216
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600217 if (!strcmp("vkGetProcAddr", pName))
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600218 return (void *) vkGetProcAddr;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600219 if (!strcmp("vkCreateDevice", pName))
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600220 return (void *) vkCreateDevice;
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600221 if (!strcmp("vkEnumeratePhysicalDevices", pName))
222 return (void*) vkEnumeratePhysicalDevices;
223 if (!strcmp("vkGetGlobalExtensionInfo", pName))
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600224 return (void*) vkGetGlobalExtensionInfo;
225 if (!strcmp("vkEnumerateLayers", pName))
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600226 return (void *) vkEnumerateLayers;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600227 if (!strcmp("vkGetFormatInfo", pName))
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600228 return (void *) vkGetFormatInfo;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600229 if (!strcmp("vkLayerExtension1", pName))
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600230 return (void *) vkLayerExtension1;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700231 else {
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600232 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700233 if (gpuw->pGPA == NULL)
234 return NULL;
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600235 return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
236 }
237}
238
239VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* pName)
240{
241 if (instance == NULL)
242 return NULL;
243
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600244 initLayerInstanceTable((const VkBaseLayerObject *) instance);
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600245
246 if (!strcmp("vkGetInstanceProcAddr", pName))
247 return (void *) vkGetInstanceProcAddr;
248 if (!strcmp("vkGetProcAddr", pName))
249 return (void *) vkGetProcAddr;
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600250 if (!strcmp("vkEnumeratePhysicalDevices", pName))
251 return (void*) vkEnumeratePhysicalDevices;
252 if (!strcmp("vkGetGlobalExtensionInfo", pName))
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600253 return (void*) vkGetGlobalExtensionInfo;
254 if (!strcmp("vkCreateDevice", pName))
255 return (void *) vkCreateDevice;
256 if (!strcmp("vkEnumerateLayers", pName))
257 return (void *) vkEnumerateLayers;
258 else {
259 VkBaseLayerObject* instancew = (VkBaseLayerObject *) instance;
260 if (instancew->pGPA == NULL)
261 return NULL;
262 return instancew->pGPA((VkObject) instancew->nextObject, pName);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700263 }
264}