diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 1c23737b..64af8d27 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -1096,6 +1096,33 @@ void main() { return BlitSurfaceTransform::Identity; } } + + static Bool RequiresShaderBlitToDefaultFramebuffer(VkSurfaceTransformFlagBitsKHR preTransform) { + switch (preTransform) { + case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR: + case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR: + return true; + default: + return false; + } + } + + static void ApplyNativeBlitDefaultFramebufferTransform(VkSurfaceTransformFlagBitsKHR preTransform, + const BlitImageBinding& dstBinding, + VkImageBlit& blitRegion) { + switch (preTransform) { + case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR: + blitRegion.dstOffsets[0].y = dstBinding.extent.y() - blitRegion.dstOffsets[0].y; + blitRegion.dstOffsets[1].y = dstBinding.extent.y() - blitRegion.dstOffsets[1].y; + break; + case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR: + blitRegion.dstOffsets[0].x = dstBinding.extent.x() - blitRegion.dstOffsets[0].x; + blitRegion.dstOffsets[1].x = dstBinding.extent.x() - blitRegion.dstOffsets[1].x; + break; + default: + break; + } + } } // namespace VkBool32 VulkanRenderer::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, @@ -2911,16 +2938,15 @@ void main() { (readFbo == MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); const Bool drawIsDefaultFbo = (drawFbo == MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); - if (isColorBlit && drawIsDefaultFbo) { + if (isColorBlit && drawIsDefaultFbo && + RequiresShaderBlitToDefaultFramebuffer(m_swapchainObject.GetPreTransform())) { if (TryBlitToDefaultFramebufferWithShader(frame, *readFbo, *drawFbo, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, filter)) { return; } - if (m_swapchainObject.GetPreTransform() != VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { - MGLOG_E("BlitFramebuffer skipped: transformed blit to default framebuffer requires a texture-backed source framebuffer"); - return; - } + MGLOG_E("BlitFramebuffer skipped: rotated blit to default framebuffer requires a texture-backed source framebuffer"); + return; } if (isDepthBlit) { @@ -3159,6 +3185,9 @@ void main() { blitRegion.dstSubresource.layerCount = 1; blitRegion.dstOffsets[0] = {dstX0, dstY0, 0}; blitRegion.dstOffsets[1] = {dstX1, dstY1, 1}; + if (drawIsDefaultFbo) { + ApplyNativeBlitDefaultFramebufferTransform(m_swapchainObject.GetPreTransform(), dstBinding, blitRegion); + } vkCmdBlitImage(frame.commandBuffer, srcBinding.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,