Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import OpenCL exported semaphore in Vulkan #1898

Merged
merged 5 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 96 additions & 10 deletions test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,26 +508,35 @@ cl_int check_external_memory_handle_type(

cl_int check_external_semaphore_handle_type(
cl_device_id deviceID,
cl_external_semaphore_handle_type_khr requiredHandleType)
cl_external_semaphore_handle_type_khr requiredHandleType,
cl_device_info queryParamName)
{
unsigned int i;
cl_external_semaphore_handle_type_khr *handle_type;
size_t handle_type_size = 0;
cl_int errNum = CL_SUCCESS;

errNum =
clGetDeviceInfo(deviceID, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,
0, NULL, &handle_type_size);
clGetDeviceInfo(deviceID, queryParamName, 0, NULL, &handle_type_size);

if (handle_type_size == 0)
{
log_error("Device does not support %s semaphore\n",
queryParamName == CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR
? "importing"
: "exporting");
return CL_INVALID_VALUE;
}

handle_type =
(cl_external_semaphore_handle_type_khr *)malloc(handle_type_size);

errNum =
clGetDeviceInfo(deviceID, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,
handle_type_size, handle_type, NULL);
errNum = clGetDeviceInfo(deviceID, queryParamName, handle_type_size,
handle_type, NULL);

test_error(
errNum,
"Unable to query CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR \n");
"Unable to query supported device semaphore handle types list\n");

for (i = 0; i < handle_type_size; i++)
{
Expand Down Expand Up @@ -897,6 +906,8 @@ clExternalExportableSemaphore::clExternalExportableSemaphore(

cl_int err = 0;
cl_device_id devList[] = { deviceId, NULL };
cl_external_semaphore_handle_type_khr clSemaphoreHandleType =
getCLSemaphoreTypeFromVulkanType(externalSemaphoreHandleType);
m_externalHandleType = externalSemaphoreHandleType;
m_externalSemaphore = nullptr;
m_device = deviceId;
Expand All @@ -908,9 +919,7 @@ clExternalExportableSemaphore::clExternalExportableSemaphore(
};
sema_props.push_back(
(cl_semaphore_properties_khr)CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR);
sema_props.push_back(
(cl_semaphore_properties_khr)getCLSemaphoreTypeFromVulkanType(
externalSemaphoreHandleType));
sema_props.push_back((cl_semaphore_properties_khr)clSemaphoreHandleType);
sema_props.push_back((cl_semaphore_properties_khr)
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_LIST_END_KHR);
sema_props.push_back(
Expand All @@ -928,6 +937,83 @@ clExternalExportableSemaphore::clExternalExportableSemaphore(
throw std::runtime_error(
"clCreateSemaphoreWithPropertiesKHRptr failed! ");
}

switch (m_externalHandleType)
{
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD: {
err = clGetSemaphoreHandleForTypeKHRptr(
m_externalSemaphore, m_device, clSemaphoreHandleType,
sizeof(int), &fd, nullptr);
if (err != CL_SUCCESS)
{
throw std::runtime_error("Failed to export OpenCL semaphore\n");
}

VkImportSemaphoreFdInfoKHR vkImportSemaphoreFdInfoKHR = {};
vkImportSemaphoreFdInfoKHR.sType =
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
vkImportSemaphoreFdInfoKHR.semaphore = m_deviceSemaphore;
vkImportSemaphoreFdInfoKHR.fd = fd;
vkImportSemaphoreFdInfoKHR.pNext = nullptr;
vkImportSemaphoreFdInfoKHR.handleType =
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
vkImportSemaphoreFdInfoKHR.flags = 0;

if (vkImportSemaphoreFdKHR(m_deviceSemaphore.getDevice(),
&vkImportSemaphoreFdInfoKHR)
!= VK_SUCCESS)
{
throw std::runtime_error(
"Failed to import semaphore in Vulkan\n");
}
break;
}
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT:
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_NT: {
err = clGetSemaphoreHandleForTypeKHRptr(
m_externalSemaphore, m_device, clSemaphoreHandleType,
sizeof(void *), (void *)&handle, nullptr);
if (err != CL_SUCCESS)
{
throw std::runtime_error("Failed to export OpenCL semaphore\n");
}

#ifdef _WIN32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a switch or an else-if branch to explicitly match the windows handle enum type. If possible eliminate the ifdef, I made an effort to reduce the reliance of ifdefs to select semaphore handle types, and instead query the the platform for supported extensions. If eliminating the ifdef entirely is not possible, can its scope be reduced? What is the behavior if not WIN32 but also not opaque fd?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, actually I wasn't aware of your efforts made in that direction, will try to remove the ifdef.
As for your second question (I guess you are referring to sync_fd?), it still gets re-imported during every signal/wait operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in recent commit, couldn't eliminate it completely as it uses vkImportSemaphoreWin32HandleKHR, a windows specific def as per vulkan header.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good. I will test and update if anything fails on my end.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is fine. Lets merge.

VkImportSemaphoreWin32HandleInfoKHR
vkImportSemaphoreWin32HandleInfoKHR = {};
vkImportSemaphoreWin32HandleInfoKHR.sType =
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR;
vkImportSemaphoreWin32HandleInfoKHR.pNext = nullptr;
vkImportSemaphoreWin32HandleInfoKHR.semaphore = m_deviceSemaphore;
vkImportSemaphoreWin32HandleInfoKHR.flags = 0;
vkImportSemaphoreWin32HandleInfoKHR.handleType =
(VkExternalSemaphoreHandleTypeFlagBits)m_externalHandleType;
vkImportSemaphoreWin32HandleInfoKHR.handle = (HANDLE)handle;
vkImportSemaphoreWin32HandleInfoKHR.name = nullptr;

if (vkImportSemaphoreWin32HandleKHR(
m_deviceSemaphore.getDevice(),
&vkImportSemaphoreWin32HandleInfoKHR)
!= VK_SUCCESS)
{
throw std::runtime_error(
"Failed to import semaphore in Vulkan\n");
}
#else
log_error(
"Opaque D3DKMT and NT handles are only supported on Windows\n");
ASSERT(0);
#endif
break;
}
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD:
// Do nothing, imported after each signal from OpenCL
break;
default:
log_error("Unsupported external semaphore handle type\n");
ASSERT(0);
break;
}
}

clExternalExportableSemaphore::~clExternalExportableSemaphore()
Expand Down
21 changes: 20 additions & 1 deletion test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@
#include <OpenCL/cl_ext.h>
#endif

#define CREATE_OPENCL_SEMAPHORE(clSemaphore, vkSemaphore, ctx, handleType, \
devIdx, createExportable) \
if (!(createExportable \
&& (check_external_semaphore_handle_type( \
devIdx, getCLSemaphoreTypeFromVulkanType(handleType), \
CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR) \
== CL_SUCCESS))) \
{ \
clSemaphore = new clExternalImportableSemaphore(vkSemaphore, ctx, \
handleType, devIdx); \
} \
else \
{ \
clSemaphore = new clExternalExportableSemaphore(vkSemaphore, ctx, \
handleType, devIdx); \
}

typedef cl_semaphore_khr (*pfnclCreateSemaphoreWithPropertiesKHR)(
cl_context context, cl_semaphore_properties_khr *sema_props,
cl_int *errcode_ret);
Expand Down Expand Up @@ -76,7 +93,9 @@ cl_int check_external_memory_handle_type(
cl_external_memory_handle_type_khr requiredHandleType);
cl_int check_external_semaphore_handle_type(
cl_device_id deviceID,
cl_external_semaphore_handle_type_khr requiredHandleType);
cl_external_semaphore_handle_type_khr requiredHandleType,
cl_device_info queryParamName =
CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR);
cl_int setMaxImageDimensions(cl_device_id deviceID, size_t &width,
size_t &height);

Expand Down
4 changes: 3 additions & 1 deletion test_conformance/common/vulkan_wrapper/vulkan_api_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
VK_FUNC_DECL(vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)
#define VK_WINDOWS_FUNC_LIST \
VK_FUNC_DECL(vkGetMemoryWin32HandleKHR) \
VK_FUNC_DECL(vkGetSemaphoreWin32HandleKHR)
VK_FUNC_DECL(vkGetSemaphoreWin32HandleKHR) \
VK_FUNC_DECL(vkImportSemaphoreWin32HandleKHR)

#define vkEnumerateInstanceVersion _vkEnumerateInstanceVersion
#define vkEnumerateInstanceExtensionProperties \
Expand Down Expand Up @@ -198,5 +199,6 @@
_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR
#define vkGetMemoryWin32HandleKHR _vkGetMemoryWin32HandleKHR
#define vkGetSemaphoreWin32HandleKHR _vkGetSemaphoreWin32HandleKHR
#define vkImportSemaphoreWin32HandleKHR _vkImportSemaphoreWin32HandleKHR

#endif //_vulkan_api_list_hpp_
54 changes: 31 additions & 23 deletions test_conformance/vulkan/test_vulkan_interop_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,12 @@ int run_test_with_two_queue(
}
else
{
clVk2CLExternalSemaphore = new clExternalImportableSemaphore(
vkVk2CLSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
clCl2VkExternalSemaphore = new clExternalExportableSemaphore(
vkCl2VkSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
CREATE_OPENCL_SEMAPHORE(clVk2CLExternalSemaphore, vkVk2CLSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, false);
CREATE_OPENCL_SEMAPHORE(clCl2VkExternalSemaphore, vkCl2VkSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, true);
}

const uint32_t maxIter = innerIterations;
Expand Down Expand Up @@ -453,10 +455,12 @@ int run_test_with_one_queue(
}
else
{
clVk2CLExternalSemaphore = new clExternalImportableSemaphore(
vkVk2CLSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
clCl2VkExternalSemaphore = new clExternalExportableSemaphore(
vkCl2VkSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
CREATE_OPENCL_SEMAPHORE(clVk2CLExternalSemaphore, vkVk2CLSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, false);
CREATE_OPENCL_SEMAPHORE(clCl2VkExternalSemaphore, vkCl2VkSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, true);
}

const uint32_t maxIter = innerIterations;
Expand Down Expand Up @@ -742,10 +746,12 @@ int run_test_with_multi_import_same_ctx(
}
else
{
clVk2CLExternalSemaphore = new clExternalImportableSemaphore(
vkVk2CLSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
clCl2VkExternalSemaphore = new clExternalExportableSemaphore(
vkCl2VkSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
CREATE_OPENCL_SEMAPHORE(clVk2CLExternalSemaphore, vkVk2CLSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, false);
CREATE_OPENCL_SEMAPHORE(clCl2VkExternalSemaphore, vkCl2VkSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, true);
}

const uint32_t maxIter = innerIterations;
Expand Down Expand Up @@ -1071,17 +1077,19 @@ int run_test_with_multi_import_diff_ctx(
}
else
{
clVk2CLExternalSemaphore = new clExternalImportableSemaphore(
vkVk2CLSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
clCl2VkExternalSemaphore = new clExternalExportableSemaphore(
vkCl2VkSemaphore, context, vkExternalSemaphoreHandleType, deviceId);

clVk2CLExternalSemaphore2 = new clExternalImportableSemaphore(
vkVk2CLSemaphore, context2, vkExternalSemaphoreHandleType,
deviceId);
clCl2VkExternalSemaphore2 = new clExternalExportableSemaphore(
vkCl2VkSemaphore, context2, vkExternalSemaphoreHandleType,
deviceId);
CREATE_OPENCL_SEMAPHORE(clVk2CLExternalSemaphore, vkVk2CLSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, false);
CREATE_OPENCL_SEMAPHORE(clCl2VkExternalSemaphore, vkCl2VkSemaphore,
context, vkExternalSemaphoreHandleType,
deviceId, false);

CREATE_OPENCL_SEMAPHORE(clVk2CLExternalSemaphore2, vkVk2CLSemaphore,
context2, vkExternalSemaphoreHandleType,
deviceId, false);
CREATE_OPENCL_SEMAPHORE(clCl2VkExternalSemaphore2, vkCl2VkSemaphore,
context2, vkExternalSemaphoreHandleType,
deviceId, false);
}

const uint32_t maxIter = innerIterations;
Expand Down
16 changes: 8 additions & 8 deletions test_conformance/vulkan/test_vulkan_interop_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ int run_test_with_two_queue(
clExternalSemaphore *clVk2CLExternalSemaphore = NULL;
clExternalSemaphore *clCl2VkExternalSemaphore = NULL;

clVk2CLExternalSemaphore = new clExternalImportableSemaphore(
vkVk2CLSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
clCl2VkExternalSemaphore = new clExternalExportableSemaphore(
vkCl2VkSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
CREATE_OPENCL_SEMAPHORE(clVk2CLExternalSemaphore, vkVk2CLSemaphore, context,
vkExternalSemaphoreHandleType, deviceId, false);
CREATE_OPENCL_SEMAPHORE(clCl2VkExternalSemaphore, vkCl2VkSemaphore, context,
vkExternalSemaphoreHandleType, deviceId, true);

std::vector<VulkanDeviceMemory *> vkImage2DListDeviceMemory1;
std::vector<VulkanDeviceMemory *> vkImage2DListDeviceMemory2;
Expand Down Expand Up @@ -816,10 +816,10 @@ int run_test_with_one_queue(
clExternalSemaphore *clVk2CLExternalSemaphore = NULL;
clExternalSemaphore *clCl2VkExternalSemaphore = NULL;

clVk2CLExternalSemaphore = new clExternalImportableSemaphore(
vkVk2CLSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
clCl2VkExternalSemaphore = new clExternalExportableSemaphore(
vkCl2VkSemaphore, context, vkExternalSemaphoreHandleType, deviceId);
CREATE_OPENCL_SEMAPHORE(clVk2CLExternalSemaphore, vkVk2CLSemaphore, context,
vkExternalSemaphoreHandleType, deviceId, false);
CREATE_OPENCL_SEMAPHORE(clCl2VkExternalSemaphore, vkCl2VkSemaphore, context,
vkExternalSemaphoreHandleType, deviceId, true);

std::vector<VulkanDeviceMemory *> vkImage2DListDeviceMemory1;
std::vector<VulkanDeviceMemory *> vkImage2DListDeviceMemory2;
Expand Down
Loading