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