• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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