Home | History | Annotate | Download | only in jni
      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:
     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>
     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 
     74 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
     75     return getProperties<VkLayerProperties>(1, &LAYER_PROPERTIES, pCount, pProperties);
     76 }
     77 
     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 
     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 
     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 
     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 
    128 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice /* dev */, const char* /* funcName */) {
    129     return nullptr;
    130 }
    131 
    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 
    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 }
    174