much more verbose logging in hook

This commit is contained in:
PancakeTAS 2025-07-06 13:30:38 +02:00
parent 2eeadd49b0
commit 9f806d5bb5
No known key found for this signature in database
7 changed files with 436 additions and 83 deletions

View file

@ -10,6 +10,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_SKIP_RPATH ON) set(CMAKE_SKIP_RPATH ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions("-DLSFG_NO_DEBUG")
endif()
# subprojects # subprojects
include(cmake/FetchDXVK.cmake) include(cmake/FetchDXVK.cmake)
include(cmake/FetchPeParse.cmake) include(cmake/FetchPeParse.cmake)

View file

@ -2,35 +2,72 @@
#define LOG_HPP #define LOG_HPP
#include <format> #include <format>
#include <fstream>
#include <iostream> #include <iostream>
#include <mutex>
#include <set>
namespace Log { namespace Log {
namespace Internal {
extern bool isSetup;
extern std::set<std::string> debugModules;
extern bool debugAllModules;
extern std::ofstream logFile;
extern std::mutex logMutex;
void setup();
}
template<typename... Args>
void log(std::string_view color, std::string_view module,
std::format_string<Args...> fmt, Args&&... args) {
Internal::setup();
std::string prefix = std::format("lsfg-vk({}): ", module);
std::string message = std::format(fmt, std::forward<Args>(args)...);
std::lock_guard<std::mutex> lock(Internal::logMutex);
std::cerr << color << prefix << message << "\033[0m" << '\n';
if (Internal::logFile.is_open()) {
Internal::logFile << prefix << message << '\n';
Internal::logFile.flush();
}
}
const std::string_view WHITE = "\033[1;37m"; const std::string_view WHITE = "\033[1;37m";
const std::string_view YELLOW = "\033[1;33m"; const std::string_view YELLOW = "\033[1;33m";
const std::string_view RED = "\033[1;31m"; const std::string_view RED = "\033[1;31m";
template<typename... Args>
void info(std::string_view module, std::format_string<Args...> fmt, Args&&... args) {
log(WHITE, module, fmt, std::forward<Args>(args)...);
}
template<typename... Args>
void warn(std::string_view module, std::format_string<Args...> fmt, Args&&... args) {
log(YELLOW, module, fmt, std::forward<Args>(args)...);
}
template<typename... Args>
void error(std::string_view module, std::format_string<Args...> fmt, Args&&... args) {
log(RED, module, fmt, std::forward<Args>(args)...);
}
const std::string_view GRAY = "\033[1;90m"; const std::string_view GRAY = "\033[1;90m";
const std::string_view RESET = "\033[0m";
#ifdef LSFG_NO_DEBUG
template<typename... Args>
void debug(std::string_view, std::format_string<Args...>, Args&&...) {} // NOLINT
#else
template<typename... Args> template<typename... Args>
void info(std::format_string<Args...> fmt, Args&&... args) { void debug(std::string_view module, std::format_string<Args...> fmt, Args&&... args) {
std::cerr << WHITE << std::format(fmt, std::forward<Args>(args)...) << RESET << '\n'; if (Internal::debugAllModules || Internal::debugModules.contains(std::string(module)))
} log(GRAY, module, fmt, std::forward<Args>(args)...);
template<typename... Args>
void warn(std::format_string<Args...> fmt, Args&&... args) {
std::cerr << YELLOW << std::format(fmt, std::forward<Args>(args)...) << RESET << '\n';
}
template<typename... Args>
void error(std::format_string<Args...> fmt, Args&&... args) {
std::cerr << RED << std::format(fmt, std::forward<Args>(args)...) << RESET << '\n';
}
template<typename... Args>
void debug(std::format_string<Args...> fmt, Args&&... args) {
std::cerr << GRAY << std::format(fmt, std::forward<Args>(args)...) << RESET << '\n';
} }
#endif
} }

View file

@ -1,5 +1,6 @@
#include "context.hpp" #include "context.hpp"
#include "layer.hpp" #include "layer.hpp"
#include "utils/log.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include <lsfg.hpp> #include <lsfg.hpp>
@ -11,7 +12,7 @@ LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain,
VkExtent2D extent, const std::vector<VkImage>& swapchainImages) VkExtent2D extent, const std::vector<VkImage>& swapchainImages)
: swapchain(swapchain), swapchainImages(swapchainImages), : swapchain(swapchain), swapchainImages(swapchainImages),
extent(extent) { extent(extent) {
// initialize lsfg // prepare textures for lsfg
int frame_0_fd{}; int frame_0_fd{};
this->frame_0 = Mini::Image( this->frame_0 = Mini::Image(
info.device, info.physicalDevice, info.device, info.physicalDevice,
@ -19,6 +20,8 @@ LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain,
VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
&frame_0_fd); &frame_0_fd);
Log::info("context", "Created frame_0 image and obtained fd: {}",
frame_0_fd);
int frame_1_fd{}; int frame_1_fd{};
this->frame_1 = Mini::Image( this->frame_1 = Mini::Image(
@ -27,27 +30,42 @@ LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain,
VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
&frame_1_fd); &frame_1_fd);
Log::info("context", "Created frame_1 image and obtained fd: {}",
frame_1_fd);
std::vector<int> out_n_fds(info.frameGen); std::vector<int> out_n_fds(info.frameGen);
for (size_t i = 0; i < info.frameGen; ++i) for (size_t i = 0; i < info.frameGen; ++i) {
this->out_n.emplace_back( this->out_n.emplace_back(
info.device, info.physicalDevice, info.device, info.physicalDevice,
extent, VK_FORMAT_R8G8B8A8_UNORM, extent, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
&out_n_fds.at(i)); &out_n_fds.at(i));
Log::info("context", "Created out_n[{}] image and obtained fd: {}",
i, out_n_fds.at(i));
}
// initialize lsfg
Log::debug("context", "(entering LSFG initialization)");
Utils::storeLayerEnv(); Utils::storeLayerEnv();
LSFG::initialize(); LSFG::initialize();
Utils::restoreLayerEnv(); Utils::restoreLayerEnv();
Log::debug("context", "(exiting LSFG initialization)");
Log::debug("context", "(entering LSFG context creation)");
this->lsfgCtxId = std::shared_ptr<int32_t>( this->lsfgCtxId = std::shared_ptr<int32_t>(
new int32_t(LSFG::createContext(extent.width, extent.height, new int32_t(LSFG::createContext(extent.width, extent.height,
frame_0_fd, frame_1_fd, out_n_fds)), frame_0_fd, frame_1_fd, out_n_fds)),
[](const int32_t* id) { [](const int32_t* id) {
Log::info("context",
"(entering LSFG context deletion with id: {})", *id);
LSFG::deleteContext(*id); LSFG::deleteContext(*id);
Log::info("context",
"(exiting LSFG context deletion with id: {})", *id);
} }
); );
Log::info("context", "(exiting LSFG context creation with id: {})",
*this->lsfgCtxId);
// prepare render passes // prepare render passes
this->cmdPool = Mini::CommandPool(info.device, info.queue.first); this->cmdPool = Mini::CommandPool(info.device, info.queue.first);
@ -59,6 +77,8 @@ LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain,
pass.postCopySemaphores.resize(info.frameGen); pass.postCopySemaphores.resize(info.frameGen);
pass.prevPostCopySemaphores.resize(info.frameGen); pass.prevPostCopySemaphores.resize(info.frameGen);
} }
Log::info("context", "Remaining misc context init finished successfully.");
} }
VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, VkQueue queue, VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, VkQueue queue,
@ -66,6 +86,8 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
auto& pass = this->passInfos.at(this->frameIdx % 8); auto& pass = this->passInfos.at(this->frameIdx % 8);
// 1. copy swapchain image to frame_0/frame_1 // 1. copy swapchain image to frame_0/frame_1
Log::debug("context2", "1. Copying swapchain image {} to frame {}",
presentIdx, this->frameIdx % 2 == 0 ? "0" : "1");
int preCopySemaphoreFd{}; int preCopySemaphoreFd{};
pass.preCopySemaphores.at(0) = Mini::Semaphore(info.device, &preCopySemaphoreFd); pass.preCopySemaphores.at(0) = Mini::Semaphore(info.device, &preCopySemaphoreFd);
pass.preCopySemaphores.at(1) = Mini::Semaphore(info.device); pass.preCopySemaphores.at(1) = Mini::Semaphore(info.device);
@ -91,16 +113,22 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
pass.preCopySemaphores.at(1).handle() }); pass.preCopySemaphores.at(1).handle() });
// 2. render intermediary frames // 2. render intermediary frames
Log::debug("context2", "2. Rendering intermediary frames");
std::vector<int> renderSemaphoreFds(info.frameGen); std::vector<int> renderSemaphoreFds(info.frameGen);
for (size_t i = 0; i < info.frameGen; ++i) for (size_t i = 0; i < info.frameGen; ++i)
pass.renderSemaphores.at(i) = Mini::Semaphore(info.device, &renderSemaphoreFds.at(i)); pass.renderSemaphores.at(i) = Mini::Semaphore(info.device, &renderSemaphoreFds.at(i));
Log::debug("context2",
"(entering LSFG present with id: {})", *this->lsfgCtxId);
LSFG::presentContext(*this->lsfgCtxId, LSFG::presentContext(*this->lsfgCtxId,
preCopySemaphoreFd, preCopySemaphoreFd,
renderSemaphoreFds); renderSemaphoreFds);
Log::debug("context2",
"(exiting LSFG present with id: {})", *this->lsfgCtxId);
for (size_t i = 0; i < info.frameGen; i++) { for (size_t i = 0; i < info.frameGen; i++) {
// 3. acquire next swapchain image // 3. acquire next swapchain image
Log::debug("context2", "3. Acquiring next swapchain image for frame {}", i);
pass.acquireSemaphores.at(i) = Mini::Semaphore(info.device); pass.acquireSemaphores.at(i) = Mini::Semaphore(info.device);
uint32_t imageIdx{}; uint32_t imageIdx{};
auto res = Layer::ovkAcquireNextImageKHR(info.device, this->swapchain, UINT64_MAX, auto res = Layer::ovkAcquireNextImageKHR(info.device, this->swapchain, UINT64_MAX,
@ -109,6 +137,7 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
throw LSFG::vulkan_error(res, "Failed to acquire next swapchain image"); throw LSFG::vulkan_error(res, "Failed to acquire next swapchain image");
// 4. copy output image to swapchain image // 4. copy output image to swapchain image
Log::debug("context2", "4. Copying output image to swapchain image for frame {}", i);
pass.postCopySemaphores.at(i) = Mini::Semaphore(info.device); pass.postCopySemaphores.at(i) = Mini::Semaphore(info.device);
pass.prevPostCopySemaphores.at(i) = Mini::Semaphore(info.device); pass.prevPostCopySemaphores.at(i) = Mini::Semaphore(info.device);
pass.postCopyBufs.at(i) = Mini::CommandBuffer(info.device, this->cmdPool); pass.postCopyBufs.at(i) = Mini::CommandBuffer(info.device, this->cmdPool);
@ -129,6 +158,7 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
pass.prevPostCopySemaphores.at(i).handle() }); pass.prevPostCopySemaphores.at(i).handle() });
// 5. present swapchain image // 5. present swapchain image
Log::debug("context2", "5. Presenting swapchain image for frame {}", i);
std::vector<VkSemaphore> waitSemaphores{ pass.postCopySemaphores.at(i).handle() }; std::vector<VkSemaphore> waitSemaphores{ pass.postCopySemaphores.at(i).handle() };
if (i != 0) waitSemaphores.emplace_back(pass.prevPostCopySemaphores.at(i - 1).handle()); if (i != 0) waitSemaphores.emplace_back(pass.prevPostCopySemaphores.at(i - 1).handle());
@ -147,6 +177,7 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
} }
// 6. present actual next frame // 6. present actual next frame
Log::debug("context2", "6. Presenting actual next frame");
VkSemaphore lastPrevPostCopySemaphore = VkSemaphore lastPrevPostCopySemaphore =
pass.prevPostCopySemaphores.at(info.frameGen - 1).handle(); pass.prevPostCopySemaphores.at(info.frameGen - 1).handle();
const VkPresentInfoKHR presentInfo{ const VkPresentInfoKHR presentInfo{

View file

@ -27,18 +27,26 @@ namespace {
"VK_KHR_external_memory_capabilities", "VK_KHR_external_memory_capabilities",
"VK_KHR_external_semaphore_capabilities" "VK_KHR_external_semaphore_capabilities"
}); });
Log::info("lsfg-vk: Created Vulkan instance");
VkInstanceCreateInfo createInfo = *pCreateInfo; VkInstanceCreateInfo createInfo = *pCreateInfo;
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size()); createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
createInfo.ppEnabledExtensionNames = extensions.data(); createInfo.ppEnabledExtensionNames = extensions.data();
return Layer::ovkCreateInstance(&createInfo, pAllocator, pInstance); auto res = Layer::ovkCreateInstance(&createInfo, pAllocator, pInstance);
if (res != VK_SUCCESS) {
Log::error("hooks", "Failed to create Vulkan instance: {:x}",
static_cast<uint32_t>(res));
return res;
}
Log::info("hooks", "Instance created successfully: {:x}",
reinterpret_cast<uintptr_t>(*pInstance));
return res;
} }
void myvkDestroyInstance( void myvkDestroyInstance(
VkInstance instance, VkInstance instance,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::info("lsfg-vk: Destroyed Vulkan instance"); Log::info("hooks", "Instance destroyed successfully: {:x}",
reinterpret_cast<uintptr_t>(instance));
Layer::ovkDestroyInstance(instance, pAllocator); Layer::ovkDestroyInstance(instance, pAllocator);
} }
@ -63,38 +71,59 @@ namespace {
VkDeviceCreateInfo createInfo = *pCreateInfo; VkDeviceCreateInfo createInfo = *pCreateInfo;
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size()); createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
createInfo.ppEnabledExtensionNames = extensions.data(); createInfo.ppEnabledExtensionNames = extensions.data();
return Layer::ovkCreateDevice(physicalDevice, &createInfo, pAllocator, pDevice); auto res = Layer::ovkCreateDevice(physicalDevice, &createInfo, pAllocator, pDevice);
if (res != VK_SUCCESS) {
Log::error("hooks", "Failed to create Vulkan device: {:x}",
static_cast<uint32_t>(res));
return res;
}
Log::info("hooks", "Device created successfully: {:x}",
reinterpret_cast<uintptr_t>(*pDevice));
return res;
} }
VkResult myvkCreateDevicePost( VkResult myvkCreateDevicePost(
VkPhysicalDevice physicalDevice, VkPhysicalDevice physicalDevice,
VkDeviceCreateInfo* pCreateInfo, VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks*, // NOLINT
VkDevice* pDevice) { VkDevice* pDevice) {
// store device info // store device info
Log::debug("hooks", "Creating device info for device: {:x}",
reinterpret_cast<uintptr_t>(*pDevice));
try { try {
const char* frameGen = std::getenv("LSFG_MULTIPLIER"); const char* frameGenEnv = std::getenv("LSFG_MULTIPLIER");
if (!frameGen) frameGen = "2"; const uint64_t frameGen = std::max<uint64_t>(1,
std::stoul(frameGenEnv ? frameGenEnv : "2") - 1);
Log::debug("hooks", "Using {}x frame generation",
frameGen + 1);
auto queue = Utils::findQueue(*pDevice, physicalDevice, pCreateInfo,
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
Log::debug("hooks", "Found queue at index {}: {:x}",
queue.first, reinterpret_cast<uintptr_t>(queue.second));
devices.emplace(*pDevice, DeviceInfo { devices.emplace(*pDevice, DeviceInfo {
.device = *pDevice, .device = *pDevice,
.physicalDevice = physicalDevice, .physicalDevice = physicalDevice,
.queue = Utils::findQueue(*pDevice, physicalDevice, pCreateInfo, .queue = queue,
VK_QUEUE_GRAPHICS_BIT), .frameGen = frameGen,
.frameGen = std::max<size_t>(1, std::stoul(frameGen) - 1)
}); });
} catch (const std::exception& e) { } catch (const std::exception& e) {
Log::error("Failed to create device info: {}", e.what()); Log::error("hooks", "Failed to create device info: {}", e.what());
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
Log::info("lsfg-vk: Created Vulkan device"); Log::info("hooks", "Device info created successfully for: {:x}",
reinterpret_cast<uintptr_t>(*pDevice));
return VK_SUCCESS; return VK_SUCCESS;
} }
void myvkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { void myvkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
devices.erase(device); // erase device info devices.erase(device); // erase device info
Log::info("lsfg-vk: Destroyed Vulkan device"); Log::info("hooks", "Device & Device info destroyed successfully: {:x}",
reinterpret_cast<uintptr_t>(device));
Layer::ovkDestroyDevice(device, pAllocator); Layer::ovkDestroyDevice(device, pAllocator);
} }
@ -118,10 +147,25 @@ namespace {
createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; // force vsync createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; // force vsync
auto res = Layer::ovkCreateSwapchainKHR(device, &createInfo, pAllocator, pSwapchain); auto res = Layer::ovkCreateSwapchainKHR(device, &createInfo, pAllocator, pSwapchain);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
Log::error("Failed to create swapchain: {:x}", static_cast<uint32_t>(res)); Log::error("hooks", "Failed to create swapchain: {:x}", static_cast<uint32_t>(res));
return res; return res;
} }
Log::info("hooks", "Swapchain created successfully: {:x}",
reinterpret_cast<uintptr_t>(*pSwapchain));
// retire previous swapchain if it exists
if (pCreateInfo->oldSwapchain) {
Log::debug("hooks", "Retiring previous swapchain context: {:x}",
reinterpret_cast<uintptr_t>(pCreateInfo->oldSwapchain));
swapchains.erase(pCreateInfo->oldSwapchain);
swapchainToDeviceTable.erase(pCreateInfo->oldSwapchain);
Log::info("hooks", "Previous swapchain context retired successfully: {:x}",
reinterpret_cast<uintptr_t>(pCreateInfo->oldSwapchain));
}
// create swapchain context
Log::debug("hooks", "Creating swapchain context for device: {:x}",
reinterpret_cast<uintptr_t>(device));
try { try {
// get swapchain images // get swapchain images
uint32_t imageCount{}; uint32_t imageCount{};
@ -133,24 +177,25 @@ namespace {
res = Layer::ovkGetSwapchainImagesKHR(device, *pSwapchain, &imageCount, swapchainImages.data()); res = Layer::ovkGetSwapchainImagesKHR(device, *pSwapchain, &imageCount, swapchainImages.data());
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
throw LSFG::vulkan_error(res, "Failed to get swapchain images"); throw LSFG::vulkan_error(res, "Failed to get swapchain images");
Log::debug("hooks", "Swapchain has {} images", swapchainImages.size());
// create swapchain context // create swapchain context
swapchains.emplace(*pSwapchain, LsContext( swapchains.emplace(*pSwapchain, LsContext(
deviceInfo, *pSwapchain, pCreateInfo->imageExtent, deviceInfo, *pSwapchain, pCreateInfo->imageExtent,
swapchainImages swapchainImages
)); ));
swapchainToDeviceTable.emplace(*pSwapchain, device); swapchainToDeviceTable.emplace(*pSwapchain, device);
} catch (const LSFG::vulkan_error& e) { } catch (const LSFG::vulkan_error& e) {
Log::error("Encountered Vulkan error {:x} while creating swapchain: {}", Log::error("hooks", "Encountered Vulkan error {:x} while creating swapchain context: {}",
static_cast<uint32_t>(e.error()), e.what()); static_cast<uint32_t>(e.error()), e.what());
return e.error(); return e.error();
} catch (const std::exception& e) { } catch (const std::exception& e) {
Log::error("Encountered error while creating swapchain: {}", e.what()); Log::error("hooks", "Encountered error while creating swapchain context: {}", e.what());
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
Log::info("lsfg-vk: Created swapchain with {} images", pCreateInfo->minImageCount); Log::info("hooks", "Swapchain context created successfully for: {:x}",
reinterpret_cast<uintptr_t>(*pSwapchain));
return res; return res;
} }
@ -160,21 +205,33 @@ namespace {
auto& deviceInfo = devices.at(swapchainToDeviceTable.at(*pPresentInfo->pSwapchains)); auto& deviceInfo = devices.at(swapchainToDeviceTable.at(*pPresentInfo->pSwapchains));
auto& swapchain = swapchains.at(*pPresentInfo->pSwapchains); auto& swapchain = swapchains.at(*pPresentInfo->pSwapchains);
Log::debug("hooks2", "Presenting swapchain: {:x} on queue: {:x}",
reinterpret_cast<uintptr_t>(*pPresentInfo->pSwapchains),
reinterpret_cast<uintptr_t>(queue));
VkResult res{};
try { try {
std::vector<VkSemaphore> waitSemaphores(pPresentInfo->waitSemaphoreCount); std::vector<VkSemaphore> semaphores(pPresentInfo->waitSemaphoreCount);
std::copy_n(pPresentInfo->pWaitSemaphores, waitSemaphores.size(), waitSemaphores.data()); std::copy_n(pPresentInfo->pWaitSemaphores, semaphores.size(), semaphores.data());
Log::debug("hooks2", "Waiting on {} semaphores", semaphores.size());
// present the next frame // present the next frame
return swapchain.present(deviceInfo, pPresentInfo->pNext, res = swapchain.present(deviceInfo, pPresentInfo->pNext,
queue, waitSemaphores, *pPresentInfo->pImageIndices); queue, semaphores, *pPresentInfo->pImageIndices);
} catch (const LSFG::vulkan_error& e) { } catch (const LSFG::vulkan_error& e) {
Log::error("Encountered Vulkan error {:x} while presenting: {}", Log::error("hooks2", "Encountered Vulkan error {:x} while presenting: {}",
static_cast<uint32_t>(e.error()), e.what()); static_cast<uint32_t>(e.error()), e.what());
return e.error(); return e.error();
} catch (const std::exception& e) { } catch (const std::exception& e) {
Log::error("Encountered error while creating presenting: {}", e.what()); Log::error("hooks2", "Encountered error while creating presenting: {}",
e.what());
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
// non VK_SUCCESS or VK_SUBOPTIMAL_KHR doesn't reach here
Log::debug("hooks2", "Presented swapchain {:x} on queue {:x} successfully",
reinterpret_cast<uintptr_t>(*pPresentInfo->pSwapchains),
reinterpret_cast<uintptr_t>(queue));
return res;
} }
void myvkDestroySwapchainKHR( void myvkDestroySwapchainKHR(
@ -184,7 +241,8 @@ namespace {
swapchains.erase(swapchain); // erase swapchain context swapchains.erase(swapchain); // erase swapchain context
swapchainToDeviceTable.erase(swapchain); swapchainToDeviceTable.erase(swapchain);
Log::info("lsfg-vk: Destroyed swapchain"); Log::info("hooks", "Swapchain & Swapchain context destroyed successfully: {:x}",
reinterpret_cast<uintptr_t>(swapchain));
Layer::ovkDestroySwapchainKHR(device, swapchain, pAllocator); Layer::ovkDestroySwapchainKHR(device, swapchain, pAllocator);
} }
} }

View file

@ -51,7 +51,7 @@ namespace {
bool initInstanceFunc(VkInstance instance, const char* name, T* func) { bool initInstanceFunc(VkInstance instance, const char* name, T* func) {
*func = reinterpret_cast<T>(next_vkGetInstanceProcAddr(instance, name)); *func = reinterpret_cast<T>(next_vkGetInstanceProcAddr(instance, name));
if (!*func) { if (!*func) {
Log::error("lsfg-vk(layer): Failed to get instance function pointer for {}", name); Log::error("layer", "Failed to get instance function pointer for {}", name);
return false; return false;
} }
return true; return true;
@ -61,7 +61,7 @@ namespace {
bool initDeviceFunc(VkDevice device, const char* name, T* func) { bool initDeviceFunc(VkDevice device, const char* name, T* func) {
*func = reinterpret_cast<T>(next_vkGetDeviceProcAddr(device, name)); *func = reinterpret_cast<T>(next_vkGetDeviceProcAddr(device, name));
if (!*func) { if (!*func) {
Log::error("lsfg-vk(layer): Failed to get device function pointer for {}", name); Log::error("layer", "Failed to get device function pointer for {}", name);
return false; return false;
} }
return true; return true;
@ -74,7 +74,7 @@ namespace {
const VkInstanceCreateInfo* pCreateInfo, const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance) { VkInstance* pInstance) {
Log::debug("lsfg-vk(layer): Initializing lsfg-vk instance layer"); Log::debug("layer", "Initializing lsfg-vk instance layer...");
// find layer creation info // find layer creation info
auto* layerDesc = const_cast<VkLayerInstanceCreateInfo*>( auto* layerDesc = const_cast<VkLayerInstanceCreateInfo*>(
@ -85,12 +85,15 @@ namespace {
reinterpret_cast<const VkLayerInstanceCreateInfo*>(layerDesc->pNext)); reinterpret_cast<const VkLayerInstanceCreateInfo*>(layerDesc->pNext));
} }
if (!layerDesc) { if (!layerDesc) {
Log::error("lsfg-vk(layer): No layer creation info found in pNext chain"); Log::error("layer", "No layer creation info found in pNext chain");
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
// advance link info (i don't really know what this does) // advance link info (i don't really know what this does)
next_vkGetInstanceProcAddr = layerDesc->u.pLayerInfo->pfnNextGetInstanceProcAddr; next_vkGetInstanceProcAddr = layerDesc->u.pLayerInfo->pfnNextGetInstanceProcAddr;
Log::debug("layer", "Next instance proc addr: {:x}",
reinterpret_cast<uintptr_t>(next_vkGetInstanceProcAddr));
layerDesc->u.pLayerInfo = layerDesc->u.pLayerInfo->pNext; layerDesc->u.pLayerInfo = layerDesc->u.pLayerInfo->pNext;
// create instance // create instance
@ -101,7 +104,7 @@ namespace {
Hooks::hooks["vkCreateInstance"]); Hooks::hooks["vkCreateInstance"]);
auto res = layer_vkCreateInstance2(pCreateInfo, pAllocator, pInstance); auto res = layer_vkCreateInstance2(pCreateInfo, pAllocator, pInstance);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
Log::error("lsfg-vk(layer): Failed to create Vulkan instance: {:x}", Log::error("layer", "Failed to create Vulkan instance: {:x}",
static_cast<uint32_t>(res)); static_cast<uint32_t>(res));
return res; return res;
} }
@ -112,11 +115,11 @@ namespace {
success &= initInstanceFunc(*pInstance, "vkGetPhysicalDeviceQueueFamilyProperties", &next_vkGetPhysicalDeviceQueueFamilyProperties); success &= initInstanceFunc(*pInstance, "vkGetPhysicalDeviceQueueFamilyProperties", &next_vkGetPhysicalDeviceQueueFamilyProperties);
success &= initInstanceFunc(*pInstance, "vkGetPhysicalDeviceMemoryProperties", &next_vkGetPhysicalDeviceMemoryProperties); success &= initInstanceFunc(*pInstance, "vkGetPhysicalDeviceMemoryProperties", &next_vkGetPhysicalDeviceMemoryProperties);
if (!success) { if (!success) {
Log::error("lsfg-vk(layer): Failed to get instance function pointers"); Log::error("layer", "Failed to get instance function pointers");
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
Log::debug("lsfg-vk(layer): Successfully initialized lsfg-vk instance layer"); Log::debug("layer", "Successfully initialized lsfg-vk instance layer");
return res; return res;
} // NOLINTEND } // NOLINTEND
@ -125,7 +128,7 @@ namespace {
const VkDeviceCreateInfo* pCreateInfo, const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice) { VkDevice* pDevice) {
Log::debug("lsfg-vk(layer): Initializing lsfg-vk device layer"); Log::debug("layer", "Initializing lsfg-vk device layer...");
// find layer creation info // find layer creation info
auto* layerDesc = const_cast<VkLayerDeviceCreateInfo*>( auto* layerDesc = const_cast<VkLayerDeviceCreateInfo*>(
@ -136,24 +139,26 @@ namespace {
reinterpret_cast<const VkLayerDeviceCreateInfo*>(layerDesc->pNext)); reinterpret_cast<const VkLayerDeviceCreateInfo*>(layerDesc->pNext));
} }
if (!layerDesc) { if (!layerDesc) {
Log::error("lsfg-vk(layer): No layer creation info found in pNext chain"); Log::error("layer", "No layer creation info found in pNext chain");
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
// advance link info (i don't really know what this does) // advance link info (i don't really know what this does)
next_vkGetDeviceProcAddr = layerDesc->u.pLayerInfo->pfnNextGetDeviceProcAddr; next_vkGetDeviceProcAddr = layerDesc->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Log::debug("layer", "Next device proc addr: {:x}",
reinterpret_cast<uintptr_t>(next_vkGetDeviceProcAddr));
layerDesc->u.pLayerInfo = layerDesc->u.pLayerInfo->pNext; layerDesc->u.pLayerInfo = layerDesc->u.pLayerInfo->pNext;
// create device // create device
auto success = initInstanceFunc(nullptr, "vkCreateDevice", auto success = initInstanceFunc(nullptr, "vkCreateDevice", &next_vkCreateDevice);
&next_vkCreateDevice);
if (!success) return VK_ERROR_INITIALIZATION_FAILED; if (!success) return VK_ERROR_INITIALIZATION_FAILED;
auto* layer_vkCreateDevice2 = reinterpret_cast<PFN_vkCreateDevice>( auto* layer_vkCreateDevice2 = reinterpret_cast<PFN_vkCreateDevice>(
Hooks::hooks["vkCreateDevicePre"]); Hooks::hooks["vkCreateDevicePre"]);
auto res = layer_vkCreateDevice2(physicalDevice, pCreateInfo, pAllocator, pDevice); auto res = layer_vkCreateDevice2(physicalDevice, pCreateInfo, pAllocator, pDevice);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
Log::error("lsfg-vk(layer): Failed to create Vulkan device: {:x}", Log::error("layer", "Failed to create Vulkan device: {:x}",
static_cast<uint32_t>(res)); static_cast<uint32_t>(res));
return res; return res;
} }
@ -187,7 +192,7 @@ namespace {
success &= initDeviceFunc(*pDevice, "vkCmdCopyImage", &next_vkCmdCopyImage); success &= initDeviceFunc(*pDevice, "vkCmdCopyImage", &next_vkCmdCopyImage);
success &= initDeviceFunc(*pDevice, "vkAcquireNextImageKHR", &next_vkAcquireNextImageKHR); success &= initDeviceFunc(*pDevice, "vkAcquireNextImageKHR", &next_vkAcquireNextImageKHR);
if (!success) { if (!success) {
Log::error("lsfg-vk(layer): Failed to get device function pointers"); Log::error("layer", "Failed to get device function pointers");
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
@ -195,12 +200,12 @@ namespace {
Hooks::hooks["vkCreateDevicePost"]); Hooks::hooks["vkCreateDevicePost"]);
res = layer_vkCreateDevice2(physicalDevice, pCreateInfo, pAllocator, pDevice); res = layer_vkCreateDevice2(physicalDevice, pCreateInfo, pAllocator, pDevice);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
Log::error("lsfg-vk(layer): Failed to create Vulkan device: {:x}", Log::error("layer", "Failed to create Vulkan device: {:x}",
static_cast<uint32_t>(res)); static_cast<uint32_t>(res));
return res; return res;
} }
Log::debug("lsfg-vk(layer): Successfully initialized lsfg-vk device layer"); Log::debug("layer", "Successfully initialized lsfg-vk device layer");
return res; return res;
} // NOLINTEND } // NOLINTEND
} }
@ -217,16 +222,16 @@ const std::unordered_map<std::string, PFN_vkVoidFunction> layerFunctions = {
}; };
PFN_vkVoidFunction layer_vkGetInstanceProcAddr(VkInstance instance, const char* pName) { PFN_vkVoidFunction layer_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
std::string name(pName); const std::string name(pName);
auto it = layerFunctions.find(name); auto it = layerFunctions.find(name);
if (it != layerFunctions.end()) { if (it != layerFunctions.end()) {
Log::debug("lsfg-vk(layer): Inserted layer function for {}", name); Log::debug("layer", "Inserted layer function for {}", name);
return it->second; return it->second;
} }
it = Hooks::hooks.find(name); it = Hooks::hooks.find(name);
if (it != Hooks::hooks.end()) { if (it != Hooks::hooks.end()) {
Log::debug("lsfg-vk(layer): Inserted hook function for {}", name); Log::debug("layer", "Inserted hook function for {}", name);
return it->second; return it->second;
} }
@ -234,16 +239,16 @@ PFN_vkVoidFunction layer_vkGetInstanceProcAddr(VkInstance instance, const char*
} }
PFN_vkVoidFunction layer_vkGetDeviceProcAddr(VkDevice device, const char* pName) { PFN_vkVoidFunction layer_vkGetDeviceProcAddr(VkDevice device, const char* pName) {
std::string name(pName); const std::string name(pName);
auto it = layerFunctions.find(name); auto it = layerFunctions.find(name);
if (it != layerFunctions.end()) { if (it != layerFunctions.end()) {
Log::debug("lsfg-vk(layer): Inserted layer function for {}", name); Log::debug("layer", "Inserted layer function for {}", name);
return it->second; return it->second;
} }
it = Hooks::hooks.find(name); it = Hooks::hooks.find(name);
if (it != Hooks::hooks.end()) { if (it != Hooks::hooks.end()) {
Log::debug("lsfg-vk(layer): Inserted hook function for {}", name); Log::debug("layer", "Inserted hook function for {}", name);
return it->second; return it->second;
} }
@ -252,15 +257,29 @@ PFN_vkVoidFunction layer_vkGetDeviceProcAddr(VkDevice device, const char* pName)
// original functions // original functions
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
// NOLINTBEGIN
VkResult Layer::ovkCreateInstance( VkResult Layer::ovkCreateInstance(
const VkInstanceCreateInfo* pCreateInfo, const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance) { VkInstance* pInstance) {
return next_vkCreateInstance(pCreateInfo, pAllocator, pInstance); Log::debug("vulkan", "vkCreateInstance called with {} extensions:",
pCreateInfo->enabledExtensionCount);
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; ++i)
Log::debug("vulkan", " - {}", pCreateInfo->ppEnabledExtensionNames[i]);
auto res = next_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
Log::debug("vulkan", "vkCreateInstance({}) returned handle {:x}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pInstance));
return res;
} }
void Layer::ovkDestroyInstance( void Layer::ovkDestroyInstance(
VkInstance instance, VkInstance instance,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::debug("vulkan", "vkDestroyInstance called for instance {:x}",
reinterpret_cast<uintptr_t>(instance));
next_vkDestroyInstance(instance, pAllocator); next_vkDestroyInstance(instance, pAllocator);
} }
@ -269,12 +288,24 @@ VkResult Layer::ovkCreateDevice(
const VkDeviceCreateInfo* pCreateInfo, const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice) { VkDevice* pDevice) {
return next_vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); Log::debug("vulkan", "vkCreateDevice called with {} extensions:",
pCreateInfo->enabledExtensionCount);
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; ++i)
Log::debug("vulkan", " - {}", pCreateInfo->ppEnabledExtensionNames[i]);
auto res = next_vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
Log::debug("vulkan", "vkCreateDevice({}) returned handle {:x}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pDevice));
return res;
} }
void Layer::ovkDestroyDevice( void Layer::ovkDestroyDevice(
VkDevice device, VkDevice device,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::debug("vulkan", "vkDestroyDevice called for device {:x}",
reinterpret_cast<uintptr_t>(device));
next_vkDestroyDevice(device, pAllocator); next_vkDestroyDevice(device, pAllocator);
Log::debug("vulkan", "Device {:x} destroyed successfully",
reinterpret_cast<uintptr_t>(device));
} }
PFN_vkVoidFunction Layer::ovkGetInstanceProcAddr( PFN_vkVoidFunction Layer::ovkGetInstanceProcAddr(
@ -293,17 +324,39 @@ VkResult Layer::ovkCreateSwapchainKHR(
const VkSwapchainCreateInfoKHR* pCreateInfo, const VkSwapchainCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkSwapchainKHR* pSwapchain) { VkSwapchainKHR* pSwapchain) {
return next_vkCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); Log::debug("vulkan", "vkCreateSwapchainKHR called with {} images, extent: {}x{}",
pCreateInfo->minImageCount, pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height);
auto res = next_vkCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
Log::debug("vulkan", "vkCreateSwapchainKHR({}) returned handle {:x}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pSwapchain));
return res;
} }
VkResult Layer::ovkQueuePresentKHR( VkResult Layer::ovkQueuePresentKHR(
VkQueue queue, VkQueue queue,
const VkPresentInfoKHR* pPresentInfo) { const VkPresentInfoKHR* pPresentInfo) {
return next_vkQueuePresentKHR(queue, pPresentInfo); Log::debug("vulkan2", "vkQueuePresentKHR called with {} wait semaphores:",
pPresentInfo->waitSemaphoreCount);
for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; i++)
Log::debug("vulkan2", " - {:x}", reinterpret_cast<uintptr_t>(pPresentInfo->pWaitSemaphores[i]));
Log::debug("vulkan2", "and {} signal semaphores:",
pPresentInfo->swapchainCount);
for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++)
Log::debug("vulkan2", " - {:x}", reinterpret_cast<uintptr_t>(pPresentInfo->pSwapchains[i]));
Log::debug("vulkan2", "and queue: {:x}, image: {}",
reinterpret_cast<uintptr_t>(queue),
*pPresentInfo->pImageIndices);
auto res = next_vkQueuePresentKHR(queue, pPresentInfo);
Log::debug("vulkan2", "vkQueuePresentKHR({}) returned",
static_cast<uint32_t>(res));
return res;
} }
void Layer::ovkDestroySwapchainKHR( void Layer::ovkDestroySwapchainKHR(
VkDevice device, VkDevice device,
VkSwapchainKHR swapchain, VkSwapchainKHR swapchain,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::debug("vulkan", "vkDestroySwapchainKHR called for swapchain {:x}",
reinterpret_cast<uintptr_t>(swapchain));
next_vkDestroySwapchainKHR(device, swapchain, pAllocator); next_vkDestroySwapchainKHR(device, swapchain, pAllocator);
} }
@ -312,30 +365,48 @@ VkResult Layer::ovkGetSwapchainImagesKHR(
VkSwapchainKHR swapchain, VkSwapchainKHR swapchain,
uint32_t* pSwapchainImageCount, uint32_t* pSwapchainImageCount,
VkImage* pSwapchainImages) { VkImage* pSwapchainImages) {
return next_vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages); Log::debug("vulkan", "vkGetSwapchainImagesKHR called for swapchain {:x}",
reinterpret_cast<uintptr_t>(swapchain));
auto res = next_vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
Log::debug("vulkan", "vkGetSwapchainImagesKHR({}) returned {} images",
static_cast<uint32_t>(res),
*pSwapchainImageCount);
return res;
} }
VkResult Layer::ovkAllocateCommandBuffers( VkResult Layer::ovkAllocateCommandBuffers(
VkDevice device, VkDevice device,
const VkCommandBufferAllocateInfo* pAllocateInfo, const VkCommandBufferAllocateInfo* pAllocateInfo,
VkCommandBuffer* pCommandBuffers) { VkCommandBuffer* pCommandBuffers) {
return next_vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers); Log::debug("vulkan2", "vkAllocateCommandBuffers called for command pool {:x}",
reinterpret_cast<uintptr_t>(pAllocateInfo->commandPool));
auto res = next_vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
Log::debug("vulkan2", "vkAllocateCommandBuffers({}) returned command buffer: {}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pCommandBuffers));
return res;
} }
void Layer::ovkFreeCommandBuffers( void Layer::ovkFreeCommandBuffers(
VkDevice device, VkDevice device,
VkCommandPool commandPool, VkCommandPool commandPool,
uint32_t commandBufferCount, uint32_t commandBufferCount,
const VkCommandBuffer* pCommandBuffers) { const VkCommandBuffer* pCommandBuffers) {
Log::debug("vulkan2", "vkFreeCommandBuffers called for command buffer: {:x}",
reinterpret_cast<uintptr_t>(*pCommandBuffers));
next_vkFreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers); next_vkFreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
} }
VkResult Layer::ovkBeginCommandBuffer( VkResult Layer::ovkBeginCommandBuffer(
VkCommandBuffer commandBuffer, VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo* pBeginInfo) { const VkCommandBufferBeginInfo* pBeginInfo) {
Log::debug("vulkan2", "vkBeginCommandBuffer called for command buffer {:x}",
reinterpret_cast<uintptr_t>(commandBuffer));
return next_vkBeginCommandBuffer(commandBuffer, pBeginInfo); return next_vkBeginCommandBuffer(commandBuffer, pBeginInfo);
} }
VkResult Layer::ovkEndCommandBuffer( VkResult Layer::ovkEndCommandBuffer(
VkCommandBuffer commandBuffer) { VkCommandBuffer commandBuffer) {
Log::debug("vulkan2", "vkEndCommandBuffer called for command buffer {:x}",
reinterpret_cast<uintptr_t>(commandBuffer));
return next_vkEndCommandBuffer(commandBuffer); return next_vkEndCommandBuffer(commandBuffer);
} }
@ -344,12 +415,19 @@ VkResult Layer::ovkCreateCommandPool(
const VkCommandPoolCreateInfo* pCreateInfo, const VkCommandPoolCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkCommandPool* pCommandPool) { VkCommandPool* pCommandPool) {
return next_vkCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool); Log::debug("vulkan", "vkCreateCommandPool called");
auto res = next_vkCreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
Log::debug("vulkan", "vkCreateCommandPool({}) returned handle {:x}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pCommandPool));
return res;
} }
void Layer::ovkDestroyCommandPool( void Layer::ovkDestroyCommandPool(
VkDevice device, VkDevice device,
VkCommandPool commandPool, VkCommandPool commandPool,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::debug("vulkan", "vkDestroyCommandPool called for command pool {:x}",
reinterpret_cast<uintptr_t>(commandPool));
next_vkDestroyCommandPool(device, commandPool, pAllocator); next_vkDestroyCommandPool(device, commandPool, pAllocator);
} }
@ -358,12 +436,22 @@ VkResult Layer::ovkCreateImage(
const VkImageCreateInfo* pCreateInfo, const VkImageCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkImage* pImage) { VkImage* pImage) {
return next_vkCreateImage(device, pCreateInfo, pAllocator, pImage); Log::debug("vulkan", "vkCreateImage called with format: {}, extent: {}x{}, usage: {}",
static_cast<uint32_t>(pCreateInfo->format),
pCreateInfo->extent.width, pCreateInfo->extent.height,
static_cast<uint32_t>(pCreateInfo->usage));
auto res = next_vkCreateImage(device, pCreateInfo, pAllocator, pImage);
Log::debug("vulkan", "vkCreateImage({}) returned handle {:x}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pImage));
return res;
} }
void Layer::ovkDestroyImage( void Layer::ovkDestroyImage(
VkDevice device, VkDevice device,
VkImage image, VkImage image,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::debug("vulkan", "vkDestroyImage called for image {:x}",
reinterpret_cast<uintptr_t>(image));
next_vkDestroyImage(device, image, pAllocator); next_vkDestroyImage(device, image, pAllocator);
} }
@ -371,6 +459,8 @@ void Layer::ovkGetImageMemoryRequirements(
VkDevice device, VkDevice device,
VkImage image, VkImage image,
VkMemoryRequirements* pMemoryRequirements) { VkMemoryRequirements* pMemoryRequirements) {
Log::debug("vulkan", "vkGetImageMemoryRequirements called for image {:x}",
reinterpret_cast<uintptr_t>(image));
next_vkGetImageMemoryRequirements(device, image, pMemoryRequirements); next_vkGetImageMemoryRequirements(device, image, pMemoryRequirements);
} }
VkResult Layer::ovkBindImageMemory( VkResult Layer::ovkBindImageMemory(
@ -378,7 +468,14 @@ VkResult Layer::ovkBindImageMemory(
VkImage image, VkImage image,
VkDeviceMemory memory, VkDeviceMemory memory,
VkDeviceSize memoryOffset) { VkDeviceSize memoryOffset) {
return next_vkBindImageMemory(device, image, memory, memoryOffset); Log::debug("vulkan", "vkBindImageMemory called for image {:x}, memory {:x}, offset: {}",
reinterpret_cast<uintptr_t>(image),
reinterpret_cast<uintptr_t>(memory),
memoryOffset);
auto res = next_vkBindImageMemory(device, image, memory, memoryOffset);
Log::debug("vulkan", "vkBindImageMemory({}) returned",
static_cast<uint32_t>(res));
return res;
} }
VkResult Layer::ovkAllocateMemory( VkResult Layer::ovkAllocateMemory(
@ -386,12 +483,21 @@ VkResult Layer::ovkAllocateMemory(
const VkMemoryAllocateInfo* pAllocateInfo, const VkMemoryAllocateInfo* pAllocateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkDeviceMemory* pMemory) { VkDeviceMemory* pMemory) {
return next_vkAllocateMemory(device, pAllocateInfo, pAllocator, pMemory); Log::debug("vulkan", "vkAllocateMemory called with size: {}, memory type index: {}",
pAllocateInfo->allocationSize,
pAllocateInfo->memoryTypeIndex);
auto res = next_vkAllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
Log::debug("vulkan", "vkAllocateMemory({}) returned handle {:x}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pMemory));
return res;
} }
void Layer::ovkFreeMemory( void Layer::ovkFreeMemory(
VkDevice device, VkDevice device,
VkDeviceMemory memory, VkDeviceMemory memory,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::debug("vulkan", "vkFreeMemory called for memory {:x}",
reinterpret_cast<uintptr_t>(memory));
next_vkFreeMemory(device, memory, pAllocator); next_vkFreeMemory(device, memory, pAllocator);
} }
@ -400,12 +506,20 @@ VkResult Layer::ovkCreateSemaphore(
const VkSemaphoreCreateInfo* pCreateInfo, const VkSemaphoreCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, const VkAllocationCallbacks* pAllocator,
VkSemaphore* pSemaphore) { VkSemaphore* pSemaphore) {
return next_vkCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore); Log::debug("vulkan2", "vkCreateSemaphore called",
static_cast<uint32_t>(pCreateInfo->flags));
auto res = next_vkCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
Log::debug("vulkan2", "vkCreateSemaphore({}) returned handle {:x}",
static_cast<uint32_t>(res),
reinterpret_cast<uintptr_t>(*pSemaphore));
return res;
} }
void Layer::ovkDestroySemaphore( void Layer::ovkDestroySemaphore(
VkDevice device, VkDevice device,
VkSemaphore semaphore, VkSemaphore semaphore,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator) {
Log::debug("vulkan2", "vkDestroySemaphore called for semaphore {:x}",
reinterpret_cast<uintptr_t>(semaphore));
next_vkDestroySemaphore(device, semaphore, pAllocator); next_vkDestroySemaphore(device, semaphore, pAllocator);
} }
@ -413,24 +527,39 @@ VkResult Layer::ovkGetMemoryFdKHR(
VkDevice device, VkDevice device,
const VkMemoryGetFdInfoKHR* pGetFdInfo, const VkMemoryGetFdInfoKHR* pGetFdInfo,
int* pFd) { int* pFd) {
return next_vkGetMemoryFdKHR(device, pGetFdInfo, pFd); Log::debug("vulkan", "vkGetMemoryFdKHR called for memory {:x}, handle type: {}",
reinterpret_cast<uintptr_t>(pGetFdInfo->memory),
static_cast<uint32_t>(pGetFdInfo->handleType));
auto res = next_vkGetMemoryFdKHR(device, pGetFdInfo, pFd);
Log::debug("vulkan", "vkGetMemoryFdKHR({}) returned fd: {}",
static_cast<uint32_t>(res), *pFd);
return res;
} }
VkResult Layer::ovkGetSemaphoreFdKHR( VkResult Layer::ovkGetSemaphoreFdKHR(
VkDevice device, VkDevice device,
const VkSemaphoreGetFdInfoKHR* pGetFdInfo, const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
int* pFd) { int* pFd) {
return next_vkGetSemaphoreFdKHR(device, pGetFdInfo, pFd); Log::debug("vulkan2", "vkGetSemaphoreFdKHR called for semaphore {:x}",
reinterpret_cast<uintptr_t>(pGetFdInfo->semaphore));
auto res = next_vkGetSemaphoreFdKHR(device, pGetFdInfo, pFd);
Log::debug("vulkan2", "vkGetSemaphoreFdKHR({}) returned fd: {}",
static_cast<uint32_t>(res), *pFd);
return res;
} }
void Layer::ovkGetPhysicalDeviceQueueFamilyProperties( void Layer::ovkGetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice, VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount, uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties* pQueueFamilyProperties) { VkQueueFamilyProperties* pQueueFamilyProperties) {
Log::debug("vulkan", "vkGetPhysicalDeviceQueueFamilyProperties called for physical device {:x}",
reinterpret_cast<uintptr_t>(physicalDevice));
next_vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties); next_vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
} }
void Layer::ovkGetPhysicalDeviceMemoryProperties( void Layer::ovkGetPhysicalDeviceMemoryProperties(
VkPhysicalDevice physicalDevice, VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties* pMemoryProperties) { VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
Log::debug("vulkan", "vkGetPhysicalDeviceMemoryProperties called for physical device {:x}",
reinterpret_cast<uintptr_t>(physicalDevice));
next_vkGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties); next_vkGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
} }
@ -439,6 +568,10 @@ void Layer::ovkGetDeviceQueue(
uint32_t queueFamilyIndex, uint32_t queueFamilyIndex,
uint32_t queueIndex, uint32_t queueIndex,
VkQueue* pQueue) { VkQueue* pQueue) {
Log::debug("vulkan", "vkGetDeviceQueue called for device {:x}, queue family index: {}, queue index: {}",
reinterpret_cast<uintptr_t>(device),
queueFamilyIndex,
queueIndex);
next_vkGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); next_vkGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
} }
VkResult Layer::ovkQueueSubmit( VkResult Layer::ovkQueueSubmit(
@ -446,7 +579,21 @@ VkResult Layer::ovkQueueSubmit(
uint32_t submitCount, uint32_t submitCount,
const VkSubmitInfo* pSubmits, const VkSubmitInfo* pSubmits,
VkFence fence) { VkFence fence) {
return next_vkQueueSubmit(queue, submitCount, pSubmits, fence); Log::debug("vulkan2", "vkQueueSubmit called for queue {:x}, submitting: {} with wait semaphores:",
reinterpret_cast<uintptr_t>(queue),
reinterpret_cast<uintptr_t>(*pSubmits->pCommandBuffers));
for (uint32_t i = 0; i < pSubmits->waitSemaphoreCount; ++i)
Log::debug("vulkan2", " - {:x}", reinterpret_cast<uintptr_t>(pSubmits->pWaitSemaphores[i]));
Log::debug("vulkan2", "and {} signal semaphores:",
pSubmits->waitSemaphoreCount);
for (uint32_t i = 0; i < submitCount; ++i)
Log::debug("vulkan2", " - {:x}", reinterpret_cast<uintptr_t>(pSubmits[i].pSignalSemaphores));
Log::debug("vulkan2", "and fence: {:x}",
reinterpret_cast<uintptr_t>(fence));
auto res = next_vkQueueSubmit(queue, submitCount, pSubmits, fence);
Log::debug("vulkan2", "vkQueueSubmit({}) returned",
static_cast<uint32_t>(res));
return res;
} }
void Layer::ovkCmdPipelineBarrier( void Layer::ovkCmdPipelineBarrier(
@ -460,6 +607,16 @@ void Layer::ovkCmdPipelineBarrier(
const VkBufferMemoryBarrier* pBufferMemoryBarriers, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount, uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier* pImageMemoryBarriers) { const VkImageMemoryBarrier* pImageMemoryBarriers) {
Log::debug("vulkan2", "vkCmdPipelineBarrier called for command buffer {:x}, src stage: {}, dst stage: {}, transitioning:",
reinterpret_cast<uintptr_t>(commandBuffer),
static_cast<uint32_t>(srcStageMask),
static_cast<uint32_t>(dstStageMask));
for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) {
Log::debug("vulkan2", " - image {:x}, old layout: {}, new layout: {}",
reinterpret_cast<uintptr_t>(pImageMemoryBarriers[i].image),
static_cast<uint32_t>(pImageMemoryBarriers[i].oldLayout),
static_cast<uint32_t>(pImageMemoryBarriers[i].newLayout));
}
next_vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, next_vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
memoryBarrierCount, pMemoryBarriers, memoryBarrierCount, pMemoryBarriers,
bufferMemoryBarrierCount, pBufferMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
@ -473,6 +630,10 @@ void Layer::ovkCmdCopyImage(
VkImageLayout dstImageLayout, VkImageLayout dstImageLayout,
uint32_t regionCount, uint32_t regionCount,
const VkImageCopy* pRegions) { const VkImageCopy* pRegions) {
Log::debug("vulkan2", "vkCmdCopyImage called for command buffer {:x}, src image {:x}, dst image {:x}",
reinterpret_cast<uintptr_t>(commandBuffer),
reinterpret_cast<uintptr_t>(srcImage),
reinterpret_cast<uintptr_t>(dstImage));
next_vkCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); next_vkCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
} }
@ -483,5 +644,17 @@ VkResult Layer::ovkAcquireNextImageKHR(
VkSemaphore semaphore, VkSemaphore semaphore,
VkFence fence, VkFence fence,
uint32_t* pImageIndex) { uint32_t* pImageIndex) {
return next_vkAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); Log::debug("vulkan", "vkAcquireNextImageKHR called for swapchain {:x}, timeout: {}, semaphore: {:x}, fence: {:x}",
reinterpret_cast<uintptr_t>(swapchain),
timeout,
reinterpret_cast<uintptr_t>(semaphore),
reinterpret_cast<uintptr_t>(fence));
auto res = next_vkAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
Log::debug("vulkan", "vkAcquireNextImageKHR({}) returned image index: {}",
static_cast<uint32_t>(res),
*pImageIndex);
return res;
} }
#pragma clang diagnostic pop
// NOLINTEND

43
src/utils/log.cpp Normal file
View file

@ -0,0 +1,43 @@
#include "utils/log.hpp"
#include <sstream>
#include <unistd.h>
using namespace Log;
bool Internal::isSetup{};
std::set<std::string> Internal::debugModules;
bool Internal::debugAllModules{};
std::ofstream Internal::logFile;
std::mutex Internal::logMutex;
void Internal::setup() {
if (isSetup) return;
isSetup = true;
// open log file
const char* env_log_file = std::getenv("LSFG_LOG_FILE");
if (env_log_file) {
std::ostringstream filename;
filename << getpid() << "_" << env_log_file;
logFile.open(filename.str(), std::ios::app);
}
// parse debug modules
const char* env_log_debug = std::getenv("LSFG_LOG_DEBUG");
if (!env_log_debug)
return;
const std::string debugModulesStr(env_log_debug);
std::stringstream ss(debugModulesStr);
std::string item;
while (std::getline(ss, item, ',')) {
if (item == "all") {
debugAllModules = true;
return;
}
debugModules.insert(item);
}
}

View file

@ -1,4 +1,5 @@
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "utils/log.hpp"
#include "layer.hpp" #include "layer.hpp"
#include <lsfg.hpp> #include <lsfg.hpp>
@ -44,8 +45,12 @@ std::vector<const char*> Utils::addExtensions(const char* const* extensions, siz
for (const auto& e : requiredExtensions) { for (const auto& e : requiredExtensions) {
auto it = std::ranges::find(ext, e); auto it = std::ranges::find(ext, e);
if (it == ext.end()) if (it == ext.end()) {
Log::debug("hooks-init", "Adding extension: {}", e);
ext.push_back(e); ext.push_back(e);
} else {
Log::debug("hooks-init", "Extension {} already present", e);
}
} }
return ext; return ext;
@ -148,6 +153,8 @@ namespace {
std::optional<std::string> layersEnvironment; std::optional<std::string> layersEnvironment;
} }
// TODO: more environment variables? what about explicit disable?
void Utils::storeLayerEnv() { void Utils::storeLayerEnv() {
const char* env = std::getenv("VK_INSTANCE_LAYERS"); const char* env = std::getenv("VK_INSTANCE_LAYERS");
if (env) if (env)