Skip to content

Commit 65b48b8

Browse files
committed
[Memory] Ensure writecombine buffers are writable
1 parent f4b471d commit 65b48b8

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

src/xenia/memory.cc

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,13 @@ void CrashDump() {
8383
}
8484

8585
xe::memory::PageAccess ToPageAccess(uint32_t protect) {
86-
if ((protect & kMemoryProtectRead) && !(protect & kMemoryProtectWrite)) {
86+
// Write-combine memory is CPU-writable (for GPU uploads)
87+
bool is_writable =
88+
(protect & kMemoryProtectWrite) || (protect & kMemoryProtectWriteCombine);
89+
90+
if ((protect & kMemoryProtectRead) && !is_writable) {
8791
return xe::memory::PageAccess::kReadOnly;
88-
} else if ((protect & kMemoryProtectRead) &&
89-
(protect & kMemoryProtectWrite)) {
92+
} else if ((protect & kMemoryProtectRead) && is_writable) {
9093
return xe::memory::PageAccess::kReadWrite;
9194
} else {
9295
return xe::memory::PageAccess::kNoAccess;
@@ -1457,14 +1460,29 @@ xe::memory::PageAccess BaseHeap::QueryRangeAccess(uint32_t low_address,
14571460
}
14581461
uint32_t low_page_number = (low_address - heap_base_) >> page_size_shift_;
14591462
uint32_t high_page_number = (high_address - heap_base_) >> page_size_shift_;
1460-
uint32_t protect = kMemoryProtectRead | kMemoryProtectWrite;
1463+
bool all_readable = true;
1464+
bool all_writable = true;
14611465
{
14621466
auto global_lock = global_critical_region_.Acquire();
1463-
for (uint32_t i = low_page_number; protect && i <= high_page_number; ++i) {
1464-
protect &= page_table_[i].current_protect;
1467+
for (uint32_t i = low_page_number; i <= high_page_number; ++i) {
1468+
uint32_t page_protect = page_table_[i].current_protect;
1469+
if (!(page_protect & kMemoryProtectRead)) {
1470+
all_readable = false;
1471+
}
1472+
// Check if page is writable in any form (Write or WriteCombine)
1473+
if (!(page_protect & kMemoryProtectWrite) &&
1474+
!(page_protect & kMemoryProtectWriteCombine)) {
1475+
all_writable = false;
1476+
}
14651477
}
14661478
}
1467-
return ToPageAccess(protect);
1479+
if (all_readable && all_writable) {
1480+
return xe::memory::PageAccess::kReadWrite;
1481+
} else if (all_readable) {
1482+
return xe::memory::PageAccess::kReadOnly;
1483+
} else {
1484+
return xe::memory::PageAccess::kNoAccess;
1485+
}
14681486
}
14691487

14701488
VirtualHeap::VirtualHeap() = default;

0 commit comments

Comments
 (0)