mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-22 10:21:43 +00:00
refactor(cleanup): remove global constructors and initialize vk funcs
This commit is contained in:
parent
1396309892
commit
864e33200a
7 changed files with 167 additions and 148 deletions
|
|
@ -29,8 +29,6 @@ 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
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ namespace vk {
|
|||
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
|
||||
};
|
||||
|
||||
/// initialize vulkan instance function pointers
|
||||
/// @param instance vulkan instance handle
|
||||
/// @param mpa function to get instance proc addresses
|
||||
VulkanInstanceFuncs initVulkanInstanceFuncs(VkInstance instance, PFN_vkGetInstanceProcAddr mpa);
|
||||
|
||||
using PhysicalDeviceSelector = const std::function<
|
||||
VkPhysicalDevice(
|
||||
const VulkanInstanceFuncs&,
|
||||
|
|
@ -94,6 +99,11 @@ namespace vk {
|
|||
PFN_vkGetSemaphoreFdKHR GetSemaphoreFdKHR;
|
||||
};
|
||||
|
||||
/// initialize vulkan device function pointers
|
||||
/// @param fi instance function pointers
|
||||
/// @param device logical device handle
|
||||
VulkanDeviceFuncs initVulkanDeviceFuncs(const VulkanInstanceFuncs& fi, VkDevice device);
|
||||
|
||||
/// vulkan version wrapper
|
||||
class version {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -91,30 +91,6 @@ namespace {
|
|||
);
|
||||
}
|
||||
|
||||
/// initialize vulkan instance function pointers
|
||||
VulkanInstanceFuncs initVulkanInstanceFuncs(VkInstance i) {
|
||||
const auto& mpa = get_mpa();
|
||||
|
||||
return {
|
||||
.DestroyInstance = ipa<PFN_vkDestroyInstance>(mpa, i, "vkDestroyInstance"),
|
||||
.EnumeratePhysicalDevices = ipa<PFN_vkEnumeratePhysicalDevices>(mpa, i,
|
||||
"vkEnumeratePhysicalDevices"),
|
||||
.EnumerateDeviceExtensionProperties = ipa<PFN_vkEnumerateDeviceExtensionProperties>(mpa, i,
|
||||
"vkEnumerateDeviceExtensionProperties"),
|
||||
.GetPhysicalDeviceProperties2 = ipa<PFN_vkGetPhysicalDeviceProperties2>(mpa, i,
|
||||
"vkGetPhysicalDeviceProperties2"),
|
||||
.GetPhysicalDeviceQueueFamilyProperties =
|
||||
ipa<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(mpa, i,
|
||||
"vkGetPhysicalDeviceQueueFamilyProperties"),
|
||||
.GetPhysicalDeviceFeatures2 = ipa<PFN_vkGetPhysicalDeviceFeatures2>(mpa, i,
|
||||
"vkGetPhysicalDeviceFeatures2"),
|
||||
.GetPhysicalDeviceMemoryProperties = ipa<PFN_vkGetPhysicalDeviceMemoryProperties>(mpa, i,
|
||||
"vkGetPhysicalDeviceMemoryProperties"),
|
||||
.CreateDevice = ipa<PFN_vkCreateDevice>(mpa, i, "vkCreateDevice"),
|
||||
.GetDeviceProcAddr = ipa<PFN_vkGetDeviceProcAddr>(mpa, i, "vkGetDeviceProcAddr"),
|
||||
};
|
||||
}
|
||||
|
||||
/// filter for a physical device
|
||||
VkPhysicalDevice findPhysicalDevice(const VulkanInstanceFuncs& fi,
|
||||
VkInstance instance,
|
||||
|
|
@ -222,75 +198,6 @@ namespace {
|
|||
);
|
||||
}
|
||||
|
||||
/// initialize vulkan device function pointers
|
||||
VulkanDeviceFuncs initVulkanDeviceFuncs(const VulkanInstanceFuncs& f, VkDevice d) {
|
||||
return {
|
||||
.GetDeviceQueue = dpa<PFN_vkGetDeviceQueue>(f, d, "vkGetDeviceQueue"),
|
||||
.DeviceWaitIdle = dpa<PFN_vkDeviceWaitIdle>(f, d, "vkDeviceWaitIdle"),
|
||||
.CreateCommandPool = dpa<PFN_vkCreateCommandPool>(f, d, "vkCreateCommandPool"),
|
||||
.DestroyCommandPool = dpa<PFN_vkDestroyCommandPool>(f, d, "vkDestroyCommandPool"),
|
||||
.CreateDescriptorPool = dpa<PFN_vkCreateDescriptorPool>(f, d, "vkCreateDescriptorPool"),
|
||||
.DestroyDescriptorPool = dpa<PFN_vkDestroyDescriptorPool>(f, d, "vkDestroyDescriptorPool"),
|
||||
.CreateBuffer = dpa<PFN_vkCreateBuffer>(f, d, "vkCreateBuffer"),
|
||||
.DestroyBuffer = dpa<PFN_vkDestroyBuffer>(f, d, "vkDestroyBuffer"),
|
||||
.GetBufferMemoryRequirements = dpa<PFN_vkGetBufferMemoryRequirements>(f, d,
|
||||
"vkGetBufferMemoryRequirements"),
|
||||
.AllocateMemory = dpa<PFN_vkAllocateMemory>(f, d, "vkAllocateMemory"),
|
||||
.FreeMemory = dpa<PFN_vkFreeMemory>(f, d, "vkFreeMemory"),
|
||||
.BindBufferMemory = dpa<PFN_vkBindBufferMemory>(f, d, "vkBindBufferMemory"),
|
||||
.MapMemory = dpa<PFN_vkMapMemory>(f, d, "vkMapMemory"),
|
||||
.UnmapMemory = dpa<PFN_vkUnmapMemory>(f, d, "vkUnmapMemory"),
|
||||
.AllocateCommandBuffers = dpa<PFN_vkAllocateCommandBuffers>(f, d,
|
||||
"vkAllocateCommandBuffers"),
|
||||
.FreeCommandBuffers = dpa<PFN_vkFreeCommandBuffers>(f, d, "vkFreeCommandBuffers"),
|
||||
.BeginCommandBuffer = dpa<PFN_vkBeginCommandBuffer>(f, d, "vkBeginCommandBuffer"),
|
||||
.EndCommandBuffer = dpa<PFN_vkEndCommandBuffer>(f, d, "vkEndCommandBuffer"),
|
||||
.CmdPipelineBarrier = dpa<PFN_vkCmdPipelineBarrier>(f, d, "vkCmdPipelineBarrier"),
|
||||
.CmdClearColorImage = dpa<PFN_vkCmdClearColorImage>(f, d, "vkCmdClearColorImage"),
|
||||
.CmdBindPipeline = dpa<PFN_vkCmdBindPipeline>(f, d, "vkCmdBindPipeline"),
|
||||
.CmdBindDescriptorSets = dpa<PFN_vkCmdBindDescriptorSets>(f, d, "vkCmdBindDescriptorSets"),
|
||||
.CmdDispatch = dpa<PFN_vkCmdDispatch>(f, d, "vkCmdDispatch"),
|
||||
.CmdCopyBufferToImage = dpa<PFN_vkCmdCopyBufferToImage>(f, d, "vkCmdCopyBufferToImage"),
|
||||
.QueueSubmit = dpa<PFN_vkQueueSubmit>(f, d, "vkQueueSubmit"),
|
||||
.AllocateDescriptorSets = dpa<PFN_vkAllocateDescriptorSets>(f, d,
|
||||
"vkAllocateDescriptorSets"),
|
||||
.FreeDescriptorSets = dpa<PFN_vkFreeDescriptorSets>(f, d, "vkFreeDescriptorSets"),
|
||||
.UpdateDescriptorSets = dpa<PFN_vkUpdateDescriptorSets>(f, d, "vkUpdateDescriptorSets"),
|
||||
.CreateFence = dpa<PFN_vkCreateFence>(f, d, "vkCreateFence"),
|
||||
.DestroyFence = dpa<PFN_vkDestroyFence>(f, d, "vkDestroyFence"),
|
||||
.ResetFences = dpa<PFN_vkResetFences>(f, d, "vkResetFences"),
|
||||
.WaitForFences = dpa<PFN_vkWaitForFences>(f, d, "vkWaitForFences"),
|
||||
.CreateImage = dpa<PFN_vkCreateImage>(f, d, "vkCreateImage"),
|
||||
.DestroyImage = dpa<PFN_vkDestroyImage>(f, d, "vkDestroyImage"),
|
||||
.GetImageMemoryRequirements = dpa<PFN_vkGetImageMemoryRequirements>(f, d,
|
||||
"vkGetImageMemoryRequirements"),
|
||||
.BindImageMemory = dpa<PFN_vkBindImageMemory>(f, d, "vkBindImageMemory"),
|
||||
.CreateImageView = dpa<PFN_vkCreateImageView>(f, d, "vkCreateImageView"),
|
||||
.DestroyImageView = dpa<PFN_vkDestroyImageView>(f, d, "vkDestroyImageView"),
|
||||
.CreateSampler = dpa<PFN_vkCreateSampler>(f, d, "vkCreateSampler"),
|
||||
.DestroySampler = dpa<PFN_vkDestroySampler>(f, d, "vkDestroySampler"),
|
||||
.CreateSemaphore = dpa<PFN_vkCreateSemaphore>(f, d, "vkCreateSemaphore"),
|
||||
.DestroySemaphore = dpa<PFN_vkDestroySemaphore>(f, d, "vkDestroySemaphore"),
|
||||
.CreateShaderModule = dpa<PFN_vkCreateShaderModule>(f, d, "vkCreateShaderModule"),
|
||||
.DestroyShaderModule = dpa<PFN_vkDestroyShaderModule>(f, d, "vkDestroyShaderModule"),
|
||||
.CreateDescriptorSetLayout = dpa<PFN_vkCreateDescriptorSetLayout>(f, d,
|
||||
"vkCreateDescriptorSetLayout"),
|
||||
.DestroyDescriptorSetLayout = dpa<PFN_vkDestroyDescriptorSetLayout>(f, d,
|
||||
"vkDestroyDescriptorSetLayout"),
|
||||
.CreatePipelineLayout = dpa<PFN_vkCreatePipelineLayout>(f, d, "vkCreatePipelineLayout"),
|
||||
.DestroyPipelineLayout = dpa<PFN_vkDestroyPipelineLayout>(f, d, "vkDestroyPipelineLayout"),
|
||||
.CreateComputePipelines = dpa<PFN_vkCreateComputePipelines>(f, d,
|
||||
"vkCreateComputePipelines"),
|
||||
.DestroyPipeline = dpa<PFN_vkDestroyPipeline>(f, d, "vkDestroyPipeline"),
|
||||
.SignalSemaphore = dpa<PFN_vkSignalSemaphore>(f, d, "vkSignalSemaphore"),
|
||||
.WaitSemaphores = dpa<PFN_vkWaitSemaphores>(f, d, "vkWaitSemaphores"),
|
||||
|
||||
.GetMemoryFdKHR = dpa<PFN_vkGetMemoryFdKHR>(f, d, "vkGetMemoryFdKHR"),
|
||||
.ImportSemaphoreFdKHR = dpa<PFN_vkImportSemaphoreFdKHR>(f, d, "vkImportSemaphoreFdKHR"),
|
||||
.GetSemaphoreFdKHR = dpa<PFN_vkGetSemaphoreFdKHR>(f, d, "vkGetSemaphoreFdKHR"),
|
||||
};
|
||||
}
|
||||
|
||||
/// get a queue from the logical device
|
||||
VkQueue getQueue(const VulkanDeviceFuncs& fd,
|
||||
VkDevice device, uint32_t cfi) {
|
||||
|
|
@ -352,6 +259,97 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
/// initialize vulkan instance function pointers
|
||||
VulkanInstanceFuncs vk::initVulkanInstanceFuncs(VkInstance i, PFN_vkGetInstanceProcAddr mpa) {
|
||||
return {
|
||||
.DestroyInstance = ipa<PFN_vkDestroyInstance>(mpa, i, "vkDestroyInstance"),
|
||||
.EnumeratePhysicalDevices = ipa<PFN_vkEnumeratePhysicalDevices>(mpa, i,
|
||||
"vkEnumeratePhysicalDevices"),
|
||||
.EnumerateDeviceExtensionProperties = ipa<PFN_vkEnumerateDeviceExtensionProperties>(mpa, i,
|
||||
"vkEnumerateDeviceExtensionProperties"),
|
||||
.GetPhysicalDeviceProperties2 = ipa<PFN_vkGetPhysicalDeviceProperties2>(mpa, i,
|
||||
"vkGetPhysicalDeviceProperties2"),
|
||||
.GetPhysicalDeviceQueueFamilyProperties =
|
||||
ipa<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(mpa, i,
|
||||
"vkGetPhysicalDeviceQueueFamilyProperties"),
|
||||
.GetPhysicalDeviceFeatures2 = ipa<PFN_vkGetPhysicalDeviceFeatures2>(mpa, i,
|
||||
"vkGetPhysicalDeviceFeatures2"),
|
||||
.GetPhysicalDeviceMemoryProperties = ipa<PFN_vkGetPhysicalDeviceMemoryProperties>(mpa, i,
|
||||
"vkGetPhysicalDeviceMemoryProperties"),
|
||||
.CreateDevice = ipa<PFN_vkCreateDevice>(mpa, i, "vkCreateDevice"),
|
||||
.GetDeviceProcAddr = ipa<PFN_vkGetDeviceProcAddr>(mpa, i, "vkGetDeviceProcAddr"),
|
||||
};
|
||||
}
|
||||
|
||||
/// initialize vulkan device function pointers
|
||||
VulkanDeviceFuncs vk::initVulkanDeviceFuncs(const VulkanInstanceFuncs& f, VkDevice d) {
|
||||
return {
|
||||
.GetDeviceQueue = dpa<PFN_vkGetDeviceQueue>(f, d, "vkGetDeviceQueue"),
|
||||
.DeviceWaitIdle = dpa<PFN_vkDeviceWaitIdle>(f, d, "vkDeviceWaitIdle"),
|
||||
.CreateCommandPool = dpa<PFN_vkCreateCommandPool>(f, d, "vkCreateCommandPool"),
|
||||
.DestroyCommandPool = dpa<PFN_vkDestroyCommandPool>(f, d, "vkDestroyCommandPool"),
|
||||
.CreateDescriptorPool = dpa<PFN_vkCreateDescriptorPool>(f, d, "vkCreateDescriptorPool"),
|
||||
.DestroyDescriptorPool = dpa<PFN_vkDestroyDescriptorPool>(f, d, "vkDestroyDescriptorPool"),
|
||||
.CreateBuffer = dpa<PFN_vkCreateBuffer>(f, d, "vkCreateBuffer"),
|
||||
.DestroyBuffer = dpa<PFN_vkDestroyBuffer>(f, d, "vkDestroyBuffer"),
|
||||
.GetBufferMemoryRequirements = dpa<PFN_vkGetBufferMemoryRequirements>(f, d,
|
||||
"vkGetBufferMemoryRequirements"),
|
||||
.AllocateMemory = dpa<PFN_vkAllocateMemory>(f, d, "vkAllocateMemory"),
|
||||
.FreeMemory = dpa<PFN_vkFreeMemory>(f, d, "vkFreeMemory"),
|
||||
.BindBufferMemory = dpa<PFN_vkBindBufferMemory>(f, d, "vkBindBufferMemory"),
|
||||
.MapMemory = dpa<PFN_vkMapMemory>(f, d, "vkMapMemory"),
|
||||
.UnmapMemory = dpa<PFN_vkUnmapMemory>(f, d, "vkUnmapMemory"),
|
||||
.AllocateCommandBuffers = dpa<PFN_vkAllocateCommandBuffers>(f, d,
|
||||
"vkAllocateCommandBuffers"),
|
||||
.FreeCommandBuffers = dpa<PFN_vkFreeCommandBuffers>(f, d, "vkFreeCommandBuffers"),
|
||||
.BeginCommandBuffer = dpa<PFN_vkBeginCommandBuffer>(f, d, "vkBeginCommandBuffer"),
|
||||
.EndCommandBuffer = dpa<PFN_vkEndCommandBuffer>(f, d, "vkEndCommandBuffer"),
|
||||
.CmdPipelineBarrier = dpa<PFN_vkCmdPipelineBarrier>(f, d, "vkCmdPipelineBarrier"),
|
||||
.CmdClearColorImage = dpa<PFN_vkCmdClearColorImage>(f, d, "vkCmdClearColorImage"),
|
||||
.CmdBindPipeline = dpa<PFN_vkCmdBindPipeline>(f, d, "vkCmdBindPipeline"),
|
||||
.CmdBindDescriptorSets = dpa<PFN_vkCmdBindDescriptorSets>(f, d, "vkCmdBindDescriptorSets"),
|
||||
.CmdDispatch = dpa<PFN_vkCmdDispatch>(f, d, "vkCmdDispatch"),
|
||||
.CmdCopyBufferToImage = dpa<PFN_vkCmdCopyBufferToImage>(f, d, "vkCmdCopyBufferToImage"),
|
||||
.QueueSubmit = dpa<PFN_vkQueueSubmit>(f, d, "vkQueueSubmit"),
|
||||
.AllocateDescriptorSets = dpa<PFN_vkAllocateDescriptorSets>(f, d,
|
||||
"vkAllocateDescriptorSets"),
|
||||
.FreeDescriptorSets = dpa<PFN_vkFreeDescriptorSets>(f, d, "vkFreeDescriptorSets"),
|
||||
.UpdateDescriptorSets = dpa<PFN_vkUpdateDescriptorSets>(f, d, "vkUpdateDescriptorSets"),
|
||||
.CreateFence = dpa<PFN_vkCreateFence>(f, d, "vkCreateFence"),
|
||||
.DestroyFence = dpa<PFN_vkDestroyFence>(f, d, "vkDestroyFence"),
|
||||
.ResetFences = dpa<PFN_vkResetFences>(f, d, "vkResetFences"),
|
||||
.WaitForFences = dpa<PFN_vkWaitForFences>(f, d, "vkWaitForFences"),
|
||||
.CreateImage = dpa<PFN_vkCreateImage>(f, d, "vkCreateImage"),
|
||||
.DestroyImage = dpa<PFN_vkDestroyImage>(f, d, "vkDestroyImage"),
|
||||
.GetImageMemoryRequirements = dpa<PFN_vkGetImageMemoryRequirements>(f, d,
|
||||
"vkGetImageMemoryRequirements"),
|
||||
.BindImageMemory = dpa<PFN_vkBindImageMemory>(f, d, "vkBindImageMemory"),
|
||||
.CreateImageView = dpa<PFN_vkCreateImageView>(f, d, "vkCreateImageView"),
|
||||
.DestroyImageView = dpa<PFN_vkDestroyImageView>(f, d, "vkDestroyImageView"),
|
||||
.CreateSampler = dpa<PFN_vkCreateSampler>(f, d, "vkCreateSampler"),
|
||||
.DestroySampler = dpa<PFN_vkDestroySampler>(f, d, "vkDestroySampler"),
|
||||
.CreateSemaphore = dpa<PFN_vkCreateSemaphore>(f, d, "vkCreateSemaphore"),
|
||||
.DestroySemaphore = dpa<PFN_vkDestroySemaphore>(f, d, "vkDestroySemaphore"),
|
||||
.CreateShaderModule = dpa<PFN_vkCreateShaderModule>(f, d, "vkCreateShaderModule"),
|
||||
.DestroyShaderModule = dpa<PFN_vkDestroyShaderModule>(f, d, "vkDestroyShaderModule"),
|
||||
.CreateDescriptorSetLayout = dpa<PFN_vkCreateDescriptorSetLayout>(f, d,
|
||||
"vkCreateDescriptorSetLayout"),
|
||||
.DestroyDescriptorSetLayout = dpa<PFN_vkDestroyDescriptorSetLayout>(f, d,
|
||||
"vkDestroyDescriptorSetLayout"),
|
||||
.CreatePipelineLayout = dpa<PFN_vkCreatePipelineLayout>(f, d, "vkCreatePipelineLayout"),
|
||||
.DestroyPipelineLayout = dpa<PFN_vkDestroyPipelineLayout>(f, d, "vkDestroyPipelineLayout"),
|
||||
.CreateComputePipelines = dpa<PFN_vkCreateComputePipelines>(f, d,
|
||||
"vkCreateComputePipelines"),
|
||||
.DestroyPipeline = dpa<PFN_vkDestroyPipeline>(f, d, "vkDestroyPipeline"),
|
||||
.SignalSemaphore = dpa<PFN_vkSignalSemaphore>(f, d, "vkSignalSemaphore"),
|
||||
.WaitSemaphores = dpa<PFN_vkWaitSemaphores>(f, d, "vkWaitSemaphores"),
|
||||
|
||||
.GetMemoryFdKHR = dpa<PFN_vkGetMemoryFdKHR>(f, d, "vkGetMemoryFdKHR"),
|
||||
.ImportSemaphoreFdKHR = dpa<PFN_vkImportSemaphoreFdKHR>(f, d, "vkImportSemaphoreFdKHR"),
|
||||
.GetSemaphoreFdKHR = dpa<PFN_vkGetSemaphoreFdKHR>(f, d, "vkGetSemaphoreFdKHR"),
|
||||
};
|
||||
}
|
||||
|
||||
Vulkan::Vulkan(const std::string& appName, version appVersion,
|
||||
const std::string& engineName, version engineVersion,
|
||||
PhysicalDeviceSelector selectPhysicalDevice) :
|
||||
|
|
@ -359,7 +357,7 @@ Vulkan::Vulkan(const std::string& appName, version appVersion,
|
|||
appName, appVersion,
|
||||
engineName, engineVersion
|
||||
)),
|
||||
instance_funcs(initVulkanInstanceFuncs(*this->instance)),
|
||||
instance_funcs(initVulkanInstanceFuncs(*this->instance, get_mpa())),
|
||||
physdev(findPhysicalDevice(this->instance_funcs,
|
||||
*this->instance,
|
||||
selectPhysicalDevice
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ Checks:
|
|||
- "-cppcoreguidelines-macro-usage"
|
||||
- "-cppcoreguidelines-pro-type-union-access"
|
||||
- "-cppcoreguidelines-avoid-non-const-global-variables"
|
||||
- "-cppcoreguidelines-pro-type-const-cast"
|
||||
# disable slow and pointless checks
|
||||
- "-modernize-use-std-numbers"
|
||||
- "-modernize-type-traits"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#include "layer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
|
@ -33,28 +33,36 @@ namespace {
|
|||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
/// struct containing various helper globals
|
||||
struct Globals {
|
||||
layer::Layer layer;
|
||||
|
||||
VkInstance instance{VK_NULL_HANDLE}; // if there are multiple instances, we scream
|
||||
vk::VulkanInstanceFuncs fi{};
|
||||
|
||||
std::unordered_map<std::string, PFN_vkVoidFunction> procAddrMap; // all overriden pointers
|
||||
|
||||
std::unordered_map<VkDevice, layer::LayerInstance> device2InstanceMap;
|
||||
};
|
||||
}
|
||||
|
||||
namespace {
|
||||
PFN_vkGetInstanceProcAddr nxvkGetInstanceProcAddr{nullptr};
|
||||
PFN_vkGetDeviceProcAddr nxvkGetDeviceProcAddr = nullptr;
|
||||
|
||||
auto& layer() {
|
||||
static std::optional<layer::Layer> instance; // NOLINT
|
||||
return instance;
|
||||
}
|
||||
|
||||
VkInstance gInstance{VK_NULL_HANDLE}; // if there are multiple instances, we scream out loud, oke?
|
||||
Globals* global{nullptr};
|
||||
void populateProcAddrMap();
|
||||
|
||||
// create instance
|
||||
PFN_vkGetInstanceProcAddr nxvkGetInstanceProcAddr{nullptr};
|
||||
VkResult myvkCreateInstance(
|
||||
const VkInstanceCreateInfo* info,
|
||||
const VkAllocationCallbacks* alloc,
|
||||
VkInstance* instance) {
|
||||
// try to load lsfg-vk layer
|
||||
try {
|
||||
if (!layer().has_value())
|
||||
layer().emplace();
|
||||
if (!global) { // cleanup in vkDestroyInstance
|
||||
global = new Globals();
|
||||
populateProcAddrMap();
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "lsfg-vk: something went wrong during lsfg-vk layer initialization:\n";
|
||||
std::cerr << "- " << e.what() << '\n';
|
||||
|
|
@ -97,14 +105,14 @@ namespace {
|
|||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
const auto& l = layer();
|
||||
if (!l.has_value() || !l->active()) // skip inactive
|
||||
const auto& l = global;
|
||||
if (!l || !l->layer.active()) // skip inactive
|
||||
return vkCreateInstance(info, alloc, instance);
|
||||
|
||||
auto extensions = add_extensions(
|
||||
info->ppEnabledExtensionNames,
|
||||
info->enabledExtensionCount,
|
||||
l->instanceExtensions());
|
||||
l->layer.instanceExtensions());
|
||||
|
||||
VkInstanceCreateInfo newInfo = *info;
|
||||
newInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||
|
|
@ -118,17 +126,13 @@ namespace {
|
|||
if (res != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
gInstance = *instance;
|
||||
l->instance = *instance;
|
||||
l->fi = vk::initVulkanInstanceFuncs(l->instance, nxvkGetInstanceProcAddr);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// map of devices to layer instances
|
||||
std::unordered_map<VkDevice, layer::LayerInstance>& device2InstanceMap() {
|
||||
static std::unordered_map<VkDevice, layer::LayerInstance> map; // NOLINT
|
||||
return map;
|
||||
}
|
||||
|
||||
// create device
|
||||
PFN_vkGetDeviceProcAddr nxvkGetDeviceProcAddr{nullptr};
|
||||
VkResult myvkCreateDevice(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkDeviceCreateInfo* info,
|
||||
|
|
@ -153,8 +157,9 @@ namespace {
|
|||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
global->fi.GetDeviceProcAddr = linkInfo->pfnNextGetDeviceProcAddr;
|
||||
nxvkGetDeviceProcAddr = linkInfo->pfnNextGetDeviceProcAddr;
|
||||
if (!nxvkGetDeviceProcAddr) {
|
||||
if (!linkInfo->pfnNextGetDeviceProcAddr) {
|
||||
std::cerr << "lsfg-vk: next layer's vkGetDeviceProcAddr is null, "
|
||||
"the previous layer does not follow spec\n";
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
|
|
@ -180,28 +185,16 @@ namespace {
|
|||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
const auto& l = layer();
|
||||
if (!l.has_value() || !l->active()) // skip inactive
|
||||
return vkCreateDevice(physicalDevice, info, alloc, device);
|
||||
|
||||
auto extensions = add_extensions(
|
||||
info->ppEnabledExtensionNames,
|
||||
info->enabledExtensionCount,
|
||||
l->deviceExtensions());
|
||||
global->layer.deviceExtensions());
|
||||
|
||||
VkDeviceCreateInfo newInfo = *info;
|
||||
newInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||
newInfo.ppEnabledExtensionNames = extensions.data();
|
||||
|
||||
auto res = vkCreateDevice(physicalDevice, &newInfo, alloc, device);
|
||||
auto res = global->fi.CreateDevice(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";
|
||||
|
|
@ -211,8 +204,14 @@ namespace {
|
|||
|
||||
// create layer instance
|
||||
try {
|
||||
device2InstanceMap().emplace(*device,
|
||||
layer::LayerInstance(*l, gInstance, *device, setLoaderData));
|
||||
global->device2InstanceMap.emplace(
|
||||
*device,
|
||||
layer::LayerInstance(
|
||||
global->layer, vk::initVulkanDeviceFuncs(global->fi, *device),
|
||||
global->instance, *device,
|
||||
setLoaderData
|
||||
)
|
||||
);
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "lsfg-vk: something went wrong during lsfg-vk initialization:\n";
|
||||
std::cerr << "- " << e.what() << '\n';
|
||||
|
|
@ -221,12 +220,32 @@ namespace {
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
PFN_vkVoidFunction getProcAddr(const std::string& name);
|
||||
// populate function pointer override map
|
||||
void populateProcAddrMap() {
|
||||
#define VKPTR(name) reinterpret_cast<PFN_vkVoidFunction>(name)
|
||||
global->procAddrMap = {
|
||||
{ "vkCreateInstance", VKPTR(myvkCreateInstance) },
|
||||
{ "vkCreateDevice", VKPTR(myvkCreateDevice) },
|
||||
};
|
||||
#undef VKPTR
|
||||
}
|
||||
|
||||
// get optional function pointer override
|
||||
PFN_vkVoidFunction getProcAddr(const std::string& name) {
|
||||
if (!global) return nullptr;
|
||||
auto it = global->procAddrMap.find(name);
|
||||
if (it != global->procAddrMap.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// get instance-level function pointers
|
||||
PFN_vkVoidFunction myvkGetInstanceProcAddr(VkInstance instance, const char* pName) {
|
||||
if (!pName) return nullptr;
|
||||
|
||||
if (std::string(pName) == "vkCreateInstance") // pre-instance function
|
||||
return reinterpret_cast<PFN_vkVoidFunction>(myvkCreateInstance);
|
||||
|
||||
auto func = getProcAddr(pName);
|
||||
if (func) return func;
|
||||
|
||||
|
|
@ -245,15 +264,6 @@ namespace {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "layer.hpp"
|
||||
#include "detection.hpp"
|
||||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
|
@ -72,7 +73,7 @@ std::vector<const char*> Layer::deviceExtensions() const {
|
|||
};
|
||||
}
|
||||
|
||||
layer::LayerInstance::LayerInstance(const Layer& layer,
|
||||
layer::LayerInstance::LayerInstance(const Layer& layer, vk::VulkanDeviceFuncs df,
|
||||
VkInstance instance, VkDevice device,
|
||||
PFN_vkSetDeviceLoaderData setLoaderData) {
|
||||
std::cerr << "lsfg-vk: Hello, world!\n";
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#include "config.hpp"
|
||||
#include "detection.hpp"
|
||||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vk_layer.h>
|
||||
|
|
@ -48,10 +48,11 @@ namespace lsfgvk::layer {
|
|||
public:
|
||||
/// create a new layer instance
|
||||
/// @param layer parent layer
|
||||
/// @param df Vulkan device function pointers
|
||||
/// @param instance Vulkan instance
|
||||
/// @param device Vulkan device
|
||||
/// @param setLoaderData function to set device loader data
|
||||
LayerInstance(const Layer& layer,
|
||||
LayerInstance(const Layer& layer, vk::VulkanDeviceFuncs df,
|
||||
VkInstance instance, VkDevice device,
|
||||
PFN_vkSetDeviceLoaderData setLoaderData);
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue