aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkraibse <33869366+kraibse@users.noreply.github.com>2026-11-01 21:44:43 +0100
committerkraibse <33869366+kraibse@users.noreply.github.com>2026-11-01 21:45:14 +0100
commit511d19f5de08102428a2841b72df7cfe0b6f6c5a (patch)
tree03406b4b3957729aee2853c52b64b452aa52f61c /src
parent703d2bbb3ba30d996fee827347ee33f36000e7ee (diff)
Revert "nx2: read command lists the GPU wrote from the GPU's copy"
This reverts commit d151e53e6148faeca1b5754e8b16f20da72c8252.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp1
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h7
-rw-r--r--src/video_core/dma_pusher.cpp27
-rw-r--r--src/video_core/dma_pusher.h2
-rw-r--r--src/video_core/nx2.h38
5 files changed, 0 insertions, 75 deletions
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 7853d17235..12923496fb 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -133,7 +133,6 @@ Module::Module(Core::System& system)
Devices::Nx2GpuMemoryRegistry::Get().Reset();
Tegra::Nx2ClearSemaphoreRegions();
Tegra::Nx2ClearSparseRegions();
- Tegra::Nx2ClearGpuWrittenPages();
Devices::g_nx2_driver = false;
Tegra::g_nx2_ampere = false;
Core::g_nx2_present_count = 0;
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index fb9f1f0553..e90af3214d 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -17,7 +17,6 @@
#include "video_core/buffer_cache/buffer_cache_base.h"
#include "video_core/guest_memory.h"
#include "video_core/host1x/gpu_device_memory_manager.h"
-#include "video_core/nx2.h"
#include "video_core/nx2_profile.h"
#include "video_core/texture_cache/util.h"
@@ -292,9 +291,6 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am
const bool has_new_downloads = tmp_intervals.size() != 0;
for (const auto& pair : tmp_intervals) {
gpu_modified_ranges.Add(pair.first, pair.second);
- if (Tegra::g_nx2_ampere.load(std::memory_order_relaxed)) {
- Tegra::Nx2MarkGpuWritten(pair.first, pair.second);
- }
}
const auto& copy = copies[0];
src_buffer.MarkUsage(copy.src_offset, copy.size);
@@ -1614,9 +1610,6 @@ void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, DAddr device_addr, u3
} else {
ArmReadTraps(device_addr, size);
}
- if (Tegra::g_nx2_ampere.load(std::memory_order_relaxed)) {
- Tegra::Nx2MarkGpuWritten(device_addr, size);
- }
}
template <class P>
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp
index 8c142b36db..88d571ae5f 100644
--- a/src/video_core/dma_pusher.cpp
+++ b/src/video_core/dma_pusher.cpp
@@ -162,7 +162,6 @@ bool DmaPusher::Step() {
command_resume_offset +=
ProcessCommands(commands.subspan(command_resume_offset), command_resume_offset);
} else {
- FlushGpuWrittenCommands(dma_state.dma_get, size_t{header.size} * sizeof(u32));
Tegra::Memory::GpuGuestMemory<Tegra::CommandHeader, Tegra::Memory::GuestMemoryFlags::UnsafeRead>headers(memory_manager, dma_state.dma_get, header.size, &command_headers);
const std::span<const CommandHeader> commands{headers.data(), headers.size()};
RecordParsedEntry(header, commands);
@@ -446,32 +445,6 @@ void DmaPusher::CallMultiMethod(const u32* base_start, u32 num_methods) {
}
}
-void DmaPusher::FlushGpuWrittenCommands(GPUVAddr address, size_t size) {
- // Title 1 runs small command lists its culling dispatches fill in each frame. Accurate GPU
- // mode reads every command list through the caches (safe reads); here only the ones on pages
- // the GPU has written are, or their draws run with an older frame's words (trees vanish).
- if (!Tegra::g_nx2_ampere.load(std::memory_order_relaxed) || size == 0) {
- return;
- }
- bool written = false;
- for (GPUVAddr page = address & ~GPUVAddr{0xfff}; page < address + size; page += 0x1000) {
- if (const auto device = memory_manager.GpuToCpuAddress(page);
- device && Tegra::Nx2IsGpuWritten(*device)) {
- written = true;
- break;
- }
- }
- if (!written) {
- return;
- }
- // The caches belong to the split's back: it first runs what the front queued (the dispatch
- // that writes these words among it).
- VideoCommon::GpuSplit::Get().Drain();
- if (memory_manager.IsMemoryDirty(address, size, VideoCommon::CacheType::BufferCache)) {
- memory_manager.FlushRegion(address, size, VideoCommon::CacheType::BufferCache);
- }
-}
-
void DmaPusher::ReportUnboundSubchannel() {
// Methods sent to a subchannel with no engine (no SetObject yet) are dropped.
static std::atomic<u32> reported{};
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h
index e8f2707096..82d29edb4b 100644
--- a/src/video_core/dma_pusher.h
+++ b/src/video_core/dma_pusher.h
@@ -182,8 +182,6 @@ public:
void DumpCurrentEntry(const char* reason);
void CheckSubmitHash(const CommandListHeader& header, u64 submit_hash);
void RecordParsedEntry(const CommandListHeader& header, std::span<const CommandHeader> commands);
- /// Brings command list words the GPU wrote (still only in host buffers) to guest memory.
- void FlushGpuWrittenCommands(GPUVAddr address, size_t size);
private:
diff --git a/src/video_core/nx2.h b/src/video_core/nx2.h
index 1fb49e15a6..318607384b 100644
--- a/src/video_core/nx2.h
+++ b/src/video_core/nx2.h
@@ -20,44 +20,6 @@ namespace Tegra {
// Ampere classes and the Turing+ macro ISA, which Eden's Maxwell engines don't implement.
inline std::atomic<bool> g_nx2_ampere{false};
-// Device pages the GPU has written through the buffer cache (shader stores, copies), ever. Title 1
-// runs command lists the GPU writes each frame (20-byte entries its culling fills in); read
-// without a flush they are stale and the draws behind them (trees) go missing. The bits never
-// clear: the dispatch that rewrites a page may still be queued on the split's back when its front
-// reads the command list. One bit per 4 KiB of the 36-bit device address space (2 MiB).
-inline constexpr u64 Nx2WrittenPageBits = 12;
-inline std::array<std::atomic<u64>, (u64{1} << (36 - Nx2WrittenPageBits)) / 64> g_nx2_gpu_written_pages{};
-
-inline void Nx2MarkGpuWritten(u64 device_address, u64 size) {
- if (size == 0) {
- return;
- }
- const u64 last = std::min<u64>((device_address + size - 1) >> Nx2WrittenPageBits,
- g_nx2_gpu_written_pages.size() * 64 - 1);
- for (u64 page = device_address >> Nx2WrittenPageBits; page <= last; ++page) {
- auto& word = g_nx2_gpu_written_pages[page / 64];
- const u64 bit = u64{1} << (page % 64);
- if ((word.load(std::memory_order_relaxed) & bit) == 0) {
- word.fetch_or(bit, std::memory_order_relaxed);
- }
- }
-}
-
-/// A new emulation session starts: no page has been written by its GPU yet.
-inline void Nx2ClearGpuWrittenPages() {
- for (auto& word : g_nx2_gpu_written_pages) {
- word.store(0, std::memory_order_relaxed);
- }
-}
-
-[[nodiscard]] inline bool Nx2IsGpuWritten(u64 device_address) {
- const u64 page = device_address >> Nx2WrittenPageBits;
- if (page >= g_nx2_gpu_written_pages.size() * 64) {
- return false;
- }
- return (g_nx2_gpu_written_pages[page / 64].load(std::memory_order_relaxed) >> (page % 64)) & 1;
-}
-
// NVN2 queues release their progress values into the second page of a two-page GPU-accessible
// region and GPU acquires read the same offsets in the first page (the CPU polls the second).
// Something on the console copies one into the other; until that is known, the puller mirrors