diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 2 | ||||
-rw-r--r-- | src/core/memory.cpp | 40 | ||||
-rw-r--r-- | src/core/memory.h | 20 |
4 files changed, 66 insertions, 7 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 94530724e..87b3a2d74 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -26,14 +26,13 @@ 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 Flags = NVFlinger::BufferQueue::BufferTransformFlags; - const bool flip_vertical = static_cast<u32>(transform) & static_cast<u32>(Flags::FlipV); - const RendererBase::FramebufferInfo framebuffer_info{ - addr, offset, width, height, stride, static_cast<PixelFormat>(format), flip_vertical}; + using PixelFormat = Tegra::FramebufferConfig::PixelFormat; + const Tegra::FramebufferConfig framebuffer{ + addr, offset, width, height, stride, static_cast<PixelFormat>(format), transform}; Core::System::GetInstance().perf_stats.EndGameFrame(); - VideoCore::g_renderer->SwapBuffers(framebuffer_info); + + VideoCore::g_renderer->SwapBuffers(framebuffer); } } // namespace Devices 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) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a9beccb95..d6469dd3d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -41,6 +41,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); @@ -288,6 +291,43 @@ u8* GetPhysicalPointer(PAddr address) { return target_pointer; } +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) { + 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); + u64 overlap_size = overlap_end - overlap_start; + + auto* rasterizer = VideoCore::g_renderer->Rasterizer(); + switch (mode) { + case FlushMode::Flush: + rasterizer->FlushRegion(overlap_start, overlap_size); + break; + case FlushMode::Invalidate: + rasterizer->InvalidateRegion(overlap_start, overlap_size); + break; + case FlushMode::FlushAndInvalidate: + rasterizer->FlushAndInvalidateRegion(overlap_start, overlap_size); + break; + } + }; + + CheckRegion(PROCESS_IMAGE_VADDR, PROCESS_IMAGE_VADDR_END); + CheckRegion(HEAP_VADDR, HEAP_VADDR_END); +} + u8 Read8(const VAddr addr) { return Read<u8>(addr); } diff --git a/src/core/memory.h b/src/core/memory.h index f5bf0141f..4b9c482fe 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, }; @@ -242,4 +245,19 @@ boost::optional<VAddr> 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, u64 size, FlushMode mode); + } // namespace Memory |