无法启用Vulkan时间线信号量扩展



我今天大部分时间都在做这件事,我已经智穷了。

我正在运行Vulkan SDK 1.2.131.2

我有一个RTX 2080钛

我有Windows 10 Education,版本1909,版本18363.657。

我使用的是Vulkan.hpp,而不是直接使用Vulkan.h。

以下是我指定使用的API版本:

appInfo.apiVersion = VK_API_VERSION_1_2;

这是创建设备的代码的相关部分:

// bla bla
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
VK_NV_RAY_TRACING_EXTENSION_NAME
};
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
m_logicalDevice = m_physicalDevice.createDeviceUnique(deviceCreateInfo);

我使用以下验证层:

"VK_LAYER_LUNARG_api_dump"
"VK_LAYER_KHRONOS_validation"

这就是我后来尝试创建时间线信号量的方式:

vk::UniqueSemaphore VulkanContext::createTimelineSemaphore(const uint32_t initialValue) const {
vk::SemaphoreTypeCreateInfo timelineCreateInfo;
timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
timelineCreateInfo.initialValue = initialValue;
vk::SemaphoreCreateInfo createInfo;
createInfo.pNext = &timelineCreateInfo;
return m_logicalDevice->createSemaphoreUnique(createInfo);
}

我得到以下错误:

vkCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore) returns VkResultVkCreateSemaphore: timelineSemaphore feature is not enabled, can not create timeline semaphores The Vulkan spec states: If the timelineSemaphore feature is not enabled, semaphoreType must not equal VK_SEMAPHORE_TYPE_TIMELINE (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSemaphoreTypeCreateInfo-timelineSemaphore-03252)

这更令人愤怒,因为时间线信号应该是Vulkan 1.2核心的一部分,但即使我从扩展列表中删除了它,我也会收到同样的错误。Swapchain扩展确实有效,我还没有时间验证光线跟踪扩展是否已启用。

它变得更加愚蠢,因为下一条消息告诉我:

VK_SUCCESS (0):
device:                         VkDevice = 0000023AA29BD8B0
pCreateInfo:                    const VkSemaphoreCreateInfo* = 0000008D145ED538:
sType:                          VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO (9)
pNext:                          VkSemaphoreTypeCreateInfo = 0000008D145ED4F8:
sType:                          VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO (1000207002)
pNext:                          const void* = NULL
semaphoreType:                  VkSemaphoreType = VK_SEMAPHORE_TYPE_TIMELINE (1)
initialValue:                   uint64_t = 0
flags:                          VkSemaphoreCreateFlags = 0
pAllocator:                     const VkAllocationCallbacks* = NULL
pSemaphore:                     VkSemaphore* = AA989B000000001E

我不知道这是创建了时间线信号量,还是只是创建了一个普通的二进制信号量。

当我稍后使用它提交到传输队列时:

vk::CommandBufferBeginInfo beginInfo;
transferCmdBuffer->begin(beginInfo);
object->recordUploadToGPU(*transferCmdBuffer);
transferCmdBuffer->end();
vk::TimelineSemaphoreSubmitInfo timelineSubmitInfo;
timelineSubmitInfo.signalSemaphoreValueCount = 1;
timelineSubmitInfo.pSignalSemaphoreValues = &signalValue;
vk::SubmitInfo submitInfo;
submitInfo.pNext = &timelineSubmitInfo;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &signalSemaphore;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &*transferCmdBuffer;
vkCtx.m_transferQueue.submit(submitInfo, nullptr);

我在这里得到这个错误:

vkQueueSubmit(queue, submitCount, pSubmits, fence) returns VkResultVkQueueSubmit: VkQueue 0x23aa2539500[] contains timeline sempahore VkSemaphore 0xaa989b000000001e[] that sets its wait value with a margin greater than maxTimelineSemaphoreValueDifference The Vulkan spec states: For each element of pSignalSemaphores created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_TIMELINE the corresponding element of VkTimelineSemaphoreSubmitInfo::pSignalSemaphoreValues must have a value which does not differ from the current value of the semaphore or the value of any outstanding semaphore wait or signal operation on that semaphore by more than maxTimelineSemaphoreValueDifference. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubmitInfo-pSignalSemaphores-03244)

更可笑的是,这是下一行:

VK_SUCCESS (0):
queue:                          VkQueue = 0000023AA2539500
submitCount:                    uint32_t = 1
pSubmits:                       const VkSubmitInfo* = 0000008D145ED370
pSubmits[0]:                    const VkSubmitInfo = 0000008D145ED370:
sType:                          VkStructureType = VK_STRUCTURE_TYPE_SUBMIT_INFO (4)
pNext:                          VkTimelineSemaphoreSubmitInfo = 0000008D145ED318:
sType:                          VkStructureType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO (1000207003)
pNext:                          const void* = NULL
waitSemaphoreValueCount:        uint32_t = 0
pWaitSemaphoreValues:           const uint64_t* = NULL
signalSemaphoreValueCount:      uint32_t = 1
pSignalSemaphoreValues:         const uint64_t* = 0000008D145ED740
pSignalSemaphoreValues[0]:      const uint64_t = 1
waitSemaphoreCount:             uint32_t = 0
pWaitSemaphores:                const VkSemaphore* = NULL
pWaitDstStageMask:              const VkPipelineStageFlags* = NULL
commandBufferCount:             uint32_t = 1
pCommandBuffers:                const VkCommandBuffer* = 0000008D145EF408
pCommandBuffers[0]:             const VkCommandBuffer = 0000023AA9CEC8E0
signalSemaphoreCount:           uint32_t = 1
pSignalSemaphores:              const VkSemaphore* = 0000008D145EF430
pSignalSemaphores[0]:           const VkSemaphore = AA989B000000001E
fence:                          VkFence = 0000000000000000

我还尝试过VK_API_VERSION_1_1VK_API_VERSION_1_0,无论是否显式启用扩展,它们都不起作用。

转储来自VK_LAYER_LUNARG_api_dump验证层,而VK_LAYER_KHRONOS_validation验证层是输出错误的层。他们似乎不同意。

那么,是什么呢?

我今天怎么这么笨?

编辑:

下面是一个你应该能够自己跑步的例子。我想我已经尽我所能做到了最低限度:

#include <vulkan/vulkan.hpp>
#include <iostream>
VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData) {
std::cerr << pCallbackData->pMessage << std::endl;
return VK_FALSE;
};
int main() {
vk::ApplicationInfo appInfo;
appInfo.apiVersion = VK_API_VERSION_1_2;
vk::InstanceCreateInfo instanceCreateInfo;
instanceCreateInfo.pApplicationInfo = &appInfo;
std::vector<const char*> extensions;
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
instanceCreateInfo.ppEnabledExtensionNames = extensions.data();
const std::vector<const char*> validationLayers = {
"VK_LAYER_LUNARG_api_dump",
"VK_LAYER_KHRONOS_validation"
};
instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
instanceCreateInfo.ppEnabledLayerNames = validationLayers.data();
vk::DebugUtilsMessengerCreateInfoEXT debugCreateInfo;
debugCreateInfo.messageSeverity =
vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
debugCreateInfo.messageType =
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
debugCreateInfo.pfnUserCallback = debugCallback;
instanceCreateInfo.pNext = &debugCreateInfo;
vk::Instance m_instance = vk::createInstance(instanceCreateInfo);
vk::DispatchLoaderDynamic m_loader = vk::DispatchLoaderDynamic(m_instance, vkGetInstanceProcAddr);
vk::DebugUtilsMessengerEXT m_debugMessenger = m_instance.createDebugUtilsMessengerEXT(debugCreateInfo, nullptr, m_loader);
vk::PhysicalDevice m_physicalDevice = m_instance.enumeratePhysicalDevices()[0];
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
vk::DeviceQueueCreateInfo queueInfo;
queueInfo.queueFamilyIndex = 0;
queueInfo.queueCount = 1;
queueCreateInfos.push_back(queueInfo);
vk::PhysicalDeviceFeatures deviceFeatures;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
// This part can be omitted from here...
const std::vector<const char*> deviceExtensions = {
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME
};
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
// ...to here. It doesn't work either way.
vk::Device m_logicalDevice = m_physicalDevice.createDevice(deviceCreateInfo);
vk::SemaphoreTypeCreateInfo timelineCreateInfo;
timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
timelineCreateInfo.initialValue = 0;
vk::SemaphoreCreateInfo semaphoreCreateInfo;
semaphoreCreateInfo.pNext = &timelineCreateInfo;
m_logicalDevice.createSemaphore(semaphoreCreateInfo);
}

该功能也需要显式启用:

vk::PhysicalDeviceVulkan12Features features;
features.timelineSemaphore = true;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.pNext = &features;

最新更新