diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/gpu.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/memory_manager.cpp | 87 | ||||
| -rw-r--r-- | src/video_core/memory_manager.h | 7 |
3 files changed, 84 insertions, 12 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 30b29e14d..4461083ff 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -31,7 +31,7 @@ u32 FramebufferConfig::BytesPerPixel(PixelFormat format) { | |||
| 31 | 31 | ||
| 32 | GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{renderer} { | 32 | GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{renderer} { |
| 33 | auto& rasterizer{renderer.Rasterizer()}; | 33 | auto& rasterizer{renderer.Rasterizer()}; |
| 34 | memory_manager = std::make_unique<Tegra::MemoryManager>(); | 34 | memory_manager = std::make_unique<Tegra::MemoryManager>(rasterizer); |
| 35 | dma_pusher = std::make_unique<Tegra::DmaPusher>(*this); | 35 | dma_pusher = std::make_unique<Tegra::DmaPusher>(*this); |
| 36 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, rasterizer, *memory_manager); | 36 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, rasterizer, *memory_manager); |
| 37 | fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager); | 37 | fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager); |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 8417324ff..0f4e820aa 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -5,16 +5,13 @@ | |||
| 5 | #include "common/alignment.h" | 5 | #include "common/alignment.h" |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/core.h" | ||
| 9 | #include "core/memory.h" | 8 | #include "core/memory.h" |
| 10 | #include "video_core/gpu.h" | ||
| 11 | #include "video_core/memory_manager.h" | 9 | #include "video_core/memory_manager.h" |
| 12 | #include "video_core/rasterizer_interface.h" | 10 | #include "video_core/rasterizer_interface.h" |
| 13 | #include "video_core/renderer_base.h" | ||
| 14 | 11 | ||
| 15 | namespace Tegra { | 12 | namespace Tegra { |
| 16 | 13 | ||
| 17 | MemoryManager::MemoryManager() { | 14 | MemoryManager::MemoryManager(VideoCore::RasterizerInterface& rasterizer) : rasterizer{rasterizer} { |
| 18 | std::fill(page_table.pointers.begin(), page_table.pointers.end(), nullptr); | 15 | std::fill(page_table.pointers.begin(), page_table.pointers.end(), nullptr); |
| 19 | std::fill(page_table.attributes.begin(), page_table.attributes.end(), | 16 | std::fill(page_table.attributes.begin(), page_table.attributes.end(), |
| 20 | Common::PageType::Unmapped); | 17 | Common::PageType::Unmapped); |
| @@ -70,8 +67,7 @@ GPUVAddr MemoryManager::UnmapBuffer(GPUVAddr gpu_addr, u64 size) { | |||
| 70 | const u64 aligned_size{Common::AlignUp(size, page_size)}; | 67 | const u64 aligned_size{Common::AlignUp(size, page_size)}; |
| 71 | const CacheAddr cache_addr{ToCacheAddr(GetPointer(gpu_addr))}; | 68 | const CacheAddr cache_addr{ToCacheAddr(GetPointer(gpu_addr))}; |
| 72 | 69 | ||
| 73 | Core::System::GetInstance().Renderer().Rasterizer().FlushAndInvalidateRegion(cache_addr, | 70 | rasterizer.FlushAndInvalidateRegion(cache_addr, aligned_size); |
| 74 | aligned_size); | ||
| 75 | UnmapRange(gpu_addr, aligned_size); | 71 | UnmapRange(gpu_addr, aligned_size); |
| 76 | 72 | ||
| 77 | return gpu_addr; | 73 | return gpu_addr; |
| @@ -204,14 +200,85 @@ const u8* MemoryManager::GetPointer(GPUVAddr addr) const { | |||
| 204 | } | 200 | } |
| 205 | 201 | ||
| 206 | void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const { | 202 | void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const { |
| 207 | std::memcpy(dest_buffer, GetPointer(src_addr), size); | 203 | std::size_t remaining_size{size}; |
| 204 | std::size_t page_index{src_addr >> page_bits}; | ||
| 205 | std::size_t page_offset{src_addr & page_mask}; | ||
| 206 | |||
| 207 | while (remaining_size > 0) { | ||
| 208 | const std::size_t copy_amount{ | ||
| 209 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | ||
| 210 | |||
| 211 | switch (page_table.attributes[page_index]) { | ||
| 212 | case Common::PageType::Memory: { | ||
| 213 | const u8* src_ptr{page_table.pointers[page_index] + page_offset}; | ||
| 214 | rasterizer.FlushRegion(ToCacheAddr(src_ptr), copy_amount); | ||
| 215 | std::memcpy(dest_buffer, src_ptr, copy_amount); | ||
| 216 | break; | ||
| 217 | } | ||
| 218 | default: | ||
| 219 | UNREACHABLE(); | ||
| 220 | } | ||
| 221 | |||
| 222 | page_index++; | ||
| 223 | page_offset = 0; | ||
| 224 | dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount; | ||
| 225 | remaining_size -= copy_amount; | ||
| 226 | } | ||
| 208 | } | 227 | } |
| 228 | |||
| 209 | void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { | 229 | void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { |
| 210 | std::memcpy(GetPointer(dest_addr), src_buffer, size); | 230 | std::size_t remaining_size{size}; |
| 231 | std::size_t page_index{dest_addr >> page_bits}; | ||
| 232 | std::size_t page_offset{dest_addr & page_mask}; | ||
| 233 | |||
| 234 | while (remaining_size > 0) { | ||
| 235 | const std::size_t copy_amount{ | ||
| 236 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | ||
| 237 | |||
| 238 | switch (page_table.attributes[page_index]) { | ||
| 239 | case Common::PageType::Memory: { | ||
| 240 | u8* dest_ptr{page_table.pointers[page_index] + page_offset}; | ||
| 241 | rasterizer.InvalidateRegion(ToCacheAddr(dest_ptr), copy_amount); | ||
| 242 | std::memcpy(dest_ptr, src_buffer, copy_amount); | ||
| 243 | break; | ||
| 244 | } | ||
| 245 | default: | ||
| 246 | UNREACHABLE(); | ||
| 247 | } | ||
| 248 | |||
| 249 | page_index++; | ||
| 250 | page_offset = 0; | ||
| 251 | src_buffer = static_cast<const u8*>(src_buffer) + copy_amount; | ||
| 252 | remaining_size -= copy_amount; | ||
| 253 | } | ||
| 211 | } | 254 | } |
| 212 | 255 | ||
| 213 | void MemoryManager::CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t size) { | 256 | void MemoryManager::CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t size) { |
| 214 | std::memcpy(GetPointer(dest_addr), GetPointer(src_addr), size); | 257 | std::size_t remaining_size{size}; |
| 258 | std::size_t page_index{src_addr >> page_bits}; | ||
| 259 | std::size_t page_offset{src_addr & page_mask}; | ||
| 260 | |||
| 261 | while (remaining_size > 0) { | ||
| 262 | const std::size_t copy_amount{ | ||
| 263 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | ||
| 264 | |||
| 265 | switch (page_table.attributes[page_index]) { | ||
| 266 | case Common::PageType::Memory: { | ||
| 267 | const u8* src_ptr{page_table.pointers[page_index] + page_offset}; | ||
| 268 | rasterizer.FlushRegion(ToCacheAddr(src_ptr), copy_amount); | ||
| 269 | WriteBlock(dest_addr, src_ptr, copy_amount); | ||
| 270 | break; | ||
| 271 | } | ||
| 272 | default: | ||
| 273 | UNREACHABLE(); | ||
| 274 | } | ||
| 275 | |||
| 276 | page_index++; | ||
| 277 | page_offset = 0; | ||
| 278 | dest_addr += static_cast<VAddr>(copy_amount); | ||
| 279 | src_addr += static_cast<VAddr>(copy_amount); | ||
| 280 | remaining_size -= copy_amount; | ||
| 281 | } | ||
| 215 | } | 282 | } |
| 216 | 283 | ||
| 217 | void MemoryManager::MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, | 284 | void MemoryManager::MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, |
| @@ -351,7 +418,7 @@ MemoryManager::VMAIter MemoryManager::CarveVMA(GPUVAddr base, u64 size) { | |||
| 351 | const VirtualMemoryArea& vma{vma_handle->second}; | 418 | const VirtualMemoryArea& vma{vma_handle->second}; |
| 352 | if (vma.type == VirtualMemoryArea::Type::Mapped) { | 419 | if (vma.type == VirtualMemoryArea::Type::Mapped) { |
| 353 | // Region is already allocated | 420 | // Region is already allocated |
| 354 | return {}; | 421 | return vma_handle; |
| 355 | } | 422 | } |
| 356 | 423 | ||
| 357 | const VAddr start_in_vma{base - vma.base}; | 424 | const VAddr start_in_vma{base - vma.base}; |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 178e2f655..647cbf93a 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -10,6 +10,10 @@ | |||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/page_table.h" | 11 | #include "common/page_table.h" |
| 12 | 12 | ||
| 13 | namespace VideoCore { | ||
| 14 | class RasterizerInterface; | ||
| 15 | } | ||
| 16 | |||
| 13 | namespace Tegra { | 17 | namespace Tegra { |
| 14 | 18 | ||
| 15 | /** | 19 | /** |
| @@ -43,7 +47,7 @@ struct VirtualMemoryArea { | |||
| 43 | 47 | ||
| 44 | class MemoryManager final { | 48 | class MemoryManager final { |
| 45 | public: | 49 | public: |
| 46 | MemoryManager(); | 50 | MemoryManager(VideoCore::RasterizerInterface& rasterizer); |
| 47 | 51 | ||
| 48 | GPUVAddr AllocateSpace(u64 size, u64 align); | 52 | GPUVAddr AllocateSpace(u64 size, u64 align); |
| 49 | GPUVAddr AllocateSpace(GPUVAddr addr, u64 size, u64 align); | 53 | GPUVAddr AllocateSpace(GPUVAddr addr, u64 size, u64 align); |
| @@ -144,6 +148,7 @@ private: | |||
| 144 | 148 | ||
| 145 | Common::PageTable page_table{page_bits}; | 149 | Common::PageTable page_table{page_bits}; |
| 146 | VMAMap vma_map; | 150 | VMAMap vma_map; |
| 151 | VideoCore::RasterizerInterface& rasterizer; | ||
| 147 | }; | 152 | }; |
| 148 | 153 | ||
| 149 | } // namespace Tegra | 154 | } // namespace Tegra |