diff options
| author | 2019-11-26 15:56:13 -0500 | |
|---|---|---|
| committer | 2019-11-26 21:55:38 -0500 | |
| commit | 849581075a230ad0f5419bb5d5e1f9e48e6cfd8a (patch) | |
| tree | 62985359329da0b65f65429ea5c403f622aea5e3 /src/core/memory.cpp | |
| parent | core/memory: Migrate over ReadCString() to the Memory class (diff) | |
| download | yuzu-849581075a230ad0f5419bb5d5e1f9e48e6cfd8a.tar.gz yuzu-849581075a230ad0f5419bb5d5e1f9e48e6cfd8a.tar.xz yuzu-849581075a230ad0f5419bb5d5e1f9e48e6cfd8a.zip | |
core/memory: Migrate over RasterizerMarkRegionCached() to the Memory class
This is only used within the accelerated rasterizer in two places, so
this is also a very trivial migration.
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 130 |
1 files changed, 67 insertions, 63 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index fb824d710..8c3489ed3 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -225,6 +225,69 @@ struct Memory::Impl { | |||
| 225 | return string; | 225 | return string; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | ||
| 229 | if (vaddr == 0) { | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | |||
| 233 | // Iterate over a contiguous CPU address space, which corresponds to the specified GPU | ||
| 234 | // address space, marking the region as un/cached. The region is marked un/cached at a | ||
| 235 | // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size | ||
| 236 | // is different). This assumes the specified GPU address region is contiguous as well. | ||
| 237 | |||
| 238 | u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1; | ||
| 239 | for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { | ||
| 240 | Common::PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; | ||
| 241 | |||
| 242 | if (cached) { | ||
| 243 | // Switch page type to cached if now cached | ||
| 244 | switch (page_type) { | ||
| 245 | case Common::PageType::Unmapped: | ||
| 246 | // It is not necessary for a process to have this region mapped into its address | ||
| 247 | // space, for example, a system module need not have a VRAM mapping. | ||
| 248 | break; | ||
| 249 | case Common::PageType::Memory: | ||
| 250 | page_type = Common::PageType::RasterizerCachedMemory; | ||
| 251 | current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; | ||
| 252 | break; | ||
| 253 | case Common::PageType::RasterizerCachedMemory: | ||
| 254 | // There can be more than one GPU region mapped per CPU region, so it's common | ||
| 255 | // that this area is already marked as cached. | ||
| 256 | break; | ||
| 257 | default: | ||
| 258 | UNREACHABLE(); | ||
| 259 | } | ||
| 260 | } else { | ||
| 261 | // Switch page type to uncached if now uncached | ||
| 262 | switch (page_type) { | ||
| 263 | case Common::PageType::Unmapped: | ||
| 264 | // It is not necessary for a process to have this region mapped into its address | ||
| 265 | // space, for example, a system module need not have a VRAM mapping. | ||
| 266 | break; | ||
| 267 | case Common::PageType::Memory: | ||
| 268 | // There can be more than one GPU region mapped per CPU region, so it's common | ||
| 269 | // that this area is already unmarked as cached. | ||
| 270 | break; | ||
| 271 | case Common::PageType::RasterizerCachedMemory: { | ||
| 272 | u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); | ||
| 273 | if (pointer == nullptr) { | ||
| 274 | // It's possible that this function has been called while updating the | ||
| 275 | // pagetable after unmapping a VMA. In that case the underlying VMA will no | ||
| 276 | // longer exist, and we should just leave the pagetable entry blank. | ||
| 277 | page_type = Common::PageType::Unmapped; | ||
| 278 | } else { | ||
| 279 | page_type = Common::PageType::Memory; | ||
| 280 | current_page_table->pointers[vaddr >> PAGE_BITS] = pointer; | ||
| 281 | } | ||
| 282 | break; | ||
| 283 | } | ||
| 284 | default: | ||
| 285 | UNREACHABLE(); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 228 | /** | 291 | /** |
| 229 | * Maps a region of pages as a specific type. | 292 | * Maps a region of pages as a specific type. |
| 230 | * | 293 | * |
| @@ -318,6 +381,10 @@ std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) { | |||
| 318 | return impl->ReadCString(vaddr, max_length); | 381 | return impl->ReadCString(vaddr, max_length); |
| 319 | } | 382 | } |
| 320 | 383 | ||
| 384 | void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | ||
| 385 | impl->RasterizerMarkRegionCached(vaddr, size, cached); | ||
| 386 | } | ||
| 387 | |||
| 321 | void SetCurrentPageTable(Kernel::Process& process) { | 388 | void SetCurrentPageTable(Kernel::Process& process) { |
| 322 | current_page_table = &process.VMManager().page_table; | 389 | current_page_table = &process.VMManager().page_table; |
| 323 | 390 | ||
| @@ -334,69 +401,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) { | |||
| 334 | return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; | 401 | return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; |
| 335 | } | 402 | } |
| 336 | 403 | ||
| 337 | void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | ||
| 338 | if (vaddr == 0) { | ||
| 339 | return; | ||
| 340 | } | ||
| 341 | |||
| 342 | // Iterate over a contiguous CPU address space, which corresponds to the specified GPU address | ||
| 343 | // space, marking the region as un/cached. The region is marked un/cached at a granularity of | ||
| 344 | // CPU pages, hence why we iterate on a CPU page basis (note: GPU page size is different). This | ||
| 345 | // assumes the specified GPU address region is contiguous as well. | ||
| 346 | |||
| 347 | u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1; | ||
| 348 | for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { | ||
| 349 | Common::PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; | ||
| 350 | |||
| 351 | if (cached) { | ||
| 352 | // Switch page type to cached if now cached | ||
| 353 | switch (page_type) { | ||
| 354 | case Common::PageType::Unmapped: | ||
| 355 | // It is not necessary for a process to have this region mapped into its address | ||
| 356 | // space, for example, a system module need not have a VRAM mapping. | ||
| 357 | break; | ||
| 358 | case Common::PageType::Memory: | ||
| 359 | page_type = Common::PageType::RasterizerCachedMemory; | ||
| 360 | current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; | ||
| 361 | break; | ||
| 362 | case Common::PageType::RasterizerCachedMemory: | ||
| 363 | // There can be more than one GPU region mapped per CPU region, so it's common that | ||
| 364 | // this area is already marked as cached. | ||
| 365 | break; | ||
| 366 | default: | ||
| 367 | UNREACHABLE(); | ||
| 368 | } | ||
| 369 | } else { | ||
| 370 | // Switch page type to uncached if now uncached | ||
| 371 | switch (page_type) { | ||
| 372 | case Common::PageType::Unmapped: | ||
| 373 | // It is not necessary for a process to have this region mapped into its address | ||
| 374 | // space, for example, a system module need not have a VRAM mapping. | ||
| 375 | break; | ||
| 376 | case Common::PageType::Memory: | ||
| 377 | // There can be more than one GPU region mapped per CPU region, so it's common that | ||
| 378 | // this area is already unmarked as cached. | ||
| 379 | break; | ||
| 380 | case Common::PageType::RasterizerCachedMemory: { | ||
| 381 | u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); | ||
| 382 | if (pointer == nullptr) { | ||
| 383 | // It's possible that this function has been called while updating the pagetable | ||
| 384 | // after unmapping a VMA. In that case the underlying VMA will no longer exist, | ||
| 385 | // and we should just leave the pagetable entry blank. | ||
| 386 | page_type = Common::PageType::Unmapped; | ||
| 387 | } else { | ||
| 388 | page_type = Common::PageType::Memory; | ||
| 389 | current_page_table->pointers[vaddr >> PAGE_BITS] = pointer; | ||
| 390 | } | ||
| 391 | break; | ||
| 392 | } | ||
| 393 | default: | ||
| 394 | UNREACHABLE(); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | u8 Read8(const VAddr addr) { | 404 | u8 Read8(const VAddr addr) { |
| 401 | return Read<u8>(addr); | 405 | return Read<u8>(addr); |
| 402 | } | 406 | } |