[Memory] Refactor GetPhysicalAddress and use it for XMA, resolve #1448

This commit is contained in:
Triang3l
2019-08-24 17:40:59 +03:00
parent 3e6c2bb47c
commit 7e6bf8022f
6 changed files with 72 additions and 40 deletions

View File

@@ -362,13 +362,26 @@ void VdSwap(lpvoid_t buffer_ptr, // ptr into primary ringbuffer
xe::copy_and_swap_32_unaligned(
&fetch, reinterpret_cast<uint32_t*>(fetch_ptr.host_address()), 6);
// Kernel virtual -> GPU physical.
uint32_t frontbuffer_address = fetch.base_address << 12;
assert_true(*frontbuffer_ptr == frontbuffer_address);
frontbuffer_address =
kernel_memory()->GetPhysicalAddress(frontbuffer_address);
assert_true(frontbuffer_address != UINT32_MAX);
if (frontbuffer_address == UINT32_MAX) {
// Xenia-specific safety check.
XELOGE("VdSwap: Invalid front buffer virtual address 0x%.8X",
fetch.base_address << 12);
return;
}
fetch.base_address = frontbuffer_address >> 12;
auto texture_format = gpu::TextureFormat(texture_format_ptr.value());
auto color_space = *color_space_ptr;
assert_true(texture_format == gpu::TextureFormat::k_8_8_8_8 ||
texture_format ==
gpu::TextureFormat::k_2_10_10_10_AS_16_16_16_16);
assert_true(color_space == 0); // RGB(0)
assert_true(*frontbuffer_ptr == fetch.base_address << 12);
assert_true(*width == 1 + fetch.size_2d.width);
assert_true(*height == 1 + fetch.size_2d.height);
@@ -379,14 +392,6 @@ void VdSwap(lpvoid_t buffer_ptr, // ptr into primary ringbuffer
// use this method.
buffer_ptr.Zero(64 * 4);
// virtual -> physical
// Doom 3: BFG Edition uses front buffers from the 0xE0000000 range with 4 KB
// offset, so & 0x1FFFF is not enough for this.
fetch.base_address = kernel_memory()
->LookupHeap(fetch.base_address << 12)
->GetPhysicalAddress(fetch.base_address << 12) >>
12;
uint32_t offset = 0;
auto dwords = buffer_ptr.as_array<uint32_t>();
@@ -402,9 +407,7 @@ void VdSwap(lpvoid_t buffer_ptr, // ptr into primary ringbuffer
dwords[offset++] = xenos::MakePacketType3(xenos::PM4_XE_SWAP, 4);
dwords[offset++] = 'SWAP';
dwords[offset++] = kernel_memory()
->LookupHeap(*frontbuffer_ptr)
->GetPhysicalAddress(*frontbuffer_ptr);
dwords[offset++] = frontbuffer_address;
dwords[offset++] = *width;
dwords[offset++] = *height;