[Memory] Refactor GetPhysicalAddress and use it for XMA, resolve #1448
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "xenia/apu/audio_system.h"
|
||||
#include "xenia/apu/xma_decoder.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/emulator.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
@@ -184,9 +185,19 @@ DECLARE_XBOXKRNL_EXPORT2(XMASetInputBufferReadOffset, kAudio, kImplemented,
|
||||
|
||||
dword_result_t XMASetInputBuffer0(lpvoid_t context_ptr, lpvoid_t buffer,
|
||||
dword_t packet_count) {
|
||||
uint32_t buffer_physical_address =
|
||||
kernel_memory()->GetPhysicalAddress(buffer.guest_address());
|
||||
assert_true(buffer_physical_address != UINT32_MAX);
|
||||
if (buffer_physical_address == UINT32_MAX) {
|
||||
// Xenia-specific safety check.
|
||||
XELOGE("XMASetInputBuffer0: Invalid buffer virtual address %.8X",
|
||||
buffer.guest_address());
|
||||
return X_E_FALSE;
|
||||
}
|
||||
|
||||
XMA_CONTEXT_DATA context(context_ptr);
|
||||
|
||||
context.input_buffer_0_ptr = buffer.guest_address();
|
||||
context.input_buffer_0_ptr = buffer_physical_address;
|
||||
context.input_buffer_0_packet_count = packet_count;
|
||||
|
||||
context.Store(context_ptr);
|
||||
@@ -215,9 +226,19 @@ DECLARE_XBOXKRNL_EXPORT2(XMASetInputBuffer0Valid, kAudio, kImplemented,
|
||||
|
||||
dword_result_t XMASetInputBuffer1(lpvoid_t context_ptr, lpvoid_t buffer,
|
||||
dword_t packet_count) {
|
||||
uint32_t buffer_physical_address =
|
||||
kernel_memory()->GetPhysicalAddress(buffer.guest_address());
|
||||
assert_true(buffer_physical_address != UINT32_MAX);
|
||||
if (buffer_physical_address == UINT32_MAX) {
|
||||
// Xenia-specific safety check.
|
||||
XELOGE("XMASetInputBuffer1: Invalid buffer virtual address %.8X",
|
||||
buffer.guest_address());
|
||||
return X_E_FALSE;
|
||||
}
|
||||
|
||||
XMA_CONTEXT_DATA context(context_ptr);
|
||||
|
||||
context.input_buffer_1_ptr = buffer.guest_address();
|
||||
context.input_buffer_1_ptr = buffer_physical_address;
|
||||
context.input_buffer_1_packet_count = packet_count;
|
||||
|
||||
context.Store(context_ptr);
|
||||
|
||||
@@ -502,13 +502,11 @@ dword_result_t MmGetPhysicalAddress(dword_t base_address) {
|
||||
// _In_ PVOID BaseAddress
|
||||
// );
|
||||
// base_address = result of MmAllocatePhysicalMemory.
|
||||
assert_true(base_address >= 0xA0000000);
|
||||
|
||||
uint32_t physical_address = base_address & 0x1FFFFFFF;
|
||||
if (base_address >= 0xE0000000) {
|
||||
physical_address += 0x1000;
|
||||
uint32_t physical_address = kernel_memory()->GetPhysicalAddress(base_address);
|
||||
assert_true(physical_address != UINT32_MAX);
|
||||
if (physical_address == UINT32_MAX) {
|
||||
physical_address = 0;
|
||||
}
|
||||
|
||||
return physical_address;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(MmGetPhysicalAddress, kMemory, kImplemented);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user