Commit 1c6adcad by Ian Elliott Committed by Commit Bot

Reimplement WindowSurfaceVk::checkForOutOfDateSwapchain

Simplified and made faster for devices that return VK_ERROR_OUT_OF_DATE_KHR (and VK_SUBOPTIMAL_KHR). Bug: b/168327817 Change-Id: Iec3dad8d528eb7d3645062a6736b397514432829 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2464921 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent 2aaeb81d
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/Overlay.h" #include "libANGLE/Overlay.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h" #include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h" #include "libANGLE/renderer/vulkan/FramebufferVk.h"
...@@ -1010,54 +1011,73 @@ bool WindowSurfaceVk::isMultiSampled() const ...@@ -1010,54 +1011,73 @@ bool WindowSurfaceVk::isMultiSampled() const
return mColorImageMS.valid(); return mColorImageMS.valid();
} }
angle::Result WindowSurfaceVk::checkForOutOfDateSwapchain(ContextVk *contextVk, angle::Result WindowSurfaceVk::queryAndAdjustSurfaceCaps(ContextVk *contextVk,
bool presentOutOfDate) VkSurfaceCapabilitiesKHR *surfaceCaps)
{ {
bool swapIntervalChanged = mSwapchainPresentMode != mDesiredSwapchainPresentMode; const VkPhysicalDevice &physicalDevice = contextVk->getRenderer()->getPhysicalDevice();
ANGLE_VK_TRY(contextVk,
// If anything has changed, recreate the swapchain. vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, surfaceCaps));
if (swapIntervalChanged || presentOutOfDate || if (surfaceCaps->currentExtent.width == kSurfaceSizedBySwapchain)
contextVk->getRenderer()->getFeatures().perFrameWindowSizeQuery.enabled)
{ {
gl::Extents swapchainExtents(getWidth(), getHeight(), 1); ASSERT(surfaceCaps->currentExtent.height == kSurfaceSizedBySwapchain);
ASSERT(!IsAndroid());
// vkGetPhysicalDeviceSurfaceCapabilitiesKHR does not provide useful extents for some
// platforms (e.g. Fuschia). Therefore, we must query the window size via a
// platform-specific mechanism. Add those extents to the surfaceCaps
gl::Extents currentExtents; gl::Extents currentExtents;
ANGLE_TRY(getCurrentWindowSize(contextVk, &currentExtents)); ANGLE_TRY(getCurrentWindowSize(contextVk, &currentExtents));
surfaceCaps->currentExtent.width = currentExtents.width;
surfaceCaps->currentExtent.height = currentExtents.height;
}
// If window size has changed, check with surface capabilities. It has been observed on return angle::Result::Continue;
// Android that `getCurrentWindowSize()` returns 1920x1080 for example, while surface }
// capabilities returns the size the surface was created with.
const VkPhysicalDevice &physicalDevice = contextVk->getRenderer()->getPhysicalDevice(); angle::Result WindowSurfaceVk::checkForOutOfDateSwapchain(ContextVk *contextVk,
ANGLE_VK_TRY(contextVk, vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, bool presentOutOfDate)
&mSurfaceCaps)); {
if (contextVk->getFeatures().enablePreRotateSurfaces.enabled) bool swapIntervalChanged = mSwapchainPresentMode != mDesiredSwapchainPresentMode;
presentOutOfDate = presentOutOfDate || swapIntervalChanged;
// If there's no change, early out.
if (!contextVk->getRenderer()->getFeatures().perFrameWindowSizeQuery.enabled &&
!presentOutOfDate)
{ {
// Update the surface's transform, which can change even if the window size does not. return angle::Result::Continue;
mPreTransform = mSurfaceCaps.currentTransform;
} }
if (currentExtents != swapchainExtents) // Get the latest surface capabilities.
{ ANGLE_TRY(queryAndAdjustSurfaceCaps(contextVk, &mSurfaceCaps));
uint32_t width = mSurfaceCaps.currentExtent.width;
uint32_t height = mSurfaceCaps.currentExtent.height;
if (width != kSurfaceSizedBySwapchain) if (contextVk->getRenderer()->getFeatures().perFrameWindowSizeQuery.enabled &&
!presentOutOfDate)
{ {
ASSERT(height != kSurfaceSizedBySwapchain); // This device generates neither VK_ERROR_OUT_OF_DATE_KHR nor VK_SUBOPTIMAL_KHR. Check for
currentExtents.width = width; // whether the size and/or rotation have changed since the swapchain was created.
currentExtents.height = height; uint32_t swapchainWidth = getWidth();
} uint32_t swapchainHeight = getHeight();
presentOutOfDate = mSurfaceCaps.currentTransform != mPreTransform ||
mSurfaceCaps.currentExtent.width != swapchainWidth ||
mSurfaceCaps.currentExtent.height != swapchainHeight;
} }
// Check for window resize and recreate swapchain if necessary. // If anything has changed, recreate the swapchain.
// Work-around for some device which does not return OUT_OF_DATE after window resizing if (!presentOutOfDate)
if (swapIntervalChanged || presentOutOfDate || currentExtents != swapchainExtents)
{ {
ANGLE_TRY(recreateSwapchain(contextVk, currentExtents)); return angle::Result::Continue;
} }
gl::Extents newSwapchainExtents(mSurfaceCaps.currentExtent.width,
mSurfaceCaps.currentExtent.height, 1);
if (contextVk->getFeatures().enablePreRotateSurfaces.enabled)
{
// Update the surface's transform, which can change even if the window size does not.
mPreTransform = mSurfaceCaps.currentTransform;
} }
return angle::Result::Continue; return recreateSwapchain(contextVk, newSwapchainExtents);
} }
void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk) void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk)
......
...@@ -264,6 +264,8 @@ class WindowSurfaceVk : public SurfaceVk ...@@ -264,6 +264,8 @@ class WindowSurfaceVk : public SurfaceVk
angle::Result createSwapChain(vk::Context *context, angle::Result createSwapChain(vk::Context *context,
const gl::Extents &extents, const gl::Extents &extents,
VkSwapchainKHR oldSwapchain); VkSwapchainKHR oldSwapchain);
angle::Result queryAndAdjustSurfaceCaps(ContextVk *contextVk,
VkSurfaceCapabilitiesKHR *surfaceCaps);
angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk, bool presentOutOfDate); angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk, bool presentOutOfDate);
angle::Result resizeSwapchainImages(vk::Context *context, uint32_t imageCount); angle::Result resizeSwapchainImages(vk::Context *context, uint32_t imageCount);
void releaseSwapchainImages(ContextVk *contextVk); void releaseSwapchainImages(ContextVk *contextVk);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment