Skip to content

Commit

Permalink
tests: Allow fd posix handle testing on Windows
Browse files Browse the repository at this point in the history
Now we can run fd posix handle tests on Windows through MockICD.

Vulkan API for posix handles are defined in a cross platform way,
so it's possible to write related code without platform #ifdefs.
This change removes restriction in the test framework that
vk_testing::Fence/Semaphore supports posix handle only in non-Windows
environments.

If the test is built around ExternalHandle abstraction, then that
abstraction if moved to corresponding test suite.
artem-lunarg committed May 4, 2023
1 parent 1b5c9c9 commit 3e8236e
Showing 5 changed files with 98 additions and 98 deletions.
89 changes: 39 additions & 50 deletions tests/framework/binding.cpp
Original file line number Diff line number Diff line change
@@ -517,42 +517,38 @@ VkResult Fence::reset() {
return vk::ResetFences(device(), 1, &fence);
}

VkResult Fence::export_handle(Fence::ExternalHandle &ext_handle, VkExternalFenceHandleTypeFlagBits handle_type) {
#ifdef _WIN32
#ifdef VK_USE_PLATFORM_WIN32_KHR
VkResult Fence::export_handle(HANDLE &win32_handle, VkExternalFenceHandleTypeFlagBits handle_type) {
auto ghi = LvlInitStruct<VkFenceGetWin32HandleInfoKHR>();
ghi.fence = handle();
ghi.handleType = handle_type;
auto vkGetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR)vk::GetDeviceProcAddr(device(), "vkGetFenceWin32HandleKHR");
return vkGetFenceWin32HandleKHR(device(), &ghi, &ext_handle);
#else
auto gfi = LvlInitStruct<VkFenceGetFdInfoKHR>();
gfi.fence = handle();
gfi.handleType = handle_type;
auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vk::GetDeviceProcAddr(device(), "vkGetFenceFdKHR");
return vkGetFenceFdKHR(device(), &gfi, &ext_handle);
#endif
return vk::GetFenceWin32HandleKHR(device(), &ghi, &win32_handle);
}

VkResult Fence::import_handle(Fence::ExternalHandle ext_handle, VkExternalFenceHandleTypeFlagBits handle_type,
VkFenceImportFlags flags) {
#ifdef _WIN32
VkResult Fence::import_handle(HANDLE win32_handle, VkExternalFenceHandleTypeFlagBits handle_type, VkFenceImportFlags flags) {
auto ifi = LvlInitStruct<VkImportFenceWin32HandleInfoKHR>();
ifi.fence = handle();
ifi.handleType = handle_type;
ifi.handle = ext_handle;
ifi.handle = win32_handle;
ifi.flags = flags;
auto vkImportFenceWin32HandleKHR =
reinterpret_cast<PFN_vkImportFenceWin32HandleKHR>(vk::GetDeviceProcAddr(device(), "vkImportFenceWin32HandleKHR"));
return vkImportFenceWin32HandleKHR(device(), &ifi);
#else
return vk::ImportFenceWin32HandleKHR(device(), &ifi);
}
#endif // VK_USE_PLATFORM_WIN32_KHR

VkResult Fence::export_handle(int &fd_handle, VkExternalFenceHandleTypeFlagBits handle_type) {
auto gfi = LvlInitStruct<VkFenceGetFdInfoKHR>();
gfi.fence = handle();
gfi.handleType = handle_type;
return vk::GetFenceFdKHR(device(), &gfi, &fd_handle);
}

VkResult Fence::import_handle(int fd_handle, VkExternalFenceHandleTypeFlagBits handle_type, VkFenceImportFlags flags) {
auto ifi = LvlInitStruct<VkImportFenceFdInfoKHR>();
ifi.fence = handle();
ifi.handleType = handle_type;
ifi.fd = ext_handle;
ifi.fd = fd_handle;
ifi.flags = flags;
auto vkImportFenceFdKHR = reinterpret_cast<PFN_vkImportFenceFdKHR>(vk::GetDeviceProcAddr(device(), "vkImportFenceFdKHR"));
return vkImportFenceFdKHR(device(), &ifi);
#endif
return vk::ImportFenceFdKHR(device(), &ifi);
}

NON_DISPATCHABLE_HANDLE_DTOR(Semaphore, vk::DestroySemaphore)
@@ -561,49 +557,42 @@ void Semaphore::init(const Device &dev, const VkSemaphoreCreateInfo &info) {
NON_DISPATCHABLE_HANDLE_INIT(vk::CreateSemaphore, dev, &info);
}

VkResult Semaphore::export_handle(Semaphore::ExternalHandle &ext_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type) {
#ifdef _WIN32
ext_handle = nullptr;
#ifdef VK_USE_PLATFORM_WIN32_KHR
VkResult Semaphore::export_handle(HANDLE &win32_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type) {
win32_handle = nullptr;
auto ghi = LvlInitStruct<VkSemaphoreGetWin32HandleInfoKHR>();
ghi.semaphore = handle();
ghi.handleType = handle_type;
auto vkGetSemaphoreWin32HandleKHR =
reinterpret_cast<PFN_vkGetSemaphoreWin32HandleKHR>(vk::GetDeviceProcAddr(device(), "vkGetSemaphoreWin32HandleKHR"));
return vkGetSemaphoreWin32HandleKHR(device(), &ghi, &ext_handle);
#else
ext_handle = -1;
auto ghi = LvlInitStruct<VkSemaphoreGetFdInfoKHR>();
ghi.semaphore = handle();
ghi.handleType = handle_type;
auto vkGetSemaphoreFdKHR = reinterpret_cast<PFN_vkGetSemaphoreFdKHR>(vk::GetDeviceProcAddr(device(), "vkGetSemaphoreFdKHR"));
return vkGetSemaphoreFdKHR(device(), &ghi, &ext_handle);
#endif
return vk::GetSemaphoreWin32HandleKHR(device(), &ghi, &win32_handle);
}

VkResult Semaphore::import_handle(Semaphore::ExternalHandle ext_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type,
VkResult Semaphore::import_handle(HANDLE win32_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type,
VkSemaphoreImportFlags flags) {
#ifdef _WIN32
auto ihi = LvlInitStruct<VkImportSemaphoreWin32HandleInfoKHR>();
ihi.semaphore = handle();
ihi.handleType = handle_type;
ihi.handle = ext_handle;
ihi.handle = win32_handle;
ihi.flags = flags;
return vk::ImportSemaphoreWin32HandleKHR(device(), &ihi);
}
#endif // VK_USE_PLATFORM_WIN32_KHR

VkResult Semaphore::export_handle(int &fd_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type) {
fd_handle = -1;
auto ghi = LvlInitStruct<VkSemaphoreGetFdInfoKHR>();
ghi.semaphore = handle();
ghi.handleType = handle_type;
return vk::GetSemaphoreFdKHR(device(), &ghi, &fd_handle);
}

auto vkImportSemaphoreWin32HandleKHR =
reinterpret_cast<PFN_vkImportSemaphoreWin32HandleKHR>(vk::GetDeviceProcAddr(device(), "vkImportSemaphoreWin32HandleKHR"));
return vkImportSemaphoreWin32HandleKHR(device(), &ihi);
#else
VkResult Semaphore::import_handle(int fd_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type, VkSemaphoreImportFlags flags) {
// Import opaque handle exported above
auto ihi = LvlInitStruct<VkImportSemaphoreFdInfoKHR>();
ihi.semaphore = handle();
ihi.handleType = handle_type;
ihi.fd = ext_handle;
ihi.fd = fd_handle;
ihi.flags = flags;

auto vkImportSemaphoreFdKHR =
reinterpret_cast<PFN_vkImportSemaphoreFdKHR>(vk::GetDeviceProcAddr(device(), "vkImportSemaphoreFdKHR"));
return vkImportSemaphoreFdKHR(device(), &ihi);
#endif
return vk::ImportSemaphoreFdKHR(device(), &ihi);
}

NON_DISPATCHABLE_HANDLE_DTOR(Event, vk::DestroyEvent)
28 changes: 12 additions & 16 deletions tests/framework/binding.h
Original file line number Diff line number Diff line change
@@ -336,12 +336,6 @@ class DeviceMemory : public internal::NonDispHandle<VkDeviceMemory> {

class Fence : public internal::NonDispHandle<VkFence> {
public:
#ifdef _WIN32
using ExternalHandle = HANDLE;
#else
using ExternalHandle = int;
#endif

Fence() = default;
Fence(const Device &dev) { init(dev, create_info()); }
Fence(const Device &dev, const VkFenceCreateInfo &info) { init(dev, info); }
@@ -357,21 +351,19 @@ class Fence : public internal::NonDispHandle<VkFence> {

VkResult reset();

VkResult export_handle(ExternalHandle &handle, VkExternalFenceHandleTypeFlagBits handle_type);
VkResult import_handle(ExternalHandle handle, VkExternalFenceHandleTypeFlagBits handle_type, VkFenceImportFlags flags = 0);
#ifdef VK_USE_PLATFORM_WIN32_KHR
VkResult export_handle(HANDLE &win32_handle, VkExternalFenceHandleTypeFlagBits handle_type);
VkResult import_handle(HANDLE win32_handle, VkExternalFenceHandleTypeFlagBits handle_type, VkFenceImportFlags flags = 0);
#endif
VkResult export_handle(int &fd_handle, VkExternalFenceHandleTypeFlagBits handle_type);
VkResult import_handle(int fd_handle, VkExternalFenceHandleTypeFlagBits handle_type, VkFenceImportFlags flags = 0);

static VkFenceCreateInfo create_info(VkFenceCreateFlags flags);
static VkFenceCreateInfo create_info();
};

class Semaphore : public internal::NonDispHandle<VkSemaphore> {
public:
#ifdef _WIN32
using ExternalHandle = HANDLE;
#else
using ExternalHandle = int;
#endif

Semaphore() = default;
Semaphore(const Device &dev) { init(dev, LvlInitStruct<VkSemaphoreCreateInfo>()); }
Semaphore(const Device &dev, const VkSemaphoreCreateInfo &info) { init(dev, info); }
@@ -381,9 +373,13 @@ class Semaphore : public internal::NonDispHandle<VkSemaphore> {
// vkCreateSemaphore()
void init(const Device &dev, const VkSemaphoreCreateInfo &info);

VkResult export_handle(ExternalHandle &ext_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type);
VkResult import_handle(ExternalHandle ext_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type,
#ifdef VK_USE_PLATFORM_WIN32_KHR
VkResult export_handle(HANDLE &win32_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type);
VkResult import_handle(HANDLE win32_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type,
VkSemaphoreImportFlags flags = 0);
#endif
VkResult export_handle(int &fd_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type);
VkResult import_handle(int fd_handle, VkExternalSemaphoreHandleTypeFlagBits handle_type, VkSemaphoreImportFlags flags = 0);

static VkSemaphoreCreateInfo create_info(VkFlags flags);
};
41 changes: 24 additions & 17 deletions tests/negative/external_memory_sync.cpp
Original file line number Diff line number Diff line change
@@ -17,7 +17,14 @@
#include "../framework/layer_validation_tests.h"
#include "utils/vk_layer_utils.h"

class NegativeExternalMemorySync : public VkLayerTest {};
class NegativeExternalMemorySync : public VkLayerTest {
protected:
#ifdef VK_USE_PLATFORM_WIN32_KHR
using ExternalHandle = HANDLE;
#else
using ExternalHandle = int;
#endif
};

TEST_F(NegativeExternalMemorySync, CreateBufferIncompatibleHandleTypes) {
TEST_DESCRIPTION("Creating buffer with incompatible external memory handle types");
@@ -518,7 +525,7 @@ TEST_F(NegativeExternalMemorySync, TimelineSemaphore) {
stci.pNext = nullptr;
vk_testing::Semaphore import_semaphore(*m_device, sci);

vk_testing::Semaphore::ExternalHandle ext_handle{};
ExternalHandle ext_handle{};
err = export_semaphore.export_handle(ext_handle, handle_type);
ASSERT_VK_SUCCESS(err);

@@ -592,17 +599,17 @@ TEST_F(NegativeExternalMemorySync, SyncFdSemaphore) {
// Create a semaphore to import payload into
vk_testing::Semaphore import_semaphore(*m_device);

vk_testing::Semaphore::ExternalHandle ext_handle{};
int fd_handle = -1;

// timeline not allowed
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreGetFdInfoKHR-handleType-01132");
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreGetFdInfoKHR-handleType-03253");
timeline_sem.export_handle(ext_handle, handle_type);
timeline_sem.export_handle(fd_handle, handle_type);
m_errorMonitor->VerifyFound();

// must have pending signal
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreGetFdInfoKHR-handleType-03254");
binary_sem.export_handle(ext_handle, handle_type);
binary_sem.export_handle(fd_handle, handle_type);
m_errorMonitor->VerifyFound();

auto si = LvlInitStruct<VkSubmitInfo>();
@@ -612,15 +619,15 @@ TEST_F(NegativeExternalMemorySync, SyncFdSemaphore) {
err = vk::QueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
ASSERT_VK_SUCCESS(err);

err = binary_sem.export_handle(ext_handle, handle_type);
err = binary_sem.export_handle(fd_handle, handle_type);
ASSERT_VK_SUCCESS(err);

// must be temporary
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImportSemaphoreFdInfoKHR-handleType-07307");
import_semaphore.import_handle(ext_handle, handle_type);
import_semaphore.import_handle(fd_handle, handle_type);
m_errorMonitor->VerifyFound();

err = import_semaphore.import_handle(ext_handle, handle_type, VK_SEMAPHORE_IMPORT_TEMPORARY_BIT);
err = import_semaphore.import_handle(fd_handle, handle_type, VK_SEMAPHORE_IMPORT_TEMPORARY_BIT);
ASSERT_VK_SUCCESS(err);

err = vk::QueueWaitIdle(m_device->m_queue);
@@ -671,7 +678,7 @@ TEST_F(NegativeExternalMemorySync, TemporaryFence) {
vk_testing::Fence import_fence(*m_device, fci);

// Export fence payload to an opaque handle
vk_testing::Fence::ExternalHandle ext_fence{};
ExternalHandle ext_fence{};
err = export_fence.export_handle(ext_fence, handle_type);
ASSERT_VK_SUCCESS(err);
err = import_fence.import_handle(ext_fence, handle_type, VK_FENCE_IMPORT_TEMPORARY_BIT_KHR);
@@ -748,7 +755,7 @@ TEST_F(NegativeExternalMemorySync, Fence) {
fci.pNext = nullptr;
vk_testing::Fence import_fence(*m_device, fci);

vk_testing::Fence::ExternalHandle ext_handle{};
ExternalHandle ext_handle{};

// windows vs unix mismatch
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, bad_export_type_vuid);
@@ -827,23 +834,23 @@ TEST_F(NegativeExternalMemorySync, SyncFdFence) {
fci.pNext = nullptr;
vk_testing::Fence import_fence(*m_device, fci);

vk_testing::Fence::ExternalHandle ext_handle{};
int fd_handle = -1;

// SYNC_FD must have a pending signal for export
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkFenceGetFdInfoKHR-handleType-01454");
export_fence.export_handle(ext_handle, handle_type);
export_fence.export_handle(fd_handle, handle_type);
m_errorMonitor->VerifyFound();

vk::QueueSubmit(m_device->m_queue, 0, nullptr, export_fence.handle());

export_fence.export_handle(ext_handle, handle_type);
export_fence.export_handle(fd_handle, handle_type);

// must be temporary
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImportFenceFdInfoKHR-handleType-07306");
import_fence.import_handle(ext_handle, handle_type);
import_fence.import_handle(fd_handle, handle_type);
m_errorMonitor->VerifyFound();

import_fence.import_handle(ext_handle, handle_type, VK_FENCE_IMPORT_TEMPORARY_BIT);
import_fence.import_handle(fd_handle, handle_type, VK_FENCE_IMPORT_TEMPORARY_BIT);

import_fence.wait(1000000000);
}
@@ -897,7 +904,7 @@ TEST_F(NegativeExternalMemorySync, TemporarySemaphore) {
sci.pNext = nullptr;
vk_testing::Semaphore import_semaphore(*m_device, sci);

vk_testing::Semaphore::ExternalHandle ext_handle{};
ExternalHandle ext_handle{};
err = export_semaphore.export_handle(ext_handle, handle_type);
ASSERT_VK_SUCCESS(err);
err = import_semaphore.import_handle(ext_handle, handle_type, VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR);
@@ -997,7 +1004,7 @@ TEST_F(NegativeExternalMemorySync, Semaphore) {
// Create a semaphore for importing
vk_testing::Semaphore import_semaphore(*m_device);

vk_testing::Semaphore::ExternalHandle ext_handle{};
ExternalHandle ext_handle{};

// windows vs unix mismatch
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, bad_export_type_vuid);
3 changes: 0 additions & 3 deletions tests/positive/external_memory_sync.cpp
Original file line number Diff line number Diff line change
@@ -65,9 +65,6 @@ TEST_F(PositiveExternalMemorySync, ExternalMemory) {
if (!AreRequiredExtensionsEnabled()) {
GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
}
if (IsPlatform(kMockICD)) {
GTEST_SKIP() << "External tests are not supported by MockICD, skipping tests";
}
// Check for import/export capability
VkPhysicalDeviceExternalBufferInfoKHR ebi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR, nullptr, 0,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, handle_type};
Loading

0 comments on commit 3e8236e

Please sign in to comment.