Validate shared semaphore and memory handles
Checks if we support specific handles and specific usages on the
current device. If we don't, Supported() fails and we stop the import.
Bug: chromium:976495
Change-Id: Icfe044a3c4d912913823728100888ab05f22afd5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10160
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Idan Raiter <idanr@google.com>
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index 354809f..128cfdd 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -580,11 +580,19 @@
VkSemaphore* outSignalSemaphore,
VkDeviceMemory* outAllocation,
std::vector<VkSemaphore>* outWaitSemaphores) {
+ const TextureDescriptor* textureDescriptor =
+ reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor);
+
// Check services support this combination of handle type / image info
if (!mExternalSemaphoreService->Supported()) {
return DAWN_VALIDATION_ERROR("External semaphore usage not supported");
}
- if (!mExternalMemoryService->Supported()) {
+ if (!mExternalMemoryService->Supported(
+ VulkanImageFormat(textureDescriptor->format), VK_IMAGE_TYPE_2D,
+ VK_IMAGE_TILING_OPTIMAL,
+ VulkanImageUsage(textureDescriptor->usage,
+ GetValidInternalFormat(textureDescriptor->format)),
+ VK_IMAGE_CREATE_ALIAS_BIT_KHR)) {
return DAWN_VALIDATION_ERROR("External memory usage not supported");
}
diff --git a/src/dawn_native/vulkan/external_memory/MemoryService.h b/src/dawn_native/vulkan/external_memory/MemoryService.h
index 8d27db6..e49d3ff 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryService.h
+++ b/src/dawn_native/vulkan/external_memory/MemoryService.h
@@ -31,7 +31,11 @@
~Service();
// True if the device reports it supports this feature
- bool Supported();
+ bool Supported(VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags);
// Given an external handle pointing to memory, import it into a VkDeviceMemory
ResultOrError<VkDeviceMemory> ImportMemory(ExternalMemoryHandle handle,
@@ -42,7 +46,7 @@
Device* mDevice = nullptr;
// True if early checks pass that determine if the service is supported
- bool mSupportedFirstPass = false;
+ bool mSupported = false;
};
}}} // namespace dawn_native::vulkan::external_memory
diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceNull.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceNull.cpp
index d10ddc7..7804ad3 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryServiceNull.cpp
+++ b/src/dawn_native/vulkan/external_memory/MemoryServiceNull.cpp
@@ -19,12 +19,16 @@
Service::Service(Device* device) : mDevice(device) {
DAWN_UNUSED(mDevice);
- DAWN_UNUSED(mSupportedFirstPass);
+ DAWN_UNUSED(mSupported);
}
Service::~Service() = default;
- bool Service::Supported() {
+ bool Service::Supported(VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags) {
return false;
}
diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
index e1f38db..d6e0e5a 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
+++ b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "dawn_native/vulkan/AdapterVk.h"
+#include "dawn_native/vulkan/BackendVk.h"
#include "dawn_native/vulkan/DeviceVk.h"
#include "dawn_native/vulkan/VulkanError.h"
#include "dawn_native/vulkan/external_memory/MemoryService.h"
@@ -19,17 +21,62 @@
namespace dawn_native { namespace vulkan { namespace external_memory {
Service::Service(Device* device) : mDevice(device) {
- const VulkanDeviceInfo& info = mDevice->GetDeviceInfo();
- mSupportedFirstPass = info.externalMemory && info.externalMemoryFD;
+ const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
+ const VulkanGlobalInfo& globalInfo =
+ ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
+
+ mSupported = globalInfo.getPhysicalDeviceProperties2 &&
+ globalInfo.externalMemoryCapabilities && deviceInfo.externalMemory &&
+ deviceInfo.externalMemoryFD;
}
Service::~Service() = default;
- bool Service::Supported() {
- // TODO(idanr): Query device here for additional support information, decide if supported
- // This will likely be done through vkGetPhysicalDeviceImageFormatProperties2KHR, where
- // we give it the intended image properties and handle type and see if it's supported
- return mSupportedFirstPass;
+ bool Service::Supported(VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags) {
+ // Early out before we try using extension functions
+ if (!mSupported) {
+ return false;
+ }
+
+ VkPhysicalDeviceExternalImageFormatInfo externalFormatInfo;
+ externalFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR;
+ externalFormatInfo.pNext = nullptr;
+ externalFormatInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ VkPhysicalDeviceImageFormatInfo2 formatInfo;
+ formatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR;
+ formatInfo.pNext = &externalFormatInfo;
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.tiling = tiling;
+ formatInfo.usage = usage;
+ formatInfo.flags = flags;
+
+ VkExternalImageFormatProperties externalFormatProperties;
+ externalFormatProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR;
+ externalFormatProperties.pNext = nullptr;
+
+ VkImageFormatProperties2 formatProperties;
+ formatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
+ formatProperties.pNext = &externalFormatProperties;
+
+ VkResult result = mDevice->fn.GetPhysicalDeviceImageFormatProperties2KHR(
+ ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &formatInfo, &formatProperties);
+
+ // If handle not supported, result == VK_ERROR_FORMAT_NOT_SUPPORTED
+ if (result != VK_SUCCESS) {
+ return false;
+ }
+
+ // TODO(http://crbug.com/dawn/206): Investigate dedicated only images
+ VkFlags memoryFlags =
+ externalFormatProperties.externalMemoryProperties.externalMemoryFeatures;
+ return (memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) &&
+ !(memoryFlags & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR);
}
ResultOrError<VkDeviceMemory> Service::ImportMemory(ExternalMemoryHandle handle,
diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreService.h b/src/dawn_native/vulkan/external_semaphore/SemaphoreService.h
index bfa72c4..cceaa2d 100644
--- a/src/dawn_native/vulkan/external_semaphore/SemaphoreService.h
+++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreService.h
@@ -46,7 +46,7 @@
Device* mDevice = nullptr;
// True if early checks pass that determine if the service is supported
- bool mSupportedFirstPass = false;
+ bool mSupported = false;
};
}}} // namespace dawn_native::vulkan::external_semaphore
diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceNull.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceNull.cpp
index e7fd859..aca4cb1 100644
--- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceNull.cpp
+++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceNull.cpp
@@ -19,7 +19,7 @@
Service::Service(Device* device) : mDevice(device) {
DAWN_UNUSED(mDevice);
- DAWN_UNUSED(mSupportedFirstPass);
+ DAWN_UNUSED(mSupported);
}
Service::~Service() = default;
diff --git a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp
index 7312142..ea7bf47 100644
--- a/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp
+++ b/src/dawn_native/vulkan/external_semaphore/SemaphoreServiceOpaqueFD.cpp
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "dawn_native/vulkan/AdapterVk.h"
+#include "dawn_native/vulkan/BackendVk.h"
#include "dawn_native/vulkan/DeviceVk.h"
#include "dawn_native/vulkan/VulkanError.h"
#include "dawn_native/vulkan/external_semaphore/SemaphoreService.h"
@@ -19,17 +21,43 @@
namespace dawn_native { namespace vulkan { namespace external_semaphore {
Service::Service(Device* device) : mDevice(device) {
- const VulkanDeviceInfo& info = mDevice->GetDeviceInfo();
- mSupportedFirstPass = info.externalSemaphore && info.externalSemaphoreFD;
- // TODO(idanr): Query device here for additional support information, decide if supported
- // This will likely be done through vkGetPhysicalDeviceExternalSemaphorePropertiesKHR, where
- // we give it the intended handle type and see if it's supported
+ const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
+ const VulkanGlobalInfo& globalInfo =
+ ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
+
+ mSupported = globalInfo.getPhysicalDeviceProperties2 &&
+ globalInfo.externalSemaphoreCapabilities && deviceInfo.externalSemaphore &&
+ deviceInfo.externalSemaphoreFD;
+
+ // Early out before we try using extension functions
+ if (!mSupported) {
+ return;
+ }
+
+ VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo;
+ semaphoreInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR;
+ semaphoreInfo.pNext = nullptr;
+ semaphoreInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ VkExternalSemaphorePropertiesKHR semaphoreProperties;
+ semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
+ semaphoreProperties.pNext = nullptr;
+
+ mDevice->fn.GetPhysicalDeviceExternalSemaphorePropertiesKHR(
+ ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo,
+ &semaphoreProperties);
+
+ VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
+ VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR;
+ mSupported =
+ mSupported &&
+ ((semaphoreProperties.externalSemaphoreFeatures & requiredFlags) == requiredFlags);
}
Service::~Service() = default;
bool Service::Supported() {
- return mSupportedFirstPass;
+ return mSupported;
}
ResultOrError<VkSemaphore> Service::ImportSemaphore(ExternalSemaphoreHandle handle) {