Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

488 lines
19 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include "vulkan_test.hh"
#include <iostream>
#include <algorithm>
VkFence VulkanTest::CreateFence() {
VkFence fence;
VkFenceCreateInfo fence_create_info = {};
fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fence_create_info.flags = 0;
VK_CHECK_RESULT(vkCreateFence(_device, &fence_create_info, nullptr, &fence));
_fences.push_back(fence);
return fence;
}
VkSemaphore VulkanTest::CreateExternalSemaphore(VkSemaphoreType sem_type, uint64_t initial_value) {
VkExportSemaphoreCreateInfoKHR export_sem_create_info = {};
VkSemaphoreTypeCreateInfo timeline_create_info = {};
export_sem_create_info.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR;
export_sem_create_info.handleTypes = _sem_handle_type;
if (sem_type == VK_SEMAPHORE_TYPE_TIMELINE) {
timeline_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
timeline_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
timeline_create_info.initialValue = initial_value;
export_sem_create_info.pNext = &timeline_create_info;
} else {
export_sem_create_info.pNext = nullptr;
}
VkSemaphoreCreateInfo semaphore_create_info = {};
semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphore_create_info.pNext = &export_sem_create_info;
VkSemaphore semaphore;
VK_CHECK_RESULT(vkCreateSemaphore(_device, &semaphore_create_info, nullptr, &semaphore));
_semaphores.push_back(semaphore);
return semaphore;
}
hipExternalSemaphoreHandleDesc VulkanTest::BuildSemaphoreDescriptor(VkSemaphore vk_sem,
VkSemaphoreType sem_type) {
hipExternalSemaphoreHandleDesc sem_handle_desc = {};
sem_handle_desc.type = VulkanSemHandleTypeToHIPHandleType(sem_type);
#ifdef _WIN64
sem_handle_desc.handle.win32.handle = GetSemaphoreHandle(vk_sem);
#else
sem_handle_desc.handle.fd = GetSemaphoreHandle(vk_sem);
#endif
sem_handle_desc.flags = 0;
return sem_handle_desc;
}
hipExternalMemoryHandleDesc VulkanTest::BuildMemoryDescriptor(VkDeviceMemory vk_mem,
uint32_t size) {
hipExternalMemoryHandleDesc mem_handle_desc = {};
mem_handle_desc.type = VulkanMemHandleTypeToHIPHandleType();
#ifdef _WIN64
mem_handle_desc.handle.win32.handle = GetMemoryHandle(vk_mem);
#else
mem_handle_desc.handle.fd = GetMemoryHandle(vk_mem);
#endif
mem_handle_desc.size = size;
return mem_handle_desc;
}
void VulkanTest::CreateInstance() {
UNSCOPED_INFO("Not all of the required instance extensions are supported");
REQUIRE(CheckExtensionSupport(_required_instance_extensions));
if (_enable_validation) {
EnableValidationLayer();
}
VkApplicationInfo app_info = {};
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.apiVersion = VK_API_VERSION_1_2;
VkInstanceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.pApplicationInfo = &app_info;
create_info.enabledExtensionCount = static_cast<uint32_t>(_required_instance_extensions.size());
create_info.ppEnabledExtensionNames = _required_instance_extensions.data();
create_info.enabledLayerCount = static_cast<uint32_t>(_enabled_layers.size());
create_info.ppEnabledLayerNames = _enabled_layers.data();
VK_CHECK_RESULT(vkCreateInstance(&create_info, nullptr, &_instance));
}
void VulkanTest::CreateDevice() {
UNSCOPED_INFO("Not all of the required device extensions are supported");
REQUIRE(CheckExtensionSupport(_required_device_extensions));
FindPhysicalDevice();
VkDeviceQueueCreateInfo queue_create_info = {};
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_info.queueFamilyIndex = _compute_family_queue_idx = GetComputeQueueFamilyIndex();
queue_create_info.queueCount = 1;
float queue_priorities = 1.0;
queue_create_info.pQueuePriorities = &queue_priorities;
VkPhysicalDeviceVulkan12Features features = {};
features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
features.timelineSemaphore = true;
VkDeviceCreateInfo device_create_info = {};
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.enabledLayerCount = _enabled_layers.size();
device_create_info.ppEnabledLayerNames = _enabled_layers.data();
device_create_info.enabledExtensionCount = _required_device_extensions.size();
device_create_info.ppEnabledExtensionNames = _required_device_extensions.data();
device_create_info.pQueueCreateInfos = &queue_create_info;
device_create_info.queueCreateInfoCount = 1;
device_create_info.pNext = &features;
VK_CHECK_RESULT(vkCreateDevice(_physical_device, &device_create_info, nullptr, &_device));
vkGetDeviceQueue(_device, _compute_family_queue_idx, 0, &_queue);
}
void VulkanTest::CreateCommandBuffer() {
VkCommandPoolCreateInfo command_pool_create_info = {};
command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
command_pool_create_info.flags = 0;
command_pool_create_info.queueFamilyIndex = _compute_family_queue_idx;
VK_CHECK_RESULT(vkCreateCommandPool(_device, &command_pool_create_info, nullptr, &_command_pool));
VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
command_buffer_allocate_info.commandPool = _command_pool;
command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
command_buffer_allocate_info.commandBufferCount = 1;
VK_CHECK_RESULT(
vkAllocateCommandBuffers(_device, &command_buffer_allocate_info, &_command_buffer));
}
bool VulkanTest::CheckExtensionSupport(std::vector<const char*> expected_extensions) {
uint32_t extension_count = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
std::vector<VkExtensionProperties> extension_properties(extension_count);
vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_properties.data());
std::vector<const char*> supported_extensions;
supported_extensions.reserve(extension_count);
std::transform(extension_properties.begin(), extension_properties.end(),
std::back_inserter(supported_extensions),
[](const auto& p) { return p.extensionName; });
auto p = [](const char* l, const char* r) { return strcmp(l, r) < 0; };
std::sort(expected_extensions.begin(), expected_extensions.end(), p);
std::sort(supported_extensions.begin(), supported_extensions.end(), p);
return std::includes(supported_extensions.begin(), supported_extensions.end(),
expected_extensions.begin(), expected_extensions.end(),
[](const char* l, const char* r) { return strcmp(l, r) == 0; });
}
void VulkanTest::EnableValidationLayer() {
uint32_t layer_count = 0;
vkEnumerateInstanceLayerProperties(&layer_count, nullptr);
std::vector<VkLayerProperties> layer_properties(layer_count);
vkEnumerateInstanceLayerProperties(&layer_count, layer_properties.data());
const bool found_val_layer =
std::any_of(layer_properties.cbegin(), layer_properties.cend(), [](const auto& props) {
return strcmp(props.layerName, "VK_LAYER_KHRONOS_validation") == 0;
});
if (found_val_layer) {
_enabled_layers.push_back("VK_LAYER_KHRONOS_validation");
} else {
UNSCOPED_INFO("Validation was requested, but the validation layer could not be located");
REQUIRE(found_val_layer);
}
}
uint32_t VulkanTest::GetComputeQueueFamilyIndex() {
uint32_t queue_family_count = 0u;
vkGetPhysicalDeviceQueueFamilyProperties(_physical_device, &queue_family_count, nullptr);
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
vkGetPhysicalDeviceQueueFamilyProperties(_physical_device, &queue_family_count,
queue_families.data());
const auto it =
std::find_if(queue_families.cbegin(), queue_families.cend(), [](const auto& props) {
return props.queueCount > 0 && (props.queueFlags & VK_QUEUE_COMPUTE_BIT);
});
REQUIRE(it != queue_families.cend());
return std::distance(queue_families.cbegin(), it);
}
void VulkanTest::FindPhysicalDevice() {
uint32_t device_count = 0;
vkEnumeratePhysicalDevices(_instance, &device_count, nullptr);
REQUIRE(device_count != 0u);
std::vector<VkPhysicalDevice> physical_devices(device_count);
vkEnumeratePhysicalDevices(_instance, &device_count, physical_devices.data());
_physical_device = physical_devices[0];
}
uint32_t VulkanTest::FindMemoryType(uint32_t memory_type_bits, VkMemoryPropertyFlags properties) {
VkPhysicalDeviceMemoryProperties memory_properties;
vkGetPhysicalDeviceMemoryProperties(_physical_device, &memory_properties);
for (uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i) {
if ((memory_type_bits & (1 << i)) &&
((memory_properties.memoryTypes[i].propertyFlags & properties) == properties)) {
return i;
}
}
return VK_MAX_MEMORY_TYPES;
}
hipExternalSemaphoreHandleType VulkanTest::VulkanSemHandleTypeToHIPHandleType(
VkSemaphoreType sem_type) {
if (sem_type == VK_SEMAPHORE_TYPE_BINARY) {
if (_sem_handle_type & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT) {
return hipExternalSemaphoreHandleTypeOpaqueWin32;
} else if (_sem_handle_type & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) {
return hipExternalSemaphoreHandleTypeOpaqueWin32Kmt;
} else if (_sem_handle_type & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
return hipExternalSemaphoreHandleTypeOpaqueFd;
}
} else if (sem_type == VK_SEMAPHORE_TYPE_TIMELINE) {
#if HT_AMD
throw std::invalid_argument("Timeline semaphore unsupported on AMD");
#else
if (_sem_handle_type & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT) {
return hipExternalSemaphoreHandleTypeTimelineSemaphoreWin32;
} else if (_sem_handle_type & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) {
return hipExternalSemaphoreHandleTypeTimelineSemaphoreWin32;
} else if (_sem_handle_type & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
return hipExternalSemaphoreHandleTypeTimelineSemaphoreFd;
}
#endif
}
throw std::invalid_argument("Invalid vulkan semaphore handle type");
}
hipExternalMemoryHandleType VulkanTest::VulkanMemHandleTypeToHIPHandleType() {
if (_mem_handle_type & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT) {
return hipExternalMemoryHandleTypeOpaqueWin32;
} else if (_mem_handle_type & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT) {
return hipExternalMemoryHandleTypeOpaqueWin32Kmt;
} else if (_mem_handle_type & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) {
return hipExternalMemoryHandleTypeOpaqueFd;
}
throw std::invalid_argument("Invalid vulkan memory handle type");
}
#ifdef _WIN64
HANDLE
VulkanTest::GetSemaphoreHandle(VkSemaphore semaphore) {
HANDLE handle = 0;
VkSemaphoreGetWin32HandleInfoKHR semaphoreGetWin32HandleInfoKHR = {};
semaphoreGetWin32HandleInfoKHR.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR;
semaphoreGetWin32HandleInfoKHR.pNext = NULL;
semaphoreGetWin32HandleInfoKHR.semaphore = semaphore;
semaphoreGetWin32HandleInfoKHR.handleType = _sem_handle_type;
PFN_vkGetSemaphoreWin32HandleKHR fpGetSemaphoreWin32HandleKHR;
fpGetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(
_device, "vkGetSemaphoreWin32HandleKHR");
if (!fpGetSemaphoreWin32HandleKHR) {
throw std::runtime_error("Failed to retrieve vkGetSemaphoreWin32HandleKHR");
}
if (fpGetSemaphoreWin32HandleKHR(_device, &semaphoreGetWin32HandleInfoKHR, &handle) !=
VK_SUCCESS) {
throw std::runtime_error("Failed to retrieve handle for buffer!");
}
return handle;
}
#else
int VulkanTest::GetSemaphoreHandle(VkSemaphore semaphore) {
int fd;
VkSemaphoreGetFdInfoKHR semaphoreGetFdInfoKHR = {};
semaphoreGetFdInfoKHR.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
semaphoreGetFdInfoKHR.pNext = NULL;
semaphoreGetFdInfoKHR.semaphore = semaphore;
semaphoreGetFdInfoKHR.handleType = _sem_handle_type;
PFN_vkGetSemaphoreFdKHR fpGetSemaphoreFdKHR;
fpGetSemaphoreFdKHR =
(PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(_device, "vkGetSemaphoreFdKHR");
if (!fpGetSemaphoreFdKHR) {
throw std::runtime_error("Failed to retrieve vkGetSemaphoreFdKHR");
}
if (fpGetSemaphoreFdKHR(_device, &semaphoreGetFdInfoKHR, &fd) != VK_SUCCESS) {
throw std::runtime_error("Failed to retrieve semaphore handle");
}
return fd;
}
#endif
#ifdef _WIN64
HANDLE
VulkanTest::GetMemoryHandle(VkDeviceMemory memory) {
HANDLE handle = 0;
VkMemoryGetWin32HandleInfoKHR vkMemoryGetWin32HandleInfoKHR = {};
vkMemoryGetWin32HandleInfoKHR.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
vkMemoryGetWin32HandleInfoKHR.memory = memory;
vkMemoryGetWin32HandleInfoKHR.handleType = _mem_handle_type;
PFN_vkGetMemoryWin32HandleKHR fpGetMemoryWin32HandleKHR =
(PFN_vkGetMemoryWin32HandleKHR)vkGetDeviceProcAddr(_device, "vkGetMemoryWin32HandleKHR");
if (!fpGetMemoryWin32HandleKHR) {
throw std::runtime_error("Failed to retrieve vkGetMemoryWin32HandleKHR");
}
if (fpGetMemoryWin32HandleKHR(_device, &vkMemoryGetWin32HandleInfoKHR, &handle) != VK_SUCCESS) {
throw std::runtime_error("Failed to retrieve memory handle");
}
return handle;
}
#else
int VulkanTest::GetMemoryHandle(VkDeviceMemory memory) {
int fd;
VkMemoryGetFdInfoKHR memoryGetFdInfoKHR = {};
memoryGetFdInfoKHR.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
memoryGetFdInfoKHR.memory = memory;
memoryGetFdInfoKHR.handleType = _mem_handle_type;
PFN_vkGetMemoryFdKHR fpGetMemoryFdKHR =
(PFN_vkGetMemoryFdKHR)vkGetDeviceProcAddr(_device, "vkGetMemoryFdKHR");
if (!fpGetMemoryFdKHR) {
throw std::runtime_error("Failed to retrieve vkGetMemoryFdKHR");
}
if (fpGetMemoryFdKHR(_device, &memoryGetFdInfoKHR, &fd) != VK_SUCCESS) {
throw std::runtime_error("Failed to retrieve memory handle");
}
return fd;
}
#endif
VkExternalSemaphoreHandleTypeFlagBits VulkanTest::GetVkSemHandlePlatformType() const {
#ifdef _WIN64
return IsWindows8OrGreater() ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
: VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
#else
return VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
#endif
}
VkExternalMemoryHandleTypeFlagBits VulkanTest::GetVkMemHandlePlatformType() const {
#ifdef _WIN64
return IsWindows8OrGreater() ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
#else
return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
#endif
}
void VulkanTest::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties, VkBuffer& buffer,
VkDeviceMemory& buffer_memory, bool external) {
VkBufferCreateInfo buffer_create_info = {};
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_create_info.size = size;
buffer_create_info.usage = usage;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkExternalMemoryBufferCreateInfo external_memory_buffer_info = {};
if (external) {
external_memory_buffer_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
external_memory_buffer_info.handleTypes = _mem_handle_type;
buffer_create_info.pNext = &external_memory_buffer_info;
}
VK_CHECK_RESULT(vkCreateBuffer(_device, &buffer_create_info, nullptr, &buffer));
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(_device, buffer, &memory_requirements);
VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = memory_requirements.size;
alloc_info.memoryTypeIndex = FindMemoryType(memory_requirements.memoryTypeBits, properties);
VkExportMemoryAllocateInfoKHR vulkan_export_memory_allocate_info = {};
#ifdef _WIN64
WindowsSecurityAttributes win_security_attributes = {};
VkExportMemoryWin32HandleInfoKHR vulkan_export_memory_win32_handle_info = {};
#endif
if (external) {
vulkan_export_memory_allocate_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
vulkan_export_memory_allocate_info.handleTypes = _mem_handle_type;
#ifdef _WIN64
vulkan_export_memory_win32_handle_info.sType =
VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
vulkan_export_memory_win32_handle_info.pNext = NULL;
vulkan_export_memory_win32_handle_info.pAttributes = &win_security_attributes;
vulkan_export_memory_win32_handle_info.dwAccess =
DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
vulkan_export_memory_win32_handle_info.name = (LPCWSTR)NULL;
vulkan_export_memory_allocate_info.pNext =
_mem_handle_type & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
? &vulkan_export_memory_win32_handle_info
: NULL;
#endif
alloc_info.pNext = &vulkan_export_memory_allocate_info;
}
VK_CHECK_RESULT(vkAllocateMemory(_device, &alloc_info, nullptr, &buffer_memory));
VK_CHECK_RESULT(vkBindBufferMemory(_device, buffer, buffer_memory, 0));
}
void VulkanTest::CopyBuffer(VkBuffer src_buffer, VkBuffer dst_buffer, VkDeviceSize size) {
VkCommandBufferAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
alloc_info.commandPool = _command_pool;
alloc_info.commandBufferCount = 1;
VkCommandBuffer command_buffer;
vkAllocateCommandBuffers(_device, &alloc_info, &command_buffer);
VkCommandBufferBeginInfo begin_info = {};
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(command_buffer, &begin_info);
VkBufferCopy buffer_copy = {};
buffer_copy.size = size;
vkCmdCopyBuffer(command_buffer, src_buffer, dst_buffer, 1, &buffer_copy);
vkEndCommandBuffer(command_buffer);
VkSubmitInfo submit_info = {};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &command_buffer;
vkQueueSubmit(_queue, 1, &submit_info, VK_NULL_HANDLE);
vkQueueWaitIdle(_queue);
vkFreeCommandBuffers(_device, _command_pool, 1, &command_buffer);
}
// Sometimes in CUDA the stream is not immediately ready after a semaphore has been signaled
void PollStream(hipStream_t stream, hipError_t expected, uint32_t num_iterations) {
hipError_t query_result;
for (uint32_t _ = 0; _ < num_iterations; ++_) {
if ((query_result = hipStreamQuery(stream)) != expected) {
std::this_thread::sleep_for(std::chrono::milliseconds{5});
} else {
break;
}
}
REQUIRE(expected == query_result);
}
hipExternalSemaphore_t ImportBinarySemaphore(VulkanTest& vkt) {
const auto semaphore = vkt.CreateExternalSemaphore(VK_SEMAPHORE_TYPE_BINARY);
const auto sem_handle_desc = vkt.BuildSemaphoreDescriptor(semaphore, VK_SEMAPHORE_TYPE_BINARY);
hipExternalSemaphore_t hip_ext_semaphore;
HIP_CHECK(hipImportExternalSemaphore(&hip_ext_semaphore, &sem_handle_desc));
return hip_ext_semaphore;
}