mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 10:35:03 +00:00
buffer_cache: Backing memory write fixes
This commit is contained in:
parent
e580073430
commit
f03d0c841e
@ -135,16 +135,25 @@ void MemoryManager::CopySparseMemory(VAddr virtual_addr, u8* dest, u64 size) {
|
||||
}
|
||||
}
|
||||
|
||||
bool MemoryManager::TryWriteBacking(void* address, const void* data, u32 num_bytes) {
|
||||
const VAddr virtual_addr = std::bit_cast<VAddr>(address);
|
||||
const auto& vma = FindVMA(virtual_addr)->second;
|
||||
ASSERT_MSG(vma.Contains(virtual_addr, num_bytes),
|
||||
bool MemoryManager::TryWriteBacking(void* address, const void* data, u32 size) {
|
||||
VAddr virtual_addr = std::bit_cast<VAddr>(address);
|
||||
const u8* src_data = std::bit_cast<const u8*>(data);
|
||||
auto vma = FindVMA(virtual_addr);
|
||||
ASSERT_MSG(vma->second.Contains(virtual_addr, 0),
|
||||
"Attempting to access out of bounds memory at address {:#x}", virtual_addr);
|
||||
if (vma.type != VMAType::Direct) {
|
||||
while (size) {
|
||||
if (vma->second.type != VMAType::Direct) {
|
||||
return false;
|
||||
}
|
||||
u8* backing = impl.BackingBase() + vma.phys_base + (virtual_addr - vma.base);
|
||||
memcpy(backing, data, num_bytes);
|
||||
const u64 offset_in_vma = virtual_addr - vma->first;
|
||||
u64 copy_size = std::min<u64>(vma->second.size - offset_in_vma, size);
|
||||
u8* backing = impl.BackingBase() + vma->second.phys_base + offset_in_vma;
|
||||
std::memcpy(backing, src_data, copy_size);
|
||||
size -= copy_size;
|
||||
virtual_addr += copy_size;
|
||||
src_data += copy_size;
|
||||
++vma;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "common/alignment.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/div_ceil.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/types.h"
|
||||
#include "core/memory.h"
|
||||
#include "video_core/amdgpu/liverpool.h"
|
||||
@ -183,8 +182,10 @@ void BufferCache::DownloadBufferMemory(const Buffer& buffer, VAddr device_addr,
|
||||
for (const auto& copy : copies) {
|
||||
const VAddr copy_device_addr = buffer.CpuAddr() + copy.srcOffset;
|
||||
const u64 dst_offset = copy.dstOffset - offset;
|
||||
ASSERT(memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr), download + dst_offset,
|
||||
copy.size));
|
||||
if (!memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr), download + dst_offset,
|
||||
copy.size)) {
|
||||
std::memcpy(std::bit_cast<u8*>(copy_device_addr), download + dst_offset, copy.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,8 +250,10 @@ bool BufferCache::CommitPendingDownloads(bool wait_done) {
|
||||
for (auto& copy : buffer_copies) {
|
||||
const VAddr copy_device_addr = buffer.CpuAddr() + copy.srcOffset;
|
||||
const u64 dst_offset = copy.dstOffset - offset;
|
||||
ASSERT(memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr),
|
||||
download + dst_offset, copy.size));
|
||||
if (!memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr),
|
||||
download + dst_offset, copy.size)) {
|
||||
std::memcpy(std::bit_cast<u8*>(copy_device_addr), download + dst_offset, copy.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "common/config.h"
|
||||
#include "common/debug.h"
|
||||
#include "core/memory.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "shader_recompiler/runtime_info.h"
|
||||
#include "video_core/amdgpu/liverpool.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
@ -61,7 +62,9 @@ void Rasterizer::CpSync() {
|
||||
}
|
||||
|
||||
bool Rasterizer::CommitPendingDownloads(bool wait_done) {
|
||||
SCOPE_EXIT {
|
||||
scheduler.PopPendingOperations();
|
||||
};
|
||||
return buffer_cache.CommitPendingDownloads(wait_done);
|
||||
}
|
||||
|
||||
@ -485,8 +488,6 @@ bool Rasterizer::BindResources(const Pipeline* pipeline) {
|
||||
uses_dma |= stage->dma_types != Shader::IR::Type::Void;
|
||||
}
|
||||
|
||||
pipeline->BindResources(set_writes, buffer_barriers, push_data);
|
||||
|
||||
if (uses_dma && !fault_process_pending) {
|
||||
// We only use fault buffer for DMA right now.
|
||||
{
|
||||
@ -503,6 +504,8 @@ bool Rasterizer::BindResources(const Pipeline* pipeline) {
|
||||
|
||||
fault_process_pending |= uses_dma;
|
||||
|
||||
pipeline->BindResources(set_writes, buffer_barriers, push_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -98,12 +98,6 @@ void Scheduler::Wait(u64 tick) {
|
||||
Flush(info);
|
||||
}
|
||||
master_semaphore.Wait(tick);
|
||||
|
||||
// CAUTION: This can introduce unexpected variation in the wait time.
|
||||
// We don't currently sync the GPU, and some games are very sensitive to this.
|
||||
// If this becomes a problem, it can be commented out.
|
||||
// Idealy we would implement proper gpu sync.
|
||||
PopPendingOperations();
|
||||
}
|
||||
|
||||
void Scheduler::AllocateWorkerCommandBuffers() {
|
||||
|
Loading…
Reference in New Issue
Block a user