diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index db030a8e2b..f6c2b24a86 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -27,10 +27,8 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 offset, width, height, stride, format); using PixelFormat = Tegra::FramebufferConfig::PixelFormat; - using Flags = NVFlinger::BufferQueue::BufferTransformFlags; - const bool flip_vertical = static_cast(transform) & static_cast(Flags::FlipV); const Tegra::FramebufferConfig framebuffer{ - addr, offset, width, height, stride, static_cast(format), flip_vertical}; + addr, offset, width, height, stride, static_cast(format), transform}; Core::System::GetInstance().perf_stats.EndGameFrame(); diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 686eadca72..1de5767cbe 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -47,6 +47,8 @@ public: ~BufferQueue() = default; enum class BufferTransformFlags : u32 { + /// No transform flags are set + Unset = 0x00, /// Flip source image horizontally (around the vertical axis) FlipH = 0x01, /// Flip source image vertically (around the horizontal axis) diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index f3c5e366a7..206b3e05e8 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -8,6 +8,7 @@ #include #include #include "common/common_types.h" +#include "core/hle/service/nvflinger/buffer_queue.h" #include "video_core/memory_manager.h" namespace Tegra { @@ -38,7 +39,9 @@ struct FramebufferConfig { u32 height; u32 stride; PixelFormat pixel_format; - bool flip_vertical; + + using TransformFlags = Service::NVFlinger::BufferQueue::BufferTransformFlags; + TransformFlags transform_flags; }; namespace Engines { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 047389feee..ef63cbcf09 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -141,6 +141,9 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf const u32 size_in_bytes{framebuffer.stride * framebuffer.height * bpp}; const VAddr framebuffer_addr{framebuffer.address}; + // Framebuffer orientation handling + framebuffer_transform_flags = framebuffer.transform_flags; + // Ensure no bad interactions with GL_UNPACK_ALIGNMENT, which by default // only allows rows to have a memory alignement of 4. ASSERT(framebuffer.stride % 4 == 0); @@ -292,8 +295,19 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float x, float y, float w, float h) { const auto& texcoords = screen_info.display_texcoords; - const auto& left = framebuffer_flip_vertical ? texcoords.right : texcoords.left; - const auto& right = framebuffer_flip_vertical ? texcoords.left : texcoords.right; + auto left = texcoords.left; + auto right = texcoords.right; + if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) + if (framebuffer_transform_flags == Tegra::FramebufferConfig::TransformFlags::FlipV) { + // Flip the framebuffer vertically + left = texcoords.right; + right = texcoords.left; + } else { + // Other transformations are unsupported + LOG_CRITICAL(HW_GPU, "unsupported framebuffer_transform_flags=%d", + framebuffer_transform_flags); + UNIMPLEMENTED(); + } std::array vertices = {{ ScreenRectVertex(x, y, texcoords.top, right),