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:
parent
786f76574a
commit
09c12ca696
|
@ -580,11 +580,19 @@ namespace dawn_native { namespace vulkan {
|
|||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,11 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
~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 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
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
|
||||
|
|
|
@ -19,12 +19,16 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
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
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
|
||||
Service::Service(Device* device) : mDevice(device) {
|
||||
DAWN_UNUSED(mDevice);
|
||||
DAWN_UNUSED(mSupportedFirstPass);
|
||||
DAWN_UNUSED(mSupported);
|
||||
}
|
||||
|
||||
Service::~Service() = default;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue