From bfe45774f16e958bf34ed0d58a1d31e2325df47d Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 22 Mar 2018 21:04:30 -0400 Subject: video_core: Move FramebufferInfo to FramebufferConfig in GPU. --- src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 94530724e..7cd1d9306 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -26,14 +26,14 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 "Drawing from address %lx offset %08X Width %u Height %u Stride %u Format %u", addr, offset, width, height, stride, format); - using PixelFormat = RendererBase::FramebufferInfo::PixelFormat; + using PixelFormat = Tegra::FramebufferConfig::PixelFormat; using Flags = NVFlinger::BufferQueue::BufferTransformFlags; const bool flip_vertical = static_cast(transform) & static_cast(Flags::FlipV); - const RendererBase::FramebufferInfo framebuffer_info{ + const Tegra::FramebufferConfig framebuffer{ addr, offset, width, height, stride, static_cast(format), flip_vertical}; Core::System::GetInstance().perf_stats.EndGameFrame(); - VideoCore::g_renderer->SwapBuffers(framebuffer_info); + VideoCore::g_renderer->SwapBuffers(framebuffer); } } // namespace Devices -- cgit v1.2.3 From 63d3924b5bb5dd17f1de9dfe3a357df293fc113d Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 22 Mar 2018 22:56:41 -0400 Subject: memory: Port RasterizerFlushVirtualRegion from Citra. --- src/core/memory.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/core/memory.h | 20 +++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4e34d8334..8a83de904 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -42,6 +42,9 @@ static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, Pa LOG_DEBUG(HW_Memory, "Mapping %p onto %016" PRIX64 "-%016" PRIX64, memory, base * PAGE_SIZE, (base + size) * PAGE_SIZE); + RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, + FlushMode::FlushAndInvalidate); + VAddr end = base + size; while (base != end) { ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %016" PRIX64, base); @@ -293,6 +296,42 @@ u8* GetPhysicalPointer(PAddr address) { return target_pointer; } +void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { + // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be + // null here + if (VideoCore::g_renderer == nullptr) { + return; + } + + VAddr end = start + size; + + auto CheckRegion = [&](VAddr region_start, VAddr region_end) { + if (start >= region_end || end <= region_start) { + // No overlap with region + return; + } + + VAddr overlap_start = std::max(start, region_start); + VAddr overlap_end = std::min(end, region_end); + u32 overlap_size = overlap_end - overlap_start; + + auto* rasterizer = VideoCore::g_renderer->Rasterizer(); + switch (mode) { + case FlushMode::Flush: + rasterizer->FlushRegion(region_start, overlap_size); + break; + case FlushMode::Invalidate: + rasterizer->InvalidateRegion(region_start, overlap_size); + break; + case FlushMode::FlushAndInvalidate: + rasterizer->FlushAndInvalidateRegion(region_start, overlap_size); + break; + } + }; + + CheckRegion(HEAP_VADDR, HEAP_VADDR_END); +} + u8 Read8(const VAddr addr) { return Read(addr); } diff --git a/src/core/memory.h b/src/core/memory.h index f406cc848..1c7232115 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -36,7 +36,10 @@ enum class PageType : u8 { Unmapped, /// Page is mapped to regular memory. This is the only type you can get pointers to. Memory, - /// Page is mapped to a memory hook, which intercepts read and write requests. + /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and + /// invalidation + RasterizerCachedMemory, + /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions. Special, }; @@ -253,4 +256,19 @@ boost::optional PhysicalToVirtualAddress(PAddr addr); */ u8* GetPhysicalPointer(PAddr address); +enum class FlushMode { + /// Write back modified surfaces to RAM + Flush, + /// Remove region from the cache + Invalidate, + /// Write back modified surfaces to RAM, and also remove them from the cache + FlushAndInvalidate, +}; + +/** + * Flushes and invalidates any externally cached rasterizer resources touching the given virtual + * address region. + */ +void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode); + } // namespace Memory -- cgit v1.2.3 From e12c2cf8c692bf7581dda96c601e30c2a969086c Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 22 Mar 2018 23:18:04 -0400 Subject: nvdisp_disp0: Always flush and invalidate framebuffer region. - Workaround for texture forwarding until we have a better place. --- src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/core') diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 7cd1d9306..db030a8e2 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -33,6 +33,13 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 addr, offset, width, height, stride, static_cast(format), flip_vertical}; Core::System::GetInstance().perf_stats.EndGameFrame(); + + // TODO(bunnei): The framebuffer region should only be flushed and invalidated if it is written + // to, not every frame. When we find the right place for this, the below line can be removed. + Memory::RasterizerFlushVirtualRegion(framebuffer.address, + framebuffer.width * framebuffer.height * 4, + Memory::FlushMode::FlushAndInvalidate); + VideoCore::g_renderer->SwapBuffers(framebuffer); } -- cgit v1.2.3 From ec4e1a3685d458147ac76f4cf53ea86632d0debd Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 23 Mar 2018 14:58:27 -0400 Subject: renderer_opengl: Better handling of framebuffer transform flags. --- src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 4 +--- src/core/hle/service/nvflinger/buffer_queue.h | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index db030a8e2..f6c2b24a8 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 686eadca7..1de5767cb 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) -- cgit v1.2.3 From 11047d7fd511fd9ae6130da7bc824fefa6fb64c1 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 23 Mar 2018 15:01:45 -0400 Subject: rasterizer: Flush and invalidate regions should be 64-bit. --- src/core/memory.cpp | 4 ++-- src/core/memory.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 8a83de904..d8aab7090 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -296,7 +296,7 @@ u8* GetPhysicalPointer(PAddr address) { return target_pointer; } -void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { +void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be // null here if (VideoCore::g_renderer == nullptr) { @@ -313,7 +313,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { VAddr overlap_start = std::max(start, region_start); VAddr overlap_end = std::min(end, region_end); - u32 overlap_size = overlap_end - overlap_start; + u64 overlap_size = overlap_end - overlap_start; auto* rasterizer = VideoCore::g_renderer->Rasterizer(); switch (mode) { diff --git a/src/core/memory.h b/src/core/memory.h index 1c7232115..3e2c3f23d 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -269,6 +269,6 @@ enum class FlushMode { * Flushes and invalidates any externally cached rasterizer resources touching the given virtual * address region. */ -void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode); +void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode); } // namespace Memory -- cgit v1.2.3 From 1a158dfcd660058d2f87cb6eb4662861db203386 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 23 Mar 2018 15:10:02 -0400 Subject: memory: RasterizerFlushVirtualRegion should also check process image region. --- src/core/memory.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index d8aab7090..fd5a57022 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -329,6 +329,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { } }; + CheckRegion(PROCESS_IMAGE_VADDR, PROCESS_IMAGE_VADDR_END); CheckRegion(HEAP_VADDR, HEAP_VADDR_END); } -- cgit v1.2.3 From b5f3e7951b69fe689408f4560c83860302c540e5 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 23 Mar 2018 15:46:21 -0400 Subject: memory: Fix typo in RasterizerFlushVirtualRegion. --- src/core/memory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index fd5a57022..0eca4e76e 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -318,13 +318,13 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { auto* rasterizer = VideoCore::g_renderer->Rasterizer(); switch (mode) { case FlushMode::Flush: - rasterizer->FlushRegion(region_start, overlap_size); + rasterizer->FlushRegion(overlap_start, overlap_size); break; case FlushMode::Invalidate: - rasterizer->InvalidateRegion(region_start, overlap_size); + rasterizer->InvalidateRegion(overlap_start, overlap_size); break; case FlushMode::FlushAndInvalidate: - rasterizer->FlushAndInvalidateRegion(region_start, overlap_size); + rasterizer->FlushAndInvalidateRegion(overlap_start, overlap_size); break; } }; -- cgit v1.2.3 From 054393917e99d307eea0aabc78c0c6e5e709b2c7 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 23 Mar 2018 15:49:04 -0400 Subject: renderer_opengl: Fixes for properly flushing & rendering the framebuffer. --- src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index f6c2b24a8..87b3a2d74 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -32,12 +32,6 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 Core::System::GetInstance().perf_stats.EndGameFrame(); - // TODO(bunnei): The framebuffer region should only be flushed and invalidated if it is written - // to, not every frame. When we find the right place for this, the below line can be removed. - Memory::RasterizerFlushVirtualRegion(framebuffer.address, - framebuffer.width * framebuffer.height * 4, - Memory::FlushMode::FlushAndInvalidate); - VideoCore::g_renderer->SwapBuffers(framebuffer); } -- cgit v1.2.3