Vulkan: Enable feature `BufferMapExtendedUsages` on specific memory types
This patch enables feature `BufferMapExtendedUsages` on the devices that
support below memory types, which means such devices support the memory
type that is CPU visible and can be efficiently accessed by GPU:
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT
Bug: 386255678
Test: dawn_end2end_tests
Change-Id: I03224cd7f4a0f6f28d5892dd26e04f06d34b7579
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/220518
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/dawn/native/vulkan/BufferVk.cpp b/src/dawn/native/vulkan/BufferVk.cpp
index fd27ea7..e5b2a03 100644
--- a/src/dawn/native/vulkan/BufferVk.cpp
+++ b/src/dawn/native/vulkan/BufferVk.cpp
@@ -174,6 +174,11 @@
kReadOnlyStorageBuffer | kIndirectBufferForBackendResourceTracking;
if (bufferUsage & kDeviceLocalBufferUsages) {
requestKind |= MemoryKind::DeviceLocal;
+ // All mappable buffers with extended buffer usages should be allocated on the memory type
+ // with `VK_MEMORY_PROPERTY_HOST_CACHED_BIT`.
+ if (bufferUsage & (wgpu::BufferUsage::MapRead | wgpu::BufferUsage::MapWrite)) {
+ requestKind |= MemoryKind::HostCached;
+ }
}
return requestKind;
@@ -734,9 +739,6 @@
size_t originalBufferCount = buffers.size();
for (const Ref<Buffer>& buffer : buffers) {
wgpu::BufferUsage mapUsage = buffer->GetInternalUsage() & kMappableBufferUsages;
- DAWN_ASSERT(mapUsage == wgpu::BufferUsage::MapRead ||
- mapUsage == wgpu::BufferUsage::MapWrite);
-
buffer->TrackUsageAndGetResourceBarrier(recordingContext, mapUsage,
wgpu::ShaderStage::None);
}
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 798c15c..307d10e 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -40,6 +40,7 @@
#include "dawn/native/Limits.h"
#include "dawn/native/vulkan/BackendVk.h"
#include "dawn/native/vulkan/DeviceVk.h"
+#include "dawn/native/vulkan/ResourceMemoryAllocatorVk.h"
#include "dawn/native/vulkan/SwapChainVk.h"
#include "dawn/native/vulkan/TextureVk.h"
#include "dawn/native/vulkan/UtilsVulkan.h"
@@ -470,6 +471,10 @@
EnableFeature(Feature::SharedTextureMemoryOpaqueFD);
}
+ if (SupportsBufferMapExtendedUsages(mDeviceInfo)) {
+ EnableFeature(Feature::BufferMapExtendedUsages);
+ }
+
#if DAWN_PLATFORM_IS(ANDROID)
if (mDeviceInfo.HasExt(DeviceExt::ExternalMemoryAndroidHardwareBuffer)) {
if (GetOrLoadAHBFunctions()->IsValid()) {
diff --git a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
index ccf383b..c7d4617 100644
--- a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
+++ b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
@@ -57,6 +57,28 @@
return memoryKind & (MemoryKind::ReadMappable | MemoryKind::WriteMappable);
}
+VkMemoryPropertyFlags GetRequiredMemoryPropertyFlags(MemoryKind memoryKind, bool mappable) {
+ VkMemoryPropertyFlags vkFlags = 0;
+
+ // Mappable resource must be host visible and host coherent.
+ if (mappable) {
+ vkFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ vkFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+ }
+
+ // DEVICE_LOCAL_BIT must be set when MemoryKind::DeviceLocal is required.
+ if (memoryKind & MemoryKind::DeviceLocal) {
+ vkFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ }
+
+ // HOST_CACHED_BIT must be set when MemoryKind::HostCached is required.
+ if (memoryKind & MemoryKind::HostCached) {
+ vkFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
+ }
+
+ return vkFlags;
+}
+
} // anonymous namespace
bool SupportsBufferMapExtendedUsages(const VulkanDeviceInfo& deviceInfo) {
@@ -274,6 +296,7 @@
int ResourceMemoryAllocator::FindBestTypeIndex(VkMemoryRequirements requirements, MemoryKind kind) {
const VulkanDeviceInfo& info = mDevice->GetDeviceInfo();
bool mappable = IsMemoryKindMappable(kind);
+ VkMemoryPropertyFlags vkRequiredFlags = GetRequiredMemoryPropertyFlags(kind, mappable);
// Find a suitable memory type for this allocation
int bestType = -1;
@@ -283,21 +306,8 @@
continue;
}
- // Mappable resource must be host visible
- if (mappable &&
- (info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
- continue;
- }
-
- // Mappable must also be host coherent.
- if (mappable &&
- (info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) {
- continue;
- }
-
- // DEVICE_LOCAL_BIT must be set when MemoryKind::DeviceLocal is required.
- if ((kind & MemoryKind::DeviceLocal) &&
- (info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0) {
+ // Memory type must have all the required memory properties.
+ if ((info.memoryTypes[i].propertyFlags & vkRequiredFlags) != vkRequiredFlags) {
continue;
}
diff --git a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
index 0d9ac68..d166fd1 100644
--- a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
+++ b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
@@ -52,6 +52,7 @@
DeviceLocal = 4,
ReadMappable = 8,
WriteMappable = 16,
+ HostCached = 32,
};
bool SupportsBufferMapExtendedUsages(const VulkanDeviceInfo& deviceInfo);