• 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_vkGetInstanceProcAddr GetInstanceProcAddr;
47 } g_VulkanDispatchTable;
48 
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 
nullCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)93 VKAPI_ATTR VkResult VKAPI_CALL nullCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
94                                                   const VkAllocationCallbacks* pAllocator,
95                                                   VkInstance* pInstance) {
96 
97     VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
98 
99     const char* msg = "nullCreateInstance called in nullLayer" xstr(LAYERNAME);
100     ALOGI("%s", msg);
101 
102     // Step through the pNext chain until we get to the link function
103     while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
104                               layerCreateInfo->function != VK_LAYER_FUNCTION_LINK)) {
105 
106       layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext;
107     }
108 
109     if(layerCreateInfo == NULL)
110       return VK_ERROR_INITIALIZATION_FAILED;
111 
112     // Grab GIPA for the next layer
113     PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
114 
115     // Track is in our dispatch table
116     g_VulkanDispatchTable.GetInstanceProcAddr = gpa;
117 
118     // Advance the chain for next layer
119     layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
120 
121     // Call the next layer
122     PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance");
123     VkResult ret = createFunc(pCreateInfo, pAllocator, pInstance);
124 
125     return ret;
126 }
127 
GetDeviceProcAddr(VkDevice,const char *)128 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice /* dev */, const char* /* funcName */) {
129     return nullptr;
130 }
131 
GetInstanceProcAddr(VkInstance instance,const char * funcName)132 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName) {
133 
134     // Our simple layer only intercepts vkCreateInstance
135     const char* targetFunc = "vkCreateInstance";
136     if (!strncmp(targetFunc, funcName, sizeof(&targetFunc)))
137         return (PFN_vkVoidFunction)nullCreateInstance;
138 
139     return (PFN_vkVoidFunction)g_VulkanDispatchTable.GetInstanceProcAddr(instance, funcName);
140 }
141 
142 }  // namespace
143 
144 // loader-layer interface v0, just wrappers since there is only a layer
145 
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)146 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
147                                                                   VkLayerProperties *pProperties) {
148     return EnumerateInstanceLayerProperties(pCount, pProperties);
149 }
150 
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)151 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
152                                                                 VkLayerProperties *pProperties) {
153     return EnumerateDeviceLayerProperties(physicalDevice, pCount, pProperties);
154 }
155 
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)156 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
157                                                                       VkExtensionProperties *pProperties) {
158     return EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
159 }
160 
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)161 __attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
162                                                                     const char *pLayerName, uint32_t *pCount,
163                                                                     VkExtensionProperties *pProperties) {
164     return EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
165 }
166 
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)167 __attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
168     return GetDeviceProcAddr(dev, funcName);
169 }
170 
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)171 __attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
172     return GetInstanceProcAddr(instance, funcName);
173 }
174