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(
|
void ovkGetPhysicalDeviceProperties(
|
||||||
VkPhysicalDevice physicalDevice,
|
VkPhysicalDevice physicalDevice,
|
||||||
VkPhysicalDeviceProperties* pProperties);
|
VkPhysicalDeviceProperties* pProperties);
|
||||||
|
/// Call to the original vkGetPhysicalDeviceSurfaceCapabilitiesKHR function.
|
||||||
|
VkResult ovkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||||
|
VkPhysicalDevice physicalDevice,
|
||||||
|
VkSurfaceKHR surface,
|
||||||
|
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
|
||||||
|
|
||||||
/// Call to the original vkCreateSwapchainKHR function.
|
/// Call to the original vkCreateSwapchainKHR function.
|
||||||
VkResult ovkCreateSwapchainKHR(
|
VkResult ovkCreateSwapchainKHR(
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,15 @@ namespace Utils {
|
||||||
///
|
///
|
||||||
uint64_t getDeviceUUID(VkPhysicalDevice physicalDevice);
|
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.
|
/// Ensure a list of extensions is present in the given array.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -151,13 +151,21 @@ namespace {
|
||||||
|
|
||||||
// update swapchain create info
|
// update swapchain create info
|
||||||
VkSwapchainCreateInfoKHR createInfo = *pCreateInfo;
|
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_DST_BIT; // allow copy from/to images
|
||||||
createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
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("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;
|
return res;
|
||||||
}
|
}
|
||||||
Log::info("hooks", "Swapchain created successfully: {:x}",
|
Log::info("hooks", "Swapchain created successfully: {:x}",
|
||||||
|
|
@ -235,6 +243,8 @@ namespace {
|
||||||
auto& swapchain = it3->second;
|
auto& swapchain = it3->second;
|
||||||
|
|
||||||
// patch vsync NOLINTBEGIN
|
// patch vsync NOLINTBEGIN
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
|
||||||
const VkSwapchainPresentModeInfoEXT* presentModeInfo =
|
const VkSwapchainPresentModeInfoEXT* presentModeInfo =
|
||||||
reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(pPresentInfo->pNext);
|
reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(pPresentInfo->pNext);
|
||||||
while (presentModeInfo) {
|
while (presentModeInfo) {
|
||||||
|
|
@ -246,6 +256,7 @@ namespace {
|
||||||
presentModeInfo =
|
presentModeInfo =
|
||||||
reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(presentModeInfo->pNext);
|
reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(presentModeInfo->pNext);
|
||||||
} // NOLINTEND
|
} // NOLINTEND
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
// present the next frame
|
// present the next frame
|
||||||
Log::debug("hooks2", "Presenting swapchain: {:x} on queue: {:x}",
|
Log::debug("hooks2", "Presenting swapchain: {:x} on queue: {:x}",
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ namespace {
|
||||||
PFN_vkGetPhysicalDeviceQueueFamilyProperties next_vkGetPhysicalDeviceQueueFamilyProperties{};
|
PFN_vkGetPhysicalDeviceQueueFamilyProperties next_vkGetPhysicalDeviceQueueFamilyProperties{};
|
||||||
PFN_vkGetPhysicalDeviceMemoryProperties next_vkGetPhysicalDeviceMemoryProperties{};
|
PFN_vkGetPhysicalDeviceMemoryProperties next_vkGetPhysicalDeviceMemoryProperties{};
|
||||||
PFN_vkGetPhysicalDeviceProperties next_vkGetPhysicalDeviceProperties{};
|
PFN_vkGetPhysicalDeviceProperties next_vkGetPhysicalDeviceProperties{};
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR{};
|
||||||
|
|
||||||
PFN_vkCreateSwapchainKHR next_vkCreateSwapchainKHR{};
|
PFN_vkCreateSwapchainKHR next_vkCreateSwapchainKHR{};
|
||||||
PFN_vkQueuePresentKHR next_vkQueuePresentKHR{};
|
PFN_vkQueuePresentKHR next_vkQueuePresentKHR{};
|
||||||
|
|
@ -122,6 +123,8 @@ namespace {
|
||||||
"vkGetPhysicalDeviceMemoryProperties", &next_vkGetPhysicalDeviceMemoryProperties);
|
"vkGetPhysicalDeviceMemoryProperties", &next_vkGetPhysicalDeviceMemoryProperties);
|
||||||
success &= initInstanceFunc(*pInstance,
|
success &= initInstanceFunc(*pInstance,
|
||||||
"vkGetPhysicalDeviceProperties", &next_vkGetPhysicalDeviceProperties);
|
"vkGetPhysicalDeviceProperties", &next_vkGetPhysicalDeviceProperties);
|
||||||
|
success &= initInstanceFunc(*pInstance,
|
||||||
|
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", &next_vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
Log::error("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;
|
||||||
|
|
@ -374,6 +377,15 @@ void Layer::ovkGetPhysicalDeviceProperties(
|
||||||
reinterpret_cast<uintptr_t>(physicalDevice));
|
reinterpret_cast<uintptr_t>(physicalDevice));
|
||||||
next_vkGetPhysicalDeviceProperties(physicalDevice, pProperties);
|
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(
|
VkResult Layer::ovkCreateSwapchainKHR(
|
||||||
VkDevice device,
|
VkDevice device,
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,17 @@ uint64_t Utils::getDeviceUUID(VkPhysicalDevice physicalDevice) {
|
||||||
return static_cast<uint64_t>(properties.vendorID) << 32 | properties.deviceID;
|
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,
|
std::vector<const char*> Utils::addExtensions(const char* const* extensions, size_t count,
|
||||||
const std::vector<const char*>& requiredExtensions) {
|
const std::vector<const char*>& requiredExtensions) {
|
||||||
std::vector<const char*> ext(count);
|
std::vector<const char*> ext(count);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue