mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +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) {
|
bool MemoryManager::TryWriteBacking(void* address, const void* data, u32 size) {
|
||||||
const VAddr virtual_addr = std::bit_cast<VAddr>(address);
|
VAddr virtual_addr = std::bit_cast<VAddr>(address);
|
||||||
const auto& vma = FindVMA(virtual_addr)->second;
|
const u8* src_data = std::bit_cast<const u8*>(data);
|
||||||
ASSERT_MSG(vma.Contains(virtual_addr, num_bytes),
|
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);
|
"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;
|
return false;
|
||||||
}
|
}
|
||||||
u8* backing = impl.BackingBase() + vma.phys_base + (virtual_addr - vma.base);
|
const u64 offset_in_vma = virtual_addr - vma->first;
|
||||||
memcpy(backing, data, num_bytes);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/div_ceil.h"
|
#include "common/div_ceil.h"
|
||||||
#include "common/scope_exit.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "video_core/amdgpu/liverpool.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) {
|
for (const auto& copy : copies) {
|
||||||
const VAddr copy_device_addr = buffer.CpuAddr() + copy.srcOffset;
|
const VAddr copy_device_addr = buffer.CpuAddr() + copy.srcOffset;
|
||||||
const u64 dst_offset = copy.dstOffset - offset;
|
const u64 dst_offset = copy.dstOffset - offset;
|
||||||
ASSERT(memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr), download + dst_offset,
|
if (!memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr), download + dst_offset,
|
||||||
copy.size));
|
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) {
|
for (auto& copy : buffer_copies) {
|
||||||
const VAddr copy_device_addr = buffer.CpuAddr() + copy.srcOffset;
|
const VAddr copy_device_addr = buffer.CpuAddr() + copy.srcOffset;
|
||||||
const u64 dst_offset = copy.dstOffset - offset;
|
const u64 dst_offset = copy.dstOffset - offset;
|
||||||
ASSERT(memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr),
|
if (!memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr),
|
||||||
download + dst_offset, copy.size));
|
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/config.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
#include "common/scope_exit.h"
|
||||||
#include "shader_recompiler/runtime_info.h"
|
#include "shader_recompiler/runtime_info.h"
|
||||||
#include "video_core/amdgpu/liverpool.h"
|
#include "video_core/amdgpu/liverpool.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
@ -61,7 +62,9 @@ void Rasterizer::CpSync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Rasterizer::CommitPendingDownloads(bool wait_done) {
|
bool Rasterizer::CommitPendingDownloads(bool wait_done) {
|
||||||
|
SCOPE_EXIT {
|
||||||
scheduler.PopPendingOperations();
|
scheduler.PopPendingOperations();
|
||||||
|
};
|
||||||
return buffer_cache.CommitPendingDownloads(wait_done);
|
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;
|
uses_dma |= stage->dma_types != Shader::IR::Type::Void;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline->BindResources(set_writes, buffer_barriers, push_data);
|
|
||||||
|
|
||||||
if (uses_dma && !fault_process_pending) {
|
if (uses_dma && !fault_process_pending) {
|
||||||
// We only use fault buffer for DMA right now.
|
// We only use fault buffer for DMA right now.
|
||||||
{
|
{
|
||||||
@ -503,6 +504,8 @@ bool Rasterizer::BindResources(const Pipeline* pipeline) {
|
|||||||
|
|
||||||
fault_process_pending |= uses_dma;
|
fault_process_pending |= uses_dma;
|
||||||
|
|
||||||
|
pipeline->BindResources(set_writes, buffer_barriers, push_data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,12 +98,6 @@ void Scheduler::Wait(u64 tick) {
|
|||||||
Flush(info);
|
Flush(info);
|
||||||
}
|
}
|
||||||
master_semaphore.Wait(tick);
|
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() {
|
void Scheduler::AllocateWorkerCommandBuffers() {
|
||||||
|
Loading…
Reference in New Issue
Block a user