summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp3
-rw-r--r--src/video_core/control/channel_state_cache.h10
-rw-r--r--src/video_core/gpu.cpp8
-rw-r--r--src/video_core/gpu.h2
-rw-r--r--src/video_core/memory_manager.cpp11
-rw-r--r--src/video_core/rasterizer_interface.h2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h2
-rw-r--r--src/video_core/texture_cache/texture_cache.h27
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h4
12 files changed, 63 insertions, 16 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 344ddfc90..db2a6c3b2 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -16,6 +16,7 @@
16#include "core/hle/service/nvdrv/devices/nvhost_gpu.h" 16#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
17#include "core/hle/service/nvdrv/nvdrv.h" 17#include "core/hle/service/nvdrv/nvdrv.h"
18#include "video_core/control/channel_state.h" 18#include "video_core/control/channel_state.h"
19#include "video_core/gpu.h"
19#include "video_core/memory_manager.h" 20#include "video_core/memory_manager.h"
20#include "video_core/rasterizer_interface.h" 21#include "video_core/rasterizer_interface.h"
21 22
@@ -24,6 +25,7 @@ namespace Service::Nvidia::Devices {
24nvhost_as_gpu::nvhost_as_gpu(Core::System& system_, Module& module_, NvCore::Container& core) 25nvhost_as_gpu::nvhost_as_gpu(Core::System& system_, Module& module_, NvCore::Container& core)
25 : nvdevice{system_}, module{module_}, container{core}, nvmap{core.GetNvMapFile()}, vm{}, 26 : nvdevice{system_}, module{module_}, container{core}, nvmap{core.GetNvMapFile()}, vm{},
26 gmmu{} {} 27 gmmu{} {}
28
27nvhost_as_gpu::~nvhost_as_gpu() = default; 29nvhost_as_gpu::~nvhost_as_gpu() = default;
28 30
29NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 31NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -132,6 +134,7 @@ NvResult nvhost_as_gpu::AllocAsEx(const std::vector<u8>& input, std::vector<u8>&
132 vm.big_page_allocator = std::make_unique<VM::Allocator>(start_big_pages, end_big_pages); 134 vm.big_page_allocator = std::make_unique<VM::Allocator>(start_big_pages, end_big_pages);
133 135
134 gmmu = std::make_shared<Tegra::MemoryManager>(system, 40, VM::PAGE_SIZE_BITS); 136 gmmu = std::make_shared<Tegra::MemoryManager>(system, 40, VM::PAGE_SIZE_BITS);
137 system.GPU().InitAddressSpace(*gmmu);
135 vm.initialised = true; 138 vm.initialised = true;
136 139
137 return NvResult::Success; 140 return NvResult::Success;
diff --git a/src/video_core/control/channel_state_cache.h b/src/video_core/control/channel_state_cache.h
index 9b1d7362b..31d80e8b7 100644
--- a/src/video_core/control/channel_state_cache.h
+++ b/src/video_core/control/channel_state_cache.h
@@ -3,6 +3,7 @@
3#include <deque> 3#include <deque>
4#include <limits> 4#include <limits>
5#include <mutex> 5#include <mutex>
6#include <optional>
6#include <unordered_map> 7#include <unordered_map>
7 8
8#include "common/common_types.h" 9#include "common/common_types.h"
@@ -59,6 +60,15 @@ public:
59 return ref->second.gpu_memory; 60 return ref->second.gpu_memory;
60 } 61 }
61 62
63 std::optional<size_t> getStorageID(size_t id) const {
64 std::unique_lock<std::mutex> lk(config_mutex);
65 const auto ref = address_spaces.find(id);
66 if (ref == address_spaces.end()) {
67 return std::nullopt;
68 }
69 return ref->second.storage_id;
70 }
71
62protected: 72protected:
63 static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()}; 73 static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()};
64 74
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 8c0ff0094..eebd7f3ff 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -73,6 +73,10 @@ struct GPU::Impl {
73 rasterizer->InitializeChannel(to_init); 73 rasterizer->InitializeChannel(to_init);
74 } 74 }
75 75
76 void InitAddressSpace(Tegra::MemoryManager& memory_manager) {
77 memory_manager.BindRasterizer(rasterizer);
78 }
79
76 void ReleaseChannel(Control::ChannelState& to_release) { 80 void ReleaseChannel(Control::ChannelState& to_release) {
77 UNIMPLEMENTED(); 81 UNIMPLEMENTED();
78 } 82 }
@@ -452,6 +456,10 @@ void GPU::ReleaseChannel(Control::ChannelState& to_release) {
452 impl->ReleaseChannel(to_release); 456 impl->ReleaseChannel(to_release);
453} 457}
454 458
459void GPU::InitAddressSpace(Tegra::MemoryManager& memory_manager) {
460 impl->InitAddressSpace(memory_manager);
461}
462
455void GPU::BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer) { 463void GPU::BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer) {
456 impl->BindRenderer(std::move(renderer)); 464 impl->BindRenderer(std::move(renderer));
457} 465}
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 74d55e074..7e84b0d2f 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -118,6 +118,8 @@ public:
118 118
119 void ReleaseChannel(Control::ChannelState& to_release); 119 void ReleaseChannel(Control::ChannelState& to_release);
120 120
121 void InitAddressSpace(Tegra::MemoryManager& memory_manager);
122
121 /// Request a host GPU memory flush from the CPU. 123 /// Request a host GPU memory flush from the CPU.
122 [[nodiscard]] u64 RequestFlush(VAddr addr, std::size_t size); 124 [[nodiscard]] u64 RequestFlush(VAddr addr, std::size_t size);
123 125
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index d4c0dca78..b36067613 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -59,10 +59,19 @@ GPUVAddr MemoryManager::PageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cp
59 } 59 }
60 for (u64 offset{}; offset < size; offset += page_size) { 60 for (u64 offset{}; offset < size; offset += page_size) {
61 const GPUVAddr current_gpu_addr = gpu_addr + offset; 61 const GPUVAddr current_gpu_addr = gpu_addr + offset;
62 [[maybe_unused]] const auto current_entry_type = GetEntry(current_gpu_addr);
62 SetEntry(current_gpu_addr, entry_type); 63 SetEntry(current_gpu_addr, entry_type);
64 if (current_entry_type != entry_type) {
65 rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, page_size);
66 }
63 if constexpr (entry_type == EntryType::Mapped) { 67 if constexpr (entry_type == EntryType::Mapped) {
64 const VAddr current_cpu_addr = cpu_addr + offset; 68 const VAddr current_cpu_addr = cpu_addr + offset;
65 const auto index = PageEntryIndex(current_gpu_addr); 69 const auto index = PageEntryIndex(current_gpu_addr);
70 const u32 sub_value = static_cast<u32>(current_cpu_addr >> 12ULL);
71 if (current_entry_type == entry_type && sub_value != page_table[index]) {
72 rasterizer->InvalidateRegion(static_cast<VAddr>(page_table[index]) << 12ULL,
73 page_size);
74 }
66 page_table[index] = static_cast<u32>(current_cpu_addr >> 12ULL); 75 page_table[index] = static_cast<u32>(current_cpu_addr >> 12ULL);
67 } 76 }
68 remaining_size -= page_size; 77 remaining_size -= page_size;
@@ -168,7 +177,7 @@ std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr, std::size_t s
168 const size_t page_last{(addr + size + page_size - 1) >> page_bits}; 177 const size_t page_last{(addr + size + page_size - 1) >> page_bits};
169 while (page_index < page_last) { 178 while (page_index < page_last) {
170 const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; 179 const auto page_addr{GpuToCpuAddress(page_index << page_bits)};
171 if (page_addr && *page_addr != 0) { 180 if (page_addr) {
172 return page_addr; 181 return page_addr;
173 } 182 }
174 ++page_index; 183 ++page_index;
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 8dacb2626..5362aafb6 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -95,7 +95,7 @@ public:
95 virtual void UnmapMemory(VAddr addr, u64 size) = 0; 95 virtual void UnmapMemory(VAddr addr, u64 size) = 0;
96 96
97 /// Remap GPU memory range. This means underneath backing memory changed 97 /// Remap GPU memory range. This means underneath backing memory changed
98 virtual void ModifyGPUMemory(GPUVAddr addr, u64 size) = 0; 98 virtual void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) = 0;
99 99
100 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory 100 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
101 /// and invalidated 101 /// and invalidated
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4eb9bd116..f745fbf56 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -379,10 +379,10 @@ void RasterizerOpenGL::UnmapMemory(VAddr addr, u64 size) {
379 shader_cache.OnCPUWrite(addr, size); 379 shader_cache.OnCPUWrite(addr, size);
380} 380}
381 381
382void RasterizerOpenGL::ModifyGPUMemory(GPUVAddr addr, u64 size) { 382void RasterizerOpenGL::ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) {
383 { 383 {
384 std::scoped_lock lock{texture_cache.mutex}; 384 std::scoped_lock lock{texture_cache.mutex};
385 texture_cache.UnmapGPUMemory(addr, size); 385 texture_cache.UnmapGPUMemory(as_id, addr, size);
386 } 386 }
387} 387}
388 388
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 39b20cfb2..d469075a1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -82,7 +82,7 @@ public:
82 void OnCPUWrite(VAddr addr, u64 size) override; 82 void OnCPUWrite(VAddr addr, u64 size) override;
83 void SyncGuestHost() override; 83 void SyncGuestHost() override;
84 void UnmapMemory(VAddr addr, u64 size) override; 84 void UnmapMemory(VAddr addr, u64 size) override;
85 void ModifyGPUMemory(GPUVAddr addr, u64 size) override; 85 void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) override;
86 void SignalSemaphore(GPUVAddr addr, u32 value) override; 86 void SignalSemaphore(GPUVAddr addr, u32 value) override;
87 void SignalSyncPoint(u32 value) override; 87 void SignalSyncPoint(u32 value) override;
88 void SignalReference() override; 88 void SignalReference() override;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 7e0805544..50fdf5e18 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -441,10 +441,10 @@ void RasterizerVulkan::UnmapMemory(VAddr addr, u64 size) {
441 pipeline_cache.OnCPUWrite(addr, size); 441 pipeline_cache.OnCPUWrite(addr, size);
442} 442}
443 443
444void RasterizerVulkan::ModifyGPUMemory(GPUVAddr addr, u64 size) { 444void RasterizerVulkan::ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) {
445 { 445 {
446 std::scoped_lock lock{texture_cache.mutex}; 446 std::scoped_lock lock{texture_cache.mutex};
447 texture_cache.UnmapGPUMemory(addr, size); 447 texture_cache.UnmapGPUMemory(as_id, addr, size);
448 } 448 }
449} 449}
450 450
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 642fe6576..c836158b8 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -78,7 +78,7 @@ public:
78 void OnCPUWrite(VAddr addr, u64 size) override; 78 void OnCPUWrite(VAddr addr, u64 size) override;
79 void SyncGuestHost() override; 79 void SyncGuestHost() override;
80 void UnmapMemory(VAddr addr, u64 size) override; 80 void UnmapMemory(VAddr addr, u64 size) override;
81 void ModifyGPUMemory(GPUVAddr addr, u64 size) override; 81 void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) override;
82 void SignalSemaphore(GPUVAddr addr, u32 value) override; 82 void SignalSemaphore(GPUVAddr addr, u32 value) override;
83 void SignalSyncPoint(u32 value) override; 83 void SignalSyncPoint(u32 value) override;
84 void SignalReference() override; 84 void SignalReference() override;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 5ef07d18f..a483892e4 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -480,12 +480,20 @@ void TextureCache<P>::UnmapMemory(VAddr cpu_addr, size_t size) {
480} 480}
481 481
482template <class P> 482template <class P>
483void TextureCache<P>::UnmapGPUMemory(GPUVAddr gpu_addr, size_t size) { 483void TextureCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t size) {
484 std::vector<ImageId> deleted_images; 484 std::vector<ImageId> deleted_images;
485 ForEachImageInRegionGPU(gpu_addr, size, 485 ForEachImageInRegionGPU(as_id, gpu_addr, size,
486 [&](ImageId id, Image&) { deleted_images.push_back(id); }); 486 [&](ImageId id, Image&) { deleted_images.push_back(id); });
487 for (const ImageId id : deleted_images) { 487 for (const ImageId id : deleted_images) {
488 Image& image = slot_images[id]; 488 Image& image = slot_images[id];
489 if (True(image.flags & ImageFlagBits::CpuModified)) {
490 return;
491 }
492 image.flags |= ImageFlagBits::CpuModified;
493 if (True(image.flags & ImageFlagBits::Tracked)) {
494 UntrackImage(image, id);
495 }
496 /*
489 if (True(image.flags & ImageFlagBits::Remapped)) { 497 if (True(image.flags & ImageFlagBits::Remapped)) {
490 continue; 498 continue;
491 } 499 }
@@ -493,6 +501,7 @@ void TextureCache<P>::UnmapGPUMemory(GPUVAddr gpu_addr, size_t size) {
493 if (True(image.flags & ImageFlagBits::Tracked)) { 501 if (True(image.flags & ImageFlagBits::Tracked)) {
494 UntrackImage(image, id); 502 UntrackImage(image, id);
495 } 503 }
504 */
496 } 505 }
497} 506}
498 507
@@ -1322,13 +1331,19 @@ void TextureCache<P>::ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& f
1322 1331
1323template <class P> 1332template <class P>
1324template <typename Func> 1333template <typename Func>
1325void TextureCache<P>::ForEachImageInRegionGPU(GPUVAddr gpu_addr, size_t size, Func&& func) { 1334void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size,
1335 Func&& func) {
1326 using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type; 1336 using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type;
1327 static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>; 1337 static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
1328 boost::container::small_vector<ImageId, 8> images; 1338 boost::container::small_vector<ImageId, 8> images;
1329 ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) { 1339 auto storage_id = getStorageID(as_id);
1330 const auto it = channel_state->gpu_page_table->find(page); 1340 if (!storage_id) {
1331 if (it == channel_state->gpu_page_table->end()) { 1341 return;
1342 }
1343 auto& gpu_page_table = gpu_page_table_storage[*storage_id];
1344 ForEachGPUPage(gpu_addr, size, [this, gpu_page_table, &images, gpu_addr, size, func](u64 page) {
1345 const auto it = gpu_page_table.find(page);
1346 if (it == gpu_page_table.end()) {
1332 if constexpr (BOOL_BREAK) { 1347 if constexpr (BOOL_BREAK) {
1333 return false; 1348 return false;
1334 } else { 1349 } else {
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index b24968b03..2f4db5047 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -173,7 +173,7 @@ public:
173 void UnmapMemory(VAddr cpu_addr, size_t size); 173 void UnmapMemory(VAddr cpu_addr, size_t size);
174 174
175 /// Remove images in a region 175 /// Remove images in a region
176 void UnmapGPUMemory(GPUVAddr gpu_addr, size_t size); 176 void UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t size);
177 177
178 /// Blit an image with the given parameters 178 /// Blit an image with the given parameters
179 void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, 179 void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
@@ -309,7 +309,7 @@ private:
309 void ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& func); 309 void ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& func);
310 310
311 template <typename Func> 311 template <typename Func>
312 void ForEachImageInRegionGPU(GPUVAddr gpu_addr, size_t size, Func&& func); 312 void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
313 313
314 template <typename Func> 314 template <typename Func>
315 void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func); 315 void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func);