|
|
@ -111,9 +111,24 @@ void BufferCache<P>::WriteMemory(VAddr cpu_addr, u64 size) { |
|
|
template <class P> |
|
|
template <class P> |
|
|
void BufferCache<P>::CachedWriteMemory(VAddr cpu_addr, u64 size) { |
|
|
void BufferCache<P>::CachedWriteMemory(VAddr cpu_addr, u64 size) { |
|
|
memory_tracker.CachedCpuWrite(cpu_addr, size); |
|
|
memory_tracker.CachedCpuWrite(cpu_addr, size); |
|
|
const IntervalType add_interval{Common::AlignDown(cpu_addr, YUZU_PAGESIZE), |
|
|
|
|
|
Common::AlignUp(cpu_addr + size, YUZU_PAGESIZE)}; |
|
|
|
|
|
cached_ranges.add(add_interval); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <class P> |
|
|
|
|
|
std::optional<VideoCore::RasterizerDownloadArea> BufferCache<P>::GetFlushArea(VAddr cpu_addr, |
|
|
|
|
|
u64 size) { |
|
|
|
|
|
std::optional<VideoCore::RasterizerDownloadArea> area{}; |
|
|
|
|
|
area.emplace(); |
|
|
|
|
|
VAddr cpu_addr_start_aligned = Common::AlignDown(cpu_addr, Core::Memory::YUZU_PAGESIZE); |
|
|
|
|
|
VAddr cpu_addr_end_aligned = Common::AlignUp(cpu_addr + size, Core::Memory::YUZU_PAGESIZE); |
|
|
|
|
|
area->start_address = cpu_addr_start_aligned; |
|
|
|
|
|
area->end_address = cpu_addr_end_aligned; |
|
|
|
|
|
if (memory_tracker.IsRegionPreflushable(cpu_addr, size)) { |
|
|
|
|
|
area->preemtive = true; |
|
|
|
|
|
return area; |
|
|
|
|
|
}; |
|
|
|
|
|
memory_tracker.MarkRegionAsPreflushable(cpu_addr_start_aligned, cpu_addr_end_aligned - cpu_addr_start_aligned); |
|
|
|
|
|
area->preemtive = !IsRegionGpuModified(cpu_addr, size); |
|
|
|
|
|
return area; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <class P> |
|
|
template <class P> |
|
|
@ -191,8 +206,10 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am |
|
|
const VAddr new_base_address = *cpu_dest_address + diff; |
|
|
const VAddr new_base_address = *cpu_dest_address + diff; |
|
|
const IntervalType add_interval{new_base_address, new_base_address + size}; |
|
|
const IntervalType add_interval{new_base_address, new_base_address + size}; |
|
|
tmp_intervals.push_back(add_interval); |
|
|
tmp_intervals.push_back(add_interval); |
|
|
uncommitted_ranges.add(add_interval); |
|
|
|
|
|
pending_ranges.add(add_interval); |
|
|
|
|
|
|
|
|
if (memory_tracker.IsRegionPreflushable(new_base_address, new_base_address + size)) { |
|
|
|
|
|
uncommitted_ranges.add(add_interval); |
|
|
|
|
|
pending_ranges.add(add_interval); |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
ForEachInRangeSet(common_ranges, *cpu_src_address, amount, mirror); |
|
|
ForEachInRangeSet(common_ranges, *cpu_src_address, amount, mirror); |
|
|
// This subtraction in this order is important for overlapping copies. |
|
|
// This subtraction in this order is important for overlapping copies. |
|
|
@ -205,7 +222,7 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am |
|
|
if (has_new_downloads) { |
|
|
if (has_new_downloads) { |
|
|
memory_tracker.MarkRegionAsGpuModified(*cpu_dest_address, amount); |
|
|
memory_tracker.MarkRegionAsGpuModified(*cpu_dest_address, amount); |
|
|
} |
|
|
} |
|
|
std::vector<u8> tmp_buffer(amount); |
|
|
|
|
|
|
|
|
tmp_buffer.resize(amount); |
|
|
cpu_memory.ReadBlockUnsafe(*cpu_src_address, tmp_buffer.data(), amount); |
|
|
cpu_memory.ReadBlockUnsafe(*cpu_src_address, tmp_buffer.data(), amount); |
|
|
cpu_memory.WriteBlockUnsafe(*cpu_dest_address, tmp_buffer.data(), amount); |
|
|
cpu_memory.WriteBlockUnsafe(*cpu_dest_address, tmp_buffer.data(), amount); |
|
|
return true; |
|
|
return true; |
|
|
@ -441,9 +458,7 @@ void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_add |
|
|
|
|
|
|
|
|
template <class P> |
|
|
template <class P> |
|
|
void BufferCache<P>::FlushCachedWrites() { |
|
|
void BufferCache<P>::FlushCachedWrites() { |
|
|
cached_write_buffer_ids.clear(); |
|
|
|
|
|
memory_tracker.FlushCachedWrites(); |
|
|
memory_tracker.FlushCachedWrites(); |
|
|
cached_ranges.clear(); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <class P> |
|
|
template <class P> |
|
|
@ -1221,6 +1236,9 @@ void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s |
|
|
|
|
|
|
|
|
const IntervalType base_interval{cpu_addr, cpu_addr + size}; |
|
|
const IntervalType base_interval{cpu_addr, cpu_addr + size}; |
|
|
common_ranges.add(base_interval); |
|
|
common_ranges.add(base_interval); |
|
|
|
|
|
if (!memory_tracker.IsRegionPreflushable(cpu_addr, cpu_addr + size)) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
uncommitted_ranges.add(base_interval); |
|
|
uncommitted_ranges.add(base_interval); |
|
|
pending_ranges.add(base_interval); |
|
|
pending_ranges.add(base_interval); |
|
|
} |
|
|
} |
|
|
@ -1629,7 +1647,6 @@ void BufferCache<P>::DeleteBuffer(BufferId buffer_id, bool do_not_mark) { |
|
|
replace(transform_feedback_buffers); |
|
|
replace(transform_feedback_buffers); |
|
|
replace(compute_uniform_buffers); |
|
|
replace(compute_uniform_buffers); |
|
|
replace(compute_storage_buffers); |
|
|
replace(compute_storage_buffers); |
|
|
std::erase(cached_write_buffer_ids, buffer_id); |
|
|
|
|
|
|
|
|
|
|
|
// Mark the whole buffer as CPU written to stop tracking CPU writes |
|
|
// Mark the whole buffer as CPU written to stop tracking CPU writes |
|
|
if (!do_not_mark) { |
|
|
if (!do_not_mark) { |
|
|
|