summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/gsp_gpu.cpp11
-rw-r--r--src/core/hle/service/y2r_u.cpp4
-rw-r--r--src/core/memory.cpp91
-rw-r--r--src/core/memory.h13
4 files changed, 72 insertions, 47 deletions
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index bc964ec60..88684b82d 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -475,12 +475,11 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
475 475
476 // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever 476 // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever
477 // possible/likely 477 // possible/likely
478 Memory::RasterizerFlushRegion( 478 Memory::RasterizerFlushVirtualRegion(command.dma_request.source_address,
479 Memory::VirtualToPhysicalAddress(command.dma_request.source_address), 479 command.dma_request.size, Memory::FlushMode::Flush);
480 command.dma_request.size); 480 Memory::RasterizerFlushVirtualRegion(command.dma_request.dest_address,
481 Memory::RasterizerFlushAndInvalidateRegion( 481 command.dma_request.size,
482 Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), 482 Memory::FlushMode::FlushAndInvalidate);
483 command.dma_request.size);
484 483
485 // TODO(Subv): These memory accesses should not go through the application's memory mapping. 484 // TODO(Subv): These memory accesses should not go through the application's memory mapping.
486 // They should go through the GSP module's memory mapping. 485 // They should go through the GSP module's memory mapping.
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index e73971d5f..57172ddd6 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -587,8 +587,8 @@ static void StartConversion(Interface* self) {
587 // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( 587 // dst_image_size would seem to be perfect for this, but it doesn't include the gap :(
588 u32 total_output_size = 588 u32 total_output_size =
589 conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap); 589 conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap);
590 Memory::RasterizerFlushAndInvalidateRegion( 590 Memory::RasterizerFlushVirtualRegion(conversion.dst.address, total_output_size,
591 Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); 591 Memory::FlushMode::FlushAndInvalidate);
592 592
593 HW::Y2R::PerformConversion(conversion); 593 HW::Y2R::PerformConversion(conversion);
594 594
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 42ca69e00..38fe9e231 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -83,19 +83,13 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) {
83 LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, 83 LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE,
84 (base + size) * PAGE_SIZE); 84 (base + size) * PAGE_SIZE);
85 85
86 u32 end = base + size; 86 RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE,
87 FlushMode::FlushAndInvalidate);
87 88
89 u32 end = base + size;
88 while (base != end) { 90 while (base != end) {
89 ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base); 91 ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base);
90 92
91 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
92 // null here
93 if (current_page_table->attributes[base] == PageType::RasterizerCachedMemory ||
94 current_page_table->attributes[base] == PageType::RasterizerCachedSpecial) {
95 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS),
96 PAGE_SIZE);
97 }
98
99 current_page_table->attributes[base] = type; 93 current_page_table->attributes[base] = type;
100 current_page_table->pointers[base] = memory; 94 current_page_table->pointers[base] = memory;
101 current_page_table->cached_res_count[base] = 0; 95 current_page_table->cached_res_count[base] = 0;
@@ -189,7 +183,7 @@ T Read(const VAddr vaddr) {
189 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); 183 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
190 break; 184 break;
191 case PageType::RasterizerCachedMemory: { 185 case PageType::RasterizerCachedMemory: {
192 RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 186 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
193 187
194 T value; 188 T value;
195 std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T)); 189 std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T));
@@ -198,8 +192,7 @@ T Read(const VAddr vaddr) {
198 case PageType::Special: 192 case PageType::Special:
199 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); 193 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
200 case PageType::RasterizerCachedSpecial: { 194 case PageType::RasterizerCachedSpecial: {
201 RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 195 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
202
203 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); 196 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
204 } 197 }
205 default: 198 default:
@@ -229,8 +222,7 @@ void Write(const VAddr vaddr, const T data) {
229 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); 222 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
230 break; 223 break;
231 case PageType::RasterizerCachedMemory: { 224 case PageType::RasterizerCachedMemory: {
232 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 225 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
233
234 std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T)); 226 std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T));
235 break; 227 break;
236 } 228 }
@@ -238,8 +230,7 @@ void Write(const VAddr vaddr, const T data) {
238 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); 230 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
239 break; 231 break;
240 case PageType::RasterizerCachedSpecial: { 232 case PageType::RasterizerCachedSpecial: {
241 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 233 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
242
243 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); 234 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
244 break; 235 break;
245 } 236 }
@@ -369,11 +360,48 @@ void RasterizerFlushRegion(PAddr start, u32 size) {
369} 360}
370 361
371void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) { 362void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) {
363 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
364 // null here
372 if (VideoCore::g_renderer != nullptr) { 365 if (VideoCore::g_renderer != nullptr) {
373 VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size); 366 VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size);
374 } 367 }
375} 368}
376 369
370void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) {
371 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
372 // null here
373 if (VideoCore::g_renderer != nullptr) {
374 VAddr end = start + size;
375
376 auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
377 if (start >= region_end || end <= region_start) {
378 // No overlap with region
379 return;
380 }
381
382 VAddr overlap_start = std::max(start, region_start);
383 VAddr overlap_end = std::min(end, region_end);
384
385 PAddr physical_start = TryVirtualToPhysicalAddress(overlap_start).value();
386 u32 overlap_size = overlap_end - overlap_start;
387
388 auto* rasterizer = VideoCore::g_renderer->Rasterizer();
389 switch (mode) {
390 case FlushMode::Flush:
391 rasterizer->FlushRegion(physical_start, overlap_size);
392 break;
393 case FlushMode::FlushAndInvalidate:
394 rasterizer->FlushAndInvalidateRegion(physical_start, overlap_size);
395 break;
396 }
397 };
398
399 CheckRegion(LINEAR_HEAP_VADDR, LINEAR_HEAP_VADDR_END);
400 CheckRegion(NEW_LINEAR_HEAP_VADDR, NEW_LINEAR_HEAP_VADDR_END);
401 CheckRegion(VRAM_VADDR, VRAM_VADDR_END);
402 }
403}
404
377u8 Read8(const VAddr addr) { 405u8 Read8(const VAddr addr) {
378 return Read<u8>(addr); 406 return Read<u8>(addr);
379} 407}
@@ -420,16 +448,13 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
420 break; 448 break;
421 } 449 }
422 case PageType::RasterizerCachedMemory: { 450 case PageType::RasterizerCachedMemory: {
423 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); 451 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
424
425 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); 452 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount);
426 break; 453 break;
427 } 454 }
428 case PageType::RasterizerCachedSpecial: { 455 case PageType::RasterizerCachedSpecial: {
429 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 456 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
430 457 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
431 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
432
433 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); 458 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount);
434 break; 459 break;
435 } 460 }
@@ -490,18 +515,13 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
490 break; 515 break;
491 } 516 }
492 case PageType::RasterizerCachedMemory: { 517 case PageType::RasterizerCachedMemory: {
493 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), 518 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
494 copy_amount);
495
496 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); 519 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount);
497 break; 520 break;
498 } 521 }
499 case PageType::RasterizerCachedSpecial: { 522 case PageType::RasterizerCachedSpecial: {
500 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 523 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
501 524 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
502 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
503 copy_amount);
504
505 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); 525 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount);
506 break; 526 break;
507 } 527 }
@@ -547,18 +567,13 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
547 break; 567 break;
548 } 568 }
549 case PageType::RasterizerCachedMemory: { 569 case PageType::RasterizerCachedMemory: {
550 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), 570 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
551 copy_amount);
552
553 std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); 571 std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount);
554 break; 572 break;
555 } 573 }
556 case PageType::RasterizerCachedSpecial: { 574 case PageType::RasterizerCachedSpecial: {
557 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 575 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
558 576 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
559 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
560 copy_amount);
561
562 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); 577 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount);
563 break; 578 break;
564 } 579 }
@@ -603,15 +618,13 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
603 break; 618 break;
604 } 619 }
605 case PageType::RasterizerCachedMemory: { 620 case PageType::RasterizerCachedMemory: {
606 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); 621 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
607
608 WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount); 622 WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount);
609 break; 623 break;
610 } 624 }
611 case PageType::RasterizerCachedSpecial: { 625 case PageType::RasterizerCachedSpecial: {
612 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 626 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
613 627 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
614 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
615 628
616 std::vector<u8> buffer(copy_amount); 629 std::vector<u8> buffer(copy_amount);
617 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size()); 630 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size());
diff --git a/src/core/memory.h b/src/core/memory.h
index 96ce9e52e..c8c56babd 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -190,6 +190,19 @@ void RasterizerFlushRegion(PAddr start, u32 size);
190 */ 190 */
191void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size); 191void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size);
192 192
193enum class FlushMode {
194 /// Write back modified surfaces to RAM
195 Flush,
196 /// Write back modified surfaces to RAM, and also remove them from the cache
197 FlushAndInvalidate,
198};
199
200/**
201 * Flushes and invalidates any externally cached rasterizer resources touching the given virtual
202 * address region.
203 */
204void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode);
205
193/** 206/**
194 * Dynarmic has an optimization to memory accesses when the pointer to the page exists that 207 * Dynarmic has an optimization to memory accesses when the pointer to the page exists that
195 * can be used by setting up the current page table as a callback. This function is used to 208 * can be used by setting up the current page table as a callback. This function is used to