mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
fix(agc): ask the swapchain for one image beyond the surface minimum
On Wayland with the NVIDIA driver the surface reports minImageCount 2. The presenter acquires with a zero timeout, so once both images were queued no image was ever free again: PPSA29340 flipped at 60 per second but presented 0 frames per 10 s (599 dropped: no free swapchain image) and its window stayed black. Ask for minImageCount + 1, capped by maxImageCount when the surface has one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK
This commit is contained in:
1 parent
8b3a6ba88d
commit
df70917ccc
3 files changed
+32
-2
No files matched your search
@@ -0,0 +1,17 @@
|
||||
#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_SWAPCHAINIMAGES_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_SWAPCHAINIMAGES_HPP
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
namespace AgcDriver {
|
||||
|
||||
inline std::uint32_t SwapchainImageCount(const VkSurfaceCapabilitiesKHR& surface) {
|
||||
const std::uint32_t count = surface.minImageCount + 1;
|
||||
return surface.maxImageCount != 0 ? std::min(count, surface.maxImageCount) : count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/SubgroupClock.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/ShaderDeviceProfile.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PresentMode.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/SwapchainImages.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PerformanceOverlay.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PresentationPass.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PresentationScaler.hpp"
|
||||
@@ -2069,7 +2070,7 @@ VulkanDevice::VulkanDevice(const PresentationWindow* window, bool compileOnly) :
|
||||
require((surface.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0, "surface does not support color attachment images");
|
||||
VkSwapchainCreateInfoKHR swapchain{VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR};
|
||||
swapchain.surface = state->surface;
|
||||
swapchain.minImageCount = surface.minImageCount;
|
||||
swapchain.minImageCount = AgcDriver::SwapchainImageCount(surface);
|
||||
swapchain.imageFormat = state->surfaceFormat;
|
||||
swapchain.imageColorSpace = state->surfaceColorSpace;
|
||||
swapchain.imageExtent = state->extent;
|
||||
@@ -2883,7 +2884,7 @@ void VulkanDevice::recreateSwapchain(std::uint32_t width, std::uint32_t height,
|
||||
require((surface.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0 && (surface.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) != 0 && (surface.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) != 0, "resized surface capabilities are unsupported");
|
||||
VkSwapchainCreateInfoKHR create{VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR};
|
||||
create.surface = state->surface;
|
||||
create.minImageCount = surface.minImageCount;
|
||||
create.minImageCount = AgcDriver::SwapchainImageCount(surface);
|
||||
create.imageFormat = state->surfaceFormat;
|
||||
create.imageColorSpace = state->surfaceColorSpace;
|
||||
create.imageExtent = {width, height};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PresentMode.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/SwapchainImages.hpp"
|
||||
#include "prx/libc/include/Shutdown.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/VideoOutput.hpp"
|
||||
#include "prx/libSceAgcDriver/Submit/include/Dcb.hpp"
|
||||
@@ -402,6 +403,17 @@ void testReset(bool compute) {
|
||||
|
||||
void testPresentMode() {
|
||||
using AgcDriver::SelectPresentMode;
|
||||
VkSurfaceCapabilitiesKHR surface{};
|
||||
surface.minImageCount = 2;
|
||||
surface.maxImageCount = 8;
|
||||
check(AgcDriver::SwapchainImageCount(surface) == 3, "the swapchain has no image beyond the surface minimum");
|
||||
surface.minImageCount = 3;
|
||||
check(AgcDriver::SwapchainImageCount(surface) == 4, "the swapchain does not follow a larger surface minimum");
|
||||
surface.maxImageCount = 3;
|
||||
check(AgcDriver::SwapchainImageCount(surface) == 3, "the swapchain exceeds the surface maximum");
|
||||
surface.minImageCount = 2;
|
||||
surface.maxImageCount = 0;
|
||||
check(AgcDriver::SwapchainImageCount(surface) == 3, "an unlimited surface maximum capped the swapchain");
|
||||
const std::array wayland{VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR};
|
||||
const std::array all{VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR};
|
||||
check(SelectPresentMode(nullptr, wayland) == VK_PRESENT_MODE_FIFO_KHR, "the default present mode is not FIFO");
|
||||
|
||||
Reference in new issue
Block a user