Some tests

This commit is contained in:
Lander Gallastegi 2025-07-11 19:21:14 +02:00
parent cee22c45e8
commit a6cdf2eac7
2 changed files with 49 additions and 49 deletions

View File

@ -1034,53 +1034,58 @@ void BufferCache::SynchronizeBuffersInRange(VAddr device_addr, u64 size) {
void BufferCache::SynchronizeBuffersForDma() { void BufferCache::SynchronizeBuffersForDma() {
RENDERER_TRACE; RENDERER_TRACE;
boost::container::small_vector<Buffer*, 64> buffers;
boost::container::small_vector<vk::BufferCopy, 4> copies; boost::container::small_vector<vk::BufferCopy, 4> copies;
const auto& mapped_ranges = rasterizer.GetMappedRanges(); const auto& mapped_ranges = rasterizer.GetMappedRanges();
bool barrier_recorded = false; BufferId last_buffer_id = NULL_BUFFER_ID;
memory_tracker->Lock();
scheduler.EndRendering(); scheduler.EndRendering();
const auto cmdbuf = scheduler.CommandBuffer(); const auto cmdbuf = scheduler.CommandBuffer();
mapped_ranges.ForEach([&](VAddr device_addr, u64 size) { const auto upload_pending = [&]() {
ForEachBufferInRange(device_addr, size, [&](BufferId buffer_id, Buffer& buffer) { if (last_buffer_id == NULL_BUFFER_ID) {
memory_tracker->ForEachUploadRange<true, false>( return;
buffer.CpuAddr(), buffer.SizeBytes(), false, }
[&](u64 device_addr_out, u64 range_size) { Buffer& buffer = slot_buffers[last_buffer_id];
if (!barrier_recorded) { const vk::BufferMemoryBarrier2 barrier = {
barrier_recorded = true; .srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
const vk::BufferMemoryBarrier2 barrier = { .srcAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite |
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands, vk::AccessFlagBits2::eTransferRead |
.srcAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eTransferWrite,
vk::AccessFlagBits2::eMemoryWrite | .dstStageMask = vk::PipelineStageFlagBits2::eTransfer,
vk::AccessFlagBits2::eTransferRead | .dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
vk::AccessFlagBits2::eTransferWrite, .buffer = buffer.Handle(),
.dstStageMask = vk::PipelineStageFlagBits2::eTransfer, .offset = 0,
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite, .size = buffer.SizeBytes(),
.buffer = buffer.Handle(), };
.offset = 0, cmdbuf.pipelineBarrier2(vk::DependencyInfo{
.size = buffer.SizeBytes(), .dependencyFlags = vk::DependencyFlagBits::eByRegion,
}; .bufferMemoryBarrierCount = 1,
cmdbuf.pipelineBarrier2(vk::DependencyInfo{ .pBufferMemoryBarriers = &barrier,
.dependencyFlags = vk::DependencyFlagBits::eByRegion,
.bufferMemoryBarrierCount = 1,
.pBufferMemoryBarriers = &barrier,
});
}
const u64 offset = staging_buffer.Copy(device_addr_out, range_size);
copies.push_back(vk::BufferCopy{
.srcOffset = offset,
.dstOffset = device_addr_out - buffer.CpuAddr(),
.size = range_size,
});
});
cmdbuf.copyBuffer(staging_buffer.Handle(), buffer.Handle(), copies);
copies.clear();
barrier_recorded = false;
}); });
cmdbuf.copyBuffer(staging_buffer.Handle(), buffer.Handle(), copies);
copies.clear();
};
mapped_ranges.ForEach([&](VAddr device_addr, u64 size) {
memory_tracker->ForEachUploadRange(device_addr, size, false, [&](u64 device_addr_out, u64 range_size) {
ForEachBufferInRange(device_addr_out, range_size, [&](BufferId buffer_id, Buffer& buffer) {
if (last_buffer_id != buffer_id) {
upload_pending();
last_buffer_id = buffer_id;
}
const VAddr copy_start = std::max(buffer.CpuAddr(), device_addr_out);
const VAddr copy_end = std::min(buffer.CpuAddr() + buffer.SizeBytes(), device_addr_out + range_size);
const u32 copy_size = static_cast<u32>(copy_end - copy_start);
if (copy_size == 0) {
return;
}
const u64 offset = staging_buffer.Copy(copy_start, copy_size);
copies.push_back(vk::BufferCopy{
.srcOffset = offset,
.dstOffset = copy_start - buffer.CpuAddr(),
.size = copy_size,
});
});
}, upload_pending);
}); });
memory_tracker->PerformDeferredProtections<Type::CPU, false, false>();
MemoryBarrier(); MemoryBarrier();
memory_tracker->Unlock();
} }
void BufferCache::MemoryBarrier() { void BufferCache::MemoryBarrier() {

View File

@ -5,7 +5,6 @@
#include "common/config.h" #include "common/config.h"
#include "common/div_ceil.h" #include "common/div_ceil.h"
#include "common/logging/log.h"
#ifdef __linux__ #ifdef __linux__
#include "common/adaptive_mutex.h" #include "common/adaptive_mutex.h"
@ -90,7 +89,7 @@ public:
* @param dirty_addr Base address to mark or unmark as modified * @param dirty_addr Base address to mark or unmark as modified
* @param size Size in bytes to mark or unmark as modified * @param size Size in bytes to mark or unmark as modified
*/ */
template <Type type, bool enable, bool defer_protect> template <Type type, bool enable>
void ChangeRegionState(u64 dirty_addr, u64 size) noexcept(type == Type::GPU) { void ChangeRegionState(u64 dirty_addr, u64 size) noexcept(type == Type::GPU) {
RENDERER_TRACE; RENDERER_TRACE;
const size_t offset = dirty_addr - cpu_addr; const size_t offset = dirty_addr - cpu_addr;
@ -107,9 +106,7 @@ public:
} else { } else {
bits.UnsetRange(start_page, end_page); bits.UnsetRange(start_page, end_page);
} }
if constexpr (defer_protect) { if constexpr (type == Type::CPU) {
deferred_protection |= type;
} else if constexpr (type == Type::CPU) {
UpdateProtection<!enable, false>(); UpdateProtection<!enable, false>();
} else if (Config::readbacks()) { } else if (Config::readbacks()) {
UpdateProtection<enable, true>(); UpdateProtection<enable, true>();
@ -124,7 +121,7 @@ public:
* @param size Size in bytes of the CPU range to loop over * @param size Size in bytes of the CPU range to loop over
* @param func Function to call for each turned off region * @param func Function to call for each turned off region
*/ */
template <Type type, bool clear, bool defer_protect> template <Type type, bool clear>
void ForEachModifiedRange(VAddr query_cpu_range, s64 size, auto&& func) { void ForEachModifiedRange(VAddr query_cpu_range, s64 size, auto&& func) {
RENDERER_TRACE; RENDERER_TRACE;
const size_t offset = query_cpu_range - cpu_addr; const size_t offset = query_cpu_range - cpu_addr;
@ -140,9 +137,7 @@ public:
if constexpr (clear) { if constexpr (clear) {
bits.UnsetRange(start_page, end_page); bits.UnsetRange(start_page, end_page);
if constexpr (defer_protect) { if constexpr (type == Type::CPU) {
deferred_protection |= type;
} else if constexpr (type == Type::CPU) {
UpdateProtection<true, false>(); UpdateProtection<true, false>();
} else if (Config::readbacks()) { } else if (Config::readbacks()) {
UpdateProtection<false, true>(); UpdateProtection<false, true>();