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>
This commit is contained in:
Idan Raiter 2019-08-16 17:58:44 +00:00 committed by Commit Bot service account
parent 786f76574a
commit 09c12ca696
7 changed files with 111 additions and 20 deletions

View File

@ -580,11 +580,19 @@ namespace dawn_native { namespace vulkan {
VkSemaphore* outSignalSemaphore, VkSemaphore* outSignalSemaphore,
VkDeviceMemory* outAllocation, VkDeviceMemory* outAllocation,
std::vector<VkSemaphore>* outWaitSemaphores) { std::vector<VkSemaphore>* outWaitSemaphores) {
const TextureDescriptor* textureDescriptor =
reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor);
// Check services support this combination of handle type / image info // Check services support this combination of handle type / image info
if (!mExternalSemaphoreService->Supported()) { if (!mExternalSemaphoreService->Supported()) {
return DAWN_VALIDATION_ERROR("External semaphore usage not 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"); return DAWN_VALIDATION_ERROR("External memory usage not supported");
} }

View File

@ -31,7 +31,11 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
~Service(); ~Service();
// True if the device reports it supports this feature // 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 // Given an external handle pointing to memory, import it into a VkDeviceMemory
ResultOrError<VkDeviceMemory> ImportMemory(ExternalMemoryHandle handle, ResultOrError<VkDeviceMemory> ImportMemory(ExternalMemoryHandle handle,
@ -42,7 +46,7 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
Device* mDevice = nullptr; Device* mDevice = nullptr;
// True if early checks pass that determine if the service is supported // True if early checks pass that determine if the service is supported
bool mSupportedFirstPass = false; bool mSupported = false;
}; };
}}} // namespace dawn_native::vulkan::external_memory }}} // namespace dawn_native::vulkan::external_memory

View File

@ -19,12 +19,16 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
Service::Service(Device* device) : mDevice(device) { Service::Service(Device* device) : mDevice(device) {
DAWN_UNUSED(mDevice); DAWN_UNUSED(mDevice);
DAWN_UNUSED(mSupportedFirstPass); DAWN_UNUSED(mSupported);
} }
Service::~Service() = default; Service::~Service() = default;
bool Service::Supported() { bool Service::Supported(VkFormat format,
VkImageType type,
VkImageTiling tiling,
VkImageUsageFlags usage,
VkImageCreateFlags flags) {
return false; return false;
} }

View File

@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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/DeviceVk.h"
#include "dawn_native/vulkan/VulkanError.h" #include "dawn_native/vulkan/VulkanError.h"
#include "dawn_native/vulkan/external_memory/MemoryService.h" #include "dawn_native/vulkan/external_memory/MemoryService.h"
@ -19,17 +21,62 @@
namespace dawn_native { namespace vulkan { namespace external_memory { namespace dawn_native { namespace vulkan { namespace external_memory {
Service::Service(Device* device) : mDevice(device) { Service::Service(Device* device) : mDevice(device) {
const VulkanDeviceInfo& info = mDevice->GetDeviceInfo(); const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
mSupportedFirstPass = info.externalMemory && info.externalMemoryFD; const VulkanGlobalInfo& globalInfo =
ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
mSupported = globalInfo.getPhysicalDeviceProperties2 &&
globalInfo.externalMemoryCapabilities && deviceInfo.externalMemory &&
deviceInfo.externalMemoryFD;
} }
Service::~Service() = default; Service::~Service() = default;
bool Service::Supported() { bool Service::Supported(VkFormat format,
// TODO(idanr): Query device here for additional support information, decide if supported VkImageType type,
// This will likely be done through vkGetPhysicalDeviceImageFormatProperties2KHR, where VkImageTiling tiling,
// we give it the intended image properties and handle type and see if it's supported VkImageUsageFlags usage,
return mSupportedFirstPass; 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, ResultOrError<VkDeviceMemory> Service::ImportMemory(ExternalMemoryHandle handle,

View File

@ -46,7 +46,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
Device* mDevice = nullptr; Device* mDevice = nullptr;
// True if early checks pass that determine if the service is supported // True if early checks pass that determine if the service is supported
bool mSupportedFirstPass = false; bool mSupported = false;
}; };
}}} // namespace dawn_native::vulkan::external_semaphore }}} // namespace dawn_native::vulkan::external_semaphore

View File

@ -19,7 +19,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
Service::Service(Device* device) : mDevice(device) { Service::Service(Device* device) : mDevice(device) {
DAWN_UNUSED(mDevice); DAWN_UNUSED(mDevice);
DAWN_UNUSED(mSupportedFirstPass); DAWN_UNUSED(mSupported);
} }
Service::~Service() = default; Service::~Service() = default;

View File

@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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/DeviceVk.h"
#include "dawn_native/vulkan/VulkanError.h" #include "dawn_native/vulkan/VulkanError.h"
#include "dawn_native/vulkan/external_semaphore/SemaphoreService.h" #include "dawn_native/vulkan/external_semaphore/SemaphoreService.h"
@ -19,17 +21,43 @@
namespace dawn_native { namespace vulkan { namespace external_semaphore { namespace dawn_native { namespace vulkan { namespace external_semaphore {
Service::Service(Device* device) : mDevice(device) { Service::Service(Device* device) : mDevice(device) {
const VulkanDeviceInfo& info = mDevice->GetDeviceInfo(); const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
mSupportedFirstPass = info.externalSemaphore && info.externalSemaphoreFD; const VulkanGlobalInfo& globalInfo =
// TODO(idanr): Query device here for additional support information, decide if supported ToBackend(mDevice->GetAdapter())->GetBackend()->GetGlobalInfo();
// This will likely be done through vkGetPhysicalDeviceExternalSemaphorePropertiesKHR, where
// we give it the intended handle type and see if it's supported 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; Service::~Service() = default;
bool Service::Supported() { bool Service::Supported() {
return mSupportedFirstPass; return mSupported;
} }
ResultOrError<VkSemaphore> Service::ImportSemaphore(ExternalSemaphoreHandle handle) { ResultOrError<VkSemaphore> Service::ImportSemaphore(ExternalSemaphoreHandle handle) {