mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 04:35:56 +00:00
buffer_cache: Move buffer barriers and copy outside of lock range
This commit is contained in:
parent
4abffb2489
commit
faee44a820
2 changed files with 43 additions and 35 deletions
|
@ -818,48 +818,22 @@ void BufferCache::SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size,
|
||||||
boost::container::small_vector<vk::BufferCopy, 4> copies;
|
boost::container::small_vector<vk::BufferCopy, 4> copies;
|
||||||
size_t total_size_bytes = 0;
|
size_t total_size_bytes = 0;
|
||||||
VAddr buffer_start = buffer.CpuAddr();
|
VAddr buffer_start = buffer.CpuAddr();
|
||||||
|
vk::Buffer src_buffer = VK_NULL_HANDLE;
|
||||||
memory_tracker->ForEachUploadRange(
|
memory_tracker->ForEachUploadRange(
|
||||||
device_addr, size, is_written,
|
device_addr, size, is_written,
|
||||||
[&](u64 device_addr_out, u64 range_size) {
|
[&](u64 device_addr_out, u64 range_size) {
|
||||||
copies.emplace_back(total_size_bytes, device_addr_out - buffer_start, range_size);
|
copies.emplace_back(total_size_bytes, device_addr_out - buffer_start, range_size);
|
||||||
total_size_bytes += range_size;
|
total_size_bytes += range_size;
|
||||||
},
|
},
|
||||||
[&] { UploadCopies(buffer, copies, total_size_bytes); });
|
[&] { src_buffer = UploadCopies(buffer, copies, total_size_bytes); });
|
||||||
if (is_texel_buffer) {
|
SCOPE_EXIT {
|
||||||
SynchronizeBufferFromImage(buffer, device_addr, size);
|
if (is_texel_buffer) {
|
||||||
}
|
SynchronizeBufferFromImage(buffer, device_addr, size);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
void BufferCache::UploadCopies(Buffer& buffer, std::span<vk::BufferCopy> copies,
|
if (!src_buffer) {
|
||||||
size_t total_size_bytes) {
|
|
||||||
if (copies.empty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vk::Buffer src_buffer = staging_buffer.Handle();
|
|
||||||
const auto [staging, offset] = staging_buffer.Map(total_size_bytes);
|
|
||||||
if (staging) {
|
|
||||||
for (auto& copy : copies) {
|
|
||||||
u8* const src_pointer = staging + copy.srcOffset;
|
|
||||||
const VAddr device_addr = buffer.CpuAddr() + copy.dstOffset;
|
|
||||||
std::memcpy(src_pointer, std::bit_cast<const u8*>(device_addr), copy.size);
|
|
||||||
// Apply the staging offset
|
|
||||||
copy.srcOffset += offset;
|
|
||||||
}
|
|
||||||
staging_buffer.Commit();
|
|
||||||
} else {
|
|
||||||
// For large one time transfers use a temporary host buffer.
|
|
||||||
auto temp_buffer =
|
|
||||||
std::make_unique<Buffer>(instance, scheduler, MemoryUsage::Upload, 0,
|
|
||||||
vk::BufferUsageFlagBits::eTransferSrc, total_size_bytes);
|
|
||||||
src_buffer = temp_buffer->Handle();
|
|
||||||
u8* const staging = temp_buffer->mapped_data.data();
|
|
||||||
for (const auto& copy : copies) {
|
|
||||||
u8* const src_pointer = staging + copy.srcOffset;
|
|
||||||
const VAddr device_addr = buffer.CpuAddr() + copy.dstOffset;
|
|
||||||
std::memcpy(src_pointer, std::bit_cast<const u8*>(device_addr), copy.size);
|
|
||||||
}
|
|
||||||
scheduler.DeferOperation([buffer = std::move(temp_buffer)]() mutable { buffer.reset(); });
|
|
||||||
}
|
|
||||||
scheduler.EndRendering();
|
scheduler.EndRendering();
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
const vk::BufferMemoryBarrier2 pre_barrier = {
|
const vk::BufferMemoryBarrier2 pre_barrier = {
|
||||||
|
@ -894,6 +868,39 @@ void BufferCache::UploadCopies(Buffer& buffer, std::span<vk::BufferCopy> copies,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vk::Buffer BufferCache::UploadCopies(Buffer& buffer, std::span<vk::BufferCopy> copies,
|
||||||
|
size_t total_size_bytes) {
|
||||||
|
if (copies.empty()) {
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
const auto [staging, offset] = staging_buffer.Map(total_size_bytes);
|
||||||
|
if (staging) {
|
||||||
|
for (auto& copy : copies) {
|
||||||
|
u8* const src_pointer = staging + copy.srcOffset;
|
||||||
|
const VAddr device_addr = buffer.CpuAddr() + copy.dstOffset;
|
||||||
|
std::memcpy(src_pointer, std::bit_cast<const u8*>(device_addr), copy.size);
|
||||||
|
// Apply the staging offset
|
||||||
|
copy.srcOffset += offset;
|
||||||
|
}
|
||||||
|
staging_buffer.Commit();
|
||||||
|
return staging_buffer.Handle();
|
||||||
|
} else {
|
||||||
|
// For large one time transfers use a temporary host buffer.
|
||||||
|
auto temp_buffer =
|
||||||
|
std::make_unique<Buffer>(instance, scheduler, MemoryUsage::Upload, 0,
|
||||||
|
vk::BufferUsageFlagBits::eTransferSrc, total_size_bytes);
|
||||||
|
const vk::Buffer src_buffer = temp_buffer->Handle();
|
||||||
|
u8* const staging = temp_buffer->mapped_data.data();
|
||||||
|
for (const auto& copy : copies) {
|
||||||
|
u8* const src_pointer = staging + copy.srcOffset;
|
||||||
|
const VAddr device_addr = buffer.CpuAddr() + copy.dstOffset;
|
||||||
|
std::memcpy(src_pointer, std::bit_cast<const u8*>(device_addr), copy.size);
|
||||||
|
}
|
||||||
|
scheduler.DeferOperation([buffer = std::move(temp_buffer)]() mutable { buffer.reset(); });
|
||||||
|
return src_buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, u32 size) {
|
bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, u32 size) {
|
||||||
boost::container::small_vector<ImageId, 6> image_ids;
|
boost::container::small_vector<ImageId, 6> image_ids;
|
||||||
texture_cache.ForEachImageInRegion(device_addr, size, [&](ImageId image_id, Image& image) {
|
texture_cache.ForEachImageInRegion(device_addr, size, [&](ImageId image_id, Image& image) {
|
||||||
|
|
|
@ -194,7 +194,8 @@ private:
|
||||||
void SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size, bool is_written,
|
void SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size, bool is_written,
|
||||||
bool is_texel_buffer);
|
bool is_texel_buffer);
|
||||||
|
|
||||||
void UploadCopies(Buffer& buffer, std::span<vk::BufferCopy> copies, size_t total_size_bytes);
|
vk::Buffer UploadCopies(Buffer& buffer, std::span<vk::BufferCopy> copies,
|
||||||
|
size_t total_size_bytes);
|
||||||
|
|
||||||
bool SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, u32 size);
|
bool SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, u32 size);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue