1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android/log.h>
18 #include <cstring>
19 #include <vulkan/vulkan.h>
20 #include "vk_layer_interface.h"
21
22 #define xstr(a) str(a)
23 #define str(a) #a
24
25 #define LOG_TAG "nullLayer" xstr(LAYERNAME)
26
27 #define ALOGI(msg, ...) \
28 __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
29
30
31 // Announce if anything loads this layer. LAYERNAME is defined in Android.mk
32 class StaticLogMessage {
33 public:
StaticLogMessage(const char * msg)34 StaticLogMessage(const char* msg) {
35 ALOGI("%s", msg);
36 }
37 };
38 StaticLogMessage g_initMessage("nullLayer" xstr(LAYERNAME) " loaded");
39
40
41 namespace {
42
43
44 // Minimal dispatch table for this simple layer
45 struct {
46 PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
47 PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
48 } g_VulkanDispatchTable;
49
50 template<class T>
getProperties(const uint32_t count,const T * properties,uint32_t * pCount,T * pProperties)51 VkResult getProperties(const uint32_t count, const T *properties, uint32_t *pCount,
52 T *pProperties) {
53 uint32_t copySize;
54
55 if (pProperties == NULL || properties == NULL) {
56 *pCount = count;
57 return VK_SUCCESS;
58 }
59
60 copySize = *pCount < count ? *pCount : count;
61 memcpy(pProperties, properties, copySize * sizeof(T));
62 *pCount = copySize;
63 if (copySize < count) {
64 return VK_INCOMPLETE;
65 }
66
67 return VK_SUCCESS;
68 }
69
70 static const VkLayerProperties LAYER_PROPERTIES = {
71 "VK_LAYER_ANDROID_nullLayer" xstr(LAYERNAME), VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION), 1, "Layer: nullLayer" xstr(LAYERNAME),
72 };
73
EnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)74 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
75 return getProperties<VkLayerProperties>(1, &LAYER_PROPERTIES, pCount, pProperties);
76 }
77
EnumerateDeviceLayerProperties(VkPhysicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)78 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice /* physicalDevice */, uint32_t *pCount,
79 VkLayerProperties *pProperties) {
80 return getProperties<VkLayerProperties>(0, NULL, pCount, pProperties);
81 }
82
EnumerateInstanceExtensionProperties(const char *,uint32_t * pCount,VkExtensionProperties * pProperties)83 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char* /* pLayerName */, uint32_t *pCount,
84 VkExtensionProperties *pProperties) {
85 return getProperties<VkExtensionProperties>(0, NULL, pCount, pProperties);
86 }
87
EnumerateDeviceExtensionProperties(VkPhysicalDevice,const char *,uint32_t * pCount,VkExtensionProperties * pProperties)88 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice /* physicalDevice */, const char* /* pLayerName */,
89 uint32_t *pCount, VkExtensionProperties *pProperties) {
90 return getProperties<VkExtensionProperties>(0, NULL, pCount, pProperties);
91 }
92
nullCreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)93 VKAPI_ATTR VkResult VKAPI_CALL nullCreateDevice(VkPhysicalDevice physicalDevice,
94 const VkDeviceCreateInfo* pCreateInfo,
95 const VkAllocationCallbacks* pAllocator,
96 VkDevice* pDevice) {
97
98 VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo*)pCreateInfo->pNext;
99
100 const char* msg = "nullCreateDevice called in nullLayer" xstr(LAYERNAME);
101 ALOGI("%s", msg);
102
103 // Step through the pNext chain until we get to the link function
104 while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO ||
105 layerCreateInfo->function != VK_LAYER_FUNCTION_LINK)) {
106
107 layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext;
108 }
109
110 if(layerCreateInfo == NULL)
111 return VK_ERROR_INITIALIZATION_FAILED;
112
113 // Grab GDPA and GIPA for the next layer
114 PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
115 PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
116
117 // Track them in our dispatch table
118 g_VulkanDispatchTable.GetDeviceProcAddr = gdpa;
119 g_VulkanDispatchTable.GetInstanceProcAddr = gipa;
120
121 // Advance the chain for next layer
122 layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
123
124 // Call the next layer
125 PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice");
126 VkResult ret = createFunc(physicalDevice, pCreateInfo, pAllocator, pDevice);
127
128 return ret;
129 }
130
nullCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)131 VKAPI_ATTR VkResult VKAPI_CALL nullCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
132 const VkAllocationCallbacks* pAllocator,
133 VkInstance* pInstance) {
134
135 VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
136
137 const char* msg = "nullCreateInstance called in nullLayer" xstr(LAYERNAME);
138 ALOGI("%s", msg);
139
140 // Step through the pNext chain until we get to the link function
141 while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
142 layerCreateInfo->function != VK_LAYER_FUNCTION_LINK)) {
143
144 layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext;
145 }
146
147 if(layerCreateInfo == NULL)
148 return VK_ERROR_INITIALIZATION_FAILED;
149
150 // Grab GIPA for the next layer
151 PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
152
153 // Track it in our dispatch table
154 g_VulkanDispatchTable.GetInstanceProcAddr = gpa;
155
156 // Advance the chain for next layer
157 layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
158
159 // Call the next layer
160 PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance");
161 VkResult ret = createFunc(pCreateInfo, pAllocator, pInstance);
162
163 return ret;
164 }
165
GetDeviceProcAddr(VkDevice dev,const char * funcName)166 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice dev, const char* funcName) {
167
168 const char* targetFunc = "vkCreateDevice";
169 if (!strncmp(targetFunc, funcName, sizeof("vkCreateDevice"))) {
170 return (PFN_vkVoidFunction)nullCreateDevice;
171 }
172
173 return (PFN_vkVoidFunction)g_VulkanDispatchTable.GetDeviceProcAddr(dev, funcName);
174 }
175
GetInstanceProcAddr(VkInstance instance,const char * funcName)176 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName) {
177
178 const char* targetFunc = "vkCreateInstance";
179 if (!strncmp(targetFunc, funcName, sizeof("vkCreateInstance"))) {
180 return (PFN_vkVoidFunction)nullCreateInstance;
181 }
182
183 return (PFN_vkVoidFunction)g_VulkanDispatchTable.GetInstanceProcAddr(instance, funcName);
184 }
185
186 } // namespace
187
188 // loader-layer interface v0, just wrappers since there is only a layer
189
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)190 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
191 VkLayerProperties *pProperties) {
192 return EnumerateInstanceLayerProperties(pCount, pProperties);
193 }
194
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)195 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
196 VkLayerProperties *pProperties) {
197 return EnumerateDeviceLayerProperties(physicalDevice, pCount, pProperties);
198 }
199
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)200 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
201 VkExtensionProperties *pProperties) {
202 return EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
203 }
204
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)205 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
206 const char *pLayerName, uint32_t *pCount,
207 VkExtensionProperties *pProperties) {
208 return EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
209 }
210
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)211 __attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
212 return GetDeviceProcAddr(dev, funcName);
213 }
214
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)215 __attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
216 return GetInstanceProcAddr(instance, funcName);
217 }
218