diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index a33d0bb1db..e331bac70f 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -359,6 +359,18 @@ auto BufferCache

::TryObtainWindowBufferGpu(GPUVAddr gpu_addr, u32 size, u64 a return TryObtainWindowBuffer(*device_addr, size, alignment, post_op); } +template +void BufferCache

::MarkGpuWrittenRange(DAddr device_addr, u32 size) { + if (size == 0) { + return; + } + const BufferId buffer_id = FindBuffer(device_addr, size); + if (buffer_id == NULL_BUFFER_ID) { + return; + } + MarkWrittenBuffer(buffer_id, device_addr, size); +} + template std::pair BufferCache

::ObtainBuffer(GPUVAddr gpu_addr, u32 size, ObtainBufferSynchronize sync_info, @@ -2311,6 +2323,9 @@ bool BufferCache

::TryUnifiedUploadMemory([[maybe_unused]] Buffer& buffer, if (Settings::values.enable_gpu_buffer_readback.GetValue()) { return false; } + if (!runtime.SupportsUnifiedUploads()) { + return false; + } boost::container::small_vector window_ids; UnifiedWindowGroups groups; for (const BufferCopy& copy : copies) { diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 5225bfea56..90e33b8aa9 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -286,6 +286,8 @@ public: [[nodiscard]] std::optional TryObtainWindowBufferGpu( GPUVAddr gpu_addr, u32 size, u64 alignment, ObtainBufferOperation post_op); + void MarkGpuWrittenRange(DAddr device_addr, u32 size); + [[nodiscard]] std::pair ObtainBuffer(GPUVAddr gpu_addr, u32 size, ObtainBufferSynchronize sync_info, ObtainBufferOperation post_op); diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 15658380bc..38cf48158a 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -124,6 +124,10 @@ public: return unified_memory != nullptr && unified_memory->SupportsDirectDescriptors(); } + [[nodiscard]] bool SupportsUnifiedUploads() const noexcept { + return unified_memory != nullptr && unified_memory->IsHardwareBufferBacked(); + } + [[nodiscard]] VkBuffer UnifiedWindowBuffer(size_t window_index) const noexcept { if (!unified_memory || window_index >= unified_memory->GetWindowCount()) { return VK_NULL_HANDLE; diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 9c52d25a0f..d889eb3e0f 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp @@ -1663,6 +1663,10 @@ void QueryCacheRuntime::SyncValues(std::span values, VkBuffer ba pair.first, static_cast(pair.second - pair.first), sync_info, post_op); impl->buffers_to_upload_to.emplace_back(buffer->Handle(), offset); } + for (const auto& sync_val : values) { + impl->buffer_cache.MarkGpuWrittenRange(sync_val.address, + static_cast(sync_val.size)); + } }); VkBuffer src_buffer; diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 56fdcf5653..014a48c7ad 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -564,6 +564,7 @@ namespace Vulkan { return false; } foreign_ownership = true; + hardware_buffer_backed = true; return true; #else return false; diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index 020531c359..6e5b873d2d 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h @@ -134,6 +134,10 @@ namespace Vulkan { return direct_addresses; } + [[nodiscard]] bool IsHardwareBufferBacked() const noexcept { + return hardware_buffer_backed; + } + [[nodiscard]] VkDeviceAddress GetWindowAddress(size_t index) const noexcept { return windows[index].address; } @@ -171,6 +175,7 @@ namespace Vulkan { bool foreign_ownership{}; bool direct_descriptors{}; bool direct_addresses{}; + bool hardware_buffer_backed{}; }; /// Memory allocator container.