blob: 260f7c3d94e00af707d73d7453f027707e5dd8f7 [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 Ashburn1fec4242014-11-26 11:10:26 -070036
Jon Ashburnbacb0f52015-04-06 10:58:22 -060037static VkLayerDispatchTable * initLayerTable(const VkBaseLayerObject *gpuw)
Jon Ashburn1fec4242014-11-26 11:10:26 -070038{
Jon Ashburnbacb0f52015-04-06 10:58:22 -060039 VkLayerDispatchTable *pTable;
Jon Ashburn1fec4242014-11-26 11:10:26 -070040
41 assert(gpuw);
Jon Ashburn4d9f4652015-04-08 21:33:34 -060042 std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap.find((void *) gpuw->baseObject);
Jon Ashburn1fec4242014-11-26 11:10:26 -070043 if (it == tableMap.end())
44 {
Jon Ashburnbacb0f52015-04-06 10:58:22 -060045 pTable = new VkLayerDispatchTable;
Jon Ashburn4d9f4652015-04-08 21:33:34 -060046 tableMap[(void *) gpuw->baseObject] = pTable;
Jon Ashburn1fec4242014-11-26 11:10:26 -070047 } else
48 {
49 return it->second;
50 }
Chia-I Wuaa4121f2015-01-04 23:11:43 +080051
Tony Barbourd1c35722015-04-16 15:59:00 -060052 layer_initialize_dispatch_table(pTable, gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
Chia-I Wuaa4121f2015-01-04 23:11:43 +080053
Jon Ashburn1fec4242014-11-26 11:10:26 -070054 return pTable;
55}
56
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -060057VK_LAYER_EXPORT VkResult VKAPI vkLayerExtension1(VkDevice device)
Jon Ashburn1fec4242014-11-26 11:10:26 -070058{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060059 printf("In vkLayerExtension1() call w/ device: %p\n", (void*)device);
60 printf("vkLayerExtension1 returning SUCCESS\n");
61 return VK_SUCCESS;
Jon Ashburn1fec4242014-11-26 11:10:26 -070062}
63
Jon Ashburn9fd4cc42015-04-10 14:33:07 -060064struct extProps {
65 uint32_t version;
66 const char * const name;
67};
68#define BASIC_LAYER_EXT_ARRAY_SIZE 2
69static const struct extProps basicExts[BASIC_LAYER_EXT_ARRAY_SIZE] = {
70 // TODO what is the version?
71 0x10, "Basic",
72 0x10, "vkLayerExtension1"
73};
74
75VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
76 VkExtensionInfoType infoType,
77 uint32_t extensionIndex,
78 size_t* pDataSize,
79 void* pData)
80{
Jon Ashburn9fd4cc42015-04-10 14:33:07 -060081 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
82 VkExtensionProperties *ext_props;
83 uint32_t *count;
84
85 if (pDataSize == NULL)
86 return VK_ERROR_INVALID_POINTER;
87
88 switch (infoType) {
89 case VK_EXTENSION_INFO_TYPE_COUNT:
90 *pDataSize = sizeof(uint32_t);
91 if (pData == NULL)
92 return VK_SUCCESS;
93 count = (uint32_t *) pData;
94 *count = BASIC_LAYER_EXT_ARRAY_SIZE;
95 break;
96 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
97 *pDataSize = sizeof(VkExtensionProperties);
98 if (pData == NULL)
99 return VK_SUCCESS;
100 if (extensionIndex >= BASIC_LAYER_EXT_ARRAY_SIZE)
101 return VK_ERROR_INVALID_VALUE;
102 ext_props = (VkExtensionProperties *) pData;
103 ext_props->version = basicExts[extensionIndex].version;
104 strncpy(ext_props->extName, basicExts[extensionIndex].name,
105 VK_MAX_EXTENSION_NAME);
106 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
107 break;
108 default:
109 return VK_ERROR_INVALID_VALUE;
110 };
111
112 return VK_SUCCESS;
113}
114
Tony Barbourd1c35722015-04-16 15:59:00 -0600115VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
Jon Ashburn1fec4242014-11-26 11:10:26 -0700116{
Jon Ashburn4d9f4652015-04-08 21:33:34 -0600117 VkLayerDispatchTable* pTable = tableMap[gpu];
Jon Ashburn1fec4242014-11-26 11:10:26 -0700118
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600119 printf("At start of wrapped vkCreateDevice() call w/ gpu: %p\n", (void*)gpu);
Jon Ashburn4d9f4652015-04-08 21:33:34 -0600120 VkResult result = pTable->CreateDevice(gpu, pCreateInfo, pDevice);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700121 // create a mapping for the device object into the dispatch table
122 tableMap.emplace(*pDevice, pTable);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600123 printf("Completed wrapped vkCreateDevice() call w/ pDevice, Device %p: %p\n", (void*)pDevice, (void *) *pDevice);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700124 return result;
125}
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600126VK_LAYER_EXPORT VkResult VKAPI vkGetFormatInfo(VkDevice device, VkFormat format, VkFormatInfoType infoType, size_t* pDataSize, void* pData)
Jon Ashburn1fec4242014-11-26 11:10:26 -0700127{
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600128 VkLayerDispatchTable* pTable = tableMap[device];
Jon Ashburn1fec4242014-11-26 11:10:26 -0700129
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600130 printf("At start of wrapped vkGetFormatInfo() call w/ device: %p\n", (void*)device);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600131 VkResult result = pTable->GetFormatInfo(device, format, infoType, pDataSize, pData);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600132 printf("Completed wrapped vkGetFormatInfo() call w/ device: %p\n", (void*)device);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700133 return result;
134}
135
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600136VK_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 -0700137{
138 if (gpu != NULL)
139 {
Jon Ashburn4d9f4652015-04-08 21:33:34 -0600140 VkLayerDispatchTable* pTable = initLayerTable((const VkBaseLayerObject *) gpu);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700141
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600142 printf("At start of wrapped vkEnumerateLayers() call w/ gpu: %p\n", gpu);
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600143 VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700144 return result;
145 } else
146 {
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600147 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pReserved == NULL)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600148 return VK_ERROR_INVALID_POINTER;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700149
150 // Example of a layer that is only compatible with Intel's GPUs
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600151 VkBaseLayerObject* gpuw = (VkBaseLayerObject*) pReserved;
Tony Barbourd1c35722015-04-16 15:59:00 -0600152 PFN_vkGetPhysicalDeviceInfo fpGetGpuInfo;
153 VkPhysicalDeviceProperties gpuProps;
154 size_t dataSize = sizeof(VkPhysicalDeviceProperties);
155 fpGetGpuInfo = (PFN_vkGetPhysicalDeviceInfo) gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, "vkGetPhysicalDeviceInfo");
156 fpGetGpuInfo((VkPhysicalDevice) gpuw->nextObject, VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES, &dataSize, &gpuProps);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700157 if (gpuProps.vendorId == 0x8086)
158 {
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600159 *pLayerCount = 1;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700160 strncpy((char *) pOutLayers[0], "Basic", maxStringSize);
161 } else
162 {
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -0600163 *pLayerCount = 0;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700164 }
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600165 return VK_SUCCESS;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700166 }
167}
168
Tony Barbourd1c35722015-04-16 15:59:00 -0600169VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700170{
Jon Ashburn1fec4242014-11-26 11:10:26 -0700171 if (gpu == NULL)
172 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800173
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600174 initLayerTable((const VkBaseLayerObject *) gpu);
Chia-I Wub665d942015-01-05 09:41:27 +0800175
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600176 if (!strncmp("vkGetProcAddr", pName, sizeof("vkGetProcAddr")))
177 return (void *) vkGetProcAddr;
178 else if (!strncmp("vkCreateDevice", pName, sizeof ("vkCreateDevice")))
179 return (void *) vkCreateDevice;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600180 else if (!strncmp("vkEnumerateLayers", pName, sizeof ("vkEnumerateLayers")))
181 return (void *) vkEnumerateLayers;
182 else if (!strncmp("vkGetFormatInfo", pName, sizeof ("vkGetFormatInfo")))
183 return (void *) vkGetFormatInfo;
184 else if (!strncmp("vkLayerExtension1", pName, sizeof("vkLayerExtension1")))
185 return (void *) vkLayerExtension1;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700186 else {
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600187 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700188 if (gpuw->pGPA == NULL)
189 return NULL;
Tony Barbourd1c35722015-04-16 15:59:00 -0600190 return gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, pName);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700191 }
192}