171 lines
6.2 KiB
C++
171 lines
6.2 KiB
C++
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <vulkan/vulkan.hpp>
|
|
#include <vulkan/vk_layer.h>
|
|
#include "dispatch_table.hpp"
|
|
#include "functions.hpp"
|
|
#include "record_list.hpp"
|
|
#include "vk_capture.h"
|
|
|
|
namespace vk_capture
|
|
{
|
|
inline constexpr std::uint32_t LOADER_LAYER_VERSION = 2;
|
|
|
|
PFN_vkVoidFunction getLayerFunctionPtr(const char* pName);
|
|
|
|
VkResult vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
|
|
{
|
|
const VkLayerInstanceCreateInfo* layerCreateInfo = static_cast<const VkLayerInstanceCreateInfo*>(pCreateInfo->pNext);
|
|
|
|
// step through the chain of pNext until we get to the link info
|
|
while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
|
|
layerCreateInfo->function != VK_LAYER_LINK_INFO))
|
|
{
|
|
layerCreateInfo = static_cast<const VkLayerInstanceCreateInfo*>(layerCreateInfo->pNext);
|
|
}
|
|
|
|
if(layerCreateInfo == nullptr)
|
|
{
|
|
// No loader instance create info
|
|
return VK_ERROR_INITIALIZATION_FAILED;
|
|
}
|
|
|
|
PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
|
|
// move chain on for next layer
|
|
const_cast<VkLayerInstanceCreateInfo*>(layerCreateInfo)->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
|
|
|
|
PFN_vkCreateInstance createFunc = reinterpret_cast<PFN_vkCreateInstance>(gpa(VK_NULL_HANDLE, "vkCreateInstance"));
|
|
|
|
VkResult ret = createFunc(pCreateInfo, pAllocator, pInstance);
|
|
if (ret != VK_SUCCESS)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
// fetch our own dispatch table for the functions we need, into the next layer
|
|
layer_init_instance_dispatch_table(*pInstance, &vk_capture::g_instanceDispatchTable, gpa);
|
|
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
VkResult vkCreateDevice(
|
|
VkPhysicalDevice physicalDevice,
|
|
const VkDeviceCreateInfo* pCreateInfo,
|
|
const VkAllocationCallbacks* pAllocator,
|
|
VkDevice* pDevice)
|
|
{
|
|
const VkLayerDeviceCreateInfo* layerCreateInfo = static_cast<const VkLayerDeviceCreateInfo*>(pCreateInfo->pNext);
|
|
|
|
// step through the chain of pNext until we get to the link info
|
|
while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO ||
|
|
layerCreateInfo->function != VK_LAYER_LINK_INFO))
|
|
{
|
|
layerCreateInfo = static_cast<const VkLayerDeviceCreateInfo*>(layerCreateInfo->pNext);
|
|
}
|
|
|
|
if(layerCreateInfo == nullptr)
|
|
{
|
|
// No loader instance create info
|
|
return VK_ERROR_INITIALIZATION_FAILED;
|
|
}
|
|
|
|
PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
|
|
PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
|
|
// move chain on for next layer
|
|
const_cast<VkLayerDeviceCreateInfo*>(layerCreateInfo)->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
|
|
|
|
PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice");
|
|
|
|
VkResult ret = createFunc(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
|
|
|
if (ret != VK_SUCCESS)
|
|
{
|
|
return ret;
|
|
}
|
|
layer_init_device_dispatch_table(*pDevice, &vk_capture::g_dispatchTable, gdpa);
|
|
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
PFN_vkVoidFunction vkGetDeviceProcAddr(VkDevice device, const char* pName)
|
|
{
|
|
PFN_vkVoidFunction ptr = getLayerFunctionPtr(pName);
|
|
if (ptr) {
|
|
return ptr;
|
|
}
|
|
else {
|
|
return g_dispatchTable.GetDeviceProcAddr(device, pName);
|
|
}
|
|
}
|
|
|
|
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* pName)
|
|
{
|
|
PFN_vkVoidFunction ptr = getLayerFunctionPtr(pName);
|
|
if (ptr) {
|
|
return ptr;
|
|
}
|
|
else {
|
|
return g_instanceDispatchTable.GetInstanceProcAddr(instance, pName);
|
|
}
|
|
}
|
|
|
|
PFN_vkVoidFunction getLayerFunctionPtr(const char* pName)
|
|
{
|
|
if (std::strcmp(pName, "vkCreateInstance") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vk_capture::vkCreateInstance);
|
|
}
|
|
else if (std::strcmp(pName, "vkCreateDevice") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vk_capture::vkCreateDevice);
|
|
}
|
|
else if (std::strcmp(pName, "vkGetInstanceProcAddr") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vk_capture::vkGetInstanceProcAddr);
|
|
}
|
|
if (std::strcmp(pName, "vkGetDeviceProcAddr") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkGetDeviceProcAddr);
|
|
}
|
|
else if (std::strcmp(pName, "vkAllocateRecordListMWN") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkAllocateRecordListMWN);
|
|
}
|
|
else if (std::strcmp(pName, "vkFreeRecordListMWN") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkFreeRecordListMWN);
|
|
}
|
|
else if (std::strcmp(pName, "vkBeginRecordingMWN") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkBeginRecordingMWN);
|
|
}
|
|
else if (std::strcmp(pName, "vkEndRecordingMWN") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkEndRecordingMWN);
|
|
}
|
|
else if (std::strcmp(pName, "vkGetRecordListItemsMWN") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkGetRecordListItemsMWN);
|
|
}
|
|
else if (std::strcmp(pName, "vkResetRecordListMWN") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkResetRecordListMWN);
|
|
}
|
|
else if (std::strcmp(pName, "vkGetFunctionNameMWN") == 0) {
|
|
return reinterpret_cast<PFN_vkVoidFunction>(&vkGetFunctionNameMWN);
|
|
}
|
|
else {
|
|
return getWrappedFunctionPtr(pName);
|
|
}
|
|
}
|
|
} // namespace vk_capture
|
|
|
|
extern "C"
|
|
{
|
|
|
|
VK_LAYER_EXPORT VkResult VKAPI_CALL vk_capture_vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface* pVersionStruct)
|
|
{
|
|
if (pVersionStruct->loaderLayerInterfaceVersion < vk_capture::LOADER_LAYER_VERSION) {
|
|
return VK_ERROR_INITIALIZATION_FAILED;
|
|
}
|
|
pVersionStruct->sType = LAYER_NEGOTIATE_INTERFACE_STRUCT;
|
|
pVersionStruct->pNext = nullptr;
|
|
pVersionStruct->loaderLayerInterfaceVersion = vk_capture::LOADER_LAYER_VERSION;
|
|
pVersionStruct->pfnGetInstanceProcAddr = &vk_capture::vkGetInstanceProcAddr;
|
|
pVersionStruct->pfnGetDeviceProcAddr = &vk_capture::vkGetDeviceProcAddr;
|
|
pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
|
|
return VK_SUCCESS;
|
|
}
|
|
} // extern "C"
|