simple presenting logic

This commit is contained in:
PancakeTAS 2025-07-01 09:59:24 +02:00
parent eb1cee1355
commit 13076e9fe3
No known key found for this signature in database
3 changed files with 82 additions and 2 deletions

View file

@ -33,11 +33,26 @@ public:
/// @param images The swapchain images. /// @param images The swapchain images.
/// ///
/// @throws std::invalid_argument if the handle is already added. /// @throws std::invalid_argument if the handle is already added.
/// @throws ls::vulkan_error if any Vulkan call fails. /// @throws LSFG::vulkan_error if any Vulkan call fails.
/// ///
void addSwapchain(VkSwapchainKHR handle, VkFormat format, VkExtent2D extent, void addSwapchain(VkSwapchainKHR handle, VkFormat format, VkExtent2D extent,
const std::vector<VkImage>& images); const std::vector<VkImage>& images);
///
/// Present the next frame on a given swapchain.
///
/// @param handle The Vulkan handle of the swapchain to present on.
/// @param queue The Vulkan queue to present the frame on.
/// @param semaphores The semaphores to wait on before presenting.
/// @param idx The index of the swapchain image to present.
///
/// @throws std::invalid_argument if the handle is not found.
/// @throws LSFG::vulkan_error if any Vulkan call fails.
///
void presentSwapchain(VkSwapchainKHR handle, VkQueue queue,
const std::vector<VkSemaphore>& semaphores, uint32_t idx);
/// ///
/// Remove a swapchain from the application. /// Remove a swapchain from the application.
/// ///
@ -86,7 +101,7 @@ public:
/// @param images The swapchain images. /// @param images The swapchain images.
/// ///
/// @throws std::invalid_argument if any parameter is null /// @throws std::invalid_argument if any parameter is null
/// @throws ls::vulkan_error if any Vulkan call fails. /// @throws LSFG::vulkan_error if any Vulkan call fails.
/// ///
SwapchainContext(VkSwapchainKHR swapchain, VkFormat format, VkExtent2D extent, SwapchainContext(VkSwapchainKHR swapchain, VkFormat format, VkExtent2D extent,
const std::vector<VkImage>& images); const std::vector<VkImage>& images);

View file

@ -1,5 +1,7 @@
#include "application.hpp" #include "application.hpp"
#include <lsfg.hpp>
#include <stdexcept> #include <stdexcept>
Application::Application(VkDevice device, VkPhysicalDevice physicalDevice) Application::Application(VkDevice device, VkPhysicalDevice physicalDevice)
@ -19,6 +21,33 @@ void Application::addSwapchain(VkSwapchainKHR handle, VkFormat format, VkExtent2
this->swapchains.emplace(handle, SwapchainContext(handle, format, extent, images)); this->swapchains.emplace(handle, SwapchainContext(handle, format, extent, images));
} }
void Application::presentSwapchain(VkSwapchainKHR handle, VkQueue queue,
const std::vector<VkSemaphore>& semaphores, uint32_t idx) {
if (handle == VK_NULL_HANDLE)
throw std::invalid_argument("Invalid swapchain handle");
// find the swapchain context
auto it = this->swapchains.find(handle);
if (it == this->swapchains.end())
throw std::logic_error("Swapchain not found");
// TODO: present
const VkPresentInfoKHR presentInfo = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = nullptr,
.waitSemaphoreCount = static_cast<uint32_t>(semaphores.size()),
.pWaitSemaphores = semaphores.data(),
.swapchainCount = 1,
.pSwapchains = &handle,
.pImageIndices = &idx,
.pResults = nullptr // can be null if not needed
};
auto res = vkQueuePresentKHR(queue, &presentInfo);
if (res != VK_SUCCESS) // do NOT check VK_SUBOPTIMAL_KHR
throw LSFG::vulkan_error(res, "Failed to present swapchain");
}
SwapchainContext::SwapchainContext(VkSwapchainKHR swapchain, VkFormat format, VkExtent2D extent, SwapchainContext::SwapchainContext(VkSwapchainKHR swapchain, VkFormat format, VkExtent2D extent,
const std::vector<VkImage>& images) const std::vector<VkImage>& images)
: swapchain(swapchain), format(format), extent(extent), images(images) { : swapchain(swapchain), format(format), extent(extent), images(images) {

View file

@ -88,6 +88,36 @@ namespace {
return res; return res;
} }
VkResult myvkQueuePresentKHR(
VkQueue queue,
const VkPresentInfoKHR* pPresentInfo) {
if (!application.has_value()) {
Log::error("Application not initialized, cannot present frame");
return VK_ERROR_INITIALIZATION_FAILED;
}
// present the next frame
try {
std::vector<VkSemaphore> waitSemaphores(pPresentInfo->waitSemaphoreCount);
std::copy_n(pPresentInfo->pWaitSemaphores, waitSemaphores.size(), waitSemaphores.data());
application->presentSwapchain(*pPresentInfo->pSwapchains,
queue, waitSemaphores, *pPresentInfo->pImageIndices);
Log::info("lsfg-vk(hooks): Frame presented successfully");
} catch (const LSFG::vulkan_error& e) {
Log::error("Encountered Vulkan error {:x} while presenting: {}",
static_cast<uint32_t>(e.error()), e.what());
return e.error(); // do not exit
} catch (const std::exception& e) {
Log::error("Encountered error while creating presenting: {}", e.what());
exit(EXIT_FAILURE);
}
return VK_SUCCESS;
}
void myvkDestroySwapchainKHR( void myvkDestroySwapchainKHR(
VkDevice device, VkDevice device,
VkSwapchainKHR swapchain, VkSwapchainKHR swapchain,
@ -140,6 +170,8 @@ void Hooks::initialize() {
reinterpret_cast<void*>(myvkCreateSwapchainKHR)); reinterpret_cast<void*>(myvkCreateSwapchainKHR));
Loader::VK::registerSymbol("vkDestroySwapchainKHR", Loader::VK::registerSymbol("vkDestroySwapchainKHR",
reinterpret_cast<void*>(myvkDestroySwapchainKHR)); reinterpret_cast<void*>(myvkDestroySwapchainKHR));
Loader::VK::registerSymbol("vkQueuePresentKHR",
reinterpret_cast<void*>(myvkQueuePresentKHR));
// register hooks to dynamic loader under libvulkan.so.1 // register hooks to dynamic loader under libvulkan.so.1
Loader::DL::File vk1("libvulkan.so.1"); Loader::DL::File vk1("libvulkan.so.1");
@ -151,6 +183,8 @@ void Hooks::initialize() {
reinterpret_cast<void*>(myvkCreateSwapchainKHR)); reinterpret_cast<void*>(myvkCreateSwapchainKHR));
vk1.defineSymbol("vkDestroySwapchainKHR", vk1.defineSymbol("vkDestroySwapchainKHR",
reinterpret_cast<void*>(myvkDestroySwapchainKHR)); reinterpret_cast<void*>(myvkDestroySwapchainKHR));
vk1.defineSymbol("vkQueuePresentKHR",
reinterpret_cast<void*>(myvkQueuePresentKHR));
Loader::DL::registerFile(vk1); Loader::DL::registerFile(vk1);
// register hooks to dynamic loader under libvulkan.so // register hooks to dynamic loader under libvulkan.so
@ -163,5 +197,7 @@ void Hooks::initialize() {
reinterpret_cast<void*>(myvkCreateSwapchainKHR)); reinterpret_cast<void*>(myvkCreateSwapchainKHR));
vk2.defineSymbol("vkDestroySwapchainKHR", vk2.defineSymbol("vkDestroySwapchainKHR",
reinterpret_cast<void*>(myvkDestroySwapchainKHR)); reinterpret_cast<void*>(myvkDestroySwapchainKHR));
vk2.defineSymbol("vkQueuePresentKHR",
reinterpret_cast<void*>(myvkQueuePresentKHR));
Loader::DL::registerFile(vk2); Loader::DL::registerFile(vk2);
} }