blob: dbbb4911e971da0c1bbf4e306a2347d9338708e6 [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
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060035static std::unordered_map<void *, VK_LAYER_DISPATCH_TABLE *> tableMap;
Jon Ashburn1fec4242014-11-26 11:10:26 -070036
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060037static VK_LAYER_DISPATCH_TABLE * initLayerTable(const VK_BASE_LAYER_OBJECT *gpuw)
Jon Ashburn1fec4242014-11-26 11:10:26 -070038{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060039 VK_LAYER_DISPATCH_TABLE *pTable;
Jon Ashburn1fec4242014-11-26 11:10:26 -070040
41 assert(gpuw);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060042 std::unordered_map<void *, VK_LAYER_DISPATCH_TABLE *>::const_iterator it = tableMap.find((void *) gpuw);
Jon Ashburn1fec4242014-11-26 11:10:26 -070043 if (it == tableMap.end())
44 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060045 pTable = new VK_LAYER_DISPATCH_TABLE;
Mark Lobodzinski17caf572015-01-29 08:55:56 -060046 tableMap[(void *) gpuw] = 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
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060052 layer_initialize_dispatch_table(pTable, gpuw->pGPA, (VK_PHYSICAL_GPU) gpuw->nextObject);
Chia-I Wuaa4121f2015-01-04 23:11:43 +080053
Jon Ashburn1fec4242014-11-26 11:10:26 -070054 return pTable;
55}
56
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060057VK_LAYER_EXPORT VK_RESULT VKAPI vkLayerExtension1(VK_DEVICE 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
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060064VK_LAYER_EXPORT VK_RESULT VKAPI vkGetExtensionSupport(VK_PHYSICAL_GPU gpu, const char* pExtName)
Jon Ashburn1fec4242014-11-26 11:10:26 -070065{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060066 VK_RESULT result;
67 VK_BASE_LAYER_OBJECT* gpuw = (VK_BASE_LAYER_OBJECT *) gpu;
Jon Ashburn1fec4242014-11-26 11:10:26 -070068
Jon Ashburn5f3960e2015-04-02 12:06:28 -060069 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060070 if (!strncmp(pExtName, "vkLayerExtension1", strlen("vkLayerExtension1")))
Jon Ashburn5f3960e2015-04-02 12:06:28 -060071 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060072 result = VK_SUCCESS;
Jon Ashburn5f3960e2015-04-02 12:06:28 -060073 } else if (!strncmp(pExtName, "Basic", strlen("Basic")))
74 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060075 result = VK_SUCCESS;
Jon Ashburn5f3960e2015-04-02 12:06:28 -060076 } else if (!tableMap.empty() && (tableMap.find(gpuw) != tableMap.end()))
77 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060078 printf("At start of wrapped vkGetExtensionSupport() call w/ gpu: %p\n", (void*)gpu);
79 VK_LAYER_DISPATCH_TABLE* pTable = tableMap[gpuw];
80 result = pTable->GetExtensionSupport((VK_PHYSICAL_GPU)gpuw->nextObject, pExtName);
81 printf("Completed wrapped vkGetExtensionSupport() call w/ gpu: %p\n", (void*)gpu);
Jon Ashburn5f3960e2015-04-02 12:06:28 -060082 } else
83 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060084 result = VK_ERROR_INVALID_EXTENSION;
Jon Ashburn5f3960e2015-04-02 12:06:28 -060085 }
Jon Ashburn1fec4242014-11-26 11:10:26 -070086 return result;
87}
88
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060089VK_LAYER_EXPORT VK_RESULT VKAPI vkCreateDevice(VK_PHYSICAL_GPU gpu, const VK_DEVICE_CREATE_INFO* pCreateInfo, VK_DEVICE* pDevice)
Jon Ashburn1fec4242014-11-26 11:10:26 -070090{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060091 VK_BASE_LAYER_OBJECT* gpuw = (VK_BASE_LAYER_OBJECT *) gpu;
92 VK_LAYER_DISPATCH_TABLE* pTable = tableMap[gpuw];
Jon Ashburn1fec4242014-11-26 11:10:26 -070093
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060094 printf("At start of wrapped vkCreateDevice() call w/ gpu: %p\n", (void*)gpu);
95 VK_RESULT result = pTable->CreateDevice((VK_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
Jon Ashburn1fec4242014-11-26 11:10:26 -070096 // create a mapping for the device object into the dispatch table
97 tableMap.emplace(*pDevice, pTable);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060098 printf("Completed wrapped vkCreateDevice() call w/ pDevice, Device %p: %p\n", (void*)pDevice, (void *) *pDevice);
Jon Ashburn1fec4242014-11-26 11:10:26 -070099 return result;
100}
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600101VK_LAYER_EXPORT VK_RESULT VKAPI vkGetFormatInfo(VK_DEVICE device, VK_FORMAT format, VK_FORMAT_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Jon Ashburn1fec4242014-11-26 11:10:26 -0700102{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600103 VK_LAYER_DISPATCH_TABLE* pTable = tableMap[device];
Jon Ashburn1fec4242014-11-26 11:10:26 -0700104
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600105 printf("At start of wrapped vkGetFormatInfo() call w/ device: %p\n", (void*)device);
106 VK_RESULT result = pTable->GetFormatInfo(device, format, infoType, pDataSize, pData);
107 printf("Completed wrapped vkGetFormatInfo() call w/ device: %p\n", (void*)device);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700108 return result;
109}
110
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600111VK_LAYER_EXPORT VK_RESULT VKAPI vkEnumerateLayers(VK_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize, size_t* pOutLayerCount, char* const* pOutLayers, void* pReserved)
Jon Ashburn1fec4242014-11-26 11:10:26 -0700112{
113 if (gpu != NULL)
114 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600115 VK_BASE_LAYER_OBJECT* gpuw = (VK_BASE_LAYER_OBJECT *) gpu;
116 VK_LAYER_DISPATCH_TABLE* pTable = initLayerTable(gpuw);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700117
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600118 printf("At start of wrapped vkEnumerateLayers() call w/ gpu: %p\n", gpu);
119 VK_RESULT result = pTable->EnumerateLayers((VK_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700120 return result;
121 } else
122 {
123 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pReserved == NULL)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600124 return VK_ERROR_INVALID_POINTER;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700125
126 // Example of a layer that is only compatible with Intel's GPUs
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600127 VK_BASE_LAYER_OBJECT* gpuw = (VK_BASE_LAYER_OBJECT*) pReserved;
128 vkGetGpuInfoType fpGetGpuInfo;
129 VK_PHYSICAL_GPU_PROPERTIES gpuProps;
130 size_t dataSize = sizeof(VK_PHYSICAL_GPU_PROPERTIES);
131 fpGetGpuInfo = (vkGetGpuInfoType) gpuw->pGPA((VK_PHYSICAL_GPU) gpuw->nextObject, "vkGetGpuInfo");
132 fpGetGpuInfo((VK_PHYSICAL_GPU) gpuw->nextObject, VK_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, &dataSize, &gpuProps);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700133 if (gpuProps.vendorId == 0x8086)
134 {
135 *pOutLayerCount = 1;
136 strncpy((char *) pOutLayers[0], "Basic", maxStringSize);
137 } else
138 {
139 *pOutLayerCount = 0;
140 }
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600141 return VK_SUCCESS;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700142 }
143}
144
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600145VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VK_PHYSICAL_GPU gpu, const char* pName)
Jon Ashburn79113cc2014-12-01 14:22:40 -0700146{
Jon Ashburn1fec4242014-11-26 11:10:26 -0700147 if (gpu == NULL)
148 return NULL;
Chia-I Wub665d942015-01-05 09:41:27 +0800149
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600150 initLayerTable((const VK_BASE_LAYER_OBJECT *) gpu);
Chia-I Wub665d942015-01-05 09:41:27 +0800151
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600152 if (!strncmp("vkGetProcAddr", pName, sizeof("vkGetProcAddr")))
153 return (void *) vkGetProcAddr;
154 else if (!strncmp("vkCreateDevice", pName, sizeof ("vkCreateDevice")))
155 return (void *) vkCreateDevice;
156 else if (!strncmp("vkGetExtensionSupport", pName, sizeof ("vkGetExtensionSupport")))
157 return (void *) vkGetExtensionSupport;
158 else if (!strncmp("vkEnumerateLayers", pName, sizeof ("vkEnumerateLayers")))
159 return (void *) vkEnumerateLayers;
160 else if (!strncmp("vkGetFormatInfo", pName, sizeof ("vkGetFormatInfo")))
161 return (void *) vkGetFormatInfo;
162 else if (!strncmp("vkLayerExtension1", pName, sizeof("vkLayerExtension1")))
163 return (void *) vkLayerExtension1;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700164 else {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600165 VK_BASE_LAYER_OBJECT* gpuw = (VK_BASE_LAYER_OBJECT *) gpu;
Jon Ashburn1fec4242014-11-26 11:10:26 -0700166 if (gpuw->pGPA == NULL)
167 return NULL;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600168 return gpuw->pGPA((VK_PHYSICAL_GPU) gpuw->nextObject, pName);
Jon Ashburn1fec4242014-11-26 11:10:26 -0700169 }
170}