From 19a03ad88b5b8ea072d62ace99cecc77956c8144 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 27 Apr 2020 15:59:35 -0700 Subject: Vulkan swap chain: auto-detecting surface rotation on Android --- Graphics/GraphicsEngine/interface/SwapChain.h | 13 +++++---- .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 34 ++++++++++++++++++++-- 2 files changed, 38 insertions(+), 9 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsEngine/interface/SwapChain.h b/Graphics/GraphicsEngine/interface/SwapChain.h index 5a9bc956..d6ffa97e 100644 --- a/Graphics/GraphicsEngine/interface/SwapChain.h +++ b/Graphics/GraphicsEngine/interface/SwapChain.h @@ -64,19 +64,20 @@ DILIGENT_BEGIN_INTERFACE(ISwapChain, IObject) /// Changes the swap chain size - /// \param [in] NewWidth - New swap chain width (not accounting for pre-transform), in pixels. - /// \param [in] NewHeight - New swap chain height (not accounting for pre-transform), in pixels. + /// \param [in] NewWidth - New logical swap chain width (not accounting for pre-transform), in pixels. + /// \param [in] NewHeight - New logical swap chain height (not accounting for pre-transform), in pixels. /// \param [in] NewTransform - New surface transform, see Diligent::SURFACE_TRANSFORM. /// /// \note When resizing non-primary swap chains, the engine unbinds the /// swap chain buffers from the output. /// /// New width and height should not account for surface pre-transform. For example, - /// if the window size is 1920 x 1080, but the surface is rotated by 90 degrees, + /// if the window size is 1920 x 1080, but the surface is pre-rotated by 90 degrees, /// NewWidth should still be 1920, and NewHeight should still be 1080. It is highly - /// preferable to always use SURFACE_TRANSFORM_OPTIMAL, however SURFACE_TRANSFORM_ROTATE_90 - /// will also work in this scenario. After the swap chain has been resized, its width - /// will be 1080, height will be 1920, and PreTransform will be SURFACE_TRANSFORM_ROTATE_90. + /// recommended to always use SURFACE_TRANSFORM_OPTIMAL to let the engine select + /// the most optimal pre-transform. However SURFACE_TRANSFORM_ROTATE_90 will also work in + /// the scenario above. After the swap chain has been resized, its actual width will be 1080, + /// actual height will be 1920, and PreTransform will be SURFACE_TRANSFORM_ROTATE_90. VIRTUAL void METHOD(Resize)(THIS_ Uint32 NewWidth, Uint32 NewHeight, diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index e0e27333..732c47e5 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -845,10 +845,38 @@ void SwapChainVkImpl::Resize(Uint32 NewWidth, Uint32 NewHeight, SURFACE_TRANSFOR VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR; - if ((surfCapabilities.currentTransform & Rotate90TransformFlags) != 0) + + if (NewWidth == 0 || NewHeight == 0) + { + NewWidth = m_SurfaceIdentityExtent.width; + NewHeight = m_SurfaceIdentityExtent.height; + + if ((surfCapabilities.currentTransform & Rotate90TransformFlags) != 0) + { + // Swap to get logical dimensions as input NewWidth and NewHeight are + // expected to be logical sizes. + std::swap(NewWidth, NewHeight); + } + } + + if (NewPreTransform == SURFACE_TRANSFORM_OPTIMAL) { - // The surface is rotated 90/270 degrees - swap width and height - std::swap(NewWidth, NewHeight); + if ((surfCapabilities.currentTransform & Rotate90TransformFlags) != 0) + { + // Swap to get physical dimensions + std::swap(NewWidth, NewHeight); + } + } + else + { + // Swap if necessary to get desired sizes after pre-transform + if (NewPreTransform == SURFACE_TRANSFORM_ROTATE_90 || + NewPreTransform == SURFACE_TRANSFORM_ROTATE_270 || + NewPreTransform == SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90 || + NewPreTransform == SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270) + { + std::swap(NewWidth, NewHeight); + } } } else -- cgit v1.2.3