Reland "Vulkan: Allow setting multiple `MemoryKind` bits"
This is a reland of commit a8f733807cbf72ebab8baecbda359ca4413d00c7
This patch no longer requires the support of DEVICE_LOCAL_BIT for
the buffer memory created from a host mapped pointer.
Original change's description:
> Vulkan: Allow setting multiple `MemoryKind` bits
>
> This patch allows setting multiple MemoryKind bits in one MemoryKind
> value and replaces MemoryKind::Opaque with MemoryKind::DeviceLocal as
> a preparation of the implementation of BufferMapExtendedUsage on
> Vulkan.
>
> Bug: 386255678
> Change-Id: I68f77de15d8267ae985d49f73497410fb08fbd49
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/227697
> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Bug: 386255678
Change-Id: I8acd518e05966b38db48879aacb9a7c029470016
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/229340
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn/native/vulkan/BufferVk.cpp b/src/dawn/native/vulkan/BufferVk.cpp
index c789fd3..fd27ea7 100644
--- a/src/dawn/native/vulkan/BufferVk.cpp
+++ b/src/dawn/native/vulkan/BufferVk.cpp
@@ -157,6 +157,28 @@
return flags;
}
+MemoryKind GetMemoryKindFor(wgpu::BufferUsage bufferUsage) {
+ MemoryKind requestKind = MemoryKind::Linear;
+ if (bufferUsage & wgpu::BufferUsage::MapRead) {
+ requestKind |= MemoryKind::ReadMappable;
+ }
+ if (bufferUsage & wgpu::BufferUsage::MapWrite) {
+ requestKind |= MemoryKind::WriteMappable;
+ }
+
+ // `kDeviceLocalBufferUsages` covers all the buffer usages that prefer the memory type
+ // `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`.
+ constexpr wgpu::BufferUsage kDeviceLocalBufferUsages =
+ wgpu::BufferUsage::Index | wgpu::BufferUsage::QueryResolve | wgpu::BufferUsage::Storage |
+ wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Vertex | kInternalStorageBuffer |
+ kReadOnlyStorageBuffer | kIndirectBufferForBackendResourceTracking;
+ if (bufferUsage & kDeviceLocalBufferUsages) {
+ requestKind |= MemoryKind::DeviceLocal;
+ }
+
+ return requestKind;
+}
+
} // namespace
// static
@@ -233,12 +255,7 @@
VkMemoryRequirements requirements;
device->fn.GetBufferMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);
- MemoryKind requestKind = MemoryKind::Linear;
- if (GetInternalUsage() & wgpu::BufferUsage::MapRead) {
- requestKind = MemoryKind::LinearReadMappable;
- } else if (GetInternalUsage() & wgpu::BufferUsage::MapWrite) {
- requestKind = MemoryKind::LinearWriteMappable;
- }
+ MemoryKind requestKind = GetMemoryKindFor(GetInternalUsage());
DAWN_TRY_ASSIGN(mMemoryAllocation,
device->GetResourceMemoryAllocator()->Allocate(requirements, requestKind));
@@ -330,15 +347,11 @@
requirements.memoryTypeBits &= hostPointerProperties.memoryTypeBits;
}
- MemoryKind requestKind;
- if (GetInternalUsage() & wgpu::BufferUsage::MapRead) {
- requestKind = MemoryKind::LinearReadMappable;
- } else if (GetInternalUsage() & wgpu::BufferUsage::MapWrite) {
- requestKind = MemoryKind::LinearWriteMappable;
- } else {
- requestKind = MemoryKind::Linear;
- }
-
+ // We can choose memory type with `requirements.memoryTypeBits` only because host-mapped memory
+ // - is CPU-visible
+ // - is device-local on UMA
+ // - cannot be non-device-local on non-UMA
+ MemoryKind requestKind = MemoryKind::Linear;
int memoryTypeIndex =
device->GetResourceMemoryAllocator()->FindBestTypeIndex(requirements, requestKind);
DAWN_INVALID_IF(memoryTypeIndex < 0, "Failed to find suitable memory type.");
diff --git a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
index d943e4a..ccf383b 100644
--- a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
+++ b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
@@ -54,19 +54,7 @@
constexpr uint64_t kBuddyHeapsSize = 2 * kMaxSizeForSubAllocation;
bool IsMemoryKindMappable(MemoryKind memoryKind) {
- switch (memoryKind) {
- case MemoryKind::LinearReadMappable:
- case MemoryKind::LinearWriteMappable:
- return true;
-
- case MemoryKind::LazilyAllocated:
- case MemoryKind::Linear:
- case MemoryKind::Opaque:
- return false;
-
- default:
- DAWN_UNREACHABLE();
- }
+ return memoryKind & (MemoryKind::ReadMappable | MemoryKind::WriteMappable);
}
} // anonymous namespace
@@ -307,6 +295,12 @@
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) {
+ continue;
+ }
+
// Found the first candidate memory type
if (bestType == -1) {
bestType = static_cast<int>(i);
@@ -347,7 +341,7 @@
info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
bool bestHostCached =
info.memoryTypes[bestType].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
- if (kind == MemoryKind::LinearReadMappable && currentHostCached != bestHostCached) {
+ if ((kind & MemoryKind::ReadMappable) && currentHostCached != bestHostCached) {
if (currentHostCached) {
bestType = static_cast<int>(i);
}
diff --git a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
index 22d4b53..0d9ac68 100644
--- a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
+++ b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
@@ -44,14 +44,14 @@
class Device;
struct VulkanDeviceInfo;
-// Various kinds of memory that influence the result of the allocation. For example, to take
-// into account mappability and Vulkan's bufferImageGranularity.
-enum class MemoryKind {
- LazilyAllocated,
- Linear,
- LinearReadMappable,
- LinearWriteMappable,
- Opaque,
+// Each bit of MemoryKind represents a kind of memory that influence the result of the allocation.
+// For example, to take into account mappability and Vulkan's bufferImageGranularity.
+enum class MemoryKind : uint8_t {
+ LazilyAllocated = 1,
+ Linear = 2,
+ DeviceLocal = 4,
+ ReadMappable = 8,
+ WriteMappable = 16,
};
bool SupportsBufferMapExtendedUsages(const VulkanDeviceInfo& deviceInfo);
@@ -83,4 +83,12 @@
} // namespace dawn::native::vulkan
+namespace wgpu {
+template <>
+struct IsWGPUBitmask<dawn::native::vulkan::MemoryKind> {
+ static constexpr bool enable = true;
+};
+
+} // namespace wgpu
+
#endif // SRC_DAWN_NATIVE_VULKAN_RESOURCEMEMORYALLOCATORVK_H_
diff --git a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
index 4bf68bd..67e2887 100644
--- a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
+++ b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
@@ -439,7 +439,7 @@
// import's constraint.
memoryRequirements.memoryTypeBits &= fdProperties.memoryTypeBits;
int memoryTypeIndex = device->GetResourceMemoryAllocator()->FindBestTypeIndex(
- memoryRequirements, MemoryKind::Opaque);
+ memoryRequirements, MemoryKind::DeviceLocal);
DAWN_INVALID_IF(memoryTypeIndex == -1, "Unable to find an appropriate memory type for import.");
SystemHandle memoryFD;
@@ -669,7 +669,7 @@
VkMemoryRequirements memoryRequirements;
memoryRequirements.memoryTypeBits = bufferProperties.memoryTypeBits;
int memoryTypeIndex = device->GetResourceMemoryAllocator()->FindBestTypeIndex(
- memoryRequirements, MemoryKind::Opaque);
+ memoryRequirements, MemoryKind::DeviceLocal);
DAWN_INVALID_IF(memoryTypeIndex == -1,
"Unable to find an appropriate memory type for import.");
diff --git a/src/dawn/native/vulkan/TextureVk.cpp b/src/dawn/native/vulkan/TextureVk.cpp
index 2cabce5..9861608 100644
--- a/src/dawn/native/vulkan/TextureVk.cpp
+++ b/src/dawn/native/vulkan/TextureVk.cpp
@@ -1382,7 +1382,7 @@
(GetInternalUsage() & (wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment));
auto memoryKind = (GetInternalUsage() & wgpu::TextureUsage::TransientAttachment)
? MemoryKind::LazilyAllocated
- : MemoryKind::Opaque;
+ : MemoryKind::DeviceLocal;
DAWN_TRY_ASSIGN(mMemoryAllocation, device->GetResourceMemoryAllocator()->Allocate(
requirements, memoryKind, forceDisableSubAllocation));
diff --git a/src/dawn/native/vulkan/external_memory/MemoryServiceImplementationDmaBuf.cpp b/src/dawn/native/vulkan/external_memory/MemoryServiceImplementationDmaBuf.cpp
index 9178027..d02ebe3 100644
--- a/src/dawn/native/vulkan/external_memory/MemoryServiceImplementationDmaBuf.cpp
+++ b/src/dawn/native/vulkan/external_memory/MemoryServiceImplementationDmaBuf.cpp
@@ -264,7 +264,7 @@
// import's constraint.
memoryRequirements.memoryTypeBits &= fdProperties.memoryTypeBits;
int memoryTypeIndex = mDevice->GetResourceMemoryAllocator()->FindBestTypeIndex(
- memoryRequirements, MemoryKind::Opaque);
+ memoryRequirements, MemoryKind::DeviceLocal);
DAWN_INVALID_IF(memoryTypeIndex == -1,
"Unable to find an appropriate memory type for import.");
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryTests_opaquefd.cpp b/src/dawn/tests/white_box/SharedTextureMemoryTests_opaquefd.cpp
index 407057c..71d313a 100644
--- a/src/dawn/tests/white_box/SharedTextureMemoryTests_opaquefd.cpp
+++ b/src/dawn/tests/white_box/SharedTextureMemoryTests_opaquefd.cpp
@@ -84,7 +84,7 @@
deviceVk->fn.GetImageMemoryRequirements(deviceVk->GetVkDevice(), vkImage, &requirements);
int bestType = deviceVk->GetResourceMemoryAllocator()->FindBestTypeIndex(
- requirements, native::vulkan::MemoryKind::Opaque);
+ requirements, native::vulkan::MemoryKind::DeviceLocal);
EXPECT_GE(bestType, 0);
VkMemoryDedicatedAllocateInfo dedicatedInfo;
diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp b/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
index cd16976..97042cc 100644
--- a/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
+++ b/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
@@ -230,7 +230,7 @@
deviceVk->fn.GetImageMemoryRequirements(deviceVk->GetVkDevice(), handle, &requirements);
int bestType = deviceVk->GetResourceMemoryAllocator()->FindBestTypeIndex(
- requirements, MemoryKind::Opaque);
+ requirements, MemoryKind::DeviceLocal);
VkMemoryAllocateInfo allocateInfo;
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;