mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 21:19:47 +00:00
[TEST] Unified uploads path
This commit is contained in:
@@ -705,7 +705,7 @@ public:
|
||||
if (get_native_handle == nullptr) {
|
||||
return false;
|
||||
}
|
||||
constexpr size_t window_size = 512ULL << 20;
|
||||
constexpr size_t window_size = 256ULL << 20;
|
||||
const AHardwareBuffer_Desc window_desc = MakeBlobDesc(window_size);
|
||||
if (AHardwareBuffer_isSupported(&window_desc) == 0) {
|
||||
return false;
|
||||
|
||||
@@ -1741,6 +1741,9 @@ bool BufferCache<P>::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 si
|
||||
template <class P>
|
||||
void BufferCache<P>::UploadMemory(Buffer& buffer, u64 total_size_bytes, u64 largest_copy,
|
||||
std::span<BufferCopy> copies) {
|
||||
if (TryUnifiedUploadMemory(buffer, copies)) {
|
||||
return;
|
||||
}
|
||||
if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) {
|
||||
MappedUploadMemory(buffer, total_size_bytes, copies);
|
||||
} else {
|
||||
@@ -1869,6 +1872,34 @@ bool BufferCache<P>::TryUnifiedDownloadMemory([[maybe_unused]] Buffer& buffer,
|
||||
}
|
||||
}
|
||||
|
||||
template <class P>
|
||||
bool BufferCache<P>::TryUnifiedUploadMemory([[maybe_unused]] Buffer& buffer,
|
||||
[[maybe_unused]] std::span<BufferCopy> copies) {
|
||||
if constexpr (USE_UNIFIED_UPLOADS) {
|
||||
if (Settings::values.enable_gpu_buffer_readback.GetValue()) {
|
||||
return false;
|
||||
}
|
||||
boost::container::small_vector<u64, 4> window_ids;
|
||||
UnifiedWindowGroups groups;
|
||||
for (const BufferCopy& copy : copies) {
|
||||
if (!ResolveUnifiedWindows(buffer.CpuAddr() + copy.dst_offset, copy.dst_offset,
|
||||
copy.size, window_ids, groups)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
runtime.UnifiedMemoryUploadBarrier();
|
||||
runtime.PreCopyBarrier();
|
||||
for (size_t i = 0; i < window_ids.size(); ++i) {
|
||||
const std::span<const BufferCopy> group_span(groups[i].data(), groups[i].size());
|
||||
runtime.CopyFromUnifiedMemory(window_ids[i], buffer, group_span);
|
||||
}
|
||||
runtime.PostCopyBarrier();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <class P>
|
||||
void BufferCache<P>::MappedUploadMemory([[maybe_unused]] Buffer& buffer,
|
||||
[[maybe_unused]] u64 total_size_bytes,
|
||||
|
||||
@@ -181,6 +181,7 @@ class BufferCache : public VideoCommon::ChannelSetupCaches<BufferCacheChannelInf
|
||||
static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS;
|
||||
static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = P::USE_MEMORY_MAPS_FOR_UPLOADS;
|
||||
static constexpr bool USE_UNIFIED_MEMORY = P::USE_UNIFIED_MEMORY;
|
||||
static constexpr bool USE_UNIFIED_UPLOADS = P::USE_UNIFIED_UPLOADS;
|
||||
|
||||
#ifdef YUZU_LEGACY
|
||||
static constexpr s64 TARGET_THRESHOLD = 3_GiB;
|
||||
@@ -446,6 +447,8 @@ private:
|
||||
|
||||
bool TryUnifiedDownloadMemory(Buffer& buffer, std::span<BufferCopy> copies);
|
||||
|
||||
bool TryUnifiedUploadMemory(Buffer& buffer, std::span<BufferCopy> copies);
|
||||
|
||||
using UnifiedWindowGroups =
|
||||
boost::container::small_vector<boost::container::small_vector<BufferCopy, 16>, 4>;
|
||||
|
||||
|
||||
@@ -262,6 +262,7 @@ struct BufferCacheParams {
|
||||
// TODO: Investigate why OpenGL seems to perform worse with persistently mapped buffer uploads
|
||||
static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = false;
|
||||
static constexpr bool USE_UNIFIED_MEMORY = false;
|
||||
static constexpr bool USE_UNIFIED_UPLOADS = false;
|
||||
};
|
||||
|
||||
using BufferCache = VideoCommon::BufferCache<BufferCacheParams>;
|
||||
|
||||
@@ -32,6 +32,14 @@ VkBufferCopy MakeBufferCopy(const VideoCommon::BufferCopy& copy) {
|
||||
};
|
||||
}
|
||||
|
||||
VkBufferCopy MakeUnifiedUploadCopy(const VideoCommon::BufferCopy& copy) {
|
||||
return VkBufferCopy{
|
||||
.srcOffset = copy.dst_offset,
|
||||
.dstOffset = copy.src_offset,
|
||||
.size = copy.size,
|
||||
};
|
||||
}
|
||||
|
||||
VkIndexType IndexTypeFromNumElements(const Device& device, u32 num_elements) {
|
||||
if (num_elements <= 0xff && device.IsExtIndexTypeUint8Supported()) {
|
||||
return VK_INDEX_TYPE_UINT8_EXT;
|
||||
@@ -438,6 +446,82 @@ void BufferCacheRuntime::CopyToUnifiedMemory(
|
||||
});
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::CopyFromUnifiedMemory(
|
||||
size_t window_index, VkBuffer dst_buffer,
|
||||
std::span<const VideoCommon::BufferCopy> copies) {
|
||||
if (!unified_memory || dst_buffer == VK_NULL_HANDLE || copies.empty() ||
|
||||
window_index >= unified_memory->GetWindowCount()) {
|
||||
return;
|
||||
}
|
||||
const VkBuffer src_buffer = unified_memory->GetWindowBuffer(window_index);
|
||||
if (src_buffer == VK_NULL_HANDLE) {
|
||||
return;
|
||||
}
|
||||
VkDeviceSize covered_begin = std::numeric_limits<VkDeviceSize>::max();
|
||||
VkDeviceSize covered_end = 0;
|
||||
for (const VideoCommon::BufferCopy& copy : copies) {
|
||||
covered_begin = (std::min)(covered_begin, static_cast<VkDeviceSize>(copy.dst_offset));
|
||||
covered_end = (std::max)(covered_end,
|
||||
static_cast<VkDeviceSize>(copy.dst_offset + copy.size));
|
||||
}
|
||||
|
||||
boost::container::small_vector<VkBufferCopy, 8> vk_copies(copies.size());
|
||||
std::ranges::transform(copies, vk_copies.begin(), MakeUnifiedUploadCopy);
|
||||
|
||||
const bool foreign = unified_memory->NeedsForeignOwnershipTransfer();
|
||||
const u32 queue_family = device.GetGraphicsFamily();
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([src_buffer, dst_buffer, vk_copies, foreign, queue_family, covered_begin,
|
||||
covered_end](vk::CommandBuffer cmdbuf) {
|
||||
if (foreign) {
|
||||
const VkBufferMemoryBarrier acquire{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
|
||||
.dstQueueFamilyIndex = queue_family,
|
||||
.buffer = src_buffer,
|
||||
.offset = covered_begin,
|
||||
.size = covered_end - covered_begin,
|
||||
};
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, acquire);
|
||||
}
|
||||
cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies));
|
||||
if (foreign) {
|
||||
const VkBufferMemoryBarrier release{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.dstAccessMask = 0,
|
||||
.srcQueueFamilyIndex = queue_family,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
|
||||
.buffer = src_buffer,
|
||||
.offset = covered_begin,
|
||||
.size = covered_end - covered_begin,
|
||||
};
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, release);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::UnifiedMemoryUploadBarrier() {
|
||||
static constexpr VkMemoryBarrier HOST_WRITE_BARRIER{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
||||
};
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
HOST_WRITE_BARRIER);
|
||||
});
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::UnifiedMemoryHostBarrier() {
|
||||
static constexpr VkMemoryBarrier HOST_BARRIER{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
|
||||
@@ -122,8 +122,13 @@ public:
|
||||
void CopyToUnifiedMemory(size_t window_index, VkBuffer src_buffer,
|
||||
std::span<const VideoCommon::BufferCopy> copies);
|
||||
|
||||
void CopyFromUnifiedMemory(size_t window_index, VkBuffer dst_buffer,
|
||||
std::span<const VideoCommon::BufferCopy> copies);
|
||||
|
||||
void UnifiedMemoryHostBarrier();
|
||||
|
||||
void UnifiedMemoryUploadBarrier();
|
||||
|
||||
u64 CurrentTick();
|
||||
|
||||
u64 KnownGpuTick();
|
||||
@@ -255,6 +260,7 @@ struct BufferCacheParams {
|
||||
static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = false;
|
||||
static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = true;
|
||||
static constexpr bool USE_UNIFIED_MEMORY = true;
|
||||
static constexpr bool USE_UNIFIED_UPLOADS = true;
|
||||
};
|
||||
|
||||
using BufferCache = VideoCommon::BufferCache<BufferCacheParams>;
|
||||
|
||||
Reference in New Issue
Block a user