mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
allow suboptimal rendering with fewer than required swapchain images
fixes #61
This commit is contained in:
parent
896a205e8e
commit
d4e4ec8df6
5 changed files with 50 additions and 2 deletions
|
|
@ -53,6 +53,11 @@ namespace Layer {
|
|||
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(
|
||||
|
|
|
|||
|
|
@ -31,6 +31,15 @@ namespace Utils {
|
|||
///
|
||||
uint64_t getDeviceUUID(VkPhysicalDevice physicalDevice);
|
||||
|
||||
///
|
||||
/// Get the max image count for a swapchain.
|
||||
///
|
||||
/// @param physicalDevice The physical device to query.
|
||||
/// @param surface The surface to query the capabilities for.
|
||||
/// @return The maximum image count for the swapchain.
|
||||
///
|
||||
uint32_t getMaxImageCount(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface);
|
||||
|
||||
///
|
||||
/// Ensure a list of extensions is present in the given array.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -151,13 +151,21 @@ namespace {
|
|||
|
||||
// update swapchain create info
|
||||
VkSwapchainCreateInfoKHR createInfo = *pCreateInfo;
|
||||
createInfo.minImageCount += 1 + deviceInfo.frameGen; // 1 deferred + N framegen, FIXME: check hardware max
|
||||
const uint32_t maxImageCount = Utils::getMaxImageCount(deviceInfo.physicalDevice, pCreateInfo->surface);
|
||||
const uint32_t imageCount = createInfo.minImageCount + 1 + static_cast<uint32_t>(deviceInfo.frameGen);
|
||||
Log::debug("hooks", "Creating swapchain with max image count: {}/{}", imageCount, maxImageCount);
|
||||
if (imageCount > maxImageCount) {
|
||||
Log::warn("hooks", "LSFG_MULTIPLIER is set very high. This might lead to performance degradation");
|
||||
createInfo.minImageCount = maxImageCount; // limit to max possible
|
||||
} else {
|
||||
createInfo.minImageCount = imageCount; // set to frameGen + 1
|
||||
}
|
||||
createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; // allow copy from/to images
|
||||
createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; // force vsync
|
||||
auto res = Layer::ovkCreateSwapchainKHR(device, &createInfo, pAllocator, pSwapchain);
|
||||
if (res != VK_SUCCESS) {
|
||||
Log::error("hooks", "Failed to create swapchain: {:x}", static_cast<uint32_t>(res));
|
||||
Log::error("hooks", "Failed to create swapchain: {}", static_cast<uint32_t>(res));
|
||||
return res;
|
||||
}
|
||||
Log::info("hooks", "Swapchain created successfully: {:x}",
|
||||
|
|
@ -235,6 +243,8 @@ namespace {
|
|||
auto& swapchain = it3->second;
|
||||
|
||||
// patch vsync NOLINTBEGIN
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
|
||||
const VkSwapchainPresentModeInfoEXT* presentModeInfo =
|
||||
reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(pPresentInfo->pNext);
|
||||
while (presentModeInfo) {
|
||||
|
|
@ -246,6 +256,7 @@ namespace {
|
|||
presentModeInfo =
|
||||
reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(presentModeInfo->pNext);
|
||||
} // NOLINTEND
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// present the next frame
|
||||
Log::debug("hooks2", "Presenting swapchain: {:x} on queue: {:x}",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ namespace {
|
|||
PFN_vkGetPhysicalDeviceQueueFamilyProperties next_vkGetPhysicalDeviceQueueFamilyProperties{};
|
||||
PFN_vkGetPhysicalDeviceMemoryProperties next_vkGetPhysicalDeviceMemoryProperties{};
|
||||
PFN_vkGetPhysicalDeviceProperties next_vkGetPhysicalDeviceProperties{};
|
||||
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR{};
|
||||
|
||||
PFN_vkCreateSwapchainKHR next_vkCreateSwapchainKHR{};
|
||||
PFN_vkQueuePresentKHR next_vkQueuePresentKHR{};
|
||||
|
|
@ -122,6 +123,8 @@ namespace {
|
|||
"vkGetPhysicalDeviceMemoryProperties", &next_vkGetPhysicalDeviceMemoryProperties);
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkGetPhysicalDeviceProperties", &next_vkGetPhysicalDeviceProperties);
|
||||
success &= initInstanceFunc(*pInstance,
|
||||
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", &next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
|
||||
if (!success) {
|
||||
Log::error("layer", "Failed to get instance function pointers");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
|
|
@ -374,6 +377,15 @@ void Layer::ovkGetPhysicalDeviceProperties(
|
|||
reinterpret_cast<uintptr_t>(physicalDevice));
|
||||
next_vkGetPhysicalDeviceProperties(physicalDevice, pProperties);
|
||||
}
|
||||
VkResult Layer::ovkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
|
||||
Log::debug("vulkan", "vkGetPhysicalDeviceSurfaceCapabilitiesKHR called for physical device {:x} and surface {:x}",
|
||||
reinterpret_cast<uintptr_t>(physicalDevice),
|
||||
reinterpret_cast<uintptr_t>(surface));
|
||||
return next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
|
||||
}
|
||||
|
||||
VkResult Layer::ovkCreateSwapchainKHR(
|
||||
VkDevice device,
|
||||
|
|
|
|||
|
|
@ -53,6 +53,17 @@ uint64_t Utils::getDeviceUUID(VkPhysicalDevice physicalDevice) {
|
|||
return static_cast<uint64_t>(properties.vendorID) << 32 | properties.deviceID;
|
||||
}
|
||||
|
||||
uint32_t Utils::getMaxImageCount(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) {
|
||||
VkSurfaceCapabilitiesKHR capabilities{};
|
||||
auto res = Layer::ovkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice,
|
||||
surface, &capabilities);
|
||||
if (res != VK_SUCCESS)
|
||||
throw LSFG::vulkan_error(res, "Failed to get surface capabilities");
|
||||
if (capabilities.maxImageCount == 0)
|
||||
return 999; // :3
|
||||
return capabilities.maxImageCount;
|
||||
}
|
||||
|
||||
std::vector<const char*> Utils::addExtensions(const char* const* extensions, size_t count,
|
||||
const std::vector<const char*>& requiredExtensions) {
|
||||
std::vector<const char*> ext(count);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue