mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-22 10:21:43 +00:00
refactor(cleanup): base of new layer
This commit is contained in:
parent
b70b403297
commit
d8888a2caf
10 changed files with 383 additions and 782 deletions
|
|
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.10)
|
|||
project(lsfg-vk LANGUAGES CXX)
|
||||
|
||||
# === user facing options
|
||||
option(LSFGVK_BUILD_VULKAN_LAYER
|
||||
"Build the Vulkan layer" ON)
|
||||
option(LSFGVK_BUILD_DEBUG_TOOL
|
||||
"Build the debug tool for testing and debugging" OFF)
|
||||
|
||||
|
|
@ -25,6 +27,8 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||
-Wno-c++98-compat-pedantic
|
||||
-Wno-switch-default
|
||||
-Wno-switch-enum
|
||||
# allow global deconstructors
|
||||
-Wno-exit-time-destructors
|
||||
# disable noisy warnings
|
||||
-Wno-missing-designated-field-initializers
|
||||
-Wno-cast-function-type-strict
|
||||
|
|
@ -40,6 +44,9 @@ endif()
|
|||
|
||||
add_subdirectory(lsfg-vk-common)
|
||||
add_subdirectory(lsfg-vk-backend)
|
||||
if(LSFGVK_BUILD_VULKAN_LAYER)
|
||||
add_subdirectory(lsfg-vk-layer)
|
||||
endif()
|
||||
if(LSFGVK_BUILD_DEBUG_TOOL)
|
||||
add_subdirectory(lsfg-vk-debug)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"file_format_version": "1.0.0",
|
||||
"layer": {
|
||||
"name": "VK_LAYER_LS_frame_generation",
|
||||
"type": "GLOBAL",
|
||||
"api_version": "1.4.313",
|
||||
"library_path": "liblsfg-vk.so",
|
||||
"implementation_version": "1",
|
||||
"description": "Lossless Scaling frame generation layer",
|
||||
"functions": {
|
||||
"vkGetInstanceProcAddr": "layer_vkGetInstanceProcAddr",
|
||||
"vkGetDeviceProcAddr": "layer_vkGetDeviceProcAddr"
|
||||
},
|
||||
"disable_environment": {
|
||||
"DISABLE_LSFG": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Layer {
|
||||
/// Call to the original vkCreateInstance function.
|
||||
VkResult ovkCreateInstance(
|
||||
const VkInstanceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkInstance* pInstance);
|
||||
/// Call to the original vkDestroyInstance function.
|
||||
void ovkDestroyInstance(
|
||||
VkInstance instance,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
/// Call to the original vkCreateDevice function.
|
||||
VkResult ovkCreateDevice(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkDeviceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDevice* pDevice);
|
||||
/// Call to the original vkDestroyDevice function.
|
||||
void ovkDestroyDevice(
|
||||
VkDevice device,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
/// Call to the original vkSetDeviceLoaderData function.
|
||||
VkResult ovkSetDeviceLoaderData(
|
||||
VkDevice device,
|
||||
void* object);
|
||||
|
||||
/// Call to the original vkGetInstanceProcAddr function.
|
||||
PFN_vkVoidFunction ovkGetInstanceProcAddr(
|
||||
VkInstance instance,
|
||||
const char* pName);
|
||||
/// Call to the original vkGetDeviceProcAddr function.
|
||||
PFN_vkVoidFunction ovkGetDeviceProcAddr(
|
||||
VkDevice device,
|
||||
const char* pName);
|
||||
|
||||
/// Call to the original vkGetPhysicalDeviceQueueFamilyProperties function.
|
||||
void ovkGetPhysicalDeviceQueueFamilyProperties(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t* pQueueFamilyPropertyCount,
|
||||
VkQueueFamilyProperties* pQueueFamilyProperties);
|
||||
/// Call to the original vkGetPhysicalDeviceMemoryProperties function.
|
||||
void ovkGetPhysicalDeviceMemoryProperties(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkPhysicalDeviceMemoryProperties* pMemoryProperties);
|
||||
/// Call to the original vkGetPhysicalDeviceProperties function.
|
||||
void ovkGetPhysicalDeviceProperties(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkPhysicalDeviceProperties* pProperties);
|
||||
/// Call to the original vkGetPhysicalDeviceSurfaceCapabilitiesKHR function.
|
||||
VkResult ovkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
|
||||
|
||||
/// Call to the original vkCreateSwapchainKHR function.
|
||||
VkResult ovkCreateSwapchainKHR(
|
||||
VkDevice device,
|
||||
const VkSwapchainCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSwapchainKHR* pSwapchain);
|
||||
/// Call to the original vkQueuePresentKHR function.
|
||||
VkResult ovkQueuePresentKHR(
|
||||
VkQueue queue,
|
||||
const VkPresentInfoKHR* pPresentInfo);
|
||||
/// Call to the original vkDestroySwapchainKHR function.
|
||||
void ovkDestroySwapchainKHR(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
/// Call to the original vkGetSwapchainImagesKHR function.
|
||||
VkResult ovkGetSwapchainImagesKHR(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain,
|
||||
uint32_t* pSwapchainImageCount,
|
||||
VkImage* pSwapchainImages);
|
||||
|
||||
/// Call to the original vkAllocateCommandBuffers function.
|
||||
VkResult ovkAllocateCommandBuffers(
|
||||
VkDevice device,
|
||||
const VkCommandBufferAllocateInfo* pAllocateInfo,
|
||||
VkCommandBuffer* pCommandBuffers);
|
||||
/// Call to the original vkFreeCommandBuffers function.
|
||||
void ovkFreeCommandBuffers(
|
||||
VkDevice device,
|
||||
VkCommandPool commandPool,
|
||||
uint32_t commandBufferCount,
|
||||
const VkCommandBuffer* pCommandBuffers);
|
||||
|
||||
/// Call to the original vkBeginCommandBuffer function.
|
||||
VkResult ovkBeginCommandBuffer(
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkCommandBufferBeginInfo* pBeginInfo);
|
||||
/// Call to the original vkEndCommandBuffer function.
|
||||
VkResult ovkEndCommandBuffer(
|
||||
VkCommandBuffer commandBuffer);
|
||||
|
||||
/// Call to the original vkCreateCommandPool function.
|
||||
VkResult ovkCreateCommandPool(
|
||||
VkDevice device,
|
||||
const VkCommandPoolCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkCommandPool* pCommandPool);
|
||||
/// Call to the original vkDestroyCommandPool function.
|
||||
void ovkDestroyCommandPool(
|
||||
VkDevice device,
|
||||
VkCommandPool commandPool,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
/// Call to the original vkCreateImage function.
|
||||
VkResult ovkCreateImage(
|
||||
VkDevice device,
|
||||
const VkImageCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkImage* pImage);
|
||||
/// Call to the original vkDestroyImage function.
|
||||
void ovkDestroyImage(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
/// Call to the original vkGetImageMemoryRequirements function.
|
||||
void ovkGetImageMemoryRequirements(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
VkMemoryRequirements* pMemoryRequirements);
|
||||
/// Call to the original vkBindImageMemory function.
|
||||
VkResult ovkBindImageMemory(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
VkDeviceMemory memory,
|
||||
VkDeviceSize memoryOffset);
|
||||
/// Call to the original vkAllocateMemory function.
|
||||
VkResult ovkAllocateMemory(
|
||||
VkDevice device,
|
||||
const VkMemoryAllocateInfo* pAllocateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDeviceMemory* pMemory);
|
||||
/// Call to the original vkFreeMemory function.
|
||||
void ovkFreeMemory(
|
||||
VkDevice device,
|
||||
VkDeviceMemory memory,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
/// Call to the original vkCreateSemaphore function.
|
||||
VkResult ovkCreateSemaphore(
|
||||
VkDevice device,
|
||||
const VkSemaphoreCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSemaphore* pSemaphore);
|
||||
/// Call to the original vkDestroySemaphore function.
|
||||
void ovkDestroySemaphore(
|
||||
VkDevice device,
|
||||
VkSemaphore semaphore,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
/// Call to the original vkGetMemoryFdKHR function.
|
||||
VkResult ovkGetMemoryFdKHR(
|
||||
VkDevice device,
|
||||
const VkMemoryGetFdInfoKHR* pGetFdInfo,
|
||||
int* pFd);
|
||||
/// Call to the original vkGetSemaphoreFdKHR function.
|
||||
VkResult ovkGetSemaphoreFdKHR(
|
||||
VkDevice device,
|
||||
const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
|
||||
int* pFd);
|
||||
|
||||
/// Call to the original vkGetDeviceQueue function.
|
||||
void ovkGetDeviceQueue(
|
||||
VkDevice device,
|
||||
uint32_t queueFamilyIndex,
|
||||
uint32_t queueIndex,
|
||||
VkQueue* pQueue);
|
||||
/// Call to the original vkQueueSubmit function.
|
||||
VkResult ovkQueueSubmit(
|
||||
VkQueue queue,
|
||||
uint32_t submitCount,
|
||||
const VkSubmitInfo* pSubmits,
|
||||
VkFence fence);
|
||||
|
||||
/// Call to the original vkCmdPipelineBarrier function.
|
||||
void ovkCmdPipelineBarrier(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask,
|
||||
VkDependencyFlags dependencyFlags,
|
||||
uint32_t memoryBarrierCount,
|
||||
const VkMemoryBarrier* pMemoryBarriers,
|
||||
uint32_t bufferMemoryBarrierCount,
|
||||
const VkBufferMemoryBarrier* pBufferMemoryBarriers,
|
||||
uint32_t imageMemoryBarrierCount,
|
||||
const VkImageMemoryBarrier* pImageMemoryBarriers);
|
||||
/// Call to the original vkCmdBlitImage function.
|
||||
void ovkCmdBlitImage(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkImage srcImage,
|
||||
VkImageLayout srcImageLayout,
|
||||
VkImage dstImage,
|
||||
VkImageLayout dstImageLayout,
|
||||
uint32_t regionCount,
|
||||
const VkImageBlit* pRegions,
|
||||
VkFilter filter);
|
||||
|
||||
/// Call to the original vkAcquireNextImageKHR function.
|
||||
VkResult ovkAcquireNextImageKHR(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain,
|
||||
uint64_t timeout,
|
||||
VkSemaphore semaphore,
|
||||
VkFence fence,
|
||||
uint32_t* pImageIndex);
|
||||
}
|
||||
|
||||
/// Symbol definition for Vulkan instance layer.
|
||||
extern "C"
|
||||
[[gnu::visibility("default")]]
|
||||
PFN_vkVoidFunction layer_vkGetInstanceProcAddr(VkInstance instance, const char* pName);
|
||||
/// Symbol definition for Vulkan device layer.
|
||||
extern "C"
|
||||
[[gnu::visibility("default")]]
|
||||
PFN_vkVoidFunction layer_vkGetDeviceProcAddr(VkDevice device, const char* pName);
|
||||
38
lsfg-vk-layer/.clang-tidy
Normal file
38
lsfg-vk-layer/.clang-tidy
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
Checks:
|
||||
# enable basic checks
|
||||
- "clang-analyzer-*"
|
||||
# configure performance checks
|
||||
- "performance-*"
|
||||
- "-performance-enum-size"
|
||||
# configure readability and bugprone checks
|
||||
- "readability-*"
|
||||
- "bugprone-*"
|
||||
- "misc-*"
|
||||
- "-readability-braces-around-statements"
|
||||
- "-readability-function-cognitive-complexity"
|
||||
- "-readability-identifier-length"
|
||||
- "-readability-implicit-bool-conversion"
|
||||
- "-readability-magic-numbers"
|
||||
- "-readability-math-missing-parentheses"
|
||||
- "-readability-named-parameter"
|
||||
- "-bugprone-easily-swappable-parameters"
|
||||
# configure modernization
|
||||
- "modernize-*"
|
||||
- "-modernize-use-trailing-return-type"
|
||||
# configure cppcoreguidelines
|
||||
- "cppcoreguidelines-*"
|
||||
- "-cppcoreguidelines-avoid-magic-numbers"
|
||||
- "-cppcoreguidelines-pro-type-reinterpret-cast"
|
||||
- "-cppcoreguidelines-macro-usage"
|
||||
- "-cppcoreguidelines-pro-type-union-access"
|
||||
- "-cppcoreguidelines-avoid-non-const-global-variables"
|
||||
# disable slow and pointless checks
|
||||
- "-modernize-use-std-numbers"
|
||||
- "-modernize-type-traits"
|
||||
- "-cppcoreguidelines-owning-memory"
|
||||
- "-cppcoreguidelines-macro-to-enum"
|
||||
- "-readability-container-contains"
|
||||
- "-bugprone-reserved-identifier"
|
||||
- "-bugprone-stringview-nullptr"
|
||||
- "-bugprone-standalone-empty"
|
||||
- "-misc-unused-using-decls"
|
||||
12
lsfg-vk-layer/CMakeLists.txt
Normal file
12
lsfg-vk-layer/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
set(LAYER_SOURCES
|
||||
"src/entrypoint.cpp"
|
||||
"src/layer.cpp")
|
||||
|
||||
add_library(lsfg-vk-layer SHARED ${LAYER_SOURCES})
|
||||
|
||||
target_link_libraries(lsfg-vk-layer
|
||||
PUBLIC lsfg-vk-common
|
||||
PUBLIC lsfg-vk-backend)
|
||||
|
||||
set_target_properties(lsfg-vk-layer PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden)
|
||||
14
lsfg-vk-layer/VkLayer_LS_frame_generation.json
Normal file
14
lsfg-vk-layer/VkLayer_LS_frame_generation.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"file_format_version": "1.1.0",
|
||||
"layer": {
|
||||
"name": "VK_LAYER_LS_frame_generation",
|
||||
"description": "Lossless Scaling frame generation layer",
|
||||
"implementation_version": "2",
|
||||
"library_path": "liblsfg-vk-layer.so",
|
||||
"type": "GLOBAL",
|
||||
"api_version": "1.4.328",
|
||||
"disable_environment": {
|
||||
"DISABLE_LSFG": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
257
lsfg-vk-layer/src/entrypoint.cpp
Normal file
257
lsfg-vk-layer/src/entrypoint.cpp
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
#include "layer.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vk_layer.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace {
|
||||
/// reinterpret cast helper with const_cast
|
||||
template<typename T, typename U>
|
||||
T vcast(U ptr) {
|
||||
return reinterpret_cast<T>(const_cast<void*>(ptr)); // NOLINT
|
||||
}
|
||||
|
||||
/// helper function to add required extensions
|
||||
std::vector<const char*> add_extensions(const char* const* existingExtensions, size_t count,
|
||||
const std::vector<std::string>& requiredExtensions) {
|
||||
std::vector<const char*> extensions(count);
|
||||
std::copy_n(existingExtensions, count, extensions.data());
|
||||
|
||||
for (const auto& requiredExtension : requiredExtensions) {
|
||||
auto it = std::ranges::find_if(extensions,
|
||||
[requiredExtension](const char* extension) {
|
||||
return std::string(extension) == requiredExtension;
|
||||
});
|
||||
if (it == extensions.end())
|
||||
extensions.push_back(requiredExtension.c_str());
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
PFN_vkGetInstanceProcAddr nxvkGetInstanceProcAddr{nullptr};
|
||||
PFN_vkGetDeviceProcAddr nxvkGetDeviceProcAddr = nullptr;
|
||||
|
||||
VkInstance gInstance{VK_NULL_HANDLE}; // if there are multiple instances, we scream out loud, oke?
|
||||
|
||||
// create instance
|
||||
VkResult myvkCreateInstance(
|
||||
const VkInstanceCreateInfo* info,
|
||||
const VkAllocationCallbacks* alloc,
|
||||
VkInstance* instance) {
|
||||
// apply layer chaining
|
||||
auto* layerInfo = vcast<VkLayerInstanceCreateInfo*>(info->pNext);
|
||||
while (layerInfo && (layerInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
|
||||
|| layerInfo->function != VK_LAYER_LINK_INFO)) {
|
||||
layerInfo = vcast<VkLayerInstanceCreateInfo*>(layerInfo->pNext);
|
||||
}
|
||||
if (!layerInfo) {
|
||||
std::cerr << "lsfg-vk: no layer info found in pNext chain, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
auto* linkInfo = layerInfo->u.pLayerInfo;
|
||||
if (!linkInfo) {
|
||||
std::cerr << "lsfg-vk: link info is null, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
nxvkGetInstanceProcAddr = linkInfo->pfnNextGetInstanceProcAddr;
|
||||
if (!nxvkGetInstanceProcAddr) {
|
||||
std::cerr << "lsfg-vk: next layer's vkGetInstanceProcAddr is null, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
layerInfo->u.pLayerInfo = linkInfo->pNext; // advance for next layer
|
||||
|
||||
// create instance
|
||||
auto* vkCreateInstance = reinterpret_cast<PFN_vkCreateInstance>(
|
||||
nxvkGetInstanceProcAddr(nullptr, "vkCreateInstance"));
|
||||
if (!vkCreateInstance) {
|
||||
std::cerr << "lsfg-vk: failed to get next layer's vkCreateInstance, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
auto requiredExtensions = lsfgvk::requiredInstanceExtensions();
|
||||
auto extensions = add_extensions(
|
||||
info->ppEnabledExtensionNames,
|
||||
info->enabledExtensionCount,
|
||||
requiredExtensions);
|
||||
|
||||
VkInstanceCreateInfo newInfo = *info;
|
||||
newInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||
newInfo.ppEnabledExtensionNames = extensions.data();
|
||||
|
||||
auto res = vkCreateInstance(&newInfo, alloc, instance);
|
||||
if (res == VK_ERROR_EXTENSION_NOT_PRESENT)
|
||||
std::cerr << "lsfg-vk: required Vulkan instance extensions are not present. "
|
||||
"Your GPU driver is not supported.\n";
|
||||
|
||||
if (res != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
gInstance = *instance;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// map of devices to layer instances
|
||||
std::unordered_map<VkDevice, lsfgvk::LayerInstance>& device2InstanceMap() {
|
||||
static std::unordered_map<VkDevice, lsfgvk::LayerInstance> map; // NOLINT
|
||||
return map;
|
||||
}
|
||||
|
||||
// create device
|
||||
VkResult myvkCreateDevice(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkDeviceCreateInfo* info,
|
||||
const VkAllocationCallbacks* alloc,
|
||||
VkDevice* device) {
|
||||
// apply layer chaining
|
||||
auto* layerInfo = vcast<VkLayerDeviceCreateInfo*>(info->pNext);
|
||||
while (layerInfo && (layerInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
|
||||
|| layerInfo->function != VK_LAYER_LINK_INFO)) {
|
||||
layerInfo = vcast<VkLayerDeviceCreateInfo*>(layerInfo->pNext);
|
||||
}
|
||||
if (!layerInfo) {
|
||||
std::cerr << "lsfg-vk: no layer info found in pNext chain, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
auto* linkInfo = layerInfo->u.pLayerInfo;
|
||||
if (!linkInfo) {
|
||||
std::cerr << "lsfg-vk: link info is null, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
nxvkGetDeviceProcAddr = linkInfo->pfnNextGetDeviceProcAddr;
|
||||
if (!nxvkGetDeviceProcAddr) {
|
||||
std::cerr << "lsfg-vk: next layer's vkGetDeviceProcAddr is null, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
layerInfo->u.pLayerInfo = linkInfo->pNext; // advance for next layer
|
||||
|
||||
// fetch device loader functions
|
||||
layerInfo = vcast<VkLayerDeviceCreateInfo*>(info->pNext);
|
||||
while (layerInfo && (layerInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
|
||||
|| layerInfo->function != VK_LOADER_DATA_CALLBACK)) {
|
||||
layerInfo = vcast<VkLayerDeviceCreateInfo*>(layerInfo->pNext);
|
||||
}
|
||||
if (!layerInfo) {
|
||||
std::cerr << "lsfg-vk: no layer loader data found in pNext chain.\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
auto* setLoaderData = layerInfo->u.pfnSetDeviceLoaderData;
|
||||
if (!setLoaderData) {
|
||||
std::cerr << "lsfg-vk: instance loader data function is null.\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
// create device
|
||||
auto* vkCreateDevice = reinterpret_cast<PFN_vkCreateDevice>(
|
||||
nxvkGetInstanceProcAddr(gInstance, "vkCreateDevice"));
|
||||
if (!vkCreateDevice) {
|
||||
std::cerr << "lsfg-vk: failed to get next layer's vkCreateDevice, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
auto requiredExtensions = lsfgvk::requiredDeviceExtensions();
|
||||
auto extensions = add_extensions(
|
||||
info->ppEnabledExtensionNames,
|
||||
info->enabledExtensionCount,
|
||||
requiredExtensions);
|
||||
|
||||
VkDeviceCreateInfo newInfo = *info;
|
||||
newInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||
newInfo.ppEnabledExtensionNames = extensions.data();
|
||||
|
||||
auto res = vkCreateDevice(physicalDevice, &newInfo, alloc, device);
|
||||
if (res == VK_ERROR_EXTENSION_NOT_PRESENT)
|
||||
std::cerr << "lsfg-vk: required Vulkan device extensions are not present. "
|
||||
"Your GPU driver is not supported.\n";
|
||||
|
||||
if (res != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
// create layer instance
|
||||
try {
|
||||
device2InstanceMap().emplace(*device,
|
||||
lsfgvk::LayerInstance(gInstance, *device, setLoaderData));
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "lsfg-vk: something went wrong during lsfg-vk initialization:\n";
|
||||
std::cerr << "- " << e.what() << '\n';
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
PFN_vkVoidFunction getProcAddr(const std::string& name);
|
||||
|
||||
// get instance-level function pointers
|
||||
PFN_vkVoidFunction myvkGetInstanceProcAddr(VkInstance instance, const char* pName) {
|
||||
if (!pName) return nullptr;
|
||||
|
||||
auto func = getProcAddr(pName);
|
||||
if (func) return func;
|
||||
|
||||
if (!nxvkGetInstanceProcAddr) return nullptr;
|
||||
return nxvkGetInstanceProcAddr(instance, pName);
|
||||
}
|
||||
|
||||
// get device-level function pointers
|
||||
PFN_vkVoidFunction myvkGetDeviceProcAddr(VkDevice device, const char* pName) {
|
||||
if (!pName) return nullptr;
|
||||
|
||||
auto func = getProcAddr(pName);
|
||||
if (func) return func;
|
||||
|
||||
if (!nxvkGetDeviceProcAddr) return nullptr;
|
||||
return nxvkGetDeviceProcAddr(device, pName);
|
||||
}
|
||||
|
||||
// get optional function pointer override
|
||||
PFN_vkVoidFunction getProcAddr(const std::string& name) {
|
||||
if (name == "vkCreateInstance")
|
||||
return reinterpret_cast<PFN_vkVoidFunction>(&myvkCreateInstance);
|
||||
if (name == "vkCreateDevice")
|
||||
return reinterpret_cast<PFN_vkVoidFunction>(&myvkCreateDevice);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Vulkan layer entrypoint
|
||||
__attribute__((visibility("default")))
|
||||
VkResult vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface* pVersionStruct) {
|
||||
// ensure loader compatibility
|
||||
if (!pVersionStruct
|
||||
|| pVersionStruct->sType != LAYER_NEGOTIATE_INTERFACE_STRUCT
|
||||
|| pVersionStruct->loaderLayerInterfaceVersion < 2)
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
|
||||
// emplace function pointers/version
|
||||
pVersionStruct->loaderLayerInterfaceVersion = 2;
|
||||
pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
|
||||
pVersionStruct->pfnGetDeviceProcAddr = myvkGetDeviceProcAddr;
|
||||
pVersionStruct->pfnGetInstanceProcAddr = myvkGetInstanceProcAddr;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
25
lsfg-vk-layer/src/layer.cpp
Normal file
25
lsfg-vk-layer/src/layer.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "layer.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vk_layer.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace lsfgvk;
|
||||
|
||||
std::vector<std::string> lsfgvk::requiredInstanceExtensions() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> lsfgvk::requiredDeviceExtensions() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
lsfgvk::LayerInstance::LayerInstance(VkInstance instance, VkDevice device,
|
||||
PFN_vkSetDeviceLoaderData setLoaderData) {
|
||||
std::cerr << "lsfg-vk: Hello, world!\n";
|
||||
std::cerr << "lsfg-vk: instance=" << instance << ", device=" << device << '\n';
|
||||
std::cerr << "lsfg-vk: setLoaderData=" << reinterpret_cast<void*>(setLoaderData) << '\n';
|
||||
}
|
||||
30
lsfg-vk-layer/src/layer.hpp
Normal file
30
lsfg-vk-layer/src/layer.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vk_layer.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace lsfgvk {
|
||||
|
||||
/// required instance extensions
|
||||
/// @return list of extension names
|
||||
std::vector<std::string> requiredInstanceExtensions() noexcept;
|
||||
|
||||
/// required device extensions
|
||||
/// @return list of extension names
|
||||
std::vector<std::string> requiredDeviceExtensions() noexcept;
|
||||
|
||||
/// instance of the lsfg-vk layer on a VkInstance/VkDevice pair.
|
||||
class LayerInstance {
|
||||
public:
|
||||
/// create a new layer instance
|
||||
/// @param instance Vulkan instance
|
||||
/// @param device Vulkan device
|
||||
/// @param setLoaderData function to set device loader data
|
||||
LayerInstance(VkInstance instance, VkDevice device,
|
||||
PFN_vkSetDeviceLoaderData setLoaderData);
|
||||
};
|
||||
|
||||
}
|
||||
536
src/layer.cpp
536
src/layer.cpp
|
|
@ -1,536 +0,0 @@
|
|||
#include "layer.hpp"
|
||||
#include "common/exception.hpp"
|
||||
#include "config/config.hpp"
|
||||
#include "hooks.hpp"
|
||||
|
||||
#include <vulkan/vk_layer.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
PFN_vkCreateInstance next_vkCreateInstance{};
|
||||
PFN_vkDestroyInstance next_vkDestroyInstance{};
|
||||
|
||||
PFN_vkCreateDevice next_vkCreateDevice{};
|
||||
PFN_vkDestroyDevice next_vkDestroyDevice{};
|
||||
|
||||
PFN_vkSetDeviceLoaderData next_vSetDeviceLoaderData{};
|
||||
|
||||
PFN_vkGetInstanceProcAddr next_vkGetInstanceProcAddr{};
|
||||
PFN_vkGetDeviceProcAddr next_vkGetDeviceProcAddr{};
|
||||
|
||||
PFN_vkGetPhysicalDeviceQueueFamilyProperties next_vkGetPhysicalDeviceQueueFamilyProperties{};
|
||||
PFN_vkGetPhysicalDeviceMemoryProperties next_vkGetPhysicalDeviceMemoryProperties{};
|
||||
PFN_vkGetPhysicalDeviceProperties next_vkGetPhysicalDeviceProperties{};
|
||||
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR{};
|
||||
|
||||
PFN_vkCreateSwapchainKHR next_vkCreateSwapchainKHR{};
|
||||
PFN_vkQueuePresentKHR next_vkQueuePresentKHR{};
|
||||
PFN_vkDestroySwapchainKHR next_vkDestroySwapchainKHR{};
|
||||
PFN_vkGetSwapchainImagesKHR next_vkGetSwapchainImagesKHR{};
|
||||
PFN_vkAllocateCommandBuffers next_vkAllocateCommandBuffers{};
|
||||
PFN_vkFreeCommandBuffers next_vkFreeCommandBuffers{};
|
||||
PFN_vkBeginCommandBuffer next_vkBeginCommandBuffer{};
|
||||
PFN_vkEndCommandBuffer next_vkEndCommandBuffer{};
|
||||
PFN_vkCreateCommandPool next_vkCreateCommandPool{};
|
||||
PFN_vkDestroyCommandPool next_vkDestroyCommandPool{};
|
||||
PFN_vkCreateImage next_vkCreateImage{};
|
||||
PFN_vkDestroyImage next_vkDestroyImage{};
|
||||
PFN_vkGetImageMemoryRequirements next_vkGetImageMemoryRequirements{};
|
||||
PFN_vkBindImageMemory next_vkBindImageMemory{};
|
||||
PFN_vkAllocateMemory next_vkAllocateMemory{};
|
||||
PFN_vkFreeMemory next_vkFreeMemory{};
|
||||
PFN_vkCreateSemaphore next_vkCreateSemaphore{};
|
||||
PFN_vkDestroySemaphore next_vkDestroySemaphore{};
|
||||
PFN_vkGetMemoryFdKHR next_vkGetMemoryFdKHR{};
|
||||
PFN_vkGetSemaphoreFdKHR next_vkGetSemaphoreFdKHR{};
|
||||
PFN_vkGetDeviceQueue next_vkGetDeviceQueue{};
|
||||
PFN_vkQueueSubmit next_vkQueueSubmit{};
|
||||
PFN_vkCmdPipelineBarrier next_vkCmdPipelineBarrier{};
|
||||
PFN_vkCmdBlitImage next_vkCmdBlitImage{};
|
||||
PFN_vkAcquireNextImageKHR next_vkAcquireNextImageKHR{};
|
||||
|
||||
template<typename T>
|
||||
bool initInstanceFunc(VkInstance instance, const char* name, T* func) {
|
||||
*func = reinterpret_cast<T>(next_vkGetInstanceProcAddr(instance, name));
|
||||
if (!*func) {
|
||||
std::cerr << "(no function pointer for " << name << ")\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool initDeviceFunc(VkDevice device, const char* name, T* func) {
|
||||
*func = reinterpret_cast<T>(next_vkGetDeviceProcAddr(device, name));
|
||||
if (!*func) {
|
||||
std::cerr << "(no function pointer for " << name << ")\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
VkResult layer_vkCreateInstance(
|
||||
const VkInstanceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkInstance* pInstance) {
|
||||
try {
|
||||
// prepare layer | NOLINTBEGIN
|
||||
auto* layerDesc = const_cast<VkLayerInstanceCreateInfo*>(
|
||||
reinterpret_cast<const VkLayerInstanceCreateInfo*>(pCreateInfo->pNext));
|
||||
while (layerDesc && (layerDesc->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
|
||||
|| layerDesc->function != VK_LAYER_LINK_INFO)) {
|
||||
layerDesc = const_cast<VkLayerInstanceCreateInfo*>(
|
||||
reinterpret_cast<const VkLayerInstanceCreateInfo*>(layerDesc->pNext));
|
||||
}
|
||||
if (!layerDesc)
|
||||
throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED,
|
||||
"No layer creation info found in pNext chain");
|
||||
|
||||
next_vkGetInstanceProcAddr = layerDesc->u.pLayerInfo->pfnNextGetInstanceProcAddr;
|
||||
layerDesc->u.pLayerInfo = layerDesc->u.pLayerInfo->pNext;
|
||||
|
||||
bool success = initInstanceFunc(nullptr, "vkCreateInstance", &next_vkCreateInstance);
|
||||
if (!success)
|
||||
throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED,
|
||||
"Failed to get instance function pointer for vkCreateInstance");
|
||||
|
||||
// NOLINTEND | skip initialization if the layer is disabled
|
||||
if (!Config::currentConf.has_value() || std::getenv("LSFG_BENCHMARK")) {
|
||||
auto res = next_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
|
||||
initInstanceFunc(*pInstance, "vkCreateDevice", &next_vkCreateDevice);
|
||||
return res;
|
||||
}
|
||||
|
||||
// create instance
|
||||
try {
|
||||
auto* createInstanceHook = reinterpret_cast<PFN_vkCreateInstance>(
|
||||
Hooks::hooks["vkCreateInstance"]);
|
||||
auto res = createInstanceHook(pCreateInfo, pAllocator, pInstance);
|
||||
if (res != VK_SUCCESS)
|
||||
throw LSFG::vulkan_error(res, "Unknown error");
|
||||
} catch (const std::exception& e) {
|
||||
throw LSFG::rethrowable_error("Failed to create Vulkan instance", e);
|
||||
}
|
||||
|
||||
// get relevant function pointers from the next layer
|
||||
success = true;
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkDestroyInstance", &next_vkDestroyInstance);
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkCreateDevice", &next_vkCreateDevice); // workaround mesa bug
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkGetPhysicalDeviceQueueFamilyProperties", &next_vkGetPhysicalDeviceQueueFamilyProperties);
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkGetPhysicalDeviceMemoryProperties", &next_vkGetPhysicalDeviceMemoryProperties);
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkGetPhysicalDeviceProperties", &next_vkGetPhysicalDeviceProperties);
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", &next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
|
||||
if (!success)
|
||||
throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED,
|
||||
"Failed to get instance function pointers");
|
||||
|
||||
std::cerr << "lsfg-vk: Vulkan instance layer initialized successfully.\n";
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "lsfg-vk: An error occurred while initializing the Vulkan instance layer:\n";
|
||||
std::cerr << "- " << e.what() << '\n';
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult layer_vkCreateDevice( // NOLINTBEGIN
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkDeviceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDevice* pDevice) {
|
||||
try {
|
||||
// prepare layer | NOLINTBEGIN
|
||||
auto* layerDesc = const_cast<VkLayerDeviceCreateInfo*>(
|
||||
reinterpret_cast<const VkLayerDeviceCreateInfo*>(pCreateInfo->pNext));
|
||||
while (layerDesc && (layerDesc->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
|
||||
|| layerDesc->function != VK_LAYER_LINK_INFO)) {
|
||||
layerDesc = const_cast<VkLayerDeviceCreateInfo*>(
|
||||
reinterpret_cast<const VkLayerDeviceCreateInfo*>(layerDesc->pNext));
|
||||
}
|
||||
if (!layerDesc)
|
||||
throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED,
|
||||
"No layer creation info found in pNext chain");
|
||||
|
||||
next_vkGetDeviceProcAddr = layerDesc->u.pLayerInfo->pfnNextGetDeviceProcAddr;
|
||||
layerDesc->u.pLayerInfo = layerDesc->u.pLayerInfo->pNext;
|
||||
|
||||
auto* layerDesc2 = const_cast<VkLayerDeviceCreateInfo*>(
|
||||
reinterpret_cast<const VkLayerDeviceCreateInfo*>(pCreateInfo->pNext));
|
||||
while (layerDesc2 && (layerDesc2->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
|
||||
|| layerDesc2->function != VK_LOADER_DATA_CALLBACK)) {
|
||||
layerDesc2 = const_cast<VkLayerDeviceCreateInfo*>(
|
||||
reinterpret_cast<const VkLayerDeviceCreateInfo*>(layerDesc2->pNext));
|
||||
}
|
||||
if (!layerDesc2)
|
||||
throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED,
|
||||
"No layer device loader data found in pNext chain");
|
||||
|
||||
next_vSetDeviceLoaderData = layerDesc2->u.pfnSetDeviceLoaderData;
|
||||
|
||||
// NOLINTEND | skip initialization if the layer is disabled
|
||||
if (!Config::currentConf.has_value() || std::getenv("LSFG_BENCHMARK"))
|
||||
return next_vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
||||
|
||||
// create device
|
||||
try {
|
||||
auto* createDeviceHook = reinterpret_cast<PFN_vkCreateDevice>(
|
||||
Hooks::hooks["vkCreateDevicePre"]);
|
||||
auto res = createDeviceHook(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
||||
if (res != VK_SUCCESS)
|
||||
throw LSFG::vulkan_error(res, "Unknown error");
|
||||
} catch (const std::exception& e) {
|
||||
throw LSFG::rethrowable_error("Failed to create Vulkan device", e);
|
||||
}
|
||||
|
||||
// get relevant function pointers from the next layer
|
||||
bool success = true;
|
||||
success &= initDeviceFunc(*pDevice, "vkDestroyDevice", &next_vkDestroyDevice);
|
||||
success &= initDeviceFunc(*pDevice, "vkCreateSwapchainKHR", &next_vkCreateSwapchainKHR);
|
||||
success &= initDeviceFunc(*pDevice, "vkQueuePresentKHR", &next_vkQueuePresentKHR);
|
||||
success &= initDeviceFunc(*pDevice, "vkDestroySwapchainKHR", &next_vkDestroySwapchainKHR);
|
||||
success &= initDeviceFunc(*pDevice, "vkGetSwapchainImagesKHR", &next_vkGetSwapchainImagesKHR);
|
||||
success &= initDeviceFunc(*pDevice, "vkAllocateCommandBuffers", &next_vkAllocateCommandBuffers);
|
||||
success &= initDeviceFunc(*pDevice, "vkFreeCommandBuffers", &next_vkFreeCommandBuffers);
|
||||
success &= initDeviceFunc(*pDevice, "vkBeginCommandBuffer", &next_vkBeginCommandBuffer);
|
||||
success &= initDeviceFunc(*pDevice, "vkEndCommandBuffer", &next_vkEndCommandBuffer);
|
||||
success &= initDeviceFunc(*pDevice, "vkCreateCommandPool", &next_vkCreateCommandPool);
|
||||
success &= initDeviceFunc(*pDevice, "vkDestroyCommandPool", &next_vkDestroyCommandPool);
|
||||
success &= initDeviceFunc(*pDevice, "vkCreateImage", &next_vkCreateImage);
|
||||
success &= initDeviceFunc(*pDevice, "vkDestroyImage", &next_vkDestroyImage);
|
||||
success &= initDeviceFunc(*pDevice, "vkGetImageMemoryRequirements", &next_vkGetImageMemoryRequirements);
|
||||
success &= initDeviceFunc(*pDevice, "vkBindImageMemory", &next_vkBindImageMemory);
|
||||
success &= initDeviceFunc(*pDevice, "vkGetMemoryFdKHR", &next_vkGetMemoryFdKHR);
|
||||
success &= initDeviceFunc(*pDevice, "vkAllocateMemory", &next_vkAllocateMemory);
|
||||
success &= initDeviceFunc(*pDevice, "vkFreeMemory", &next_vkFreeMemory);
|
||||
success &= initDeviceFunc(*pDevice, "vkCreateSemaphore", &next_vkCreateSemaphore);
|
||||
success &= initDeviceFunc(*pDevice, "vkDestroySemaphore", &next_vkDestroySemaphore);
|
||||
success &= initDeviceFunc(*pDevice, "vkGetSemaphoreFdKHR", &next_vkGetSemaphoreFdKHR);
|
||||
success &= initDeviceFunc(*pDevice, "vkGetDeviceQueue", &next_vkGetDeviceQueue);
|
||||
success &= initDeviceFunc(*pDevice, "vkQueueSubmit", &next_vkQueueSubmit);
|
||||
success &= initDeviceFunc(*pDevice, "vkCmdPipelineBarrier", &next_vkCmdPipelineBarrier);
|
||||
success &= initDeviceFunc(*pDevice, "vkCmdBlitImage", &next_vkCmdBlitImage);
|
||||
success &= initDeviceFunc(*pDevice, "vkAcquireNextImageKHR", &next_vkAcquireNextImageKHR);
|
||||
if (!success)
|
||||
throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED,
|
||||
"Failed to get device function pointers");
|
||||
|
||||
auto postCreateDeviceHook = reinterpret_cast<PFN_vkCreateDevice>(
|
||||
Hooks::hooks["vkCreateDevicePost"]);
|
||||
auto res = postCreateDeviceHook(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
||||
if (res != VK_SUCCESS)
|
||||
throw LSFG::vulkan_error(res, "Unknown error");
|
||||
|
||||
std::cerr << "lsfg-vk: Vulkan device layer initialized successfully.\n";
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "lsfg-vk: An error occurred while initializing the Vulkan device layer:\n";
|
||||
std::cerr << "- " << e.what() << '\n';
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
} // NOLINTEND
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, PFN_vkVoidFunction> layerFunctions = {
|
||||
{ "vkCreateInstance",
|
||||
reinterpret_cast<PFN_vkVoidFunction>(&layer_vkCreateInstance) },
|
||||
{ "vkCreateDevice",
|
||||
reinterpret_cast<PFN_vkVoidFunction>(&layer_vkCreateDevice) },
|
||||
{ "vkGetInstanceProcAddr",
|
||||
reinterpret_cast<PFN_vkVoidFunction>(&layer_vkGetInstanceProcAddr) },
|
||||
{ "vkGetDeviceProcAddr",
|
||||
reinterpret_cast<PFN_vkVoidFunction>(&layer_vkGetDeviceProcAddr) },
|
||||
};
|
||||
|
||||
PFN_vkVoidFunction layer_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
|
||||
const std::string name(pName);
|
||||
auto it = layerFunctions.find(name);
|
||||
if (it != layerFunctions.end())
|
||||
return it->second;
|
||||
|
||||
it = Hooks::hooks.find(name);
|
||||
if (it != Hooks::hooks.end() && (Config::currentConf.has_value() && !std::getenv("LSFG_BENCHMARK")))
|
||||
return it->second;
|
||||
|
||||
return next_vkGetInstanceProcAddr(instance, pName);
|
||||
}
|
||||
|
||||
PFN_vkVoidFunction layer_vkGetDeviceProcAddr(VkDevice device, const char* pName) {
|
||||
const std::string name(pName);
|
||||
auto it = layerFunctions.find(name);
|
||||
if (it != layerFunctions.end())
|
||||
return it->second;
|
||||
|
||||
it = Hooks::hooks.find(name);
|
||||
if (it != Hooks::hooks.end() && (Config::currentConf.has_value() && !std::getenv("LSFG_BENCHMARK")))
|
||||
return it->second;
|
||||
|
||||
return next_vkGetDeviceProcAddr(device, pName);
|
||||
}
|
||||
|
||||
// original functions
|
||||
namespace Layer {
|
||||
VkResult ovkCreateInstance(
|
||||
const VkInstanceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkInstance* pInstance) {
|
||||
return next_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
|
||||
}
|
||||
void ovkDestroyInstance(
|
||||
VkInstance instance,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
next_vkDestroyInstance(instance, pAllocator);
|
||||
}
|
||||
|
||||
VkResult ovkCreateDevice(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkDeviceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDevice* pDevice) {
|
||||
return next_vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
||||
}
|
||||
void ovkDestroyDevice(
|
||||
VkDevice device,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
next_vkDestroyDevice(device, pAllocator);
|
||||
}
|
||||
|
||||
VkResult ovkSetDeviceLoaderData(VkDevice device, void* object) {
|
||||
return next_vSetDeviceLoaderData(device, object);
|
||||
}
|
||||
|
||||
PFN_vkVoidFunction ovkGetInstanceProcAddr(
|
||||
VkInstance instance,
|
||||
const char* pName) {
|
||||
return next_vkGetInstanceProcAddr(instance, pName);
|
||||
}
|
||||
PFN_vkVoidFunction ovkGetDeviceProcAddr(
|
||||
VkDevice device,
|
||||
const char* pName) {
|
||||
return next_vkGetDeviceProcAddr(device, pName);
|
||||
}
|
||||
|
||||
void ovkGetPhysicalDeviceQueueFamilyProperties(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t* pQueueFamilyPropertyCount,
|
||||
VkQueueFamilyProperties* pQueueFamilyProperties) {
|
||||
next_vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
|
||||
}
|
||||
void ovkGetPhysicalDeviceMemoryProperties(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
|
||||
next_vkGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
|
||||
}
|
||||
void ovkGetPhysicalDeviceProperties(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkPhysicalDeviceProperties* pProperties) {
|
||||
next_vkGetPhysicalDeviceProperties(physicalDevice, pProperties);
|
||||
}
|
||||
VkResult ovkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
|
||||
return next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
|
||||
}
|
||||
|
||||
VkResult ovkCreateSwapchainKHR(
|
||||
VkDevice device,
|
||||
const VkSwapchainCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSwapchainKHR* pSwapchain) {
|
||||
return next_vkCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
|
||||
}
|
||||
VkResult ovkQueuePresentKHR(
|
||||
VkQueue queue,
|
||||
const VkPresentInfoKHR* pPresentInfo) {
|
||||
return next_vkQueuePresentKHR(queue, pPresentInfo);
|
||||
}
|
||||
void ovkDestroySwapchainKHR(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
next_vkDestroySwapchainKHR(device, swapchain, pAllocator);
|
||||
}
|
||||
|
||||
VkResult ovkGetSwapchainImagesKHR(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain,
|
||||
uint32_t* pSwapchainImageCount,
|
||||
VkImage* pSwapchainImages) {
|
||||
return next_vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
|
||||
}
|
||||
|
||||
VkResult ovkAllocateCommandBuffers(
|
||||
VkDevice device,
|
||||
const VkCommandBufferAllocateInfo* pAllocateInfo,
|
||||
VkCommandBuffer* pCommandBuffers) {
|
||||
return next_vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
|
||||
}
|
||||
void ovkFreeCommandBuffers(
|
||||
VkDevice device,
|
||||
VkCommandPool commandPool,
|
||||
uint32_t commandBufferCount,
|
||||
const VkCommandBuffer* pCommandBuffers) {
|
||||
next_vkFreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
|
||||
}
|
||||
|
||||
VkResult ovkBeginCommandBuffer(
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkCommandBufferBeginInfo* pBeginInfo) {
|
||||
return next_vkBeginCommandBuffer(commandBuffer, pBeginInfo);
|
||||
}
|
||||
VkResult ovkEndCommandBuffer(
|
||||
VkCommandBuffer commandBuffer) {
|
||||
return next_vkEndCommandBuffer(commandBuffer);
|
||||
}
|
||||
|
||||
VkResult ovkCreateCommandPool(
|
||||
VkDevice device,
|
||||
const VkCommandPoolCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkCommandPool* pCommandPool) {
|
||||
return next_vkCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
|
||||
}
|
||||
void ovkDestroyCommandPool(
|
||||
VkDevice device,
|
||||
VkCommandPool commandPool,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
next_vkDestroyCommandPool(device, commandPool, pAllocator);
|
||||
}
|
||||
|
||||
VkResult ovkCreateImage(
|
||||
VkDevice device,
|
||||
const VkImageCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkImage* pImage) {
|
||||
return next_vkCreateImage(device, pCreateInfo, pAllocator, pImage);
|
||||
}
|
||||
void ovkDestroyImage(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
next_vkDestroyImage(device, image, pAllocator);
|
||||
}
|
||||
|
||||
void ovkGetImageMemoryRequirements(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
VkMemoryRequirements* pMemoryRequirements) {
|
||||
next_vkGetImageMemoryRequirements(device, image, pMemoryRequirements);
|
||||
}
|
||||
VkResult ovkBindImageMemory(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
VkDeviceMemory memory,
|
||||
VkDeviceSize memoryOffset) {
|
||||
return next_vkBindImageMemory(device, image, memory, memoryOffset);
|
||||
}
|
||||
|
||||
VkResult ovkAllocateMemory(
|
||||
VkDevice device,
|
||||
const VkMemoryAllocateInfo* pAllocateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkDeviceMemory* pMemory) {
|
||||
return next_vkAllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
|
||||
}
|
||||
void ovkFreeMemory(
|
||||
VkDevice device,
|
||||
VkDeviceMemory memory,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
next_vkFreeMemory(device, memory, pAllocator);
|
||||
}
|
||||
|
||||
VkResult ovkCreateSemaphore(
|
||||
VkDevice device,
|
||||
const VkSemaphoreCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSemaphore* pSemaphore) {
|
||||
return next_vkCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
|
||||
}
|
||||
void ovkDestroySemaphore(
|
||||
VkDevice device,
|
||||
VkSemaphore semaphore,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
next_vkDestroySemaphore(device, semaphore, pAllocator);
|
||||
}
|
||||
|
||||
VkResult ovkGetMemoryFdKHR(
|
||||
VkDevice device,
|
||||
const VkMemoryGetFdInfoKHR* pGetFdInfo,
|
||||
int* pFd) {
|
||||
return next_vkGetMemoryFdKHR(device, pGetFdInfo, pFd);
|
||||
}
|
||||
VkResult ovkGetSemaphoreFdKHR(
|
||||
VkDevice device,
|
||||
const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
|
||||
int* pFd) {
|
||||
return next_vkGetSemaphoreFdKHR(device, pGetFdInfo, pFd);
|
||||
}
|
||||
|
||||
void ovkGetDeviceQueue(
|
||||
VkDevice device,
|
||||
uint32_t queueFamilyIndex,
|
||||
uint32_t queueIndex,
|
||||
VkQueue* pQueue) {
|
||||
next_vkGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
|
||||
}
|
||||
VkResult ovkQueueSubmit(
|
||||
VkQueue queue,
|
||||
uint32_t submitCount,
|
||||
const VkSubmitInfo* pSubmits,
|
||||
VkFence fence) {
|
||||
return next_vkQueueSubmit(queue, submitCount, pSubmits, fence);
|
||||
}
|
||||
|
||||
void ovkCmdPipelineBarrier(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask,
|
||||
VkDependencyFlags dependencyFlags,
|
||||
uint32_t memoryBarrierCount,
|
||||
const VkMemoryBarrier* pMemoryBarriers,
|
||||
uint32_t bufferMemoryBarrierCount,
|
||||
const VkBufferMemoryBarrier* pBufferMemoryBarriers,
|
||||
uint32_t imageMemoryBarrierCount,
|
||||
const VkImageMemoryBarrier* pImageMemoryBarriers) {
|
||||
next_vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
|
||||
memoryBarrierCount, pMemoryBarriers,
|
||||
bufferMemoryBarrierCount, pBufferMemoryBarriers,
|
||||
imageMemoryBarrierCount, pImageMemoryBarriers);
|
||||
}
|
||||
void ovkCmdBlitImage(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkImage srcImage,
|
||||
VkImageLayout srcImageLayout,
|
||||
VkImage dstImage,
|
||||
VkImageLayout dstImageLayout,
|
||||
uint32_t regionCount,
|
||||
const VkImageBlit* pRegions,
|
||||
VkFilter filter) {
|
||||
next_vkCmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
|
||||
}
|
||||
|
||||
VkResult ovkAcquireNextImageKHR(
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain,
|
||||
uint64_t timeout,
|
||||
VkSemaphore semaphore,
|
||||
VkFence fence,
|
||||
uint32_t* pImageIndex) {
|
||||
return next_vkAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue