blob: 7253b5cd892c9dd9bc635a45d0f0ec9d89379597 [file] [log] [blame]
Cody Northropfab47c32017-11-19 14:37:45 -07001/*
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
32class StaticLogMessage {
33 public:
34 StaticLogMessage(const char* msg) {
35 ALOGI("%s", msg);
36 }
37};
38StaticLogMessage g_initMessage("nullLayer" xstr(LAYERNAME) " loaded");
39
40
41namespace {
42
43
44// Minimal dispatch table for this simple layer
45struct {
46 PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
47} g_VulkanDispatchTable;
48
49
50template<class T>
51VkResult 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
70static 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
74VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
75 return getProperties<VkLayerProperties>(1, &LAYER_PROPERTIES, pCount, pProperties);
76}
77
78VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice /* physicalDevice */, uint32_t *pCount,
79 VkLayerProperties *pProperties) {
80 return getProperties<VkLayerProperties>(0, NULL, pCount, pProperties);
81}
82
83VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char* /* pLayerName */, uint32_t *pCount,
84 VkExtensionProperties *pProperties) {
85 return getProperties<VkExtensionProperties>(0, NULL, pCount, pProperties);
86}
87
88VKAPI_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
93VKAPI_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
128VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice /* dev */, const char* /* funcName */) {
129 return nullptr;
130}
131
132VKAPI_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
146__attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
147 VkLayerProperties *pProperties) {
148 return EnumerateInstanceLayerProperties(pCount, pProperties);
149}
150
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
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
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
167__attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
168 return GetDeviceProcAddr(dev, funcName);
169}
170
171__attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
172 return GetInstanceProcAddr(instance, funcName);
173}