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.