You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
9.2 KiB
229 lines
9.2 KiB
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <cstring>
|
|
#include <string>
|
|
|
|
#include "vk_layer_interface.h"
|
|
#include <android/log.h>
|
|
#include <vulkan/vulkan.h>
|
|
|
|
#define xstr(a) str(a)
|
|
#define str(a) #a
|
|
|
|
#define LAYER_FULL_NAME "VK_LAYER_ANDROID_nullLayer" xstr(LAYERNAME)
|
|
#define LOG_TAG LAYER_FULL_NAME
|
|
|
|
#define ALOGI(msg, ...) \
|
|
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
|
|
|
|
#ifdef DEBUGUTILSPECVERSION
|
|
const VkExtensionProperties debug_utils_extension = {
|
|
"VK_EXT_debug_utils",
|
|
static_cast<uint32_t>(std::atoi(xstr(DEBUGUTILSPECVERSION))),
|
|
};
|
|
#endif
|
|
|
|
// Announce if anything loads this layer. LAYERNAME is defined in Android.mk
|
|
class StaticLogMessage {
|
|
public:
|
|
StaticLogMessage(const char* msg) {
|
|
ALOGI("%s", msg);
|
|
}
|
|
};
|
|
StaticLogMessage
|
|
g_initMessage("VK_LAYER_ANDROID_nullLayer" xstr(LAYERNAME) " loaded");
|
|
|
|
namespace {
|
|
|
|
|
|
// Minimal dispatch table for this simple layer
|
|
struct {
|
|
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
|
|
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
|
} g_VulkanDispatchTable;
|
|
|
|
template<class T>
|
|
VkResult getProperties(const uint32_t count, const T *properties, uint32_t *pCount,
|
|
T *pProperties) {
|
|
uint32_t copySize;
|
|
|
|
if (pProperties == NULL || properties == NULL) {
|
|
*pCount = count;
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
copySize = *pCount < count ? *pCount : count;
|
|
memcpy(pProperties, properties, copySize * sizeof(T));
|
|
*pCount = copySize;
|
|
if (copySize < count) {
|
|
return VK_INCOMPLETE;
|
|
}
|
|
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
static const VkLayerProperties LAYER_PROPERTIES = {
|
|
LAYER_FULL_NAME,
|
|
VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION),
|
|
1,
|
|
"Layer: nullLayer" xstr(LAYERNAME),
|
|
};
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
|
|
return getProperties<VkLayerProperties>(1, &LAYER_PROPERTIES, pCount, pProperties);
|
|
}
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice /* physicalDevice */, uint32_t *pCount,
|
|
VkLayerProperties *pProperties) {
|
|
return getProperties<VkLayerProperties>(0, NULL, pCount, pProperties);
|
|
}
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char* /* pLayerName */, uint32_t *pCount,
|
|
VkExtensionProperties *pProperties) {
|
|
#ifdef DEBUGUTILSPECVERSION
|
|
return getProperties<VkExtensionProperties>(1, &debug_utils_extension, pCount,
|
|
pProperties);
|
|
#else
|
|
return getProperties<VkExtensionProperties>(0, NULL, pCount, pProperties);
|
|
#endif
|
|
}
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice /* physicalDevice */, const char* /* pLayerName */,
|
|
uint32_t *pCount, VkExtensionProperties *pProperties) {
|
|
return getProperties<VkExtensionProperties>(0, NULL, pCount, pProperties);
|
|
}
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL nullCreateDevice(VkPhysicalDevice physicalDevice,
|
|
const VkDeviceCreateInfo* pCreateInfo,
|
|
const VkAllocationCallbacks* pAllocator,
|
|
VkDevice* pDevice) {
|
|
VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo*)pCreateInfo->pNext;
|
|
const char *msg = "nullCreateDevice called in " LAYER_FULL_NAME;
|
|
ALOGI("%s", msg);
|
|
|
|
// Step through the pNext chain until we get to the link function
|
|
while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO ||
|
|
layerCreateInfo->function != VK_LAYER_FUNCTION_LINK)) {
|
|
layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext;
|
|
}
|
|
|
|
if(layerCreateInfo == NULL)
|
|
return VK_ERROR_INITIALIZATION_FAILED;
|
|
|
|
// Grab GDPA and GIPA for the next layer
|
|
PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
|
|
PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
|
|
|
|
// Track them in our dispatch table
|
|
g_VulkanDispatchTable.GetDeviceProcAddr = gdpa;
|
|
g_VulkanDispatchTable.GetInstanceProcAddr = gipa;
|
|
|
|
// Advance the chain for next layer
|
|
layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
|
|
|
|
// Call the next layer
|
|
PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice");
|
|
VkResult ret = createFunc(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
|
|
|
return ret;
|
|
}
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL nullCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
|
|
const VkAllocationCallbacks* pAllocator,
|
|
VkInstance* pInstance) {
|
|
VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
|
|
const char *msg = "nullCreateInstance called in " LAYER_FULL_NAME;
|
|
ALOGI("%s", msg);
|
|
|
|
// Step through the pNext chain until we get to the link function
|
|
while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
|
|
layerCreateInfo->function != VK_LAYER_FUNCTION_LINK)) {
|
|
layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext;
|
|
}
|
|
|
|
if(layerCreateInfo == NULL)
|
|
return VK_ERROR_INITIALIZATION_FAILED;
|
|
|
|
// Grab GIPA for the next layer
|
|
PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
|
|
|
|
// Track it in our dispatch table
|
|
g_VulkanDispatchTable.GetInstanceProcAddr = gpa;
|
|
|
|
// Advance the chain for next layer
|
|
layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
|
|
|
|
// Call the next layer
|
|
PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance");
|
|
VkResult ret = createFunc(pCreateInfo, pAllocator, pInstance);
|
|
|
|
return ret;
|
|
}
|
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice dev, const char* funcName) {
|
|
|
|
const char* targetFunc = "vkCreateDevice";
|
|
if (!strncmp(targetFunc, funcName, sizeof("vkCreateDevice"))) {
|
|
return (PFN_vkVoidFunction)nullCreateDevice;
|
|
}
|
|
|
|
return (PFN_vkVoidFunction)g_VulkanDispatchTable.GetDeviceProcAddr(dev, funcName);
|
|
}
|
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName) {
|
|
|
|
const char* targetFunc = "vkCreateInstance";
|
|
if (!strncmp(targetFunc, funcName, sizeof("vkCreateInstance"))) {
|
|
return (PFN_vkVoidFunction)nullCreateInstance;
|
|
}
|
|
|
|
return (PFN_vkVoidFunction)g_VulkanDispatchTable.GetInstanceProcAddr(instance, funcName);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// loader-layer interface v0, just wrappers since there is only a layer
|
|
|
|
__attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
|
|
VkLayerProperties *pProperties) {
|
|
return EnumerateInstanceLayerProperties(pCount, pProperties);
|
|
}
|
|
|
|
__attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
|
|
VkLayerProperties *pProperties) {
|
|
return EnumerateDeviceLayerProperties(physicalDevice, pCount, pProperties);
|
|
}
|
|
|
|
__attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
|
|
VkExtensionProperties *pProperties) {
|
|
return EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
|
|
}
|
|
|
|
__attribute((visibility("default"))) VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
|
|
const char *pLayerName, uint32_t *pCount,
|
|
VkExtensionProperties *pProperties) {
|
|
return EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
|
|
}
|
|
|
|
__attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
|
|
return GetDeviceProcAddr(dev, funcName);
|
|
}
|
|
|
|
__attribute((visibility("default"))) VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
|
|
return GetInstanceProcAddr(instance, funcName);
|
|
}
|